[webkit-changes] [WebKit/WebKit] baeabe: Discard decoded image data in Web processes with n...

Cameron McCormack noreply at github.com
Tue Apr 4 13:22:29 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: baeabe11daecb0ce0df709e88ae0ef821f7a2bcb
      https://github.com/WebKit/WebKit/commit/baeabe11daecb0ce0df709e88ae0ef821f7a2bcb
  Author: Cameron McCormack <heycam at apple.com>
  Date:   2023-04-04 (Tue, 04 Apr 2023)

  Changed paths:
    M Source/WebCore/rendering/RenderBoxModelObject.cpp
    M Source/WebKit/GPUProcess/graphics/QualifiedResourceHeap.h
    M Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp
    M Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h
    M Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in
    M Source/WebKit/GPUProcess/graphics/RemoteResourceCache.cpp
    M Source/WebKit/GPUProcess/graphics/RemoteResourceCache.h
    M Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.h
    M Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.mm
    M Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp
    M Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h
    M Source/WebKit/WebProcess/GPU/graphics/RemoteResourceCacheProxy.cpp
    M Source/WebKit/WebProcess/GPU/graphics/RemoteResourceCacheProxy.h
    M Source/WebKit/WebProcess/WebPage/DrawingArea.h
    M Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.h
    M Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.mm
    M Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.h
    M Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm
    M Source/WebKit/WebProcess/WebPage/WebPage.cpp
    M Source/WebKit/WebProcess/WebPage/WebPage.h
    M Source/WebKit/WebProcess/WebProcess.cpp
    M Source/WebKit/WebProcess/WebProcess.h

  Log Message:
  -----------
  Discard decoded image data in Web processes with no foreground tabs
https://bugs.webkit.org/show_bug.cgi?id=254768
<rdar://problem/107437769>

Reviewed by Said Abou-Hallawa.

To reduce memory footprint, this patch discards decoded image data in
Web processes with no foreground tabs.

Destroying the decoded data means there is a risk of images not
rendering next time we paint, if we had decided to async decode (due to
the images being large, or referenced with <img decode=async>, etc.).
This can manifest in a couple of ways:

1. When switching back to a tab that's had its decoded image data
   destroyed, we won't see the effect immediately, since we'll show the
   page snapshot without painting the page again. By the next time we
   do need to paint (e.g. after the user interacts with the page in some
   way), the image may briefly disappear while we wait for the async
   decode.

2. When hovering over the tab strip, Safari generates thumbnails showing
   the contents of the tabs. Although the image painting is performed
   with PaintBehavior::Snapshotting, this does not currently override
   <img decode=async>, so any previously decoded <img decode=async>
   image will appear blank in the thumbnail.

To avoid these issues, we tell the RemoteLayerTreeDrawingArea to decode
images synchronously in the next rendering update, and adjust
RenderBoxModelObject::decodingModeForImageDraw to prioritize
PaintBehavior::Snapshotting over <img decode=async>.

RemoteLayerTreeDrawingArea can perform no-paint rendering updates when
switching back to a background tab, so we wait until we do some painting
(a backing store has a non-empty dirty region) before clearing
m_nextRenderingUpdateRequiresSynchronousImageDecoding.

WebProcess::m_nonVisibleProcessEarlyMemoryCleanupTimer is changed to a
DeferrableOneShotTimer. If a tab is in the background, and we have
already destroyed the image decoded data, we schedule the timer again.
This avoids the image data persisting if the page thumbnails are
generated. If a tab is in the background, and we haven't yet destroyed
the image decoded data (i.e., if the timer is pending), then we defer
the timer when an image is painted. This avoids continuously destroying
then regenerating the decoded data, if the page is repeatedly drawing
images in the background.

When the timer fires, we also tell the RemoteResourceCacheProxy to clear
all its image resources at once, rather than have each NativeImage in
its destructor tell the RemoteResourceCacheProxy to remove a single
image resource, to reduce IPC traffic.

For now, we only do this when UI side compositing is enabled, but it
would also be beneficial in other configurations.

* Source/WebCore/rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::decodingModeForImageDraw const):
* Source/WebKit/GPUProcess/graphics/QualifiedResourceHeap.h:
(WebKit::QualifiedResourceHeap::releaseAllImageResources):
* Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp:
(WebKit::RemoteRenderingBackend::releaseAllImageResources):
* Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h:
* Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in:
* Source/WebKit/GPUProcess/graphics/RemoteResourceCache.cpp:
(WebKit::RemoteResourceCache::releaseAllImageResources):
* Source/WebKit/GPUProcess/graphics/RemoteResourceCache.h:
* Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.h:
* Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.mm:
(WebKit::RemoteLayerBackingStoreCollection::paintReachableBackingStoreContents):
* Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp:
(WebKit::RemoteRenderingBackendProxy::releaseAllImageResources):
* Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h:
* Source/WebKit/WebProcess/GPU/graphics/RemoteResourceCacheProxy.cpp:
(WebKit::RemoteResourceCacheProxy::recordNativeImageUse):
(WebKit::RemoteResourceCacheProxy::releaseAllImageResources):
* Source/WebKit/WebProcess/GPU/graphics/RemoteResourceCacheProxy.h:
* Source/WebKit/WebProcess/WebPage/DrawingArea.h:
(WebKit::DrawingArea::setNextRenderingUpdateRequiresSynchronousImageDecoding):
* Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.h:
(WebKit::RemoteLayerTreeContext::setNextRenderingUpdateRequiresSynchronousImageDecoding):
* Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.mm:
(WebKit::RemoteLayerTreeContext::buildTransaction):
* Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.h:
* Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::setNextRenderingUpdateRequiresSynchronousImageDecoding):
(WebKit::RemoteLayerTreeDrawingArea::updateRendering):
(WebKit::RemoteLayerTreeDrawingArea::activityStateDidChange):
(WebKit::RemoteLayerTreeDrawingArea::dispatchAfterEnsuringDrawing):
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::willDestroyDecodedDataForAllImages):
* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Source/WebKit/WebProcess/WebProcess.cpp:
(WebKit::WebProcess::WebProcess):
(WebKit::WebProcess::pageDidEnterWindow):
(WebKit::WebProcess::pageWillLeaveWindow):
(WebKit::WebProcess::nonVisibleProcessEarlyMemoryCleanupTimerFired):
(WebKit::WebProcess::destroyDecodedDataForAllImages):
(WebKit::WebProcess::deferNonVisibleProcessEarlyMemoryCleanupTimer):
* Source/WebKit/WebProcess/WebProcess.h:

Canonical link: https://commits.webkit.org/262585@main




More information about the webkit-changes mailing list