@@ -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+
283308private:
284309 SurfaceRegistry () = default ;
285310 mutable std::shared_mutex _mutex;
0 commit comments