react-native-wgpu 0.1.8 → 0.1.10

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 (70) hide show
  1. package/android/cpp/cpp-adapter.cpp +23 -36
  2. package/android/src/main/java/com/webgpu/WebGPUModule.java +0 -37
  3. package/android/src/main/java/com/webgpu/WebGPUView.java +10 -2
  4. package/android/src/main/java/com/webgpu/WebGPUViewPackage.java +1 -1
  5. package/cpp/rnwgpu/RNWebGPUManager.cpp +1 -0
  6. package/cpp/rnwgpu/RNWebGPUManager.h +3 -2
  7. package/cpp/rnwgpu/SurfaceRegistry.h +196 -14
  8. package/cpp/rnwgpu/api/Canvas.h +15 -15
  9. package/cpp/rnwgpu/api/GPUCanvasContext.cpp +15 -25
  10. package/cpp/rnwgpu/api/GPUCanvasContext.h +12 -9
  11. package/cpp/rnwgpu/api/GPUDevice.cpp +3 -2
  12. package/cpp/rnwgpu/api/RNWebGPU.h +25 -10
  13. package/ios/MetalView.mm +13 -0
  14. package/ios/SurfaceUtils.h +2 -0
  15. package/ios/SurfaceUtils.mm +16 -5
  16. package/ios/WebGPUModule.mm +8 -25
  17. package/ios/WebGPUView.mm +9 -6
  18. package/lib/commonjs/Canvas.js +79 -18
  19. package/lib/commonjs/Canvas.js.map +1 -1
  20. package/lib/commonjs/Offscreen.js +3 -0
  21. package/lib/commonjs/Offscreen.js.map +1 -1
  22. package/lib/commonjs/hooks.js +56 -0
  23. package/lib/commonjs/hooks.js.map +1 -0
  24. package/lib/commonjs/index.js +12 -4
  25. package/lib/commonjs/index.js.map +1 -1
  26. package/lib/module/Canvas.js +80 -19
  27. package/lib/module/Canvas.js.map +1 -1
  28. package/lib/module/Offscreen.js +3 -0
  29. package/lib/module/Offscreen.js.map +1 -1
  30. package/lib/module/hooks.js +47 -0
  31. package/lib/module/hooks.js.map +1 -0
  32. package/lib/module/index.js +6 -1
  33. package/lib/module/index.js.map +1 -1
  34. package/lib/typescript/lib/commonjs/Offscreen.d.ts +1 -0
  35. package/lib/typescript/lib/commonjs/Offscreen.d.ts.map +1 -1
  36. package/lib/typescript/lib/commonjs/hooks.d.ts +12 -0
  37. package/lib/typescript/lib/commonjs/hooks.d.ts.map +1 -0
  38. package/lib/typescript/lib/commonjs/index.d.ts +1 -0
  39. package/lib/typescript/lib/commonjs/index.d.ts.map +1 -1
  40. package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
  41. package/lib/typescript/lib/module/Offscreen.d.ts +1 -0
  42. package/lib/typescript/lib/module/Offscreen.d.ts.map +1 -1
  43. package/lib/typescript/lib/module/hooks.d.ts +10 -0
  44. package/lib/typescript/lib/module/hooks.d.ts.map +1 -0
  45. package/lib/typescript/lib/module/index.d.ts +2 -1
  46. package/lib/typescript/lib/module/index.d.ts.map +1 -1
  47. package/lib/typescript/src/Canvas.d.ts +4 -2
  48. package/lib/typescript/src/Canvas.d.ts.map +1 -1
  49. package/lib/typescript/src/Offscreen.d.ts +16 -1
  50. package/lib/typescript/src/Offscreen.d.ts.map +1 -1
  51. package/lib/typescript/src/hooks.d.ts +13 -0
  52. package/lib/typescript/src/hooks.d.ts.map +1 -0
  53. package/lib/typescript/src/index.d.ts +2 -1
  54. package/lib/typescript/src/index.d.ts.map +1 -1
  55. package/package.json +1 -1
  56. package/src/Canvas.tsx +99 -35
  57. package/src/Offscreen.ts +6 -2
  58. package/src/hooks.ts +53 -0
  59. package/src/index.tsx +9 -1
  60. package/lib/commonjs/utils.js +0 -39
  61. package/lib/commonjs/utils.js.map +0 -1
  62. package/lib/module/utils.js +0 -31
  63. package/lib/module/utils.js.map +0 -1
  64. package/lib/typescript/lib/commonjs/utils.d.ts +0 -5
  65. package/lib/typescript/lib/commonjs/utils.d.ts.map +0 -1
  66. package/lib/typescript/lib/module/utils.d.ts +0 -3
  67. package/lib/typescript/lib/module/utils.d.ts.map +0 -1
  68. package/lib/typescript/src/utils.d.ts +0 -7
  69. package/lib/typescript/src/utils.d.ts.map +0 -1
  70. package/src/utils.ts +0 -42
@@ -27,52 +27,39 @@ extern "C" JNIEXPORT void JNICALL Java_com_webgpu_WebGPUModule_initializeNative(
27
27
  platformContext);
28
28
  }
29
29
 
30
- extern "C" JNIEXPORT void JNICALL
31
- Java_com_webgpu_WebGPUModule_createSurfaceContext(JNIEnv *env, jobject thiz,
32
- jlong jsRuntime,
33
- jint contextId) {
34
- auto canvas = manager->surfacesRegistry.getSurface(contextId);
35
- if (canvas == nullptr) {
36
- throw std::runtime_error("Surface haven't configured yet");
37
- }
38
-
39
- auto runtime = reinterpret_cast<facebook::jsi::Runtime *>(jsRuntime);
40
- auto webGPUContextRegistry = runtime->global().getPropertyAsObject(
41
- *runtime, "__WebGPUContextRegistry");
42
- if (webGPUContextRegistry.hasProperty(*runtime,
43
- std::to_string(contextId).c_str())) {
44
- // Context already exists, just update width/height
45
- auto prop =
46
- webGPUContextRegistry
47
- .getPropertyAsObject(*runtime, std::to_string(contextId).c_str())
48
- .asHostObject<rnwgpu::Canvas>(*runtime);
49
- prop->setWidth(canvas->getWidth());
50
- prop->setHeight(canvas->getHeight());
51
- return;
52
- }
53
- webGPUContextRegistry.setProperty(
54
- *runtime, std::to_string(contextId).c_str(),
55
- facebook::jsi::Object::createFromHostObject(*runtime, canvas));
56
- }
57
-
58
30
  extern "C" JNIEXPORT void JNICALL Java_com_webgpu_WebGPUView_onSurfaceChanged(
59
31
  JNIEnv *env, jobject thiz, jobject surface, jint contextId, jfloat width,
60
32
  jfloat height) {
61
- manager->surfacesRegistry.updateSurface(contextId, width, height);
33
+ auto &registry = rnwgpu::SurfaceRegistry::getInstance();
34
+ registry.getSurfaceInfo(contextId)->resize(static_cast<int>(width),
35
+ static_cast<int>(height));
62
36
  }
63
37
 
64
38
  extern "C" JNIEXPORT void JNICALL Java_com_webgpu_WebGPUView_onSurfaceCreate(
65
- JNIEnv *env, jobject thiz, jobject surface, jint contextId, jfloat width,
39
+ JNIEnv *env, jobject thiz, jobject jSurface, jint contextId, jfloat width,
66
40
  jfloat height) {
67
- auto window = ANativeWindow_fromSurface(env, surface);
41
+ auto window = ANativeWindow_fromSurface(env, jSurface);
68
42
  // ANativeWindow_acquire(window);
69
- manager->surfacesRegistry.addSurface(contextId, window, width, height);
43
+ auto &registry = rnwgpu::SurfaceRegistry::getInstance();
44
+ auto gpu = manager->_gpu;
45
+ auto surface = manager->_platformContext->makeSurface(
46
+ gpu, window, static_cast<int>(width), static_cast<int>(height));
47
+ registry
48
+ .getSurfaceInfoOrCreate(contextId, gpu, static_cast<int>(width),
49
+ static_cast<int>(height))
50
+ ->switchToOnscreen(window, surface);
51
+ }
52
+
53
+ extern "C" JNIEXPORT void JNICALL
54
+ Java_com_webgpu_WebGPUView_switchToOffscreenSurface(JNIEnv *env, jobject thiz,
55
+ jint contextId) {
56
+ auto &registry = rnwgpu::SurfaceRegistry::getInstance();
57
+ auto nativeSurface = registry.getSurfaceInfo(contextId)->switchToOffscreen();
58
+ ANativeWindow_release(reinterpret_cast<ANativeWindow *>(nativeSurface));
70
59
  }
71
60
 
72
61
  extern "C" JNIEXPORT void JNICALL Java_com_webgpu_WebGPUView_onSurfaceDestroy(
73
62
  JNIEnv *env, jobject thiz, jint contextId) {
74
- auto canvas = manager->surfacesRegistry.getSurface(contextId);
75
- ANativeWindow_release(
76
- reinterpret_cast<ANativeWindow *>(canvas->getSurface()));
77
- manager->surfacesRegistry.removeSurface(contextId);
63
+ auto &registry = rnwgpu::SurfaceRegistry::getInstance();
64
+ registry.removeSurfaceInfo(contextId);
78
65
  }
@@ -24,9 +24,6 @@ public class WebGPUModule extends NativeWebGPUModuleSpec {
24
24
  System.loadLibrary("react-native-wgpu"); // Load the C++ library
25
25
  }
26
26
 
27
- private final Object mContextLock = new Object();
28
- private final Set<Integer> mSurfaceContextsIds = new HashSet<>();
29
-
30
27
  public WebGPUModule(ReactApplicationContext reactContext) {
31
28
  super(reactContext);
32
29
  // Initialize the C++ module
@@ -50,38 +47,4 @@ public class WebGPUModule extends NativeWebGPUModuleSpec {
50
47
  @OptIn(markerClass = FrameworkAPI.class)
51
48
  @DoNotStrip
52
49
  private native void initializeNative(long jsRuntime, CallInvokerHolderImpl jsInvoker, BlobModule blobModule);
53
-
54
- @ReactMethod(isBlockingSynchronousMethod = true)
55
- public boolean createSurfaceContext(double contextId) {
56
- waitForNativeSurface((int)contextId);
57
-
58
- ReactApplicationContext context = getReactApplicationContext();
59
- JavaScriptContextHolder jsContext = context.getJavaScriptContextHolder();
60
- createSurfaceContext(jsContext.get(), (int)contextId);
61
- return true;
62
- }
63
-
64
- @DoNotStrip
65
- private native void createSurfaceContext(long jsRuntime, int contextId);
66
-
67
- private void waitForNativeSurface(Integer contextId) {
68
- synchronized (mContextLock) {
69
- while (!mSurfaceContextsIds.contains(contextId)) {
70
- try {
71
- mContextLock.wait();
72
- } catch (InterruptedException e) {
73
- Log.e("RNWebGPU", "Unable to create a context");
74
- return;
75
- }
76
- }
77
- }
78
- }
79
-
80
- protected void onSurfaceCreated(Integer contextId) {
81
- synchronized (mContextLock) {
82
- mSurfaceContextsIds.add(contextId);
83
- mContextLock.notifyAll();
84
- }
85
- }
86
-
87
50
  }
@@ -41,7 +41,6 @@ public class WebGPUView extends SurfaceView implements SurfaceHolder.Callback {
41
41
  float width = getWidth() / density;
42
42
  float height = getHeight() / density;
43
43
  onSurfaceCreate(holder.getSurface(), mContextId, width, height);
44
- mModule.onSurfaceCreated(mContextId);
45
44
  }
46
45
 
47
46
  @Override
@@ -53,10 +52,16 @@ public class WebGPUView extends SurfaceView implements SurfaceHolder.Callback {
53
52
  }
54
53
 
55
54
  @Override
56
- public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
55
+ protected void onDetachedFromWindow() {
56
+ super.onDetachedFromWindow();
57
57
  onSurfaceDestroy(mContextId);
58
58
  }
59
59
 
60
+ @Override
61
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
62
+ switchToOffscreenSurface(mContextId);
63
+ }
64
+
60
65
  @DoNotStrip
61
66
  private native void onSurfaceCreate(
62
67
  Surface surface,
@@ -76,4 +81,7 @@ public class WebGPUView extends SurfaceView implements SurfaceHolder.Callback {
76
81
 
77
82
  @DoNotStrip
78
83
  private native void onSurfaceDestroy(int contextId);
84
+
85
+ @DoNotStrip
86
+ private native void switchToOffscreenSurface(int contextId);
79
87
  }
@@ -21,6 +21,6 @@ public class WebGPUViewPackage implements ReactPackage {
21
21
 
22
22
  @Override
23
23
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
24
- return Arrays.asList(new WebGPUModule(reactContext));
24
+ return List.of(new WebGPUModule(reactContext));
25
25
  }
26
26
  }
@@ -24,6 +24,7 @@ RNWebGPUManager::RNWebGPUManager(
24
24
 
25
25
  auto gpu = std::make_shared<GPU>();
26
26
  auto rnWebGPU = std::make_shared<RNWebGPU>(gpu, _platformContext);
27
+ _gpu = gpu->get();
27
28
  _jsRuntime->global().setProperty(
28
29
  *_jsRuntime, "RNWebGPU",
29
30
  jsi::Object::createFromHostObject(*_jsRuntime, rnWebGPU));
@@ -27,11 +27,12 @@ public:
27
27
  std::shared_ptr<PlatformContext> platformContext);
28
28
  ~RNWebGPUManager();
29
29
 
30
- SurfaceRegistry surfacesRegistry;
31
-
32
30
  private:
33
31
  jsi::Runtime *_jsRuntime;
34
32
  std::shared_ptr<facebook::react::CallInvoker> _jsCallInvoker;
33
+
34
+ public:
35
+ wgpu::Instance _gpu;
35
36
  std::shared_ptr<PlatformContext> _platformContext;
36
37
  };
37
38
 
@@ -1,35 +1,217 @@
1
1
  #pragma once
2
2
 
3
3
  #include <memory>
4
+ #include <shared_mutex>
4
5
  #include <unordered_map>
5
6
 
6
7
  #include "webgpu/webgpu_cpp.h"
7
8
 
8
- #include "Canvas.h"
9
-
10
9
  namespace rnwgpu {
11
10
 
12
- class SurfaceRegistry {
13
- std::unordered_map<int, std::shared_ptr<Canvas>> _registry;
11
+ struct NativeInfo {
12
+ void *nativeSurface;
13
+ int width;
14
+ int height;
15
+ };
16
+
17
+ struct Size {
18
+ int width;
19
+ int height;
20
+ };
21
+
22
+ class SurfaceInfo {
23
+ public:
24
+ SurfaceInfo(wgpu::Instance gpu, int width, int height)
25
+ : gpu(gpu), width(width), height(height) {}
26
+
27
+ void reconfigure(int newWidth, int newHeight) {
28
+ std::unique_lock<std::shared_mutex> lock(_mutex);
29
+ config.width = newWidth;
30
+ config.height = newHeight;
31
+ _configure();
32
+ }
33
+
34
+ void configure(wgpu::SurfaceConfiguration &newConfig) {
35
+ std::unique_lock<std::shared_mutex> lock(_mutex);
36
+ config = newConfig;
37
+ config.width = width;
38
+ config.height = height;
39
+ _configure();
40
+ }
41
+
42
+ void unconfigure() {
43
+ std::unique_lock<std::shared_mutex> lock(_mutex);
44
+ if (surface) {
45
+ surface.Unconfigure();
46
+ } else {
47
+ texture = nullptr;
48
+ }
49
+ }
50
+
51
+ void *switchToOffscreen() {
52
+ std::unique_lock<std::shared_mutex> lock(_mutex);
53
+ wgpu::TextureDescriptor textureDesc;
54
+ textureDesc.usage = wgpu::TextureUsage::RenderAttachment |
55
+ wgpu::TextureUsage::CopySrc |
56
+ wgpu::TextureUsage::TextureBinding;
57
+ textureDesc.format = config.format;
58
+ textureDesc.size.width = config.width;
59
+ textureDesc.size.height = config.height;
60
+ texture = config.device.CreateTexture(&textureDesc);
61
+ surface = nullptr;
62
+ return nativeSurface;
63
+ }
64
+
65
+ void switchToOnscreen(void *newNativeSurface, wgpu::Surface newSurface) {
66
+ std::unique_lock<std::shared_mutex> lock(_mutex);
67
+ nativeSurface = newNativeSurface;
68
+ surface = std::move(newSurface);
69
+ // If we are comming from an offscreen context, we need to configure the new
70
+ // surface
71
+ if (texture != nullptr) {
72
+ config.usage = config.usage | wgpu::TextureUsage::CopyDst;
73
+ _configure();
74
+ // We flush the offscreen texture to the onscreen one
75
+ // TODO: there is a faster way to do this without validation?
76
+ wgpu::CommandEncoderDescriptor encoderDesc;
77
+ auto device = config.device;
78
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder(&encoderDesc);
79
+
80
+ wgpu::ImageCopyTexture sourceTexture = {};
81
+ sourceTexture.texture = texture;
82
+
83
+ wgpu::ImageCopyTexture destinationTexture = {};
84
+ wgpu::SurfaceTexture surfaceTexture;
85
+ surface.GetCurrentTexture(&surfaceTexture);
86
+ destinationTexture.texture = surfaceTexture.texture;
87
+
88
+ wgpu::Extent3D size = {sourceTexture.texture.GetWidth(),
89
+ sourceTexture.texture.GetHeight(),
90
+ sourceTexture.texture.GetDepthOrArrayLayers()};
91
+
92
+ encoder.CopyTextureToTexture(&sourceTexture, &destinationTexture, &size);
93
+
94
+ wgpu::CommandBuffer commands = encoder.Finish();
95
+ wgpu::Queue queue = device.GetQueue();
96
+ queue.Submit(1, &commands);
97
+ surface.Present();
98
+ texture = nullptr;
99
+ }
100
+ }
101
+
102
+ void resize(int newWidth, int newHeight) {
103
+ std::unique_lock<std::shared_mutex> lock(_mutex);
104
+ width = newWidth;
105
+ height = newHeight;
106
+ }
107
+
108
+ void present() {
109
+ std::unique_lock<std::shared_mutex> lock(_mutex);
110
+ if (surface) {
111
+ surface.Present();
112
+ }
113
+ }
114
+
115
+ wgpu::Texture getCurrentTexture() {
116
+ std::shared_lock<std::shared_mutex> lock(_mutex);
117
+ if (surface) {
118
+ wgpu::SurfaceTexture surfaceTexture;
119
+ surface.GetCurrentTexture(&surfaceTexture);
120
+ return surfaceTexture.texture;
121
+ } else {
122
+ return texture;
123
+ }
124
+ }
125
+
126
+ NativeInfo getNativeInfo() {
127
+ std::shared_lock<std::shared_mutex> lock(_mutex);
128
+ return {.nativeSurface = nativeSurface, .width = width, .height = height};
129
+ }
130
+
131
+ Size getSize() {
132
+ std::shared_lock<std::shared_mutex> lock(_mutex);
133
+ return {.width = width, .height = height};
134
+ }
135
+
136
+ wgpu::Device getDevice() {
137
+ std::shared_lock<std::shared_mutex> lock(_mutex);
138
+ return config.device;
139
+ }
14
140
 
141
+ private:
142
+ void _configure() {
143
+ if (surface) {
144
+ surface.Configure(&config);
145
+ } else {
146
+ wgpu::TextureDescriptor textureDesc;
147
+ textureDesc.format = config.format;
148
+ textureDesc.size.width = config.width;
149
+ textureDesc.size.height = config.height;
150
+ textureDesc.usage = wgpu::TextureUsage::RenderAttachment |
151
+ wgpu::TextureUsage::CopySrc |
152
+ wgpu::TextureUsage::TextureBinding;
153
+ texture = config.device.CreateTexture(&textureDesc);
154
+ }
155
+ }
156
+
157
+ mutable std::shared_mutex _mutex;
158
+ void *nativeSurface = nullptr;
159
+ wgpu::Surface surface = nullptr;
160
+ wgpu::Texture texture = nullptr;
161
+ wgpu::Instance gpu;
162
+ wgpu::SurfaceConfiguration config;
163
+ int width;
164
+ int height;
165
+ };
166
+
167
+ class SurfaceRegistry {
15
168
  public:
16
- void addSurface(const int contextId, void *surface, float width,
17
- float height) {
18
- _registry[contextId] = std::make_shared<Canvas>(surface, width, height);
169
+ static SurfaceRegistry &getInstance() {
170
+ static SurfaceRegistry instance;
171
+ return instance;
19
172
  }
20
173
 
21
- std::shared_ptr<Canvas> getSurface(const int contextId) {
22
- return _registry[contextId];
174
+ SurfaceRegistry(const SurfaceRegistry &) = delete;
175
+ SurfaceRegistry &operator=(const SurfaceRegistry &) = delete;
176
+
177
+ std::shared_ptr<SurfaceInfo> getSurfaceInfo(int id) {
178
+ std::shared_lock<std::shared_mutex> lock(_mutex);
179
+ auto it = _registry.find(id);
180
+ if (it != _registry.end()) {
181
+ return it->second;
182
+ }
183
+ return nullptr;
184
+ }
185
+
186
+ void removeSurfaceInfo(int id) {
187
+ std::unique_lock<std::shared_mutex> lock(_mutex);
188
+ _registry.erase(id);
23
189
  }
24
190
 
25
- void removeSurface(const int contextId) { _registry.erase(contextId); }
191
+ std::shared_ptr<SurfaceInfo> addSurfaceInfo(int id, wgpu::Instance gpu,
192
+ int width, int height) {
193
+ std::unique_lock<std::shared_mutex> lock(_mutex);
194
+ auto info = std::make_shared<SurfaceInfo>(gpu, width, height);
195
+ _registry[id] = info;
196
+ return info;
197
+ }
26
198
 
27
- void updateSurface(const int contextId, float width, float height) {
28
- if (_registry.find(contextId) != _registry.end()) {
29
- _registry[contextId]->setClientWidth(width);
30
- _registry[contextId]->setClientHeight(height);
199
+ std::shared_ptr<SurfaceInfo>
200
+ getSurfaceInfoOrCreate(int id, wgpu::Instance gpu, int width, int height) {
201
+ std::unique_lock<std::shared_mutex> lock(_mutex);
202
+ auto it = _registry.find(id);
203
+ if (it != _registry.end()) {
204
+ return it->second;
31
205
  }
206
+ auto info = std::make_shared<SurfaceInfo>(gpu, width, height);
207
+ _registry[id] = info;
208
+ return info;
32
209
  }
210
+
211
+ private:
212
+ SurfaceRegistry() = default;
213
+ mutable std::shared_mutex _mutex;
214
+ std::unordered_map<int, std::shared_ptr<SurfaceInfo>> _registry;
33
215
  };
34
216
 
35
217
  } // namespace rnwgpu
@@ -15,24 +15,24 @@ namespace m = margelo;
15
15
 
16
16
  class Canvas : public m::HybridObject {
17
17
  public:
18
- explicit Canvas(void* surface, const float width, const float height)
18
+ explicit Canvas(void *surface, const int width, const int height)
19
19
  : HybridObject("Canvas"), _surface(surface), _width(width),
20
20
  _height(height), _clientWidth(width), _clientHeight(height) {}
21
21
 
22
- float getWidth() { return _width; }
23
- float getHeight() { return _height; }
22
+ int getWidth() { return _width; }
23
+ int getHeight() { return _height; }
24
24
 
25
- void setWidth(const float width) { _width = width; }
26
- void setHeight(const float height) { _height = height; }
25
+ void setWidth(const int width) { _width = width; }
26
+ void setHeight(const int height) { _height = height; }
27
27
 
28
- float getClientWidth() { return _clientWidth; }
29
- float getClientHeight() { return _clientHeight; }
28
+ int getClientWidth() { return _clientWidth; }
29
+ int getClientHeight() { return _clientHeight; }
30
30
 
31
- void setClientWidth(const float width) { _clientWidth = width; }
31
+ void setClientWidth(const int width) { _clientWidth = width; }
32
32
 
33
- void setClientHeight(const float height) { _clientHeight = height; }
33
+ void setClientHeight(const int height) { _clientHeight = height; }
34
34
 
35
- void* getSurface() { return _surface; }
35
+ void *getSurface() { return _surface; }
36
36
 
37
37
  void loadHybridMethods() override {
38
38
  registerHybridGetter("surface", &Canvas::getSurface, this);
@@ -45,11 +45,11 @@ public:
45
45
  }
46
46
 
47
47
  private:
48
- void* _surface;
49
- float _width;
50
- float _height;
51
- float _clientWidth;
52
- float _clientHeight;
48
+ void *_surface;
49
+ int _width;
50
+ int _height;
51
+ int _clientWidth;
52
+ int _clientHeight;
53
53
  };
54
54
 
55
55
  } // namespace rnwgpu
@@ -9,7 +9,6 @@ void GPUCanvasContext::configure(
9
9
  Convertor conv;
10
10
  wgpu::SurfaceConfiguration surfaceConfiguration;
11
11
  surfaceConfiguration.device = configuration->device->get();
12
- _device = configuration->device->get();
13
12
  if (configuration->viewFormats.has_value()) {
14
13
  if (!conv(surfaceConfiguration.viewFormats,
15
14
  surfaceConfiguration.viewFormatCount,
@@ -23,41 +22,32 @@ void GPUCanvasContext::configure(
23
22
  if (!conv(surfaceConfiguration.usage, configuration->usage)) {
24
23
  throw std::runtime_error("Error with SurfaceConfiguration");
25
24
  }
26
- surfaceConfiguration.width = _canvas->getWidth();
27
- surfaceConfiguration.height = _canvas->getHeight();
28
- _instance.Configure(&surfaceConfiguration);
29
- _lastConfig = configuration;
30
- _width = _canvas->getWidth();
31
- _height = _canvas->getHeight();
25
+ _surfaceInfo->configure(surfaceConfiguration);
32
26
  }
33
27
 
34
- void GPUCanvasContext::unconfigure() {
35
- _lastConfig = nullptr;
36
- _width = _canvas->getWidth();
37
- _height = _canvas->getHeight();
38
- _instance.Unconfigure();
39
- }
28
+ void GPUCanvasContext::unconfigure() {}
40
29
 
41
30
  std::shared_ptr<GPUTexture> GPUCanvasContext::getCurrentTexture() {
42
- // we need to reconfigure if the size of the canvas has changed
43
- if (_width != _canvas->getWidth() || _height != _canvas->getHeight()) {
44
- configure(_lastConfig);
45
- }
46
- wgpu::SurfaceTexture surfaceTexture;
47
- _instance.GetCurrentTexture(&surfaceTexture);
48
- auto texture = surfaceTexture.texture;
49
- if (texture == nullptr) {
50
- throw std::runtime_error("Couldn't get current texture");
31
+ auto prevSize = _surfaceInfo->getSize();
32
+ auto width = _canvas->getWidth();
33
+ auto height = _canvas->getHeight();
34
+ auto sizeHasChanged = prevSize.width != width || prevSize.height != height;
35
+ if (sizeHasChanged) {
36
+ _surfaceInfo->reconfigure(width, height);
51
37
  }
52
- // Default canvas texture label is ""
38
+ auto texture = _surfaceInfo->getCurrentTexture();
53
39
  return std::make_shared<GPUTexture>(texture, "");
54
40
  }
55
41
 
56
42
  void GPUCanvasContext::present() {
57
43
  #ifdef __APPLE__
58
- dawn::native::metal::WaitForCommandsToBeScheduled(_device.Get());
44
+ dawn::native::metal::WaitForCommandsToBeScheduled(
45
+ _surfaceInfo->getDevice().Get());
59
46
  #endif
60
- _instance.Present();
47
+ auto size = _surfaceInfo->getSize();
48
+ _canvas->setClientWidth(size.width);
49
+ _canvas->setClientHeight(size.height);
50
+ _surfaceInfo->present();
61
51
  }
62
52
 
63
53
  } // namespace rnwgpu
@@ -12,6 +12,7 @@
12
12
  #include "AsyncRunner.h"
13
13
 
14
14
  #include "Canvas.h"
15
+ #include "GPU.h"
15
16
  #include "GPUCanvasConfiguration.h"
16
17
  #include "GPUTexture.h"
17
18
  #include "SurfaceRegistry.h"
@@ -38,9 +39,13 @@ namespace m = margelo;
38
39
 
39
40
  class GPUCanvasContext : public m::HybridObject {
40
41
  public:
41
- explicit GPUCanvasContext(wgpu::Surface instance,
42
- std::shared_ptr<Canvas> canvas)
43
- : HybridObject("GPUCanvasContext"), _instance(instance), _canvas(canvas) {
42
+ GPUCanvasContext(std::shared_ptr<GPU> gpu, int contextId, int width,
43
+ int height)
44
+ : HybridObject("GPUCanvasContext"), _gpu(std::move(gpu)) {
45
+ _canvas = std::make_shared<Canvas>(nullptr, width, height);
46
+ auto &registry = rnwgpu::SurfaceRegistry::getInstance();
47
+ _surfaceInfo =
48
+ registry.getSurfaceInfoOrCreate(contextId, _gpu->get(), width, height);
44
49
  }
45
50
 
46
51
  public:
@@ -58,19 +63,17 @@ public:
58
63
  registerHybridMethod("present", &GPUCanvasContext::present, this);
59
64
  }
60
65
 
61
- inline const wgpu::Surface get() { return _instance; }
66
+ // TODO: is this ok?
67
+ inline const wgpu::Surface get() { return nullptr; }
62
68
  void configure(std::shared_ptr<GPUCanvasConfiguration> configuration);
63
69
  void unconfigure();
64
70
  std::shared_ptr<GPUTexture> getCurrentTexture();
65
71
  void present();
66
72
 
67
73
  private:
68
- wgpu::Surface _instance;
69
- wgpu::Device _device;
70
74
  std::shared_ptr<Canvas> _canvas;
71
- std::shared_ptr<GPUCanvasConfiguration> _lastConfig;
72
- float _width;
73
- float _height;
75
+ std::shared_ptr<SurfaceInfo> _surfaceInfo;
76
+ std::shared_ptr<GPU> _gpu;
74
77
  };
75
78
 
76
79
  } // namespace rnwgpu
@@ -70,8 +70,9 @@ std::shared_ptr<GPUShaderModule> GPUDevice::createShaderModule(
70
70
  wgpu::ShaderModuleWGSLDescriptor wgsl_desc{};
71
71
  wgpu::ShaderModuleDescriptor sm_desc{};
72
72
  Convertor conv;
73
- if (!conv(wgsl_desc.code, descriptor->code) || !conv(sm_desc.label, descriptor->label)) {
74
- return {};
73
+ if (!conv(wgsl_desc.code, descriptor->code) ||
74
+ !conv(sm_desc.label, descriptor->label)) {
75
+ return {};
75
76
  }
76
77
  sm_desc.nextInChain = &wgsl_desc;
77
78
  if (descriptor->code.find('\0') != std::string::npos) {
@@ -3,6 +3,7 @@
3
3
  #include <memory>
4
4
  #include <string>
5
5
 
6
+ #include "Canvas.h"
6
7
  #include "GPU.h"
7
8
  #include "GPUCanvasContext.h"
8
9
  #include "ImageBitmap.h"
@@ -29,17 +30,18 @@ public:
29
30
 
30
31
  std::shared_ptr<GPU> getGPU() { return _gpu; }
31
32
 
33
+ bool getFabric() {
34
+ #ifdef RCT_NEW_ARCH_ENABLED
35
+ return true;
36
+ #else
37
+ return false;
38
+ #endif
39
+ }
40
+
32
41
  std::shared_ptr<GPUCanvasContext>
33
- MakeWebGPUCanvasContext(std::shared_ptr<Canvas> canvas) {
34
- auto nativeSurface = canvas->getSurface();
35
- auto width = canvas->getWidth();
36
- auto height = canvas->getHeight();
37
- auto surface = _platformContext->makeSurface(
38
- _gpu->get(), reinterpret_cast<void *>(nativeSurface), width, height);
39
- if (surface == nullptr) {
40
- throw std::runtime_error("null surface");
41
- }
42
- auto ctx = std::make_shared<GPUCanvasContext>(surface, canvas);
42
+ MakeWebGPUCanvasContext(int contextId, float width, float height) {
43
+ auto ctx =
44
+ std::make_shared<GPUCanvasContext>(_gpu, contextId, width, height);
43
45
  return ctx;
44
46
  }
45
47
 
@@ -50,10 +52,23 @@ public:
50
52
  return imageBitmap;
51
53
  }
52
54
 
55
+ std::shared_ptr<Canvas> getNativeSurface(int contextId) {
56
+ auto &registry = rnwgpu::SurfaceRegistry::getInstance();
57
+ auto info = registry.getSurfaceInfo(contextId);
58
+ if (info == nullptr) {
59
+ return std::make_shared<Canvas>(nullptr, 0, 0);
60
+ }
61
+ auto nativeInfo = info->getNativeInfo();
62
+ return std::make_shared<Canvas>(nativeInfo.nativeSurface, nativeInfo.width,
63
+ nativeInfo.height);
64
+ }
65
+
53
66
  void loadHybridMethods() override {
67
+ registerHybridGetter("fabric", &RNWebGPU::getFabric, this);
54
68
  registerHybridGetter("gpu", &RNWebGPU::getGPU, this);
55
69
  registerHybridMethod("createImageBitmap", &RNWebGPU::createImageBitmap,
56
70
  this);
71
+ registerHybridMethod("getNativeSurface", &RNWebGPU::getNativeSurface, this);
57
72
  registerHybridMethod("MakeWebGPUCanvasContext",
58
73
  &RNWebGPU::MakeWebGPUCanvasContext, this);
59
74
  }