@shopify/react-native-skia 0.1.241 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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;