Commit 6bc6abaa authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

[PE] Add a fast path in GeometryMapper::LocalToAncestorClipRectInternal()

For
  descendant->Parent() == ancestor_clip &&
  descendant->LocalTransformSpace() == ancestor_transform
we can return the clip rect of |descendant| directly to avoid the more
complex logic.

This also reduces the number of entries in the clip cache, which can
speed-up cache lookup.

Premilinary stats show that the fast path is used for about half of all
calls to the function.

Bug: 803867
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I8c390e17cbc7c5e225716e6e90ac8be4dfa615d8
Reviewed-on: https://chromium-review.googlesource.com/963012Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543201}
parent 572936b0
...@@ -258,18 +258,32 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRect( ...@@ -258,18 +258,32 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRect(
return result; return result;
} }
static const FloatRoundedRect& GetClipRect(
const ClipPaintPropertyNode* clip_node,
OverlayScrollbarClipBehavior clip_behavior) {
return UNLIKELY(clip_behavior == kExcludeOverlayScrollbarSizeForHitTesting)
? clip_node->ClipRectExcludingOverlayScrollbars()
: clip_node->ClipRect();
}
FloatClipRect GeometryMapper::LocalToAncestorClipRectInternal( FloatClipRect GeometryMapper::LocalToAncestorClipRectInternal(
const ClipPaintPropertyNode* descendant, const ClipPaintPropertyNode* descendant,
const ClipPaintPropertyNode* ancestor_clip, const ClipPaintPropertyNode* ancestor_clip,
const TransformPaintPropertyNode* ancestor_transform, const TransformPaintPropertyNode* ancestor_transform,
OverlayScrollbarClipBehavior clip_behavior, OverlayScrollbarClipBehavior clip_behavior,
bool& success) { bool& success) {
FloatClipRect clip;
if (descendant == ancestor_clip) { if (descendant == ancestor_clip) {
success = true; success = true;
return FloatClipRect(); return FloatClipRect();
} }
if (descendant->Parent() == ancestor_clip &&
descendant->LocalTransformSpace() == ancestor_transform) {
success = true;
return FloatClipRect(GetClipRect(descendant, clip_behavior));
}
FloatClipRect clip;
const ClipPaintPropertyNode* clip_node = descendant; const ClipPaintPropertyNode* clip_node = descendant;
Vector<const ClipPaintPropertyNode*> intermediate_nodes; Vector<const ClipPaintPropertyNode*> intermediate_nodes;
...@@ -317,10 +331,7 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRectInternal( ...@@ -317,10 +331,7 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRectInternal(
// This is where we generate the roundedness and tightness of clip rect // This is where we generate the roundedness and tightness of clip rect
// from clip and transform properties, and propagate them to |clip|. // from clip and transform properties, and propagate them to |clip|.
FloatClipRect mapped_rect(clip_behavior == FloatClipRect mapped_rect(GetClipRect((*it), clip_behavior));
kExcludeOverlayScrollbarSizeForHitTesting
? (*it)->ClipRectExcludingOverlayScrollbars()
: (*it)->ClipRect());
mapped_rect.Map(transform_matrix); mapped_rect.Map(transform_matrix);
clip.Intersect(mapped_rect); clip.Intersect(mapped_rect);
......
...@@ -108,8 +108,6 @@ INSTANTIATE_TEST_CASE_P(All, ...@@ -108,8 +108,6 @@ INSTANTIATE_TEST_CASE_P(All,
#define CHECK_SOURCE_TO_DESTINATION_PROJECTION() \ #define CHECK_SOURCE_TO_DESTINATION_PROJECTION() \
do { \ do { \
if (ancestor_state.Transform() == local_state.Transform()) \
break; \
SCOPED_TRACE("Check SourceToDestinationProjection"); \ SCOPED_TRACE("Check SourceToDestinationProjection"); \
const auto& actual_transform_to_ancestor = \ const auto& actual_transform_to_ancestor = \
GeometryMapper::SourceToDestinationProjection( \ GeometryMapper::SourceToDestinationProjection( \
...@@ -117,16 +115,22 @@ INSTANTIATE_TEST_CASE_P(All, ...@@ -117,16 +115,22 @@ INSTANTIATE_TEST_CASE_P(All,
EXPECT_EQ(expected_transform, actual_transform_to_ancestor); \ EXPECT_EQ(expected_transform, actual_transform_to_ancestor); \
} while (false) } while (false)
#define CHECK_CACHED_CLIP() \ #define CHECK_CACHED_CLIP() \
do { \ do { \
if (ancestor_state.Clip() == local_state.Clip() || \ if (ancestor_state.Effect() != local_state.Effect()) \
ancestor_state.Effect() != local_state.Effect()) \ break; \
break; \ SCOPED_TRACE("Check cached clip"); \
SCOPED_TRACE("Check cached clip"); \ const auto* cached_clip = \
const auto* cached_clip = \ GetCachedClip(local_state.Clip(), ancestor_state); \
GetCachedClip(local_state.Clip(), ancestor_state); \ if (ancestor_state.Clip() == local_state.Clip() || \
DCHECK(cached_clip); \ (ancestor_state.Clip() == local_state.Clip()->Parent() && \
EXPECT_CLIP_RECT_EQ(expected_clip, *cached_clip); \ ancestor_state.Transform() == \
local_state.Clip()->LocalTransformSpace())) { \
EXPECT_EQ(nullptr, cached_clip); \
break; \
} \
ASSERT_NE(nullptr, cached_clip); \
EXPECT_CLIP_RECT_EQ(expected_clip, *cached_clip); \
} while (false) } while (false)
// See the data fields of GeometryMapperTest for variables that will be used in // See the data fields of GeometryMapperTest for variables that will be used in
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment