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.
- package/android/cpp/AndroidPlatformContext.h +108 -2
- package/android/cpp/cpp-adapter.cpp +5 -2
- package/android/src/main/java/com/webgpu/WebGPUModule.java +8 -2
- package/cpp/rnwgpu/PlatformContext.h +14 -1
- package/cpp/rnwgpu/RNWebGPUManager.cpp +6 -9
- package/cpp/rnwgpu/RNWebGPUManager.h +0 -3
- package/cpp/rnwgpu/api/GPU.cpp +33 -52
- package/cpp/rnwgpu/api/GPUAdapter.cpp +92 -92
- package/cpp/rnwgpu/api/GPUBuffer.h +1 -1
- package/cpp/rnwgpu/api/GPUQueue.cpp +45 -2
- package/cpp/rnwgpu/api/ImageBitmap.h +34 -0
- package/cpp/rnwgpu/api/RNWebGPU.h +100 -0
- package/cpp/rnwgpu/api/descriptors/GPUImageCopyExternalImage.h +14 -4
- package/ios/IOSPlatformContext.h +3 -0
- package/ios/IOSPlatformContext.mm +50 -0
- package/ios/SurfaceUtils.mm +0 -1
- package/lib/commonjs/Canvas.js +1 -3
- package/lib/commonjs/Canvas.js.map +1 -1
- package/lib/commonjs/index.js +25 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/utils.js +39 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/module/Canvas.js +1 -3
- package/lib/module/Canvas.js.map +1 -1
- package/lib/module/index.js +14 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils.js +31 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/typescript/lib/commonjs/utils.d.ts +5 -0
- package/lib/typescript/lib/commonjs/utils.d.ts.map +1 -0
- package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
- package/lib/typescript/lib/module/WebGPUViewNativeComponent.d.ts +0 -1
- package/lib/typescript/lib/module/index.d.ts +1 -0
- package/lib/typescript/lib/module/utils.d.ts +3 -0
- package/lib/typescript/lib/module/utils.d.ts.map +1 -0
- package/lib/typescript/src/Canvas.d.ts +6 -1
- package/lib/typescript/src/Canvas.d.ts.map +1 -1
- package/lib/typescript/src/WebGPUViewNativeComponent.d.ts +0 -1
- package/lib/typescript/src/WebGPUViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/utils.d.ts +6 -0
- package/lib/typescript/src/utils.d.ts.map +1 -0
- package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
- package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
- package/libs/android/x86/libwebgpu_dawn.so +0 -0
- package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
- package/libs/ios/arm64_iphoneos/libwebgpu_dawn.a +0 -0
- package/libs/ios/arm64_iphonesimulator/libwebgpu_dawn.a +0 -0
- package/libs/ios/arm64_xros/libwebgpu_dawn.a +0 -0
- package/libs/ios/arm64_xrsimulator/libwebgpu_dawn.a +0 -0
- package/libs/ios/libwebgpu_dawn.a +0 -0
- package/libs/ios/libwebgpu_dawn.xcframework/Info.plist +36 -5
- package/libs/ios/libwebgpu_dawn.xcframework/ios-arm64/libwebgpu_dawn.a +0 -0
- package/libs/ios/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
- package/libs/ios/libwebgpu_dawn.xcframework/xros-arm64/libwebgpu_dawn.a +0 -0
- package/libs/ios/libwebgpu_dawn.xcframework/xros-arm64_x86_64-simulator/libwebgpu_dawn_visionos.a +0 -0
- package/libs/ios/libwebgpu_dawn_visionos.a +0 -0
- package/libs/ios/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
- package/libs/ios/x86_64_xrsimulator/libwebgpu_dawn.a +0 -0
- package/package.json +3 -20
- package/react-native-wgpu.podspec +1 -1
- package/src/Canvas.tsx +8 -3
- package/src/index.tsx +19 -0
- package/src/utils.ts +40 -0
- package/cpp/rnwgpu/api/ImageData.h +0 -50
- package/cpp/rnwgpu/api/Navigator.h +0 -46
- package/lib/typescript/example/src/Triangle/triangle.d.ts +0 -3
- package/lib/typescript/example/src/Triangle/triangle.d.ts.map +0 -1
- package/lib/typescript/example/src/Wireframe/Shaders.d.ts +0 -3
- package/lib/typescript/example/src/Wireframe/Shaders.d.ts.map +0 -1
- package/lib/typescript/example/src/Wireframe/models.d.ts +0 -29
- package/lib/typescript/example/src/Wireframe/models.d.ts.map +0 -1
- package/lib/typescript/example/src/components/DrawingContext.d.ts +0 -13
- package/lib/typescript/example/src/components/DrawingContext.d.ts.map +0 -1
- package/lib/typescript/example/src/components/cube.d.ts +0 -7
- package/lib/typescript/example/src/components/cube.d.ts.map +0 -1
- package/lib/typescript/example/src/components/meshes/sphere.d.ts +0 -12
- package/lib/typescript/example/src/components/meshes/sphere.d.ts.map +0 -1
- package/lib/typescript/example/src/components/meshes/teapot.d.ts +0 -6
- package/lib/typescript/example/src/components/meshes/teapot.d.ts.map +0 -1
- package/lib/typescript/example/src/components/meshes/utils.d.ts +0 -10
- 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()
|
|
14
|
-
~AndroidPlatformContext()
|
|
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
|
-
|
|
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
|
-
|
|
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 "
|
|
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
|
-
|
|
26
|
-
auto
|
|
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
|
package/cpp/rnwgpu/api/GPU.cpp
CHANGED
|
@@ -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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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() {
|
|
@@ -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>
|
|
90
|
-
|
|
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
|