@shopify/react-native-skia 2.12.0 → 2.13.1
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/LICENSE.md +2 -1
- package/Package.swift +4 -4
- package/android/CMakeLists.txt +22 -177
- package/android/build.gradle +40 -209
- package/android/cpp/jni/JniSkiaManager.cpp +3 -45
- package/android/cpp/jni/include/JniPlatformContext.h +1 -1
- package/android/cpp/jni/include/JniSkiaBaseView.h +18 -11
- package/android/cpp/jni/include/JniSkiaManager.h +3 -4
- package/android/cpp/jni/include/JniSkiaPictureView.h +5 -5
- package/android/cpp/rnskia-android/OpenGLContext.h +1 -1
- package/android/cpp/rnskia-android/RNSkAndroidView.h +6 -6
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +4 -4
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +2 -2
- package/android/cpp/rnskia-android/gl/Surface.h +1 -1
- package/android/src/main/AndroidManifest.xml +1 -1
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/PlatformContext.java +1 -1
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/RNSkVideo.java +1 -1
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/RNSkiaModule.java +1 -8
- package/android/src/main/java/com/reactnative/skia/RNSkiaPackage.java +57 -0
- package/android/src/main/java/com/reactnative/skia/SkiaBaseView.java +185 -0
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaBaseViewManager.java +20 -1
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaManager.java +11 -6
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaPictureView.java +3 -3
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaPictureViewManager.java +1 -1
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaSurfaceView.java +13 -3
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaTextureView.java +5 -3
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaViewAPI.java +1 -1
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/ViewScreenshotService.java +1 -1
- package/apple/MetalContext.mm +1 -1
- package/apple/RNSkiaModule.h +1 -10
- package/apple/RNSkiaModule.mm +2 -10
- package/apple/SkiaManager.h +0 -2
- package/apple/SkiaManager.mm +4 -6
- package/apple/SkiaPictureView.h +2 -2
- package/apple/SkiaPictureView.mm +0 -4
- package/apple/SkiaUIView.h +3 -18
- package/apple/SkiaUIView.mm +0 -30
- package/cpp/api/CustomBlendModes.h +17 -0
- package/cpp/api/JsiSkCanvas.h +19 -10
- package/cpp/api/JsiSkImage.h +1 -1
- package/cpp/api/JsiSkImageFilter.h +3 -1
- package/cpp/api/JsiSkParagraph.h +2 -1
- package/cpp/api/JsiSkParagraphBuilder.h +1 -1
- package/cpp/api/JsiSkParagraphBuilderFactory.h +1 -1
- package/cpp/api/JsiSkPath.h +11 -4
- package/cpp/api/JsiSkPathBuilder.h +11 -4
- package/cpp/api/JsiSkPictureRecorder.h +2 -1
- package/cpp/api/JsiSkShader.h +3 -1
- package/cpp/api/JsiSkSkottie.h +27 -25
- package/cpp/api/recorder/Command.h +1 -1
- package/cpp/api/recorder/Convertor.h +1 -1
- package/cpp/api/recorder/DataTypes.h +1 -1
- package/cpp/api/recorder/DrawingCtx.h +1 -1
- package/cpp/api/recorder/JsiRecorder.h +7 -4
- package/cpp/api/third_party/base64.cpp +1 -1
- package/cpp/jsi/JSICache.cpp +23 -0
- package/cpp/jsi/JSICache.h +28 -1
- package/cpp/jsi/NativeObject.h +36 -7
- package/cpp/jsi/ViewProperty.h +0 -4
- package/cpp/rnskia/RNDawnContext.h +1 -1
- package/lib/commonjs/animation/functions/interpolatePaths.js +18 -0
- package/lib/commonjs/animation/functions/interpolatePaths.js.map +1 -1
- package/lib/commonjs/mock/index.js +0 -1
- package/lib/commonjs/mock/index.js.map +1 -1
- package/lib/commonjs/renderer/Canvas.d.ts +11 -3
- package/lib/commonjs/renderer/Canvas.js +8 -6
- package/lib/commonjs/renderer/Canvas.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkCanvas.js +9 -4
- package/lib/commonjs/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/commonjs/specs/SkiaPictureViewNativeComponent.d.ts +2 -0
- package/lib/commonjs/specs/SkiaPictureViewNativeComponent.js.map +1 -1
- package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
- package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.js +3 -0
- package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.js.map +1 -1
- package/lib/commonjs/views/SkiaPictureView.js +2 -12
- package/lib/commonjs/views/SkiaPictureView.js.map +1 -1
- package/lib/commonjs/views/types.d.ts +19 -8
- package/lib/commonjs/views/types.js.map +1 -1
- package/lib/module/animation/functions/interpolatePaths.js +18 -0
- package/lib/module/animation/functions/interpolatePaths.js.map +1 -1
- package/lib/module/mock/index.js +0 -1
- package/lib/module/mock/index.js.map +1 -1
- package/lib/module/renderer/Canvas.d.ts +11 -3
- package/lib/module/renderer/Canvas.js +7 -5
- package/lib/module/renderer/Canvas.js.map +1 -1
- package/lib/module/skia/web/JsiSkCanvas.js +9 -4
- package/lib/module/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/module/specs/SkiaPictureViewNativeComponent.d.ts +2 -0
- package/lib/module/specs/SkiaPictureViewNativeComponent.js.map +1 -1
- package/lib/module/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
- package/lib/module/specs/SkiaPictureViewNativeComponent.web.js +3 -0
- package/lib/module/specs/SkiaPictureViewNativeComponent.web.js.map +1 -1
- package/lib/module/views/SkiaPictureView.js +2 -12
- package/lib/module/views/SkiaPictureView.js.map +1 -1
- package/lib/module/views/types.d.ts +19 -8
- package/lib/module/views/types.js.map +1 -1
- package/lib/typescript/lib/commonjs/mock/index.d.ts +0 -1
- package/lib/typescript/lib/commonjs/renderer/Canvas.d.ts +2 -2
- package/lib/typescript/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
- package/lib/typescript/lib/module/mock/index.d.ts +0 -1
- package/lib/typescript/lib/module/renderer/Canvas.d.ts +2 -2
- package/lib/typescript/lib/module/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
- package/lib/typescript/src/renderer/Canvas.d.ts +11 -3
- package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.d.ts +2 -0
- package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
- package/lib/typescript/src/views/types.d.ts +19 -8
- package/package.json +3 -3
- package/react-native-skia.podspec +4 -10
- package/src/animation/functions/interpolatePaths.ts +24 -0
- package/src/mock/index.ts +0 -1
- package/src/renderer/Canvas.tsx +23 -5
- package/src/skia/web/JsiSkCanvas.ts +14 -9
- package/src/specs/SkiaPictureViewNativeComponent.ts +5 -0
- package/src/specs/SkiaPictureViewNativeComponent.web.ts +5 -0
- package/src/views/SkiaPictureView.tsx +2 -10
- package/src/views/types.ts +23 -10
- package/android/src/latest/java/com/shopify/reactnative/skia/ReactNativeCompatible.java +0 -11
- package/android/src/main/java/com/shopify/reactnative/skia/RNSkiaPackage.java +0 -79
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaAHBView.java +0 -113
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +0 -136
- package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerDelegate.java +0 -41
- package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerInterface.java +0 -20
- package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaWebGPUViewManagerDelegate.java +0 -35
- package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaWebGPUViewManagerInterface.java +0 -17
- package/android/src/paper/java/com/shopify/reactnative/skia/NativeSkiaModuleSpec.java +0 -38
- package/android/src/reactnative74/java/com/shopify/reactnative/skia/ReactNativeCompatible.java +0 -14
- package/apple/SkiaPictureViewManager.h +0 -8
- package/apple/SkiaPictureViewManager.mm +0 -60
- package/apple/SkiaWebGPUView.h +0 -20
- package/apple/WebGPUMetalView.h +0 -12
|
@@ -21,24 +21,28 @@ class JniSkiaBaseView {
|
|
|
21
21
|
public:
|
|
22
22
|
JniSkiaBaseView(jni::alias_ref<JniSkiaManager::javaobject> skiaManager,
|
|
23
23
|
std::shared_ptr<RNSkBaseAndroidView> skiaView)
|
|
24
|
-
: _skiaAndroidView(std::move(skiaView)),
|
|
24
|
+
: _skiaAndroidView(std::move(skiaView)),
|
|
25
|
+
_manager(skiaManager->cthis()->getSkiaManager()) {}
|
|
25
26
|
|
|
26
27
|
~JniSkiaBaseView() = default;
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
// The manager is owned by the RNSkiaModule and is destroyed when the module
|
|
30
|
+
// is invalidated (reload). Fabric drops views on the UI thread while the
|
|
31
|
+
// module is invalidated on a background thread, so a view can outlive its
|
|
32
|
+
// manager: holding a weak reference makes a late unregister a no-op and a
|
|
33
|
+
// concurrent one keep the manager alive for the duration of the call.
|
|
34
|
+
std::shared_ptr<RNSkManager> getSkiaManager() { return _manager.lock(); }
|
|
31
35
|
|
|
32
36
|
protected:
|
|
33
37
|
virtual void surfaceAvailable(jobject surface, int width, int height,
|
|
34
|
-
bool
|
|
35
|
-
_skiaAndroidView->surfaceAvailable(surface, width, height,
|
|
38
|
+
bool isSurface, bool highBitDepth) {
|
|
39
|
+
_skiaAndroidView->surfaceAvailable(surface, width, height, isSurface,
|
|
36
40
|
highBitDepth);
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
virtual void surfaceSizeChanged(jobject surface, int width, int height,
|
|
40
|
-
bool
|
|
41
|
-
_skiaAndroidView->surfaceSizeChanged(surface, width, height,
|
|
44
|
+
bool isSurface, bool highBitDepth) {
|
|
45
|
+
_skiaAndroidView->surfaceSizeChanged(surface, width, height, isSurface,
|
|
42
46
|
highBitDepth);
|
|
43
47
|
}
|
|
44
48
|
|
|
@@ -49,8 +53,11 @@ protected:
|
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
virtual void registerView(int nativeId) {
|
|
52
|
-
getSkiaManager()
|
|
53
|
-
|
|
56
|
+
auto manager = getSkiaManager();
|
|
57
|
+
if (manager == nullptr) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
manager->registerSkiaView(nativeId, _skiaAndroidView->getSkiaView());
|
|
54
61
|
}
|
|
55
62
|
|
|
56
63
|
virtual void unregisterView() {
|
|
@@ -74,7 +81,7 @@ protected:
|
|
|
74
81
|
std::shared_ptr<RNSkBaseAndroidView> _skiaAndroidView;
|
|
75
82
|
|
|
76
83
|
private:
|
|
77
|
-
|
|
84
|
+
std::weak_ptr<RNSkManager> _manager;
|
|
78
85
|
};
|
|
79
86
|
|
|
80
87
|
} // namespace RNSkia
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
#include <fbjni/fbjni.h>
|
|
6
6
|
#include <jsi/jsi.h>
|
|
7
7
|
#include <memory>
|
|
8
|
-
#include <react/jni/JRuntimeExecutor.h>
|
|
9
8
|
|
|
10
9
|
#include "JniPlatformContext.h"
|
|
11
10
|
#include "RNSkAndroidPlatformContext.h"
|
|
@@ -23,13 +22,13 @@ using JavaPlatformContext = jni::alias_ref<JniPlatformContext::javaobject>;
|
|
|
23
22
|
class JniSkiaManager : public jni::HybridClass<JniSkiaManager> {
|
|
24
23
|
public:
|
|
25
24
|
static auto constexpr kJavaDescriptor =
|
|
26
|
-
"Lcom/
|
|
25
|
+
"Lcom/reactnative/skia/SkiaManager;";
|
|
27
26
|
static auto constexpr TAG = "ReactNativeSkia";
|
|
28
27
|
|
|
29
28
|
static jni::local_ref<jni::HybridClass<JniSkiaManager>::jhybriddata>
|
|
30
29
|
initHybrid(jni::alias_ref<jhybridobject> jThis, jlong jsContext,
|
|
31
|
-
jni::alias_ref<facebook::react::
|
|
32
|
-
|
|
30
|
+
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>
|
|
31
|
+
jsCallInvokerHolder,
|
|
33
32
|
JavaPlatformContext platformContext);
|
|
34
33
|
|
|
35
34
|
static void registerNatives();
|
|
@@ -39,7 +39,7 @@ class JniSkiaPictureView : public jni::HybridClass<JniSkiaPictureView>,
|
|
|
39
39
|
public JniSkiaBaseView {
|
|
40
40
|
public:
|
|
41
41
|
static auto constexpr kJavaDescriptor =
|
|
42
|
-
"Lcom/
|
|
42
|
+
"Lcom/reactnative/skia/SkiaPictureView;";
|
|
43
43
|
|
|
44
44
|
static jni::local_ref<jhybriddata>
|
|
45
45
|
initHybrid(jni::alias_ref<jhybridobject> jThis,
|
|
@@ -63,15 +63,15 @@ public:
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
protected:
|
|
66
|
-
void surfaceAvailable(jobject surface, int width, int height, bool
|
|
66
|
+
void surfaceAvailable(jobject surface, int width, int height, bool isSurface,
|
|
67
67
|
bool highBitDepth) override {
|
|
68
|
-
JniSkiaBaseView::surfaceAvailable(surface, width, height,
|
|
68
|
+
JniSkiaBaseView::surfaceAvailable(surface, width, height, isSurface,
|
|
69
69
|
highBitDepth);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
void surfaceSizeChanged(jobject surface, int width, int height, bool
|
|
72
|
+
void surfaceSizeChanged(jobject surface, int width, int height, bool isSurface,
|
|
73
73
|
bool highBitDepth) override {
|
|
74
|
-
JniSkiaBaseView::surfaceSizeChanged(surface, width, height,
|
|
74
|
+
JniSkiaBaseView::surfaceSizeChanged(surface, width, height, isSurface,
|
|
75
75
|
highBitDepth);
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -28,7 +28,7 @@ public:
|
|
|
28
28
|
|
|
29
29
|
gl::Display *getDisplay() { return _glDisplay.get(); }
|
|
30
30
|
gl::Context *getContext() { return _glContext.get(); }
|
|
31
|
-
gl::Surface *getSurface() { return _glSurface.get(); }
|
|
31
|
+
gl::Surface *getSurface() { return _glSurface.get(); }
|
|
32
32
|
EGLConfig getConfig() { return _glConfig; }
|
|
33
33
|
|
|
34
34
|
private:
|
|
@@ -12,12 +12,12 @@ namespace RNSkia {
|
|
|
12
12
|
class RNSkBaseAndroidView {
|
|
13
13
|
public:
|
|
14
14
|
virtual void surfaceAvailable(jobject surface, int width, int height,
|
|
15
|
-
bool
|
|
15
|
+
bool isSurface, bool highBitDepth) = 0;
|
|
16
16
|
|
|
17
17
|
virtual void surfaceDestroyed() = 0;
|
|
18
18
|
|
|
19
19
|
virtual void surfaceSizeChanged(jobject surface, int width, int height,
|
|
20
|
-
bool
|
|
20
|
+
bool isSurface, bool highBitDepth) = 0;
|
|
21
21
|
|
|
22
22
|
virtual float getPixelDensity() = 0;
|
|
23
23
|
|
|
@@ -34,10 +34,10 @@ public:
|
|
|
34
34
|
std::make_shared<RNSkOpenGLCanvasProvider>(
|
|
35
35
|
std::bind(&RNSkia::RNSkView::requestRedraw, this), context)) {}
|
|
36
36
|
|
|
37
|
-
void surfaceAvailable(jobject surface, int width, int height, bool
|
|
37
|
+
void surfaceAvailable(jobject surface, int width, int height, bool isSurface,
|
|
38
38
|
bool highBitDepth) override {
|
|
39
39
|
std::static_pointer_cast<RNSkOpenGLCanvasProvider>(T::getCanvasProvider())
|
|
40
|
-
->surfaceAvailable(surface, width, height,
|
|
40
|
+
->surfaceAvailable(surface, width, height, isSurface, highBitDepth);
|
|
41
41
|
RNSkView::redraw();
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -46,10 +46,10 @@ public:
|
|
|
46
46
|
->surfaceDestroyed();
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
void surfaceSizeChanged(jobject surface, int width, int height, bool
|
|
49
|
+
void surfaceSizeChanged(jobject surface, int width, int height, bool isSurface,
|
|
50
50
|
bool highBitDepth) override {
|
|
51
51
|
std::static_pointer_cast<RNSkOpenGLCanvasProvider>(T::getCanvasProvider())
|
|
52
|
-
->surfaceSizeChanged(surface, width, height,
|
|
52
|
+
->surfaceSizeChanged(surface, width, height, isSurface, highBitDepth);
|
|
53
53
|
// This is only need for the first time to frame, this renderImmediate call
|
|
54
54
|
// will invoke updateTexImage for the previous frame
|
|
55
55
|
RNSkView::redraw();
|
|
@@ -78,7 +78,7 @@ bool RNSkOpenGLCanvasProvider::renderToCanvas(
|
|
|
78
78
|
|
|
79
79
|
void RNSkOpenGLCanvasProvider::surfaceAvailable(jobject jSurfaceTexture,
|
|
80
80
|
int width, int height,
|
|
81
|
-
bool
|
|
81
|
+
bool isSurface,
|
|
82
82
|
bool highBitDepth) {
|
|
83
83
|
// Release the old surface
|
|
84
84
|
_surfaceHolder = nullptr;
|
|
@@ -86,7 +86,7 @@ void RNSkOpenGLCanvasProvider::surfaceAvailable(jobject jSurfaceTexture,
|
|
|
86
86
|
// Create renderer!
|
|
87
87
|
ANativeWindow *window = nullptr;
|
|
88
88
|
JNIEnv *env = facebook::jni::Environment::current();
|
|
89
|
-
if (!
|
|
89
|
+
if (!isSurface) {
|
|
90
90
|
_jSurfaceTexture = env->NewGlobalRef(jSurfaceTexture);
|
|
91
91
|
jclass surfaceClass = env->FindClass("android/view/Surface");
|
|
92
92
|
jmethodID surfaceConstructor = env->GetMethodID(
|
|
@@ -131,7 +131,7 @@ void RNSkOpenGLCanvasProvider::surfaceDestroyed() {
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
void RNSkOpenGLCanvasProvider::surfaceSizeChanged(jobject jSurface, int width,
|
|
134
|
-
int height, bool
|
|
134
|
+
int height, bool isSurface,
|
|
135
135
|
bool highBitDepth) {
|
|
136
136
|
if (width == 0 && height == 0) {
|
|
137
137
|
// Setting width/height to zero is nothing we need to care about when
|
|
@@ -141,7 +141,7 @@ void RNSkOpenGLCanvasProvider::surfaceSizeChanged(jobject jSurface, int width,
|
|
|
141
141
|
|
|
142
142
|
if (_surfaceHolder == nullptr) {
|
|
143
143
|
_surfaceHolder = nullptr;
|
|
144
|
-
surfaceAvailable(jSurface, width, height,
|
|
144
|
+
surfaceAvailable(jSurface, width, height, isSurface, highBitDepth);
|
|
145
145
|
} else {
|
|
146
146
|
_surfaceHolder->resize(width, height);
|
|
147
147
|
}
|
|
@@ -27,12 +27,12 @@ public:
|
|
|
27
27
|
|
|
28
28
|
bool renderToCanvas(const std::function<void(SkCanvas *)> &cb) override;
|
|
29
29
|
|
|
30
|
-
void surfaceAvailable(jobject surface, int width, int height, bool
|
|
30
|
+
void surfaceAvailable(jobject surface, int width, int height, bool isSurface,
|
|
31
31
|
bool highBitDepth);
|
|
32
32
|
|
|
33
33
|
void surfaceDestroyed();
|
|
34
34
|
|
|
35
|
-
void surfaceSizeChanged(jobject jSurface, int width, int height, bool
|
|
35
|
+
void surfaceSizeChanged(jobject jSurface, int width, int height, bool isSurface,
|
|
36
36
|
bool highBitDepth);
|
|
37
37
|
|
|
38
38
|
private:
|
package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/RNSkiaModule.java
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// RnskiaModule.java
|
|
2
2
|
|
|
3
|
-
package com.
|
|
3
|
+
package com.reactnative.skia;
|
|
4
4
|
|
|
5
5
|
import android.util.Log;
|
|
6
6
|
|
|
@@ -17,11 +17,6 @@ public class RNSkiaModule extends NativeSkiaModuleSpec {
|
|
|
17
17
|
|
|
18
18
|
private final WeakReference<ReactApplicationContext> weakReactContext;
|
|
19
19
|
private SkiaManager skiaManager;
|
|
20
|
-
private static volatile boolean sIsValid = false;
|
|
21
|
-
|
|
22
|
-
public static boolean isModuleValid() {
|
|
23
|
-
return sIsValid;
|
|
24
|
-
}
|
|
25
20
|
|
|
26
21
|
public RNSkiaModule(ReactApplicationContext reactContext) {
|
|
27
22
|
super(reactContext);
|
|
@@ -31,7 +26,6 @@ public class RNSkiaModule extends NativeSkiaModuleSpec {
|
|
|
31
26
|
@Override
|
|
32
27
|
public void invalidate() {
|
|
33
28
|
super.invalidate();
|
|
34
|
-
sIsValid = false;
|
|
35
29
|
|
|
36
30
|
if (this.skiaManager != null) {
|
|
37
31
|
this.skiaManager.invalidate();
|
|
@@ -64,7 +58,6 @@ public class RNSkiaModule extends NativeSkiaModuleSpec {
|
|
|
64
58
|
return false;
|
|
65
59
|
}
|
|
66
60
|
skiaManager = new SkiaManager(context);
|
|
67
|
-
sIsValid = true;
|
|
68
61
|
return true;
|
|
69
62
|
} catch (Exception exception) {
|
|
70
63
|
Log.e(NAME, "Failed to initialize Skia Manager!", exception);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// RnskiaPackage.java
|
|
2
|
+
|
|
3
|
+
package com.reactnative.skia;
|
|
4
|
+
|
|
5
|
+
import androidx.annotation.Nullable;
|
|
6
|
+
|
|
7
|
+
import java.util.Arrays;
|
|
8
|
+
import java.util.HashMap;
|
|
9
|
+
import java.util.List;
|
|
10
|
+
import java.util.Map;
|
|
11
|
+
|
|
12
|
+
import com.facebook.react.BaseReactPackage;
|
|
13
|
+
import com.facebook.react.ReactPackage;
|
|
14
|
+
import com.facebook.react.bridge.NativeModule;
|
|
15
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
16
|
+
import com.facebook.react.module.model.ReactModuleInfo;
|
|
17
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
|
18
|
+
import com.facebook.react.uimanager.ViewManager;
|
|
19
|
+
|
|
20
|
+
// `implements ReactPackage` is redundant (BaseReactPackage already implements it)
|
|
21
|
+
// but required: older @react-native-community/cli versions only autolink
|
|
22
|
+
// classes matching `implements ReactPackage` or `extends TurboReactPackage`.
|
|
23
|
+
public class RNSkiaPackage extends BaseReactPackage implements ReactPackage {
|
|
24
|
+
@Nullable
|
|
25
|
+
@Override
|
|
26
|
+
public NativeModule getModule(String name, ReactApplicationContext reactApplicationContext) {
|
|
27
|
+
if (RNSkiaModule.NAME.equals(name)) {
|
|
28
|
+
return new RNSkiaModule(reactApplicationContext);
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@Override
|
|
34
|
+
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
|
35
|
+
return Arrays.<ViewManager>asList(
|
|
36
|
+
new SkiaPictureViewManager()
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Override
|
|
41
|
+
public ReactModuleInfoProvider getReactModuleInfoProvider() {
|
|
42
|
+
return () -> {
|
|
43
|
+
final Map<String, ReactModuleInfo> reactModuleInfoMap = new HashMap<>();
|
|
44
|
+
reactModuleInfoMap.put(
|
|
45
|
+
RNSkiaModule.NAME,
|
|
46
|
+
new ReactModuleInfo(
|
|
47
|
+
RNSkiaModule.NAME,
|
|
48
|
+
RNSkiaModule.class.getName(),
|
|
49
|
+
false, // canOverrideExistingModule
|
|
50
|
+
false, // needsEagerInit
|
|
51
|
+
false, // isCxxModule
|
|
52
|
+
true // isTurboModule
|
|
53
|
+
));
|
|
54
|
+
return reactModuleInfoMap;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
package com.reactnative.skia;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.graphics.SurfaceTexture;
|
|
5
|
+
import android.util.Log;
|
|
6
|
+
import android.view.MotionEvent;
|
|
7
|
+
import android.view.Surface;
|
|
8
|
+
import android.view.View;
|
|
9
|
+
|
|
10
|
+
import com.facebook.react.uimanager.PointerEvents;
|
|
11
|
+
import com.facebook.react.views.view.ReactViewGroup;
|
|
12
|
+
|
|
13
|
+
public abstract class SkiaBaseView extends ReactViewGroup implements SkiaViewAPI {
|
|
14
|
+
// Backing view kinds, see updateView().
|
|
15
|
+
private static final int KIND_SURFACE_VIEW = 0;
|
|
16
|
+
private static final int KIND_TEXTURE_VIEW = 1;
|
|
17
|
+
|
|
18
|
+
private View mView;
|
|
19
|
+
|
|
20
|
+
// Props, applied together in updateView().
|
|
21
|
+
private boolean mOpaque = false;
|
|
22
|
+
private String mSurfaceType = "auto";
|
|
23
|
+
private boolean mZOrderOnTop = false;
|
|
24
|
+
private boolean mHighBitDepth = false;
|
|
25
|
+
|
|
26
|
+
// What the current backing view was created with.
|
|
27
|
+
private int mAppliedKind = -1;
|
|
28
|
+
private boolean mAppliedZOrderOnTop;
|
|
29
|
+
private boolean mAppliedHighBitDepth;
|
|
30
|
+
|
|
31
|
+
private final boolean debug = false;
|
|
32
|
+
private final String tag = "SkiaView";
|
|
33
|
+
|
|
34
|
+
public SkiaBaseView(Context context) {
|
|
35
|
+
super(context);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@Override
|
|
39
|
+
public boolean dispatchTouchEvent(MotionEvent ev) {
|
|
40
|
+
// When pointerEvents is "none" or "box-none", make this view completely
|
|
41
|
+
// transparent to touch dispatch so events pass through to views behind it
|
|
42
|
+
if (!PointerEvents.canBeTouchTarget(getPointerEvents())) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return super.dispatchTouchEvent(ev);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public void setOpaque(boolean value) {
|
|
49
|
+
mOpaque = value;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public void setSurfaceType(String value) {
|
|
53
|
+
mSurfaceType = value == null ? "auto" : value;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public void setZOrderOnTop(boolean value) {
|
|
57
|
+
mZOrderOnTop = value;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public void setHighBitDepth(boolean value) {
|
|
61
|
+
mHighBitDepth = value;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Resolve the backing view from the props. "auto" picks SurfaceView for an
|
|
65
|
+
// opaque canvas and TextureView for a non-opaque one.
|
|
66
|
+
private int resolveKind() {
|
|
67
|
+
if ("SurfaceView".equals(mSurfaceType)) {
|
|
68
|
+
return KIND_SURFACE_VIEW;
|
|
69
|
+
}
|
|
70
|
+
if ("TextureView".equals(mSurfaceType)) {
|
|
71
|
+
return KIND_TEXTURE_VIEW;
|
|
72
|
+
}
|
|
73
|
+
return mOpaque ? KIND_SURFACE_VIEW : KIND_TEXTURE_VIEW;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// The 10-bit buffer format only has 2 bits of alpha, which would visibly
|
|
77
|
+
// break translucency, and the extra precision would be lost in the 8-bit
|
|
78
|
+
// composition pass of a TextureView anyway. So the flag only applies to an
|
|
79
|
+
// opaque SurfaceView.
|
|
80
|
+
private boolean resolveHighBitDepth(int kind) {
|
|
81
|
+
if (!mHighBitDepth) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
if (kind != KIND_SURFACE_VIEW || !mOpaque) {
|
|
85
|
+
Log.w(tag, "highBitDepth requires an opaque SurfaceView on Android, falling back to the 8-bit format");
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Apply the complete prop transaction once, after every prop has arrived.
|
|
92
|
+
// Only a change of backing view, or of a setting the view must know before
|
|
93
|
+
// it attaches (zOrderOnTop, the buffer format), replaces the child; opacity
|
|
94
|
+
// is applied in place.
|
|
95
|
+
void updateView() {
|
|
96
|
+
int kind = resolveKind();
|
|
97
|
+
boolean zOrderOnTop = kind == KIND_SURFACE_VIEW && mZOrderOnTop;
|
|
98
|
+
boolean highBitDepth = resolveHighBitDepth(kind);
|
|
99
|
+
if (mView == null
|
|
100
|
+
|| kind != mAppliedKind
|
|
101
|
+
|| zOrderOnTop != mAppliedZOrderOnTop
|
|
102
|
+
|| highBitDepth != mAppliedHighBitDepth) {
|
|
103
|
+
if (mView != null) {
|
|
104
|
+
removeView(mView);
|
|
105
|
+
}
|
|
106
|
+
mAppliedKind = kind;
|
|
107
|
+
mAppliedZOrderOnTop = zOrderOnTop;
|
|
108
|
+
mAppliedHighBitDepth = highBitDepth;
|
|
109
|
+
mView = kind == KIND_SURFACE_VIEW
|
|
110
|
+
? new SkiaSurfaceView(getContext(), this, debug, zOrderOnTop, mOpaque)
|
|
111
|
+
: new SkiaTextureView(getContext(), this, debug, mOpaque);
|
|
112
|
+
addView(mView);
|
|
113
|
+
// React Native sizes native children explicitly through onLayout, so
|
|
114
|
+
// the requestLayout triggered by addView is ignored; size the new
|
|
115
|
+
// child ourselves or it stays 0x0 and never gets a surface.
|
|
116
|
+
if (getWidth() > 0 || getHeight() > 0) {
|
|
117
|
+
mView.layout(0, 0, getWidth(), getHeight());
|
|
118
|
+
}
|
|
119
|
+
} else if (kind == KIND_SURFACE_VIEW) {
|
|
120
|
+
((SkiaSurfaceView) mView).setOpaque(mOpaque);
|
|
121
|
+
} else {
|
|
122
|
+
((SkiaTextureView) mView).setOpaque(mOpaque);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
void dropInstance() {
|
|
127
|
+
unregisterView();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@Override
|
|
131
|
+
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
132
|
+
super.onLayout(changed, left, top, right, bottom);
|
|
133
|
+
if (mView != null) {
|
|
134
|
+
mView.layout(0, 0, right - left, bottom - top);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// SurfaceView callbacks: the native side receives an android.view.Surface.
|
|
139
|
+
|
|
140
|
+
@Override
|
|
141
|
+
public void onSurfaceCreated(Surface surface, int width, int height) {
|
|
142
|
+
surfaceAvailable(surface, width, height, true, mAppliedHighBitDepth);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@Override
|
|
146
|
+
public void onSurfaceChanged(Surface surface, int width, int height) {
|
|
147
|
+
Log.i(tag, "onSurfaceChanged " + width + "/" + height);
|
|
148
|
+
surfaceSizeChanged(surface, width, height, true, mAppliedHighBitDepth);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// TextureView callbacks: the native side receives a SurfaceTexture and
|
|
152
|
+
// drives updateTexImage itself. The 10-bit format is never used here.
|
|
153
|
+
|
|
154
|
+
@Override
|
|
155
|
+
public void onSurfaceTextureCreated(SurfaceTexture surface, int width, int height) {
|
|
156
|
+
surfaceAvailable(surface, width, height, false, false);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@Override
|
|
160
|
+
public void onSurfaceTextureChanged(SurfaceTexture surface, int width, int height) {
|
|
161
|
+
Log.i(tag, "onSurfaceTextureSizeChanged " + width + "/" + height);
|
|
162
|
+
surfaceSizeChanged(surface, width, height, false, false);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@Override
|
|
166
|
+
public void onSurfaceDestroyed() {
|
|
167
|
+
surfaceDestroyed();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// isSurface tells the native side whether `surface` is an
|
|
171
|
+
// android.view.Surface (SurfaceView) or a SurfaceTexture (TextureView).
|
|
172
|
+
protected abstract void surfaceAvailable(Object surface, int width, int height, boolean isSurface, boolean highBitDepth);
|
|
173
|
+
|
|
174
|
+
protected abstract void surfaceSizeChanged(Object surface, int width, int height, boolean isSurface, boolean highBitDepth);
|
|
175
|
+
|
|
176
|
+
protected abstract void surfaceDestroyed();
|
|
177
|
+
|
|
178
|
+
protected abstract void setDebugMode(boolean show);
|
|
179
|
+
|
|
180
|
+
protected abstract void registerView(int nativeId);
|
|
181
|
+
|
|
182
|
+
protected abstract void unregisterView();
|
|
183
|
+
|
|
184
|
+
protected abstract int[] getBitmap(int width, int height);
|
|
185
|
+
}
|
package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaBaseViewManager.java
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.reactnative.skia;
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.uimanager.PointerEvents;
|
|
4
4
|
import com.facebook.react.uimanager.ViewProps;
|
|
@@ -33,6 +33,25 @@ public abstract class SkiaBaseViewManager<T extends SkiaBaseView> extends ReactV
|
|
|
33
33
|
((SkiaBaseView)view).setHighBitDepth(value);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
@ReactProp(name = "androidSurfaceType")
|
|
37
|
+
public void setAndroidSurfaceType(T view, @Nullable String value) {
|
|
38
|
+
((SkiaBaseView)view).setSurfaceType(value);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@ReactProp(name = "androidZOrderOnTop")
|
|
42
|
+
public void setAndroidZOrderOnTop(T view, boolean value) {
|
|
43
|
+
((SkiaBaseView)view).setZOrderOnTop(value);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// The backing view depends on several props (opaque, androidSurfaceType,
|
|
47
|
+
// androidZOrderOnTop, highBitDepth), so it is resolved once per transaction
|
|
48
|
+
// rather than in each setter.
|
|
49
|
+
@Override
|
|
50
|
+
protected void onAfterUpdateTransaction(@NonNull ReactViewGroup view) {
|
|
51
|
+
super.onAfterUpdateTransaction(view);
|
|
52
|
+
((SkiaBaseView)view).updateView();
|
|
53
|
+
}
|
|
54
|
+
|
|
36
55
|
@ReactProp(name = ViewProps.POINTER_EVENTS)
|
|
37
56
|
public void setPointerEvents(T view, @Nullable String pointerEventsStr) {
|
|
38
57
|
view.setPointerEvents(PointerEvents.parsePointerEvents(pointerEventsStr));
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.reactnative.skia;
|
|
2
2
|
|
|
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.turbomodule.core.CallInvokerHolderImpl;
|
|
7
|
+
import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder;
|
|
7
8
|
|
|
8
9
|
@DoNotStrip
|
|
9
10
|
public class SkiaManager {
|
|
@@ -22,11 +23,15 @@ public class SkiaManager {
|
|
|
22
23
|
super();
|
|
23
24
|
mContext = context;
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
CallInvokerHolder jsCallInvokerHolder = context.getJSCallInvokerHolder();
|
|
27
|
+
if (jsCallInvokerHolder == null) {
|
|
28
|
+
throw new IllegalStateException("React instance is not ready: no JS CallInvoker available");
|
|
29
|
+
}
|
|
26
30
|
|
|
27
31
|
mPlatformContext = new PlatformContext(context);
|
|
28
32
|
|
|
29
|
-
mHybridData = initHybrid(context.getJavaScriptContextHolder().get(),
|
|
33
|
+
mHybridData = initHybrid(context.getJavaScriptContextHolder().get(),
|
|
34
|
+
(CallInvokerHolderImpl) jsCallInvokerHolder, mPlatformContext);
|
|
30
35
|
|
|
31
36
|
initializeRuntime();
|
|
32
37
|
}
|
|
@@ -44,10 +49,10 @@ public class SkiaManager {
|
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
// private C++ functions
|
|
47
|
-
private native HybridData initHybrid(long jsContext,
|
|
52
|
+
private native HybridData initHybrid(long jsContext, CallInvokerHolderImpl jsCallInvokerHolder,
|
|
48
53
|
PlatformContext platformContext);
|
|
49
54
|
|
|
50
55
|
private native void initializeRuntime();
|
|
51
56
|
public native void invalidate();
|
|
52
57
|
|
|
53
|
-
}
|
|
58
|
+
}
|
package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaPictureView.java
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.reactnative.skia;
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
import android.graphics.Bitmap;
|
|
@@ -67,9 +67,9 @@ public class SkiaPictureView extends SkiaBaseView {
|
|
|
67
67
|
|
|
68
68
|
private native HybridData initHybrid(SkiaManager skiaManager);
|
|
69
69
|
|
|
70
|
-
protected native void surfaceAvailable(Object surface, int width, int height, boolean
|
|
70
|
+
protected native void surfaceAvailable(Object surface, int width, int height, boolean isSurface, boolean highBitDepth);
|
|
71
71
|
|
|
72
|
-
protected native void surfaceSizeChanged(Object surface, int width, int height, boolean
|
|
72
|
+
protected native void surfaceSizeChanged(Object surface, int width, int height, boolean isSurface, boolean highBitDepth);
|
|
73
73
|
|
|
74
74
|
protected native void surfaceDestroyed();
|
|
75
75
|
|
package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaSurfaceView.java
RENAMED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.reactnative.skia;
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint;
|
|
4
4
|
import android.content.Context;
|
|
5
|
+
import android.graphics.PixelFormat;
|
|
5
6
|
import android.view.SurfaceHolder;
|
|
6
7
|
import android.view.SurfaceView;
|
|
7
8
|
import androidx.annotation.NonNull;
|
|
@@ -12,13 +13,22 @@ public class SkiaSurfaceView extends SurfaceView implements SurfaceHolder.Callba
|
|
|
12
13
|
SkiaViewAPI mApi;
|
|
13
14
|
boolean mDebug;
|
|
14
15
|
|
|
15
|
-
public SkiaSurfaceView(Context context, SkiaViewAPI api, boolean debug) {
|
|
16
|
+
public SkiaSurfaceView(Context context, SkiaViewAPI api, boolean debug, boolean zOrderOnTop, boolean opaque) {
|
|
16
17
|
super(context);
|
|
17
18
|
mApi = api;
|
|
18
19
|
mDebug = debug;
|
|
20
|
+
// Must be set before the surface is created.
|
|
21
|
+
setZOrderOnTop(zOrderOnTop);
|
|
22
|
+
setOpaque(opaque);
|
|
19
23
|
getHolder().addCallback(this);
|
|
20
24
|
}
|
|
21
25
|
|
|
26
|
+
// The format drives the compositor's opaque flag for this layer. It can
|
|
27
|
+
// change on a live surface: SurfaceView reports it through surfaceChanged.
|
|
28
|
+
public void setOpaque(boolean opaque) {
|
|
29
|
+
getHolder().setFormat(opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT);
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
@Override
|
|
23
33
|
protected void onDetachedFromWindow() {
|
|
24
34
|
super.onDetachedFromWindow();
|
|
@@ -39,4 +49,4 @@ public class SkiaSurfaceView extends SurfaceView implements SurfaceHolder.Callba
|
|
|
39
49
|
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
|
|
40
50
|
mApi.onSurfaceDestroyed();
|
|
41
51
|
}
|
|
42
|
-
}
|
|
52
|
+
}
|