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