зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1875369 [Linux] Get renderer again after WillPaintWindow() r=emilio
WillPaintWindow() spins event loop which can lead to any action related to nsWindow - it can be hid, shown or destroyed. If the nsWindow visibility is changed, compositor/renderer is deleted and we need to get it again. Differential Revision: https://phabricator.services.mozilla.com/D200272
This commit is contained in:
Родитель
68c3134ed5
Коммит
6eeb6c8e7f
|
@ -3753,6 +3753,26 @@ void nsWindow::CreateCompositorVsyncDispatcher() {
|
|||
}
|
||||
#endif
|
||||
|
||||
void nsWindow::RequestRepaint(LayoutDeviceIntRegion& aRepaintRegion) {
|
||||
WindowRenderer* renderer = GetWindowRenderer();
|
||||
WebRenderLayerManager* layerManager = renderer->AsWebRender();
|
||||
KnowsCompositor* knowsCompositor = renderer->AsKnowsCompositor();
|
||||
|
||||
if (knowsCompositor && layerManager && mCompositorSession) {
|
||||
if (!mConfiguredClearColor && !IsPopup()) {
|
||||
layerManager->WrBridge()->SendSetDefaultClearColor(LookAndFeel::Color(
|
||||
LookAndFeel::ColorID::Window, PreferenceSheet::ColorSchemeForChrome(),
|
||||
LookAndFeel::UseStandins::No));
|
||||
mConfiguredClearColor = true;
|
||||
}
|
||||
|
||||
// We need to paint to the screen even if nothing changed, since if we
|
||||
// don't have a compositing window manager, our pixels could be stale.
|
||||
layerManager->SetNeedsComposite(true);
|
||||
layerManager->SendInvalidRegion(aRepaintRegion.ToUnknownRegion());
|
||||
}
|
||||
}
|
||||
|
||||
gboolean nsWindow::OnExposeEvent(cairo_t* cr) {
|
||||
// This might destroy us.
|
||||
NotifyOcclusionState(OcclusionState::VISIBLE);
|
||||
|
@ -3777,8 +3797,7 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) {
|
|||
}
|
||||
#endif
|
||||
|
||||
nsIWidgetListener* listener = GetListener();
|
||||
if (!listener) {
|
||||
if (!GetListener()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -3795,45 +3814,30 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) {
|
|||
LayoutDeviceIntRegion region = exposeRegion;
|
||||
region.ScaleRoundOut(scale, scale);
|
||||
|
||||
WindowRenderer* renderer = GetWindowRenderer();
|
||||
WebRenderLayerManager* layerManager = renderer->AsWebRender();
|
||||
KnowsCompositor* knowsCompositor = renderer->AsKnowsCompositor();
|
||||
|
||||
if (knowsCompositor && layerManager && mCompositorSession) {
|
||||
if (!mConfiguredClearColor && !IsPopup()) {
|
||||
layerManager->WrBridge()->SendSetDefaultClearColor(LookAndFeel::Color(
|
||||
LookAndFeel::ColorID::Window, PreferenceSheet::ColorSchemeForChrome(),
|
||||
LookAndFeel::UseStandins::No));
|
||||
mConfiguredClearColor = true;
|
||||
}
|
||||
|
||||
// We need to paint to the screen even if nothing changed, since if we
|
||||
// don't have a compositing window manager, our pixels could be stale.
|
||||
layerManager->SetNeedsComposite(true);
|
||||
layerManager->SendInvalidRegion(region.ToUnknownRegion());
|
||||
}
|
||||
RequestRepaint(region);
|
||||
|
||||
RefPtr<nsWindow> strongThis(this);
|
||||
|
||||
// Dispatch WillPaintWindow notification to allow scripts etc. to run
|
||||
// before we paint
|
||||
{
|
||||
listener->WillPaintWindow(this);
|
||||
// before we paint. It also spins event loop which may show/hide the window
|
||||
// so we may have new renderer etc.
|
||||
GetListener()->WillPaintWindow(this);
|
||||
|
||||
// If the window has been destroyed during the will paint notification,
|
||||
// there is nothing left to do.
|
||||
if (!mGdkWindow) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Re-get the listener since the will paint notification might have
|
||||
// killed it.
|
||||
listener = GetListener();
|
||||
if (!listener) {
|
||||
return FALSE;
|
||||
}
|
||||
// If the window has been destroyed during the will paint notification,
|
||||
// there is nothing left to do.
|
||||
if (!mGdkWindow || mIsDestroyed) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Re-get all rendering components since the will paint notification
|
||||
// might have killed it.
|
||||
nsIWidgetListener* listener = GetListener();
|
||||
if (!listener) return FALSE;
|
||||
|
||||
WindowRenderer* renderer = GetWindowRenderer();
|
||||
WebRenderLayerManager* layerManager = renderer->AsWebRender();
|
||||
KnowsCompositor* knowsCompositor = renderer->AsKnowsCompositor();
|
||||
|
||||
if (knowsCompositor && layerManager && layerManager->NeedsComposite()) {
|
||||
layerManager->ScheduleComposite(wr::RenderReasons::WIDGET);
|
||||
layerManager->SetNeedsComposite(false);
|
||||
|
|
|
@ -986,6 +986,8 @@ class nsWindow final : public nsBaseWidget {
|
|||
|
||||
void EmulateResizeDrag(GdkEventMotion* aEvent);
|
||||
|
||||
void RequestRepaint(LayoutDeviceIntRegion& aRepaintRegion);
|
||||
|
||||
#ifdef MOZ_X11
|
||||
typedef enum {GTK_WIDGET_COMPOSIDED_DEFAULT = 0,
|
||||
GTK_WIDGET_COMPOSIDED_DISABLED = 1,
|
||||
|
|
Загрузка…
Ссылка в новой задаче