| Index: third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp
|
| diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp
|
| index 6258d642b44163697b80df40d37b24c93ed689c8..733cd67c26aeb10382b9a7bc3fe6202527124a5d 100644
|
| --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp
|
| +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp
|
| @@ -9,26 +9,27 @@
|
|
|
| namespace blink {
|
|
|
| -void GeometryMapper::sourceToDestinationVisualRect(
|
| +FloatClipRect GeometryMapper::sourceToDestinationVisualRect(
|
| + const FloatRect& rect,
|
| + const PropertyTreeState& sourceState,
|
| + const PropertyTreeState& destinationState) {
|
| + bool success = false;
|
| + FloatClipRect result = sourceToDestinationVisualRectInternal(
|
| + rect, sourceState, destinationState, success);
|
| + DCHECK(success);
|
| + return result;
|
| +}
|
| +
|
| +FloatClipRect GeometryMapper::sourceToDestinationVisualRectInternal(
|
| + const FloatRect& rect,
|
| const PropertyTreeState& sourceState,
|
| const PropertyTreeState& destinationState,
|
| - FloatRect& rect) {
|
| - bool success = false;
|
| - sourceToDestinationVisualRectInternal(sourceState, destinationState, rect,
|
| - success);
|
| - DCHECK(success);
|
| -}
|
| -
|
| -void GeometryMapper::sourceToDestinationVisualRectInternal(
|
| - const PropertyTreeState& sourceState,
|
| - const PropertyTreeState& destinationState,
|
| - FloatRect& mappingRect,
|
| - bool& success) {
|
| - localToAncestorVisualRectInternal(sourceState, destinationState, mappingRect,
|
| - success);
|
| + bool& success) {
|
| + FloatClipRect result = localToAncestorVisualRectInternal(
|
| + rect, sourceState, destinationState, success);
|
| // Success if destinationState is an ancestor state.
|
| if (success)
|
| - return;
|
| + return result;
|
|
|
| // Otherwise first map to the lowest common ancestor, then map to destination.
|
| const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor(
|
| @@ -41,75 +42,78 @@
|
| PropertyTreeState lcaState = destinationState;
|
| lcaState.setTransform(lcaTransform);
|
|
|
| - localToAncestorVisualRectInternal(sourceState, lcaState, mappingRect,
|
| - success);
|
| + result =
|
| + localToAncestorVisualRectInternal(rect, sourceState, lcaState, success);
|
| if (!success)
|
| - return;
|
| -
|
| - ancestorToLocalRect(lcaTransform, destinationState.transform(), mappingRect);
|
| -}
|
| -
|
| -void GeometryMapper::sourceToDestinationRect(
|
| + return result;
|
| + if (!result.isInfinite()) {
|
| + FloatRect final = ancestorToLocalRect(result.rect(), lcaTransform,
|
| + destinationState.transform());
|
| + result.setRect(final);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +FloatRect GeometryMapper::sourceToDestinationRect(
|
| + const FloatRect& rect,
|
| const TransformPaintPropertyNode* sourceTransformNode,
|
| - const TransformPaintPropertyNode* destinationTransformNode,
|
| - FloatRect& mappingRect) {
|
| - bool success = false;
|
| - localToAncestorRectInternal(sourceTransformNode, destinationTransformNode,
|
| - mappingRect, success);
|
| + const TransformPaintPropertyNode* destinationTransformNode) {
|
| + bool success = false;
|
| + FloatRect result = localToAncestorRectInternal(
|
| + rect, sourceTransformNode, destinationTransformNode, success);
|
| // Success if destinationTransformNode is an ancestor of sourceTransformNode.
|
| if (success)
|
| - return;
|
| + return result;
|
|
|
| // Otherwise first map to the least common ancestor, then map to destination.
|
| const TransformPaintPropertyNode* lcaTransform =
|
| lowestCommonAncestor(sourceTransformNode, destinationTransformNode);
|
| DCHECK(lcaTransform);
|
|
|
| - localToAncestorRect(sourceTransformNode, lcaTransform, mappingRect);
|
| - ancestorToLocalRect(lcaTransform, destinationTransformNode, mappingRect);
|
| -}
|
| -
|
| -void GeometryMapper::localToAncestorVisualRect(
|
| + FloatRect lcaRect =
|
| + localToAncestorRect(rect, sourceTransformNode, lcaTransform);
|
| + return ancestorToLocalRect(lcaRect, lcaTransform, destinationTransformNode);
|
| +}
|
| +
|
| +FloatClipRect GeometryMapper::localToAncestorVisualRect(
|
| + const FloatRect& rect,
|
| + const PropertyTreeState& localState,
|
| + const PropertyTreeState& ancestorState) {
|
| + bool success = false;
|
| + FloatClipRect result = localToAncestorVisualRectInternal(
|
| + rect, localState, ancestorState, success);
|
| + DCHECK(success);
|
| + return result;
|
| +}
|
| +
|
| +FloatClipRect GeometryMapper::localToAncestorVisualRectInternal(
|
| + const FloatRect& rect,
|
| const PropertyTreeState& localState,
|
| const PropertyTreeState& ancestorState,
|
| - FloatRect& mappingRect) {
|
| - bool success = false;
|
| - localToAncestorVisualRectInternal(localState, ancestorState, mappingRect,
|
| - success);
|
| - DCHECK(success);
|
| -}
|
| -
|
| -void GeometryMapper::localToAncestorVisualRectInternal(
|
| - const PropertyTreeState& localState,
|
| - const PropertyTreeState& ancestorState,
|
| - FloatRect& rectToMap,
|
| bool& success) {
|
| if (localState == ancestorState) {
|
| success = true;
|
| - return;
|
| + return rect;
|
| }
|
|
|
| if (localState.effect() != ancestorState.effect()) {
|
| - slowLocalToAncestorVisualRectWithEffects(localState, ancestorState,
|
| - rectToMap, success);
|
| - return;
|
| + return slowLocalToAncestorVisualRectWithEffects(rect, localState,
|
| + ancestorState, success);
|
| }
|
|
|
| const auto& transformMatrix = localToAncestorMatrixInternal(
|
| localState.transform(), ancestorState.transform(), success);
|
| - if (!success) {
|
| - return;
|
| - }
|
| -
|
| - FloatRect mappedRect = transformMatrix.mapRect(rectToMap);
|
| -
|
| - const FloatClipRect& clipRect =
|
| + if (!success)
|
| + return rect;
|
| +
|
| + FloatRect mappedRect = transformMatrix.mapRect(rect);
|
| +
|
| + FloatClipRect clipRect =
|
| localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(),
|
| ancestorState.transform(), success);
|
|
|
| if (success) {
|
| - rectToMap = clipRect.rect();
|
| - rectToMap.intersect(mappedRect);
|
| + clipRect.intersect(mappedRect);
|
| } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
|
| // On SPv1 we may fail when the paint invalidation container creates an
|
| // overflow clip (in ancestorState) which is not in localState of an
|
| @@ -119,15 +123,18 @@
|
| // Ignore it for SPv1 for now.
|
| success = true;
|
| }
|
| -}
|
| -
|
| -void GeometryMapper::slowLocalToAncestorVisualRectWithEffects(
|
| +
|
| + return clipRect;
|
| +}
|
| +
|
| +FloatClipRect GeometryMapper::slowLocalToAncestorVisualRectWithEffects(
|
| + const FloatRect& rect,
|
| const PropertyTreeState& localState,
|
| const PropertyTreeState& ancestorState,
|
| - FloatRect& mappingRect,
|
| bool& success) {
|
| PropertyTreeState lastTransformAndClipState(localState.transform(),
|
| localState.clip(), nullptr);
|
| + FloatClipRect result(rect);
|
|
|
| for (const auto* effect = localState.effect();
|
| effect && effect != ancestorState.effect(); effect = effect->parent()) {
|
| @@ -136,62 +143,75 @@
|
|
|
| PropertyTreeState transformAndClipState(effect->localTransformSpace(),
|
| effect->outputClip(), nullptr);
|
| - sourceToDestinationVisualRectInternal(
|
| - lastTransformAndClipState, transformAndClipState, mappingRect, success);
|
| - if (!success)
|
| - return;
|
| -
|
| - mappingRect = effect->mapRect(mappingRect);
|
| + bool hasRadius = result.hasRadius();
|
| + result = sourceToDestinationVisualRectInternal(
|
| + result.rect(), lastTransformAndClipState, transformAndClipState,
|
| + success);
|
| + hasRadius |= result.hasRadius();
|
| + if (!success) {
|
| + if (hasRadius)
|
| + result.setHasRadius();
|
| + return result;
|
| + }
|
| +
|
| + result = effect->mapRect(result.rect());
|
| + if (hasRadius)
|
| + result.setHasRadius();
|
| lastTransformAndClipState = transformAndClipState;
|
| }
|
|
|
| PropertyTreeState finalTransformAndClipState(ancestorState.transform(),
|
| ancestorState.clip(), nullptr);
|
| - sourceToDestinationVisualRectInternal(lastTransformAndClipState,
|
| - finalTransformAndClipState, mappingRect,
|
| - success);
|
| -}
|
| -
|
| -void GeometryMapper::localToAncestorRect(
|
| + bool hasRadius = result.hasRadius();
|
| + result = sourceToDestinationVisualRectInternal(
|
| + result.rect(), lastTransformAndClipState, finalTransformAndClipState,
|
| + success);
|
| + if (hasRadius || result.hasRadius())
|
| + result.setHasRadius();
|
| + return result;
|
| +}
|
| +
|
| +FloatRect GeometryMapper::localToAncestorRect(
|
| + const FloatRect& rect,
|
| + const TransformPaintPropertyNode* localTransformNode,
|
| + const TransformPaintPropertyNode* ancestorTransformNode) {
|
| + bool success = false;
|
| + FloatRect result = localToAncestorRectInternal(
|
| + rect, localTransformNode, ancestorTransformNode, success);
|
| + DCHECK(success);
|
| + return result;
|
| +}
|
| +
|
| +FloatRect GeometryMapper::localToAncestorRectInternal(
|
| + const FloatRect& rect,
|
| const TransformPaintPropertyNode* localTransformNode,
|
| const TransformPaintPropertyNode* ancestorTransformNode,
|
| - FloatRect& mappingRect) {
|
| - bool success = false;
|
| - localToAncestorRectInternal(localTransformNode, ancestorTransformNode,
|
| - mappingRect, success);
|
| - DCHECK(success);
|
| -}
|
| -
|
| -void GeometryMapper::localToAncestorRectInternal(
|
| - const TransformPaintPropertyNode* localTransformNode,
|
| - const TransformPaintPropertyNode* ancestorTransformNode,
|
| - FloatRect& mappingRect,
|
| bool& success) {
|
| if (localTransformNode == ancestorTransformNode) {
|
| success = true;
|
| - return;
|
| + return rect;
|
| }
|
|
|
| const auto& transformMatrix = localToAncestorMatrixInternal(
|
| localTransformNode, ancestorTransformNode, success);
|
| if (!success)
|
| - return;
|
| - mappingRect = transformMatrix.mapRect(mappingRect);
|
| -}
|
| -
|
| -void GeometryMapper::ancestorToLocalRect(
|
| + return rect;
|
| + return transformMatrix.mapRect(rect);
|
| +}
|
| +
|
| +FloatRect GeometryMapper::ancestorToLocalRect(
|
| + const FloatRect& rect,
|
| const TransformPaintPropertyNode* ancestorTransformNode,
|
| - const TransformPaintPropertyNode* localTransformNode,
|
| - FloatRect& rect) {
|
| + const TransformPaintPropertyNode* localTransformNode) {
|
| if (localTransformNode == ancestorTransformNode)
|
| - return;
|
| + return rect;
|
|
|
| const auto& transformMatrix =
|
| localToAncestorMatrix(localTransformNode, ancestorTransformNode);
|
| DCHECK(transformMatrix.isInvertible());
|
|
|
| // TODO(chrishtr): Cache the inverse?
|
| - rect = transformMatrix.inverse().mapRect(rect);
|
| + return transformMatrix.inverse().mapRect(rect);
|
| }
|
|
|
| FloatClipRect GeometryMapper::localToAncestorClipRect(
|
| @@ -207,22 +227,22 @@
|
| return result;
|
| }
|
|
|
| -const FloatClipRect& GeometryMapper::sourceToDestinationClipRect(
|
| +FloatClipRect GeometryMapper::sourceToDestinationClipRect(
|
| const PropertyTreeState& sourceState,
|
| const PropertyTreeState& destinationState) {
|
| bool success = false;
|
| - const FloatClipRect& result = sourceToDestinationClipRectInternal(
|
| + FloatClipRect result = sourceToDestinationClipRectInternal(
|
| sourceState, destinationState, success);
|
| DCHECK(success);
|
|
|
| return result;
|
| }
|
|
|
| -const FloatClipRect& GeometryMapper::sourceToDestinationClipRectInternal(
|
| +FloatClipRect GeometryMapper::sourceToDestinationClipRectInternal(
|
| const PropertyTreeState& sourceState,
|
| const PropertyTreeState& destinationState,
|
| bool& success) {
|
| - const FloatClipRect& result = localToAncestorClipRectInternal(
|
| + FloatClipRect result = localToAncestorClipRectInternal(
|
| sourceState.clip(), destinationState.clip(), destinationState.transform(),
|
| success);
|
| // Success if destinationState is an ancestor state.
|
| @@ -241,8 +261,8 @@
|
| PropertyTreeState lcaState = destinationState;
|
| lcaState.setTransform(lcaTransform);
|
|
|
| - const FloatClipRect& result2 = localToAncestorClipRectInternal(
|
| - sourceState.clip(), lcaState.clip(), lcaState.transform(), success);
|
| + result = localToAncestorClipRectInternal(sourceState.clip(), lcaState.clip(),
|
| + lcaState.transform(), success);
|
| if (!success) {
|
| if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
|
| // On SPv1 we may fail when the paint invalidation container creates an
|
| @@ -253,17 +273,14 @@
|
| // Ignore it for SPv1 for now.
|
| success = true;
|
| }
|
| - return result2;
|
| - }
|
| - if (!result2.isInfinite()) {
|
| - FloatRect rect = result2.rect();
|
| - ancestorToLocalRect(lcaTransform, destinationState.transform(), rect);
|
| - m_tempRect.setRect(rect);
|
| - if (result2.hasRadius())
|
| - m_tempRect.setHasRadius();
|
| - return m_tempRect;
|
| - }
|
| - return result2;
|
| + return result;
|
| + }
|
| + if (!result.isInfinite()) {
|
| + FloatRect final = ancestorToLocalRect(result.rect(), lcaTransform,
|
| + destinationState.transform());
|
| + result.setRect(final);
|
| + }
|
| + return result;
|
| }
|
|
|
| const FloatClipRect& GeometryMapper::localToAncestorClipRectInternal(
|
| @@ -312,7 +329,6 @@
|
| clip.intersect(mappedRect);
|
| if ((*it)->clipRect().isRounded())
|
| clip.setHasRadius();
|
| -
|
| (*it)->getClipCache().setCachedClip(clipAndTransform, clip);
|
| }
|
|
|
| @@ -321,7 +337,6 @@
|
| const FloatClipRect* cachedClip =
|
| descendant->getClipCache().getCachedClip(clipAndTransform);
|
| DCHECK(cachedClip);
|
| - CHECK(clip.hasRadius() == cachedClip->hasRadius());
|
| return *cachedClip;
|
| }
|
|
|
|
|