forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Track hit test opaqueness of cc::Layers
During paint, ObjectPainter::RecordHitTestData() records hit test data with hit test opaqueness, which is transparent with pointer-events:none, mixed with border radius, or opaque otherwise. The opaqueness of multiple hit test data are then merged at the PaintChunk level, then at PendingLayer level, then is passed to cc::Layer then cc::LayerImpl. The new behavior is behind the blink runtime flag "HitTestOpaqueness". The opaqueness on cc::LayerImpl will be used in the next CL to reduce unreliable scroll begins on the compositor. Bug: 1413877 Change-Id: I416e3cfab4157d50db3fee91aff765cb2dd4a245 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4754732 Reviewed-by: Philip Rogers <pdr@chromium.org> Reviewed-by: Kentaro Hara <haraken@chromium.org> Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org> Cr-Commit-Position: refs/heads/main@{#1182332}
- Loading branch information
1 parent
0281be9
commit 0e6d443
Showing
50 changed files
with
772 additions
and
349 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "cc/input/hit_test_opaqueness.h" | ||
#include "base/check_op.h" | ||
#include "base/notreached.h" | ||
|
||
namespace cc { | ||
|
||
namespace { | ||
|
||
// Returns true if UnionRects(rect1, rect2) doesn't have any area not covered | ||
// by either rect1 or rect2. | ||
bool UnionIsTight(const gfx::Rect& rect1, const gfx::Rect& rect2) { | ||
return gfx::UnionRects(rect1, rect2) == gfx::MaximumCoveredRect(rect1, rect2); | ||
} | ||
|
||
} // anonymous namespace | ||
|
||
const char* HitTestOpaquenessToString(HitTestOpaqueness opaqueness) { | ||
return opaqueness == HitTestOpaqueness::kTransparent ? "transparent" | ||
: opaqueness == HitTestOpaqueness::kOpaque ? "opaque" | ||
: "mixed"; | ||
} | ||
|
||
HitTestOpaqueness UnionHitTestOpaqueness(const gfx::Rect& rect1, | ||
HitTestOpaqueness opaqueness1, | ||
const gfx::Rect& rect2, | ||
HitTestOpaqueness opaqueness2) { | ||
if (rect1.IsEmpty()) { | ||
return opaqueness2; | ||
} | ||
if (rect2.IsEmpty()) { | ||
return opaqueness1; | ||
} | ||
if (opaqueness1 < opaqueness2) { | ||
return UnionHitTestOpaqueness(rect2, opaqueness2, rect1, opaqueness1); | ||
} | ||
|
||
switch (opaqueness1) { | ||
case HitTestOpaqueness::kTransparent: | ||
DCHECK_EQ(opaqueness2, HitTestOpaqueness::kTransparent); | ||
return HitTestOpaqueness::kTransparent; | ||
case HitTestOpaqueness::kMixed: | ||
DCHECK_NE(opaqueness2, HitTestOpaqueness::kOpaque); | ||
return HitTestOpaqueness::kMixed; | ||
case HitTestOpaqueness::kOpaque: | ||
if (opaqueness2 == HitTestOpaqueness::kOpaque) { | ||
return UnionIsTight(rect1, rect2) ? HitTestOpaqueness::kOpaque | ||
: HitTestOpaqueness::kMixed; | ||
} | ||
return rect1.Contains(rect2) ? HitTestOpaqueness::kOpaque | ||
: HitTestOpaqueness::kMixed; | ||
} | ||
NOTREACHED_NORETURN(); | ||
} | ||
|
||
} // namespace cc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CC_INPUT_HIT_TEST_OPAQUENESS_H_ | ||
#define CC_INPUT_HIT_TEST_OPAQUENESS_H_ | ||
|
||
#include <stdint.h> | ||
|
||
#include "cc/cc_export.h" | ||
#include "ui/gfx/geometry/rect.h" | ||
|
||
namespace cc { | ||
|
||
// Describes the opaqueness for hit testing in a layered content e.g. a layer. | ||
enum class HitTestOpaqueness : uint8_t { | ||
// The whole layered content is transparent (i.e. as if it didn't exist) | ||
// to hit test. | ||
kTransparent, | ||
// Some areas may be transparent, while some may be opaque. | ||
kMixed, | ||
// The whole layered content is opaque to hit test. | ||
kOpaque, | ||
}; | ||
|
||
CC_EXPORT const char* HitTestOpaquenessToString(HitTestOpaqueness opaqueness); | ||
|
||
// Returns the hit test opaqueness of the bounds containing `rect1` and `rect2` | ||
// of specified opaqueness. | ||
CC_EXPORT HitTestOpaqueness | ||
UnionHitTestOpaqueness(const gfx::Rect& rect1, | ||
HitTestOpaqueness opaqueness1, | ||
const gfx::Rect& rect2, | ||
HitTestOpaqueness opaqueness2); | ||
|
||
} // namespace cc | ||
|
||
#endif // CC_INPUT_HIT_TEST_OPAQUENESS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "cc/input/hit_test_opaqueness.h" | ||
|
||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
namespace cc { | ||
namespace { | ||
|
||
constexpr auto kTransparent = HitTestOpaqueness::kTransparent; | ||
constexpr auto kMixed = HitTestOpaqueness::kMixed; | ||
constexpr auto kOpaque = HitTestOpaqueness::kOpaque; | ||
|
||
#define EXPECT_OPAQUENESS(expected, r1, o1, r2, o2) \ | ||
do { \ | ||
EXPECT_EQ(expected, UnionHitTestOpaqueness(r1, o1, r2, o2)); \ | ||
EXPECT_EQ(expected, UnionHitTestOpaqueness(r2, o2, r1, o1)); \ | ||
} while (false) | ||
|
||
TEST(HitTestOpaquenessTest, BothTransparent) { | ||
EXPECT_OPAQUENESS(kTransparent, gfx::Rect(), kTransparent, gfx::Rect(), | ||
kTransparent); | ||
EXPECT_OPAQUENESS(kTransparent, gfx::Rect(0, 0, 100, 100), kTransparent, | ||
gfx::Rect(0, 0, 100, 100), kTransparent); | ||
EXPECT_OPAQUENESS(kTransparent, gfx::Rect(0, 0, 100, 100), kTransparent, | ||
gfx::Rect(0, 100, 100, 100), kTransparent); | ||
EXPECT_OPAQUENESS(kTransparent, gfx::Rect(0, 0, 100, 100), kTransparent, | ||
gfx::Rect(0, 0, 50, 100), kTransparent); | ||
EXPECT_OPAQUENESS(kTransparent, gfx::Rect(0, 0, 100, 100), kTransparent, | ||
gfx::Rect(0, 200, 100, 100), kTransparent); | ||
EXPECT_OPAQUENESS(kTransparent, gfx::Rect(0, 0, 100, 100), kTransparent, | ||
gfx::Rect(50, 50, 100, 100), kTransparent); | ||
} | ||
|
||
TEST(HitTestOpaquenessTest, BothOpaque) { | ||
EXPECT_OPAQUENESS(kOpaque, gfx::Rect(), kOpaque, gfx::Rect(), kOpaque); | ||
EXPECT_OPAQUENESS(kOpaque, gfx::Rect(0, 0, 100, 100), kOpaque, | ||
gfx::Rect(0, 0, 100, 100), kOpaque); | ||
EXPECT_OPAQUENESS(kOpaque, gfx::Rect(0, 0, 100, 100), kOpaque, | ||
gfx::Rect(0, 100, 100, 100), kOpaque); | ||
EXPECT_OPAQUENESS(kOpaque, gfx::Rect(0, 0, 100, 100), kOpaque, | ||
gfx::Rect(0, 0, 50, 100), kOpaque); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kOpaque, | ||
gfx::Rect(0, 200, 100, 100), kOpaque); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kOpaque, | ||
gfx::Rect(50, 50, 100, 100), kOpaque); | ||
} | ||
|
||
TEST(HitTestOpaquenessTest, BothMixed) { | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(), kMixed, gfx::Rect(), kMixed); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(0, 0, 100, 100), kMixed); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(0, 100, 100, 100), kMixed); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(0, 0, 50, 100), kMixed); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(0, 200, 100, 100), kMixed); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(50, 50, 100, 100), kMixed); | ||
} | ||
|
||
TEST(HitTestOpaquenessTest, MixedAndTransparent) { | ||
EXPECT_OPAQUENESS(kTransparent, gfx::Rect(), kMixed, | ||
gfx::Rect(0, 0, 100, 100), kTransparent); | ||
EXPECT_OPAQUENESS(kTransparent, gfx::Rect(), kMixed, | ||
gfx::Rect(0, 0, 100, 100), kTransparent); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(0, 0, 100, 100), kTransparent); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(0, 100, 100, 100), kTransparent); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(0, 100, 100, 100), kTransparent); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(50, 50, 100, 100), kTransparent); | ||
} | ||
|
||
TEST(HitTestOpaquenessTest, MixedAndOpaque) { | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, gfx::Rect(), | ||
kOpaque); | ||
EXPECT_OPAQUENESS(kOpaque, gfx::Rect(), kMixed, gfx::Rect(0, 0, 100, 100), | ||
kOpaque); | ||
EXPECT_OPAQUENESS(kOpaque, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(0, 0, 100, 100), kOpaque); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(0, 100, 100, 100), kOpaque); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(0, 100, 100, 100), kOpaque); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kMixed, | ||
gfx::Rect(50, 50, 100, 100), kOpaque); | ||
} | ||
|
||
TEST(HitTestOpaquenessTest, TransparentAndOpaque) { | ||
EXPECT_OPAQUENESS(kTransparent, gfx::Rect(0, 0, 100, 100), kTransparent, | ||
gfx::Rect(), kOpaque); | ||
EXPECT_OPAQUENESS(kOpaque, gfx::Rect(), kTransparent, | ||
gfx::Rect(0, 0, 100, 100), kOpaque); | ||
EXPECT_OPAQUENESS(kOpaque, gfx::Rect(0, 0, 100, 100), kTransparent, | ||
gfx::Rect(0, 0, 100, 100), kOpaque); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kTransparent, | ||
gfx::Rect(0, 100, 100, 100), kOpaque); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kTransparent, | ||
gfx::Rect(0, 100, 100, 100), kOpaque); | ||
EXPECT_OPAQUENESS(kMixed, gfx::Rect(0, 0, 100, 100), kTransparent, | ||
gfx::Rect(50, 50, 100, 100), kOpaque); | ||
} | ||
|
||
} // anonymous namespace | ||
} // namespace cc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.