@shopify/react-native-skia 0.1.241 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -73,6 +73,8 @@ target_include_directories(
73
73
  "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi"
74
74
  "${NODE_MODULES_DIR}/react-native/ReactCommon"
75
75
  "${NODE_MODULES_DIR}/react-native/ReactCommon/react/nativemodule/core"
76
+ "${NODE_MODULES_DIR}/react-native/ReactCommon/runtimeexecutor"
77
+ "${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/jni"
76
78
  "${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni"
77
79
 
78
80
  cpp/jni/include
@@ -178,6 +180,34 @@ else()
178
180
  endif()
179
181
  message("-- FBJNI : " ${FBJNI_LIBRARY})
180
182
 
183
+ unset(REACTNATIVEJNI_LIB CACHE)
184
+ if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71)
185
+ # RN 0.71 distributes prebuilt binaries.
186
+ set (REACTNATIVEJNI_LIB "ReactAndroid::reactnativejni")
187
+ else()
188
+ find_library(
189
+ REACTNATIVEJNI_LIB
190
+ reactnativejni
191
+ PATHS ${LIBRN_DIR}
192
+ NO_CMAKE_FIND_ROOT_PATH
193
+ )
194
+ endif()
195
+ message("-- REACTNATIVEJNI : " ${REACTNATIVEJNI_LIB})
196
+
197
+ unset(RUNTIMEEXECUTOR_LIB CACHE)
198
+ if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71)
199
+ # RN 0.71 distributes prebuilt binaries.
200
+ set (RUNTIMEEXECUTOR_LIB "ReactAndroid::runtimeexecutor")
201
+ else()
202
+ find_library(
203
+ RUNTIMEEXECUTOR_LIB
204
+ runtimeexecutor
205
+ PATHS ${LIBRN_DIR}
206
+ NO_CMAKE_FIND_ROOT_PATH
207
+ )
208
+ endif()
209
+ message("-- RUNTIMEEXECUTOR : " ${RUNTIMEEXECUTOR_LIB})
210
+
181
211
  unset(TURBOMODULES_LIB CACHE)
182
212
  if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71)
183
213
  # RN 0.71 distributes prebuilt binaries.
@@ -199,6 +229,8 @@ target_link_libraries(
199
229
  ${FBJNI_LIBRARY}
200
230
  ${REACT_LIB}
201
231
  ${JSI_LIB}
232
+ ${REACTNATIVEJNI_LIB}
233
+ ${RUNTIMEEXECUTOR_LIB}
202
234
  ${TURBOMODULES_LIB}
203
235
  ${SKIA_SVG_LIB}
204
236
  ${SKIA_SKSHAPER_LIB}
@@ -167,6 +167,16 @@ android {
167
167
  "src/paper/java",
168
168
  ]
169
169
  }
170
+
171
+ if (REACT_NATIVE_VERSION >= 74) {
172
+ srcDirs += [
173
+ "src/reactnative74/java"
174
+ ]
175
+ } else {
176
+ srcDirs += [
177
+ "src/reactnative69/java"
178
+ ]
179
+ }
170
180
  }
171
181
  }
172
182
 
@@ -182,6 +192,8 @@ android {
182
192
  "**/libfbjni.so",
183
193
  "**/libjsi.so",
184
194
  "**/libreact_nativemodule_core.so",
195
+ "**/libreactnativejni.so",
196
+ "**/libruntimeexecutor.so",
185
197
  "**/libturbomodulejsijni.so",
186
198
  "META-INF/**"
187
199
  ]
@@ -7,6 +7,36 @@
7
7
 
8
8
  #include <RNSkManager.h>
9
9
 
10
+ namespace {
11
+
12
+ // For bridgeless mode, currently we don't have a way to get the JSCallInvoker
13
+ // from Java. Workaround to use RuntimeExecutor to simulate the behavior of
14
+ // JSCallInvoker. In the future when bridgeless mode is a standard and no more
15
+ // backward compatible to be considered, we could just use RuntimeExecutor to
16
+ // run task on JS thread.
17
+ class BridgelessJSCallInvoker : public facebook::react::CallInvoker {
18
+ public:
19
+ explicit BridgelessJSCallInvoker(
20
+ facebook::react::RuntimeExecutor runtimeExecutor)
21
+ : runtimeExecutor_(std::move(runtimeExecutor)) {}
22
+
23
+ void invokeAsync(std::function<void()> &&func) noexcept override {
24
+ runtimeExecutor_(
25
+ [func = std::move(func)](facebook::jsi::Runtime &runtime) { func(); });
26
+ }
27
+
28
+ void invokeSync(std::function<void()> &&func) override {
29
+ throw std::runtime_error(
30
+ "Synchronous native -> JS calls are currently not supported.");
31
+ }
32
+
33
+ private:
34
+ facebook::react::RuntimeExecutor runtimeExecutor_;
35
+
36
+ }; // class BridgelessJSCallInvoker
37
+
38
+ } // namespace
39
+
10
40
  namespace RNSkia {
11
41
 
12
42
  namespace jsi = facebook::jsi;
@@ -22,14 +52,17 @@ void JniSkiaManager::registerNatives() {
22
52
 
23
53
  // JNI init
24
54
  jni::local_ref<jni::HybridClass<JniSkiaManager>::jhybriddata>
25
- JniSkiaManager::initHybrid(jni::alias_ref<jhybridobject> jThis, jlong jsContext,
26
- JSCallInvokerHolder jsCallInvokerHolder,
27
- JavaPlatformContext skiaContext) {
55
+ JniSkiaManager::initHybrid(
56
+ jni::alias_ref<jhybridobject> jThis, jlong jsContext,
57
+ jni::alias_ref<facebook::react::JRuntimeExecutor::javaobject>
58
+ jRuntimeExecutor,
59
+ JavaPlatformContext skiaContext) {
28
60
 
61
+ auto jsCallInvoker = std::make_shared<BridgelessJSCallInvoker>(
62
+ jRuntimeExecutor->cthis()->get());
29
63
  // cast from JNI hybrid objects to C++ instances
30
64
  return makeCxxInstance(jThis, reinterpret_cast<jsi::Runtime *>(jsContext),
31
- jsCallInvokerHolder->cthis()->getCallInvoker(),
32
- skiaContext->cthis());
65
+ jsCallInvoker, skiaContext->cthis());
33
66
  }
34
67
 
35
68
  void JniSkiaManager::initializeRuntime() {
@@ -1,6 +1,5 @@
1
1
  #pragma once
2
2
 
3
- #include <ReactCommon/CallInvokerHolder.h>
4
3
  #include <fbjni/fbjni.h>
5
4
 
6
5
  #include <exception>
@@ -18,9 +17,6 @@ namespace RNSkia {
18
17
  namespace jsi = facebook::jsi;
19
18
  namespace jni = facebook::jni;
20
19
 
21
- using JSCallInvokerHolder =
22
- jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>;
23
-
24
20
  class JniPlatformContext : public jni::HybridClass<JniPlatformContext> {
25
21
  public:
26
22
  static auto constexpr kJavaDescriptor =
@@ -5,6 +5,7 @@
5
5
  #include <fbjni/fbjni.h>
6
6
  #include <jsi/jsi.h>
7
7
  #include <memory>
8
+ #include <react/jni/JRuntimeExecutor.h>
8
9
 
9
10
  #include <JniPlatformContext.h>
10
11
  #include <RNSkAndroidPlatformContext.h>
@@ -17,9 +18,6 @@ class RNSkManager;
17
18
 
18
19
  namespace jsi = facebook::jsi;
19
20
 
20
- using JSCallInvokerHolder =
21
- jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>;
22
-
23
21
  using JavaPlatformContext = jni::alias_ref<JniPlatformContext::javaobject>;
24
22
 
25
23
  class JniSkiaManager : public jni::HybridClass<JniSkiaManager> {
@@ -30,7 +28,8 @@ public:
30
28
 
31
29
  static jni::local_ref<jni::HybridClass<JniSkiaManager>::jhybriddata>
32
30
  initHybrid(jni::alias_ref<jhybridobject> jThis, jlong jsContext,
33
- JSCallInvokerHolder jsCallInvokerHolder,
31
+ jni::alias_ref<facebook::react::JRuntimeExecutor::javaobject>
32
+ jRuntimeExecutor,
34
33
  JavaPlatformContext platformContext);
35
34
 
36
35
  static void registerNatives();
@@ -5,14 +5,15 @@ import android.content.Context;
5
5
  import com.facebook.jni.HybridData;
6
6
  import com.facebook.jni.annotations.DoNotStrip;
7
7
  import com.facebook.react.bridge.ReactContext;
8
+ import com.facebook.react.uimanager.ThemedReactContext;
8
9
 
9
10
  public class SkiaDomView extends SkiaBaseView {
10
11
  @DoNotStrip
11
12
  private HybridData mHybridData;
12
13
 
13
- public SkiaDomView(Context context) {
14
+ public SkiaDomView(ThemedReactContext context) {
14
15
  super(context);
15
- RNSkiaModule skiaModule = ((ReactContext) context).getNativeModule(RNSkiaModule.class);
16
+ RNSkiaModule skiaModule = context.getReactApplicationContext().getNativeModule(RNSkiaModule.class);
16
17
  mHybridData = initHybrid(skiaModule.getSkiaManager());
17
18
  }
18
19
 
@@ -3,7 +3,7 @@ package com.shopify.reactnative.skia;
3
3
  import com.facebook.jni.HybridData;
4
4
  import com.facebook.proguard.annotations.DoNotStrip;
5
5
  import com.facebook.react.bridge.ReactContext;
6
- import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
6
+ import com.facebook.react.bridge.RuntimeExecutor;
7
7
 
8
8
  @DoNotStrip
9
9
  public class SkiaManager {
@@ -22,11 +22,11 @@ public class SkiaManager {
22
22
  super();
23
23
  mContext = context;
24
24
 
25
- CallInvokerHolderImpl holder = (CallInvokerHolderImpl) context.getCatalystInstance().getJSCallInvokerHolder();
25
+ RuntimeExecutor runtimeExecutor = ReactNativeCompatible.getRuntimeExecutor(context);
26
26
 
27
27
  mPlatformContext = new PlatformContext(context);
28
28
 
29
- mHybridData = initHybrid(context.getJavaScriptContextHolder().get(), holder, mPlatformContext);
29
+ mHybridData = initHybrid(context.getJavaScriptContextHolder().get(), runtimeExecutor, mPlatformContext);
30
30
 
31
31
  initializeRuntime();
32
32
  }
@@ -48,7 +48,7 @@ public class SkiaManager {
48
48
  public void onHostPause() { mPlatformContext.onPause(); }
49
49
 
50
50
  // private C++ functions
51
- private native HybridData initHybrid(long jsContext, CallInvokerHolderImpl jsCallInvokerHolder,
51
+ private native HybridData initHybrid(long jsContext, RuntimeExecutor runtimeExecutor,
52
52
  PlatformContext platformContext);
53
53
 
54
54
  private native void initializeRuntime();
@@ -0,0 +1,11 @@
1
+ package com.shopify.reactnative.skia;
2
+
3
+ import com.facebook.react.bridge.ReactContext;
4
+ import com.facebook.react.bridge.RuntimeExecutor;
5
+
6
+ /* package */ final class ReactNativeCompatible {
7
+ public static RuntimeExecutor getRuntimeExecutor(ReactContext context) {
8
+ return context.getCatalystInstance().getRuntimeExecutor();
9
+ }
10
+ }
11
+
@@ -0,0 +1,14 @@
1
+ package com.shopify.reactnative.skia;
2
+
3
+ import androidx.annotation.OptIn;
4
+
5
+ import com.facebook.react.bridge.ReactContext;
6
+ import com.facebook.react.bridge.RuntimeExecutor;
7
+ import com.facebook.react.common.annotations.FrameworkAPI;
8
+
9
+ /* package */ final class ReactNativeCompatible {
10
+ @OptIn(markerClass = FrameworkAPI.class)
11
+ public static RuntimeExecutor getRuntimeExecutor(ReactContext context) {
12
+ return context.getRuntimeExecutor();
13
+ }
14
+ }
@@ -42,8 +42,8 @@ const drawAsImageFromPicture = (picture, size) => {
42
42
  canvas.drawPicture(picture);
43
43
  surface.flush();
44
44
  const image = surface.makeImageSnapshot();
45
- // If we are not on the main thread, we need to make the image non-texture.
46
- if (!isOnMainThread()) {
45
+ // If we are not on the main thread or if we are on Web, we need to make the image non-texture.
46
+ if (!isOnMainThread() || _Platform.Platform.OS === "web") {
47
47
  return image.makeNonTextureImage();
48
48
  } else {
49
49
  return image;
@@ -1 +1 @@
1
- {"version":3,"names":["_types","require","_skia","_Platform","_Reconciler","isOnMainThread","_WORKLET","Platform","OS","exports","drawAsPicture","element","recorder","Skia","PictureRecorder","canvas","beginRecording","root","SkiaRoot","render","ctx","JsiDrawingContext","dom","picture","finishRecordingAsPicture","drawAsImage","size","drawAsImageFromPicture","pd","surface","Surface","MakeOffscreen","width","height","getCanvas","scale","drawPicture","flush","image","makeImageSnapshot","makeNonTextureImage"],"sources":["Offscreen.tsx"],"sourcesContent":["import type { ReactElement } from \"react\";\n\nimport { JsiDrawingContext } from \"../dom/types\";\nimport type { SkPicture, SkSize } from \"../skia/types\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\n\nimport { SkiaRoot } from \"./Reconciler\";\n\n// We call it main thread because on web main is JS thread\nexport const isOnMainThread = () => {\n \"worklet\";\n return (\n (typeof _WORKLET !== \"undefined\" && _WORKLET === true) ||\n Platform.OS === \"web\"\n );\n};\n\nexport const drawAsPicture = (element: ReactElement) => {\n const recorder = Skia.PictureRecorder();\n const canvas = recorder.beginRecording();\n const root = new SkiaRoot(Skia, false);\n root.render(element);\n const ctx = new JsiDrawingContext(Skia, canvas);\n root.dom.render(ctx);\n const picture = recorder.finishRecordingAsPicture();\n return picture;\n};\n\nexport const drawAsImage = (element: ReactElement, size: SkSize) => {\n return drawAsImageFromPicture(drawAsPicture(element), size);\n};\n\n// TODO: We're not sure yet why PixelRatio is not needed here.\nconst pd = 1;\nexport const drawAsImageFromPicture = (picture: SkPicture, size: SkSize) => {\n \"worklet\";\n const surface = Skia.Surface.MakeOffscreen(\n size.width * pd,\n size.height * pd\n )!;\n const canvas = surface.getCanvas();\n canvas.scale(pd, pd);\n canvas.drawPicture(picture);\n surface.flush();\n const image = surface.makeImageSnapshot();\n // If we are not on the main thread, we need to make the image non-texture.\n if (!isOnMainThread()) {\n return image.makeNonTextureImage();\n } else {\n return image;\n }\n};\n"],"mappings":";;;;;;AAEA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,KAAA,GAAAD,OAAA;AACA,IAAAE,SAAA,GAAAF,OAAA;AAEA,IAAAG,WAAA,GAAAH,OAAA;AAEA;AACO,MAAMI,cAAc,GAAGA,CAAA,KAAM;EAClC,SAAS;;EACT,OACG,OAAOC,QAAQ,KAAK,WAAW,IAAIA,QAAQ,KAAK,IAAI,IACrDC,kBAAQ,CAACC,EAAE,KAAK,KAAK;AAEzB,CAAC;AAACC,OAAA,CAAAJ,cAAA,GAAAA,cAAA;AAEK,MAAMK,aAAa,GAAIC,OAAqB,IAAK;EACtD,MAAMC,QAAQ,GAAGC,UAAI,CAACC,eAAe,CAAC,CAAC;EACvC,MAAMC,MAAM,GAAGH,QAAQ,CAACI,cAAc,CAAC,CAAC;EACxC,MAAMC,IAAI,GAAG,IAAIC,oBAAQ,CAACL,UAAI,EAAE,KAAK,CAAC;EACtCI,IAAI,CAACE,MAAM,CAACR,OAAO,CAAC;EACpB,MAAMS,GAAG,GAAG,IAAIC,wBAAiB,CAACR,UAAI,EAAEE,MAAM,CAAC;EAC/CE,IAAI,CAACK,GAAG,CAACH,MAAM,CAACC,GAAG,CAAC;EACpB,MAAMG,OAAO,GAAGX,QAAQ,CAACY,wBAAwB,CAAC,CAAC;EACnD,OAAOD,OAAO;AAChB,CAAC;AAACd,OAAA,CAAAC,aAAA,GAAAA,aAAA;AAEK,MAAMe,WAAW,GAAGA,CAACd,OAAqB,EAAEe,IAAY,KAAK;EAClE,OAAOC,sBAAsB,CAACjB,aAAa,CAACC,OAAO,CAAC,EAAEe,IAAI,CAAC;AAC7D,CAAC;;AAED;AAAAjB,OAAA,CAAAgB,WAAA,GAAAA,WAAA;AACA,MAAMG,EAAE,GAAG,CAAC;AACL,MAAMD,sBAAsB,GAAGA,CAACJ,OAAkB,EAAEG,IAAY,KAAK;EAC1E,SAAS;;EACT,MAAMG,OAAO,GAAGhB,UAAI,CAACiB,OAAO,CAACC,aAAa,CACxCL,IAAI,CAACM,KAAK,GAAGJ,EAAE,EACfF,IAAI,CAACO,MAAM,GAAGL,EAChB,CAAE;EACF,MAAMb,MAAM,GAAGc,OAAO,CAACK,SAAS,CAAC,CAAC;EAClCnB,MAAM,CAACoB,KAAK,CAACP,EAAE,EAAEA,EAAE,CAAC;EACpBb,MAAM,CAACqB,WAAW,CAACb,OAAO,CAAC;EAC3BM,OAAO,CAACQ,KAAK,CAAC,CAAC;EACf,MAAMC,KAAK,GAAGT,OAAO,CAACU,iBAAiB,CAAC,CAAC;EACzC;EACA,IAAI,CAAClC,cAAc,CAAC,CAAC,EAAE;IACrB,OAAOiC,KAAK,CAACE,mBAAmB,CAAC,CAAC;EACpC,CAAC,MAAM;IACL,OAAOF,KAAK;EACd;AACF,CAAC;AAAC7B,OAAA,CAAAkB,sBAAA,GAAAA,sBAAA"}
1
+ {"version":3,"names":["_types","require","_skia","_Platform","_Reconciler","isOnMainThread","_WORKLET","Platform","OS","exports","drawAsPicture","element","recorder","Skia","PictureRecorder","canvas","beginRecording","root","SkiaRoot","render","ctx","JsiDrawingContext","dom","picture","finishRecordingAsPicture","drawAsImage","size","drawAsImageFromPicture","pd","surface","Surface","MakeOffscreen","width","height","getCanvas","scale","drawPicture","flush","image","makeImageSnapshot","makeNonTextureImage"],"sources":["Offscreen.tsx"],"sourcesContent":["import type { ReactElement } from \"react\";\n\nimport { JsiDrawingContext } from \"../dom/types\";\nimport type { SkPicture, SkSize } from \"../skia/types\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\n\nimport { SkiaRoot } from \"./Reconciler\";\n\n// We call it main thread because on web main is JS thread\nexport const isOnMainThread = () => {\n \"worklet\";\n return (\n (typeof _WORKLET !== \"undefined\" && _WORKLET === true) ||\n Platform.OS === \"web\"\n );\n};\n\nexport const drawAsPicture = (element: ReactElement) => {\n const recorder = Skia.PictureRecorder();\n const canvas = recorder.beginRecording();\n const root = new SkiaRoot(Skia, false);\n root.render(element);\n const ctx = new JsiDrawingContext(Skia, canvas);\n root.dom.render(ctx);\n const picture = recorder.finishRecordingAsPicture();\n return picture;\n};\n\nexport const drawAsImage = (element: ReactElement, size: SkSize) => {\n return drawAsImageFromPicture(drawAsPicture(element), size);\n};\n\n// TODO: We're not sure yet why PixelRatio is not needed here.\nconst pd = 1;\nexport const drawAsImageFromPicture = (picture: SkPicture, size: SkSize) => {\n \"worklet\";\n const surface = Skia.Surface.MakeOffscreen(\n size.width * pd,\n size.height * pd\n )!;\n const canvas = surface.getCanvas();\n canvas.scale(pd, pd);\n canvas.drawPicture(picture);\n surface.flush();\n const image = surface.makeImageSnapshot();\n // If we are not on the main thread or if we are on Web, we need to make the image non-texture.\n if (!isOnMainThread() || Platform.OS === \"web\") {\n return image.makeNonTextureImage();\n } else {\n return image;\n }\n};\n"],"mappings":";;;;;;AAEA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,KAAA,GAAAD,OAAA;AACA,IAAAE,SAAA,GAAAF,OAAA;AAEA,IAAAG,WAAA,GAAAH,OAAA;AAEA;AACO,MAAMI,cAAc,GAAGA,CAAA,KAAM;EAClC,SAAS;;EACT,OACG,OAAOC,QAAQ,KAAK,WAAW,IAAIA,QAAQ,KAAK,IAAI,IACrDC,kBAAQ,CAACC,EAAE,KAAK,KAAK;AAEzB,CAAC;AAACC,OAAA,CAAAJ,cAAA,GAAAA,cAAA;AAEK,MAAMK,aAAa,GAAIC,OAAqB,IAAK;EACtD,MAAMC,QAAQ,GAAGC,UAAI,CAACC,eAAe,CAAC,CAAC;EACvC,MAAMC,MAAM,GAAGH,QAAQ,CAACI,cAAc,CAAC,CAAC;EACxC,MAAMC,IAAI,GAAG,IAAIC,oBAAQ,CAACL,UAAI,EAAE,KAAK,CAAC;EACtCI,IAAI,CAACE,MAAM,CAACR,OAAO,CAAC;EACpB,MAAMS,GAAG,GAAG,IAAIC,wBAAiB,CAACR,UAAI,EAAEE,MAAM,CAAC;EAC/CE,IAAI,CAACK,GAAG,CAACH,MAAM,CAACC,GAAG,CAAC;EACpB,MAAMG,OAAO,GAAGX,QAAQ,CAACY,wBAAwB,CAAC,CAAC;EACnD,OAAOD,OAAO;AAChB,CAAC;AAACd,OAAA,CAAAC,aAAA,GAAAA,aAAA;AAEK,MAAMe,WAAW,GAAGA,CAACd,OAAqB,EAAEe,IAAY,KAAK;EAClE,OAAOC,sBAAsB,CAACjB,aAAa,CAACC,OAAO,CAAC,EAAEe,IAAI,CAAC;AAC7D,CAAC;;AAED;AAAAjB,OAAA,CAAAgB,WAAA,GAAAA,WAAA;AACA,MAAMG,EAAE,GAAG,CAAC;AACL,MAAMD,sBAAsB,GAAGA,CAACJ,OAAkB,EAAEG,IAAY,KAAK;EAC1E,SAAS;;EACT,MAAMG,OAAO,GAAGhB,UAAI,CAACiB,OAAO,CAACC,aAAa,CACxCL,IAAI,CAACM,KAAK,GAAGJ,EAAE,EACfF,IAAI,CAACO,MAAM,GAAGL,EAChB,CAAE;EACF,MAAMb,MAAM,GAAGc,OAAO,CAACK,SAAS,CAAC,CAAC;EAClCnB,MAAM,CAACoB,KAAK,CAACP,EAAE,EAAEA,EAAE,CAAC;EACpBb,MAAM,CAACqB,WAAW,CAACb,OAAO,CAAC;EAC3BM,OAAO,CAACQ,KAAK,CAAC,CAAC;EACf,MAAMC,KAAK,GAAGT,OAAO,CAACU,iBAAiB,CAAC,CAAC;EACzC;EACA,IAAI,CAAClC,cAAc,CAAC,CAAC,IAAIE,kBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;IAC9C,OAAO8B,KAAK,CAACE,mBAAmB,CAAC,CAAC;EACpC,CAAC,MAAM;IACL,OAAOF,KAAK;EACd;AACF,CAAC;AAAC7B,OAAA,CAAAkB,sBAAA,GAAAA,sBAAA"}
@@ -34,8 +34,8 @@ export const drawAsImageFromPicture = (picture, size) => {
34
34
  canvas.drawPicture(picture);
35
35
  surface.flush();
36
36
  const image = surface.makeImageSnapshot();
37
- // If we are not on the main thread, we need to make the image non-texture.
38
- if (!isOnMainThread()) {
37
+ // If we are not on the main thread or if we are on Web, we need to make the image non-texture.
38
+ if (!isOnMainThread() || Platform.OS === "web") {
39
39
  return image.makeNonTextureImage();
40
40
  } else {
41
41
  return image;
@@ -1 +1 @@
1
- {"version":3,"names":["JsiDrawingContext","Skia","Platform","SkiaRoot","isOnMainThread","_WORKLET","OS","drawAsPicture","element","recorder","PictureRecorder","canvas","beginRecording","root","render","ctx","dom","picture","finishRecordingAsPicture","drawAsImage","size","drawAsImageFromPicture","pd","surface","Surface","MakeOffscreen","width","height","getCanvas","scale","drawPicture","flush","image","makeImageSnapshot","makeNonTextureImage"],"sources":["Offscreen.tsx"],"sourcesContent":["import type { ReactElement } from \"react\";\n\nimport { JsiDrawingContext } from \"../dom/types\";\nimport type { SkPicture, SkSize } from \"../skia/types\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\n\nimport { SkiaRoot } from \"./Reconciler\";\n\n// We call it main thread because on web main is JS thread\nexport const isOnMainThread = () => {\n \"worklet\";\n return (\n (typeof _WORKLET !== \"undefined\" && _WORKLET === true) ||\n Platform.OS === \"web\"\n );\n};\n\nexport const drawAsPicture = (element: ReactElement) => {\n const recorder = Skia.PictureRecorder();\n const canvas = recorder.beginRecording();\n const root = new SkiaRoot(Skia, false);\n root.render(element);\n const ctx = new JsiDrawingContext(Skia, canvas);\n root.dom.render(ctx);\n const picture = recorder.finishRecordingAsPicture();\n return picture;\n};\n\nexport const drawAsImage = (element: ReactElement, size: SkSize) => {\n return drawAsImageFromPicture(drawAsPicture(element), size);\n};\n\n// TODO: We're not sure yet why PixelRatio is not needed here.\nconst pd = 1;\nexport const drawAsImageFromPicture = (picture: SkPicture, size: SkSize) => {\n \"worklet\";\n const surface = Skia.Surface.MakeOffscreen(\n size.width * pd,\n size.height * pd\n )!;\n const canvas = surface.getCanvas();\n canvas.scale(pd, pd);\n canvas.drawPicture(picture);\n surface.flush();\n const image = surface.makeImageSnapshot();\n // If we are not on the main thread, we need to make the image non-texture.\n if (!isOnMainThread()) {\n return image.makeNonTextureImage();\n } else {\n return image;\n }\n};\n"],"mappings":"AAEA,SAASA,iBAAiB,QAAQ,cAAc;AAEhD,SAASC,IAAI,QAAQ,SAAS;AAC9B,SAASC,QAAQ,QAAQ,aAAa;AAEtC,SAASC,QAAQ,QAAQ,cAAc;;AAEvC;AACA,OAAO,MAAMC,cAAc,GAAGA,CAAA,KAAM;EAClC,SAAS;;EACT,OACG,OAAOC,QAAQ,KAAK,WAAW,IAAIA,QAAQ,KAAK,IAAI,IACrDH,QAAQ,CAACI,EAAE,KAAK,KAAK;AAEzB,CAAC;AAED,OAAO,MAAMC,aAAa,GAAIC,OAAqB,IAAK;EACtD,MAAMC,QAAQ,GAAGR,IAAI,CAACS,eAAe,CAAC,CAAC;EACvC,MAAMC,MAAM,GAAGF,QAAQ,CAACG,cAAc,CAAC,CAAC;EACxC,MAAMC,IAAI,GAAG,IAAIV,QAAQ,CAACF,IAAI,EAAE,KAAK,CAAC;EACtCY,IAAI,CAACC,MAAM,CAACN,OAAO,CAAC;EACpB,MAAMO,GAAG,GAAG,IAAIf,iBAAiB,CAACC,IAAI,EAAEU,MAAM,CAAC;EAC/CE,IAAI,CAACG,GAAG,CAACF,MAAM,CAACC,GAAG,CAAC;EACpB,MAAME,OAAO,GAAGR,QAAQ,CAACS,wBAAwB,CAAC,CAAC;EACnD,OAAOD,OAAO;AAChB,CAAC;AAED,OAAO,MAAME,WAAW,GAAGA,CAACX,OAAqB,EAAEY,IAAY,KAAK;EAClE,OAAOC,sBAAsB,CAACd,aAAa,CAACC,OAAO,CAAC,EAAEY,IAAI,CAAC;AAC7D,CAAC;;AAED;AACA,MAAME,EAAE,GAAG,CAAC;AACZ,OAAO,MAAMD,sBAAsB,GAAGA,CAACJ,OAAkB,EAAEG,IAAY,KAAK;EAC1E,SAAS;;EACT,MAAMG,OAAO,GAAGtB,IAAI,CAACuB,OAAO,CAACC,aAAa,CACxCL,IAAI,CAACM,KAAK,GAAGJ,EAAE,EACfF,IAAI,CAACO,MAAM,GAAGL,EAChB,CAAE;EACF,MAAMX,MAAM,GAAGY,OAAO,CAACK,SAAS,CAAC,CAAC;EAClCjB,MAAM,CAACkB,KAAK,CAACP,EAAE,EAAEA,EAAE,CAAC;EACpBX,MAAM,CAACmB,WAAW,CAACb,OAAO,CAAC;EAC3BM,OAAO,CAACQ,KAAK,CAAC,CAAC;EACf,MAAMC,KAAK,GAAGT,OAAO,CAACU,iBAAiB,CAAC,CAAC;EACzC;EACA,IAAI,CAAC7B,cAAc,CAAC,CAAC,EAAE;IACrB,OAAO4B,KAAK,CAACE,mBAAmB,CAAC,CAAC;EACpC,CAAC,MAAM;IACL,OAAOF,KAAK;EACd;AACF,CAAC"}
1
+ {"version":3,"names":["JsiDrawingContext","Skia","Platform","SkiaRoot","isOnMainThread","_WORKLET","OS","drawAsPicture","element","recorder","PictureRecorder","canvas","beginRecording","root","render","ctx","dom","picture","finishRecordingAsPicture","drawAsImage","size","drawAsImageFromPicture","pd","surface","Surface","MakeOffscreen","width","height","getCanvas","scale","drawPicture","flush","image","makeImageSnapshot","makeNonTextureImage"],"sources":["Offscreen.tsx"],"sourcesContent":["import type { ReactElement } from \"react\";\n\nimport { JsiDrawingContext } from \"../dom/types\";\nimport type { SkPicture, SkSize } from \"../skia/types\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\n\nimport { SkiaRoot } from \"./Reconciler\";\n\n// We call it main thread because on web main is JS thread\nexport const isOnMainThread = () => {\n \"worklet\";\n return (\n (typeof _WORKLET !== \"undefined\" && _WORKLET === true) ||\n Platform.OS === \"web\"\n );\n};\n\nexport const drawAsPicture = (element: ReactElement) => {\n const recorder = Skia.PictureRecorder();\n const canvas = recorder.beginRecording();\n const root = new SkiaRoot(Skia, false);\n root.render(element);\n const ctx = new JsiDrawingContext(Skia, canvas);\n root.dom.render(ctx);\n const picture = recorder.finishRecordingAsPicture();\n return picture;\n};\n\nexport const drawAsImage = (element: ReactElement, size: SkSize) => {\n return drawAsImageFromPicture(drawAsPicture(element), size);\n};\n\n// TODO: We're not sure yet why PixelRatio is not needed here.\nconst pd = 1;\nexport const drawAsImageFromPicture = (picture: SkPicture, size: SkSize) => {\n \"worklet\";\n const surface = Skia.Surface.MakeOffscreen(\n size.width * pd,\n size.height * pd\n )!;\n const canvas = surface.getCanvas();\n canvas.scale(pd, pd);\n canvas.drawPicture(picture);\n surface.flush();\n const image = surface.makeImageSnapshot();\n // If we are not on the main thread or if we are on Web, we need to make the image non-texture.\n if (!isOnMainThread() || Platform.OS === \"web\") {\n return image.makeNonTextureImage();\n } else {\n return image;\n }\n};\n"],"mappings":"AAEA,SAASA,iBAAiB,QAAQ,cAAc;AAEhD,SAASC,IAAI,QAAQ,SAAS;AAC9B,SAASC,QAAQ,QAAQ,aAAa;AAEtC,SAASC,QAAQ,QAAQ,cAAc;;AAEvC;AACA,OAAO,MAAMC,cAAc,GAAGA,CAAA,KAAM;EAClC,SAAS;;EACT,OACG,OAAOC,QAAQ,KAAK,WAAW,IAAIA,QAAQ,KAAK,IAAI,IACrDH,QAAQ,CAACI,EAAE,KAAK,KAAK;AAEzB,CAAC;AAED,OAAO,MAAMC,aAAa,GAAIC,OAAqB,IAAK;EACtD,MAAMC,QAAQ,GAAGR,IAAI,CAACS,eAAe,CAAC,CAAC;EACvC,MAAMC,MAAM,GAAGF,QAAQ,CAACG,cAAc,CAAC,CAAC;EACxC,MAAMC,IAAI,GAAG,IAAIV,QAAQ,CAACF,IAAI,EAAE,KAAK,CAAC;EACtCY,IAAI,CAACC,MAAM,CAACN,OAAO,CAAC;EACpB,MAAMO,GAAG,GAAG,IAAIf,iBAAiB,CAACC,IAAI,EAAEU,MAAM,CAAC;EAC/CE,IAAI,CAACG,GAAG,CAACF,MAAM,CAACC,GAAG,CAAC;EACpB,MAAME,OAAO,GAAGR,QAAQ,CAACS,wBAAwB,CAAC,CAAC;EACnD,OAAOD,OAAO;AAChB,CAAC;AAED,OAAO,MAAME,WAAW,GAAGA,CAACX,OAAqB,EAAEY,IAAY,KAAK;EAClE,OAAOC,sBAAsB,CAACd,aAAa,CAACC,OAAO,CAAC,EAAEY,IAAI,CAAC;AAC7D,CAAC;;AAED;AACA,MAAME,EAAE,GAAG,CAAC;AACZ,OAAO,MAAMD,sBAAsB,GAAGA,CAACJ,OAAkB,EAAEG,IAAY,KAAK;EAC1E,SAAS;;EACT,MAAMG,OAAO,GAAGtB,IAAI,CAACuB,OAAO,CAACC,aAAa,CACxCL,IAAI,CAACM,KAAK,GAAGJ,EAAE,EACfF,IAAI,CAACO,MAAM,GAAGL,EAChB,CAAE;EACF,MAAMX,MAAM,GAAGY,OAAO,CAACK,SAAS,CAAC,CAAC;EAClCjB,MAAM,CAACkB,KAAK,CAACP,EAAE,EAAEA,EAAE,CAAC;EACpBX,MAAM,CAACmB,WAAW,CAACb,OAAO,CAAC;EAC3BM,OAAO,CAACQ,KAAK,CAAC,CAAC;EACf,MAAMC,KAAK,GAAGT,OAAO,CAACU,iBAAiB,CAAC,CAAC;EACzC;EACA,IAAI,CAAC7B,cAAc,CAAC,CAAC,IAAIF,QAAQ,CAACI,EAAE,KAAK,KAAK,EAAE;IAC9C,OAAO0B,KAAK,CAACE,mBAAmB,CAAC,CAAC;EACpC,CAAC,MAAM;IACL,OAAOF,KAAK;EACd;AACF,CAAC"}
package/package.json CHANGED
@@ -7,9 +7,12 @@
7
7
  "setup-skia-web": "./scripts/setup-canvaskit.js"
8
8
  },
9
9
  "title": "React Native Skia",
10
- "version": "0.1.241",
10
+ "version": "1.0.2",
11
11
  "description": "High-performance React Native Graphics using Skia",
12
12
  "main": "lib/module/index.js",
13
+ "react-native": "src/index.ts",
14
+ "module": "lib/module/index.js",
15
+ "types": "lib/typescript/index.d.ts",
13
16
  "files": [
14
17
  "src",
15
18
  "lib",
@@ -45,7 +48,8 @@
45
48
  "lint": "eslint . --ext .ts,.tsx --max-warnings 0 --cache",
46
49
  "test": "jest",
47
50
  "e2e": "E2E=true yarn test -i e2e",
48
- "build": "bob build && merge-dirs lib/typescript/src lib/commonjs && merge-dirs lib/typescript/src lib/module"
51
+ "build": "bob build && merge-dirs lib/typescript/src lib/commonjs && merge-dirs lib/typescript/src lib/module",
52
+ "release": "standard-version"
49
53
  },
50
54
  "repository": {
51
55
  "type": "git",
@@ -102,6 +106,7 @@
102
106
  "react-native": "0.72.6",
103
107
  "react-native-builder-bob": "0.18.2",
104
108
  "react-native-reanimated": "3.6.2",
109
+ "standard-version": "^9.5.0",
105
110
  "ts-jest": "29.1.1",
106
111
  "typescript": "5.1.6",
107
112
  "ws": "8.11.0"
@@ -139,8 +144,5 @@
139
144
  "resolutions": {
140
145
  "@typescript-eslint/eslint-plugin": "6.10.0",
141
146
  "@typescript-eslint/parser": "6.10.0"
142
- },
143
- "types": "lib/typescript/index.d.ts",
144
- "module": "lib/module/index.js",
145
- "react-native": "src/index.ts"
146
- }
147
+ }
148
+ }
@@ -44,8 +44,8 @@ export const drawAsImageFromPicture = (picture: SkPicture, size: SkSize) => {
44
44
  canvas.drawPicture(picture);
45
45
  surface.flush();
46
46
  const image = surface.makeImageSnapshot();
47
- // If we are not on the main thread, we need to make the image non-texture.
48
- if (!isOnMainThread()) {
47
+ // If we are not on the main thread or if we are on Web, we need to make the image non-texture.
48
+ if (!isOnMainThread() || Platform.OS === "web") {
49
49
  return image.makeNonTextureImage();
50
50
  } else {
51
51
  return image;