@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.
- 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
|
|