Skip to content

Commit 8e51f23

Browse files
committed
[PageLifecycle] Destroy/recreate gl assets on freeze/resume.
1 parent 34c0708 commit 8e51f23

9 files changed

Lines changed: 116 additions & 0 deletions

File tree

Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8037,6 +8037,12 @@ void WebGLRenderingContextBase::maybeRestoreContext()
80378037
if (!hostWindow)
80388038
return;
80398039

8040+
if (frame->settings().nonCompositedWebGLEnabled()) {
8041+
// If the context was lost because the browser was frozen, the nativeWindow will have changed
8042+
// when resuming, so we need to set the vale again.
8043+
m_attributes.nativeWindowID = hostWindow->nativeWindowID();
8044+
}
8045+
80408046
RefPtr<GraphicsContextGL> context = hostWindow->createGraphicsContextGL(m_attributes);
80418047
if (!context) {
80428048
if (m_contextLostState->mode == RealLostContext)

Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,5 +429,52 @@ void ThreadedCompositor::targetRefreshRateDidChange(unsigned rate)
429429
m_displayRefreshMonitor->setTargetRefreshRate(rate);
430430
}
431431

432+
void ThreadedCompositor::destroyGLResourcesAfterSuspend(bool destroyNativeWindow)
433+
{
434+
// This must be called with the RunLoop suspended.
435+
if (m_suspendedCount <= 0)
436+
return;
437+
438+
m_scene->detach();
439+
m_compositingRunLoop->performTaskSync([this, protectedThis = Ref { *this }, destroyNativeWindow] {
440+
if (m_context) {
441+
if (!m_context->makeContextCurrent())
442+
return;
443+
444+
updateSceneWithoutRendering();
445+
m_scene->purgeGLResources();
446+
m_context = nullptr;
447+
}
448+
449+
if (destroyNativeWindow) {
450+
m_client.didDestroyGLContext();
451+
m_nativeSurfaceHandle = 0;
452+
}
453+
454+
m_scene = nullptr;
455+
});
456+
}
457+
458+
void ThreadedCompositor::recreateGLResourcesBeforeResume(bool nativeWindowWasDestroyed)
459+
{
460+
// This must be called with the RunLoop suspended.
461+
if (m_suspendedCount <= 0)
462+
return;
463+
464+
m_compositingRunLoop->performTaskSync([this, protectedThis = Ref { *this }, nativeWindowWasDestroyed] {
465+
m_scene = adoptRef(new CoordinatedGraphicsScene(this));
466+
467+
if (nativeWindowWasDestroyed)
468+
m_nativeSurfaceHandle = m_client.nativeSurfaceHandleForCompositing();
469+
470+
createGLContext();
471+
if (m_context) {
472+
if (!m_nativeSurfaceHandle)
473+
m_paintFlags |= TextureMapper::PaintingMirrored;
474+
}
475+
});
476+
}
477+
478+
432479
}
433480
#endif // USE(COORDINATED_GRAPHICS)

Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ class ThreadedCompositor : public CoordinatedGraphicsSceneClient, public ThreadS
8383
void resume();
8484
void renderSingleFrame();
8585

86+
void destroyGLResourcesAfterSuspend(bool);
87+
void recreateGLResourcesBeforeResume(bool);
88+
8689
private:
8790
ThreadedCompositor(Client&, ThreadedDisplayRefreshMonitor::Client&, WebCore::PlatformDisplayID, const WebCore::IntSize&, float scaleFactor, WebCore::TextureMapper::PaintFlags, bool);
8891

Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,4 +947,21 @@ void DrawingAreaCoordinatedGraphics::renderSingleFrameIfRenderingPaused()
947947
m_layerTreeHost->renderSingleFrameWhilePaused();
948948
}
949949

950+
951+
void DrawingAreaCoordinatedGraphics::destroyGLResourcesAfterSuspend()
952+
{
953+
if (!m_isPaintingSuspended || !m_usingPageLifecycle || !m_layerTreeHost)
954+
return;
955+
956+
m_layerTreeHost->destroyGLResourcesAfterSuspend();
957+
}
958+
959+
void DrawingAreaCoordinatedGraphics::recreateGLResourcesBeforeResume()
960+
{
961+
if (!m_isPaintingSuspended || !m_usingPageLifecycle || !m_layerTreeHost)
962+
return;
963+
964+
m_layerTreeHost->recreateGLResourcesBeforeResume();
965+
}
966+
950967
} // namespace WebKit

Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ class DrawingAreaCoordinatedGraphics final : public DrawingArea {
111111

112112
void renderSingleFrameIfRenderingPaused() final;
113113

114+
void destroyGLResourcesAfterSuspend() final;
115+
void recreateGLResourcesBeforeResume() final;
116+
114117
uint64_t m_backingStoreStateID { 0 };
115118

116119
// Whether painting is enabled. If painting is disabled, any calls to setNeedsDisplay and scroll are ignored.

Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ LayerTreeHost::LayerTreeHost(WebPage& webPage)
5757
, m_layerFlushTimer(RunLoop::main(), this, &LayerTreeHost::layerFlushTimerFired)
5858
, m_coordinator(webPage, *this)
5959
, m_usingPageLifecycle(webPage.corePage()->settings().pageLifecycleAPIEnabled())
60+
, m_destroyNativeWindowOnSuspend(webPage.corePage()->settings().pageLifecycleAPIDestroyWindowOnFreeze())
6061
{
6162
#if USE(GLIB_EVENT_LOOP)
6263
m_layerFlushTimer.setPriority(RunLoopSourcePriority::LayerFlushTimer);
@@ -557,6 +558,31 @@ void LayerTreeHost::commitTransientZoom(double scale, FloatPoint origin)
557558
}
558559
#endif
559560

561+
void LayerTreeHost::destroyGLResourcesAfterSuspend()
562+
{
563+
if (!m_isSuspended || !m_usingPageLifecycle)
564+
return;
565+
566+
// Tell the ThreadedCompositor to release its OpenGL resources.
567+
m_compositor->destroyGLResourcesAfterSuspend(m_destroyNativeWindowOnSuspend);
568+
569+
// Destroy the sharingContext.
570+
auto& display = PlatformDisplay::sharedDisplayForCompositing();
571+
display.sharingGLContext()->makeContextCurrent();
572+
display.clearSharingGLContext();
573+
}
574+
575+
void LayerTreeHost::recreateGLResourcesBeforeResume()
576+
{
577+
if (!m_isSuspended || !m_usingPageLifecycle)
578+
return;
579+
580+
// The sharingContext will be automatically recreated when any GLContext is created.
581+
582+
// Tell the ThreadedCompositor to recreate its OpenGL resources.
583+
m_compositor->recreateGLResourcesBeforeResume(m_destroyNativeWindowOnSuspend);
584+
}
585+
560586
} // namespace WebKit
561587

562588
#endif // USE(COORDINATED_GRAPHICS)

Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ class LayerTreeHost
107107

108108
uint64_t nativeWindowID() { return m_surface->window(); }
109109

110+
void destroyGLResourcesAfterSuspend();
111+
void recreateGLResourcesBeforeResume();
112+
110113
private:
111114
#if USE(COORDINATED_GRAPHICS)
112115
void layerFlushTimerFired();
@@ -222,6 +225,7 @@ class LayerTreeHost
222225
WebCore::FloatPoint m_transientZoomOrigin;
223226
#endif
224227
bool m_usingPageLifecycle { false };
228+
bool m_destroyNativeWindowOnSuspend { false };
225229
};
226230

227231
#if !USE(COORDINATED_GRAPHICS)

Source/WebKit/WebProcess/WebPage/DrawingArea.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ class DrawingArea : public IPC::MessageReceiver, public WebCore::DisplayRefreshM
158158

159159
virtual void renderSingleFrameIfRenderingPaused() { };
160160

161+
virtual void destroyGLResourcesAfterSuspend() { };
162+
virtual void recreateGLResourcesBeforeResume() { };
163+
161164
protected:
162165
DrawingArea(DrawingAreaType, DrawingAreaIdentifier, WebPage&);
163166

Source/WebKit/WebProcess/WebPage/WebPage.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3805,6 +3805,10 @@ void WebPage::suspend(CompletionHandler<void(bool)>&& completionHandler)
38053805
ASSERT(m_cachedPage);
38063806
if (auto mainFrame = m_mainFrame->coreFrame())
38073807
mainFrame->loader().detachFromAllOpenedFrames();
3808+
3809+
// Now that the page has been suspended, destroy the OpenGL resources used for rendering.
3810+
m_drawingArea->destroyGLResourcesAfterSuspend();
3811+
38083812
completionHandler(true);
38093813
}
38103814

@@ -3837,6 +3841,9 @@ void WebPage::resume(CompletionHandler<void(bool)>&& completionHandler)
38373841
if (!cachedPage)
38383842
return completionHandler(false);
38393843

3844+
// Before resuming the page, recreate the OpenGL resources required for rendering.
3845+
m_drawingArea->recreateGLResourcesBeforeResume();
3846+
38403847
cachedPage->restore(*m_page);
38413848
unfreezeLayerTree(LayerTreeFreezeReason::PageSuspended);
38423849

0 commit comments

Comments
 (0)