@shopify/react-native-skia 0.1.199 → 0.1.201
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 +1 -1
- package/android/cpp/jni/include/JniSkiaBaseView.h +74 -13
- package/android/cpp/jni/include/JniSkiaDomView.h +20 -12
- package/android/cpp/jni/include/JniSkiaDrawView.h +20 -14
- package/android/cpp/jni/include/JniSkiaPictureView.h +24 -15
- package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +2 -2
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +41 -44
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +4 -6
- package/android/cpp/rnskia-android/SkiaOpenGLHelper.h +310 -0
- package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp +132 -0
- package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.h +125 -0
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +80 -11
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaDomView.java +2 -0
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaDrawView.java +2 -0
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureView.java +3 -0
- package/android/src/main/java/com/shopify/reactnative/skia/ViewScreenshotService.java +7 -5
- package/cpp/api/JsiSkHostObjects.h +0 -10
- package/cpp/rnskia/RNSkJsView.cpp +35 -10
- package/cpp/rnskia/RNSkJsiViewApi.h +1 -1
- package/cpp/rnskia/RNSkView.h +9 -9
- package/ios/RNSkia-iOS/ViewScreenshotService.mm +1 -0
- package/package.json +2 -3
- package/android/cpp/rnskia-android/SkiaOpenGLRenderer.cpp +0 -347
- package/android/cpp/rnskia-android/SkiaOpenGLRenderer.h +0 -124
package/android/CMakeLists.txt
CHANGED
@@ -45,7 +45,7 @@ add_library(
|
|
45
45
|
|
46
46
|
"${PROJECT_SOURCE_DIR}/cpp/jni/JniPlatformContext.cpp"
|
47
47
|
"${PROJECT_SOURCE_DIR}/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp"
|
48
|
-
"${PROJECT_SOURCE_DIR}/cpp/rnskia-android/
|
48
|
+
"${PROJECT_SOURCE_DIR}/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp"
|
49
49
|
|
50
50
|
"${PROJECT_SOURCE_DIR}/../cpp/jsi/JsiHostObject.cpp"
|
51
51
|
"${PROJECT_SOURCE_DIR}/../cpp/jsi/JsiValue.cpp"
|
@@ -10,6 +10,8 @@
|
|
10
10
|
#include <JniSkiaManager.h>
|
11
11
|
#include <RNSkAndroidView.h>
|
12
12
|
|
13
|
+
#include <android/bitmap.h>
|
14
|
+
|
13
15
|
namespace RNSkia {
|
14
16
|
|
15
17
|
namespace jsi = facebook::jsi;
|
@@ -18,7 +20,7 @@ class JniSkiaBaseView {
|
|
18
20
|
public:
|
19
21
|
JniSkiaBaseView(jni::alias_ref<JniSkiaManager::javaobject> skiaManager,
|
20
22
|
std::shared_ptr<RNSkBaseAndroidView> skiaView)
|
21
|
-
: _manager(skiaManager->cthis()),
|
23
|
+
: _manager(skiaManager->cthis()), _skiaAndroidView(skiaView) {}
|
22
24
|
|
23
25
|
~JniSkiaBaseView() {}
|
24
26
|
|
@@ -28,38 +30,97 @@ public:
|
|
28
30
|
|
29
31
|
protected:
|
30
32
|
virtual void updateTouchPoints(jni::JArrayDouble touches) {
|
31
|
-
|
33
|
+
_skiaAndroidView->updateTouchPoints(touches);
|
32
34
|
}
|
33
35
|
|
34
36
|
virtual void surfaceAvailable(jobject surface, int width, int height) {
|
35
|
-
|
37
|
+
_skiaAndroidView->surfaceAvailable(surface, width, height);
|
36
38
|
}
|
37
39
|
|
38
40
|
virtual void surfaceSizeChanged(int width, int height) {
|
39
|
-
|
41
|
+
_skiaAndroidView->surfaceSizeChanged(width, height);
|
40
42
|
}
|
41
43
|
|
42
|
-
virtual void surfaceDestroyed() {
|
44
|
+
virtual void surfaceDestroyed() { _skiaAndroidView->surfaceDestroyed(); }
|
43
45
|
|
44
|
-
virtual void setMode(std::string mode) {
|
46
|
+
virtual void setMode(std::string mode) { _skiaAndroidView->setMode(mode); }
|
45
47
|
|
46
|
-
virtual void setDebugMode(bool show) {
|
48
|
+
virtual void setDebugMode(bool show) {
|
49
|
+
_skiaAndroidView->setShowDebugInfo(show);
|
50
|
+
}
|
47
51
|
|
48
52
|
virtual void registerView(int nativeId) {
|
49
|
-
getSkiaManager()->registerSkiaView(nativeId,
|
53
|
+
getSkiaManager()->registerSkiaView(nativeId,
|
54
|
+
_skiaAndroidView->getSkiaView());
|
50
55
|
}
|
51
56
|
|
52
57
|
virtual void unregisterView() {
|
53
|
-
getSkiaManager()->setSkiaView(
|
54
|
-
|
58
|
+
getSkiaManager()->setSkiaView(
|
59
|
+
_skiaAndroidView->getSkiaView()->getNativeId(), nullptr);
|
55
60
|
getSkiaManager()->unregisterSkiaView(
|
56
|
-
|
57
|
-
|
61
|
+
_skiaAndroidView->getSkiaView()->getNativeId());
|
62
|
+
_skiaAndroidView->viewDidUnmount();
|
58
63
|
}
|
59
64
|
|
65
|
+
/**
|
66
|
+
* Android specific method for rendering an offscreen GPU buffer to an Android
|
67
|
+
* bitmap. The result can be used to render the first frame of the Skia render
|
68
|
+
* to avoid flickering on android.
|
69
|
+
*/
|
70
|
+
/*
|
71
|
+
// TODO: Remove if we find another solution for first frame rendering
|
72
|
+
// protected native Object renderToBitmap(Object bitmap, int width, int
|
73
|
+
height); virtual jobject renderToBitmap(jobject bitmapIn, int width, int
|
74
|
+
height) { auto platformContext = getSkiaManager()->getPlatformContext(); auto
|
75
|
+
provider = std::make_shared<RNSkOffscreenCanvasProvider>( platformContext,
|
76
|
+
[]() {}, width, height);
|
77
|
+
|
78
|
+
// Render into a gpu backed buffer
|
79
|
+
_skiaAndroidView->getSkiaView()->getRenderer()->renderImmediate(provider);
|
80
|
+
auto rect = SkRect::MakeXYWH(0, 0, width, height);
|
81
|
+
auto image = provider->makeSnapshot(&rect);
|
82
|
+
|
83
|
+
AndroidBitmapInfo infoIn;
|
84
|
+
auto env = facebook::jni::Environment::current();
|
85
|
+
void *pixels;
|
86
|
+
|
87
|
+
// Get image info
|
88
|
+
if (AndroidBitmap_getInfo(env, bitmapIn, &infoIn) !=
|
89
|
+
ANDROID_BITMAP_RESULT_SUCCESS) {
|
90
|
+
return env->NewStringUTF("failed");
|
91
|
+
}
|
92
|
+
|
93
|
+
// Check image
|
94
|
+
if (infoIn.format != ANDROID_BITMAP_FORMAT_RGBA_8888 &&
|
95
|
+
infoIn.format != ANDROID_BITMAP_FORMAT_RGB_565) {
|
96
|
+
return env->NewStringUTF("Only support ANDROID_BITMAP_FORMAT_RGBA_8888 "
|
97
|
+
"and ANDROID_BITMAP_FORMAT_RGB_565");
|
98
|
+
}
|
99
|
+
|
100
|
+
auto imageInfo = SkImageInfo::Make(image->width(), image->height(),
|
101
|
+
image->colorType(), image->alphaType());
|
102
|
+
|
103
|
+
// Lock all images
|
104
|
+
if (AndroidBitmap_lockPixels(env, bitmapIn, &pixels) !=
|
105
|
+
ANDROID_BITMAP_RESULT_SUCCESS) {
|
106
|
+
return env->NewStringUTF("AndroidBitmap_lockPixels failed!");
|
107
|
+
}
|
108
|
+
|
109
|
+
// Set pixels from SkImage
|
110
|
+
image->readPixels(imageInfo, pixels, imageInfo.minRowBytes(), 0, 0);
|
111
|
+
|
112
|
+
// Unlocks everything
|
113
|
+
AndroidBitmap_unlockPixels(env, bitmapIn);
|
114
|
+
|
115
|
+
image = nullptr;
|
116
|
+
provider = nullptr;
|
117
|
+
|
118
|
+
return bitmapIn;
|
119
|
+
}*/
|
120
|
+
|
60
121
|
private:
|
61
122
|
JniSkiaManager *_manager;
|
62
|
-
std::shared_ptr<RNSkBaseAndroidView>
|
123
|
+
std::shared_ptr<RNSkBaseAndroidView> _skiaAndroidView;
|
63
124
|
};
|
64
125
|
|
65
126
|
} // namespace RNSkia
|
@@ -34,18 +34,21 @@ public:
|
|
34
34
|
}
|
35
35
|
|
36
36
|
static void registerNatives() {
|
37
|
-
registerHybrid(
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
37
|
+
registerHybrid({
|
38
|
+
makeNativeMethod("initHybrid", JniSkiaDomView::initHybrid),
|
39
|
+
makeNativeMethod("surfaceAvailable", JniSkiaDomView::surfaceAvailable),
|
40
|
+
makeNativeMethod("surfaceDestroyed", JniSkiaDomView::surfaceDestroyed),
|
41
|
+
makeNativeMethod("surfaceSizeChanged",
|
42
|
+
JniSkiaDomView::surfaceSizeChanged),
|
43
|
+
makeNativeMethod("setMode", JniSkiaDomView::setMode),
|
44
|
+
makeNativeMethod("setDebugMode", JniSkiaDomView::setDebugMode),
|
45
|
+
makeNativeMethod("updateTouchPoints",
|
46
|
+
JniSkiaDomView::updateTouchPoints),
|
47
|
+
makeNativeMethod("registerView", JniSkiaDomView::registerView),
|
48
|
+
makeNativeMethod("unregisterView", JniSkiaDomView::unregisterView)
|
49
|
+
// TODO: Remove if we find another solution for first frame rendering
|
50
|
+
// makeNativeMethod("renderToBitmap", JniSkiaDomView::renderToBitmap)
|
51
|
+
});
|
49
52
|
}
|
50
53
|
|
51
54
|
protected:
|
@@ -73,6 +76,11 @@ protected:
|
|
73
76
|
|
74
77
|
void unregisterView() override { JniSkiaBaseView::unregisterView(); }
|
75
78
|
|
79
|
+
// TODO: Remove if we find another solution for first frame rendering
|
80
|
+
/*jobject renderToBitmap(jobject bitmap, int width, int height) override {
|
81
|
+
return JniSkiaBaseView::renderToBitmap(bitmap, width, height);
|
82
|
+
}*/
|
83
|
+
|
76
84
|
private:
|
77
85
|
friend HybridBase;
|
78
86
|
|
@@ -33,20 +33,21 @@ public:
|
|
33
33
|
}
|
34
34
|
|
35
35
|
static void registerNatives() {
|
36
|
-
registerHybrid(
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
36
|
+
registerHybrid({
|
37
|
+
makeNativeMethod("initHybrid", JniSkiaDrawView::initHybrid),
|
38
|
+
makeNativeMethod("surfaceAvailable", JniSkiaDrawView::surfaceAvailable),
|
39
|
+
makeNativeMethod("surfaceDestroyed", JniSkiaDrawView::surfaceDestroyed),
|
40
|
+
makeNativeMethod("surfaceSizeChanged",
|
41
|
+
JniSkiaDrawView::surfaceSizeChanged),
|
42
|
+
makeNativeMethod("setMode", JniSkiaDrawView::setMode),
|
43
|
+
makeNativeMethod("setDebugMode", JniSkiaDrawView::setDebugMode),
|
44
|
+
makeNativeMethod("updateTouchPoints",
|
45
|
+
JniSkiaDrawView::updateTouchPoints),
|
46
|
+
makeNativeMethod("registerView", JniSkiaDrawView::registerView),
|
47
|
+
makeNativeMethod("unregisterView", JniSkiaDrawView::unregisterView),
|
48
|
+
// TODO: Remove if we find another solution for first frame rendering
|
49
|
+
// makeNativeMethod("renderToBitmap", JniSkiaDrawView::renderToBitmap)
|
50
|
+
});
|
50
51
|
}
|
51
52
|
|
52
53
|
protected:
|
@@ -74,6 +75,11 @@ protected:
|
|
74
75
|
|
75
76
|
void unregisterView() override { JniSkiaBaseView::unregisterView(); }
|
76
77
|
|
78
|
+
// TODO: Remove if we find another solution for first frame rendering
|
79
|
+
/*jobject renderToBitmap(jobject bitmap, int width, int height) override {
|
80
|
+
return JniSkiaBaseView::renderToBitmap(bitmap, width, height);
|
81
|
+
}*/
|
82
|
+
|
77
83
|
private:
|
78
84
|
friend HybridBase;
|
79
85
|
|
@@ -33,21 +33,24 @@ public:
|
|
33
33
|
}
|
34
34
|
|
35
35
|
static void registerNatives() {
|
36
|
-
registerHybrid(
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
36
|
+
registerHybrid({
|
37
|
+
makeNativeMethod("initHybrid", JniSkiaPictureView::initHybrid),
|
38
|
+
makeNativeMethod("surfaceAvailable",
|
39
|
+
JniSkiaPictureView::surfaceAvailable),
|
40
|
+
makeNativeMethod("surfaceDestroyed",
|
41
|
+
JniSkiaPictureView::surfaceDestroyed),
|
42
|
+
makeNativeMethod("surfaceSizeChanged",
|
43
|
+
JniSkiaPictureView::surfaceSizeChanged),
|
44
|
+
makeNativeMethod("setMode", JniSkiaPictureView::setMode),
|
45
|
+
makeNativeMethod("setDebugMode", JniSkiaPictureView::setDebugMode),
|
46
|
+
makeNativeMethod("updateTouchPoints",
|
47
|
+
JniSkiaPictureView::updateTouchPoints),
|
48
|
+
makeNativeMethod("registerView", JniSkiaPictureView::registerView),
|
49
|
+
makeNativeMethod("unregisterView", JniSkiaPictureView::unregisterView),
|
50
|
+
// TODO: Remove if we find another solution for first frame rendering
|
51
|
+
// makeNativeMethod("renderToBitmap",
|
52
|
+
// JniSkiaPictureView::renderToBitmap)
|
53
|
+
});
|
51
54
|
}
|
52
55
|
|
53
56
|
protected:
|
@@ -75,6 +78,12 @@ protected:
|
|
75
78
|
|
76
79
|
void unregisterView() override { JniSkiaBaseView::unregisterView(); }
|
77
80
|
|
81
|
+
/*
|
82
|
+
TODO: Remove if we find another solution for first frame rendering
|
83
|
+
jobject renderToBitmap(jobject bitmap, int width, int height) override {
|
84
|
+
return JniSkiaBaseView::renderToBitmap(bitmap, width, height);
|
85
|
+
}*/
|
86
|
+
|
78
87
|
private:
|
79
88
|
friend HybridBase;
|
80
89
|
|
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
#include <JniPlatformContext.h>
|
9
9
|
#include <RNSkPlatformContext.h>
|
10
|
-
#include <
|
10
|
+
#include <SkiaOpenGLSurfaceFactory.h>
|
11
11
|
|
12
12
|
namespace RNSkia {
|
13
13
|
namespace jsi = facebook::jsi;
|
@@ -38,7 +38,7 @@ public:
|
|
38
38
|
}
|
39
39
|
|
40
40
|
sk_sp<SkSurface> makeOffscreenSurface(int width, int height) override {
|
41
|
-
return
|
41
|
+
return SkiaOpenGLSurfaceFactory::makeOffscreenSurface(width, height);
|
42
42
|
}
|
43
43
|
|
44
44
|
void runOnMainThread(std::function<void()> task) override {
|
@@ -14,64 +14,60 @@ namespace RNSkia {
|
|
14
14
|
|
15
15
|
RNSkOpenGLCanvasProvider::RNSkOpenGLCanvasProvider(
|
16
16
|
std::function<void()> requestRedraw,
|
17
|
-
std::shared_ptr<RNSkia::RNSkPlatformContext>
|
18
|
-
: RNSkCanvasProvider(requestRedraw),
|
17
|
+
std::shared_ptr<RNSkia::RNSkPlatformContext> platformContext)
|
18
|
+
: RNSkCanvasProvider(requestRedraw), _platformContext(platformContext) {}
|
19
19
|
|
20
20
|
RNSkOpenGLCanvasProvider::~RNSkOpenGLCanvasProvider() {}
|
21
21
|
|
22
|
-
float RNSkOpenGLCanvasProvider::getScaledWidth() {
|
22
|
+
float RNSkOpenGLCanvasProvider::getScaledWidth() {
|
23
|
+
return _surfaceHolder ? _surfaceHolder->getWidth() : 0;
|
24
|
+
}
|
23
25
|
|
24
|
-
float RNSkOpenGLCanvasProvider::getScaledHeight() {
|
26
|
+
float RNSkOpenGLCanvasProvider::getScaledHeight() {
|
27
|
+
return _surfaceHolder ? _surfaceHolder->getHeight() : 0;
|
28
|
+
}
|
25
29
|
|
26
30
|
bool RNSkOpenGLCanvasProvider::renderToCanvas(
|
27
31
|
const std::function<void(SkCanvas *)> &cb) {
|
28
|
-
|
29
|
-
|
32
|
+
|
33
|
+
if (_surfaceHolder != nullptr && cb != nullptr) {
|
34
|
+
// Get the surface
|
35
|
+
auto surface = _surfaceHolder->getSurface();
|
36
|
+
if (surface) {
|
37
|
+
|
38
|
+
// Ensure we are ready to render
|
39
|
+
if (!_surfaceHolder->makeCurrent()) {
|
40
|
+
return false;
|
41
|
+
}
|
42
|
+
|
43
|
+
// Draw into canvas using callback
|
44
|
+
cb(surface->getCanvas());
|
45
|
+
|
46
|
+
// Swap buffers and show on screen
|
47
|
+
return _surfaceHolder->present();
|
48
|
+
|
49
|
+
} else {
|
50
|
+
// the render context did not provide a surface
|
51
|
+
return false;
|
52
|
+
}
|
30
53
|
}
|
54
|
+
|
31
55
|
return false;
|
32
56
|
}
|
33
57
|
|
34
58
|
void RNSkOpenGLCanvasProvider::surfaceAvailable(jobject surface, int width,
|
35
59
|
int height) {
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
if (_renderer == nullptr) {
|
40
|
-
// Create renderer!
|
41
|
-
_renderer = std::make_unique<SkiaOpenGLRenderer>(surface);
|
60
|
+
// Create renderer!
|
61
|
+
_surfaceHolder =
|
62
|
+
SkiaOpenGLSurfaceFactory::makeWindowedSurface(surface, width, height);
|
42
63
|
|
43
|
-
|
44
|
-
|
45
|
-
}
|
64
|
+
// Post redraw request to ensure we paint in the next draw cycle.
|
65
|
+
_requestRedraw();
|
46
66
|
}
|
47
67
|
void RNSkOpenGLCanvasProvider::surfaceDestroyed() {
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
// Teardown renderer on the render thread since OpenGL demands
|
53
|
-
// same thread access for OpenGL contexts.
|
54
|
-
std::condition_variable cv;
|
55
|
-
std::mutex m;
|
56
|
-
std::unique_lock<std::mutex> lock(m);
|
57
|
-
|
58
|
-
_context->runOnRenderThread([&cv, &m, weakSelf = weak_from_this()]() {
|
59
|
-
// Lock
|
60
|
-
std::unique_lock<std::mutex> lock(m);
|
61
|
-
|
62
|
-
auto self = weakSelf.lock();
|
63
|
-
if (self) {
|
64
|
-
if (self->_renderer != nullptr) {
|
65
|
-
self->_renderer->run(nullptr, 0, 0);
|
66
|
-
}
|
67
|
-
// Remove renderer
|
68
|
-
self->_renderer = nullptr;
|
69
|
-
}
|
70
|
-
cv.notify_one();
|
71
|
-
});
|
72
|
-
|
73
|
-
cv.wait(lock);
|
74
|
-
}
|
68
|
+
// destroy the renderer (a unique pointer so the dtor will be called
|
69
|
+
// immediately.)
|
70
|
+
_surfaceHolder = nullptr;
|
75
71
|
}
|
76
72
|
|
77
73
|
void RNSkOpenGLCanvasProvider::surfaceSizeChanged(int width, int height) {
|
@@ -80,8 +76,9 @@ void RNSkOpenGLCanvasProvider::surfaceSizeChanged(int width, int height) {
|
|
80
76
|
// it comes to invalidating the surface.
|
81
77
|
return;
|
82
78
|
}
|
83
|
-
|
84
|
-
|
79
|
+
|
80
|
+
// Recreate RenderContext surface based on size change???
|
81
|
+
_surfaceHolder->resize(width, height);
|
85
82
|
|
86
83
|
// Redraw after size change
|
87
84
|
_requestRedraw();
|
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
#include <RNSkJsView.h>
|
8
8
|
|
9
|
-
#include "
|
9
|
+
#include "SkiaOpenGLSurfaceFactory.h"
|
10
10
|
#include <android/native_window.h>
|
11
11
|
|
12
12
|
namespace RNSkia {
|
@@ -17,7 +17,7 @@ class RNSkOpenGLCanvasProvider
|
|
17
17
|
public:
|
18
18
|
RNSkOpenGLCanvasProvider(
|
19
19
|
std::function<void()> requestRedraw,
|
20
|
-
std::shared_ptr<RNSkia::RNSkPlatformContext>
|
20
|
+
std::shared_ptr<RNSkia::RNSkPlatformContext> platformContext);
|
21
21
|
|
22
22
|
~RNSkOpenGLCanvasProvider();
|
23
23
|
|
@@ -34,9 +34,7 @@ public:
|
|
34
34
|
void surfaceSizeChanged(int width, int height);
|
35
35
|
|
36
36
|
private:
|
37
|
-
std::unique_ptr<
|
38
|
-
std::shared_ptr<RNSkPlatformContext>
|
39
|
-
float _width = -1;
|
40
|
-
float _height = -1;
|
37
|
+
std::unique_ptr<WindowSurfaceHolder> _surfaceHolder = nullptr;
|
38
|
+
std::shared_ptr<RNSkPlatformContext> _platformContext;
|
41
39
|
};
|
42
40
|
} // namespace RNSkia
|