react-native-webgpu 0.15.1 → 0.16.0
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/cpp/cpp-adapter.cpp +160 -49
- package/android/src/main/java/com/webgpu/SurfaceFrameRateVote.java +196 -0
- package/android/src/main/java/com/webgpu/WebGPUView.java +29 -2
- package/apple/ApplePlatformContext.h +1 -0
- package/cpp/jsi/JSICache.cpp +2 -0
- package/cpp/jsi/NativeObject.h +36 -12
- package/cpp/rnwgpu/RNWebGPUManager.cpp +4 -0
- package/cpp/rnwgpu/SurfaceRegistry.h +28 -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 +142 -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.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/Canvas.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/Canvas.d.ts +2 -31
- package/lib/typescript/src/Canvas.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/types.d.ts +33 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Canvas.tsx +3 -36
- package/src/index.tsx +24 -0
- package/src/types.ts +97 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <memory>
|
|
4
|
+
#include <string>
|
|
5
|
+
#include <utility>
|
|
6
|
+
|
|
7
|
+
#include "webgpu/webgpu_cpp.h"
|
|
8
|
+
|
|
9
|
+
#include "GPUNativeBufferWrapper.h"
|
|
10
|
+
#include "GPUTexture.h"
|
|
11
|
+
#include "VideoFrame.h"
|
|
12
|
+
|
|
13
|
+
namespace rnwgpu {
|
|
14
|
+
|
|
15
|
+
namespace jsi = facebook::jsi;
|
|
16
|
+
|
|
17
|
+
// A native color buffer (an RGBA / R8 / ... AHardwareBuffer, a BGRA IOSurface)
|
|
18
|
+
// imported once as a regular texture, with the access window of each use
|
|
19
|
+
// explicit: GPUHardwareBufferTexture of Dawn's Android layer. Created by
|
|
20
|
+
// GPUDevice.createNativeBufferTexture().
|
|
21
|
+
class GPUNativeBufferTexture
|
|
22
|
+
: public GPUNativeBufferWrapper<GPUNativeBufferTexture, GPUTexture> {
|
|
23
|
+
public:
|
|
24
|
+
static constexpr const char *CLASS_NAME = "GPUNativeBufferTexture";
|
|
25
|
+
|
|
26
|
+
GPUNativeBufferTexture(wgpu::Device device, wgpu::SharedTextureMemory memory,
|
|
27
|
+
std::shared_ptr<GPUTexture> texture,
|
|
28
|
+
std::shared_ptr<VideoFrame> source, std::string label)
|
|
29
|
+
: GPUNativeBufferWrapper(std::move(device), std::move(memory),
|
|
30
|
+
texture->get(), texture, std::move(source),
|
|
31
|
+
std::move(label)) {}
|
|
32
|
+
|
|
33
|
+
// The texture that aliases the buffer. Bind it only between beginAccess()
|
|
34
|
+
// and endAccess().
|
|
35
|
+
std::shared_ptr<GPUTexture> getTexture() { return _wrapped; }
|
|
36
|
+
|
|
37
|
+
// Releases the texture and the import (see NativeBufferAccess::destroy).
|
|
38
|
+
void destroy() {
|
|
39
|
+
_access.destroy();
|
|
40
|
+
_wrapped->destroy();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {
|
|
44
|
+
defineWrapperPrototype(runtime, prototype);
|
|
45
|
+
installGetter(runtime, prototype, "texture",
|
|
46
|
+
&GPUNativeBufferTexture::getTexture);
|
|
47
|
+
installMethod(runtime, prototype, "destroy",
|
|
48
|
+
&GPUNativeBufferTexture::destroy);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
} // namespace rnwgpu
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#include "GPUNativeBufferWrapper.h"
|
|
2
|
+
|
|
3
|
+
#include <cstdint>
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <stdexcept>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <utility>
|
|
8
|
+
#include <vector>
|
|
9
|
+
|
|
10
|
+
#include "DestroyedError.h"
|
|
11
|
+
#include "GPUSharedFence.h"
|
|
12
|
+
#include "GPUSharedFenceState.h"
|
|
13
|
+
#include "NativeFrameImport.h"
|
|
14
|
+
|
|
15
|
+
namespace rnwgpu {
|
|
16
|
+
|
|
17
|
+
NativeBufferAccess::NativeBufferAccess(const char *className,
|
|
18
|
+
wgpu::Device device,
|
|
19
|
+
wgpu::SharedTextureMemory memory,
|
|
20
|
+
wgpu::Texture texture,
|
|
21
|
+
std::shared_ptr<VideoFrame> source,
|
|
22
|
+
std::string label)
|
|
23
|
+
: _className(className), _device(std::move(device)),
|
|
24
|
+
_memory(std::move(memory)), _texture(std::move(texture)),
|
|
25
|
+
_source(std::move(source)), _label(std::move(label)) {}
|
|
26
|
+
|
|
27
|
+
// The garbage-collection fallback: releases without reporting, there is no
|
|
28
|
+
// one left to report to.
|
|
29
|
+
NativeBufferAccess::~NativeBufferAccess() { release(false); }
|
|
30
|
+
|
|
31
|
+
void NativeBufferAccess::setLabel(const std::string &label) {
|
|
32
|
+
_label = label;
|
|
33
|
+
if (_memory) {
|
|
34
|
+
_memory.SetLabel(_label.c_str());
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
void NativeBufferAccess::injectDestroyedError(const char *method) {
|
|
39
|
+
reportDestroyedUse(_device, _className, _label, method);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void NativeBufferAccess::beginAccess(jsi::Runtime &runtime,
|
|
43
|
+
const jsi::Value *args, size_t count) {
|
|
44
|
+
const std::string caller = std::string(_className) + "::beginAccess";
|
|
45
|
+
// Fails like an access Dawn rejects: a validation error, then the throw.
|
|
46
|
+
if (!_memory) {
|
|
47
|
+
injectDestroyedError("beginAccess");
|
|
48
|
+
throw jsi::JSError(runtime, caller + "(): the wrapper was destroyed");
|
|
49
|
+
}
|
|
50
|
+
// Built in lockstep so fenceCount covers both arrays, and kept in locals so
|
|
51
|
+
// the raw pointers outlive the synchronous BeginAccess() below.
|
|
52
|
+
std::vector<wgpu::SharedFence> fences;
|
|
53
|
+
std::vector<uint64_t> signaledValues;
|
|
54
|
+
if (count > 0 && !args[0].isUndefined() && !args[0].isNull()) {
|
|
55
|
+
auto states = JSIConverter<
|
|
56
|
+
std::vector<std::shared_ptr<GPUSharedFenceState>>>::fromJSI(runtime,
|
|
57
|
+
args[0],
|
|
58
|
+
false);
|
|
59
|
+
for (const auto &state : states) {
|
|
60
|
+
if (!state || !state->fence) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
auto fence = state->fence->get();
|
|
64
|
+
if (!fence) {
|
|
65
|
+
state->fence->injectDestroyedError("beginAccess");
|
|
66
|
+
throw jsi::JSError(runtime, caller + "(): a fence was destroyed");
|
|
67
|
+
}
|
|
68
|
+
fences.push_back(std::move(fence));
|
|
69
|
+
signaledValues.push_back(state->signaledValue);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
native_frame::beginAccess(_memory, _texture, true, fences, signaledValues,
|
|
74
|
+
caller.c_str());
|
|
75
|
+
} catch (const std::exception &e) {
|
|
76
|
+
throw jsi::JSError(runtime, e.what());
|
|
77
|
+
}
|
|
78
|
+
_accessOpen = true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
jsi::Value NativeBufferAccess::endAccess(jsi::Runtime &runtime) {
|
|
82
|
+
const std::string caller = std::string(_className) + "::endAccess";
|
|
83
|
+
if (!_memory) {
|
|
84
|
+
injectDestroyedError("endAccess");
|
|
85
|
+
throw jsi::JSError(runtime, caller + "(): the wrapper was destroyed");
|
|
86
|
+
}
|
|
87
|
+
wgpu::SharedTextureMemoryEndAccessState state{};
|
|
88
|
+
try {
|
|
89
|
+
native_frame::endAccess(_memory, _texture, &state, caller.c_str());
|
|
90
|
+
} catch (const std::exception &e) {
|
|
91
|
+
throw jsi::JSError(runtime, e.what());
|
|
92
|
+
}
|
|
93
|
+
_accessOpen = false;
|
|
94
|
+
|
|
95
|
+
wgpu::SharedFence fence;
|
|
96
|
+
uint64_t signaledValue = 0;
|
|
97
|
+
bool hasFence = false;
|
|
98
|
+
try {
|
|
99
|
+
hasFence = native_frame::mergeFences(_device, state, &fence, &signaledValue,
|
|
100
|
+
caller.c_str());
|
|
101
|
+
} catch (const std::exception &e) {
|
|
102
|
+
throw jsi::JSError(runtime, e.what());
|
|
103
|
+
}
|
|
104
|
+
if (!hasFence) {
|
|
105
|
+
return jsi::Value::null();
|
|
106
|
+
}
|
|
107
|
+
jsi::Object result(runtime);
|
|
108
|
+
result.setProperty(
|
|
109
|
+
runtime, "fence",
|
|
110
|
+
GPUSharedFence::create(runtime, std::make_shared<GPUSharedFence>(
|
|
111
|
+
_device, std::move(fence), "")));
|
|
112
|
+
result.setProperty(runtime, "signaledValue",
|
|
113
|
+
jsi::BigInt::fromUint64(runtime, signaledValue));
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
void NativeBufferAccess::destroy() { release(true); }
|
|
118
|
+
|
|
119
|
+
void NativeBufferAccess::release(bool reportOpenAccess) {
|
|
120
|
+
if (!_memory) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (_accessOpen) {
|
|
124
|
+
if (reportOpenAccess) {
|
|
125
|
+
// Dawn's contract is an endAccess() for every beginAccess(). Report the
|
|
126
|
+
// misuse, and end the access anyway: the wrapper owns the texture, so
|
|
127
|
+
// an access left open would keep the buffer from its producer for good.
|
|
128
|
+
auto message = "Destroyed " + describeDestroyed(_className, _label) +
|
|
129
|
+
" with an access still open: call endAccess() first. The "
|
|
130
|
+
"access was ended; its fence is lost.";
|
|
131
|
+
_device.InjectError(wgpu::ErrorType::Validation, message.c_str());
|
|
132
|
+
}
|
|
133
|
+
native_frame::endAccess(_memory, _texture);
|
|
134
|
+
_accessOpen = false;
|
|
135
|
+
}
|
|
136
|
+
if (_texture) {
|
|
137
|
+
_texture.Destroy();
|
|
138
|
+
}
|
|
139
|
+
_texture = nullptr;
|
|
140
|
+
_memory = nullptr;
|
|
141
|
+
_source = nullptr;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
} // namespace rnwgpu
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <memory>
|
|
4
|
+
#include <string>
|
|
5
|
+
|
|
6
|
+
#include <jsi/jsi.h>
|
|
7
|
+
|
|
8
|
+
#include "webgpu/webgpu_cpp.h"
|
|
9
|
+
|
|
10
|
+
#include "NativeObject.h"
|
|
11
|
+
#include "VideoFrame.h"
|
|
12
|
+
|
|
13
|
+
namespace rnwgpu {
|
|
14
|
+
|
|
15
|
+
namespace jsi = facebook::jsi;
|
|
16
|
+
|
|
17
|
+
// What GPUNativeBufferTexture and GPUNativeBufferExternalTexture share:
|
|
18
|
+
// the import of a native buffer, done once, the access window around each use
|
|
19
|
+
// and the release. The counterpart of GPUHardwareBufferWrapper in Dawn's
|
|
20
|
+
// Android layer (tools/android/webgpu), whose JNI side owns the same objects:
|
|
21
|
+
// the shared texture memory, the texture, the buffer reference.
|
|
22
|
+
//
|
|
23
|
+
// A decoder or a camera renders into the same few buffers in turn: importing
|
|
24
|
+
// each one once and bracketing every frame with beginAccess() / endAccess()
|
|
25
|
+
// is what Dawn's layer does, and saves the import (and the pipeline recreation
|
|
26
|
+
// behind a new external texture) that importExternalTexture() pays per frame.
|
|
27
|
+
class NativeBufferAccess {
|
|
28
|
+
public:
|
|
29
|
+
NativeBufferAccess(const char *className, wgpu::Device device,
|
|
30
|
+
wgpu::SharedTextureMemory memory, wgpu::Texture texture,
|
|
31
|
+
std::shared_ptr<VideoFrame> source, std::string label);
|
|
32
|
+
~NativeBufferAccess();
|
|
33
|
+
|
|
34
|
+
NativeBufferAccess(const NativeBufferAccess &) = delete;
|
|
35
|
+
NativeBufferAccess &operator=(const NativeBufferAccess &) = delete;
|
|
36
|
+
|
|
37
|
+
// beginAccess(fences?): begins an access to the buffer's texture, after the
|
|
38
|
+
// GPU waited for the optional GPUSharedFenceState[] (the producer's fence
|
|
39
|
+
// for the frame: NativeVideoFrame.acquireFenceFd imported with
|
|
40
|
+
// importSharedFence, or the fences a native module hands over). The frame
|
|
41
|
+
// is taken as initialized, as Dawn's layer does. Throws (after a validation
|
|
42
|
+
// error) on a destroyed wrapper or fence, and if Dawn rejects the access.
|
|
43
|
+
void beginAccess(jsi::Runtime &runtime, const jsi::Value *args, size_t count);
|
|
44
|
+
|
|
45
|
+
// endAccess(): ends the access and returns the one fence that signals once
|
|
46
|
+
// the GPU work of the access is done, as { fence, signaledValue }, or null
|
|
47
|
+
// when there is none. Hand it to the buffer's producer before it reuses the
|
|
48
|
+
// buffer, or destroy it.
|
|
49
|
+
jsi::Value endAccess(jsi::Runtime &runtime);
|
|
50
|
+
|
|
51
|
+
// Releases the import now rather than when the JS object is garbage
|
|
52
|
+
// collected: the texture, the memory and the frame that keeps the buffer
|
|
53
|
+
// alive. An access still open is a validation error; it is ended (its fence
|
|
54
|
+
// is lost) so the producer gets its buffer back. A later use is a validation
|
|
55
|
+
// error and a throw.
|
|
56
|
+
void destroy();
|
|
57
|
+
|
|
58
|
+
bool destroyed() const { return _memory == nullptr; }
|
|
59
|
+
|
|
60
|
+
const std::string &label() const { return _label; }
|
|
61
|
+
void setLabel(const std::string &label);
|
|
62
|
+
|
|
63
|
+
private:
|
|
64
|
+
void release(bool reportOpenAccess);
|
|
65
|
+
void injectDestroyedError(const char *method);
|
|
66
|
+
|
|
67
|
+
const char *_className;
|
|
68
|
+
wgpu::Device _device;
|
|
69
|
+
wgpu::SharedTextureMemory _memory;
|
|
70
|
+
wgpu::Texture _texture;
|
|
71
|
+
// Keeps the native buffer (and, on Android, its acquire fence) alive for as
|
|
72
|
+
// long as the import is.
|
|
73
|
+
std::shared_ptr<VideoFrame> _source;
|
|
74
|
+
std::string _label;
|
|
75
|
+
bool _accessOpen = false;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// The JS side GPUNativeBufferTexture and GPUNativeBufferExternalTexture share:
|
|
79
|
+
// beginAccess(), endAccess(), the label and the brand, around a
|
|
80
|
+
// NativeBufferAccess and the object it wraps (a GPUTexture, a
|
|
81
|
+
// GPUExternalTexture), which takes the label too. Each class installs the
|
|
82
|
+
// getter of its wrapped object and its destroy(), whose order differs.
|
|
83
|
+
template <typename Derived, typename Wrapped>
|
|
84
|
+
class GPUNativeBufferWrapper : public NativeObject<Derived> {
|
|
85
|
+
public:
|
|
86
|
+
GPUNativeBufferWrapper(wgpu::Device device, wgpu::SharedTextureMemory memory,
|
|
87
|
+
wgpu::Texture texture,
|
|
88
|
+
std::shared_ptr<Wrapped> wrapped,
|
|
89
|
+
std::shared_ptr<VideoFrame> source, std::string label)
|
|
90
|
+
: NativeObject<Derived>(Derived::CLASS_NAME),
|
|
91
|
+
_access(Derived::CLASS_NAME, std::move(device), std::move(memory),
|
|
92
|
+
std::move(texture), std::move(source), std::move(label)),
|
|
93
|
+
_wrapped(std::move(wrapped)) {}
|
|
94
|
+
|
|
95
|
+
std::string getBrand() { return Derived::CLASS_NAME; }
|
|
96
|
+
|
|
97
|
+
jsi::Value beginAccess(jsi::Runtime &runtime, const jsi::Value &,
|
|
98
|
+
const jsi::Value *args, size_t count) {
|
|
99
|
+
_access.beginAccess(runtime, args, count);
|
|
100
|
+
return jsi::Value::undefined();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
jsi::Value endAccess(jsi::Runtime &runtime, const jsi::Value &,
|
|
104
|
+
const jsi::Value *, size_t) {
|
|
105
|
+
return _access.endAccess(runtime);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
std::string getLabel() { return _access.label(); }
|
|
109
|
+
void setLabel(const std::string &label) {
|
|
110
|
+
_access.setLabel(label);
|
|
111
|
+
_wrapped->setLabel(label);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
protected:
|
|
115
|
+
using HostMethod = jsi::Value (Derived::*)(jsi::Runtime &, const jsi::Value &,
|
|
116
|
+
const jsi::Value *, size_t);
|
|
117
|
+
|
|
118
|
+
static void defineWrapperPrototype(jsi::Runtime &runtime,
|
|
119
|
+
jsi::Object &prototype) {
|
|
120
|
+
using Base = NativeObject<Derived>;
|
|
121
|
+
Base::installGetter(runtime, prototype, "__brand",
|
|
122
|
+
static_cast<std::string (Derived::*)()>(
|
|
123
|
+
&GPUNativeBufferWrapper::getBrand));
|
|
124
|
+
Base::installMethod(
|
|
125
|
+
runtime, prototype, "beginAccess",
|
|
126
|
+
static_cast<HostMethod>(&GPUNativeBufferWrapper::beginAccess));
|
|
127
|
+
Base::installMethod(
|
|
128
|
+
runtime, prototype, "endAccess",
|
|
129
|
+
static_cast<HostMethod>(&GPUNativeBufferWrapper::endAccess));
|
|
130
|
+
Base::installGetterSetter(
|
|
131
|
+
runtime, prototype, "label",
|
|
132
|
+
static_cast<std::string (Derived::*)()>(
|
|
133
|
+
&GPUNativeBufferWrapper::getLabel),
|
|
134
|
+
static_cast<void (Derived::*)(const std::string &)>(
|
|
135
|
+
&GPUNativeBufferWrapper::setLabel));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
NativeBufferAccess _access;
|
|
139
|
+
std::shared_ptr<Wrapped> _wrapped;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
} // namespace rnwgpu
|
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
#include <memory>
|
|
5
5
|
#include <stdexcept>
|
|
6
6
|
#include <string>
|
|
7
|
+
#include <utility>
|
|
8
|
+
#include <vector>
|
|
7
9
|
|
|
8
10
|
#include "Convertors.h"
|
|
9
11
|
#include "DestroyedError.h"
|
|
12
|
+
#include "NativeFrameImport.h"
|
|
10
13
|
|
|
11
14
|
namespace rnwgpu {
|
|
12
15
|
|
|
@@ -87,9 +90,6 @@ void GPUSharedTextureMemory::beginAccess(
|
|
|
87
90
|
throw std::runtime_error(
|
|
88
91
|
"GPUSharedTextureMemory::beginAccess(): the memory was destroyed");
|
|
89
92
|
}
|
|
90
|
-
wgpu::SharedTextureMemoryBeginAccessDescriptor desc{};
|
|
91
|
-
desc.initialized = initialized;
|
|
92
|
-
desc.concurrentRead = false;
|
|
93
93
|
|
|
94
94
|
// Built in lockstep so fenceCount covers both arrays, and kept in locals so
|
|
95
95
|
// the raw pointers outlive the synchronous BeginAccess() below.
|
|
@@ -109,36 +109,11 @@ void GPUSharedTextureMemory::beginAccess(
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
if (!rawFences.empty()) {
|
|
113
|
-
desc.fenceCount = rawFences.size();
|
|
114
|
-
desc.fences = rawFences.data();
|
|
115
|
-
desc.signaledValueCount = values.size();
|
|
116
|
-
desc.signaledValues = values.data();
|
|
117
|
-
} else {
|
|
118
|
-
desc.fenceCount = 0;
|
|
119
|
-
desc.fences = nullptr;
|
|
120
|
-
desc.signaledValueCount = 0;
|
|
121
|
-
desc.signaledValues = nullptr;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
#if defined(__ANDROID__)
|
|
125
|
-
// Dawn's Vulkan backend (AHardwareBuffer) validates that the begin-access
|
|
126
|
-
// descriptor chains a SharedTextureMemoryVkImageLayoutBeginState specifying
|
|
127
|
-
// the VkImageLayout to acquire the image into. UNDEFINED (= 0) on both ends
|
|
128
|
-
// is the canonical "no prior GPU producer" pattern: Dawn performs an
|
|
129
|
-
// external-queue acquire from VK_QUEUE_FAMILY_EXTERNAL which preserves the
|
|
130
|
-
// AHB contents, then transitions to whatever layout the texture's actual
|
|
131
|
-
// usage requires.
|
|
132
|
-
wgpu::SharedTextureMemoryVkImageLayoutBeginState vkLayout{};
|
|
133
|
-
vkLayout.oldLayout = 0;
|
|
134
|
-
vkLayout.newLayout = 0;
|
|
135
|
-
desc.nextInChain = &vkLayout;
|
|
136
|
-
#endif
|
|
137
112
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
113
|
+
// The access descriptor (and, on Vulkan, the layout the image is acquired
|
|
114
|
+
// in) is the one of every native frame import: see NativeFrameImport.cpp.
|
|
115
|
+
native_frame::beginAccess(_instance, texture->get(), initialized, rawFences,
|
|
116
|
+
values, "GPUSharedTextureMemory::beginAccess");
|
|
142
117
|
_accessed.push_back(texture->get());
|
|
143
118
|
}
|
|
144
119
|
|
|
@@ -159,18 +134,11 @@ jsi::Value GPUSharedTextureMemory::endAccess(jsi::Runtime &runtime,
|
|
|
159
134
|
auto texture = GPUTexture::fromValue(runtime, args[0]);
|
|
160
135
|
|
|
161
136
|
wgpu::SharedTextureMemoryEndAccessState state{};
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
wgpu::SharedTextureMemoryVkImageLayoutEndState vkLayout{};
|
|
168
|
-
state.nextInChain = &vkLayout;
|
|
169
|
-
#endif
|
|
170
|
-
|
|
171
|
-
auto status = _instance.EndAccess(texture->get(), &state);
|
|
172
|
-
if (status != wgpu::Status::Success) {
|
|
173
|
-
throw jsi::JSError(runtime, "GPUSharedTextureMemory::endAccess() failed");
|
|
137
|
+
try {
|
|
138
|
+
native_frame::endAccess(_instance, texture->get(), &state,
|
|
139
|
+
"GPUSharedTextureMemory::endAccess");
|
|
140
|
+
} catch (const std::exception &e) {
|
|
141
|
+
throw jsi::JSError(runtime, e.what());
|
|
174
142
|
}
|
|
175
143
|
auto ended = texture->get();
|
|
176
144
|
_accessed.erase(std::remove_if(_accessed.begin(), _accessed.end(),
|