[webkit-changes] [WebKit/WebKit] ea9faa: [UnifiedPDF] There's a tile flicker after resizing...
Simon Fraser
noreply at github.com
Mon Oct 14 20:05:56 PDT 2024
Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: ea9faa806d568971180b321b28271beb4dd1db8c
https://github.com/WebKit/WebKit/commit/ea9faa806d568971180b321b28271beb4dd1db8c
Author: Simon Fraser <simon.fraser at apple.com>
Date: 2024-10-14 (Mon, 14 Oct 2024)
Changed paths:
M Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/AsyncPDFRenderer.h
M Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/AsyncPDFRenderer.mm
M Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/PDFDiscretePresentationController.mm
M Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/PDFPageCoverage.h
M Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/PDFPageCoverage.mm
M Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/PDFScrollingPresentationController.mm
M Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/UnifiedPDFPlugin.mm
Log Message:
-----------
[UnifiedPDF] There's a tile flicker after resizing has finished
https://bugs.webkit.org/show_bug.cgi?id=270041
rdar://123566595
Reviewed by Abrar Rahman Protyasha.
In UnifiedPDF, which uses TiledBacking for tiling, there are a couple of cases where we drop all our
rendered tiles, and temporarily show the low-resolution page previews, which is jarring. Those
two cases are when the tile size changes, and when the scale changes.
This PR avoids the display of the low-resolution page preview by keeping tiles around from
the previous state, and painting them before the high-resolution tiles. These tiles correspond
to what the use saw last time, so painting them is never lower resolution than earlier frames.
To track when we should keep old tiles around, respond to the TiledBackingClient functions that
tell us when it's doing a full tile revalidation, and when it's repainting after a scale change,
by tracking some per-TileGrid state. When we get `willRepaintTile` or `willRemoveTile` in those
states, instead of deleting the old buffers, move them to `m_rendereredTilesForOldState`.
Now we have to figure out when to clear `m_rendereredTilesForOldState` (otherwise we'll just
accumulate memory). Do so in `didRevalidateTiles()` by storing a set of all the tile renders
for the new tiles; when those renders are complete, we can clear `m_rendereredTilesForOldState`.
These are also tracked on a per-TileGrid basis.
We paint the old tiles in `AsyncPDFRenderer::paintTilesForPage()` before the current tiles.
Because their geometry no longer matches the current tiles, we have to map the correct parts
of their ImageBuffers into the current painting coordinates. We can do so by converting
geometry into PDF layout coordinates. To do this, we need to store data on how painting rects ("clip rects")
mapped into PDF layout coordinates per tile, so enhance `PerPageInfo` in `PDFPageCoverage` to store an
additional per-page rect, which is some arbitrary rect mapped into PDF layout coordinates. For our
purposes, this rect is a painting clip rect. The painting code then uses `mapRect()` to compute
source and destination rects for the relevant portion of the stale tile's ImageBuffer.
* Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/AsyncPDFRenderer.h:
* Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/AsyncPDFRenderer.mm:
(WebKit::AsyncPDFRenderer::stopTrackingLayer):
(WebKit::AsyncPDFRenderer::willRepaintTile):
(WebKit::AsyncPDFRenderer::enqueueTilePaintForTileGridRepaint):
(WebKit::AsyncPDFRenderer::willRemoveTile):
(WebKit::AsyncPDFRenderer::willRevalidateTiles):
(WebKit::AsyncPDFRenderer::didRevalidateTiles):
(WebKit::AsyncPDFRenderer::revalidationStateForGrid):
(WebKit::AsyncPDFRenderer::trackRendersForStaleTileMaintenance):
(WebKit::AsyncPDFRenderer::trackRenderCompletionForStaleTileMaintenance):
(WebKit::AsyncPDFRenderer::willRepaintTilesAfterScaleFactorChange):
(WebKit::AsyncPDFRenderer::didRepaintTilesAfterScaleFactorChange):
(WebKit::AsyncPDFRenderer::clearRequestsAndCachedTiles):
(WebKit::AsyncPDFRenderer::enqueueTilePaintIfNecessary):
(WebKit::AsyncPDFRenderer::enqueuePaintWithClip):
(WebKit::AsyncPDFRenderer::didCompleteTileRender):
(WebKit::AsyncPDFRenderer::paintTilesForPage):
* Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/PDFDiscretePresentationController.mm:
(WebKit::PDFDiscretePresentationController::pageCoverageForContentsRect const):
Don't intersect with the document bounds. First this wasn't necessary because elsewhere we clip
to PDF page bounds which are inside the content rect. Second, this clipping would mutate the clipRects
that we need later to correctly map subsets of the tile buffers.
* Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/PDFPageCoverage.h:
* Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/PDFPageCoverage.mm:
(WebKit::operator<<):
* Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/PDFScrollingPresentationController.mm:
(WebKit::PDFScrollingPresentationController::pageCoverageForContentsRect const):
Don't intersect with the document bounds. First this wasn't necessary because elsewhere we clip
to PDF page bounds which are inside the content rect. Second, this clipping would mutate the clipRects
that we need later to correctly map subsets of the tile buffers.
* Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/UnifiedPDFPlugin.mm:
(WebKit::UnifiedPDFPlugin::paintPDFContent):
Just paint the yellow first so other things paint over it.
Canonical link: https://commits.webkit.org/285170@main
To unsubscribe from these emails, change your notification settings at https://github.com/WebKit/WebKit/settings/notifications
More information about the webkit-changes
mailing list