@shopify/react-native-skia 0.1.200 → 0.1.201

Sign up to get free protection for your applications and to get access to all the features.
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 +1 -1
  23. package/android/cpp/rnskia-android/SkiaOpenGLRenderer.cpp +0 -347
  24. package/android/cpp/rnskia-android/SkiaOpenGLRenderer.h +0 -124
@@ -1,347 +0,0 @@
1
- #include "SkiaOpenGLRenderer.h"
2
-
3
- #include <RNSkLog.h>
4
- #include <android/native_window.h>
5
- #include <android/native_window_jni.h>
6
-
7
- #pragma clang diagnostic push
8
-
9
- #define STENCIL_BUFFER_SIZE 8
10
-
11
- namespace RNSkia {
12
- /** Static members */
13
- sk_sp<SkSurface> MakeOffscreenGLSurface(int width, int height) {
14
- EGLDisplay eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
15
- if (eglDisplay == EGL_NO_DISPLAY) {
16
- RNSkLogger::logToConsole("eglGetdisplay failed : %i", glGetError());
17
- return nullptr;
18
- }
19
-
20
- EGLint major;
21
- EGLint minor;
22
- if (!eglInitialize(eglDisplay, &major, &minor)) {
23
- RNSkLogger::logToConsole("eglInitialize failed : %i", glGetError());
24
- return nullptr;
25
- }
26
-
27
- EGLint att[] = {EGL_RENDERABLE_TYPE,
28
- EGL_OPENGL_ES2_BIT,
29
- EGL_SURFACE_TYPE,
30
- EGL_PBUFFER_BIT,
31
- EGL_ALPHA_SIZE,
32
- 8,
33
- EGL_BLUE_SIZE,
34
- 8,
35
- EGL_GREEN_SIZE,
36
- 8,
37
- EGL_RED_SIZE,
38
- 8,
39
- EGL_DEPTH_SIZE,
40
- 0,
41
- EGL_STENCIL_SIZE,
42
- 0,
43
- EGL_NONE};
44
-
45
- EGLint numConfigs;
46
- EGLConfig eglConfig;
47
- eglConfig = 0;
48
- if (!eglChooseConfig(eglDisplay, att, &eglConfig, 1, &numConfigs) ||
49
- numConfigs == 0) {
50
- RNSkLogger::logToConsole("Failed to choose a config %d\n", eglGetError());
51
- return nullptr;
52
- }
53
-
54
- EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
55
-
56
- EGLContext eglContext =
57
- eglCreateContext(eglDisplay, eglConfig, NULL, contextAttribs);
58
-
59
- if (eglContext == EGL_NO_CONTEXT) {
60
- RNSkLogger::logToConsole("eglCreateContext failed: %d\n", eglGetError());
61
- return nullptr;
62
- }
63
-
64
- const EGLint offScreenSurfaceAttribs[] = {EGL_WIDTH, width, EGL_HEIGHT,
65
- height, EGL_NONE};
66
- EGLSurface eglSurface =
67
- eglCreatePbufferSurface(eglDisplay, eglConfig, offScreenSurfaceAttribs);
68
- if (!eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
69
- RNSkLogger::logToConsole("eglMakeCurrent failed: %d\n", eglGetError());
70
- return nullptr;
71
- }
72
- GLint buffer;
73
- glGetIntegerv(GL_FRAMEBUFFER_BINDING, &buffer);
74
-
75
- GLint stencil;
76
- glGetIntegerv(GL_STENCIL_BITS, &stencil);
77
-
78
- GLint samples;
79
- glGetIntegerv(GL_SAMPLES, &samples);
80
-
81
- // Create the Skia backend context
82
- auto backendInterface = GrGLMakeNativeInterface();
83
- auto grContext = GrDirectContext::MakeGL(backendInterface);
84
- if (grContext == nullptr) {
85
- RNSkLogger::logToConsole("GrDirectContext::MakeGL failed");
86
- return nullptr;
87
- }
88
- auto maxSamples =
89
- grContext->maxSurfaceSampleCountForColorType(kRGBA_8888_SkColorType);
90
-
91
- if (samples > maxSamples)
92
- samples = maxSamples;
93
-
94
- GrGLFramebufferInfo fbInfo;
95
- fbInfo.fFBOID = buffer;
96
- fbInfo.fFormat = 0x8058;
97
-
98
- auto renderTarget =
99
- GrBackendRenderTarget(width, height, samples, stencil, fbInfo);
100
-
101
- struct OffscreenRenderContext {
102
- EGLDisplay display;
103
- EGLSurface surface;
104
- };
105
- auto ctx = new OffscreenRenderContext({eglDisplay, eglSurface});
106
-
107
- auto surface = SkSurfaces::WrapBackendRenderTarget(
108
- grContext.get(), renderTarget, kBottomLeft_GrSurfaceOrigin,
109
- kRGBA_8888_SkColorType, nullptr, nullptr,
110
- [](void *addr) {
111
- auto ctx = reinterpret_cast<OffscreenRenderContext *>(addr);
112
- eglDestroySurface(ctx->display, ctx->surface);
113
- delete ctx;
114
- },
115
- reinterpret_cast<void *>(ctx));
116
- return surface;
117
- }
118
-
119
- std::shared_ptr<OpenGLDrawingContext>
120
- SkiaOpenGLRenderer::getThreadDrawingContext() {
121
- auto threadId = std::this_thread::get_id();
122
- if (threadContexts.count(threadId) == 0) {
123
- auto drawingContext = std::make_shared<OpenGLDrawingContext>();
124
- drawingContext->glContext = EGL_NO_CONTEXT;
125
- drawingContext->glDisplay = EGL_NO_DISPLAY;
126
- drawingContext->glConfig = 0;
127
- drawingContext->skContext = nullptr;
128
- threadContexts.emplace(threadId, drawingContext);
129
- }
130
- return threadContexts.at(threadId);
131
- }
132
-
133
- SkiaOpenGLRenderer::SkiaOpenGLRenderer(jobject surface) {
134
- _nativeWindow =
135
- ANativeWindow_fromSurface(facebook::jni::Environment::current(), surface);
136
- }
137
-
138
- SkiaOpenGLRenderer::~SkiaOpenGLRenderer() {
139
- // Release surface
140
- ANativeWindow_release(_nativeWindow);
141
- _nativeWindow = nullptr;
142
- }
143
-
144
- bool SkiaOpenGLRenderer::run(const std::function<void(SkCanvas *)> &cb,
145
- int width, int height) {
146
- switch (_renderState) {
147
- case RenderState::Initializing: {
148
- _renderState = RenderState::Rendering;
149
- // Just let the case drop to drawing - we have initialized
150
- // and we should be able to render (if the picture is set)
151
- }
152
- case RenderState::Rendering: {
153
- // Make sure to initialize the rendering pipeline
154
- if (!ensureInitialised()) {
155
- return false;
156
- }
157
-
158
- if (cb != nullptr) {
159
- // RNSkLogger::logToConsole("SKIARENDER - Render begin");
160
-
161
- getThreadDrawingContext()->skContext->resetContext();
162
-
163
- SkColorType colorType;
164
- // setup surface for fbo0
165
- GrGLFramebufferInfo fboInfo;
166
- fboInfo.fFBOID = 0;
167
- fboInfo.fFormat = 0x8058;
168
- colorType = kN32_SkColorType;
169
-
170
- GrBackendRenderTarget backendRT(width, height, 0, STENCIL_BUFFER_SIZE,
171
- fboInfo);
172
-
173
- SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
174
-
175
- sk_sp<SkSurface> renderTarget(SkSurfaces::WrapBackendRenderTarget(
176
- getThreadDrawingContext()->skContext.get(), backendRT,
177
- kBottomLeft_GrSurfaceOrigin, colorType, nullptr, &props));
178
-
179
- auto canvas = renderTarget->getCanvas();
180
-
181
- // Draw picture into surface
182
- cb(canvas);
183
-
184
- // Flush
185
- canvas->flush();
186
-
187
- if (!eglSwapBuffers(getThreadDrawingContext()->glDisplay, _glSurface)) {
188
- RNSkLogger::logToConsole("eglSwapBuffers failed: %d\n", eglGetError());
189
- return false;
190
- }
191
-
192
- // RNSkLogger::logToConsole("SKIARENDER - render done");
193
- return true;
194
- }
195
-
196
- return false;
197
- }
198
- case RenderState::Finishing: {
199
- _renderState = RenderState::Done;
200
-
201
- // Release GL surface
202
- if (_glSurface != EGL_NO_SURFACE &&
203
- getThreadDrawingContext()->glDisplay != EGL_NO_DISPLAY) {
204
- eglDestroySurface(getThreadDrawingContext()->glDisplay, _glSurface);
205
- _glSurface = EGL_NO_SURFACE;
206
- }
207
-
208
- return true;
209
- }
210
- case RenderState::Done: {
211
- // Do nothing. We're done.
212
- return true;
213
- }
214
- }
215
- }
216
-
217
- bool SkiaOpenGLRenderer::ensureInitialised() {
218
- // Set up static OpenGL context
219
- if (!initStaticGLContext()) {
220
- return false;
221
- }
222
-
223
- // Set up OpenGL Surface
224
- if (!initGLSurface()) {
225
- return false;
226
- }
227
-
228
- // Init skia static context
229
- if (!initStaticSkiaContext()) {
230
- return false;
231
- }
232
-
233
- return true;
234
- }
235
-
236
- void SkiaOpenGLRenderer::teardown() { _renderState = RenderState::Finishing; }
237
-
238
- bool SkiaOpenGLRenderer::initStaticGLContext() {
239
- if (getThreadDrawingContext()->glContext != EGL_NO_CONTEXT) {
240
- return true;
241
- }
242
-
243
- getThreadDrawingContext()->glDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
244
- if (getThreadDrawingContext()->glDisplay == EGL_NO_DISPLAY) {
245
- RNSkLogger::logToConsole("eglGetdisplay failed : %i", glGetError());
246
- return false;
247
- }
248
-
249
- EGLint major;
250
- EGLint minor;
251
- if (!eglInitialize(getThreadDrawingContext()->glDisplay, &major, &minor)) {
252
- RNSkLogger::logToConsole("eglInitialize failed : %i", glGetError());
253
- return false;
254
- }
255
-
256
- EGLint att[] = {EGL_RENDERABLE_TYPE,
257
- EGL_OPENGL_ES2_BIT,
258
- EGL_SURFACE_TYPE,
259
- EGL_WINDOW_BIT,
260
- EGL_ALPHA_SIZE,
261
- 8,
262
- EGL_BLUE_SIZE,
263
- 8,
264
- EGL_GREEN_SIZE,
265
- 8,
266
- EGL_RED_SIZE,
267
- 8,
268
- EGL_DEPTH_SIZE,
269
- 0,
270
- EGL_STENCIL_SIZE,
271
- 0,
272
- EGL_NONE};
273
-
274
- EGLint numConfigs;
275
- getThreadDrawingContext()->glConfig = 0;
276
- if (!eglChooseConfig(getThreadDrawingContext()->glDisplay, att,
277
- &getThreadDrawingContext()->glConfig, 1, &numConfigs) ||
278
- numConfigs == 0) {
279
- RNSkLogger::logToConsole("Failed to choose a config %d\n", eglGetError());
280
- return false;
281
- }
282
-
283
- EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
284
-
285
- getThreadDrawingContext()->glContext = eglCreateContext(
286
- getThreadDrawingContext()->glDisplay, getThreadDrawingContext()->glConfig,
287
- NULL, contextAttribs);
288
-
289
- if (getThreadDrawingContext()->glContext == EGL_NO_CONTEXT) {
290
- RNSkLogger::logToConsole("eglCreateContext failed: %d\n", eglGetError());
291
- return false;
292
- }
293
-
294
- return true;
295
- }
296
-
297
- bool SkiaOpenGLRenderer::initStaticSkiaContext() {
298
- if (getThreadDrawingContext()->skContext != nullptr) {
299
- return true;
300
- }
301
-
302
- // Create the Skia backend context
303
- auto backendInterface = GrGLMakeNativeInterface();
304
- getThreadDrawingContext()->skContext =
305
- GrDirectContext::MakeGL(backendInterface);
306
- if (getThreadDrawingContext()->skContext == nullptr) {
307
- RNSkLogger::logToConsole("GrDirectContext::MakeGL failed");
308
- return false;
309
- }
310
-
311
- return true;
312
- }
313
-
314
- bool SkiaOpenGLRenderer::initGLSurface() {
315
- if (_nativeWindow == nullptr) {
316
- return false;
317
- }
318
-
319
- if (_glSurface != EGL_NO_SURFACE) {
320
- if (!eglMakeCurrent(getThreadDrawingContext()->glDisplay, _glSurface,
321
- _glSurface, getThreadDrawingContext()->glContext)) {
322
- RNSkLogger::logToConsole("eglMakeCurrent failed: %d\n", eglGetError());
323
- return false;
324
- }
325
- return true;
326
- }
327
-
328
- // Create the opengl surface
329
- _glSurface = eglCreateWindowSurface(getThreadDrawingContext()->glDisplay,
330
- getThreadDrawingContext()->glConfig,
331
- _nativeWindow, nullptr);
332
-
333
- if (_glSurface == EGL_NO_SURFACE) {
334
- RNSkLogger::logToConsole("eglCreateWindowSurface failed: %d\n",
335
- eglGetError());
336
- return false;
337
- }
338
-
339
- if (!eglMakeCurrent(getThreadDrawingContext()->glDisplay, _glSurface,
340
- _glSurface, getThreadDrawingContext()->glContext)) {
341
- RNSkLogger::logToConsole("eglMakeCurrent failed: %d\n", eglGetError());
342
- return false;
343
- }
344
-
345
- return true;
346
- }
347
- } // namespace RNSkia
@@ -1,124 +0,0 @@
1
- #pragma once
2
-
3
- #include <RNSkLog.h>
4
-
5
- #include "EGL/egl.h"
6
- #include "GLES2/gl2.h"
7
- #include "android/native_window.h"
8
- #include <fbjni/fbjni.h>
9
- #include <jni.h>
10
-
11
- #include <condition_variable>
12
- #include <memory>
13
- #include <thread>
14
- #include <unordered_map>
15
-
16
- #pragma clang diagnostic push
17
- #pragma clang diagnostic ignored "-Wdocumentation"
18
-
19
- #include "SkCanvas.h"
20
- #include "SkColorSpace.h"
21
- #include "SkPicture.h"
22
- #include "SkSurface.h"
23
-
24
- #include "include/gpu/GrBackendSurface.h"
25
- #include "include/gpu/GrDirectContext.h"
26
- #include "include/gpu/ganesh/SkSurfaceGanesh.h"
27
- #include "include/gpu/gl/GrGLInterface.h"
28
-
29
- #pragma clang diagnostic pop
30
-
31
- namespace RNSkia {
32
- sk_sp<SkSurface> MakeOffscreenGLSurface(int width, int height);
33
-
34
- using OpenGLDrawingContext = struct {
35
- EGLContext glContext;
36
- EGLDisplay glDisplay;
37
- EGLConfig glConfig;
38
- sk_sp<GrDirectContext> skContext;
39
- };
40
-
41
- static std::unordered_map<std::thread::id,
42
- std::shared_ptr<OpenGLDrawingContext>>
43
- threadContexts;
44
-
45
- enum RenderState : int {
46
- Initializing,
47
- Rendering,
48
- Finishing,
49
- Done,
50
- };
51
-
52
- class SkiaOpenGLRenderer {
53
- public:
54
- explicit SkiaOpenGLRenderer(jobject surface);
55
- ~SkiaOpenGLRenderer();
56
-
57
- /**
58
- * Initializes, renders and tears down the render pipeline depending on the
59
- * state of the renderer. All OpenGL/Skia context operations are done on a
60
- * separate thread which must be the same for all calls to the render method.
61
- *
62
- * @param callback Render callback
63
- * @param width Width of surface to render if there is a picture
64
- * @param height Height of surface to render if there is a picture
65
- */
66
- bool run(const std::function<void(SkCanvas *)> &cb, int width, int height);
67
-
68
- /**
69
- * Sets the state to finishing. Next time the renderer will be called it
70
- * will tear down and release its resources. It is important that this
71
- * is done on the same thread as the other OpenGL context stuff is handled.
72
- *
73
- * Teardown can be called fom whatever thread we want - but we must ensure
74
- * that at least one call to render on the render thread is done after calling
75
- * teardown.
76
- */
77
- void teardown();
78
-
79
- private:
80
- /**
81
- * Initializes all required OpenGL and Skia objects
82
- * @return True if initialization went well.
83
- */
84
- bool ensureInitialised();
85
-
86
- /**
87
- * Initializes the static OpenGL context that is shared between
88
- * all instances of the renderer.
89
- * @return True if initialization went well
90
- */
91
- bool initStaticGLContext();
92
-
93
- /**
94
- * Initializes the static Skia context that is shared between
95
- * all instances of the renderer
96
- * @return True if initialization went well
97
- */
98
- bool initStaticSkiaContext();
99
-
100
- /**
101
- * Inititalizes the OpenGL surface from the native view pointer we
102
- * got on initialization. Each renderer has its own OpenGL surface to
103
- * render on.
104
- * @return True if initialization went well
105
- */
106
- bool initGLSurface();
107
-
108
- /**
109
- * To be able to use static contexts (and avoid reloading the skia context for
110
- * each new view, we track the OpenGL and Skia drawing context per thread.
111
- * @return The drawing context for the current thread
112
- */
113
- static std::shared_ptr<OpenGLDrawingContext> getThreadDrawingContext();
114
-
115
- EGLSurface _glSurface = EGL_NO_SURFACE;
116
-
117
- ANativeWindow *_nativeWindow = nullptr;
118
-
119
- int _prevWidth = 0;
120
- int _prevHeight = 0;
121
-
122
- std::atomic<RenderState> _renderState = {RenderState::Initializing};
123
- };
124
- } // namespace RNSkia