зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1782049 [Linux] Update nsWindow compositor configuration r=emilio
- Don't delete layer manager when nsWindow is unrealized but leave that to Destroy() when it's actually deleted. Only disable rendering in ReleaseGdkWindow(). - Create msWindow with enabled composition - Use single nsWindow::ConfigureCompositor() routine to configure compositor and use it from ConfigureGdkWindow() and SetCompositorWidgetDelegate(). Depends on D153206 Differential Revision: https://phabricator.services.mozilla.com/D153207
This commit is contained in:
Родитель
1d37f8759d
Коммит
43cd54a683
|
@ -580,10 +580,6 @@ void nsWindow::Destroy() {
|
|||
/** Need to clean our LayerManager up while still alive */
|
||||
DestroyLayerManager();
|
||||
|
||||
if (mCompositorWidgetDelegate) {
|
||||
mCompositorWidgetDelegate->DisableRendering();
|
||||
}
|
||||
|
||||
// Ensure any resources assigned to the window get cleaned up first
|
||||
// to avoid double-freeing.
|
||||
mSurfaceProvider.CleanupResources();
|
||||
|
@ -5306,8 +5302,48 @@ bool nsWindow::GetShapedState() {
|
|||
return mIsTransparent && !mHasAlphaVisual && !mTransparencyBitmapForTitlebar;
|
||||
}
|
||||
|
||||
void nsWindow::ConfigureCompositor() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mCompositorState == COMPOSITOR_ENABLED);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mIsMapped);
|
||||
|
||||
LOG("nsWindow::ConfigureCompositor()");
|
||||
auto startCompositing = [self = RefPtr{this}, this]() -> void {
|
||||
LOG(" moz_container_wayland_add_initial_draw_callback "
|
||||
"ConfigureCompositor");
|
||||
|
||||
// too late
|
||||
if (mIsDestroyed || !mIsMapped) {
|
||||
LOG(" quit, mIsDestroyed = %d mIsMapped = %d", mIsDestroyed, mIsMapped);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(mCompositorState == COMPOSITOR_ENABLED);
|
||||
MOZ_ASSERT(mCompositorWidgetDelegate);
|
||||
mCompositorWidgetDelegate->EnableRendering(GetX11Window(),
|
||||
GetShapedState());
|
||||
|
||||
// As WaylandStartVsync needs mCompositorWidgetDelegate this is the right
|
||||
// time to start it.
|
||||
WaylandStartVsync();
|
||||
|
||||
CompositorBridgeChild* remoteRenderer = GetRemoteRenderer();
|
||||
MOZ_ASSERT(remoteRenderer);
|
||||
remoteRenderer->SendResumeAsync();
|
||||
remoteRenderer->SendForcePresent(wr::RenderReasons::WIDGET);
|
||||
};
|
||||
|
||||
if (GdkIsWaylandDisplay()) {
|
||||
#ifdef MOZ_WAYLAND
|
||||
moz_container_wayland_add_initial_draw_callback(mContainer,
|
||||
startCompositing);
|
||||
#endif
|
||||
} else {
|
||||
startCompositing();
|
||||
}
|
||||
}
|
||||
|
||||
void nsWindow::ConfigureGdkWindow() {
|
||||
LOG("nsWindow::ConfigureGdkWindow() [%p]", this);
|
||||
LOG("nsWindow::ConfigureGdkWindow()");
|
||||
|
||||
EnsureGdkWindow();
|
||||
|
||||
|
@ -5364,42 +5400,9 @@ void nsWindow::ConfigureGdkWindow() {
|
|||
|
||||
RefreshWindowClass();
|
||||
|
||||
if (mCompositorState == COMPOSITOR_PAUSED_INITIALLY) {
|
||||
auto startCompositing = [self = RefPtr{this}, this]() -> void {
|
||||
LOG(" moz_container_wayland_add_initial_draw_callback start initial "
|
||||
"compositing");
|
||||
|
||||
// Call GetWindowRenderer() to make sure we have
|
||||
// mCompositorWidgetDelegate & mCompositorBridgeChild
|
||||
// (a.k.a remoteRenderer).
|
||||
(void)GetWindowRenderer();
|
||||
|
||||
CompositorBridgeChild* remoteRenderer = GetRemoteRenderer();
|
||||
MOZ_ASSERT(mCompositorWidgetDelegate);
|
||||
MOZ_ASSERT(remoteRenderer);
|
||||
|
||||
// If we're missing mCompositorWidgetDelegate here, EnableRendering()
|
||||
// will be called later by SetCompositorWidgetDelegate(), which is
|
||||
// fired by GetWindowRenderer()/CreateCompositor().
|
||||
if (mCompositorWidgetDelegate) {
|
||||
mCompositorWidgetDelegate->EnableRendering(GetX11Window(),
|
||||
GetShapedState());
|
||||
WaylandStartVsync();
|
||||
}
|
||||
|
||||
remoteRenderer->SendResumeAsync();
|
||||
remoteRenderer->SendForcePresent(wr::RenderReasons::WIDGET);
|
||||
mCompositorState = COMPOSITOR_ENABLED;
|
||||
};
|
||||
|
||||
if (GdkIsWaylandDisplay()) {
|
||||
#ifdef MOZ_WAYLAND
|
||||
moz_container_wayland_add_initial_draw_callback(mContainer,
|
||||
startCompositing);
|
||||
#endif
|
||||
} else {
|
||||
startCompositing();
|
||||
}
|
||||
// We're not mapped yet but we have already created compositor.
|
||||
if (mCompositorWidgetDelegate) {
|
||||
ConfigureCompositor();
|
||||
}
|
||||
|
||||
if (mHasMappedToplevel) {
|
||||
|
@ -5410,12 +5413,13 @@ void nsWindow::ConfigureGdkWindow() {
|
|||
}
|
||||
|
||||
void nsWindow::ReleaseGdkWindow() {
|
||||
LOG("nsWindow::ReleaseGdkWindow() [%p]", this);
|
||||
LOG("nsWindow::ReleaseGdkWindow()");
|
||||
|
||||
WaylandStopVsync();
|
||||
DestroyChildWindows();
|
||||
|
||||
DestroyLayerManager();
|
||||
if (mCompositorWidgetDelegate) {
|
||||
mCompositorWidgetDelegate->DisableRendering();
|
||||
}
|
||||
|
||||
if (mGdkWindow) {
|
||||
g_object_set_data(G_OBJECT(mGdkWindow), "nsWindow", nullptr);
|
||||
|
@ -6150,17 +6154,11 @@ void nsWindow::ResumeCompositor() {
|
|||
mCompositorPauseTimeoutID = 0;
|
||||
}
|
||||
|
||||
// We're expected to have mCompositorWidgetDelegate present
|
||||
// as we don't delete LayerManager (in PauseCompositor())
|
||||
// to avoid flickering.
|
||||
MOZ_RELEASE_ASSERT(mCompositorWidgetDelegate);
|
||||
|
||||
CompositorBridgeChild* remoteRenderer = GetRemoteRenderer();
|
||||
if (remoteRenderer) {
|
||||
mCompositorState = COMPOSITOR_ENABLED;
|
||||
remoteRenderer->SendResumeAsync();
|
||||
remoteRenderer->SendForcePresent(wr::RenderReasons::WIDGET);
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(remoteRenderer);
|
||||
remoteRenderer->SendResumeAsync();
|
||||
remoteRenderer->SendForcePresent(wr::RenderReasons::WIDGET);
|
||||
mCompositorState = COMPOSITOR_ENABLED;
|
||||
}
|
||||
|
||||
void nsWindow::ResumeCompositorFromCompositorThread() {
|
||||
|
@ -8450,46 +8448,13 @@ void nsWindow::SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate) {
|
|||
"mCompositorWidgetDelegate %p\n",
|
||||
delegate, mIsMapped, mCompositorWidgetDelegate);
|
||||
|
||||
// Remove reference to GdkWindow/XWindow from remote widget.
|
||||
if (mCompositorWidgetDelegate) {
|
||||
mCompositorWidgetDelegate->DisableRendering();
|
||||
WaylandStopVsync();
|
||||
}
|
||||
|
||||
if (delegate) {
|
||||
mCompositorWidgetDelegate = delegate->AsPlatformSpecificDelegate();
|
||||
MOZ_ASSERT(mCompositorWidgetDelegate,
|
||||
"nsWindow::SetCompositorWidgetDelegate called with a "
|
||||
"non-PlatformCompositorWidgetDelegate");
|
||||
|
||||
// If we're mapped we only need to submit XWindow/shape to newly
|
||||
// created compositor.
|
||||
// If we're not mapped, leave compolete config to ConfigureGdkWindow().
|
||||
if (mIsMapped) {
|
||||
auto startCompositing = [self = RefPtr{this}, this]() -> void {
|
||||
LOG(" moz_container_wayland_add_initial_draw_callback resume "
|
||||
"compositor from SetCompositorWidgetDelegate()");
|
||||
// Pass recent GdkWindow/XWindow to remote widget.
|
||||
mCompositorWidgetDelegate->EnableRendering(GetX11Window(),
|
||||
GetShapedState());
|
||||
// CompositorBridgeChild::Resume() creates a new surface
|
||||
// based on GetX11Window()/GetShapedState() set above.
|
||||
// Resume() is effective even without compositor pause.
|
||||
if (mCompositorState == COMPOSITOR_ENABLED) {
|
||||
CompositorBridgeChild* remoteRenderer = GetRemoteRenderer();
|
||||
remoteRenderer->SendResumeAsync();
|
||||
remoteRenderer->SendForcePresent(wr::RenderReasons::WIDGET);
|
||||
}
|
||||
WaylandStartVsync();
|
||||
};
|
||||
if (GdkIsWaylandDisplay()) {
|
||||
#ifdef MOZ_WAYLAND
|
||||
moz_container_wayland_add_initial_draw_callback(mContainer,
|
||||
startCompositing);
|
||||
#endif
|
||||
} else {
|
||||
startCompositing();
|
||||
}
|
||||
ConfigureCompositor();
|
||||
}
|
||||
} else {
|
||||
mCompositorWidgetDelegate = nullptr;
|
||||
|
|
|
@ -432,8 +432,6 @@ class nsWindow final : public nsBaseWidget {
|
|||
typedef enum {
|
||||
// WebRender compositor is enabled
|
||||
COMPOSITOR_ENABLED,
|
||||
// WebRender compositor is paused after window creation.
|
||||
COMPOSITOR_PAUSED_INITIALLY,
|
||||
// WebRender compositor is paused as we're repainting whole window and
|
||||
// we're waiting for content process to update page content.
|
||||
COMPOSITOR_PAUSED_FLICKERING
|
||||
|
@ -455,9 +453,7 @@ class nsWindow final : public nsBaseWidget {
|
|||
void DispatchPanGesture(mozilla::PanGestureInput& aPanInput);
|
||||
|
||||
void RegisterTouchWindow() override;
|
||||
bool CompositorInitiallyPaused() override {
|
||||
return mCompositorState == COMPOSITOR_PAUSED_INITIALLY;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWidget> mParent;
|
||||
nsPopupType mPopupHint{};
|
||||
int mWindowScaleFactor = 1;
|
||||
|
@ -525,7 +521,7 @@ class nsWindow final : public nsBaseWidget {
|
|||
GdkWindow* mGdkWindow = nullptr;
|
||||
PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate = nullptr;
|
||||
mozilla::Atomic<WindowCompositorState, mozilla::Relaxed> mCompositorState{
|
||||
COMPOSITOR_PAUSED_INITIALLY};
|
||||
COMPOSITOR_ENABLED};
|
||||
// This is used in COMPOSITOR_PAUSED_FLICKERING mode only to resume compositor
|
||||
// in some reasonable time when page content is not updated.
|
||||
int mCompositorPauseTimeoutID = 0;
|
||||
|
@ -768,6 +764,7 @@ class nsWindow final : public nsBaseWidget {
|
|||
// rendering to released window.
|
||||
void ConfigureGdkWindow();
|
||||
void ReleaseGdkWindow();
|
||||
void ConfigureCompositor();
|
||||
|
||||
// nsBaseWidget
|
||||
WindowRenderer* GetWindowRenderer() override;
|
||||
|
|
Загрузка…
Ссылка в новой задаче