Skip to content

Commit 2c76dc3

Browse files
committed
Add _beginSection and _endSection JSI bindings for systraces
1 parent eaaab30 commit 2c76dc3

6 files changed

Lines changed: 101 additions & 1 deletion

File tree

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

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-reanimated/src/privateGlobals.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ declare global {
2424
var _REANIMATED_VERSION_JS: string | undefined;
2525
var __reanimatedModuleProxy: ReanimatedModuleProxy | undefined;
2626
var _log: (value: unknown) => void;
27+
var _beginSection: (name: string) => void;
28+
var _endSection: () => void;
2729
var _notifyAboutProgress: (
2830
tag: number,
2931
value: Record<string, unknown>

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

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,36 @@
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 = os_log_create("dev.worklets.instruments", OS_LOG_CATEGORY_POINTS_OF_INTEREST);
35+
}
36+
return workletsInstrumentsLogHandle;
37+
}
38+
#endif
39+
1540
namespace worklets {
1641

1742
static inline double performanceNow() {
@@ -87,6 +112,33 @@ void WorkletRuntimeDecorator::decorate(
87112
return jsi::String::createFromUtf8(rt, stringifyJSIValue(rt, value));
88113
});
89114

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