https://bugs.webkit.org/show_bug.cgi?id=197105
Source/WebCore:
rdar://problem/
50068230
Reviewed by Zalan Bujtas.
Make sure we trigger a geometry update when style properties change that
result in a StyleDifference::RecompositeLayer, and which are updated on layers
via RenderLayerBacking::updateGeometry().
Tests: compositing/style-change/backface-visibility-change.html
compositing/style-change/perspective-change.html
compositing/style-change/perspective-origin-change.html
compositing/style-change/transform-origin-change.html
compositing/style-change/transform-style-change.html
* rendering/RenderLayerCompositor.cpp:
(WebCore::recompositeChangeRequiresGeometryUpdate):
(WebCore::RenderLayerCompositor::layerStyleChanged):
LayoutTests:
Reviewed by Zalan Bujtas.
* compositing/style-change/backface-visibility-change-expected.html: Added.
* compositing/style-change/backface-visibility-change.html: Added.
* compositing/style-change/perspective-change-expected.html: Added.
* compositing/style-change/perspective-change.html: Added.
* compositing/style-change/perspective-origin-change-expected.html: Added.
* compositing/style-change/perspective-origin-change.html: Added.
* compositing/style-change/transform-origin-change-expected.html: Added.
* compositing/style-change/transform-origin-change.html: Added.
* compositing/style-change/transform-style-change-expected.html: Added.
* compositing/style-change/transform-style-change.html: Added.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244612
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
2019-04-24 Simon Fraser <simon.fraser@apple.com>
+ REGRESSION (iOS 12.2): CSS perspective property value can only be set correctly once
+ https://bugs.webkit.org/show_bug.cgi?id=197105
+
+ Reviewed by Zalan Bujtas.
+
+ * compositing/style-change/backface-visibility-change-expected.html: Added.
+ * compositing/style-change/backface-visibility-change.html: Added.
+ * compositing/style-change/perspective-change-expected.html: Added.
+ * compositing/style-change/perspective-change.html: Added.
+ * compositing/style-change/perspective-origin-change-expected.html: Added.
+ * compositing/style-change/perspective-origin-change.html: Added.
+ * compositing/style-change/transform-origin-change-expected.html: Added.
+ * compositing/style-change/transform-origin-change.html: Added.
+ * compositing/style-change/transform-style-change-expected.html: Added.
+ * compositing/style-change/transform-style-change.html: Added.
+
+2019-04-24 Simon Fraser <simon.fraser@apple.com>
+
Make it possible to control the renderTreeAsText output by setting options on testRunner
https://bugs.webkit.org/show_bug.cgi?id=197133
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .container {
+ margin: 50px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ perspective: 500px;
+ }
+
+ .transformed {
+ width: 100%;
+ height: 100%;
+ background-color: blue;
+ transform: rotateY(145deg);
+ -webkit-backface-visibility: visible;
+ }
+ </style>
+</head>
+<body>
+ <div class="container">
+ <div class="transformed"></div>
+ </div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .container {
+ margin: 50px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ perspective: 500px;
+ }
+
+ .transformed {
+ width: 100%;
+ height: 100%;
+ background-color: blue;
+ transform: rotateY(145deg);
+ -webkit-backface-visibility: hidden;
+ }
+
+ .transformed.changed {
+ -webkit-backface-visibility: visible;
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ window.addEventListener('load', () => {
+ setTimeout(() => {
+ document.querySelector('.transformed').classList.add('changed');
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }, 1000);
+
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="container">
+ <div class="transformed"></div>
+ </div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .container {
+ margin: 50px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ perspective: 1500px;
+ }
+
+ .transformed {
+ width: 100%;
+ height: 100%;
+ transform: rotateY(45deg);
+ background-color: blue;
+ }
+ </style>
+</head>
+<body>
+ <div class="container">
+ <div class="transformed"></div>
+ </div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .container {
+ margin: 50px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ perspective: 500px;
+ }
+
+ .container.changed {
+ perspective: 1500px;
+ }
+
+ .transformed {
+ width: 100%;
+ height: 100%;
+ transform: rotateY(45deg);
+ background-color: blue;
+ }
+
+ .transformed:hover {
+ transform-origin: top left;
+ background-color: orange;
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ window.addEventListener('load', () => {
+ setTimeout(() => {
+ document.querySelector('.container').classList.add('changed');
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }, 0);
+
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="container">
+ <div class="transformed"></div>
+ </div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .container {
+ margin: 50px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ perspective: 500px;
+ perspective-origin: top left;
+ }
+
+ .transformed {
+ width: 100%;
+ height: 100%;
+ transform: rotateY(45deg);
+ background-color: blue;
+ }
+ </style>
+</head>
+<body>
+ <div class="container">
+ <div class="transformed"></div>
+ </div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .container {
+ margin: 50px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ perspective: 500px;
+ }
+
+ .container.changed {
+ perspective-origin: top left;
+ }
+
+ .transformed {
+ width: 100%;
+ height: 100%;
+ transform: rotateY(45deg);
+ background-color: blue;
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ window.addEventListener('load', () => {
+ setTimeout(() => {
+ document.querySelector('.container').classList.add('changed');
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }, 0);
+
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="container">
+ <div class="transformed"></div>
+ </div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .container {
+ margin: 50px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ }
+
+ .transformed {
+ width: 100%;
+ height: 100%;
+ background-color: blue;
+ transform: rotateY(45deg);
+ transform-origin: top left;
+ }
+ </style>
+</head>
+<body>
+ <div class="container">
+ <div class="transformed"></div>
+ </div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .container {
+ margin: 50px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ }
+
+ .transformed {
+ width: 100%;
+ height: 100%;
+ background-color: blue;
+ transform: rotateY(45deg);
+ }
+
+ .transformed.changed {
+ transform-origin: top left;
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ window.addEventListener('load', () => {
+ setTimeout(() => {
+ document.querySelector('.transformed').classList.add('changed');
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }, 0);
+
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="container">
+ <div class="transformed"></div>
+ </div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .container {
+ margin: 50px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ perspective: 500px;
+ }
+
+ .intermediate {
+ width: 100%;
+ height: 100%;
+ transform: translateX(0);
+ transform-style: preserve-3d;
+ }
+
+ .transformed {
+ width: 100%;
+ height: 100%;
+ background-color: blue;
+ transform: rotateY(45deg);
+ }
+ </style>
+</head>
+<body>
+ <div class="container">
+ <div class="intermediate">
+ <div class="transformed"></div>
+ </div>
+ </div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .container {
+ margin: 50px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ perspective: 500px;
+ }
+
+ .intermediate {
+ width: 100%;
+ height: 100%;
+ transform: translateX(0);
+ transform-style: flat;
+ }
+
+ .intermediate.changed {
+ transform-style: preserve-3d;
+ }
+
+ .transformed {
+ width: 100%;
+ height: 100%;
+ background-color: blue;
+ transform: rotateY(45deg);
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ window.addEventListener('load', () => {
+ setTimeout(() => {
+ document.querySelector('.intermediate').classList.add('changed');
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }, 0);
+
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="container">
+ <div class="intermediate">
+ <div class="transformed"></div>
+ </div>
+ </div>
+</body>
+</html>
2019-04-24 Simon Fraser <simon.fraser@apple.com>
+ REGRESSION (iOS 12.2): CSS perspective property value can only be set correctly once
+ https://bugs.webkit.org/show_bug.cgi?id=197105
+ rdar://problem/50068230
+
+ Reviewed by Zalan Bujtas.
+
+ Make sure we trigger a geometry update when style properties change that
+ result in a StyleDifference::RecompositeLayer, and which are updated on layers
+ via RenderLayerBacking::updateGeometry().
+
+ Tests: compositing/style-change/backface-visibility-change.html
+ compositing/style-change/perspective-change.html
+ compositing/style-change/perspective-origin-change.html
+ compositing/style-change/transform-origin-change.html
+ compositing/style-change/transform-style-change.html
+
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::recompositeChangeRequiresGeometryUpdate):
+ (WebCore::RenderLayerCompositor::layerStyleChanged):
+
+2019-04-24 Simon Fraser <simon.fraser@apple.com>
+
Make it possible to control the renderTreeAsText output by setting options on testRunner
https://bugs.webkit.org/show_bug.cgi?id=197133
return style.hasClip() || style.clipPath() || style.hasBorderRadius();
}
+static bool recompositeChangeRequiresGeometryUpdate(const RenderStyle& oldStyle, const RenderStyle& newStyle)
+{
+ return oldStyle.transform() != newStyle.transform()
+ || oldStyle.transformOriginX() != newStyle.transformOriginX()
+ || oldStyle.transformOriginY() != newStyle.transformOriginY()
+ || oldStyle.transformOriginZ() != newStyle.transformOriginZ()
+ || oldStyle.transformStyle3D() != newStyle.transformStyle3D()
+ || oldStyle.perspective() != newStyle.perspective()
+ || oldStyle.perspectiveOriginX() != newStyle.perspectiveOriginX()
+ || oldStyle.perspectiveOriginY() != newStyle.perspectiveOriginY()
+ || oldStyle.backfaceVisibility() != newStyle.backfaceVisibility();
+}
+
void RenderLayerCompositor::layerStyleChanged(StyleDifference diff, RenderLayer& layer, const RenderStyle* oldStyle)
{
if (diff == StyleDifference::Equal)
if (diff == StyleDifference::RecompositeLayer && layer.isComposited() && is<RenderWidget>(layer.renderer()))
layer.setNeedsCompositingConfigurationUpdate();
- if (diff >= StyleDifference::RecompositeLayer && oldStyle) {
- if (oldStyle->transform() != newStyle.transform()) {
- // FIXME: transform changes really need to trigger layout. See RenderElement::adjustStyleDifference().
- layer.setNeedsPostLayoutCompositingUpdate();
- layer.setNeedsCompositingGeometryUpdate();
- }
+ if (diff >= StyleDifference::RecompositeLayer && oldStyle && recompositeChangeRequiresGeometryUpdate(*oldStyle, newStyle)) {
+ // FIXME: transform changes really need to trigger layout. See RenderElement::adjustStyleDifference().
+ layer.setNeedsPostLayoutCompositingUpdate();
+ layer.setNeedsCompositingGeometryUpdate();
}
if (diff >= StyleDifference::Layout) {