| Index: ui/compositor/layer_unittest.cc
|
| diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc
|
| index 3f12bca1ac47343a78d2afa1996b6498e28df714..46a33b3391c7c4ac437c19c475a210c4d398aa23 100644
|
| --- a/ui/compositor/layer_unittest.cc
|
| +++ b/ui/compositor/layer_unittest.cc
|
| @@ -747,6 +747,131 @@ TEST_F(LayerWithRealCompositorTest, HierarchyNoTexture) {
|
| EXPECT_TRUE(d3.painted());
|
| }
|
|
|
| +TEST_F(LayerWithDelegateTest, Cloning) {
|
| + std::unique_ptr<Layer> layer(CreateLayer(LAYER_SOLID_COLOR));
|
| +
|
| + gfx::Transform transform;
|
| + transform.Scale(2, 1);
|
| + transform.Translate(10, 5);
|
| +
|
| + layer->SetTransform(transform);
|
| + layer->SetColor(SK_ColorRED);
|
| + layer->SetLayerInverted(true);
|
| +
|
| + auto clone = layer->Clone();
|
| +
|
| + // Cloning preserves layer state.
|
| + EXPECT_EQ(transform, clone->GetTargetTransform());
|
| + EXPECT_EQ(SK_ColorRED, clone->background_color());
|
| + EXPECT_EQ(SK_ColorRED, clone->GetTargetColor());
|
| + EXPECT_TRUE(clone->layer_inverted());
|
| +
|
| + layer->SetTransform(gfx::Transform());
|
| + layer->SetColor(SK_ColorGREEN);
|
| + layer->SetLayerInverted(false);
|
| +
|
| + // The clone is an independent copy, so state changes do not propagate.
|
| + EXPECT_EQ(transform, clone->GetTargetTransform());
|
| + EXPECT_EQ(SK_ColorRED, clone->background_color());
|
| + EXPECT_EQ(SK_ColorRED, clone->GetTargetColor());
|
| + EXPECT_TRUE(clone->layer_inverted());
|
| +
|
| + constexpr SkColor kTransparent = SK_ColorTRANSPARENT;
|
| + layer->SetColor(kTransparent);
|
| + layer->SetFillsBoundsOpaquely(false);
|
| + // Color and opaqueness targets should be preserved during cloning, even after
|
| + // switching away from solid color content.
|
| + layer->SwitchCCLayerForTest();
|
| +
|
| + clone = layer->Clone();
|
| +
|
| + // The clone is a copy of the latest state.
|
| + EXPECT_TRUE(clone->GetTargetTransform().IsIdentity());
|
| + EXPECT_EQ(kTransparent, clone->background_color());
|
| + EXPECT_EQ(kTransparent, clone->GetTargetColor());
|
| + EXPECT_FALSE(clone->layer_inverted());
|
| + EXPECT_FALSE(clone->fills_bounds_opaquely());
|
| +
|
| + layer.reset(CreateLayer(LAYER_SOLID_COLOR));
|
| + layer->SetVisible(true);
|
| + layer->SetOpacity(1.0f);
|
| + layer->SetColor(SK_ColorRED);
|
| +
|
| + ScopedLayerAnimationSettings settings(layer->GetAnimator());
|
| + layer->SetVisible(false);
|
| + layer->SetOpacity(0.0f);
|
| + layer->SetColor(SK_ColorGREEN);
|
| +
|
| + EXPECT_TRUE(layer->visible());
|
| + EXPECT_EQ(1.0f, layer->opacity());
|
| + EXPECT_EQ(SK_ColorRED, layer->background_color());
|
| +
|
| + clone = layer->Clone();
|
| +
|
| + // Cloning copies animation targets.
|
| + EXPECT_FALSE(clone->visible());
|
| + EXPECT_EQ(0.0f, clone->opacity());
|
| + EXPECT_EQ(SK_ColorGREEN, clone->background_color());
|
| +}
|
| +
|
| +TEST_F(LayerWithDelegateTest, Mirroring) {
|
| + std::unique_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 100, 100)));
|
| + std::unique_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
|
| +
|
| + const gfx::Rect bounds(0, 0, 50, 50);
|
| + child->SetBounds(bounds);
|
| + child->SetVisible(true);
|
| +
|
| + DrawTreeLayerDelegate delegate(child->bounds());
|
| + child->set_delegate(&delegate);
|
| +
|
| + const auto mirror = child->Mirror();
|
| +
|
| + // Bounds and visibility are preserved.
|
| + EXPECT_EQ(bounds, mirror->bounds());
|
| + EXPECT_TRUE(mirror->visible());
|
| +
|
| + root->Add(child.get());
|
| + root->Add(mirror.get());
|
| +
|
| + DrawTree(root.get());
|
| + EXPECT_TRUE(delegate.painted());
|
| + delegate.Reset();
|
| +
|
| + // Both layers should be clean.
|
| + EXPECT_TRUE(child->damaged_region_for_testing().IsEmpty());
|
| + EXPECT_TRUE(mirror->damaged_region_for_testing().IsEmpty());
|
| +
|
| + const gfx::Rect damaged_rect(10, 10, 20, 20);
|
| + EXPECT_TRUE(child->SchedulePaint(damaged_rect));
|
| + EXPECT_EQ(damaged_rect, child->damaged_region_for_testing().bounds());
|
| +
|
| + DrawTree(root.get());
|
| + EXPECT_TRUE(delegate.painted());
|
| + delegate.Reset();
|
| +
|
| + // Damage should be propagated to the mirror.
|
| + EXPECT_EQ(damaged_rect, mirror->damaged_region_for_testing().bounds());
|
| + EXPECT_TRUE(child->damaged_region_for_testing().IsEmpty());
|
| +
|
| + DrawTree(root.get());
|
| + EXPECT_TRUE(delegate.painted());
|
| +
|
| + // Mirror should be clean.
|
| + EXPECT_TRUE(mirror->damaged_region_for_testing().IsEmpty());
|
| +
|
| + // Bounds are not synchronized by default.
|
| + const gfx::Rect new_bounds(10, 10, 10, 10);
|
| + child->SetBounds(new_bounds);
|
| + EXPECT_EQ(bounds, mirror->bounds());
|
| + child->SetBounds(bounds);
|
| +
|
| + // Bounds should be synchronized if requested.
|
| + child->set_sync_bounds(true);
|
| + child->SetBounds(new_bounds);
|
| + EXPECT_EQ(new_bounds, mirror->bounds());
|
| +}
|
| +
|
| class LayerWithNullDelegateTest : public LayerWithDelegateTest {
|
| public:
|
| LayerWithNullDelegateTest() {}
|
| @@ -1721,6 +1846,41 @@ TEST_F(LayerWithDelegateTest, ExternalContent) {
|
| EXPECT_NE(before.get(), child->cc_layer_for_testing());
|
| }
|
|
|
| +TEST_F(LayerWithDelegateTest, ExternalContentMirroring) {
|
| + std::unique_ptr<Layer> layer(CreateLayer(LAYER_SOLID_COLOR));
|
| +
|
| + const auto satisfy_callback = base::Bind(&FakeSatisfyCallback);
|
| + const auto require_callback = base::Bind(&FakeRequireCallback);
|
| +
|
| + cc::SurfaceId surface_id(cc::FrameSinkId(0, 1), cc::LocalFrameId(2, 3));
|
| + layer->SetShowSurface(surface_id, satisfy_callback, require_callback,
|
| + gfx::Size(10, 10), 1.0f, gfx::Size(10, 10));
|
| +
|
| + const auto mirror = layer->Mirror();
|
| + auto* const cc_layer = mirror->cc_layer_for_testing();
|
| + const auto* surface = static_cast<cc::SurfaceLayer*>(cc_layer);
|
| +
|
| + // Mirroring preserves surface state.
|
| + EXPECT_EQ(surface_id, surface->surface_id());
|
| + EXPECT_TRUE(satisfy_callback.Equals(surface->satisfy_callback()));
|
| + EXPECT_TRUE(require_callback.Equals(surface->require_callback()));
|
| + EXPECT_EQ(gfx::Size(10, 10), surface->surface_size());
|
| + EXPECT_EQ(1.0f, surface->surface_scale());
|
| +
|
| + surface_id = cc::SurfaceId(cc::FrameSinkId(1, 2), cc::LocalFrameId(3, 4));
|
| + layer->SetShowSurface(surface_id, satisfy_callback, require_callback,
|
| + gfx::Size(20, 20), 2.0f, gfx::Size(20, 20));
|
| +
|
| + // A new cc::Layer should be created for the mirror.
|
| + EXPECT_NE(cc_layer, mirror->cc_layer_for_testing());
|
| + surface = static_cast<cc::SurfaceLayer*>(mirror->cc_layer_for_testing());
|
| +
|
| + // Surface updates propagate to the mirror.
|
| + EXPECT_EQ(surface_id, surface->surface_id());
|
| + EXPECT_EQ(gfx::Size(20, 20), surface->surface_size());
|
| + EXPECT_EQ(2.0f, surface->surface_scale());
|
| +}
|
| +
|
| // Verifies that layer filters still attached after changing implementation
|
| // layer.
|
| TEST_F(LayerWithDelegateTest, LayerFiltersSurvival) {
|
|
|