mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-11 16:32:59 +00:00
Bug 1656211 - Force recompositing frames on GTK when popup window configuration changes. r=nical
Similar to bug 1280653, it appears that GLX invalidates the back buffer while we are drawing. The only indication we get of this are resize and configure events from X. We suppress the configure event for popups for various reasons, so this patch explicitly generates a forced recomposite of the frame. It does it immediately so that most of the time it should beat the presentation of the buffer and avoid displaying of the bad frame to the user; popups generally are not complicated and should have plenty of budget to perform the second composite. Differential Revision: https://phabricator.services.mozilla.com/D93862
This commit is contained in:
parent
da10e9b814
commit
38752f6def
@ -381,6 +381,12 @@ class LayerManager : public FrameRecorder {
|
||||
*/
|
||||
virtual void ScheduleComposite() {}
|
||||
|
||||
/**
|
||||
* Force a composition with the remote Compositor, if one exists
|
||||
* for this LayerManager, as soon as possible.
|
||||
*/
|
||||
virtual void ForceComposite() {}
|
||||
|
||||
virtual void SetNeedsComposite(bool aNeedsComposite) {}
|
||||
virtual bool NeedsComposite() const { return false; }
|
||||
|
||||
|
@ -71,6 +71,8 @@ parent:
|
||||
async InvalidateRenderedFrame();
|
||||
// Schedule a composite if one isn't already scheduled.
|
||||
async ScheduleComposite();
|
||||
// Force a composite immediately.
|
||||
async ForceComposite();
|
||||
// Save the frame capture to disk
|
||||
async Capture();
|
||||
// Start capturing each frame and save to disk, and if already started, stop.
|
||||
|
@ -1809,6 +1809,23 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvScheduleComposite() {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvForceComposite() {
|
||||
MOZ_ASSERT(IsRootWebRenderBridgeParent());
|
||||
if (mDestroyed) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
TimeStamp start = TimeStamp::Now();
|
||||
wr::RenderThread::Get()->IncPendingFrameCount(mApi->GetId(), VsyncId(),
|
||||
start);
|
||||
|
||||
wr::TransactionBuilder fastTxn(/* aUseSceneBuilderThread */ false);
|
||||
fastTxn.InvalidateRenderedFrame();
|
||||
fastTxn.GenerateFrame();
|
||||
mApi->SendTransaction(fastTxn);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::InvalidateRenderedFrame() {
|
||||
if (mDestroyed) {
|
||||
return;
|
||||
|
@ -179,6 +179,7 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
|
||||
mozilla::ipc::IPCResult RecvClearCachedResources() override;
|
||||
mozilla::ipc::IPCResult RecvInvalidateRenderedFrame() override;
|
||||
mozilla::ipc::IPCResult RecvScheduleComposite() override;
|
||||
mozilla::ipc::IPCResult RecvForceComposite() override;
|
||||
mozilla::ipc::IPCResult RecvCapture() override;
|
||||
mozilla::ipc::IPCResult RecvToggleCaptureSequence() override;
|
||||
mozilla::ipc::IPCResult RecvSyncWithCompositor() override;
|
||||
|
@ -709,6 +709,10 @@ void WebRenderLayerManager::ScheduleComposite() {
|
||||
WrBridge()->SendScheduleComposite();
|
||||
}
|
||||
|
||||
void WebRenderLayerManager::ForceComposite() {
|
||||
WrBridge()->SendForceComposite();
|
||||
}
|
||||
|
||||
void WebRenderLayerManager::SetRoot(Layer* aLayer) {
|
||||
// This should never get called
|
||||
MOZ_ASSERT(false);
|
||||
|
@ -122,6 +122,7 @@ class WebRenderLayerManager final : public LayerManager {
|
||||
void SendInvalidRegion(const nsIntRegion& aRegion) override;
|
||||
|
||||
void ScheduleComposite() override;
|
||||
void ForceComposite() override;
|
||||
|
||||
void SetNeedsComposite(bool aNeedsComposite) override {
|
||||
mNeedsComposite = aNeedsComposite;
|
||||
|
@ -3067,6 +3067,12 @@ gboolean nsWindow::OnConfigureEvent(GtkWidget* aWidget,
|
||||
// loop when nsXULPopupManager::PopupMoved moves the window to the new
|
||||
// position and nsMenuPopupFrame::SetPopupPosition adds
|
||||
// offsetForContextMenu on each iteration.
|
||||
|
||||
// Our back buffer might have been invalidated while we drew the last
|
||||
// frame, and its contents might be incorrect. See bug 1280653 comment 7
|
||||
// and comment 10. Specifically we must ensure we recomposite the frame
|
||||
// as soon as possible to avoid the corrupted frame being displayed.
|
||||
GetLayerManager()->ForceComposite();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user