Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Use device pixel ratio scaled backing stores for unscaled bitmap cont…
…ent if the page is downscaling

https://bugs.webkit.org/show_bug.cgi?id=242978

Reviewed by Simon Fraser and Dean Jackson.

If the page is downscaled, then not including the device pixel ratio in the backing store means that we'll
end up downscaling the image/canvas content and then upscaling it again by the device pixel ratio during
compositing.

This checks if we'd downscaling during painting if we removed the device pixel ratio, and skips the
unscaled bitmap optimization if so.

* LayoutTests/compositing/canvas/hidpi-canvas-backing-store-invalidation-2-expected.txt: Added.
* LayoutTests/compositing/canvas/hidpi-canvas-backing-store-invalidation-2.html: Added.
* Source/WebCore/rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::isUnscaledBitmapOnly const):

Canonical link: https://commits.webkit.org/252855@main
  • Loading branch information
mattwoodrow committed Jul 27, 2022
1 parent 9b9da1b commit fe12c1c
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 0 deletions.
@@ -0,0 +1,63 @@
Tests whether we switch back to a hidpi backing store when we zoom out (and would otherwise downscale the content too much).

(GraphicsLayer
(anchor 0.00 0.00)
(bounds 2008.00 1141.00)
(device scale 2.00)
(children 1
(GraphicsLayer
(bounds 2008.00 1141.00)
(contentsOpaque 1)
(device scale 2.00)
(children 1
(GraphicsLayer
(position 8.00 68.00)
(bounds 2000.00 1004.00)
(opacity 0.50)
(device scale 2.00)
(children 1
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 2000.00 1000.00)
(drawsContent 1)
(transform [0.50 0.00 0.00 0.00] [0.00 0.50 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 0.00 1.00])
(device scale 1.00)
)
)
)
)
)
)
)
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 1004.00 780.00)
(device scale 2.00)
(children 1
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 2008.00 1561.00)
(contentsOpaque 1)
(transform [0.50 0.00 0.00 0.00] [0.00 0.50 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 0.00 1.00])
(device scale 2.00)
(children 1
(GraphicsLayer
(position 8.00 68.00)
(bounds 2000.00 1004.00)
(opacity 0.50)
(device scale 2.00)
(children 1
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 2000.00 1000.00)
(drawsContent 1)
(transform [0.50 0.00 0.00 0.00] [0.00 0.50 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 0.00 1.00])
(device scale 2.00)
)
)
)
)
)
)
)

@@ -0,0 +1,56 @@
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="initial-scale=1">
<script>

if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}

function doTest() {
var canvasElement = document.getElementById("canvas");
let dpr = window.devicePixelRatio || 1;

canvas.width *= dpr;
canvas.height *= dpr;

canvas.style.transform = "scale(" + 1/dpr + ", " + 1/dpr + ")";

let ctx = canvas.getContext('2d');
ctx.scale(dpr, dpr);

ctx.fillStyle = 'green';
ctx.fillRect(0, 0, 1000, 500);

if (window.testRunner) {
document.getElementById('layers-before').innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_DEVICE_SCALE);
}

requestAnimationFrame(function() {
if (window.internals) {
window.internals.setPageScaleFactor(0.5, 0, 0);
}

if (window.testRunner) {
document.getElementById('layers-after').innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_DEVICE_SCALE);
testRunner.notifyDone();
}
});
}

window.addEventListener('load', doTest, false);
</script>
</head>

<body>
<p> Tests whether we switch back to a hidpi backing store when we zoom out (and would otherwise downscale the content too much).</p>
<div style="opacity:0.5">
<canvas id="canvas" width="1000" height="500" style="transform-origin:top left"></canvas>
</div>
<pre id="layers-before">Initial layer tree goes here in DRT</pre>
<pre id="layers-after">Mutated layer tree goes here in DRT</pre>
</body>

</html>
@@ -0,0 +1,3 @@
Tests whether we switch back to a hidpi backing store when we zoom out (and would otherwise downscale the content too much).


@@ -0,0 +1,62 @@
Tests whether we switch back to a hidpi backing store when we zoom out (and would otherwise downscale the content too much).

(GraphicsLayer
(anchor 0.00 0.00)
(bounds 2008.00 1144.00)
(device scale 2.00)
(children 1
(GraphicsLayer
(bounds 2008.00 1144.00)
(contentsOpaque 1)
(device scale 2.00)
(children 1
(GraphicsLayer
(position 8.00 72.00)
(bounds 2000.00 1005.00)
(opacity 0.50)
(device scale 2.00)
(children 1
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 2000.00 1000.00)
(usingTiledLayer 1)
(drawsContent 1)
(transform [0.50 0.00 0.00 0.00] [0.00 0.50 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 0.00 1.00])
(device scale 1.00)
)
)
)
)
)
)
)
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 2008.00 1550.00)
(device scale 2.00)
(children 1
(GraphicsLayer
(bounds 2008.00 1550.00)
(contentsOpaque 1)
(device scale 2.00)
(children 1
(GraphicsLayer
(position 8.00 72.00)
(bounds 2000.00 1005.00)
(opacity 0.50)
(device scale 2.00)
(children 1
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 2000.00 1000.00)
(drawsContent 1)
(transform [0.50 0.00 0.00 0.00] [0.00 0.50 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 0.00 1.00])
(device scale 1.00)
)
)
)
)
)
)
)

10 changes: 10 additions & 0 deletions Source/WebCore/page/FrameView.cpp
Expand Up @@ -3173,6 +3173,16 @@ void FrameView::setNeedsCompositingGeometryUpdate()
}
}

void FrameView::setDescendantsNeedUpdateBackingAndHierarchyTraversal()
{
RenderView* renderView = this->renderView();
if (renderView->usesCompositing()) {
if (auto* rootLayer = renderView->layer())
rootLayer->setDescendantsNeedUpdateBackingAndHierarchyTraversal();
renderView->compositor().scheduleCompositingLayerUpdate();
}
}

void FrameView::scheduleSelectionUpdate()
{
if (needsLayout())
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/page/FrameView.h
Expand Up @@ -133,6 +133,7 @@ class FrameView final : public ScrollView {

void setNeedsCompositingConfigurationUpdate();
void setNeedsCompositingGeometryUpdate();
void setDescendantsNeedUpdateBackingAndHierarchyTraversal();

WEBCORE_EXPORT void setViewportConstrainedObjectsNeedLayout();

Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/page/Page.cpp
Expand Up @@ -1208,6 +1208,7 @@ void Page::setPageScaleFactor(float scale, const IntPoint& origin, bool inStable
if (view && !delegatesScaling()) {
view->setNeedsLayoutAfterViewConfigurationChange();
view->setNeedsCompositingGeometryUpdate();
view->setDescendantsNeedUpdateBackingAndHierarchyTraversal();

document->resolveStyle(Document::ResolveStyleType::Rebuild);

Expand Down
3 changes: 3 additions & 0 deletions Source/WebCore/rendering/RenderLayerBacking.cpp
Expand Up @@ -2900,6 +2900,9 @@ bool RenderLayerBacking::isUnscaledBitmapOnly() const
if (m_owningLayer.hasVisibleBoxDecorationsOrBackground())
return false;

if (pageScaleFactor() < 1.0f)
return false;

auto contents = contentsBox();
if (contents.location() != LayoutPoint(0, 0))
return false;
Expand Down

0 comments on commit fe12c1c

Please sign in to comment.