@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.
- package/android/CMakeLists.txt +32 -0
- package/android/build.gradle +12 -0
- package/android/cpp/jni/JniSkiaManager.cpp +38 -5
- package/android/cpp/jni/include/JniPlatformContext.h +0 -4
- package/android/cpp/jni/include/JniSkiaManager.h +3 -4
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaDomView.java +3 -2
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaManager.java +4 -4
- package/android/src/reactnative69/java/com/shopify/reactnative/skia/ReactNativeCompatible.java +11 -0
- package/android/src/reactnative74/java/com/shopify/reactnative/skia/ReactNativeCompatible.java +14 -0
- package/lib/commonjs/renderer/Offscreen.js +2 -2
- package/lib/commonjs/renderer/Offscreen.js.map +1 -1
- package/lib/module/renderer/Offscreen.js +2 -2
- package/lib/module/renderer/Offscreen.js.map +1 -1
- package/package.json +9 -7
- package/src/renderer/Offscreen.tsx +2 -2
package/android/CMakeLists.txt
CHANGED
@@ -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}
|
package/android/build.gradle
CHANGED
@@ -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(
|
26
|
-
|
27
|
-
|
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
|
-
|
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
|
-
|
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(
|
14
|
+
public SkiaDomView(ThemedReactContext context) {
|
14
15
|
super(context);
|
15
|
-
RNSkiaModule skiaModule = (
|
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.
|
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
|
-
|
25
|
+
RuntimeExecutor runtimeExecutor = ReactNativeCompatible.getRuntimeExecutor(context);
|
26
26
|
|
27
27
|
mPlatformContext = new PlatformContext(context);
|
28
28
|
|
29
|
-
mHybridData = initHybrid(context.getJavaScriptContextHolder().get(),
|
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,
|
51
|
+
private native HybridData initHybrid(long jsContext, RuntimeExecutor runtimeExecutor,
|
52
52
|
PlatformContext platformContext);
|
53
53
|
|
54
54
|
private native void initializeRuntime();
|
package/android/src/reactnative69/java/com/shopify/reactnative/skia/ReactNativeCompatible.java
ADDED
@@ -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
|
+
|
package/android/src/reactnative74/java/com/shopify/reactnative/skia/ReactNativeCompatible.java
ADDED
@@ -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;
|
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;
|
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.
|
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
|
-
|
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;
|