@shopify/react-native-skia 2.5.1 → 2.5.3
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 +8 -6
- package/android/build.gradle +5 -32
- package/android/cpp/jni/JniWebGPUView.cpp +67 -0
- package/android/cpp/rnskia-android/OpenGLContext.h +9 -2
- package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +6 -3
- package/android/cpp/rnskia-android/SkiaPlatformContext.h +26 -0
- package/android/src/main/java/com/shopify/reactnative/skia/RNSkiaPackage.java +4 -1
- package/android/src/main/java/com/shopify/reactnative/skia/WebGPUSurfaceView.java +41 -0
- package/android/src/main/java/com/shopify/reactnative/skia/WebGPUTextureView.java +44 -0
- package/android/src/main/java/com/shopify/reactnative/skia/WebGPUView.java +95 -0
- package/android/src/main/java/com/shopify/reactnative/skia/WebGPUViewAPI.java +14 -0
- package/android/src/main/java/com/shopify/reactnative/skia/WebGPUViewManager.java +58 -0
- package/apple/MetalContext.h +10 -2
- package/apple/MetalWindowContext.h +1 -0
- package/apple/MetalWindowContext.mm +8 -1
- package/apple/RNSkApplePlatformContext.h +2 -1
- package/apple/RNSkApplePlatformContext.mm +6 -4
- package/apple/RNSkUIKit.h +13 -0
- package/apple/SkiaPictureView.mm +3 -0
- package/apple/SkiaPlatformContext.h +20 -0
- package/apple/SkiaPlatformContext.mm +21 -0
- package/apple/WebGPUMetalView.h +12 -0
- package/apple/WebGPUMetalView.mm +93 -0
- package/apple/WebGPUView.h +20 -0
- package/apple/WebGPUView.mm +77 -0
- package/cpp/api/JsiSkImage.h +76 -0
- package/cpp/api/JsiSkSurfaceFactory.h +12 -1
- package/cpp/jsi2/JSIConverter.h +11 -0
- package/cpp/rnskia/RNDawnContext.h +24 -16
- package/cpp/rnskia/RNDawnUtils.h +12 -0
- package/cpp/rnskia/RNSkManager.cpp +11 -4
- package/cpp/rnskia/RNSkPlatformContext.h +3 -1
- package/cpp/rnwgpu/Canvas.h +45 -0
- package/cpp/rnwgpu/PlatformContext.h +18 -0
- package/cpp/rnwgpu/SurfaceRegistry.h +229 -0
- package/cpp/rnwgpu/api/GPUAdapter.cpp +26 -0
- package/cpp/rnwgpu/api/GPUCanvasContext.cpp +64 -0
- package/cpp/rnwgpu/api/GPUCanvasContext.h +65 -0
- package/cpp/rnwgpu/api/GPUDevice.cpp +52 -0
- package/cpp/rnwgpu/api/GPUDevice.h +62 -1
- package/cpp/rnwgpu/api/GPUUncapturedErrorEvent.h +61 -0
- package/cpp/rnwgpu/api/RNWebGPU.h +62 -0
- package/cpp/rnwgpu/api/descriptors/GPUBindGroupEntry.h +4 -0
- package/cpp/rnwgpu/api/descriptors/GPUCanvasConfiguration.h +76 -0
- package/lib/commonjs/external/reanimated/useVideo.js +1 -4
- package/lib/commonjs/external/reanimated/useVideo.js.map +1 -1
- package/lib/commonjs/mock/index.js +1 -0
- package/lib/commonjs/mock/index.js.map +1 -1
- package/lib/commonjs/skia/types/Surface/SurfaceFactory.d.ts +10 -1
- package/lib/commonjs/skia/types/Surface/SurfaceFactory.js +5 -0
- package/lib/commonjs/skia/types/Surface/SurfaceFactory.js.map +1 -1
- package/lib/commonjs/sksg/Container.native.js +4 -0
- package/lib/commonjs/sksg/Container.native.js.map +1 -1
- package/lib/commonjs/sksg/Container.web.js +4 -0
- package/lib/commonjs/sksg/Container.web.js.map +1 -1
- package/lib/commonjs/specs/WebGPUViewNativeComponent.d.ts +8 -0
- package/lib/commonjs/specs/WebGPUViewNativeComponent.js +11 -0
- package/lib/commonjs/specs/WebGPUViewNativeComponent.js.map +1 -0
- package/lib/commonjs/specs/WebGPUViewNativeComponent.web.d.ts +8 -0
- package/lib/commonjs/specs/WebGPUViewNativeComponent.web.js +101 -0
- package/lib/commonjs/specs/WebGPUViewNativeComponent.web.js.map +1 -0
- package/lib/commonjs/specs/utils.d.ts +1 -0
- package/lib/commonjs/specs/utils.js +11 -0
- package/lib/commonjs/specs/utils.js.map +1 -0
- package/lib/commonjs/views/WebGPUCanvas.d.ts +32 -0
- package/lib/commonjs/views/WebGPUCanvas.js +66 -0
- package/lib/commonjs/views/WebGPUCanvas.js.map +1 -0
- package/lib/commonjs/views/WebGPUCanvas.web.d.ts +23 -0
- package/lib/commonjs/views/WebGPUCanvas.web.js +20 -0
- package/lib/commonjs/views/WebGPUCanvas.web.js.map +1 -0
- package/lib/commonjs/views/index.d.ts +1 -0
- package/lib/commonjs/views/index.js +11 -0
- package/lib/commonjs/views/index.js.map +1 -1
- package/lib/module/external/reanimated/useVideo.js +1 -4
- package/lib/module/external/reanimated/useVideo.js.map +1 -1
- package/lib/module/mock/index.js +1 -0
- package/lib/module/mock/index.js.map +1 -1
- package/lib/module/skia/types/Surface/SurfaceFactory.d.ts +10 -1
- package/lib/module/skia/types/Surface/SurfaceFactory.js +4 -1
- package/lib/module/skia/types/Surface/SurfaceFactory.js.map +1 -1
- package/lib/module/sksg/Container.native.js +5 -0
- package/lib/module/sksg/Container.native.js.map +1 -1
- package/lib/module/sksg/Container.web.js +5 -0
- package/lib/module/sksg/Container.web.js.map +1 -1
- package/lib/module/specs/WebGPUViewNativeComponent.d.ts +8 -0
- package/lib/module/specs/WebGPUViewNativeComponent.js +4 -0
- package/lib/module/specs/WebGPUViewNativeComponent.js.map +1 -0
- package/lib/module/specs/WebGPUViewNativeComponent.web.d.ts +8 -0
- package/lib/module/specs/WebGPUViewNativeComponent.web.js +94 -0
- package/lib/module/specs/WebGPUViewNativeComponent.web.js.map +1 -0
- package/lib/module/specs/utils.d.ts +1 -0
- package/lib/module/specs/utils.js +5 -0
- package/lib/module/specs/utils.js.map +1 -0
- package/lib/module/views/WebGPUCanvas.d.ts +32 -0
- package/lib/module/views/WebGPUCanvas.js +57 -0
- package/lib/module/views/WebGPUCanvas.js.map +1 -0
- package/lib/module/views/WebGPUCanvas.web.d.ts +23 -0
- package/lib/module/views/WebGPUCanvas.web.js +12 -0
- package/lib/module/views/WebGPUCanvas.web.js.map +1 -0
- package/lib/module/views/index.d.ts +1 -0
- package/lib/module/views/index.js +1 -0
- package/lib/module/views/index.js.map +1 -1
- package/lib/typescript/lib/commonjs/mock/index.d.ts +1 -0
- package/lib/typescript/lib/commonjs/skia/types/Surface/SurfaceFactory.d.ts +4 -0
- package/lib/typescript/lib/commonjs/specs/WebGPUViewNativeComponent.d.ts +3 -0
- package/lib/typescript/lib/commonjs/specs/WebGPUViewNativeComponent.web.d.ts +3 -0
- package/lib/typescript/lib/commonjs/specs/utils.d.ts +2 -0
- package/lib/typescript/lib/commonjs/views/WebGPUCanvas.d.ts +6 -0
- package/lib/typescript/lib/commonjs/views/WebGPUCanvas.web.d.ts +6 -0
- package/lib/typescript/lib/module/mock/index.d.ts +7 -1
- package/lib/typescript/lib/module/skia/types/Surface/SurfaceFactory.d.ts +4 -1
- package/lib/typescript/lib/module/specs/WebGPUViewNativeComponent.d.ts +2 -0
- package/lib/typescript/lib/module/specs/WebGPUViewNativeComponent.web.d.ts +2 -0
- package/lib/typescript/lib/module/specs/utils.d.ts +1 -0
- package/lib/typescript/lib/module/views/WebGPUCanvas.d.ts +7 -0
- package/lib/typescript/lib/module/views/WebGPUCanvas.web.d.ts +8 -0
- package/lib/typescript/lib/module/views/index.d.ts +1 -0
- package/lib/typescript/src/skia/types/Surface/SurfaceFactory.d.ts +10 -1
- package/lib/typescript/src/specs/WebGPUViewNativeComponent.d.ts +8 -0
- package/lib/typescript/src/specs/WebGPUViewNativeComponent.web.d.ts +8 -0
- package/lib/typescript/src/specs/utils.d.ts +1 -0
- package/lib/typescript/src/views/WebGPUCanvas.d.ts +32 -0
- package/lib/typescript/src/views/WebGPUCanvas.web.d.ts +23 -0
- package/lib/typescript/src/views/index.d.ts +1 -0
- package/package.json +7 -3
- package/react-native-skia.podspec +16 -83
- package/scripts/install-libs.js +131 -0
- package/src/external/reanimated/useVideo.ts +1 -4
- package/src/mock/index.ts +1 -0
- package/src/skia/types/Surface/SurfaceFactory.ts +17 -1
- package/src/sksg/Container.native.ts +3 -0
- package/src/sksg/Container.web.ts +3 -0
- package/src/specs/WebGPUViewNativeComponent.ts +11 -0
- package/src/specs/WebGPUViewNativeComponent.web.ts +108 -0
- package/src/specs/utils.ts +4 -0
- package/src/views/WebGPUCanvas.tsx +109 -0
- package/src/views/WebGPUCanvas.web.tsx +36 -0
- package/src/views/index.ts +1 -0
package/android/CMakeLists.txt
CHANGED
|
@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.4.1)
|
|
|
4
4
|
set (CMAKE_VERBOSE_MAKEFILE ON)
|
|
5
5
|
set (CMAKE_CXX_STANDARD 20)
|
|
6
6
|
|
|
7
|
-
# SKIA_LIBS_PATH is passed from Gradle (
|
|
7
|
+
# SKIA_LIBS_PATH is passed from Gradle (pointing to libs/android/, populated by npm postinstall)
|
|
8
8
|
# Append the ABI to get the full path
|
|
9
9
|
set (SKIA_LIBS_PATH "${SKIA_LIBS_PATH}/${ANDROID_ABI}")
|
|
10
10
|
|
|
@@ -17,14 +17,12 @@ if(NOT EXISTS "${SKIA_LIBS_PATH}/libskia.a")
|
|
|
17
17
|
message("│ │")
|
|
18
18
|
message("│ Could not find libskia.a at: ${SKIA_LIBS_PATH} │")
|
|
19
19
|
message("│ │")
|
|
20
|
-
message("│
|
|
21
|
-
message("│
|
|
22
|
-
message("│ │")
|
|
23
|
-
message("│ See: https://shopify.github.io/react-native-skia/docs/getting-started/installation │")
|
|
20
|
+
message("│ Run the following command to install them: │")
|
|
21
|
+
message("│ npx install-skia │")
|
|
24
22
|
message("│ │")
|
|
25
23
|
message("└─────────────────────────────────────────────────────────────────────────────┘")
|
|
26
24
|
message("")
|
|
27
|
-
message(FATAL_ERROR "Skia prebuilt binaries not found
|
|
25
|
+
message(FATAL_ERROR "Skia prebuilt binaries not found. Run `npx install-skia` to fix this.")
|
|
28
26
|
endif()
|
|
29
27
|
|
|
30
28
|
# Import libskia
|
|
@@ -130,6 +128,7 @@ if(SK_GRAPHITE)
|
|
|
130
128
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUAdapter.cpp"
|
|
131
129
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUBindGroup.cpp"
|
|
132
130
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUBuffer.cpp"
|
|
131
|
+
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUCanvasContext.cpp"
|
|
133
132
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUCommandEncoder.cpp"
|
|
134
133
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUComputePassEncoder.cpp"
|
|
135
134
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUComputePipeline.cpp"
|
|
@@ -143,6 +142,9 @@ if(SK_GRAPHITE)
|
|
|
143
142
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUShaderModule.cpp"
|
|
144
143
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUSupportedLimits.cpp"
|
|
145
144
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUTexture.cpp"
|
|
145
|
+
|
|
146
|
+
# WebGPU Canvas JNI bindings
|
|
147
|
+
"${PROJECT_SOURCE_DIR}/cpp/jni/JniWebGPUView.cpp"
|
|
146
148
|
)
|
|
147
149
|
endif()
|
|
148
150
|
|
package/android/build.gradle
CHANGED
|
@@ -56,41 +56,15 @@ static def findNodeModules(baseDir) {
|
|
|
56
56
|
throw new GradleException("React-Native-Skia: Failed to find node_modules/ path!")
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
// Resolve npm package path using Node.js resolution (handles monorepos, pnpm, etc.)
|
|
60
|
-
def resolveSkiaPackage(packageName) {
|
|
61
|
-
def cmdResult = providers.exec {
|
|
62
|
-
commandLine "node", "-e", "console.log(require.resolve('${packageName}/package.json'))"
|
|
63
|
-
ignoreExitValue = true
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (cmdResult.result.get().exitValue == 0) {
|
|
67
|
-
def packageJsonPath = cmdResult.standardOutput.asText.get().trim()
|
|
68
|
-
return new File(packageJsonPath).parent
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Fallback: walk up directories looking for node_modules
|
|
72
|
-
def basePath = projectDir.toPath().normalize()
|
|
73
|
-
while (basePath) {
|
|
74
|
-
def candidate = Paths.get(basePath.toString(), "node_modules", packageName)
|
|
75
|
-
if (candidate.toFile().exists() && new File(candidate.toString(), "package.json").exists()) {
|
|
76
|
-
return candidate.toString()
|
|
77
|
-
}
|
|
78
|
-
basePath = basePath.getParent()
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
throw new GradleException("React-Native-Skia: Could not find ${packageName}. Make sure you have run 'yarn install' or 'npm install'.")
|
|
82
|
-
}
|
|
83
|
-
|
|
84
59
|
def nodeModules = findNodeModules(projectDir)
|
|
85
60
|
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
def
|
|
89
|
-
def
|
|
90
|
-
def skiaLibsPath = "${skiaAndroidPackage}/libs"
|
|
61
|
+
// Skia prebuilt libs are copied into libs/android/ by the npm postinstall script
|
|
62
|
+
// Graphite is detected via marker file created by install-skia-graphite
|
|
63
|
+
def useGraphite = file("${projectDir}/../libs/.graphite").exists()
|
|
64
|
+
def skiaLibsPath = "${projectDir}/../libs/android"
|
|
91
65
|
|
|
92
66
|
logger.warn("react-native-skia: SK_GRAPHITE: ${useGraphite}")
|
|
93
|
-
logger.warn("react-native-skia: Skia
|
|
67
|
+
logger.warn("react-native-skia: Skia libs: ${skiaLibsPath}")
|
|
94
68
|
logger.warn("react-native-skia: node_modules/ found at: ${nodeModules}")
|
|
95
69
|
|
|
96
70
|
def sourceBuild = false
|
|
@@ -292,7 +266,6 @@ repositories {
|
|
|
292
266
|
}
|
|
293
267
|
}
|
|
294
268
|
google()
|
|
295
|
-
maven { url 'https://www.jitpack.io' }
|
|
296
269
|
}
|
|
297
270
|
|
|
298
271
|
dependencies {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#include <jni.h>
|
|
2
|
+
#include <android/native_window_jni.h>
|
|
3
|
+
|
|
4
|
+
#ifdef SK_GRAPHITE
|
|
5
|
+
#include "webgpu/webgpu_cpp.h"
|
|
6
|
+
#include "rnwgpu/SurfaceRegistry.h"
|
|
7
|
+
#include "rnskia/RNDawnContext.h"
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
extern "C" JNIEXPORT void JNICALL
|
|
11
|
+
Java_com_shopify_reactnative_skia_WebGPUView_onSurfaceCreate(
|
|
12
|
+
JNIEnv *env, jobject thiz, jobject jSurface, jint contextId, jfloat width,
|
|
13
|
+
jfloat height) {
|
|
14
|
+
#ifdef SK_GRAPHITE
|
|
15
|
+
auto window = ANativeWindow_fromSurface(env, jSurface);
|
|
16
|
+
auto ®istry = rnwgpu::SurfaceRegistry::getInstance();
|
|
17
|
+
auto &dawnContext = RNSkia::DawnContext::getInstance();
|
|
18
|
+
auto gpu = dawnContext.getWGPUInstance();
|
|
19
|
+
|
|
20
|
+
// Create surface from ANativeWindow
|
|
21
|
+
wgpu::SurfaceDescriptorFromAndroidNativeWindow androidSurfaceDesc;
|
|
22
|
+
androidSurfaceDesc.window = window;
|
|
23
|
+
wgpu::SurfaceDescriptor surfaceDescriptor;
|
|
24
|
+
surfaceDescriptor.nextInChain = &androidSurfaceDesc;
|
|
25
|
+
auto surface = gpu.CreateSurface(&surfaceDescriptor);
|
|
26
|
+
|
|
27
|
+
registry
|
|
28
|
+
.getSurfaceInfoOrCreate(contextId, gpu, static_cast<int>(width),
|
|
29
|
+
static_cast<int>(height))
|
|
30
|
+
->switchToOnscreen(window, surface);
|
|
31
|
+
#endif
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
extern "C" JNIEXPORT void JNICALL
|
|
35
|
+
Java_com_shopify_reactnative_skia_WebGPUView_onSurfaceChanged(
|
|
36
|
+
JNIEnv *env, jobject thiz, jobject surface, jint contextId, jfloat width,
|
|
37
|
+
jfloat height) {
|
|
38
|
+
#ifdef SK_GRAPHITE
|
|
39
|
+
auto ®istry = rnwgpu::SurfaceRegistry::getInstance();
|
|
40
|
+
auto surfaceInfo = registry.getSurfaceInfo(contextId);
|
|
41
|
+
if (surfaceInfo) {
|
|
42
|
+
surfaceInfo->resize(static_cast<int>(width), static_cast<int>(height));
|
|
43
|
+
}
|
|
44
|
+
#endif
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
extern "C" JNIEXPORT void JNICALL
|
|
48
|
+
Java_com_shopify_reactnative_skia_WebGPUView_switchToOffscreenSurface(
|
|
49
|
+
JNIEnv *env, jobject thiz, jint contextId) {
|
|
50
|
+
#ifdef SK_GRAPHITE
|
|
51
|
+
auto ®istry = rnwgpu::SurfaceRegistry::getInstance();
|
|
52
|
+
auto surfaceInfo = registry.getSurfaceInfo(contextId);
|
|
53
|
+
if (surfaceInfo) {
|
|
54
|
+
surfaceInfo->switchToOffscreen();
|
|
55
|
+
}
|
|
56
|
+
#endif
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
extern "C" JNIEXPORT void JNICALL
|
|
60
|
+
Java_com_shopify_reactnative_skia_WebGPUView_onSurfaceDestroy(JNIEnv *env,
|
|
61
|
+
jobject thiz,
|
|
62
|
+
jint contextId) {
|
|
63
|
+
#ifdef SK_GRAPHITE
|
|
64
|
+
auto ®istry = rnwgpu::SurfaceRegistry::getInstance();
|
|
65
|
+
registry.removeSurfaceInfo(contextId);
|
|
66
|
+
#endif
|
|
67
|
+
}
|
|
@@ -58,7 +58,8 @@ public:
|
|
|
58
58
|
return instance;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
sk_sp<SkSurface> MakeOffscreen(int width, int height
|
|
61
|
+
sk_sp<SkSurface> MakeOffscreen(int width, int height,
|
|
62
|
+
bool useP3ColorSpace = false) {
|
|
62
63
|
auto colorType = kRGBA_8888_SkColorType;
|
|
63
64
|
|
|
64
65
|
SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
|
|
@@ -89,10 +90,16 @@ public:
|
|
|
89
90
|
auto releaseCtx = new ReleaseContext{.directContext = _directContext.get(),
|
|
90
91
|
.texture = texture};
|
|
91
92
|
|
|
93
|
+
sk_sp<SkColorSpace> colorSpace =
|
|
94
|
+
useP3ColorSpace
|
|
95
|
+
? SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,
|
|
96
|
+
SkNamedGamut::kDisplayP3)
|
|
97
|
+
: nullptr;
|
|
98
|
+
|
|
92
99
|
// Create a SkSurface from the GrBackendTexture
|
|
93
100
|
return SkSurfaces::WrapBackendTexture(
|
|
94
101
|
_directContext.get(), texture, kTopLeft_GrSurfaceOrigin, 0, colorType,
|
|
95
|
-
|
|
102
|
+
colorSpace, &props,
|
|
96
103
|
[](void *addr) {
|
|
97
104
|
auto releaseCtx = reinterpret_cast<ReleaseContext *>(addr);
|
|
98
105
|
releaseCtx->directContext->deleteBackendTexture(releaseCtx->texture);
|
|
@@ -50,11 +50,14 @@ public:
|
|
|
50
50
|
_jniPlatformContext->raiseError(err);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
sk_sp<SkSurface> makeOffscreenSurface(int width, int height
|
|
53
|
+
sk_sp<SkSurface> makeOffscreenSurface(int width, int height,
|
|
54
|
+
bool useP3ColorSpace = false) override {
|
|
54
55
|
#if defined(SK_GRAPHITE)
|
|
55
|
-
return DawnContext::getInstance().MakeOffscreen(width, height
|
|
56
|
+
return DawnContext::getInstance().MakeOffscreen(width, height,
|
|
57
|
+
useP3ColorSpace);
|
|
56
58
|
#else
|
|
57
|
-
return OpenGLContext::getInstance().MakeOffscreen(width, height
|
|
59
|
+
return OpenGLContext::getInstance().MakeOffscreen(width, height,
|
|
60
|
+
useP3ColorSpace);
|
|
58
61
|
#endif
|
|
59
62
|
}
|
|
60
63
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#ifdef SK_GRAPHITE
|
|
4
|
+
|
|
5
|
+
#include "rnwgpu/PlatformContext.h"
|
|
6
|
+
|
|
7
|
+
namespace rnwgpu {
|
|
8
|
+
|
|
9
|
+
class SkiaPlatformContext : public PlatformContext {
|
|
10
|
+
public:
|
|
11
|
+
SkiaPlatformContext() = default;
|
|
12
|
+
~SkiaPlatformContext() = default;
|
|
13
|
+
|
|
14
|
+
wgpu::Surface makeSurface(wgpu::Instance instance, void *surface, int width,
|
|
15
|
+
int height) override {
|
|
16
|
+
wgpu::SurfaceDescriptorFromAndroidNativeWindow androidSurfaceDesc;
|
|
17
|
+
androidSurfaceDesc.window = surface;
|
|
18
|
+
wgpu::SurfaceDescriptor surfaceDescriptor;
|
|
19
|
+
surfaceDescriptor.nextInChain = &androidSurfaceDesc;
|
|
20
|
+
return instance.CreateSurface(&surfaceDescriptor);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
} // namespace rnwgpu
|
|
25
|
+
|
|
26
|
+
#endif // SK_GRAPHITE
|
|
@@ -42,7 +42,10 @@ public class RNSkiaPackage extends TurboReactPackage {
|
|
|
42
42
|
|
|
43
43
|
@Override
|
|
44
44
|
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
|
45
|
-
return Arrays.<ViewManager>asList(
|
|
45
|
+
return Arrays.<ViewManager>asList(
|
|
46
|
+
new SkiaPictureViewManager(),
|
|
47
|
+
new WebGPUViewManager()
|
|
48
|
+
);
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
@Override
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
package com.shopify.reactnative.skia;
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint;
|
|
4
|
+
import android.content.Context;
|
|
5
|
+
import android.view.SurfaceHolder;
|
|
6
|
+
import android.view.SurfaceView;
|
|
7
|
+
|
|
8
|
+
import androidx.annotation.NonNull;
|
|
9
|
+
|
|
10
|
+
@SuppressLint("ViewConstructor")
|
|
11
|
+
public class WebGPUSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
|
|
12
|
+
|
|
13
|
+
WebGPUViewAPI mApi;
|
|
14
|
+
|
|
15
|
+
public WebGPUSurfaceView(Context context, WebGPUViewAPI api) {
|
|
16
|
+
super(context);
|
|
17
|
+
mApi = api;
|
|
18
|
+
getHolder().addCallback(this);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@Override
|
|
22
|
+
protected void onDetachedFromWindow() {
|
|
23
|
+
super.onDetachedFromWindow();
|
|
24
|
+
mApi.surfaceDestroyed();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@Override
|
|
28
|
+
public void surfaceCreated(@NonNull SurfaceHolder holder) {
|
|
29
|
+
mApi.surfaceCreated(holder.getSurface());
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@Override
|
|
33
|
+
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
|
|
34
|
+
mApi.surfaceChanged(holder.getSurface());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Override
|
|
38
|
+
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
|
|
39
|
+
mApi.surfaceOffscreen();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
package com.shopify.reactnative.skia;
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint;
|
|
4
|
+
import android.content.Context;
|
|
5
|
+
import android.graphics.SurfaceTexture;
|
|
6
|
+
import android.view.Surface;
|
|
7
|
+
import android.view.TextureView;
|
|
8
|
+
import androidx.annotation.NonNull;
|
|
9
|
+
|
|
10
|
+
@SuppressLint("ViewConstructor")
|
|
11
|
+
public class WebGPUTextureView extends TextureView implements TextureView.SurfaceTextureListener {
|
|
12
|
+
|
|
13
|
+
WebGPUViewAPI mApi;
|
|
14
|
+
|
|
15
|
+
public WebGPUTextureView(Context context, WebGPUViewAPI api) {
|
|
16
|
+
super(context);
|
|
17
|
+
mApi = api;
|
|
18
|
+
setOpaque(false);
|
|
19
|
+
setSurfaceTextureListener(this);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@Override
|
|
23
|
+
public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int width, int height) {
|
|
24
|
+
Surface surface = new Surface(surfaceTexture);
|
|
25
|
+
mApi.surfaceCreated(surface);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@Override
|
|
29
|
+
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int width, int height) {
|
|
30
|
+
Surface surface = new Surface(surfaceTexture);
|
|
31
|
+
mApi.surfaceChanged(surface);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@Override
|
|
35
|
+
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) {
|
|
36
|
+
mApi.surfaceDestroyed();
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Override
|
|
41
|
+
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) {
|
|
42
|
+
// No implementation needed
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
package com.shopify.reactnative.skia;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.view.Surface;
|
|
5
|
+
import android.view.View;
|
|
6
|
+
|
|
7
|
+
import com.facebook.proguard.annotations.DoNotStrip;
|
|
8
|
+
import com.facebook.react.views.view.ReactViewGroup;
|
|
9
|
+
|
|
10
|
+
public class WebGPUView extends ReactViewGroup implements WebGPUViewAPI {
|
|
11
|
+
|
|
12
|
+
private int mContextId;
|
|
13
|
+
private boolean mTransparent = false;
|
|
14
|
+
private View mView = null;
|
|
15
|
+
|
|
16
|
+
WebGPUView(Context context) {
|
|
17
|
+
super(context);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public void setContextId(int contextId) {
|
|
21
|
+
mContextId = contextId;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public void setTransparent(boolean value) {
|
|
25
|
+
Context ctx = getContext();
|
|
26
|
+
if (value != mTransparent || mView == null) {
|
|
27
|
+
if (mView != null) {
|
|
28
|
+
removeView(mView);
|
|
29
|
+
}
|
|
30
|
+
mTransparent = value;
|
|
31
|
+
if (mTransparent) {
|
|
32
|
+
mView = new WebGPUTextureView(ctx, this);
|
|
33
|
+
} else {
|
|
34
|
+
mView = new WebGPUSurfaceView(ctx, this);
|
|
35
|
+
}
|
|
36
|
+
addView(mView);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Override
|
|
41
|
+
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
42
|
+
super.onLayout(changed, left, top, right, bottom);
|
|
43
|
+
if (mView != null) {
|
|
44
|
+
mView.layout(0, 0, this.getMeasuredWidth(), this.getMeasuredHeight());
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@Override
|
|
49
|
+
public void surfaceCreated(Surface surface) {
|
|
50
|
+
float density = getResources().getDisplayMetrics().density;
|
|
51
|
+
float width = getWidth() / density;
|
|
52
|
+
float height = getHeight() / density;
|
|
53
|
+
onSurfaceCreate(surface, mContextId, width, height);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@Override
|
|
57
|
+
public void surfaceChanged(Surface surface) {
|
|
58
|
+
float density = getResources().getDisplayMetrics().density;
|
|
59
|
+
float width = getWidth() / density;
|
|
60
|
+
float height = getHeight() / density;
|
|
61
|
+
onSurfaceChanged(surface, mContextId, width, height);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@Override
|
|
65
|
+
public void surfaceDestroyed() {
|
|
66
|
+
onSurfaceDestroy(mContextId);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@Override
|
|
70
|
+
public void surfaceOffscreen() {
|
|
71
|
+
switchToOffscreenSurface(mContextId);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@DoNotStrip
|
|
75
|
+
private native void onSurfaceCreate(
|
|
76
|
+
Surface surface,
|
|
77
|
+
int contextId,
|
|
78
|
+
float width,
|
|
79
|
+
float height
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
@DoNotStrip
|
|
83
|
+
private native void onSurfaceChanged(
|
|
84
|
+
Surface surface,
|
|
85
|
+
int contextId,
|
|
86
|
+
float width,
|
|
87
|
+
float height
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
@DoNotStrip
|
|
91
|
+
private native void onSurfaceDestroy(int contextId);
|
|
92
|
+
|
|
93
|
+
@DoNotStrip
|
|
94
|
+
private native void switchToOffscreenSurface(int contextId);
|
|
95
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
package com.shopify.reactnative.skia;
|
|
2
|
+
|
|
3
|
+
import android.view.Surface;
|
|
4
|
+
|
|
5
|
+
public interface WebGPUViewAPI {
|
|
6
|
+
|
|
7
|
+
void surfaceCreated(Surface surface);
|
|
8
|
+
|
|
9
|
+
void surfaceChanged(Surface surface);
|
|
10
|
+
|
|
11
|
+
void surfaceDestroyed();
|
|
12
|
+
|
|
13
|
+
void surfaceOffscreen();
|
|
14
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
package com.shopify.reactnative.skia;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.module.annotations.ReactModule;
|
|
4
|
+
import com.facebook.react.uimanager.ThemedReactContext;
|
|
5
|
+
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
6
|
+
import com.facebook.react.views.view.ReactViewGroup;
|
|
7
|
+
import com.facebook.react.views.view.ReactViewManager;
|
|
8
|
+
import com.facebook.react.viewmanagers.WebGPUViewManagerDelegate;
|
|
9
|
+
import com.facebook.react.viewmanagers.WebGPUViewManagerInterface;
|
|
10
|
+
|
|
11
|
+
import androidx.annotation.NonNull;
|
|
12
|
+
import androidx.annotation.Nullable;
|
|
13
|
+
|
|
14
|
+
@ReactModule(name = WebGPUViewManager.NAME)
|
|
15
|
+
public class WebGPUViewManager extends ReactViewManager implements WebGPUViewManagerInterface<WebGPUView> {
|
|
16
|
+
|
|
17
|
+
public static final String NAME = "WebGPUView";
|
|
18
|
+
|
|
19
|
+
protected WebGPUViewManagerDelegate mDelegate;
|
|
20
|
+
|
|
21
|
+
public WebGPUViewManager() {
|
|
22
|
+
mDelegate = new WebGPUViewManagerDelegate(this);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
protected WebGPUViewManagerDelegate getDelegate() {
|
|
26
|
+
return mDelegate;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@NonNull
|
|
30
|
+
@Override
|
|
31
|
+
public String getName() {
|
|
32
|
+
return NAME;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@NonNull
|
|
36
|
+
@Override
|
|
37
|
+
public WebGPUView createViewInstance(@NonNull ThemedReactContext context) {
|
|
38
|
+
return new WebGPUView(context);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@Override
|
|
42
|
+
@ReactProp(name = "transparent")
|
|
43
|
+
public void setTransparent(WebGPUView view, boolean value) {
|
|
44
|
+
view.setTransparent(value);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@Override
|
|
48
|
+
@ReactProp(name = "contextId")
|
|
49
|
+
public void setContextId(WebGPUView view, int value) {
|
|
50
|
+
view.setContextId(value);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@Override
|
|
54
|
+
public void onDropViewInstance(@NonNull ReactViewGroup view) {
|
|
55
|
+
super.onDropViewInstance(view);
|
|
56
|
+
((WebGPUView) view).surfaceDestroyed();
|
|
57
|
+
}
|
|
58
|
+
}
|
package/apple/MetalContext.h
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
#import <include/gpu/ganesh/mtl/GrMtlBackendSurface.h>
|
|
14
14
|
#import <include/gpu/ganesh/mtl/GrMtlDirectContext.h>
|
|
15
15
|
#import <include/gpu/ganesh/mtl/SkSurfaceMetal.h>
|
|
16
|
+
#include "include/core/SkColorSpace.h"
|
|
16
17
|
|
|
17
18
|
struct OffscreenRenderContext {
|
|
18
19
|
id<MTLTexture> texture;
|
|
@@ -44,7 +45,8 @@ public:
|
|
|
44
45
|
return instance;
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
sk_sp<SkSurface> MakeOffscreen(int width, int height
|
|
48
|
+
sk_sp<SkSurface> MakeOffscreen(int width, int height,
|
|
49
|
+
bool useP3ColorSpace = false) {
|
|
48
50
|
auto device = _device;
|
|
49
51
|
auto ctx = new OffscreenRenderContext(device, _directContext, _commandQueue,
|
|
50
52
|
width, height);
|
|
@@ -55,10 +57,16 @@ public:
|
|
|
55
57
|
GrBackendTexture backendTexture =
|
|
56
58
|
GrBackendTextures::MakeMtl(width, height, skgpu::Mipmapped::kNo, info);
|
|
57
59
|
|
|
60
|
+
sk_sp<SkColorSpace> colorSpace =
|
|
61
|
+
useP3ColorSpace
|
|
62
|
+
? SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,
|
|
63
|
+
SkNamedGamut::kDisplayP3)
|
|
64
|
+
: nullptr;
|
|
65
|
+
|
|
58
66
|
// Create a SkSurface from the GrBackendTexture
|
|
59
67
|
auto surface = SkSurfaces::WrapBackendTexture(
|
|
60
68
|
_directContext.get(), backendTexture, kTopLeft_GrSurfaceOrigin, 0,
|
|
61
|
-
kBGRA_8888_SkColorType,
|
|
69
|
+
kBGRA_8888_SkColorType, colorSpace, nullptr,
|
|
62
70
|
[](void *addr) { delete (OffscreenRenderContext *)addr; }, ctx);
|
|
63
71
|
|
|
64
72
|
return surface;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
#include "MetalContext.h"
|
|
4
4
|
#include "RNSkLog.h"
|
|
5
|
+
#include "include/core/SkColorSpace.h"
|
|
5
6
|
|
|
6
7
|
MetalWindowContext::MetalWindowContext(GrDirectContext *directContext,
|
|
7
8
|
id<MTLDevice> device,
|
|
@@ -46,6 +47,7 @@ MetalWindowContext::MetalWindowContext(GrDirectContext *directContext,
|
|
|
46
47
|
CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3);
|
|
47
48
|
_layer.colorspace = colorSpace;
|
|
48
49
|
CGColorSpaceRelease(colorSpace);
|
|
50
|
+
_useP3ColorSpace = true;
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
|
|
@@ -69,9 +71,14 @@ sk_sp<SkSurface> MetalWindowContext::getSurface() {
|
|
|
69
71
|
GrBackendRenderTarget backendRT = GrBackendRenderTargets::MakeMtl(
|
|
70
72
|
_layer.drawableSize.width, _layer.drawableSize.height, fbInfo);
|
|
71
73
|
|
|
74
|
+
sk_sp<SkColorSpace> skColorSpace =
|
|
75
|
+
_useP3ColorSpace
|
|
76
|
+
? SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,
|
|
77
|
+
SkNamedGamut::kDisplayP3)
|
|
78
|
+
: nullptr;
|
|
72
79
|
_skSurface = SkSurfaces::WrapBackendRenderTarget(
|
|
73
80
|
_directContext, backendRT, kTopLeft_GrSurfaceOrigin,
|
|
74
|
-
kBGRA_8888_SkColorType,
|
|
81
|
+
kBGRA_8888_SkColorType, skColorSpace, nullptr);
|
|
75
82
|
|
|
76
83
|
return _skSurface;
|
|
77
84
|
}
|
|
@@ -69,7 +69,8 @@ public:
|
|
|
69
69
|
const std::function<void(std::unique_ptr<SkStreamAsset>)> &op) override;
|
|
70
70
|
|
|
71
71
|
void raiseError(const std::exception &err) override;
|
|
72
|
-
sk_sp<SkSurface> makeOffscreenSurface(int width, int height
|
|
72
|
+
sk_sp<SkSurface> makeOffscreenSurface(int width, int height,
|
|
73
|
+
bool useP3ColorSpace = false) override;
|
|
73
74
|
|
|
74
75
|
sk_sp<SkFontMgr> createFontMgr() override;
|
|
75
76
|
|
|
@@ -251,12 +251,14 @@ void RNSkApplePlatformContext::raiseError(const std::exception &err) {
|
|
|
251
251
|
RCTFatal(RCTErrorWithMessage([NSString stringWithUTF8String:err.what()]));
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
sk_sp<SkSurface> RNSkApplePlatformContext::makeOffscreenSurface(
|
|
255
|
-
|
|
254
|
+
sk_sp<SkSurface> RNSkApplePlatformContext::makeOffscreenSurface(
|
|
255
|
+
int width, int height, bool useP3ColorSpace) {
|
|
256
256
|
#if defined(SK_GRAPHITE)
|
|
257
|
-
return DawnContext::getInstance().MakeOffscreen(width, height
|
|
257
|
+
return DawnContext::getInstance().MakeOffscreen(width, height,
|
|
258
|
+
useP3ColorSpace);
|
|
258
259
|
#else
|
|
259
|
-
return MetalContext::getInstance().MakeOffscreen(width, height
|
|
260
|
+
return MetalContext::getInstance().MakeOffscreen(width, height,
|
|
261
|
+
useP3ColorSpace);
|
|
260
262
|
#endif
|
|
261
263
|
}
|
|
262
264
|
|
package/apple/SkiaPictureView.mm
CHANGED
|
@@ -58,6 +58,9 @@ using namespace facebook::react;
|
|
|
58
58
|
if (newProps.colorSpace == "" || newProps.colorSpace == "srgb") {
|
|
59
59
|
bool useP3 = false;
|
|
60
60
|
[self setUseP3ColorSpace:useP3];
|
|
61
|
+
} else if (newProps.colorSpace == "p3") {
|
|
62
|
+
bool useP3 = true;
|
|
63
|
+
[self setUseP3ColorSpace:useP3];
|
|
61
64
|
}
|
|
62
65
|
}
|
|
63
66
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#ifdef SK_GRAPHITE
|
|
4
|
+
|
|
5
|
+
#include "rnwgpu/PlatformContext.h"
|
|
6
|
+
|
|
7
|
+
namespace rnwgpu {
|
|
8
|
+
|
|
9
|
+
class SkiaPlatformContext : public PlatformContext {
|
|
10
|
+
public:
|
|
11
|
+
SkiaPlatformContext() = default;
|
|
12
|
+
~SkiaPlatformContext() = default;
|
|
13
|
+
|
|
14
|
+
wgpu::Surface makeSurface(wgpu::Instance instance, void *surface, int width,
|
|
15
|
+
int height) override;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
} // namespace rnwgpu
|
|
19
|
+
|
|
20
|
+
#endif // SK_GRAPHITE
|