mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1645677 [Wayland] Update EGLSurface when wl_surface is deleted r=emilio,jgilbert
When GtkWidget is hidden, underlying wl_surface is deleted. We need to also update EGLSurface of GtkWidget (GtkCompositorWidget)
as EGLSurface is directly linked to wl_surface:
- When GtkWidget is hidden, call GtkCompositorWidget::DisableRendering(). That releases GtkCompositorWidget resources
related to GtkWidget (XWindow/XVisual etc.) and marks the widget as hidden.
- If GtkWidget is backed by EGL call compositor resume which forces compositor to create new EGLSurface.
- Make sure GLContextEGL can create EGLSurface even when GtkWidget is hidden and wl_surface is missing.
It prevents fallback to SW rendering or pause RenderCompositorEGL which leads to Bug 1777664
(whole browser UI freeze).
- Return early from RenderCompositorEGL::BeginFrame()/RenderCompositorEGL::EndFrame() when GtkCompositorWidget is hidden.
Depends on D157357
Differential Revision: https://phabricator.services.mozilla.com/D157358
This commit is contained in:
parent
24d8cfd0dd
commit
cb46f7b2dd
@ -346,6 +346,18 @@ EGLSurface GLContextEGL::CreateEGLSurfaceForCompositorWidget(
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aCompositorWidget);
|
||||
#ifdef MOZ_WAYLAND
|
||||
// RenderCompositorEGL does not like EGL_NO_SURFACE as it fallbacks
|
||||
// to SW rendering or claims itself as paused.
|
||||
// In case we're missing valid native window because aCompositorWidget hidden,
|
||||
// just create a fallback EGLSurface.
|
||||
// Actual EGLSurface will be created by widget code later when
|
||||
// aCompositorWidget becomes visible.
|
||||
if (widget::GdkIsWaylandDisplay() && aCompositorWidget->IsHidden()) {
|
||||
mozilla::gfx::IntSize pbSize(16, 16);
|
||||
return CreateWaylandBufferSurface(*egl, aConfig, pbSize);
|
||||
}
|
||||
#endif
|
||||
EGLNativeWindowType window =
|
||||
GET_NATIVE_WINDOW_FROM_COMPOSITOR_WIDGET(aCompositorWidget);
|
||||
if (!window) {
|
||||
|
@ -127,6 +127,11 @@ RenderedFrameId RenderCompositorEGL::EndFrame(
|
||||
#endif
|
||||
|
||||
RenderedFrameId frameId = GetNextRenderFrameId();
|
||||
#ifdef MOZ_WAYLAND
|
||||
if (mWidget->IsHidden()) {
|
||||
return frameId;
|
||||
}
|
||||
#endif
|
||||
if (mEGLSurface != EGL_NO_SURFACE && aDirtyRects.Length() > 0) {
|
||||
gfx::IntRegion bufferInvalid;
|
||||
const auto bufferSize = GetBufferSize();
|
||||
|
@ -3442,6 +3442,10 @@ void* nsWindow::GetNativeData(uint32_t aDataType) {
|
||||
#endif
|
||||
#ifdef MOZ_WAYLAND
|
||||
if (GdkIsWaylandDisplay()) {
|
||||
if (mCompositorWidgetDelegate) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
!mCompositorWidgetDelegate->AsGtkCompositorWidget()->IsHidden());
|
||||
}
|
||||
eglWindow = moz_container_wayland_get_egl_window(
|
||||
mContainer, FractionalScaleFactor());
|
||||
}
|
||||
@ -4059,6 +4063,26 @@ void nsWindow::OnMap() {
|
||||
|
||||
void nsWindow::OnUnmap() {
|
||||
LOG("nsWindow::OnUnmap");
|
||||
|
||||
// wl_surface owned by mContainer is going to be deleted.
|
||||
// Make sure we don't paint to it on Wayland.
|
||||
if (GdkIsWaylandDisplay() && mCompositorWidgetDelegate) {
|
||||
mCompositorWidgetDelegate->DisableRendering();
|
||||
}
|
||||
#ifdef MOZ_WAYLAND
|
||||
if (moz_container_wayland_has_egl_window(mContainer)) {
|
||||
// Widget is backed by OpenGL EGLSurface created over wl_surface
|
||||
// owned by mContainer.
|
||||
// RenderCompositorEGL::Resume() deletes recent EGLSurface based on
|
||||
// wl_surface owned by mContainer and creates a new fallback EGLSurface.
|
||||
// Then we can delete wl_surface in moz_container_wayland_unmap().
|
||||
// We don't want to pause compositor as it may lead to whole
|
||||
// browser freeze (Bug 1777664).
|
||||
if (CompositorBridgeChild* remoteRenderer = GetRemoteRenderer()) {
|
||||
remoteRenderer->SendResume();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
moz_container_wayland_unmap(GTK_WIDGET(mContainer));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user