[webkit-changes] [WebKit/WebKit] 800a12: Persistent black rectangles (or entirely black) pa...

Simon Fraser noreply at github.com
Wed Jun 14 13:33:22 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 800a12569f6908d448eb0f6834113ad3afe83fa4
      https://github.com/WebKit/WebKit/commit/800a12569f6908d448eb0f6834113ad3afe83fa4
  Author: Simon Fraser <simon.fraser at apple.com>
  Date:   2023-06-14 (Wed, 14 Jun 2023)

  Changed paths:
    M Source/WebCore/platform/graphics/ImageBuffer.cpp
    M Source/WebCore/platform/graphics/ImageBuffer.h
    M Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.h
    M Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm
    M Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h
    M Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.cpp

  Log Message:
  -----------
  Persistent black rectangles (or entirely black) page after app switching after GPU Process jetsam
https://bugs.webkit.org/show_bug.cgi?id=258083
rdar://110507750

Reviewed by Kimmo Kinnunen.

After 261553 at main there was an assumption that there was a 1:1 relationship between an ImageBuffer
(identified by a RenderingResourceIdentifier) and an IOSurface, since the UI process cached
IOSurfaces via RemoteLayerTreeNode::m_cachedContentsBuffers and left these IOSurfaces on layers
contents if the RenderingResourceIdentifier didn't change.

This assumption is broken in the case of a GPU Process exit (crash, jetsam or idle exit). When that
happens, RemoteResourceCacheProxy::remoteResourceCacheWasDestroyed() is called, and triggers backend
recreation on all the ImageBuffers, which allocates new IOSurfaces in the GPU Process.

This could lead to the following scenario:
* We have a layer, and make two or more ImageBuffers for it, referencing IOSurfaces which make their way
  to the UI Process and are set as layer contents.
* Tab goes into the background, we make the IOSurfaces volatile
* Device suffers memory pressure and the IOSurfaces are purged
* GPU Process exits for some reason
* RemoteRenderingBackendProxy::didClose() calls m_remoteResourceCacheProxy.remoteResourceCacheWasDestroyed() which
  clears ImageBuffer backends, then creates new ones but reusing the same rendering resource identifiers
* We buffer swap using the new ImageBuffers
* In the UI process, we get to RemoteLayerBackingStoreProperties::updateCachedBuffers(), compare with RemoteLayerTreeNode’s
  m_cachedContentsBuffers, and decide that we can re-use the RetainPtr<id> m_buffer; because the RenderingResourceIdentifier match.
* We leave a purged IOSurface on a CALayer, which renders black or otherwise wrong.

Fix by adding ImageBuffer::backendGeneration() which is incremented when the ImageBuffer gets a new
backend. Track both the RenderingResourceIdentifier and the backend generation in
CachedContentsBuffer via BufferAndBackendInfo, and clear the cached buffers when the
backendGeneration changes.

* Source/WebCore/platform/graphics/ImageBuffer.cpp:
(WebCore::ImageBuffer::setBackend):
(WebCore::ImageBuffer::backendGeneration const):
* Source/WebCore/platform/graphics/ImageBuffer.h:
* Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.h:
(WebKit::BufferAndBackendInfo::BufferAndBackendInfo):
(WebKit::RemoteLayerBackingStoreProperties::frontBufferIdentifier const): Deleted.
(WebKit::RemoteLayerBackingStoreProperties::backBufferIdentifier const): Deleted.
(WebKit::RemoteLayerBackingStoreProperties::secondaryBackBufferIdentifier const): Deleted.
* Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm:
(WebKit::BufferAndBackendInfo::encode const):
(WebKit::BufferAndBackendInfo::decode):
(WebKit::RemoteLayerBackingStore::encode const):
(WebKit::RemoteLayerBackingStoreProperties::decode):
(WebKit::RemoteLayerBackingStoreProperties::dump const):
(WebKit::RemoteLayerBackingStoreProperties::applyBackingStoreToLayer):
(WebKit::RemoteLayerBackingStoreProperties::updateCachedBuffers):
(WebKit::operator<<):
(WebKit::RemoteLayerBackingStore::Buffer::encode const): Deleted.
* Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h:
(WebKit::RemoteLayerTreeNode::takeCachedContentsBuffers):
* Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.cpp:
(WebKit::RemoteImageBufferProxy::didCreateImageBufferBackend):

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




More information about the webkit-changes mailing list