@shopify/react-native-skia 2.5.2 → 2.5.4
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 +11 -0
- package/android/cpp/jni/JniWebGPUView.cpp +67 -0
- 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/RNSkUIKit.h +13 -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/jsi2/JSIConverter.h +11 -0
- package/cpp/rnskia/RNDawnContext.h +2 -2
- package/cpp/rnskia/RNDawnWindowContext.h +3 -0
- package/cpp/rnskia/RNSkManager.cpp +11 -4
- package/cpp/rnwgpu/Canvas.h +50 -0
- package/cpp/rnwgpu/PlatformContext.h +18 -0
- package/cpp/rnwgpu/SurfaceRegistry.h +229 -0
- package/cpp/rnwgpu/api/GPU.cpp +12 -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/GPUQueue.cpp +1 -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.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.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/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 +3 -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/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 +3 -2
- package/react-native-skia.podspec +3 -0
- package/scripts/install-libs.js +24 -32
- package/src/external/reanimated/useVideo.ts +1 -4
- package/src/mock/index.ts +1 -0
- package/src/skia/types/Surface/SurfaceFactory.ts +5 -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
|
@@ -128,6 +128,7 @@ if(SK_GRAPHITE)
|
|
|
128
128
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUAdapter.cpp"
|
|
129
129
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUBindGroup.cpp"
|
|
130
130
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUBuffer.cpp"
|
|
131
|
+
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUCanvasContext.cpp"
|
|
131
132
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUCommandEncoder.cpp"
|
|
132
133
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUComputePassEncoder.cpp"
|
|
133
134
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUComputePipeline.cpp"
|
|
@@ -141,6 +142,9 @@ if(SK_GRAPHITE)
|
|
|
141
142
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUShaderModule.cpp"
|
|
142
143
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUSupportedLimits.cpp"
|
|
143
144
|
"${PROJECT_SOURCE_DIR}/../cpp/rnwgpu/api/GPUTexture.cpp"
|
|
145
|
+
|
|
146
|
+
# WebGPU Canvas JNI bindings
|
|
147
|
+
"${PROJECT_SOURCE_DIR}/cpp/jni/JniWebGPUView.cpp"
|
|
144
148
|
)
|
|
145
149
|
endif()
|
|
146
150
|
|
|
@@ -210,6 +214,12 @@ set_property(TARGET pathops PROPERTY IMPORTED_LOCATION "${SKIA_LIBS_PATH}/libpat
|
|
|
210
214
|
add_library(jsonreader STATIC IMPORTED)
|
|
211
215
|
set_property(TARGET jsonreader PROPERTY IMPORTED_LOCATION "${SKIA_LIBS_PATH}/libjsonreader.a")
|
|
212
216
|
|
|
217
|
+
# Dawn library for Graphite builds (contains dawn::native symbols)
|
|
218
|
+
if(SK_GRAPHITE)
|
|
219
|
+
add_library(dawn_combined STATIC IMPORTED)
|
|
220
|
+
set_property(TARGET dawn_combined PROPERTY IMPORTED_LOCATION "${SKIA_LIBS_PATH}/libdawn_combined.a")
|
|
221
|
+
endif()
|
|
222
|
+
|
|
213
223
|
find_library(
|
|
214
224
|
LOG_LIB
|
|
215
225
|
log
|
|
@@ -382,6 +392,7 @@ endif()
|
|
|
382
392
|
if(SK_GRAPHITE)
|
|
383
393
|
target_link_libraries(${PACKAGE_NAME}
|
|
384
394
|
${COMMON_LIBS}
|
|
395
|
+
dawn_combined
|
|
385
396
|
)
|
|
386
397
|
else()
|
|
387
398
|
target_link_libraries(${PACKAGE_NAME}
|
|
@@ -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::SurfaceSourceAndroidNativeWindow 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
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -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
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#ifdef SK_GRAPHITE
|
|
2
|
+
|
|
3
|
+
#include "SkiaPlatformContext.h"
|
|
4
|
+
|
|
5
|
+
#include <TargetConditionals.h>
|
|
6
|
+
|
|
7
|
+
namespace rnwgpu {
|
|
8
|
+
|
|
9
|
+
wgpu::Surface SkiaPlatformContext::makeSurface(wgpu::Instance instance,
|
|
10
|
+
void *surface, int width,
|
|
11
|
+
int height) {
|
|
12
|
+
wgpu::SurfaceSourceMetalLayer metalSurfaceDesc;
|
|
13
|
+
metalSurfaceDesc.layer = surface;
|
|
14
|
+
wgpu::SurfaceDescriptor surfaceDescriptor;
|
|
15
|
+
surfaceDescriptor.nextInChain = &metalSurfaceDesc;
|
|
16
|
+
return instance.CreateSurface(&surfaceDescriptor);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
} // namespace rnwgpu
|
|
20
|
+
|
|
21
|
+
#endif // SK_GRAPHITE
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#import "WebGPUMetalView.h"
|
|
2
|
+
|
|
3
|
+
#ifdef SK_GRAPHITE
|
|
4
|
+
|
|
5
|
+
#import "webgpu/webgpu_cpp.h"
|
|
6
|
+
#import <QuartzCore/CAMetalLayer.h>
|
|
7
|
+
|
|
8
|
+
#import "rnwgpu/SurfaceRegistry.h"
|
|
9
|
+
#import "rnskia/RNDawnContext.h"
|
|
10
|
+
|
|
11
|
+
@implementation WebGPUMetalView {
|
|
12
|
+
BOOL _isConfigured;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#if !TARGET_OS_OSX
|
|
16
|
+
+ (Class)layerClass {
|
|
17
|
+
return [CAMetalLayer class];
|
|
18
|
+
}
|
|
19
|
+
#else // !TARGET_OS_OSX
|
|
20
|
+
- (instancetype)init {
|
|
21
|
+
self = [super init];
|
|
22
|
+
if (self) {
|
|
23
|
+
self.wantsLayer = true;
|
|
24
|
+
self.layer = [CAMetalLayer layer];
|
|
25
|
+
}
|
|
26
|
+
return self;
|
|
27
|
+
}
|
|
28
|
+
#endif // !TARGET_OS_OSX
|
|
29
|
+
|
|
30
|
+
- (void)configure {
|
|
31
|
+
auto size = self.frame.size;
|
|
32
|
+
void *nativeSurface = (__bridge void *)self.layer;
|
|
33
|
+
auto ®istry = rnwgpu::SurfaceRegistry::getInstance();
|
|
34
|
+
auto &dawnContext = RNSkia::DawnContext::getInstance();
|
|
35
|
+
auto gpu = dawnContext.getWGPUInstance();
|
|
36
|
+
|
|
37
|
+
// Create the surface using Dawn's API directly
|
|
38
|
+
wgpu::SurfaceSourceMetalLayer metalSurfaceDesc;
|
|
39
|
+
metalSurfaceDesc.layer = nativeSurface;
|
|
40
|
+
wgpu::SurfaceDescriptor surfaceDescriptor;
|
|
41
|
+
surfaceDescriptor.nextInChain = &metalSurfaceDesc;
|
|
42
|
+
auto surface = gpu.CreateSurface(&surfaceDescriptor);
|
|
43
|
+
|
|
44
|
+
registry
|
|
45
|
+
.getSurfaceInfoOrCreate([_contextId intValue], gpu, size.width,
|
|
46
|
+
size.height)
|
|
47
|
+
->switchToOnscreen(nativeSurface, surface);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
- (void)update {
|
|
51
|
+
auto size = self.frame.size;
|
|
52
|
+
auto ®istry = rnwgpu::SurfaceRegistry::getInstance();
|
|
53
|
+
auto surfaceInfo = registry.getSurfaceInfo([_contextId intValue]);
|
|
54
|
+
if (surfaceInfo) {
|
|
55
|
+
surfaceInfo->resize(size.width, size.height);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
- (void)dealloc {
|
|
60
|
+
auto ®istry = rnwgpu::SurfaceRegistry::getInstance();
|
|
61
|
+
// Remove the surface info from the registry
|
|
62
|
+
registry.removeSurfaceInfo([_contextId intValue]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@end
|
|
66
|
+
|
|
67
|
+
#else // SK_GRAPHITE
|
|
68
|
+
|
|
69
|
+
// Stub implementation when GRAPHITE is not enabled
|
|
70
|
+
@implementation WebGPUMetalView
|
|
71
|
+
|
|
72
|
+
#if !TARGET_OS_OSX
|
|
73
|
+
+ (Class)layerClass {
|
|
74
|
+
return [CAMetalLayer class];
|
|
75
|
+
}
|
|
76
|
+
#else // !TARGET_OS_OSX
|
|
77
|
+
- (instancetype)init {
|
|
78
|
+
self = [super init];
|
|
79
|
+
return self;
|
|
80
|
+
}
|
|
81
|
+
#endif // !TARGET_OS_OSX
|
|
82
|
+
|
|
83
|
+
- (void)configure {
|
|
84
|
+
// No-op when GRAPHITE is not enabled
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
- (void)update {
|
|
88
|
+
// No-op when GRAPHITE is not enabled
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@end
|
|
92
|
+
|
|
93
|
+
#endif // SK_GRAPHITE
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
4
|
+
|
|
5
|
+
#import "WebGPUMetalView.h"
|
|
6
|
+
#import <React/RCTViewComponentView.h>
|
|
7
|
+
#if !TARGET_OS_OSX
|
|
8
|
+
#import <UIKit/UIKit.h>
|
|
9
|
+
#else
|
|
10
|
+
#import <AppKit/AppKit.h>
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
14
|
+
|
|
15
|
+
@interface WebGPUView : RCTViewComponentView
|
|
16
|
+
@end
|
|
17
|
+
|
|
18
|
+
NS_ASSUME_NONNULL_END
|
|
19
|
+
|
|
20
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
2
|
+
|
|
3
|
+
#import "WebGPUView.h"
|
|
4
|
+
|
|
5
|
+
#import <react/renderer/components/rnskia/ComponentDescriptors.h>
|
|
6
|
+
#import <react/renderer/components/rnskia/EventEmitters.h>
|
|
7
|
+
#import <react/renderer/components/rnskia/Props.h>
|
|
8
|
+
#import <react/renderer/components/rnskia/RCTComponentViewHelpers.h>
|
|
9
|
+
|
|
10
|
+
#import "WebGPUMetalView.h"
|
|
11
|
+
#import "RCTFabricComponentsPlugins.h"
|
|
12
|
+
|
|
13
|
+
using namespace facebook::react;
|
|
14
|
+
|
|
15
|
+
@implementation WebGPUView
|
|
16
|
+
|
|
17
|
+
- (instancetype)initWithFrame:(CGRect)frame {
|
|
18
|
+
if (self = [super initWithFrame:frame]) {
|
|
19
|
+
static const auto defaultProps = std::make_shared<const WebGPUViewProps>();
|
|
20
|
+
_props = defaultProps;
|
|
21
|
+
}
|
|
22
|
+
return self;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider {
|
|
26
|
+
return concreteComponentDescriptorProvider<WebGPUViewComponentDescriptor>();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
- (void)prepareForRecycle {
|
|
30
|
+
[super prepareForRecycle];
|
|
31
|
+
/*
|
|
32
|
+
It's important to destroy the Metal Layer before releasing a view
|
|
33
|
+
to the recycled pool to prevent displaying outdated content from
|
|
34
|
+
the last usage in the new context.
|
|
35
|
+
*/
|
|
36
|
+
self.contentView = nil;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
- (WebGPUMetalView *)getContentView {
|
|
40
|
+
if (!self.contentView) {
|
|
41
|
+
self.contentView = [WebGPUMetalView new];
|
|
42
|
+
}
|
|
43
|
+
return (WebGPUMetalView *)self.contentView;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
- (void)updateProps:(const Props::Shared &)props
|
|
47
|
+
oldProps:(const Props::Shared &)oldProps {
|
|
48
|
+
const auto &oldViewProps =
|
|
49
|
+
*std::static_pointer_cast<const WebGPUViewProps>(_props);
|
|
50
|
+
const auto &newViewProps =
|
|
51
|
+
*std::static_pointer_cast<const WebGPUViewProps>(props);
|
|
52
|
+
|
|
53
|
+
if (newViewProps.contextId != oldViewProps.contextId) {
|
|
54
|
+
/*
|
|
55
|
+
The context is set only once during mounting the component
|
|
56
|
+
and never changes because it isn't available for users to modify.
|
|
57
|
+
*/
|
|
58
|
+
WebGPUMetalView *metalView = [WebGPUMetalView new];
|
|
59
|
+
self.contentView = metalView;
|
|
60
|
+
[metalView setContextId:@(newViewProps.contextId)];
|
|
61
|
+
[metalView configure];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
[super updateProps:props oldProps:oldProps];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
- (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
|
|
68
|
+
oldLayoutMetrics:(const LayoutMetrics &)oldLayoutMetrics {
|
|
69
|
+
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
|
|
70
|
+
[(WebGPUMetalView *)self.contentView update];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@end
|
|
74
|
+
|
|
75
|
+
Class<RCTComponentViewProtocol> WebGPUViewCls(void) { return WebGPUView.class; }
|
|
76
|
+
|
|
77
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
package/cpp/jsi2/JSIConverter.h
CHANGED
|
@@ -238,6 +238,17 @@ template <> struct JSIConverter<rnwgpu::async::AsyncTaskHandle> {
|
|
|
238
238
|
};
|
|
239
239
|
#endif
|
|
240
240
|
|
|
241
|
+
// jsi::Function <> Function
|
|
242
|
+
template <> struct JSIConverter<jsi::Function> {
|
|
243
|
+
static jsi::Function fromJSI(jsi::Runtime &runtime, const jsi::Value &arg,
|
|
244
|
+
bool outOfBound) {
|
|
245
|
+
return arg.asObject(runtime).asFunction(runtime);
|
|
246
|
+
}
|
|
247
|
+
static jsi::Value toJSI(jsi::Runtime &runtime, jsi::Function &&arg) {
|
|
248
|
+
return std::move(arg);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
|
|
241
252
|
// std::map<std::string, T> <> Record<string, T>
|
|
242
253
|
template <typename ValueType>
|
|
243
254
|
struct JSIConverter<std::map<std::string, ValueType>> {
|