@shopify/react-native-skia 2.5.2 → 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.
Files changed (115) hide show
  1. package/android/CMakeLists.txt +4 -0
  2. package/android/cpp/jni/JniWebGPUView.cpp +67 -0
  3. package/android/cpp/rnskia-android/SkiaPlatformContext.h +26 -0
  4. package/android/src/main/java/com/shopify/reactnative/skia/RNSkiaPackage.java +4 -1
  5. package/android/src/main/java/com/shopify/reactnative/skia/WebGPUSurfaceView.java +41 -0
  6. package/android/src/main/java/com/shopify/reactnative/skia/WebGPUTextureView.java +44 -0
  7. package/android/src/main/java/com/shopify/reactnative/skia/WebGPUView.java +95 -0
  8. package/android/src/main/java/com/shopify/reactnative/skia/WebGPUViewAPI.java +14 -0
  9. package/android/src/main/java/com/shopify/reactnative/skia/WebGPUViewManager.java +58 -0
  10. package/apple/RNSkUIKit.h +13 -0
  11. package/apple/SkiaPlatformContext.h +20 -0
  12. package/apple/SkiaPlatformContext.mm +21 -0
  13. package/apple/WebGPUMetalView.h +12 -0
  14. package/apple/WebGPUMetalView.mm +93 -0
  15. package/apple/WebGPUView.h +20 -0
  16. package/apple/WebGPUView.mm +77 -0
  17. package/cpp/jsi2/JSIConverter.h +11 -0
  18. package/cpp/rnskia/RNSkManager.cpp +11 -4
  19. package/cpp/rnwgpu/Canvas.h +45 -0
  20. package/cpp/rnwgpu/PlatformContext.h +18 -0
  21. package/cpp/rnwgpu/SurfaceRegistry.h +229 -0
  22. package/cpp/rnwgpu/api/GPUAdapter.cpp +26 -0
  23. package/cpp/rnwgpu/api/GPUCanvasContext.cpp +64 -0
  24. package/cpp/rnwgpu/api/GPUCanvasContext.h +65 -0
  25. package/cpp/rnwgpu/api/GPUDevice.cpp +52 -0
  26. package/cpp/rnwgpu/api/GPUDevice.h +62 -1
  27. package/cpp/rnwgpu/api/GPUUncapturedErrorEvent.h +61 -0
  28. package/cpp/rnwgpu/api/RNWebGPU.h +62 -0
  29. package/cpp/rnwgpu/api/descriptors/GPUBindGroupEntry.h +4 -0
  30. package/cpp/rnwgpu/api/descriptors/GPUCanvasConfiguration.h +76 -0
  31. package/lib/commonjs/external/reanimated/useVideo.js +1 -4
  32. package/lib/commonjs/external/reanimated/useVideo.js.map +1 -1
  33. package/lib/commonjs/mock/index.js +1 -0
  34. package/lib/commonjs/mock/index.js.map +1 -1
  35. package/lib/commonjs/skia/types/Surface/SurfaceFactory.js.map +1 -1
  36. package/lib/commonjs/sksg/Container.native.js +4 -0
  37. package/lib/commonjs/sksg/Container.native.js.map +1 -1
  38. package/lib/commonjs/sksg/Container.web.js +4 -0
  39. package/lib/commonjs/sksg/Container.web.js.map +1 -1
  40. package/lib/commonjs/specs/WebGPUViewNativeComponent.d.ts +8 -0
  41. package/lib/commonjs/specs/WebGPUViewNativeComponent.js +11 -0
  42. package/lib/commonjs/specs/WebGPUViewNativeComponent.js.map +1 -0
  43. package/lib/commonjs/specs/WebGPUViewNativeComponent.web.d.ts +8 -0
  44. package/lib/commonjs/specs/WebGPUViewNativeComponent.web.js +101 -0
  45. package/lib/commonjs/specs/WebGPUViewNativeComponent.web.js.map +1 -0
  46. package/lib/commonjs/specs/utils.d.ts +1 -0
  47. package/lib/commonjs/specs/utils.js +11 -0
  48. package/lib/commonjs/specs/utils.js.map +1 -0
  49. package/lib/commonjs/views/WebGPUCanvas.d.ts +32 -0
  50. package/lib/commonjs/views/WebGPUCanvas.js +66 -0
  51. package/lib/commonjs/views/WebGPUCanvas.js.map +1 -0
  52. package/lib/commonjs/views/WebGPUCanvas.web.d.ts +23 -0
  53. package/lib/commonjs/views/WebGPUCanvas.web.js +20 -0
  54. package/lib/commonjs/views/WebGPUCanvas.web.js.map +1 -0
  55. package/lib/commonjs/views/index.d.ts +1 -0
  56. package/lib/commonjs/views/index.js +11 -0
  57. package/lib/commonjs/views/index.js.map +1 -1
  58. package/lib/module/external/reanimated/useVideo.js +1 -4
  59. package/lib/module/external/reanimated/useVideo.js.map +1 -1
  60. package/lib/module/mock/index.js +1 -0
  61. package/lib/module/mock/index.js.map +1 -1
  62. package/lib/module/skia/types/Surface/SurfaceFactory.js.map +1 -1
  63. package/lib/module/sksg/Container.native.js +5 -0
  64. package/lib/module/sksg/Container.native.js.map +1 -1
  65. package/lib/module/sksg/Container.web.js +5 -0
  66. package/lib/module/sksg/Container.web.js.map +1 -1
  67. package/lib/module/specs/WebGPUViewNativeComponent.d.ts +8 -0
  68. package/lib/module/specs/WebGPUViewNativeComponent.js +4 -0
  69. package/lib/module/specs/WebGPUViewNativeComponent.js.map +1 -0
  70. package/lib/module/specs/WebGPUViewNativeComponent.web.d.ts +8 -0
  71. package/lib/module/specs/WebGPUViewNativeComponent.web.js +94 -0
  72. package/lib/module/specs/WebGPUViewNativeComponent.web.js.map +1 -0
  73. package/lib/module/specs/utils.d.ts +1 -0
  74. package/lib/module/specs/utils.js +5 -0
  75. package/lib/module/specs/utils.js.map +1 -0
  76. package/lib/module/views/WebGPUCanvas.d.ts +32 -0
  77. package/lib/module/views/WebGPUCanvas.js +57 -0
  78. package/lib/module/views/WebGPUCanvas.js.map +1 -0
  79. package/lib/module/views/WebGPUCanvas.web.d.ts +23 -0
  80. package/lib/module/views/WebGPUCanvas.web.js +12 -0
  81. package/lib/module/views/WebGPUCanvas.web.js.map +1 -0
  82. package/lib/module/views/index.d.ts +1 -0
  83. package/lib/module/views/index.js +1 -0
  84. package/lib/module/views/index.js.map +1 -1
  85. package/lib/typescript/lib/commonjs/mock/index.d.ts +1 -0
  86. package/lib/typescript/lib/commonjs/specs/WebGPUViewNativeComponent.d.ts +3 -0
  87. package/lib/typescript/lib/commonjs/specs/WebGPUViewNativeComponent.web.d.ts +3 -0
  88. package/lib/typescript/lib/commonjs/specs/utils.d.ts +2 -0
  89. package/lib/typescript/lib/commonjs/views/WebGPUCanvas.d.ts +6 -0
  90. package/lib/typescript/lib/commonjs/views/WebGPUCanvas.web.d.ts +6 -0
  91. package/lib/typescript/lib/module/mock/index.d.ts +3 -1
  92. package/lib/typescript/lib/module/specs/WebGPUViewNativeComponent.d.ts +2 -0
  93. package/lib/typescript/lib/module/specs/WebGPUViewNativeComponent.web.d.ts +2 -0
  94. package/lib/typescript/lib/module/specs/utils.d.ts +1 -0
  95. package/lib/typescript/lib/module/views/WebGPUCanvas.d.ts +7 -0
  96. package/lib/typescript/lib/module/views/WebGPUCanvas.web.d.ts +8 -0
  97. package/lib/typescript/lib/module/views/index.d.ts +1 -0
  98. package/lib/typescript/src/specs/WebGPUViewNativeComponent.d.ts +8 -0
  99. package/lib/typescript/src/specs/WebGPUViewNativeComponent.web.d.ts +8 -0
  100. package/lib/typescript/src/specs/utils.d.ts +1 -0
  101. package/lib/typescript/src/views/WebGPUCanvas.d.ts +32 -0
  102. package/lib/typescript/src/views/WebGPUCanvas.web.d.ts +23 -0
  103. package/lib/typescript/src/views/index.d.ts +1 -0
  104. package/package.json +3 -2
  105. package/src/external/reanimated/useVideo.ts +1 -4
  106. package/src/mock/index.ts +1 -0
  107. package/src/skia/types/Surface/SurfaceFactory.ts +5 -1
  108. package/src/sksg/Container.native.ts +3 -0
  109. package/src/sksg/Container.web.ts +3 -0
  110. package/src/specs/WebGPUViewNativeComponent.ts +11 -0
  111. package/src/specs/WebGPUViewNativeComponent.web.ts +108 -0
  112. package/src/specs/utils.ts +4 -0
  113. package/src/views/WebGPUCanvas.tsx +109 -0
  114. package/src/views/WebGPUCanvas.web.tsx +36 -0
  115. package/src/views/index.ts +1 -0
@@ -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
 
@@ -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 &registry = 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 &registry = 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 &registry = 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 &registry = 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(new SkiaPictureViewManager());
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,13 @@
1
+ #pragma once
2
+
3
+ #if !TARGET_OS_OSX
4
+ #import <UIKit/UIKit.h>
5
+ #else
6
+ #import <Appkit/Appkit.h>
7
+ #endif
8
+
9
+ #if !TARGET_OS_OSX
10
+ typedef UIView RNSkPlatformView;
11
+ #else
12
+ typedef NSView RNSkPlatformView;
13
+ #endif
@@ -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,12 @@
1
+ #pragma once
2
+
3
+ #import "RNSkUIKit.h"
4
+
5
+ @interface WebGPUMetalView : RNSkPlatformView
6
+
7
+ @property (nonatomic, strong) NSNumber *contextId;
8
+
9
+ - (void)configure;
10
+ - (void)update;
11
+
12
+ @end
@@ -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 &registry = 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 &registry = 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 &registry = 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
@@ -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>> {