Skip to content

Commit 4e013cc

Browse files
committed
feat(skia): migrate JSI bindings to NativeState
Migrate ContourMeasure, ContourMeasureIter, Data, RSXform and related JSI bindings to JSI NativeState, and update associated factories and build scripts.
1 parent ab55c43 commit 4e013cc

17 files changed

Lines changed: 455 additions & 242 deletions

apps/example/ios/Podfile.lock

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3207,89 +3207,89 @@ SPEC CHECKSUMS:
32073207
FBLazyVector: 309703e71d3f2f1ed7dc7889d58309c9d77a95a4
32083208
fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd
32093209
glog: 5683914934d5b6e4240e497e0f4a3b42d1854183
3210-
hermes-engine: 11b010917f5f15150b2c015abddef1573d2bb05d
3211-
RCT-Folly: 59ec0ac1f2f39672a0c6e6cecdd39383b764646f
3210+
hermes-engine: ad676c360175e5b8af471b8ce1389e6cf4f9e1ee
3211+
RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669
32123212
RCTDeprecation: a41bbdd9af30bf2e5715796b313e44ec43eefff1
32133213
RCTRequired: 7be34aabb0b77c3cefe644528df0fa0afad4e4d0
32143214
RCTSwiftUI: a6c7271c39098bf00dbdad8f8ed997a59bbfbe44
3215-
RCTSwiftUIWrapper: 5ec163e8fde163d3fba714a992b50a266e1ece37
3215+
RCTSwiftUIWrapper: ff9098ccf7727e58218f2f8ea110349863f43438
32163216
RCTTypeSafety: 27927d0ca04e419ed9467578b3e6297e37210b5c
32173217
React: 4bc1f928568ad4bcfd147260f907b4ea5873a03b
32183218
React-callinvoker: 87f8728235a0dc62e9dc19b3851c829d9347d015
3219-
React-Core: 19e0183e28d7a6613ecacebd7525fe6650efa3b6
3220-
React-CoreModules: 73cc86f2a0ff84b93d6325073ad2e4874d21ad40
3221-
React-cxxreact: 4bf734645c77c9b86e2f3e933e0411cf2f14d1ba
3219+
React-Core: 76bed73b02821e5630e7f2cb2e82432ee964695d
3220+
React-CoreModules: 752dbfdaeb096658aa0adc4a03ba6214815a08df
3221+
React-cxxreact: b6798528aa601c6db66e6adc7e2da2b059c8be74
32223222
React-debug: 8978deb306f6f38c28b5091e52b0ac9f942b157e
3223-
React-defaultsnativemodule: 724eb9ec388d494f1e2057d83355ee8fe6f1d780
3224-
React-domnativemodule: 9068f41092f725acd09950233d2847364c731947
3225-
React-Fabric: 945cc8abf08d9d0966acef605bffce7b501c49d9
3226-
React-FabricComponents: 4c4ad6f0d16c964a68f945e029505e2eeec6654b
3227-
React-FabricImage: a8b628fd98db21b9f8588e06f14a9194dda11b40
3228-
React-featureflags: 0937601c1af1cc125851ec5bbf4654285d47a3e7
3229-
React-featureflagsnativemodule: ac1a3e0353e1a6e15411b17ed6c7122adb0468a4
3230-
React-graphics: cca521e06463608be46207a4aa160f8a7f725f8b
3231-
React-hermes: ec50b9fcea2c3bfdd42f8cec845eac3f35888572
3232-
React-idlecallbacksnativemodule: effcae5b7b4473211adb154aaa321d5d9e2fbcc9
3233-
React-ImageManager: b38459e538f1840fa5c3e7612a4bcb0029a3c366
3234-
React-intersectionobservernativemodule: 8d33366661971200cf2e151727f6fe007b62ae7b
3235-
React-jserrorhandler: f94c688a0dbe2e045b91b992722b92e97d56f77f
3236-
React-jsi: 3216c876cd4c571a57909e22d77c8fd9530aa067
3237-
React-jsiexecutor: 475563c0042841a85930a455d3199f6b1483a5fe
3238-
React-jsinspector: bc484fb32bf1b9fed80afe8793e614eba4f7b39e
3239-
React-jsinspectorcdp: 5a574d1d35016968a67e78e6b8a7917473ffbb77
3240-
React-jsinspectornetwork: dce3a5a1351b527ee8c28ad4a8bdd211507e1a45
3241-
React-jsinspectortracing: 65f6b166bd67e5adc31eba027e1570bacf7a3cc7
3242-
React-jsitooling: d5463f5489a31640b0fa0ec4e31566ca8aa86c13
3243-
React-jsitracing: 3c7fc18821aba64855acb8658aa857ca6a7fddf6
3244-
React-logger: 6ac901f5c7f7321d2be1a40b203bccc2e23411e3
3245-
React-Mapbuffer: 2e0e7cc5b7064eaed9c8b8afc3a87621cb7ef5cd
3246-
React-microtasksnativemodule: dd4d33b251b57e5027c572c6d0b45cbfbcfaa386
3247-
react-native-safe-area-context: 54d812805f3c4e08a4580ad086cbde1d8780c2e4
3248-
react-native-skia: 737c68c79b5a18eb23c2701672d7958807e8e4e0
3249-
React-NativeModulesApple: 7f2f2fed3f6c858889eb61d09941be965d52df58
3250-
React-networking: 43e5e6773ac2ca2a93261a1388fed269c9fce092
3223+
React-defaultsnativemodule: 682b77ef4acfb298017be15f4f93c1d998deb174
3224+
React-domnativemodule: 4c4b44f7eb68dbc3a2218db088bef318a7302017
3225+
React-Fabric: b6f82a4d8498ce4475586f71ca8397a771fe292d
3226+
React-FabricComponents: c8695f4b11918a127c4560d66f7d3fdb01a17986
3227+
React-FabricImage: d64f48830f63830e8ffaaf69fa487116856fbbf1
3228+
React-featureflags: 2a46b229903e906d33dbaf9207ce57c59306c369
3229+
React-featureflagsnativemodule: cba6c0814051a0934f8bcee4a436ee2a6bcc9754
3230+
React-graphics: 3d0435051e1ab8904d065f8ffbe981a9fc202841
3231+
React-hermes: 32fc9c231c1aa5c2fcfe851b0d19ee9269f88f4c
3232+
React-idlecallbacksnativemodule: f8ee42581795c4844d97147596bcc2d824c0f188
3233+
React-ImageManager: e8f7377ef0585fd2df05559a17e01a03e187d5cf
3234+
React-intersectionobservernativemodule: b1bea12ca29accdd2eda60c87605a6030b894eb9
3235+
React-jserrorhandler: 1a86df895b4eaf4e771abe8cf34cbb26d821f771
3236+
React-jsi: adf8527fec197ad9d0480cc5b8945eb56de627f0
3237+
React-jsiexecutor: 315fa2f879b43e3a9ca08f5f4b733472f7e4e8a4
3238+
React-jsinspector: b4fd1933666bcb2549b566b40656c1e45e9d7632
3239+
React-jsinspectorcdp: 80141710f2668e5b8f00417298d9b76b4abf90fa
3240+
React-jsinspectornetwork: 1d3ea717dbbec316cd8c21a0af53928a7bf74901
3241+
React-jsinspectortracing: 4ce745374d4b2bfbd164cce9f8de8383d3d818a0
3242+
React-jsitooling: fc4ac4c3b1f3f9f7fedf0c777c6ff3f244f568bd
3243+
React-jsitracing: bff08a6faeef4a9bd286487da191f5e5329e21a9
3244+
React-logger: b8483fa08e0d62e430c76d864309d90576ca2f68
3245+
React-Mapbuffer: 7b72a669e94662359dad4f42b5af005eb24b4e83
3246+
React-microtasksnativemodule: cdc02da075f2857803ed63f24f5f72fc40e094c0
3247+
react-native-safe-area-context: c00143b4823773bba23f2f19f85663ae89ceb460
3248+
react-native-skia: 2abc105ef969b15bc2082e3d32931e27edafdf0d
3249+
React-NativeModulesApple: a2c3d2cbec893956a5b3e4060322db2984fff75b
3250+
React-networking: 3f98bd96893a294376e7e03730947a08d474c380
32513251
React-oscompat: 80166b66da22e7af7fad94474e9997bd52d4c8c6
3252-
React-perflogger: 63c90e0d8c24df87ffa14dad01aeafc352847dd0
3253-
React-performancecdpmetrics: 5a9b81c08f75045635127d626440d9ada01e774b
3254-
React-performancetimeline: 31cebfff69ec9174b3fb54b0606fcb12ef91cbad
3252+
React-perflogger: d6797918d2b1031e91a9d8f5e7fdd2c8728fb390
3253+
React-performancecdpmetrics: 5570be61e2f97c4741c5d432c91570e8e5a39892
3254+
React-performancetimeline: 5763499ae1991fc18dcf416e340ce7bc829bb298
32553255
React-RCTActionSheet: 3bd5f5db9f983cf38d51bb9a7a198e2ebea94821
3256-
React-RCTAnimation: 346865a809fa5132f6c594c8b376c6cf46b44e88
3257-
React-RCTAppDelegate: b2d1e0d3663c987f49f45094883b9e36fcbf0181
3258-
React-RCTBlob: 74759ebb7ff9077d19f60c301782c1f8c3eb2813
3259-
React-RCTFabric: 7b4b14dad21ca99333ebcbc0bf5c205647a315a8
3260-
React-RCTFBReactNativeSpec: 39151968adb68b8c59f29a8bd4223d4d7780a793
3261-
React-RCTImage: 60763f56e8a5e45d861d7c4777e428bb820ec52a
3262-
React-RCTLinking: 52aee78b0b3163167c7fcf58f80a42943c03a056
3263-
React-RCTNetwork: f5e1e8ae5eff6982efff6289b06ec0a76d0a6ac2
3264-
React-RCTRuntime: 0e99199322afd372e74b95ae5c58f4e074cc2855
3265-
React-RCTSettings: 298bb40d3412bf32e0b4f0797e48416b0b7278a1
3266-
React-RCTText: dfb74800e27d792d1188fa975a3b9807c3362e3e
3267-
React-RCTVibration: ffe5fd4f50a835e353a3b6869eb005dab11eea44
3256+
React-RCTAnimation: 46a9978f27dc434dbeed16afa7b82619b690a9af
3257+
React-RCTAppDelegate: 62ecd60a2b2a8cae26ce6a066bfa59cfde97af01
3258+
React-RCTBlob: 8285c859513023ee3cc8c806d9b59d4da078c4ba
3259+
React-RCTFabric: 05ed09347e938de985052f791a6a0698816d5761
3260+
React-RCTFBReactNativeSpec: 83ba579fca9a51e774ac32578ef5dd3262edd7e2
3261+
React-RCTImage: a5364d0f098692cfbf5bef1e8a63e7712ecb14b7
3262+
React-RCTLinking: 34b63b0aa0e92d30f5d7aa2c255a8f95fa75ee8f
3263+
React-RCTNetwork: 1ef88b7a5310b8f915d3556b5b247def113191ed
3264+
React-RCTRuntime: ed29cf68a46782fec891e5afe1d8d758ca6ccd9b
3265+
React-RCTSettings: 2c45623d6c0f30851a123f621eb9d32298bcbb0c
3266+
React-RCTText: 0ee70f5dc18004b4d81b2c214267c6cbec058587
3267+
React-RCTVibration: 88557e21e7cc3fe76b5b174cba28ff45c6def997
32683268
React-rendererconsistency: d280314a3e7f0097152f89e815b4de821c2be8b9
3269-
React-renderercss: 8a1a346f3665fd5ea7a7be7b3b9f95d4743e1180
3270-
React-rendererdebug: af74afdfb3d6c5382ebab35562efd8eb9e690473
3271-
React-RuntimeApple: 06e33d291e72fd0c73ac47046c3536d77d5aeedd
3272-
React-RuntimeCore: 99273d2af072062eb07f0b2d2d4a0f2de697ea14
3273-
React-runtimeexecutor: 2063c03c18810ee57939d138142e6493333360ef
3274-
React-RuntimeHermes: 2253a7f4c8d56b449230b330b0b15383ed4b3df4
3275-
React-runtimescheduler: ff37ac6720a943da91645c06274282ac46b71f23
3276-
React-timing: 831d7e081ba4c332ca5cccf389b88e363f13f2b4
3277-
React-utils: 25db6c17598c4fed22b5956d7551bb8bddf1f95b
3278-
React-webperformancenativemodule: 57e41e6193cfb815bde0b5534bef68673f1270eb
3279-
ReactAppDependencyProvider: bfb12ead469222b022a2024f32aba47ce50de512
3280-
ReactCodegen: 9ca1bd49eee1eccf6e427e406d2163f49e9c48c0
3281-
ReactCommon: 05ad684db7d88e194272ae26baddf6300e30b8b7
3282-
ReactNativeHost: e7e0a518b0120f0070b3e1f13c7006d3e0e8ee13
3283-
ReactTestApp-DevSupport: 6994b53b5b81139a8ce63e0776c726c95de079a1
3269+
React-renderercss: f8cbf83d95c2c2bbf893d37fe50c73f046584411
3270+
React-rendererdebug: 37216ddfcd38e49d1e92bf9052ea4bc9d7b932e5
3271+
React-RuntimeApple: 1c0e7cb8e1c2c5775585afcaaa666ec151629a8d
3272+
React-RuntimeCore: 925fe2ca24cf8e6ed87586dbb92827306b93b83f
3273+
React-runtimeexecutor: 962dae024f6df760d029512a7d99e3f73d570935
3274+
React-RuntimeHermes: 19a7c59ec1bc9908516f0bbc29b49425f6ec64ba
3275+
React-runtimescheduler: 62f21127cd97f4d8f164eee5150d3ce53dd36f66
3276+
React-timing: 8757bf6fb96227c264f2d1609f4ba5c68217b8ce
3277+
React-utils: 8ab26781c2f5c2f7fafb2022c8ab39d39f231b80
3278+
React-webperformancenativemodule: 7953b7fe519f76fa595111fe18ff3d5de131bfe9
3279+
ReactAppDependencyProvider: 0eb286cc274abb059ee601b862ebddac2e681d01
3280+
ReactCodegen: b8e56b780fffe6edd6405be0af4a1e3049a937f7
3281+
ReactCommon: ac934cb340aee91282ecd6f273a26d24d4c55cae
3282+
ReactNativeHost: eef98ec49b55d88ad4cabf5a4378a12b42b551ee
3283+
ReactTestApp-DevSupport: ea18f446cff64b6c9a3e28788600c82ecf51bde6
32843284
ReactTestApp-Resources: 1bd9ff10e4c24f2ad87101a32023721ae923bccf
3285-
RNGestureHandler: 77eecab5fd636666ca73a55bb61e2f1a685b7e84
3286-
RNReanimated: d1a7a4c20eefc371e062990ce1debeaff4f1b9be
3287-
RNScreens: b2a5c76af24a02a2fd71bfce42780fdd9c79cc6d
3288-
RNSVG: ea9cbf6dcdbebdfff5822b0ad9311bbc4510a0b7
3289-
RNWorklets: 5f6e5664c1819eac103ca75cc2f36191f55aa110
3285+
RNGestureHandler: cd4be101cfa17ea6bbd438710caa02e286a84381
3286+
RNReanimated: c26dfcd831add485c2ed93de9d7bfb90b035eeaa
3287+
RNScreens: 714e10b6b554f7dc7ad9f78dcf36dc8e3fc73415
3288+
RNSVG: 11354d28dd6cb71a59570b68c91ba6772a2d781d
3289+
RNWorklets: b89b501d37972e6419d6f87effe41d6d76157648
32903290
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
3291-
Yoga: 5bd0956bf9cb16f75101e78b5e852c7577bc5a45
3291+
Yoga: 5456bb010373068fc92221140921b09d126b116e
32923292

32933293
PODFILE CHECKSUM: dca89d921c9f2a2d3d405a5fca0bfb60b30b5022
32943294

3295-
COCOAPODS: 1.15.2
3295+
COCOAPODS: 1.16.2

packages/skia/cpp/api/JsiSkAnimatedImageFactory.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace jsi = facebook::jsi;
1717
class JsiSkAnimatedImageFactory : public JsiSkHostObject {
1818
public:
1919
JSI_HOST_FUNCTION(MakeAnimatedImageFromEncoded) {
20-
auto data = JsiSkData::fromValue(runtime, arguments[0]);
20+
auto data = JsiSkData::fromValue(runtime, arguments[0])->getObject();
2121
auto codec = SkAndroidCodec::MakeFromData(data);
2222
auto image = SkAnimatedImage::Make(std::move(codec));
2323
if (image == nullptr) {

packages/skia/cpp/api/JsiSkCanvas.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ class JsiSkCanvas : public JsiSkHostObject {
554554
int xformsSize = static_cast<int>(transforms.size(runtime));
555555
xforms.reserve(xformsSize);
556556
for (int i = 0; i < xformsSize; i++) {
557-
auto xform = JsiSkRSXform::fromValue(
557+
auto xform = JsiSkRSXform::toRSXform(
558558
runtime, transforms.getValueAtIndex(runtime, i).asObject(runtime));
559559
xforms.push_back(*xform.get());
560560
}

packages/skia/cpp/api/JsiSkContourMeasure.h

Lines changed: 83 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
#pragma once
22

3+
#include <atomic>
34
#include <memory>
5+
#include <stdexcept>
6+
#include <string>
47
#include <utility>
58

69
#include <jsi/jsi.h>
710

811
#include "JsiSkHostObjects.h"
12+
#include "jsi2/NativeObject.h"
913

1014
#pragma clang diagnostic push
1115
#pragma clang diagnostic ignored "-Wdocumentation"
@@ -20,13 +24,29 @@ namespace RNSkia {
2024

2125
namespace jsi = facebook::jsi;
2226

23-
class JsiSkContourMeasure
24-
: public JsiSkWrappingSkPtrHostObject<SkContourMeasure> {
27+
/**
28+
* Migrated from the deprecated jsi::HostObject API to the JSI NativeState
29+
* pattern (rnwgpu::NativeObject, see cpp/jsi2/NativeObject.h).
30+
*
31+
* Instead of intercepting every property access through HostObject::get(),
32+
* the methods/getters live on a shared prototype installed once per runtime,
33+
* and the native data is attached to a plain JS object via setNativeState().
34+
*/
35+
class JsiSkContourMeasure : public rnwgpu::NativeObject<JsiSkContourMeasure> {
2536
public:
37+
// Used both for Symbol.toStringTag and (if ever installed) the global
38+
// constructor name. The JS-facing type guard relies on __typename__ below.
39+
static constexpr const char *CLASS_NAME = "ContourMeasure";
40+
2641
JsiSkContourMeasure(std::shared_ptr<RNSkPlatformContext> context,
27-
const sk_sp<SkContourMeasure> contourMeasure)
28-
: JsiSkWrappingSkPtrHostObject(std::move(context),
29-
std::move(contourMeasure)) {}
42+
sk_sp<SkContourMeasure> contourMeasure)
43+
: rnwgpu::NativeObject<JsiSkContourMeasure>(CLASS_NAME),
44+
_context(std::move(context)), _object(std::move(contourMeasure)) {}
45+
46+
// The method bodies below are unchanged from the HostObject implementation.
47+
// They are installed on the prototype via installMethod(); because they
48+
// return jsi::Value they take full control of argument handling (NativeObject
49+
// forwards `arguments`/`count` and passes an undefined `thisValue`).
3050

3151
JSI_HOST_FUNCTION(getPosTan) {
3252
auto dist = arguments[0].asNumber();
@@ -67,16 +87,66 @@ class JsiSkContourMeasure
6787
return JsiSkPath::toValue(runtime, getContext(), builder.snapshot());
6888
}
6989

70-
size_t getMemoryPressure() const override { return 1024; }
90+
// Preserves the SkJSIInstance<"ContourMeasure"> contract on the JS side.
91+
std::string getTypename() { return CLASS_NAME; }
92+
93+
size_t getMemoryPressure() override { return 1024; }
94+
95+
static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {
96+
installGetter(runtime, prototype, "__typename__",
97+
&JsiSkContourMeasure::getTypename);
98+
installMethod(runtime, prototype, "getPosTan",
99+
&JsiSkContourMeasure::getPosTan);
100+
installMethod(runtime, prototype, "length", &JsiSkContourMeasure::length);
101+
installMethod(runtime, prototype, "isClosed",
102+
&JsiSkContourMeasure::isClosed);
103+
installMethod(runtime, prototype, "getSegment",
104+
&JsiSkContourMeasure::getSegment);
105+
// dispose() needs access to the JS object (`thisValue`) to lower the
106+
// reported memory pressure, so it is installed as a raw host function
107+
// rather than through installMethod() (which hides `thisValue`).
108+
prototype.setProperty(
109+
runtime, "dispose",
110+
jsi::Function::createFromHostFunction(
111+
runtime, jsi::PropNameID::forUtf8(runtime, "dispose"), 0,
112+
[](jsi::Runtime &rt, const jsi::Value &thisValue,
113+
const jsi::Value * /*arguments*/,
114+
size_t /*count*/) -> jsi::Value {
115+
auto self = JsiSkContourMeasure::fromValue(rt, thisValue);
116+
self->release();
117+
if (thisValue.isObject()) {
118+
thisValue.getObject(rt).setExternalMemoryPressure(
119+
rt, rnwgpu::kMinMemoryPressure);
120+
}
121+
return jsi::Value::undefined();
122+
}));
123+
}
124+
125+
protected:
126+
/**
127+
* Returns the wrapped object, throwing if it has been disposed. Mirrors the
128+
* behaviour of the former JsiSkWrapping* base classes.
129+
*/
130+
sk_sp<SkContourMeasure> getObject() const {
131+
if (_disposed.load(std::memory_order_acquire)) {
132+
throw std::runtime_error("Attempted to access a disposed object.");
133+
}
134+
return _object;
135+
}
71136

72-
std::string getObjectType() const override { return "JsiSkContourMeasure"; }
137+
std::shared_ptr<RNSkPlatformContext> getContext() const { return _context; }
73138

74-
EXPORT_JSI_API_TYPENAME(JsiSkContourMeasure, ContourMeasure)
139+
private:
140+
void release() {
141+
bool expected = false;
142+
if (_disposed.compare_exchange_strong(expected, true,
143+
std::memory_order_acq_rel)) {
144+
_object = nullptr;
145+
}
146+
}
75147

76-
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkContourMeasure, getPosTan),
77-
JSI_EXPORT_FUNC(JsiSkContourMeasure, length),
78-
JSI_EXPORT_FUNC(JsiSkContourMeasure, isClosed),
79-
JSI_EXPORT_FUNC(JsiSkContourMeasure, getSegment),
80-
JSI_EXPORT_FUNC(JsiSkContourMeasure, dispose))
148+
std::shared_ptr<RNSkPlatformContext> _context;
149+
sk_sp<SkContourMeasure> _object;
150+
std::atomic<bool> _disposed = {false};
81151
};
82152
} // namespace RNSkia

0 commit comments

Comments
 (0)