@shopify/react-native-skia 1.5.3 → 1.5.5
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/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
|