@shopify/react-native-skia 1.5.0 → 1.5.2
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.
- package/android/cpp/jni/include/JniSkiaBaseView.h +0 -1
- package/android/cpp/jni/include/JniSkiaPictureView.h +0 -1
- package/android/cpp/rnskia-android/OpenGLContext.h +40 -0
- package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +5 -5
- package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +2 -2
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +49 -14
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +5 -2
- package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp +19 -133
- package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.h +30 -138
- package/cpp/api/JsiSkTypefaceFontProvider.h +1 -1
- package/cpp/api/JsiSkiaContext.h +6 -3
- package/cpp/jsi/JsiValue.cpp +1 -2
- package/cpp/rnskia/RNSkPlatformContext.h +2 -2
- package/cpp/rnskia/{SkiaContext.h → WindowContext.h} +5 -2
- package/ios/RNSkia-iOS/DisplayLink.mm +7 -0
- package/ios/RNSkia-iOS/MetalContext.h +46 -0
- package/ios/RNSkia-iOS/MetalContext.mm +33 -0
- package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.mm +8 -28
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +1 -1
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +8 -9
- package/ios/RNSkia-iOS/RNSkiOSView.mm +0 -2
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +28 -32
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +18 -60
- package/ios/RNSkia-iOS/SkiaUIView.h +0 -2
- package/ios/RNSkia-iOS/ViewScreenshotService.mm +1 -8
- package/lib/commonjs/web/WithSkiaWeb.js +4 -1
- package/lib/commonjs/web/WithSkiaWeb.js.map +1 -1
- package/lib/module/web/WithSkiaWeb.js +4 -1
- package/lib/module/web/WithSkiaWeb.js.map +1 -1
- package/libs/ios/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
- package/libs/ios/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
- package/libs/ios/libskottie.xcframework/Info.plist +5 -5
- package/libs/ios/libskottie.xcframework/ios-arm64_arm64e/libskottie.a +0 -0
- package/libs/ios/libskottie.xcframework/ios-arm64_arm64e_x86_64-simulator/libskottie.a +0 -0
- package/libs/ios/libskparagraph.xcframework/Info.plist +5 -5
- package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e/libskparagraph.a +0 -0
- package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e_x86_64-simulator/libskparagraph.a +0 -0
- package/libs/ios/libsksg.xcframework/ios-arm64_arm64e/libsksg.a +0 -0
- package/libs/ios/libsksg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsksg.a +0 -0
- package/libs/ios/libskshaper.xcframework/Info.plist +5 -5
- package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e/libskshaper.a +0 -0
- package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e_x86_64-simulator/libskshaper.a +0 -0
- package/libs/ios/libskunicode_core.xcframework/ios-arm64_arm64e/libskunicode_core.a +0 -0
- package/libs/ios/libskunicode_core.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_core.a +0 -0
- package/libs/ios/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e/libskunicode_libgrapheme.a +0 -0
- package/libs/ios/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_libgrapheme.a +0 -0
- package/libs/ios/libsvg.xcframework/Info.plist +5 -5
- package/libs/ios/libsvg.xcframework/ios-arm64_arm64e/libsvg.a +0 -0
- package/libs/ios/libsvg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsvg.a +0 -0
- package/package.json +3 -6
- package/src/web/WithSkiaWeb.tsx +3 -1
@@ -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
|
54
|
+
return OpenGLContext::getInstance().MakeOffscreen(width, height);
|
55
55
|
}
|
56
56
|
|
57
|
-
std::shared_ptr<
|
57
|
+
std::shared_ptr<WindowContext>
|
58
58
|
makeContextFromNativeSurface(void *surface, int width, int height) override {
|
59
|
-
return
|
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
|
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
|
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
|
-
|
25
|
+
if (_surfaceHolder) {
|
26
|
+
return static_cast<float>(_surfaceHolder->getWidth());
|
27
|
+
}
|
28
|
+
return 0;
|
24
29
|
}
|
25
30
|
|
26
31
|
float RNSkOpenGLCanvasProvider::getScaledHeight() {
|
27
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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 "
|
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<
|
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
|
-
|
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
|
-
|
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
|
-
|
73
|
-
|
74
|
-
|
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>
|
84
|
-
|
85
|
-
|
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
|
-
|
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
|
-
|
130
|
-
|
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
|
-
|
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
|
-
|
290
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
162
|
-
->flushAndSubmit();
|
52
|
+
_context->directContext->flushAndSubmit();
|
163
53
|
|
164
54
|
// Swap buffers
|
165
|
-
SkiaOpenGLHelper::swapBuffers(
|
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(
|
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,
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
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
|
|