react-native-webgpu 0.6.0 → 0.6.1

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 (43) hide show
  1. package/android/cpp/cpp-adapter.cpp +35 -13
  2. package/android/src/main/java/com/webgpu/WebGPUAHBView.java +2 -2
  3. package/android/src/main/java/com/webgpu/WebGPUAPI.java +7 -2
  4. package/android/src/main/java/com/webgpu/WebGPUSurfaceView.java +3 -1
  5. package/android/src/main/java/com/webgpu/WebGPUTextureView.java +11 -7
  6. package/android/src/main/java/com/webgpu/WebGPUView.java +10 -7
  7. package/android/src/main/java/com/webgpu/WebGPUViewManager.java +6 -0
  8. package/apple/MetalView.mm +33 -8
  9. package/cpp/rnwgpu/RNWebGPUManager.cpp +14 -1
  10. package/cpp/rnwgpu/RNWebGPUManager.h +9 -0
  11. package/cpp/rnwgpu/SurfaceRegistry.h +469 -131
  12. package/cpp/rnwgpu/api/GPUAdapter.cpp +10 -3
  13. package/cpp/rnwgpu/api/GPUAdapter.h +5 -4
  14. package/cpp/rnwgpu/api/GPUBuffer.cpp +12 -2
  15. package/cpp/rnwgpu/api/GPUBuffer.h +3 -2
  16. package/cpp/rnwgpu/api/GPUCanvasContext.cpp +33 -19
  17. package/cpp/rnwgpu/api/GPUCanvasContext.h +3 -1
  18. package/cpp/rnwgpu/api/GPUDevice.cpp +32 -17
  19. package/cpp/rnwgpu/api/GPUDevice.h +9 -7
  20. package/cpp/rnwgpu/api/GPUQueue.cpp +6 -2
  21. package/cpp/rnwgpu/api/GPUQueue.h +3 -3
  22. package/cpp/rnwgpu/api/GPUShaderModule.cpp +7 -2
  23. package/cpp/rnwgpu/api/GPUShaderModule.h +3 -3
  24. package/cpp/rnwgpu/api/RNWebGPU.h +22 -1
  25. package/cpp/rnwgpu/async/RuntimeContext.h +9 -2
  26. package/lib/commonjs/Canvas.js +10 -0
  27. package/lib/commonjs/Canvas.js.map +1 -1
  28. package/lib/commonjs/WebPolyfillGPUModule.js +2 -0
  29. package/lib/commonjs/WebPolyfillGPUModule.js.map +1 -1
  30. package/lib/module/Canvas.js +11 -1
  31. package/lib/module/Canvas.js.map +1 -1
  32. package/lib/module/WebPolyfillGPUModule.js +2 -0
  33. package/lib/module/WebPolyfillGPUModule.js.map +1 -1
  34. package/lib/typescript/lib/commonjs/Canvas.d.ts.map +1 -1
  35. package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
  36. package/lib/typescript/src/Canvas.d.ts.map +1 -1
  37. package/lib/typescript/src/index.d.ts +1 -0
  38. package/lib/typescript/src/index.d.ts.map +1 -1
  39. package/package.json +2 -6
  40. package/src/Canvas.tsx +11 -1
  41. package/src/WebPolyfillGPUModule.ts +2 -0
  42. package/src/index.tsx +3 -0
  43. package/android/src/main/java/com/webgpu/WebGPUBaseView.java +0 -61
@@ -23,6 +23,7 @@
23
23
  namespace rnwgpu {
24
24
 
25
25
  async::AsyncTaskHandle GPUAdapter::requestDevice(
26
+ jsi::Runtime &runtime,
26
27
  std::optional<std::shared_ptr<GPUDeviceDescriptor>> descriptor) {
27
28
  // Enable the react-native-wgpu "native-texture" umbrella by default, mirroring
28
29
  // the web where importExternalTexture is core and needs no feature request.
@@ -135,9 +136,15 @@ async::AsyncTaskHandle GPUAdapter::requestDevice(
135
136
  descriptor.has_value() ? descriptor.value()->label.value_or("") : "";
136
137
 
137
138
  auto creationRuntime = getCreationRuntime();
138
- return _async->postTask(
139
+ // Post to the CALLING runtime's context so the promise settles on the
140
+ // thread that requested it (see GPUBuffer::mapAsync). The GPUDevice is also
141
+ // bound to this context, honoring the contract that a device belongs to the
142
+ // runtime that requested it.
143
+ auto context =
144
+ async::RuntimeContext::getOrCreate(runtime, _async->instance());
145
+ return context->postTask(
139
146
  [this, aDescriptor, descriptor, label = std::move(label),
140
- deviceLostBinding,
147
+ deviceLostBinding, context,
141
148
  creationRuntime](const async::AsyncTaskHandle::ResolveFunction &resolve,
142
149
  const async::AsyncTaskHandle::RejectFunction &reject) {
143
150
  // Build a local mutable copy so we can chain Dawn's device toggles.
@@ -193,7 +200,7 @@ async::AsyncTaskHandle GPUAdapter::requestDevice(
193
200
  }
194
201
  _instance.RequestDevice(
195
202
  &deviceDesc, wgpu::CallbackMode::AllowProcessEvents,
196
- [context = _async, resolve, reject, label, creationRuntime,
203
+ [context, resolve, reject, label, creationRuntime,
197
204
  deviceLostBinding](wgpu::RequestDeviceStatus status,
198
205
  wgpu::Device device, wgpu::StringView message) {
199
206
  if (message.length) {
@@ -33,8 +33,9 @@ public:
33
33
  public:
34
34
  std::string getBrand() { return CLASS_NAME; }
35
35
 
36
- async::AsyncTaskHandle
37
- requestDevice(std::optional<std::shared_ptr<GPUDeviceDescriptor>> descriptor);
36
+ async::AsyncTaskHandle requestDevice(
37
+ jsi::Runtime &runtime,
38
+ std::optional<std::shared_ptr<GPUDeviceDescriptor>> descriptor);
38
39
 
39
40
  std::unordered_set<std::string> getFeatures();
40
41
  std::shared_ptr<GPUSupportedLimits> getLimits();
@@ -42,8 +43,8 @@ public:
42
43
 
43
44
  static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {
44
45
  installGetter(runtime, prototype, "__brand", &GPUAdapter::getBrand);
45
- installMethod(runtime, prototype, "requestDevice",
46
- &GPUAdapter::requestDevice);
46
+ installMethodWithRuntime(runtime, prototype, "requestDevice",
47
+ &GPUAdapter::requestDevice);
47
48
  installGetter(runtime, prototype, "features", &GPUAdapter::getFeatures);
48
49
  installGetter(runtime, prototype, "limits", &GPUAdapter::getLimits);
49
50
  installGetter(runtime, prototype, "info", &GPUAdapter::getInfo);
@@ -37,7 +37,8 @@ GPUBuffer::getMappedRange(std::optional<size_t> o, std::optional<size_t> size) {
37
37
 
38
38
  void GPUBuffer::destroy() { _instance.Destroy(); }
39
39
 
40
- async::AsyncTaskHandle GPUBuffer::mapAsync(uint64_t modeIn,
40
+ async::AsyncTaskHandle GPUBuffer::mapAsync(jsi::Runtime &runtime,
41
+ uint64_t modeIn,
41
42
  std::optional<uint64_t> offset,
42
43
  std::optional<uint64_t> size) {
43
44
  Convertor conv;
@@ -51,7 +52,16 @@ async::AsyncTaskHandle GPUBuffer::mapAsync(uint64_t modeIn,
51
52
  auto bufferHandle = _instance;
52
53
  uint64_t resolvedOffset = offset.value_or(0);
53
54
 
54
- return _async->postTask(
55
+ // Post to the CALLING runtime's context, not the one captured at buffer
56
+ // creation (_async): the buffer may have been created on another runtime and
57
+ // boxed across (e.g. device created on the main JS runtime, mapAsync called
58
+ // from a worklet). The returned Promise lives on the calling runtime, so it
59
+ // must be settled from that runtime's own thread — and postTask itself
60
+ // schedules the pump through its context's runtime (setTimeout), which is
61
+ // only safe for the runtime we are currently executing on.
62
+ auto context =
63
+ async::RuntimeContext::getOrCreate(runtime, _async->instance());
64
+ return context->postTask(
55
65
  [bufferHandle, mode, resolvedOffset,
56
66
  rangeSize](const async::AsyncTaskHandle::ResolveFunction &resolve,
57
67
  const async::AsyncTaskHandle::RejectFunction &reject) {
@@ -33,7 +33,7 @@ public:
33
33
  public:
34
34
  std::string getBrand() { return CLASS_NAME; }
35
35
 
36
- async::AsyncTaskHandle mapAsync(uint64_t modeIn,
36
+ async::AsyncTaskHandle mapAsync(jsi::Runtime &runtime, uint64_t modeIn,
37
37
  std::optional<uint64_t> offset,
38
38
  std::optional<uint64_t> size);
39
39
  std::shared_ptr<ArrayBuffer> getMappedRange(std::optional<size_t> offset,
@@ -53,7 +53,8 @@ public:
53
53
 
54
54
  static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {
55
55
  installGetter(runtime, prototype, "__brand", &GPUBuffer::getBrand);
56
- installMethod(runtime, prototype, "mapAsync", &GPUBuffer::mapAsync);
56
+ installMethodWithRuntime(runtime, prototype, "mapAsync",
57
+ &GPUBuffer::mapAsync);
57
58
  installMethod(runtime, prototype, "getMappedRange",
58
59
  &GPUBuffer::getMappedRange);
59
60
  installMethod(runtime, prototype, "unmap", &GPUBuffer::unmap);
@@ -1,7 +1,10 @@
1
1
  #include "GPUCanvasContext.h"
2
2
  #include "Convertors.h"
3
3
  #include "RNWebGPUManager.h"
4
+ #include <algorithm>
4
5
  #include <memory>
6
+ #include <utility>
7
+ #include <vector>
5
8
 
6
9
  namespace rnwgpu {
7
10
 
@@ -10,37 +13,50 @@ void GPUCanvasContext::configure(
10
13
  Convertor conv;
11
14
  wgpu::SurfaceConfiguration surfaceConfiguration;
12
15
  surfaceConfiguration.device = configuration->device->get();
13
- if (configuration->viewFormats.has_value()) {
14
- if (!conv(surfaceConfiguration.viewFormats,
15
- surfaceConfiguration.viewFormatCount,
16
- configuration->viewFormats.value())) {
17
- throw std::runtime_error("Error with SurfaceConfiguration");
18
- }
19
- }
20
16
  if (!conv(surfaceConfiguration.usage, configuration->usage) ||
21
17
  !conv(surfaceConfiguration.format, configuration->format)) {
22
18
  throw std::runtime_error("Error with SurfaceConfiguration");
23
19
  }
20
+ // viewFormats are deep-copied into SurfaceInfo (which outlives this call);
21
+ // Convertor-allocated arrays would dangle.
22
+ std::vector<wgpu::TextureFormat> viewFormats;
23
+ if (configuration->viewFormats.has_value()) {
24
+ viewFormats = configuration->viewFormats.value();
25
+ }
24
26
 
25
27
  #ifdef __APPLE__
26
28
  surfaceConfiguration.alphaMode = configuration->alphaMode;
27
29
  #endif
28
30
  surfaceConfiguration.presentMode = wgpu::PresentMode::Fifo;
29
- _surfaceInfo->configure(surfaceConfiguration);
31
+ _surfaceInfo->configure(surfaceConfiguration, std::move(viewFormats));
30
32
  }
31
33
 
32
- void GPUCanvasContext::unconfigure() {}
34
+ void GPUCanvasContext::unconfigure() { _surfaceInfo->unconfigure(); }
33
35
 
34
36
  std::shared_ptr<GPUTexture> GPUCanvasContext::getCurrentTexture() {
37
+ if (!_surfaceInfo->isConfigured()) {
38
+ // Web parity: on the web this is an InvalidStateError, not a crash.
39
+ throw std::runtime_error(
40
+ "[WebGPU] getCurrentTexture() called on a canvas context that is not "
41
+ "configured; call context.configure() first");
42
+ }
43
+ // The drawing buffer tracks canvas.width/height (like on the web); resize it
44
+ // lazily when they changed. Sizes are clamped to 1 so a canvas that has not
45
+ // been laid out yet (0x0) keeps working.
35
46
  auto prevSize = _surfaceInfo->getConfig();
36
- auto width = _canvas->getWidth();
37
- auto height = _canvas->getHeight();
38
- auto sizeHasChanged = prevSize.width != width || prevSize.height != height;
47
+ auto width = std::max(1, _canvas->getWidth());
48
+ auto height = std::max(1, _canvas->getHeight());
49
+ auto sizeHasChanged = prevSize.width != static_cast<uint32_t>(width) ||
50
+ prevSize.height != static_cast<uint32_t>(height);
39
51
  if (sizeHasChanged) {
40
52
  _surfaceInfo->reconfigure(width, height);
41
53
  }
42
54
 
43
55
  auto texture = _surfaceInfo->getCurrentTexture();
56
+ if (texture == nullptr) {
57
+ throw std::runtime_error(
58
+ "[WebGPU] getCurrentTexture() failed to acquire a texture");
59
+ }
44
60
 
45
61
  auto size = _surfaceInfo->getSize();
46
62
  _canvas->setClientWidth(size.width);
@@ -52,13 +68,11 @@ std::shared_ptr<GPUTexture> GPUCanvasContext::getCurrentTexture() {
52
68
  }
53
69
 
54
70
  void GPUCanvasContext::present() {
55
- // Present runs synchronously on the calling thread (the one that did
56
- // getCurrentTexture / submit), preserving Dawn surface thread-affinity.
57
- // Required on every runtime (main JS, Reanimated UI, dedicated worklet);
58
- // offscreen surfaces have no wgpu::Surface so they no-op.
59
- if (_surfaceInfo->hasSurface()) {
60
- _surfaceInfo->presentFrame();
61
- }
71
+ // presentFrame() is the end-of-frame boundary: it presents when this frame's
72
+ // texture was acquired from the on-screen surface (offscreen and dropped
73
+ // frames are skipped), clears the frame state, and adopts any surface that
74
+ // attached while the frame was in flight.
75
+ _surfaceInfo->presentFrame();
62
76
  }
63
77
 
64
78
  } // namespace rnwgpu
@@ -57,7 +57,9 @@ public:
57
57
  std::shared_ptr<GPUTexture> getCurrentTexture();
58
58
  // Present is explicit on every runtime (main JS, Reanimated UI, and dedicated
59
59
  // worklet runtimes). It runs synchronously on the calling thread, preserving
60
- // Dawn surface thread-affinity; offscreen surfaces no-op.
60
+ // Dawn surface thread-affinity; frames rendered offscreen (no surface
61
+ // attached) are skipped. It is also the end-of-frame boundary at which a
62
+ // newly attached native surface is adopted (see SurfaceInfo).
61
63
  void present();
62
64
 
63
65
  private:
@@ -348,6 +348,7 @@ std::shared_ptr<GPUSharedFence> GPUDevice::importSharedFence(
348
348
  }
349
349
 
350
350
  async::AsyncTaskHandle GPUDevice::createComputePipelineAsync(
351
+ jsi::Runtime &runtime,
351
352
  std::shared_ptr<GPUComputePipelineDescriptor> descriptor) {
352
353
  wgpu::ComputePipelineDescriptor desc{};
353
354
  Convertor conv;
@@ -360,12 +361,16 @@ async::AsyncTaskHandle GPUDevice::createComputePipelineAsync(
360
361
  descriptor->label.has_value() ? descriptor->label.value() : "");
361
362
  auto pipelineHolder = std::make_shared<GPUComputePipeline>(nullptr, label);
362
363
 
363
- return _async->postTask([device = _instance, desc, descriptor,
364
- pipelineHolder](
365
- const async::AsyncTaskHandle::ResolveFunction
366
- &resolve,
367
- const async::AsyncTaskHandle::RejectFunction
368
- &reject) {
364
+ // Post to the CALLING runtime's context so the promise settles on the
365
+ // thread that requested it (see GPUBuffer::mapAsync).
366
+ auto context =
367
+ async::RuntimeContext::getOrCreate(runtime, _async->instance());
368
+ return context->postTask([device = _instance, desc, descriptor,
369
+ pipelineHolder](
370
+ const async::AsyncTaskHandle::ResolveFunction
371
+ &resolve,
372
+ const async::AsyncTaskHandle::RejectFunction
373
+ &reject) {
369
374
  (void)descriptor;
370
375
  device.CreateComputePipelineAsync(
371
376
  &desc, wgpu::CallbackMode::AllowProcessEvents,
@@ -389,6 +394,7 @@ async::AsyncTaskHandle GPUDevice::createComputePipelineAsync(
389
394
  }
390
395
 
391
396
  async::AsyncTaskHandle GPUDevice::createRenderPipelineAsync(
397
+ jsi::Runtime &runtime,
392
398
  std::shared_ptr<GPURenderPipelineDescriptor> descriptor) {
393
399
  wgpu::RenderPipelineDescriptor desc{};
394
400
  Convertor conv;
@@ -402,12 +408,16 @@ async::AsyncTaskHandle GPUDevice::createRenderPipelineAsync(
402
408
  descriptor->label.has_value() ? descriptor->label.value() : "");
403
409
  auto pipelineHolder = std::make_shared<GPURenderPipeline>(nullptr, label);
404
410
 
405
- return _async->postTask([device = _instance, desc, descriptor,
406
- pipelineHolder](
407
- const async::AsyncTaskHandle::ResolveFunction
408
- &resolve,
409
- const async::AsyncTaskHandle::RejectFunction
410
- &reject) {
411
+ // Post to the CALLING runtime's context so the promise settles on the
412
+ // thread that requested it (see GPUBuffer::mapAsync).
413
+ auto context =
414
+ async::RuntimeContext::getOrCreate(runtime, _async->instance());
415
+ return context->postTask([device = _instance, desc, descriptor,
416
+ pipelineHolder](
417
+ const async::AsyncTaskHandle::ResolveFunction
418
+ &resolve,
419
+ const async::AsyncTaskHandle::RejectFunction
420
+ &reject) {
411
421
  (void)descriptor;
412
422
  device.CreateRenderPipelineAsync(
413
423
  &desc, wgpu::CallbackMode::AllowProcessEvents,
@@ -433,13 +443,18 @@ void GPUDevice::pushErrorScope(wgpu::ErrorFilter filter) {
433
443
  _instance.PushErrorScope(filter);
434
444
  }
435
445
 
436
- async::AsyncTaskHandle GPUDevice::popErrorScope() {
446
+ async::AsyncTaskHandle GPUDevice::popErrorScope(jsi::Runtime &runtime) {
437
447
  auto device = _instance;
438
448
 
439
- return _async->postTask([device](const async::AsyncTaskHandle::ResolveFunction
440
- &resolve,
441
- const async::AsyncTaskHandle::RejectFunction
442
- &reject) {
449
+ // Post to the CALLING runtime's context so the promise settles on the
450
+ // thread that requested it (see GPUBuffer::mapAsync).
451
+ auto context =
452
+ async::RuntimeContext::getOrCreate(runtime, _async->instance());
453
+ return context->postTask([device](
454
+ const async::AsyncTaskHandle::ResolveFunction
455
+ &resolve,
456
+ const async::AsyncTaskHandle::RejectFunction
457
+ &reject) {
443
458
  device.PopErrorScope(
444
459
  wgpu::CallbackMode::AllowProcessEvents,
445
460
  [resolve, reject](wgpu::PopErrorScopeStatus status,
@@ -136,8 +136,10 @@ public:
136
136
  std::shared_ptr<GPURenderPipeline>
137
137
  createRenderPipeline(std::shared_ptr<GPURenderPipelineDescriptor> descriptor);
138
138
  async::AsyncTaskHandle createComputePipelineAsync(
139
+ jsi::Runtime &runtime,
139
140
  std::shared_ptr<GPUComputePipelineDescriptor> descriptor);
140
141
  async::AsyncTaskHandle createRenderPipelineAsync(
142
+ jsi::Runtime &runtime,
141
143
  std::shared_ptr<GPURenderPipelineDescriptor> descriptor);
142
144
  std::shared_ptr<GPUCommandEncoder> createCommandEncoder(
143
145
  std::optional<std::shared_ptr<GPUCommandEncoderDescriptor>> descriptor);
@@ -146,7 +148,7 @@ public:
146
148
  std::shared_ptr<GPUQuerySet>
147
149
  createQuerySet(std::shared_ptr<GPUQuerySetDescriptor> descriptor);
148
150
  void pushErrorScope(wgpu::ErrorFilter filter);
149
- async::AsyncTaskHandle popErrorScope();
151
+ async::AsyncTaskHandle popErrorScope(jsi::Runtime &runtime);
150
152
 
151
153
  std::unordered_set<std::string> getFeatures();
152
154
  std::shared_ptr<GPUSupportedLimits> getLimits();
@@ -192,10 +194,10 @@ public:
192
194
  &GPUDevice::createComputePipeline);
193
195
  installMethod(runtime, prototype, "createRenderPipeline",
194
196
  &GPUDevice::createRenderPipeline);
195
- installMethod(runtime, prototype, "createComputePipelineAsync",
196
- &GPUDevice::createComputePipelineAsync);
197
- installMethod(runtime, prototype, "createRenderPipelineAsync",
198
- &GPUDevice::createRenderPipelineAsync);
197
+ installMethodWithRuntime(runtime, prototype, "createComputePipelineAsync",
198
+ &GPUDevice::createComputePipelineAsync);
199
+ installMethodWithRuntime(runtime, prototype, "createRenderPipelineAsync",
200
+ &GPUDevice::createRenderPipelineAsync);
199
201
  installMethod(runtime, prototype, "createCommandEncoder",
200
202
  &GPUDevice::createCommandEncoder);
201
203
  installMethod(runtime, prototype, "createRenderBundleEncoder",
@@ -204,8 +206,8 @@ public:
204
206
  &GPUDevice::createQuerySet);
205
207
  installMethod(runtime, prototype, "pushErrorScope",
206
208
  &GPUDevice::pushErrorScope);
207
- installMethod(runtime, prototype, "popErrorScope",
208
- &GPUDevice::popErrorScope);
209
+ installMethodWithRuntime(runtime, prototype, "popErrorScope",
210
+ &GPUDevice::popErrorScope);
209
211
  installGetter(runtime, prototype, "features", &GPUDevice::getFeatures);
210
212
  installGetter(runtime, prototype, "limits", &GPUDevice::getLimits);
211
213
  installGetter(runtime, prototype, "queue", &GPUDevice::getQueue);
@@ -78,9 +78,13 @@ void GPUQueue::writeBuffer(std::shared_ptr<GPUBuffer> buffer,
78
78
  static_cast<size_t>(size64));
79
79
  }
80
80
 
81
- async::AsyncTaskHandle GPUQueue::onSubmittedWorkDone() {
81
+ async::AsyncTaskHandle GPUQueue::onSubmittedWorkDone(jsi::Runtime &runtime) {
82
82
  auto queue = _instance;
83
- return _async->postTask(
83
+ // Post to the CALLING runtime's context so the promise settles on the
84
+ // thread that requested it (see GPUBuffer::mapAsync).
85
+ auto context =
86
+ async::RuntimeContext::getOrCreate(runtime, _async->instance());
87
+ return context->postTask(
84
88
  [queue](const async::AsyncTaskHandle::ResolveFunction &resolve,
85
89
  const async::AsyncTaskHandle::RejectFunction &reject) {
86
90
  queue.OnSubmittedWorkDone(
@@ -37,7 +37,7 @@ public:
37
37
  std::string getBrand() { return CLASS_NAME; }
38
38
 
39
39
  void submit(std::vector<std::shared_ptr<GPUCommandBuffer>> commandBuffers);
40
- async::AsyncTaskHandle onSubmittedWorkDone();
40
+ async::AsyncTaskHandle onSubmittedWorkDone(jsi::Runtime &runtime);
41
41
  void writeBuffer(std::shared_ptr<GPUBuffer> buffer, uint64_t bufferOffset,
42
42
  std::shared_ptr<ArrayBuffer> data,
43
43
  std::optional<uint64_t> dataOffsetElements,
@@ -60,8 +60,8 @@ public:
60
60
  static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {
61
61
  installGetter(runtime, prototype, "__brand", &GPUQueue::getBrand);
62
62
  installMethod(runtime, prototype, "submit", &GPUQueue::submit);
63
- installMethod(runtime, prototype, "onSubmittedWorkDone",
64
- &GPUQueue::onSubmittedWorkDone);
63
+ installMethodWithRuntime(runtime, prototype, "onSubmittedWorkDone",
64
+ &GPUQueue::onSubmittedWorkDone);
65
65
  installMethod(runtime, prototype, "writeBuffer", &GPUQueue::writeBuffer);
66
66
  installMethod(runtime, prototype, "writeTexture", &GPUQueue::writeTexture);
67
67
  installMethod(runtime, prototype, "copyExternalImageToTexture",
@@ -7,10 +7,15 @@
7
7
 
8
8
  namespace rnwgpu {
9
9
 
10
- async::AsyncTaskHandle GPUShaderModule::getCompilationInfo() {
10
+ async::AsyncTaskHandle
11
+ GPUShaderModule::getCompilationInfo(jsi::Runtime &runtime) {
11
12
  auto module = _instance;
12
13
 
13
- return _async->postTask(
14
+ // Post to the CALLING runtime's context so the promise settles on the
15
+ // thread that requested it (see GPUBuffer::mapAsync).
16
+ auto context =
17
+ async::RuntimeContext::getOrCreate(runtime, _async->instance());
18
+ return context->postTask(
14
19
  [module](const async::AsyncTaskHandle::ResolveFunction &resolve,
15
20
  const async::AsyncTaskHandle::RejectFunction &reject) {
16
21
  auto result = std::make_shared<GPUCompilationInfo>();
@@ -31,7 +31,7 @@ public:
31
31
  public:
32
32
  std::string getBrand() { return CLASS_NAME; }
33
33
 
34
- async::AsyncTaskHandle getCompilationInfo();
34
+ async::AsyncTaskHandle getCompilationInfo(jsi::Runtime &runtime);
35
35
 
36
36
  std::string getLabel() { return _label; }
37
37
  void setLabel(const std::string &label) {
@@ -41,8 +41,8 @@ public:
41
41
 
42
42
  static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {
43
43
  installGetter(runtime, prototype, "__brand", &GPUShaderModule::getBrand);
44
- installMethod(runtime, prototype, "getCompilationInfo",
45
- &GPUShaderModule::getCompilationInfo);
44
+ installMethodWithRuntime(runtime, prototype, "getCompilationInfo",
45
+ &GPUShaderModule::getCompilationInfo);
46
46
  installGetterSetter(runtime, prototype, "label", &GPUShaderModule::getLabel,
47
47
  &GPUShaderModule::setLabel);
48
48
  }
@@ -173,7 +173,8 @@ public:
173
173
  return std::make_shared<VideoFrame>(std::move(frame));
174
174
  }
175
175
 
176
- std::shared_ptr<VideoFrame> createTestVideoFrame(double width, double height) {
176
+ std::shared_ptr<VideoFrame> createTestVideoFrame(double width,
177
+ double height) {
177
178
  auto frame = _platformContext->createTestVideoFrame(
178
179
  static_cast<uint32_t>(width), static_cast<uint32_t>(height));
179
180
  return std::make_shared<VideoFrame>(std::move(frame));
@@ -211,6 +212,24 @@ public:
211
212
  nativeInfo.height);
212
213
  }
213
214
 
215
+ // Retires a canvas context from the JS side (Canvas unmount cleanup).
216
+ // Registry entries have two owners, split by whether a native surface is
217
+ // attached:
218
+ // - A native view currently owns a surface (or one is pending): its own
219
+ // teardown (MetalView dealloc / WebGPUViewManager.onDropViewInstance)
220
+ // removes the entry. Skipping here keeps React StrictMode safe: its
221
+ // simulated unmount re-runs JS effects without unmounting native views,
222
+ // and removing the entry then would orphan the still-attached surface.
223
+ // - No native surface: the JS side is the last owner and removes the entry.
224
+ // The check-and-erase runs atomically under the registry lock
225
+ // (removeSurfaceInfoIfDetached), serialized against the UI thread's
226
+ // find-or-create + attach (SurfaceRegistry::attachSurface), so a concurrent
227
+ // attach can never be orphaned by this removal.
228
+ void destroyContext(int contextId) {
229
+ auto &registry = rnwgpu::SurfaceRegistry::getInstance();
230
+ registry.removeSurfaceInfoIfDetached(contextId);
231
+ }
232
+
214
233
  static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {
215
234
  installGetter(runtime, prototype, "fabric", &RNWebGPU::getFabric);
216
235
  installGetter(runtime, prototype, "gpu", &RNWebGPU::getGPU);
@@ -218,6 +237,8 @@ public:
218
237
  &RNWebGPU::createImageBitmap);
219
238
  installMethod(runtime, prototype, "getNativeSurface",
220
239
  &RNWebGPU::getNativeSurface);
240
+ installMethod(runtime, prototype, "destroyContext",
241
+ &RNWebGPU::destroyContext);
221
242
  installMethod(runtime, prototype, "MakeWebGPUCanvasContext",
222
243
  &RNWebGPU::MakeWebGPUCanvasContext);
223
244
  installMethod(runtime, prototype, "loadVideoFrame",
@@ -56,8 +56,15 @@ namespace rnwgpu::async {
56
56
  * ProcessEvents on one instance is not guaranteed reentrant.
57
57
  *
58
58
  * Threading contract: a RuntimeContext must only be pumped from the runtime it
59
- * was created for. Create and use a GPUDevice (and the buffers/queues derived
60
- * from it) on the same runtime that requested the adapter.
59
+ * was created for. Request/response async entry points (mapAsync,
60
+ * onSubmittedWorkDone, popErrorScope, createComputePipelineAsync,
61
+ * createRenderPipelineAsync, getCompilationInfo, requestAdapter,
62
+ * requestDevice) must NOT use a context captured when the object was created —
63
+ * the object may have been boxed across to another runtime. They resolve the
64
+ * CALLING runtime's context via getOrCreate(runtime, instance) so the promise
65
+ * is settled on the thread it was created on. Spontaneous events (device.lost,
66
+ * uncapturederror) remain bound to the device's own context (best-effort, main
67
+ * runtime only; see the class doc above).
61
68
  */
62
69
  class RuntimeContext : public std::enable_shared_from_this<RuntimeContext> {
63
70
  public:
@@ -21,6 +21,16 @@ const Canvas = ({
21
21
  }) => {
22
22
  const viewRef = (0, _react.useRef)(null);
23
23
  const [contextId, _] = (0, _react.useState)(() => generateContextId());
24
+ // Retire the native registry entry for this contextId on unmount. When a
25
+ // native surface is still attached, this is a no-op and the native view's
26
+ // own teardown retires the entry instead — which keeps StrictMode's
27
+ // simulated unmount (which re-runs effects without unmounting native views)
28
+ // from orphaning a live surface.
29
+ (0, _react.useEffect)(() => {
30
+ return () => {
31
+ RNWebGPU.destroyContext(contextId);
32
+ };
33
+ }, [contextId]);
24
34
  (0, _react.useImperativeHandle)(ref, () => ({
25
35
  getContextId: () => contextId,
26
36
  getNativeSurface: () => {
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_WebGPUViewNativeComponent","_interopRequireDefault","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_extends","assign","bind","arguments","length","apply","CONTEXT_COUNTER","generateContextId","Canvas","transparent","ref","props","viewRef","useRef","contextId","_","useState","useImperativeHandle","getContextId","getNativeSurface","RNWebGPU","getContext","contextName","Error","current","view","size","getBoundingClientRect","unstable_getBoundingClientRect","MakeWebGPUCanvasContext","width","height","createElement","View","collapsable","style","flex","exports"],"sourceRoot":"../../src","sources":["Canvas.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_WebGPUViewNativeComponent","_interopRequireDefault","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_extends","assign","bind","arguments","length","apply","CONTEXT_COUNTER","generateContextId","Canvas","transparent","ref","props","viewRef","useRef","contextId","_","useState","useEffect","RNWebGPU","destroyContext","useImperativeHandle","getContextId","getNativeSurface","getContext","contextName","Error","current","view","size","getBoundingClientRect","unstable_getBoundingClientRect","MakeWebGPUCanvasContext","width","height","createElement","View","collapsable","style","flex","exports"],"sourceRoot":"../../src","sources":["Canvas.tsx"],"mappings":"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","ignoreList":[]}
@@ -43,6 +43,8 @@ function makeWebGPUCanvasContext(contextId, width, height) {
43
43
  window.RNWebGPU = {
44
44
  getNativeSurface,
45
45
  MakeWebGPUCanvasContext: makeWebGPUCanvasContext,
46
+ // On web the browser owns the canvas/context lifecycle; nothing to retire.
47
+ destroyContext: _contextId => {},
46
48
  fabric
47
49
  };
48
50
  //# sourceMappingURL=WebPolyfillGPUModule.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_utils","require","fabric","getNativeSurface","contextId","canvas","document","getElementById","contextIdToId","height","width","getBoundingClientRect","surface","BigInt","clientHeight","clientWidth","addEventListener","bind","removeEventListener","dispatchEvent","setPointerCapture","releasePointerCapture","makeWebGPUCanvasContext","dpr","window","devicePixelRatio","pixelWidth","toString","pixelHeight","getAttribute","setAttribute","context","getContext","Object","assign","present","RNWebGPU","MakeWebGPUCanvasContext"],"sourceRoot":"../../src","sources":["WebPolyfillGPUModule.ts"],"mappings":";;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,MAAMC,MAAM,GAAG,IAAI;AAEnB,SAASC,gBAAgBA,CAACC,SAAiB,EAAE;EAC3C,MAAMC,MAAM,GAAGC,QAAQ,CAACC,cAAc,CACpC,IAAAC,oBAAa,EAACJ,SAAS,CACzB,CAAsB;EAEtB,MAAM;IAAEK,MAAM;IAAEC;EAAM,CAAC,GAAGL,MAAM,CAACM,qBAAqB,CAAC,CAAE;EAEzD,OAAO;IACLC,OAAO,EAAEC,MAAM,CAACT,SAAS,CAAC;IAC1BK,MAAM;IACNC,KAAK;IACLI,YAAY,EAAEL,MAAM;IACpBM,WAAW,EAAEL,KAAK;IAClB;IACAM,gBAAgB,EAAEX,MAAM,CAACW,gBAAgB,CAACC,IAAI,CAACZ,MAAM,CAAC;IACtDa,mBAAmB,EAAEb,MAAM,CAACa,mBAAmB,CAACD,IAAI,CAACZ,MAAM,CAAC;IAC5Dc,aAAa,EAAEd,MAAM,CAACc,aAAa,CAACF,IAAI,CAACZ,MAAM,CAAC;IAChDe,iBAAiB,EAAEf,MAAM,CAACe,iBAAiB,CAACH,IAAI,CAACZ,MAAM,CAAC;IACxDgB,qBAAqB,EAAEhB,MAAM,CAACgB,qBAAqB,CAACJ,IAAI,CAACZ,MAAM;EACjE,CAAC;AACH;AAEA,SAASiB,uBAAuBA,CAC9BlB,SAAiB,EACjBM,KAAa,EACbD,MAAc,EACd;EACA,MAAMJ,MAAM,GAAGC,QAAQ,CAACC,cAAc,CACpC,IAAAC,oBAAa,EAACJ,SAAS,CACzB,CAAsB;EAEtB,MAAMmB,GAAG,GAAGC,MAAM,CAACC,gBAAgB,IAAI,CAAC;EACxC,MAAMC,UAAU,GAAG,CAAChB,KAAK,GAAGa,GAAG,EAAEI,QAAQ,CAAC,CAAC;EAC3C,MAAMC,WAAW,GAAG,CAACnB,MAAM,GAAGc,GAAG,EAAEI,QAAQ,CAAC,CAAC;EAE7C,IACEtB,MAAM,CAACwB,YAAY,CAAC,OAAO,CAAC,KAAKH,UAAU,IAC3CrB,MAAM,CAACwB,YAAY,CAAC,QAAQ,CAAC,KAAKD,WAAW,EAC7C;IACAvB,MAAM,CAACyB,YAAY,CAAC,OAAO,EAAEJ,UAAU,CAAC;IACxCrB,MAAM,CAACyB,YAAY,CAAC,QAAQ,EAAEF,WAAW,CAAC;EAC5C;EAEA,MAAMG,OAAO,GAAG1B,MAAM,CAAC2B,UAAU,CAAC,QAAQ,CAAE;EAC5C;EACA;EACA,OAAOC,MAAM,CAACC,MAAM,CAACH,OAAO,EAAE;IAAEI,OAAO,EAAEA,CAAA,KAAM,CAAC;EAAE,CAAC,CAAC;AACtD;;AAEA;AACAX,MAAM,CAACY,QAAQ,GAAG;EAChBjC,gBAAgB;EAChBkC,uBAAuB,EAAEf,uBAAuB;EAChDpB;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_utils","require","fabric","getNativeSurface","contextId","canvas","document","getElementById","contextIdToId","height","width","getBoundingClientRect","surface","BigInt","clientHeight","clientWidth","addEventListener","bind","removeEventListener","dispatchEvent","setPointerCapture","releasePointerCapture","makeWebGPUCanvasContext","dpr","window","devicePixelRatio","pixelWidth","toString","pixelHeight","getAttribute","setAttribute","context","getContext","Object","assign","present","RNWebGPU","MakeWebGPUCanvasContext","destroyContext","_contextId"],"sourceRoot":"../../src","sources":["WebPolyfillGPUModule.ts"],"mappings":";;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,MAAMC,MAAM,GAAG,IAAI;AAEnB,SAASC,gBAAgBA,CAACC,SAAiB,EAAE;EAC3C,MAAMC,MAAM,GAAGC,QAAQ,CAACC,cAAc,CACpC,IAAAC,oBAAa,EAACJ,SAAS,CACzB,CAAsB;EAEtB,MAAM;IAAEK,MAAM;IAAEC;EAAM,CAAC,GAAGL,MAAM,CAACM,qBAAqB,CAAC,CAAE;EAEzD,OAAO;IACLC,OAAO,EAAEC,MAAM,CAACT,SAAS,CAAC;IAC1BK,MAAM;IACNC,KAAK;IACLI,YAAY,EAAEL,MAAM;IACpBM,WAAW,EAAEL,KAAK;IAClB;IACAM,gBAAgB,EAAEX,MAAM,CAACW,gBAAgB,CAACC,IAAI,CAACZ,MAAM,CAAC;IACtDa,mBAAmB,EAAEb,MAAM,CAACa,mBAAmB,CAACD,IAAI,CAACZ,MAAM,CAAC;IAC5Dc,aAAa,EAAEd,MAAM,CAACc,aAAa,CAACF,IAAI,CAACZ,MAAM,CAAC;IAChDe,iBAAiB,EAAEf,MAAM,CAACe,iBAAiB,CAACH,IAAI,CAACZ,MAAM,CAAC;IACxDgB,qBAAqB,EAAEhB,MAAM,CAACgB,qBAAqB,CAACJ,IAAI,CAACZ,MAAM;EACjE,CAAC;AACH;AAEA,SAASiB,uBAAuBA,CAC9BlB,SAAiB,EACjBM,KAAa,EACbD,MAAc,EACd;EACA,MAAMJ,MAAM,GAAGC,QAAQ,CAACC,cAAc,CACpC,IAAAC,oBAAa,EAACJ,SAAS,CACzB,CAAsB;EAEtB,MAAMmB,GAAG,GAAGC,MAAM,CAACC,gBAAgB,IAAI,CAAC;EACxC,MAAMC,UAAU,GAAG,CAAChB,KAAK,GAAGa,GAAG,EAAEI,QAAQ,CAAC,CAAC;EAC3C,MAAMC,WAAW,GAAG,CAACnB,MAAM,GAAGc,GAAG,EAAEI,QAAQ,CAAC,CAAC;EAE7C,IACEtB,MAAM,CAACwB,YAAY,CAAC,OAAO,CAAC,KAAKH,UAAU,IAC3CrB,MAAM,CAACwB,YAAY,CAAC,QAAQ,CAAC,KAAKD,WAAW,EAC7C;IACAvB,MAAM,CAACyB,YAAY,CAAC,OAAO,EAAEJ,UAAU,CAAC;IACxCrB,MAAM,CAACyB,YAAY,CAAC,QAAQ,EAAEF,WAAW,CAAC;EAC5C;EAEA,MAAMG,OAAO,GAAG1B,MAAM,CAAC2B,UAAU,CAAC,QAAQ,CAAE;EAC5C;EACA;EACA,OAAOC,MAAM,CAACC,MAAM,CAACH,OAAO,EAAE;IAAEI,OAAO,EAAEA,CAAA,KAAM,CAAC;EAAE,CAAC,CAAC;AACtD;;AAEA;AACAX,MAAM,CAACY,QAAQ,GAAG;EAChBjC,gBAAgB;EAChBkC,uBAAuB,EAAEf,uBAAuB;EAChD;EACAgB,cAAc,EAAGC,UAAkB,IAAK,CAAC,CAAC;EAC1CrC;AACF,CAAC","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
- import React, { useImperativeHandle, useRef, useState } from "react";
2
+ import React, { useEffect, useImperativeHandle, useRef, useState } from "react";
3
3
  import { View } from "react-native";
4
4
  import WebGPUNativeView from "./WebGPUViewNativeComponent";
5
5
  let CONTEXT_COUNTER = 1;
@@ -13,6 +13,16 @@ export const Canvas = ({
13
13
  }) => {
14
14
  const viewRef = useRef(null);
15
15
  const [contextId, _] = useState(() => generateContextId());
16
+ // Retire the native registry entry for this contextId on unmount. When a
17
+ // native surface is still attached, this is a no-op and the native view's
18
+ // own teardown retires the entry instead — which keeps StrictMode's
19
+ // simulated unmount (which re-runs effects without unmounting native views)
20
+ // from orphaning a live surface.
21
+ useEffect(() => {
22
+ return () => {
23
+ RNWebGPU.destroyContext(contextId);
24
+ };
25
+ }, [contextId]);
16
26
  useImperativeHandle(ref, () => ({
17
27
  getContextId: () => contextId,
18
28
  getNativeSurface: () => {
@@ -1 +1 @@
1
- {"version":3,"names":["React","useImperativeHandle","useRef","useState","View","WebGPUNativeView","CONTEXT_COUNTER","generateContextId","Canvas","transparent","ref","props","viewRef","contextId","_","getContextId","getNativeSurface","RNWebGPU","getContext","contextName","Error","current","view","size","getBoundingClientRect","unstable_getBoundingClientRect","MakeWebGPUCanvasContext","width","height","createElement","_extends","collapsable","style","flex"],"sourceRoot":"../../src","sources":["Canvas.tsx"],"mappings":";AAAA,OAAOA,KAAK,IAAIC,mBAAmB,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAEpE,SAASC,IAAI,QAAQ,cAAc;AAEnC,OAAOC,gBAAgB,MAAM,6BAA6B;AAE1D,IAAIC,eAAe,GAAG,CAAC;AACvB,SAASC,iBAAiBA,CAAA,EAAG;EAC3B,OAAOD,eAAe,EAAE;AAC1B;AA2CA,OAAO,MAAME,MAAM,GAAGA,CAAC;EAAEC,WAAW;EAAEC,GAAG;EAAE,GAAGC;AAAmB,CAAC,KAAK;EACrE,MAAMC,OAAO,GAAGV,MAAM,CAAC,IAAI,CAAC;EAC5B,MAAM,CAACW,SAAS,EAAEC,CAAC,CAAC,GAAGX,QAAQ,CAAC,MAAMI,iBAAiB,CAAC,CAAC,CAAC;EAC1DN,mBAAmB,CAACS,GAAG,EAAE,OAAO;IAC9BK,YAAY,EAAEA,CAAA,KAAMF,SAAS;IAC7BG,gBAAgB,EAAEA,CAAA,KAAM;MACtB,OAAOC,QAAQ,CAACD,gBAAgB,CAACH,SAAS,CAAC;IAC7C,CAAC;IACDK,UAAUA,CAACC,WAAqB,EAA0B;MACxD,IAAIA,WAAW,KAAK,QAAQ,EAAE;QAC5B,MAAM,IAAIC,KAAK,CAAC,iCAAiCD,WAAW,EAAE,CAAC;MACjE;MACA,IAAI,CAACP,OAAO,CAACS,OAAO,EAAE;QACpB,MAAM,IAAID,KAAK,CAAC,0CAA0C,CAAC;MAC7D;MACA;MACA;MACA,MAAME,IAAI,GAAGV,OAAO,CAACS,OAAc;MACnC,MAAME,IAAI,GACR,uBAAuB,IAAID,IAAI,GAC3BA,IAAI,CAACE,qBAAqB,CAAC,CAAC,GAC5BF,IAAI,CAACG,8BAA8B,CAAC,CAAC;MAC3C,OAAOR,QAAQ,CAACS,uBAAuB,CACrCb,SAAS,EACTU,IAAI,CAACI,KAAK,EACVJ,IAAI,CAACK,MACP,CAAC;IACH;EACF,CAAC,CAAC,CAAC;EAEH,oBACE5B,KAAA,CAAA6B,aAAA,CAACzB,IAAI,EAAA0B,QAAA;IAACC,WAAW,EAAE,KAAM;IAACrB,GAAG,EAAEE;EAAQ,GAAKD,KAAK,gBAC/CX,KAAA,CAAA6B,aAAA,CAACxB,gBAAgB;IACf2B,KAAK,EAAE;MAAEC,IAAI,EAAE;IAAE,CAAE;IACnBpB,SAAS,EAAEA,SAAU;IACrBJ,WAAW,EAAE,CAAC,CAACA;EAAY,CAC5B,CACG,CAAC;AAEX,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["React","useEffect","useImperativeHandle","useRef","useState","View","WebGPUNativeView","CONTEXT_COUNTER","generateContextId","Canvas","transparent","ref","props","viewRef","contextId","_","RNWebGPU","destroyContext","getContextId","getNativeSurface","getContext","contextName","Error","current","view","size","getBoundingClientRect","unstable_getBoundingClientRect","MakeWebGPUCanvasContext","width","height","createElement","_extends","collapsable","style","flex"],"sourceRoot":"../../src","sources":["Canvas.tsx"],"mappings":";AAAA,OAAOA,KAAK,IAAIC,SAAS,EAAEC,mBAAmB,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAE/E,SAASC,IAAI,QAAQ,cAAc;AAEnC,OAAOC,gBAAgB,MAAM,6BAA6B;AAE1D,IAAIC,eAAe,GAAG,CAAC;AACvB,SAASC,iBAAiBA,CAAA,EAAG;EAC3B,OAAOD,eAAe,EAAE;AAC1B;AA2CA,OAAO,MAAME,MAAM,GAAGA,CAAC;EAAEC,WAAW;EAAEC,GAAG;EAAE,GAAGC;AAAmB,CAAC,KAAK;EACrE,MAAMC,OAAO,GAAGV,MAAM,CAAC,IAAI,CAAC;EAC5B,MAAM,CAACW,SAAS,EAAEC,CAAC,CAAC,GAAGX,QAAQ,CAAC,MAAMI,iBAAiB,CAAC,CAAC,CAAC;EAC1D;EACA;EACA;EACA;EACA;EACAP,SAAS,CAAC,MAAM;IACd,OAAO,MAAM;MACXe,QAAQ,CAACC,cAAc,CAACH,SAAS,CAAC;IACpC,CAAC;EACH,CAAC,EAAE,CAACA,SAAS,CAAC,CAAC;EACfZ,mBAAmB,CAACS,GAAG,EAAE,OAAO;IAC9BO,YAAY,EAAEA,CAAA,KAAMJ,SAAS;IAC7BK,gBAAgB,EAAEA,CAAA,KAAM;MACtB,OAAOH,QAAQ,CAACG,gBAAgB,CAACL,SAAS,CAAC;IAC7C,CAAC;IACDM,UAAUA,CAACC,WAAqB,EAA0B;MACxD,IAAIA,WAAW,KAAK,QAAQ,EAAE;QAC5B,MAAM,IAAIC,KAAK,CAAC,iCAAiCD,WAAW,EAAE,CAAC;MACjE;MACA,IAAI,CAACR,OAAO,CAACU,OAAO,EAAE;QACpB,MAAM,IAAID,KAAK,CAAC,0CAA0C,CAAC;MAC7D;MACA;MACA;MACA,MAAME,IAAI,GAAGX,OAAO,CAACU,OAAc;MACnC,MAAME,IAAI,GACR,uBAAuB,IAAID,IAAI,GAC3BA,IAAI,CAACE,qBAAqB,CAAC,CAAC,GAC5BF,IAAI,CAACG,8BAA8B,CAAC,CAAC;MAC3C,OAAOX,QAAQ,CAACY,uBAAuB,CACrCd,SAAS,EACTW,IAAI,CAACI,KAAK,EACVJ,IAAI,CAACK,MACP,CAAC;IACH;EACF,CAAC,CAAC,CAAC;EAEH,oBACE9B,KAAA,CAAA+B,aAAA,CAAC1B,IAAI,EAAA2B,QAAA;IAACC,WAAW,EAAE,KAAM;IAACtB,GAAG,EAAEE;EAAQ,GAAKD,KAAK,gBAC/CZ,KAAA,CAAA+B,aAAA,CAACzB,gBAAgB;IACf4B,KAAK,EAAE;MAAEC,IAAI,EAAE;IAAE,CAAE;IACnBrB,SAAS,EAAEA,SAAU;IACrBJ,WAAW,EAAE,CAAC,CAACA;EAAY,CAC5B,CACG,CAAC;AAEX,CAAC","ignoreList":[]}
@@ -41,6 +41,8 @@ function makeWebGPUCanvasContext(contextId, width, height) {
41
41
  window.RNWebGPU = {
42
42
  getNativeSurface,
43
43
  MakeWebGPUCanvasContext: makeWebGPUCanvasContext,
44
+ // On web the browser owns the canvas/context lifecycle; nothing to retire.
45
+ destroyContext: _contextId => {},
44
46
  fabric
45
47
  };
46
48
  //# sourceMappingURL=WebPolyfillGPUModule.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["contextIdToId","fabric","getNativeSurface","contextId","canvas","document","getElementById","height","width","getBoundingClientRect","surface","BigInt","clientHeight","clientWidth","addEventListener","bind","removeEventListener","dispatchEvent","setPointerCapture","releasePointerCapture","makeWebGPUCanvasContext","dpr","window","devicePixelRatio","pixelWidth","toString","pixelHeight","getAttribute","setAttribute","context","getContext","Object","assign","present","RNWebGPU","MakeWebGPUCanvasContext"],"sourceRoot":"../../src","sources":["WebPolyfillGPUModule.ts"],"mappings":"AAAA,SAASA,aAAa,QAAQ,SAAS;AAEvC,MAAMC,MAAM,GAAG,IAAI;AAEnB,SAASC,gBAAgBA,CAACC,SAAiB,EAAE;EAC3C,MAAMC,MAAM,GAAGC,QAAQ,CAACC,cAAc,CACpCN,aAAa,CAACG,SAAS,CACzB,CAAsB;EAEtB,MAAM;IAAEI,MAAM;IAAEC;EAAM,CAAC,GAAGJ,MAAM,CAACK,qBAAqB,CAAC,CAAE;EAEzD,OAAO;IACLC,OAAO,EAAEC,MAAM,CAACR,SAAS,CAAC;IAC1BI,MAAM;IACNC,KAAK;IACLI,YAAY,EAAEL,MAAM;IACpBM,WAAW,EAAEL,KAAK;IAClB;IACAM,gBAAgB,EAAEV,MAAM,CAACU,gBAAgB,CAACC,IAAI,CAACX,MAAM,CAAC;IACtDY,mBAAmB,EAAEZ,MAAM,CAACY,mBAAmB,CAACD,IAAI,CAACX,MAAM,CAAC;IAC5Da,aAAa,EAAEb,MAAM,CAACa,aAAa,CAACF,IAAI,CAACX,MAAM,CAAC;IAChDc,iBAAiB,EAAEd,MAAM,CAACc,iBAAiB,CAACH,IAAI,CAACX,MAAM,CAAC;IACxDe,qBAAqB,EAAEf,MAAM,CAACe,qBAAqB,CAACJ,IAAI,CAACX,MAAM;EACjE,CAAC;AACH;AAEA,SAASgB,uBAAuBA,CAC9BjB,SAAiB,EACjBK,KAAa,EACbD,MAAc,EACd;EACA,MAAMH,MAAM,GAAGC,QAAQ,CAACC,cAAc,CACpCN,aAAa,CAACG,SAAS,CACzB,CAAsB;EAEtB,MAAMkB,GAAG,GAAGC,MAAM,CAACC,gBAAgB,IAAI,CAAC;EACxC,MAAMC,UAAU,GAAG,CAAChB,KAAK,GAAGa,GAAG,EAAEI,QAAQ,CAAC,CAAC;EAC3C,MAAMC,WAAW,GAAG,CAACnB,MAAM,GAAGc,GAAG,EAAEI,QAAQ,CAAC,CAAC;EAE7C,IACErB,MAAM,CAACuB,YAAY,CAAC,OAAO,CAAC,KAAKH,UAAU,IAC3CpB,MAAM,CAACuB,YAAY,CAAC,QAAQ,CAAC,KAAKD,WAAW,EAC7C;IACAtB,MAAM,CAACwB,YAAY,CAAC,OAAO,EAAEJ,UAAU,CAAC;IACxCpB,MAAM,CAACwB,YAAY,CAAC,QAAQ,EAAEF,WAAW,CAAC;EAC5C;EAEA,MAAMG,OAAO,GAAGzB,MAAM,CAAC0B,UAAU,CAAC,QAAQ,CAAE;EAC5C;EACA;EACA,OAAOC,MAAM,CAACC,MAAM,CAACH,OAAO,EAAE;IAAEI,OAAO,EAAEA,CAAA,KAAM,CAAC;EAAE,CAAC,CAAC;AACtD;;AAEA;AACAX,MAAM,CAACY,QAAQ,GAAG;EAChBhC,gBAAgB;EAChBiC,uBAAuB,EAAEf,uBAAuB;EAChDnB;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["contextIdToId","fabric","getNativeSurface","contextId","canvas","document","getElementById","height","width","getBoundingClientRect","surface","BigInt","clientHeight","clientWidth","addEventListener","bind","removeEventListener","dispatchEvent","setPointerCapture","releasePointerCapture","makeWebGPUCanvasContext","dpr","window","devicePixelRatio","pixelWidth","toString","pixelHeight","getAttribute","setAttribute","context","getContext","Object","assign","present","RNWebGPU","MakeWebGPUCanvasContext","destroyContext","_contextId"],"sourceRoot":"../../src","sources":["WebPolyfillGPUModule.ts"],"mappings":"AAAA,SAASA,aAAa,QAAQ,SAAS;AAEvC,MAAMC,MAAM,GAAG,IAAI;AAEnB,SAASC,gBAAgBA,CAACC,SAAiB,EAAE;EAC3C,MAAMC,MAAM,GAAGC,QAAQ,CAACC,cAAc,CACpCN,aAAa,CAACG,SAAS,CACzB,CAAsB;EAEtB,MAAM;IAAEI,MAAM;IAAEC;EAAM,CAAC,GAAGJ,MAAM,CAACK,qBAAqB,CAAC,CAAE;EAEzD,OAAO;IACLC,OAAO,EAAEC,MAAM,CAACR,SAAS,CAAC;IAC1BI,MAAM;IACNC,KAAK;IACLI,YAAY,EAAEL,MAAM;IACpBM,WAAW,EAAEL,KAAK;IAClB;IACAM,gBAAgB,EAAEV,MAAM,CAACU,gBAAgB,CAACC,IAAI,CAACX,MAAM,CAAC;IACtDY,mBAAmB,EAAEZ,MAAM,CAACY,mBAAmB,CAACD,IAAI,CAACX,MAAM,CAAC;IAC5Da,aAAa,EAAEb,MAAM,CAACa,aAAa,CAACF,IAAI,CAACX,MAAM,CAAC;IAChDc,iBAAiB,EAAEd,MAAM,CAACc,iBAAiB,CAACH,IAAI,CAACX,MAAM,CAAC;IACxDe,qBAAqB,EAAEf,MAAM,CAACe,qBAAqB,CAACJ,IAAI,CAACX,MAAM;EACjE,CAAC;AACH;AAEA,SAASgB,uBAAuBA,CAC9BjB,SAAiB,EACjBK,KAAa,EACbD,MAAc,EACd;EACA,MAAMH,MAAM,GAAGC,QAAQ,CAACC,cAAc,CACpCN,aAAa,CAACG,SAAS,CACzB,CAAsB;EAEtB,MAAMkB,GAAG,GAAGC,MAAM,CAACC,gBAAgB,IAAI,CAAC;EACxC,MAAMC,UAAU,GAAG,CAAChB,KAAK,GAAGa,GAAG,EAAEI,QAAQ,CAAC,CAAC;EAC3C,MAAMC,WAAW,GAAG,CAACnB,MAAM,GAAGc,GAAG,EAAEI,QAAQ,CAAC,CAAC;EAE7C,IACErB,MAAM,CAACuB,YAAY,CAAC,OAAO,CAAC,KAAKH,UAAU,IAC3CpB,MAAM,CAACuB,YAAY,CAAC,QAAQ,CAAC,KAAKD,WAAW,EAC7C;IACAtB,MAAM,CAACwB,YAAY,CAAC,OAAO,EAAEJ,UAAU,CAAC;IACxCpB,MAAM,CAACwB,YAAY,CAAC,QAAQ,EAAEF,WAAW,CAAC;EAC5C;EAEA,MAAMG,OAAO,GAAGzB,MAAM,CAAC0B,UAAU,CAAC,QAAQ,CAAE;EAC5C;EACA;EACA,OAAOC,MAAM,CAACC,MAAM,CAACH,OAAO,EAAE;IAAEI,OAAO,EAAEA,CAAA,KAAM,CAAC;EAAE,CAAC,CAAC;AACtD;;AAEA;AACAX,MAAM,CAACY,QAAQ,GAAG;EAChBhC,gBAAgB;EAChBiC,uBAAuB,EAAEf,uBAAuB;EAChD;EACAgB,cAAc,EAAGC,UAAkB,IAAK,CAAC,CAAC;EAC1CpC;AACF,CAAC","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../../commonjs/Canvas.js"],"names":[],"mappings":";AAgBA;;;;QAoCC"}
1
+ {"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../../commonjs/Canvas.js"],"names":[],"mappings":";AAgBA;;;;QA8CC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../../module/Canvas.js"],"names":[],"mappings":"AAQO;;;;2DAoCN;qBA1CoB,cAAc;kBAD0B,OAAO"}
1
+ {"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../../module/Canvas.js"],"names":[],"mappings":"AAQO;;;;2DA8CN;qBApDoB,cAAc;kBADqC,OAAO"}