Skip to content

Commit 0d25e99

Browse files
committed
Add _beginSection and _endSection JSI bindings for systraces
1 parent eaaab30 commit 0d25e99

5 files changed

Lines changed: 95 additions & 1 deletion

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Button, StyleSheet, Text, View } from 'react-native';
2+
3+
import React from 'react';
4+
import { scheduleOnUI } from 'react-native-worklets';
5+
6+
function handlePress() {
7+
scheduleOnUI(() => {
8+
globalThis._beginSection('SystraceSectionExample');
9+
const start = performance.now();
10+
while (performance.now() - start < 1000) {}
11+
globalThis._endSection();
12+
});
13+
}
14+
15+
export default function SystraceSectionExample() {
16+
return (
17+
<View style={styles.container}>
18+
<Text>Hello world!</Text>
19+
<Button
20+
title="Begin section, wait 1 second, end section"
21+
onPress={handlePress}
22+
/>
23+
</View>
24+
);
25+
}
26+
27+
const styles = StyleSheet.create({
28+
container: {
29+
flex: 1,
30+
alignItems: 'center',
31+
justifyContent: 'center',
32+
},
33+
});

apps/common-app/src/apps/reanimated/examples/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ import SvgExample from './SvgExample';
144144
import SwipeableListExample from './SwipeableListExample';
145145
import SynchronizablePerformanceExample from './SynchronizableExample';
146146
import SynchronousPropsExample from './SynchronousPropsExample';
147+
import SystraceSectionExample from './SystraceSectionExample';
147148
import ThirdPartyComponentsExample from './ThirdPartyComponentsExample';
148149
import TransformExample from './TransformExample';
149150
import TransformOriginExample from './TransformOriginExample';
@@ -198,6 +199,11 @@ export const EXAMPLES: Record<string, Example> = {
198199
title: 'FPS',
199200
screen: FpsExample,
200201
},
202+
SystraceSectionExample: {
203+
icon: '📊',
204+
title: 'Systrace section',
205+
screen: SystraceSectionExample,
206+
},
201207
SyncBackToReactExample: {
202208
icon: '🔄',
203209
title: 'Sync back to React',

packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,37 @@
77
#include <worklets/WorkletRuntime/WorkletRuntime.h>
88
#include <worklets/WorkletRuntime/WorkletRuntimeDecorator.h>
99

10+
#ifdef ANDROID
11+
#include <android/trace.h>
12+
#endif
13+
14+
#if defined(__APPLE__)
15+
#include <os/trace_base.h>
16+
#if OS_LOG_TARGET_HAS_10_15_FEATURES
17+
#include <os/log.h>
18+
#include <os/signpost.h>
19+
#endif
20+
#endif
21+
1022
#include <memory>
1123
#include <string>
1224
#include <utility>
1325
#include <vector>
1426

27+
#if defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES
28+
static os_log_t workletsInstrumentsLogHandle = nullptr;
29+
static thread_local os_signpost_id_t tls_signpostId = OS_SIGNPOST_ID_INVALID;
30+
static thread_local std::string tls_signpostName;
31+
32+
static os_log_t getWorkletsInstrumentsLogHandle() {
33+
if (!workletsInstrumentsLogHandle) {
34+
workletsInstrumentsLogHandle =
35+
os_log_create("dev.worklets.instruments", OS_LOG_CATEGORY_POINTS_OF_INTEREST);
36+
}
37+
return workletsInstrumentsLogHandle;
38+
}
39+
#endif
40+
1541
namespace worklets {
1642

1743
static inline double performanceNow() {
@@ -87,6 +113,33 @@ void WorkletRuntimeDecorator::decorate(
87113
return jsi::String::createFromUtf8(rt, stringifyJSIValue(rt, value));
88114
});
89115

116+
jsi_utils::installJsiFunction(rt, "_beginSection", [](jsi::Runtime &rt, const jsi::Value &nameValue) {
117+
#ifdef ANDROID
118+
ATrace_beginSection(nameValue.asString(rt).utf8(rt).c_str());
119+
#elif defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES
120+
os_log_t logHandle = getWorkletsInstrumentsLogHandle();
121+
if (os_signpost_enabled(logHandle)) {
122+
tls_signpostName = nameValue.asString(rt).utf8(rt);
123+
tls_signpostId = os_signpost_id_make_with_pointer(logHandle, &tls_signpostId);
124+
os_signpost_interval_begin(logHandle, tls_signpostId, "Worklets", "%s", tls_signpostName.c_str());
125+
}
126+
#endif
127+
return jsi::Value::undefined();
128+
});
129+
130+
jsi_utils::installJsiFunction(rt, "_endSection", [](jsi::Runtime &rt) {
131+
#ifdef ANDROID
132+
ATrace_endSection();
133+
#elif defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES
134+
os_log_t logHandle = getWorkletsInstrumentsLogHandle();
135+
if (os_signpost_enabled(logHandle) && tls_signpostId != OS_SIGNPOST_ID_INVALID) {
136+
os_signpost_interval_end(logHandle, tls_signpostId, "Worklets", "%s end", tls_signpostName.c_str());
137+
tls_signpostId = OS_SIGNPOST_ID_INVALID;
138+
}
139+
#endif
140+
return jsi::Value::undefined();
141+
});
142+
90143
jsi_utils::installJsiFunction(
91144
rt, "_createSerializable", [](jsi::Runtime &rt, const jsi::Value &value, const jsi::Value &nativeStateSource) {
92145
auto shouldRetainRemote = jsi::Value::undefined();

packages/react-native-worklets/android/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ target_include_directories(
9999
# build shared lib
100100
set_target_properties(worklets PROPERTIES LINKER_LANGUAGE CXX)
101101

102-
target_link_libraries(worklets log ReactAndroid::reactnative ReactAndroid::jsi
102+
target_link_libraries(worklets android log ReactAndroid::reactnative ReactAndroid::jsi
103103
fbjni::fbjni)
104104

105105
if(${JS_RUNTIME} STREQUAL "hermes")

packages/react-native-worklets/src/privateGlobals.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ declare global {
7373
var __flushAnimationFrame: (timestamp: number) => void;
7474
var __frameTimestamp: number | undefined;
7575
var _log: (value: unknown) => void;
76+
var _beginSection: (name: string) => void;
77+
var _endSection: () => void;
7678
var _getAnimationTimestamp: () => number;
7779
var _scheduleOnRuntime: (
7880
runtime: WorkletRuntime,

0 commit comments

Comments
 (0)