@shopify/react-native-skia 1.5.4 → 1.5.6

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.
@@ -54,7 +54,7 @@ if(SK_GRAPHITE)
54
54
  else()
55
55
  add_definitions(-DSK_GL -DSK_GANESH)
56
56
  set(BACKEND_SOURCES
57
- "${PROJECT_SOURCE_DIR}/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp"
57
+ "${PROJECT_SOURCE_DIR}/cpp/rnskia-android/OpenGLWindowContext.cpp"
58
58
  "${PROJECT_SOURCE_DIR}/cpp/rnskia-android/GrAHardwareBufferUtils.cpp"
59
59
  )
60
60
  endif()
@@ -74,6 +74,7 @@ add_library(
74
74
  "${PROJECT_SOURCE_DIR}/cpp/jni/JniSkiaManager.cpp"
75
75
 
76
76
  "${PROJECT_SOURCE_DIR}/cpp/jni/JniPlatformContext.cpp"
77
+ "${PROJECT_SOURCE_DIR}/cpp/rnskia-android/gl/Error.cpp"
77
78
  "${PROJECT_SOURCE_DIR}/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp"
78
79
  "${PROJECT_SOURCE_DIR}/cpp/rnskia-android/AHardwareBufferUtils.cpp"
79
80
  "${PROJECT_SOURCE_DIR}/cpp/rnskia-android/RNSkAndroidVideo.cpp"
@@ -1,12 +1,25 @@
1
1
  #pragma once
2
2
 
3
- #include "SkiaOpenGLSurfaceFactory.h"
4
- #include "WindowContext.h"
3
+ #include "GrAHardwareBufferUtils.h"
4
+ #include "OpenGLWindowContext.h"
5
+ #include "gl/Display.h"
5
6
 
7
+ #include "include/core/SkCanvas.h"
8
+ #include "include/core/SkColorSpace.h"
6
9
  #include "include/core/SkSurface.h"
10
+ #include "include/gpu/ganesh/GrDirectContext.h"
11
+ #include "include/gpu/ganesh/SkImageGanesh.h"
12
+ #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
13
+ #include "include/gpu/ganesh/gl/GrGLDirectContext.h"
14
+ #include "include/gpu/ganesh/gl/GrGLInterface.h"
15
+ #include "src/gpu/ganesh/gl/GrGLDefines.h"
16
+
17
+ namespace RNSkia {
7
18
 
8
19
  class OpenGLContext {
9
20
  public:
21
+ friend class OpenGLWindowContext;
22
+
10
23
  OpenGLContext(const OpenGLContext &) = delete;
11
24
  OpenGLContext &operator=(const OpenGLContext &) = delete;
12
25
 
@@ -16,25 +29,127 @@ public:
16
29
  }
17
30
 
18
31
  sk_sp<SkSurface> MakeOffscreen(int width, int height) {
19
- return RNSkia::SkiaOpenGLSurfaceFactory::makeOffscreenSurface(
20
- &_context, width, height);
32
+ auto colorType = kRGBA_8888_SkColorType;
33
+
34
+ SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
35
+
36
+ auto result = _glContext->makeCurrent(_glSurface.get());
37
+ if (!result) {
38
+ return nullptr;
39
+ }
40
+
41
+ // Create texture
42
+ auto texture = _directContext->createBackendTexture(
43
+ width, height, colorType, skgpu::Mipmapped::kNo, GrRenderable::kYes);
44
+
45
+ if (!texture.isValid()) {
46
+ RNSkLogger::logToConsole("couldn't create offscreen texture %dx%d", width,
47
+ height);
48
+ }
49
+
50
+ struct ReleaseContext {
51
+ GrDirectContext *directContext;
52
+ GrBackendTexture texture;
53
+ };
54
+
55
+ auto releaseCtx = new ReleaseContext{.directContext = _directContext.get(),
56
+ .texture = texture};
57
+
58
+ // Create a SkSurface from the GrBackendTexture
59
+ return SkSurfaces::WrapBackendTexture(
60
+ _directContext.get(), texture, kTopLeft_GrSurfaceOrigin, 0, colorType,
61
+ nullptr, &props,
62
+ [](void *addr) {
63
+ auto releaseCtx = reinterpret_cast<ReleaseContext *>(addr);
64
+ releaseCtx->directContext->deleteBackendTexture(releaseCtx->texture);
65
+ delete releaseCtx;
66
+ },
67
+ releaseCtx);
21
68
  }
22
69
 
23
- sk_sp<SkImage> MakeImageFromBuffer(void *buffer) {
24
- return RNSkia::SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(
25
- &_context, buffer);
70
+ sk_sp<SkImage> MakeImageFromBuffer(void *buffer,
71
+ bool requireKnownFormat = false) {
72
+ #if __ANDROID_API__ >= 26
73
+ const AHardwareBuffer *hardwareBuffer =
74
+ static_cast<AHardwareBuffer *>(buffer);
75
+ DeleteImageProc deleteImageProc = nullptr;
76
+ UpdateImageProc updateImageProc = nullptr;
77
+ TexImageCtx deleteImageCtx = nullptr;
78
+
79
+ AHardwareBuffer_Desc description;
80
+ AHardwareBuffer_describe(hardwareBuffer, &description);
81
+ GrBackendFormat format;
82
+ switch (description.format) {
83
+ // TODO: find out if we can detect, which graphic buffers support
84
+ // GR_GL_TEXTURE_2D
85
+ case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
86
+ format = GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_EXTERNAL);
87
+ case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
88
+ format = GrBackendFormats::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_EXTERNAL);
89
+ case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
90
+ format = GrBackendFormats::MakeGL(GR_GL_RGB565, GR_GL_TEXTURE_EXTERNAL);
91
+ case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
92
+ format = GrBackendFormats::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_EXTERNAL);
93
+ case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
94
+ format = GrBackendFormats::MakeGL(GR_GL_RGB8, GR_GL_TEXTURE_EXTERNAL);
95
+ #if __ANDROID_API__ >= 33
96
+ case AHARDWAREBUFFER_FORMAT_R8_UNORM:
97
+ format = GrBackendFormats::MakeGL(GR_GL_R8, GR_GL_TEXTURE_EXTERNAL);
98
+ #endif
99
+ default:
100
+ if (requireKnownFormat) {
101
+ format = GrBackendFormat();
102
+ } else {
103
+ format = GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_EXTERNAL);
104
+ }
105
+ }
106
+
107
+ auto backendTex = MakeGLBackendTexture(
108
+ _directContext.get(), const_cast<AHardwareBuffer *>(hardwareBuffer),
109
+ description.width, description.height, &deleteImageProc,
110
+ &updateImageProc, &deleteImageCtx, false, format, false);
111
+ if (!backendTex.isValid()) {
112
+ RNSkLogger::logToConsole(
113
+ "Failed to convert HardwareBuffer to OpenGL Texture!");
114
+ return nullptr;
115
+ }
116
+ sk_sp<SkImage> image = SkImages::BorrowTextureFrom(
117
+ _directContext.get(), backendTex, kTopLeft_GrSurfaceOrigin,
118
+ kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr, deleteImageProc,
119
+ deleteImageCtx);
120
+ return image;
121
+ #else
122
+ throw std::runtime_error(
123
+ "HardwareBuffers are only supported on Android API 26 or higher! Set "
124
+ "your minSdk to 26 (or higher) and try again.");
125
+ #endif
26
126
  }
27
127
 
28
- std::unique_ptr<RNSkia::WindowContext> MakeWindow(ANativeWindow *window,
29
- int width, int height) {
30
- return RNSkia::SkiaOpenGLSurfaceFactory::makeContext(&_context, window,
31
- width, height);
128
+ std::unique_ptr<WindowContext> MakeWindow(ANativeWindow *window, int width,
129
+ int height) {
130
+ return std::make_unique<OpenGLWindowContext>(this, window, width, height);
32
131
  }
33
132
 
34
133
  private:
35
- RNSkia::SkiaOpenGLContext _context;
134
+ EGLConfig _glConfig;
135
+ std::unique_ptr<gl::Display> _glDisplay;
136
+ std::unique_ptr<gl::Context> _glContext;
137
+ std::unique_ptr<gl::Surface> _glSurface;
138
+ sk_sp<GrDirectContext> _directContext;
36
139
 
37
140
  OpenGLContext() {
38
- RNSkia::SkiaOpenGLHelper::createSkiaDirectContextIfNecessary(&_context);
141
+ _glDisplay = std::make_unique<gl::Display>();
142
+ _glConfig = _glDisplay->chooseConfig();
143
+ _glContext = _glDisplay->makeContext(_glConfig, nullptr);
144
+ _glSurface = _glDisplay->makePixelBufferSurface(_glConfig, 1, 1);
145
+ _glContext->makeCurrent(_glSurface.get());
146
+ auto backendInterface = GrGLMakeNativeInterface();
147
+ _directContext = GrDirectContexts::MakeGL(backendInterface);
148
+
149
+ if (_directContext == nullptr) {
150
+ throw std::runtime_error("GrDirectContexts::MakeGL failed");
151
+ }
39
152
  }
40
153
  };
154
+
155
+ } // namespace RNSkia
@@ -0,0 +1,90 @@
1
+ #include "OpenGLWindowContext.h"
2
+ #include "GrAHardwareBufferUtils.h"
3
+
4
+ #include "OpenGLContext.h"
5
+
6
+ #pragma clang diagnostic push
7
+ #pragma clang diagnostic ignored "-Wdocumentation"
8
+
9
+ #include "include/gpu/ganesh/SkImageGanesh.h"
10
+ #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
11
+ #include "src/gpu/ganesh/gl/GrGLDefines.h"
12
+
13
+ #pragma clang diagnostic pop
14
+
15
+ namespace RNSkia {
16
+
17
+ sk_sp<SkSurface> OpenGLWindowContext::getSurface() {
18
+ if (_skSurface == nullptr) {
19
+
20
+ struct ReleaseContext {
21
+ std::unique_ptr<gl::Surface> surface = nullptr;
22
+ };
23
+
24
+ if (!_window) {
25
+ throw std::runtime_error("No native window provided");
26
+ }
27
+ auto releaseCtx = new ReleaseContext();
28
+ releaseCtx->surface =
29
+ _context->_glDisplay->makeWindowSurface(_context->_glConfig, _window);
30
+ if (!releaseCtx->surface) {
31
+ throw std::runtime_error("Failed to create window surface");
32
+ }
33
+ _glSurface = releaseCtx->surface.get();
34
+
35
+ // Now make this one current
36
+ auto success = _context->_glContext->makeCurrent(releaseCtx->surface.get());
37
+ if (!success) {
38
+ throw std::runtime_error("Failed to make window surface current");
39
+ }
40
+
41
+ // Set up parameters for the render target so that it
42
+ // matches the underlying OpenGL context.
43
+ GrGLFramebufferInfo fboInfo;
44
+
45
+ // We pass 0 as the framebuffer id, since the
46
+ // underlying Skia GrGlGpu will read this when wrapping the context in the
47
+ // render target and the GrGlGpu object.
48
+ fboInfo.fFBOID = 0;
49
+ fboInfo.fFormat = 0x8058; // GL_RGBA8
50
+
51
+ GLint stencil;
52
+ glGetIntegerv(GL_STENCIL_BITS, &stencil);
53
+
54
+ GLint samples;
55
+ glGetIntegerv(GL_SAMPLES, &samples);
56
+
57
+ auto colorType = kN32_SkColorType;
58
+
59
+ auto maxSamples =
60
+ _context->_directContext->maxSurfaceSampleCountForColorType(colorType);
61
+
62
+ if (samples > maxSamples) {
63
+ samples = maxSamples;
64
+ }
65
+
66
+ auto renderTarget = GrBackendRenderTargets::MakeGL(_width, _height, samples,
67
+ stencil, fboInfo);
68
+
69
+ SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
70
+
71
+ // Create surface object
72
+ _skSurface = SkSurfaces::WrapBackendRenderTarget(
73
+ _context->_directContext.get(), renderTarget,
74
+ kBottomLeft_GrSurfaceOrigin, colorType, nullptr, &props,
75
+ [](void *addr) {
76
+ auto releaseCtx = reinterpret_cast<ReleaseContext *>(addr);
77
+ delete releaseCtx;
78
+ },
79
+ reinterpret_cast<void *>(releaseCtx));
80
+ }
81
+ return _skSurface;
82
+ }
83
+
84
+ void OpenGLWindowContext::present() {
85
+ _context->_glContext->makeCurrent(_glSurface);
86
+ _context->_directContext->flushAndSubmit();
87
+ _glSurface->present();
88
+ }
89
+
90
+ } // namespace RNSkia
@@ -0,0 +1,73 @@
1
+ #pragma once
2
+
3
+ #include "RNSkLog.h"
4
+
5
+ #include <fbjni/fbjni.h>
6
+ #include <jni.h>
7
+
8
+ #include <android/native_window_jni.h>
9
+ #include <android/surface_texture.h>
10
+ #include <android/surface_texture_jni.h>
11
+ #include <condition_variable>
12
+ #include <memory>
13
+ #include <thread>
14
+ #include <unordered_map>
15
+
16
+ #include "WindowContext.h"
17
+ #include "gl/Display.h"
18
+
19
+ #pragma clang diagnostic push
20
+ #pragma clang diagnostic ignored "-Wdocumentation"
21
+
22
+ #include "include/core/SkCanvas.h"
23
+ #include "include/core/SkColorSpace.h"
24
+ #include "include/core/SkSurface.h"
25
+ #include "include/gpu/ganesh/GrBackendSurface.h"
26
+ #include "include/gpu/ganesh/GrDirectContext.h"
27
+ #include "include/gpu/ganesh/SkSurfaceGanesh.h"
28
+ #include "include/gpu/ganesh/gl/GrGLInterface.h"
29
+
30
+ #pragma clang diagnostic pop
31
+
32
+ namespace RNSkia {
33
+
34
+ class OpenGLContext;
35
+
36
+ class OpenGLWindowContext : public WindowContext {
37
+ public:
38
+ OpenGLWindowContext(OpenGLContext *context, ANativeWindow *window, int width,
39
+ int height)
40
+ : _context(context), _window(window), _width(width), _height(height) {
41
+ ANativeWindow_acquire(_window);
42
+ }
43
+
44
+ ~OpenGLWindowContext() {
45
+ _skSurface = nullptr;
46
+ _glSurface = nullptr;
47
+ ANativeWindow_release(_window);
48
+ }
49
+
50
+ sk_sp<SkSurface> getSurface() override;
51
+
52
+ void present() override;
53
+
54
+ void resize(int width, int height) override {
55
+ _skSurface = nullptr;
56
+ _width = width;
57
+ _height = height;
58
+ }
59
+
60
+ int getWidth() override { return _width; };
61
+
62
+ int getHeight() override { return _height; };
63
+
64
+ private:
65
+ OpenGLContext *_context;
66
+ ANativeWindow *_window;
67
+ sk_sp<SkSurface> _skSurface = nullptr;
68
+ gl::Surface *_glSurface = nullptr;
69
+ int _width = 0;
70
+ int _height = 0;
71
+ };
72
+
73
+ } // namespace RNSkia
@@ -68,8 +68,8 @@ public:
68
68
  #if defined(SK_GRAPHITE)
69
69
  return DawnContext::getInstance().MakeWindow(surface, width, height);
70
70
  #else
71
- return OpenGLContext::getInstance().MakeWindow(
72
- reinterpret_cast<ANativeWindow *>(surface), width, height);
71
+ auto aWindow = reinterpret_cast<ANativeWindow *>(surface);
72
+ return OpenGLContext::getInstance().MakeWindow(aWindow, width, height);
73
73
  #endif
74
74
  }
75
75
 
@@ -71,7 +71,6 @@ bool RNSkOpenGLCanvasProvider::renderToCanvas(
71
71
  return false;
72
72
  }
73
73
  }
74
-
75
74
  return false;
76
75
  }
77
76
 
@@ -0,0 +1,77 @@
1
+ #pragma once
2
+
3
+ #include "gl/Error.h"
4
+ #include "gl/Surface.h"
5
+
6
+ namespace gl {
7
+
8
+ class Surface;
9
+ class Display;
10
+
11
+ class Context {
12
+ public:
13
+ ~Context() {
14
+ if (_context != EGL_NO_CONTEXT) {
15
+ if (eglDestroyContext(_display, _context) != EGL_TRUE) {
16
+ LOG_EGL_ERROR;
17
+ }
18
+ }
19
+ }
20
+
21
+ bool isValid() const { return _context != EGL_NO_CONTEXT; }
22
+
23
+ const EGLContext &getHandle() const { return _context; }
24
+
25
+ bool makeCurrent(const Surface *surface) {
26
+ if (_context == EGL_NO_CONTEXT) {
27
+ return false;
28
+ }
29
+ const auto result =
30
+ eglMakeCurrentIfNecessary(_display, surface->getHandle(),
31
+ surface->getHandle(), _context) == EGL_TRUE;
32
+ if (!result) {
33
+ LOG_EGL_ERROR;
34
+ }
35
+ return result;
36
+ }
37
+
38
+ bool clearCurrent() {
39
+ const auto result =
40
+ eglMakeCurrentIfNecessary(_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
41
+ EGL_NO_CONTEXT) == EGL_TRUE;
42
+ if (!result) {
43
+ LOG_EGL_ERROR;
44
+ }
45
+ return result;
46
+ }
47
+
48
+ bool isCurrent() const { return eglGetCurrentContext() == _context; }
49
+
50
+ private:
51
+ friend class Display;
52
+
53
+ EGLDisplay _display = EGL_NO_DISPLAY;
54
+ EGLContext _context = EGL_NO_CONTEXT;
55
+
56
+ static EGLBoolean eglMakeCurrentIfNecessary(EGLDisplay display,
57
+ EGLSurface draw, EGLSurface read,
58
+ EGLContext context) {
59
+ if (display != eglGetCurrentDisplay() ||
60
+ draw != eglGetCurrentSurface(EGL_DRAW) ||
61
+ read != eglGetCurrentSurface(EGL_READ) ||
62
+ context != eglGetCurrentContext()) {
63
+ return eglMakeCurrent(display, draw, read, context);
64
+ }
65
+
66
+ return EGL_TRUE;
67
+ }
68
+
69
+ Context(EGLDisplay display, EGLContext context)
70
+ : _display(display), _context(context) {}
71
+
72
+ Context(const Context &) = delete;
73
+
74
+ Context &operator=(const Context &) = delete;
75
+ };
76
+
77
+ } // namespace gl
@@ -0,0 +1,117 @@
1
+ #pragma once
2
+
3
+ #include <memory>
4
+
5
+ #include "EGL/egl.h"
6
+ #include "GLES2/gl2.h"
7
+
8
+ #include "gl/Context.h"
9
+ #include "gl/Error.h"
10
+
11
+ namespace gl {
12
+
13
+ class Context;
14
+ class Surface;
15
+
16
+ class Display {
17
+ public:
18
+ Display() {
19
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
20
+
21
+ if (eglInitialize(display, nullptr, nullptr) != EGL_TRUE) {
22
+ LOG_EGL_ERROR;
23
+ return;
24
+ }
25
+ _display = display;
26
+ }
27
+
28
+ ~Display() {
29
+ if (_display != EGL_NO_DISPLAY) {
30
+ if (eglTerminate(_display) != EGL_TRUE) {
31
+ LOG_EGL_ERROR;
32
+ }
33
+ }
34
+ }
35
+
36
+ bool isValid() const { return _display != EGL_NO_DISPLAY; }
37
+
38
+ EGLConfig chooseConfig() {
39
+
40
+ EGLint att[] = {EGL_RENDERABLE_TYPE,
41
+ EGL_OPENGL_ES2_BIT,
42
+ EGL_ALPHA_SIZE,
43
+ 8,
44
+ EGL_BLUE_SIZE,
45
+ 8,
46
+ EGL_GREEN_SIZE,
47
+ 8,
48
+ EGL_RED_SIZE,
49
+ 8,
50
+ EGL_DEPTH_SIZE,
51
+ 0,
52
+ EGL_STENCIL_SIZE,
53
+ 0,
54
+ EGL_SAMPLE_BUFFERS,
55
+ 0,
56
+ EGL_NONE};
57
+
58
+ EGLint numConfigs;
59
+ EGLConfig glConfig = 0;
60
+ if (eglChooseConfig(_display, att, &glConfig, 1, &numConfigs) != EGL_TRUE ||
61
+ numConfigs == 0) {
62
+ LOG_EGL_ERROR;
63
+ return 0;
64
+ }
65
+
66
+ return glConfig;
67
+ }
68
+
69
+ std::unique_ptr<Context> makeContext(const EGLConfig &config,
70
+ const Context *share_context) {
71
+ EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
72
+ auto context = eglCreateContext(
73
+ _display, config,
74
+ share_context != nullptr ? share_context->getHandle() : nullptr,
75
+ contextAttribs);
76
+
77
+ if (context == EGL_NO_CONTEXT) {
78
+ LOG_EGL_ERROR;
79
+ return nullptr;
80
+ }
81
+ return std::unique_ptr<Context>(new Context(_display, context));
82
+ }
83
+
84
+ std::unique_ptr<Surface> makeWindowSurface(const EGLConfig &config,
85
+ ANativeWindow *window) {
86
+ const EGLint attribs[] = {EGL_NONE};
87
+ auto surface = eglCreateWindowSurface(_display, config, window, attribs);
88
+ if (surface == EGL_NO_SURFACE) {
89
+ LOG_EGL_ERROR;
90
+ return nullptr;
91
+ }
92
+ return std::make_unique<Surface>(_display, surface);
93
+ }
94
+
95
+ std::unique_ptr<Surface> makePixelBufferSurface(const EGLConfig &config,
96
+ size_t width, size_t height) {
97
+ const EGLint attribs[] = {EGL_WIDTH, static_cast<EGLint>(width), EGL_HEIGHT,
98
+ static_cast<EGLint>(height), EGL_NONE};
99
+ auto surface = eglCreatePbufferSurface(_display, config, attribs);
100
+ if (surface == EGL_NO_SURFACE) {
101
+ LOG_EGL_ERROR;
102
+ return nullptr;
103
+ }
104
+ return std::make_unique<Surface>(_display, surface);
105
+ }
106
+
107
+ const EGLDisplay &getHandle() const { return _display; }
108
+
109
+ private:
110
+ EGLDisplay _display = EGL_NO_DISPLAY;
111
+
112
+ Display(const Display &) = delete;
113
+
114
+ Display &operator=(const Display &) = delete;
115
+ };
116
+
117
+ } // namespace gl
@@ -0,0 +1,9 @@
1
+ #include "gl/Error.h"
2
+
3
+ #include "RNSkLog.h"
4
+
5
+ void LogEGLError(const char *file, int line) {
6
+ const auto error = eglGetError();
7
+ RNSkia::RNSkLogger::logToConsole("EGL Error: %s (%d) in %s:%d",
8
+ EGLErrorToString(error), error, file, line);
9
+ }
@@ -0,0 +1,44 @@
1
+ #pragma once
2
+
3
+ #include "EGL/egl.h"
4
+ #include "GLES2/gl2.h"
5
+
6
+ #define LOG_EGL_ERROR LogEGLError(__FILE__, __LINE__);
7
+
8
+ static const char *EGLErrorToString(EGLint error) {
9
+ switch (error) {
10
+ case EGL_SUCCESS:
11
+ return "Success";
12
+ case EGL_NOT_INITIALIZED:
13
+ return "Not Initialized";
14
+ case EGL_BAD_ACCESS:
15
+ return "Bad Access";
16
+ case EGL_BAD_ALLOC:
17
+ return "Bad Alloc";
18
+ case EGL_BAD_ATTRIBUTE:
19
+ return "Bad Attribute";
20
+ case EGL_BAD_CONTEXT:
21
+ return "Bad Context";
22
+ case EGL_BAD_CONFIG:
23
+ return "Bad Config";
24
+ case EGL_BAD_CURRENT_SURFACE:
25
+ return "Bad Current Surface";
26
+ case EGL_BAD_DISPLAY:
27
+ return "Bad Display";
28
+ case EGL_BAD_SURFACE:
29
+ return "Bad Surface";
30
+ case EGL_BAD_MATCH:
31
+ return "Bad Match";
32
+ case EGL_BAD_PARAMETER:
33
+ return "Bad Parameter";
34
+ case EGL_BAD_NATIVE_PIXMAP:
35
+ return "Bad Native Pixmap";
36
+ case EGL_BAD_NATIVE_WINDOW:
37
+ return "Bad Native Window";
38
+ case EGL_CONTEXT_LOST:
39
+ return "Context Lost";
40
+ }
41
+ return "Unknown";
42
+ }
43
+
44
+ void LogEGLError(const char *file, int line);
@@ -0,0 +1,43 @@
1
+ #pragma once
2
+
3
+ #include "gl/Error.h"
4
+
5
+ namespace gl {
6
+
7
+ class Surface {
8
+ public:
9
+ Surface(EGLDisplay display, EGLSurface surface)
10
+ : _display(display), _surface(surface) {}
11
+
12
+ ~Surface() {
13
+ if (_surface != EGL_NO_SURFACE) {
14
+ if (eglDestroySurface(_display, _surface) != EGL_TRUE) {
15
+ LOG_EGL_ERROR;
16
+ }
17
+ }
18
+ }
19
+
20
+ bool isValid() { return _surface != EGL_NO_SURFACE; }
21
+
22
+ const EGLSurface &getHandle() const { return _surface; }
23
+
24
+ bool present() {
25
+ const auto result = eglSwapBuffers(_display, _surface) == EGL_TRUE;
26
+ if (!result) {
27
+ LOG_EGL_ERROR;
28
+ }
29
+ return result;
30
+ }
31
+
32
+ private:
33
+ friend class Display;
34
+
35
+ EGLDisplay _display = EGL_NO_DISPLAY;
36
+ EGLSurface _surface = EGL_NO_SURFACE;
37
+
38
+ Surface(const Surface &) = delete;
39
+
40
+ Surface &operator=(const Surface &) = delete;
41
+ };
42
+
43
+ } // Namespace gl
@@ -69,6 +69,9 @@ public:
69
69
  void *surface = reinterpret_cast<void *>(nativeBufferPointer);
70
70
  auto width = static_cast<int>(arguments[1].asNumber());
71
71
  auto height = static_cast<int>(arguments[2].asNumber());
72
+ if (surface == nullptr) {
73
+ throw std::runtime_error("Surface is null");
74
+ }
72
75
  auto result =
73
76
  context->makeContextFromNativeSurface(surface, width, height);
74
77
  // Return the newly constructed object
@@ -77,6 +77,9 @@ bool RNSkMetalCanvasProvider::renderToCanvas(
77
77
  // usage growing very fast in the simulator without this.
78
78
  @autoreleasepool {
79
79
  auto surface = _ctx->getSurface();
80
+ if (!surface) {
81
+ return false;
82
+ }
80
83
  auto canvas = surface->getCanvas();
81
84
  cb(canvas);
82
85
  _ctx->present();
@@ -109,9 +109,13 @@ public:
109
109
 
110
110
  void resize(int width, int height) override { _skSurface = nullptr; }
111
111
 
112
- int getWidth() override { return _layer.frame.size.width * _layer.contentsScale; };
112
+ int getWidth() override {
113
+ return _layer.frame.size.width * _layer.contentsScale;
114
+ };
113
115
 
114
- int getHeight() override { return _layer.frame.size.height * _layer.contentsScale; };
116
+ int getHeight() override {
117
+ return _layer.frame.size.height * _layer.contentsScale;
118
+ };
115
119
 
116
120
  private:
117
121
  SkiaMetalContext *_context;
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "setup-skia-web": "./scripts/setup-canvaskit.js"
8
8
  },
9
9
  "title": "React Native Skia",
10
- "version": "1.5.4",
10
+ "version": "1.5.6",
11
11
  "description": "High-performance React Native Graphics using Skia",
12
12
  "main": "lib/module/index.js",
13
13
  "react-native": "src/index.ts",
@@ -1,310 +0,0 @@
1
- #pragma once
2
-
3
- #include "EGL/egl.h"
4
- #include "GLES2/gl2.h"
5
- #include <fbjni/fbjni.h>
6
- #include <jni.h>
7
-
8
- #include <atomic>
9
-
10
- #include "RNSkLog.h"
11
-
12
- #pragma clang diagnostic push
13
- #pragma clang diagnostic ignored "-Wdocumentation"
14
-
15
- #include "include/core/SkCanvas.h"
16
- #include "include/core/SkColorSpace.h"
17
- #include "include/core/SkSurface.h"
18
- #include "include/gpu/ganesh/GrDirectContext.h"
19
- #include "include/gpu/ganesh/gl/GrGLDirectContext.h"
20
- #include "include/gpu/ganesh/gl/GrGLInterface.h"
21
-
22
- #pragma clang diagnostic pop
23
-
24
- namespace RNSkia {
25
-
26
- /**
27
- * Singleton holding the default display and shared eglContext that will be the
28
- * first context we create so that we can share data between contexts.
29
- */
30
- class OpenGLResourceHolder {
31
- private:
32
- OpenGLResourceHolder() {
33
- // Initialize OpenGL
34
- glDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
35
- if (glDisplay == EGL_NO_DISPLAY) {
36
- RNSkLogger::logToConsole("eglGetDisplay failed : %i", glGetError());
37
- return;
38
- }
39
-
40
- EGLint major;
41
- EGLint minor;
42
- if (eglInitialize(glDisplay, &major, &minor) != EGL_TRUE) {
43
- RNSkLogger::logToConsole("eglInitialize failed : %i", glGetError());
44
- return;
45
- }
46
-
47
- // Create a default shared context
48
- glConfig = getConfig(glDisplay);
49
-
50
- // Create OpenGL context attributes
51
- EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
52
-
53
- // Initialize the offscreen context for this thread
54
- glContext =
55
- eglCreateContext(glDisplay, glConfig, glContext, contextAttribs);
56
- if (glContext == EGL_NO_CONTEXT) {
57
- RNSkLogger::logToConsole("eglCreateContext failed : %i", glGetError());
58
- }
59
- }
60
-
61
- ~OpenGLResourceHolder() {
62
- if (glContext != EGL_NO_CONTEXT) {
63
- eglDestroyContext(glDisplay, glContext);
64
- glContext = EGL_NO_CONTEXT;
65
- }
66
-
67
- if (glDisplay != EGL_NO_DISPLAY) {
68
- eglTerminate(glDisplay);
69
- glDisplay = EGL_NO_DISPLAY;
70
- }
71
- }
72
- /* Explicitly disallow copying. */
73
- OpenGLResourceHolder(const OpenGLResourceHolder &) = delete;
74
- OpenGLResourceHolder &operator=(const OpenGLResourceHolder &) = delete;
75
-
76
- public:
77
- static OpenGLResourceHolder &getInstance() {
78
- static OpenGLResourceHolder Instance;
79
- return Instance;
80
- }
81
-
82
- /**
83
- * The first context created will be considered the parent / shared context
84
- * and will be used as the parent / shareable context when creating subsequent
85
- * contexts.
86
- */
87
- std::atomic<EGLContext> glContext = EGL_NO_CONTEXT;
88
- /**
89
- * Shared egl display
90
- */
91
- std::atomic<EGLDisplay> glDisplay = EGL_NO_DISPLAY;
92
-
93
- /**
94
- * Shared eglConfig
95
- */
96
- std::atomic<EGLConfig> glConfig = 0;
97
-
98
- private:
99
- /**
100
- * Finds the correct EGL Config for the given parameters
101
- * @param glDisplay
102
- * @return Config or zero if no matching context could be found.
103
- */
104
- static EGLConfig getConfig(EGLDisplay glDisplay) {
105
-
106
- EGLint att[] = {EGL_RENDERABLE_TYPE,
107
- EGL_OPENGL_ES2_BIT,
108
- EGL_ALPHA_SIZE,
109
- 8,
110
- EGL_BLUE_SIZE,
111
- 8,
112
- EGL_GREEN_SIZE,
113
- 8,
114
- EGL_RED_SIZE,
115
- 8,
116
- EGL_DEPTH_SIZE,
117
- 0,
118
- EGL_STENCIL_SIZE,
119
- 0,
120
- EGL_SAMPLE_BUFFERS,
121
- 0,
122
- EGL_NONE};
123
-
124
- EGLint numConfigs;
125
- EGLConfig glConfig = 0;
126
- if (eglChooseConfig(glDisplay, att, &glConfig, 1, &numConfigs) !=
127
- EGL_TRUE ||
128
- numConfigs == 0) {
129
- RNSkLogger::logToConsole(
130
- "Failed to choose a config for %s surface. Error code: %d\n",
131
- eglGetError());
132
- return 0;
133
- }
134
-
135
- return glConfig;
136
- }
137
- };
138
-
139
- struct SkiaOpenGLContext {
140
- SkiaOpenGLContext() {
141
- glContext = EGL_NO_CONTEXT;
142
- gl1x1Surface = EGL_NO_SURFACE;
143
- directContext = nullptr;
144
- }
145
- ~SkiaOpenGLContext() {
146
- if (gl1x1Surface != EGL_NO_SURFACE) {
147
- eglDestroySurface(OpenGLResourceHolder::getInstance().glDisplay,
148
- gl1x1Surface);
149
- gl1x1Surface = EGL_NO_SURFACE;
150
- }
151
-
152
- if (directContext) {
153
- directContext->releaseResourcesAndAbandonContext();
154
- directContext = nullptr;
155
- }
156
-
157
- if (glContext != EGL_NO_CONTEXT) {
158
- eglDestroyContext(OpenGLResourceHolder::getInstance().glDisplay,
159
- glContext);
160
- glContext = EGL_NO_CONTEXT;
161
- }
162
- }
163
- EGLContext glContext;
164
- EGLSurface gl1x1Surface;
165
- sk_sp<GrDirectContext> directContext;
166
- };
167
-
168
- class SkiaOpenGLHelper {
169
- public:
170
- /**
171
- * Calls eglMakeCurrent on the surface provided using the provided
172
- * thread context.
173
- * @param context Skia OpenGL context to use
174
- * @param surface Surface to set as current
175
- * @return true if eglMakeCurrent was successfull
176
- */
177
- static bool makeCurrent(SkiaOpenGLContext *context, EGLSurface glSurface) {
178
- // We don't need to call make current if we already are current:
179
- if (eglGetCurrentSurface(EGL_DRAW) != glSurface ||
180
- eglGetCurrentSurface(EGL_READ) != glSurface ||
181
- eglGetCurrentContext() != context->glContext) {
182
-
183
- // Make current!
184
- if (eglMakeCurrent(OpenGLResourceHolder::getInstance().glDisplay,
185
- glSurface, glSurface,
186
- context->glContext) != EGL_TRUE) {
187
- RNSkLogger::logToConsole("eglMakeCurrent failed: %d\n", eglGetError());
188
- return false;
189
- }
190
- }
191
- return true;
192
- }
193
-
194
- /**
195
- * Creates a new windowed surface
196
- * @param window ANativeWindow to create surface in
197
- * @return EGLSurface or EGL_NO_SURFACE if the call failed
198
- */
199
- static EGLSurface createWindowedSurface(ANativeWindow *window) {
200
- const EGLint attribs[] = {EGL_NONE};
201
- return eglCreateWindowSurface(OpenGLResourceHolder::getInstance().glDisplay,
202
- OpenGLResourceHolder::getInstance().glConfig,
203
- window, attribs);
204
- }
205
-
206
- /**
207
- * Destroys an egl surface
208
- * @param glSurface
209
- * @return
210
- */
211
- static bool destroySurface(EGLSurface glSurface) {
212
- if (eglMakeCurrent(OpenGLResourceHolder::getInstance().glDisplay,
213
- EGL_NO_SURFACE, EGL_NO_SURFACE,
214
- EGL_NO_CONTEXT) != EGL_TRUE) {
215
- RNSkLogger::logToConsole(
216
- "destroySurface: Could not clear selected surface");
217
- return false;
218
- }
219
- return eglDestroySurface(OpenGLResourceHolder::getInstance().glDisplay,
220
- glSurface) == EGL_TRUE;
221
- }
222
-
223
- /**
224
- * Calls the eglSwapBuffer in the current thread with the provided surface
225
- * @param context Thread context
226
- * @param glSurface surface to present
227
- * @return true if eglSwapBuffers succeeded.
228
- */
229
- static bool swapBuffers(SkiaOpenGLContext *context, EGLSurface glSurface) {
230
- if (eglSwapBuffers(OpenGLResourceHolder::getInstance().glDisplay,
231
- glSurface) != EGL_TRUE) {
232
- RNSkLogger::logToConsole("eglSwapBuffers failed: %d\n", eglGetError());
233
- return false;
234
- }
235
- return true;
236
- }
237
-
238
- /***
239
- * Creates a new Skia direct context backed by the provided eglContext in the
240
- * SkiaOpenGLContext.
241
- * @param context Context to store results in
242
- * @param sharedContext Shared Context
243
- * @return true if the call to create a skia direct context suceeded.
244
- */
245
- static bool createSkiaDirectContextIfNecessary(SkiaOpenGLContext *context) {
246
- if (context->directContext == nullptr) {
247
-
248
- // Create OpenGL context
249
- createOpenGLContext(context);
250
-
251
- // Create attributes for a simple 1x1 pbuffer surface that we can
252
- // use to activate and create Skia direct context for
253
- const EGLint offScreenSurfaceAttribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1,
254
- EGL_NONE};
255
-
256
- context->gl1x1Surface =
257
- eglCreatePbufferSurface(OpenGLResourceHolder::getInstance().glDisplay,
258
- OpenGLResourceHolder::getInstance().glConfig,
259
- offScreenSurfaceAttribs);
260
-
261
- if (context->gl1x1Surface == EGL_NO_SURFACE) {
262
- RNSkLogger::logToConsole("Failed creating a 1x1 pbuffer surface");
263
- return false;
264
- }
265
-
266
- // Activate
267
- if (!makeCurrent(context, context->gl1x1Surface)) {
268
- return false;
269
- }
270
-
271
- // Create the Skia context
272
- auto backendInterface = GrGLMakeNativeInterface();
273
- context->directContext = GrDirectContexts::MakeGL(backendInterface);
274
-
275
- if (context->directContext == nullptr) {
276
- RNSkLogger::logToConsole("GrDirectContexts::MakeGL failed");
277
- return false;
278
- }
279
- }
280
-
281
- // It all went well!
282
- return true;
283
- }
284
-
285
- private:
286
- /**
287
- * Creates a new GLContext.
288
- * @param context Context to save results in
289
- * @return True if the call to eglCreateContext returned a valid OpenGL
290
- * Context or if the context already is setup.
291
- */
292
- static bool createOpenGLContext(SkiaOpenGLContext *context) {
293
- // Create OpenGL context attributes
294
- EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
295
-
296
- // Initialize the offscreen context for this thread
297
- context->glContext = eglCreateContext(
298
- OpenGLResourceHolder::getInstance().glDisplay,
299
- OpenGLResourceHolder::getInstance().glConfig,
300
- OpenGLResourceHolder::getInstance().glContext, contextAttribs);
301
-
302
- if (context->glContext == EGL_NO_CONTEXT) {
303
- RNSkLogger::logToConsole("eglCreateContext failed: %d\n", eglGetError());
304
- return EGL_NO_CONTEXT;
305
- }
306
-
307
- return true;
308
- }
309
- };
310
- } // namespace RNSkia
@@ -1,188 +0,0 @@
1
- #include "SkiaOpenGLSurfaceFactory.h"
2
- #include "GrAHardwareBufferUtils.h"
3
- #include "SkiaOpenGLHelper.h"
4
-
5
- #pragma clang diagnostic push
6
- #pragma clang diagnostic ignored "-Wdocumentation"
7
-
8
- #include "include/gpu/ganesh/SkImageGanesh.h"
9
- #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
10
- #include "src/gpu/ganesh/gl/GrGLDefines.h"
11
-
12
- #pragma clang diagnostic pop
13
-
14
- namespace RNSkia {
15
-
16
- sk_sp<SkImage> SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(
17
- SkiaOpenGLContext *context, void *buffer, bool requireKnownFormat) {
18
- #if __ANDROID_API__ >= 26
19
- const AHardwareBuffer *hardwareBuffer =
20
- static_cast<AHardwareBuffer *>(buffer);
21
- DeleteImageProc deleteImageProc = nullptr;
22
- UpdateImageProc updateImageProc = nullptr;
23
- TexImageCtx deleteImageCtx = nullptr;
24
-
25
- AHardwareBuffer_Desc description;
26
- AHardwareBuffer_describe(hardwareBuffer, &description);
27
- GrBackendFormat format;
28
- switch (description.format) {
29
- // TODO: find out if we can detect, which graphic buffers support
30
- // GR_GL_TEXTURE_2D
31
- case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
32
- format = GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_EXTERNAL);
33
- case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
34
- format = GrBackendFormats::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_EXTERNAL);
35
- case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
36
- format = GrBackendFormats::MakeGL(GR_GL_RGB565, GR_GL_TEXTURE_EXTERNAL);
37
- case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
38
- format = GrBackendFormats::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_EXTERNAL);
39
- case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
40
- format = GrBackendFormats::MakeGL(GR_GL_RGB8, GR_GL_TEXTURE_EXTERNAL);
41
- #if __ANDROID_API__ >= 33
42
- case AHARDWAREBUFFER_FORMAT_R8_UNORM:
43
- format = GrBackendFormats::MakeGL(GR_GL_R8, GR_GL_TEXTURE_EXTERNAL);
44
- #endif
45
- default:
46
- if (requireKnownFormat) {
47
- format = GrBackendFormat();
48
- } else {
49
- format = GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_EXTERNAL);
50
- }
51
- }
52
-
53
- auto backendTex = MakeGLBackendTexture(
54
- context->directContext.get(),
55
- const_cast<AHardwareBuffer *>(hardwareBuffer), description.width,
56
- description.height, &deleteImageProc, &updateImageProc, &deleteImageCtx,
57
- false, format, false);
58
- if (!backendTex.isValid()) {
59
- RNSkLogger::logToConsole(
60
- "Failed to convert HardwareBuffer to OpenGL Texture!");
61
- return nullptr;
62
- }
63
- sk_sp<SkImage> image = SkImages::BorrowTextureFrom(
64
- context->directContext.get(), backendTex, kTopLeft_GrSurfaceOrigin,
65
- kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr, deleteImageProc,
66
- deleteImageCtx);
67
- return image;
68
- #else
69
- throw std::runtime_error(
70
- "HardwareBuffers are only supported on Android API 26 or higher! Set "
71
- "your minSdk to 26 (or higher) and try again.");
72
- #endif
73
- }
74
-
75
- sk_sp<SkSurface>
76
- SkiaOpenGLSurfaceFactory::makeOffscreenSurface(SkiaOpenGLContext *context,
77
- int width, int height) {
78
-
79
- auto colorType = kN32_SkColorType;
80
-
81
- SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
82
-
83
- if (!SkiaOpenGLHelper::makeCurrent(context, context->gl1x1Surface)) {
84
- RNSkLogger::logToConsole(
85
- "Could not create EGL Surface from native window / surface. Could "
86
- "not set new surface as current surface.");
87
- return nullptr;
88
- }
89
-
90
- // Create texture
91
- auto texture = context->directContext->createBackendTexture(
92
- width, height, colorType, skgpu::Mipmapped::kNo, GrRenderable::kYes);
93
-
94
- if (!texture.isValid()) {
95
- RNSkLogger::logToConsole("couldn't create offscreen texture %dx%d", width,
96
- height);
97
- }
98
-
99
- struct ReleaseContext {
100
- SkiaOpenGLContext *context;
101
- GrBackendTexture texture;
102
- };
103
-
104
- auto releaseCtx = new ReleaseContext({context, texture});
105
-
106
- // Create a SkSurface from the GrBackendTexture
107
- return SkSurfaces::WrapBackendTexture(
108
- context->directContext.get(), texture, kTopLeft_GrSurfaceOrigin, 0,
109
- colorType, nullptr, &props,
110
- [](void *addr) {
111
- auto releaseCtx = reinterpret_cast<ReleaseContext *>(addr);
112
-
113
- releaseCtx->context->directContext->deleteBackendTexture(
114
- releaseCtx->texture);
115
- },
116
- releaseCtx);
117
- }
118
-
119
- sk_sp<SkSurface> AndroidSkiaContext::getSurface() {
120
- if (_skSurface == nullptr) {
121
-
122
- // Now we can create a surface
123
- _glSurface = SkiaOpenGLHelper::createWindowedSurface(_window);
124
- if (_glSurface == EGL_NO_SURFACE) {
125
- RNSkLogger::logToConsole(
126
- "Could not create EGL Surface from native window / surface.");
127
- return nullptr;
128
- }
129
-
130
- // Now make this one current
131
- if (!SkiaOpenGLHelper::makeCurrent(_context, _glSurface)) {
132
- RNSkLogger::logToConsole(
133
- "Could not create EGL Surface from native window / surface. Could "
134
- "not set new surface as current surface.");
135
- return nullptr;
136
- }
137
-
138
- // Set up parameters for the render target so that it
139
- // matches the underlying OpenGL context.
140
- GrGLFramebufferInfo fboInfo;
141
-
142
- // We pass 0 as the framebuffer id, since the
143
- // underlying Skia GrGlGpu will read this when wrapping the context in the
144
- // render target and the GrGlGpu object.
145
- fboInfo.fFBOID = 0;
146
- fboInfo.fFormat = 0x8058; // GL_RGBA8
147
-
148
- GLint stencil;
149
- glGetIntegerv(GL_STENCIL_BITS, &stencil);
150
-
151
- GLint samples;
152
- glGetIntegerv(GL_SAMPLES, &samples);
153
-
154
- auto colorType = kN32_SkColorType;
155
-
156
- auto maxSamples =
157
- _context->directContext->maxSurfaceSampleCountForColorType(colorType);
158
-
159
- if (samples > maxSamples) {
160
- samples = maxSamples;
161
- }
162
-
163
- auto renderTarget = GrBackendRenderTargets::MakeGL(_width, _height, samples,
164
- stencil, fboInfo);
165
-
166
- SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
167
-
168
- struct ReleaseContext {
169
- EGLSurface glSurface;
170
- };
171
-
172
- auto releaseCtx = new ReleaseContext({_glSurface});
173
-
174
- // Create surface object
175
- _skSurface = SkSurfaces::WrapBackendRenderTarget(
176
- _context->directContext.get(), renderTarget,
177
- kBottomLeft_GrSurfaceOrigin, colorType, nullptr, &props,
178
- [](void *addr) {
179
- auto releaseCtx = reinterpret_cast<ReleaseContext *>(addr);
180
- SkiaOpenGLHelper::destroySurface(releaseCtx->glSurface);
181
- delete releaseCtx;
182
- },
183
- reinterpret_cast<void *>(releaseCtx));
184
- }
185
- return _skSurface;
186
- }
187
-
188
- } // namespace RNSkia
@@ -1,100 +0,0 @@
1
- #pragma once
2
-
3
- #include "RNSkLog.h"
4
-
5
- #include <fbjni/fbjni.h>
6
- #include <jni.h>
7
-
8
- #include <android/native_window_jni.h>
9
- #include <android/surface_texture.h>
10
- #include <android/surface_texture_jni.h>
11
- #include <condition_variable>
12
- #include <memory>
13
- #include <thread>
14
- #include <unordered_map>
15
-
16
- #include "SkiaOpenGLHelper.h"
17
- #include "WindowContext.h"
18
-
19
- #pragma clang diagnostic push
20
- #pragma clang diagnostic ignored "-Wdocumentation"
21
-
22
- #include "include/core/SkCanvas.h"
23
- #include "include/core/SkColorSpace.h"
24
- #include "include/core/SkSurface.h"
25
- #include "include/gpu/ganesh/GrBackendSurface.h"
26
- #include "include/gpu/ganesh/GrDirectContext.h"
27
- #include "include/gpu/ganesh/SkSurfaceGanesh.h"
28
- #include "include/gpu/ganesh/gl/GrGLInterface.h"
29
-
30
- #pragma clang diagnostic pop
31
-
32
- namespace RNSkia {
33
-
34
- class AndroidSkiaContext : public WindowContext {
35
- public:
36
- AndroidSkiaContext(SkiaOpenGLContext *context, ANativeWindow *window,
37
- int width, int height)
38
- : _context(context), _window(window), _width(width), _height(height) {}
39
-
40
- ~AndroidSkiaContext() { ANativeWindow_release(_window); }
41
-
42
- sk_sp<SkSurface> getSurface() override;
43
-
44
- void present() override {
45
- if (!SkiaOpenGLHelper::makeCurrent(_context, _glSurface)) {
46
- RNSkLogger::logToConsole(
47
- "Could not create EGL Surface from native window / surface. Could "
48
- "not set new surface as current surface.");
49
- return;
50
- }
51
- // Flush and submit the direct context
52
- _context->directContext->flushAndSubmit();
53
-
54
- // Swap buffers
55
- SkiaOpenGLHelper::swapBuffers(_context, _glSurface);
56
- }
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
-
68
- private:
69
- ANativeWindow *_window;
70
- sk_sp<SkSurface> _skSurface = nullptr;
71
- EGLSurface _glSurface = EGL_NO_SURFACE;
72
- SkiaOpenGLContext *_context;
73
- int _width = 0;
74
- int _height = 0;
75
- };
76
-
77
- class SkiaOpenGLSurfaceFactory {
78
- public:
79
- /**
80
- * Creates a new Skia surface that is backed by a texture.
81
- * @param width Width of surface
82
- * @param height Height of surface
83
- * @return An SkSurface backed by a texture.
84
- */
85
- static sk_sp<SkSurface> makeOffscreenSurface(SkiaOpenGLContext *context,
86
- int width, int height);
87
-
88
- static sk_sp<SkImage>
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);
97
- }
98
- };
99
-
100
- } // namespace RNSkia