Skip to content

Commit

Permalink
[TransformInterop] Make blocks whose DOM parent is an inline follow D…
Browse files Browse the repository at this point in the history
…OM tree.

When the TransformInterop feature is enabled, 3D scene extension
(transform-style: preserve-3d) and the perspective property should
follow the DOM tree.  This makes that happen for blocks (or, really, any
non-inlines) whose DOM parent is an inline.

Bug: 1008483
Change-Id: I5bcd6d7087c28639a053b686f90880d94f4c6986
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2956891
Reviewed-by: Koji Ishii <kojii@chromium.org>
Reviewed-by: Chris Harrelson <chrishtr@chromium.org>
Commit-Queue: David Baron <dbaron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#892164}
  • Loading branch information
dbaron authored and Chromium LUCI CQ committed Jun 14, 2021
1 parent 2c854cd commit 14e7fed
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 6 deletions.
2 changes: 1 addition & 1 deletion third_party/blink/renderer/core/layout/layout_box.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1986,7 +1986,7 @@ bool LayoutBox::MapVisualRectToContainer(
bool has_perspective = container_object && container_object->HasLayer() &&
container_object->StyleRef().HasPerspective();
if (has_perspective && RuntimeEnabledFeatures::TransformInteropEnabled() &&
container_object != NonAnonymousAncestor())
container_object != NearestAncestorForElement())
has_perspective = false;

// d) Perspective applied by container.
Expand Down
34 changes: 33 additions & 1 deletion third_party/blink/renderer/core/layout/layout_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,30 @@ LayoutObject* LayoutObject::NextInPreOrder() const {
return NextInPreOrderAfterChildren();
}

bool LayoutObject::IsForElement() const {
if (!IsAnonymous()) {
return true;
}

// When a block is inside of an inline, the part of the inline that
// wraps the block is represented in the layout tree by a block that
// is marked as anonymous, but has a continuation that's not
// anonymous.

if (!IsBox()) {
return false;
}

auto* continuation = To<LayoutBox>(this)->Continuation();
if (!continuation || continuation->IsAnonymous()) {
return false;
}

DCHECK(continuation->IsInline());
DCHECK(IsLayoutBlockFlow());
return true;
}

bool LayoutObject::HasClipRelatedProperty() const {
NOT_DESTROYED();
// This function detects a bunch of properties that can potentially affect
Expand Down Expand Up @@ -1550,6 +1574,14 @@ LayoutObject* LayoutObject::NonAnonymousAncestor() const {
return ancestor;
}

LayoutObject* LayoutObject::NearestAncestorForElement() const {
NOT_DESTROYED();
LayoutObject* ancestor = Parent();
while (ancestor && !ancestor->IsForElement())
ancestor = ancestor->Parent();
return ancestor;
}

LayoutBlock* LayoutObject::FindNonAnonymousContainingBlock(
LayoutObject* container,
AncestorSkipInfo* skip_info) {
Expand Down Expand Up @@ -3355,7 +3387,7 @@ void LayoutObject::GetTransformFromContainer(
bool has_perspective = container_object && container_object->HasLayer() &&
container_object->StyleRef().HasPerspective();
if (has_perspective && RuntimeEnabledFeatures::TransformInteropEnabled() &&
container_object != NonAnonymousAncestor())
container_object != NearestAncestorForElement())
has_perspective = false;

if (has_perspective) {
Expand Down
14 changes: 13 additions & 1 deletion third_party/blink/renderer/core/layout/layout_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -1353,6 +1353,14 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
StyleRef().StyleType() == kPseudoIdNone && IsLayoutBlock() &&
!IsLayoutFlowThread() && !IsLayoutMultiColumnSet();
}
// This is similar to the negation of IsAnonymous, with a single difference.
// When a block is inside an inline, there is an anonymous block that is a
// continuation of the inline, wrapping the block that is inside it, as
// https://www.w3.org/TR/CSS21/visuren.html#anonymous-block-level describes.
// That anonymous block also returns true here. This allows us to track
// when layout object parent-child relationships correspond to DOM
// parent-child relationships.
bool IsForElement() const;
// If node has been split into continuations, it returns the first layout
// object generated for the node.
const LayoutObject* ContinuationRoot() const {
Expand Down Expand Up @@ -2291,10 +2299,14 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
LayoutObject* container,
AncestorSkipInfo* = nullptr);

// Returns the nearest anceestor in the layout tree that is not anonymous,
// Returns the nearest ancestor in the layout tree that is not anonymous,
// or null if there is none.
LayoutObject* NonAnonymousAncestor() const;

// Returns the nearest ancestor in the layout tree that IsForElement(),
// or null if there is none.
LayoutObject* NearestAncestorForElement() const;

const LayoutBlock* InclusiveContainingBlock() const;

const LayoutBlock* EnclosingScrollportBox() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateTransform() {
transform->Translation2D();
}
} else if (RuntimeEnabledFeatures::TransformInteropEnabled() &&
!object_.IsAnonymous()) {
object_.IsForElement()) {
// With kTransformInterop enabled, 3D rendering contexts follow the
// DOM ancestor chain, so flattening should apply regardless of
// presence of transform.
Expand Down Expand Up @@ -2803,7 +2803,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateForSelf() {
UpdateFilter();
UpdateOverflowControlsClip();
} else if (RuntimeEnabledFeatures::TransformInteropEnabled() &&
!object_.IsAnonymous()) {
object_.IsForElement()) {
// With kTransformInterop enabled, 3D rendering contexts follow the
// DOM ancestor chain, so flattening should apply regardless of
// presence of transform.
Expand Down
13 changes: 12 additions & 1 deletion third_party/blink/web_tests/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -5463,12 +5463,14 @@ crbug.com/1008483 external/wpt/css/css-transforms/backface-visibility-hidden-ani
crbug.com/1008483 external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties-containing-block.tentative.html [ Failure ]
crbug.com/1008483 external/wpt/css/css-transforms/3d-rendering-context-and-abspos.html [ Failure ]
crbug.com/1008483 external/wpt/css/css-transforms/3d-rendering-context-and-fixpos.html [ Failure ]
crbug.com/1008483 external/wpt/css/css-transforms/3d-rendering-context-and-inline.html [ Failure ]
crbug.com/1008483 external/wpt/css/css-transforms/transform3d-sorting-004.html [ Failure ]

crbug.com/1008483 virtual/transform-interop/external/wpt/css/css-transforms/3d-rendering-context-behavior.tentative.html [ Pass ]
crbug.com/1008483 virtual/transform-interop/external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties-containing-block.tentative.html [ Pass ]
crbug.com/1008483 virtual/transform-interop/external/wpt/css/css-transforms/3d-rendering-context-and-abspos.html [ Pass ]
crbug.com/1008483 virtual/transform-interop/external/wpt/css/css-transforms/3d-rendering-context-and-fixpos.html [ Pass ]
crbug.com/1008483 virtual/transform-interop/external/wpt/css/css-transforms/3d-rendering-context-and-inline.html [ Pass ]
crbug.com/1008483 virtual/transform-interop/external/wpt/css/css-transforms/transform3d-sorting-004.html [ Pass ]
crbug.com/1008483 virtual/transform-interop/compositing/geometry/require-own-backing-recalc-order.html [ Failure ]
crbug.com/1008483 virtual/transform-interop/paint/invalidation/scroll/sticky/invalidate-after-composited-scroll-with-sticky.html [ Failure ]
Expand All @@ -5481,6 +5483,7 @@ crbug.com/1008483 virtual/backface-visibility-interop/external/wpt/css/css-trans
crbug.com/1008483 virtual/backface-visibility-interop/external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties-containing-block.tentative.html [ Pass ]
crbug.com/1008483 virtual/backface-visibility-interop/external/wpt/css/css-transforms/3d-rendering-context-and-abspos.html [ Pass ]
crbug.com/1008483 virtual/backface-visibility-interop/external/wpt/css/css-transforms/3d-rendering-context-and-fixpos.html [ Pass ]
crbug.com/1008483 virtual/backface-visibility-interop/external/wpt/css/css-transforms/3d-rendering-context-and-inline.html [ Pass ]
crbug.com/1008483 virtual/backface-visibility-interop/external/wpt/css/css-transforms/transform3d-sorting-004.html [ Pass ]
crbug.com/1008483 virtual/backface-visibility-interop/compositing/geometry/require-own-backing-recalc-order.html [ Failure ]
crbug.com/1008483 virtual/backface-visibility-interop/compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor.html [ Failure ]
Expand All @@ -5491,13 +5494,21 @@ crbug.com/1008483 virtual/backface-visibility-interop/transforms/3d/point-mappin

crbug.com/943503 external/wpt/css/css-transforms/transform3d-perspective-003.html [ Failure ]
crbug.com/943503 external/wpt/css/css-transforms/transform3d-perspective-004.html [ Failure ]
crbug.com/943503 external/wpt/css/css-transforms/perspective-children-only-abspos.html [ Failure ]
crbug.com/943503 external/wpt/css/css-transforms/perspective-children-only-fixpos.html [ Failure ]
crbug.com/943503 external/wpt/css/css-transforms/perspective-children-only-inline.html [ Failure ]

crbug.com/943503 virtual/transform-interop/external/wpt/css/css-transforms/transform3d-perspective-003.html [ Pass ]
crbug.com/943503 virtual/transform-interop/external/wpt/css/css-transforms/transform3d-perspective-004.html [ Pass ]
crbug.com/943503 virtual/transform-interop/external/wpt/css/css-transforms/perspective-children-only-abspos.html [ Pass ]
crbug.com/943503 virtual/transform-interop/external/wpt/css/css-transforms/perspective-children-only-fixpos.html [ Pass ]
crbug.com/943503 virtual/transform-interop/external/wpt/css/css-transforms/perspective-children-only-inline.html [ Pass ]

crbug.com/943503 virtual/backface-visibility-interop/external/wpt/css/css-transforms/transform3d-perspective-003.html [ Pass ]
crbug.com/943503 virtual/backface-visibility-interop/external/wpt/css/css-transforms/transform3d-perspective-004.html [ Pass ]
crbug.com/943503 virtual/backface-visibility-interop/external/wpt/css/css-transforms/transform3d-perspective-005.html [ Pass ]
crbug.com/943503 virtual/backface-visibility-interop/external/wpt/css/css-transforms/perspective-children-only-abspos.html [ Pass ]
crbug.com/943503 virtual/backface-visibility-interop/external/wpt/css/css-transforms/perspective-children-only-fixpos.html [ Pass ]
crbug.com/943503 virtual/backface-visibility-interop/external/wpt/css/css-transforms/perspective-children-only-inline.html [ Pass ]

# Swiftshader issue.
crbug.com/1048149 external/wpt/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerwidth.html [ Crash Timeout ]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<title>CSS Test (Transforms): 3D Rendering Context following DOM Tree (inlines)</title>
<link rel="author" title="L. David Baron" href="https://dbaron.org/">
<link rel="author" title="Google" href="http://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#3d-rendering-contexts">
<meta name="assert" content="Blocks inside of inlines participate in 3D Rendering Contexts based on their parent, not their containing block.">
<link rel="match" href="transform-blank-ref.html">

<style>

.outer {
display: block;
width: 100px;
height: 100px;
transform-style: preserve-3d;
transform: rotateX(90deg);
}

.middle {
display: inline;
}

.inner {
display: block;
width: 100px;
height: 100px;
transform: rotateX(-90deg);
background: red;
}

</style>

<p>Nothing should appear except this sentence.</p>

<div class="outer">
<div class="middle">
<div class="inner"></div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<meta charset=UTF-8>
<title>CSS Test (Transforms): perspective applies only to DOM children (position: absolute)</title>
<link rel="author" title="L. David Baron" href="https://dbaron.org/">
<link rel="author" title="Google" href="http://www.google.com/">
<link rel="help" href="https://www.w3.org/TR/css-transforms-2/#perspective">
<link rel="help" href="https://www.w3.org/TR/css-transforms-2/#propdef-perspective">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/918">
<meta name="assert" content="The perspective property influences an element's children.">
<link rel="match" href="reference/green.html">
<style>

div {
width: 100px;
height: 100px;
}

#outer {
position: relative;
background: red;
perspective: 100px;
}

#middle {
}

#inner {
transform: translateZ(-100px);
position: absolute;
top: 0;
left: 0;
background: green;
}

</style>

<p>Pass if there is NO red below:</p>

<div id="outer">
<div id="middle">
<div id="inner"></div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<meta charset=UTF-8>
<title>CSS Test (Transforms): perspective applies only to DOM children (position: absolute)</title>
<link rel="author" title="L. David Baron" href="https://dbaron.org/">
<link rel="author" title="Google" href="http://www.google.com/">
<link rel="help" href="https://www.w3.org/TR/css-transforms-2/#perspective">
<link rel="help" href="https://www.w3.org/TR/css-transforms-2/#propdef-perspective">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/918">
<meta name="assert" content="The perspective property influences an element's children.">
<link rel="match" href="reference/green.html">
<style>

div {
width: 100px;
height: 100px;
}

#outer {
transform: scale(1);
position: relative;
background: red;
perspective: 100px;
}

#middle {
}

#inner {
transform: translateZ(-100px);
position: fixed;
top: 0;
left: 0;
background: green;
}

</style>

<p>Pass if there is NO red below:</p>

<div id="outer">
<div id="middle">
<div id="inner"></div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<meta charset=UTF-8>
<title>CSS Test (Transforms): perspective applies only to DOM children (position: absolute)</title>
<link rel="author" title="L. David Baron" href="https://dbaron.org/">
<link rel="author" title="Google" href="http://www.google.com/">
<link rel="help" href="https://www.w3.org/TR/css-transforms-2/#perspective">
<link rel="help" href="https://www.w3.org/TR/css-transforms-2/#propdef-perspective">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/918">
<meta name="assert" content="The perspective property influences an element's children.">
<link rel="match" href="reference/green.html">
<style>

div {
width: 100px;
height: 100px;
}

#outer {
background: red;
perspective: 100px;
}

#middle {
display: inline;
}

#inner {
transform: translateZ(-100px);
background: green;
}

</style>

<p>Pass if there is NO red below:</p>

<div id="outer">
<div id="middle">
<div id="inner"></div>
</div>
</div>

0 comments on commit 14e7fed

Please sign in to comment.