@shopify/react-native-skia 1.5.0 → 1.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. package/android/cpp/jni/include/JniSkiaBaseView.h +0 -1
  2. package/android/cpp/jni/include/JniSkiaPictureView.h +0 -1
  3. package/android/cpp/rnskia-android/OpenGLContext.h +40 -0
  4. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +5 -5
  5. package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +2 -2
  6. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +49 -14
  7. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +5 -2
  8. package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp +19 -133
  9. package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.h +30 -138
  10. package/cpp/api/JsiSkTypefaceFontProvider.h +1 -1
  11. package/cpp/api/JsiSkiaContext.h +6 -3
  12. package/cpp/jsi/JsiValue.cpp +1 -2
  13. package/cpp/rnskia/RNSkPlatformContext.h +2 -2
  14. package/cpp/rnskia/{SkiaContext.h → WindowContext.h} +5 -2
  15. package/ios/RNSkia-iOS/DisplayLink.mm +7 -0
  16. package/ios/RNSkia-iOS/MetalContext.h +46 -0
  17. package/ios/RNSkia-iOS/MetalContext.mm +33 -0
  18. package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.mm +8 -28
  19. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +1 -1
  20. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +8 -9
  21. package/ios/RNSkia-iOS/RNSkiOSView.mm +0 -2
  22. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +28 -32
  23. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +18 -60
  24. package/ios/RNSkia-iOS/SkiaUIView.h +0 -2
  25. package/ios/RNSkia-iOS/ViewScreenshotService.mm +1 -8
  26. package/lib/commonjs/web/WithSkiaWeb.js +4 -1
  27. package/lib/commonjs/web/WithSkiaWeb.js.map +1 -1
  28. package/lib/module/web/WithSkiaWeb.js +4 -1
  29. package/lib/module/web/WithSkiaWeb.js.map +1 -1
  30. package/libs/ios/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
  31. package/libs/ios/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
  32. package/libs/ios/libskottie.xcframework/Info.plist +5 -5
  33. package/libs/ios/libskottie.xcframework/ios-arm64_arm64e/libskottie.a +0 -0
  34. package/libs/ios/libskottie.xcframework/ios-arm64_arm64e_x86_64-simulator/libskottie.a +0 -0
  35. package/libs/ios/libskparagraph.xcframework/Info.plist +5 -5
  36. package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e/libskparagraph.a +0 -0
  37. package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e_x86_64-simulator/libskparagraph.a +0 -0
  38. package/libs/ios/libsksg.xcframework/ios-arm64_arm64e/libsksg.a +0 -0
  39. package/libs/ios/libsksg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsksg.a +0 -0
  40. package/libs/ios/libskshaper.xcframework/Info.plist +5 -5
  41. package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e/libskshaper.a +0 -0
  42. package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e_x86_64-simulator/libskshaper.a +0 -0
  43. package/libs/ios/libskunicode_core.xcframework/ios-arm64_arm64e/libskunicode_core.a +0 -0
  44. package/libs/ios/libskunicode_core.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_core.a +0 -0
  45. package/libs/ios/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e/libskunicode_libgrapheme.a +0 -0
  46. package/libs/ios/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_libgrapheme.a +0 -0
  47. package/libs/ios/libsvg.xcframework/Info.plist +5 -5
  48. package/libs/ios/libsvg.xcframework/ios-arm64_arm64e/libsvg.a +0 -0
  49. package/libs/ios/libsvg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsvg.a +0 -0
  50. package/package.json +3 -6
  51. package/src/web/WithSkiaWeb.tsx +3 -1
@@ -29,7 +29,6 @@ public:
29
29
  }
30
30
 
31
31
  protected:
32
-
33
32
  virtual void surfaceAvailable(jobject surface, int width, int height) {
34
33
  _skiaAndroidView->surfaceAvailable(surface, width, height);
35
34
  }
@@ -49,7 +49,6 @@ public:
49
49
  }
50
50
 
51
51
  protected:
52
-
53
52
  void surfaceAvailable(jobject surface, int width, int height) override {
54
53
  JniSkiaBaseView::surfaceAvailable(surface, width, height);
55
54
  }
@@ -0,0 +1,40 @@
1
+ #pragma once
2
+
3
+ #include "SkiaOpenGLSurfaceFactory.h"
4
+ #include "WindowContext.h"
5
+
6
+ #include "include/core/SkSurface.h"
7
+
8
+ class OpenGLContext {
9
+ public:
10
+ OpenGLContext(const OpenGLContext &) = delete;
11
+ OpenGLContext &operator=(const OpenGLContext &) = delete;
12
+
13
+ static OpenGLContext &getInstance() {
14
+ static thread_local OpenGLContext instance;
15
+ return instance;
16
+ }
17
+
18
+ sk_sp<SkSurface> MakeOffscreen(int width, int height) {
19
+ return RNSkia::SkiaOpenGLSurfaceFactory::makeOffscreenSurface(
20
+ &_context, width, height);
21
+ }
22
+
23
+ sk_sp<SkImage> MakeImageFromBuffer(void *buffer) {
24
+ return RNSkia::SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(
25
+ &_context, buffer);
26
+ }
27
+
28
+ std::unique_ptr<RNSkia::WindowContext> MakeWindow(ANativeWindow *window,
29
+ int width, int height) {
30
+ return RNSkia::SkiaOpenGLSurfaceFactory::makeContext(&_context, window,
31
+ width, height);
32
+ }
33
+
34
+ private:
35
+ RNSkia::SkiaOpenGLContext _context;
36
+
37
+ OpenGLContext() {
38
+ RNSkia::SkiaOpenGLHelper::createSkiaDirectContextIfNecessary(&_context);
39
+ }
40
+ };
@@ -11,9 +11,9 @@
11
11
 
12
12
  #include "AHardwareBufferUtils.h"
13
13
  #include "JniPlatformContext.h"
14
+ #include "OpenGLContext.h"
14
15
  #include "RNSkAndroidVideo.h"
15
16
  #include "RNSkPlatformContext.h"
16
- #include "SkiaOpenGLSurfaceFactory.h"
17
17
 
18
18
  #pragma clang diagnostic push
19
19
  #pragma clang diagnostic ignored "-Wdocumentation"
@@ -51,17 +51,17 @@ public:
51
51
  }
52
52
 
53
53
  sk_sp<SkSurface> makeOffscreenSurface(int width, int height) override {
54
- return SkiaOpenGLSurfaceFactory::makeOffscreenSurface(width, height);
54
+ return OpenGLContext::getInstance().MakeOffscreen(width, height);
55
55
  }
56
56
 
57
- std::shared_ptr<SkiaContext>
57
+ std::shared_ptr<WindowContext>
58
58
  makeContextFromNativeSurface(void *surface, int width, int height) override {
59
- return SkiaOpenGLSurfaceFactory::makeContext(
59
+ return OpenGLContext::getInstance().MakeWindow(
60
60
  reinterpret_cast<ANativeWindow *>(surface), width, height);
61
61
  }
62
62
 
63
63
  sk_sp<SkImage> makeImageFromNativeBuffer(void *buffer) override {
64
- return SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(buffer);
64
+ return OpenGLContext::getInstance().MakeImageFromBuffer(buffer);
65
65
  }
66
66
 
67
67
  std::shared_ptr<RNSkVideo> createVideo(const std::string &url) override {
@@ -13,8 +13,8 @@
13
13
 
14
14
  #pragma clang diagnostic pop
15
15
 
16
+ #include "OpenGLContext.h"
16
17
  #include "RNSkAndroidVideo.h"
17
- #include "SkiaOpenGLSurfaceFactory.h"
18
18
 
19
19
  namespace RNSkia {
20
20
 
@@ -52,7 +52,7 @@ sk_sp<SkImage> RNSkAndroidVideo::nextImage(double *timeStamp) {
52
52
  // Convert jobject to AHardwareBuffer
53
53
  AHardwareBuffer *buffer =
54
54
  AHardwareBuffer_fromHardwareBuffer(env, jHardwareBuffer);
55
- return SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(buffer);
55
+ return OpenGLContext::getInstance().MakeImageFromBuffer(buffer);
56
56
  #else
57
57
  return nullptr;
58
58
  #endif
@@ -2,6 +2,8 @@
2
2
 
3
3
  #include <memory>
4
4
 
5
+ #include "OpenGLContext.h"
6
+
5
7
  #pragma clang diagnostic push
6
8
  #pragma clang diagnostic ignored "-Wdocumentation"
7
9
 
@@ -20,33 +22,41 @@ RNSkOpenGLCanvasProvider::RNSkOpenGLCanvasProvider(
20
22
  RNSkOpenGLCanvasProvider::~RNSkOpenGLCanvasProvider() {}
21
23
 
22
24
  float RNSkOpenGLCanvasProvider::getScaledWidth() {
23
- return _surfaceHolder ? _surfaceHolder->getWidth() : 0;
25
+ if (_surfaceHolder) {
26
+ return static_cast<float>(_surfaceHolder->getWidth());
27
+ }
28
+ return 0;
24
29
  }
25
30
 
26
31
  float RNSkOpenGLCanvasProvider::getScaledHeight() {
27
- return _surfaceHolder ? _surfaceHolder->getHeight() : 0;
32
+ if (_surfaceHolder) {
33
+ return static_cast<float>(_surfaceHolder->getHeight());
34
+ }
35
+ return 0;
28
36
  }
29
37
 
30
38
  bool RNSkOpenGLCanvasProvider::renderToCanvas(
31
39
  const std::function<void(SkCanvas *)> &cb) {
32
-
40
+ JNIEnv *env = facebook::jni::Environment::current();
33
41
  if (_surfaceHolder != nullptr && cb != nullptr) {
34
42
  // Get the surface
35
43
  auto surface = _surfaceHolder->getSurface();
36
- if (surface) {
37
-
38
- // Ensure we are ready to render
39
- if (!_surfaceHolder->makeCurrent()) {
40
- return false;
41
- }
42
- _surfaceHolder->updateTexImage();
44
+ env->CallVoidMethod(_jSurfaceTexture, _updateTexImageMethod);
43
45
 
46
+ // Check for exceptions
47
+ if (env->ExceptionCheck()) {
48
+ RNSkLogger::logToConsole("updateAndRelease() failed. The exception above "
49
+ "can safely be ignored");
50
+ env->ExceptionClear();
51
+ }
52
+ if (surface) {
44
53
  // Draw into canvas using callback
45
54
  cb(surface->getCanvas());
46
55
 
47
56
  // Swap buffers and show on screen
48
- return _surfaceHolder->present();
57
+ _surfaceHolder->present();
49
58
 
59
+ return true;
50
60
  } else {
51
61
  // the render context did not provide a surface
52
62
  return false;
@@ -56,11 +66,31 @@ bool RNSkOpenGLCanvasProvider::renderToCanvas(
56
66
  return false;
57
67
  }
58
68
 
59
- void RNSkOpenGLCanvasProvider::surfaceAvailable(jobject surface, int width,
60
- int height) {
69
+ void RNSkOpenGLCanvasProvider::surfaceAvailable(jobject jSurfaceTexture,
70
+ int width, int height) {
61
71
  // Create renderer!
72
+ JNIEnv *env = facebook::jni::Environment::current();
73
+
74
+ _jSurfaceTexture = env->NewGlobalRef(jSurfaceTexture);
75
+ jclass surfaceClass = env->FindClass("android/view/Surface");
76
+ jmethodID surfaceConstructor = env->GetMethodID(
77
+ surfaceClass, "<init>", "(Landroid/graphics/SurfaceTexture;)V");
78
+ // Create a new Surface instance
79
+ jobject jSurface =
80
+ env->NewObject(surfaceClass, surfaceConstructor, jSurfaceTexture);
81
+
82
+ jclass surfaceTextureClass = env->GetObjectClass(_jSurfaceTexture);
83
+ _updateTexImageMethod =
84
+ env->GetMethodID(surfaceTextureClass, "updateTexImage", "()V");
85
+
86
+ // Acquire the native window from the Surface
87
+ auto window = ANativeWindow_fromSurface(env, jSurface);
88
+ // Clean up local references
89
+ env->DeleteLocalRef(jSurface);
90
+ env->DeleteLocalRef(surfaceClass);
91
+ env->DeleteLocalRef(surfaceTextureClass);
62
92
  _surfaceHolder =
63
- SkiaOpenGLSurfaceFactory::makeWindowedSurface(surface, width, height);
93
+ OpenGLContext::getInstance().MakeWindow(window, width, height);
64
94
 
65
95
  // Post redraw request to ensure we paint in the next draw cycle.
66
96
  _requestRedraw();
@@ -69,6 +99,11 @@ void RNSkOpenGLCanvasProvider::surfaceDestroyed() {
69
99
  // destroy the renderer (a unique pointer so the dtor will be called
70
100
  // immediately.)
71
101
  _surfaceHolder = nullptr;
102
+ if (_jSurfaceTexture) {
103
+ JNIEnv *env = facebook::jni::Environment::current();
104
+ env->DeleteGlobalRef(_jSurfaceTexture);
105
+ _jSurfaceTexture = nullptr;
106
+ }
72
107
  }
73
108
 
74
109
  void RNSkOpenGLCanvasProvider::surfaceSizeChanged(int width, int height) {
@@ -5,7 +5,8 @@
5
5
  #include <memory>
6
6
 
7
7
  #include "RNSkView.h"
8
- #include "SkiaOpenGLSurfaceFactory.h"
8
+ #include "WindowContext.h"
9
+
9
10
  #include <android/native_window.h>
10
11
 
11
12
  namespace RNSkia {
@@ -33,7 +34,9 @@ public:
33
34
  void surfaceSizeChanged(int width, int height);
34
35
 
35
36
  private:
36
- std::unique_ptr<WindowSurfaceHolder> _surfaceHolder = nullptr;
37
+ std::unique_ptr<WindowContext> _surfaceHolder = nullptr;
37
38
  std::shared_ptr<RNSkPlatformContext> _platformContext;
39
+ jobject _jSurfaceTexture = nullptr;
40
+ jmethodID _updateTexImageMethod = nullptr;
38
41
  };
39
42
  } // namespace RNSkia
@@ -13,17 +13,9 @@
13
13
 
14
14
  namespace RNSkia {
15
15
 
16
- thread_local SkiaOpenGLContext ThreadContextHolder::ThreadSkiaOpenGLContext;
17
-
18
- sk_sp<SkImage>
19
- SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(void *buffer,
20
- bool requireKnownFormat) {
16
+ sk_sp<SkImage> SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(
17
+ SkiaOpenGLContext *context, void *buffer, bool requireKnownFormat) {
21
18
  #if __ANDROID_API__ >= 26
22
- // Setup OpenGL and Skia:
23
- if (!SkiaOpenGLHelper::createSkiaDirectContextIfNecessary(
24
- &ThreadContextHolder::ThreadSkiaOpenGLContext)) [[unlikely]] {
25
- throw std::runtime_error("Failed to create Skia Context for this Thread!");
26
- }
27
19
  const AHardwareBuffer *hardwareBuffer =
28
20
  static_cast<AHardwareBuffer *>(buffer);
29
21
  DeleteImageProc deleteImageProc = nullptr;
@@ -59,7 +51,7 @@ SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(void *buffer,
59
51
  }
60
52
 
61
53
  auto backendTex = MakeGLBackendTexture(
62
- ThreadContextHolder::ThreadSkiaOpenGLContext.directContext.get(),
54
+ context->directContext.get(),
63
55
  const_cast<AHardwareBuffer *>(hardwareBuffer), description.width,
64
56
  description.height, &deleteImageProc, &updateImageProc, &deleteImageCtx,
65
57
  false, format, false);
@@ -69,9 +61,9 @@ SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(void *buffer,
69
61
  return nullptr;
70
62
  }
71
63
  sk_sp<SkImage> image = SkImages::BorrowTextureFrom(
72
- ThreadContextHolder::ThreadSkiaOpenGLContext.directContext.get(),
73
- backendTex, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
74
- kOpaque_SkAlphaType, nullptr, deleteImageProc, deleteImageCtx);
64
+ context->directContext.get(), backendTex, kTopLeft_GrSurfaceOrigin,
65
+ kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr, deleteImageProc,
66
+ deleteImageCtx);
75
67
  return image;
76
68
  #else
77
69
  throw std::runtime_error(
@@ -80,25 +72,15 @@ SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(void *buffer,
80
72
  #endif
81
73
  }
82
74
 
83
- sk_sp<SkSurface> SkiaOpenGLSurfaceFactory::makeOffscreenSurface(int width,
84
- int height) {
85
- // Setup OpenGL and Skia:
86
- if (!SkiaOpenGLHelper::createSkiaDirectContextIfNecessary(
87
- &ThreadContextHolder::ThreadSkiaOpenGLContext)) {
88
-
89
- RNSkLogger::logToConsole(
90
- "Could not create Skia Surface from native window / surface. "
91
- "Failed creating Skia Direct Context");
92
- return nullptr;
93
- }
75
+ sk_sp<SkSurface>
76
+ SkiaOpenGLSurfaceFactory::makeOffscreenSurface(SkiaOpenGLContext *context,
77
+ int width, int height) {
94
78
 
95
79
  auto colorType = kN32_SkColorType;
96
80
 
97
81
  SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
98
82
 
99
- if (!SkiaOpenGLHelper::makeCurrent(
100
- &ThreadContextHolder::ThreadSkiaOpenGLContext,
101
- ThreadContextHolder::ThreadSkiaOpenGLContext.gl1x1Surface)) {
83
+ if (!SkiaOpenGLHelper::makeCurrent(context, context->gl1x1Surface)) {
102
84
  RNSkLogger::logToConsole(
103
85
  "Could not create EGL Surface from native window / surface. Could "
104
86
  "not set new surface as current surface.");
@@ -106,10 +88,8 @@ sk_sp<SkSurface> SkiaOpenGLSurfaceFactory::makeOffscreenSurface(int width,
106
88
  }
107
89
 
108
90
  // Create texture
109
- auto texture =
110
- ThreadContextHolder::ThreadSkiaOpenGLContext.directContext
111
- ->createBackendTexture(width, height, colorType,
112
- skgpu::Mipmapped::kNo, GrRenderable::kYes);
91
+ auto texture = context->directContext->createBackendTexture(
92
+ width, height, colorType, skgpu::Mipmapped::kNo, GrRenderable::kYes);
113
93
 
114
94
  if (!texture.isValid()) {
115
95
  RNSkLogger::logToConsole("couldn't create offscreen texture %dx%d", width,
@@ -121,13 +101,12 @@ sk_sp<SkSurface> SkiaOpenGLSurfaceFactory::makeOffscreenSurface(int width,
121
101
  GrBackendTexture texture;
122
102
  };
123
103
 
124
- auto releaseCtx = new ReleaseContext(
125
- {&ThreadContextHolder::ThreadSkiaOpenGLContext, texture});
104
+ auto releaseCtx = new ReleaseContext({context, texture});
126
105
 
127
106
  // Create a SkSurface from the GrBackendTexture
128
107
  return SkSurfaces::WrapBackendTexture(
129
- ThreadContextHolder::ThreadSkiaOpenGLContext.directContext.get(), texture,
130
- kTopLeft_GrSurfaceOrigin, 0, colorType, nullptr, &props,
108
+ context->directContext.get(), texture, kTopLeft_GrSurfaceOrigin, 0,
109
+ colorType, nullptr, &props,
131
110
  [](void *addr) {
132
111
  auto releaseCtx = reinterpret_cast<ReleaseContext *>(addr);
133
112
 
@@ -137,99 +116,9 @@ sk_sp<SkSurface> SkiaOpenGLSurfaceFactory::makeOffscreenSurface(int width,
137
116
  releaseCtx);
138
117
  }
139
118
 
140
- sk_sp<SkSurface> WindowSurfaceHolder::getSurface() {
141
- if (_skSurface == nullptr) {
142
-
143
- // Setup OpenGL and Skia
144
- if (!SkiaOpenGLHelper::createSkiaDirectContextIfNecessary(
145
- &ThreadContextHolder::ThreadSkiaOpenGLContext)) {
146
- RNSkLogger::logToConsole(
147
- "Could not create Skia Surface from native window / surface. "
148
- "Failed creating Skia Direct Context");
149
- return nullptr;
150
- }
151
-
152
- // Now we can create a surface
153
- _glSurface = SkiaOpenGLHelper::createWindowedSurface(_window);
154
- if (_glSurface == EGL_NO_SURFACE) {
155
- RNSkLogger::logToConsole(
156
- "Could not create EGL Surface from native window / surface.");
157
- return nullptr;
158
- }
159
-
160
- // Now make this one current
161
- if (!SkiaOpenGLHelper::makeCurrent(
162
- &ThreadContextHolder::ThreadSkiaOpenGLContext, _glSurface)) {
163
- RNSkLogger::logToConsole(
164
- "Could not create EGL Surface from native window / surface. Could "
165
- "not set new surface as current surface.");
166
- return nullptr;
167
- }
168
-
169
- // Set up parameters for the render target so that it
170
- // matches the underlying OpenGL context.
171
- GrGLFramebufferInfo fboInfo;
172
-
173
- // We pass 0 as the framebuffer id, since the
174
- // underlying Skia GrGlGpu will read this when wrapping the context in the
175
- // render target and the GrGlGpu object.
176
- fboInfo.fFBOID = 0;
177
- fboInfo.fFormat = 0x8058; // GL_RGBA8
178
-
179
- GLint stencil;
180
- glGetIntegerv(GL_STENCIL_BITS, &stencil);
181
-
182
- GLint samples;
183
- glGetIntegerv(GL_SAMPLES, &samples);
184
-
185
- auto colorType = kN32_SkColorType;
186
-
187
- auto maxSamples =
188
- ThreadContextHolder::ThreadSkiaOpenGLContext.directContext
189
- ->maxSurfaceSampleCountForColorType(colorType);
190
-
191
- if (samples > maxSamples) {
192
- samples = maxSamples;
193
- }
194
-
195
- auto renderTarget = GrBackendRenderTargets::MakeGL(_width, _height, samples,
196
- stencil, fboInfo);
197
-
198
- SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
199
-
200
- struct ReleaseContext {
201
- EGLSurface glSurface;
202
- };
203
-
204
- auto releaseCtx = new ReleaseContext({_glSurface});
205
-
206
- // Create surface object
207
- _skSurface = SkSurfaces::WrapBackendRenderTarget(
208
- ThreadContextHolder::ThreadSkiaOpenGLContext.directContext.get(),
209
- renderTarget, kBottomLeft_GrSurfaceOrigin, colorType, nullptr, &props,
210
- [](void *addr) {
211
- auto releaseCtx = reinterpret_cast<ReleaseContext *>(addr);
212
- SkiaOpenGLHelper::destroySurface(releaseCtx->glSurface);
213
- delete releaseCtx;
214
- },
215
- reinterpret_cast<void *>(releaseCtx));
216
- }
217
-
218
- return _skSurface;
219
- }
220
-
221
119
  sk_sp<SkSurface> AndroidSkiaContext::getSurface() {
222
120
  if (_skSurface == nullptr) {
223
121
 
224
- // Setup OpenGL and Skia
225
- if (!SkiaOpenGLHelper::createSkiaDirectContextIfNecessary(
226
- &ThreadContextHolder::ThreadSkiaOpenGLContext)) {
227
- RNSkLogger::logToConsole(
228
- "Could not create Skia Surface from native window / surface. "
229
- "Failed creating Skia Direct Context");
230
- return nullptr;
231
- }
232
-
233
122
  // Now we can create a surface
234
123
  _glSurface = SkiaOpenGLHelper::createWindowedSurface(_window);
235
124
  if (_glSurface == EGL_NO_SURFACE) {
@@ -239,8 +128,7 @@ sk_sp<SkSurface> AndroidSkiaContext::getSurface() {
239
128
  }
240
129
 
241
130
  // Now make this one current
242
- if (!SkiaOpenGLHelper::makeCurrent(
243
- &ThreadContextHolder::ThreadSkiaOpenGLContext, _glSurface)) {
131
+ if (!SkiaOpenGLHelper::makeCurrent(_context, _glSurface)) {
244
132
  RNSkLogger::logToConsole(
245
133
  "Could not create EGL Surface from native window / surface. Could "
246
134
  "not set new surface as current surface.");
@@ -266,8 +154,7 @@ sk_sp<SkSurface> AndroidSkiaContext::getSurface() {
266
154
  auto colorType = kN32_SkColorType;
267
155
 
268
156
  auto maxSamples =
269
- ThreadContextHolder::ThreadSkiaOpenGLContext.directContext
270
- ->maxSurfaceSampleCountForColorType(colorType);
157
+ _context->directContext->maxSurfaceSampleCountForColorType(colorType);
271
158
 
272
159
  if (samples > maxSamples) {
273
160
  samples = maxSamples;
@@ -286,8 +173,8 @@ sk_sp<SkSurface> AndroidSkiaContext::getSurface() {
286
173
 
287
174
  // Create surface object
288
175
  _skSurface = SkSurfaces::WrapBackendRenderTarget(
289
- ThreadContextHolder::ThreadSkiaOpenGLContext.directContext.get(),
290
- renderTarget, kBottomLeft_GrSurfaceOrigin, colorType, nullptr, &props,
176
+ _context->directContext.get(), renderTarget,
177
+ kBottomLeft_GrSurfaceOrigin, colorType, nullptr, &props,
291
178
  [](void *addr) {
292
179
  auto releaseCtx = reinterpret_cast<ReleaseContext *>(addr);
293
180
  SkiaOpenGLHelper::destroySurface(releaseCtx->glSurface);
@@ -295,7 +182,6 @@ sk_sp<SkSurface> AndroidSkiaContext::getSurface() {
295
182
  },
296
183
  reinterpret_cast<void *>(releaseCtx));
297
184
  }
298
-
299
185
  return _skSurface;
300
186
  }
301
187
 
@@ -13,8 +13,8 @@
13
13
  #include <thread>
14
14
  #include <unordered_map>
15
15
 
16
- #include "SkiaContext.h"
17
16
  #include "SkiaOpenGLHelper.h"
17
+ #include "WindowContext.h"
18
18
 
19
19
  #pragma clang diagnostic push
20
20
  #pragma clang diagnostic ignored "-Wdocumentation"
@@ -31,145 +31,45 @@
31
31
 
32
32
  namespace RNSkia {
33
33
 
34
- /**
35
- * Holder of the thread local SkiaOpenGLContext member
36
- */
37
- class ThreadContextHolder {
34
+ class AndroidSkiaContext : public WindowContext {
38
35
  public:
39
- static thread_local SkiaOpenGLContext ThreadSkiaOpenGLContext;
40
- };
41
-
42
- /**
43
- * Holder of the Windowed SkSurface with support for making current
44
- * and presenting to screen
45
- */
46
- class WindowSurfaceHolder {
47
- public:
48
- WindowSurfaceHolder(jobject jSurfaceTexture, int width, int height)
49
- : _width(width), _height(height) {
50
- JNIEnv *env = facebook::jni::Environment::current();
51
- _jSurfaceTexture = env->NewGlobalRef(jSurfaceTexture);
52
- jclass surfaceClass = env->FindClass("android/view/Surface");
53
- jmethodID surfaceConstructor = env->GetMethodID(
54
- surfaceClass, "<init>", "(Landroid/graphics/SurfaceTexture;)V");
55
- // Create a new Surface instance
56
- jobject jSurface =
57
- env->NewObject(surfaceClass, surfaceConstructor, jSurfaceTexture);
58
-
59
- jclass surfaceTextureClass = env->GetObjectClass(_jSurfaceTexture);
60
- _updateTexImageMethod =
61
- env->GetMethodID(surfaceTextureClass, "updateTexImage", "()V");
62
-
63
- // Acquire the native window from the Surface
64
- _window = ANativeWindow_fromSurface(env, jSurface);
65
- // Clean up local references
66
- env->DeleteLocalRef(jSurface);
67
- env->DeleteLocalRef(surfaceClass);
68
- env->DeleteLocalRef(surfaceTextureClass);
69
- }
70
-
71
- ~WindowSurfaceHolder() {
72
- JNIEnv *env = facebook::jni::Environment::current();
73
- env->DeleteGlobalRef(_jSurfaceTexture);
74
- ANativeWindow_release(_window);
75
- }
76
-
77
- int getWidth() { return _width; }
78
- int getHeight() { return _height; }
79
-
80
- /*
81
- * Ensures that the holder has a valid surface and returns the surface.
82
- */
83
- sk_sp<SkSurface> getSurface();
84
-
85
- void updateTexImage() {
86
- JNIEnv *env = facebook::jni::Environment::current();
87
-
88
- // Call updateTexImage on the SurfaceTexture object
89
- env->CallVoidMethod(_jSurfaceTexture, _updateTexImageMethod);
90
-
91
- // Check for exceptions
92
- if (env->ExceptionCheck()) {
93
- RNSkLogger::logToConsole("updateAndRelease() failed. The exception above "
94
- "can safely be ignored");
95
- env->ExceptionClear();
96
- }
97
- }
98
-
99
- /**
100
- * Resizes the surface
101
- * @param width
102
- * @param height
103
- */
104
- void resize(int width, int height) {
105
- _width = width;
106
- _height = height;
107
- _skSurface = nullptr;
108
- }
109
-
110
- /**
111
- * Sets the current surface as the active surface
112
- * @return true if make current succeeds
113
- */
114
- bool makeCurrent() {
115
- return SkiaOpenGLHelper::makeCurrent(
116
- &ThreadContextHolder::ThreadSkiaOpenGLContext, _glSurface);
117
- }
118
-
119
- /**
120
- * Presents the current drawing operations by swapping buffers
121
- * @return true if make current succeeds
122
- */
123
- bool present() {
124
- // Flush and submit the direct context
125
- ThreadContextHolder::ThreadSkiaOpenGLContext.directContext
126
- ->flushAndSubmit();
127
-
128
- // Swap buffers
129
- return SkiaOpenGLHelper::swapBuffers(
130
- &ThreadContextHolder::ThreadSkiaOpenGLContext, _glSurface);
131
- }
132
-
133
- private:
134
- ANativeWindow *_window;
135
- sk_sp<SkSurface> _skSurface = nullptr;
136
- jobject _jSurfaceTexture = nullptr;
137
- EGLSurface _glSurface = EGL_NO_SURFACE;
138
- jmethodID _updateTexImageMethod = nullptr;
139
- int _width = 0;
140
- int _height = 0;
141
- };
36
+ AndroidSkiaContext(SkiaOpenGLContext *context, ANativeWindow *window,
37
+ int width, int height)
38
+ : _context(context), _window(window), _width(width), _height(height) {}
142
39
 
143
- class AndroidSkiaContext : public SkiaContext {
144
- public:
145
- AndroidSkiaContext(ANativeWindow *window, int width, int height)
146
- : _window(window), _width(width), _height(height) {}
147
-
148
- ~AndroidSkiaContext() {}
40
+ ~AndroidSkiaContext() { ANativeWindow_release(_window); }
149
41
 
150
42
  sk_sp<SkSurface> getSurface() override;
151
43
 
152
44
  void present() override {
153
- if (!SkiaOpenGLHelper::makeCurrent(
154
- &ThreadContextHolder::ThreadSkiaOpenGLContext, _glSurface)) {
45
+ if (!SkiaOpenGLHelper::makeCurrent(_context, _glSurface)) {
155
46
  RNSkLogger::logToConsole(
156
47
  "Could not create EGL Surface from native window / surface. Could "
157
48
  "not set new surface as current surface.");
158
49
  return;
159
50
  }
160
51
  // Flush and submit the direct context
161
- ThreadContextHolder::ThreadSkiaOpenGLContext.directContext
162
- ->flushAndSubmit();
52
+ _context->directContext->flushAndSubmit();
163
53
 
164
54
  // Swap buffers
165
- SkiaOpenGLHelper::swapBuffers(&ThreadContextHolder::ThreadSkiaOpenGLContext,
166
- _glSurface);
55
+ SkiaOpenGLHelper::swapBuffers(_context, _glSurface);
167
56
  }
168
57
 
58
+ void resize(int width, int height) override {
59
+ _skSurface = nullptr;
60
+ _width = width;
61
+ _height = height;
62
+ }
63
+
64
+ int getWidth() override { return _width; };
65
+
66
+ int getHeight() override { return _height; };
67
+
169
68
  private:
170
69
  ANativeWindow *_window;
171
70
  sk_sp<SkSurface> _skSurface = nullptr;
172
71
  EGLSurface _glSurface = EGL_NO_SURFACE;
72
+ SkiaOpenGLContext *_context;
173
73
  int _width = 0;
174
74
  int _height = 0;
175
75
  };
@@ -182,26 +82,18 @@ public:
182
82
  * @param height Height of surface
183
83
  * @return An SkSurface backed by a texture.
184
84
  */
185
- static sk_sp<SkSurface> makeOffscreenSurface(int width, int height);
85
+ static sk_sp<SkSurface> makeOffscreenSurface(SkiaOpenGLContext *context,
86
+ int width, int height);
186
87
 
187
88
  static sk_sp<SkImage>
188
- makeImageFromHardwareBuffer(void *buffer, bool requireKnownFormat = false);
189
-
190
- static std::shared_ptr<AndroidSkiaContext>
191
- makeContext(ANativeWindow *surface, int width, int height) {
192
- return std::make_shared<AndroidSkiaContext>(surface, width, height);
193
- }
194
-
195
- /**
196
- * Creates a windowed Skia Surface holder.
197
- * @param width Initial width of surface
198
- * @param height Initial height of surface
199
- * @param window Window coming from Java
200
- * @return A Surface holder
201
- */
202
- static std::unique_ptr<WindowSurfaceHolder>
203
- makeWindowedSurface(jobject window, int width, int height) {
204
- return std::make_unique<WindowSurfaceHolder>(window, width, height);
89
+ makeImageFromHardwareBuffer(SkiaOpenGLContext *context, void *buffer,
90
+ bool requireKnownFormat = false);
91
+
92
+ static std::unique_ptr<AndroidSkiaContext>
93
+ makeContext(SkiaOpenGLContext *context, ANativeWindow *surface, int width,
94
+ int height) {
95
+ return std::make_unique<AndroidSkiaContext>(context, surface, width,
96
+ height);
205
97
  }
206
98
  };
207
99