- Revision
- 234343
- Author
- [email protected]
- Date
- 2018-07-27 22:22:05 -0700 (Fri, 27 Jul 2018)
Log Message
Animation stops with object-fit:contain on an animated 2d canvas
https://bugs.webkit.org/show_bug.cgi?id=187840
Reviewed by Zalan Bujtas.
Source/WebCore:
If a canvas has object-fit: cover or contain, repaints need to mapped through
the rect that is used to position the canvas in the element bounds, which is replacedContentRect().
Add a version of replacedContentRect() that doesn't require passing the intrinsicSize() since
all but RenderVideo just pass the RenderReplaced's intrinsicSize.
Test: fast/repaint/canvas-object-fit.html
* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::didDraw):
* rendering/RenderHTMLCanvas.cpp:
(WebCore::RenderHTMLCanvas::paintReplaced):
* rendering/RenderImage.cpp:
(WebCore::RenderImage::updateInnerContentRect):
(WebCore::RenderImage::paintReplaced):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::contentsBox const):
* rendering/RenderReplaced.h:
(WebCore::RenderReplaced::replacedContentRect const):
* rendering/shapes/ShapeOutsideInfo.cpp:
(WebCore::ShapeOutsideInfo::createShapeForImage const):
LayoutTests:
* fast/repaint/canvas-object-fit-expected.txt: Added.
* fast/repaint/canvas-object-fit.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (234342 => 234343)
--- trunk/LayoutTests/ChangeLog 2018-07-28 02:23:30 UTC (rev 234342)
+++ trunk/LayoutTests/ChangeLog 2018-07-28 05:22:05 UTC (rev 234343)
@@ -1,3 +1,13 @@
+2018-07-24 Simon Fraser <[email protected]>
+
+ Animation stops with object-fit:contain on an animated 2d canvas
+ https://bugs.webkit.org/show_bug.cgi?id=187840
+
+ Reviewed by Zalan Bujtas.
+
+ * fast/repaint/canvas-object-fit-expected.txt: Added.
+ * fast/repaint/canvas-object-fit.html: Added.
+
2018-07-27 Basuke Suzuki <[email protected]>
[Curl] Test gardening
Added: trunk/LayoutTests/fast/repaint/canvas-object-fit-expected.txt (0 => 234343)
--- trunk/LayoutTests/fast/repaint/canvas-object-fit-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/repaint/canvas-object-fit-expected.txt 2018-07-28 05:22:05 UTC (rev 234343)
@@ -0,0 +1,21 @@
+ (GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (contentsOpaque 1)
+ (children 1
+ (GraphicsLayer
+ (position 8.00 8.00)
+ (bounds 202.00 102.00)
+ (drawsContent 1)
+ (repaint rects
+ (rect 70.00 20.00 7.00 7.00)
+ )
+ )
+ )
+ )
+ )
+)
+
Added: trunk/LayoutTests/fast/repaint/canvas-object-fit.html (0 => 234343)
--- trunk/LayoutTests/fast/repaint/canvas-object-fit.html (rev 0)
+++ trunk/LayoutTests/fast/repaint/canvas-object-fit.html 2018-07-28 05:22:05 UTC (rev 234343)
@@ -0,0 +1,49 @@
+<head>
+ <style>
+ canvas {
+ object-fit: contain;
+ border: 1px solid black;
+ width: 200px;
+ height: 100px;
+ }
+ </style>
+</head>
+<body>
+ <canvas id="canvas" width="200" height="200"></canvas>
+<pre id="layers"></pre>
+ <script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = "rgb(0, 128, 0)";
+ ctx.fillRect(0, 0, 200, 200);
+
+ function repaintTest()
+ {
+ if (window.testRunner)
+ testRunner.displayAndTrackRepaints();
+
+ ctx.fillStyle = "rgb(0, 0, 128)";
+ ctx.fillRect(40, 40, 10, 10);
+
+ if (window.internals)
+ document.getElementById('layers').textContent = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_REPAINT_RECTS);
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }
+
+ function startTest()
+ {
+ setTimeout(function() {
+ repaintTest();
+ }, 0)
+ }
+ window.addEventListener('load', startTest, false);
+ </script>
+</body>
Modified: trunk/Source/WebCore/ChangeLog (234342 => 234343)
--- trunk/Source/WebCore/ChangeLog 2018-07-28 02:23:30 UTC (rev 234342)
+++ trunk/Source/WebCore/ChangeLog 2018-07-28 05:22:05 UTC (rev 234343)
@@ -1,3 +1,32 @@
+2018-07-24 Simon Fraser <[email protected]>
+
+ Animation stops with object-fit:contain on an animated 2d canvas
+ https://bugs.webkit.org/show_bug.cgi?id=187840
+
+ Reviewed by Zalan Bujtas.
+
+ If a canvas has object-fit: cover or contain, repaints need to mapped through
+ the rect that is used to position the canvas in the element bounds, which is replacedContentRect().
+
+ Add a version of replacedContentRect() that doesn't require passing the intrinsicSize() since
+ all but RenderVideo just pass the RenderReplaced's intrinsicSize.
+
+ Test: fast/repaint/canvas-object-fit.html
+
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::didDraw):
+ * rendering/RenderHTMLCanvas.cpp:
+ (WebCore::RenderHTMLCanvas::paintReplaced):
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::updateInnerContentRect):
+ (WebCore::RenderImage::paintReplaced):
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::contentsBox const):
+ * rendering/RenderReplaced.h:
+ (WebCore::RenderReplaced::replacedContentRect const):
+ * rendering/shapes/ShapeOutsideInfo.cpp:
+ (WebCore::ShapeOutsideInfo::createShapeForImage const):
+
2018-07-27 Simon Fraser <[email protected]>
Adjust the color matrix for the inverse apple-invert-lightness() transformation
Modified: trunk/Source/WebCore/html/HTMLCanvasElement.cpp (234342 => 234343)
--- trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2018-07-28 02:23:30 UTC (rev 234342)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2018-07-28 05:22:05 UTC (rev 234343)
@@ -508,16 +508,23 @@
clearCopiedImage();
FloatRect dirtyRect = rect;
- if (RenderBox* ro = renderBox()) {
- FloatRect destRect = ro->contentBoxRect();
+ if (auto* renderer = renderBox()) {
+ FloatRect destRect;
+ if (is<RenderReplaced>(renderer))
+ destRect = downcast<RenderReplaced>(renderer)->replacedContentRect();
+ else
+ destRect = renderer->contentBoxRect();
+
// Inflate dirty rect to cover antialiasing on image buffers.
if (drawingContext() && drawingContext()->shouldAntialias())
dirtyRect.inflate(1);
+
FloatRect r = mapRect(dirtyRect, FloatRect(0, 0, size().width(), size().height()), destRect);
r.intersect(destRect);
+
if (!r.isEmpty() && !m_dirtyRect.contains(r)) {
m_dirtyRect.unite(r);
- ro->repaintRectangle(enclosingIntRect(m_dirtyRect));
+ renderer->repaintRectangle(enclosingIntRect(m_dirtyRect));
}
}
notifyObserversCanvasChanged(dirtyRect);
Modified: trunk/Source/WebCore/rendering/RenderHTMLCanvas.cpp (234342 => 234343)
--- trunk/Source/WebCore/rendering/RenderHTMLCanvas.cpp 2018-07-28 02:23:30 UTC (rev 234342)
+++ trunk/Source/WebCore/rendering/RenderHTMLCanvas.cpp 2018-07-28 05:22:05 UTC (rev 234343)
@@ -74,7 +74,7 @@
LayoutRect contentBoxRect = this->contentBoxRect();
contentBoxRect.moveBy(paintOffset);
- LayoutRect replacedContentRect = this->replacedContentRect(intrinsicSize());
+ LayoutRect replacedContentRect = this->replacedContentRect();
replacedContentRect.moveBy(paintOffset);
// Not allowed to overflow the content box.
Modified: trunk/Source/WebCore/rendering/RenderImage.cpp (234342 => 234343)
--- trunk/Source/WebCore/rendering/RenderImage.cpp 2018-07-28 02:23:30 UTC (rev 234342)
+++ trunk/Source/WebCore/rendering/RenderImage.cpp 2018-07-28 05:22:05 UTC (rev 234343)
@@ -285,7 +285,7 @@
void RenderImage::updateInnerContentRect()
{
// Propagate container size to image resource.
- IntSize containerSize(replacedContentRect(intrinsicSize()).size());
+ IntSize containerSize(replacedContentRect().size());
if (!containerSize.isEmpty()) {
URL imageSourceURL;
if (HTMLImageElement* imageElement = is<HTMLImageElement>(element()) ? downcast<HTMLImageElement>(element()) : nullptr)
@@ -497,7 +497,7 @@
LayoutRect contentBoxRect = this->contentBoxRect();
contentBoxRect.moveBy(paintOffset);
- LayoutRect replacedContentRect = this->replacedContentRect(intrinsicSize());
+ LayoutRect replacedContentRect = this->replacedContentRect();
replacedContentRect.moveBy(paintOffset);
bool clip = !contentBoxRect.contains(replacedContentRect);
GraphicsContextStateSaver stateSaver(context, clip);
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (234342 => 234343)
--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2018-07-28 02:23:30 UTC (rev 234342)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2018-07-28 05:22:05 UTC (rev 234343)
@@ -2342,7 +2342,7 @@
#endif
if (is<RenderReplaced>(renderBox)) {
RenderReplaced& renderReplaced = downcast<RenderReplaced>(renderBox);
- contentsRect = renderReplaced.replacedContentRect(renderBox.intrinsicSize());
+ contentsRect = renderReplaced.replacedContentRect();
} else
contentsRect = renderBox.contentBoxRect();
Modified: trunk/Source/WebCore/rendering/RenderReplaced.h (234342 => 234343)
--- trunk/Source/WebCore/rendering/RenderReplaced.h 2018-07-28 02:23:30 UTC (rev 234342)
+++ trunk/Source/WebCore/rendering/RenderReplaced.h 2018-07-28 05:22:05 UTC (rev 234343)
@@ -34,6 +34,7 @@
LayoutUnit computeReplacedLogicalHeight(std::optional<LayoutUnit> estimatedUsedWidth = std::nullopt) const override;
LayoutRect replacedContentRect(const LayoutSize& intrinsicSize) const;
+ LayoutRect replacedContentRect() const { return replacedContentRect(intrinsicSize()); }
bool hasReplacedLogicalWidth() const;
bool hasReplacedLogicalHeight() const;
Modified: trunk/Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp (234342 => 234343)
--- trunk/Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp 2018-07-28 02:23:30 UTC (rev 234342)
+++ trunk/Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp 2018-07-28 05:22:05 UTC (rev 234343)
@@ -151,7 +151,7 @@
const LayoutRect& marginRect = getShapeImageMarginRect(m_renderer, m_referenceBoxLogicalSize);
const LayoutRect& imageRect = is<RenderImage>(m_renderer)
- ? downcast<RenderImage>(m_renderer).replacedContentRect(m_renderer.intrinsicSize())
+ ? downcast<RenderImage>(m_renderer).replacedContentRect()
: LayoutRect(LayoutPoint(), imageSize);
ASSERT(!styleImage->isPending());