From 3d7bc7cd6cb4940f99a4b9f03de8683c264938e2 Mon Sep 17 00:00:00 2001 From: Devan Buggay Date: Thu, 23 Oct 2025 08:53:31 -0700 Subject: [PATCH] Add CDP frame events Summary: Scaffolding for the bare minimum events needed to have frames show up on the performance timeline. layerTreeId hardcoded to `1` for now. Support for dropped and idle frames to be added later, full list can be found here https://github.com/facebook/react-native-devtools-frontend/blob/main/front_end/models/trace/types/TraceEvents.ts#L2971. Some more thought needs to be put into how Android frame timing maps to these events. {F1982947634} Changelog: [Internal] Differential Revision: D85347959 --- .../tracing/PerformanceTracer.cpp | 60 +++++++++++++++++++ .../tracing/PerformanceTracer.h | 35 ++++++++++- 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp index 8cd38188c3463c..e635ab6c85e10a 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp @@ -679,6 +679,66 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent( .args = folly::dynamic::object("data", std::move(data)), }); }, + [&](PerformanceTracerSetLayerTreeIdEvent&& event) { + folly::dynamic data = folly::dynamic::object("frame", event.frame)( + "layerTreeId", event.layerTreeId); + + events.emplace_back(TraceEvent{ + .name = "SetLayerTreeId", + .cat = "devtools.timeline", + .ph = 'I', + .ts = event.start, + .pid = processId_, + .s = 't', + .tid = event.threadId, + .args = folly::dynamic::object("data", std::move(data)), + }); + }, + [&](PerformanceTracerFrameBeginDrawEvent&& event) { + folly::dynamic data = folly::dynamic::object( + "frameSeqId", event.frameSeqId)("layerTreeId", 1); + + events.emplace_back(TraceEvent{ + .name = "BeginFrame", + .cat = "devtools.timeline", + .ph = 'I', + .ts = event.start, + .pid = processId_, + .s = 't', + .tid = event.threadId, + .args = std::move(data), + }); + }, + [&](PerformanceTracerFrameCommitEvent&& event) { + folly::dynamic data = folly::dynamic::object( + "frameSeqId", event.frameSeqId)("layerTreeId", 1); + + events.emplace_back(TraceEvent{ + .name = "Commit", + .cat = "devtools.timeline", + .ph = 'I', + .ts = event.start, + .pid = processId_, + .s = 't', + .tid = event.threadId, + .args = std::move(data), + }); + }, + [&](PerformanceTracerFrameDrawEvent&& event) { + folly::dynamic data = folly::dynamic::object( + "frameSeqId", event.frameSeqId)("layerTreeId", 1); + + events.emplace_back(TraceEvent{ + .name = "DrawFrame", + .cat = "devtools.timeline", + .ph = 'I', + .ts = event.start, + .pid = processId_, + .s = 't', + .tid = event.threadId, + .args = std::move(data), + }); + }, }, std::move(event)); } diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h index e93e985525e6c7..5e378fa8d85f13 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h @@ -268,6 +268,35 @@ class PerformanceTracer { HighResTimeStamp createdAt = HighResTimeStamp::now(); }; + struct PerformanceTracerSetLayerTreeIdEvent { + std::string frame; + int layerTreeId; + HighResTimeStamp start; + ThreadId threadId; + HighResTimeStamp createdAt = HighResTimeStamp::now(); + }; + + struct PerformanceTracerFrameBeginDrawEvent { + int frameSeqId; + HighResTimeStamp start; + ThreadId threadId; + HighResTimeStamp createdAt = HighResTimeStamp::now(); + }; + + struct PerformanceTracerFrameCommitEvent { + int frameSeqId; + HighResTimeStamp start; + ThreadId threadId; + HighResTimeStamp createdAt = HighResTimeStamp::now(); + }; + + struct PerformanceTracerFrameDrawEvent { + int frameSeqId; + HighResTimeStamp start; + ThreadId threadId; + HighResTimeStamp createdAt = HighResTimeStamp::now(); + }; + using PerformanceTracerEvent = std::variant< PerformanceTracerEventTimeStamp, PerformanceTracerEventEventLoopTask, @@ -276,7 +305,11 @@ class PerformanceTracer { PerformanceTracerEventMeasure, PerformanceTracerResourceSendRequest, PerformanceTracerResourceReceiveResponse, - PerformanceTracerResourceFinish>; + PerformanceTracerResourceFinish, + PerformanceTracerSetLayerTreeIdEvent, + PerformanceTracerFrameBeginDrawEvent, + PerformanceTracerFrameCommitEvent, + PerformanceTracerFrameDrawEvent>; #pragma mark - Private fields and methods