REGRESSION(SUBPIXEL_LAYOUT) Composited layers can cause one pixel shifts

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

Reviewed by David Hyatt.

Source/WebCore:

Accelerated layers can cause blocks at subpixel offsets to shift because
accumulated subpixel offsets are lost between each layers.

To solve this layer bounds are now calculated in LayoutUnits, and their
subpixel offset saved so it can be used to ensure correct pixel-snapping
during painting.

Test: fast/sub-pixel/sub-pixel-composited-layers.html

* WebCore.exp.in:
* inspector/InspectorLayerTreeAgent.cpp:
(WebCore::InspectorLayerTreeAgent::buildObjectForLayer):
* platform/graphics/LayoutPoint.h:
(WebCore::LayoutPoint::fraction):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::setupClipPath):
(WebCore::RenderLayer::setupFilters):
(WebCore::RenderLayer::paintLayerContents):
(WebCore::RenderLayer::calculateLayerBounds):
* rendering/RenderLayer.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateCompositedBounds):
(WebCore::RenderLayerBacking::updateAfterWidgetResize):
(WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
(WebCore::RenderLayerBacking::resetContentsRect):
(WebCore::RenderLayerBacking::contentOffsetInCompostingLayer):
(WebCore::RenderLayerBacking::contentsBox):
(WebCore::RenderLayerBacking::backgroundBox):
(WebCore::RenderLayerBacking::paintIntoLayer):
(WebCore::RenderLayerBacking::paintContents):
(WebCore::RenderLayerBacking::compositedBounds):
(WebCore::RenderLayerBacking::setCompositedBounds):
* rendering/RenderLayerBacking.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::logLayerInfo):
(WebCore::RenderLayerCompositor::calculateCompositedBounds):
* rendering/RenderLayerCompositor.h:
* rendering/RenderTreeAsText.cpp:
(WebCore::operator<<):
* rendering/RenderTreeAsText.h:

LayoutTests:

* fast/sub-pixel/sub-pixel-composited-layers-expected.html: Added.
* fast/sub-pixel/sub-pixel-composited-layers.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154009 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent f18ab334
2013-08-13 Allan Sandfeld Jensen <allan.jensen@digia.com>
REGRESSION(SUBPIXEL_LAYOUT) Composited layers can cause one pixel shifts
https://bugs.webkit.org/show_bug.cgi?id=115304
Reviewed by David Hyatt.
* fast/sub-pixel/sub-pixel-composited-layers-expected.html: Added.
* fast/sub-pixel/sub-pixel-composited-layers.html: Added.
2013-08-13 Christophe Dumez <ch.dumez@sisa.samsung.com>
HTMLSelectElement.item() does not behave according to specification
<html>
<head>
<style>
#test {
margin: 5px;
}
.container {
position: absolute;
opacity: 0.95;
}
.shifter {
position: absolute;
background-color: black;
width: 12.5px;
height: 12.5px;
}
.shifter8x8 {
position: absolute;
background-color: black;
width: 16.5px;
height: 16.5px;
}
</style>
</head>
<body>
<div id=test>
</div>
<script>
function setupGrid10x10(leftOffset, topOffset, leftFraction, topFraction)
{
var test = document.getElementById('test');
for (var i = 0; i < 10; i++) {
if (i == 5)
topOffset += 5;
var leftOffsetj = leftOffset;
for (var j = 0; j < 10; j++) {
if (j == 5)
leftOffsetj += 5;
var container = document.createElement("div");
var shifter = document.createElement("div");
container.setAttribute('class', 'container');
shifter.setAttribute('class', 'shifter');
container.style.left = (leftOffsetj + j * 16 + i * leftFraction) + "px"
container.style.top = (topOffset + i * 16 + i * topFraction) + "px"
shifter.style.left = (5 + j * leftFraction) + "px"
shifter.style.top = (5 + j * topFraction) + "px"
container.appendChild(shifter);
test.appendChild(container);
}
}
}
function setupGrid8x8(leftOffset, topOffset, leftFraction, topFraction)
{
var test = document.getElementById('test');
for (var i = 0; i < 8; i++) {
if (i == 4)
topOffset += 5;
var leftOffsetj = leftOffset;
for (var j = 0; j < 8; j++) {
if (j == 4)
leftOffsetj += 5;
var container = document.createElement("div");
var shifter = document.createElement("div");
container.setAttribute('class', 'container');
shifter.setAttribute('class', 'shifter8x8');
container.style.left = (leftOffsetj + j * 20 + i * leftFraction) + "px"
container.style.top = (topOffset + i * 20 + i * topFraction) + "px"
shifter.style.left = (5 + j * leftFraction) + "px"
shifter.style.top = (5 + j * topFraction) + "px"
container.appendChild(shifter);
test.appendChild(container);
}
}
}
function setupTest()
{
// Vertical shifts:
setupGrid10x10(10, 10, 0, 0.1)
// Horizontal shifts:
setupGrid10x10(200, 10, 0.1, 0);
// And in 8x8 (where exactly 0.5 is more common)
setupGrid8x8(10, 200, 0, 0.125);
setupGrid8x8(200, 200, 0.125, 0);
}
setupTest();
</script>
</body>
</html>
\ No newline at end of file
<html>
<head>
<style>
#test {
margin: 5px;
}
#test.composite > .container {
-webkit-transform: translateZ(0);
opacity: 0.95;
}
.container {
position: absolute;
}
.shifter {
position: absolute;
background-color: black;
width: 12.5px;
height: 12.5px;
}
.shifter8x8 {
position: absolute;
background-color: black;
width: 16.5px;
height: 16.5px;
}
</style>
</head>
<body>
<div id=test class=composite>
</div>
<script>
function setupGrid10x10(leftOffset, topOffset, leftFraction, topFraction)
{
var test = document.getElementById('test');
for (var i = 0; i < 10; i++) {
if (i == 5)
topOffset += 5;
var leftOffsetj = leftOffset;
for (var j = 0; j < 10; j++) {
if (j == 5)
leftOffsetj += 5;
var container = document.createElement("div");
var shifter = document.createElement("div");
container.setAttribute('class', 'container');
shifter.setAttribute('class', 'shifter');
container.style.left = (leftOffsetj + j * 16 + i * leftFraction) + "px"
container.style.top = (topOffset + i * 16 + i * topFraction) + "px"
shifter.style.left = (5 + j * leftFraction) + "px"
shifter.style.top = (5 + j * topFraction) + "px"
container.appendChild(shifter);
test.appendChild(container);
}
}
}
function setupGrid8x8(leftOffset, topOffset, leftFraction, topFraction)
{
var test = document.getElementById('test');
for (var i = 0; i < 8; i++) {
if (i == 4)
topOffset += 5;
var leftOffsetj = leftOffset;
for (var j = 0; j < 8; j++) {
if (j == 4)
leftOffsetj += 5;
var container = document.createElement("div");
var shifter = document.createElement("div");
container.setAttribute('class', 'container');
shifter.setAttribute('class', 'shifter8x8');
container.style.left = (leftOffsetj + j * 20 + i * leftFraction) + "px"
container.style.top = (topOffset + i * 20 + i * topFraction) + "px"
shifter.style.left = (5 + j * leftFraction) + "px"
shifter.style.top = (5 + j * topFraction) + "px"
container.appendChild(shifter);
test.appendChild(container);
}
}
}
function setupTest()
{
// Vertical shifts:
setupGrid10x10(10, 10, 0, 0.1)
// Horizontal shifts:
setupGrid10x10(200, 10, 0.1, 0);
// And in 8x8 (where exactly 0.5 is more common)
setupGrid8x8(10, 200, 0, 0.125);
setupGrid8x8(200, 200, 0.125, 0);
}
setupTest();
</script>
</body>
</html>
\ No newline at end of file
2013-08-13 Allan Sandfeld Jensen <allan.jensen@digia.com>
REGRESSION(SUBPIXEL_LAYOUT) Composited layers can cause one pixel shifts
https://bugs.webkit.org/show_bug.cgi?id=115304
Reviewed by David Hyatt.
Accelerated layers can cause blocks at subpixel offsets to shift because
accumulated subpixel offsets are lost between each layers.
To solve this layer bounds are now calculated in LayoutUnits, and their
subpixel offset saved so it can be used to ensure correct pixel-snapping
during painting.
Test: fast/sub-pixel/sub-pixel-composited-layers.html
* WebCore.exp.in:
* inspector/InspectorLayerTreeAgent.cpp:
(WebCore::InspectorLayerTreeAgent::buildObjectForLayer):
* platform/graphics/LayoutPoint.h:
(WebCore::LayoutPoint::fraction):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::setupClipPath):
(WebCore::RenderLayer::setupFilters):
(WebCore::RenderLayer::paintLayerContents):
(WebCore::RenderLayer::calculateLayerBounds):
* rendering/RenderLayer.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateCompositedBounds):
(WebCore::RenderLayerBacking::updateAfterWidgetResize):
(WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
(WebCore::RenderLayerBacking::resetContentsRect):
(WebCore::RenderLayerBacking::contentOffsetInCompostingLayer):
(WebCore::RenderLayerBacking::contentsBox):
(WebCore::RenderLayerBacking::backgroundBox):
(WebCore::RenderLayerBacking::paintIntoLayer):
(WebCore::RenderLayerBacking::paintContents):
(WebCore::RenderLayerBacking::compositedBounds):
(WebCore::RenderLayerBacking::setCompositedBounds):
* rendering/RenderLayerBacking.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::logLayerInfo):
(WebCore::RenderLayerCompositor::calculateCompositedBounds):
* rendering/RenderLayerCompositor.h:
* rendering/RenderTreeAsText.cpp:
(WebCore::operator<<):
* rendering/RenderTreeAsText.h:
2013-08-13 peavo@outlook.com <peavo@outlook.com>
[Curl] Possible infinite loop while downloading.
......@@ -1136,6 +1136,7 @@ __ZN7WebCore8toUInt64EPN3JSC9ExecStateENS0_7JSValueENS_30IntegerConversionConfig
__ZN7WebCore9DOMWindow30dispatchAllPendingUnloadEventsEv
__ZN7WebCore9DOMWindow36dispatchAllPendingBeforeUnloadEventsEv
__ZN7WebCore9FloatRectC1ERK6CGRect
__ZN7WebCore9FloatRectC1ERKNS_10LayoutRectE
__ZN7WebCore9FloatRectC1ERKNS_7IntRectE
__ZN7WebCore9FloatSizeC1ERK6CGSize
__ZN7WebCore9FloatSizeC1ERKNS_7IntSizeE
......
......@@ -180,7 +180,7 @@ PassRefPtr<TypeBuilder::LayerTree::Layer> InspectorLayerTreeAgent::buildObjectFo
.setNodeId(idForNode(errorString, node))
.setBounds(buildObjectForIntRect(renderer->absoluteBoundingBoxRect()))
.setMemory(backing->backingStoreMemoryEstimate())
.setCompositedBounds(buildObjectForIntRect(backing->compositedBounds()))
.setCompositedBounds(buildObjectForIntRect(enclosingIntRect(backing->compositedBounds())))
.setPaintCount(backing->graphicsLayer()->repaintCount());
if (node && node->shadowHost())
......
......@@ -81,7 +81,12 @@ public:
{
return LayoutPoint(m_y, m_x);
}
LayoutPoint fraction() const
{
return LayoutPoint(m_x.fraction(), m_y.fraction());
}
operator FloatPoint() const { return FloatPoint(m_x, m_y); }
private:
......
......@@ -3730,7 +3730,7 @@ bool RenderLayer::setupFontSubpixelQuantization(GraphicsContext* context, bool&
return false;
}
bool RenderLayer::setupClipPath(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, const LayoutPoint& offsetFromRoot, IntRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)
bool RenderLayer::setupClipPath(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, const LayoutPoint& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)
{
if (!renderer()->hasClipPath() || context->paintingDisabled())
return false;
......@@ -3773,7 +3773,7 @@ bool RenderLayer::setupClipPath(GraphicsContext* context, const LayerPaintingInf
}
#if ENABLE(CSS_FILTERS)
PassOwnPtr<FilterEffectRendererHelper> RenderLayer::setupFilters(GraphicsContext* context, LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& offsetFromRoot, IntRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)
PassOwnPtr<FilterEffectRendererHelper> RenderLayer::setupFilters(GraphicsContext* context, LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)
{
if (context->paintingDisabled())
return nullptr;
......@@ -3864,7 +3864,7 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
LayoutPoint offsetFromRoot;
convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
IntRect rootRelativeBounds;
LayoutRect rootRelativeBounds;
bool rootRelativeBoundsComputed = false;
// FIXME: We shouldn't have to disable subpixel quantization for overflow clips or subframes once we scroll those
......@@ -5381,14 +5381,14 @@ IntRect RenderLayer::absoluteBoundingBox() const
return pixelSnappedIntRect(boundingBox(root()));
}
IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot, CalculateLayerBoundsFlags flags) const
LayoutRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot, CalculateLayerBoundsFlags flags) const
{
if (!isSelfPaintingLayer())
return IntRect();
return LayoutRect();
// FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580).
if ((flags & ExcludeHiddenDescendants) && this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant())
return IntRect();
return LayoutRect();
RenderLayerModelObject* renderer = this->renderer();
......@@ -5428,7 +5428,7 @@ IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, cons
LayoutPoint ancestorRelOffset;
convertToLayerCoords(ancestorLayer, ancestorRelOffset);
localClipRect.moveBy(ancestorRelOffset);
return pixelSnappedIntRect(localClipRect);
return localClipRect;
}
}
......@@ -5439,7 +5439,7 @@ IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, cons
if (RenderLayer* reflection = reflectionLayer()) {
if (!reflection->isComposited()) {
IntRect childUnionBounds = reflection->calculateLayerBounds(this, 0, descendantFlags);
LayoutRect childUnionBounds = reflection->calculateLayerBounds(this, 0, descendantFlags);
unionBounds.unite(childUnionBounds);
}
}
......@@ -5455,7 +5455,7 @@ IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, cons
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = negZOrderList->at(i);
if (flags & IncludeCompositedDescendants || !curLayer->isComposited()) {
IntRect childUnionBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags);
LayoutRect childUnionBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags);
unionBounds.unite(childUnionBounds);
}
}
......@@ -5466,7 +5466,7 @@ IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, cons
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = posZOrderList->at(i);
if (flags & IncludeCompositedDescendants || !curLayer->isComposited()) {
IntRect childUnionBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags);
LayoutRect childUnionBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags);
unionBounds.unite(childUnionBounds);
}
}
......@@ -5480,7 +5480,7 @@ IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, cons
// so there's no way we could hit a RenderNamedFlowThread here.
ASSERT(!curLayer->isOutOfFlowRenderFlowThread());
if (flags & IncludeCompositedDescendants || !curLayer->isComposited()) {
IntRect curAbsBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags);
LayoutRect curAbsBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags);
unionBounds.unite(curAbsBounds);
}
}
......@@ -5507,7 +5507,7 @@ IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, cons
convertToLayerCoords(ancestorLayer, ancestorRelOffset);
unionBounds.moveBy(ancestorRelOffset);
return pixelSnappedIntRect(unionBounds);
return unionBounds;
}
void RenderLayer::clearClipRectsIncludingDescendants(ClipRectsType typeToClear)
......
......@@ -705,7 +705,7 @@ public:
#endif
// Can pass offsetFromRoot if known.
IntRect calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot = 0, CalculateLayerBoundsFlags = DefaultCalculateLayerBoundsFlags) const;
LayoutRect calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot = 0, CalculateLayerBoundsFlags = DefaultCalculateLayerBoundsFlags) const;
// WARNING: This method returns the offset for the parent as this is what updateLayerPositions expects.
LayoutPoint computeOffsetFromRoot(bool& hasLayerOffset) const;
......@@ -940,9 +940,9 @@ private:
};
bool setupFontSubpixelQuantization(GraphicsContext*, bool& didQuantizeFonts);
bool setupClipPath(GraphicsContext*, const LayerPaintingInfo&, const LayoutPoint& offsetFromRoot, IntRect& rootRelativeBounds, bool& rootRelativeBoundsComputed);
bool setupClipPath(GraphicsContext*, const LayerPaintingInfo&, const LayoutPoint& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed);
#if ENABLE(CSS_FILTERS)
PassOwnPtr<FilterEffectRendererHelper> setupFilters(GraphicsContext*, LayerPaintingInfo&, PaintLayerFlags, const LayoutPoint& offsetFromRoot, IntRect& rootRelativeBounds, bool& rootRelativeBoundsComputed);
PassOwnPtr<FilterEffectRendererHelper> setupFilters(GraphicsContext*, LayerPaintingInfo&, PaintLayerFlags, const LayoutPoint& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed);
GraphicsContext* applyFilters(FilterEffectRendererHelper*, GraphicsContext* originalContext, LayerPaintingInfo&, LayerFragments&);
#endif
......
......@@ -425,7 +425,7 @@ bool RenderLayerBacking::shouldClipCompositedBounds() const
void RenderLayerBacking::updateCompositedBounds()
{
IntRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
LayoutRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
// Clip to the size of the document or enclosing overflow-scroll layer.
// If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
......@@ -447,7 +447,7 @@ void RenderLayerBacking::updateCompositedBounds()
m_owningLayer->convertToLayerCoords(rootLayer, delta);
clippingBounds.move(-delta.x(), -delta.y());
layerBounds.intersect(pixelSnappedIntRect(clippingBounds));
layerBounds.intersect(clippingBounds);
m_boundsConstrainedByClipping = true;
} else
m_boundsConstrainedByClipping = false;
......@@ -470,7 +470,7 @@ void RenderLayerBacking::updateAfterWidgetResize()
if (renderer()->isRenderPart()) {
if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderPart(renderer()))) {
innerCompositor->frameViewDidChangeSize();
innerCompositor->frameViewDidChangeLocation(contentsBox().location());
innerCompositor->frameViewDidChangeLocation(flooredIntPoint(contentsBox().location()));
}
}
}
......@@ -647,11 +647,16 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
ancestorCompositingBounds = pixelSnappedIntRect(compAncestor->backing()->compositedBounds());
}
IntRect localCompositingBounds = pixelSnappedIntRect(compositedBounds());
LayoutRect localRawCompositingBounds = compositedBounds();
LayoutPoint rawDelta;
m_owningLayer->convertToLayerCoords(compAncestor, rawDelta);
IntPoint delta = flooredIntPoint(rawDelta);
m_subpixelAccumulation = toLayoutSize(rawDelta.fraction());
// Move the bounds by the subpixel accumulation so that it pixel-snaps relative to absolute pixels instead of local coordinates.
localRawCompositingBounds.move(m_subpixelAccumulation);
IntRect localCompositingBounds = pixelSnappedIntRect(localRawCompositingBounds);
IntRect relativeCompositingBounds(localCompositingBounds);
IntPoint delta;
m_owningLayer->convertToPixelSnappedLayerCoords(compAncestor, delta);
relativeCompositingBounds.moveBy(delta);
IntPoint graphicsLayerParentLocation;
......@@ -701,7 +706,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
FloatSize oldSize = m_graphicsLayer->size();
if (oldSize != contentsSize) {
m_graphicsLayer->setSize(contentsSize);
......@@ -739,7 +744,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect();
// Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
IntRect layerBounds = IntRect(delta, borderBox.size());
IntRect layerBounds(delta, borderBox.size());
// Update properties that depend on layer dimensions
FloatPoint3D transformOrigin = computeTransformOrigin(borderBox);
......@@ -953,7 +958,7 @@ void RenderLayerBacking::updateInternalHierarchy()
void RenderLayerBacking::resetContentsRect()
{
IntRect rect = contentsBox();
IntRect rect = pixelSnappedIntRect(contentsBox());
m_graphicsLayer->setContentsRect(rect);
m_graphicsLayer->setContentsTileSize(IntSize());
m_graphicsLayer->setContentsTilePhase(IntPoint());
......@@ -1757,7 +1762,7 @@ void RenderLayerBacking::updateImageContents()
return;
// This is a no-op if the layer doesn't have an inner layer for the image.
m_graphicsLayer->setContentsRect(contentsBox());
m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox()));
m_graphicsLayer->setContentsToImage(image);
bool isSimpleContainer = false;
updateDrawsContent(isSimpleContainer);
......@@ -1795,24 +1800,24 @@ FloatPoint RenderLayerBacking::computePerspectiveOrigin(const IntRect& borderBox
}
// Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
IntSize RenderLayerBacking::contentOffsetInCompostingLayer() const
LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const
{
return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y());
return LayoutSize(-m_compositedBounds.x(), -m_compositedBounds.y());
}
IntRect RenderLayerBacking::contentsBox() const
LayoutRect RenderLayerBacking::contentsBox() const
{
if (!renderer()->isBox())
return IntRect();
return LayoutRect();
IntRect contentsRect;
LayoutRect contentsRect;
#if ENABLE(VIDEO)
if (renderer()->isVideo()) {
RenderVideo* videoRenderer = toRenderVideo(renderer());
contentsRect = videoRenderer->videoBox();
} else
#endif
contentsRect = pixelSnappedIntRect(toRenderBox(renderer())->contentBoxRect());
contentsRect = toRenderBox(renderer())->contentBoxRect();
contentsRect.move(contentOffsetInCompostingLayer());
return contentsRect;
......@@ -1840,9 +1845,9 @@ IntRect RenderLayerBacking::backgroundBox() const
if (!renderer()->isBox())
return IntRect();
IntRect pixelSnappedBackgroundBox = pixelSnappedIntRect(backgroundRectForBox(toRenderBox(renderer())));
pixelSnappedBackgroundBox.move(contentOffsetInCompostingLayer());
return pixelSnappedBackgroundBox;
LayoutRect backgroundBox = backgroundRectForBox(toRenderBox(renderer()));
backgroundBox.move(contentOffsetInCompostingLayer());
return pixelSnappedIntRect(backgroundBox);
}
GraphicsLayer* RenderLayerBacking::parentForSublayers() const
......@@ -1988,7 +1993,7 @@ void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, Grap
paintFlags |= RenderLayer::PaintLayerPaintingSkipRootBackground;
// FIXME: GraphicsLayers need a way to split for RenderRegions.
RenderLayer::LayerPaintingInfo paintingInfo(m_owningLayer, paintDirtyRect, paintBehavior, LayoutSize());
RenderLayer::LayerPaintingInfo paintingInfo(m_owningLayer, paintDirtyRect, paintBehavior, m_subpixelAccumulation);
m_owningLayer->paintLayerContents(context, paintingInfo, paintFlags);
if (m_owningLayer->containsDirtyOverlayScrollbars())
......@@ -2031,7 +2036,7 @@ void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, Graph
// The dirtyRect is in the coords of the painting root.
IntRect dirtyRect = clip;
if (!(paintingPhase & GraphicsLayerPaintOverflowContents))
dirtyRect.intersect(compositedBounds());
dirtyRect.intersect(enclosingIntRect(compositedBounds()));
// We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
paintIntoLayer(graphicsLayer, &context, dirtyRect, PaintBehaviorNormal, paintingPhase);
......@@ -2264,12 +2269,12 @@ void RenderLayerBacking::resumeAnimations()
m_graphicsLayer->resumeAnimations();
}
IntRect RenderLayerBacking::compositedBounds() const
LayoutRect RenderLayerBacking::compositedBounds() const
{
return m_compositedBounds;
}
void RenderLayerBacking::setCompositedBounds(const IntRect& bounds)
void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds)
{
m_compositedBounds = bounds;
}
......
......@@ -141,8 +141,8 @@ public:
void suspendAnimations(double time = 0);
void resumeAnimations();
IntRect compositedBounds() const;
void setCompositedBounds(const IntRect&);
LayoutRect compositedBounds() const;
void setCompositedBounds(const LayoutRect&);
void updateCompositedBounds();
void updateAfterWidgetResize();
......@@ -175,7 +175,7 @@ public:
virtual void verifyNotPainting();
#endif
IntRect contentsBox() const;
LayoutRect contentsBox() const;
IntRect backgroundBox() const;
// For informative purposes only.
......@@ -229,7 +229,7 @@ private:
GraphicsLayerPaintingPhase paintingPhaseForPrimaryLayer() const;
IntSize contentOffsetInCompostingLayer() const;
LayoutSize contentOffsetInCompostingLayer() const;
// Result is transform origin in pixels.
FloatPoint3D computeTransformOrigin(const IntRect& borderBox) const;
// Result is perspective origin in pixels.
......@@ -297,7 +297,8 @@ private:
uint64_t m_scrollLayerID;
IntRect m_compositedBounds;
LayoutRect m_compositedBounds;
LayoutSize m_subpixelAccumulation; // The accumulated subpixel offset of the compositedBounds compared to absolute coordinates.
bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work
bool m_boundsConstrainedByClipping;
......
......@@ -654,7 +654,7 @@ void RenderLayerCompositor::logLayerInfo(const RenderLayer* layer, int depth)
StringBuilder logString;
logString.append(String::format("%*p %dx%d %.2fKB", 12 + depth * 2, layer,
backing->compositedBounds().width(), backing->compositedBounds().height(),
backing->compositedBounds().width().round(), backing->compositedBounds().height().round(),
backing->backingStoreMemoryEstimate() / 1024));
logString.append(" (");
......@@ -830,10 +830,10 @@ void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer* layer, cons
// The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
// RenderLayers that are rendered by the composited RenderLayer.
IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) const
LayoutRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) const
{