Skip to content

Commit

Permalink
[view-transitions] Computed transform for captured elements with 3d t…
Browse files Browse the repository at this point in the history
…ransforms is incorrect

https://bugs.webkit.org/show_bug.cgi?id=270428
<rdar://123984960>

Reviewed by Tim Nguyen.

This reverses the order that the matrices are concatenated when walking
ancestors. It also applies the inverse of the changes that will be applied
for transform-origin, since the computed transform already takes that into
account.

* LayoutTests/TestExpectations:
* Source/WebCore/dom/ViewTransition.cpp:
(WebCore::ViewTransition::captureOldState):
(WebCore::ViewTransition::copyElementBaseProperties):
(WebCore::ViewTransition::updatePseudoElementStyles):
* Source/WebCore/dom/ViewTransition.h:
* Source/WebCore/rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::collectViewTransitionNewContentLayers):

Canonical link: https://commits.webkit.org/275810@main
  • Loading branch information
mattwoodrow committed Mar 7, 2024
1 parent 5e8c33f commit b6a5d7e
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 11 deletions.
2 changes: 0 additions & 2 deletions LayoutTests/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -6877,8 +6877,6 @@ imported/w3c/web-platform-tests/navigation-api/updateCurrentEntry-method/locatio

# -- View Transitions -- #
# Reftest failures:
imported/w3c/web-platform-tests/css/css-view-transitions/3d-transform-incoming.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-view-transitions/3d-transform-outgoing.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-view-transitions/capture-with-offscreen-child-translated.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-view-transitions/capture-with-visibility-mixed-descendants.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-view-transitions/content-with-child-with-transparent-background.html [ ImageOnlyFailure ]
Expand Down
19 changes: 12 additions & 7 deletions Source/WebCore/dom/ViewTransition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ ExceptionOr<void> ViewTransition::captureOldState()
CheckedPtr renderBox = dynamicDowncast<RenderBox>(element->renderer());
if (renderBox)
capture.oldSize = renderBox->size();
capture.oldProperties = copyElementBaseProperties(element);
capture.oldProperties = copyElementBaseProperties(element, capture.oldSize);
if (m_document->frame())
capture.oldImage = snapshotNodeVisualOverflowClippedToViewport(*m_document->frame(), element.get(), capture.oldOverflowRect);

Expand Down Expand Up @@ -571,7 +571,7 @@ void ViewTransition::clearViewTransition()
documentElement->invalidateStyleInternal();
}

Ref<MutableStyleProperties> ViewTransition::copyElementBaseProperties(Element& element)
Ref<MutableStyleProperties> ViewTransition::copyElementBaseProperties(Element& element, const LayoutSize& size)
{
ComputedStyleExtractor styleExtractor(&element);

Expand Down Expand Up @@ -599,10 +599,14 @@ Ref<MutableStyleProperties> ViewTransition::copyElementBaseProperties(Element& e
break;
LayoutSize containerOffset = renderer->offsetFromContainer(*container, LayoutPoint());
TransformationMatrix localTransform;
renderer->getTransformFromContainer(nullptr, containerOffset, localTransform);
transform.multiply(localTransform);
renderer->getTransformFromContainer(container, containerOffset, localTransform);
transform = localTransform * transform;
renderer = container;
}
// Apply the inverse of what will be added by the default value of 'transform-origin',
// since the computed transform has already included it.
transform.translate(size.width() / 2, size.height() / 2);
transform.translateRight(-size.width() / 2, -size.height() / 2);

if (element.renderer()) {
Ref<CSSValue> transformListValue = CSSTransformListValue::create(ComputedStyleExtractor::matrixTransformValue(transform, element.renderer()->style()));
Expand All @@ -620,9 +624,10 @@ void ViewTransition::updatePseudoElementStyles()

for (auto& [name, capturedElement] : m_namedElements.map()) {
RefPtr<MutableStyleProperties> properties;
if (capturedElement->newElement)
properties = copyElementBaseProperties(*capturedElement->newElement);
else
if (capturedElement->newElement) {
CheckedPtr renderBox = dynamicDowncast<RenderBox>(capturedElement->newElement->renderer());
properties = copyElementBaseProperties(*capturedElement->newElement, renderBox ? renderBox->size() : LayoutSize { });
} else
properties = capturedElement->oldProperties;

if (properties) {
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/dom/ViewTransition.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class ViewTransition : public RefCounted<ViewTransition>, public CanMakeWeakPtr<
private:
ViewTransition(Document&, RefPtr<ViewTransitionUpdateCallback>&&);

Ref<MutableStyleProperties> copyElementBaseProperties(Element&);
Ref<MutableStyleProperties> copyElementBaseProperties(Element&, const LayoutSize&);

void updatePseudoElementStyles();
void setupDynamicStyleSheet(const AtomString&, const CapturedElement&);
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/RenderLayerCompositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1402,7 +1402,7 @@ void RenderLayerCompositor::traverseUnchangedSubtree(RenderLayer* ancestorLayer,

void RenderLayerCompositor::collectViewTransitionNewContentLayers(RenderLayer& layer, Vector<Ref<GraphicsLayer>>& childList)
{
if (layer.renderer().style().pseudoElementType() != PseudoId::ViewTransitionNew)
if (layer.renderer().style().pseudoElementType() != PseudoId::ViewTransitionNew || !layer.hasVisibleContent())
return;

RefPtr activeViewTransition = layer.renderer().document().activeViewTransition();
Expand Down

0 comments on commit b6a5d7e

Please sign in to comment.