qt: synchronously drain subsurface dmabuf on Vulkan resize
The Vulkan path's resize-sync fix (commit 6ba3d06b9) drained
m_pending (QImage) inside syncSurfaceSize so the new-size frame
was visible before resizeEvent returned. After the Phase 3
switch to the wl_subsurface present path, the renderer parks
to m_pendingDmabuf instead and the old drain found nothing —
so the new-size buffer wasn't attached to the subsurface before
Qt's parent-surface commit. Result: one frame where the parent
QWidget is already at the new geometry but our subsurface is
still at the old size, with the parent's translucent
background showing through the gap.
Fix: when the subsurface path is active, run the synchronous
ghostty_surface_draw and immediately call drainVulkan() (which
forwards to presentDmabuf) before returning from
syncSurfaceSize. Subsurface gets the new-size buffer first,
parent commit lands at the matching size, no transient gap.
Legacy QImage fallback path is preserved for the
presenter-absent case (e.g. compositor refusing
linux-dmabuf-v1, first-show window before presenter init).
Co-Authored-By: claude-flow <ruv@ruv.net>
pull/12846/head
parent
8f584155c3
commit
b8d2f25cf5
|
|
@ -233,14 +233,30 @@ void GhosttySurface::syncSurfaceSize() {
|
|||
ghostty_surface_set_content_scale(m_surface, dpr, dpr);
|
||||
ghostty_surface_set_size(m_surface, static_cast<uint32_t>(w),
|
||||
static_cast<uint32_t>(h));
|
||||
|
||||
// Subsurface (zero-copy) path: synchronously render at the new
|
||||
// size and dispatch the resulting dmabuf to the presenter BEFORE
|
||||
// returning from resizeEvent. That ensures our wl_subsurface
|
||||
// has its new-size buffer attached + committed before Qt's
|
||||
// following parent-surface commit lands at the new geometry —
|
||||
// without this, the compositor sees one frame where the parent
|
||||
// surface is already at the new size but our subsurface is
|
||||
// still at the old one, and the parent's translucent QWidget
|
||||
// background shows through the gap. Counterpart of the
|
||||
// m_image.isNull() drain below, which served the same purpose
|
||||
// before the subsurface present path replaced the QImage one.
|
||||
if (m_useSubsurface.load(std::memory_order_acquire) &&
|
||||
m_subsurfacePresenter) {
|
||||
ghostty_surface_draw(m_surface);
|
||||
drainVulkan(); // runs presentDmabuf at the new size + commits
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_image.isNull()) {
|
||||
// Block until the renderer thread (or this thread, since
|
||||
// `Surface.draw` says renderers must support being called
|
||||
// from main) finishes a frame at the new size. The frame
|
||||
// lands in `m_pending` via `presentVulkanDmabuf` on whichever
|
||||
// thread runs the present; drain it into `m_image` here so
|
||||
// we don't have to wait for the next 60Hz timer tick before
|
||||
// the resized frame is visible.
|
||||
// Legacy QImage fallback path (presenter absent — e.g. the
|
||||
// compositor refused linux-dmabuf-v1, or we're in the
|
||||
// first-show window before presenter init). Drain m_pending
|
||||
// into m_image so the next paintEvent has the new-size frame.
|
||||
ghostty_surface_draw(m_surface);
|
||||
QImage frame;
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue