react-native-webgpu 0.15.2 → 0.16.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.
- package/android/CMakeLists.txt +5 -0
- package/android/build.gradle +11 -1
- package/android/cpp/cpp-adapter.cpp +109 -11
- package/android/src/main/java/com/webgpu/SurfaceFrameRateVote.java +97 -85
- package/android/src/main/java/com/webgpu/WebGPUView.java +97 -42
- package/apple/ApplePlatformContext.h +1 -0
- package/cpp/jsi/JSICache.cpp +2 -0
- package/cpp/jsi/NativeObject.h +81 -17
- package/cpp/rnwgpu/RNWebGPUManager.cpp +51 -41
- package/cpp/rnwgpu/RNWebGPUManager.h +10 -0
- package/cpp/rnwgpu/SurfaceRegistry.h +4 -4
- package/cpp/rnwgpu/api/GPUDevice.cpp +96 -0
- package/cpp/rnwgpu/api/GPUDevice.h +22 -0
- package/cpp/rnwgpu/api/GPUError.h +1 -0
- package/cpp/rnwgpu/api/GPUExtent2D.h +56 -0
- package/cpp/rnwgpu/api/GPUExternalTexture.cpp +32 -408
- package/cpp/rnwgpu/api/GPUExternalTexture.h +12 -37
- package/cpp/rnwgpu/api/GPUInternalError.h +1 -0
- package/cpp/rnwgpu/api/GPUNativeBufferExternalTexture.h +60 -0
- package/cpp/rnwgpu/api/GPUNativeBufferTexture.h +52 -0
- package/cpp/rnwgpu/api/GPUNativeBufferWrapper.cpp +144 -0
- package/cpp/rnwgpu/api/GPUNativeBufferWrapper.h +143 -0
- package/cpp/rnwgpu/api/GPUOutOfMemoryError.h +1 -0
- package/cpp/rnwgpu/api/GPUQueue.h +1 -0
- package/cpp/rnwgpu/api/GPUSharedFence.h +1 -0
- package/cpp/rnwgpu/api/GPUSharedTextureMemory.cpp +12 -44
- package/cpp/rnwgpu/api/GPUSharedTextureMemory.h +1 -0
- package/cpp/rnwgpu/api/GPUUncapturedErrorEvent.h +1 -0
- package/cpp/rnwgpu/api/GPUValidationError.h +1 -0
- package/cpp/rnwgpu/api/NativeFrameImport.cpp +638 -0
- package/cpp/rnwgpu/api/NativeFrameImport.h +86 -0
- package/cpp/rnwgpu/api/VideoFrame.h +21 -7
- package/cpp/rnwgpu/api/descriptors/GPUExternalTextureDescriptor.h +153 -1
- package/cpp/rnwgpu/api/descriptors/GPUNativeBufferTextureDescriptor.h +55 -0
- package/cpp/rnwgpu/async/RuntimeContext.cpp +1 -0
- package/lib/commonjs/Canvas.js +51 -0
- package/lib/commonjs/Canvas.js.map +1 -1
- package/lib/commonjs/external/reanimated/registerWebGPUForReanimated.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/install.js +26 -7
- package/lib/commonjs/install.js.map +1 -1
- package/lib/module/Canvas.js +51 -0
- package/lib/module/Canvas.js.map +1 -1
- package/lib/module/external/reanimated/registerWebGPUForReanimated.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/install.js +26 -7
- package/lib/module/install.js.map +1 -1
- package/lib/typescript/lib/commonjs/Canvas.d.ts.map +1 -1
- package/lib/typescript/lib/commonjs/install.d.ts +10 -7
- package/lib/typescript/lib/commonjs/install.d.ts.map +1 -1
- package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
- package/lib/typescript/lib/module/install.d.ts.map +1 -1
- package/lib/typescript/src/Canvas.d.ts +20 -35
- package/lib/typescript/src/Canvas.d.ts.map +1 -1
- package/lib/typescript/src/external/reanimated/registerWebGPUForReanimated.d.ts +1 -0
- package/lib/typescript/src/external/reanimated/registerWebGPUForReanimated.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +4 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/install.d.ts +10 -7
- package/lib/typescript/src/install.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +34 -1
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +6 -5
- package/plugin/build/index.js +2 -1
- package/plugin/build/setMinSdkVersion.d.ts +9 -0
- package/plugin/build/setMinSdkVersion.js +25 -0
- package/plugin/build/withMinSdkVersion.d.ts +11 -0
- package/plugin/build/withMinSdkVersion.js +20 -0
- package/src/Canvas.tsx +74 -40
- package/src/external/reanimated/registerWebGPUForReanimated.ts +4 -0
- package/src/index.tsx +24 -0
- package/src/install.ts +26 -7
- package/src/types.ts +98 -1
|
@@ -2,6 +2,7 @@ package com.webgpu;
|
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
import android.os.Build;
|
|
5
|
+
import android.util.Log;
|
|
5
6
|
import android.view.Surface;
|
|
6
7
|
import android.view.View;
|
|
7
8
|
|
|
@@ -10,6 +11,7 @@ import com.facebook.react.uimanager.ThemedReactContext;
|
|
|
10
11
|
import com.facebook.react.views.view.ReactViewGroup;
|
|
11
12
|
|
|
12
13
|
public class WebGPUView extends ReactViewGroup implements WebGPUAPI {
|
|
14
|
+
private static final String TAG = "WebGPUView";
|
|
13
15
|
|
|
14
16
|
// Backing view kinds, see updateView().
|
|
15
17
|
private static final int KIND_SURFACE_VIEW = 0;
|
|
@@ -17,16 +19,22 @@ public class WebGPUView extends ReactViewGroup implements WebGPUAPI {
|
|
|
17
19
|
private static final int KIND_HARDWARE_BUFFER_VIEW = 2;
|
|
18
20
|
|
|
19
21
|
private int mContextId;
|
|
22
|
+
// Props. opaque is applied in place, and so is zOrderOnTop where Android
|
|
23
|
+
// allows it (see setZOrderOnTop); surfaceType is read once, when the
|
|
24
|
+
// backing view is created (see updateView()).
|
|
20
25
|
private boolean mOpaque = true;
|
|
21
26
|
private String mSurfaceType = "auto";
|
|
22
27
|
private boolean mZOrderOnTop = false;
|
|
23
|
-
private int mAppliedKind = -1;
|
|
24
|
-
private boolean mAppliedZOrderOnTop;
|
|
25
28
|
private WebGPUModule mModule;
|
|
29
|
+
// The backing view, created by the first prop transaction and kept, with
|
|
30
|
+
// the kind it was created with. The kind is -1 until then: it is what
|
|
31
|
+
// tells a mounted canvas apart.
|
|
26
32
|
private View mView = null;
|
|
33
|
+
private int mKind = -1;
|
|
27
34
|
// Only a SurfaceView votes: a TextureView or HardwareBufferView is
|
|
28
35
|
// composited into the window, which votes for it.
|
|
29
|
-
private final SurfaceFrameRateVote mFrameRateVote = new SurfaceFrameRateVote(
|
|
36
|
+
private final SurfaceFrameRateVote mFrameRateVote = new SurfaceFrameRateVote(
|
|
37
|
+
this, idleAfterNanos -> releaseFrameRateVoteIfIdle(mContextId, idleAfterNanos));
|
|
30
38
|
|
|
31
39
|
WebGPUView(Context context) {
|
|
32
40
|
super(context);
|
|
@@ -54,12 +62,52 @@ public class WebGPUView extends ReactViewGroup implements WebGPUAPI {
|
|
|
54
62
|
mOpaque = value;
|
|
55
63
|
}
|
|
56
64
|
|
|
65
|
+
// The backing view is chosen from the props of the first transaction and
|
|
66
|
+
// kept (see updateView()). React calls a setter again only when its prop
|
|
67
|
+
// changed, so a call on a mounted canvas is a change: the setters below
|
|
68
|
+
// apply it in place where the view can take it, else they ignore it and
|
|
69
|
+
// say so (a canvas that needs another backing view is remounted, with a
|
|
70
|
+
// new key). The JS side warns about the same changes in development (see
|
|
71
|
+
// Canvas.tsx), mirroring these rules.
|
|
72
|
+
|
|
57
73
|
public void setSurfaceType(String value) {
|
|
74
|
+
if (mKind != -1) {
|
|
75
|
+
warnIgnoredOnceMounted("android.surfaceType");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
58
78
|
mSurfaceType = value;
|
|
59
79
|
}
|
|
60
80
|
|
|
61
81
|
public void setZOrderOnTop(boolean value) {
|
|
82
|
+
if (mKind == -1) {
|
|
83
|
+
mZOrderOnTop = value;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// Only a SurfaceView has a z-order of its own: elsewhere the prop never
|
|
87
|
+
// applied, and the change is moot.
|
|
88
|
+
if (mKind != KIND_SURFACE_VIEW) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (!zOrderChangesInPlace()) {
|
|
92
|
+
warnIgnoredOnceMounted("android.zOrderOnTop");
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
62
95
|
mZOrderOnTop = value;
|
|
96
|
+
((WebGPUSurfaceView) mView).setZOrderOnTop(value);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private void warnIgnoredOnceMounted(String prop) {
|
|
100
|
+
Log.w(TAG, "Ignoring a change of " + prop + " on a mounted canvas: the backing view"
|
|
101
|
+
+ " is chosen when the canvas mounts. Remount the canvas (give it a new key)"
|
|
102
|
+
+ " to change it.");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// SurfaceView.setZOrderOnTop() moves a live surface since Android 11, for
|
|
106
|
+
// an app targeting it; before that, the surface reads it when it is
|
|
107
|
+
// created (see updateView()).
|
|
108
|
+
private boolean zOrderChangesInPlace() {
|
|
109
|
+
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
|
|
110
|
+
&& getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R;
|
|
63
111
|
}
|
|
64
112
|
|
|
65
113
|
// Resolve the backing view from the props. "auto" picks SurfaceView for an
|
|
@@ -83,41 +131,44 @@ public class WebGPUView extends ReactViewGroup implements WebGPUAPI {
|
|
|
83
131
|
}
|
|
84
132
|
|
|
85
133
|
// Apply the complete prop transaction once, after contextId and all rendering
|
|
86
|
-
// options have arrived.
|
|
87
|
-
//
|
|
88
|
-
//
|
|
134
|
+
// options have arrived. The first one creates the backing view, which is
|
|
135
|
+
// then kept: a SurfaceView must know its z-order before it attaches (before
|
|
136
|
+
// Android 11), and replacing a backing view on screen hands the canvas from
|
|
137
|
+
// one view to another, which no release of Android does without a frame of
|
|
138
|
+
// nothing, or of black, in between (the two views are composited by
|
|
139
|
+
// different frames). A canvas that needs another backing view is remounted
|
|
140
|
+
// instead. Later transactions apply the opacity in place (the setters decide
|
|
141
|
+
// what else is taken); WebGPUHardwareBufferView always composites with
|
|
142
|
+
// alpha, so there it is a no-op.
|
|
89
143
|
public void updateView() {
|
|
144
|
+
if (mKind != -1) {
|
|
145
|
+
if (mKind == KIND_TEXTURE_VIEW) {
|
|
146
|
+
((WebGPUTextureView) mView).setOpaque(mOpaque);
|
|
147
|
+
} else if (mKind == KIND_SURFACE_VIEW) {
|
|
148
|
+
((WebGPUSurfaceView) mView).setOpaque(mOpaque);
|
|
149
|
+
}
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
90
152
|
int kind = resolveKind();
|
|
91
153
|
boolean zOrderOnTop = kind == KIND_SURFACE_VIEW && mZOrderOnTop;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
mView = new WebGPUTextureView(ctx, this, mOpaque);
|
|
105
|
-
break;
|
|
106
|
-
default:
|
|
107
|
-
mView = new WebGPUSurfaceView(ctx, this, zOrderOnTop, mOpaque);
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
addView(mView);
|
|
111
|
-
// ReactViewGroup.requestLayout() is a deliberate no-op, so addView outside
|
|
112
|
-
// the layout pass never lays the child out; do it by hand or the new view
|
|
113
|
-
// stays 0x0 and never gets a surface.
|
|
114
|
-
layoutChild();
|
|
115
|
-
} else if (kind == KIND_TEXTURE_VIEW) {
|
|
116
|
-
((WebGPUTextureView) mView).setOpaque(mOpaque);
|
|
117
|
-
} else if (kind == KIND_SURFACE_VIEW) {
|
|
118
|
-
((WebGPUSurfaceView) mView).setOpaque(mOpaque);
|
|
154
|
+
mKind = kind;
|
|
155
|
+
Context ctx = getContext();
|
|
156
|
+
switch (kind) {
|
|
157
|
+
case KIND_HARDWARE_BUFFER_VIEW:
|
|
158
|
+
mView = new WebGPUHardwareBufferView(ctx, this);
|
|
159
|
+
break;
|
|
160
|
+
case KIND_TEXTURE_VIEW:
|
|
161
|
+
mView = new WebGPUTextureView(ctx, this, mOpaque);
|
|
162
|
+
break;
|
|
163
|
+
default:
|
|
164
|
+
mView = new WebGPUSurfaceView(ctx, this, zOrderOnTop, mOpaque);
|
|
165
|
+
break;
|
|
119
166
|
}
|
|
120
|
-
|
|
167
|
+
addView(mView);
|
|
168
|
+
// ReactViewGroup.requestLayout() is a deliberate no-op, so addView outside
|
|
169
|
+
// the layout pass never lays the child out; do it by hand or the new view
|
|
170
|
+
// stays 0x0 and never gets a surface.
|
|
171
|
+
layoutChild();
|
|
121
172
|
}
|
|
122
173
|
|
|
123
174
|
private void layoutChild() {
|
|
@@ -137,7 +188,7 @@ public class WebGPUView extends ReactViewGroup implements WebGPUAPI {
|
|
|
137
188
|
float density = getResources().getDisplayMetrics().density;
|
|
138
189
|
float width = getWidth() / density;
|
|
139
190
|
float height = getHeight() / density;
|
|
140
|
-
boolean votesFrameRate =
|
|
191
|
+
boolean votesFrameRate = mKind == KIND_SURFACE_VIEW;
|
|
141
192
|
if (votesFrameRate) {
|
|
142
193
|
mFrameRateVote.attach(surface);
|
|
143
194
|
}
|
|
@@ -160,12 +211,12 @@ public class WebGPUView extends ReactViewGroup implements WebGPUAPI {
|
|
|
160
211
|
}
|
|
161
212
|
|
|
162
213
|
/**
|
|
163
|
-
* Called from native (
|
|
164
|
-
*
|
|
214
|
+
* Called from native (AnimationReporter in cpp-adapter.cpp) on the thread
|
|
215
|
+
* that presents to the surface, once per animation, only for a SurfaceView.
|
|
165
216
|
*/
|
|
166
217
|
@DoNotStrip
|
|
167
|
-
void
|
|
168
|
-
mFrameRateVote.
|
|
218
|
+
void onAnimating() {
|
|
219
|
+
mFrameRateVote.onAnimating();
|
|
169
220
|
}
|
|
170
221
|
|
|
171
222
|
@Override
|
|
@@ -182,15 +233,15 @@ public class WebGPUView extends ReactViewGroup implements WebGPUAPI {
|
|
|
182
233
|
onViewDestroyed(mContextId);
|
|
183
234
|
}
|
|
184
235
|
|
|
185
|
-
//
|
|
186
|
-
// presented to this surface.
|
|
236
|
+
// reportAnimation asks native to call onAnimating() when frames start being
|
|
237
|
+
// presented to this surface back to back.
|
|
187
238
|
@DoNotStrip
|
|
188
239
|
private native void onSurfaceCreate(
|
|
189
240
|
Surface surface,
|
|
190
241
|
int contextId,
|
|
191
242
|
float width,
|
|
192
243
|
float height,
|
|
193
|
-
boolean
|
|
244
|
+
boolean reportAnimation
|
|
194
245
|
);
|
|
195
246
|
|
|
196
247
|
@DoNotStrip
|
|
@@ -207,4 +258,8 @@ public class WebGPUView extends ReactViewGroup implements WebGPUAPI {
|
|
|
207
258
|
@DoNotStrip
|
|
208
259
|
private native void onViewDestroyed(int contextId);
|
|
209
260
|
|
|
261
|
+
// See SurfaceFrameRateVote.AnimationSource.
|
|
262
|
+
@DoNotStrip
|
|
263
|
+
private native long releaseFrameRateVoteIfIdle(int contextId, long idleAfterNanos);
|
|
264
|
+
|
|
210
265
|
}
|
package/cpp/jsi/JSICache.cpp
CHANGED
package/cpp/jsi/NativeObject.h
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
#include <typeindex>
|
|
15
15
|
#include <unordered_map>
|
|
16
16
|
#include <utility>
|
|
17
|
+
#include <vector>
|
|
17
18
|
|
|
18
19
|
#include "EnforceRange.h"
|
|
19
20
|
#include "JSICache.h"
|
|
@@ -178,6 +179,14 @@ private:
|
|
|
178
179
|
* getters and Proxy traps of unrelated objects never run.
|
|
179
180
|
* - box(value): wraps the object into a BoxedWebGPUObject, branded with its
|
|
180
181
|
* class name, for unbox() on the target runtime.
|
|
182
|
+
* - installConstructors(): installs the constructor of every WebGPU class on
|
|
183
|
+
* the calling runtime, skipping the ones already there, so `instanceof`
|
|
184
|
+
* works against any class on that runtime, including classes no object of
|
|
185
|
+
* which was ever created there or crossed into it (unboxing installs only
|
|
186
|
+
* the class of the object that crosses). installWebGPU() calls it. The
|
|
187
|
+
* class list belongs to the API layer (RNWebGPUManager::installConstructors)
|
|
188
|
+
* and is handed in at construction: every API class includes this header,
|
|
189
|
+
* which therefore cannot include them back.
|
|
181
190
|
*
|
|
182
191
|
* One instance is installed on the main runtime as
|
|
183
192
|
* globalThis.__webgpuWorkletHelpers and captured by the serializer's
|
|
@@ -188,8 +197,26 @@ private:
|
|
|
188
197
|
*/
|
|
189
198
|
class WebGPUWorkletHelpers : public jsi::HostObject {
|
|
190
199
|
public:
|
|
200
|
+
using InstallConstructors = void (*)(jsi::Runtime &);
|
|
201
|
+
|
|
202
|
+
explicit WebGPUWorkletHelpers(InstallConstructors installConstructors)
|
|
203
|
+
: _installConstructors(installConstructors) {}
|
|
204
|
+
|
|
191
205
|
jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override {
|
|
192
206
|
auto propName = name.utf8(runtime);
|
|
207
|
+
if (propName == "installConstructors") {
|
|
208
|
+
auto install = _installConstructors;
|
|
209
|
+
return jsi::Function::createFromHostFunction(
|
|
210
|
+
runtime, name, 0,
|
|
211
|
+
[install](jsi::Runtime &rt, const jsi::Value & /*thisVal*/,
|
|
212
|
+
const jsi::Value * /*args*/,
|
|
213
|
+
size_t /*count*/) -> jsi::Value {
|
|
214
|
+
if (install != nullptr) {
|
|
215
|
+
install(rt);
|
|
216
|
+
}
|
|
217
|
+
return jsi::Value::undefined();
|
|
218
|
+
});
|
|
219
|
+
}
|
|
193
220
|
if (propName == "isNativeObject") {
|
|
194
221
|
return jsi::Function::createFromHostFunction(
|
|
195
222
|
runtime, name, 1,
|
|
@@ -229,11 +256,15 @@ public:
|
|
|
229
256
|
std::vector<jsi::PropNameID>
|
|
230
257
|
getPropertyNames(jsi::Runtime &runtime) override {
|
|
231
258
|
std::vector<jsi::PropNameID> names;
|
|
232
|
-
names.reserve(
|
|
259
|
+
names.reserve(3);
|
|
233
260
|
names.push_back(jsi::PropNameID::forUtf8(runtime, "isNativeObject"));
|
|
234
261
|
names.push_back(jsi::PropNameID::forUtf8(runtime, "box"));
|
|
262
|
+
names.push_back(jsi::PropNameID::forUtf8(runtime, "installConstructors"));
|
|
235
263
|
return names;
|
|
236
264
|
}
|
|
265
|
+
|
|
266
|
+
private:
|
|
267
|
+
InstallConstructors _installConstructors;
|
|
237
268
|
};
|
|
238
269
|
|
|
239
270
|
/**
|
|
@@ -377,6 +408,9 @@ public:
|
|
|
377
408
|
* The constructor throws if called directly (these objects are only
|
|
378
409
|
* created internally by the native code).
|
|
379
410
|
*
|
|
411
|
+
* Idempotent per runtime: once the global exists there, later calls return
|
|
412
|
+
* without touching it, so the constructor object keeps its identity.
|
|
413
|
+
*
|
|
380
414
|
* Also registers this class with NativeObjectRegistry so that
|
|
381
415
|
* BoxedWebGPUObject::unbox() can rebuild its objects on secondary runtimes.
|
|
382
416
|
*/
|
|
@@ -393,10 +427,9 @@ public:
|
|
|
393
427
|
if (instance == nullptr) {
|
|
394
428
|
throw jsi::JSError(rt, "Invalid boxed native object state");
|
|
395
429
|
}
|
|
396
|
-
// The constructor makes `instanceof` work on this runtime too
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
}
|
|
430
|
+
// The constructor makes `instanceof` work on this runtime too
|
|
431
|
+
// (a no-op once it is installed there).
|
|
432
|
+
Derived::installConstructor(rt);
|
|
400
433
|
// Unboxing hands back the wrapper cached for the target runtime,
|
|
401
434
|
// creating it on first use. Keep the runtime the object was
|
|
402
435
|
// originally created on: async native code (GPUDevice error/lost
|
|
@@ -414,6 +447,14 @@ public:
|
|
|
414
447
|
|
|
415
448
|
installPrototype(runtime);
|
|
416
449
|
|
|
450
|
+
// Once per runtime. installWebGPU() runs this at the top of every worklet
|
|
451
|
+
// invocation, and reinstalling would replace the global with a new
|
|
452
|
+
// function object each time (`const C = GPUBuffer; C === GPUBuffer`
|
|
453
|
+
// would be false).
|
|
454
|
+
if (runtime.global().hasProperty(runtime, Derived::CLASS_NAME)) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
|
|
417
458
|
auto *prototype = getCachedPrototype(runtime);
|
|
418
459
|
if (prototype == nullptr) {
|
|
419
460
|
return;
|
|
@@ -640,19 +681,26 @@ protected:
|
|
|
640
681
|
rt, std::move(result));
|
|
641
682
|
}
|
|
642
683
|
});
|
|
684
|
+
defineGetter(runtime, prototype, name, getterFunc);
|
|
685
|
+
}
|
|
643
686
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
687
|
+
/**
|
|
688
|
+
* Install a getter whose native implementation builds the JS value itself,
|
|
689
|
+
* from the calling jsi::Runtime: for values no JSIConverter produces (null
|
|
690
|
+
* or a BigInt, say).
|
|
691
|
+
*/
|
|
692
|
+
static void installGetter(jsi::Runtime &runtime, jsi::Object &prototype,
|
|
693
|
+
const char *name,
|
|
694
|
+
jsi::Value (Derived::*getter)(jsi::Runtime &)) {
|
|
695
|
+
auto getterFunc = jsi::Function::createFromHostFunction(
|
|
696
|
+
runtime, jsi::PropNameID::forUtf8(runtime, std::string("get_") + name),
|
|
697
|
+
0,
|
|
698
|
+
[getter](jsi::Runtime &rt, const jsi::Value &thisVal,
|
|
699
|
+
const jsi::Value *args, size_t count) -> jsi::Value {
|
|
700
|
+
auto native = Derived::fromValue(rt, thisVal);
|
|
701
|
+
return (native.get()->*getter)(rt);
|
|
702
|
+
});
|
|
703
|
+
defineGetter(runtime, prototype, name, getterFunc);
|
|
656
704
|
}
|
|
657
705
|
|
|
658
706
|
/**
|
|
@@ -757,6 +805,22 @@ protected:
|
|
|
757
805
|
}
|
|
758
806
|
|
|
759
807
|
private:
|
|
808
|
+
// Use Object.defineProperty to create a proper getter
|
|
809
|
+
static void defineGetter(jsi::Runtime &runtime, jsi::Object &prototype,
|
|
810
|
+
const char *name, const jsi::Function &getterFunc) {
|
|
811
|
+
auto objectCtor = runtime.global().getPropertyAsObject(runtime, "Object");
|
|
812
|
+
auto defineProperty =
|
|
813
|
+
objectCtor.getPropertyAsFunction(runtime, "defineProperty");
|
|
814
|
+
|
|
815
|
+
jsi::Object descriptor(runtime);
|
|
816
|
+
descriptor.setProperty(runtime, "get", getterFunc);
|
|
817
|
+
descriptor.setProperty(runtime, "enumerable", true);
|
|
818
|
+
descriptor.setProperty(runtime, "configurable", true);
|
|
819
|
+
|
|
820
|
+
defineProperty.call(runtime, prototype,
|
|
821
|
+
jsi::String::createFromUtf8(runtime, name), descriptor);
|
|
822
|
+
}
|
|
823
|
+
|
|
760
824
|
// Helper to call a method that takes the calling jsi::Runtime as its first
|
|
761
825
|
// parameter, with JSI argument conversion for the rest and JSI conversion of
|
|
762
826
|
// the result.
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
#include "GPUError.h"
|
|
23
23
|
#include "GPUExternalTexture.h"
|
|
24
24
|
#include "GPUInternalError.h"
|
|
25
|
+
#include "GPUNativeBufferExternalTexture.h"
|
|
26
|
+
#include "GPUNativeBufferTexture.h"
|
|
25
27
|
#include "GPUOutOfMemoryError.h"
|
|
26
28
|
#include "GPUPipelineLayout.h"
|
|
27
29
|
#include "GPUQuerySet.h"
|
|
@@ -85,43 +87,7 @@ RNWebGPUManager::RNWebGPUManager(
|
|
|
85
87
|
RNWebGPU::create(*_jsRuntime, rnWebGPU));
|
|
86
88
|
|
|
87
89
|
// Install constructors for instanceof support
|
|
88
|
-
|
|
89
|
-
GPUAdapter::installConstructor(*_jsRuntime);
|
|
90
|
-
GPUAdapterInfo::installConstructor(*_jsRuntime);
|
|
91
|
-
GPUBindGroup::installConstructor(*_jsRuntime);
|
|
92
|
-
GPUBindGroupLayout::installConstructor(*_jsRuntime);
|
|
93
|
-
GPUBuffer::installConstructor(*_jsRuntime);
|
|
94
|
-
GPUCanvasContext::installConstructor(*_jsRuntime);
|
|
95
|
-
GPUCommandBuffer::installConstructor(*_jsRuntime);
|
|
96
|
-
GPUCommandEncoder::installConstructor(*_jsRuntime);
|
|
97
|
-
GPUCompilationInfo::installConstructor(*_jsRuntime);
|
|
98
|
-
GPUCompilationMessage::installConstructor(*_jsRuntime);
|
|
99
|
-
GPUComputePassEncoder::installConstructor(*_jsRuntime);
|
|
100
|
-
GPUComputePipeline::installConstructor(*_jsRuntime);
|
|
101
|
-
GPUDevice::installConstructor(*_jsRuntime);
|
|
102
|
-
GPUDeviceLostInfo::installConstructor(*_jsRuntime);
|
|
103
|
-
GPUError::installConstructor(*_jsRuntime);
|
|
104
|
-
GPUExternalTexture::installConstructor(*_jsRuntime);
|
|
105
|
-
GPUInternalError::installConstructor(*_jsRuntime);
|
|
106
|
-
GPUOutOfMemoryError::installConstructor(*_jsRuntime);
|
|
107
|
-
GPUValidationError::installConstructor(*_jsRuntime);
|
|
108
|
-
GPUUncapturedErrorEvent::installConstructor(*_jsRuntime);
|
|
109
|
-
GPUPipelineLayout::installConstructor(*_jsRuntime);
|
|
110
|
-
GPUQuerySet::installConstructor(*_jsRuntime);
|
|
111
|
-
GPUQueue::installConstructor(*_jsRuntime);
|
|
112
|
-
GPURenderBundle::installConstructor(*_jsRuntime);
|
|
113
|
-
GPURenderBundleEncoder::installConstructor(*_jsRuntime);
|
|
114
|
-
GPURenderPassEncoder::installConstructor(*_jsRuntime);
|
|
115
|
-
GPURenderPipeline::installConstructor(*_jsRuntime);
|
|
116
|
-
GPUSampler::installConstructor(*_jsRuntime);
|
|
117
|
-
GPUSharedFence::installConstructor(*_jsRuntime);
|
|
118
|
-
GPUSharedTextureMemory::installConstructor(*_jsRuntime);
|
|
119
|
-
GPUShaderModule::installConstructor(*_jsRuntime);
|
|
120
|
-
GPUSupportedLimits::installConstructor(*_jsRuntime);
|
|
121
|
-
GPUTexture::installConstructor(*_jsRuntime);
|
|
122
|
-
GPUTextureView::installConstructor(*_jsRuntime);
|
|
123
|
-
VideoFrame::installConstructor(*_jsRuntime);
|
|
124
|
-
VideoPlayer::installConstructor(*_jsRuntime);
|
|
90
|
+
installConstructors(*_jsRuntime);
|
|
125
91
|
|
|
126
92
|
// Install constant objects as plain JS objects with own properties
|
|
127
93
|
_jsRuntime->global().setProperty(*_jsRuntime, "GPUBufferUsage",
|
|
@@ -140,14 +106,58 @@ RNWebGPUManager::RNWebGPUManager(
|
|
|
140
106
|
installWebGPUWorkletHelpers(*_jsRuntime);
|
|
141
107
|
}
|
|
142
108
|
|
|
109
|
+
void RNWebGPUManager::installConstructors(jsi::Runtime &runtime) {
|
|
110
|
+
GPU::installConstructor(runtime);
|
|
111
|
+
GPUAdapter::installConstructor(runtime);
|
|
112
|
+
GPUAdapterInfo::installConstructor(runtime);
|
|
113
|
+
GPUBindGroup::installConstructor(runtime);
|
|
114
|
+
GPUBindGroupLayout::installConstructor(runtime);
|
|
115
|
+
GPUBuffer::installConstructor(runtime);
|
|
116
|
+
GPUCanvasContext::installConstructor(runtime);
|
|
117
|
+
GPUCommandBuffer::installConstructor(runtime);
|
|
118
|
+
GPUCommandEncoder::installConstructor(runtime);
|
|
119
|
+
GPUCompilationInfo::installConstructor(runtime);
|
|
120
|
+
GPUCompilationMessage::installConstructor(runtime);
|
|
121
|
+
GPUComputePassEncoder::installConstructor(runtime);
|
|
122
|
+
GPUComputePipeline::installConstructor(runtime);
|
|
123
|
+
GPUDevice::installConstructor(runtime);
|
|
124
|
+
GPUDeviceLostInfo::installConstructor(runtime);
|
|
125
|
+
GPUError::installConstructor(runtime);
|
|
126
|
+
GPUExternalTexture::installConstructor(runtime);
|
|
127
|
+
GPUNativeBufferExternalTexture::installConstructor(runtime);
|
|
128
|
+
GPUNativeBufferTexture::installConstructor(runtime);
|
|
129
|
+
GPUInternalError::installConstructor(runtime);
|
|
130
|
+
GPUOutOfMemoryError::installConstructor(runtime);
|
|
131
|
+
GPUValidationError::installConstructor(runtime);
|
|
132
|
+
GPUUncapturedErrorEvent::installConstructor(runtime);
|
|
133
|
+
GPUPipelineLayout::installConstructor(runtime);
|
|
134
|
+
GPUQuerySet::installConstructor(runtime);
|
|
135
|
+
GPUQueue::installConstructor(runtime);
|
|
136
|
+
GPURenderBundle::installConstructor(runtime);
|
|
137
|
+
GPURenderBundleEncoder::installConstructor(runtime);
|
|
138
|
+
GPURenderPassEncoder::installConstructor(runtime);
|
|
139
|
+
GPURenderPipeline::installConstructor(runtime);
|
|
140
|
+
GPUSampler::installConstructor(runtime);
|
|
141
|
+
GPUSharedFence::installConstructor(runtime);
|
|
142
|
+
GPUSharedTextureMemory::installConstructor(runtime);
|
|
143
|
+
GPUShaderModule::installConstructor(runtime);
|
|
144
|
+
GPUSupportedLimits::installConstructor(runtime);
|
|
145
|
+
GPUTexture::installConstructor(runtime);
|
|
146
|
+
GPUTextureView::installConstructor(runtime);
|
|
147
|
+
VideoFrame::installConstructor(runtime);
|
|
148
|
+
VideoPlayer::installConstructor(runtime);
|
|
149
|
+
}
|
|
150
|
+
|
|
143
151
|
void RNWebGPUManager::installWebGPUWorkletHelpers(jsi::Runtime &runtime) {
|
|
144
|
-
// The serializer worklets capture this object by
|
|
145
|
-
// HostObject to every runtime by reference, so
|
|
146
|
-
// main runtime, is enough (see
|
|
152
|
+
// The serializer worklets and installWebGPU() capture this object by
|
|
153
|
+
// closure; worklets passes a HostObject to every runtime by reference, so
|
|
154
|
+
// installing it here, on the main runtime, is enough (see
|
|
155
|
+
// WebGPUWorkletHelpers).
|
|
147
156
|
runtime.global().setProperty(
|
|
148
157
|
runtime, "__webgpuWorkletHelpers",
|
|
149
158
|
jsi::Object::createFromHostObject(
|
|
150
|
-
runtime, std::make_shared<WebGPUWorkletHelpers>(
|
|
159
|
+
runtime, std::make_shared<WebGPUWorkletHelpers>(
|
|
160
|
+
&RNWebGPUManager::installConstructors)));
|
|
151
161
|
}
|
|
152
162
|
|
|
153
163
|
void RNWebGPUManager::flushPendingSurfaceTransition(
|
|
@@ -35,6 +35,16 @@ public:
|
|
|
35
35
|
*/
|
|
36
36
|
static void installWebGPUWorkletHelpers(jsi::Runtime &runtime);
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Installs the constructor of every WebGPU API class on `runtime` (see
|
|
40
|
+
* NativeObject::installConstructor), skipping the ones already there. Runs
|
|
41
|
+
* on the main runtime at startup and, through
|
|
42
|
+
* __webgpuWorkletHelpers.installConstructors(), on every runtime that calls
|
|
43
|
+
* installWebGPU(). RNWebGPU itself is not part of it: that global is the
|
|
44
|
+
* module instance, main runtime only.
|
|
45
|
+
*/
|
|
46
|
+
static void installConstructors(jsi::Runtime &runtime);
|
|
47
|
+
|
|
38
48
|
/**
|
|
39
49
|
* Applies a surface attach latched by the platform UI thread (see
|
|
40
50
|
* SurfaceInfo::applyPendingAttach) from the JS thread. Surface attaches are
|
|
@@ -59,7 +59,7 @@ struct Size {
|
|
|
59
59
|
using NativeSurfaceReleaser = std::function<void(void *)>;
|
|
60
60
|
|
|
61
61
|
#if defined(__ANDROID__)
|
|
62
|
-
// --- AHB-pool presentation mode (
|
|
62
|
+
// --- AHB-pool presentation mode (WebGPUNativeBufferView)
|
|
63
63
|
// -----------------------------
|
|
64
64
|
//
|
|
65
65
|
// A third presentation backend (besides the on-screen wgpu::Surface swapchain
|
|
@@ -71,7 +71,7 @@ using NativeSurfaceReleaser = std::function<void(void *)>;
|
|
|
71
71
|
// like the swapchain, so the canvas texture always matches the app's other
|
|
72
72
|
// attachments (e.g. its depth texture).
|
|
73
73
|
|
|
74
|
-
#define RNWGPU_LOG_TAG "
|
|
74
|
+
#define RNWGPU_LOG_TAG "WebGPUNativeBufferView"
|
|
75
75
|
// Failure / anomaly reporting only (never per-frame).
|
|
76
76
|
#define RNWGPU_POOL_WARN(...) \
|
|
77
77
|
__android_log_print(ANDROID_LOG_WARN, RNWGPU_LOG_TAG, __VA_ARGS__)
|
|
@@ -435,7 +435,7 @@ public:
|
|
|
435
435
|
bool hasNativeSurface() {
|
|
436
436
|
std::shared_lock<std::shared_mutex> lock(_mutex);
|
|
437
437
|
#if defined(__ANDROID__)
|
|
438
|
-
// A
|
|
438
|
+
// A WebGPUNativeBufferView in pool mode owns presentation the same way a
|
|
439
439
|
// surface-backed view does, and retires the entry on its own teardown.
|
|
440
440
|
if (_poolMode.load()) {
|
|
441
441
|
return true;
|
|
@@ -725,7 +725,7 @@ private:
|
|
|
725
725
|
{
|
|
726
726
|
std::unique_lock<std::shared_mutex> lock(_mutex);
|
|
727
727
|
#if defined(__ANDROID__)
|
|
728
|
-
// Leaving pool mode (the
|
|
728
|
+
// Leaving pool mode (the WebGPUNativeBufferView detached): drop the
|
|
729
729
|
// pool. A configured context keeps rendering into the offscreen
|
|
730
730
|
// fallback, exactly like the surface path.
|
|
731
731
|
if (_poolMode.load()) {
|