react-native-wgpu 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/android/cpp/AndroidPlatformContext.h +108 -2
  2. package/android/cpp/cpp-adapter.cpp +5 -2
  3. package/android/src/main/java/com/webgpu/WebGPUModule.java +8 -2
  4. package/cpp/rnwgpu/PlatformContext.h +14 -1
  5. package/cpp/rnwgpu/RNWebGPUManager.cpp +6 -9
  6. package/cpp/rnwgpu/RNWebGPUManager.h +0 -3
  7. package/cpp/rnwgpu/api/GPU.cpp +33 -52
  8. package/cpp/rnwgpu/api/GPUAdapter.cpp +92 -92
  9. package/cpp/rnwgpu/api/GPUBuffer.h +1 -1
  10. package/cpp/rnwgpu/api/GPUQueue.cpp +45 -2
  11. package/cpp/rnwgpu/api/ImageBitmap.h +34 -0
  12. package/cpp/rnwgpu/api/RNWebGPU.h +100 -0
  13. package/cpp/rnwgpu/api/descriptors/GPUImageCopyExternalImage.h +14 -4
  14. package/ios/IOSPlatformContext.h +3 -0
  15. package/ios/IOSPlatformContext.mm +50 -0
  16. package/ios/SurfaceUtils.mm +0 -1
  17. package/lib/commonjs/Canvas.js +1 -3
  18. package/lib/commonjs/Canvas.js.map +1 -1
  19. package/lib/commonjs/index.js +25 -0
  20. package/lib/commonjs/index.js.map +1 -1
  21. package/lib/commonjs/utils.js +39 -0
  22. package/lib/commonjs/utils.js.map +1 -0
  23. package/lib/module/Canvas.js +1 -3
  24. package/lib/module/Canvas.js.map +1 -1
  25. package/lib/module/index.js +14 -0
  26. package/lib/module/index.js.map +1 -1
  27. package/lib/module/utils.js +31 -0
  28. package/lib/module/utils.js.map +1 -0
  29. package/lib/typescript/lib/commonjs/utils.d.ts +5 -0
  30. package/lib/typescript/lib/commonjs/utils.d.ts.map +1 -0
  31. package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
  32. package/lib/typescript/lib/module/WebGPUViewNativeComponent.d.ts +0 -1
  33. package/lib/typescript/lib/module/index.d.ts +1 -0
  34. package/lib/typescript/lib/module/utils.d.ts +3 -0
  35. package/lib/typescript/lib/module/utils.d.ts.map +1 -0
  36. package/lib/typescript/src/Canvas.d.ts +6 -1
  37. package/lib/typescript/src/Canvas.d.ts.map +1 -1
  38. package/lib/typescript/src/WebGPUViewNativeComponent.d.ts +0 -1
  39. package/lib/typescript/src/WebGPUViewNativeComponent.d.ts.map +1 -1
  40. package/lib/typescript/src/index.d.ts +1 -0
  41. package/lib/typescript/src/index.d.ts.map +1 -1
  42. package/lib/typescript/src/utils.d.ts +6 -0
  43. package/lib/typescript/src/utils.d.ts.map +1 -0
  44. package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
  45. package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
  46. package/libs/android/x86/libwebgpu_dawn.so +0 -0
  47. package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
  48. package/libs/ios/arm64_iphoneos/libwebgpu_dawn.a +0 -0
  49. package/libs/ios/arm64_iphonesimulator/libwebgpu_dawn.a +0 -0
  50. package/libs/ios/arm64_xros/libwebgpu_dawn.a +0 -0
  51. package/libs/ios/arm64_xrsimulator/libwebgpu_dawn.a +0 -0
  52. package/libs/ios/libwebgpu_dawn.a +0 -0
  53. package/libs/ios/libwebgpu_dawn.xcframework/Info.plist +36 -5
  54. package/libs/ios/libwebgpu_dawn.xcframework/ios-arm64/libwebgpu_dawn.a +0 -0
  55. package/libs/ios/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
  56. package/libs/ios/libwebgpu_dawn.xcframework/xros-arm64/libwebgpu_dawn.a +0 -0
  57. package/libs/ios/libwebgpu_dawn.xcframework/xros-arm64_x86_64-simulator/libwebgpu_dawn_visionos.a +0 -0
  58. package/libs/ios/libwebgpu_dawn_visionos.a +0 -0
  59. package/libs/ios/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
  60. package/libs/ios/x86_64_xrsimulator/libwebgpu_dawn.a +0 -0
  61. package/package.json +3 -20
  62. package/react-native-wgpu.podspec +1 -1
  63. package/src/Canvas.tsx +8 -3
  64. package/src/index.tsx +19 -0
  65. package/src/utils.ts +40 -0
  66. package/cpp/rnwgpu/api/ImageData.h +0 -50
  67. package/cpp/rnwgpu/api/Navigator.h +0 -46
  68. package/lib/typescript/example/src/Triangle/triangle.d.ts +0 -3
  69. package/lib/typescript/example/src/Triangle/triangle.d.ts.map +0 -1
  70. package/lib/typescript/example/src/Wireframe/Shaders.d.ts +0 -3
  71. package/lib/typescript/example/src/Wireframe/Shaders.d.ts.map +0 -1
  72. package/lib/typescript/example/src/Wireframe/models.d.ts +0 -29
  73. package/lib/typescript/example/src/Wireframe/models.d.ts.map +0 -1
  74. package/lib/typescript/example/src/components/DrawingContext.d.ts +0 -13
  75. package/lib/typescript/example/src/components/DrawingContext.d.ts.map +0 -1
  76. package/lib/typescript/example/src/components/cube.d.ts +0 -7
  77. package/lib/typescript/example/src/components/cube.d.ts.map +0 -1
  78. package/lib/typescript/example/src/components/meshes/sphere.d.ts +0 -12
  79. package/lib/typescript/example/src/components/meshes/sphere.d.ts.map +0 -1
  80. package/lib/typescript/example/src/components/meshes/teapot.d.ts +0 -6
  81. package/lib/typescript/example/src/components/meshes/teapot.d.ts.map +0 -1
  82. package/lib/typescript/example/src/components/meshes/utils.d.ts +0 -10
  83. package/lib/typescript/example/src/components/meshes/utils.d.ts.map +0 -1
@@ -1,6 +1,11 @@
1
1
  #pragma once
2
2
 
3
+ #include <android/bitmap.h>
4
+ #include <jni.h>
5
+
3
6
  #include <memory>
7
+ #include <string>
8
+ #include <vector>
4
9
 
5
10
  #include "webgpu/webgpu_cpp.h"
6
11
 
@@ -8,10 +13,23 @@
8
13
  #include "RNWebGPUManager.h"
9
14
 
10
15
  namespace rnwgpu {
16
+
17
+ namespace jsi = facebook::jsi;
18
+ namespace jni = facebook::jni;
19
+
11
20
  class AndroidPlatformContext : public PlatformContext {
21
+ private:
22
+ jobject _blobModule;
23
+
12
24
  public:
13
- AndroidPlatformContext() = default;
14
- ~AndroidPlatformContext() = default;
25
+ explicit AndroidPlatformContext(jobject blobModule) : _blobModule(blobModule) {}
26
+ ~AndroidPlatformContext() {
27
+ if (_blobModule) {
28
+ JNIEnv *env = facebook::jni::Environment::current();
29
+ env->DeleteGlobalRef(_blobModule);
30
+ _blobModule = nullptr;
31
+ }
32
+ }
15
33
 
16
34
  wgpu::Surface makeSurface(wgpu::Instance instance, void *window, int width,
17
35
  int height) override {
@@ -21,6 +39,94 @@ public:
21
39
  surfaceDescriptor.nextInChain = &androidSurfaceDesc;
22
40
  return instance.CreateSurface(&surfaceDescriptor);
23
41
  }
42
+
43
+ ImageData createImageBitmap(std::string blobId, double offset,
44
+ double size) override {
45
+ jni::Environment::ensureCurrentThreadIsAttached();
46
+
47
+ JNIEnv *env = facebook::jni::Environment::current();
48
+ if (!env) {
49
+ throw std::runtime_error("Couldn't get JNI environment");
50
+ }
51
+
52
+ // Use the BlobModule instance from _blobModule
53
+ if (!_blobModule) {
54
+ throw std::runtime_error("BlobModule instance is null");
55
+ }
56
+
57
+ // Get the resolve method ID
58
+ jclass blobModuleClass = env->GetObjectClass(_blobModule);
59
+ if (!blobModuleClass) {
60
+ throw std::runtime_error("Couldn't find BlobModule class");
61
+ }
62
+
63
+ jmethodID resolveMethod = env->GetMethodID(blobModuleClass, "resolve",
64
+ "(Ljava/lang/String;II)[B");
65
+ if (!resolveMethod) {
66
+ throw std::runtime_error("Couldn't find resolve method in BlobModule");
67
+ }
68
+
69
+ // Resolve the blob data
70
+ jstring jBlobId = env->NewStringUTF(blobId.c_str());
71
+ jbyteArray blobData = (jbyteArray)env->CallObjectMethod(
72
+ _blobModule, resolveMethod, jBlobId, static_cast<jint>(offset),
73
+ static_cast<jint>(size));
74
+ env->DeleteLocalRef(jBlobId);
75
+
76
+ if (!blobData) {
77
+ throw std::runtime_error("Couldn't retrieve blob data");
78
+ }
79
+
80
+ // Create a Bitmap from the blob data
81
+ jclass bitmapFactoryClass =
82
+ env->FindClass("android/graphics/BitmapFactory");
83
+ jmethodID decodeByteArrayMethod =
84
+ env->GetStaticMethodID(bitmapFactoryClass, "decodeByteArray",
85
+ "([BII)Landroid/graphics/Bitmap;");
86
+ jint blobLength = env->GetArrayLength(blobData);
87
+ jobject bitmap = env->CallStaticObjectMethod(
88
+ bitmapFactoryClass, decodeByteArrayMethod, blobData, 0, blobLength);
89
+
90
+ if (!bitmap) {
91
+ env->DeleteLocalRef(blobData);
92
+ throw std::runtime_error("Couldn't decode image");
93
+ }
94
+
95
+ // Get bitmap info
96
+ AndroidBitmapInfo bitmapInfo;
97
+ if (AndroidBitmap_getInfo(env, bitmap, &bitmapInfo) !=
98
+ ANDROID_BITMAP_RESULT_SUCCESS) {
99
+ env->DeleteLocalRef(blobData);
100
+ env->DeleteLocalRef(bitmap);
101
+ throw std::runtime_error("Couldn't get bitmap info");
102
+ }
103
+
104
+ // Lock the bitmap pixels
105
+ void *bitmapPixels;
106
+ if (AndroidBitmap_lockPixels(env, bitmap, &bitmapPixels) !=
107
+ ANDROID_BITMAP_RESULT_SUCCESS) {
108
+ env->DeleteLocalRef(blobData);
109
+ env->DeleteLocalRef(bitmap);
110
+ throw std::runtime_error("Couldn't lock bitmap pixels");
111
+ }
112
+
113
+ // Copy the bitmap data
114
+ std::vector<uint8_t> imageData(bitmapInfo.height * bitmapInfo.stride);
115
+ memcpy(imageData.data(), bitmapPixels, imageData.size());
116
+
117
+ // Unlock the bitmap pixels
118
+ AndroidBitmap_unlockPixels(env, bitmap);
119
+
120
+ // Clean up JNI references
121
+ env->DeleteLocalRef(blobData);
122
+ env->DeleteLocalRef(bitmap);
123
+
124
+ ImageData result;
125
+ result.width = static_cast<int>(bitmapInfo.width);
126
+ result.height = static_cast<int>(bitmapInfo.height);
127
+ result.data = imageData;
128
+ return result;
129
+ }
24
130
  };
25
131
 
26
132
  } // namespace rnwgpu
@@ -17,9 +17,12 @@
17
17
  std::shared_ptr<rnwgpu::RNWebGPUManager> manager;
18
18
 
19
19
  extern "C" JNIEXPORT void JNICALL Java_com_webgpu_WebGPUModule_initializeNative(
20
- JNIEnv *env, jobject /* this */, jlong jsRuntime, jobject jsInvokerHolder) {
20
+ JNIEnv *env, jobject /* this */, jlong jsRuntime, jobject jsInvokerHolder,
21
+ jobject blobModule) {
21
22
  auto runtime = reinterpret_cast<facebook::jsi::Runtime *>(jsRuntime);
22
- auto platformContext = std::make_shared<rnwgpu::AndroidPlatformContext>();
23
+ jobject globalBlobModule = env->NewGlobalRef(blobModule);
24
+ auto platformContext =
25
+ std::make_shared<rnwgpu::AndroidPlatformContext>(globalBlobModule);
23
26
  manager = std::make_shared<rnwgpu::RNWebGPUManager>(runtime, nullptr,
24
27
  platformContext);
25
28
  }
@@ -13,6 +13,8 @@ import com.facebook.react.bridge.JavaScriptContextHolder;
13
13
  import com.facebook.react.bridge.ReactMethod;
14
14
  import com.facebook.react.common.annotations.FrameworkAPI;
15
15
  import com.facebook.react.module.annotations.ReactModule;
16
+ import com.facebook.react.modules.blob.BlobModule;
17
+ import com.facebook.react.modules.blob.BlobProvider;
16
18
  import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
17
19
  import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder;
18
20
 
@@ -37,13 +39,17 @@ public class WebGPUModule extends NativeWebGPUModuleSpec {
37
39
  ReactApplicationContext context = getReactApplicationContext();
38
40
  JavaScriptContextHolder jsContext = context.getJavaScriptContextHolder();
39
41
  CallInvokerHolder callInvokerHolder = context.getCatalystInstance().getJSCallInvokerHolder();
40
- initializeNative(jsContext.get(), (CallInvokerHolderImpl) callInvokerHolder);
42
+ BlobModule blobModule = getReactApplicationContext().getNativeModule(BlobModule.class);
43
+ if (blobModule == null) {
44
+ throw new RuntimeException("React Native's BlobModule was not found!");
45
+ }
46
+ initializeNative(jsContext.get(), (CallInvokerHolderImpl) callInvokerHolder, blobModule);
41
47
  return true;
42
48
  }
43
49
 
44
50
  @OptIn(markerClass = FrameworkAPI.class)
45
51
  @DoNotStrip
46
- private native void initializeNative(long jsRuntime, CallInvokerHolderImpl jsInvoker);
52
+ private native void initializeNative(long jsRuntime, CallInvokerHolderImpl jsInvoker, BlobModule blobModule);
47
53
 
48
54
  @ReactMethod(isBlockingSynchronousMethod = true)
49
55
  public boolean createSurfaceContext(double contextId) {
@@ -1,9 +1,20 @@
1
1
  #pragma once
2
2
 
3
+ #include <memory>
4
+ #include <string>
5
+ #include <vector>
6
+
3
7
  #include "webgpu/webgpu_cpp.h"
4
8
 
5
9
  namespace rnwgpu {
6
10
 
11
+ struct ImageData {
12
+ std::vector<uint8_t> data;
13
+ size_t width;
14
+ size_t height;
15
+ wgpu::TextureFormat format;
16
+ };
17
+
7
18
  class PlatformContext {
8
19
  public:
9
20
  PlatformContext() = default;
@@ -11,6 +22,8 @@ public:
11
22
 
12
23
  virtual wgpu::Surface makeSurface(wgpu::Instance instance, void *surface,
13
24
  int width, int height) = 0;
25
+ virtual ImageData createImageBitmap(std::string blobId, double offset,
26
+ double size) = 0;
14
27
  };
15
28
 
16
- } // namespace rnwgpu
29
+ } // namespace rnwgpu
@@ -1,7 +1,7 @@
1
1
  #include "RNWebGPUManager.h"
2
2
 
3
3
  #include "GPU.h"
4
- #include "Navigator.h"
4
+ #include "RNWebGPU.h"
5
5
 
6
6
  // Enums
7
7
  #include "GPUBufferUsage.h"
@@ -22,8 +22,11 @@ RNWebGPUManager::RNWebGPUManager(
22
22
  : _jsRuntime(jsRuntime), _jsCallInvoker(jsCallInvoker),
23
23
  _platformContext(platformContext) {
24
24
 
25
- _gpu = std::make_shared<GPU>();
26
- auto navigator = std::make_shared<Navigator>(_gpu, _platformContext);
25
+ auto gpu = std::make_shared<GPU>();
26
+ auto rnWebGPU = std::make_shared<RNWebGPU>(gpu, _platformContext);
27
+ _jsRuntime->global().setProperty(
28
+ *_jsRuntime, "RNWebGPU",
29
+ jsi::Object::createFromHostObject(*_jsRuntime, rnWebGPU));
27
30
 
28
31
  auto bufferUsage = std::make_shared<GPUBufferUsage>();
29
32
  _jsRuntime->global().setProperty(
@@ -49,10 +52,6 @@ RNWebGPUManager::RNWebGPUManager(
49
52
  _jsRuntime->global().setProperty(
50
53
  *_jsRuntime, "GPUTextureUsage",
51
54
  jsi::Object::createFromHostObject(*_jsRuntime, std::move(textureUsage)));
52
-
53
- _jsRuntime->global().setProperty(
54
- *_jsRuntime, "navigator",
55
- jsi::Object::createFromHostObject(*_jsRuntime, navigator));
56
55
  }
57
56
 
58
57
  RNWebGPUManager::~RNWebGPUManager() {
@@ -60,6 +59,4 @@ RNWebGPUManager::~RNWebGPUManager() {
60
59
  _jsCallInvoker = nullptr;
61
60
  }
62
61
 
63
- std::shared_ptr<GPU> RNWebGPUManager::getGPU() { return _gpu; }
64
-
65
62
  } // namespace rnwgpu
@@ -29,13 +29,10 @@ public:
29
29
 
30
30
  SurfaceRegistry surfacesRegistry;
31
31
 
32
- std::shared_ptr<GPU> getGPU();
33
-
34
32
  private:
35
33
  jsi::Runtime *_jsRuntime;
36
34
  std::shared_ptr<facebook::react::CallInvoker> _jsCallInvoker;
37
35
  std::shared_ptr<PlatformContext> _platformContext;
38
- std::shared_ptr<GPU> _gpu;
39
36
  };
40
37
 
41
38
  } // namespace rnwgpu
@@ -10,61 +10,42 @@ namespace rnwgpu {
10
10
  std::future<std::variant<std::nullptr_t, std::shared_ptr<GPUAdapter>>>
11
11
  GPU::requestAdapter(
12
12
  std::optional<std::shared_ptr<GPURequestAdapterOptions>> options) {
13
- return std::async(
14
- std::launch::async,
15
- [this,
16
- options]() -> std::variant<std::nullptr_t, std::shared_ptr<GPUAdapter>> {
17
- wgpu::RequestAdapterOptions aOptions;
18
- Convertor conv;
19
- if (!conv(aOptions, options)) {
20
- throw std::runtime_error("Failed to convert GPUDeviceDescriptor");
21
- }
22
- wgpu::Adapter adapter = nullptr;
23
- _instance.RequestAdapter(
24
- &aOptions,
25
- [](WGPURequestAdapterStatus, WGPUAdapter cAdapter,
26
- const char *message, void *userdata) {
27
- if (message != nullptr) {
28
- fprintf(stderr, "%s", message);
29
- return;
30
- }
31
- *static_cast<wgpu::Adapter *>(userdata) =
32
- wgpu::Adapter::Acquire(cAdapter);
33
- },
34
- &adapter);
35
- if (!adapter) {
36
- return nullptr;
37
- }
13
+ std::promise<std::variant<std::nullptr_t, std::shared_ptr<GPUAdapter>>>
14
+ promise;
15
+ auto future = promise.get_future();
38
16
 
39
- return std::make_shared<GPUAdapter>(std::move(adapter), _async);
40
- });
17
+ wgpu::RequestAdapterOptions aOptions;
18
+ Convertor conv;
19
+ if (!conv(aOptions, options)) {
20
+ throw std::runtime_error("Failed to convert GPUDeviceDescriptor");
21
+ }
22
+ #ifdef __APPLE__
23
+ constexpr auto kDefaultBackendType = wgpu::BackendType::Metal;
24
+ #else
25
+ constexpr auto kDefaultBackendType = wgpu::BackendType::Vulkan;
26
+ #endif
27
+ aOptions.backendType = kDefaultBackendType;
28
+ wgpu::Adapter adapter = nullptr;
29
+ _instance.RequestAdapter(
30
+ &aOptions,
31
+ [](WGPURequestAdapterStatus, WGPUAdapter cAdapter, const char *message,
32
+ void *userdata) {
33
+ if (message != nullptr) {
34
+ fprintf(stderr, "%s", message);
35
+ return;
36
+ }
37
+ *static_cast<wgpu::Adapter *>(userdata) =
38
+ wgpu::Adapter::Acquire(cAdapter);
39
+ },
40
+ &adapter);
41
+ if (!adapter) {
42
+ promise.set_value(nullptr);
43
+ } else {
44
+ promise.set_value(std::make_shared<GPUAdapter>(std::move(adapter), _async));
45
+ }
46
+ return future;
41
47
  }
42
48
 
43
- // Async impl keeping here as a reference
44
- // std::future<std::shared_ptr<GPUAdapter>>
45
- // GPU::requestAdapter(std::shared_ptr<GPURequestAdapterOptions> options) {
46
- // return _async->runAsync([=](wgpu::Instance *instance) {
47
- // auto aOptions = options->getInstance();
48
- // wgpu::Adapter adapter = nullptr;
49
- // auto result = std::make_shared<GPUAdapter>(adapter, _async);
50
- // wgpu::RequestAdapterCallbackInfo callback;
51
- // callback.callback = [](WGPURequestAdapterStatus, WGPUAdapter cAdapter,
52
- // const char *message, void *userdata) {
53
- // if (message != nullptr) {
54
- // fprintf(stderr, "%s", message);
55
- // return;
56
- // }
57
- // *static_cast<wgpu::Adapter *>(userdata) =
58
- // wgpu::Adapter::Acquire(cAdapter);
59
- // };
60
- // callback.mode = wgpu::CallbackMode::WaitAnyOnly;
61
- // callback.userdata = &(result->_instance);
62
- // auto future = _instance.RequestAdapter(aOptions, callback);
63
- // instance->WaitAny(future, UINT64_MAX);
64
- // return result;
65
- // });
66
- // }
67
-
68
49
  std::unordered_set<std::string> GPU::getWgslLanguageFeatures() {
69
50
  auto count = _instance.EnumerateWGSLLanguageFeatures(nullptr);
70
51
  std::vector<wgpu::WGSLFeatureName> features(count);
@@ -13,100 +13,100 @@ namespace rnwgpu {
13
13
 
14
14
  std::future<std::shared_ptr<GPUDevice>> GPUAdapter::requestDevice(
15
15
  std::optional<std::shared_ptr<GPUDeviceDescriptor>> descriptor) {
16
- return std::async(std::launch::async, [this,
17
- descriptor = std::move(descriptor)]() {
18
- wgpu::Device device = nullptr;
19
- wgpu::DeviceDescriptor aDescriptor;
20
- Convertor conv;
21
- if (!conv(aDescriptor, descriptor)) {
22
- throw std::runtime_error("Failed to convert GPUDeviceDescriptor");
16
+ std::promise<std::shared_ptr<GPUDevice>> promise;
17
+ auto future = promise.get_future();
18
+ wgpu::Device device = nullptr;
19
+ wgpu::DeviceDescriptor aDescriptor;
20
+ Convertor conv;
21
+ if (!conv(aDescriptor, descriptor)) {
22
+ throw std::runtime_error("Failed to convert GPUDeviceDescriptor");
23
+ }
24
+ wgpu::DeviceLostCallbackInfo info = {
25
+ .callback = [](WGPUDevice const *device, WGPUDeviceLostReason reason,
26
+ char const *message, void *userdata) {
27
+ const char *lostReason = "";
28
+ switch (reason) {
29
+ case WGPUDeviceLostReason_Destroyed:
30
+ lostReason = "Destroyed";
31
+ break;
32
+ case WGPUDeviceLostReason_Unknown:
33
+ lostReason = "Unknown";
34
+ break;
35
+ default:
36
+ lostReason = "Unknown";
37
+ }
38
+ Logger::logToConsole("GPU Device Lost (%s): %s", lostReason, message);
39
+ }};
40
+ aDescriptor.deviceLostCallbackInfo = info;
41
+ wgpu::UncapturedErrorCallbackInfo errorInfo;
42
+ errorInfo.userdata = static_cast<void *>(_creationRuntime);
43
+ errorInfo.callback = [](WGPUErrorType type, const char *message,
44
+ void *userdata) {
45
+ auto creationRuntime = static_cast<jsi::Runtime *>(userdata);
46
+ const char *errorType = "";
47
+ switch (type) {
48
+ case WGPUErrorType_Validation:
49
+ errorType = "Validation";
50
+ break;
51
+ case WGPUErrorType_OutOfMemory:
52
+ errorType = "Out of Memory";
53
+ break;
54
+ case WGPUErrorType_Internal:
55
+ errorType = "Internal";
56
+ break;
57
+ case WGPUErrorType_Unknown:
58
+ errorType = "Unknown";
59
+ break;
60
+ default:
61
+ errorType = "Unknown";
23
62
  }
24
- wgpu::DeviceLostCallbackInfo info = {
25
- .callback = [](WGPUDevice const *device, WGPUDeviceLostReason reason,
26
- char const *message, void *userdata) {
27
- const char *lostReason = "";
28
- switch (reason) {
29
- case WGPUDeviceLostReason_Destroyed:
30
- lostReason = "Destroyed";
31
- break;
32
- case WGPUDeviceLostReason_Unknown:
33
- lostReason = "Unknown";
34
- break;
35
- default:
36
- lostReason = "Unknown";
37
- }
38
- Logger::logToConsole("GPU Device Lost (%s): %s", lostReason, message);
39
- }};
40
- aDescriptor.deviceLostCallbackInfo = info;
41
- wgpu::UncapturedErrorCallbackInfo errorInfo;
42
- errorInfo.userdata = static_cast<void *>(_creationRuntime);
43
- errorInfo.callback = [](WGPUErrorType type, const char *message,
44
- void *userdata) {
45
- auto creationRuntime = static_cast<jsi::Runtime *>(userdata);
46
- const char *errorType = "";
47
- switch (type) {
48
- case WGPUErrorType_Validation:
49
- errorType = "Validation";
50
- break;
51
- case WGPUErrorType_OutOfMemory:
52
- errorType = "Out of Memory";
53
- break;
54
- case WGPUErrorType_Internal:
55
- errorType = "Internal";
56
- break;
57
- case WGPUErrorType_Unknown:
58
- errorType = "Unknown";
59
- break;
60
- default:
61
- errorType = "Unknown";
62
- }
63
- std::string fullMessage = std::string(errorType) + ": " + message;
64
- Logger::errorToJavascriptConsole(*creationRuntime, fullMessage.c_str());
65
- };
66
- aDescriptor.uncapturedErrorCallbackInfo = errorInfo;
67
- _instance.RequestDevice(
68
- &aDescriptor,
69
- [](WGPURequestDeviceStatus status, WGPUDevice cDevice,
70
- const char *message, void *userdata) {
71
- if (message != nullptr) {
72
- fprintf(stderr, "%s", message);
73
- return;
74
- }
75
- *static_cast<wgpu::Device *>(userdata) =
76
- wgpu::Device::Acquire(cDevice);
77
- },
78
- &device);
63
+ std::string fullMessage = std::string(errorType) + ": " + message;
64
+ Logger::errorToJavascriptConsole(*creationRuntime, fullMessage.c_str());
65
+ };
66
+ aDescriptor.uncapturedErrorCallbackInfo = errorInfo;
67
+ _instance.RequestDevice(
68
+ &aDescriptor,
69
+ [](WGPURequestDeviceStatus status, WGPUDevice cDevice,
70
+ const char *message, void *userdata) {
71
+ if (message != nullptr) {
72
+ fprintf(stderr, "%s", message);
73
+ return;
74
+ }
75
+ *static_cast<wgpu::Device *>(userdata) = wgpu::Device::Acquire(cDevice);
76
+ },
77
+ &device);
79
78
 
80
- if (!device) {
81
- throw std::runtime_error("Failed to request device");
82
- }
83
- device.SetLoggingCallback(
84
- [](WGPULoggingType type, const char *message, void *userdata) {
85
- auto creationRuntime = static_cast<jsi::Runtime *>(userdata);
86
- const char *logLevel = "";
87
- switch (type) {
88
- case WGPULoggingType_Warning:
89
- logLevel = "Warning";
90
- Logger::warnToJavascriptConsole(*creationRuntime, message);
91
- break;
92
- case WGPULoggingType_Error:
93
- logLevel = "Error";
94
- Logger::errorToJavascriptConsole(*creationRuntime, message);
95
- break;
96
- case WGPULoggingType_Verbose:
97
- logLevel = "Verbose";
98
- case WGPULoggingType_Info:
99
- logLevel = "Info";
100
- default:
101
- logLevel = "Unknown";
102
- Logger::logToConsole("%s: %s", logLevel, message);
103
- }
104
- },
105
- _creationRuntime);
106
- std::string label =
107
- descriptor.has_value() ? descriptor.value()->label.value_or("") : "";
108
- return std::make_shared<GPUDevice>(std::move(device), _async, label);
109
- });
79
+ if (!device) {
80
+ throw std::runtime_error("Failed to request device");
81
+ }
82
+ device.SetLoggingCallback(
83
+ [](WGPULoggingType type, const char *message, void *userdata) {
84
+ auto creationRuntime = static_cast<jsi::Runtime *>(userdata);
85
+ const char *logLevel = "";
86
+ switch (type) {
87
+ case WGPULoggingType_Warning:
88
+ logLevel = "Warning";
89
+ Logger::warnToJavascriptConsole(*creationRuntime, message);
90
+ break;
91
+ case WGPULoggingType_Error:
92
+ logLevel = "Error";
93
+ Logger::errorToJavascriptConsole(*creationRuntime, message);
94
+ break;
95
+ case WGPULoggingType_Verbose:
96
+ logLevel = "Verbose";
97
+ case WGPULoggingType_Info:
98
+ logLevel = "Info";
99
+ default:
100
+ logLevel = "Unknown";
101
+ Logger::logToConsole("%s: %s", logLevel, message);
102
+ }
103
+ },
104
+ _creationRuntime);
105
+ std::string label =
106
+ descriptor.has_value() ? descriptor.value()->label.value_or("") : "";
107
+ promise.set_value(
108
+ std::make_shared<GPUDevice>(std::move(device), _async, label));
109
+ return future;
110
110
  }
111
111
 
112
112
  std::unordered_set<std::string> GPUAdapter::getFeatures() {
@@ -77,4 +77,4 @@ private:
77
77
  std::vector<Mapping> mappings;
78
78
  };
79
79
 
80
- } // namespace rnwgpu
80
+ } // namespace rnwgpu
@@ -86,8 +86,51 @@ std::future<void> GPUQueue::onSubmittedWorkDone() {
86
86
  void GPUQueue::copyExternalImageToTexture(
87
87
  std::shared_ptr<GPUImageCopyExternalImage> source,
88
88
  std::shared_ptr<GPUImageCopyTextureTagged> destination,
89
- std::shared_ptr<GPUExtent3D> copySize) {
90
- throw std::runtime_error("Unimplemented");
89
+ std::shared_ptr<GPUExtent3D> size) {
90
+ wgpu::ImageCopyTexture dst{};
91
+ wgpu::TextureDataLayout layout{};
92
+ wgpu::Extent3D sz{};
93
+ Convertor conv;
94
+ uint32_t bytesPerPixel =
95
+ source->source->getSize() /
96
+ (source->source->getWidth() * source->source->getHeight());
97
+ auto dataLayout = std::make_shared<GPUImageDataLayout>(GPUImageDataLayout{
98
+ std::optional<double>{0.0},
99
+ std::optional<double>{
100
+ static_cast<double>(bytesPerPixel * source->source->getWidth())},
101
+ std::optional<double>{static_cast<double>(source->source->getHeight())}});
102
+ if (!conv(dst.aspect, destination->aspect) ||
103
+ !conv(dst.mipLevel, destination->mipLevel) ||
104
+ !conv(dst.origin, destination->origin) ||
105
+ !conv(dst.texture, destination->texture) ||
106
+ !conv(layout, dataLayout) || //
107
+ !conv(sz, size)) {
108
+ throw std::runtime_error("Invalid input for GPUQueue::writeTexture()");
109
+ }
110
+
111
+ if (source->flipY) {
112
+ // Calculate the row size and total size
113
+ uint32_t rowSize = bytesPerPixel * source->source->getWidth();
114
+ uint32_t totalSize = source->source->getSize();
115
+
116
+ // Create a new buffer for the flipped data
117
+ std::vector<uint8_t> flippedData(totalSize);
118
+
119
+ // Flip the data vertically
120
+ for (uint32_t row = 0; row < source->source->getHeight(); ++row) {
121
+ std::memcpy(flippedData.data() +
122
+ (source->source->getHeight() - 1 - row) * rowSize,
123
+ static_cast<const uint8_t *>(source->source->getData()) +
124
+ row * rowSize,
125
+ rowSize);
126
+ }
127
+ // Use the flipped data for writing to texture
128
+ _instance.WriteTexture(&dst, flippedData.data(), totalSize, &layout, &sz);
129
+ } else {
130
+
131
+ _instance.WriteTexture(&dst, source->source->getData(),
132
+ source->source->getSize(), &layout, &sz);
133
+ }
91
134
  }
92
135
 
93
136
  void GPUQueue::writeTexture(std::shared_ptr<GPUImageCopyTexture> destination,
@@ -0,0 +1,34 @@
1
+ #pragma once
2
+
3
+ #include <memory>
4
+
5
+ #include "webgpu/webgpu_cpp.h"
6
+
7
+ #include "PlatformContext.h"
8
+ #include "RNFHybridObject.h"
9
+
10
+ namespace rnwgpu {
11
+
12
+ class ImageBitmap : public margelo::HybridObject {
13
+ public:
14
+ explicit ImageBitmap(ImageData &imageData)
15
+ : HybridObject("ImageBitmap"), _imageData(imageData) {}
16
+
17
+ size_t getWidth() { return _imageData.width; }
18
+
19
+ size_t getHeight() { return _imageData.height; }
20
+
21
+ void *getData() { return _imageData.data.data(); }
22
+
23
+ size_t getSize() { return _imageData.data.size(); }
24
+
25
+ void loadHybridMethods() override {
26
+ registerHybridGetter("width", &ImageBitmap::getWidth, this);
27
+ registerHybridGetter("height", &ImageBitmap::getHeight, this);
28
+ }
29
+
30
+ private:
31
+ ImageData _imageData;
32
+ };
33
+
34
+ } // namespace rnwgpu