From 0213783bdae249392e758e1dc687f3c25f214d5c Mon Sep 17 00:00:00 2001 From: Przemyslaw Gorszkowski Date: Tue, 24 Sep 2024 14:20:27 +0200 Subject: [PATCH] [WPE][GTK] visible rect in case animations is not correctly calculated https://bugs.webkit.org/show_bug.cgi?id=280612 Reviewed by Miguel Gomez. For animations starting partially outside the viewport were not fully rendered when the first frame entered the visible area. This caused incomplete or cut-off frames during the initial stages of the animation. The issue was more noticeable on low-end devices(RPi) or during slow-motion or frame-by-frame analysis of the recordings on x86. With this change the visible rect is extended with the elements which are currently not fully visible but they will be in a future bacause of animations. * Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp: (WebCore::CoordinatedGraphicsLayer::transformedVisibleRectIncludingFuture): (WebCore::CoordinatedGraphicsLayer::updateContentBuffers): (WebCore::CoordinatedGraphicsLayer::computeTransformedVisibleRect): * Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h: --- .../coordinated/CoordinatedGraphicsLayer.cpp | 32 +++++++++++++++++-- .../coordinated/CoordinatedGraphicsLayer.h | 3 ++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp index ffb510822d3e3..2771fceb34288 100644 --- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp +++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp @@ -1113,6 +1113,18 @@ IntRect CoordinatedGraphicsLayer::transformedVisibleRect() return enclosingIntRect(rect); } +IntRect CoordinatedGraphicsLayer::transformedVisibleRectIncludingFuture() +{ + auto visibleRectIncludingFuture = transformedVisibleRect(); + if (m_cachedInverseTransform != m_cachedFutureInverseTransform) { + FloatRect rect = m_cachedFutureInverseTransform.clampedBoundsOfProjectedQuad(FloatQuad(m_coordinator->visibleContentsRect())); + clampToContentsRectIfRectIsInfinite(rect, size()); + visibleRectIncludingFuture.unite(enclosingIntRect(rect)); + } + + return visibleRectIncludingFuture; +} + void CoordinatedGraphicsLayer::requestBackingStoreUpdate() { setNeedsVisibleRectAdjustment(); @@ -1185,7 +1197,7 @@ void CoordinatedGraphicsLayer::updateContentBuffers() if (m_pendingVisibleRectAdjustment) { m_pendingVisibleRectAdjustment = false; - layerState.mainBackingStore->createTilesIfNeeded(transformedVisibleRect(), IntRect(0, 0, m_size.width(), m_size.height())); + layerState.mainBackingStore->createTilesIfNeeded(transformedVisibleRectIncludingFuture(), IntRect(0, 0, m_size.width(), m_size.height())); } if (is(m_nicosia.animatedBackingStoreClient)) { @@ -1375,8 +1387,13 @@ void CoordinatedGraphicsLayer::computeTransformedVisibleRect() m_shouldUpdateVisibleRect = false; TransformationMatrix currentTransform = transform(); - if (m_movingVisibleRect) + TransformationMatrix futureTransform = currentTransform; + if (m_movingVisibleRect) { client().getCurrentTransform(this, currentTransform); + Nicosia::Animation::ApplicationResult futureApplicationResults; + m_animations.applyKeepingInternalState(futureApplicationResults, MonotonicTime::now() + 300_ms); + futureTransform = futureApplicationResults.transform.value_or(currentTransform); + } m_layerTransform.setLocalTransform(currentTransform); m_layerTransform.setAnchorPoint(m_adjustedAnchorPoint); @@ -1389,6 +1406,17 @@ void CoordinatedGraphicsLayer::computeTransformedVisibleRect() m_cachedInverseTransform = m_layerTransform.combined().inverse().value_or(TransformationMatrix()); + m_layerFutureTransform = m_layerTransform; + m_cachedFutureInverseTransform = m_cachedInverseTransform; + + CoordinatedGraphicsLayer* parentLayer = downcast(parent()); + + if (currentTransform != futureTransform || (parentLayer && parentLayer->m_layerTransform.combinedForChildren() != parentLayer->m_layerFutureTransform.combinedForChildren())) { + m_layerFutureTransform.setLocalTransform(futureTransform); + m_layerFutureTransform.combineTransforms(parentLayer ? parentLayer->m_layerFutureTransform.combinedForChildren() : TransformationMatrix()); + m_cachedFutureInverseTransform = m_layerFutureTransform.combined().inverse().value_or(TransformationMatrix()); + } + // The combined transform will be used in tiledBackingStoreVisibleRect. setNeedsVisibleRectAdjustment(); } diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h index 7c04caec7a8f9..383e109b5bcdd 100644 --- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h +++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h @@ -134,6 +134,7 @@ class WEBCORE_EXPORT CoordinatedGraphicsLayer : public GraphicsLayer { void computePixelAlignment(FloatPoint& position, FloatSize&, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset); IntRect transformedVisibleRect(); + IntRect transformedVisibleRectIncludingFuture(); void invalidateCoordinator(); void setCoordinatorIncludingSubLayersIfNeeded(CoordinatedGraphicsLayerClient*); @@ -211,7 +212,9 @@ class WEBCORE_EXPORT CoordinatedGraphicsLayer : public GraphicsLayer { Nicosia::PlatformLayer::LayerID m_id; GraphicsLayerTransform m_layerTransform; + GraphicsLayerTransform m_layerFutureTransform; TransformationMatrix m_cachedInverseTransform; + TransformationMatrix m_cachedFutureInverseTransform; FloatSize m_pixelAlignmentOffset; FloatSize m_adjustedSize; FloatPoint m_adjustedPosition;