@shopify/react-native-skia 1.5.10 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. package/android/cpp/jni/include/JniSkiaBaseView.h +6 -5
  2. package/android/cpp/jni/include/JniSkiaDomView.h +6 -4
  3. package/android/cpp/jni/include/JniSkiaManager.h +2 -2
  4. package/android/cpp/jni/include/JniSkiaPictureView.h +6 -4
  5. package/android/cpp/rnskia-android/MainThreadDispatcher.h +3 -0
  6. package/android/cpp/rnskia-android/OpenGLContext.h +44 -9
  7. package/android/cpp/rnskia-android/OpenGLWindowContext.cpp +0 -1
  8. package/android/cpp/rnskia-android/OpenGLWindowContext.h +2 -2
  9. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +61 -3
  10. package/android/cpp/rnskia-android/RNSkAndroidView.h +10 -13
  11. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +42 -36
  12. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +2 -2
  13. package/android/cpp/rnskia-android/gl/Display.h +2 -0
  14. package/android/src/main/java/com/shopify/reactnative/skia/SkiaAHBView.java +113 -0
  15. package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +45 -54
  16. package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseViewManager.java +5 -0
  17. package/android/src/main/java/com/shopify/reactnative/skia/SkiaDomView.java +2 -2
  18. package/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureView.java +2 -2
  19. package/android/src/main/java/com/shopify/reactnative/skia/SkiaSurfaceView.java +42 -0
  20. package/android/src/main/java/com/shopify/reactnative/skia/SkiaTextureView.java +90 -0
  21. package/android/src/main/java/com/shopify/reactnative/skia/SkiaViewAPI.java +16 -0
  22. package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaDomViewManagerDelegate.java +3 -0
  23. package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaDomViewManagerInterface.java +1 -0
  24. package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerDelegate.java +3 -1
  25. package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerInterface.java +1 -0
  26. package/cpp/api/JsiSkContourMeasure.h +1 -5
  27. package/cpp/api/JsiSkImage.h +11 -0
  28. package/cpp/api/JsiSkImageFactory.h +14 -0
  29. package/cpp/api/JsiSkPicture.h +2 -0
  30. package/cpp/api/JsiSkSurface.h +7 -0
  31. package/cpp/api/JsiTextureInfo.h +53 -0
  32. package/cpp/jsi/ViewProperty.h +48 -0
  33. package/cpp/rnskia/RNSkDomView.cpp +0 -20
  34. package/cpp/rnskia/RNSkDomView.h +4 -9
  35. package/cpp/rnskia/RNSkJsiViewApi.h +3 -3
  36. package/cpp/rnskia/RNSkPictureView.h +11 -28
  37. package/cpp/rnskia/RNSkPlatformContext.h +18 -12
  38. package/cpp/rnskia/RNSkView.h +5 -29
  39. package/ios/RNSkia-iOS/MetalContext.h +101 -15
  40. package/ios/RNSkia-iOS/MetalContext.mm +9 -8
  41. package/ios/RNSkia-iOS/MetalWindowContext.h +39 -0
  42. package/ios/RNSkia-iOS/MetalWindowContext.mm +60 -0
  43. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +13 -25
  44. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +88 -2
  45. package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.mm +9 -2
  46. package/ios/RNSkia-iOS/SkiaDomViewManager.mm +5 -0
  47. package/ios/RNSkia-iOS/SkiaManager.mm +1 -2
  48. package/ios/RNSkia-iOS/SkiaPictureView.mm +1 -0
  49. package/ios/RNSkia-iOS/SkiaPictureViewManager.mm +5 -0
  50. package/ios/RNSkia-iOS/SkiaUIView.h +1 -0
  51. package/ios/RNSkia-iOS/SkiaUIView.mm +21 -14
  52. package/lib/commonjs/skia/types/Image/ColorType.d.ts +21 -0
  53. package/lib/commonjs/skia/types/Image/ColorType.js +29 -0
  54. package/lib/commonjs/skia/types/Image/ColorType.js.map +1 -0
  55. package/lib/commonjs/skia/types/Image/ColorType.web.d.ts +19 -0
  56. package/lib/commonjs/skia/types/Image/ColorType.web.js +27 -0
  57. package/lib/commonjs/skia/types/Image/ColorType.web.js.map +1 -0
  58. package/lib/commonjs/skia/types/Image/Image.d.ts +10 -0
  59. package/lib/commonjs/skia/types/Image/Image.js.map +1 -1
  60. package/lib/commonjs/skia/types/Image/ImageFactory.d.ts +19 -19
  61. package/lib/commonjs/skia/types/Image/ImageFactory.js +1 -21
  62. package/lib/commonjs/skia/types/Image/ImageFactory.js.map +1 -1
  63. package/lib/commonjs/skia/types/Image/index.d.ts +1 -0
  64. package/lib/commonjs/skia/types/Image/index.js +11 -0
  65. package/lib/commonjs/skia/types/Image/index.js.map +1 -1
  66. package/lib/commonjs/skia/types/Matrix4.d.ts +6 -0
  67. package/lib/commonjs/skia/types/Matrix4.js +69 -1
  68. package/lib/commonjs/skia/types/Matrix4.js.map +1 -1
  69. package/lib/commonjs/skia/types/Surface/Surface.d.ts +11 -0
  70. package/lib/commonjs/skia/types/Surface/Surface.js.map +1 -1
  71. package/lib/commonjs/skia/web/JsiSkImage.d.ts +1 -0
  72. package/lib/commonjs/skia/web/JsiSkImage.js +4 -0
  73. package/lib/commonjs/skia/web/JsiSkImage.js.map +1 -1
  74. package/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +1 -0
  75. package/lib/commonjs/skia/web/JsiSkImageFactory.js +3 -0
  76. package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
  77. package/lib/commonjs/skia/web/JsiSkSurface.d.ts +1 -0
  78. package/lib/commonjs/skia/web/JsiSkSurface.js +4 -0
  79. package/lib/commonjs/skia/web/JsiSkSurface.js.map +1 -1
  80. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.d.ts +1 -0
  81. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.js.map +1 -1
  82. package/lib/commonjs/views/SkiaDomView.js +3 -1
  83. package/lib/commonjs/views/SkiaDomView.js.map +1 -1
  84. package/lib/commonjs/views/SkiaPictureView.js +5 -1
  85. package/lib/commonjs/views/SkiaPictureView.js.map +1 -1
  86. package/lib/commonjs/views/types.d.ts +2 -0
  87. package/lib/commonjs/views/types.js.map +1 -1
  88. package/lib/module/skia/types/Image/ColorType.d.ts +21 -0
  89. package/lib/module/skia/types/Image/ColorType.js +23 -0
  90. package/lib/module/skia/types/Image/ColorType.js.map +1 -0
  91. package/lib/module/skia/types/Image/ColorType.web.d.ts +19 -0
  92. package/lib/module/skia/types/Image/ColorType.web.js +21 -0
  93. package/lib/module/skia/types/Image/ColorType.web.js.map +1 -0
  94. package/lib/module/skia/types/Image/Image.d.ts +10 -0
  95. package/lib/module/skia/types/Image/Image.js.map +1 -1
  96. package/lib/module/skia/types/Image/ImageFactory.d.ts +19 -19
  97. package/lib/module/skia/types/Image/ImageFactory.js +0 -20
  98. package/lib/module/skia/types/Image/ImageFactory.js.map +1 -1
  99. package/lib/module/skia/types/Image/index.d.ts +1 -0
  100. package/lib/module/skia/types/Image/index.js +1 -0
  101. package/lib/module/skia/types/Image/index.js.map +1 -1
  102. package/lib/module/skia/types/Matrix4.d.ts +6 -0
  103. package/lib/module/skia/types/Matrix4.js +67 -0
  104. package/lib/module/skia/types/Matrix4.js.map +1 -1
  105. package/lib/module/skia/types/Surface/Surface.d.ts +11 -0
  106. package/lib/module/skia/types/Surface/Surface.js.map +1 -1
  107. package/lib/module/skia/web/JsiSkImage.d.ts +1 -0
  108. package/lib/module/skia/web/JsiSkImage.js +4 -0
  109. package/lib/module/skia/web/JsiSkImage.js.map +1 -1
  110. package/lib/module/skia/web/JsiSkImageFactory.d.ts +1 -0
  111. package/lib/module/skia/web/JsiSkImageFactory.js +3 -0
  112. package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
  113. package/lib/module/skia/web/JsiSkSurface.d.ts +1 -0
  114. package/lib/module/skia/web/JsiSkSurface.js +4 -0
  115. package/lib/module/skia/web/JsiSkSurface.js.map +1 -1
  116. package/lib/module/specs/SkiaPictureViewNativeComponent.d.ts +1 -0
  117. package/lib/module/specs/SkiaPictureViewNativeComponent.js.map +1 -1
  118. package/lib/module/views/SkiaDomView.js +3 -1
  119. package/lib/module/views/SkiaDomView.js.map +1 -1
  120. package/lib/module/views/SkiaPictureView.js +5 -1
  121. package/lib/module/views/SkiaPictureView.js.map +1 -1
  122. package/lib/module/views/types.d.ts +2 -0
  123. package/lib/module/views/types.js.map +1 -1
  124. package/lib/typescript/lib/commonjs/skia/types/Image/ColorType.d.ts +2 -0
  125. package/lib/typescript/lib/commonjs/skia/types/Image/ColorType.web.d.ts +2 -0
  126. package/lib/typescript/lib/commonjs/skia/types/Image/ImageFactory.d.ts +0 -1
  127. package/lib/typescript/lib/commonjs/skia/types/Matrix4.d.ts +6 -0
  128. package/lib/typescript/lib/commonjs/skia/web/JsiSkImage.d.ts +1 -0
  129. package/lib/typescript/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +1 -0
  130. package/lib/typescript/lib/commonjs/skia/web/JsiSkSurface.d.ts +1 -0
  131. package/lib/typescript/lib/module/mock/index.d.ts +1 -0
  132. package/lib/typescript/lib/module/skia/types/Image/ColorType.d.ts +1 -0
  133. package/lib/typescript/lib/module/skia/types/Image/ColorType.web.d.ts +1 -0
  134. package/lib/typescript/lib/module/skia/types/Image/ImageFactory.d.ts +0 -1
  135. package/lib/typescript/lib/module/skia/types/Image/index.d.ts +1 -0
  136. package/lib/typescript/lib/module/skia/types/Matrix4.d.ts +1 -0
  137. package/lib/typescript/lib/module/skia/web/JsiSkImage.d.ts +1 -0
  138. package/lib/typescript/lib/module/skia/web/JsiSkImageFactory.d.ts +1 -0
  139. package/lib/typescript/lib/module/skia/web/JsiSkSurface.d.ts +1 -0
  140. package/lib/typescript/src/skia/types/Image/ColorType.d.ts +21 -0
  141. package/lib/typescript/src/skia/types/Image/ColorType.web.d.ts +19 -0
  142. package/lib/typescript/src/skia/types/Image/Image.d.ts +10 -0
  143. package/lib/typescript/src/skia/types/Image/ImageFactory.d.ts +19 -19
  144. package/lib/typescript/src/skia/types/Image/index.d.ts +1 -0
  145. package/lib/typescript/src/skia/types/Matrix4.d.ts +6 -0
  146. package/lib/typescript/src/skia/types/Surface/Surface.d.ts +11 -0
  147. package/lib/typescript/src/skia/web/JsiSkImage.d.ts +1 -0
  148. package/lib/typescript/src/skia/web/JsiSkImageFactory.d.ts +1 -0
  149. package/lib/typescript/src/skia/web/JsiSkSurface.d.ts +1 -0
  150. package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.d.ts +1 -0
  151. package/lib/typescript/src/views/types.d.ts +2 -0
  152. package/package.json +1 -1
  153. package/src/renderer/__tests__/e2e/Matrix4.spec.tsx +93 -0
  154. package/src/skia/__tests__/Enums.spec.ts +2 -2
  155. package/src/skia/types/Image/ColorType.ts +21 -0
  156. package/src/skia/types/Image/ColorType.web.ts +19 -0
  157. package/src/skia/types/Image/Image.ts +11 -0
  158. package/src/skia/types/Image/ImageFactory.ts +25 -20
  159. package/src/skia/types/Image/index.ts +1 -0
  160. package/src/skia/types/Matrix4.ts +101 -0
  161. package/src/skia/types/Surface/Surface.ts +12 -0
  162. package/src/skia/web/JsiSkImage.ts +5 -0
  163. package/src/skia/web/JsiSkImageFactory.ts +4 -0
  164. package/src/skia/web/JsiSkSurface.ts +5 -0
  165. package/src/specs/SkiaPictureViewNativeComponent.ts +1 -0
  166. package/src/views/SkiaDomView.tsx +2 -1
  167. package/src/views/SkiaPictureView.tsx +4 -1
  168. package/src/views/types.ts +3 -0
  169. package/cpp/jsi/JsiValueWrapper.h +0 -164
  170. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +0 -128
  171. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +0 -92
@@ -29,12 +29,14 @@ public:
29
29
  }
30
30
 
31
31
  protected:
32
- virtual void surfaceAvailable(jobject surface, int width, int height) {
33
- _skiaAndroidView->surfaceAvailable(surface, width, height);
32
+ virtual void surfaceAvailable(jobject surface, int width, int height,
33
+ bool opaque) {
34
+ _skiaAndroidView->surfaceAvailable(surface, width, height, opaque);
34
35
  }
35
36
 
36
- virtual void surfaceSizeChanged(jobject surface, int width, int height) {
37
- _skiaAndroidView->surfaceSizeChanged(surface, width, height);
37
+ virtual void surfaceSizeChanged(jobject surface, int width, int height,
38
+ bool opaque) {
39
+ _skiaAndroidView->surfaceSizeChanged(surface, width, height, opaque);
38
40
  }
39
41
 
40
42
  virtual void surfaceDestroyed() { _skiaAndroidView->surfaceDestroyed(); }
@@ -53,7 +55,6 @@ protected:
53
55
  _skiaAndroidView->getSkiaView()->getNativeId(), nullptr);
54
56
  getSkiaManager()->unregisterSkiaView(
55
57
  _skiaAndroidView->getSkiaView()->getNativeId());
56
- _skiaAndroidView->viewDidUnmount();
57
58
  }
58
59
 
59
60
  private:
@@ -46,12 +46,14 @@ public:
46
46
  }
47
47
 
48
48
  protected:
49
- void surfaceAvailable(jobject surface, int width, int height) override {
50
- JniSkiaBaseView::surfaceAvailable(surface, width, height);
49
+ void surfaceAvailable(jobject surface, int width, int height,
50
+ bool opaque) override {
51
+ JniSkiaBaseView::surfaceAvailable(surface, width, height, opaque);
51
52
  }
52
53
 
53
- void surfaceSizeChanged(jobject surface, int width, int height) override {
54
- JniSkiaBaseView::surfaceSizeChanged(surface, width, height);
54
+ void surfaceSizeChanged(jobject surface, int width, int height,
55
+ bool opaque) override {
56
+ JniSkiaBaseView::surfaceSizeChanged(surface, width, height, opaque);
55
57
  }
56
58
 
57
59
  void surfaceDestroyed() override { JniSkiaBaseView::surfaceDestroyed(); }
@@ -44,8 +44,8 @@ public:
44
44
  JniPlatformContext *platformContext)
45
45
  : _javaPart(jni::make_global(jThis)), _jsRuntime(runtime),
46
46
  _jsCallInvoker(jsCallInvoker),
47
- _context(std::make_shared<RNSkAndroidPlatformContext>(
48
- platformContext, runtime, jsCallInvoker)) {}
47
+ _context(std::make_shared<RNSkAndroidPlatformContext>(platformContext,
48
+ jsCallInvoker)) {}
49
49
 
50
50
  std::shared_ptr<RNSkAndroidPlatformContext> getPlatformContext() {
51
51
  return _context;
@@ -48,12 +48,14 @@ public:
48
48
  }
49
49
 
50
50
  protected:
51
- void surfaceAvailable(jobject surface, int width, int height) override {
52
- JniSkiaBaseView::surfaceAvailable(surface, width, height);
51
+ void surfaceAvailable(jobject surface, int width, int height,
52
+ bool opaque) override {
53
+ JniSkiaBaseView::surfaceAvailable(surface, width, height, opaque);
53
54
  }
54
55
 
55
- void surfaceSizeChanged(jobject surface, int width, int height) override {
56
- JniSkiaBaseView::surfaceSizeChanged(surface, width, height);
56
+ void surfaceSizeChanged(jobject surface, int width, int height,
57
+ bool opaque) override {
58
+ JniSkiaBaseView::surfaceSizeChanged(surface, width, height, opaque);
57
59
  }
58
60
 
59
61
  void surfaceDestroyed() override { JniSkiaBaseView::surfaceDestroyed(); }
@@ -1,6 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  #include <android/looper.h>
4
+ #include <queue>
4
5
  #include <unistd.h>
5
6
 
6
7
  class MainThreadDispatcher {
@@ -27,6 +28,8 @@ public:
27
28
  return instance;
28
29
  }
29
30
 
31
+ bool isOnMainThread() { return ALooper_forThread() == mainLooper; }
32
+
30
33
  void post(std::function<void()> task) {
31
34
  // TODO: this is disabled for now but we can clean this up
32
35
  // if (ALooper_forThread() == mainLooper) {
@@ -16,6 +16,36 @@
16
16
 
17
17
  namespace RNSkia {
18
18
 
19
+ class OpenGLSharedContext {
20
+ public:
21
+ OpenGLSharedContext(const OpenGLSharedContext &) = delete;
22
+ OpenGLSharedContext &operator=(const OpenGLSharedContext &) = delete;
23
+
24
+ static OpenGLSharedContext &getInstance() {
25
+ static OpenGLSharedContext instance;
26
+ return instance;
27
+ }
28
+
29
+ gl::Display *getDisplay() { return _glDisplay.get(); }
30
+ gl::Context *getContext() { return _glContext.get(); }
31
+ gl::Surface *getSurface() { return _glSurface.get(); };
32
+ EGLConfig getConfig() { return _glConfig; }
33
+
34
+ private:
35
+ std::unique_ptr<gl::Display> _glDisplay;
36
+ std::unique_ptr<gl::Context> _glContext;
37
+ std::unique_ptr<gl::Surface> _glSurface;
38
+ EGLConfig _glConfig;
39
+
40
+ OpenGLSharedContext() {
41
+ _glDisplay = std::make_unique<gl::Display>();
42
+ _glConfig = _glDisplay->chooseConfig();
43
+ _glContext = _glDisplay->makeContext(_glConfig, nullptr);
44
+ _glSurface = _glDisplay->makePixelBufferSurface(_glConfig, 1, 1);
45
+ _glContext->makeCurrent(_glSurface.get());
46
+ }
47
+ };
48
+
19
49
  class OpenGLContext {
20
50
  public:
21
51
  friend class OpenGLWindowContext;
@@ -39,8 +69,11 @@ public:
39
69
  }
40
70
 
41
71
  // Create texture
72
+ auto GL_RGBA8 = 0x8058;
73
+ auto format = GrBackendFormats::MakeGL(GL_RGBA8, GL_TEXTURE_2D);
42
74
  auto texture = _directContext->createBackendTexture(
43
- width, height, colorType, skgpu::Mipmapped::kNo, GrRenderable::kYes);
75
+ width, height, format, SkColors::kTransparent, skgpu::Mipmapped::kNo,
76
+ GrRenderable::kYes);
44
77
 
45
78
  if (!texture.isValid()) {
46
79
  RNSkLogger::logToConsole("couldn't create offscreen texture %dx%d", width,
@@ -128,24 +161,26 @@ public:
128
161
  // TODO: remove width, height
129
162
  std::unique_ptr<WindowContext> MakeWindow(ANativeWindow *window, int width,
130
163
  int height) {
164
+ auto display = OpenGLSharedContext::getInstance().getDisplay();
131
165
  return std::make_unique<OpenGLWindowContext>(
132
- _directContext.get(), _glDisplay.get(), _glContext.get(), window);
166
+ _directContext.get(), display, _glContext.get(), window,
167
+ OpenGLSharedContext::getInstance().getConfig());
133
168
  }
134
169
 
135
170
  GrDirectContext *getDirectContext() { return _directContext.get(); }
171
+ void makeCurrent() { _glContext->makeCurrent(_glSurface.get()); }
136
172
 
137
173
  private:
138
- EGLConfig _glConfig;
139
- std::unique_ptr<gl::Display> _glDisplay;
140
174
  std::unique_ptr<gl::Context> _glContext;
141
175
  std::unique_ptr<gl::Surface> _glSurface;
142
176
  sk_sp<GrDirectContext> _directContext;
143
177
 
144
178
  OpenGLContext() {
145
- _glDisplay = std::make_unique<gl::Display>();
146
- _glConfig = _glDisplay->chooseConfig();
147
- _glContext = _glDisplay->makeContext(_glConfig, nullptr);
148
- _glSurface = _glDisplay->makePixelBufferSurface(_glConfig, 1, 1);
179
+ auto display = OpenGLSharedContext::getInstance().getDisplay();
180
+ auto sharedContext = OpenGLSharedContext::getInstance().getContext();
181
+ auto glConfig = OpenGLSharedContext::getInstance().getConfig();
182
+ _glContext = display->makeContext(glConfig, sharedContext);
183
+ _glSurface = display->makePixelBufferSurface(glConfig, 1, 1);
149
184
  _glContext->makeCurrent(_glSurface.get());
150
185
  auto backendInterface = GrGLMakeNativeInterface();
151
186
  _directContext = GrDirectContexts::MakeGL(backendInterface);
@@ -156,4 +191,4 @@ private:
156
191
  }
157
192
  };
158
193
 
159
- } // namespace RNSkia
194
+ } // namespace RNSkia
@@ -53,7 +53,6 @@ sk_sp<SkSurface> OpenGLWindowContext::getSurface() {
53
53
 
54
54
  void OpenGLWindowContext::present() {
55
55
  _glContext->makeCurrent(_glSurface.get());
56
- // TODO: is flushAndSubmit needed here?
57
56
  _directContext->flushAndSubmit();
58
57
  _glSurface->present();
59
58
  }
@@ -34,11 +34,11 @@ namespace RNSkia {
34
34
  class OpenGLWindowContext : public WindowContext {
35
35
  public:
36
36
  OpenGLWindowContext(GrDirectContext *directContext, gl::Display *display,
37
- gl::Context *glContext, ANativeWindow *window)
37
+ gl::Context *glContext, ANativeWindow *window,
38
+ EGLConfig config)
38
39
  : _directContext(directContext), _display(display), _glContext(glContext),
39
40
  _window(window) {
40
41
  ANativeWindow_acquire(_window);
41
- auto config = display->chooseConfig();
42
42
  _glSurface = display->makeWindowSurface(config, _window);
43
43
  }
44
44
 
@@ -20,7 +20,6 @@
20
20
  #include "MainThreadDispatcher.h"
21
21
  #include "RNSkAndroidVideo.h"
22
22
  #include "RNSkPlatformContext.h"
23
-
24
23
  #pragma clang diagnostic push
25
24
  #pragma clang diagnostic ignored "-Wdocumentation"
26
25
 
@@ -34,9 +33,9 @@ namespace jsi = facebook::jsi;
34
33
  class RNSkAndroidPlatformContext : public RNSkPlatformContext {
35
34
  public:
36
35
  RNSkAndroidPlatformContext(
37
- JniPlatformContext *jniPlatformContext, jsi::Runtime *runtime,
36
+ JniPlatformContext *jniPlatformContext,
38
37
  std::shared_ptr<facebook::react::CallInvoker> jsCallInvoker)
39
- : RNSkPlatformContext(runtime, jsCallInvoker,
38
+ : RNSkPlatformContext(jsCallInvoker,
40
39
  jniPlatformContext->getPixelDensity()),
41
40
  _jniPlatformContext(jniPlatformContext) {}
42
41
 
@@ -78,6 +77,31 @@ public:
78
77
  #endif
79
78
  }
80
79
 
80
+ sk_sp<SkImage> makeImageFromNativeTexture(const TextureInfo &texInfo,
81
+ int width, int height,
82
+ bool mipMapped) override {
83
+ GrGLTextureInfo textureInfo;
84
+ textureInfo.fTarget = (GrGLenum)texInfo.glTarget;
85
+ textureInfo.fID = (GrGLuint)texInfo.glID;
86
+ textureInfo.fFormat = (GrGLenum)texInfo.glFormat;
87
+ textureInfo.fProtected =
88
+ texInfo.glProtected ? skgpu::Protected::kYes : skgpu::Protected::kNo;
89
+
90
+ OpenGLContext::getInstance().makeCurrent();
91
+ if (glIsTexture(textureInfo.fID) == GL_FALSE) {
92
+ throw new std::runtime_error("Invalid textureInfo");
93
+ }
94
+
95
+ GrBackendTexture backendTexture = GrBackendTextures::MakeGL(
96
+ width, height,
97
+ mipMapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo,
98
+ textureInfo);
99
+ return SkImages::BorrowTextureFrom(
100
+ OpenGLContext::getInstance().getDirectContext(), backendTexture,
101
+ kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType,
102
+ nullptr);
103
+ }
104
+
81
105
  std::shared_ptr<RNSkVideo> createVideo(const std::string &url) override {
82
106
  auto jniVideo = _jniPlatformContext->createVideo(url);
83
107
  return std::make_shared<RNSkAndroidVideo>(jniVideo);
@@ -149,6 +173,40 @@ public:
149
173
  #endif
150
174
  }
151
175
 
176
+ const TextureInfo getTexture(sk_sp<SkImage> image) override {
177
+ GrBackendTexture texture;
178
+ if (!SkImages::GetBackendTextureFromImage(image, &texture, true)) {
179
+ throw std::runtime_error("Couldn't get backend texture from image.");
180
+ }
181
+ return getJSITextureInfo(texture);
182
+ }
183
+
184
+ const TextureInfo getTexture(sk_sp<SkSurface> surface) override {
185
+ GrBackendTexture texture = SkSurfaces::GetBackendTexture(
186
+ surface.get(), SkSurface::BackendHandleAccess::kFlushRead);
187
+ return getJSITextureInfo(texture);
188
+ }
189
+
190
+ static const TextureInfo getJSITextureInfo(const GrBackendTexture &texture) {
191
+ if (!texture.isValid()) {
192
+ throw std::runtime_error("invalid backend texture");
193
+ }
194
+ GrGLTextureInfo textureInfo;
195
+ if (!GrBackendTextures::GetGLTextureInfo(texture, &textureInfo)) {
196
+ throw std::runtime_error("couldn't get OpenGL texture");
197
+ }
198
+
199
+ OpenGLContext::getInstance().makeCurrent();
200
+ glFlush();
201
+
202
+ TextureInfo texInfo;
203
+ texInfo.glProtected = textureInfo.isProtected();
204
+ texInfo.glID = textureInfo.fID;
205
+ texInfo.glFormat = textureInfo.fFormat;
206
+ texInfo.glTarget = textureInfo.fTarget;
207
+ return texInfo;
208
+ }
209
+
152
210
  #if !defined(SK_GRAPHITE)
153
211
  GrDirectContext *getDirectContext() override {
154
212
  return OpenGLContext::getInstance().getDirectContext();
@@ -11,18 +11,18 @@ namespace RNSkia {
11
11
 
12
12
  class RNSkBaseAndroidView {
13
13
  public:
14
- virtual void surfaceAvailable(jobject surface, int width, int height) = 0;
14
+ virtual void surfaceAvailable(jobject surface, int width, int height,
15
+ bool opaque) = 0;
15
16
 
16
17
  virtual void surfaceDestroyed() = 0;
17
18
 
18
- virtual void surfaceSizeChanged(jobject surface, int width, int height) = 0;
19
+ virtual void surfaceSizeChanged(jobject surface, int width, int height,
20
+ bool opaque) = 0;
19
21
 
20
22
  virtual float getPixelDensity() = 0;
21
23
 
22
24
  virtual void setShowDebugInfo(bool show) = 0;
23
25
 
24
- virtual void viewDidUnmount() = 0;
25
-
26
26
  virtual std::shared_ptr<RNSkView> getSkiaView() = 0;
27
27
  };
28
28
 
@@ -34,12 +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) override {
37
+ void surfaceAvailable(jobject surface, int width, int height,
38
+ bool opaque) override {
38
39
  std::static_pointer_cast<RNSkOpenGLCanvasProvider>(T::getCanvasProvider())
39
- ->surfaceAvailable(surface, width, height);
40
-
41
- // Try to render directly when the surface has been set so that
42
- // we don't have to wait until the draw loop returns.
40
+ ->surfaceAvailable(surface, width, height, opaque);
43
41
  RNSkView::redraw();
44
42
  }
45
43
 
@@ -48,9 +46,10 @@ public:
48
46
  ->surfaceDestroyed();
49
47
  }
50
48
 
51
- void surfaceSizeChanged(jobject surface, int width, int height) override {
49
+ void surfaceSizeChanged(jobject surface, int width, int height,
50
+ bool opaque) override {
52
51
  std::static_pointer_cast<RNSkOpenGLCanvasProvider>(T::getCanvasProvider())
53
- ->surfaceSizeChanged(surface, width, height);
52
+ ->surfaceSizeChanged(surface, width, height, opaque);
54
53
  // This is only need for the first time to frame, this renderImmediate call
55
54
  // will invoke updateTexImage for the previous frame
56
55
  RNSkView::redraw();
@@ -62,8 +61,6 @@ public:
62
61
 
63
62
  void setShowDebugInfo(bool show) override { T::setShowDebugOverlays(show); }
64
63
 
65
- void viewDidUnmount() override {}
66
-
67
64
  std::shared_ptr<RNSkView> getSkiaView() override {
68
65
  return T::shared_from_this();
69
66
  }
@@ -46,22 +46,24 @@ float RNSkOpenGLCanvasProvider::getScaledHeight() {
46
46
 
47
47
  bool RNSkOpenGLCanvasProvider::renderToCanvas(
48
48
  const std::function<void(SkCanvas *)> &cb) {
49
- JNIEnv *env = facebook::jni::Environment::current();
50
49
  if (_surfaceHolder != nullptr && cb != nullptr) {
51
50
  // Get the surface
52
51
  auto surface = _surfaceHolder->getSurface();
53
- env->CallVoidMethod(_jSurfaceTexture, _updateTexImageMethod);
54
-
55
- // Check for exceptions
56
- if (env->ExceptionCheck()) {
57
- RNSkLogger::logToConsole("updateAndRelease() failed. The exception above "
58
- "can safely be ignored");
59
- env->ExceptionClear();
52
+ if (_jSurfaceTexture) {
53
+ JNIEnv *env = facebook::jni::Environment::current();
54
+ env->CallVoidMethod(_jSurfaceTexture, _updateTexImageMethod);
55
+
56
+ // Check for exceptions
57
+ if (env->ExceptionCheck()) {
58
+ RNSkLogger::logToConsole(
59
+ "updateAndRelease() failed. The exception above "
60
+ "can safely be ignored");
61
+ env->ExceptionClear();
62
+ }
60
63
  }
61
64
  if (surface) {
62
65
  // Draw into canvas using callback
63
66
  cb(surface->getCanvas());
64
-
65
67
  // Swap buffers and show on screen
66
68
  _surfaceHolder->present();
67
69
  return true;
@@ -74,32 +76,36 @@ bool RNSkOpenGLCanvasProvider::renderToCanvas(
74
76
  }
75
77
 
76
78
  void RNSkOpenGLCanvasProvider::surfaceAvailable(jobject jSurfaceTexture,
77
- int width, int height) {
78
- // If the surface is 0, we can skip it
79
- if (width == 0 && height == 0) {
80
- return;
81
- }
79
+ int width, int height,
80
+ bool opaque) {
81
+ // Release the old surface
82
+ _surfaceHolder = nullptr;
83
+
82
84
  // Create renderer!
85
+ ANativeWindow *window = nullptr;
83
86
  JNIEnv *env = facebook::jni::Environment::current();
84
-
85
- _jSurfaceTexture = env->NewGlobalRef(jSurfaceTexture);
86
- jclass surfaceClass = env->FindClass("android/view/Surface");
87
- jmethodID surfaceConstructor = env->GetMethodID(
88
- surfaceClass, "<init>", "(Landroid/graphics/SurfaceTexture;)V");
89
- // Create a new Surface instance
90
- jobject jSurface =
91
- env->NewObject(surfaceClass, surfaceConstructor, jSurfaceTexture);
92
-
93
- jclass surfaceTextureClass = env->GetObjectClass(_jSurfaceTexture);
94
- _updateTexImageMethod =
95
- env->GetMethodID(surfaceTextureClass, "updateTexImage", "()V");
96
-
97
- // Acquire the native window from the Surface
98
- auto window = ANativeWindow_fromSurface(env, jSurface);
99
- // Clean up local references
100
- env->DeleteLocalRef(jSurface);
101
- env->DeleteLocalRef(surfaceClass);
102
- env->DeleteLocalRef(surfaceTextureClass);
87
+ if (!opaque) {
88
+ _jSurfaceTexture = env->NewGlobalRef(jSurfaceTexture);
89
+ jclass surfaceClass = env->FindClass("android/view/Surface");
90
+ jmethodID surfaceConstructor = env->GetMethodID(
91
+ surfaceClass, "<init>", "(Landroid/graphics/SurfaceTexture;)V");
92
+ // Create a new Surface instance
93
+ auto jSurface =
94
+ env->NewObject(surfaceClass, surfaceConstructor, jSurfaceTexture);
95
+ window = ANativeWindow_fromSurface(env, jSurface);
96
+
97
+ jclass surfaceTextureClass = env->GetObjectClass(_jSurfaceTexture);
98
+ _updateTexImageMethod =
99
+ env->GetMethodID(surfaceTextureClass, "updateTexImage", "()V");
100
+
101
+ // Acquire the native window from the Surface
102
+ // Clean up local references
103
+ env->DeleteLocalRef(jSurface);
104
+ env->DeleteLocalRef(surfaceClass);
105
+ env->DeleteLocalRef(surfaceTextureClass);
106
+ } else {
107
+ window = ANativeWindow_fromSurface(env, jSurfaceTexture);
108
+ }
103
109
  #if defined(SK_GRAPHITE)
104
110
  _surfaceHolder = DawnContext::getInstance().MakeWindow(window, width, height);
105
111
  #else
@@ -121,8 +127,8 @@ void RNSkOpenGLCanvasProvider::surfaceDestroyed() {
121
127
  }
122
128
  }
123
129
 
124
- void RNSkOpenGLCanvasProvider::surfaceSizeChanged(jobject jSurfaceTexture,
125
- int width, int height) {
130
+ void RNSkOpenGLCanvasProvider::surfaceSizeChanged(jobject jSurface, int width,
131
+ int height, bool opaque) {
126
132
  if (width == 0 && height == 0) {
127
133
  // Setting width/height to zero is nothing we need to care about when
128
134
  // it comes to invalidating the surface.
@@ -131,7 +137,7 @@ void RNSkOpenGLCanvasProvider::surfaceSizeChanged(jobject jSurfaceTexture,
131
137
 
132
138
  if (_surfaceHolder == nullptr) {
133
139
  _surfaceHolder = nullptr;
134
- surfaceAvailable(jSurfaceTexture, width, height);
140
+ surfaceAvailable(jSurface, width, height, opaque);
135
141
  } else {
136
142
  _surfaceHolder->resize(width, height);
137
143
  }
@@ -27,11 +27,11 @@ 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);
30
+ void surfaceAvailable(jobject surface, int width, int height, bool opaque);
31
31
 
32
32
  void surfaceDestroyed();
33
33
 
34
- void surfaceSizeChanged(jobject jSurface, int width, int height);
34
+ void surfaceSizeChanged(jobject jSurface, int width, int height, bool opaque);
35
35
 
36
36
  private:
37
37
  std::unique_ptr<WindowContext> _surfaceHolder = nullptr;
@@ -43,6 +43,8 @@ public:
43
43
 
44
44
  EGLint att[] = {EGL_RENDERABLE_TYPE,
45
45
  EGL_OPENGL_ES2_BIT,
46
+ EGL_SURFACE_TYPE,
47
+ EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
46
48
  EGL_ALPHA_SIZE,
47
49
  8,
48
50
  EGL_BLUE_SIZE,
@@ -0,0 +1,113 @@
1
+ package com.shopify.reactnative.skia;
2
+
3
+
4
+ import android.annotation.SuppressLint;
5
+ import android.content.Context;
6
+ import android.graphics.Bitmap;
7
+ import android.graphics.Canvas;
8
+ import android.graphics.Matrix;
9
+ import android.graphics.PixelFormat;
10
+ import android.hardware.HardwareBuffer;
11
+ import android.media.Image;
12
+ import android.media.ImageReader;
13
+ import android.os.Build;
14
+ import android.util.Log;
15
+ import android.view.View;
16
+
17
+ import androidx.annotation.NonNull;
18
+ import androidx.annotation.RequiresApi;
19
+
20
+ @SuppressLint("ViewConstructor")
21
+ @RequiresApi(api = Build.VERSION_CODES.Q)
22
+ public class SkiaAHBView extends View implements ImageReader.OnImageAvailableListener {
23
+
24
+ private ImageReader mReader;
25
+
26
+ private Bitmap mBitmap = null;
27
+
28
+ private final Matrix matrix = new Matrix();
29
+
30
+ SkiaViewAPI mApi;
31
+ boolean mDebug;
32
+
33
+ public SkiaAHBView(Context context, SkiaViewAPI api, boolean debug) {
34
+ super(context);
35
+ mApi = api;
36
+ mDebug = debug;
37
+ }
38
+
39
+ private ImageReader createReader() {
40
+ ImageReader reader = ImageReader.newInstance(getWidth(), getHeight(), PixelFormat.RGBA_8888, 2, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE |
41
+ HardwareBuffer.USAGE_GPU_COLOR_OUTPUT);
42
+ reader.setOnImageAvailableListener(this, null);
43
+ return reader;
44
+ }
45
+
46
+ @Override
47
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
48
+ super.onLayout(changed, left, top, right, bottom);
49
+ int width = getWidth();
50
+ int height = getHeight();
51
+ if (mReader == null) {
52
+ mReader = createReader();
53
+ mApi.onSurfaceCreated(mReader.getSurface(), width, height);
54
+ } else {
55
+ mReader = createReader();
56
+ mApi.onSurfaceChanged(mReader.getSurface(), width, height);
57
+ }
58
+ }
59
+
60
+ @Override
61
+ public void onImageAvailable(ImageReader reader) {
62
+ try (Image image = reader.acquireLatestImage()) {
63
+ if (image != null) {
64
+ HardwareBuffer hb = image.getHardwareBuffer();
65
+ if (mDebug) {
66
+ textureUpdated(image.getTimestamp());
67
+ }
68
+ if (hb != null) {
69
+ Bitmap bitmap = Bitmap.wrapHardwareBuffer(hb, null);
70
+ if (bitmap != null) {
71
+ mBitmap = bitmap;
72
+ hb.close();
73
+ invalidate();
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ @Override
81
+ protected void onDraw(@NonNull Canvas canvas) {
82
+ super.onDraw(canvas);
83
+ if (mBitmap != null) {
84
+ float viewWidth = getWidth();
85
+ float viewHeight = getHeight();
86
+ float bitmapWidth = mBitmap.getWidth();
87
+ float bitmapHeight = mBitmap.getHeight();
88
+
89
+ // Calculate the scale factors
90
+ float scaleX = viewWidth / bitmapWidth;
91
+ float scaleY = viewHeight / bitmapHeight;
92
+
93
+ // Reset the matrix and apply scaling
94
+ matrix.reset();
95
+ matrix.setScale(scaleX, scaleY);
96
+
97
+ canvas.drawBitmap(mBitmap, matrix, null);
98
+ }
99
+ }
100
+
101
+ private long _prevTimestamp = 0;
102
+ public void textureUpdated(long ts) {
103
+ long frameDuration = (ts - _prevTimestamp)/1000000;
104
+ Log.i("SkiaAHBView", "onSurfaceTextureUpdated "+frameDuration+"ms");
105
+ _prevTimestamp = ts;
106
+ }
107
+
108
+ @Override
109
+ protected void onDetachedFromWindow() {
110
+ super.onDetachedFromWindow();
111
+ mApi.onSurfaceDestroyed();
112
+ }
113
+ }