@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.
Files changed (24) hide show
  1. package/android/CMakeLists.txt +1 -1
  2. package/android/cpp/jni/include/JniSkiaBaseView.h +74 -13
  3. package/android/cpp/jni/include/JniSkiaDomView.h +20 -12
  4. package/android/cpp/jni/include/JniSkiaDrawView.h +20 -14
  5. package/android/cpp/jni/include/JniSkiaPictureView.h +24 -15
  6. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +2 -2
  7. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +41 -44
  8. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +4 -6
  9. package/android/cpp/rnskia-android/SkiaOpenGLHelper.h +310 -0
  10. package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp +132 -0
  11. package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.h +125 -0
  12. package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +80 -11
  13. package/android/src/main/java/com/shopify/reactnative/skia/SkiaDomView.java +2 -0
  14. package/android/src/main/java/com/shopify/reactnative/skia/SkiaDrawView.java +2 -0
  15. package/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureView.java +3 -0
  16. package/android/src/main/java/com/shopify/reactnative/skia/ViewScreenshotService.java +7 -5
  17. package/cpp/api/JsiSkHostObjects.h +0 -10
  18. package/cpp/rnskia/RNSkJsView.cpp +35 -10
  19. package/cpp/rnskia/RNSkJsiViewApi.h +1 -1
  20. package/cpp/rnskia/RNSkView.h +9 -9
  21. package/ios/RNSkia-iOS/ViewScreenshotService.mm +1 -0
  22. package/package.json +2 -3
  23. package/android/cpp/rnskia-android/SkiaOpenGLRenderer.cpp +0 -347
  24. package/android/cpp/rnskia-android/SkiaOpenGLRenderer.h +0 -124
@@ -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/SkiaOpenGLRenderer.cpp"
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()), _skiaView(skiaView) {}
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
- _skiaView->updateTouchPoints(touches);
33
+ _skiaAndroidView->updateTouchPoints(touches);
32
34
  }
33
35
 
34
36
  virtual void surfaceAvailable(jobject surface, int width, int height) {
35
- _skiaView->surfaceAvailable(surface, width, height);
37
+ _skiaAndroidView->surfaceAvailable(surface, width, height);
36
38
  }
37
39
 
38
40
  virtual void surfaceSizeChanged(int width, int height) {
39
- _skiaView->surfaceSizeChanged(width, height);
41
+ _skiaAndroidView->surfaceSizeChanged(width, height);
40
42
  }
41
43
 
42
- virtual void surfaceDestroyed() { _skiaView->surfaceDestroyed(); }
44
+ virtual void surfaceDestroyed() { _skiaAndroidView->surfaceDestroyed(); }
43
45
 
44
- virtual void setMode(std::string mode) { _skiaView->setMode(mode); }
46
+ virtual void setMode(std::string mode) { _skiaAndroidView->setMode(mode); }
45
47
 
46
- virtual void setDebugMode(bool show) { _skiaView->setShowDebugInfo(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, _skiaView->getSkiaView());
53
+ getSkiaManager()->registerSkiaView(nativeId,
54
+ _skiaAndroidView->getSkiaView());
50
55
  }
51
56
 
52
57
  virtual void unregisterView() {
53
- getSkiaManager()->setSkiaView(_skiaView->getSkiaView()->getNativeId(),
54
- nullptr);
58
+ getSkiaManager()->setSkiaView(
59
+ _skiaAndroidView->getSkiaView()->getNativeId(), nullptr);
55
60
  getSkiaManager()->unregisterSkiaView(
56
- _skiaView->getSkiaView()->getNativeId());
57
- _skiaView->viewDidUnmount();
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> _skiaView;
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
- {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)});
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
- {makeNativeMethod("initHybrid", JniSkiaDrawView::initHybrid),
38
- makeNativeMethod("surfaceAvailable",
39
- JniSkiaDrawView::surfaceAvailable),
40
- makeNativeMethod("surfaceDestroyed",
41
- JniSkiaDrawView::surfaceDestroyed),
42
- makeNativeMethod("surfaceSizeChanged",
43
- JniSkiaDrawView::surfaceSizeChanged),
44
- makeNativeMethod("setMode", JniSkiaDrawView::setMode),
45
- makeNativeMethod("setDebugMode", JniSkiaDrawView::setDebugMode),
46
- makeNativeMethod("updateTouchPoints",
47
- JniSkiaDrawView::updateTouchPoints),
48
- makeNativeMethod("registerView", JniSkiaDrawView::registerView),
49
- makeNativeMethod("unregisterView", JniSkiaDrawView::unregisterView)});
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
- {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",
50
- JniSkiaPictureView::unregisterView)});
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 <SkiaOpenGLRenderer.h>
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 MakeOffscreenGLSurface(width, height);
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> context)
18
- : RNSkCanvasProvider(requestRedraw), _context(context) {}
17
+ std::shared_ptr<RNSkia::RNSkPlatformContext> platformContext)
18
+ : RNSkCanvasProvider(requestRedraw), _platformContext(platformContext) {}
19
19
 
20
20
  RNSkOpenGLCanvasProvider::~RNSkOpenGLCanvasProvider() {}
21
21
 
22
- float RNSkOpenGLCanvasProvider::getScaledWidth() { return _width; }
22
+ float RNSkOpenGLCanvasProvider::getScaledWidth() {
23
+ return _surfaceHolder ? _surfaceHolder->getWidth() : 0;
24
+ }
23
25
 
24
- float RNSkOpenGLCanvasProvider::getScaledHeight() { return _height; }
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
- if (_renderer != nullptr) {
29
- return _renderer->run(cb, _width, _height);
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
- _width = width;
37
- _height = height;
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
- // Redraw
44
- _requestRedraw();
45
- }
64
+ // Post redraw request to ensure we paint in the next draw cycle.
65
+ _requestRedraw();
46
66
  }
47
67
  void RNSkOpenGLCanvasProvider::surfaceDestroyed() {
48
- if (_renderer != nullptr) {
49
- // teardown
50
- _renderer->teardown();
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
- _width = width;
84
- _height = height;
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 "SkiaOpenGLRenderer.h"
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> context);
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<SkiaOpenGLRenderer> _renderer = nullptr;
38
- std::shared_ptr<RNSkPlatformContext> _context;
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