Skip to content

Commit 9c7d46d

Browse files
committed
🔧
1 parent 4dfc66a commit 9c7d46d

3 files changed

Lines changed: 41 additions & 6 deletions

File tree

packages/webgpu/apple/WebGPUModule.mm

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ - (void *)runtime;
2424

2525
@implementation WebGPUModule {
2626
CADisplayLink *_displayLink;
27+
BOOL _displayLinkActive;
2728
}
2829

2930
RCT_EXPORT_MODULE(WebGPUModule)
@@ -52,24 +53,29 @@ - (void)invalidate {
5253
}
5354

5455
- (void)startDisplayLink {
56+
_displayLinkActive = YES;
5557
if (_displayLink != nil) {
5658
return;
5759
}
5860
// CADisplayLink callbacks must be scheduled on a run loop. The main run
5961
// loop is the safest choice: CAMetalLayer ops are main-thread-only, and
6062
// SurfaceInfo's mutex serialises access with the JS thread.
6163
dispatch_async(dispatch_get_main_queue(), ^{
64+
if (!self->_displayLinkActive) {
65+
return;
66+
}
6267
if (self->_displayLink != nil) {
6368
return;
6469
}
65-
self->_displayLink = [CADisplayLink displayLinkWithTarget:self
66-
selector:@selector(onVsync:)];
70+
self->_displayLink =
71+
[CADisplayLink displayLinkWithTarget:self selector:@selector(onVsync:)];
6772
[self->_displayLink addToRunLoop:[NSRunLoop mainRunLoop]
6873
forMode:NSRunLoopCommonModes];
6974
});
7075
}
7176

7277
- (void)stopDisplayLink {
78+
_displayLinkActive = NO;
7379
CADisplayLink *link = _displayLink;
7480
_displayLink = nil;
7581
if (link == nil) {

packages/webgpu/cpp/rnwgpu/SurfaceRegistry.h

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,22 +130,31 @@ class SurfaceInfo {
130130
_presentLocked();
131131
}
132132

133-
// Called by the display-link tick. Presents only if the texture was acquired
134-
// in a strictly earlier frame, so the user's render code (which runs between
135-
// vsyncs) has finished encoding and submitting before we present.
133+
// Called by the display-link tick. Presents only after the app has submitted
134+
// work for an acquired texture and at least one tick has passed since
135+
// acquire.
136136
void maybePresentForFrame(uint64_t currentFrame) {
137137
std::unique_lock<std::shared_mutex> lock(_mutex);
138-
if (_acquiredAtFrame && *_acquiredAtFrame < currentFrame) {
138+
if (_readyToPresent && _acquiredAtFrame &&
139+
*_acquiredAtFrame < currentFrame) {
139140
_presentLocked();
140141
}
141142
}
142143

144+
void markSubmittedForPresentation() {
145+
std::unique_lock<std::shared_mutex> lock(_mutex);
146+
if (_textureAcquired) {
147+
_readyToPresent = true;
148+
}
149+
}
150+
143151
wgpu::Texture getCurrentTexture(uint64_t currentFrame) {
144152
std::unique_lock<std::shared_mutex> lock(_mutex);
145153
if (surface) {
146154
wgpu::SurfaceTexture surfaceTexture;
147155
surface.GetCurrentTexture(&surfaceTexture);
148156
_textureAcquired = true;
157+
_readyToPresent = false;
149158
_acquiredAtFrame = currentFrame;
150159
return surfaceTexture.texture;
151160
} else {
@@ -199,6 +208,7 @@ class SurfaceInfo {
199208
#endif
200209
surface.Present();
201210
_textureAcquired = false;
211+
_readyToPresent = false;
202212
_acquiredAtFrame.reset();
203213
}
204214
}
@@ -212,6 +222,7 @@ class SurfaceInfo {
212222
int width;
213223
int height;
214224
bool _textureAcquired = false;
225+
bool _readyToPresent = false;
215226
std::optional<uint64_t> _acquiredAtFrame;
216227
};
217228

@@ -280,6 +291,20 @@ class SurfaceRegistry {
280291
}
281292
}
282293

294+
void markSubmittedSurfacesForPresentation() {
295+
std::vector<std::shared_ptr<SurfaceInfo>> snapshot;
296+
{
297+
std::shared_lock<std::shared_mutex> lock(_mutex);
298+
snapshot.reserve(_registry.size());
299+
for (auto &entry : _registry) {
300+
snapshot.push_back(entry.second);
301+
}
302+
}
303+
for (auto &info : snapshot) {
304+
info->markSubmittedForPresentation();
305+
}
306+
}
307+
283308
private:
284309
SurfaceRegistry() = default;
285310
mutable std::shared_mutex _mutex;

packages/webgpu/cpp/rnwgpu/api/GPUQueue.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
#include <limits>
44
#include <memory>
5+
#include <string>
6+
#include <utility>
57
#include <vector>
68

79
#include "Convertors.h"
10+
#include "SurfaceRegistry.h"
811

912
namespace rnwgpu {
1013

@@ -26,6 +29,7 @@ void GPUQueue::submit(
2629
return;
2730
}
2831
_instance.Submit(bufs_size, bufs.data());
32+
SurfaceRegistry::getInstance().markSubmittedSurfacesForPresentation();
2933
}
3034

3135
void GPUQueue::writeBuffer(std::shared_ptr<GPUBuffer> buffer,

0 commit comments

Comments
 (0)