Modified: trunk/Source/WebKit/ChangeLog (270590 => 270591)
--- trunk/Source/WebKit/ChangeLog 2020-12-09 19:30:10 UTC (rev 270590)
+++ trunk/Source/WebKit/ChangeLog 2020-12-09 19:50:11 UTC (rev 270591)
@@ -1,3 +1,45 @@
+2020-12-09 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [Concurrent display lists] Support playback of display list items with cached resources
+ https://bugs.webkit.org/show_bug.cgi?id=218614
+ <rdar://problem/71326662>
+
+ Reviewed by Tim Horton.
+
+ Teaches the GPU process to resume playback of display list items that were previously unable to be played back
+ due to missing cached resources. See below for more details.
+
+ * GPUProcess/graphics/RemoteRenderingBackend.cpp:
+ (WebKit::RemoteRenderingBackend::createImageBuffer):
+
+ See if the newly created image buffer's ID matches that of the pending wakeup message; if so, immediately kick
+ off the wakeup loop.
+
+ (WebKit::RemoteRenderingBackend::nextDestinationImageBufferAfterApplyingDisplayLists):
+ (WebKit::RemoteRenderingBackend::wakeUpAndApplyDisplayList):
+
+ In the case where the next destination image buffer is unknown, bail early and resume when we eventually learn
+ about the image buffer in the GPU process. This can happen if a MetaCommandChangeDestinationImageBuffer item is
+ added that references a newly created image buffer.
+
+ (WebKit::RemoteRenderingBackend::setNextItemBufferToRead):
+ (WebKit::RemoteRenderingBackend::cacheNativeImage):
+
+ See if the newly cached image's ID matches that of the pending wakeup message; if so, immediately kick off the
+ wakeup loop.
+
+ (WebKit::RemoteRenderingBackend::didCreateSharedDisplayListHandle):
+ * GPUProcess/graphics/RemoteRenderingBackend.h:
+
+ Add a private `PendingWakeupInformation` struct that encapsulates all the information needed to remember that
+ we stopped display list processing, and resume processing in the future. Currently, this contains a set of
+ wakeup message arguments, and (optionally) the identifier of the missing resource that we need to receive in
+ order to continue.
+
+ We also use this in place of storing GPUProcessWakeupMessageArguments on RemoteRenderingBackend.
+
+ (WebKit::RemoteRenderingBackend::PendingWakeupInformation::shouldPerformWakeup const):
+
2020-12-09 Kimmo Kinnunen <kkinnu...@apple.com>
Implement RemoteWebGLBackend
Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp (270590 => 270591)
--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp 2020-12-09 19:30:10 UTC (rev 270590)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp 2020-12-09 19:50:11 UTC (rev 270591)
@@ -127,6 +127,9 @@
}
m_remoteResourceCache.cacheImageBuffer(makeRef(*imageBuffer));
+
+ if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(renderingResourceIdentifier))
+ wakeUpAndApplyDisplayList(std::exchange(m_pendingWakeupInfo, WTF::nullopt)->arguments);
}
DisplayList::ReplayResult RemoteRenderingBackend::submit(const DisplayList::DisplayList& displayList, ImageBuffer& destination)
@@ -190,12 +193,19 @@
if (result.reasonForStopping == DisplayList::StopReplayReason::ChangeDestinationImageBuffer) {
destination = makeRefPtr(m_remoteResourceCache.cachedImageBuffer(*result.nextDestinationImageBuffer));
if (!destination) {
- ASSERT(!m_pendingWakeupArguments);
- m_pendingWakeupArguments = {{ handle.identifier(), offset, *result.nextDestinationImageBuffer }};
+ ASSERT(!m_pendingWakeupInfo);
+ m_pendingWakeupInfo = {{{ handle.identifier(), offset, *result.nextDestinationImageBuffer }, WTF::nullopt }};
}
}
- if (m_pendingWakeupArguments)
+ if (result.reasonForStopping == DisplayList::StopReplayReason::MissingCachedResource) {
+ m_pendingWakeupInfo = {{
+ { handle.identifier(), offset, destination->renderingResourceIdentifier() },
+ result.missingCachedResourceIdentifier
+ }};
+ }
+
+ if (m_pendingWakeupInfo)
break;
if (!sizeToRead)
@@ -224,12 +234,15 @@
destinationImageBuffer = nextDestinationImageBufferAfterApplyingDisplayLists(*destinationImageBuffer, arguments.offset, *initialHandle);
if (!destinationImageBuffer) {
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT(m_pendingWakeupInfo);
return;
}
- while (m_pendingWakeupArguments) {
- auto nextHandle = m_sharedDisplayListHandles.get(m_pendingWakeupArguments->itemBufferIdentifier);
+ while (m_pendingWakeupInfo) {
+ if (m_pendingWakeupInfo->missingCachedResourceIdentifier)
+ break;
+
+ auto nextHandle = m_sharedDisplayListHandles.get(m_pendingWakeupInfo->arguments.itemBufferIdentifier);
if (!nextHandle) {
// If the handle identifier is currently unknown, wait until the GPU process receives an
// IPC message with a shared memory handle to the next item buffer.
@@ -237,11 +250,11 @@
}
// Otherwise, continue reading the next display list item buffer from the start.
- auto arguments = *std::exchange(m_pendingWakeupArguments, WTF::nullopt);
+ auto arguments = std::exchange(m_pendingWakeupInfo, WTF::nullopt)->arguments;
destinationImageBuffer = nextDestinationImageBufferAfterApplyingDisplayLists(*destinationImageBuffer, arguments.offset, *nextHandle);
if (!destinationImageBuffer) {
- ASSERT_NOT_REACHED();
- return;
+ RELEASE_ASSERT(m_pendingWakeupInfo);
+ break;
}
}
}
@@ -248,12 +261,12 @@
void RemoteRenderingBackend::setNextItemBufferToRead(DisplayList::ItemBufferIdentifier identifier, WebCore::RenderingResourceIdentifier destinationIdentifier)
{
- if (UNLIKELY(m_pendingWakeupArguments)) {
+ if (UNLIKELY(m_pendingWakeupInfo)) {
// FIXME: Add a message check to terminate the web process.
ASSERT_NOT_REACHED();
return;
}
- m_pendingWakeupArguments = {{ identifier, SharedDisplayListHandle::headerSize(), destinationIdentifier }};
+ m_pendingWakeupInfo = {{{ identifier, SharedDisplayListHandle::headerSize(), destinationIdentifier }, WTF::nullopt }};
}
void RemoteRenderingBackend::getImageData(AlphaPremultiplication outputFormat, IntRect srcRect, RenderingResourceIdentifier renderingResourceIdentifier, CompletionHandler<void(IPC::ImageDataReference&&)>&& completionHandler)
@@ -266,10 +279,18 @@
void RemoteRenderingBackend::cacheNativeImage(const ShareableBitmap::Handle& handle, RenderingResourceIdentifier renderingResourceIdentifier)
{
- if (auto bitmap = ShareableBitmap::create(handle)) {
- if (auto image = NativeImage::create(bitmap->createPlatformImage(), renderingResourceIdentifier))
- m_remoteResourceCache.cacheNativeImage(makeRef(*image));
- }
+ auto bitmap = ShareableBitmap::create(handle);
+ if (!bitmap)
+ return;
+
+ auto image = NativeImage::create(bitmap->createPlatformImage(), renderingResourceIdentifier);
+ if (!image)
+ return;
+
+ m_remoteResourceCache.cacheNativeImage(makeRef(*image));
+
+ if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(renderingResourceIdentifier))
+ wakeUpAndApplyDisplayList(std::exchange(m_pendingWakeupInfo, WTF::nullopt)->arguments);
}
void RemoteRenderingBackend::releaseRemoteResource(RenderingResourceIdentifier renderingResourceIdentifier)
@@ -288,8 +309,8 @@
if (auto sharedMemory = SharedMemory::map(handle.handle, SharedMemory::Protection::ReadWrite))
m_sharedDisplayListHandles.set(identifier, DisplayListReaderHandle::create(identifier, sharedMemory.releaseNonNull()));
- if (m_pendingWakeupArguments && m_pendingWakeupArguments->itemBufferIdentifier == identifier)
- wakeUpAndApplyDisplayList(*std::exchange(m_pendingWakeupArguments, WTF::nullopt));
+ if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(identifier))
+ wakeUpAndApplyDisplayList(std::exchange(m_pendingWakeupInfo, WTF::nullopt)->arguments);
}
Optional<DisplayList::ItemHandle> WARN_UNUSED_RETURN RemoteRenderingBackend::decodeItem(const uint8_t* data, size_t length, DisplayList::ItemType type, uint8_t* handleLocation)
Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h (270590 => 270591)
--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h 2020-12-09 19:30:10 UTC (rev 270590)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h 2020-12-09 19:50:11 UTC (rev 270591)
@@ -113,11 +113,27 @@
void releaseRemoteResource(WebCore::RenderingResourceIdentifier);
void didCreateSharedDisplayListHandle(WebCore::DisplayList::ItemBufferIdentifier, const SharedMemory::IPCHandle&, WebCore::RenderingResourceIdentifier destinationBufferIdentifier);
+ struct PendingWakeupInformation {
+ GPUProcessWakeupMessageArguments arguments;
+ Optional<WebCore::RenderingResourceIdentifier> missingCachedResourceIdentifier;
+
+ bool shouldPerformWakeup(WebCore::RenderingResourceIdentifier identifier) const
+ {
+ return arguments.destinationImageBufferIdentifier == identifier
+ || missingCachedResourceIdentifier == identifier;
+ }
+
+ bool shouldPerformWakeup(WebCore::DisplayList::ItemBufferIdentifier identifier) const
+ {
+ return arguments.itemBufferIdentifier == identifier;
+ }
+ };
+
RemoteResourceCache m_remoteResourceCache;
WeakPtr<GPUConnectionToWebProcess> m_gpuConnectionToWebProcess;
RenderingBackendIdentifier m_renderingBackendIdentifier;
HashMap<WebCore::DisplayList::ItemBufferIdentifier, RefPtr<DisplayListReaderHandle>> m_sharedDisplayListHandles;
- Optional<GPUProcessWakeupMessageArguments> m_pendingWakeupArguments;
+ Optional<PendingWakeupInformation> m_pendingWakeupInfo;
};
} // namespace WebKit