@shopify/react-native-skia 1.5.3 → 1.5.5
Sign up to get free protection for your applications and to get access to all the features.
- package/android/CMakeLists.txt +53 -13
- package/android/build.gradle +3 -0
- package/android/cpp/rnskia-android/OpenGLContext.h +122 -11
- package/android/cpp/rnskia-android/OpenGLWindowContext.cpp +73 -0
- package/android/cpp/rnskia-android/OpenGLWindowContext.h +74 -0
- package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +18 -1
- package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +12 -1
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +13 -1
- package/android/cpp/rnskia-android/opengl/Context.h +77 -0
- package/android/cpp/rnskia-android/opengl/Display.h +117 -0
- package/android/cpp/rnskia-android/opengl/Error.cpp +9 -0
- package/android/cpp/rnskia-android/opengl/Error.h +44 -0
- package/android/cpp/rnskia-android/opengl/Surface.h +43 -0
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +0 -1
- package/cpp/api/JsiSkImage.h +15 -2
- package/cpp/api/JsiSkSurface.h +18 -3
- package/cpp/rnskia/DawnContext.h +241 -0
- package/cpp/rnskia/DawnUtils.h +127 -0
- package/cpp/rnskia/DawnWindowContext.cpp +19 -0
- package/cpp/rnskia/DawnWindowContext.h +77 -0
- package/cpp/rnskia/ImageProvider.h +100 -0
- package/cpp/rnskia/RNSkView.h +6 -0
- package/cpp/skia/include/android/SkAnimatedImage.h +14 -0
- package/cpp/skia/include/codec/SkAvifDecoder.h +39 -3
- package/cpp/skia/include/codec/SkCodec.h +16 -0
- package/cpp/skia/include/config/SkUserConfig.h +3 -2
- package/cpp/skia/include/core/SkCanvas.h +55 -10
- package/cpp/skia/include/core/SkContourMeasure.h +76 -0
- package/cpp/skia/include/core/SkFontScanner.h +48 -0
- package/cpp/skia/include/core/SkMilestone.h +1 -1
- package/cpp/skia/include/core/SkPath.h +11 -0
- package/cpp/skia/include/core/SkPathEffect.h +0 -23
- package/cpp/skia/include/core/SkRect.h +2 -0
- package/cpp/skia/include/core/SkString.h +4 -0
- package/cpp/skia/include/core/SkTypeface.h +5 -0
- package/cpp/skia/include/core/SkTypes.h +8 -3
- package/cpp/skia/include/docs/SkPDFDocument.h +3 -3
- package/cpp/skia/include/effects/SkOverdrawColorFilter.h +1 -0
- package/cpp/skia/include/effects/SkRuntimeEffect.h +2 -1
- package/cpp/skia/include/encode/SkJpegEncoder.h +4 -0
- package/cpp/skia/include/gpu/ganesh/GrContextOptions.h +8 -1
- package/cpp/skia/include/gpu/ganesh/GrDirectContext.h +18 -3
- package/cpp/skia/include/gpu/ganesh/GrTypes.h +11 -0
- package/cpp/skia/include/gpu/ganesh/gl/GrGLFunctions.h +5 -1
- package/cpp/skia/include/gpu/ganesh/gl/GrGLInterface.h +0 -1
- package/cpp/skia/include/gpu/graphite/GraphiteTypes.h +8 -0
- package/cpp/skia/include/gpu/graphite/Recorder.h +0 -2
- package/cpp/skia/include/gpu/graphite/precompile/PaintOptions.h +7 -4
- package/cpp/skia/include/gpu/graphite/precompile/PrecompileImageFilter.h +2 -0
- package/cpp/skia/include/gpu/graphite/precompile/PrecompileMaskFilter.h +2 -0
- package/cpp/skia/include/ports/SkFontMgr_android_ndk.h +25 -0
- package/cpp/skia/include/ports/SkFontMgr_fontconfig.h +4 -2
- package/cpp/skia/include/ports/SkFontScanner_Fontations.h +15 -0
- package/cpp/skia/include/ports/SkFontScanner_FreeType.h +15 -0
- package/cpp/skia/include/private/SkExif.h +14 -0
- package/cpp/skia/include/private/SkPathRef.h +36 -0
- package/cpp/skia/include/private/base/SkFeatures.h +4 -0
- package/cpp/skia/include/private/base/SkSpan_impl.h +1 -3
- package/cpp/skia/modules/skcms/src/skcms_internals.h +3 -0
- package/cpp/skia/src/base/SkMathPriv.h +1 -8
- package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.h +1 -2
- package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.mm +25 -19
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +23 -0
- package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.mm +4 -8
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +26 -8
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +0 -20
- package/libs/android/arm64-v8a/libskia.a +0 -0
- package/libs/android/arm64-v8a/libskottie.a +0 -0
- package/libs/android/armeabi-v7a/libskia.a +0 -0
- package/libs/android/armeabi-v7a/libskottie.a +0 -0
- package/libs/android/x86/libskia.a +0 -0
- package/libs/android/x86/libskottie.a +0 -0
- package/libs/android/x86_64/libskia.a +0 -0
- package/libs/android/x86_64/libskottie.a +0 -0
- 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/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/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/Info.plist +5 -5
- 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/Info.plist +5 -5
- 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/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 +1 -1
- package/react-native-skia.podspec +35 -9
- package/src/renderer/__tests__/e2e/SVG.spec.tsx +2 -1
- package/android/cpp/rnskia-android/SkiaOpenGLHelper.h +0 -310
- package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp +0 -188
- package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.h +0 -100
@@ -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 "opengl/Context.h"
|
9
|
+
#include "opengl/Error.h"
|
10
|
+
|
11
|
+
namespace RNSkia {
|
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() const {
|
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
|
+
EGLNativeWindowType 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::unique_ptr<Surface>(new 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::unique_ptr<Surface>(new 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 RNSkia
|
@@ -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 "opengl/Error.h"
|
4
|
+
|
5
|
+
namespace RNSkia {
|
6
|
+
|
7
|
+
class Surface {
|
8
|
+
public:
|
9
|
+
~Surface() {
|
10
|
+
if (_surface != EGL_NO_SURFACE) {
|
11
|
+
if (eglDestroySurface(_display, _surface) != EGL_TRUE) {
|
12
|
+
LOG_EGL_ERROR;
|
13
|
+
}
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
bool isValid() { return _surface != EGL_NO_SURFACE; }
|
18
|
+
|
19
|
+
const EGLSurface &getHandle() const { return _surface; }
|
20
|
+
|
21
|
+
bool Present() const {
|
22
|
+
const auto result = eglSwapBuffers(_display, _surface) == EGL_TRUE;
|
23
|
+
if (!result) {
|
24
|
+
LOG_EGL_ERROR;
|
25
|
+
}
|
26
|
+
return result;
|
27
|
+
}
|
28
|
+
|
29
|
+
private:
|
30
|
+
friend class Display;
|
31
|
+
|
32
|
+
EGLDisplay _display = EGL_NO_DISPLAY;
|
33
|
+
EGLSurface _surface = EGL_NO_SURFACE;
|
34
|
+
|
35
|
+
Surface(EGLDisplay display, EGLSurface surface)
|
36
|
+
: _display(display), _surface(surface) {}
|
37
|
+
|
38
|
+
Surface(const Surface &) = delete;
|
39
|
+
|
40
|
+
Surface &operator=(const Surface &) = delete;
|
41
|
+
};
|
42
|
+
|
43
|
+
} // Namespace RNSkia
|
package/cpp/api/JsiSkImage.h
CHANGED
@@ -12,6 +12,11 @@
|
|
12
12
|
|
13
13
|
#include "RNSkTypedArray.h"
|
14
14
|
|
15
|
+
#if defined(SK_GRAPHITE)
|
16
|
+
#include "DawnContext.h"
|
17
|
+
#include "include/gpu/graphite/Context.h"
|
18
|
+
#endif
|
19
|
+
|
15
20
|
#pragma clang diagnostic push
|
16
21
|
#pragma clang diagnostic ignored "-Wdocumentation"
|
17
22
|
|
@@ -83,9 +88,13 @@ public:
|
|
83
88
|
? arguments[1].asNumber()
|
84
89
|
: 100.0;
|
85
90
|
auto image = getObject();
|
91
|
+
#if defined(SK_GRAPHITE)
|
92
|
+
image = DawnContext::getInstance().MakeRasterImage(image);
|
93
|
+
#else
|
86
94
|
if (image->isTextureBacked()) {
|
87
95
|
image = image->makeNonTextureImage();
|
88
96
|
}
|
97
|
+
#endif
|
89
98
|
sk_sp<SkData> data;
|
90
99
|
|
91
100
|
if (format == SkEncodedImageFormat::kJPEG) {
|
@@ -181,9 +190,13 @@ public:
|
|
181
190
|
}
|
182
191
|
|
183
192
|
JSI_HOST_FUNCTION(makeNonTextureImage) {
|
184
|
-
|
193
|
+
#if defined(SK_GRAPHITE)
|
194
|
+
auto rasterImage = DawnContext::getInstance().MakeRasterImage(getObject());
|
195
|
+
#else
|
196
|
+
auto rasterImage = getObject()->makeNonTextureImage();
|
197
|
+
#endif
|
185
198
|
return jsi::Object::createFromHostObject(
|
186
|
-
runtime, std::make_shared<JsiSkImage>(getContext(),
|
199
|
+
runtime, std::make_shared<JsiSkImage>(getContext(), rasterImage));
|
187
200
|
}
|
188
201
|
|
189
202
|
EXPORT_JSI_API_TYPENAME(JsiSkImage, Image)
|
package/cpp/api/JsiSkSurface.h
CHANGED
@@ -10,6 +10,10 @@
|
|
10
10
|
#include "JsiSkCanvas.h"
|
11
11
|
#include "JsiSkImage.h"
|
12
12
|
|
13
|
+
#if defined(SK_GRAPHITE)
|
14
|
+
#include "DawnContext.h"
|
15
|
+
#endif
|
16
|
+
|
13
17
|
#pragma clang diagnostic push
|
14
18
|
#pragma clang diagnostic ignored "-Wdocumentation"
|
15
19
|
|
@@ -44,21 +48,32 @@ public:
|
|
44
48
|
}
|
45
49
|
|
46
50
|
JSI_HOST_FUNCTION(flush) {
|
47
|
-
|
51
|
+
auto surface = getObject();
|
52
|
+
#if defined(SK_GRAPHITE)
|
53
|
+
auto recording = surface->recorder()->snap();
|
54
|
+
DawnContext::getInstance().submitRecording(recording.get());
|
55
|
+
#else
|
56
|
+
if (auto dContext = GrAsDirectContext(surface->recordingContext())) {
|
48
57
|
dContext->flushAndSubmit();
|
49
58
|
}
|
59
|
+
#endif
|
50
60
|
return jsi::Value::undefined();
|
51
61
|
}
|
52
62
|
|
53
63
|
JSI_HOST_FUNCTION(makeImageSnapshot) {
|
64
|
+
auto surface = getObject();
|
54
65
|
sk_sp<SkImage> image;
|
55
66
|
if (count == 1) {
|
56
67
|
auto rect = JsiSkRect::fromValue(runtime, arguments[0]);
|
57
|
-
image =
|
68
|
+
image = surface->makeImageSnapshot(SkIRect::MakeXYWH(
|
58
69
|
rect->x(), rect->y(), rect->width(), rect->height()));
|
59
70
|
} else {
|
60
|
-
image =
|
71
|
+
image = surface->makeImageSnapshot();
|
61
72
|
}
|
73
|
+
#if defined(SK_GRAPHITE)
|
74
|
+
auto recording = surface->recorder()->snap();
|
75
|
+
DawnContext::getInstance().submitRecording(recording.get());
|
76
|
+
#endif
|
62
77
|
return jsi::Object::createFromHostObject(
|
63
78
|
runtime, std::make_shared<JsiSkImage>(getContext(), std::move(image)));
|
64
79
|
}
|
@@ -0,0 +1,241 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <memory>
|
4
|
+
#include <mutex>
|
5
|
+
|
6
|
+
#include "DawnUtils.h"
|
7
|
+
#include "DawnWindowContext.h"
|
8
|
+
#include "ImageProvider.h"
|
9
|
+
|
10
|
+
#include "include/core/SkData.h"
|
11
|
+
#include "include/gpu/graphite/BackendTexture.h"
|
12
|
+
#include "include/gpu/graphite/Context.h"
|
13
|
+
#include "include/gpu/graphite/ContextOptions.h"
|
14
|
+
#include "include/gpu/graphite/GraphiteTypes.h"
|
15
|
+
#include "include/gpu/graphite/Recorder.h"
|
16
|
+
#include "include/gpu/graphite/Recording.h"
|
17
|
+
#include "include/gpu/graphite/Surface.h"
|
18
|
+
#include "include/gpu/graphite/dawn/DawnBackendContext.h"
|
19
|
+
#include "include/gpu/graphite/dawn/DawnTypes.h"
|
20
|
+
#include "include/gpu/graphite/dawn/DawnUtils.h"
|
21
|
+
|
22
|
+
#include "src/gpu/graphite/ContextOptionsPriv.h"
|
23
|
+
|
24
|
+
#ifdef __APPLE__
|
25
|
+
#include <CoreVideo/CVPixelBuffer.h>
|
26
|
+
#else
|
27
|
+
#include <android/hardware_buffer.h>
|
28
|
+
#include <android/hardware_buffer_jni.h>
|
29
|
+
#endif
|
30
|
+
|
31
|
+
namespace RNSkia {
|
32
|
+
|
33
|
+
struct AsyncContext {
|
34
|
+
bool fCalled = false;
|
35
|
+
std::unique_ptr<const SkSurface::AsyncReadResult> fResult;
|
36
|
+
};
|
37
|
+
|
38
|
+
struct SharedTextureContext {
|
39
|
+
wgpu::SharedTextureMemory sharedTextureMemory;
|
40
|
+
wgpu::Texture texture;
|
41
|
+
};
|
42
|
+
|
43
|
+
static void
|
44
|
+
async_callback(void *c,
|
45
|
+
std::unique_ptr<const SkImage::AsyncReadResult> result) {
|
46
|
+
auto context = static_cast<AsyncContext *>(c);
|
47
|
+
context->fResult = std::move(result);
|
48
|
+
context->fCalled = true;
|
49
|
+
}
|
50
|
+
|
51
|
+
class DawnContext {
|
52
|
+
public:
|
53
|
+
// TODO: remove
|
54
|
+
friend class RNSkiOSPlatformContext;
|
55
|
+
|
56
|
+
DawnContext(const DawnContext &) = delete;
|
57
|
+
DawnContext &operator=(const DawnContext &) = delete;
|
58
|
+
|
59
|
+
static DawnContext &getInstance() {
|
60
|
+
static DawnContext instance;
|
61
|
+
return instance;
|
62
|
+
}
|
63
|
+
|
64
|
+
sk_sp<SkImage> MakeRasterImage(sk_sp<SkImage> image) {
|
65
|
+
if (!image->isTextureBacked()) {
|
66
|
+
return image;
|
67
|
+
}
|
68
|
+
std::lock_guard<std::mutex> lock(_mutex);
|
69
|
+
AsyncContext asyncContext;
|
70
|
+
fGraphiteContext->asyncRescaleAndReadPixels(
|
71
|
+
image.get(), image->imageInfo(), image->imageInfo().bounds(),
|
72
|
+
SkImage::RescaleGamma::kSrc, SkImage::RescaleMode::kNearest,
|
73
|
+
async_callback, &asyncContext);
|
74
|
+
fGraphiteContext->submit();
|
75
|
+
while (!asyncContext.fCalled) {
|
76
|
+
tick();
|
77
|
+
fGraphiteContext->checkAsyncWorkCompletion();
|
78
|
+
}
|
79
|
+
auto bytesPerRow = asyncContext.fResult->rowBytes(0);
|
80
|
+
auto bufferSize = bytesPerRow * image->imageInfo().height();
|
81
|
+
auto data = SkData::MakeWithProc(
|
82
|
+
asyncContext.fResult->data(0), bufferSize,
|
83
|
+
[](const void *ptr, void *context) {
|
84
|
+
auto *result =
|
85
|
+
reinterpret_cast<const SkSurface::AsyncReadResult *>(context);
|
86
|
+
delete result;
|
87
|
+
},
|
88
|
+
reinterpret_cast<void *>(const_cast<SkSurface::AsyncReadResult *>(
|
89
|
+
asyncContext.fResult.release())));
|
90
|
+
auto rasterImage =
|
91
|
+
SkImages::RasterFromData(image->imageInfo(), data, bytesPerRow);
|
92
|
+
return rasterImage;
|
93
|
+
}
|
94
|
+
|
95
|
+
void submitRecording(
|
96
|
+
skgpu::graphite::Recording *recording,
|
97
|
+
skgpu::graphite::SyncToCpu syncToCpu = skgpu::graphite::SyncToCpu::kNo) {
|
98
|
+
std::lock_guard<std::mutex> lock(_mutex);
|
99
|
+
skgpu::graphite::InsertRecordingInfo info;
|
100
|
+
info.fRecording = recording;
|
101
|
+
fGraphiteContext->insertRecording(info);
|
102
|
+
fGraphiteContext->submit(syncToCpu);
|
103
|
+
}
|
104
|
+
|
105
|
+
sk_sp<SkImage> MakeImageFromBuffer(void *buffer) {
|
106
|
+
#ifdef __APPLE__
|
107
|
+
wgpu::SharedTextureMemoryIOSurfaceDescriptor platformDesc;
|
108
|
+
auto ioSurface = CVPixelBufferGetIOSurface((CVPixelBufferRef)buffer);
|
109
|
+
platformDesc.ioSurface = ioSurface;
|
110
|
+
int width = static_cast<int>(IOSurfaceGetWidth(ioSurface));
|
111
|
+
int height = static_cast<int>(IOSurfaceGetHeight(ioSurface));
|
112
|
+
#else
|
113
|
+
wgpu::SharedTextureMemoryAHardwareBufferDescriptor platformDesc;
|
114
|
+
auto ahb = (AHardwareBuffer *)buffer;
|
115
|
+
platformDesc.handle = ahb;
|
116
|
+
platformDesc.useExternalFormat = true;
|
117
|
+
AHardwareBuffer_Desc adesc;
|
118
|
+
AHardwareBuffer_describe(ahb, &adesc);
|
119
|
+
int width = adesc.width;
|
120
|
+
int height = adesc.height;
|
121
|
+
#endif
|
122
|
+
|
123
|
+
wgpu::SharedTextureMemoryDescriptor desc = {};
|
124
|
+
desc.nextInChain = &platformDesc;
|
125
|
+
wgpu::SharedTextureMemory memory =
|
126
|
+
backendContext.fDevice.ImportSharedTextureMemory(&desc);
|
127
|
+
|
128
|
+
wgpu::TextureDescriptor textureDesc;
|
129
|
+
textureDesc.format = DawnUtils::PreferredTextureFormat;
|
130
|
+
textureDesc.dimension = wgpu::TextureDimension::e2D;
|
131
|
+
textureDesc.usage =
|
132
|
+
wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc;
|
133
|
+
textureDesc.size = {static_cast<uint32_t>(width),
|
134
|
+
static_cast<uint32_t>(height), 1};
|
135
|
+
|
136
|
+
wgpu::Texture texture = memory.CreateTexture(&textureDesc);
|
137
|
+
|
138
|
+
wgpu::SharedTextureMemoryBeginAccessDescriptor beginAccessDesc;
|
139
|
+
beginAccessDesc.initialized = true;
|
140
|
+
beginAccessDesc.fenceCount = 0;
|
141
|
+
bool success = memory.BeginAccess(texture, &beginAccessDesc);
|
142
|
+
|
143
|
+
if (success) {
|
144
|
+
skgpu::graphite::BackendTexture betFromView =
|
145
|
+
skgpu::graphite::BackendTextures::MakeDawn(texture.Get());
|
146
|
+
auto result = SkImages::WrapTexture(
|
147
|
+
getRecorder(), betFromView, DawnUtils::PreferedColorType,
|
148
|
+
kPremul_SkAlphaType, nullptr,
|
149
|
+
[](void *context) {
|
150
|
+
auto ctx = static_cast<SharedTextureContext *>(context);
|
151
|
+
wgpu::SharedTextureMemoryEndAccessState endState = {};
|
152
|
+
ctx->sharedTextureMemory.EndAccess(ctx->texture, &endState);
|
153
|
+
delete ctx;
|
154
|
+
},
|
155
|
+
new SharedTextureContext{memory, texture});
|
156
|
+
return result;
|
157
|
+
}
|
158
|
+
if (!success) {
|
159
|
+
return nullptr;
|
160
|
+
}
|
161
|
+
return nullptr;
|
162
|
+
}
|
163
|
+
|
164
|
+
// Create offscreen surface
|
165
|
+
sk_sp<SkSurface> MakeOffscreen(int width, int height) {
|
166
|
+
SkImageInfo info = SkImageInfo::Make(
|
167
|
+
width, height, DawnUtils::PreferedColorType, kPremul_SkAlphaType);
|
168
|
+
sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(getRecorder(), info);
|
169
|
+
|
170
|
+
if (!surface) {
|
171
|
+
throw std::runtime_error("Failed to create offscreen Skia surface.");
|
172
|
+
}
|
173
|
+
|
174
|
+
return surface;
|
175
|
+
}
|
176
|
+
|
177
|
+
// Create onscreen surface with window
|
178
|
+
std::unique_ptr<WindowContext> MakeWindow(void *window, int width,
|
179
|
+
int height) {
|
180
|
+
// 1. Create Surface
|
181
|
+
wgpu::SurfaceDescriptor surfaceDescriptor;
|
182
|
+
#ifdef __APPLE__
|
183
|
+
wgpu::SurfaceDescriptorFromMetalLayer metalSurfaceDesc;
|
184
|
+
metalSurfaceDesc.layer = window;
|
185
|
+
surfaceDescriptor.nextInChain = &metalSurfaceDesc;
|
186
|
+
#else
|
187
|
+
wgpu::SurfaceDescriptorFromAndroidNativeWindow androidSurfaceDesc;
|
188
|
+
androidSurfaceDesc.window = window;
|
189
|
+
surfaceDescriptor.nextInChain = &androidSurfaceDesc;
|
190
|
+
#endif
|
191
|
+
auto surface =
|
192
|
+
wgpu::Instance(instance->Get()).CreateSurface(&surfaceDescriptor);
|
193
|
+
return std::make_unique<DawnWindowContext>(
|
194
|
+
getRecorder(), backendContext.fDevice, surface, width, height);
|
195
|
+
}
|
196
|
+
|
197
|
+
private:
|
198
|
+
std::unique_ptr<dawn::native::Instance> instance;
|
199
|
+
std::unique_ptr<skgpu::graphite::Context> fGraphiteContext;
|
200
|
+
skgpu::graphite::DawnBackendContext backendContext;
|
201
|
+
std::mutex _mutex;
|
202
|
+
|
203
|
+
DawnContext() {
|
204
|
+
DawnProcTable backendProcs = dawn::native::GetProcs();
|
205
|
+
dawnProcSetProcs(&backendProcs);
|
206
|
+
WGPUInstanceDescriptor desc{};
|
207
|
+
desc.features.timedWaitAnyEnable = true;
|
208
|
+
instance = std::make_unique<dawn::native::Instance>(&desc);
|
209
|
+
|
210
|
+
backendContext = DawnUtils::createDawnBackendContext(instance.get());
|
211
|
+
|
212
|
+
skgpu::graphite::ContextOptions ctxOptions;
|
213
|
+
skgpu::graphite::ContextOptionsPriv contextOptionsPriv;
|
214
|
+
ctxOptions.fOptionsPriv = &contextOptionsPriv;
|
215
|
+
ctxOptions.fOptionsPriv->fStoreContextRefInRecorder = true;
|
216
|
+
fGraphiteContext =
|
217
|
+
skgpu::graphite::ContextFactory::MakeDawn(backendContext, ctxOptions);
|
218
|
+
|
219
|
+
if (!fGraphiteContext) {
|
220
|
+
throw std::runtime_error("Failed to create graphite context");
|
221
|
+
}
|
222
|
+
}
|
223
|
+
|
224
|
+
void tick() { backendContext.fTick(backendContext.fInstance); }
|
225
|
+
|
226
|
+
skgpu::graphite::Recorder *getRecorder() {
|
227
|
+
static thread_local skgpu::graphite::RecorderOptions recorderOptions;
|
228
|
+
if (!recorderOptions.fImageProvider) {
|
229
|
+
auto imageProvider = ImageProvider::Make();
|
230
|
+
recorderOptions.fImageProvider = imageProvider;
|
231
|
+
}
|
232
|
+
static thread_local auto recorder =
|
233
|
+
fGraphiteContext->makeRecorder(recorderOptions);
|
234
|
+
if (!recorder) {
|
235
|
+
throw std::runtime_error("Failed to create graphite context");
|
236
|
+
}
|
237
|
+
return recorder.get();
|
238
|
+
}
|
239
|
+
};
|
240
|
+
|
241
|
+
} // namespace RNSkia
|
@@ -0,0 +1,127 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "webgpu/webgpu_cpp.h"
|
4
|
+
|
5
|
+
#include "dawn/dawn_proc.h"
|
6
|
+
#include "dawn/native/DawnNative.h"
|
7
|
+
|
8
|
+
#include "include/core/SkColorType.h"
|
9
|
+
#include "include/gpu/graphite/dawn/DawnBackendContext.h"
|
10
|
+
|
11
|
+
namespace DawnUtils {
|
12
|
+
|
13
|
+
#ifdef __APPLE__
|
14
|
+
static const SkColorType PreferedColorType = kBGRA_8888_SkColorType;
|
15
|
+
static const wgpu::TextureFormat PreferredTextureFormat =
|
16
|
+
wgpu::TextureFormat::BGRA8Unorm;
|
17
|
+
#else
|
18
|
+
static const SkColorType PreferedColorType = kRGBA_8888_SkColorType;
|
19
|
+
static const wgpu::TextureFormat PreferredTextureFormat =
|
20
|
+
wgpu::TextureFormat::RGBA8Unorm;
|
21
|
+
#endif
|
22
|
+
|
23
|
+
inline skgpu::graphite::DawnBackendContext
|
24
|
+
createDawnBackendContext(dawn::native::Instance *instance) {
|
25
|
+
|
26
|
+
auto useTintIR = false;
|
27
|
+
static constexpr const char *kToggles[] = {
|
28
|
+
"allow_unsafe_apis",
|
29
|
+
"use_user_defined_labels_in_backend",
|
30
|
+
"disable_robustness",
|
31
|
+
"use_tint_ir",
|
32
|
+
};
|
33
|
+
wgpu::DawnTogglesDescriptor togglesDesc;
|
34
|
+
togglesDesc.enabledToggleCount = std::size(kToggles) - (useTintIR ? 0 : 1);
|
35
|
+
togglesDesc.enabledToggles = kToggles;
|
36
|
+
|
37
|
+
wgpu::RequestAdapterOptions options;
|
38
|
+
#ifdef __APPLE__
|
39
|
+
constexpr auto kDefaultBackendType = wgpu::BackendType::Metal;
|
40
|
+
#elif __ANDROID__
|
41
|
+
constexpr auto kDefaultBackendType = wgpu::BackendType::Vulkan;
|
42
|
+
#endif
|
43
|
+
options.backendType = kDefaultBackendType;
|
44
|
+
options.nextInChain = &togglesDesc;
|
45
|
+
|
46
|
+
std::vector<dawn::native::Adapter> adapters =
|
47
|
+
instance->EnumerateAdapters(&options);
|
48
|
+
if (adapters.empty()) {
|
49
|
+
throw std::runtime_error("No matching adapter found");
|
50
|
+
}
|
51
|
+
|
52
|
+
wgpu::Adapter adapter = adapters[0].Get();
|
53
|
+
|
54
|
+
std::vector<wgpu::FeatureName> features;
|
55
|
+
if (adapter.HasFeature(wgpu::FeatureName::MSAARenderToSingleSampled)) {
|
56
|
+
features.push_back(wgpu::FeatureName::MSAARenderToSingleSampled);
|
57
|
+
}
|
58
|
+
if (adapter.HasFeature(wgpu::FeatureName::TransientAttachments)) {
|
59
|
+
features.push_back(wgpu::FeatureName::TransientAttachments);
|
60
|
+
}
|
61
|
+
if (adapter.HasFeature(wgpu::FeatureName::Unorm16TextureFormats)) {
|
62
|
+
features.push_back(wgpu::FeatureName::Unorm16TextureFormats);
|
63
|
+
}
|
64
|
+
if (adapter.HasFeature(wgpu::FeatureName::DualSourceBlending)) {
|
65
|
+
features.push_back(wgpu::FeatureName::DualSourceBlending);
|
66
|
+
}
|
67
|
+
if (adapter.HasFeature(wgpu::FeatureName::FramebufferFetch)) {
|
68
|
+
features.push_back(wgpu::FeatureName::FramebufferFetch);
|
69
|
+
}
|
70
|
+
if (adapter.HasFeature(wgpu::FeatureName::BufferMapExtendedUsages)) {
|
71
|
+
features.push_back(wgpu::FeatureName::BufferMapExtendedUsages);
|
72
|
+
}
|
73
|
+
if (adapter.HasFeature(wgpu::FeatureName::TextureCompressionETC2)) {
|
74
|
+
features.push_back(wgpu::FeatureName::TextureCompressionETC2);
|
75
|
+
}
|
76
|
+
if (adapter.HasFeature(wgpu::FeatureName::TextureCompressionBC)) {
|
77
|
+
features.push_back(wgpu::FeatureName::TextureCompressionBC);
|
78
|
+
}
|
79
|
+
if (adapter.HasFeature(wgpu::FeatureName::R8UnormStorage)) {
|
80
|
+
features.push_back(wgpu::FeatureName::R8UnormStorage);
|
81
|
+
}
|
82
|
+
if (adapter.HasFeature(wgpu::FeatureName::DawnLoadResolveTexture)) {
|
83
|
+
features.push_back(wgpu::FeatureName::DawnLoadResolveTexture);
|
84
|
+
}
|
85
|
+
if (adapter.HasFeature(wgpu::FeatureName::DawnPartialLoadResolveTexture)) {
|
86
|
+
features.push_back(wgpu::FeatureName::DawnPartialLoadResolveTexture);
|
87
|
+
}
|
88
|
+
#ifdef __APPLE__
|
89
|
+
if (adapter.HasFeature(wgpu::FeatureName::SharedTextureMemoryIOSurface)) {
|
90
|
+
features.push_back(wgpu::FeatureName::SharedTextureMemoryIOSurface);
|
91
|
+
}
|
92
|
+
#else
|
93
|
+
if (adapter.HasFeature(
|
94
|
+
wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer)) {
|
95
|
+
features.push_back(wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer);
|
96
|
+
}
|
97
|
+
#endif
|
98
|
+
|
99
|
+
wgpu::DeviceDescriptor desc;
|
100
|
+
desc.requiredFeatureCount = features.size();
|
101
|
+
desc.requiredFeatures = features.data();
|
102
|
+
desc.nextInChain = &togglesDesc;
|
103
|
+
desc.SetDeviceLostCallback(
|
104
|
+
wgpu::CallbackMode::AllowSpontaneous,
|
105
|
+
[](const wgpu::Device &, wgpu::DeviceLostReason reason,
|
106
|
+
const char *message) {
|
107
|
+
if (reason != wgpu::DeviceLostReason::Destroyed) {
|
108
|
+
SK_ABORT("Device lost: %s\n", message);
|
109
|
+
}
|
110
|
+
});
|
111
|
+
desc.SetUncapturedErrorCallback(
|
112
|
+
[](const wgpu::Device &, wgpu::ErrorType, const char *message) {
|
113
|
+
SkDebugf("Device error: %s\n", message);
|
114
|
+
});
|
115
|
+
|
116
|
+
wgpu::Device device = adapter.CreateDevice(&desc);
|
117
|
+
SkASSERT(device);
|
118
|
+
|
119
|
+
skgpu::graphite::DawnBackendContext backendContext;
|
120
|
+
backendContext.fInstance = wgpu::Instance(instance->Get());
|
121
|
+
backendContext.fDevice = device;
|
122
|
+
backendContext.fQueue = device.GetQueue();
|
123
|
+
|
124
|
+
return backendContext;
|
125
|
+
}
|
126
|
+
|
127
|
+
} // namespace DawnUtils
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#include "DawnWindowContext.h"
|
2
|
+
|
3
|
+
#include "DawnContext.h"
|
4
|
+
|
5
|
+
namespace RNSkia {
|
6
|
+
|
7
|
+
void DawnWindowContext::present() {
|
8
|
+
auto recording = _recorder->snap();
|
9
|
+
if (!recording) {
|
10
|
+
throw std::runtime_error("Failed to create graphite recording");
|
11
|
+
}
|
12
|
+
DawnContext::getInstance().submitRecording(recording.get());
|
13
|
+
#ifdef __APPLE__
|
14
|
+
dawn::native::metal::WaitForCommandsToBeScheduled(_device.Get());
|
15
|
+
#endif
|
16
|
+
_surface.Present();
|
17
|
+
}
|
18
|
+
|
19
|
+
} // namespace RNSkia
|