Bug 1420648 - Ensure WebRender computes the snapped image decode size the same as the fallback path. r=tnikkel

This commit is contained in:
Andrew Osmond 2017-12-01 07:18:53 -05:00
Родитель 7b8023dcab
Коммит cc5c98e1d3
3 изменённых файлов: 52 добавлений и 9 удалений

Просмотреть файл

@ -40,7 +40,8 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen
// Compute scale for fallback rendering. // Compute scale for fallback rendering.
gfx::Matrix transform2d; gfx::Matrix transform2d;
if (aBoundTransform && aBoundTransform->CanDraw2D(&transform2d)) { if (aBoundTransform && aBoundTransform->CanDraw2D(&transform2d)) {
mScale = transform2d.ScaleFactors(true) * aParentSC.mScale; mInheritedTransform = transform2d * aParentSC.mInheritedTransform;
mScale = mInheritedTransform.ScaleFactors(true);
} }
mBuilder->PushStackingContext(wr::LayoutRect(), mBuilder->PushStackingContext(wr::LayoutRect(),

Просмотреть файл

@ -68,6 +68,11 @@ public:
// Export the inherited scale // Export the inherited scale
gfx::Size GetInheritedScale() const { return mScale; } gfx::Size GetInheritedScale() const { return mScale; }
const gfx::Matrix& GetInheritedTransform() const
{
return mInheritedTransform;
}
bool IsBackfaceVisible() const { return mTransform.IsBackfaceVisible(); } bool IsBackfaceVisible() const { return mTransform.IsBackfaceVisible(); }
private: private:
@ -75,6 +80,7 @@ private:
LayoutDevicePoint mOrigin; LayoutDevicePoint mOrigin;
gfx::Matrix4x4 mTransform; gfx::Matrix4x4 mTransform;
gfx::Size mScale; gfx::Size mScale;
gfx::Matrix mInheritedTransform;
}; };
} // namespace layers } // namespace layers

Просмотреть файл

@ -6766,6 +6766,8 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx,
// Snap even if we have a scale in the context. But don't snap if // Snap even if we have a scale in the context. But don't snap if
// we have something that's not translation+scale, or if the scale flips in // we have something that's not translation+scale, or if the scale flips in
// the X or Y direction, because snapped image drawing can't handle that yet. // the X or Y direction, because snapped image drawing can't handle that yet.
// Any changes to this algorithm will need to be reflected in
// ComputeImageContainerDrawingParameters.
if (!currentMatrix.HasNonAxisAlignedTransform() && if (!currentMatrix.HasNonAxisAlignedTransform() &&
currentMatrix._11 > 0.0 && currentMatrix._22 > 0.0 && currentMatrix._11 > 0.0 && currentMatrix._22 > 0.0 &&
aCtx->UserToDevicePixelSnapped(fill, true) && aCtx->UserToDevicePixelSnapped(fill, true) &&
@ -7191,15 +7193,49 @@ nsLayoutUtils::ComputeImageContainerDrawingParameters(imgIContainer*
viewportSize.height))); viewportSize.height)));
} }
// Compute our size in layer pixels. // Attempt to snap pixels, the same as ComputeSnappedImageDrawingParameters.
const LayerIntSize layerSize = // Any changes to the algorithm here will need to be reflected there.
RoundedToInt(LayerSize(aDestRect.Width() * scaleFactors.width, bool snapped = false;
aDestRect.Height() * scaleFactors.height)); gfxSize gfxLayerSize;
const gfx::Matrix& itm = aSc.GetInheritedTransform();
if (!itm.HasNonAxisAlignedTransform() &&
itm._11 > 0.0 &&
itm._22 > 0.0) {
gfxRect rect(gfxPoint(aDestRect.X(), aDestRect.Y()),
gfxSize(aDestRect.Width(), aDestRect.Height()));
gfxPoint p1 = ThebesPoint(itm.TransformPoint(ToPoint(rect.TopLeft())));
gfxPoint p2 = ThebesPoint(itm.TransformPoint(ToPoint(rect.TopRight())));
gfxPoint p3 = ThebesPoint(itm.TransformPoint(ToPoint(rect.BottomRight())));
if (p2 == gfxPoint(p1.x, p3.y) || p2 == gfxPoint(p3.x, p1.y)) {
p1.Round();
p3.Round();
rect.MoveTo(gfxPoint(std::min(p1.x, p3.x), std::min(p1.y, p3.y)));
rect.SizeTo(gfxSize(std::max(p1.x, p3.x) - rect.X(),
std::max(p1.y, p3.y) - rect.Y()));
// An empty size is unacceptable so we ensure our suggested size is at
// least 1 pixel wide/tall.
gfxLayerSize = gfxSize(std::max(rect.Width(), 1.0),
std::max(rect.Height(), 1.0));
snapped = true;
}
}
if (!snapped) {
// Compute our size in layer pixels.
const LayerIntSize layerSize =
RoundedToInt(LayerSize(aDestRect.Width() * scaleFactors.width,
aDestRect.Height() * scaleFactors.height));
// An empty size is unacceptable so we ensure our suggested size is at least
// 1 pixel wide/tall.
gfxLayerSize = gfxSize(std::max(layerSize.width, 1),
std::max(layerSize.height, 1));
}
// Determine the optimal image size to use. An empty size is unacceptable so
// we ensure our suggested size is at least 1 pixel wide/tall.
gfxSize gfxLayerSize = gfxSize(std::max(layerSize.width, 1),
std::max(layerSize.height, 1));
return aImage->OptimalImageSizeForDest(gfxLayerSize, return aImage->OptimalImageSizeForDest(gfxLayerSize,
imgIContainer::FRAME_CURRENT, imgIContainer::FRAME_CURRENT,
samplingFilter, aFlags); samplingFilter, aFlags);