зеркало из 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
|
#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) {
|
gboolean nsWindow::OnExposeEvent(cairo_t* cr) {
|
||||||
// This might destroy us.
|
// This might destroy us.
|
||||||
NotifyOcclusionState(OcclusionState::VISIBLE);
|
NotifyOcclusionState(OcclusionState::VISIBLE);
|
||||||
|
@ -3777,8 +3797,7 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsIWidgetListener* listener = GetListener();
|
if (!GetListener()) {
|
||||||
if (!listener) {
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3795,44 +3814,29 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) {
|
||||||
LayoutDeviceIntRegion region = exposeRegion;
|
LayoutDeviceIntRegion region = exposeRegion;
|
||||||
region.ScaleRoundOut(scale, scale);
|
region.ScaleRoundOut(scale, scale);
|
||||||
|
|
||||||
WindowRenderer* renderer = GetWindowRenderer();
|
RequestRepaint(region);
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
RefPtr<nsWindow> strongThis(this);
|
RefPtr<nsWindow> strongThis(this);
|
||||||
|
|
||||||
// Dispatch WillPaintWindow notification to allow scripts etc. to run
|
// Dispatch WillPaintWindow notification to allow scripts etc. to run
|
||||||
// before we paint
|
// before we paint. It also spins event loop which may show/hide the window
|
||||||
{
|
// so we may have new renderer etc.
|
||||||
listener->WillPaintWindow(this);
|
GetListener()->WillPaintWindow(this);
|
||||||
|
|
||||||
// If the window has been destroyed during the will paint notification,
|
// If the window has been destroyed during the will paint notification,
|
||||||
// there is nothing left to do.
|
// there is nothing left to do.
|
||||||
if (!mGdkWindow) {
|
if (!mGdkWindow || mIsDestroyed) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-get the listener since the will paint notification might have
|
// Re-get all rendering components since the will paint notification
|
||||||
// killed it.
|
// might have killed it.
|
||||||
listener = GetListener();
|
nsIWidgetListener* listener = GetListener();
|
||||||
if (!listener) {
|
if (!listener) return FALSE;
|
||||||
return FALSE;
|
|
||||||
}
|
WindowRenderer* renderer = GetWindowRenderer();
|
||||||
}
|
WebRenderLayerManager* layerManager = renderer->AsWebRender();
|
||||||
|
KnowsCompositor* knowsCompositor = renderer->AsKnowsCompositor();
|
||||||
|
|
||||||
if (knowsCompositor && layerManager && layerManager->NeedsComposite()) {
|
if (knowsCompositor && layerManager && layerManager->NeedsComposite()) {
|
||||||
layerManager->ScheduleComposite(wr::RenderReasons::WIDGET);
|
layerManager->ScheduleComposite(wr::RenderReasons::WIDGET);
|
||||||
|
|
|
@ -986,6 +986,8 @@ class nsWindow final : public nsBaseWidget {
|
||||||
|
|
||||||
void EmulateResizeDrag(GdkEventMotion* aEvent);
|
void EmulateResizeDrag(GdkEventMotion* aEvent);
|
||||||
|
|
||||||
|
void RequestRepaint(LayoutDeviceIntRegion& aRepaintRegion);
|
||||||
|
|
||||||
#ifdef MOZ_X11
|
#ifdef MOZ_X11
|
||||||
typedef enum {GTK_WIDGET_COMPOSIDED_DEFAULT = 0,
|
typedef enum {GTK_WIDGET_COMPOSIDED_DEFAULT = 0,
|
||||||
GTK_WIDGET_COMPOSIDED_DISABLED = 1,
|
GTK_WIDGET_COMPOSIDED_DISABLED = 1,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче