diff --git a/apps/docs/docs/animations/reanimated3.md b/apps/docs/docs/animations/reanimated3.md index d26f142bfb..5d2d7f6d91 100644 --- a/apps/docs/docs/animations/reanimated3.md +++ b/apps/docs/docs/animations/reanimated3.md @@ -5,7 +5,8 @@ sidebar_label: Animations slug: /animations/animations --- -React Native Skia offers integration with [Reanimated v3 and above](https://docs.swmansion.com/react-native-reanimated/), enabling the execution of animations on the UI thread. +React Native Skia offers integration with [Reanimated](https://docs.swmansion.com/react-native-reanimated/), enabling the execution of animations on the UI thread. +Starting version `2.10` and above, this integration requires **Reanimated v4 or above**. For lower version numbers, you can use Reanimated v3. React Native Skia supports the direct usage of Reanimated's shared and derived values as properties. There is no need for functions like `createAnimatedComponent` or `useAnimatedProps`; simply pass the Reanimated values directly as properties. diff --git a/apps/docs/docs/getting-started/installation.md b/apps/docs/docs/getting-started/installation.md index 3920306319..75a3f81aa1 100644 --- a/apps/docs/docs/getting-started/installation.md +++ b/apps/docs/docs/getting-started/installation.md @@ -11,7 +11,8 @@ Skia serves as the graphics engine for Google Chrome and Chrome OS, Android, Flu **Version compatibility:** `react-native@>=0.79` and `react@>=19` are required.
In addition you should make sure you're on at least `iOS 14` and `Android API level 21` or above.
-To use React Native Skia with video support, `Android API level 26` or above is required. +To use React Native Skia with video support, `Android API level 26` or above is required.
+To use React Native Skia with Reanimated on native platforms, `react-native-reanimated@>=4.0.0` (with `react-native-worklets@>=0.7.0`) is required. For `react-native@<=0.78` and `react@<=18`, you need to use `@shopify/react-native-skia` version `1.12.4` or below. diff --git a/apps/example/ios/Podfile.lock b/apps/example/ios/Podfile.lock index 91b6a07c4e..79b8fb4a8f 100644 --- a/apps/example/ios/Podfile.lock +++ b/apps/example/ios/Podfile.lock @@ -3207,7 +3207,7 @@ SPEC CHECKSUMS: FBLazyVector: 309703e71d3f2f1ed7dc7889d58309c9d77a95a4 fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 - hermes-engine: 11b010917f5f15150b2c015abddef1573d2bb05d + hermes-engine: ad676c360175e5b8af471b8ce1389e6cf4f9e1ee RCT-Folly: 59ec0ac1f2f39672a0c6e6cecdd39383b764646f RCTDeprecation: a41bbdd9af30bf2e5715796b313e44ec43eefff1 RCTRequired: 7be34aabb0b77c3cefe644528df0fa0afad4e4d0 @@ -3245,7 +3245,7 @@ SPEC CHECKSUMS: React-Mapbuffer: 2e0e7cc5b7064eaed9c8b8afc3a87621cb7ef5cd React-microtasksnativemodule: dd4d33b251b57e5027c572c6d0b45cbfbcfaa386 react-native-safe-area-context: 54d812805f3c4e08a4580ad086cbde1d8780c2e4 - react-native-skia: b28747dc1cf8c344ad041f14a618eda7f429bfeb + react-native-skia: 4a90dfa21f4544d69c6be0c49958378169a88532 React-NativeModulesApple: 7f2f2fed3f6c858889eb61d09941be965d52df58 React-networking: 43e5e6773ac2ca2a93261a1388fed269c9fce092 React-oscompat: 80166b66da22e7af7fad94474e9997bd52d4c8c6 diff --git a/externals/depot_tools b/externals/depot_tools index f488573369..c46c2e9057 160000 --- a/externals/depot_tools +++ b/externals/depot_tools @@ -1 +1 @@ -Subproject commit f488573369dfbbdd523177b93a369d4096d06e5d +Subproject commit c46c2e905741fa94ce6870f9c95978117b8a7917 diff --git a/packages/skia/android/CMakeLists.txt b/packages/skia/android/CMakeLists.txt index 61b71abadc..1341c12ad8 100644 --- a/packages/skia/android/CMakeLists.txt +++ b/packages/skia/android/CMakeLists.txt @@ -99,10 +99,10 @@ add_library( "${PROJECT_SOURCE_DIR}/cpp/rnskia-android/AHardwareBufferUtils.cpp" "${PROJECT_SOURCE_DIR}/cpp/rnskia-android/RNSkAndroidVideo.cpp" - "${PROJECT_SOURCE_DIR}/../cpp/jsi/JsiHostObject.cpp" "${PROJECT_SOURCE_DIR}/../cpp/jsi/RuntimeLifecycleMonitor.cpp" "${PROJECT_SOURCE_DIR}/../cpp/jsi/RuntimeAwareCache.cpp" "${PROJECT_SOURCE_DIR}/../cpp/jsi/JsiPromises.cpp" + "${PROJECT_SOURCE_DIR}/../cpp/jsi/Promise.cpp" "${PROJECT_SOURCE_DIR}/../cpp/rnskia/RNSkManager.cpp" @@ -115,10 +115,7 @@ add_library( ) if(SK_GRAPHITE) - # WebGPU JSI infrastructure (jsi2) target_sources(${PACKAGE_NAME} PRIVATE - "${PROJECT_SOURCE_DIR}/../cpp/jsi2/Promise.cpp" - # WebGPU async system "${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/async/AsyncTaskHandle.cpp" "${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/async/RuntimeContext.cpp" @@ -181,7 +178,6 @@ target_include_directories( # WebGPU bindings ../cpp - ../cpp/jsi2 ../cpp/rnwgpu ../cpp/rnwgpu/api ../cpp/rnwgpu/api/descriptors diff --git a/packages/skia/cpp/api/JsiNativeBuffer.h b/packages/skia/cpp/api/JsiNativeBuffer.h index 480e8baca9..109ecaaae9 100644 --- a/packages/skia/cpp/api/JsiNativeBuffer.h +++ b/packages/skia/cpp/api/JsiNativeBuffer.h @@ -6,6 +6,7 @@ #include #include "JsiSkImage.h" +#include "JsiSkNativeObjects.h" namespace RNSkia { @@ -15,8 +16,11 @@ namespace jsi = facebook::jsi; Implementation of the ParagraphBuilderFactory for making ParagraphBuilder JSI object */ -class JsiNativeBufferFactory : public JsiSkHostObject { +class JsiNativeBufferFactory + : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "NativeBufferFactory"; + JSI_HOST_FUNCTION(MakeFromImage) { auto image = JsiSkImage::fromValue(runtime, arguments[0]); image->makeNonTextureImage(); @@ -40,18 +44,19 @@ class JsiNativeBufferFactory : public JsiSkHostObject { return jsi::Value::undefined(); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiNativeBufferFactory, Release), - JSI_EXPORT_FUNC(JsiNativeBufferFactory, MakeFromImage), - JSI_EXPORT_FUNC(JsiNativeBufferFactory, MakeTestBuffer)) - - size_t getMemoryPressure() const override { return 1024; } - - std::string getObjectType() const override { - return "JsiNativeBufferFactory"; + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "Release", + &JsiNativeBufferFactory::Release); + installHostMethod(runtime, prototype, "MakeFromImage", + &JsiNativeBufferFactory::MakeFromImage); + installHostMethod(runtime, prototype, "MakeTestBuffer", + &JsiNativeBufferFactory::MakeTestBuffer); } + size_t getMemoryPressure() override { return 1024; } + explicit JsiNativeBufferFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkAnimatedImage.h b/packages/skia/cpp/api/JsiSkAnimatedImage.h index a7e47214e8..eb181ccd3b 100644 --- a/packages/skia/cpp/api/JsiSkAnimatedImage.h +++ b/packages/skia/cpp/api/JsiSkAnimatedImage.h @@ -7,7 +7,7 @@ #include #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "api/third_party/base64.h" #pragma clang diagnostic push @@ -29,15 +29,16 @@ namespace RNSkia { namespace jsi = facebook::jsi; class JsiSkAnimatedImage - : public JsiSkWrappingSkPtrHostObject { + : public JsiSkWrappingSkPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "AnimatedImage"; + // TODO-API: Properties? JSI_HOST_FUNCTION(getCurrentFrame) { auto image = getObject()->getCurrentFrame(); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(image)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(image))); } JSI_HOST_FUNCTION(getFrameCount) { @@ -52,21 +53,24 @@ class JsiSkAnimatedImage return static_cast(getObject()->decodeNextFrame()); } - EXPORT_JSI_API_TYPENAME(JsiSkAnimatedImage, AnimatedImage) - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkAnimatedImage, dispose), - JSI_EXPORT_FUNC(JsiSkAnimatedImage, getFrameCount), - JSI_EXPORT_FUNC(JsiSkAnimatedImage, getCurrentFrame), - JSI_EXPORT_FUNC(JsiSkAnimatedImage, - currentFrameDuration), - JSI_EXPORT_FUNC(JsiSkAnimatedImage, decodeNextFrame)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "getFrameCount", + &JsiSkAnimatedImage::getFrameCount); + installHostMethod(runtime, prototype, "getCurrentFrame", + &JsiSkAnimatedImage::getCurrentFrame); + installHostMethod(runtime, prototype, "currentFrameDuration", + &JsiSkAnimatedImage::currentFrameDuration); + installHostMethod(runtime, prototype, "decodeNextFrame", + &JsiSkAnimatedImage::decodeNextFrame); + } JsiSkAnimatedImage(std::shared_ptr context, const sk_sp image) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(image)) {} + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(image)) {} - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { auto animation = getObject(); if (!animation) { return 0; @@ -131,8 +135,6 @@ class JsiSkAnimatedImage return estimated; } - - std::string getObjectType() const override { return "JsiSkAnimatedImage"; } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkAnimatedImageFactory.h b/packages/skia/cpp/api/JsiSkAnimatedImageFactory.h index 20222c3311..d6ecff500b 100644 --- a/packages/skia/cpp/api/JsiSkAnimatedImageFactory.h +++ b/packages/skia/cpp/api/JsiSkAnimatedImageFactory.h @@ -5,17 +5,20 @@ #include -#include "jsi/JsiPromises.h" #include "JsiSkAnimatedImage.h" #include "JsiSkData.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" +#include "jsi/JsiPromises.h" namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkAnimatedImageFactory : public JsiSkHostObject { +class JsiSkAnimatedImageFactory + : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "AnimatedImageFactory"; + JSI_HOST_FUNCTION(MakeAnimatedImageFromEncoded) { auto data = JsiSkData::fromValue(runtime, arguments[0]); auto codec = SkAndroidCodec::MakeFromData(data); @@ -23,24 +26,20 @@ class JsiSkAnimatedImageFactory : public JsiSkHostObject { if (image == nullptr) { return jsi::Value::null(); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(image)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(image))); } - size_t getMemoryPressure() const override { return 1024; } + size_t getMemoryPressure() override { return 1024; } - std::string getObjectType() const override { - return "JsiSkAnimatedImageFactory"; + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "MakeAnimatedImageFromEncoded", + &JsiSkAnimatedImageFactory::MakeAnimatedImageFromEncoded); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkAnimatedImageFactory, - MakeAnimatedImageFromEncoded)) - explicit JsiSkAnimatedImageFactory( std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkApi.h b/packages/skia/cpp/api/JsiSkApi.h index 2962b61b2a..b71ef9bab4 100644 --- a/packages/skia/cpp/api/JsiSkApi.h +++ b/packages/skia/cpp/api/JsiSkApi.h @@ -4,7 +4,7 @@ #include "rnskia/RNSkPlatformContext.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #ifdef SK_GRAPHITE #include "rnskia/RNDawnContext.h" @@ -67,11 +67,11 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkApi : public JsiSkHostObject { +class JsiSkApi : public JsiSkNativeObject { public: - size_t getMemoryPressure() const override { return 8192; } + static constexpr const char *CLASS_NAME = "Api"; - std::string getObjectType() const override { return "JsiSkApi"; } + size_t getMemoryPressure() override { return 8192; } /** * Constructs the Skia Api object that can be installed into a runtime @@ -79,104 +79,258 @@ class JsiSkApi : public JsiSkHostObject { * @param context Platform context */ explicit JsiSkApi(const std::shared_ptr &context) - : JsiSkHostObject(context) { + : JsiSkNativeObject(context), + _svgFactory(std::make_shared(context)), + _imageFactory(std::make_shared(context)), + _animatedImageFactory( + std::make_shared(context)), + _typefaceFactory(std::make_shared(context)), + _dataFactory(std::make_shared(context)), + _imageFilterFactory(std::make_shared(context)), + _pathEffectFactory(std::make_shared(context)), + _pathFactory(std::make_shared(context)), + _pathBuilderFactory(std::make_shared(context)), + _colorFilterFactory(std::make_shared(context)), + _maskFilterFactory(std::make_shared(context)), + _runtimeEffectFactory( + std::make_shared(context)), + _shaderFactory(std::make_shared(context)), + _textBlobFactory(std::make_shared(context)), + _surfaceFactory(std::make_shared(context)), + _pictureFactory(std::make_shared(context)), + _fontMgrFactory(std::make_shared(context)), + _skottieFactory(std::make_shared(context)), + _typefaceFontProviderFactory( + std::make_shared(context)), + _paragraphBuilderFactory( + std::make_shared(context)), + _nativeBufferFactory( + std::make_shared(context)) { // We create the system font manager eagerly since it has proven to be too // slow to do it on demand JsiSkFontMgrFactory::getFontMgr(getContext()); - installFunction("Video", JsiVideo::createCtor(context)); - installFunction("Context", JsiSkiaContext::createCtor(context)); - installFunction("Font", JsiSkFont::createCtor(context)); - installFunction("Paint", JsiSkPaint::createCtor(context)); - installFunction("RSXform", JsiSkRSXform::createCtor(context)); - installFunction("RSXformFromRadians", - JsiSkRSXform::createCtorFromRadians(context)); - installFunction("Matrix", JsiSkMatrix::createCtor(context)); - installFunction("XYWHRect", JsiSkRect::createCtor(context)); - installFunction("RRectXY", JsiSkRRect::createCtor(context)); - installFunction("Point", JsiSkPoint::createCtor(context)); - installFunction("RuntimeShaderBuilder", - JsiSkRuntimeShaderBuilder::createCtor(context)); - installFunction("ContourMeasureIter", - JsiSkContourMeasureIter::createCtor(context)); - installFunction("MakeVertices", JsiSkVertices::createCtor(context)); - installFunction("PictureRecorder", - JsiSkPictureRecorder::createCtor(context)); - installFunction("Color", JsiSkColor::createCtor()); - - installReadonlyProperty("SVG", std::make_shared(context)); - installReadonlyProperty("Image", - std::make_shared(context)); - installReadonlyProperty( - "AnimatedImage", std::make_shared(context)); - installReadonlyProperty("Typeface", - std::make_shared(context)); - installReadonlyProperty("Data", - std::make_shared(context)); - installReadonlyProperty("ImageFilter", - std::make_shared(context)); - installReadonlyProperty("PathEffect", - std::make_shared(context)); - installReadonlyProperty("Path", - std::make_shared(context)); - installReadonlyProperty("PathBuilder", - std::make_shared(context)); - installReadonlyProperty("ColorFilter", - std::make_shared(context)); - installReadonlyProperty("MaskFilter", - std::make_shared(context)); - installReadonlyProperty( - "RuntimeEffect", std::make_shared(context)); - installReadonlyProperty("Shader", - std::make_shared(context)); - installReadonlyProperty("TextBlob", - std::make_shared(context)); - installReadonlyProperty("Surface", - std::make_shared(context)); - installReadonlyProperty("Picture", - std::make_shared(context)); - installReadonlyProperty("FontMgr", - std::make_shared(context)); - installReadonlyProperty("Skottie", - std::make_shared(context)); - installReadonlyProperty( - "TypefaceFontProvider", - std::make_shared(context)); - - installReadonlyProperty( - "ParagraphBuilder", - std::make_shared(context)); - - installReadonlyProperty("NativeBuffer", - std::make_shared(context)); - - installFunction("Recorder", JsiRecorder::createCtor(context)); - - installFunction( - "hasDevice", JSI_HOST_FUNCTION_LAMBDA { + } + + // Constructor functions: each delegates to the class's createCtor host + // function using the platform context resolved from native state, so the + // prototype stays context-free and can be installed on any runtime. + JSI_HOST_FUNCTION(Video) { + return JsiVideo::createCtor(getContext())(runtime, thisValue, arguments, + count); + } + JSI_HOST_FUNCTION(Context) { + return JsiSkiaContext::createCtor(getContext())(runtime, thisValue, + arguments, count); + } + JSI_HOST_FUNCTION(Font) { + return JsiSkFont::createCtor(getContext())(runtime, thisValue, arguments, + count); + } + JSI_HOST_FUNCTION(Paint) { + return JsiSkPaint::createCtor(getContext())(runtime, thisValue, arguments, + count); + } + JSI_HOST_FUNCTION(RSXform) { + return JsiSkRSXform::createCtor(getContext())(runtime, thisValue, arguments, + count); + } + JSI_HOST_FUNCTION(RSXformFromRadians) { + return JsiSkRSXform::createCtorFromRadians(getContext())(runtime, thisValue, + arguments, count); + } + JSI_HOST_FUNCTION(Matrix) { + return JsiSkMatrix::createCtor(getContext())(runtime, thisValue, arguments, + count); + } + JSI_HOST_FUNCTION(XYWHRect) { + return JsiSkRect::createCtor(getContext())(runtime, thisValue, arguments, + count); + } + JSI_HOST_FUNCTION(RRectXY) { + return JsiSkRRect::createCtor(getContext())(runtime, thisValue, arguments, + count); + } + JSI_HOST_FUNCTION(Point) { + return JsiSkPoint::createCtor(getContext())(runtime, thisValue, arguments, + count); + } + JSI_HOST_FUNCTION(RuntimeShaderBuilder) { + return JsiSkRuntimeShaderBuilder::createCtor(getContext())( + runtime, thisValue, arguments, count); + } + JSI_HOST_FUNCTION(ContourMeasureIter) { + return JsiSkContourMeasureIter::createCtor(getContext())(runtime, thisValue, + arguments, count); + } + JSI_HOST_FUNCTION(MakeVertices) { + return JsiSkVertices::createCtor(getContext())(runtime, thisValue, + arguments, count); + } + JSI_HOST_FUNCTION(PictureRecorder) { + return JsiSkPictureRecorder::createCtor(getContext())(runtime, thisValue, + arguments, count); + } + JSI_HOST_FUNCTION(Color) { + return JsiSkColor::createCtor()(runtime, thisValue, arguments, count); + } + JSI_HOST_FUNCTION(Recorder) { + return JsiRecorder::createCtor(getContext())(runtime, thisValue, arguments, + count); + } + + JSI_HOST_FUNCTION(hasDevice) { #ifdef SK_GRAPHITE - return jsi::Value(true); + return jsi::Value(true); #else - return jsi::Value(false); + return jsi::Value(false); #endif - }); + } - installFunction( - "getDevice", JSI_HOST_FUNCTION_LAMBDA { + JSI_HOST_FUNCTION(getDevice) { #ifdef SK_GRAPHITE - auto &dawnContext = DawnContext::getInstance(); - // Per-runtime context: async ops on this device resolve on the calling - // runtime's own thread (via its ProcessEvents pump). - auto context = rnwgpu::async::RuntimeContext::getOrCreate( - runtime, dawnContext.getWGPUInstance()); - auto device = std::make_shared( - dawnContext.getWGPUDevice(), context, "Skia Device"); - return rnwgpu::GPUDevice::create(runtime, device); + auto &dawnContext = DawnContext::getInstance(); + // Per-runtime context: async ops on this device resolve on the calling + // runtime's own thread (via its ProcessEvents pump). + auto context = rnwgpu::async::RuntimeContext::getOrCreate( + runtime, dawnContext.getWGPUInstance()); + auto device = std::make_shared( + dawnContext.getWGPUDevice(), context, "Skia Device"); + return rnwgpu::GPUDevice::create(runtime, device); #else - throw jsi::JSError(runtime, - "getDevice() is only available with the Graphite " - "backend. Rebuild with SK_GRAPHITE enabled."); + throw jsi::JSError(runtime, + "getDevice() is only available with the Graphite " + "backend. Rebuild with SK_GRAPHITE enabled."); #endif - }); } + + // Factory properties: like the legacy HostObject implementation, each + // property access returns a fresh JS wrapper around the shared factory + // instance. + JSI_PROPERTY_GET(SVG) { return makeJsiObject(runtime, _svgFactory); } + JSI_PROPERTY_GET(Image) { return makeJsiObject(runtime, _imageFactory); } + JSI_PROPERTY_GET(AnimatedImage) { + return makeJsiObject(runtime, _animatedImageFactory); + } + JSI_PROPERTY_GET(Typeface) { + return makeJsiObject(runtime, _typefaceFactory); + } + JSI_PROPERTY_GET(Data) { return makeJsiObject(runtime, _dataFactory); } + JSI_PROPERTY_GET(ImageFilter) { + return makeJsiObject(runtime, _imageFilterFactory); + } + JSI_PROPERTY_GET(PathEffect) { + return makeJsiObject(runtime, _pathEffectFactory); + } + JSI_PROPERTY_GET(Path) { return makeJsiObject(runtime, _pathFactory); } + JSI_PROPERTY_GET(PathBuilder) { + return makeJsiObject(runtime, _pathBuilderFactory); + } + JSI_PROPERTY_GET(ColorFilter) { + return makeJsiObject(runtime, _colorFilterFactory); + } + JSI_PROPERTY_GET(MaskFilter) { + return makeJsiObject(runtime, _maskFilterFactory); + } + JSI_PROPERTY_GET(RuntimeEffect) { + return makeJsiObject(runtime, _runtimeEffectFactory); + } + JSI_PROPERTY_GET(Shader) { return makeJsiObject(runtime, _shaderFactory); } + JSI_PROPERTY_GET(TextBlob) { + return makeJsiObject(runtime, _textBlobFactory); + } + JSI_PROPERTY_GET(Surface) { return makeJsiObject(runtime, _surfaceFactory); } + JSI_PROPERTY_GET(Picture) { return makeJsiObject(runtime, _pictureFactory); } + JSI_PROPERTY_GET(FontMgr) { return makeJsiObject(runtime, _fontMgrFactory); } + JSI_PROPERTY_GET(Skottie) { return makeJsiObject(runtime, _skottieFactory); } + JSI_PROPERTY_GET(TypefaceFontProvider) { + return makeJsiObject(runtime, _typefaceFontProviderFactory); + } + JSI_PROPERTY_GET(ParagraphBuilder) { + return makeJsiObject(runtime, _paragraphBuilderFactory); + } + JSI_PROPERTY_GET(NativeBuffer) { + return makeJsiObject(runtime, _nativeBufferFactory); + } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "Video", &JsiSkApi::Video); + installHostMethod(runtime, prototype, "Context", &JsiSkApi::Context); + installHostMethod(runtime, prototype, "Font", &JsiSkApi::Font); + installHostMethod(runtime, prototype, "Paint", &JsiSkApi::Paint); + installHostMethod(runtime, prototype, "RSXform", &JsiSkApi::RSXform); + installHostMethod(runtime, prototype, "RSXformFromRadians", + &JsiSkApi::RSXformFromRadians); + installHostMethod(runtime, prototype, "Matrix", &JsiSkApi::Matrix); + installHostMethod(runtime, prototype, "XYWHRect", &JsiSkApi::XYWHRect); + installHostMethod(runtime, prototype, "RRectXY", &JsiSkApi::RRectXY); + installHostMethod(runtime, prototype, "Point", &JsiSkApi::Point); + installHostMethod(runtime, prototype, "RuntimeShaderBuilder", + &JsiSkApi::RuntimeShaderBuilder); + installHostMethod(runtime, prototype, "ContourMeasureIter", + &JsiSkApi::ContourMeasureIter); + installHostMethod(runtime, prototype, "MakeVertices", + &JsiSkApi::MakeVertices); + installHostMethod(runtime, prototype, "PictureRecorder", + &JsiSkApi::PictureRecorder); + installHostMethod(runtime, prototype, "Color", &JsiSkApi::Color); + installHostMethod(runtime, prototype, "Recorder", &JsiSkApi::Recorder); + installHostMethod(runtime, prototype, "hasDevice", &JsiSkApi::hasDevice); + installHostMethod(runtime, prototype, "getDevice", &JsiSkApi::getDevice); + installHostGetter(runtime, prototype, "SVG", &JsiSkApi::get_SVG); + installHostGetter(runtime, prototype, "Image", &JsiSkApi::get_Image); + installHostGetter(runtime, prototype, "AnimatedImage", + &JsiSkApi::get_AnimatedImage); + installHostGetter(runtime, prototype, "Typeface", &JsiSkApi::get_Typeface); + installHostGetter(runtime, prototype, "Data", &JsiSkApi::get_Data); + installHostGetter(runtime, prototype, "ImageFilter", + &JsiSkApi::get_ImageFilter); + installHostGetter(runtime, prototype, "PathEffect", + &JsiSkApi::get_PathEffect); + installHostGetter(runtime, prototype, "Path", &JsiSkApi::get_Path); + installHostGetter(runtime, prototype, "PathBuilder", + &JsiSkApi::get_PathBuilder); + installHostGetter(runtime, prototype, "ColorFilter", + &JsiSkApi::get_ColorFilter); + installHostGetter(runtime, prototype, "MaskFilter", + &JsiSkApi::get_MaskFilter); + installHostGetter(runtime, prototype, "RuntimeEffect", + &JsiSkApi::get_RuntimeEffect); + installHostGetter(runtime, prototype, "Shader", &JsiSkApi::get_Shader); + installHostGetter(runtime, prototype, "TextBlob", &JsiSkApi::get_TextBlob); + installHostGetter(runtime, prototype, "Surface", &JsiSkApi::get_Surface); + installHostGetter(runtime, prototype, "Picture", &JsiSkApi::get_Picture); + installHostGetter(runtime, prototype, "FontMgr", &JsiSkApi::get_FontMgr); + installHostGetter(runtime, prototype, "Skottie", &JsiSkApi::get_Skottie); + installHostGetter(runtime, prototype, "TypefaceFontProvider", + &JsiSkApi::get_TypefaceFontProvider); + installHostGetter(runtime, prototype, "ParagraphBuilder", + &JsiSkApi::get_ParagraphBuilder); + installHostGetter(runtime, prototype, "NativeBuffer", + &JsiSkApi::get_NativeBuffer); + } + +private: + std::shared_ptr _svgFactory; + std::shared_ptr _imageFactory; + std::shared_ptr _animatedImageFactory; + std::shared_ptr _typefaceFactory; + std::shared_ptr _dataFactory; + std::shared_ptr _imageFilterFactory; + std::shared_ptr _pathEffectFactory; + std::shared_ptr _pathFactory; + std::shared_ptr _pathBuilderFactory; + std::shared_ptr _colorFilterFactory; + std::shared_ptr _maskFilterFactory; + std::shared_ptr _runtimeEffectFactory; + std::shared_ptr _shaderFactory; + std::shared_ptr _textBlobFactory; + std::shared_ptr _surfaceFactory; + std::shared_ptr _pictureFactory; + std::shared_ptr _fontMgrFactory; + std::shared_ptr _skottieFactory; + std::shared_ptr + _typefaceFontProviderFactory; + std::shared_ptr _paragraphBuilderFactory; + std::shared_ptr _nativeBufferFactory; }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkCanvas.h b/packages/skia/cpp/api/JsiSkCanvas.h index 7cfa9ea2f8..3376463d15 100644 --- a/packages/skia/cpp/api/JsiSkCanvas.h +++ b/packages/skia/cpp/api/JsiSkCanvas.h @@ -5,10 +5,10 @@ #include #include "JsiSkFont.h" -#include "JsiSkHostObjects.h" #include "JsiSkImage.h" #include "JsiSkImageInfo.h" #include "JsiSkMatrix.h" +#include "JsiSkNativeObjects.h" #include "JsiSkPaint.h" #include "JsiSkPath.h" #include "JsiSkPicture.h" @@ -49,8 +49,10 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkCanvas : public JsiSkHostObject { +class JsiSkCanvas : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "Canvas"; + JSI_HOST_FUNCTION(drawPaint) { auto paint = JsiSkPaint::fromValue(runtime, arguments[0]); _canvas->drawPaint(*paint); @@ -246,10 +248,8 @@ class JsiSkCanvas : public JsiSkHostObject { } JSI_HOST_FUNCTION(getTotalMatrix) { - auto matrix = - std::make_shared(getContext(), _canvas->getTotalMatrix()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, matrix, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), _canvas->getTotalMatrix())); } JSI_HOST_FUNCTION(drawPoints) { @@ -651,9 +651,10 @@ class JsiSkCanvas : public JsiSkHostObject { #if defined(SK_GRAPHITE) // Graphite records draws lazily and offers no synchronous GPU readback. If // this canvas belongs to a surface, snap & submit its recording, snapshot - // it to a CPU raster image and read from that (mirroring makeImageSnapshot). - // A canvas without an owning surface (e.g. a picture-recording canvas) has - // no texture to read back, so fall through to the raster canvas read below. + // it to a CPU raster image and read from that (mirroring + // makeImageSnapshot). A canvas without an owning surface (e.g. a + // picture-recording canvas) has no texture to read back, so fall through to + // the raster canvas read below. if (_surface) { // Snapshot first: makeImageSnapshot records a copy task into the recorder // that must be submitted before the texture can be read back (this is the @@ -663,8 +664,8 @@ class JsiSkCanvas : public JsiSkHostObject { DawnContext::getInstance().submitRecording(recorder->snap().get()); } auto raster = DawnContext::getInstance().MakeRasterImage(snapshot); - if (!raster || - !raster->readPixels(nullptr, *info, bfrPtr, bytesPerRow, srcX, srcY)) { + if (!raster || !raster->readPixels(nullptr, *info, bfrPtr, bytesPerRow, + srcX, srcY)) { return jsi::Value::null(); } return dest; @@ -677,55 +678,72 @@ class JsiSkCanvas : public JsiSkHostObject { return dest; } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkCanvas, drawPaint), - JSI_EXPORT_FUNC(JsiSkCanvas, drawLine), - JSI_EXPORT_FUNC(JsiSkCanvas, drawRect), - JSI_EXPORT_FUNC(JsiSkCanvas, drawImage), - JSI_EXPORT_FUNC(JsiSkCanvas, drawImageRect), - JSI_EXPORT_FUNC(JsiSkCanvas, drawImageCubic), - JSI_EXPORT_FUNC(JsiSkCanvas, drawImageOptions), - JSI_EXPORT_FUNC(JsiSkCanvas, drawImageNine), - JSI_EXPORT_FUNC(JsiSkCanvas, drawImageRectCubic), - JSI_EXPORT_FUNC(JsiSkCanvas, drawImageRectOptions), - JSI_EXPORT_FUNC(JsiSkCanvas, drawCircle), - JSI_EXPORT_FUNC(JsiSkCanvas, drawArc), - JSI_EXPORT_FUNC(JsiSkCanvas, drawRRect), - JSI_EXPORT_FUNC(JsiSkCanvas, drawDRRect), - JSI_EXPORT_FUNC(JsiSkCanvas, drawOval), - JSI_EXPORT_FUNC(JsiSkCanvas, restoreToCount), - JSI_EXPORT_FUNC(JsiSkCanvas, getSaveCount), - JSI_EXPORT_FUNC(JsiSkCanvas, getTotalMatrix), - JSI_EXPORT_FUNC(JsiSkCanvas, drawPoints), - JSI_EXPORT_FUNC(JsiSkCanvas, drawPatch), - JSI_EXPORT_FUNC(JsiSkCanvas, drawPath), - JSI_EXPORT_FUNC(JsiSkCanvas, drawVertices), - JSI_EXPORT_FUNC(JsiSkCanvas, drawText), - JSI_EXPORT_FUNC(JsiSkCanvas, drawTextBlob), - JSI_EXPORT_FUNC(JsiSkCanvas, drawGlyphs), - JSI_EXPORT_FUNC(JsiSkCanvas, drawSvg), - JSI_EXPORT_FUNC(JsiSkCanvas, clipPath), - JSI_EXPORT_FUNC(JsiSkCanvas, clipRect), - JSI_EXPORT_FUNC(JsiSkCanvas, clipRRect), - JSI_EXPORT_FUNC(JsiSkCanvas, save), - JSI_EXPORT_FUNC(JsiSkCanvas, saveLayer), - JSI_EXPORT_FUNC(JsiSkCanvas, restore), - JSI_EXPORT_FUNC(JsiSkCanvas, rotate), - JSI_EXPORT_FUNC(JsiSkCanvas, translate), - JSI_EXPORT_FUNC(JsiSkCanvas, scale), - JSI_EXPORT_FUNC(JsiSkCanvas, skew), - JSI_EXPORT_FUNC(JsiSkCanvas, drawColor), - JSI_EXPORT_FUNC(JsiSkCanvas, clear), - JSI_EXPORT_FUNC(JsiSkCanvas, concat), - JSI_EXPORT_FUNC(JsiSkCanvas, drawPicture), - JSI_EXPORT_FUNC(JsiSkCanvas, drawAtlas), - JSI_EXPORT_FUNC(JsiSkCanvas, readPixels)) - - size_t getMemoryPressure() const override { return 1024; } - - std::string getObjectType() const override { return "JsiSkCanvas"; } + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "drawPaint", &JsiSkCanvas::drawPaint); + installHostMethod(runtime, prototype, "drawLine", &JsiSkCanvas::drawLine); + installHostMethod(runtime, prototype, "drawRect", &JsiSkCanvas::drawRect); + installHostMethod(runtime, prototype, "drawImage", &JsiSkCanvas::drawImage); + installHostMethod(runtime, prototype, "drawImageRect", + &JsiSkCanvas::drawImageRect); + installHostMethod(runtime, prototype, "drawImageCubic", + &JsiSkCanvas::drawImageCubic); + installHostMethod(runtime, prototype, "drawImageOptions", + &JsiSkCanvas::drawImageOptions); + installHostMethod(runtime, prototype, "drawImageNine", + &JsiSkCanvas::drawImageNine); + installHostMethod(runtime, prototype, "drawImageRectCubic", + &JsiSkCanvas::drawImageRectCubic); + installHostMethod(runtime, prototype, "drawImageRectOptions", + &JsiSkCanvas::drawImageRectOptions); + installHostMethod(runtime, prototype, "drawCircle", + &JsiSkCanvas::drawCircle); + installHostMethod(runtime, prototype, "drawArc", &JsiSkCanvas::drawArc); + installHostMethod(runtime, prototype, "drawRRect", &JsiSkCanvas::drawRRect); + installHostMethod(runtime, prototype, "drawDRRect", + &JsiSkCanvas::drawDRRect); + installHostMethod(runtime, prototype, "drawOval", &JsiSkCanvas::drawOval); + installHostMethod(runtime, prototype, "restoreToCount", + &JsiSkCanvas::restoreToCount); + installHostMethod(runtime, prototype, "getSaveCount", + &JsiSkCanvas::getSaveCount); + installHostMethod(runtime, prototype, "getTotalMatrix", + &JsiSkCanvas::getTotalMatrix); + installHostMethod(runtime, prototype, "drawPoints", + &JsiSkCanvas::drawPoints); + installHostMethod(runtime, prototype, "drawPatch", &JsiSkCanvas::drawPatch); + installHostMethod(runtime, prototype, "drawPath", &JsiSkCanvas::drawPath); + installHostMethod(runtime, prototype, "drawVertices", + &JsiSkCanvas::drawVertices); + installHostMethod(runtime, prototype, "drawText", &JsiSkCanvas::drawText); + installHostMethod(runtime, prototype, "drawTextBlob", + &JsiSkCanvas::drawTextBlob); + installHostMethod(runtime, prototype, "drawGlyphs", + &JsiSkCanvas::drawGlyphs); + installHostMethod(runtime, prototype, "drawSvg", &JsiSkCanvas::drawSvg); + installHostMethod(runtime, prototype, "clipPath", &JsiSkCanvas::clipPath); + installHostMethod(runtime, prototype, "clipRect", &JsiSkCanvas::clipRect); + installHostMethod(runtime, prototype, "clipRRect", &JsiSkCanvas::clipRRect); + installHostMethod(runtime, prototype, "save", &JsiSkCanvas::save); + installHostMethod(runtime, prototype, "saveLayer", &JsiSkCanvas::saveLayer); + installHostMethod(runtime, prototype, "restore", &JsiSkCanvas::restore); + installHostMethod(runtime, prototype, "rotate", &JsiSkCanvas::rotate); + installHostMethod(runtime, prototype, "translate", &JsiSkCanvas::translate); + installHostMethod(runtime, prototype, "scale", &JsiSkCanvas::scale); + installHostMethod(runtime, prototype, "skew", &JsiSkCanvas::skew); + installHostMethod(runtime, prototype, "drawColor", &JsiSkCanvas::drawColor); + installHostMethod(runtime, prototype, "clear", &JsiSkCanvas::clear); + installHostMethod(runtime, prototype, "concat", &JsiSkCanvas::concat); + installHostMethod(runtime, prototype, "drawPicture", + &JsiSkCanvas::drawPicture); + installHostMethod(runtime, prototype, "drawAtlas", &JsiSkCanvas::drawAtlas); + installHostMethod(runtime, prototype, "readPixels", + &JsiSkCanvas::readPixels); + } + + size_t getMemoryPressure() override { return 1024; } explicit JsiSkCanvas(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} JsiSkCanvas(std::shared_ptr context, SkCanvas *canvas) : JsiSkCanvas(std::move(context)) { diff --git a/packages/skia/cpp/api/JsiSkColor.h b/packages/skia/cpp/api/JsiSkColor.h index 305a8b8bac..5391c383bb 100644 --- a/packages/skia/cpp/api/JsiSkColor.h +++ b/packages/skia/cpp/api/JsiSkColor.h @@ -6,7 +6,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "api/third_party/CSSColorParser.h" #pragma clang diagnostic push @@ -20,11 +20,13 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkColor : public RNJsi::JsiHostObject { +/** + * JsiSkColor is a pure utility class — colors are represented as + * Float32Arrays on the JS side, so there is no wrapper object. + */ +class JsiSkColor { public: - JsiSkColor() : JsiHostObject() {} - - ~JsiSkColor() override = default; + JsiSkColor() = default; static jsi::Object toValue(jsi::Runtime &runtime, SkColor color) { auto result = runtime.global() diff --git a/packages/skia/cpp/api/JsiSkColorFilter.h b/packages/skia/cpp/api/JsiSkColorFilter.h index 8cba568c5e..f323068246 100644 --- a/packages/skia/cpp/api/JsiSkColorFilter.h +++ b/packages/skia/cpp/api/JsiSkColorFilter.h @@ -1,6 +1,6 @@ #pragma once -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include #include #include @@ -16,19 +16,26 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkColorFilter : public JsiSkWrappingSkPtrHostObject { +class JsiSkColorFilter + : public JsiSkWrappingSkPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "ColorFilter"; + JsiSkColorFilter(std::shared_ptr context, sk_sp colorFilter) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(colorFilter)) {} + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(colorFilter)) {} - size_t getMemoryPressure() const override { return 2048; } + size_t getMemoryPressure() override { return 2048; } - std::string getObjectType() const override { return "JsiSkColorFilter"; } + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } - EXPORT_JSI_API_TYPENAME(JsiSkColorFilter, ColorFilter) - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkColorFilter, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkColorFilterFactory.h b/packages/skia/cpp/api/JsiSkColorFilterFactory.h index d9a70b9c2d..70e2a64d00 100644 --- a/packages/skia/cpp/api/JsiSkColorFilterFactory.h +++ b/packages/skia/cpp/api/JsiSkColorFilterFactory.h @@ -2,7 +2,7 @@ #include "JsiSkColor.h" #include "JsiSkColorFilter.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include #include #include @@ -19,8 +19,11 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkColorFilterFactory : public JsiSkHostObject { +class JsiSkColorFilterFactory + : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "ColorFilterFactory"; + JSI_HOST_FUNCTION(MakeMatrix) { auto jsiMatrix = arguments[0].asObject(runtime).asArray(runtime); float matrix[20]; @@ -30,31 +33,28 @@ class JsiSkColorFilterFactory : public JsiSkHostObject { } } // Return the newly constructed object - auto colorFilter = std::make_shared( - getContext(), SkColorFilters::Matrix(std::move(matrix))); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, colorFilter, - getContext()); + return makeJsiObject( + runtime, std::make_shared( + getContext(), SkColorFilters::Matrix(std::move(matrix)))); } JSI_HOST_FUNCTION(MakeBlend) { auto color = JsiSkColor::fromValue(runtime, arguments[0]); SkBlendMode blend = (SkBlendMode)arguments[1].asNumber(); // Return the newly constructed object - auto colorFilter = std::make_shared( - getContext(), SkColorFilters::Blend(color, blend)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, colorFilter, - getContext()); + return makeJsiObject( + runtime, std::make_shared( + getContext(), SkColorFilters::Blend(color, blend))); } JSI_HOST_FUNCTION(MakeCompose) { auto outer = JsiSkColorFilter::fromValue(runtime, arguments[0]); auto inner = JsiSkColorFilter::fromValue(runtime, arguments[1]); // Return the newly constructed object - auto colorFilter = std::make_shared( - getContext(), - SkColorFilters::Compose(std::move(outer), std::move(inner))); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, colorFilter, - getContext()); + return makeJsiObject( + runtime, std::make_shared( + getContext(), SkColorFilters::Compose(std::move(outer), + std::move(inner)))); } JSI_HOST_FUNCTION(MakeLerp) { @@ -62,52 +62,52 @@ class JsiSkColorFilterFactory : public JsiSkHostObject { auto dst = JsiSkColorFilter::fromValue(runtime, arguments[1]); auto src = JsiSkColorFilter::fromValue(runtime, arguments[2]); // Return the newly constructed object - auto colorFilter = std::make_shared( - getContext(), SkColorFilters::Lerp(t, std::move(dst), std::move(src))); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, colorFilter, - getContext()); + return makeJsiObject( + runtime, std::make_shared( + getContext(), + SkColorFilters::Lerp(t, std::move(dst), std::move(src)))); } JSI_HOST_FUNCTION(MakeSRGBToLinearGamma) { // Return the newly constructed object - auto colorFilter = std::make_shared( - getContext(), SkColorFilters::SRGBToLinearGamma()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, colorFilter, - getContext()); + return makeJsiObject( + runtime, std::make_shared( + getContext(), SkColorFilters::SRGBToLinearGamma())); } JSI_HOST_FUNCTION(MakeLinearToSRGBGamma) { // Return the newly constructed object - auto colorFilter = std::make_shared( - getContext(), SkColorFilters::LinearToSRGBGamma()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, colorFilter, - getContext()); + return makeJsiObject( + runtime, std::make_shared( + getContext(), SkColorFilters::LinearToSRGBGamma())); } JSI_HOST_FUNCTION(MakeLumaColorFilter) { // Return the newly constructed object - auto colorFilter = std::make_shared( - getContext(), SkLumaColorFilter::Make()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, colorFilter, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), SkLumaColorFilter::Make())); } - size_t getMemoryPressure() const override { return 1024; } - - std::string getObjectType() const override { - return "JsiSkColorFilterFactory"; + size_t getMemoryPressure() override { return 1024; } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "MakeMatrix", + &JsiSkColorFilterFactory::MakeMatrix); + installHostMethod(runtime, prototype, "MakeBlend", + &JsiSkColorFilterFactory::MakeBlend); + installHostMethod(runtime, prototype, "MakeCompose", + &JsiSkColorFilterFactory::MakeCompose); + installHostMethod(runtime, prototype, "MakeLerp", + &JsiSkColorFilterFactory::MakeLerp); + installHostMethod(runtime, prototype, "MakeSRGBToLinearGamma", + &JsiSkColorFilterFactory::MakeSRGBToLinearGamma); + installHostMethod(runtime, prototype, "MakeLinearToSRGBGamma", + &JsiSkColorFilterFactory::MakeLinearToSRGBGamma); + installHostMethod(runtime, prototype, "MakeLumaColorFilter", + &JsiSkColorFilterFactory::MakeLumaColorFilter); } - JSI_EXPORT_FUNCTIONS( - JSI_EXPORT_FUNC(JsiSkColorFilterFactory, MakeMatrix), - JSI_EXPORT_FUNC(JsiSkColorFilterFactory, MakeBlend), - JSI_EXPORT_FUNC(JsiSkColorFilterFactory, MakeCompose), - JSI_EXPORT_FUNC(JsiSkColorFilterFactory, MakeLerp), - JSI_EXPORT_FUNC(JsiSkColorFilterFactory, MakeSRGBToLinearGamma), - JSI_EXPORT_FUNC(JsiSkColorFilterFactory, MakeLinearToSRGBGamma), - JSI_EXPORT_FUNC(JsiSkColorFilterFactory, MakeLumaColorFilter)) - explicit JsiSkColorFilterFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkContourMeasure.h b/packages/skia/cpp/api/JsiSkContourMeasure.h index 4e0fed0269..a0f137ddb6 100644 --- a/packages/skia/cpp/api/JsiSkContourMeasure.h +++ b/packages/skia/cpp/api/JsiSkContourMeasure.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -21,12 +21,15 @@ namespace RNSkia { namespace jsi = facebook::jsi; class JsiSkContourMeasure - : public JsiSkWrappingSkPtrHostObject { + : public JsiSkWrappingSkPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "ContourMeasure"; + JsiSkContourMeasure(std::shared_ptr context, const sk_sp contourMeasure) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(contourMeasure)) {} + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(contourMeasure)) {} JSI_HOST_FUNCTION(getPosTan) { auto dist = arguments[0].asNumber(); @@ -37,12 +40,10 @@ class JsiSkContourMeasure throw jsi::JSError(runtime, "getPosTan() failed"); } auto posTan = jsi::Array(runtime, 2); - auto posPoint = std::make_shared(getContext(), position); - auto pos = JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, posPoint, - getContext()); - auto tanPoint = std::make_shared(getContext(), tangent); - auto tan = JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, tanPoint, - getContext()); + auto pos = makeJsiObject( + runtime, std::make_shared(getContext(), position)); + auto tan = makeJsiObject( + runtime, std::make_shared(getContext(), tangent)); posTan.setValueAtIndex(runtime, 0, pos); posTan.setValueAtIndex(runtime, 1, tan); return posTan; @@ -67,16 +68,18 @@ class JsiSkContourMeasure return JsiSkPath::toValue(runtime, getContext(), builder.snapshot()); } - size_t getMemoryPressure() const override { return 1024; } - - std::string getObjectType() const override { return "JsiSkContourMeasure"; } - - EXPORT_JSI_API_TYPENAME(JsiSkContourMeasure, ContourMeasure) - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkContourMeasure, getPosTan), - JSI_EXPORT_FUNC(JsiSkContourMeasure, length), - JSI_EXPORT_FUNC(JsiSkContourMeasure, isClosed), - JSI_EXPORT_FUNC(JsiSkContourMeasure, getSegment), - JSI_EXPORT_FUNC(JsiSkContourMeasure, dispose)) + size_t getMemoryPressure() override { return 1024; } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "getPosTan", + &JsiSkContourMeasure::getPosTan); + installHostMethod(runtime, prototype, "length", + &JsiSkContourMeasure::length); + installHostMethod(runtime, prototype, "isClosed", + &JsiSkContourMeasure::isClosed); + installHostMethod(runtime, prototype, "getSegment", + &JsiSkContourMeasure::getSegment); + } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkContourMeasureIter.h b/packages/skia/cpp/api/JsiSkContourMeasureIter.h index 32da03aa67..7102cf2678 100644 --- a/packages/skia/cpp/api/JsiSkContourMeasureIter.h +++ b/packages/skia/cpp/api/JsiSkContourMeasureIter.h @@ -4,7 +4,7 @@ #include #include "JsiSkContourMeasure.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -20,12 +20,16 @@ namespace RNSkia { namespace jsi = facebook::jsi; class JsiSkContourMeasureIter - : public JsiSkWrappingSharedPtrHostObject { + : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "ContourMeasureIter"; + JsiSkContourMeasureIter(std::shared_ptr context, const SkPath &path, bool forceClosed, SkScalar resScale = 1) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), std::make_shared( path, forceClosed, resScale)) {} @@ -34,24 +38,18 @@ class JsiSkContourMeasureIter if (next == nullptr) { return jsi::Value::undefined(); } - auto nextObject = - std::make_shared(getContext(), std::move(next)); - - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, nextObject, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(next))); } - EXPORT_JSI_API_TYPENAME(JsiSkContourMeasureIter, ContourMeasureIter) - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkContourMeasureIter, next), - JSI_EXPORT_FUNC(JsiSkContourMeasureIter, dispose)) - - size_t getMemoryPressure() const override { - return std::max(sizeof(SkContourMeasureIter), kMinMemoryPressure); + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "next", + &JsiSkContourMeasureIter::next); } - std::string getObjectType() const override { - return "JsiSkContourMeasureIter"; + size_t getMemoryPressure() override { + return std::max(sizeof(SkContourMeasureIter), kMinMemoryPressure); } /** @@ -68,10 +66,9 @@ class JsiSkContourMeasureIter auto forceClosed = arguments[1].getBool(); auto resScale = arguments[2].asNumber(); // Return the newly constructed object - auto iter = std::make_shared( - std::move(context), path->snapshot(), forceClosed, resScale); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, iter, - context); + return makeJsiObject(runtime, std::make_shared( + std::move(context), path->snapshot(), + forceClosed, resScale)); }; } }; diff --git a/packages/skia/cpp/api/JsiSkData.h b/packages/skia/cpp/api/JsiSkData.h index e63052e203..788bf4dfb7 100644 --- a/packages/skia/cpp/api/JsiSkData.h +++ b/packages/skia/cpp/api/JsiSkData.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -19,19 +19,25 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkData : public JsiSkWrappingSkPtrHostObject { +class JsiSkData : public JsiSkWrappingSkPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "Data"; + JsiSkData(std::shared_ptr context, sk_sp asset) - : JsiSkWrappingSkPtrHostObject(std::move(context), std::move(asset)) {} + : JsiSkWrappingSkPtrNativeObject(std::move(context), + std::move(asset)) {} - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { auto data = getObject(); return data ? data->size() : 0; } - std::string getObjectType() const override { return "JsiSkData"; } + static sk_sp fromValue(jsi::Runtime &runtime, const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } - EXPORT_JSI_API_TYPENAME(JsiSkData, Data) - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkData, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkDataFactory.h b/packages/skia/cpp/api/JsiSkDataFactory.h index 477992b1e8..0b9cc868ab 100644 --- a/packages/skia/cpp/api/JsiSkDataFactory.h +++ b/packages/skia/cpp/api/JsiSkDataFactory.h @@ -5,16 +5,19 @@ #include -#include "jsi/JsiPromises.h" #include "JsiSkData.h" +#include "JsiSkNativeObjects.h" #include "api/third_party/base64.h" +#include "jsi/JsiPromises.h" namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkDataFactory : public JsiSkHostObject { +class JsiSkDataFactory : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "DataFactory"; + JSI_HOST_FUNCTION(fromURI) { auto jsiLocalUri = arguments[0].asString(runtime); auto localUri = jsiLocalUri.utf8(runtime); @@ -38,10 +41,9 @@ class JsiSkDataFactory : public JsiSkHostObject { context = std::move(context), promise = std::move(promise), result = std::move(result)]() { - auto hostObjectInstance = - std::make_shared(context, std::move(result)); - promise->resolve(JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, context)); + promise->resolve(makeJsiObject( + runtime, + std::make_shared(context, std::move(result)))); }); }); }); @@ -56,10 +58,8 @@ class JsiSkDataFactory : public JsiSkHostObject { auto data = SkData::MakeWithCopy(buffer.data(runtime), buffer.size(runtime)); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(data)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(data))); } JSI_HOST_FUNCTION(fromBase64) { @@ -85,22 +85,23 @@ class JsiSkDataFactory : public JsiSkHostObject { return jsi::Value::undefined(); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(data)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(data))); } - size_t getMemoryPressure() const override { return 1024; } + size_t getMemoryPressure() override { return 1024; } - std::string getObjectType() const override { return "JsiSkDataFactory"; } - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkDataFactory, fromURI), - JSI_EXPORT_FUNC(JsiSkDataFactory, fromBytes), - JSI_EXPORT_FUNC(JsiSkDataFactory, fromBase64)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "fromURI", + &JsiSkDataFactory::fromURI); + installHostMethod(runtime, prototype, "fromBytes", + &JsiSkDataFactory::fromBytes); + installHostMethod(runtime, prototype, "fromBase64", + &JsiSkDataFactory::fromBase64); + } explicit JsiSkDataFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkFont.h b/packages/skia/cpp/api/JsiSkFont.h index be387ed61d..0b85c4fbdf 100644 --- a/packages/skia/cpp/api/JsiSkFont.h +++ b/packages/skia/cpp/api/JsiSkFont.h @@ -5,7 +5,7 @@ #include #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "utils/RNSkLog.h" #include @@ -26,8 +26,10 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkFont : public JsiSkWrappingSharedPtrHostObject { +class JsiSkFont : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "Font"; + JSI_HOST_FUNCTION(getGlyphWidths) { auto jsiGlyphs = arguments[0].asObject(runtime).asArray(runtime); std::vector glyphs; @@ -91,9 +93,8 @@ class JsiSkFont : public JsiSkWrappingSharedPtrHostObject { getObject()->measureText(str.c_str(), str.length(), SkTextEncoding::kUTF8, &bounds); } - auto rect = std::make_shared(getContext(), std::move(bounds)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, rect, - getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(bounds))); } JSI_HOST_FUNCTION(getMetrics) { @@ -251,39 +252,56 @@ class JsiSkFont : public JsiSkWrappingSharedPtrHostObject { return jsi::Value::undefined(); } - EXPORT_JSI_API_TYPENAME(JsiSkFont, Font) - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkFont, getSize), - JSI_EXPORT_FUNC(JsiSkFont, getMetrics), - JSI_EXPORT_FUNC(JsiSkFont, getGlyphIDs), - JSI_EXPORT_FUNC(JsiSkFont, getGlyphIntercepts), - JSI_EXPORT_FUNC(JsiSkFont, getScaleX), - JSI_EXPORT_FUNC(JsiSkFont, getSkewX), - JSI_EXPORT_FUNC(JsiSkFont, getTypeface), - JSI_EXPORT_FUNC(JsiSkFont, setEdging), - JSI_EXPORT_FUNC(JsiSkFont, embeddedBitmaps), - JSI_EXPORT_FUNC(JsiSkFont, setHinting), - JSI_EXPORT_FUNC(JsiSkFont, setLinearMetrics), - JSI_EXPORT_FUNC(JsiSkFont, setScaleX), - JSI_EXPORT_FUNC(JsiSkFont, setSkewX), - JSI_EXPORT_FUNC(JsiSkFont, setSize), - JSI_EXPORT_FUNC(JsiSkFont, setEmbolden), - JSI_EXPORT_FUNC(JsiSkFont, setSubpixel), - JSI_EXPORT_FUNC(JsiSkFont, setTypeface), - JSI_EXPORT_FUNC(JsiSkFont, getGlyphWidths), - JSI_EXPORT_FUNC(JsiSkFont, getTextWidth), - JSI_EXPORT_FUNC(JsiSkFont, measureText), - JSI_EXPORT_FUNC(JsiSkFont, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "getSize", &JsiSkFont::getSize); + installHostMethod(runtime, prototype, "getMetrics", &JsiSkFont::getMetrics); + installHostMethod(runtime, prototype, "getGlyphIDs", + &JsiSkFont::getGlyphIDs); + installHostMethod(runtime, prototype, "getGlyphIntercepts", + &JsiSkFont::getGlyphIntercepts); + installHostMethod(runtime, prototype, "getScaleX", &JsiSkFont::getScaleX); + installHostMethod(runtime, prototype, "getSkewX", &JsiSkFont::getSkewX); + installHostMethod(runtime, prototype, "getTypeface", + &JsiSkFont::getTypeface); + installHostMethod(runtime, prototype, "setEdging", &JsiSkFont::setEdging); + installHostMethod(runtime, prototype, "embeddedBitmaps", + &JsiSkFont::embeddedBitmaps); + installHostMethod(runtime, prototype, "setHinting", &JsiSkFont::setHinting); + installHostMethod(runtime, prototype, "setLinearMetrics", + &JsiSkFont::setLinearMetrics); + installHostMethod(runtime, prototype, "setScaleX", &JsiSkFont::setScaleX); + installHostMethod(runtime, prototype, "setSkewX", &JsiSkFont::setSkewX); + installHostMethod(runtime, prototype, "setSize", &JsiSkFont::setSize); + installHostMethod(runtime, prototype, "setEmbolden", + &JsiSkFont::setEmbolden); + installHostMethod(runtime, prototype, "setSubpixel", + &JsiSkFont::setSubpixel); + installHostMethod(runtime, prototype, "setTypeface", + &JsiSkFont::setTypeface); + installHostMethod(runtime, prototype, "getGlyphWidths", + &JsiSkFont::getGlyphWidths); + installHostMethod(runtime, prototype, "getTextWidth", + &JsiSkFont::getTextWidth); + installHostMethod(runtime, prototype, "measureText", + &JsiSkFont::measureText); + } JsiSkFont(std::shared_ptr context, const SkFont &font) - : JsiSkWrappingSharedPtrHostObject(std::move(context), - std::make_shared(font)) {} + : JsiSkWrappingSharedPtrNativeObject( + std::move(context), std::make_shared(font)) {} - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { return std::max(sizeof(SkFont), kMinMemoryPressure); } - std::string getObjectType() const override { return "JsiSkFont"; } + /** + Returns the underlying object from a host object of this type + */ + static std::shared_ptr fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } /** * Creates the function for construction a new instance of the SkFont @@ -299,22 +317,16 @@ class JsiSkFont : public JsiSkWrappingSharedPtrHostObject { if (count == 2) { auto typeface = JsiSkTypeface::fromValue(runtime, arguments[0]); auto size = arguments[1].asNumber(); - auto hostObjectInstance = - std::make_shared(context, SkFont(typeface, size)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, std::move(context)); + return makeJsiObject(runtime, std::make_shared( + context, SkFont(typeface, size))); } else if (count == 1) { auto typeface = JsiSkTypeface::fromValue(runtime, arguments[0]); - auto hostObjectInstance = - std::make_shared(context, SkFont(typeface)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, std::move(context)); + return makeJsiObject( + runtime, std::make_shared(context, SkFont(typeface))); } else { // Return the newly constructed object - auto hostObjectInstance = - std::make_shared(context, SkFont()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, std::move(context)); + return makeJsiObject(runtime, + std::make_shared(context, SkFont())); } }; } diff --git a/packages/skia/cpp/api/JsiSkFontMgr.h b/packages/skia/cpp/api/JsiSkFontMgr.h index 4ce5837ea4..c4f1936d57 100644 --- a/packages/skia/cpp/api/JsiSkFontMgr.h +++ b/packages/skia/cpp/api/JsiSkFontMgr.h @@ -6,7 +6,7 @@ #include #include "JsiSkFontStyle.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "utils/RNSkLog.h" #include @@ -21,13 +21,15 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkFontMgr : public JsiSkWrappingSkPtrHostObject { +class JsiSkFontMgr + : public JsiSkWrappingSkPtrNativeObject { public: - EXPORT_JSI_API_TYPENAME(JsiSkFontMgr, FontMgr) + static constexpr const char *CLASS_NAME = "FontMgr"; JsiSkFontMgr(std::shared_ptr context, sk_sp fontMgr) - : JsiSkWrappingSkPtrHostObject(context, fontMgr), + : JsiSkWrappingSkPtrNativeObject(context, + fontMgr), _systemFontFamilies(context->getSystemFontFamilies()) {} JSI_HOST_FUNCTION(countFamilies) { @@ -63,19 +65,26 @@ class JsiSkFontMgr : public JsiSkWrappingSkPtrHostObject { auto fontStyle = JsiSkFontStyle::fromValue(runtime, arguments[1]); auto typeface = getObject()->matchFamilyStyle(resolvedName.c_str(), *fontStyle); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(typeface)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(typeface))); } - size_t getMemoryPressure() const override { return 2048; } + size_t getMemoryPressure() override { return 2048; } - std::string getObjectType() const override { return "JsiSkFontMgr"; } + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkFontMgr, countFamilies), - JSI_EXPORT_FUNC(JsiSkFontMgr, getFamilyName), - JSI_EXPORT_FUNC(JsiSkFontMgr, matchFamilyStyle)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "countFamilies", + &JsiSkFontMgr::countFamilies); + installHostMethod(runtime, prototype, "getFamilyName", + &JsiSkFontMgr::getFamilyName); + installHostMethod(runtime, prototype, "matchFamilyStyle", + &JsiSkFontMgr::matchFamilyStyle); + } private: std::vector _systemFontFamilies; diff --git a/packages/skia/cpp/api/JsiSkFontMgrFactory.h b/packages/skia/cpp/api/JsiSkFontMgrFactory.h index d283862b88..879a4d4149 100644 --- a/packages/skia/cpp/api/JsiSkFontMgrFactory.h +++ b/packages/skia/cpp/api/JsiSkFontMgrFactory.h @@ -6,7 +6,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -20,8 +20,10 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkFontMgrFactory : public JsiSkHostObject { +class JsiSkFontMgrFactory : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "FontMgrFactory"; + static sk_sp getFontMgr(std::shared_ptr context) { static SkOnce once; @@ -32,19 +34,19 @@ class JsiSkFontMgrFactory : public JsiSkHostObject { JSI_HOST_FUNCTION(System) { auto fontMgr = JsiSkFontMgrFactory::getFontMgr(getContext()); - auto fontMgrObj = std::make_shared(getContext(), fontMgr); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, fontMgrObj, - getContext()); + return makeJsiObject(runtime, + std::make_shared(getContext(), fontMgr)); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkFontMgrFactory, System)) - - size_t getMemoryPressure() const override { return 1024; } + size_t getMemoryPressure() override { return 1024; } - std::string getObjectType() const override { return "JsiSkFontMgrFactory"; } + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "System", + &JsiSkFontMgrFactory::System); + } explicit JsiSkFontMgrFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkFontStyle.h b/packages/skia/cpp/api/JsiSkFontStyle.h index ea93f52999..439fd60b39 100644 --- a/packages/skia/cpp/api/JsiSkFontStyle.h +++ b/packages/skia/cpp/api/JsiSkFontStyle.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -18,13 +18,14 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkFontStyle : public JsiSkWrappingSharedPtrHostObject { +class JsiSkFontStyle + : public JsiSkWrappingSharedPtrNativeObject { public: - JSI_API_TYPENAME("FontStyle"); + static constexpr const char *CLASS_NAME = "FontStyle"; JsiSkFontStyle(std::shared_ptr context, const SkFontStyle &fontStyle) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), std::make_shared(fontStyle)) {} /** @@ -33,8 +34,9 @@ class JsiSkFontStyle : public JsiSkWrappingSharedPtrHostObject { static std::shared_ptr fromValue(jsi::Runtime &runtime, const jsi::Value &obj) { const auto &object = obj.asObject(runtime); - if (object.isHostObject(runtime)) { - return object.asHostObject(runtime)->getObject(); + auto fontStyle = tryGetJsiObject(runtime, object); + if (fontStyle) { + return fontStyle->getObject(); } else { auto weightProp = object.getProperty(runtime, "weight"); auto weight = static_cast( @@ -56,11 +58,13 @@ class JsiSkFontStyle : public JsiSkWrappingSharedPtrHostObject { } } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { return std::max(sizeof(SkFontStyle), kMinMemoryPressure); } - std::string getObjectType() const override { return "JsiSkFontStyle"; } + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + } /** Returns the jsi object from a host object of this type @@ -68,10 +72,8 @@ class JsiSkFontStyle : public JsiSkWrappingSharedPtrHostObject { static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, const SkFontStyle &fontStyle) { - auto fontStyleObj = - std::make_shared(std::move(context), fontStyle); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, fontStyleObj, - context); + return makeJsiObject(runtime, std::make_shared( + std::move(context), fontStyle)); } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkHostObjects.h b/packages/skia/cpp/api/JsiSkHostObjects.h deleted file mode 100644 index 6d8f2c01e3..0000000000 --- a/packages/skia/cpp/api/JsiSkHostObjects.h +++ /dev/null @@ -1,257 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "jsi/JsiHostObject.h" -#include "utils/RNSkLog.h" -#include "rnskia/RNSkPlatformContext.h" - -namespace RNSkia { - -namespace jsi = facebook::jsi; - -// Minimum memory pressure reported for any host object. -// This accounts for C++ wrapper overhead and ensures dispose() never -// increases reported memory pressure (which would defeat its purpose). -static constexpr size_t kMinMemoryPressure = 256; - -/** - * Base class for jsi host objects - these are all implemented as JsiHostObjects - * and has a pointer to the platform context. - */ -class JsiSkHostObject : public RNJsi::JsiHostObject { -public: - /** - * Default constructor - * @param context Platform context - */ - explicit JsiSkHostObject(std::shared_ptr context) - : _context(context) {} - - /** - * Override this method to return the memory pressure for the wrapped object. - * @return The memory pressure in bytes - */ - virtual size_t getMemoryPressure() const = 0; - - /** - * Returns the type name of the host object. - */ - virtual std::string getObjectType() const = 0; - -protected: - /** - * @return A pointer to the platform context - */ - std::shared_ptr getContext() { return _context; } - -private: - std::shared_ptr _context; -}; - -#define JSI_API_TYPENAME(A) \ - JSI_PROPERTY_GET(__typename__) { \ - return jsi::String::createFromUtf8(runtime, #A); \ - } - -#define EXPORT_JSI_API_TYPENAME(CLASS, TYPENAME) \ - JSI_API_TYPENAME(TYPENAME) \ - JSI_EXPORT_PROPERTY_GETTERS(JSI_EXPORT_PROP_GET(CLASS, __typename__)) - -// Define this macro to enable memory pressure debug logging -// #define RNSKIA_DEBUG_MEMORY_PRESSURE - -#ifdef RNSKIA_DEBUG_MEMORY_PRESSURE -// Version with debug logging -#define JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( \ - runtime, hostObjectInstance, context) \ - [&]() { \ - auto result = \ - jsi::Object::createFromHostObject(runtime, hostObjectInstance); \ - auto memoryPressure = hostObjectInstance->getMemoryPressure(); \ - const void *hostObjectId = \ - static_cast(hostObjectInstance.get()); \ - const char *mpUnit = "bytes"; \ - double mpValue = static_cast(memoryPressure); \ - if (memoryPressure >= 1024ULL * 1024ULL) { \ - mpUnit = "MB"; \ - mpValue /= (1024.0 * 1024.0); \ - RNSkLogger::logToConsole( \ - "Host object %s (id=%p) memory pressure %.2f %s", \ - hostObjectInstance->getObjectType().c_str(), hostObjectId, mpValue, \ - mpUnit); \ - } else if (memoryPressure >= 1024ULL) { \ - mpUnit = "KB"; \ - mpValue /= 1024.0; \ - RNSkLogger::logToConsole( \ - "Host object %s (id=%p) memory pressure %.2f %s", \ - hostObjectInstance->getObjectType().c_str(), hostObjectId, mpValue, \ - mpUnit); \ - } else { \ - RNSkLogger::logToConsole( \ - "Host object %s (id=%p) memory pressure %zu %s", \ - hostObjectInstance->getObjectType().c_str(), hostObjectId, \ - memoryPressure, mpUnit); \ - } \ - if (memoryPressure > 0) { \ - result.setExternalMemoryPressure(runtime, memoryPressure); \ - } \ - return result; \ - }() -#else -// Version without debug logging (optimized) -#define JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( \ - runtime, hostObjectInstance, context) \ - [&]() { \ - auto result = \ - jsi::Object::createFromHostObject(runtime, hostObjectInstance); \ - auto memoryPressure = hostObjectInstance->getMemoryPressure(); \ - if (memoryPressure > 0) { \ - result.setExternalMemoryPressure(runtime, memoryPressure); \ - } \ - return result; \ - }() -#endif - -template class JsiSkWrappingHostObject : public JsiSkHostObject { -public: - /** - * Default constructor - * @param context Platform context - */ - JsiSkWrappingHostObject(std::shared_ptr context, - T object) - : JsiSkHostObject(std::move(context)), _object(std::move(object)) {} - - /** - * Returns the underlying object exposed by this host object. This object - * should be wrapped in a shared pointer of some kind. - * Throws if the object has been disposed. - * @return Underlying object - */ - T getObject() { return validateObject(); } - const T getObject() const { return validateObject(); } - - /** - * Updates the inner object with a new version of the object. - */ - void setObject(T object) { _object = object; } - - /** - * Dispose function that can be exposed to JS by using the JSI_API_TYPENAME - * macro. - */ - JSI_HOST_FUNCTION(dispose) { - if (!isDisposed()) { - thisValue.asObject(runtime).setExternalMemoryPressure(runtime, - kMinMemoryPressure); - } - safeDispose(); - return jsi::Value::undefined(); - } - -protected: - /** - * Override to implement disposal of allocated resources like smart pointers. - * This method will only be called once for each instance of this class. - */ - virtual void releaseResources() = 0; - - /** - * Returns true if the object has been disposed. - */ - bool isDisposed() const { - return _isDisposed.load(std::memory_order_acquire); - } - - /** - * Returns the underlying object without checking if disposed. - * Use this in destructors and releaseResources() where we need to access - * the object even after dispose() was called. - */ - T getObjectUnchecked() const { return _object; } - -private: - /** - * Validates that _object was not disposed and returns it. - */ - T validateObject() const { - if (_isDisposed.load(std::memory_order_acquire)) { - throw std::runtime_error("Attempted to access a disposed object."); - } - return _object; - } - - void safeDispose() { - bool expected = false; - if (_isDisposed.compare_exchange_strong(expected, true, - std::memory_order_acq_rel)) { - releaseResources(); - } - } - - /** - * Wrapped object. - */ - T _object; - - /** - * Resource disposed flag. - */ - std::atomic _isDisposed = {false}; -}; - -template -class JsiSkWrappingSharedPtrHostObject - : public JsiSkWrappingHostObject> { -public: - JsiSkWrappingSharedPtrHostObject(std::shared_ptr context, - std::shared_ptr object) - : JsiSkWrappingHostObject>(std::move(context), - std::move(object)) {} - - /** - Returns the underlying object from a host object of this type - */ - static std::shared_ptr fromValue(jsi::Runtime &runtime, - const jsi::Value &obj) { - return std::static_pointer_cast( - obj.asObject(runtime).asHostObject(runtime)) - ->getObject(); - } - -protected: - void releaseResources() override { - // Clear internally allocated objects - this->setObject(nullptr); - } -}; - -template -class JsiSkWrappingSkPtrHostObject : public JsiSkWrappingHostObject> { -public: - JsiSkWrappingSkPtrHostObject(std::shared_ptr context, - sk_sp object) - : JsiSkWrappingHostObject>(std::move(context), - std::move(object)) {} - - /** - Returns the underlying object from a host object of this type - */ - static sk_sp fromValue(jsi::Runtime &runtime, const jsi::Value &obj) { - return std::static_pointer_cast( - obj.asObject(runtime).asHostObject(runtime)) - ->getObject(); - } - -protected: - void releaseResources() override { - // Clear internally allocated objects - this->setObject(nullptr); - } -}; - -} // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkImage.h b/packages/skia/cpp/api/JsiSkImage.h index 377324b762..8551a58371 100644 --- a/packages/skia/cpp/api/JsiSkImage.h +++ b/packages/skia/cpp/api/JsiSkImage.h @@ -5,9 +5,9 @@ #include #include "JsiSkDispatcher.h" -#include "JsiSkHostObjects.h" #include "JsiSkImageInfo.h" #include "JsiSkMatrix.h" +#include "JsiSkNativeObjects.h" #include "JsiSkShader.h" #include "api/third_party/base64.h" @@ -15,8 +15,8 @@ #include "utils/RNSkTypedArray.h" #if defined(SK_GRAPHITE) -#include "rnskia/RNDawnContext.h" #include "include/gpu/graphite/Context.h" +#include "rnskia/RNDawnContext.h" #else #include "include/gpu/ganesh/GrDirectContext.h" #endif @@ -140,11 +140,13 @@ inline SkSamplingOptions SamplingOptionsFromValue(jsi::Runtime &runtime, return samplingOptions; } -class JsiSkImage : public JsiSkWrappingSkPtrHostObject { +class JsiSkImage : public JsiSkWrappingSkPtrNativeObject { private: std::shared_ptr _dispatcher; public: + static constexpr const char *CLASS_NAME = "Image"; + // TODO-API: Properties? JSI_HOST_FUNCTION(width) { return static_cast(getObject()->width()); } JSI_HOST_FUNCTION(height) { @@ -166,10 +168,8 @@ class JsiSkImage : public JsiSkWrappingSkPtrHostObject { : nullptr; auto shader = getObject()->makeShader(tmx, tmy, SkSamplingOptions(fm, mm), m); - auto shaderObj = - std::make_shared(getContext(), std::move(shader)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shaderObj, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(shader))); } JSI_HOST_FUNCTION(makeShaderCubic) { @@ -182,10 +182,8 @@ class JsiSkImage : public JsiSkWrappingSkPtrHostObject { : nullptr; auto shader = getObject()->makeShader(tmx, tmy, SkSamplingOptions({B, C}), m); - auto shaderObj = - std::make_shared(getContext(), std::move(shader)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shaderObj, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(shader))); } sk_sp encodeImageData(const jsi::Value *arguments, size_t count) { @@ -344,10 +342,8 @@ class JsiSkImage : public JsiSkWrappingSkPtrHostObject { if (!rasterImage) { return jsi::Value::null(); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(rasterImage)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(rasterImage))); } JSI_HOST_FUNCTION(getNativeTextureUnstable) { @@ -363,25 +359,42 @@ class JsiSkImage : public JsiSkWrappingSkPtrHostObject { return jsi::Value(getObject()->isTextureBacked()); } - EXPORT_JSI_API_TYPENAME(JsiSkImage, Image) - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkImage, width), - JSI_EXPORT_FUNC(JsiSkImage, height), - JSI_EXPORT_FUNC(JsiSkImage, getImageInfo), - JSI_EXPORT_FUNC(JsiSkImage, makeShaderOptions), - JSI_EXPORT_FUNC(JsiSkImage, makeShaderCubic), - JSI_EXPORT_FUNC(JsiSkImage, encodeToBytes), - JSI_EXPORT_FUNC(JsiSkImage, encodeToBase64), - JSI_EXPORT_FUNC(JsiSkImage, readPixels), - JSI_EXPORT_FUNC(JsiSkImage, makeNonTextureImage), - JSI_EXPORT_FUNC(JsiSkImage, getNativeTextureUnstable), - JSI_EXPORT_FUNC(JsiSkImage, isTextureBacked), - JSI_EXPORT_FUNC(JsiSkImage, dispose)) + /** + Returns the underlying object from a host object of this type + */ + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "width", &JsiSkImage::width); + installHostMethod(runtime, prototype, "height", &JsiSkImage::height); + installHostMethod(runtime, prototype, "getImageInfo", + &JsiSkImage::getImageInfo); + installHostMethod(runtime, prototype, "makeShaderOptions", + &JsiSkImage::makeShaderOptions); + installHostMethod(runtime, prototype, "makeShaderCubic", + &JsiSkImage::makeShaderCubic); + installHostMethod(runtime, prototype, "encodeToBytes", + &JsiSkImage::encodeToBytes); + installHostMethod(runtime, prototype, "encodeToBase64", + &JsiSkImage::encodeToBase64); + installHostMethod(runtime, prototype, "readPixels", + &JsiSkImage::readPixels); + installHostMethod(runtime, prototype, "makeNonTextureImage", + &JsiSkImage::makeNonTextureImage); + installHostMethod(runtime, prototype, "getNativeTextureUnstable", + &JsiSkImage::getNativeTextureUnstable); + installHostMethod(runtime, prototype, "isTextureBacked", + &JsiSkImage::isTextureBacked); + } JsiSkImage(std::shared_ptr context, const sk_sp image) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(image)) { + : JsiSkWrappingSkPtrNativeObject(std::move(context), + std::move(image)) { // Get the dispatcher for the current thread _dispatcher = Dispatcher::getDispatcher(); // Process any pending operations (e.g. deletions of previous resources) @@ -406,7 +419,7 @@ class JsiSkImage : public JsiSkWrappingSkPtrHostObject { } } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { if (isDisposed()) { return 0; } @@ -420,8 +433,6 @@ class JsiSkImage : public JsiSkWrappingSkPtrHostObject { } return 0; } - - std::string getObjectType() const override { return "JsiSkImage"; } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkImageFactory.h b/packages/skia/cpp/api/JsiSkImageFactory.h index e6382c749b..4ad5d400a6 100644 --- a/packages/skia/cpp/api/JsiSkImageFactory.h +++ b/packages/skia/cpp/api/JsiSkImageFactory.h @@ -5,11 +5,11 @@ #include -#include "jsi/JsiPromises.h" #include "JsiSkData.h" -#include "JsiSkHostObjects.h" #include "JsiSkImage.h" #include "JsiSkImageInfo.h" +#include "JsiSkNativeObjects.h" +#include "jsi/JsiPromises.h" #ifdef SK_GRAPHITE #include "rnskia/RNDawnContext.h" @@ -20,13 +20,13 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkImageFactory : public JsiSkHostObject { +class JsiSkImageFactory : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "ImageFactory"; + JSI_HOST_FUNCTION(MakeNull) { - auto hostObjectInstance = - std::make_shared(getContext(), nullptr); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, + std::make_shared(getContext(), nullptr)); } JSI_HOST_FUNCTION(MakeImageFromEncoded) { @@ -35,10 +35,8 @@ class JsiSkImageFactory : public JsiSkHostObject { if (image == nullptr) { return jsi::Value::null(); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(image)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(image))); } JSI_HOST_FUNCTION(MakeImageFromNativeBuffer) { @@ -49,10 +47,8 @@ class JsiSkImageFactory : public JsiSkHostObject { if (image == nullptr) { throw std::runtime_error("Failed to convert NativeBuffer to SkImage!"); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(image)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(image))); } JSI_HOST_FUNCTION(MakeImage) { @@ -63,10 +59,8 @@ class JsiSkImageFactory : public JsiSkHostObject { if (image == nullptr) { return jsi::Value::null(); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(image)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(image))); } JSI_HOST_FUNCTION(MakeImageFromViewTag) { @@ -88,10 +82,9 @@ class JsiSkImageFactory : public JsiSkHostObject { promise->reject("Failed to create image from view tag"); return; } - auto hostObjectInstance = - std::make_shared(context, std::move(result)); - promise->resolve(JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, context)); + promise->resolve( + makeJsiObject(runtime, std::make_shared( + context, std::move(result)))); }); }); }); @@ -105,17 +98,15 @@ class JsiSkImageFactory : public JsiSkHostObject { if (image == nullptr) { throw std::runtime_error("Failed to convert native texture to SkImage!"); } - if (count > 4 && arguments[4].isObject() && - arguments[4].asObject(runtime).isHostObject(runtime)) { - auto jsiImage = - arguments[4].asObject(runtime).asHostObject(runtime); - jsiImage->setObject(image); - return jsi::Value(runtime, arguments[4]); + if (count > 4) { + auto jsiImage = tryGetJsiObject(runtime, arguments[4]); + if (jsiImage) { + jsiImage->setObject(image); + return jsi::Value(runtime, arguments[4]); + } } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(image)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(image))); } JSI_HOST_FUNCTION(MakeImageFromTexture) { @@ -141,10 +132,8 @@ class JsiSkImageFactory : public JsiSkHostObject { if (image == nullptr) { throw std::runtime_error("Failed to create SkImage from GPUTexture!"); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(image)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(image))); #else throw std::runtime_error( "MakeImageFromTexture is only available with the Graphite backend. " @@ -179,23 +168,29 @@ class JsiSkImageFactory : public JsiSkHostObject { #endif } - size_t getMemoryPressure() const override { return 1024; } - - std::string getObjectType() const override { return "JsiSkImageFactory"; } - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImageFromEncoded), - JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImageFromViewTag), - JSI_EXPORT_FUNC(JsiSkImageFactory, - MakeImageFromNativeBuffer), - JSI_EXPORT_FUNC(JsiSkImageFactory, - MakeImageFromNativeTextureUnstable), - JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImage), - JSI_EXPORT_FUNC(JsiSkImageFactory, MakeNull), - JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImageFromTexture), - JSI_EXPORT_FUNC(JsiSkImageFactory, MakeTextureFromImage)) + size_t getMemoryPressure() override { return 1024; } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "MakeImageFromEncoded", + &JsiSkImageFactory::MakeImageFromEncoded); + installHostMethod(runtime, prototype, "MakeImageFromViewTag", + &JsiSkImageFactory::MakeImageFromViewTag); + installHostMethod(runtime, prototype, "MakeImageFromNativeBuffer", + &JsiSkImageFactory::MakeImageFromNativeBuffer); + installHostMethod(runtime, prototype, "MakeImageFromNativeTextureUnstable", + &JsiSkImageFactory::MakeImageFromNativeTextureUnstable); + installHostMethod(runtime, prototype, "MakeImage", + &JsiSkImageFactory::MakeImage); + installHostMethod(runtime, prototype, "MakeNull", + &JsiSkImageFactory::MakeNull); + installHostMethod(runtime, prototype, "MakeImageFromTexture", + &JsiSkImageFactory::MakeImageFromTexture); + installHostMethod(runtime, prototype, "MakeTextureFromImage", + &JsiSkImageFactory::MakeTextureFromImage); + } explicit JsiSkImageFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkImageFilter.h b/packages/skia/cpp/api/JsiSkImageFilter.h index 5a54f51b4c..68763c2872 100644 --- a/packages/skia/cpp/api/JsiSkImageFilter.h +++ b/packages/skia/cpp/api/JsiSkImageFilter.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -18,19 +18,29 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkImageFilter : public JsiSkWrappingSkPtrHostObject { +class JsiSkImageFilter + : public JsiSkWrappingSkPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "ImageFilter"; + JsiSkImageFilter(std::shared_ptr context, sk_sp imageFilter) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(imageFilter)) {} - - size_t getMemoryPressure() const override { return 1024 * 1024; } - - std::string getObjectType() const override { return "JsiSkImageFilter"; } - - EXPORT_JSI_API_TYPENAME(JsiSkImageFilter, ImageFilter) - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkImageFilter, dispose)) + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(imageFilter)) {} + + size_t getMemoryPressure() override { return 1024 * 1024; } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + } + + /** + Returns the underlying object from a host object of this type + */ + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkImageFilterFactory.h b/packages/skia/cpp/api/JsiSkImageFilterFactory.h index 11edc86b72..77119119d9 100644 --- a/packages/skia/cpp/api/JsiSkImageFilterFactory.h +++ b/packages/skia/cpp/api/JsiSkImageFilterFactory.h @@ -5,8 +5,8 @@ #include -#include "JsiSkHostObjects.h" #include "JsiSkImageFilter.h" +#include "JsiSkNativeObjects.h" #include "JsiSkPicture.h" #include "JsiSkRuntimeShaderBuilder.h" @@ -28,8 +28,11 @@ inline bool hasOptionalArgument(const jsi::Value *arguments, size_t count, !arguments[index].isUndefined()); } -class JsiSkImageFilterFactory : public JsiSkHostObject { +class JsiSkImageFilterFactory + : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "ImageFilterFactory"; + JSI_HOST_FUNCTION(MakeBlur) { float sigmaX = arguments[0].asNumber(); float sigmaY = arguments[1].asNumber(); @@ -45,8 +48,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { auto filter = std::make_shared( getContext(), SkImageFilters::Blur(sigmaX, sigmaY, (SkTileMode)tileMode, imageFilter, cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeColorFilter) { @@ -62,8 +64,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { auto filter = std::make_shared( getContext(), SkImageFilters::ColorFilter(std::move(cf), std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeOffset) { @@ -79,8 +80,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { } auto filter = std::make_shared( getContext(), SkImageFilters::Offset(x, y, std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeDisplacementMap) { @@ -102,8 +102,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { getContext(), SkImageFilters::DisplacementMap( fXChannelSelector, fYChannelSelector, scale, std::move(in2), std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeShader) { @@ -120,8 +119,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { auto filter = std::make_shared( getContext(), SkImageFilters::Shader(std::move(shader), dither, cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeCompose) { @@ -136,8 +134,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { auto filter = std::make_shared( getContext(), SkImageFilters::Compose(std::move(outer), std::move(inner))); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeBlend) { @@ -159,8 +156,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { getContext(), SkImageFilters::Blend(std::move(mode), std::move(background), std::move(foreground), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeDropShadow) { @@ -180,8 +176,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { auto filter = std::make_shared( getContext(), SkImageFilters::DropShadow(dx, dy, sigmaX, sigmaY, color, std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeDropShadowOnly) { @@ -202,8 +197,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { getContext(), SkImageFilters::DropShadowOnly(dx, dy, sigmaX, sigmaY, color, std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeErode) { @@ -220,8 +214,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { auto filter = std::make_shared( getContext(), SkImageFilters::Erode(rx, ry, std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeDilate) { @@ -238,8 +231,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { auto filter = std::make_shared( getContext(), SkImageFilters::Dilate(rx, ry, std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeRuntimeShader) { @@ -259,8 +251,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { auto filter = std::make_shared( getContext(), SkImageFilters::RuntimeShader(*rtb, childName, std::move(input))); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeArithmetic) { @@ -285,8 +276,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { getContext(), SkImageFilters::Arithmetic( k1, k2, k3, k4, enforcePMColor, std::move(background), std::move(foreground), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeCrop) { @@ -302,15 +292,13 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { auto filter = std::make_shared( getContext(), SkImageFilters::Crop(rect, tileMode, std::move(imageFilter))); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeEmpty) { auto filter = std::make_shared(getContext(), SkImageFilters::Empty()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } inline SkPoint3 SkPoint3FromValue(jsi::Runtime &runtime, @@ -339,8 +327,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { getContext(), SkImageFilters::DistantLitDiffuse(direction, lightColor, surfaceScale, kd, std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakePointLitDiffuse) { @@ -360,8 +347,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { getContext(), SkImageFilters::PointLitDiffuse(location, lightColor, surfaceScale, kd, std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeSpotLitDiffuse) { @@ -385,8 +371,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { SkImageFilters::SpotLitDiffuse(location, target, falloffExponent, cutoffAngle, lightColor, surfaceScale, kd, std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeDistantLitSpecular) { @@ -407,8 +392,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { getContext(), SkImageFilters::DistantLitSpecular( direction, lightColor, surfaceScale, ks, shininess, std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakePointLitSpecular) { @@ -429,8 +413,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { getContext(), SkImageFilters::PointLitSpecular( location, lightColor, surfaceScale, ks, shininess, std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeSpotLitSpecular) { @@ -455,8 +438,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { SkImageFilters::SpotLitSpecular( location, target, falloffExponent, cutoffAngle, lightColor, surfaceScale, ks, shininess, std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeImage) { @@ -485,8 +467,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { getContext(), SkImageFilters::Image(std::move(image), srcRect, dstRect, SkSamplingOptions(filterMode, mipmap))); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeMagnifier) { @@ -514,8 +495,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { SkImageFilters::Magnifier(lensBounds, zoomAmount, inset, SkSamplingOptions(filterMode, mipmap), input, cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeMatrixConvolution) { @@ -545,8 +525,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { getContext(), SkImageFilters::MatrixConvolution( kernelSize, kernel.data(), gain, bias, kernelOffset, tileMode, convolveAlpha, std::move(input), cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeMatrixTransform) { @@ -567,8 +546,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { getContext(), SkImageFilters::MatrixTransform( matrix, SkSamplingOptions(filterMode, mipmap), std::move(input))); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeMerge) { @@ -590,8 +568,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { auto filter = std::make_shared( getContext(), SkImageFilters::Merge(filters.data(), filtersCount, cropRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakePicture) { @@ -604,8 +581,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { } auto filter = std::make_shared( getContext(), SkImageFilters::Picture(std::move(picture), targetRect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeRuntimeShaderWithChildren) { @@ -641,8 +617,7 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { getContext(), SkImageFilters::RuntimeShader(*rtb, maxSampleRadius, childNamesStringView.data(), inputs.data(), length)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } JSI_HOST_FUNCTION(MakeTile) { @@ -654,49 +629,74 @@ class JsiSkImageFilterFactory : public JsiSkHostObject { } auto filter = std::make_shared( getContext(), SkImageFilters::Tile(src, dst, std::move(input))); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, filter, - getContext()); + return makeJsiObject(runtime, std::move(filter)); } - JSI_EXPORT_FUNCTIONS( - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeBlur), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeOffset), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeColorFilter), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeShader), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeDisplacementMap), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeCompose), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeErode), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeDilate), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeBlend), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeDropShadow), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeDropShadowOnly), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeRuntimeShader), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeArithmetic), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeCrop), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeEmpty), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeImage), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeMagnifier), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeMatrixConvolution), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeMatrixTransform), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeMerge), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakePicture), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeRuntimeShaderWithChildren), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeTile), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeDistantLitDiffuse), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakePointLitDiffuse), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeSpotLitDiffuse), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeDistantLitSpecular), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakePointLitSpecular), - JSI_EXPORT_FUNC(JsiSkImageFilterFactory, MakeSpotLitSpecular)) - - size_t getMemoryPressure() const override { return 2048; } - - std::string getObjectType() const override { - return "JsiSkImageFilterFactory"; + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "MakeBlur", + &JsiSkImageFilterFactory::MakeBlur); + installHostMethod(runtime, prototype, "MakeOffset", + &JsiSkImageFilterFactory::MakeOffset); + installHostMethod(runtime, prototype, "MakeColorFilter", + &JsiSkImageFilterFactory::MakeColorFilter); + installHostMethod(runtime, prototype, "MakeShader", + &JsiSkImageFilterFactory::MakeShader); + installHostMethod(runtime, prototype, "MakeDisplacementMap", + &JsiSkImageFilterFactory::MakeDisplacementMap); + installHostMethod(runtime, prototype, "MakeCompose", + &JsiSkImageFilterFactory::MakeCompose); + installHostMethod(runtime, prototype, "MakeErode", + &JsiSkImageFilterFactory::MakeErode); + installHostMethod(runtime, prototype, "MakeDilate", + &JsiSkImageFilterFactory::MakeDilate); + installHostMethod(runtime, prototype, "MakeBlend", + &JsiSkImageFilterFactory::MakeBlend); + installHostMethod(runtime, prototype, "MakeDropShadow", + &JsiSkImageFilterFactory::MakeDropShadow); + installHostMethod(runtime, prototype, "MakeDropShadowOnly", + &JsiSkImageFilterFactory::MakeDropShadowOnly); + installHostMethod(runtime, prototype, "MakeRuntimeShader", + &JsiSkImageFilterFactory::MakeRuntimeShader); + installHostMethod(runtime, prototype, "MakeArithmetic", + &JsiSkImageFilterFactory::MakeArithmetic); + installHostMethod(runtime, prototype, "MakeCrop", + &JsiSkImageFilterFactory::MakeCrop); + installHostMethod(runtime, prototype, "MakeEmpty", + &JsiSkImageFilterFactory::MakeEmpty); + installHostMethod(runtime, prototype, "MakeImage", + &JsiSkImageFilterFactory::MakeImage); + installHostMethod(runtime, prototype, "MakeMagnifier", + &JsiSkImageFilterFactory::MakeMagnifier); + installHostMethod(runtime, prototype, "MakeMatrixConvolution", + &JsiSkImageFilterFactory::MakeMatrixConvolution); + installHostMethod(runtime, prototype, "MakeMatrixTransform", + &JsiSkImageFilterFactory::MakeMatrixTransform); + installHostMethod(runtime, prototype, "MakeMerge", + &JsiSkImageFilterFactory::MakeMerge); + installHostMethod(runtime, prototype, "MakePicture", + &JsiSkImageFilterFactory::MakePicture); + installHostMethod(runtime, prototype, "MakeRuntimeShaderWithChildren", + &JsiSkImageFilterFactory::MakeRuntimeShaderWithChildren); + installHostMethod(runtime, prototype, "MakeTile", + &JsiSkImageFilterFactory::MakeTile); + installHostMethod(runtime, prototype, "MakeDistantLitDiffuse", + &JsiSkImageFilterFactory::MakeDistantLitDiffuse); + installHostMethod(runtime, prototype, "MakePointLitDiffuse", + &JsiSkImageFilterFactory::MakePointLitDiffuse); + installHostMethod(runtime, prototype, "MakeSpotLitDiffuse", + &JsiSkImageFilterFactory::MakeSpotLitDiffuse); + installHostMethod(runtime, prototype, "MakeDistantLitSpecular", + &JsiSkImageFilterFactory::MakeDistantLitSpecular); + installHostMethod(runtime, prototype, "MakePointLitSpecular", + &JsiSkImageFilterFactory::MakePointLitSpecular); + installHostMethod(runtime, prototype, "MakeSpotLitSpecular", + &JsiSkImageFilterFactory::MakeSpotLitSpecular); } + size_t getMemoryPressure() override { return 2048; } + explicit JsiSkImageFilterFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkImageInfo.h b/packages/skia/cpp/api/JsiSkImageInfo.h index 3bd2fd5be8..d1c23eb0f8 100644 --- a/packages/skia/cpp/api/JsiSkImageInfo.h +++ b/packages/skia/cpp/api/JsiSkImageInfo.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -18,11 +18,14 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkImageInfo : public JsiSkWrappingSharedPtrHostObject { +class JsiSkImageInfo + : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "ImageInfo"; + JsiSkImageInfo(std::shared_ptr context, const SkImageInfo &imageInfo) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), std::make_shared(imageInfo)) {} /** @@ -31,8 +34,9 @@ class JsiSkImageInfo : public JsiSkWrappingSharedPtrHostObject { static std::shared_ptr fromValue(jsi::Runtime &runtime, const jsi::Value &obj) { const auto &object = obj.asObject(runtime); - if (object.isHostObject(runtime)) { - return object.asHostObject(runtime)->getObject(); + auto imageInfo = tryGetJsiObject(runtime, object); + if (imageInfo) { + return imageInfo->getObject(); } else { auto width = object.getProperty(runtime, "width").asNumber(); auto height = object.getProperty(runtime, "height").asNumber(); @@ -52,10 +56,8 @@ class JsiSkImageInfo : public JsiSkWrappingSharedPtrHostObject { static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, const SkImageInfo &imageInfo) { - auto imageInfoObj = - std::make_shared(std::move(context), imageInfo); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, imageInfoObj, - context); + return makeJsiObject(runtime, std::make_shared( + std::move(context), imageInfo)); } JSI_PROPERTY_GET(width) { return static_cast(getObject()->width()); } @@ -69,18 +71,19 @@ class JsiSkImageInfo : public JsiSkWrappingSharedPtrHostObject { return static_cast(getObject()->alphaType()); } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { return std::max(sizeof(SkImageInfo), kMinMemoryPressure); } - std::string getObjectType() const override { return "JsiSkImageInfo"; } - - JSI_API_TYPENAME(ImageInfo); - - JSI_EXPORT_PROPERTY_GETTERS(JSI_EXPORT_PROP_GET(JsiSkImageInfo, width), - JSI_EXPORT_PROP_GET(JsiSkImageInfo, height), - JSI_EXPORT_PROP_GET(JsiSkImageInfo, colorType), - JSI_EXPORT_PROP_GET(JsiSkImageInfo, alphaType), - JSI_EXPORT_PROP_GET(JsiSkImageInfo, __typename__)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostGetter(runtime, prototype, "width", &JsiSkImageInfo::get_width); + installHostGetter(runtime, prototype, "height", + &JsiSkImageInfo::get_height); + installHostGetter(runtime, prototype, "colorType", + &JsiSkImageInfo::get_colorType); + installHostGetter(runtime, prototype, "alphaType", + &JsiSkImageInfo::get_alphaType); + } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkMaskFilter.h b/packages/skia/cpp/api/JsiSkMaskFilter.h index ed2ca599b2..26559bfc4b 100644 --- a/packages/skia/cpp/api/JsiSkMaskFilter.h +++ b/packages/skia/cpp/api/JsiSkMaskFilter.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -18,19 +18,29 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkMaskFilter : public JsiSkWrappingSkPtrHostObject { +class JsiSkMaskFilter + : public JsiSkWrappingSkPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "MaskFilter"; + JsiSkMaskFilter(std::shared_ptr context, sk_sp maskFilter) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(maskFilter)) {} - - size_t getMemoryPressure() const override { return 2048; } - - std::string getObjectType() const override { return "JsiSkMaskFilter"; } - - EXPORT_JSI_API_TYPENAME(JsiSkMaskFilter, MaskFilter) - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkMaskFilter, dispose)) + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(maskFilter)) {} + + size_t getMemoryPressure() override { return 2048; } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + } + + /** + Returns the underlying object from a host object of this type + */ + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkMaskFilterFactory.h b/packages/skia/cpp/api/JsiSkMaskFilterFactory.h index 1413943695..6fa1be0fa8 100644 --- a/packages/skia/cpp/api/JsiSkMaskFilterFactory.h +++ b/packages/skia/cpp/api/JsiSkMaskFilterFactory.h @@ -6,7 +6,8 @@ #include #include "JsiSkColorFilter.h" -#include "JsiSkHostObjects.h" +#include "JsiSkMaskFilter.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -19,29 +20,31 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkMaskFilterFactory : public JsiSkHostObject { +class JsiSkMaskFilterFactory + : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "MaskFilterFactory"; + JSI_HOST_FUNCTION(MakeBlur) { int blurStyle = arguments[0].asNumber(); float sigma = arguments[1].asNumber(); bool respectCTM = arguments[2].getBool(); - auto maskFilter = std::make_shared( - getContext(), - SkMaskFilter::MakeBlur((SkBlurStyle)blurStyle, sigma, respectCTM)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, maskFilter, - getContext()); + return makeJsiObject( + runtime, + std::make_shared( + getContext(), + SkMaskFilter::MakeBlur((SkBlurStyle)blurStyle, sigma, respectCTM))); } - size_t getMemoryPressure() const override { return 1024; } + size_t getMemoryPressure() override { return 1024; } - std::string getObjectType() const override { - return "JsiSkMaskFilterFactory"; + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "MakeBlur", + &JsiSkMaskFilterFactory::MakeBlur); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkMaskFilterFactory, MakeBlur)) - explicit JsiSkMaskFilterFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkMatrix.h b/packages/skia/cpp/api/JsiSkMatrix.h index 1d8def7e74..9732b38da1 100644 --- a/packages/skia/cpp/api/JsiSkMatrix.h +++ b/packages/skia/cpp/api/JsiSkMatrix.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -18,10 +18,13 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkMatrix : public JsiSkWrappingSharedPtrHostObject { +class JsiSkMatrix + : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "Matrix"; + JsiSkMatrix(std::shared_ptr context, SkMatrix m) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( context, std::make_shared(std::move(m))) {} static SkMatrix getMatrix(jsi::Runtime &runtime, const jsi::Value &value) { @@ -57,10 +60,9 @@ class JsiSkMatrix : public JsiSkWrappingSharedPtrHostObject { } JSI_HOST_FUNCTION(concat) { - if (arguments[0].isObject() && - arguments[0].asObject(runtime).isHostObject(runtime)) { - auto m3 = JsiSkMatrix::fromValue(runtime, arguments[0]); - getObject()->preConcat(*m3); + auto matrix = tryGetJsiObject(runtime, arguments[0]); + if (matrix) { + getObject()->preConcat(*matrix->getObject()); } else { auto m3 = JsiSkMatrix::getMatrix(runtime, arguments[0]); getObject()->preConcat(m3); @@ -138,40 +140,40 @@ class JsiSkMatrix : public JsiSkWrappingSharedPtrHostObject { } #pragma clang diagnostic pop - EXPORT_JSI_API_TYPENAME(JsiSkMatrix, Matrix) - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkMatrix, concat), - JSI_EXPORT_FUNC(JsiSkMatrix, translate), - JSI_EXPORT_FUNC(JsiSkMatrix, postTranslate), - JSI_EXPORT_FUNC(JsiSkMatrix, scale), - JSI_EXPORT_FUNC(JsiSkMatrix, postScale), - JSI_EXPORT_FUNC(JsiSkMatrix, skew), - JSI_EXPORT_FUNC(JsiSkMatrix, postSkew), - JSI_EXPORT_FUNC(JsiSkMatrix, rotate), - JSI_EXPORT_FUNC(JsiSkMatrix, postRotate), - JSI_EXPORT_FUNC(JsiSkMatrix, identity), - JSI_EXPORT_FUNC(JsiSkMatrix, get), - JSI_EXPORT_FUNC(JsiSkMatrix, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "concat", &JsiSkMatrix::concat); + installHostMethod(runtime, prototype, "translate", &JsiSkMatrix::translate); + installHostMethod(runtime, prototype, "postTranslate", + &JsiSkMatrix::postTranslate); + installHostMethod(runtime, prototype, "scale", &JsiSkMatrix::scale); + installHostMethod(runtime, prototype, "postScale", &JsiSkMatrix::postScale); + installHostMethod(runtime, prototype, "skew", &JsiSkMatrix::skew); + installHostMethod(runtime, prototype, "postSkew", &JsiSkMatrix::postSkew); + installHostMethod(runtime, prototype, "rotate", &JsiSkMatrix::rotate); + installHostMethod(runtime, prototype, "postRotate", + &JsiSkMatrix::postRotate); + installHostMethod(runtime, prototype, "identity", &JsiSkMatrix::identity); + installHostMethod(runtime, prototype, "get", &JsiSkMatrix::get); + } /** * Returns the underlying object from a host object of this type */ static std::shared_ptr fromValue(jsi::Runtime &runtime, const jsi::Value &obj) { - const auto &object = obj.asObject(runtime); - if (object.isHostObject(runtime)) { - return object.asHostObject(runtime)->getObject(); + auto matrix = tryGetJsiObject(runtime, obj); + if (matrix) { + return matrix->getObject(); } else { return std::make_shared(JsiSkMatrix::getMatrix(runtime, obj)); } } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { return std::max(sizeof(SkMatrix), kMinMemoryPressure); } - std::string getObjectType() const override { return "JsiSkMatrix"; } - static const jsi::HostFunctionType createCtor(std::shared_ptr context) { return JSI_HOST_FUNCTION_LAMBDA { @@ -181,10 +183,8 @@ class JsiSkMatrix : public JsiSkWrappingSharedPtrHostObject { } else { matrix = SkMatrix::I(); } - auto hostObjectInstance = - std::make_shared(context, std::move(matrix)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, context); + return makeJsiObject( + runtime, std::make_shared(context, std::move(matrix))); }; } }; diff --git a/packages/skia/cpp/api/JsiSkNativeObjects.h b/packages/skia/cpp/api/JsiSkNativeObjects.h new file mode 100644 index 0000000000..09b7f52ecc --- /dev/null +++ b/packages/skia/cpp/api/JsiSkNativeObjects.h @@ -0,0 +1,419 @@ +#pragma once + +#include +#include +#include +#include + +#include + +#include "jsi/NativeObject.h" +#include "rnskia/RNSkPlatformContext.h" +#include "utils/RNSkLog.h" + +#define STR_CAT_NX(A, B) A##B +#define STR_CAT(A, B) STR_CAT_NX(A, B) +#define STR_GET get_ +#define STR_SET set_ + +/** + * Creates a new Host function declaration as a lambda with all deps passed + * with implicit lambda capture clause + */ +#define JSI_HOST_FUNCTION_LAMBDA \ + [=](jsi::Runtime & runtime, const jsi::Value &thisValue, \ + const jsi::Value *arguments, size_t count) -> jsi::Value + +/** + * Creates a new Host function declaration + */ +#define JSI_HOST_FUNCTION(NAME) \ + jsi::Value NAME(jsi::Runtime &runtime, const jsi::Value &thisValue, \ + const jsi::Value *arguments, size_t count) + +/** + * Creates a new property setter function declaration + */ +#define JSI_PROPERTY_SET(NAME) \ + void STR_CAT(STR_SET, NAME)(jsi::Runtime & runtime, const jsi::Value &value) + +/** + * Creates a new property getter function declaration + */ +#define JSI_PROPERTY_GET(NAME) \ + jsi::Value STR_CAT(STR_GET, NAME)(jsi::Runtime & runtime) + +namespace RNSkia { + +namespace jsi = facebook::jsi; + +// Minimum memory pressure reported for any native object — aliased from the +// NativeObject infrastructure so dispose() and create() agree on the floor. +static constexpr size_t kMinMemoryPressure = rnwgpu::kMinMemoryPressure; + +/** + * Creates the JS object for a wrapper instance (a class based on the + * NativeObject pattern below). + */ +template +jsi::Value makeJsiObject(jsi::Runtime &runtime, std::shared_ptr instance) { + return T::create(runtime, std::move(instance)); +} + +/** + * Returns the wrapper instance backing the given JS object or nullptr if the + * object is not backed by the requested type. + */ +template +std::shared_ptr tryGetJsiObject(jsi::Runtime &runtime, + const jsi::Object &object) { + if (object.hasNativeState(runtime)) { + return object.getNativeState(runtime); + } + return nullptr; +} + +template +std::shared_ptr tryGetJsiObject(jsi::Runtime &runtime, + const jsi::Value &value) { + if (!value.isObject()) { + return nullptr; + } + auto object = value.asObject(runtime); + return tryGetJsiObject(runtime, object); +} + +/** + * Returns the wrapper instance backing the given JS value or throws a JS + * error if the value is not backed by the requested type. + */ +template +std::shared_ptr getJsiObject(jsi::Runtime &runtime, + const jsi::Value &value) { + auto result = tryGetJsiObject(runtime, value); + if (result == nullptr) { + throw jsi::JSError(runtime, "Expected a Skia object of a different type."); + } + return result; +} + +/** + * Base class for Skia API objects implemented with the NativeObject / + * jsi::NativeState pattern (see jsi/NativeObject.h). Instead of a HostObject + * intercepting every property access, methods and properties live on a shared + * per-runtime prototype and the C++ instance is attached to plain JS objects + * as native state. + * + * Derived classes must provide: + * - `static constexpr const char *CLASS_NAME` — the public __typename__ + * (e.g. "Rect"); also used as the boxing brand, so it must be unique. + * - `static void definePrototype(jsi::Runtime&, jsi::Object& prototype)` — + * installs methods/getters. The shared pieces (`__typename__`, `__box()` + * and the boxing reconstructor) are installed by + * NativeObject::installPrototype; wrapping classes additionally call + * `installCommon(runtime, proto)` to install dispose(). + * + * The existing JSI_HOST_FUNCTION / JSI_PROPERTY_GET / JSI_PROPERTY_SET method + * bodies keep working unchanged; they are installed on the prototype with the + * installHostMethod / installHostGetter / installHostSetter helpers below, + * which resolve the C++ instance from `this` via native state. + */ +template +class JsiSkNativeObject : public rnwgpu::NativeObject { +public: + explicit JsiSkNativeObject(std::shared_ptr context) + : rnwgpu::NativeObject(Derived::CLASS_NAME), + _context(std::move(context)) {} + + /** + * Resolves the C++ instance backing `thisValue`. Throws a JSError if the + * value is not backed by this class. + */ + static std::shared_ptr fromThis(jsi::Runtime &runtime, + const jsi::Value &thisValue) { + return rnwgpu::NativeObject::fromValue(runtime, thisValue); + } + +protected: + std::shared_ptr getContext() { return _context; } + + /** + @Returns a reference to the argument at the given position in the arguments + array. Raises an error if the index is above the number of arguments. + */ + static const jsi::Value &getArgument(jsi::Runtime &runtime, + const jsi::Value *arguments, + size_t count, size_t index) { + if (index >= count) { + throw jsi::JSError(runtime, "Argument index out of bounds."); + } + + return arguments[index]; + } + + /** + Returns argument as number or throws + */ + static double getArgumentAsNumber(jsi::Runtime &runtime, + const jsi::Value *arguments, size_t count, + size_t index) { + const jsi::Value &value = getArgument(runtime, arguments, count, index); + if (!value.isNumber()) { + throw jsi::JSError(runtime, + "Expected type number for parameter at index " + + std::to_string(index)); + } + return value.asNumber(); + } + + /** + Returns argument as string or throws + */ + static jsi::String getArgumentAsString(jsi::Runtime &runtime, + const jsi::Value *arguments, + size_t count, size_t index) { + const jsi::Value &value = getArgument(runtime, arguments, count, index); + if (!value.isString()) { + throw jsi::JSError(runtime, + "Expected type string for parameter at index " + + std::to_string(index)); + } + return value.asString(runtime); + } + + /** + Returns argument as object or throws + */ + static jsi::Object getArgumentAsObject(jsi::Runtime &runtime, + const jsi::Value *arguments, + size_t count, size_t index) { + const jsi::Value &value = getArgument(runtime, arguments, count, index); + if (!value.isObject()) { + throw jsi::JSError(runtime, + "Expected type object for parameter at index " + + std::to_string(index)); + } + return value.asObject(runtime); + } + + /** + Returns argument as function or throws + */ + static jsi::Object getArgumentAsFunction(jsi::Runtime &runtime, + const jsi::Value *arguments, + size_t count, size_t index) { + auto value = getArgumentAsObject(runtime, arguments, count, index); + if (!value.isFunction(runtime)) { + throw jsi::JSError(runtime, + "Expected type function for parameter at index " + + std::to_string(index)); + } + return value.asFunction(runtime); + } + + using HostMethod = jsi::Value (Derived::*)(jsi::Runtime &, const jsi::Value &, + const jsi::Value *, size_t); + using HostGetter = jsi::Value (Derived::*)(jsi::Runtime &); + using HostSetter = void (Derived::*)(jsi::Runtime &, const jsi::Value &); + + /** + * Installs a method with the classic host-function signature + * (JSI_HOST_FUNCTION) on the prototype. + */ + static void installHostMethod(jsi::Runtime &runtime, jsi::Object &prototype, + const char *name, HostMethod method) { + auto func = jsi::Function::createFromHostFunction( + runtime, jsi::PropNameID::forUtf8(runtime, name), 0, + [method](jsi::Runtime &rt, const jsi::Value &thisValue, + const jsi::Value *arguments, size_t count) -> jsi::Value { + auto native = fromThis(rt, thisValue); + return ((*native).*method)(rt, thisValue, arguments, count); + }); + prototype.setProperty(runtime, name, func); + } + + /** + * Installs a property getter with the classic JSI_PROPERTY_GET signature on + * the prototype. + */ + static void installHostGetter(jsi::Runtime &runtime, jsi::Object &prototype, + const char *name, HostGetter getter) { + auto getterFunc = jsi::Function::createFromHostFunction( + runtime, jsi::PropNameID::forUtf8(runtime, std::string("get_") + name), + 0, + [getter](jsi::Runtime &rt, const jsi::Value &thisValue, + const jsi::Value *, size_t) -> jsi::Value { + auto native = fromThis(rt, thisValue); + return ((*native).*getter)(rt); + }); + defineProperty(runtime, prototype, name, &getterFunc, nullptr); + } + + /** + * Installs a property setter with the classic JSI_PROPERTY_SET signature on + * the prototype, preserving a previously installed getter. + */ + static void installHostSetter(jsi::Runtime &runtime, jsi::Object &prototype, + const char *name, HostSetter setter) { + auto setterFunc = jsi::Function::createFromHostFunction( + runtime, jsi::PropNameID::forUtf8(runtime, std::string("set_") + name), + 1, + [setter](jsi::Runtime &rt, const jsi::Value &thisValue, + const jsi::Value *arguments, size_t count) -> jsi::Value { + if (count < 1) { + throw jsi::JSError(rt, "Setter requires a value argument"); + } + auto native = fromThis(rt, thisValue); + ((*native).*setter)(rt, arguments[0]); + return jsi::Value::undefined(); + }); + defineProperty(runtime, prototype, name, nullptr, &setterFunc); + } + + /** + * Installs both getter and setter for a property on the prototype. + */ + static void installHostProperty(jsi::Runtime &runtime, jsi::Object &prototype, + const char *name, HostGetter getter, + HostSetter setter) { + installHostGetter(runtime, prototype, name, getter); + installHostSetter(runtime, prototype, name, setter); + } + +private: + static void defineProperty(jsi::Runtime &runtime, jsi::Object &prototype, + const char *name, jsi::Function *getter, + jsi::Function *setter) { + auto objectCtor = runtime.global().getPropertyAsObject(runtime, "Object"); + auto defineProp = + objectCtor.getPropertyAsFunction(runtime, "defineProperty"); + auto getOwnPropertyDescriptor = + objectCtor.getPropertyAsFunction(runtime, "getOwnPropertyDescriptor"); + auto existing = getOwnPropertyDescriptor.call( + runtime, prototype, jsi::String::createFromUtf8(runtime, name)); + + jsi::Object descriptor(runtime); + if (existing.isObject()) { + auto existingObj = existing.getObject(runtime); + if (existingObj.hasProperty(runtime, "get")) { + descriptor.setProperty(runtime, "get", + existingObj.getProperty(runtime, "get")); + } + if (existingObj.hasProperty(runtime, "set")) { + descriptor.setProperty(runtime, "set", + existingObj.getProperty(runtime, "set")); + } + } + if (getter != nullptr) { + descriptor.setProperty(runtime, "get", *getter); + } + if (setter != nullptr) { + descriptor.setProperty(runtime, "set", *setter); + } + descriptor.setProperty(runtime, "enumerable", true); + descriptor.setProperty(runtime, "configurable", true); + defineProp.call(runtime, prototype, + jsi::String::createFromUtf8(runtime, name), descriptor); + } + + std::shared_ptr _context; +}; + +/** + * NativeObject equivalent of JsiSkWrappingHostObject: wraps an inner object + * (a std::shared_ptr or sk_sp) and provides dispose() semantics. + */ +template +class JsiSkWrappingNativeObject : public JsiSkNativeObject { +public: + JsiSkWrappingNativeObject(std::shared_ptr context, + T object) + : JsiSkNativeObject(std::move(context)), + _object(std::move(object)) {} + + /** + * Returns the wrapped object. Throws if the object has been disposed. + */ + T getObject() { return validateObject(); } + const T getObject() const { return validateObject(); } + + /** + * Updates the inner object with a new version of the object. + */ + void setObject(T object) { _object = object; } + + /** + * Returns the wrapped object from a JS value backed by this class. + */ + static T objectFromValue(jsi::Runtime &runtime, const jsi::Value &value) { + return JsiSkNativeObject::fromThis(runtime, value)->getObject(); + } + + /** + * dispose() releases the wrapped resources eagerly instead of waiting for + * garbage collection. Installed on the prototype via installCommon. + */ + JSI_HOST_FUNCTION(dispose) { + if (!isDisposed()) { + thisValue.asObject(runtime).setExternalMemoryPressure(runtime, + kMinMemoryPressure); + } + safeDispose(); + return jsi::Value::undefined(); + } + + /** + * Installs dispose() on the prototype (the shared pieces — __typename__, + * __box() and the boxing reconstructor — are installed by + * NativeObject::installPrototype). Must be called from definePrototype(). + */ + static void installCommon(jsi::Runtime &runtime, jsi::Object &prototype) { + JsiSkNativeObject::installHostMethod(runtime, prototype, "dispose", + &Derived::dispose); + } + +protected: + /** + * Override to release additional resources. Called exactly once. + */ + virtual void releaseResources() { setObject(nullptr); } + + bool isDisposed() const { + return _isDisposed.load(std::memory_order_acquire); + } + + /** + * Returns the wrapped object without the disposed check — for destructors + * and releaseResources() implementations. + */ + T getObjectUnchecked() const { return _object; } + +private: + T validateObject() const { + if (_isDisposed.load(std::memory_order_acquire)) { + throw std::runtime_error("Attempted to access a disposed object."); + } + return _object; + } + + void safeDispose() { + bool expected = false; + if (_isDisposed.compare_exchange_strong(expected, true, + std::memory_order_acq_rel)) { + releaseResources(); + } + } + + T _object; + std::atomic _isDisposed = {false}; +}; + +template +using JsiSkWrappingSharedPtrNativeObject = + JsiSkWrappingNativeObject>; + +template +using JsiSkWrappingSkPtrNativeObject = + JsiSkWrappingNativeObject>; + +} // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkPaint.h b/packages/skia/cpp/api/JsiSkPaint.h index 61ad36a307..a7e63994de 100644 --- a/packages/skia/cpp/api/JsiSkPaint.h +++ b/packages/skia/cpp/api/JsiSkPaint.h @@ -8,9 +8,9 @@ #include "CustomBlendModes.h" #include "JsiSkColor.h" #include "JsiSkColorFilter.h" -#include "JsiSkHostObjects.h" #include "JsiSkImageFilter.h" #include "JsiSkMaskFilter.h" +#include "JsiSkNativeObjects.h" #include "JsiSkPathEffect.h" #include "JsiSkShader.h" @@ -24,9 +24,10 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkPaint : public JsiSkWrappingSharedPtrHostObject { +class JsiSkPaint + : public JsiSkWrappingSharedPtrNativeObject { public: - EXPORT_JSI_API_TYPENAME(JsiSkPaint, Paint) + static constexpr const char *CLASS_NAME = "Paint"; JSI_HOST_FUNCTION(assign) { SkPaint *paint = JsiSkPaint::fromValue(runtime, arguments[0]).get(); @@ -36,10 +37,8 @@ class JsiSkPaint : public JsiSkWrappingSharedPtrHostObject { JSI_HOST_FUNCTION(copy) { const auto *paint = getObject().get(); - auto hostObjectInstance = - std::make_shared(getContext(), SkPaint(*paint)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), SkPaint(*paint))); } JSI_HOST_FUNCTION(reset) { @@ -172,36 +171,60 @@ class JsiSkPaint : public JsiSkWrappingSharedPtrHostObject { return jsi::Value::undefined(); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkPaint, assign), - JSI_EXPORT_FUNC(JsiSkPaint, copy), - JSI_EXPORT_FUNC(JsiSkPaint, reset), - JSI_EXPORT_FUNC(JsiSkPaint, getAlphaf), - JSI_EXPORT_FUNC(JsiSkPaint, getColor), - JSI_EXPORT_FUNC(JsiSkPaint, getStrokeCap), - JSI_EXPORT_FUNC(JsiSkPaint, getStrokeJoin), - JSI_EXPORT_FUNC(JsiSkPaint, getStrokeMiter), - JSI_EXPORT_FUNC(JsiSkPaint, getStrokeWidth), - JSI_EXPORT_FUNC(JsiSkPaint, setPathEffect), - JSI_EXPORT_FUNC(JsiSkPaint, setShader), - JSI_EXPORT_FUNC(JsiSkPaint, setColorFilter), - JSI_EXPORT_FUNC(JsiSkPaint, setImageFilter), - JSI_EXPORT_FUNC(JsiSkPaint, setMaskFilter), - JSI_EXPORT_FUNC(JsiSkPaint, setBlendMode), - JSI_EXPORT_FUNC(JsiSkPaint, setStrokeMiter), - JSI_EXPORT_FUNC(JsiSkPaint, setStrokeJoin), - JSI_EXPORT_FUNC(JsiSkPaint, setStrokeCap), - JSI_EXPORT_FUNC(JsiSkPaint, setAntiAlias), - JSI_EXPORT_FUNC(JsiSkPaint, setDither), - JSI_EXPORT_FUNC(JsiSkPaint, setStrokeWidth), - JSI_EXPORT_FUNC(JsiSkPaint, setStyle), - JSI_EXPORT_FUNC(JsiSkPaint, setColor), - JSI_EXPORT_FUNC(JsiSkPaint, setAlphaf), - JSI_EXPORT_FUNC(JsiSkPaint, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "assign", &JsiSkPaint::assign); + installHostMethod(runtime, prototype, "copy", &JsiSkPaint::copy); + installHostMethod(runtime, prototype, "reset", &JsiSkPaint::reset); + installHostMethod(runtime, prototype, "getAlphaf", &JsiSkPaint::getAlphaf); + installHostMethod(runtime, prototype, "getColor", &JsiSkPaint::getColor); + installHostMethod(runtime, prototype, "getStrokeCap", + &JsiSkPaint::getStrokeCap); + installHostMethod(runtime, prototype, "getStrokeJoin", + &JsiSkPaint::getStrokeJoin); + installHostMethod(runtime, prototype, "getStrokeMiter", + &JsiSkPaint::getStrokeMiter); + installHostMethod(runtime, prototype, "getStrokeWidth", + &JsiSkPaint::getStrokeWidth); + installHostMethod(runtime, prototype, "setPathEffect", + &JsiSkPaint::setPathEffect); + installHostMethod(runtime, prototype, "setShader", &JsiSkPaint::setShader); + installHostMethod(runtime, prototype, "setColorFilter", + &JsiSkPaint::setColorFilter); + installHostMethod(runtime, prototype, "setImageFilter", + &JsiSkPaint::setImageFilter); + installHostMethod(runtime, prototype, "setMaskFilter", + &JsiSkPaint::setMaskFilter); + installHostMethod(runtime, prototype, "setBlendMode", + &JsiSkPaint::setBlendMode); + installHostMethod(runtime, prototype, "setStrokeMiter", + &JsiSkPaint::setStrokeMiter); + installHostMethod(runtime, prototype, "setStrokeJoin", + &JsiSkPaint::setStrokeJoin); + installHostMethod(runtime, prototype, "setStrokeCap", + &JsiSkPaint::setStrokeCap); + installHostMethod(runtime, prototype, "setAntiAlias", + &JsiSkPaint::setAntiAlias); + installHostMethod(runtime, prototype, "setDither", &JsiSkPaint::setDither); + installHostMethod(runtime, prototype, "setStrokeWidth", + &JsiSkPaint::setStrokeWidth); + installHostMethod(runtime, prototype, "setStyle", &JsiSkPaint::setStyle); + installHostMethod(runtime, prototype, "setColor", &JsiSkPaint::setColor); + installHostMethod(runtime, prototype, "setAlphaf", &JsiSkPaint::setAlphaf); + } JsiSkPaint(std::shared_ptr context, SkPaint paint) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), std::make_shared(std::move(paint))) {} + /** + Returns the underlying object from a host object of this type + */ + static std::shared_ptr fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } + /** Copy from another paint */ @@ -209,12 +232,10 @@ class JsiSkPaint : public JsiSkWrappingSharedPtrHostObject { setObject(std::make_shared(std::move(paint))); } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { return std::max(sizeof(SkPaint), kMinMemoryPressure); } - std::string getObjectType() const override { return "JsiSkPaint"; } - /** * Creates the function for construction a new instance of the SkPaint * wrapper @@ -228,9 +249,8 @@ class JsiSkPaint : public JsiSkWrappingSharedPtrHostObject { auto paint = SkPaint(); paint.setAntiAlias(true); // Return the newly constructed object - auto hostObjectInstance = std::make_shared(context, paint); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, context); + return makeJsiObject(runtime, + std::make_shared(context, paint)); }; } }; diff --git a/packages/skia/cpp/api/JsiSkParagraph.h b/packages/skia/cpp/api/JsiSkParagraph.h index 2657296ac9..fbc6d31841 100644 --- a/packages/skia/cpp/api/JsiSkParagraph.h +++ b/packages/skia/cpp/api/JsiSkParagraph.h @@ -9,7 +9,7 @@ #include "JsiSkCanvas.h" #include "JsiSkFont.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkPath.h" #include "JsiSkRect.h" @@ -31,9 +31,10 @@ namespace para = skia::textlayout; * Implementation of the Paragraph object in JSI */ class JsiSkParagraph - : public JsiSkWrappingSharedPtrHostObject { + : public JsiSkWrappingSharedPtrNativeObject { public: - EXPORT_JSI_API_TYPENAME(JsiSkParagraph, Paragraph) + static constexpr const char *CLASS_NAME = "Paragraph"; JSI_HOST_FUNCTION(layout) { auto width = getArgumentAsNumber(runtime, arguments, count, 0); @@ -42,8 +43,8 @@ class JsiSkParagraph } JSI_HOST_FUNCTION(paint) { - auto jsiCanvas = - getArgumentAsHostObject(runtime, arguments, count, 0); + auto jsiCanvas = getJsiObject( + runtime, getArgument(runtime, arguments, count, 0)); auto x = getArgumentAsNumber(runtime, arguments, count, 1); auto y = getArgumentAsNumber(runtime, arguments, count, 2); getObject()->paint(jsiCanvas->getCanvas(), x, y); @@ -182,10 +183,8 @@ class JsiSkParagraph &rec); }); SkPath path = builder.detach(); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(path)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(path))); } JSI_HOST_FUNCTION(extendedVisit) { @@ -203,10 +202,9 @@ class JsiSkParagraph } auto value = jsi::Object(runtime); - auto fontInstance = std::make_shared(context, info->font); value.setProperty(runtime, "font", - JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, fontInstance, context)); + makeJsiObject(runtime, std::make_shared( + context, info->font))); auto origin = jsi::Object(runtime); origin.setProperty(runtime, "x", @@ -269,29 +267,38 @@ class JsiSkParagraph return returnValue; } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkParagraph, layout), - JSI_EXPORT_FUNC(JsiSkParagraph, paint), - JSI_EXPORT_FUNC(JsiSkParagraph, getMaxWidth), - JSI_EXPORT_FUNC(JsiSkParagraph, getMinIntrinsicWidth), - JSI_EXPORT_FUNC(JsiSkParagraph, getMaxIntrinsicWidth), - JSI_EXPORT_FUNC(JsiSkParagraph, getLongestLine), - JSI_EXPORT_FUNC(JsiSkParagraph, getHeight), - JSI_EXPORT_FUNC(JsiSkParagraph, getRectsForPlaceholders), - JSI_EXPORT_FUNC(JsiSkParagraph, - getGlyphPositionAtCoordinate), - JSI_EXPORT_FUNC(JsiSkParagraph, getRectsForRange), - JSI_EXPORT_FUNC(JsiSkParagraph, getLineMetrics), - JSI_EXPORT_FUNC(JsiSkParagraph, getPath), - JSI_EXPORT_FUNC(JsiSkParagraph, extendedVisit), - JSI_EXPORT_FUNC(JsiSkParagraph, dispose)) - - size_t getMemoryPressure() const override { return 1024 * 1024; } - - std::string getObjectType() const override { return "JsiSkParagraph"; } + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "layout", &JsiSkParagraph::layout); + installHostMethod(runtime, prototype, "paint", &JsiSkParagraph::paint); + installHostMethod(runtime, prototype, "getMaxWidth", + &JsiSkParagraph::getMaxWidth); + installHostMethod(runtime, prototype, "getMinIntrinsicWidth", + &JsiSkParagraph::getMinIntrinsicWidth); + installHostMethod(runtime, prototype, "getMaxIntrinsicWidth", + &JsiSkParagraph::getMaxIntrinsicWidth); + installHostMethod(runtime, prototype, "getLongestLine", + &JsiSkParagraph::getLongestLine); + installHostMethod(runtime, prototype, "getHeight", + &JsiSkParagraph::getHeight); + installHostMethod(runtime, prototype, "getRectsForPlaceholders", + &JsiSkParagraph::getRectsForPlaceholders); + installHostMethod(runtime, prototype, "getGlyphPositionAtCoordinate", + &JsiSkParagraph::getGlyphPositionAtCoordinate); + installHostMethod(runtime, prototype, "getRectsForRange", + &JsiSkParagraph::getRectsForRange); + installHostMethod(runtime, prototype, "getLineMetrics", + &JsiSkParagraph::getLineMetrics); + installHostMethod(runtime, prototype, "getPath", &JsiSkParagraph::getPath); + installHostMethod(runtime, prototype, "extendedVisit", + &JsiSkParagraph::extendedVisit); + } + + size_t getMemoryPressure() override { return 1024 * 1024; } explicit JsiSkParagraph(std::shared_ptr context, para::ParagraphBuilder *paragraphBuilder) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), paragraphBuilder->Build()) {} }; diff --git a/packages/skia/cpp/api/JsiSkParagraphBuilder.h b/packages/skia/cpp/api/JsiSkParagraphBuilder.h index d7e0956b1e..c8a938bf1b 100644 --- a/packages/skia/cpp/api/JsiSkParagraphBuilder.h +++ b/packages/skia/cpp/api/JsiSkParagraphBuilder.h @@ -8,7 +8,7 @@ #include "JsiSkFont.h" #include "JsiSkFontMgr.h" #include "JsiSkFontMgrFactory.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkParagraph.h" #include "JsiSkParagraphStyle.h" #include "JsiSkTextStyle.h" @@ -36,15 +36,13 @@ namespace para = skia::textlayout; /** Implementation of the ParagraphBuilder object in JSI */ -class JsiSkParagraphBuilder : public JsiSkHostObject { +class JsiSkParagraphBuilder : public JsiSkNativeObject { public: - JSI_API_TYPENAME("ParagraphBuilder"); + static constexpr const char *CLASS_NAME = "ParagraphBuilder"; JSI_HOST_FUNCTION(build) { - auto paragraph = - std::make_shared(getContext(), _builder.get()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, paragraph, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), _builder.get())); } JSI_HOST_FUNCTION(reset) { @@ -84,16 +82,16 @@ class JsiSkParagraphBuilder : public JsiSkHostObject { auto textStyle = JsiSkTextStyle::fromValue(runtime, arguments[0]); // Foreground paint if (count >= 2) { - auto foreground = - tryGetArgumentAsHostObject(runtime, arguments, count, 1); + auto foreground = tryGetJsiObject( + runtime, getArgument(runtime, arguments, count, 1)); if (foreground) { textStyle.setForegroundPaint(*foreground->getObject().get()); } } // Background paint if (count >= 3) { - auto background = - tryGetArgumentAsHostObject(runtime, arguments, count, 2); + auto background = tryGetJsiObject( + runtime, getArgument(runtime, arguments, count, 2)); if (background) { textStyle.setBackgroundPaint(*background->getObject().get()); } @@ -109,21 +107,26 @@ class JsiSkParagraphBuilder : public JsiSkHostObject { return thisValue.asObject(runtime); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkParagraphBuilder, build), - JSI_EXPORT_FUNC(JsiSkParagraphBuilder, reset), - JSI_EXPORT_FUNC(JsiSkParagraphBuilder, addText), - JSI_EXPORT_FUNC(JsiSkParagraphBuilder, addPlaceholder), - JSI_EXPORT_FUNC(JsiSkParagraphBuilder, pushStyle), - JSI_EXPORT_FUNC(JsiSkParagraphBuilder, pop)) - - size_t getMemoryPressure() const override { return 1024 * 1024; } + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "build", + &JsiSkParagraphBuilder::build); + installHostMethod(runtime, prototype, "reset", + &JsiSkParagraphBuilder::reset); + installHostMethod(runtime, prototype, "addText", + &JsiSkParagraphBuilder::addText); + installHostMethod(runtime, prototype, "addPlaceholder", + &JsiSkParagraphBuilder::addPlaceholder); + installHostMethod(runtime, prototype, "pushStyle", + &JsiSkParagraphBuilder::pushStyle); + installHostMethod(runtime, prototype, "pop", &JsiSkParagraphBuilder::pop); + } - std::string getObjectType() const override { return "JsiSkParagraphBuilder"; } + size_t getMemoryPressure() override { return 1024 * 1024; } explicit JsiSkParagraphBuilder(std::shared_ptr context, para::ParagraphStyle paragraphStyle, sk_sp fontManager) - : JsiSkHostObject(std::move(context)) { + : JsiSkNativeObject(std::move(context)) { _fontCollection = sk_make_sp(); auto fontMgr = JsiSkFontMgrFactory::getFontMgr(getContext()); _fontCollection->setDefaultFontManager(fontMgr); diff --git a/packages/skia/cpp/api/JsiSkParagraphBuilderFactory.h b/packages/skia/cpp/api/JsiSkParagraphBuilderFactory.h index 5b1e925e87..8ccbbc279a 100644 --- a/packages/skia/cpp/api/JsiSkParagraphBuilderFactory.h +++ b/packages/skia/cpp/api/JsiSkParagraphBuilderFactory.h @@ -5,6 +5,7 @@ #include +#include "JsiSkNativeObjects.h" #include "JsiSkParagraphBuilder.h" #include "JsiSkParagraphStyle.h" @@ -25,8 +26,11 @@ namespace para = skia::textlayout; Implementation of the ParagraphBuilderFactory for making ParagraphBuilder JSI object */ -class JsiSkParagraphBuilderFactory : public JsiSkHostObject { +class JsiSkParagraphBuilderFactory + : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "ParagraphBuilderFactory"; + JSI_HOST_FUNCTION(Make) { // Get paragraph style from params auto paragraphStyle = @@ -39,23 +43,20 @@ class JsiSkParagraphBuilderFactory : public JsiSkHostObject { : nullptr; // Create the paragraph builder - auto builder = std::make_shared( - getContext(), paragraphStyle, fontMgr); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, builder, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), paragraphStyle, fontMgr)); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkParagraphBuilderFactory, Make)) - - size_t getMemoryPressure() const override { return 1024 * 1024; } - - std::string getObjectType() const override { - return "JsiSkParagraphBuilderFactory"; + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "Make", + &JsiSkParagraphBuilderFactory::Make); } + size_t getMemoryPressure() override { return 1024 * 1024; } + explicit JsiSkParagraphBuilderFactory( std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkPath.h b/packages/skia/cpp/api/JsiSkPath.h index 1b0b8d86b1..469c1f59f0 100644 --- a/packages/skia/cpp/api/JsiSkPath.h +++ b/packages/skia/cpp/api/JsiSkPath.h @@ -9,8 +9,8 @@ #include -#include "JsiSkHostObjects.h" #include "JsiSkMatrix.h" +#include "JsiSkNativeObjects.h" #include "JsiSkPoint.h" #include "JsiSkRRect.h" #include "JsiSkRect.h" @@ -61,7 +61,11 @@ inline void warnDeprecatedPathMethod(jsi::Runtime &runtime, RNSkLogger::warnToJavascriptConsole(runtime, message); } -class JsiSkPath : public JsiSkWrappingSharedPtrHostObject { +class JsiSkPath + : public JsiSkWrappingSharedPtrNativeObject { +public: + static constexpr const char *CLASS_NAME = "Path"; + private: static const int MOVE = 0; static const int LINE = 1; @@ -529,16 +533,14 @@ class JsiSkPath : public JsiSkWrappingSharedPtrHostObject { JSI_HOST_FUNCTION(computeTightBounds) { auto path = asPath(); auto result = path.computeTightBounds(); - auto hostObjectInstance = std::make_shared(getContext(), result); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, + std::make_shared(getContext(), result)); } JSI_HOST_FUNCTION(getBounds) { auto result = getObject()->computeBounds(); - auto hostObjectInstance = std::make_shared(getContext(), result); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, + std::make_shared(getContext(), result)); } JSI_HOST_FUNCTION(contains) { @@ -557,9 +559,8 @@ class JsiSkPath : public JsiSkWrappingSharedPtrHostObject { JSI_HOST_FUNCTION(getPoint) { auto index = arguments[0].asNumber(); auto point = asPath().getPoint(index); - auto hostObjectInstance = std::make_shared(getContext(), point); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, + std::make_shared(getContext(), point)); } JSI_HOST_FUNCTION(isEmpty) { return jsi::Value(getObject()->isEmpty()); } @@ -596,9 +597,8 @@ class JsiSkPath : public JsiSkWrappingSharedPtrHostObject { JSI_HOST_FUNCTION(copy) { auto path = asPath(); - auto hostObjectInstance = std::make_shared(getContext(), path); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, + std::make_shared(getContext(), path)); } JSI_HOST_FUNCTION(isInterpolatable) { @@ -618,10 +618,8 @@ class JsiSkPath : public JsiSkWrappingSharedPtrHostObject { if (!succeed) { return jsi::Value::null(); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(result)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(result))); } JSI_HOST_FUNCTION(toCmds) { @@ -703,51 +701,76 @@ class JsiSkPath : public JsiSkWrappingSharedPtrHostObject { return cmds; } - EXPORT_JSI_API_TYPENAME(JsiSkPath, Path) - - JSI_EXPORT_FUNCTIONS( - // Mutable building methods - JSI_EXPORT_FUNC(JsiSkPath, moveTo), JSI_EXPORT_FUNC(JsiSkPath, rMoveTo), - JSI_EXPORT_FUNC(JsiSkPath, lineTo), JSI_EXPORT_FUNC(JsiSkPath, rLineTo), - JSI_EXPORT_FUNC(JsiSkPath, quadTo), JSI_EXPORT_FUNC(JsiSkPath, rQuadTo), - JSI_EXPORT_FUNC(JsiSkPath, conicTo), JSI_EXPORT_FUNC(JsiSkPath, rConicTo), - JSI_EXPORT_FUNC(JsiSkPath, cubicTo), JSI_EXPORT_FUNC(JsiSkPath, rCubicTo), - JSI_EXPORT_FUNC(JsiSkPath, close), JSI_EXPORT_FUNC(JsiSkPath, reset), - JSI_EXPORT_FUNC(JsiSkPath, rewind), JSI_EXPORT_FUNC(JsiSkPath, addPath), - JSI_EXPORT_FUNC(JsiSkPath, addArc), JSI_EXPORT_FUNC(JsiSkPath, addOval), - JSI_EXPORT_FUNC(JsiSkPath, addRect), JSI_EXPORT_FUNC(JsiSkPath, addRRect), - JSI_EXPORT_FUNC(JsiSkPath, addCircle), - JSI_EXPORT_FUNC(JsiSkPath, addPoly), - JSI_EXPORT_FUNC(JsiSkPath, arcToOval), - JSI_EXPORT_FUNC(JsiSkPath, arcToRotated), - JSI_EXPORT_FUNC(JsiSkPath, rArcTo), - JSI_EXPORT_FUNC(JsiSkPath, arcToTangent), - JSI_EXPORT_FUNC(JsiSkPath, setFillType), - JSI_EXPORT_FUNC(JsiSkPath, setIsVolatile), - // Mutable transform methods - JSI_EXPORT_FUNC(JsiSkPath, transform), JSI_EXPORT_FUNC(JsiSkPath, offset), - // Mutable path operations - JSI_EXPORT_FUNC(JsiSkPath, simplify), JSI_EXPORT_FUNC(JsiSkPath, op), - JSI_EXPORT_FUNC(JsiSkPath, makeAsWinding), - JSI_EXPORT_FUNC(JsiSkPath, dash), JSI_EXPORT_FUNC(JsiSkPath, stroke), - JSI_EXPORT_FUNC(JsiSkPath, trim), - // Query methods - JSI_EXPORT_FUNC(JsiSkPath, computeTightBounds), - JSI_EXPORT_FUNC(JsiSkPath, getBounds), - JSI_EXPORT_FUNC(JsiSkPath, contains), - JSI_EXPORT_FUNC(JsiSkPath, getFillType), - JSI_EXPORT_FUNC(JsiSkPath, isVolatile), - JSI_EXPORT_FUNC(JsiSkPath, getPoint), JSI_EXPORT_FUNC(JsiSkPath, isEmpty), - JSI_EXPORT_FUNC(JsiSkPath, countPoints), - JSI_EXPORT_FUNC(JsiSkPath, getLastPt), - JSI_EXPORT_FUNC(JsiSkPath, toSVGString), - JSI_EXPORT_FUNC(JsiSkPath, equals), JSI_EXPORT_FUNC(JsiSkPath, copy), - JSI_EXPORT_FUNC(JsiSkPath, isInterpolatable), - JSI_EXPORT_FUNC(JsiSkPath, interpolate), - JSI_EXPORT_FUNC(JsiSkPath, toCmds), JSI_EXPORT_FUNC(JsiSkPath, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + // Mutable building methods + installHostMethod(runtime, prototype, "moveTo", &JsiSkPath::moveTo); + installHostMethod(runtime, prototype, "rMoveTo", &JsiSkPath::rMoveTo); + installHostMethod(runtime, prototype, "lineTo", &JsiSkPath::lineTo); + installHostMethod(runtime, prototype, "rLineTo", &JsiSkPath::rLineTo); + installHostMethod(runtime, prototype, "quadTo", &JsiSkPath::quadTo); + installHostMethod(runtime, prototype, "rQuadTo", &JsiSkPath::rQuadTo); + installHostMethod(runtime, prototype, "conicTo", &JsiSkPath::conicTo); + installHostMethod(runtime, prototype, "rConicTo", &JsiSkPath::rConicTo); + installHostMethod(runtime, prototype, "cubicTo", &JsiSkPath::cubicTo); + installHostMethod(runtime, prototype, "rCubicTo", &JsiSkPath::rCubicTo); + installHostMethod(runtime, prototype, "close", &JsiSkPath::close); + installHostMethod(runtime, prototype, "reset", &JsiSkPath::reset); + installHostMethod(runtime, prototype, "rewind", &JsiSkPath::rewind); + installHostMethod(runtime, prototype, "addPath", &JsiSkPath::addPath); + installHostMethod(runtime, prototype, "addArc", &JsiSkPath::addArc); + installHostMethod(runtime, prototype, "addOval", &JsiSkPath::addOval); + installHostMethod(runtime, prototype, "addRect", &JsiSkPath::addRect); + installHostMethod(runtime, prototype, "addRRect", &JsiSkPath::addRRect); + installHostMethod(runtime, prototype, "addCircle", &JsiSkPath::addCircle); + installHostMethod(runtime, prototype, "addPoly", &JsiSkPath::addPoly); + installHostMethod(runtime, prototype, "arcToOval", &JsiSkPath::arcToOval); + installHostMethod(runtime, prototype, "arcToRotated", + &JsiSkPath::arcToRotated); + installHostMethod(runtime, prototype, "rArcTo", &JsiSkPath::rArcTo); + installHostMethod(runtime, prototype, "arcToTangent", + &JsiSkPath::arcToTangent); + installHostMethod(runtime, prototype, "setFillType", + &JsiSkPath::setFillType); + installHostMethod(runtime, prototype, "setIsVolatile", + &JsiSkPath::setIsVolatile); + // Mutable transform methods + installHostMethod(runtime, prototype, "transform", &JsiSkPath::transform); + installHostMethod(runtime, prototype, "offset", &JsiSkPath::offset); + // Mutable path operations + installHostMethod(runtime, prototype, "simplify", &JsiSkPath::simplify); + installHostMethod(runtime, prototype, "op", &JsiSkPath::op); + installHostMethod(runtime, prototype, "makeAsWinding", + &JsiSkPath::makeAsWinding); + installHostMethod(runtime, prototype, "dash", &JsiSkPath::dash); + installHostMethod(runtime, prototype, "stroke", &JsiSkPath::stroke); + installHostMethod(runtime, prototype, "trim", &JsiSkPath::trim); + // Query methods + installHostMethod(runtime, prototype, "computeTightBounds", + &JsiSkPath::computeTightBounds); + installHostMethod(runtime, prototype, "getBounds", &JsiSkPath::getBounds); + installHostMethod(runtime, prototype, "contains", &JsiSkPath::contains); + installHostMethod(runtime, prototype, "getFillType", + &JsiSkPath::getFillType); + installHostMethod(runtime, prototype, "isVolatile", &JsiSkPath::isVolatile); + installHostMethod(runtime, prototype, "getPoint", &JsiSkPath::getPoint); + installHostMethod(runtime, prototype, "isEmpty", &JsiSkPath::isEmpty); + installHostMethod(runtime, prototype, "countPoints", + &JsiSkPath::countPoints); + installHostMethod(runtime, prototype, "getLastPt", &JsiSkPath::getLastPt); + installHostMethod(runtime, prototype, "toSVGString", + &JsiSkPath::toSVGString); + installHostMethod(runtime, prototype, "equals", &JsiSkPath::equals); + installHostMethod(runtime, prototype, "copy", &JsiSkPath::copy); + installHostMethod(runtime, prototype, "isInterpolatable", + &JsiSkPath::isInterpolatable); + installHostMethod(runtime, prototype, "interpolate", + &JsiSkPath::interpolate); + installHostMethod(runtime, prototype, "toCmds", &JsiSkPath::toCmds); + } JsiSkPath(std::shared_ptr context, SkPathBuilder builder) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), std::make_shared(std::move(builder))) {} @@ -755,7 +778,7 @@ class JsiSkPath : public JsiSkWrappingSharedPtrHostObject { JsiSkPath(std::shared_ptr context, const SkPath &path) : JsiSkPath(std::move(context), SkPathBuilder(path)) {} - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { auto builder = getObject(); if (!builder) return 0; @@ -763,7 +786,13 @@ class JsiSkPath : public JsiSkWrappingSharedPtrHostObject { return builder->snapshot().approximateBytesUsed(); } - std::string getObjectType() const override { return "JsiSkPath"; } + /** + Returns the underlying object from a host object of this type + */ + static std::shared_ptr fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } static SkPath pathFromValue(jsi::Runtime &runtime, const jsi::Value &obj) { return fromValue(runtime, obj)->snapshot(); @@ -772,18 +801,14 @@ class JsiSkPath : public JsiSkWrappingSharedPtrHostObject { static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, const SkPath &path) { - auto hostObjectInstance = std::make_shared(context, path); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, context); + return makeJsiObject(runtime, std::make_shared(context, path)); } static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, SkPath &&path) { - auto hostObjectInstance = - std::make_shared(context, std::move(path)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, context); + return makeJsiObject(runtime, + std::make_shared(context, std::move(path))); } }; diff --git a/packages/skia/cpp/api/JsiSkPathBuilder.h b/packages/skia/cpp/api/JsiSkPathBuilder.h index 5bafc202e6..2999501005 100644 --- a/packages/skia/cpp/api/JsiSkPathBuilder.h +++ b/packages/skia/cpp/api/JsiSkPathBuilder.h @@ -6,8 +6,8 @@ #include -#include "JsiSkHostObjects.h" #include "JsiSkMatrix.h" +#include "JsiSkNativeObjects.h" #include "JsiSkPath.h" #include "JsiSkPoint.h" #include "JsiSkRRect.h" @@ -27,8 +27,11 @@ namespace RNSkia { namespace jsi = facebook::jsi; class JsiSkPathBuilder - : public JsiSkWrappingSharedPtrHostObject { + : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "PathBuilder"; + // Movement methods JSI_HOST_FUNCTION(moveTo) { SkScalar x = arguments[0].asNumber(); @@ -299,9 +302,8 @@ class JsiSkPathBuilder JSI_HOST_FUNCTION(computeBounds) { auto path = getObject()->snapshot(); auto result = path.getBounds(); - auto hostObjectInstance = std::make_shared(getContext(), result); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, + std::make_shared(getContext(), result)); } JSI_HOST_FUNCTION(isEmpty) { @@ -326,73 +328,91 @@ class JsiSkPathBuilder JSI_HOST_FUNCTION(build) { // snapshot() returns a copy without resetting the builder auto path = getObject()->snapshot(); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(path)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(path))); } JSI_HOST_FUNCTION(detach) { // detach() returns the path and resets the builder auto path = getObject()->detach(); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(path)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); - } - - EXPORT_JSI_API_TYPENAME(JsiSkPathBuilder, PathBuilder) - - JSI_EXPORT_FUNCTIONS( - // Movement - JSI_EXPORT_FUNC(JsiSkPathBuilder, moveTo), - JSI_EXPORT_FUNC(JsiSkPathBuilder, rMoveTo), - JSI_EXPORT_FUNC(JsiSkPathBuilder, lineTo), - JSI_EXPORT_FUNC(JsiSkPathBuilder, rLineTo), - // Curves - JSI_EXPORT_FUNC(JsiSkPathBuilder, quadTo), - JSI_EXPORT_FUNC(JsiSkPathBuilder, rQuadTo), - JSI_EXPORT_FUNC(JsiSkPathBuilder, conicTo), - JSI_EXPORT_FUNC(JsiSkPathBuilder, rConicTo), - JSI_EXPORT_FUNC(JsiSkPathBuilder, cubicTo), - JSI_EXPORT_FUNC(JsiSkPathBuilder, rCubicTo), - JSI_EXPORT_FUNC(JsiSkPathBuilder, close), - // Arcs - JSI_EXPORT_FUNC(JsiSkPathBuilder, arcToOval), - JSI_EXPORT_FUNC(JsiSkPathBuilder, arcToRotated), - JSI_EXPORT_FUNC(JsiSkPathBuilder, rArcTo), - JSI_EXPORT_FUNC(JsiSkPathBuilder, arcToTangent), - // Shapes - JSI_EXPORT_FUNC(JsiSkPathBuilder, addRect), - JSI_EXPORT_FUNC(JsiSkPathBuilder, addOval), - JSI_EXPORT_FUNC(JsiSkPathBuilder, addArc), - JSI_EXPORT_FUNC(JsiSkPathBuilder, addRRect), - JSI_EXPORT_FUNC(JsiSkPathBuilder, addCircle), - JSI_EXPORT_FUNC(JsiSkPathBuilder, addPoly), - JSI_EXPORT_FUNC(JsiSkPathBuilder, addPath), - // Config - JSI_EXPORT_FUNC(JsiSkPathBuilder, setFillType), - JSI_EXPORT_FUNC(JsiSkPathBuilder, setIsVolatile), - JSI_EXPORT_FUNC(JsiSkPathBuilder, reset), - JSI_EXPORT_FUNC(JsiSkPathBuilder, offset), - JSI_EXPORT_FUNC(JsiSkPathBuilder, transform), - // Query - JSI_EXPORT_FUNC(JsiSkPathBuilder, computeBounds), - JSI_EXPORT_FUNC(JsiSkPathBuilder, isEmpty), - JSI_EXPORT_FUNC(JsiSkPathBuilder, getLastPt), - JSI_EXPORT_FUNC(JsiSkPathBuilder, countPoints), - // Build - JSI_EXPORT_FUNC(JsiSkPathBuilder, build), - JSI_EXPORT_FUNC(JsiSkPathBuilder, detach), - JSI_EXPORT_FUNC(JsiSkPathBuilder, dispose)) + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(path))); + } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + // Movement + installHostMethod(runtime, prototype, "moveTo", &JsiSkPathBuilder::moveTo); + installHostMethod(runtime, prototype, "rMoveTo", + &JsiSkPathBuilder::rMoveTo); + installHostMethod(runtime, prototype, "lineTo", &JsiSkPathBuilder::lineTo); + installHostMethod(runtime, prototype, "rLineTo", + &JsiSkPathBuilder::rLineTo); + // Curves + installHostMethod(runtime, prototype, "quadTo", &JsiSkPathBuilder::quadTo); + installHostMethod(runtime, prototype, "rQuadTo", + &JsiSkPathBuilder::rQuadTo); + installHostMethod(runtime, prototype, "conicTo", + &JsiSkPathBuilder::conicTo); + installHostMethod(runtime, prototype, "rConicTo", + &JsiSkPathBuilder::rConicTo); + installHostMethod(runtime, prototype, "cubicTo", + &JsiSkPathBuilder::cubicTo); + installHostMethod(runtime, prototype, "rCubicTo", + &JsiSkPathBuilder::rCubicTo); + installHostMethod(runtime, prototype, "close", &JsiSkPathBuilder::close); + // Arcs + installHostMethod(runtime, prototype, "arcToOval", + &JsiSkPathBuilder::arcToOval); + installHostMethod(runtime, prototype, "arcToRotated", + &JsiSkPathBuilder::arcToRotated); + installHostMethod(runtime, prototype, "rArcTo", &JsiSkPathBuilder::rArcTo); + installHostMethod(runtime, prototype, "arcToTangent", + &JsiSkPathBuilder::arcToTangent); + // Shapes + installHostMethod(runtime, prototype, "addRect", + &JsiSkPathBuilder::addRect); + installHostMethod(runtime, prototype, "addOval", + &JsiSkPathBuilder::addOval); + installHostMethod(runtime, prototype, "addArc", &JsiSkPathBuilder::addArc); + installHostMethod(runtime, prototype, "addRRect", + &JsiSkPathBuilder::addRRect); + installHostMethod(runtime, prototype, "addCircle", + &JsiSkPathBuilder::addCircle); + installHostMethod(runtime, prototype, "addPoly", + &JsiSkPathBuilder::addPoly); + installHostMethod(runtime, prototype, "addPath", + &JsiSkPathBuilder::addPath); + // Config + installHostMethod(runtime, prototype, "setFillType", + &JsiSkPathBuilder::setFillType); + installHostMethod(runtime, prototype, "setIsVolatile", + &JsiSkPathBuilder::setIsVolatile); + installHostMethod(runtime, prototype, "reset", &JsiSkPathBuilder::reset); + installHostMethod(runtime, prototype, "offset", &JsiSkPathBuilder::offset); + installHostMethod(runtime, prototype, "transform", + &JsiSkPathBuilder::transform); + // Query + installHostMethod(runtime, prototype, "computeBounds", + &JsiSkPathBuilder::computeBounds); + installHostMethod(runtime, prototype, "isEmpty", + &JsiSkPathBuilder::isEmpty); + installHostMethod(runtime, prototype, "getLastPt", + &JsiSkPathBuilder::getLastPt); + installHostMethod(runtime, prototype, "countPoints", + &JsiSkPathBuilder::countPoints); + // Build + installHostMethod(runtime, prototype, "build", &JsiSkPathBuilder::build); + installHostMethod(runtime, prototype, "detach", &JsiSkPathBuilder::detach); + } JsiSkPathBuilder(std::shared_ptr context, SkPathBuilder builder) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), std::make_shared(std::move(builder))) {} - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { auto builder = getObject(); if (!builder) return 0; @@ -400,15 +420,11 @@ class JsiSkPathBuilder return builder->snapshot().approximateBytesUsed(); } - std::string getObjectType() const override { return "JsiSkPathBuilder"; } - static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, const SkPathBuilder &builder) { - auto hostObjectInstance = - std::make_shared(context, builder); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, context); + return makeJsiObject(runtime, + std::make_shared(context, builder)); } }; diff --git a/packages/skia/cpp/api/JsiSkPathBuilderFactory.h b/packages/skia/cpp/api/JsiSkPathBuilderFactory.h index 6fef36cf16..acb21b4ec5 100644 --- a/packages/skia/cpp/api/JsiSkPathBuilderFactory.h +++ b/packages/skia/cpp/api/JsiSkPathBuilderFactory.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkPathBuilder.h" #pragma clang diagnostic push @@ -20,34 +20,33 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkPathBuilderFactory : public JsiSkHostObject { +class JsiSkPathBuilderFactory + : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "PathBuilderFactory"; + JSI_HOST_FUNCTION(Make) { - auto hostObjectInstance = - std::make_shared(getContext(), SkPathBuilder()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), SkPathBuilder())); } JSI_HOST_FUNCTION(MakeFromPath) { auto path = JsiSkPath::fromValue(runtime, arguments[0]); - auto hostObjectInstance = - std::make_shared(getContext(), SkPathBuilder(*path)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), SkPathBuilder(*path))); } - size_t getMemoryPressure() const override { return 1024; } + size_t getMemoryPressure() override { return 1024; } - std::string getObjectType() const override { - return "JsiSkPathBuilderFactory"; + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "Make", + &JsiSkPathBuilderFactory::Make); + installHostMethod(runtime, prototype, "MakeFromPath", + &JsiSkPathBuilderFactory::MakeFromPath); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkPathBuilderFactory, Make), - JSI_EXPORT_FUNC(JsiSkPathBuilderFactory, MakeFromPath)) - explicit JsiSkPathBuilderFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkPathEffect.h b/packages/skia/cpp/api/JsiSkPathEffect.h index d303f033c1..6372479b15 100644 --- a/packages/skia/cpp/api/JsiSkPathEffect.h +++ b/packages/skia/cpp/api/JsiSkPathEffect.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -18,19 +18,29 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkPathEffect : public JsiSkWrappingSkPtrHostObject { +class JsiSkPathEffect + : public JsiSkWrappingSkPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "PathEffect"; + JsiSkPathEffect(std::shared_ptr context, sk_sp pathEffect) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(pathEffect)) {} - - size_t getMemoryPressure() const override { return 2048; } - - std::string getObjectType() const override { return "JsiSkPathEffect"; } - - EXPORT_JSI_API_TYPENAME(JsiSkPathEffect, PathEffect) - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkPathEffect, dispose)) + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(pathEffect)) {} + + size_t getMemoryPressure() override { return 2048; } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + } + + /** + Returns the underlying object from a host object of this type + */ + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkPathEffectFactory.h b/packages/skia/cpp/api/JsiSkPathEffectFactory.h index 5bd93a6c4b..4ffa4d598d 100644 --- a/packages/skia/cpp/api/JsiSkPathEffectFactory.h +++ b/packages/skia/cpp/api/JsiSkPathEffectFactory.h @@ -6,7 +6,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkPathEffect.h" #pragma clang diagnostic push @@ -25,14 +25,16 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkPathEffectFactory : public JsiSkHostObject { +class JsiSkPathEffectFactory + : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "PathEffectFactory"; + JSI_HOST_FUNCTION(MakeCorner) { int radius = arguments[0].asNumber(); auto pathEffect = std::make_shared( getContext(), SkCornerPathEffect::Make(radius)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, pathEffect, - getContext()); + return makeJsiObject(runtime, std::move(pathEffect)); } JSI_HOST_FUNCTION(MakeDash) { @@ -51,8 +53,7 @@ class JsiSkPathEffectFactory : public JsiSkHostObject { auto i = SkSpan(intervals.data(), intervals.size()); auto pathEffect = std::make_shared( getContext(), SkDashPathEffect::Make(i, phase)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, pathEffect, - getContext()); + return makeJsiObject(runtime, std::move(pathEffect)); } JSI_HOST_FUNCTION(MakeDiscrete) { @@ -61,8 +62,7 @@ class JsiSkPathEffectFactory : public JsiSkHostObject { int seedAssist = arguments[2].asNumber(); auto pathEffect = std::make_shared( getContext(), SkDiscretePathEffect::Make(segLength, dec, seedAssist)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, pathEffect, - getContext()); + return makeJsiObject(runtime, std::move(pathEffect)); } JSI_HOST_FUNCTION(MakeCompose) { @@ -71,8 +71,7 @@ class JsiSkPathEffectFactory : public JsiSkHostObject { auto pathEffect = std::make_shared( getContext(), SkPathEffect::MakeCompose(std::move(outer), std::move(inner))); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, pathEffect, - getContext()); + return makeJsiObject(runtime, std::move(pathEffect)); } JSI_HOST_FUNCTION(MakeSum) { @@ -81,8 +80,7 @@ class JsiSkPathEffectFactory : public JsiSkHostObject { auto pathEffect = std::make_shared( getContext(), SkPathEffect::MakeSum(std::move(outer), std::move(inner))); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, pathEffect, - getContext()); + return makeJsiObject(runtime, std::move(pathEffect)); } JSI_HOST_FUNCTION(MakePath1D) { @@ -94,8 +92,7 @@ class JsiSkPathEffectFactory : public JsiSkHostObject { auto pathEffect = std::make_shared( getContext(), SkPath1DPathEffect::Make(path->snapshot(), advance, phase, style)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, pathEffect, - getContext()); + return makeJsiObject(runtime, std::move(pathEffect)); } JSI_HOST_FUNCTION(MakePath2D) { @@ -103,8 +100,7 @@ class JsiSkPathEffectFactory : public JsiSkHostObject { auto path = JsiSkPath::fromValue(runtime, arguments[1]); auto pathEffect = std::make_shared( getContext(), SkPath2DPathEffect::Make(*matrix, path->snapshot())); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, pathEffect, - getContext()); + return makeJsiObject(runtime, std::move(pathEffect)); } JSI_HOST_FUNCTION(MakeLine2D) { @@ -112,27 +108,32 @@ class JsiSkPathEffectFactory : public JsiSkHostObject { auto matrix = JsiSkMatrix::fromValue(runtime, arguments[1]); auto pathEffect = std::make_shared( getContext(), SkLine2DPathEffect::Make(width, *matrix)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, pathEffect, - getContext()); + return makeJsiObject(runtime, std::move(pathEffect)); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkPathEffectFactory, MakeCorner), - JSI_EXPORT_FUNC(JsiSkPathEffectFactory, MakeDash), - JSI_EXPORT_FUNC(JsiSkPathEffectFactory, MakeDiscrete), - JSI_EXPORT_FUNC(JsiSkPathEffectFactory, MakeCompose), - JSI_EXPORT_FUNC(JsiSkPathEffectFactory, MakeSum), - JSI_EXPORT_FUNC(JsiSkPathEffectFactory, MakeLine2D), - JSI_EXPORT_FUNC(JsiSkPathEffectFactory, MakePath1D), - JSI_EXPORT_FUNC(JsiSkPathEffectFactory, MakePath2D)) - - size_t getMemoryPressure() const override { return 1024; } - - std::string getObjectType() const override { - return "JsiSkPathEffectFactory"; + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "MakeCorner", + &JsiSkPathEffectFactory::MakeCorner); + installHostMethod(runtime, prototype, "MakeDash", + &JsiSkPathEffectFactory::MakeDash); + installHostMethod(runtime, prototype, "MakeDiscrete", + &JsiSkPathEffectFactory::MakeDiscrete); + installHostMethod(runtime, prototype, "MakeCompose", + &JsiSkPathEffectFactory::MakeCompose); + installHostMethod(runtime, prototype, "MakeSum", + &JsiSkPathEffectFactory::MakeSum); + installHostMethod(runtime, prototype, "MakeLine2D", + &JsiSkPathEffectFactory::MakeLine2D); + installHostMethod(runtime, prototype, "MakePath1D", + &JsiSkPathEffectFactory::MakePath1D); + installHostMethod(runtime, prototype, "MakePath2D", + &JsiSkPathEffectFactory::MakePath2D); } + size_t getMemoryPressure() override { return 1024; } + explicit JsiSkPathEffectFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkPathFactory.h b/packages/skia/cpp/api/JsiSkPathFactory.h index ec639d9186..519caae739 100644 --- a/packages/skia/cpp/api/JsiSkPathFactory.h +++ b/packages/skia/cpp/api/JsiSkPathFactory.h @@ -7,8 +7,8 @@ #include -#include "JsiSkHostObjects.h" #include "JsiSkMatrix.h" +#include "JsiSkNativeObjects.h" #include "JsiSkPathEffect.h" #include "JsiSkPoint.h" #include "JsiSkRRect.h" @@ -17,7 +17,6 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" -#include "utils/RNSkLog.h" #include "include/core/SkPath.h" #include "include/core/SkPathBuilder.h" #include "include/core/SkPathUtils.h" @@ -26,6 +25,7 @@ #include "include/effects/SkTrimPathEffect.h" #include "include/pathops/SkPathOps.h" #include "include/utils/SkTextUtils.h" +#include "utils/RNSkLog.h" #pragma clang diagnostic pop @@ -33,7 +33,7 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkPathFactory : public JsiSkHostObject { +class JsiSkPathFactory : public JsiSkNativeObject { static const int MOVE = 0; static const int LINE = 1; @@ -43,11 +43,11 @@ class JsiSkPathFactory : public JsiSkHostObject { static const int CLOSE = 5; public: + static constexpr const char *CLASS_NAME = "PathFactory"; + JSI_HOST_FUNCTION(Make) { - auto hostObjectInstance = - std::make_shared(getContext(), SkPath()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, + std::make_shared(getContext(), SkPath())); } JSI_HOST_FUNCTION(MakeFromSVGString) { @@ -57,10 +57,8 @@ class JsiSkPathFactory : public JsiSkHostObject { throw jsi::JSError(runtime, "Could not parse Svg path"); return jsi::Value(nullptr); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(result.value())); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(result.value()))); } JSI_HOST_FUNCTION(MakeFromOp) { @@ -71,10 +69,8 @@ class JsiSkPathFactory : public JsiSkHostObject { if (!result.has_value()) { return jsi::Value(nullptr); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(result.value())); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(result.value()))); } JSI_HOST_FUNCTION(MakeFromCmds) { @@ -159,10 +155,8 @@ class JsiSkPathFactory : public JsiSkHostObject { } } } - auto hostObjectInstance = - std::make_shared(getContext(), builder.snapshot()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), builder.snapshot())); } JSI_HOST_FUNCTION(MakeFromText) { @@ -173,10 +167,8 @@ class JsiSkPathFactory : public JsiSkHostObject { SkPath path; SkTextUtils::GetPath(text.c_str(), strlen(text.c_str()), SkTextEncoding::kUTF8, x, y, *font, &path); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(path)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(path))); } // Static shape factories @@ -188,10 +180,8 @@ class JsiSkPathFactory : public JsiSkHostObject { } SkPathBuilder builder; builder.addRect(*rect, direction); - auto hostObjectInstance = - std::make_shared(getContext(), builder.snapshot()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), builder.snapshot())); } JSI_HOST_FUNCTION(Oval) { @@ -203,10 +193,8 @@ class JsiSkPathFactory : public JsiSkHostObject { unsigned startIndex = count < 3 ? 0 : arguments[2].asNumber(); SkPathBuilder builder; builder.addOval(*rect, direction, startIndex); - auto hostObjectInstance = - std::make_shared(getContext(), builder.snapshot()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), builder.snapshot())); } JSI_HOST_FUNCTION(Circle) { @@ -215,10 +203,8 @@ class JsiSkPathFactory : public JsiSkHostObject { auto r = arguments[2].asNumber(); SkPathBuilder builder; builder.addCircle(x, y, r); - auto hostObjectInstance = - std::make_shared(getContext(), builder.snapshot()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), builder.snapshot())); } JSI_HOST_FUNCTION(RRect) { @@ -229,10 +215,8 @@ class JsiSkPathFactory : public JsiSkHostObject { } SkPathBuilder builder; builder.addRRect(*rrect, direction); - auto hostObjectInstance = - std::make_shared(getContext(), builder.snapshot()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), builder.snapshot())); } JSI_HOST_FUNCTION(Line) { @@ -241,10 +225,8 @@ class JsiSkPathFactory : public JsiSkHostObject { SkPathBuilder builder; builder.moveTo(*p1); builder.lineTo(*p2); - auto hostObjectInstance = - std::make_shared(getContext(), builder.snapshot()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), builder.snapshot())); } JSI_HOST_FUNCTION(Polygon) { @@ -260,10 +242,8 @@ class JsiSkPathFactory : public JsiSkHostObject { } SkPathBuilder builder; builder.addPolygon(SkSpan(points), close); - auto hostObjectInstance = - std::make_shared(getContext(), builder.snapshot()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), builder.snapshot())); } // Static path operations @@ -307,19 +287,17 @@ class JsiSkPathFactory : public JsiSkHostObject { auto success = skpathutils::FillPathWithPaint(path, p, &resultBuilder, nullptr, ctm); if (success) { - auto hostObjectInstance = - std::make_shared(getContext(), resultBuilder.snapshot()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), + resultBuilder.snapshot())); } } else { SkPathBuilder resultBuilder; auto success = skpathutils::FillPathWithPaint(path, p, &resultBuilder); if (success) { - auto hostObjectInstance = - std::make_shared(getContext(), resultBuilder.snapshot()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), + resultBuilder.snapshot())); } } return jsi::Value::null(); @@ -335,10 +313,8 @@ class JsiSkPathFactory : public JsiSkHostObject { // If requesting the full path in normal mode, just return a copy if (start <= 0 && end >= 1 && !isComplement) { SkPath result = srcPath->snapshot(); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(result)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(result))); } SkPath path = srcPath->snapshot(); auto mode = isComplement ? SkTrimPathEffect::Mode::kInverted @@ -351,10 +327,8 @@ class JsiSkPathFactory : public JsiSkHostObject { SkPathBuilder resultBuilder; if (pe->filterPath(&resultBuilder, path, &rec)) { auto result = resultBuilder.detach(); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(result)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(result))); } return jsi::Value::null(); } @@ -363,10 +337,9 @@ class JsiSkPathFactory : public JsiSkHostObject { auto srcPath = JsiSkPath::fromValue(runtime, arguments[0]); auto result = ::Simplify(srcPath->snapshot()); if (result.has_value()) { - auto hostObjectInstance = - std::make_shared(getContext(), std::move(result.value())); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, + std::make_shared(getContext(), std::move(result.value()))); } return jsi::Value::null(); } @@ -386,10 +359,8 @@ class JsiSkPathFactory : public JsiSkHostObject { SkPathBuilder resultBuilder; if (pe->filterPath(&resultBuilder, srcPath->snapshot(), &rec)) { auto result = resultBuilder.detach(); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(result)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(result))); } return jsi::Value::null(); } @@ -398,10 +369,9 @@ class JsiSkPathFactory : public JsiSkHostObject { auto srcPath = JsiSkPath::fromValue(runtime, arguments[0]); auto result = ::AsWinding(srcPath->snapshot()); if (result.has_value()) { - auto hostObjectInstance = - std::make_shared(getContext(), std::move(result.value())); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, + std::make_shared(getContext(), std::move(result.value()))); } return jsi::Value::null(); } @@ -417,38 +387,44 @@ class JsiSkPathFactory : public JsiSkHostObject { if (!succeed) { return jsi::Value::null(); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(result)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(result))); } - size_t getMemoryPressure() const override { return 1024; } - - std::string getObjectType() const override { return "JsiSkPathFactory"; } - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkPathFactory, Make), - JSI_EXPORT_FUNC(JsiSkPathFactory, MakeFromSVGString), - JSI_EXPORT_FUNC(JsiSkPathFactory, MakeFromOp), - JSI_EXPORT_FUNC(JsiSkPathFactory, MakeFromCmds), - JSI_EXPORT_FUNC(JsiSkPathFactory, MakeFromText), - // Static shape factories - JSI_EXPORT_FUNC(JsiSkPathFactory, Rect), - JSI_EXPORT_FUNC(JsiSkPathFactory, Oval), - JSI_EXPORT_FUNC(JsiSkPathFactory, Circle), - JSI_EXPORT_FUNC(JsiSkPathFactory, RRect), - JSI_EXPORT_FUNC(JsiSkPathFactory, Line), - JSI_EXPORT_FUNC(JsiSkPathFactory, Polygon), - // Static path operations - JSI_EXPORT_FUNC(JsiSkPathFactory, Stroke), - JSI_EXPORT_FUNC(JsiSkPathFactory, Trim), - JSI_EXPORT_FUNC(JsiSkPathFactory, Simplify), - JSI_EXPORT_FUNC(JsiSkPathFactory, Dash), - JSI_EXPORT_FUNC(JsiSkPathFactory, AsWinding), - JSI_EXPORT_FUNC(JsiSkPathFactory, Interpolate)) + size_t getMemoryPressure() override { return 1024; } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "Make", &JsiSkPathFactory::Make); + installHostMethod(runtime, prototype, "MakeFromSVGString", + &JsiSkPathFactory::MakeFromSVGString); + installHostMethod(runtime, prototype, "MakeFromOp", + &JsiSkPathFactory::MakeFromOp); + installHostMethod(runtime, prototype, "MakeFromCmds", + &JsiSkPathFactory::MakeFromCmds); + installHostMethod(runtime, prototype, "MakeFromText", + &JsiSkPathFactory::MakeFromText); + // Static shape factories + installHostMethod(runtime, prototype, "Rect", &JsiSkPathFactory::Rect); + installHostMethod(runtime, prototype, "Oval", &JsiSkPathFactory::Oval); + installHostMethod(runtime, prototype, "Circle", &JsiSkPathFactory::Circle); + installHostMethod(runtime, prototype, "RRect", &JsiSkPathFactory::RRect); + installHostMethod(runtime, prototype, "Line", &JsiSkPathFactory::Line); + installHostMethod(runtime, prototype, "Polygon", + &JsiSkPathFactory::Polygon); + // Static path operations + installHostMethod(runtime, prototype, "Stroke", &JsiSkPathFactory::Stroke); + installHostMethod(runtime, prototype, "Trim", &JsiSkPathFactory::Trim); + installHostMethod(runtime, prototype, "Simplify", + &JsiSkPathFactory::Simplify); + installHostMethod(runtime, prototype, "Dash", &JsiSkPathFactory::Dash); + installHostMethod(runtime, prototype, "AsWinding", + &JsiSkPathFactory::AsWinding); + installHostMethod(runtime, prototype, "Interpolate", + &JsiSkPathFactory::Interpolate); + } explicit JsiSkPathFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkPicture.h b/packages/skia/cpp/api/JsiSkPicture.h index b58d412a25..71b2f28c68 100644 --- a/packages/skia/cpp/api/JsiSkPicture.h +++ b/packages/skia/cpp/api/JsiSkPicture.h @@ -4,8 +4,8 @@ #include "JsiSkData.h" #include "JsiSkDispatcher.h" -#include "JsiSkHostObjects.h" #include "JsiSkMatrix.h" +#include "JsiSkNativeObjects.h" #include "JsiSkRect.h" #include "JsiSkShader.h" @@ -20,14 +20,18 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkPicture : public JsiSkWrappingSkPtrHostObject { +class JsiSkPicture + : public JsiSkWrappingSkPtrNativeObject { private: std::shared_ptr _dispatcher; public: + static constexpr const char *CLASS_NAME = "Picture"; + JsiSkPicture(std::shared_ptr context, const sk_sp picture) - : JsiSkWrappingSkPtrHostObject(context, picture) { + : JsiSkWrappingSkPtrNativeObject(context, + picture) { // Get the dispatcher for the current thread _dispatcher = Dispatcher::getDispatcher(); // Process any pending operations @@ -66,9 +70,8 @@ class JsiSkPicture : public JsiSkWrappingSkPtrHostObject { // Create shader auto shader = getObject()->makeShader(tmx, tmy, fm, m, tr); - auto shaderObj = std::make_shared(getContext(), shader); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shaderObj, - getContext()); + return makeJsiObject(runtime, + std::make_shared(getContext(), shader)); } JSI_HOST_FUNCTION(serialize) { @@ -90,13 +93,23 @@ class JsiSkPicture : public JsiSkWrappingSkPtrHostObject { return array; } - EXPORT_JSI_API_TYPENAME(JsiSkPicture, Picture) + /** + Returns the underlying object from a host object of this type + */ + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return getJsiObject(runtime, obj)->getObject(); + } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkPicture, makeShader), - JSI_EXPORT_FUNC(JsiSkPicture, serialize), - JSI_EXPORT_FUNC(JsiSkPicture, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "makeShader", + &JsiSkPicture::makeShader); + installHostMethod(runtime, prototype, "serialize", + &JsiSkPicture::serialize); + } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { if (isDisposed()) { return 0; } @@ -108,7 +121,5 @@ class JsiSkPicture : public JsiSkWrappingSkPtrHostObject { auto bytesUsed = picture->approximateBytesUsed(); return bytesUsed; } - - std::string getObjectType() const override { return "JsiSkPicture"; } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkPictureFactory.h b/packages/skia/cpp/api/JsiSkPictureFactory.h index f23047ab39..e27e671b74 100644 --- a/packages/skia/cpp/api/JsiSkPictureFactory.h +++ b/packages/skia/cpp/api/JsiSkPictureFactory.h @@ -4,7 +4,7 @@ #include "JsiSkColorFilter.h" #include "JsiSkData.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkPicture.h" #pragma clang diagnostic push @@ -19,15 +19,15 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkPictureFactory : public JsiSkHostObject { +class JsiSkPictureFactory : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "PictureFactory"; + JSI_HOST_FUNCTION(MakePicture) { // Handle null case - create JsiSkPicture with nullptr if (arguments[0].isNull() || arguments[0].isUndefined()) { - auto hostObjectInstance = - std::make_shared(getContext(), nullptr); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), nullptr)); } if (!arguments[0].isObject()) { @@ -36,18 +36,14 @@ class JsiSkPictureFactory : public JsiSkHostObject { auto obj = arguments[0].asObject(runtime); // Check if it's a JsiSkData object first - if (obj.isHostObject(runtime)) { - if (auto jsiData = obj.asHostObject(runtime)) { - auto data = jsiData->getObject(); - auto picture = SkPicture::MakeFromData(data.get()); - if (picture != nullptr) { - auto hostObjectInstance = - std::make_shared(getContext(), std::move(picture)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); - } - return jsi::Value::undefined(); + if (auto jsiData = tryGetJsiObject(runtime, obj)) { + auto data = jsiData->getObject(); + auto picture = SkPicture::MakeFromData(data.get()); + if (picture != nullptr) { + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(picture))); } + return jsi::Value::undefined(); } // Get ArrayBuffer - try buffer property first (Uint8Array, etc.), then @@ -64,23 +60,22 @@ class JsiSkPictureFactory : public JsiSkHostObject { SkData::MakeWithCopy(buffer.data(runtime), buffer.size(runtime)); auto picture = SkPicture::MakeFromData(data.get()); if (picture != nullptr) { - auto hostObjectInstance = - std::make_shared(getContext(), std::move(picture)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(picture))); } else { return jsi::Value::undefined(); } } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkPictureFactory, MakePicture)) + size_t getMemoryPressure() override { return 1024; } - size_t getMemoryPressure() const override { return 1024; } - - std::string getObjectType() const override { return "JsiSkPictureFactory"; } + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "MakePicture", + &JsiSkPictureFactory::MakePicture); + } explicit JsiSkPictureFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkPictureRecorder.h b/packages/skia/cpp/api/JsiSkPictureRecorder.h index c950a99405..7e1a5ef136 100644 --- a/packages/skia/cpp/api/JsiSkPictureRecorder.h +++ b/packages/skia/cpp/api/JsiSkPictureRecorder.h @@ -3,7 +3,7 @@ #include #include "JsiSkCanvas.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkPicture.h" #include "JsiSkRect.h" @@ -20,10 +20,14 @@ namespace RNSkia { namespace jsi = facebook::jsi; class JsiSkPictureRecorder - : public JsiSkWrappingSharedPtrHostObject { + : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "PictureRecorder"; + explicit JsiSkPictureRecorder(std::shared_ptr context) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( context, std::make_shared()) {} JSI_HOST_FUNCTION(beginRecording) { @@ -37,36 +41,31 @@ class JsiSkPictureRecorder SkRect rect = SkRect::Make(size); canvas = getObject()->beginRecording(rect, nullptr); } - auto canvasObj = std::make_shared(getContext(), canvas); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, canvasObj, - getContext()); + return makeJsiObject(runtime, + std::make_shared(getContext(), canvas)); } JSI_HOST_FUNCTION(finishRecordingAsPicture) { auto picture = getObject()->finishRecordingAsPicture(); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(picture)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(picture))); } - EXPORT_JSI_API_TYPENAME(JsiSkPictureRecorder, PictureRecorder) - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkPictureRecorder, beginRecording), - JSI_EXPORT_FUNC(JsiSkPictureRecorder, - finishRecordingAsPicture), - JSI_EXPORT_FUNC(JsiSkPictureRecorder, dispose)) - - size_t getMemoryPressure() const override { return 1024 * 1024; } + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "beginRecording", + &JsiSkPictureRecorder::beginRecording); + installHostMethod(runtime, prototype, "finishRecordingAsPicture", + &JsiSkPictureRecorder::finishRecordingAsPicture); + } - std::string getObjectType() const override { return "JsiSkPictureRecorder"; } + size_t getMemoryPressure() override { return 1024 * 1024; } static const jsi::HostFunctionType createCtor(std::shared_ptr context) { return JSI_HOST_FUNCTION_LAMBDA { - auto recorder = std::make_shared(context); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, recorder, - context); + return makeJsiObject(runtime, + std::make_shared(context)); }; } }; diff --git a/packages/skia/cpp/api/JsiSkPoint.h b/packages/skia/cpp/api/JsiSkPoint.h index 32192209b3..5bff76ac59 100644 --- a/packages/skia/cpp/api/JsiSkPoint.h +++ b/packages/skia/cpp/api/JsiSkPoint.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -18,22 +18,23 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkPoint : public JsiSkWrappingSharedPtrHostObject { +class JsiSkPoint + : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "Point"; + JSI_PROPERTY_GET(x) { return static_cast(getObject()->x()); } JSI_PROPERTY_GET(y) { return static_cast(getObject()->y()); } - JSI_API_TYPENAME("Point"); - - JSI_EXPORT_PROPERTY_GETTERS(JSI_EXPORT_PROP_GET(JsiSkPoint, x), - JSI_EXPORT_PROP_GET(JsiSkPoint, y), - JSI_EXPORT_PROP_GET(JsiSkPoint, __typename__)) - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkPoint, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostGetter(runtime, prototype, "x", &JsiSkPoint::get_x); + installHostGetter(runtime, prototype, "y", &JsiSkPoint::get_y); + } JsiSkPoint(std::shared_ptr context, const SkPoint &point) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), std::make_shared(point)) {} /** @@ -42,8 +43,9 @@ class JsiSkPoint : public JsiSkWrappingSharedPtrHostObject { static std::shared_ptr fromValue(jsi::Runtime &runtime, const jsi::Value &obj) { const auto &object = obj.asObject(runtime); - if (object.isHostObject(runtime)) { - return object.asHostObject(runtime)->getObject(); + auto point = tryGetJsiObject(runtime, object); + if (point) { + return point->getObject(); } else { auto x = object.getProperty(runtime, "x").asNumber(); auto y = object.getProperty(runtime, "y").asNumber(); @@ -57,17 +59,14 @@ class JsiSkPoint : public JsiSkWrappingSharedPtrHostObject { static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, const SkPoint &point) { - auto pointObj = std::make_shared(std::move(context), point); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, pointObj, - context); + return makeJsiObject( + runtime, std::make_shared(std::move(context), point)); } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { return std::max(sizeof(SkPoint), kMinMemoryPressure); } - std::string getObjectType() const override { return "JsiSkPoint"; } - /** * Creates the function for construction a new instance of the SkPoint * wrapper @@ -82,10 +81,8 @@ class JsiSkPoint : public JsiSkWrappingSharedPtrHostObject { SkPoint::Make(arguments[0].asNumber(), arguments[1].asNumber()); // Return the newly constructed object - auto pointObj = - std::make_shared(std::move(context), std::move(point)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, pointObj, - context); + return makeJsiObject(runtime, std::make_shared( + std::move(context), std::move(point))); }; } }; diff --git a/packages/skia/cpp/api/JsiSkRRect.h b/packages/skia/cpp/api/JsiSkRRect.h index c1c5c48a9d..9f455966f9 100644 --- a/packages/skia/cpp/api/JsiSkRRect.h +++ b/packages/skia/cpp/api/JsiSkRRect.h @@ -6,7 +6,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -21,8 +21,11 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkRRect : public JsiSkWrappingSharedPtrHostObject { +class JsiSkRRect + : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "RRect"; + JSI_PROPERTY_GET(rx) { return static_cast(getObject()->getSimpleRadii().x()); } @@ -30,23 +33,19 @@ class JsiSkRRect : public JsiSkWrappingSharedPtrHostObject { return static_cast(getObject()->getSimpleRadii().y()); } JSI_PROPERTY_GET(rect) { - auto rectObj = - std::make_shared(getContext(), getObject()->getBounds()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, rectObj, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), getObject()->getBounds())); } - JSI_API_TYPENAME("RRect"); - - JSI_EXPORT_PROPERTY_GETTERS(JSI_EXPORT_PROP_GET(JsiSkRRect, rx), - JSI_EXPORT_PROP_GET(JsiSkRRect, ry), - JSI_EXPORT_PROP_GET(JsiSkRRect, rect), - JSI_EXPORT_PROP_GET(JsiSkRRect, __typename__)) - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkRRect, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostGetter(runtime, prototype, "rx", &JsiSkRRect::get_rx); + installHostGetter(runtime, prototype, "ry", &JsiSkRRect::get_ry); + installHostGetter(runtime, prototype, "rect", &JsiSkRRect::get_rect); + } JsiSkRRect(std::shared_ptr context, const SkRRect &rect) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), std::make_shared(rect)) {} /** @@ -56,10 +55,9 @@ class JsiSkRRect : public JsiSkWrappingSharedPtrHostObject { const jsi::Value &obj) { const auto &object = obj.asObject(runtime); - if (object.isHostObject(runtime)) { - return obj.asObject(runtime) - .asHostObject(runtime) - ->getObject(); + auto rrect = tryGetJsiObject(runtime, object); + if (rrect) { + return rrect->getObject(); } else { auto rect = JsiSkRect::fromValue(runtime, object.getProperty(runtime, "rect")); @@ -101,17 +99,14 @@ class JsiSkRRect : public JsiSkWrappingSharedPtrHostObject { static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, const SkRRect &rect) { - auto rrectObj = std::make_shared(std::move(context), rect); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, rrectObj, - context); + return makeJsiObject( + runtime, std::make_shared(std::move(context), rect)); } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { return std::max(sizeof(SkRRect), kMinMemoryPressure); } - std::string getObjectType() const override { return "JsiSkRRect"; } - /** * Creates the function for construction a new instance of the SkRect * wrapper @@ -128,10 +123,8 @@ class JsiSkRRect : public JsiSkWrappingSharedPtrHostObject { auto ry = arguments[2].asNumber(); auto rrect = SkRRect::MakeRectXY(*rect, rx, ry); // Return the newly constructed object - auto rrectObj = - std::make_shared(std::move(context), std::move(rrect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, rrectObj, - context); + return makeJsiObject(runtime, std::make_shared( + std::move(context), std::move(rrect))); }; } }; diff --git a/packages/skia/cpp/api/JsiSkRSXform.h b/packages/skia/cpp/api/JsiSkRSXform.h index ea2f636c2e..f83f978554 100644 --- a/packages/skia/cpp/api/JsiSkRSXform.h +++ b/packages/skia/cpp/api/JsiSkRSXform.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -18,15 +18,16 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkRSXform : public JsiSkWrappingSharedPtrHostObject { +class JsiSkRSXform + : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "RSXform"; + JsiSkRSXform(std::shared_ptr context, const SkRSXform &rsxform) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), std::make_shared(rsxform)) {} - JSI_API_TYPENAME("RSXform"); - JSI_PROPERTY_GET(scos) { return jsi::Value(SkScalarToDouble(getObject()->fSCos)); } @@ -52,14 +53,14 @@ class JsiSkRSXform : public JsiSkWrappingSharedPtrHostObject { } #pragma clang diagnostic pop - JSI_EXPORT_PROPERTY_GETTERS(JSI_EXPORT_PROP_GET(JsiSkRSXform, __typename__), - JSI_EXPORT_PROP_GET(JsiSkRSXform, scos), - JSI_EXPORT_PROP_GET(JsiSkRSXform, ssin), - JSI_EXPORT_PROP_GET(JsiSkRSXform, tx), - JSI_EXPORT_PROP_GET(JsiSkRSXform, ty)) - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkRSXform, set), - JSI_EXPORT_FUNC(JsiSkRSXform, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostGetter(runtime, prototype, "scos", &JsiSkRSXform::get_scos); + installHostGetter(runtime, prototype, "ssin", &JsiSkRSXform::get_ssin); + installHostGetter(runtime, prototype, "tx", &JsiSkRSXform::get_tx); + installHostGetter(runtime, prototype, "ty", &JsiSkRSXform::get_ty); + installHostMethod(runtime, prototype, "set", &JsiSkRSXform::set); + } /** Returns the underlying object from a host object of this type @@ -67,8 +68,9 @@ class JsiSkRSXform : public JsiSkWrappingSharedPtrHostObject { static std::shared_ptr fromValue(jsi::Runtime &runtime, const jsi::Value &obj) { const auto &object = obj.asObject(runtime); - if (object.isHostObject(runtime)) { - return object.asHostObject(runtime)->getObject(); + auto rsxform = tryGetJsiObject(runtime, object); + if (rsxform) { + return rsxform->getObject(); } else { auto scos = object.getProperty(runtime, "scos").asNumber(); auto ssin = object.getProperty(runtime, "ssin").asNumber(); @@ -84,10 +86,8 @@ class JsiSkRSXform : public JsiSkWrappingSharedPtrHostObject { static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, const SkRSXform &rsxform) { - auto rsxformObj = - std::make_shared(std::move(context), rsxform); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, rsxformObj, - context); + return makeJsiObject( + runtime, std::make_shared(std::move(context), rsxform)); } /** @@ -105,18 +105,15 @@ class JsiSkRSXform : public JsiSkWrappingSharedPtrHostObject { arguments[2].asNumber(), arguments[3].asNumber(), arguments[4].asNumber(), arguments[5].asNumber()); // Return the newly constructed object - auto rsxformObj = std::make_shared(std::move(context), - std::move(rsxform)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, rsxformObj, - context); + return makeJsiObject(runtime, + std::make_shared(std::move(context), + std::move(rsxform))); }; } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { return std::max(sizeof(SkRSXform), kMinMemoryPressure); } - std::string getObjectType() const override { return "JsiSkRSXform"; } - /** * Creates the function for construction a new instance of the SkRSXform * wrapper @@ -131,10 +128,9 @@ class JsiSkRSXform : public JsiSkWrappingSharedPtrHostObject { SkRSXform::Make(arguments[0].asNumber(), arguments[1].asNumber(), arguments[2].asNumber(), arguments[3].asNumber()); // Return the newly constructed object - auto rsxformObj = std::make_shared(std::move(context), - std::move(rsxform)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, rsxformObj, - context); + return makeJsiObject(runtime, + std::make_shared(std::move(context), + std::move(rsxform))); }; } }; diff --git a/packages/skia/cpp/api/JsiSkRect.h b/packages/skia/cpp/api/JsiSkRect.h index 144bb522bb..407c831188 100644 --- a/packages/skia/cpp/api/JsiSkRect.h +++ b/packages/skia/cpp/api/JsiSkRect.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -18,8 +18,10 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkRect : public JsiSkWrappingSharedPtrHostObject { +class JsiSkRect : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "Rect"; + JSI_PROPERTY_GET(x) { return static_cast(getObject()->x()); } JSI_PROPERTY_GET(y) { return static_cast(getObject()->y()); } JSI_PROPERTY_GET(width) { return static_cast(getObject()->width()); } @@ -33,14 +35,6 @@ class JsiSkRect : public JsiSkWrappingSharedPtrHostObject { return static_cast(getObject()->bottom()); } - JSI_API_TYPENAME("Rect"); - - JSI_EXPORT_PROPERTY_GETTERS(JSI_EXPORT_PROP_GET(JsiSkRect, x), - JSI_EXPORT_PROP_GET(JsiSkRect, y), - JSI_EXPORT_PROP_GET(JsiSkRect, width), - JSI_EXPORT_PROP_GET(JsiSkRect, height), - JSI_EXPORT_PROP_GET(JsiSkRect, __typename__)) - JSI_HOST_FUNCTION(setXYWH) { getObject()->setXYWH(arguments[0].asNumber(), arguments[1].asNumber(), arguments[2].asNumber(), arguments[3].asNumber()); @@ -53,15 +47,25 @@ class JsiSkRect : public JsiSkWrappingSharedPtrHostObject { return jsi::Value::undefined(); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkRect, setXYWH), - JSI_EXPORT_FUNC(JsiSkRect, setLTRB), - JSI_EXPORT_FUNC(JsiSkRect, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostGetter(runtime, prototype, "x", &JsiSkRect::get_x); + installHostGetter(runtime, prototype, "y", &JsiSkRect::get_y); + installHostGetter(runtime, prototype, "width", &JsiSkRect::get_width); + installHostGetter(runtime, prototype, "height", &JsiSkRect::get_height); + installHostGetter(runtime, prototype, "left", &JsiSkRect::get_left); + installHostGetter(runtime, prototype, "top", &JsiSkRect::get_top); + installHostGetter(runtime, prototype, "right", &JsiSkRect::get_right); + installHostGetter(runtime, prototype, "bottom", &JsiSkRect::get_bottom); + installHostMethod(runtime, prototype, "setXYWH", &JsiSkRect::setXYWH); + installHostMethod(runtime, prototype, "setLTRB", &JsiSkRect::setLTRB); + } /** Constructor */ JsiSkRect(std::shared_ptr context, const SkRect &rect) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), std::make_shared(rect)) {} /** @@ -70,8 +74,9 @@ class JsiSkRect : public JsiSkWrappingSharedPtrHostObject { static std::shared_ptr fromValue(jsi::Runtime &runtime, const jsi::Value &obj) { const auto &object = obj.asObject(runtime); - if (object.isHostObject(runtime)) { - return object.asHostObject(runtime)->getObject(); + auto rect = tryGetJsiObject(runtime, object); + if (rect) { + return rect->getObject(); } else { auto x = object.getProperty(runtime, "x").asNumber(); auto y = object.getProperty(runtime, "y").asNumber(); @@ -87,25 +92,20 @@ class JsiSkRect : public JsiSkWrappingSharedPtrHostObject { static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, const SkRect &rect) { - auto rectObj = std::make_shared(std::move(context), rect); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, rectObj, - context); + return makeJsiObject(runtime, + std::make_shared(std::move(context), rect)); } static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, SkRect &&rect) { - auto rectObj = - std::make_shared(std::move(context), std::move(rect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, rectObj, - context); + return makeJsiObject(runtime, std::make_shared( + std::move(context), std::move(rect))); } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { return std::max(sizeof(SkRect), kMinMemoryPressure); } - std::string getObjectType() const override { return "JsiSkRect"; } - /** * Creates the function for construction a new instance of the SkRect * wrapper @@ -122,10 +122,8 @@ class JsiSkRect : public JsiSkWrappingSharedPtrHostObject { arguments[2].asNumber(), arguments[3].asNumber()); // Return the newly constructed object - auto rectObj = - std::make_shared(std::move(context), std::move(rect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, rectObj, - context); + return makeJsiObject(runtime, std::make_shared( + std::move(context), std::move(rect))); }; } }; diff --git a/packages/skia/cpp/api/JsiSkRuntimeEffect.h b/packages/skia/cpp/api/JsiSkRuntimeEffect.h index 0c51f78d6e..ad77d168e0 100644 --- a/packages/skia/cpp/api/JsiSkRuntimeEffect.h +++ b/packages/skia/cpp/api/JsiSkRuntimeEffect.h @@ -5,8 +5,8 @@ #include #include -#include "JsiSkHostObjects.h" #include "JsiSkMatrix.h" +#include "JsiSkNativeObjects.h" #include "JsiSkShader.h" #include @@ -37,8 +37,11 @@ struct RuntimeEffectUniform { }; class JsiSkRuntimeEffect - : public JsiSkWrappingSkPtrHostObject { + : public JsiSkWrappingSkPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "RuntimeEffect"; + JSI_HOST_FUNCTION(makeShader) { auto uniforms = castUniforms(runtime, arguments[0]); @@ -51,10 +54,8 @@ class JsiSkRuntimeEffect auto shader = getObject()->makeShader(std::move(uniforms), nullptr, 0, matrix); - auto shaderObj = - std::make_shared(getContext(), std::move(shader)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shaderObj, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(shader))); } JSI_HOST_FUNCTION(makeShaderWithChildren) { @@ -66,9 +67,8 @@ class JsiSkRuntimeEffect auto jsiChildCount = jsiChildren.size(runtime); children.reserve(jsiChildCount); for (int i = 0; i < jsiChildCount; i++) { - auto shader = jsiChildren.getValueAtIndex(runtime, i) - .asObject(runtime) - .asHostObject(runtime) + auto shader = getJsiObject( + runtime, jsiChildren.getValueAtIndex(runtime, i)) ->getObject(); children.push_back(shader); } @@ -82,10 +82,8 @@ class JsiSkRuntimeEffect auto shader = getObject()->makeShader(std::move(uniforms), children.data(), children.size(), matrix); - auto shaderObj = - std::make_shared(getContext(), std::move(shader)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shaderObj, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(shader))); } JSI_HOST_FUNCTION(getUniformCount) { @@ -124,27 +122,38 @@ class JsiSkRuntimeEffect return jsi::String::createFromAscii(runtime, getObject()->source()); } - EXPORT_JSI_API_TYPENAME(JsiSkRuntimeEffect, RuntimeEffect) - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkRuntimeEffect, makeShader), - JSI_EXPORT_FUNC(JsiSkRuntimeEffect, - makeShaderWithChildren), - JSI_EXPORT_FUNC(JsiSkRuntimeEffect, getUniformCount), - JSI_EXPORT_FUNC(JsiSkRuntimeEffect, - getUniformFloatCount), - JSI_EXPORT_FUNC(JsiSkRuntimeEffect, getUniformName), - JSI_EXPORT_FUNC(JsiSkRuntimeEffect, getUniform), - JSI_EXPORT_FUNC(JsiSkRuntimeEffect, source), - JSI_EXPORT_FUNC(JsiSkRuntimeEffect, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "makeShader", + &JsiSkRuntimeEffect::makeShader); + installHostMethod(runtime, prototype, "makeShaderWithChildren", + &JsiSkRuntimeEffect::makeShaderWithChildren); + installHostMethod(runtime, prototype, "getUniformCount", + &JsiSkRuntimeEffect::getUniformCount); + installHostMethod(runtime, prototype, "getUniformFloatCount", + &JsiSkRuntimeEffect::getUniformFloatCount); + installHostMethod(runtime, prototype, "getUniformName", + &JsiSkRuntimeEffect::getUniformName); + installHostMethod(runtime, prototype, "getUniform", + &JsiSkRuntimeEffect::getUniform); + installHostMethod(runtime, prototype, "source", + &JsiSkRuntimeEffect::source); + } JsiSkRuntimeEffect(std::shared_ptr context, sk_sp rt) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(rt)) {} - - size_t getMemoryPressure() const override { return 4096; } + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(rt)) {} + + /** + Returns the underlying object from a host object of this type + */ + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return getJsiObject(runtime, obj)->getObject(); + } - std::string getObjectType() const override { return "JsiSkRuntimeEffect"; } + size_t getMemoryPressure() override { return 4096; } static RuntimeEffectUniform fromUniform(const SkRuntimeEffect::Uniform &u) { RuntimeEffectUniform su; diff --git a/packages/skia/cpp/api/JsiSkRuntimeEffectFactory.h b/packages/skia/cpp/api/JsiSkRuntimeEffectFactory.h index ff904b2929..9f0fe96e99 100644 --- a/packages/skia/cpp/api/JsiSkRuntimeEffectFactory.h +++ b/packages/skia/cpp/api/JsiSkRuntimeEffectFactory.h @@ -6,15 +6,18 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkRuntimeEffect.h" namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkRuntimeEffectFactory : public JsiSkHostObject { +class JsiSkRuntimeEffectFactory + : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "RuntimeEffectFactory"; + JSI_HOST_FUNCTION(Make) { auto sksl = arguments[0].asString(runtime).utf8(runtime); auto result = SkRuntimeEffect::MakeForShader(SkString(sksl)); @@ -26,23 +29,20 @@ class JsiSkRuntimeEffectFactory : public JsiSkHostObject { .c_str()); return jsi::Value::null(); } - auto runtimeEffect = - std::make_shared(getContext(), std::move(effect)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, runtimeEffect, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(effect))); } - size_t getMemoryPressure() const override { return 1024; } + size_t getMemoryPressure() override { return 1024; } - std::string getObjectType() const override { - return "JsiSkRuntimeEffectFactory"; + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "Make", + &JsiSkRuntimeEffectFactory::Make); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkRuntimeEffectFactory, Make)) - explicit JsiSkRuntimeEffectFactory( std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkRuntimeShaderBuilder.h b/packages/skia/cpp/api/JsiSkRuntimeShaderBuilder.h index 8b69244eac..725802aa45 100644 --- a/packages/skia/cpp/api/JsiSkRuntimeShaderBuilder.h +++ b/packages/skia/cpp/api/JsiSkRuntimeShaderBuilder.h @@ -6,7 +6,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -21,14 +21,18 @@ namespace RNSkia { namespace jsi = facebook::jsi; class JsiSkRuntimeShaderBuilder - : public JsiSkWrappingSharedPtrHostObject { + : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "RuntimeShaderBuilder"; + /** Constructor */ JsiSkRuntimeShaderBuilder(std::shared_ptr context, const SkRuntimeShaderBuilder &rt) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), std::make_shared(rt)) {} JSI_HOST_FUNCTION(setUniform) { @@ -47,8 +51,19 @@ class JsiSkRuntimeShaderBuilder return jsi::Value::undefined(); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkRuntimeShaderBuilder, setUniform), - JSI_EXPORT_FUNC(JsiSkRuntimeShaderBuilder, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "setUniform", + &JsiSkRuntimeShaderBuilder::setUniform); + } + + /** + Returns the underlying object from a host object of this type + */ + static std::shared_ptr + fromValue(jsi::Runtime &runtime, const jsi::Value &obj) { + return getJsiObject(runtime, obj)->getObject(); + } /** Returns the jsi object from a host object of this type @@ -56,20 +71,14 @@ class JsiSkRuntimeShaderBuilder static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, const SkRuntimeShaderBuilder &rt) { - auto builder = - std::make_shared(std::move(context), rt); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, builder, - context); + return makeJsiObject(runtime, std::make_shared( + std::move(context), rt)); } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { return std::max(sizeof(SkRuntimeShaderBuilder), kMinMemoryPressure); } - std::string getObjectType() const override { - return "JsiSkRuntimeShaderBuilder"; - } - /** * Creates the function for construction a new instance of the SkRect * wrapper @@ -83,10 +92,8 @@ class JsiSkRuntimeShaderBuilder auto rt = JsiSkRuntimeEffect::fromValue(runtime, arguments[0]); auto rtb = SkRuntimeShaderBuilder(rt); // Return the newly constructed object - auto builder = std::make_shared( - std::move(context), std::move(rtb)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, builder, - context); + return makeJsiObject(runtime, std::make_shared( + std::move(context), std::move(rtb))); }; } }; diff --git a/packages/skia/cpp/api/JsiSkSVG.h b/packages/skia/cpp/api/JsiSkSVG.h index df631bae3a..85e6defb9e 100644 --- a/packages/skia/cpp/api/JsiSkSVG.h +++ b/packages/skia/cpp/api/JsiSkSVG.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -18,17 +18,17 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkSVG : public JsiSkWrappingSkPtrHostObject { +class JsiSkSVG : public JsiSkWrappingSkPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "SVG"; + JsiSkSVG(std::shared_ptr context, sk_sp svgdom, sk_sp resourceProvider = nullptr) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(svgdom)) {} + : JsiSkWrappingSkPtrNativeObject(std::move(context), + std::move(svgdom)) {} ~JsiSkSVG() = default; - EXPORT_JSI_API_TYPENAME(JsiSkSVG, SVG) - JSI_HOST_FUNCTION(width) { return static_cast(getObject()->containerSize().width()); } @@ -37,19 +37,21 @@ class JsiSkSVG : public JsiSkWrappingSkPtrHostObject { return static_cast(getObject()->containerSize().height()); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkSVG, width), - JSI_EXPORT_FUNC(JsiSkSVG, height), - JSI_EXPORT_FUNC(JsiSkSVG, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "width", &JsiSkSVG::width); + installHostMethod(runtime, prototype, "height", &JsiSkSVG::height); + } /** Returns the underlying object from a host object of this type */ static sk_sp fromValue(jsi::Runtime &runtime, const jsi::Value &obj) { - return obj.asObject(runtime).asHostObject(runtime)->getObject(); + return getJsiObject(runtime, obj)->getObject(); } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { auto svgdom = getObject(); if (!svgdom) { return 1024; // Base size if no SVG @@ -72,8 +74,6 @@ class JsiSkSVG : public JsiSkWrappingSkPtrHostObject { return (rasterBufferSize / 4) + baseOverhead; // Quarter of full raster + overhead } - - std::string getObjectType() const override { return "JsiSkSVG"; } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkSVGFactory.h b/packages/skia/cpp/api/JsiSkSVGFactory.h index 80a78c0992..e5122bc799 100644 --- a/packages/skia/cpp/api/JsiSkSVGFactory.h +++ b/packages/skia/cpp/api/JsiSkSVGFactory.h @@ -7,7 +7,7 @@ #include #include "JsiSkData.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkSVG.h" #include "JsiSkTypeface.h" @@ -55,8 +55,10 @@ class SVGAssetProvider : public skresources::ResourceProvider { const skresources::ImageDecodeStrategy fStrategy; }; -class JsiSkSVGFactory : public JsiSkHostObject { +class JsiSkSVGFactory : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "SVGFactory"; + // Helper function to parse asset map from JS object static SVGAssetProvider::AssetMap parseAssetMap(jsi::Runtime &runtime, const jsi::Value &jsValue) { @@ -83,15 +85,9 @@ class JsiSkSVGFactory : public JsiSkHostObject { continue; } - if (jsValue.isObject()) { - auto jsObject = jsValue.asObject(runtime); - if (jsObject.isHostObject(runtime)) { - auto hostObject = jsObject.getHostObject(runtime); - auto skData = std::dynamic_pointer_cast(hostObject); - if (skData) { - assets[key] = skData->getObject(); - } - } + auto skData = tryGetJsiObject(runtime, jsValue); + if (skData) { + assets[key] = skData->getObject(); } } @@ -120,9 +116,8 @@ class JsiSkSVGFactory : public JsiSkHostObject { builder.setResourceProvider(provider); auto svg_dom = builder.make(*stream); - auto svg = std::make_shared(getContext(), std::move(svg_dom)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, svg, - getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(svg_dom))); } public: @@ -160,15 +155,17 @@ class JsiSkSVGFactory : public JsiSkHostObject { std::move(assets)); } - size_t getMemoryPressure() const override { return kMinMemoryPressure; } - - std::string getObjectType() const override { return "JsiSkSVGFactory"; } + size_t getMemoryPressure() override { return kMinMemoryPressure; } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkSVGFactory, MakeFromData), - JSI_EXPORT_FUNC(JsiSkSVGFactory, MakeFromString)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "MakeFromData", + &JsiSkSVGFactory::MakeFromData); + installHostMethod(runtime, prototype, "MakeFromString", + &JsiSkSVGFactory::MakeFromString); + } explicit JsiSkSVGFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkShader.h b/packages/skia/cpp/api/JsiSkShader.h index 3c1f152939..f0b081faa4 100644 --- a/packages/skia/cpp/api/JsiSkShader.h +++ b/packages/skia/cpp/api/JsiSkShader.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -19,18 +19,25 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkShader : public JsiSkWrappingSkPtrHostObject { +class JsiSkShader + : public JsiSkWrappingSkPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "Shader"; + JsiSkShader(std::shared_ptr context, sk_sp shader) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(shader)) {} + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(shader)) {} - size_t getMemoryPressure() const override { return 1024 * 1024; } + size_t getMemoryPressure() override { return 1024 * 1024; } - std::string getObjectType() const override { return "JsiSkShader"; } + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } - EXPORT_JSI_API_TYPENAME(JsiSkShader, Shader) - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkShader, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkShaderFactory.h b/packages/skia/cpp/api/JsiSkShaderFactory.h index fdcc71fb4f..e77b473539 100644 --- a/packages/skia/cpp/api/JsiSkShaderFactory.h +++ b/packages/skia/cpp/api/JsiSkShaderFactory.h @@ -7,7 +7,7 @@ #include #include "JsiSkColorFilter.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -75,8 +75,10 @@ std::vector getPositions(jsi::Runtime &runtime, return positions; } -class JsiSkShaderFactory : public JsiSkHostObject { +class JsiSkShaderFactory : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "ShaderFactory"; + JSI_HOST_FUNCTION(MakeLinearGradient) { auto p1 = *JsiSkPoint::fromValue(runtime, arguments[0].asObject(runtime)).get(); @@ -107,10 +109,8 @@ class JsiSkShaderFactory : public JsiSkHostObject { SkGradient grad(gradColors, SkGradient::Interpolation::FromFlags(flag)); sk_sp gradient = SkShaders::LinearGradient(pts, grad, localMatrix); - auto shader = - std::make_shared(getContext(), std::move(gradient)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shader, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(gradient))); } JSI_HOST_FUNCTION(MakeRadialGradient) { @@ -141,10 +141,8 @@ class JsiSkShaderFactory : public JsiSkHostObject { SkGradient grad(gradColors, SkGradient::Interpolation::FromFlags(flag)); sk_sp gradient = SkShaders::RadialGradient(center, r, grad, localMatrix); - auto shader = - std::make_shared(getContext(), std::move(gradient)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shader, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(gradient))); } JSI_HOST_FUNCTION(MakeSweepGradient) { @@ -179,10 +177,8 @@ class JsiSkShaderFactory : public JsiSkHostObject { SkGradient grad(gradColors, SkGradient::Interpolation::FromFlags(flag)); sk_sp gradient = SkShaders::SweepGradient( SkPoint::Make(x, y), startAngle, endAngle, grad, localMatrix); - auto shader = - std::make_shared(getContext(), std::move(gradient)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shader, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(gradient))); } JSI_HOST_FUNCTION(MakeTwoPointConicalGradient) { @@ -218,10 +214,8 @@ class JsiSkShaderFactory : public JsiSkHostObject { sk_sp gradient = SkShaders::TwoPointConicalGradient( start, startRadius, end, endRadius, grad, localMatrix); - auto shader = - std::make_shared(getContext(), std::move(gradient)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shader, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(gradient))); } JSI_HOST_FUNCTION(MakeTurbulence) { @@ -234,10 +228,8 @@ class JsiSkShaderFactory : public JsiSkHostObject { SkISize size = SkISize::Make(tileW, tileH); sk_sp gradient = SkShaders::MakeTurbulence(baseFreqX, baseFreqY, octaves, seed, &size); - auto shader = - std::make_shared(getContext(), std::move(gradient)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shader, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(gradient))); } JSI_HOST_FUNCTION(MakeFractalNoise) { @@ -250,10 +242,8 @@ class JsiSkShaderFactory : public JsiSkHostObject { SkISize size = SkISize::Make(tileW, tileH); sk_sp gradient = SkShaders::MakeFractalNoise(baseFreqX, baseFreqY, octaves, seed, &size); - auto shader = - std::make_shared(getContext(), std::move(gradient)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shader, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(gradient))); } JSI_HOST_FUNCTION(MakeBlend) { @@ -261,37 +251,40 @@ class JsiSkShaderFactory : public JsiSkHostObject { auto one = JsiSkShader::fromValue(runtime, arguments[1]); auto two = JsiSkShader::fromValue(runtime, arguments[2]); sk_sp gradient = SkShaders::Blend(blendMode, one, two); - auto shader = - std::make_shared(getContext(), std::move(gradient)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shader, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(gradient))); } JSI_HOST_FUNCTION(MakeColor) { auto color = JsiSkColor::fromValue(runtime, arguments[0]); sk_sp gradient = SkShaders::Color(color); - auto shader = - std::make_shared(getContext(), std::move(gradient)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, shader, - getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(gradient))); } - size_t getMemoryPressure() const override { return 1024; } - - std::string getObjectType() const override { return "JsiSkShaderFactory"; } - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkShaderFactory, MakeLinearGradient), - JSI_EXPORT_FUNC(JsiSkShaderFactory, MakeRadialGradient), - JSI_EXPORT_FUNC(JsiSkShaderFactory, MakeSweepGradient), - JSI_EXPORT_FUNC(JsiSkShaderFactory, - MakeTwoPointConicalGradient), - JSI_EXPORT_FUNC(JsiSkShaderFactory, MakeTurbulence), - JSI_EXPORT_FUNC(JsiSkShaderFactory, MakeFractalNoise), - JSI_EXPORT_FUNC(JsiSkShaderFactory, MakeBlend), - JSI_EXPORT_FUNC(JsiSkShaderFactory, MakeColor)) + size_t getMemoryPressure() override { return 1024; } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "MakeLinearGradient", + &JsiSkShaderFactory::MakeLinearGradient); + installHostMethod(runtime, prototype, "MakeRadialGradient", + &JsiSkShaderFactory::MakeRadialGradient); + installHostMethod(runtime, prototype, "MakeSweepGradient", + &JsiSkShaderFactory::MakeSweepGradient); + installHostMethod(runtime, prototype, "MakeTwoPointConicalGradient", + &JsiSkShaderFactory::MakeTwoPointConicalGradient); + installHostMethod(runtime, prototype, "MakeTurbulence", + &JsiSkShaderFactory::MakeTurbulence); + installHostMethod(runtime, prototype, "MakeFractalNoise", + &JsiSkShaderFactory::MakeFractalNoise); + installHostMethod(runtime, prototype, "MakeBlend", + &JsiSkShaderFactory::MakeBlend); + installHostMethod(runtime, prototype, "MakeColor", + &JsiSkShaderFactory::MakeColor); + } explicit JsiSkShaderFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkSkottie.h b/packages/skia/cpp/api/JsiSkSkottie.h index d6c6933c4a..5bbb2f7dce 100644 --- a/packages/skia/cpp/api/JsiSkSkottie.h +++ b/packages/skia/cpp/api/JsiSkSkottie.h @@ -4,7 +4,7 @@ #include "JsiSkCanvas.h" #include "JsiSkColor.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkPoint.h" #include "JsiSkRect.h" #include "api/third_party/SkottieUtils.h" @@ -146,8 +146,12 @@ class ManagedAnimation { std::unique_ptr _propManager = nullptr; }; -class JsiSkSkottie : public JsiSkWrappingSharedPtrHostObject { +class JsiSkSkottie + : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "Skottie"; + // #region Properties JSI_HOST_FUNCTION(duration) { return static_cast(getObject()->_animation->duration()); @@ -155,12 +159,6 @@ class JsiSkSkottie : public JsiSkWrappingSharedPtrHostObject { JSI_HOST_FUNCTION(fps) { return static_cast(getObject()->_animation->fps()); } - - JSI_PROPERTY_GET(__typename__) { - return jsi::String::createFromUtf8(runtime, "Skottie"); - } - - JSI_EXPORT_PROPERTY_GETTERS(JSI_EXPORT_PROP_GET(JsiSkSkottie, __typename__)) // #endregion // #region Methods @@ -186,10 +184,7 @@ class JsiSkSkottie : public JsiSkWrappingSharedPtrHostObject { } JSI_HOST_FUNCTION(render) { - auto canvas = arguments[0] - .asObject(runtime) - .asHostObject(runtime) - ->getCanvas(); + auto canvas = getJsiObject(runtime, arguments[0])->getCanvas(); if (count > 1) { auto rect = JsiSkRect::fromValue(runtime, arguments[1]); getObject()->_animation->render(canvas, rect.get()); @@ -554,29 +549,46 @@ class JsiSkSkottie : public JsiSkWrappingSharedPtrHostObject { return transformProps; } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkSkottie, duration), - JSI_EXPORT_FUNC(JsiSkSkottie, fps), - JSI_EXPORT_FUNC(JsiSkSkottie, seekFrame), - JSI_EXPORT_FUNC(JsiSkSkottie, render), - JSI_EXPORT_FUNC(JsiSkSkottie, size), - JSI_EXPORT_FUNC(JsiSkSkottie, version), - JSI_EXPORT_FUNC(JsiSkSkottie, getSlotInfo), - JSI_EXPORT_FUNC(JsiSkSkottie, setColorSlot), - JSI_EXPORT_FUNC(JsiSkSkottie, setScalarSlot), - JSI_EXPORT_FUNC(JsiSkSkottie, setVec2Slot), - JSI_EXPORT_FUNC(JsiSkSkottie, setTextSlot), - JSI_EXPORT_FUNC(JsiSkSkottie, setImageSlot), - JSI_EXPORT_FUNC(JsiSkSkottie, getColorSlot), - JSI_EXPORT_FUNC(JsiSkSkottie, getScalarSlot), - JSI_EXPORT_FUNC(JsiSkSkottie, getVec2Slot), - JSI_EXPORT_FUNC(JsiSkSkottie, getTextSlot), - JSI_EXPORT_FUNC(JsiSkSkottie, getColorProps), - JSI_EXPORT_FUNC(JsiSkSkottie, getOpacityProps), - JSI_EXPORT_FUNC(JsiSkSkottie, getTransformProps), - JSI_EXPORT_FUNC(JsiSkSkottie, getTextProps), - JSI_EXPORT_FUNC(JsiSkSkottie, setColor), - JSI_EXPORT_FUNC(JsiSkSkottie, setText), - JSI_EXPORT_FUNC(JsiSkSkottie, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "duration", &JsiSkSkottie::duration); + installHostMethod(runtime, prototype, "fps", &JsiSkSkottie::fps); + installHostMethod(runtime, prototype, "seekFrame", + &JsiSkSkottie::seekFrame); + installHostMethod(runtime, prototype, "render", &JsiSkSkottie::render); + installHostMethod(runtime, prototype, "size", &JsiSkSkottie::size); + installHostMethod(runtime, prototype, "version", &JsiSkSkottie::version); + installHostMethod(runtime, prototype, "getSlotInfo", + &JsiSkSkottie::getSlotInfo); + installHostMethod(runtime, prototype, "setColorSlot", + &JsiSkSkottie::setColorSlot); + installHostMethod(runtime, prototype, "setScalarSlot", + &JsiSkSkottie::setScalarSlot); + installHostMethod(runtime, prototype, "setVec2Slot", + &JsiSkSkottie::setVec2Slot); + installHostMethod(runtime, prototype, "setTextSlot", + &JsiSkSkottie::setTextSlot); + installHostMethod(runtime, prototype, "setImageSlot", + &JsiSkSkottie::setImageSlot); + installHostMethod(runtime, prototype, "getColorSlot", + &JsiSkSkottie::getColorSlot); + installHostMethod(runtime, prototype, "getScalarSlot", + &JsiSkSkottie::getScalarSlot); + installHostMethod(runtime, prototype, "getVec2Slot", + &JsiSkSkottie::getVec2Slot); + installHostMethod(runtime, prototype, "getTextSlot", + &JsiSkSkottie::getTextSlot); + installHostMethod(runtime, prototype, "getColorProps", + &JsiSkSkottie::getColorProps); + installHostMethod(runtime, prototype, "getOpacityProps", + &JsiSkSkottie::getOpacityProps); + installHostMethod(runtime, prototype, "getTransformProps", + &JsiSkSkottie::getTransformProps); + installHostMethod(runtime, prototype, "getTextProps", + &JsiSkSkottie::getTextProps); + installHostMethod(runtime, prototype, "setColor", &JsiSkSkottie::setColor); + installHostMethod(runtime, prototype, "setText", &JsiSkSkottie::setText); + } // #endregion /** @@ -584,10 +596,10 @@ class JsiSkSkottie : public JsiSkWrappingSharedPtrHostObject { */ JsiSkSkottie(std::shared_ptr context, std::shared_ptr animation) - : JsiSkWrappingSharedPtrHostObject( + : JsiSkWrappingSharedPtrNativeObject( std::move(context), std::move(animation)) {} - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { auto animation = getObject(); if (!animation || !animation->_animation) { return 1024; // Base size if no animation @@ -615,7 +627,5 @@ class JsiSkSkottie : public JsiSkWrappingSharedPtrHostObject { return animationMemory + baseOverhead; } - - std::string getObjectType() const override { return "JsiSkSkottie"; } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkSurface.h b/packages/skia/cpp/api/JsiSkSurface.h index de6ad08a69..fe7211bc44 100644 --- a/packages/skia/cpp/api/JsiSkSurface.h +++ b/packages/skia/cpp/api/JsiSkSurface.h @@ -8,7 +8,7 @@ #include #include "JsiSkDispatcher.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiTextureInfo.h" #include "JsiSkCanvas.h" @@ -30,15 +30,18 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkSurface : public JsiSkWrappingSkPtrHostObject { +class JsiSkSurface + : public JsiSkWrappingSkPtrNativeObject { private: std::shared_ptr _dispatcher; public: + static constexpr const char *CLASS_NAME = "Surface"; + JsiSkSurface(std::shared_ptr context, sk_sp surface) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(surface)) { + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(surface)) { // Get the dispatcher for the current thread _dispatcher = Dispatcher::getDispatcher(); // Process any pending operations @@ -63,8 +66,6 @@ class JsiSkSurface : public JsiSkWrappingSkPtrHostObject { } } - EXPORT_JSI_API_TYPENAME(JsiSkSurface, Surface) - // TODO-API: Properties? JSI_HOST_FUNCTION(width) { return static_cast(getObject()->width()); } JSI_HOST_FUNCTION(height) { @@ -78,8 +79,7 @@ class JsiSkSurface : public JsiSkWrappingSkPtrHostObject { // Keep a reference to the owning surface so the canvas can read pixels back // through a snapshot on Graphite (which lacks synchronous canvas readback). canvas->setSurface(surface); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, canvas, - getContext()); + return makeJsiObject(runtime, std::move(canvas)); } JSI_HOST_FUNCTION(flush) { @@ -124,15 +124,12 @@ class JsiSkSurface : public JsiSkWrappingSkPtrHostObject { } #endif if (count > 1 && arguments[1].isObject()) { - auto jsiImage = - arguments[1].asObject(runtime).asHostObject(runtime); + auto jsiImage = getJsiObject(runtime, arguments[1]); jsiImage->setObject(image); return jsi::Value(runtime, arguments[1]); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(image)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(image))); } JSI_HOST_FUNCTION(getNativeTextureUnstable) { @@ -140,7 +137,7 @@ class JsiSkSurface : public JsiSkWrappingSkPtrHostObject { return JsiTextureInfo::toValue(runtime, texInfo); } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { if (isDisposed()) { return 0; } @@ -196,15 +193,18 @@ class JsiSkSurface : public JsiSkWrappingSkPtrHostObject { return estimated; } - std::string getObjectType() const override { return "JsiSkSurface"; } - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkSurface, width), - JSI_EXPORT_FUNC(JsiSkSurface, height), - JSI_EXPORT_FUNC(JsiSkSurface, getCanvas), - JSI_EXPORT_FUNC(JsiSkSurface, makeImageSnapshot), - JSI_EXPORT_FUNC(JsiSkSurface, flush), - JSI_EXPORT_FUNC(JsiSkSurface, getNativeTextureUnstable), - JSI_EXPORT_FUNC(JsiSkSurface, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "width", &JsiSkSurface::width); + installHostMethod(runtime, prototype, "height", &JsiSkSurface::height); + installHostMethod(runtime, prototype, "getCanvas", + &JsiSkSurface::getCanvas); + installHostMethod(runtime, prototype, "makeImageSnapshot", + &JsiSkSurface::makeImageSnapshot); + installHostMethod(runtime, prototype, "flush", &JsiSkSurface::flush); + installHostMethod(runtime, prototype, "getNativeTextureUnstable", + &JsiSkSurface::getNativeTextureUnstable); + } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkSurfaceFactory.h b/packages/skia/cpp/api/JsiSkSurfaceFactory.h index aad9442934..28b7531094 100644 --- a/packages/skia/cpp/api/JsiSkSurfaceFactory.h +++ b/packages/skia/cpp/api/JsiSkSurfaceFactory.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkSurface.h" @@ -20,8 +20,10 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkSurfaceFactory : public JsiSkHostObject { +class JsiSkSurfaceFactory : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "SurfaceFactory"; + JSI_HOST_FUNCTION(Make) { auto width = static_cast(arguments[0].asNumber()); auto height = static_cast(arguments[1].asNumber()); @@ -30,10 +32,8 @@ class JsiSkSurfaceFactory : public JsiSkHostObject { if (surface == nullptr) { return jsi::Value::null(); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(surface)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(surface))); } JSI_HOST_FUNCTION(MakeOffscreen) { @@ -56,21 +56,20 @@ class JsiSkSurfaceFactory : public JsiSkHostObject { if (surface == nullptr) { return jsi::Value::null(); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(surface)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(surface))); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkSurfaceFactory, Make), - JSI_EXPORT_FUNC(JsiSkSurfaceFactory, MakeOffscreen)) - - size_t getMemoryPressure() const override { return 2048; } + size_t getMemoryPressure() override { return 2048; } - std::string getObjectType() const override { return "JsiSkSurfaceFactory"; } + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "Make", &JsiSkSurfaceFactory::Make); + installHostMethod(runtime, prototype, "MakeOffscreen", + &JsiSkSurfaceFactory::MakeOffscreen); + } explicit JsiSkSurfaceFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkTextBlob.h b/packages/skia/cpp/api/JsiSkTextBlob.h index 248fb55c7a..2f8860933c 100644 --- a/packages/skia/cpp/api/JsiSkTextBlob.h +++ b/packages/skia/cpp/api/JsiSkTextBlob.h @@ -5,7 +5,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -18,14 +18,17 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkTextBlob : public JsiSkWrappingSkPtrHostObject { +class JsiSkTextBlob + : public JsiSkWrappingSkPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "TextBlob"; + JsiSkTextBlob(std::shared_ptr context, sk_sp shader) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(shader)) {} + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(shader)) {} - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { auto textBlob = getObject(); if (!textBlob) return 0; @@ -37,9 +40,13 @@ class JsiSkTextBlob : public JsiSkWrappingSkPtrHostObject { 1024; // Area estimation + base overhead } - std::string getObjectType() const override { return "JsiSkTextBlob"; } + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } - EXPORT_JSI_API_TYPENAME(JsiSkTextBlob, TextBlob) - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkTextBlob, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkTextBlobFactory.h b/packages/skia/cpp/api/JsiSkTextBlobFactory.h index e2d4fe3fca..44d4abdc28 100644 --- a/packages/skia/cpp/api/JsiSkTextBlobFactory.h +++ b/packages/skia/cpp/api/JsiSkTextBlobFactory.h @@ -7,7 +7,7 @@ #include #include "JsiSkFont.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkRSXform.h" #include "JsiSkTextBlob.h" @@ -22,16 +22,16 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkTextBlobFactory : public JsiSkHostObject { +class JsiSkTextBlobFactory : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "TextBlobFactory"; + JSI_HOST_FUNCTION(MakeFromText) { auto str = arguments[0].asString(runtime).utf8(runtime); auto font = JsiSkFont::fromValue(runtime, arguments[1]); auto textBlob = SkTextBlob::MakeFromString(str.c_str(), *font); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(textBlob)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(textBlob))); } JSI_HOST_FUNCTION(MakeFromGlyphs) { @@ -47,10 +47,8 @@ class JsiSkTextBlobFactory : public JsiSkHostObject { auto textBlob = SkTextBlob::MakeFromText(glyphs.data(), glyphs.size() * bytesPerGlyph, *font, SkTextEncoding::kGlyphID); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(textBlob)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(textBlob))); } JSI_HOST_FUNCTION(MakeFromRSXform) { @@ -68,10 +66,8 @@ class JsiSkTextBlobFactory : public JsiSkHostObject { auto x = SkSpan(rsxforms.data(), rsxforms.size()); auto textBlob = SkTextBlob::MakeFromRSXform(str.c_str(), str.length(), x, *font); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(textBlob)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(textBlob))); } JSI_HOST_FUNCTION(MakeFromRSXformGlyphs) { @@ -97,24 +93,25 @@ class JsiSkTextBlobFactory : public JsiSkHostObject { auto textBlob = SkTextBlob::MakeFromRSXform( glyphs.data(), glyphs.size() * bytesPerGlyph, x, *font, SkTextEncoding::kGlyphID); - auto hostObjectInstance = - std::make_shared(getContext(), std::move(textBlob)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(textBlob))); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkTextBlobFactory, MakeFromText), - JSI_EXPORT_FUNC(JsiSkTextBlobFactory, MakeFromGlyphs), - JSI_EXPORT_FUNC(JsiSkTextBlobFactory, MakeFromRSXform), - JSI_EXPORT_FUNC(JsiSkTextBlobFactory, - MakeFromRSXformGlyphs), ) - - size_t getMemoryPressure() const override { return 2048; } - - std::string getObjectType() const override { return "JsiSkTextBlobFactory"; } + size_t getMemoryPressure() override { return 2048; } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "MakeFromText", + &JsiSkTextBlobFactory::MakeFromText); + installHostMethod(runtime, prototype, "MakeFromGlyphs", + &JsiSkTextBlobFactory::MakeFromGlyphs); + installHostMethod(runtime, prototype, "MakeFromRSXform", + &JsiSkTextBlobFactory::MakeFromRSXform); + installHostMethod(runtime, prototype, "MakeFromRSXformGlyphs", + &JsiSkTextBlobFactory::MakeFromRSXformGlyphs); + } explicit JsiSkTextBlobFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkTypeface.h b/packages/skia/cpp/api/JsiSkTypeface.h index 6e79c325c2..667c978fd1 100644 --- a/packages/skia/cpp/api/JsiSkTypeface.h +++ b/packages/skia/cpp/api/JsiSkTypeface.h @@ -6,7 +6,7 @@ #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "utils/RNSkLog.h" #pragma clang diagnostic push @@ -22,15 +22,15 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkTypeface : public JsiSkWrappingSkPtrHostObject { +class JsiSkTypeface + : public JsiSkWrappingSkPtrNativeObject { public: - EXPORT_JSI_API_TYPENAME(JsiSkTypeface, Typeface) - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkTypeface, getGlyphIDs), - JSI_EXPORT_FUNC(JsiSkTypeface, dispose)) + static constexpr const char *CLASS_NAME = "Typeface"; JsiSkTypeface(std::shared_ptr context, sk_sp typeface) - : JsiSkWrappingSkPtrHostObject(std::move(context), std::move(typeface)) {} + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(typeface)) {} JSI_HOST_FUNCTION(getGlyphIDs) { auto str = arguments[0].asString(runtime).utf8(runtime); @@ -53,7 +53,7 @@ class JsiSkTypeface : public JsiSkWrappingSkPtrHostObject { return jsiGlyphIDs; } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { auto typeface = getObject(); if (!typeface) { return 0; @@ -74,13 +74,20 @@ class JsiSkTypeface : public JsiSkWrappingSkPtrHostObject { static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, sk_sp tf) { - auto hostObjectInstance = - std::make_shared(context, std::move(tf)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, context); + return makeJsiObject( + runtime, std::make_shared(context, std::move(tf))); } - std::string getObjectType() const override { return "JsiSkTypeface"; } + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "getGlyphIDs", + &JsiSkTypeface::getGlyphIDs); + } }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkTypefaceFactory.h b/packages/skia/cpp/api/JsiSkTypefaceFactory.h index 606abadb06..d5d130a6d9 100644 --- a/packages/skia/cpp/api/JsiSkTypefaceFactory.h +++ b/packages/skia/cpp/api/JsiSkTypefaceFactory.h @@ -6,15 +6,17 @@ #include #include "JsiSkData.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkTypeface.h" namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkTypefaceFactory : public JsiSkHostObject { +class JsiSkTypefaceFactory : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "TypefaceFactory"; + JSI_HOST_FUNCTION(MakeFreeTypeFaceFromData) { auto data = JsiSkData::fromValue(runtime, arguments[0]); auto fontMgr = JsiSkFontMgrFactory::getFontMgr(getContext()); @@ -22,21 +24,19 @@ class JsiSkTypefaceFactory : public JsiSkHostObject { if (typeface == nullptr) { return jsi::Value::null(); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(typeface)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(typeface))); } - size_t getMemoryPressure() const override { return 1024; } - - std::string getObjectType() const override { return "JsiSkTypefaceFactory"; } + size_t getMemoryPressure() override { return 1024; } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkTypefaceFactory, - MakeFreeTypeFaceFromData)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "MakeFreeTypeFaceFromData", + &JsiSkTypefaceFactory::MakeFreeTypeFaceFromData); + } explicit JsiSkTypefaceFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkTypefaceFontProvider.h b/packages/skia/cpp/api/JsiSkTypefaceFontProvider.h index 8d4ef8c3dd..8174182fb3 100644 --- a/packages/skia/cpp/api/JsiSkTypefaceFontProvider.h +++ b/packages/skia/cpp/api/JsiSkTypefaceFontProvider.h @@ -6,7 +6,7 @@ #include #include "JsiSkFontStyle.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkTypeface.h" #include "utils/RNSkLog.h" @@ -25,16 +25,10 @@ namespace jsi = facebook::jsi; namespace para = skia::textlayout; class JsiSkTypefaceFontProvider - : public JsiSkWrappingSkPtrHostObject { + : public JsiSkWrappingSkPtrNativeObject { public: - EXPORT_JSI_API_TYPENAME(JsiSkTypefaceFontProvider, TypefaceFontProvider) - - JSI_EXPORT_FUNCTIONS( - JSI_EXPORT_FUNC(JsiSkTypefaceFontProvider, dispose), - JSI_EXPORT_FUNC(JsiSkTypefaceFontProvider, registerFont), - JSI_EXPORT_FUNC(JsiSkTypefaceFontProvider, matchFamilyStyle), - JSI_EXPORT_FUNC(JsiSkTypefaceFontProvider, countFamilies), - JSI_EXPORT_FUNC(JsiSkTypefaceFontProvider, getFamilyName)) + static constexpr const char *CLASS_NAME = "TypefaceFontProvider"; JSI_HOST_FUNCTION(registerFont) { sk_sp typeface = @@ -59,10 +53,8 @@ class JsiSkTypefaceFontProvider if (!typeface) { throw std::runtime_error("Could not find font style for " + name); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(typeface)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(typeface))); } JSI_HOST_FUNCTION(countFamilies) { return getObject()->countFamilies(); } @@ -76,14 +68,11 @@ class JsiSkTypefaceFontProvider JsiSkTypefaceFontProvider(std::shared_ptr context, sk_sp tfProvider) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(tfProvider)) {} - - size_t getMemoryPressure() const override { return 4096; } + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(tfProvider)) {} - std::string getObjectType() const override { - return "JsiSkTypefaceFontProvider"; - } + size_t getMemoryPressure() override { return 4096; } /** Returns the jsi object from a host object of this type @@ -91,10 +80,26 @@ class JsiSkTypefaceFontProvider static jsi::Value toValue(jsi::Runtime &runtime, std::shared_ptr context, sk_sp tfProvider) { - auto provider = std::make_shared( - std::move(context), std::move(tfProvider)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, provider, - context); + return makeJsiObject(runtime, + std::make_shared( + std::move(context), std::move(tfProvider))); + } + + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } + + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "registerFont", + &JsiSkTypefaceFontProvider::registerFont); + installHostMethod(runtime, prototype, "matchFamilyStyle", + &JsiSkTypefaceFontProvider::matchFamilyStyle); + installHostMethod(runtime, prototype, "countFamilies", + &JsiSkTypefaceFontProvider::countFamilies); + installHostMethod(runtime, prototype, "getFamilyName", + &JsiSkTypefaceFontProvider::getFamilyName); } }; diff --git a/packages/skia/cpp/api/JsiSkTypefaceFontProviderFactory.h b/packages/skia/cpp/api/JsiSkTypefaceFontProviderFactory.h index 65f361347b..d2a7713676 100644 --- a/packages/skia/cpp/api/JsiSkTypefaceFontProviderFactory.h +++ b/packages/skia/cpp/api/JsiSkTypefaceFontProviderFactory.h @@ -6,7 +6,7 @@ #include #include "JsiSkData.h" -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "JsiSkTypefaceFontProvider.h" namespace RNSkia { @@ -14,26 +14,28 @@ namespace RNSkia { namespace jsi = facebook::jsi; namespace para = skia::textlayout; -class JsiSkTypefaceFontProviderFactory : public JsiSkHostObject { +class JsiSkTypefaceFontProviderFactory + : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "TypefaceFontProviderFactory"; + JSI_HOST_FUNCTION(Make) { - auto provider = std::make_shared( - getContext(), sk_make_sp()); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, provider, - getContext()); + return makeJsiObject( + runtime, std::make_shared( + getContext(), sk_make_sp())); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkTypefaceFontProviderFactory, Make)) - - size_t getMemoryPressure() const override { return 2048; } + size_t getMemoryPressure() override { return 2048; } - std::string getObjectType() const override { - return "JsiSkTypefaceFontProviderFactory"; + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "Make", + &JsiSkTypefaceFontProviderFactory::Make); } explicit JsiSkTypefaceFontProviderFactory( std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject( + std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkVertices.h b/packages/skia/cpp/api/JsiSkVertices.h index bc623fd8db..43366edb13 100644 --- a/packages/skia/cpp/api/JsiSkVertices.h +++ b/packages/skia/cpp/api/JsiSkVertices.h @@ -5,7 +5,7 @@ #include #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -18,27 +18,27 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkVertices : public JsiSkWrappingSkPtrHostObject { +class JsiSkVertices + : public JsiSkWrappingSkPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "Vertices"; + JsiSkVertices(std::shared_ptr context, sk_sp vertices) - : JsiSkWrappingSkPtrHostObject(std::move(context), - std::move(vertices)) {} - - EXPORT_JSI_API_TYPENAME(JsiSkVertices, Vertices) + : JsiSkWrappingSkPtrNativeObject( + std::move(context), std::move(vertices)) {} JSI_HOST_FUNCTION(bounds) { const auto &result = getObject()->bounds(); - auto hostObjectInstance = std::make_shared(getContext(), result); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, + std::make_shared(getContext(), result)); } JSI_HOST_FUNCTION(uniqueID) { return static_cast(getObject()->uniqueID()); } - size_t getMemoryPressure() const override { + size_t getMemoryPressure() override { auto vertices = getObject(); if (!vertices) return 0; @@ -47,11 +47,16 @@ class JsiSkVertices : public JsiSkWrappingSkPtrHostObject { return vertices->approximateSize(); } - std::string getObjectType() const override { return "JsiSkVertices"; } + static sk_sp fromValue(jsi::Runtime &runtime, + const jsi::Value &obj) { + return objectFromValue(runtime, obj); + } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkVertices, bounds), - JSI_EXPORT_FUNC(JsiSkVertices, uniqueID), - JSI_EXPORT_FUNC(JsiSkVertices, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "bounds", &JsiSkVertices::bounds); + installHostMethod(runtime, prototype, "uniqueID", &JsiSkVertices::uniqueID); + } /** * Creates the function for construction a new instance of the SkVertices @@ -158,10 +163,8 @@ class JsiSkVertices : public JsiSkWrappingSkPtrHostObject { texs.size() > 0 ? texs.data() : nullptr, colors.size() > 0 ? colors.data() : nullptr, indicesSize, indices.data()); - auto hostObjectInstance = - std::make_shared(context, std::move(vertices)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, context); + return makeJsiObject(runtime, std::make_shared( + context, std::move(vertices))); }; } }; diff --git a/packages/skia/cpp/api/JsiSkiaContext.h b/packages/skia/cpp/api/JsiSkiaContext.h index 2b547c9c49..75bb2b539a 100644 --- a/packages/skia/cpp/api/JsiSkiaContext.h +++ b/packages/skia/cpp/api/JsiSkiaContext.h @@ -5,7 +5,7 @@ #include #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "utils/RNSkLog.h" #include @@ -28,19 +28,18 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkiaContext : public JsiSkWrappingSharedPtrHostObject { +class JsiSkiaContext + : public JsiSkWrappingSharedPtrNativeObject { public: - EXPORT_JSI_API_TYPENAME(JsiSkiaContext, SkiaContext) + static constexpr const char *CLASS_NAME = "SkiaContext"; JSI_HOST_FUNCTION(getSurface) { auto surface = getObject()->getSurface(); if (surface == nullptr) { return jsi::Value::null(); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(surface)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject(runtime, std::make_shared( + getContext(), std::move(surface))); } JSI_HOST_FUNCTION(present) { @@ -48,16 +47,19 @@ class JsiSkiaContext : public JsiSkWrappingSharedPtrHostObject { return jsi::Value::undefined(); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkiaContext, getSurface), - JSI_EXPORT_FUNC(JsiSkiaContext, present)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "getSurface", + &JsiSkiaContext::getSurface); + installHostMethod(runtime, prototype, "present", &JsiSkiaContext::present); + } JsiSkiaContext(std::shared_ptr context, std::shared_ptr ctx) - : JsiSkWrappingSharedPtrHostObject(std::move(context), std::move(ctx)) {} - - size_t getMemoryPressure() const override { return 10 * 1024 * 1024; } + : JsiSkWrappingSharedPtrNativeObject( + std::move(context), std::move(ctx)) {} - std::string getObjectType() const override { return "JsiSkiaContext"; } + size_t getMemoryPressure() override { return 10 * 1024 * 1024; } /** * Creates the function for construction a new instance of the SkFont @@ -84,10 +86,8 @@ class JsiSkiaContext : public JsiSkWrappingSharedPtrHostObject { "Couldn't create a Skia context from the native surface"); } // Return the newly constructed object - auto hostObjectInstance = - std::make_shared(context, std::move(result)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, context); + return makeJsiObject(runtime, std::make_shared( + context, std::move(result))); }; } }; diff --git a/packages/skia/cpp/api/JsiSkottieFactory.h b/packages/skia/cpp/api/JsiSkottieFactory.h index 2f59642052..0060ba86ee 100644 --- a/packages/skia/cpp/api/JsiSkottieFactory.h +++ b/packages/skia/cpp/api/JsiSkottieFactory.h @@ -5,14 +5,17 @@ #include +#include "JsiSkNativeObjects.h" #include "JsiSkSkottie.h" namespace RNSkia { namespace jsi = facebook::jsi; -class JsiSkottieFactory : public JsiSkHostObject { +class JsiSkottieFactory : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "SkottieFactory"; + JSI_HOST_FUNCTION(Make) { auto fontMgr = JsiSkFontMgrFactory::getFontMgr(getContext()); auto json = arguments[0].asString(runtime).utf8(runtime); @@ -34,13 +37,10 @@ class JsiSkottieFactory : public JsiSkHostObject { auto jsObject = jsValue.asObject(runtime); // Check if the object is a SkData host object - if (jsObject.isHostObject(runtime)) { - auto hostObject = jsObject.getHostObject(runtime); - auto skData = std::dynamic_pointer_cast(hostObject); - if (skData) { - std::string k = key; - assets[k] = skData->getObject(); - } + auto skData = tryGetJsiObject(runtime, jsObject); + if (skData) { + std::string k = key; + assets[k] = skData->getObject(); } } } @@ -51,20 +51,19 @@ class JsiSkottieFactory : public JsiSkHostObject { if (!managedAnimation->_animation) { return jsi::Value::null(); } - auto skottie = std::make_shared(getContext(), - std::move(managedAnimation)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, skottie, - getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), + std::move(managedAnimation))); } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkottieFactory, Make)) - - size_t getMemoryPressure() const override { return 4096; } + size_t getMemoryPressure() override { return 4096; } - std::string getObjectType() const override { return "JsiSkottieFactory"; } + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "Make", &JsiSkottieFactory::Make); + } explicit JsiSkottieFactory(std::shared_ptr context) - : JsiSkHostObject(std::move(context)) {} + : JsiSkNativeObject(std::move(context)) {} }; } // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiVideo.h b/packages/skia/cpp/api/JsiVideo.h index 6205ba44a6..896300d5c2 100644 --- a/packages/skia/cpp/api/JsiVideo.h +++ b/packages/skia/cpp/api/JsiVideo.h @@ -5,7 +5,7 @@ #include #include -#include "JsiSkHostObjects.h" +#include "JsiSkNativeObjects.h" #include "utils/RNSkLog.h" #include @@ -28,9 +28,10 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiVideo : public JsiSkWrappingSharedPtrHostObject { +class JsiVideo + : public JsiSkWrappingSharedPtrNativeObject { public: - EXPORT_JSI_API_TYPENAME(JsiVideo, Video) + static constexpr const char *CLASS_NAME = "Video"; JSI_HOST_FUNCTION(nextImage) { double timestamp = 0; @@ -39,10 +40,8 @@ class JsiVideo : public JsiSkWrappingSharedPtrHostObject { if (!image) { return jsi::Value::null(); } - auto hostObjectInstance = - std::make_shared(getContext(), std::move(image)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE( - runtime, hostObjectInstance, getContext()); + return makeJsiObject( + runtime, std::make_shared(getContext(), std::move(image))); } JSI_HOST_FUNCTION(duration) { return getObject()->duration(); } @@ -96,24 +95,29 @@ class JsiVideo : public JsiSkWrappingSharedPtrHostObject { return jsi::Value::undefined(); } - JSI_EXPORT_FUNCTIONS( - JSI_EXPORT_FUNC(JsiVideo, nextImage), JSI_EXPORT_FUNC(JsiVideo, duration), - JSI_EXPORT_FUNC(JsiVideo, framerate), - JSI_EXPORT_FUNC(JsiVideo, currentTime), - JSI_EXPORT_FUNC(JsiVideo, isPlaying), JSI_EXPORT_FUNC(JsiVideo, seek), - JSI_EXPORT_FUNC(JsiVideo, rotation), JSI_EXPORT_FUNC(JsiVideo, size), - JSI_EXPORT_FUNC(JsiVideo, play), JSI_EXPORT_FUNC(JsiVideo, pause), - JSI_EXPORT_FUNC(JsiVideo, setVolume), - JSI_EXPORT_FUNC(JsiVideo, setLooping), JSI_EXPORT_FUNC(JsiVideo, dispose)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "nextImage", &JsiVideo::nextImage); + installHostMethod(runtime, prototype, "duration", &JsiVideo::duration); + installHostMethod(runtime, prototype, "framerate", &JsiVideo::framerate); + installHostMethod(runtime, prototype, "currentTime", + &JsiVideo::currentTime); + installHostMethod(runtime, prototype, "isPlaying", &JsiVideo::isPlaying); + installHostMethod(runtime, prototype, "seek", &JsiVideo::seek); + installHostMethod(runtime, prototype, "rotation", &JsiVideo::rotation); + installHostMethod(runtime, prototype, "size", &JsiVideo::size); + installHostMethod(runtime, prototype, "play", &JsiVideo::play); + installHostMethod(runtime, prototype, "pause", &JsiVideo::pause); + installHostMethod(runtime, prototype, "setVolume", &JsiVideo::setVolume); + installHostMethod(runtime, prototype, "setLooping", &JsiVideo::setLooping); + } JsiVideo(std::shared_ptr context, std::shared_ptr video) - : JsiSkWrappingSharedPtrHostObject(std::move(context), std::move(video)) { - } - - size_t getMemoryPressure() const override { return 32768; } + : JsiSkWrappingSharedPtrNativeObject( + std::move(context), std::move(video)) {} - std::string getObjectType() const override { return "JsiVideo"; } + size_t getMemoryPressure() override { return 32768; } /** * Creates the function for construction a new instance of the SkFont @@ -128,10 +132,8 @@ class JsiVideo : public JsiSkWrappingSharedPtrHostObject { auto url = arguments[0].asString(runtime).utf8(runtime); auto video = context->createVideo(url); // Return the newly constructed object - auto videoObj = - std::make_shared(std::move(context), std::move(video)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, videoObj, - context); + return makeJsiObject(runtime, std::make_shared( + std::move(context), std::move(video))); }; } }; diff --git a/packages/skia/cpp/api/recorder/Convertor.h b/packages/skia/cpp/api/recorder/Convertor.h index 0e58c16e4e..6f15f3d904 100644 --- a/packages/skia/cpp/api/recorder/Convertor.h +++ b/packages/skia/cpp/api/recorder/Convertor.h @@ -394,8 +394,7 @@ SkSamplingOptions getPropertyValue(jsi::Runtime &runtime, template <> SkFont getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { if (value.isObject()) { - auto font = - value.asObject(runtime).asHostObject(runtime)->getObject(); + auto font = getJsiObject(runtime, value)->getObject(); return SkFont(*font); } throw std::runtime_error("Invalid prop value for SkFont received"); @@ -427,9 +426,7 @@ GlyphData getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { template <> SkRSXform getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { if (value.isObject()) { - auto form = value.asObject(runtime) - .asHostObject(runtime) - ->getObject(); + auto form = getJsiObject(runtime, value)->getObject(); return SkRSXform::Make(form->fSCos, form->fSSin, form->fTx, form->fTy); } throw std::runtime_error("Invalid prop value for SkRSXform received"); @@ -438,13 +435,11 @@ SkRSXform getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { template <> sk_sp getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { - if (value.isObject() && value.asObject(runtime).isHostObject(runtime)) { - auto ptr = std::dynamic_pointer_cast( - value.asObject(runtime).asHostObject(runtime)); - if (ptr != nullptr) { - return ptr->getObject(); - } - } else if (value.isNull()) { + auto ptr = tryGetJsiObject(runtime, value); + if (ptr != nullptr) { + return ptr->getObject(); + } + if (value.isNull()) { return nullptr; } throw std::runtime_error( @@ -454,13 +449,11 @@ sk_sp getPropertyValue(jsi::Runtime &runtime, template <> sk_sp getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { - if (value.isObject() && value.asObject(runtime).isHostObject(runtime)) { - auto ptr = std::dynamic_pointer_cast( - value.asObject(runtime).asHostObject(runtime)); - if (ptr != nullptr) { - return ptr->getObject()->_animation; - } - } else if (value.isNull()) { + auto ptr = tryGetJsiObject(runtime, value); + if (ptr != nullptr) { + return ptr->getObject()->_animation; + } + if (value.isNull()) { return nullptr; } throw std::runtime_error( @@ -470,13 +463,11 @@ sk_sp getPropertyValue(jsi::Runtime &runtime, template <> sk_sp getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { - if (value.isObject() && value.asObject(runtime).isHostObject(runtime)) { - auto ptr = std::dynamic_pointer_cast( - value.asObject(runtime).asHostObject(runtime)); - if (ptr != nullptr) { - return ptr->getObject(); - } - } else if (value.isNull()) { + auto ptr = tryGetJsiObject(runtime, value); + if (ptr != nullptr) { + return ptr->getObject(); + } + if (value.isNull()) { return nullptr; } throw std::runtime_error( @@ -487,9 +478,7 @@ template <> sk_sp getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { if (value.isObject()) { - auto picture = value.asObject(runtime) - .asHostObject(runtime) - ->getObject(); + auto picture = getJsiObject(runtime, value)->getObject(); return picture; } throw std::runtime_error("Invalid prop value for SkTextBlob received"); @@ -498,8 +487,7 @@ sk_sp getPropertyValue(jsi::Runtime &runtime, template <> SkPaint getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { if (value.isObject()) { - auto paint = - value.asObject(runtime).asHostObject(runtime)->getObject(); + auto paint = getJsiObject(runtime, value)->getObject(); return SkPaint(*paint); } throw std::runtime_error("Invalid prop value for SkPaint received"); @@ -508,28 +496,15 @@ SkPaint getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { template <> std::shared_ptr getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { - if (value.isObject()) { - auto hostObject = value.asObject(runtime).asHostObject(runtime); - if (!hostObject) { - return nullptr; - } - auto para = std::dynamic_pointer_cast(hostObject); - if (!para) { - return nullptr; - } - // Return a shared_ptr instead of raw pointer - return para; - } - return nullptr; + // Return a shared_ptr instead of raw pointer + return tryGetJsiObject(runtime, value); } template <> sk_sp getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { if (value.isObject()) { - auto blob = value.asObject(runtime) - .asHostObject(runtime) - ->getObject(); + auto blob = getJsiObject(runtime, value)->getObject(); return blob; } throw std::runtime_error("Invalid prop value for SkTextBlob received"); @@ -539,9 +514,7 @@ template <> sk_sp getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { if (value.isObject()) { - auto effect = value.asObject(runtime) - .asHostObject(runtime) - ->getObject(); + auto effect = getJsiObject(runtime, value)->getObject(); return effect; } throw std::runtime_error("Invalid prop value for SkRuntimeEffect received"); @@ -552,8 +525,7 @@ sk_sp getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { if (value.isObject()) { - auto effect = - value.asObject(runtime).asHostObject(runtime)->getObject(); + auto effect = getJsiObject(runtime, value)->getObject(); return effect; } else if (value.isNull()) { return nullptr; @@ -564,11 +536,9 @@ sk_sp getPropertyValue(jsi::Runtime &runtime, template <> SkMatrix getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { if (value.isObject()) { - auto object = value.asObject(runtime); - - if (object.isHostObject(runtime)) { - auto matrix = - object.asHostObject(runtime)->getObject().get(); + auto ptr = tryGetJsiObject(runtime, value); + if (ptr != nullptr) { + auto matrix = ptr->getObject().get(); return SkMatrix(*matrix); } else { return JsiSkMatrix::getMatrix(runtime, value); @@ -1008,10 +978,10 @@ Layer getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) { if (value.isBool()) { Layer layer = value.asBool(); return layer; - } else if (value.isObject() && - value.asObject(runtime).isHostObject(runtime)) { - auto paint = - value.asObject(runtime).asHostObject(runtime)->getObject(); + } + auto ptr = tryGetJsiObject(runtime, value); + if (ptr != nullptr) { + auto paint = ptr->getObject(); Layer layer = SkPaint(*paint); return layer; } diff --git a/packages/skia/cpp/api/recorder/DataTypes.h b/packages/skia/cpp/api/recorder/DataTypes.h index 494920502f..ab4e745dd0 100644 --- a/packages/skia/cpp/api/recorder/DataTypes.h +++ b/packages/skia/cpp/api/recorder/DataTypes.h @@ -51,12 +51,9 @@ std::shared_ptr processRect(jsi::Runtime &runtime, const jsi::Value &value) { if (value.isObject()) { auto object = value.asObject(runtime); - if (object.isHostObject(runtime)) { - auto ptr = std::dynamic_pointer_cast( - value.asObject(runtime).asHostObject(runtime)); - if (ptr != nullptr) { - return ptr->getObject(); - } + auto ptr = tryGetJsiObject(runtime, object); + if (ptr != nullptr) { + return ptr->getObject(); } else if (object.hasProperty(runtime, "x") && object.hasProperty(runtime, "y") && object.hasProperty(runtime, "width") && @@ -88,12 +85,9 @@ std::shared_ptr processRRect(jsi::Runtime &runtime, const jsi::Value &value) { if (value.isObject()) { auto object = value.asObject(runtime); - if (object.isHostObject(runtime)) { - auto ptr = std::dynamic_pointer_cast( - value.asObject(runtime).asHostObject(runtime)); - if (ptr != nullptr) { - return ptr->getObject(); - } + auto ptr = tryGetJsiObject(runtime, object); + if (ptr != nullptr) { + return ptr->getObject(); } else if (object.hasProperty(runtime, "rect") && object.hasProperty(runtime, "rx") && object.hasProperty(runtime, "ry")) { @@ -136,10 +130,8 @@ std::shared_ptr processPath(jsi::Runtime &runtime, } else { throw std::runtime_error("Could not parse path from string."); } - } else if (value.isObject() && - value.asObject(runtime).isHostObject(runtime)) { - auto ptr = std::dynamic_pointer_cast( - value.asObject(runtime).asHostObject(runtime)); + } else { + auto ptr = tryGetJsiObject(runtime, value); if (ptr != nullptr) { return std::make_shared(ptr->getObject()->snapshot()); } diff --git a/packages/skia/cpp/api/recorder/JsiRecorder.h b/packages/skia/cpp/api/recorder/JsiRecorder.h index 742eebacc9..04139e4080 100644 --- a/packages/skia/cpp/api/recorder/JsiRecorder.h +++ b/packages/skia/cpp/api/recorder/JsiRecorder.h @@ -6,7 +6,7 @@ #include #include "api/JsiSkCanvas.h" -#include "api/JsiSkHostObjects.h" +#include "api/JsiSkNativeObjects.h" #include "api/JsiSkPicture.h" #include "DrawingCtx.h" @@ -19,11 +19,14 @@ namespace RNSkia { namespace jsi = facebook::jsi; -class JsiRecorder : public JsiSkWrappingSharedPtrHostObject { +class JsiRecorder + : public JsiSkWrappingSharedPtrNativeObject { public: + static constexpr const char *CLASS_NAME = "Recorder"; + JsiRecorder(std::shared_ptr context) - : JsiSkWrappingSharedPtrHostObject(std::move(context), - std::make_shared()) { + : JsiSkWrappingSharedPtrNativeObject( + std::move(context), std::make_shared()) { getObject()->_context = getContext(); } @@ -61,7 +64,8 @@ class JsiRecorder : public JsiSkWrappingSharedPtrHostObject { // Get the JsiSkPicture from the argument auto pictureObject = arguments[0].asObject(runtime); - auto pictureHostObject = pictureObject.asHostObject(runtime); + auto pictureHostObject = + tryGetJsiObject(runtime, pictureObject); if (!pictureHostObject) { throw jsi::JSError(runtime, "Invalid Picture object provided to play()"); } @@ -302,65 +306,89 @@ class JsiRecorder : public JsiSkWrappingSharedPtrHostObject { return jsi::Value::undefined(); } - EXPORT_JSI_API_TYPENAME(JsiRecorder, Recorder) - - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiRecorder, saveGroup), - JSI_EXPORT_FUNC(JsiRecorder, restoreGroup), - JSI_EXPORT_FUNC(JsiRecorder, savePaint), - JSI_EXPORT_FUNC(JsiRecorder, restorePaint), - JSI_EXPORT_FUNC(JsiRecorder, restorePaintDeclaration), - JSI_EXPORT_FUNC(JsiRecorder, materializePaint), - JSI_EXPORT_FUNC(JsiRecorder, pushPathEffect), - JSI_EXPORT_FUNC(JsiRecorder, pushImageFilter), - JSI_EXPORT_FUNC(JsiRecorder, pushColorFilter), - JSI_EXPORT_FUNC(JsiRecorder, pushShader), - JSI_EXPORT_FUNC(JsiRecorder, pushBlurMaskFilter), - JSI_EXPORT_FUNC(JsiRecorder, composePathEffect), - JSI_EXPORT_FUNC(JsiRecorder, composeColorFilter), - JSI_EXPORT_FUNC(JsiRecorder, composeImageFilter), - JSI_EXPORT_FUNC(JsiRecorder, saveCTM), - JSI_EXPORT_FUNC(JsiRecorder, restoreCTM), - JSI_EXPORT_FUNC(JsiRecorder, drawPaint), - JSI_EXPORT_FUNC(JsiRecorder, saveLayer), - JSI_EXPORT_FUNC(JsiRecorder, saveBackdropFilter), - JSI_EXPORT_FUNC(JsiRecorder, drawBox), - JSI_EXPORT_FUNC(JsiRecorder, drawImage), - JSI_EXPORT_FUNC(JsiRecorder, drawCircle), - JSI_EXPORT_FUNC(JsiRecorder, drawPoints), - JSI_EXPORT_FUNC(JsiRecorder, drawPath), - JSI_EXPORT_FUNC(JsiRecorder, drawRect), - JSI_EXPORT_FUNC(JsiRecorder, drawRRect), - JSI_EXPORT_FUNC(JsiRecorder, drawOval), - JSI_EXPORT_FUNC(JsiRecorder, drawLine), - JSI_EXPORT_FUNC(JsiRecorder, drawPatch), - JSI_EXPORT_FUNC(JsiRecorder, drawVertices), - JSI_EXPORT_FUNC(JsiRecorder, drawDiffRect), - JSI_EXPORT_FUNC(JsiRecorder, drawText), - JSI_EXPORT_FUNC(JsiRecorder, drawTextPath), - JSI_EXPORT_FUNC(JsiRecorder, drawTextBlob), - JSI_EXPORT_FUNC(JsiRecorder, drawGlyphs), - JSI_EXPORT_FUNC(JsiRecorder, drawPicture), - JSI_EXPORT_FUNC(JsiRecorder, drawImageSVG), - JSI_EXPORT_FUNC(JsiRecorder, drawParagraph), - JSI_EXPORT_FUNC(JsiRecorder, drawAtlas), - JSI_EXPORT_FUNC(JsiRecorder, drawSkottie), - JSI_EXPORT_FUNC(JsiRecorder, play), - JSI_EXPORT_FUNC(JsiRecorder, applyUpdates), - JSI_EXPORT_FUNC(JsiRecorder, reset)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installCommon(runtime, prototype); + installHostMethod(runtime, prototype, "saveGroup", &JsiRecorder::saveGroup); + installHostMethod(runtime, prototype, "restoreGroup", + &JsiRecorder::restoreGroup); + installHostMethod(runtime, prototype, "savePaint", &JsiRecorder::savePaint); + installHostMethod(runtime, prototype, "restorePaint", + &JsiRecorder::restorePaint); + installHostMethod(runtime, prototype, "restorePaintDeclaration", + &JsiRecorder::restorePaintDeclaration); + installHostMethod(runtime, prototype, "materializePaint", + &JsiRecorder::materializePaint); + installHostMethod(runtime, prototype, "pushPathEffect", + &JsiRecorder::pushPathEffect); + installHostMethod(runtime, prototype, "pushImageFilter", + &JsiRecorder::pushImageFilter); + installHostMethod(runtime, prototype, "pushColorFilter", + &JsiRecorder::pushColorFilter); + installHostMethod(runtime, prototype, "pushShader", + &JsiRecorder::pushShader); + installHostMethod(runtime, prototype, "pushBlurMaskFilter", + &JsiRecorder::pushBlurMaskFilter); + installHostMethod(runtime, prototype, "composePathEffect", + &JsiRecorder::composePathEffect); + installHostMethod(runtime, prototype, "composeColorFilter", + &JsiRecorder::composeColorFilter); + installHostMethod(runtime, prototype, "composeImageFilter", + &JsiRecorder::composeImageFilter); + installHostMethod(runtime, prototype, "saveCTM", &JsiRecorder::saveCTM); + installHostMethod(runtime, prototype, "restoreCTM", + &JsiRecorder::restoreCTM); + installHostMethod(runtime, prototype, "drawPaint", &JsiRecorder::drawPaint); + installHostMethod(runtime, prototype, "saveLayer", &JsiRecorder::saveLayer); + installHostMethod(runtime, prototype, "saveBackdropFilter", + &JsiRecorder::saveBackdropFilter); + installHostMethod(runtime, prototype, "drawBox", &JsiRecorder::drawBox); + installHostMethod(runtime, prototype, "drawImage", &JsiRecorder::drawImage); + installHostMethod(runtime, prototype, "drawCircle", + &JsiRecorder::drawCircle); + installHostMethod(runtime, prototype, "drawPoints", + &JsiRecorder::drawPoints); + installHostMethod(runtime, prototype, "drawPath", &JsiRecorder::drawPath); + installHostMethod(runtime, prototype, "drawRect", &JsiRecorder::drawRect); + installHostMethod(runtime, prototype, "drawRRect", &JsiRecorder::drawRRect); + installHostMethod(runtime, prototype, "drawOval", &JsiRecorder::drawOval); + installHostMethod(runtime, prototype, "drawLine", &JsiRecorder::drawLine); + installHostMethod(runtime, prototype, "drawPatch", &JsiRecorder::drawPatch); + installHostMethod(runtime, prototype, "drawVertices", + &JsiRecorder::drawVertices); + installHostMethod(runtime, prototype, "drawDiffRect", + &JsiRecorder::drawDiffRect); + installHostMethod(runtime, prototype, "drawText", &JsiRecorder::drawText); + installHostMethod(runtime, prototype, "drawTextPath", + &JsiRecorder::drawTextPath); + installHostMethod(runtime, prototype, "drawTextBlob", + &JsiRecorder::drawTextBlob); + installHostMethod(runtime, prototype, "drawGlyphs", + &JsiRecorder::drawGlyphs); + installHostMethod(runtime, prototype, "drawPicture", + &JsiRecorder::drawPicture); + installHostMethod(runtime, prototype, "drawImageSVG", + &JsiRecorder::drawImageSVG); + installHostMethod(runtime, prototype, "drawParagraph", + &JsiRecorder::drawParagraph); + installHostMethod(runtime, prototype, "drawAtlas", &JsiRecorder::drawAtlas); + installHostMethod(runtime, prototype, "drawSkottie", + &JsiRecorder::drawSkottie); + installHostMethod(runtime, prototype, "play", &JsiRecorder::play); + installHostMethod(runtime, prototype, "applyUpdates", + &JsiRecorder::applyUpdates); + installHostMethod(runtime, prototype, "reset", &JsiRecorder::reset); + } // This has no basis in reality but since since these are private long-lived // objects, we think it is more than fine. - size_t getMemoryPressure() const override { return 5 * 1024 * 1024; } - - std::string getObjectType() const override { return "JsiRecorder"; } + size_t getMemoryPressure() override { return 5 * 1024 * 1024; } static const jsi::HostFunctionType createCtor(std::shared_ptr context) { return JSI_HOST_FUNCTION_LAMBDA { // Return the newly constructed object auto recorder = std::make_shared(std::move(context)); - return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(runtime, recorder, - context); + return makeJsiObject(runtime, std::move(recorder)); }; } }; diff --git a/packages/skia/cpp/api/recorder/RNRecorder.h b/packages/skia/cpp/api/recorder/RNRecorder.h index 18a4ef7300..2cb0b440f5 100644 --- a/packages/skia/cpp/api/recorder/RNRecorder.h +++ b/packages/skia/cpp/api/recorder/RNRecorder.h @@ -17,8 +17,8 @@ #include "ImageFilters.h" #include "Paint.h" #include "PathEffects.h" -#include "rnskia/RNSkPlatformContext.h" #include "Shaders.h" +#include "rnskia/RNSkPlatformContext.h" namespace RNSkia { diff --git a/packages/skia/cpp/jsi/BoxedNativeObject.h b/packages/skia/cpp/jsi/BoxedNativeObject.h new file mode 100644 index 0000000000..b222a3f9a9 --- /dev/null +++ b/packages/skia/cpp/jsi/BoxedNativeObject.h @@ -0,0 +1,146 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace RNJsi { + +namespace jsi = facebook::jsi; + +/** + * Registry mapping a NativeObject class brand (CLASS_NAME) to a reconstructor + * that can recreate a fully functional JS object (prototype + native state) + * on any runtime. This is what enables native objects (Skia and WebGPU) to + * travel between the React Native runtime and secondary runtimes (Reanimated + * worklets) via BoxedNativeObject. + */ +class BoxedNativeObjectRegistry { +public: + using Reconstructor = std::function)>; + + static BoxedNativeObjectRegistry &getInstance() { + static BoxedNativeObjectRegistry instance; + return instance; + } + + void registerClass(const std::string &brand, Reconstructor reconstructor) { + std::lock_guard lock(_mutex); + // Brands are the unboxing key and must be unique process-wide; a silent + // overwrite would make one class unbox into another's reconstructor. + if (_reconstructors.count(brand) > 0) { + throw std::runtime_error("Duplicate native object brand registered: " + + brand); + } + _reconstructors[brand] = std::move(reconstructor); + } + + jsi::Value reconstruct(jsi::Runtime &runtime, const std::string &brand, + std::shared_ptr state) { + Reconstructor reconstructor; + { + std::lock_guard lock(_mutex); + auto it = _reconstructors.find(brand); + if (it == _reconstructors.end()) { + throw jsi::JSError(runtime, + "No native class registered for brand: " + brand); + } + reconstructor = it->second; + } + return reconstructor(runtime, std::move(state)); + } + +private: + BoxedNativeObjectRegistry() = default; + std::mutex _mutex; + std::unordered_map _reconstructors; +}; + +/** + * HostObject bridge used to move NativeObjects between runtimes. + * + * NativeObject-based values are plain JS objects carrying jsi::NativeState; + * worklets cannot serialize their prototype, so they are "boxed" into this + * HostObject (which worklets pass across runtimes by reference) and unboxed + * on the target runtime, where the prototype is re-installed from the class + * registry. See registerCustomSerializable in + * src/skia/SkiaWorkletSerialization.ts. + */ +class BoxedNativeObject : public jsi::HostObject { +public: + BoxedNativeObject(std::shared_ptr state, std::string brand) + : _state(std::move(state)), _brand(std::move(brand)) {} + + jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override { + auto propName = name.utf8(runtime); + if (propName == "unbox") { + auto state = _state; + auto brand = _brand; + return jsi::Function::createFromHostFunction( + runtime, jsi::PropNameID::forUtf8(runtime, "unbox"), 0, + [state, brand](jsi::Runtime &rt, const jsi::Value &, + const jsi::Value *, size_t) -> jsi::Value { + return BoxedNativeObjectRegistry::getInstance().reconstruct( + rt, brand, state); + }); + } + if (propName == "__boxedNativeObject") { + return jsi::Value(true); + } + if (propName == "__brand") { + return jsi::String::createFromUtf8(runtime, _brand); + } + return jsi::Value::undefined(); + } + + void set(jsi::Runtime &runtime, const jsi::PropNameID &, + const jsi::Value &) override { + throw jsi::JSError(runtime, "Boxed native objects are read-only"); + } + + std::vector getPropertyNames(jsi::Runtime &rt) override { + std::vector names; + names.reserve(3); + names.push_back(jsi::PropNameID::forUtf8(rt, "unbox")); + names.push_back(jsi::PropNameID::forUtf8(rt, "__boxedNativeObject")); + names.push_back(jsi::PropNameID::forUtf8(rt, "__brand")); + return names; + } + +private: + std::shared_ptr _state; + std::string _brand; +}; + +/** + * Boxes a NativeObject-backed JS value so it can be serialized by worklets + * and unboxed on another runtime. + */ +inline jsi::Value boxNativeObject(jsi::Runtime &runtime, + const jsi::Value &value) { + if (!value.isObject()) { + throw jsi::JSError(runtime, "box() expects a native object"); + } + auto object = value.asObject(runtime); + if (!object.hasNativeState(runtime)) { + throw jsi::JSError(runtime, "box() expects a native object"); + } + auto brand = object.getProperty(runtime, "__typename__"); + if (!brand.isString()) { + throw jsi::JSError(runtime, "box() expects a native object"); + } + return jsi::Object::createFromHostObject( + runtime, std::make_shared( + object.getNativeState(runtime), + brand.asString(runtime).utf8(runtime))); +} + +} // namespace RNJsi diff --git a/packages/skia/cpp/jsi2/EnumMapper.h b/packages/skia/cpp/jsi/EnumMapper.h similarity index 89% rename from packages/skia/cpp/jsi2/EnumMapper.h rename to packages/skia/cpp/jsi/EnumMapper.h index c661e1b688..aec155b381 100644 --- a/packages/skia/cpp/jsi2/EnumMapper.h +++ b/packages/skia/cpp/jsi/EnumMapper.h @@ -12,7 +12,10 @@ namespace EnumMapper { // outEnum)` // 2. `static void convertEnumToJSUnion(Enum inEnum, std::string* outUnion)` -static std::runtime_error invalidUnion(const std::string &passedUnion) { +// inline (not static): this header is now included by every TU via +// NativeObject.h, and an unused file-scope static would trip +// -Werror=unused-function in non-Graphite builds. +inline std::runtime_error invalidUnion(const std::string &passedUnion) { return std::runtime_error( "Cannot convert JS Value to Enum: Invalid Union value passed! (\"" + std::string(passedUnion) + "\")"); diff --git a/packages/skia/cpp/jsi2/JSIConverter.h b/packages/skia/cpp/jsi/JSIConverter.h similarity index 100% rename from packages/skia/cpp/jsi2/JSIConverter.h rename to packages/skia/cpp/jsi/JSIConverter.h diff --git a/packages/skia/cpp/jsi/JsiHostObject.cpp b/packages/skia/cpp/jsi/JsiHostObject.cpp deleted file mode 100644 index 4c4ee26f61..0000000000 --- a/packages/skia/cpp/jsi/JsiHostObject.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include "JsiHostObject.h" -#include -#include - -namespace RNJsi { - -void JsiHostObject::set(jsi::Runtime &rt, const jsi::PropNameID &name, - const jsi::Value &value) { - - auto nameStr = name.utf8(rt); - - /** Check the static setters map */ - const JsiPropertySettersMap &setters = getExportedPropertySettersMap(); - auto setter = setters.find(nameStr); - if (setter != setters.end()) { - auto dispatcher = std::bind(setter->second, this, std::placeholders::_1, - std::placeholders::_2); - return dispatcher(rt, value); - } - - if (_propMap.count(nameStr) > 0) { - auto prop = _propMap.at(nameStr); - (prop.set)(rt, value); - } -} - -jsi::Value JsiHostObject::get(jsi::Runtime &runtime, - const jsi::PropNameID &name) { - auto nameStr = name.utf8(runtime); - - // Happy path - cached host functions are cheapest to look up - const JsiFunctionMap &funcs = getExportedFunctionMap(); - auto func = funcs.find(nameStr); - - // Check function cache - if (func != funcs.end()) { - std::map &runtimeCache = - _hostFunctionCache.get(runtime); - auto cachedFunc = runtimeCache.find(nameStr); - if (cachedFunc != runtimeCache.end()) { - return cachedFunc->second.asFunction(runtime); - } - } - - // Check the static getters map - const JsiPropertyGettersMap &getters = getExportedPropertyGettersMap(); - auto getter = getters.find(nameStr); - if (getter != getters.end()) { - auto dispatcher = std::bind(getter->second, this, std::placeholders::_1); - return dispatcher(runtime); - } - - // Check the static function map - if (func != funcs.end()) { - - // Create dispatcher - auto dispatcher = - std::bind(func->second, reinterpret_cast(this), - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4); - - // Add to cache - it is important to cache the results from the - // createFromHostFunction function which takes some time. - return _hostFunctionCache.get(runtime) - .emplace(nameStr, jsi::Function::createFromHostFunction(runtime, name, - 0, dispatcher)) - .first->second.asFunction(runtime); - } - - if (_funcMap.count(nameStr) > 0) { - return jsi::Function::createFromHostFunction(runtime, name, 0, - _funcMap.at(nameStr)); - } - - if (_propMap.count(nameStr) > 0) { - auto prop = _propMap.at(nameStr); - return (prop.get)(runtime); - } - - // Check for dispose symbol as last resort - static const auto disposeSymbol = jsi::PropNameID::forSymbol( - runtime, - runtime.global() - .getPropertyAsObject(runtime, "Symbol") - .getPropertyAsFunction(runtime, "for") - .call(runtime, "Symbol.dispose") - .getSymbol(runtime)); - if (jsi::PropNameID::compare(runtime, disposeSymbol, name)) { - // Recursively call get with "dispose" string - auto disposeName = jsi::PropNameID::forAscii(runtime, "dispose"); - return get(runtime, disposeName); - } - - return jsi::Value::undefined(); -} - -std::vector -JsiHostObject::getPropertyNames(jsi::Runtime &runtime) { - // statically exported functions - const auto &funcs = getExportedFunctionMap(); - - // Statically exported property getters - const auto &getters = getExportedPropertyGettersMap(); - - // Statically exported property setters - const auto &setters = getExportedPropertySettersMap(); - - std::vector propNames; - propNames.reserve(funcs.size() + getters.size() + setters.size() + - _funcMap.size() + _propMap.size()); - - for (auto it = funcs.cbegin(); it != funcs.cend(); ++it) { - propNames.push_back(jsi::PropNameID::forAscii(runtime, it->first)); - } - - for (auto it = getters.cbegin(); it != getters.cend(); ++it) { - propNames.push_back(jsi::PropNameID::forUtf8(runtime, it->first)); - } - - for (auto it = getters.cbegin(); it != getters.cend(); ++it) { - if (getters.count(it->first) == 0) { - propNames.push_back(jsi::PropNameID::forUtf8(runtime, it->first)); - } - } - - // functions - for (auto it = _funcMap.cbegin(); it != _funcMap.cend(); ++it) { - propNames.push_back(jsi::PropNameID::forAscii(runtime, it->first)); - } - // props - for (auto it = _propMap.cbegin(); it != _propMap.cend(); ++it) { - propNames.push_back(jsi::PropNameID::forAscii(runtime, it->first)); - } - return propNames; -} - -} // namespace RNJsi diff --git a/packages/skia/cpp/jsi/JsiHostObject.h b/packages/skia/cpp/jsi/JsiHostObject.h deleted file mode 100644 index 93e71c0280..0000000000 --- a/packages/skia/cpp/jsi/JsiHostObject.h +++ /dev/null @@ -1,385 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include -#include -#include - -#include "RuntimeAwareCache.h" - -#define STR_CAT_NX(A, B) A##B -#define STR_CAT(A, B) STR_CAT_NX(A, B) -#define STR_GET get_ -#define STR_SET set_ - -/** - * Creates a new Host function declaration as a lambda with all deps passed - * with implicit lambda capture clause - */ -#define JSI_HOST_FUNCTION_LAMBDA \ - [=](jsi::Runtime & runtime, const jsi::Value &thisValue, \ - const jsi::Value *arguments, size_t count) -> jsi::Value - -/** - * Creates a new Host function declaration - */ -#define JSI_HOST_FUNCTION(NAME) \ - jsi::Value NAME(jsi::Runtime &runtime, const jsi::Value &thisValue, \ - const jsi::Value *arguments, size_t count) - -/** - * Creates a new property setter function declaration - */ -#define JSI_PROPERTY_SET(NAME) \ - void STR_CAT(STR_SET, NAME)(jsi::Runtime & runtime, const jsi::Value &value) - -/** - * Creates a new property getter function declaration - */ -#define JSI_PROPERTY_GET(NAME) \ - jsi::Value STR_CAT(STR_GET, NAME)(jsi::Runtime & runtime) - -/** - * Creates a JSI export function declaration - */ -#define JSI_EXPORT_FUNC(CLASS, FUNCTION) \ - {#FUNCTION, (jsi::Value(JsiHostObject::*)( \ - jsi::Runtime & runtime, const jsi::Value &thisValue, \ - const jsi::Value *arguments, size_t)) & \ - CLASS::FUNCTION} - -/** - * Creates a JSI export functions statement - */ -#define JSI_EXPORT_FUNCTIONS(...) \ - const RNJsi::JsiFunctionMap &getExportedFunctionMap() override { \ - static RNJsi::JsiFunctionMap map = {__VA_ARGS__}; \ - return map; \ - } - -/** - * Creates a JSI export getter declaration - */ -#define JSI_EXPORT_PROP_GET(CLASS, FUNCTION) \ - {#FUNCTION, (jsi::Value(JsiHostObject::*)(jsi::Runtime & runtime)) & \ - CLASS::STR_CAT(STR_GET, FUNCTION)} - -/** - * Creates a JSI export getters statement - */ -#define JSI_EXPORT_PROPERTY_GETTERS(...) \ - const RNJsi::JsiPropertyGettersMap &getExportedPropertyGettersMap() \ - override { \ - static RNJsi::JsiPropertyGettersMap map = {__VA_ARGS__}; \ - return map; \ - } - -/** - * Creates a JSI export setter declaration - */ -#define JSI_EXPORT_PROP_SET(CLASS, FUNCTION) \ - {#FUNCTION, \ - (void(JsiHostObject::*)(jsi::Runtime & runtime, const jsi::Value &)) & \ - CLASS::STR_CAT(STR_SET, FUNCTION)} - -/** - * Creates a JSI export setters statement - */ -#define JSI_EXPORT_PROPERTY_SETTERS(...) \ - const RNJsi::JsiPropertySettersMap &getExportedPropertySettersMap() \ - override { \ - static RNJsi::JsiPropertySettersMap map = {__VA_ARGS__}; \ - return map; \ - } - -namespace RNJsi { - -namespace jsi = facebook::jsi; - -using JsPropertyType = struct { - std::function get; - std::function set; -}; - -class JsiHostObject; - -using JsiFunctionMap = - std::unordered_map; - -using JsiPropertyGettersMap = - std::unordered_map; - -using JsiPropertySettersMap = - std::unordered_map; - -/** - * Base class for jsi host objects - */ -class JsiHostObject : public jsi::HostObject { -public: - JsiHostObject() = default; - ~JsiHostObject() = default; - - /** - * Overridden jsi::HostObject set property method - * @param rt Runtime - * @param name Name of value to set - * @param value Value to set - */ - void set(jsi::Runtime &rt, const jsi::PropNameID &name, - const jsi::Value &value) override; - - /** - * Overridden jsi::HostObject get property method. Returns functions from - * the map of functions. - * @param runtime Runtime - * @param name Name of value to get - * @return Value - */ - jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override; - - /** - * Overridden getPropertyNames from jsi::HostObject. Returns all keys in the - * function and property maps - * @param runtime Runtime - * @return List of property names - */ - std::vector getPropertyNames(jsi::Runtime &runtime) override; - -protected: - /** - Override to return map of name/functions - */ - virtual const RNJsi::JsiFunctionMap &getExportedFunctionMap() { - static const RNJsi::JsiFunctionMap empty; - return empty; - } - - /** - Override to get property getters map of name/functions - */ - virtual const JsiPropertyGettersMap &getExportedPropertyGettersMap() { - static const JsiPropertyGettersMap empty; - return empty; - } - - /** - Override to get property setters map of name/functions - */ - virtual const JsiPropertySettersMap &getExportedPropertySettersMap() { - static const JsiPropertySettersMap empty; - return empty; - } - - /** - * Installs a function into the function map - */ - void installFunction(const std::string &name, - const jsi::HostFunctionType &function) { - _funcMap.emplace(name, function); - } - - /** - * Installs a property with get/set - * @param name Name of property to install - * @param get Getter function - * @param set Setter function - */ - void installProperty( - const std::string &name, - const std::function &get, - const std::function &set) { - _propMap.emplace(name, JsPropertyType{.get = get, .set = set}); - } - - /** - * Installs a property with only getter - * @param name Name of property to install - * @param get Getter function - */ - void installReadonlyProperty( - const std::string &name, - const std::function &get) { - _propMap.emplace(name, JsPropertyType{ - .get = get, - .set = [](jsi::Runtime &, const jsi::Value &) {}, - }); - } - - /** - * Installs a property which points to a given host object - * @param name Name of property to install - * @param hostObject Object to return - */ - void installReadonlyProperty(const std::string &name, - std::shared_ptr hostObject) { - _propMap.emplace(name, JsPropertyType{ - .get = - [hostObject](jsi::Runtime &runtime) { - return jsi::Object::createFromHostObject( - runtime, hostObject); - }, - .set = [](jsi::Runtime &, const jsi::Value &) {}, - }); - } - - /** - @Returns a reference to the argument at the given position in the arguments - array. Raises an error if the index is above the number of arguments. - @param runtime jsi::Runtime - @param arguments Arguments list - @param count Number of arguments in arguments list - @param index Index of parameter to return - */ - static const jsi::Value &getArgument(jsi::Runtime &runtime, - const jsi::Value *arguments, - size_t count, size_t index) { - if (index >= count) { - throw jsi::JSError(runtime, "Argument index out of bounds."); - } - - return arguments[index]; - } - - /** - Returns argument as number or throws - */ - static double getArgumentAsNumber(jsi::Runtime &runtime, - const jsi::Value *arguments, size_t count, - size_t index) { - const jsi::Value &value = getArgument(runtime, arguments, count, index); - if (!value.isNumber()) { - throw jsi::JSError(runtime, - "Expected type number for parameter at index " + - std::to_string(index)); - } - return value.asNumber(); - } - - /** - Returns argument as bool or throws - */ - static bool getArgumentAsBool(jsi::Runtime &runtime, - const jsi::Value *arguments, size_t count, - size_t index) { - const jsi::Value &value = getArgument(runtime, arguments, count, index); - if (!value.isBool()) { - throw jsi::JSError(runtime, - "Expected type boolean for parameter at index " + - std::to_string(index)); - } - return value.getBool(); - } - - /** - Returns argument as string or throws - */ - static jsi::String getArgumentAsString(jsi::Runtime &runtime, - const jsi::Value *arguments, - size_t count, size_t index) { - const jsi::Value &value = getArgument(runtime, arguments, count, index); - if (!value.isString()) { - throw jsi::JSError(runtime, - "Expected type string for parameter at index " + - std::to_string(index)); - } - return value.asString(runtime); - } - - /** - Returns argument as object or throws - */ - static jsi::Object getArgumentAsObject(jsi::Runtime &runtime, - const jsi::Value *arguments, - size_t count, size_t index) { - const jsi::Value &value = getArgument(runtime, arguments, count, index); - if (!value.isObject()) { - throw jsi::JSError(runtime, - "Expected type object for parameter at index " + - std::to_string(index)); - } - return value.asObject(runtime); - } - - /** - Returns argument as host object or throws - */ - template - static std::shared_ptr - getArgumentAsHostObject(jsi::Runtime &runtime, const jsi::Value *arguments, - size_t count, size_t index) { - auto value = getArgumentAsObject(runtime, arguments, count, index); - if (!value.isHostObject(runtime)) { - throw jsi::JSError(runtime, - "Expected type host object for parameter at index " + - std::to_string(index)); - } - return value.asHostObject(runtime); - } - - /** - Returns argument as host object or nullptr if the value is not a valid host - object of requested type - */ - template - static std::shared_ptr - tryGetArgumentAsHostObject(jsi::Runtime &runtime, const jsi::Value *arguments, - size_t count, size_t index) { - const jsi::Value &value = getArgument(runtime, arguments, count, index); - if (!value.isObject()) { - return nullptr; - } - - auto object = value.asObject(runtime); - if (!object.isHostObject(runtime)) { - return nullptr; - } - - return object.asHostObject(runtime); - } - - /** - Returns argument as array or throws - */ - static jsi::Array getArgumentAsArray(jsi::Runtime &runtime, - const jsi::Value *arguments, - size_t count, size_t index) { - auto value = getArgumentAsObject(runtime, arguments, count, index); - if (!value.isArray(runtime)) { - throw jsi::JSError(runtime, - "Expected type array for parameter at index " + - std::to_string(index)); - } - return value.asArray(runtime); - } - - /** - Returns argument as function or throws - */ - static jsi::Object getArgumentAsFunction(jsi::Runtime &runtime, - const jsi::Value *arguments, - size_t count, size_t index) { - auto value = getArgumentAsObject(runtime, arguments, count, index); - if (!value.isFunction(runtime)) { - throw jsi::JSError(runtime, - "Expected type function for parameter at index " + - std::to_string(index)); - } - return value.asFunction(runtime); - } - -private: - std::unordered_map _funcMap; - std::unordered_map _propMap; - - RuntimeAwareCache> _hostFunctionCache; -}; -} // namespace RNJsi diff --git a/packages/skia/cpp/jsi2/NativeObject.h b/packages/skia/cpp/jsi/NativeObject.h similarity index 77% rename from packages/skia/cpp/jsi2/NativeObject.h rename to packages/skia/cpp/jsi/NativeObject.h index e41ab7d3e4..a2f8b8b536 100644 --- a/packages/skia/cpp/jsi2/NativeObject.h +++ b/packages/skia/cpp/jsi/NativeObject.h @@ -14,6 +14,7 @@ #include #include +#include "jsi/BoxedNativeObject.h" #include "jsi/RuntimeAwareCache.h" // Use Skia's RuntimeAwareCache // Forward declare to avoid circular dependency @@ -36,41 +37,6 @@ static constexpr size_t kMinMemoryPressure = 256; // Forward declaration template class NativeObject; -/** - * Registry for NativeObject prototype installers. - * This allows BoxedWebGPUObject::unbox() to install prototypes on any runtime - * by looking up the brand name and calling the appropriate installer. - */ -class NativeObjectRegistry { -public: - using InstallerFunc = std::function; - - static NativeObjectRegistry &getInstance() { - static NativeObjectRegistry instance; - return instance; - } - - void registerInstaller(const std::string &brand, InstallerFunc installer) { - std::lock_guard lock(_mutex); - _installers[brand] = std::move(installer); - } - - bool installPrototype(jsi::Runtime &runtime, const std::string &brand) { - std::lock_guard lock(_mutex); - auto it = _installers.find(brand); - if (it != _installers.end()) { - it->second(runtime); - return true; - } - return false; - } - -private: - NativeObjectRegistry() = default; - std::mutex _mutex; - std::unordered_map _installers; -}; - /** * Per-runtime cache entry for a prototype object. * Uses std::optional so the prototype is stored directly @@ -110,93 +76,6 @@ template struct StaticRuntimeAwareCache { } }; -/** - * BoxedWebGPUObject is a HostObject wrapper that holds a reference to ANY - * WebGPU NativeObject. This is used for Reanimated/Worklets serialization. - * - * Since NativeObject uses NativeState (not HostObject), Worklets can't - * serialize them directly. But Worklets CAN serialize HostObjects. - * - * This class stores: - * - The NativeState from the original object - * - The brand name for prototype reconstruction - * - * Usage pattern with registerCustomSerializable: - * - pack(): Call WebGPU.box(obj) to create a BoxedWebGPUObject (HostObject) - * - The HostObject is serialized by Worklets and transferred to UI runtime - * - unpack(): Call boxed.unbox() to get back the original object with prototype - * - * This is similar to NitroModules.box()/unbox() pattern. - */ -class BoxedWebGPUObject : public jsi::HostObject { -public: - BoxedWebGPUObject(std::shared_ptr nativeState, - const std::string &brand) - : _nativeState(std::move(nativeState)), _brand(brand) {} - - jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override { - auto propName = name.utf8(runtime); - if (propName == "unbox") { - return jsi::Function::createFromHostFunction( - runtime, jsi::PropNameID::forUtf8(runtime, "unbox"), 0, - [this](jsi::Runtime &rt, const jsi::Value & /*thisVal*/, - const jsi::Value * /*args*/, size_t /*count*/) -> jsi::Value { - // Try to get the prototype from the global constructor - auto ctor = rt.global().getProperty(rt, _brand.c_str()); - if (!ctor.isObject()) { - // Constructor doesn't exist on this runtime - install it - NativeObjectRegistry::getInstance().installPrototype(rt, _brand); - ctor = rt.global().getProperty(rt, _brand.c_str()); - } - - // Create a new object and attach the native state - jsi::Object obj(rt); - obj.setNativeState(rt, _nativeState); - - // Set the prototype if constructor exists - if (ctor.isObject()) { - auto ctorObj = ctor.getObject(rt); - auto proto = ctorObj.getProperty(rt, "prototype"); - if (proto.isObject()) { - auto objectCtor = rt.global().getPropertyAsObject(rt, "Object"); - auto setPrototypeOf = - objectCtor.getPropertyAsFunction(rt, "setPrototypeOf"); - setPrototypeOf.call(rt, obj, proto); - } - } - - return std::move(obj); - }); - } - if (propName == "__boxedWebGPU") { - return jsi::Value(true); - } - if (propName == "__brand") { - return jsi::String::createFromUtf8(runtime, _brand); - } - return jsi::Value::undefined(); - } - - void set(jsi::Runtime &runtime, const jsi::PropNameID &name, - const jsi::Value &value) override { - throw jsi::JSError(runtime, "BoxedWebGPUObject is read-only"); - } - - std::vector - getPropertyNames(jsi::Runtime &runtime) override { - std::vector names; - names.reserve(3); - names.push_back(jsi::PropNameID::forUtf8(runtime, "unbox")); - names.push_back(jsi::PropNameID::forUtf8(runtime, "__boxedWebGPU")); - names.push_back(jsi::PropNameID::forUtf8(runtime, "__brand")); - return names; - } - -private: - std::shared_ptr _nativeState; - std::string _brand; -}; - /** * Base class for native objects using the NativeState pattern. * @@ -237,6 +116,10 @@ class NativeObject : public jsi::NativeState, * Each NativeObject type has its own static cache. * Uses StaticRuntimeAwareCache to properly handle runtime lifecycle * and hot reload (where the main runtime is destroyed and recreated). + * + * Callers must hold getPrototypeCacheMutex(): the cache is reached + * concurrently from the main JS thread (create()) and from worklet + * runtime threads (BoxedNativeObject::unbox() -> installPrototype()). */ static RNJsi::RuntimeAwareCache & getPrototypeCache(jsi::Runtime &runtime) { @@ -244,11 +127,22 @@ class NativeObject : public jsi::NativeState, return cache.get(runtime); } + /** + * Per-class mutex guarding getPrototypeCache() and prototype + * installation. Serializes the StaticRuntimeAwareCache pointer swap + * (hot reload) and the per-runtime cache lookups. + */ + static std::mutex &getPrototypeCacheMutex() { + static std::mutex mutex; + return mutex; + } + /** * Ensure the prototype is installed for this runtime. * Called automatically by create(), but can be called manually. */ static void installPrototype(jsi::Runtime &runtime) { + std::lock_guard lock(getPrototypeCacheMutex()); auto &entry = getPrototypeCache(runtime).get(runtime); if (entry.prototype.has_value()) { return; // Already installed @@ -279,6 +173,95 @@ class NativeObject : public jsi::NativeState, defineProperty.call(runtime, prototype, toStringTag, descriptor); } + // Install the shared pieces every native object needs for JS type + // detection and cross-runtime transfer (worklets): + // - `__typename__` (CLASS_NAME), used by JS type guards and as the + // boxing brand + // - `__box()`, which wraps the object into a RNJsi::BoxedNativeObject + // HostObject that worklets can pass across runtimes by reference + // See registerCustomSerializable in src/skia/SkiaWorkletSerialization.ts. + prototype.setProperty( + runtime, "__typename__", + jsi::String::createFromUtf8(runtime, Derived::CLASS_NAME)); + + auto boxFunc = jsi::Function::createFromHostFunction( + runtime, jsi::PropNameID::forUtf8(runtime, "__box"), 0, + [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *, + size_t) -> jsi::Value { + return RNJsi::boxNativeObject(rt, thisValue); + }); + prototype.setProperty(runtime, "__box", boxFunc); + + // Install a generic toJSON so JSON.stringify sees the data properties. + // They live on the prototype (getters), and JSON.stringify only + // serializes *own* enumerable properties — with the legacy HostObject + // pattern all properties were reported as own, so e.g. + // JSON.stringify(rect) used to produce {x, y, width, height, + // __typename__} and now would produce {} without this. + auto toJSONFunc = jsi::Function::createFromHostFunction( + runtime, jsi::PropNameID::forUtf8(runtime, "toJSON"), 0, + [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *, + size_t) -> jsi::Value { + if (!thisValue.isObject()) { + return jsi::Value::undefined(); + } + auto self = thisValue.asObject(rt); + auto objectCtor = rt.global().getPropertyAsObject(rt, "Object"); + auto getPrototypeOf = + objectCtor.getPropertyAsFunction(rt, "getPrototypeOf"); + auto getOwnPropertyNames = + objectCtor.getPropertyAsFunction(rt, "getOwnPropertyNames"); + auto proto = getPrototypeOf.call(rt, self); + jsi::Object result(rt); + if (proto.isObject()) { + auto names = + getOwnPropertyNames.call(rt, proto).asObject(rt).asArray(rt); + auto size = names.size(rt); + for (size_t i = 0; i < size; i++) { + auto name = names.getValueAtIndex(rt, i).asString(rt).utf8(rt); + if (name == "constructor" || name == "toJSON") { + continue; + } + auto value = self.getProperty(rt, name.c_str()); + // Skip methods (dispose, __box, ...) — JSON.stringify would + // drop them anyway; skipping avoids serializing them at all. + if (value.isObject() && value.asObject(rt).isFunction(rt)) { + continue; + } + result.setProperty(rt, name.c_str(), value); + } + } + return result; + }); + prototype.setProperty(runtime, "toJSON", toJSONFunc); + + // Register the reconstructor used by BoxedNativeObject::unbox() to + // rebuild this object (prototype + native state) on another runtime. + static std::once_flag boxingRegistered; + std::call_once(boxingRegistered, []() { + RNJsi::BoxedNativeObjectRegistry::getInstance().registerClass( + Derived::CLASS_NAME, + [](jsi::Runtime &rt, + std::shared_ptr state) -> jsi::Value { + auto instance = std::dynamic_pointer_cast(state); + if (instance == nullptr) { + throw jsi::JSError(rt, "Invalid boxed native object state"); + } + // Unboxing creates a *view* of the object on the target runtime. + // Keep the runtime the object was originally created on: async + // native code (e.g. GPUDevice error/lost events) delivers into + // the creation runtime, and rebinding it to a worklet runtime + // would invoke main-runtime jsi::Functions on the wrong runtime + // and thread. + auto *originalRuntime = instance->getCreationRuntime(); + auto value = Derived::create(rt, instance); + if (originalRuntime != nullptr) { + instance->setCreationRuntime(originalRuntime); + } + return value; + }); + }); + // Cache the prototype entry.prototype = std::move(prototype); } @@ -289,22 +272,11 @@ class NativeObject : public jsi::NativeState, * * The constructor throws if called directly (these objects are only * created internally by the native code). - * - * Also registers this class with NativeObjectRegistry so that - * BoxedWebGPUObject::unbox() can install prototypes on secondary runtimes. */ static void installConstructor(jsi::Runtime &runtime) { - // Register this class's installer in the registry (only needs to happen - // once) - static std::once_flag registryFlag; - std::call_once(registryFlag, []() { - NativeObjectRegistry::getInstance().registerInstaller( - Derived::CLASS_NAME, - [](jsi::Runtime &rt) { Derived::installConstructor(rt); }); - }); - installPrototype(runtime); + std::lock_guard lock(getPrototypeCacheMutex()); auto &entry = getPrototypeCache(runtime).get(runtime); if (!entry.prototype.has_value()) { return; @@ -348,13 +320,17 @@ class NativeObject : public jsi::NativeState, obj.setNativeState(runtime, instance); // Set prototype - auto &entry = getPrototypeCache(runtime).get(runtime); - if (entry.prototype.has_value()) { - // Use Object.setPrototypeOf to set the prototype - auto objectCtor = runtime.global().getPropertyAsObject(runtime, "Object"); - auto setPrototypeOf = - objectCtor.getPropertyAsFunction(runtime, "setPrototypeOf"); - setPrototypeOf.call(runtime, obj, *entry.prototype); + { + std::lock_guard lock(getPrototypeCacheMutex()); + auto &entry = getPrototypeCache(runtime).get(runtime); + if (entry.prototype.has_value()) { + // Use Object.setPrototypeOf to set the prototype + auto objectCtor = + runtime.global().getPropertyAsObject(runtime, "Object"); + auto setPrototypeOf = + objectCtor.getPropertyAsFunction(runtime, "setPrototypeOf"); + setPrototypeOf.call(runtime, obj, *entry.prototype); + } } // Set memory pressure hint for GC @@ -438,11 +414,9 @@ class NativeObject : public jsi::NativeState, * (e.g. GPU::requestAdapter, which creates a per-runtime RuntimeContext). */ template - static void - installMethodWithRuntime(jsi::Runtime &runtime, jsi::Object &prototype, - const char *name, - ReturnType (Derived::*method)(jsi::Runtime &, - Args...)) { + static void installMethodWithRuntime( + jsi::Runtime &runtime, jsi::Object &prototype, const char *name, + ReturnType (Derived::*method)(jsi::Runtime &, Args...)) { auto func = jsi::Function::createFromHostFunction( runtime, jsi::PropNameID::forUtf8(runtime, name), sizeof...(Args), [method](jsi::Runtime &rt, const jsi::Value &thisVal, diff --git a/packages/skia/cpp/jsi2/Promise.cpp b/packages/skia/cpp/jsi/Promise.cpp similarity index 100% rename from packages/skia/cpp/jsi2/Promise.cpp rename to packages/skia/cpp/jsi/Promise.cpp diff --git a/packages/skia/cpp/jsi2/Promise.h b/packages/skia/cpp/jsi/Promise.h similarity index 100% rename from packages/skia/cpp/jsi2/Promise.h rename to packages/skia/cpp/jsi/Promise.h diff --git a/packages/skia/cpp/jsi/RuntimeAwareCache.cpp b/packages/skia/cpp/jsi/RuntimeAwareCache.cpp index ec9d5bad74..5bde17afba 100644 --- a/packages/skia/cpp/jsi/RuntimeAwareCache.cpp +++ b/packages/skia/cpp/jsi/RuntimeAwareCache.cpp @@ -2,6 +2,6 @@ namespace RNJsi { -jsi::Runtime *BaseRuntimeAwareCache::_mainRuntime = nullptr; +std::atomic BaseRuntimeAwareCache::_mainRuntime{nullptr}; } // namespace RNJsi diff --git a/packages/skia/cpp/jsi/RuntimeAwareCache.h b/packages/skia/cpp/jsi/RuntimeAwareCache.h index f4680267ca..18d68d3ea2 100644 --- a/packages/skia/cpp/jsi/RuntimeAwareCache.h +++ b/packages/skia/cpp/jsi/RuntimeAwareCache.h @@ -2,7 +2,9 @@ #include +#include #include +#include #include #include @@ -14,17 +16,21 @@ namespace jsi = facebook::jsi; class BaseRuntimeAwareCache { public: - static void setMainJsRuntime(jsi::Runtime *rt) { _mainRuntime = rt; } + static void setMainJsRuntime(jsi::Runtime *rt) { + // Atomic: hot reload rewrites this from the JS thread while worklet + // runtime threads read it concurrently. + _mainRuntime.store(rt, std::memory_order_release); + } static jsi::Runtime *getMainJsRuntime() { - assert(_mainRuntime != nullptr && - "Expected main Javascript runtime to be set in the " - "BaseRuntimeAwareCache class."); + auto *rt = _mainRuntime.load(std::memory_order_acquire); + assert(rt != nullptr && "Expected main Javascript runtime to be set in the " + "BaseRuntimeAwareCache class."); - return _mainRuntime; + return rt; } private: - static jsi::Runtime *_mainRuntime; + static std::atomic _mainRuntime; }; /** @@ -55,7 +61,10 @@ class RuntimeAwareCache : public BaseRuntimeAwareCache, public: void onRuntimeDestroyed(jsi::Runtime *rt) override { if (getMainJsRuntime() != rt) { - // We are removing a secondary runtime + // We are removing a secondary runtime. This is invoked by + // RuntimeLifecycleMonitor on the destroyed runtime's thread, which may + // run concurrently with get() on another runtime's thread. + std::lock_guard lock(_secondaryCachesMutex); _secondaryRuntimeCaches.erase(rt); } } @@ -74,6 +83,14 @@ class RuntimeAwareCache : public BaseRuntimeAwareCache, if (getMainJsRuntime() == &rt) { return _primaryCache; } else { + // Guard the secondary map: it can be mutated concurrently by get() + // on a worklet runtime's thread and by onRuntimeDestroyed() when + // another secondary runtime is torn down. The main-runtime path above + // stays lock-free. References into the map remain valid after the + // lock is released (unordered_map never invalidates references on + // insert/erase of other keys, and this runtime's entry can only be + // erased from this runtime's own thread). + std::lock_guard lock(_secondaryCachesMutex); if (_secondaryRuntimeCaches.count(&rt) == 0) { // we only add listener when the secondary runtime is used, this assumes // that the secondary runtime is terminated first. This lets us avoid @@ -87,11 +104,12 @@ class RuntimeAwareCache : public BaseRuntimeAwareCache, T cache; _secondaryRuntimeCaches.emplace(&rt, std::move(cache)); } + return _secondaryRuntimeCaches.at(&rt); } - return _secondaryRuntimeCaches.at(&rt); } private: + std::mutex _secondaryCachesMutex; std::unordered_map _secondaryRuntimeCaches; T _primaryCache; }; diff --git a/packages/skia/cpp/jsi/ViewProperty.h b/packages/skia/cpp/jsi/ViewProperty.h index a361086cfd..9f6ca53c60 100644 --- a/packages/skia/cpp/jsi/ViewProperty.h +++ b/packages/skia/cpp/jsi/ViewProperty.h @@ -7,8 +7,8 @@ #include #include -#include "api/JsiSkPicture.h" #include "RuntimeLifecycleMonitor.h" +#include "api/JsiSkPicture.h" namespace RNJsi { namespace jsi = facebook::jsi; @@ -38,16 +38,10 @@ class RuntimeAwareRuntimeGuard : public RuntimeLifecycleListener { class ViewProperty { public: ViewProperty(jsi::Runtime &runtime, const jsi::Value &value) { - if (value.isObject()) { - auto object = value.asObject(runtime); - if (object.isHostObject(runtime)) { - auto hostObject = object.asHostObject(runtime); - auto jsiPicture = - std::dynamic_pointer_cast(hostObject); - if (jsiPicture) { - _value = jsiPicture->getObject(); - } - } + auto jsiPicture = + RNSkia::tryGetJsiObject(runtime, value); + if (jsiPicture) { + _value = jsiPicture->getObject(); } } diff --git a/packages/skia/cpp/rnskia/RNSkJsiViewApi.h b/packages/skia/cpp/rnskia/RNSkJsiViewApi.h index b48bd686b3..795bd16109 100644 --- a/packages/skia/cpp/rnskia/RNSkJsiViewApi.h +++ b/packages/skia/cpp/rnskia/RNSkJsiViewApi.h @@ -13,7 +13,8 @@ #include "RNSkPictureView.h" #include "RNSkPlatformContext.h" #include "RNSkView.h" -#include "jsi/JsiHostObject.h" +#include "api/JsiSkNativeObjects.h" +#include "jsi/JsiPromises.h" #include "jsi/ViewProperty.h" #include @@ -92,9 +93,10 @@ class ViewRegistry { std::unordered_set _unregistered; }; -class RNSkJsiViewApi : public RNJsi::JsiHostObject, - public std::enable_shared_from_this { +class RNSkJsiViewApi : public JsiSkNativeObject { public: + static constexpr const char *CLASS_NAME = "ViewApi"; + /** Sets a custom property on a view given a view id. The property name/value will be stored in a map alongside the id of the view and propagated to the @@ -199,7 +201,7 @@ class RNSkJsiViewApi : public RNJsi::JsiHostObject, "Could not create image from current surface."); return jsi::Value::undefined(); } - return jsi::Object::createFromHostObject( + return makeJsiObject( runtime, std::make_shared(_platformContext, image)); } throw jsi::JSError(runtime, "No Skia View currently available."); @@ -245,7 +247,7 @@ class RNSkJsiViewApi : public RNJsi::JsiHostObject, promise->reject("Failed to make snapshot from view."); return; } - promise->resolve(jsi::Object::createFromHostObject( + promise->resolve(makeJsiObject( runtime, std::make_shared(std::move(context), std::move(image)))); }); @@ -286,18 +288,25 @@ class RNSkJsiViewApi : public RNJsi::JsiHostObject, return sizeObj; } - JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(RNSkJsiViewApi, setJsiProperty), - JSI_EXPORT_FUNC(RNSkJsiViewApi, requestRedraw), - JSI_EXPORT_FUNC(RNSkJsiViewApi, makeImageSnapshotAsync), - JSI_EXPORT_FUNC(RNSkJsiViewApi, makeImageSnapshot), - JSI_EXPORT_FUNC(RNSkJsiViewApi, size)) + static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { + installHostMethod(runtime, prototype, "setJsiProperty", + &RNSkJsiViewApi::setJsiProperty); + installHostMethod(runtime, prototype, "requestRedraw", + &RNSkJsiViewApi::requestRedraw); + installHostMethod(runtime, prototype, "makeImageSnapshotAsync", + &RNSkJsiViewApi::makeImageSnapshotAsync); + installHostMethod(runtime, prototype, "makeImageSnapshot", + &RNSkJsiViewApi::makeImageSnapshot); + installHostMethod(runtime, prototype, "size", &RNSkJsiViewApi::size); + } /** * Constructor * @param platformContext Platform context */ explicit RNSkJsiViewApi(std::shared_ptr platformContext) - : JsiHostObject(), _platformContext(platformContext) {} + : JsiSkNativeObject(platformContext), + _platformContext(platformContext) {} /** Call to remove all draw view infos diff --git a/packages/skia/cpp/rnskia/RNSkManager.cpp b/packages/skia/cpp/rnskia/RNSkManager.cpp index dda43c14fd..a9353141ac 100644 --- a/packages/skia/cpp/rnskia/RNSkManager.cpp +++ b/packages/skia/cpp/rnskia/RNSkManager.cpp @@ -5,27 +5,27 @@ #include -#include "api/JsiSkApi.h" #include "RNSkJsiViewApi.h" #include "RNSkView.h" +#include "api/JsiSkApi.h" #include "jsi/RuntimeAwareCache.h" #ifdef SK_GRAPHITE #include "RNDawnContext.h" +#include "jsi/Promise.h" #include "rnwgpu/ArrayBuffer.h" #include "rnwgpu/api/GPU.h" #include "rnwgpu/api/GPUUncapturedErrorEvent.h" #include "rnwgpu/api/ImageBitmap.h" #include "rnwgpu/api/RNWebGPU.h" +#include "rnwgpu/api/WebGPUConstants.h" #include "rnwgpu/api/descriptors/GPUBufferUsage.h" #include "rnwgpu/api/descriptors/GPUColorWrite.h" #include "rnwgpu/api/descriptors/GPUMapMode.h" #include "rnwgpu/api/descriptors/GPUShaderStage.h" #include "rnwgpu/api/descriptors/GPUTextureUsage.h" -#include "rnwgpu/api/WebGPUConstants.h" #include "rnwgpu/async/RuntimeContext.h" -#include "jsi2/Promise.h" #include "include/core/SkData.h" #include "include/core/SkImage.h" @@ -82,19 +82,18 @@ void RNSkManager::installBindings() { // provided runtime. auto skiaApi = std::make_shared(_platformContext); _jsRuntime->global().setProperty( - *_jsRuntime, "SkiaApi", - jsi::Object::createFromHostObject(*_jsRuntime, std::move(skiaApi))); + *_jsRuntime, "SkiaApi", makeJsiObject(*_jsRuntime, std::move(skiaApi))); - _jsRuntime->global().setProperty( - *_jsRuntime, "SkiaViewApi", - jsi::Object::createFromHostObject(*_jsRuntime, _viewApi)); + _jsRuntime->global().setProperty(*_jsRuntime, "SkiaViewApi", + makeJsiObject(*_jsRuntime, _viewApi)); #ifdef SK_GRAPHITE // Register the main runtime + its CallInvoker so spontaneous events // (device.lost / uncapturederror) on main-runtime devices can be delivered to // the JS thread without the ProcessEvents pump. Worklet-runtime devices have // no invoker (best-effort; see the RuntimeContext "Threading model" doc). - rnwgpu::async::RuntimeContext::registerMainRuntime(_jsRuntime, _jsCallInvoker); + rnwgpu::async::RuntimeContext::registerMainRuntime(_jsRuntime, + _jsCallInvoker); // Install WebGPU constructors rnwgpu::GPU::installConstructor(*_jsRuntime); @@ -121,13 +120,14 @@ void RNSkManager::installBindings() { // Install WebGPU constant objects as plain JS objects on the main runtime. rnwgpu::installWebGPUConstants(*_jsRuntime); - // Install a global `installWebGPU()` host function so worklet runtimes can get - // the same constants. A host function captured into a worklet is serialized as - // a SerializableHostFunction and re-created on the worklet runtime, so the body - // runs there (its `rt` is the worklet runtime) and installs the constants on - // that runtime. The constants come from the native wgpu::*Usage enums, so the - // values stay a single source of truth across every runtime. Calling it on a - // runtime that already has the globals is a safe, idempotent no-op. + // Install a global `installWebGPU()` host function so worklet runtimes can + // get the same constants. A host function captured into a worklet is + // serialized as a SerializableHostFunction and re-created on the worklet + // runtime, so the body runs there (its `rt` is the worklet runtime) and + // installs the constants on that runtime. The constants come from the native + // wgpu::*Usage enums, so the values stay a single source of truth across + // every runtime. Calling it on a runtime that already has the globals is a + // safe, idempotent no-op. _jsRuntime->global().setProperty( *_jsRuntime, "installWebGPU", jsi::Function::createFromHostFunction( @@ -172,9 +172,8 @@ void RNSkManager::installBindings() { bool isBufferSource = obj.isArrayBuffer(rt); if (!isBufferSource && obj.hasProperty(rt, "buffer")) { auto bufferProp = obj.getProperty(rt, "buffer"); - isBufferSource = - bufferProp.isObject() && - bufferProp.getObject(rt).isArrayBuffer(rt); + isBufferSource = bufferProp.isObject() && + bufferProp.getObject(rt).isArrayBuffer(rt); } if (!isBufferSource) { throw jsi::JSError(rt, "createImageBitmap: unsupported source " @@ -183,9 +182,9 @@ void RNSkManager::installBindings() { } // Validates bounds and THROWS synchronously on a spoofed view, so // the bad pointer never reaches the copy below. - auto buffer = - rnwgpu::JSIConverter>:: - fromJSI(rt, args[0], false); + auto buffer = rnwgpu::JSIConverter< + std::shared_ptr>::fromJSI(rt, args[0], + false); // Copy the encoded bytes off the JS-owned ArrayBuffer. const uint8_t *bytes = buffer->data(); std::vector encoded(bytes, bytes + buffer->size()); @@ -204,9 +203,8 @@ void RNSkManager::installBindings() { } const int w = image->width(); const int h = image->height(); - auto info = - SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, - kUnpremul_SkAlphaType); + auto info = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, + kUnpremul_SkAlphaType); std::vector pixels(info.computeMinByteSize()); // nullptr context: decode/read on the CPU (raster). if (!image->readPixels(nullptr, info, pixels.data(), diff --git a/packages/skia/cpp/rnskia/RNSkPictureView.h b/packages/skia/cpp/rnskia/RNSkPictureView.h index 8cc91b690b..5535f8fb30 100644 --- a/packages/skia/cpp/rnskia/RNSkPictureView.h +++ b/packages/skia/cpp/rnskia/RNSkPictureView.h @@ -13,9 +13,9 @@ #include "RNSkView.h" #include "jsi/ViewProperty.h" +#include "RNSkPlatformContext.h" #include "api/JsiSkPicture.h" #include "utils/RNSkLog.h" -#include "RNSkPlatformContext.h" #include "utils/RNSkTimingInfo.h" #pragma clang diagnostic push diff --git a/packages/skia/cpp/rnwgpu/ArrayBuffer.h b/packages/skia/cpp/rnwgpu/ArrayBuffer.h index 2f3d949887..3d4544ced6 100644 --- a/packages/skia/cpp/rnwgpu/ArrayBuffer.h +++ b/packages/skia/cpp/rnwgpu/ArrayBuffer.h @@ -5,7 +5,7 @@ #include #include -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace rnwgpu { @@ -77,8 +77,7 @@ template <> struct JSIConverter> { const size_t byteLength = static_cast(byteLengthValue); // Overflow-safe bounds check: byteOffset + byteLength <= bufferSize. - if (byteOffset > bufferSize || - byteLength > bufferSize - byteOffset) { + if (byteOffset > bufferSize || byteLength > bufferSize - byteOffset) { throw std::runtime_error( "ArrayBuffer::fromJSI: view bounds [byteOffset, byteOffset + " "byteLength) exceed the backing ArrayBuffer size"); @@ -98,9 +97,9 @@ template <> struct JSIConverter> { } } - return std::make_shared( - arrayBuffer.data(runtime) + byteOffset, byteLength, - bytesPerElements); + return std::make_shared(arrayBuffer.data(runtime) + + byteOffset, + byteLength, bytesPerElements); } } } diff --git a/packages/skia/cpp/rnwgpu/Canvas.h b/packages/skia/cpp/rnwgpu/Canvas.h index 22030c3ad5..be3a34461b 100644 --- a/packages/skia/cpp/rnwgpu/Canvas.h +++ b/packages/skia/cpp/rnwgpu/Canvas.h @@ -2,7 +2,7 @@ #include -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" namespace rnwgpu { @@ -10,7 +10,9 @@ namespace jsi = facebook::jsi; class Canvas : public NativeObject { public: - static constexpr const char *CLASS_NAME = "Canvas"; + // Note: not "Canvas" — that brand belongs to RNSkia::JsiSkCanvas, and + // boxing brands must be unique process-wide (see BoxedNativeObjectRegistry). + static constexpr const char *CLASS_NAME = "WebGPUCanvas"; Canvas(void *nativeSurface, int width, int height) : NativeObject(CLASS_NAME), _nativeSurface(nativeSurface), _width(width), diff --git a/packages/skia/cpp/rnwgpu/api/GPU.cpp b/packages/skia/cpp/rnwgpu/api/GPU.cpp index bddc26cd0b..59ff840235 100644 --- a/packages/skia/cpp/rnwgpu/api/GPU.cpp +++ b/packages/skia/cpp/rnwgpu/api/GPU.cpp @@ -8,7 +8,7 @@ #include #include "Convertors.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/async/RuntimeContext.h" namespace rnwgpu { @@ -40,9 +40,9 @@ async::AsyncTaskHandle GPU::requestAdapter( const async::AsyncTaskHandle::RejectFunction &reject) { _instance.RequestAdapter( &aOptions, wgpu::CallbackMode::AllowProcessEvents, - [context, resolve, - reject](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, - wgpu::StringView message) { + [context, resolve, reject](wgpu::RequestAdapterStatus status, + wgpu::Adapter adapter, + wgpu::StringView message) { if (message.length) { fprintf(stderr, "%s", message.data); } diff --git a/packages/skia/cpp/rnwgpu/api/GPU.h b/packages/skia/cpp/rnwgpu/api/GPU.h index d4ec87525f..96f0329835 100644 --- a/packages/skia/cpp/rnwgpu/api/GPU.h +++ b/packages/skia/cpp/rnwgpu/api/GPU.h @@ -7,7 +7,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "rnwgpu/async/AsyncTaskHandle.h" #include "rnwgpu/async/RuntimeContext.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUAdapter.cpp b/packages/skia/cpp/rnwgpu/api/GPUAdapter.cpp index ba724338de..c975845307 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUAdapter.cpp +++ b/packages/skia/cpp/rnwgpu/api/GPUAdapter.cpp @@ -13,7 +13,7 @@ #include "GPUInternalError.h" #include "GPUOutOfMemoryError.h" #include "GPUValidationError.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace rnwgpu { @@ -147,8 +147,7 @@ async::AsyncTaskHandle GPUAdapter::requestDevice( &deviceDesc, wgpu::CallbackMode::AllowProcessEvents, [context, resolve, reject, label, creationRuntime, deviceLostBinding](wgpu::RequestDeviceStatus status, - wgpu::Device device, - wgpu::StringView message) { + wgpu::Device device, wgpu::StringView message) { if (message.length) { fprintf(stderr, "%s", message.data); } diff --git a/packages/skia/cpp/rnwgpu/api/GPUAdapter.h b/packages/skia/cpp/rnwgpu/api/GPUAdapter.h index 8c56eb9205..1294ca0d9c 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUAdapter.h +++ b/packages/skia/cpp/rnwgpu/api/GPUAdapter.h @@ -6,7 +6,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "rnwgpu/async/AsyncTaskHandle.h" #include "rnwgpu/async/RuntimeContext.h" @@ -33,9 +33,9 @@ class GPUAdapter : public NativeObject { public: std::string getBrand() { return CLASS_NAME; } - async::AsyncTaskHandle requestDevice( - jsi::Runtime &runtime, - std::optional> descriptor); + async::AsyncTaskHandle + requestDevice(jsi::Runtime &runtime, + std::optional> descriptor); std::unordered_set getFeatures(); std::shared_ptr getLimits(); diff --git a/packages/skia/cpp/rnwgpu/api/GPUAdapterInfo.h b/packages/skia/cpp/rnwgpu/api/GPUAdapterInfo.h index 8103195ed2..e6ca5975e9 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUAdapterInfo.h +++ b/packages/skia/cpp/rnwgpu/api/GPUAdapterInfo.h @@ -5,7 +5,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "Convertors.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUBindGroup.h b/packages/skia/cpp/rnwgpu/api/GPUBindGroup.h index 0e038bd22b..4cfad22802 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUBindGroup.h +++ b/packages/skia/cpp/rnwgpu/api/GPUBindGroup.h @@ -4,7 +4,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUBindGroupLayout.h b/packages/skia/cpp/rnwgpu/api/GPUBindGroupLayout.h index 6328cd3b77..a4322b3a22 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUBindGroupLayout.h +++ b/packages/skia/cpp/rnwgpu/api/GPUBindGroupLayout.h @@ -4,7 +4,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUBuffer.h b/packages/skia/cpp/rnwgpu/api/GPUBuffer.h index b0ed1e95d7..00ae857662 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUBuffer.h +++ b/packages/skia/cpp/rnwgpu/api/GPUBuffer.h @@ -7,7 +7,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "rnwgpu/async/AsyncTaskHandle.h" #include "rnwgpu/async/RuntimeContext.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUCanvasContext.h b/packages/skia/cpp/rnwgpu/api/GPUCanvasContext.h index 4952d742c3..9691dabccb 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUCanvasContext.h +++ b/packages/skia/cpp/rnwgpu/api/GPUCanvasContext.h @@ -8,7 +8,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "GPU.h" #include "GPUTexture.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUCommandBuffer.h b/packages/skia/cpp/rnwgpu/api/GPUCommandBuffer.h index aa0bd21c10..6e77f17696 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUCommandBuffer.h +++ b/packages/skia/cpp/rnwgpu/api/GPUCommandBuffer.h @@ -4,7 +4,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUCommandEncoder.h b/packages/skia/cpp/rnwgpu/api/GPUCommandEncoder.h index ae342abfb3..c5a216d532 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUCommandEncoder.h +++ b/packages/skia/cpp/rnwgpu/api/GPUCommandEncoder.h @@ -5,7 +5,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUCompilationInfo.h b/packages/skia/cpp/rnwgpu/api/GPUCompilationInfo.h index 794f07207c..acde2378cb 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUCompilationInfo.h +++ b/packages/skia/cpp/rnwgpu/api/GPUCompilationInfo.h @@ -5,7 +5,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUCompilationMessage.h b/packages/skia/cpp/rnwgpu/api/GPUCompilationMessage.h index e7c06c5dc2..d8d43f2144 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUCompilationMessage.h +++ b/packages/skia/cpp/rnwgpu/api/GPUCompilationMessage.h @@ -4,7 +4,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUComputePassEncoder.h b/packages/skia/cpp/rnwgpu/api/GPUComputePassEncoder.h index a67ea97f12..1c5ddf1d81 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUComputePassEncoder.h +++ b/packages/skia/cpp/rnwgpu/api/GPUComputePassEncoder.h @@ -8,7 +8,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUComputePipeline.h b/packages/skia/cpp/rnwgpu/api/GPUComputePipeline.h index 013b9efcb1..c360a0d695 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUComputePipeline.h +++ b/packages/skia/cpp/rnwgpu/api/GPUComputePipeline.h @@ -5,7 +5,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUDevice.cpp b/packages/skia/cpp/rnwgpu/api/GPUDevice.cpp index b9ca531e44..3d9a51c870 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUDevice.cpp +++ b/packages/skia/cpp/rnwgpu/api/GPUDevice.cpp @@ -10,7 +10,7 @@ #include "Convertors.h" #include "NativeBufferUtils.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUFeatures.h" #include "GPUInternalError.h" @@ -363,9 +363,9 @@ async::AsyncTaskHandle GPUDevice::createComputePipelineAsync( runtime, pipelineHolder); }); } else { - std::string error = - msg.length ? std::string(msg.data, msg.length) - : "Failed to create compute pipeline"; + std::string error = msg.length + ? std::string(msg.data, msg.length) + : "Failed to create compute pipeline"; reject(std::move(error)); } }); @@ -410,9 +410,8 @@ async::AsyncTaskHandle GPUDevice::createRenderPipelineAsync( runtime, pipelineHolder); }); } else { - std::string error = - msg.length ? std::string(msg.data, msg.length) - : "Failed to create render pipeline"; + std::string error = msg.length ? std::string(msg.data, msg.length) + : "Failed to create render pipeline"; reject(std::move(error)); } }); diff --git a/packages/skia/cpp/rnwgpu/api/GPUDevice.h b/packages/skia/cpp/rnwgpu/api/GPUDevice.h index e20cc402a2..f0e18556eb 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUDevice.h +++ b/packages/skia/cpp/rnwgpu/api/GPUDevice.h @@ -13,7 +13,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "rnwgpu/async/AsyncTaskHandle.h" #include "rnwgpu/async/RuntimeContext.h" @@ -240,8 +240,8 @@ class GPUDevice : public NativeObject { std::shared_ptr _async; std::string _label; // Guards the device-lost state below. In the ProcessEvents model both - // notifyDeviceLost() (fired by Dawn during ProcessEvents) and getLost() run on - // the owning runtime's own thread, but device destruction can also trigger + // notifyDeviceLost() (fired by Dawn during ProcessEvents) and getLost() run + // on the owning runtime's own thread, but device destruction can also trigger // notifyDeviceLost() synchronously, so the mutex keeps these fields safe. std::mutex _lostMutex; std::optional _lostHandle; diff --git a/packages/skia/cpp/rnwgpu/api/GPUDeviceLostInfo.h b/packages/skia/cpp/rnwgpu/api/GPUDeviceLostInfo.h index b2acdfce2e..63550fd95d 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUDeviceLostInfo.h +++ b/packages/skia/cpp/rnwgpu/api/GPUDeviceLostInfo.h @@ -4,7 +4,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUError.h b/packages/skia/cpp/rnwgpu/api/GPUError.h index eca992aca0..93140a2595 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUError.h +++ b/packages/skia/cpp/rnwgpu/api/GPUError.h @@ -2,7 +2,7 @@ #include -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" namespace rnwgpu { diff --git a/packages/skia/cpp/rnwgpu/api/GPUExtent3D.h b/packages/skia/cpp/rnwgpu/api/GPUExtent3D.h index 036f2187b3..68281c6c03 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUExtent3D.h +++ b/packages/skia/cpp/rnwgpu/api/GPUExtent3D.h @@ -2,7 +2,7 @@ #include -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUExternalTexture.h b/packages/skia/cpp/rnwgpu/api/GPUExternalTexture.h index 1e32d6db44..7264d91d3b 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUExternalTexture.h +++ b/packages/skia/cpp/rnwgpu/api/GPUExternalTexture.h @@ -6,7 +6,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUInternalError.h b/packages/skia/cpp/rnwgpu/api/GPUInternalError.h index 444144f592..54e0e25e84 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUInternalError.h +++ b/packages/skia/cpp/rnwgpu/api/GPUInternalError.h @@ -2,7 +2,7 @@ #include -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" namespace rnwgpu { diff --git a/packages/skia/cpp/rnwgpu/api/GPUOrigin2D.h b/packages/skia/cpp/rnwgpu/api/GPUOrigin2D.h index bce7cb8153..dd9a9875b9 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUOrigin2D.h +++ b/packages/skia/cpp/rnwgpu/api/GPUOrigin2D.h @@ -2,7 +2,7 @@ #include -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUOrigin3D.h b/packages/skia/cpp/rnwgpu/api/GPUOrigin3D.h index 633dcb6bcb..b0100f6c2f 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUOrigin3D.h +++ b/packages/skia/cpp/rnwgpu/api/GPUOrigin3D.h @@ -2,7 +2,7 @@ #include -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUOutOfMemoryError.h b/packages/skia/cpp/rnwgpu/api/GPUOutOfMemoryError.h index 4ca713264b..5772396e6a 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUOutOfMemoryError.h +++ b/packages/skia/cpp/rnwgpu/api/GPUOutOfMemoryError.h @@ -2,7 +2,7 @@ #include -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" namespace rnwgpu { diff --git a/packages/skia/cpp/rnwgpu/api/GPUPipelineLayout.h b/packages/skia/cpp/rnwgpu/api/GPUPipelineLayout.h index a2e3be2e2e..a5b06d4d23 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUPipelineLayout.h +++ b/packages/skia/cpp/rnwgpu/api/GPUPipelineLayout.h @@ -4,7 +4,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUQuerySet.h b/packages/skia/cpp/rnwgpu/api/GPUQuerySet.h index 3e488f1906..5027b53ab2 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUQuerySet.h +++ b/packages/skia/cpp/rnwgpu/api/GPUQuerySet.h @@ -4,7 +4,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUQueue.h b/packages/skia/cpp/rnwgpu/api/GPUQueue.h index 2e82f68fc4..afff8c870d 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUQueue.h +++ b/packages/skia/cpp/rnwgpu/api/GPUQueue.h @@ -6,7 +6,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "rnwgpu/async/AsyncTaskHandle.h" #include "rnwgpu/async/RuntimeContext.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPURenderBundle.h b/packages/skia/cpp/rnwgpu/api/GPURenderBundle.h index 35a341043a..1d5af275d0 100644 --- a/packages/skia/cpp/rnwgpu/api/GPURenderBundle.h +++ b/packages/skia/cpp/rnwgpu/api/GPURenderBundle.h @@ -4,7 +4,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPURenderBundleEncoder.h b/packages/skia/cpp/rnwgpu/api/GPURenderBundleEncoder.h index 5966cfdf8b..3addd702b0 100644 --- a/packages/skia/cpp/rnwgpu/api/GPURenderBundleEncoder.h +++ b/packages/skia/cpp/rnwgpu/api/GPURenderBundleEncoder.h @@ -8,7 +8,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPURenderPassEncoder.h b/packages/skia/cpp/rnwgpu/api/GPURenderPassEncoder.h index b0ca40a137..b8f7d6d7bc 100644 --- a/packages/skia/cpp/rnwgpu/api/GPURenderPassEncoder.h +++ b/packages/skia/cpp/rnwgpu/api/GPURenderPassEncoder.h @@ -8,7 +8,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPURenderPipeline.h b/packages/skia/cpp/rnwgpu/api/GPURenderPipeline.h index 286b5d4eb8..af3b6aa566 100644 --- a/packages/skia/cpp/rnwgpu/api/GPURenderPipeline.h +++ b/packages/skia/cpp/rnwgpu/api/GPURenderPipeline.h @@ -5,7 +5,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUSampler.h b/packages/skia/cpp/rnwgpu/api/GPUSampler.h index 57e1483bca..19774fd259 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUSampler.h +++ b/packages/skia/cpp/rnwgpu/api/GPUSampler.h @@ -4,7 +4,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUShaderModule.cpp b/packages/skia/cpp/rnwgpu/api/GPUShaderModule.cpp index 763ae95c02..bf5d6b1e07 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUShaderModule.cpp +++ b/packages/skia/cpp/rnwgpu/api/GPUShaderModule.cpp @@ -3,7 +3,7 @@ #include #include -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace rnwgpu { diff --git a/packages/skia/cpp/rnwgpu/api/GPUShaderModule.h b/packages/skia/cpp/rnwgpu/api/GPUShaderModule.h index 6b3684cef8..3b2abc1eb1 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUShaderModule.h +++ b/packages/skia/cpp/rnwgpu/api/GPUShaderModule.h @@ -5,7 +5,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "rnwgpu/async/AsyncTaskHandle.h" #include "rnwgpu/async/RuntimeContext.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUSharedFence.h b/packages/skia/cpp/rnwgpu/api/GPUSharedFence.h index 41a6e9e4f8..d3bbe6cb03 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUSharedFence.h +++ b/packages/skia/cpp/rnwgpu/api/GPUSharedFence.h @@ -3,7 +3,7 @@ #include #include -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUSharedTextureMemory.h b/packages/skia/cpp/rnwgpu/api/GPUSharedTextureMemory.h index b5db61f9c3..329b0cc605 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUSharedTextureMemory.h +++ b/packages/skia/cpp/rnwgpu/api/GPUSharedTextureMemory.h @@ -6,7 +6,7 @@ #include #include -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUSupportedLimits.h b/packages/skia/cpp/rnwgpu/api/GPUSupportedLimits.h index d497a5e694..d4f13fa02b 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUSupportedLimits.h +++ b/packages/skia/cpp/rnwgpu/api/GPUSupportedLimits.h @@ -4,7 +4,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUTexture.h b/packages/skia/cpp/rnwgpu/api/GPUTexture.h index e86e11c0bf..3902d6333f 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUTexture.h +++ b/packages/skia/cpp/rnwgpu/api/GPUTexture.h @@ -6,7 +6,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUTextureView.h b/packages/skia/cpp/rnwgpu/api/GPUTextureView.h index ce65ae6212..94656b3f06 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUTextureView.h +++ b/packages/skia/cpp/rnwgpu/api/GPUTextureView.h @@ -4,7 +4,7 @@ #include "descriptors/Unions.h" -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUUncapturedErrorEvent.h b/packages/skia/cpp/rnwgpu/api/GPUUncapturedErrorEvent.h index 9d17900d26..71ba5e024b 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUUncapturedErrorEvent.h +++ b/packages/skia/cpp/rnwgpu/api/GPUUncapturedErrorEvent.h @@ -4,7 +4,7 @@ #include #include -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "GPUError.h" #include "GPUInternalError.h" diff --git a/packages/skia/cpp/rnwgpu/api/GPUValidationError.h b/packages/skia/cpp/rnwgpu/api/GPUValidationError.h index cb715f3e94..c103ab6606 100644 --- a/packages/skia/cpp/rnwgpu/api/GPUValidationError.h +++ b/packages/skia/cpp/rnwgpu/api/GPUValidationError.h @@ -2,7 +2,7 @@ #include -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" namespace rnwgpu { diff --git a/packages/skia/cpp/rnwgpu/api/ImageBitmap.h b/packages/skia/cpp/rnwgpu/api/ImageBitmap.h index 556cad86ad..dcaa8ad081 100644 --- a/packages/skia/cpp/rnwgpu/api/ImageBitmap.h +++ b/packages/skia/cpp/rnwgpu/api/ImageBitmap.h @@ -5,7 +5,7 @@ #include #include -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" namespace rnwgpu { diff --git a/packages/skia/cpp/rnwgpu/api/RNWebGPU.h b/packages/skia/cpp/rnwgpu/api/RNWebGPU.h index 28a3d5ac8e..a0d7cc2453 100644 --- a/packages/skia/cpp/rnwgpu/api/RNWebGPU.h +++ b/packages/skia/cpp/rnwgpu/api/RNWebGPU.h @@ -3,7 +3,7 @@ #include #include -#include "jsi2/NativeObject.h" +#include "jsi/NativeObject.h" #include "GPU.h" #include "GPUCanvasContext.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupDescriptor.h index 8998b487c8..18df4f42bc 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupDescriptor.h @@ -6,7 +6,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUBindGroupEntry.h" #include "rnwgpu/api/GPUBindGroupLayout.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupEntry.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupEntry.h index 813389bd0d..ed437cfb21 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupEntry.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupEntry.h @@ -6,7 +6,7 @@ #include "webgpu/webgpu_cpp.h" #include "GPUBufferBinding.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUExternalTexture.h" #include "rnwgpu/api/GPUSampler.h" #include "rnwgpu/api/GPUTextureView.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupLayoutDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupLayoutDescriptor.h index 634328e8e8..3ad0869521 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupLayoutDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupLayoutDescriptor.h @@ -6,7 +6,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUBindGroupLayoutEntry.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupLayoutEntry.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupLayoutEntry.h index 3a78fd6b6e..f86796ee04 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupLayoutEntry.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBindGroupLayoutEntry.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUBufferBindingLayout.h" #include "GPUExternalTextureBindingLayout.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBlendComponent.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBlendComponent.h index 9c5c3c72c6..68d49997e0 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBlendComponent.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBlendComponent.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBlendState.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBlendState.h index 3188ec4295..d4806f1a66 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBlendState.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBlendState.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUBlendComponent.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBufferBinding.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBufferBinding.h index cd07e8d1af..f451de3625 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBufferBinding.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBufferBinding.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUBuffer.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBufferBindingLayout.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBufferBindingLayout.h index b82c5556fd..2a961fd5f5 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBufferBindingLayout.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBufferBindingLayout.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBufferDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBufferDescriptor.h index cd44444f20..e1e1b544fb 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUBufferDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUBufferDescriptor.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUCanvasConfiguration.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUCanvasConfiguration.h index cb319b7d72..6b6ecb5449 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUCanvasConfiguration.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUCanvasConfiguration.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUDevice.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUColor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUColor.h index 2ac2b31615..5214ae9268 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUColor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUColor.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUColorTargetState.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUColorTargetState.h index 02b88503be..f5c84409a1 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUColorTargetState.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUColorTargetState.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUBlendState.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUCommandBufferDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUCommandBufferDescriptor.h index 5edfecaa28..75cd9bd2ef 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUCommandBufferDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUCommandBufferDescriptor.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUCommandEncoderDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUCommandEncoderDescriptor.h index 8098933c26..0dfebc3448 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUCommandEncoderDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUCommandEncoderDescriptor.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUComputePassDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUComputePassDescriptor.h index d04e6cb343..828d4ed4b8 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUComputePassDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUComputePassDescriptor.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUComputePassTimestampWrites.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUComputePassTimestampWrites.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUComputePassTimestampWrites.h index 2841ca44a9..3e3298007f 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUComputePassTimestampWrites.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUComputePassTimestampWrites.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUQuerySet.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUComputePipelineDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUComputePipelineDescriptor.h index 9ddaa7e5ee..fda9329995 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUComputePipelineDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUComputePipelineDescriptor.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUProgrammableStage.h" #include "rnwgpu/api/GPUPipelineLayout.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUDawnTogglesDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUDawnTogglesDescriptor.h index c31460664d..d92f913442 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUDawnTogglesDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUDawnTogglesDescriptor.h @@ -6,7 +6,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUDepthStencilState.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUDepthStencilState.h index aea68b6c5e..116dd7af22 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUDepthStencilState.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUDepthStencilState.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUStencilFaceState.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUDeviceDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUDeviceDescriptor.h index b1aebb603d..1c747103d2 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUDeviceDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUDeviceDescriptor.h @@ -7,7 +7,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUDawnTogglesDescriptor.h" #include "GPUQueueDescriptor.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUExternalTextureBindingLayout.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUExternalTextureBindingLayout.h index dd047dbb2f..752894d0e5 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUExternalTextureBindingLayout.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUExternalTextureBindingLayout.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUExternalTextureDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUExternalTextureDescriptor.h index 05e30c3397..d6c3a6fa41 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUExternalTextureDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUExternalTextureDescriptor.h @@ -7,7 +7,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUFragmentState.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUFragmentState.h index ebdb668441..b5b37d666a 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUFragmentState.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUFragmentState.h @@ -8,7 +8,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUColorTargetState.h" #include "rnwgpu/api/GPUShaderModule.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyBuffer.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyBuffer.h index 4e10f8a041..beb5346ac0 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyBuffer.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyBuffer.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUBuffer.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyExternalImage.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyExternalImage.h index 45e36176db..fa56dd2b2e 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyExternalImage.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyExternalImage.h @@ -7,8 +7,8 @@ #include "webgpu/webgpu_cpp.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/Convertors.h" -#include "jsi2/JSIConverter.h" #include "rnwgpu/api/GPUOrigin2D.h" #include "rnwgpu/api/ImageBitmap.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyTexture.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyTexture.h index ff3472d0e0..17afe808b4 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyTexture.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyTexture.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUOrigin3D.h" #include "rnwgpu/api/GPUTexture.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyTextureTagged.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyTextureTagged.h index fa8191a963..bf52d4cfbe 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyTextureTagged.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageCopyTextureTagged.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/External.h" #include "rnwgpu/api/GPUOrigin3D.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageDataLayout.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageDataLayout.h index dddb32c9fc..e59f4a674b 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageDataLayout.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUImageDataLayout.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUMultisampleState.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUMultisampleState.h index 21604bfe77..4c8649b330 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUMultisampleState.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUMultisampleState.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUPipelineLayoutDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUPipelineLayoutDescriptor.h index 493616881e..9b32c521da 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUPipelineLayoutDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUPipelineLayoutDescriptor.h @@ -6,7 +6,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUBindGroupLayout.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUPrimitiveState.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUPrimitiveState.h index 785b64c7aa..0f921a8ce2 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUPrimitiveState.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUPrimitiveState.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUProgrammableStage.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUProgrammableStage.h index f148e376b0..37fcc2ab2e 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUProgrammableStage.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUProgrammableStage.h @@ -6,7 +6,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUShaderModule.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUQuerySetDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUQuerySetDescriptor.h index 63b2404c08..059bcbb4f0 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUQuerySetDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUQuerySetDescriptor.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUQueueDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUQueueDescriptor.h index bbb3cc3f17..fd01f26644 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUQueueDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUQueueDescriptor.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderBundleDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderBundleDescriptor.h index d1c6279a5c..24d542e07a 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderBundleDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderBundleDescriptor.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderBundleEncoderDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderBundleEncoderDescriptor.h index bb85263eec..4b47a0f25e 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderBundleEncoderDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderBundleEncoderDescriptor.h @@ -6,7 +6,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassColorAttachment.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassColorAttachment.h index 48ab5658ee..639ab41571 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassColorAttachment.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassColorAttachment.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUColor.h" #include "rnwgpu/api/GPUTextureView.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassDepthStencilAttachment.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassDepthStencilAttachment.h index d1e0b68821..9e7aab37bc 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassDepthStencilAttachment.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassDepthStencilAttachment.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUTextureView.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassDescriptor.h index c3e1f32200..2b6ed03247 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassDescriptor.h @@ -7,7 +7,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPURenderPassColorAttachment.h" #include "GPURenderPassDepthStencilAttachment.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassTimestampWrites.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassTimestampWrites.h index 6287ceed47..bd5ada293a 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassTimestampWrites.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPassTimestampWrites.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUQuerySet.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPipelineDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPipelineDescriptor.h index 794d608dd4..b73426eef9 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPipelineDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPURenderPipelineDescriptor.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUDepthStencilState.h" #include "GPUFragmentState.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPURequestAdapterOptions.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPURequestAdapterOptions.h index 79e0a26712..2e11a27815 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPURequestAdapterOptions.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPURequestAdapterOptions.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUSamplerBindingLayout.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUSamplerBindingLayout.h index 769dc2a249..934a850812 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUSamplerBindingLayout.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUSamplerBindingLayout.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUSamplerDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUSamplerDescriptor.h index c70944b6fc..f1428f032e 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUSamplerDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUSamplerDescriptor.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUShaderModuleCompilationHint.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUShaderModuleCompilationHint.h index 3a381f1093..47fff28e5c 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUShaderModuleCompilationHint.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUShaderModuleCompilationHint.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUPipelineLayout.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUShaderModuleDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUShaderModuleDescriptor.h index d0237b13fd..32b823adc6 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUShaderModuleDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUShaderModuleDescriptor.h @@ -6,7 +6,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUShaderModuleCompilationHint.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUSharedFenceDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUSharedFenceDescriptor.h index 2943a2f349..47efb8893e 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUSharedFenceDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUSharedFenceDescriptor.h @@ -6,7 +6,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUSharedFenceState.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUSharedFenceState.h index d82f0ccb53..b08741dfff 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUSharedFenceState.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUSharedFenceState.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUSharedFence.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUSharedTextureMemoryDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUSharedTextureMemoryDescriptor.h index e5ce67ad31..d86e679b33 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUSharedTextureMemoryDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUSharedTextureMemoryDescriptor.h @@ -7,7 +7,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUStencilFaceState.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUStencilFaceState.h index 0c79ad4cb9..febe8f8c99 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUStencilFaceState.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUStencilFaceState.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUStorageTextureBindingLayout.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUStorageTextureBindingLayout.h index 1e25203261..dba068c83a 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUStorageTextureBindingLayout.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUStorageTextureBindingLayout.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUTextureBindingLayout.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUTextureBindingLayout.h index 8928f792ef..ed43e78608 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUTextureBindingLayout.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUTextureBindingLayout.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUTextureDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUTextureDescriptor.h index 177ca0e876..dd2fb1d33f 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUTextureDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUTextureDescriptor.h @@ -6,7 +6,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUExtent3D.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUTextureViewDescriptor.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUTextureViewDescriptor.h index fe763c8d44..1cb2e597da 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUTextureViewDescriptor.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUTextureViewDescriptor.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUUncapturedErrorEventInit.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUUncapturedErrorEventInit.h index 329bd0f9c1..74917ac7f9 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUUncapturedErrorEventInit.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUUncapturedErrorEventInit.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "rnwgpu/api/GPUError.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUVertexAttribute.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUVertexAttribute.h index c213b45a91..3ca2bddd12 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUVertexAttribute.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUVertexAttribute.h @@ -4,7 +4,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" namespace jsi = facebook::jsi; diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUVertexBufferLayout.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUVertexBufferLayout.h index 042b98a9f6..d64cf4ca34 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUVertexBufferLayout.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUVertexBufferLayout.h @@ -5,7 +5,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUVertexAttribute.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/GPUVertexState.h b/packages/skia/cpp/rnwgpu/api/descriptors/GPUVertexState.h index 54257c2573..84934d0e98 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/GPUVertexState.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/GPUVertexState.h @@ -8,7 +8,7 @@ #include "webgpu/webgpu_cpp.h" -#include "jsi2/JSIConverter.h" +#include "jsi/JSIConverter.h" #include "GPUVertexBufferLayout.h" #include "rnwgpu/api/GPUShaderModule.h" diff --git a/packages/skia/cpp/rnwgpu/api/descriptors/Unions.h b/packages/skia/cpp/rnwgpu/api/descriptors/Unions.h index e853324a24..b5551214b9 100644 --- a/packages/skia/cpp/rnwgpu/api/descriptors/Unions.h +++ b/packages/skia/cpp/rnwgpu/api/descriptors/Unions.h @@ -2,7 +2,7 @@ #include -#include "jsi2/EnumMapper.h" +#include "jsi/EnumMapper.h" #include "rnwgpu/api/External.h" #include "webgpu/webgpu_cpp.h" diff --git a/packages/skia/cpp/rnwgpu/async/AsyncTaskHandle.cpp b/packages/skia/cpp/rnwgpu/async/AsyncTaskHandle.cpp index c62a6675e2..9353357184 100644 --- a/packages/skia/cpp/rnwgpu/async/AsyncTaskHandle.cpp +++ b/packages/skia/cpp/rnwgpu/async/AsyncTaskHandle.cpp @@ -6,7 +6,7 @@ #include -#include "jsi2/Promise.h" +#include "jsi/Promise.h" #include "RuntimeContext.h" @@ -96,11 +96,11 @@ void AsyncTaskHandle::State::schedule(Action action) { auto self = shared_from_this(); if (!keepPumping) { - // Spontaneous task (e.g. device.lost): not driven by the ProcessEvents pump. - // Settle on the owning runtime's JS thread via its CallInvoker, which is - // wired only for the main JS runtime. A device created on a worklet runtime - // has no invoker, so its device.lost is dropped (best-effort; see the - // Threading model). invokeAsync runs the closure on the main JS thread, + // Spontaneous task (e.g. device.lost): not driven by the ProcessEvents + // pump. Settle on the owning runtime's JS thread via its CallInvoker, which + // is wired only for the main JS runtime. A device created on a worklet + // runtime has no invoker, so its device.lost is dropped (best-effort; see + // the Threading model). invokeAsync runs the closure on the main JS thread, // where promiseRef->runtime lives for a main-runtime device. auto invoker = context->callInvoker(); if (invoker) { @@ -119,21 +119,20 @@ void AsyncTaskHandle::State::schedule(Action action) { // Pumping task (request/response op). The resolve/reject callback may fire on // a thread that is NOT the owning runtime's thread: with a shared - // wgpu::Instance, another runtime's ProcessEvents() pump can consume this Dawn - // event. Touching the Promise's runtime off-thread would corrupt Hermes. So we - // deposit the actual settle (the only JSI-touching work) into the owning - // context's mailbox; the context drains it on its own thread during its next - // tick. The deposited closure captures only C++ state and runs no JSI until - // drained, so depositing from any thread is safe. - context->postSettle( - [self, action = std::move(action), promiseRef]() mutable { - action(promiseRef->runtime, *promiseRef); - if (self->context) { - self->context->onTaskSettled(/*keepPumping=*/true); - } - std::lock_guard lock(self->mutex); - self->keepAlive.reset(); - }); + // wgpu::Instance, another runtime's ProcessEvents() pump can consume this + // Dawn event. Touching the Promise's runtime off-thread would corrupt Hermes. + // So we deposit the actual settle (the only JSI-touching work) into the + // owning context's mailbox; the context drains it on its own thread during + // its next tick. The deposited closure captures only C++ state and runs no + // JSI until drained, so depositing from any thread is safe. + context->postSettle([self, action = std::move(action), promiseRef]() mutable { + action(promiseRef->runtime, *promiseRef); + if (self->context) { + self->context->onTaskSettled(/*keepPumping=*/true); + } + std::lock_guard lock(self->mutex); + self->keepAlive.reset(); + }); } AsyncTaskHandle::ResolveFunction diff --git a/packages/skia/package.json b/packages/skia/package.json index 705da252fe..ea95aefc28 100644 --- a/packages/skia/package.json +++ b/packages/skia/package.json @@ -79,7 +79,8 @@ "peerDependencies": { "react": ">=19.0", "react-native": ">=0.78", - "react-native-reanimated": ">=3.19.1" + "react-native-reanimated": ">=4.0.0", + "react-native-worklets": ">=0.7.0" }, "peerDependenciesMeta": { "react-native": { @@ -87,6 +88,9 @@ }, "react-native-reanimated": { "optional": true + }, + "react-native-worklets": { + "optional": true } }, "devDependencies": { diff --git a/packages/skia/react-native-skia.podspec b/packages/skia/react-native-skia.podspec index 451c8b957e..8da3212433 100644 --- a/packages/skia/react-native-skia.podspec +++ b/packages/skia/react-native-skia.podspec @@ -155,8 +155,7 @@ Pod::Spec.new do |s| 'cpp/rnskia/RNDawnWindowContext.h', 'cpp/rnskia/RNDawnWindowContext.cpp', 'cpp/rnskia/RNImageProvider.h', - 'cpp/rnwgpu/**/*.{h,cpp}', - 'cpp/jsi2/**/*.{h,cpp}' + 'cpp/rnwgpu/**/*.{h,cpp}' ] s.exclude_files = graphite_exclusions unless use_graphite diff --git a/packages/skia/src/external/reanimated/renderHelpers.ts b/packages/skia/src/external/reanimated/renderHelpers.ts index d46856a340..47878f42d6 100644 --- a/packages/skia/src/external/reanimated/renderHelpers.ts +++ b/packages/skia/src/external/reanimated/renderHelpers.ts @@ -1,5 +1,22 @@ export let HAS_REANIMATED_3 = false; +/** + * True when the worklets-based Reanimated integration is available + * (Reanimated 4 with react-native-worklets providing + * registerCustomSerializable). Skia objects use the JSI NativeState pattern + * and can only be transferred to worklet runtimes through a custom + * serializer, so on native the Reanimated integration requires Reanimated 4 — + * Reanimated 3 is not supported. + */ +export let HAS_REANIMATED_4 = false; + +/** + * Major version of the installed react-native-reanimated package, or null if + * it is not installed. Used to give actionable diagnostics when the + * integration cannot be enabled. + */ +export let REANIMATED_VERSION_MAJOR: number | null = null; + try { // This logic is convoluted but necessary // In most systems, `require("react-native-reanimated")` throws an error, all is well. @@ -14,6 +31,19 @@ try { ) { HAS_REANIMATED_3 = true; } + const majorVersion = parseInt(reanimatedVersion.split(".")[0], 10); + if (!isNaN(majorVersion)) { + REANIMATED_VERSION_MAJOR = majorVersion; + } + if (majorVersion >= 4) { + try { + const worklets = require("react-native-worklets"); + HAS_REANIMATED_4 = + typeof worklets.registerCustomSerializable === "function"; + } catch (e) { + // react-native-worklets not installed + } + } } catch (e) { // do nothing } diff --git a/packages/skia/src/skia/NativeSetup.ts b/packages/skia/src/skia/NativeSetup.ts index 8d2cffb9c7..2c632dd290 100644 --- a/packages/skia/src/skia/NativeSetup.ts +++ b/packages/skia/src/skia/NativeSetup.ts @@ -1,6 +1,8 @@ import { Platform } from "../Platform"; import NativeSkiaModule from "../specs/NativeSkiaModule"; +import { registerSkiaWorkletSerialization } from "./SkiaWorkletSerialization"; + if (Platform.OS !== "web" && global.SkiaApi == null) { // Initialize RN Skia const SkiaModule = NativeSkiaModule; @@ -16,4 +18,7 @@ if (Platform.OS !== "web" && global.SkiaApi == null) { `Native Skia Module failed to correctly install JSI Bindings! Result: ${result}` ); } + // Skia objects use the JSI NativeState pattern and need a custom + // serializer to be transferable to worklet runtimes (Reanimated). + registerSkiaWorkletSerialization(); } diff --git a/packages/skia/src/skia/SkiaWorkletSerialization.ts b/packages/skia/src/skia/SkiaWorkletSerialization.ts new file mode 100644 index 0000000000..455b8874c2 --- /dev/null +++ b/packages/skia/src/skia/SkiaWorkletSerialization.ts @@ -0,0 +1,67 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +/** + * Skia and WebGPU API objects are implemented with the JSI NativeState + * pattern: plain JS objects with a shared prototype and native state + * attached. Worklets cannot serialize such objects by default (the prototype + * would be lost when moving them to another runtime), so we register a + * Custom Serializable that: + * + * - determine: detects native objects via the `__box` method installed on + * every Skia and WebGPU prototype (plain objects never reach the + * custom-serializable path, so this cannot misfire on user data). + * - pack: boxes the object into a HostObject wrapper that carries the native + * state and the class brand. HostObjects are transferred by reference. + * - unpack: unboxes on the target runtime, re-installing the class prototype + * there and re-attaching the same native state. + * + * See cpp/jsi/BoxedNativeObject.h for the native side. + * + * `react-native-worklets` (Reanimated 4) is required for this to work — + * without it, Skia and WebGPU objects cannot be captured in worklets or + * stored in shared values. + */ + +interface BoxedNativeObject { + unbox: () => object; + __boxedNativeObject: true; +} + +const determine = (value: object): value is object => { + "worklet"; + return typeof (value as any).__box === "function"; +}; + +const pack = (value: object): BoxedNativeObject => { + "worklet"; + return (value as any).__box(); +}; + +const unpack = (packed: BoxedNativeObject): object => { + "worklet"; + return packed.unbox(); +}; + +export const registerSkiaWorkletSerialization = () => { + try { + const worklets = require("react-native-worklets"); + if (typeof worklets.registerCustomSerializable === "function") { + worklets.registerCustomSerializable({ + name: "ReactNativeSkia", + determine, + pack, + unpack, + }); + } else { + console.error( + "React Native Skia requires react-native-worklets >= 0.7.0 " + + "(registerCustomSerializable) to use Skia objects inside worklets. " + + "Please upgrade react-native-worklets and react-native-reanimated." + ); + } + } catch (e) { + // react-native-worklets is not installed. This is fine for apps that do + // not use Reanimated: Skia objects simply cannot be used inside worklets + // or shared values in this configuration. + } +}; diff --git a/packages/skia/src/sksg/Container.native.ts b/packages/skia/src/sksg/Container.native.ts index 0f849f9d15..d722312b20 100644 --- a/packages/skia/src/sksg/Container.native.ts +++ b/packages/skia/src/sksg/Container.native.ts @@ -1,6 +1,10 @@ import Rea from "../external/reanimated/ReanimatedProxy"; import type { Skia, SkPicture } from "../skia/types"; -import { HAS_REANIMATED_3 } from "../external/reanimated/renderHelpers"; +import { + HAS_REANIMATED_3, + HAS_REANIMATED_4, + REANIMATED_VERSION_MAJOR, +} from "../external/reanimated/renderHelpers"; import type { JsiRecorder } from "../skia/types/Recorder"; import { ReanimatedRecorder } from "./Recorder/ReanimatedRecorder"; @@ -79,10 +83,44 @@ class NativeReanimatedContainer extends Container { } } +let hasWarnedAboutReanimatedSupport = false; + +const reanimatedSupportError = () => { + if (REANIMATED_VERSION_MAJOR !== null && REANIMATED_VERSION_MAJOR >= 4) { + return ( + "React Native Skia requires react-native-worklets >= 0.7.0 for its " + + "Reanimated integration on native platforms. Reanimated 4 is " + + "installed, but react-native-worklets is missing or too old. " + + "Please install or upgrade react-native-worklets." + ); + } + return ( + "React Native Skia requires Reanimated 4 (react-native-worklets >= " + + "0.7.0) for its Reanimated integration on native platforms. " + + "Reanimated 3 is not supported anymore: Skia objects cannot be used " + + "inside worklets or shared values with it. " + + "Please upgrade to react-native-reanimated >= 4.0.0." + ); +}; + export const createContainer = (Skia: Skia, nativeId: number) => { - if (HAS_REANIMATED_3 && nativeId !== -1) { + if (HAS_REANIMATED_4 && nativeId !== -1) { return new NativeReanimatedContainer(Skia, nativeId); } else { + if (HAS_REANIMATED_3 && !HAS_REANIMATED_4) { + const message = reanimatedSupportError(); + if (__DEV__) { + // Fail loudly in development — a silent fallback to static rendering + // would only be noticed as frozen animations. + throw new Error(message); + } + if (!hasWarnedAboutReanimatedSupport) { + hasWarnedAboutReanimatedSupport = true; + console.error( + `${message} Falling back to static rendering (animations will not run).` + ); + } + } return new StaticContainer(Skia, nativeId); } }; diff --git a/yarn.lock b/yarn.lock index 0703f9cce2..e2b598b92d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9119,12 +9119,15 @@ __metadata: peerDependencies: react: ">=19.0" react-native: ">=0.78" - react-native-reanimated: ">=3.19.1" + react-native-reanimated: ">=4.0.0" + react-native-worklets: ">=0.7.0" peerDependenciesMeta: react-native: optional: true react-native-reanimated: optional: true + react-native-worklets: + optional: true bin: setup-skia-web: scripts/setup-canvaskit.js languageName: unknown