blob: 097131b54ea482b0adaabc9123251c6b21d892ae [file] [log] [blame]
// 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 <memory>
#include <utility>
#include <vector>
#include "base/memory/ref_counted.h"
#include "base/unguessable_token.h"
#include "cc/layers/deadline_policy.h"
#include "cc/resources/ui_resource_manager.h"
#include "cc/slim/filter.h"
#include "cc/slim/layer.h"
#include "cc/slim/layer_tree.h"
#include "cc/slim/nine_patch_layer.h"
#include "cc/slim/solid_color_layer.h"
#include "cc/slim/surface_layer.h"
#include "cc/slim/test_layer_tree_client.h"
#include "cc/slim/ui_resource_layer.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/transform.h"
namespace cc::slim {
TEST(SlimLayerTest, LayerTreeManipulation) {
scoped_refptr<Layer> layer1 = Layer::Create();
scoped_refptr<Layer> layer2 = Layer::Create();
scoped_refptr<Layer> layer3 = Layer::Create();
scoped_refptr<Layer> layer4 = Layer::Create();
scoped_refptr<Layer> layer5 = Layer::Create();
EXPECT_FALSE(layer1->parent());
EXPECT_EQ(layer1->RootLayer(), layer1.get());
EXPECT_TRUE(layer1->children().empty());
layer1->AddChild(layer2);
EXPECT_EQ(layer2->parent(), layer1.get());
EXPECT_EQ(layer1->RootLayer(), layer1.get());
EXPECT_EQ(layer2->RootLayer(), layer1.get());
EXPECT_EQ(layer1->children().size(), 1u);
EXPECT_EQ(layer1->children()[0].get(), layer2.get());
EXPECT_TRUE(layer2->HasAncestor(layer1.get()));
EXPECT_FALSE(layer1->HasAncestor(layer2.get()));
layer1->InsertChild(layer3, /*position=*/0u);
EXPECT_EQ(layer3->parent(), layer1.get());
EXPECT_EQ(layer3->RootLayer(), layer1.get());
EXPECT_EQ(layer1->children().size(), 2u);
EXPECT_EQ(layer1->children()[0].get(), layer3.get());
EXPECT_TRUE(layer3->HasAncestor(layer1.get()));
EXPECT_FALSE(layer1->HasAncestor(layer3.get()));
layer1->ReplaceChild(layer2.get(), layer4);
EXPECT_EQ(layer2->parent(), nullptr);
EXPECT_TRUE(layer2->HasOneRef());
EXPECT_EQ(layer4->parent(), layer1.get());
EXPECT_EQ(layer4->RootLayer(), layer1.get());
EXPECT_EQ(layer1->children().size(), 2u);
EXPECT_EQ(layer1->children()[1].get(), layer4.get());
EXPECT_TRUE(layer4->HasAncestor(layer1.get()));
layer4->AddChild(layer5);
EXPECT_EQ(layer5->parent(), layer4.get());
EXPECT_EQ(layer5->RootLayer(), layer1.get());
EXPECT_TRUE(layer5->HasAncestor(layer1.get()));
EXPECT_EQ(layer4->children().size(), 1u);
EXPECT_EQ(layer4->children()[0].get(), layer5.get());
layer5->RemoveFromParent();
EXPECT_TRUE(layer5->HasOneRef());
EXPECT_TRUE(layer4->children().empty());
layer1->RemoveAllChildren();
EXPECT_TRUE(layer1->children().empty());
EXPECT_TRUE(layer1->HasOneRef());
EXPECT_TRUE(layer2->HasOneRef());
EXPECT_TRUE(layer3->HasOneRef());
EXPECT_TRUE(layer4->HasOneRef());
}
TEST(SlimLayerTest, LayerProperties) {
scoped_refptr<Layer> layer = Layer::Create();
layer->SetPosition(gfx::PointF(1.f, 2.f));
EXPECT_EQ(layer->position(), gfx::PointF(1.f, 2.f));
layer->SetBounds(gfx::Size(1, 2));
EXPECT_EQ(layer->bounds(), gfx::Size(1, 2));
layer->SetTransform(gfx::Transform::MakeTranslation(1.f, 2.f));
EXPECT_EQ(layer->transform(), gfx::Transform::MakeTranslation(1.f, 2.f));
layer->SetTransformOrigin(gfx::Point3F(1.f, 2.f, 3.f));
EXPECT_EQ(layer->transform_origin(), gfx::Point3F(1.f, 2.f, 3.f));
layer->SetIsDrawable(true);
EXPECT_TRUE(layer->draws_content());
layer->SetIsDrawable(false);
EXPECT_FALSE(layer->draws_content());
layer->SetBackgroundColor(SkColors::kGray);
EXPECT_EQ(layer->background_color(), SkColors::kGray);
layer->SetContentsOpaque(true);
EXPECT_TRUE(layer->contents_opaque());
layer->SetContentsOpaque(false);
EXPECT_FALSE(layer->contents_opaque());
layer->SetOpacity(0.5f);
EXPECT_EQ(layer->opacity(), 0.5f);
layer->SetHideLayerAndSubtree(true);
EXPECT_TRUE(layer->hide_layer_and_subtree());
layer->SetHideLayerAndSubtree(false);
EXPECT_FALSE(layer->hide_layer_and_subtree());
layer->SetMasksToBounds(true);
EXPECT_TRUE(layer->masks_to_bounds());
layer->SetMasksToBounds(false);
EXPECT_FALSE(layer->masks_to_bounds());
std::vector<Filter> filters;
filters.push_back(Filter::CreateBrightness(0.5f));
layer->SetFilters(std::move(filters));
EXPECT_FALSE(layer->HasNonTrivialMaskFilterInfo());
layer->SetRoundedCorner(gfx::RoundedCornersF(50));
EXPECT_EQ(layer->corner_radii(), gfx::RoundedCornersF(50));
EXPECT_TRUE(layer->HasNonTrivialMaskFilterInfo());
layer->SetRoundedCorner(gfx::RoundedCornersF());
EXPECT_FALSE(layer->HasNonTrivialMaskFilterInfo());
gfx::LinearGradient gradient;
gradient.AddStep(0.0f, 0);
gradient.AddStep(1.0f, 255);
EXPECT_FALSE(layer->HasNonTrivialMaskFilterInfo());
layer->SetGradientMask(gradient);
EXPECT_EQ(layer->gradient_mask(), gradient);
EXPECT_TRUE(layer->HasNonTrivialMaskFilterInfo());
layer->SetGradientMask(gfx::LinearGradient());
EXPECT_FALSE(layer->HasNonTrivialMaskFilterInfo());
}
TEST(SlimLayerTest, SurfaceLayerProperties) {
scoped_refptr<SurfaceLayer> layer = SurfaceLayer::Create();
layer->SetStretchContentToFillBounds(true);
EXPECT_TRUE(layer->stretch_content_to_fill_bounds());
layer->SetStretchContentToFillBounds(false);
EXPECT_FALSE(layer->stretch_content_to_fill_bounds());
base::UnguessableToken token = base::UnguessableToken::Create();
viz::SurfaceId start(viz::FrameSinkId(1u, 2u),
viz::LocalSurfaceId(3u, 4u, token));
viz::SurfaceId end(viz::FrameSinkId(1u, 2u),
viz::LocalSurfaceId(5u, 6u, token));
EXPECT_EQ(layer->oldest_acceptable_fallback(), std::nullopt);
layer->SetOldestAcceptableFallback(start);
EXPECT_EQ(layer->oldest_acceptable_fallback(), start);
layer->SetSurfaceId(end, cc::DeadlinePolicy::UseDefaultDeadline());
EXPECT_EQ(layer->surface_id(), end);
}
TEST(SlimLayerTest, UIResourceLayerProperties) {
scoped_refptr<UIResourceLayer> layer = UIResourceLayer::Create();
layer->SetUIResourceId(1);
layer->SetUIResourceId(0);
auto image_info =
SkImageInfo::Make(1, 1, kN32_SkColorType, kPremul_SkAlphaType);
SkBitmap bitmap;
bitmap.allocPixels(image_info);
bitmap.setImmutable();
layer->SetBitmap(bitmap);
layer->SetUV(gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f));
layer->SetVertexOpacity(0.1f, 0.2f, 0.3f, 0.4f);
TestLayerTreeClient client;
auto layer_tree = LayerTree::Create(&client);
layer_tree->SetRoot(layer);
EXPECT_NE(layer->resource_id(), 0);
EXPECT_EQ(layer_tree->GetUIResourceManager()
->owned_shared_resources_size_for_test(),
1u);
}
TEST(SlimLayerTest, NinePatchLayerProperties) {
scoped_refptr<NinePatchLayer> layer = NinePatchLayer::Create();
auto image_info =
SkImageInfo::Make(10, 10, kN32_SkColorType, kPremul_SkAlphaType);
SkBitmap bitmap;
bitmap.allocPixels(image_info);
bitmap.setImmutable();
layer->SetBitmap(bitmap);
layer->SetBorder(gfx::Rect(1, 1, 8, 8));
layer->SetAperture(gfx::Rect(4, 4, 2, 2));
layer->SetFillCenter(true);
layer->SetNearestNeighbor(true);
TestLayerTreeClient client;
auto layer_tree = LayerTree::Create(&client);
layer_tree->SetRoot(layer);
EXPECT_EQ(layer_tree->GetUIResourceManager()
->owned_shared_resources_size_for_test(),
1u);
}
TEST(SlimLayerTest, NumDescendantsThatDrawContent) {
auto layer0 = Layer::Create();
auto layer1 = Layer::Create();
auto layer2 = Layer::Create();
layer0->AddChild(layer1);
layer0->AddChild(layer2);
EXPECT_EQ(layer0->NumDescendantsThatDrawContent(), 0);
EXPECT_EQ(layer1->NumDescendantsThatDrawContent(), 0);
EXPECT_EQ(layer2->NumDescendantsThatDrawContent(), 0);
auto drawing_layer0 = SolidColorLayer::Create();
auto drawing_layer1 = SolidColorLayer::Create();
auto drawing_layer2 = SolidColorLayer::Create();
drawing_layer0->SetIsDrawable(true);
drawing_layer1->SetIsDrawable(true);
drawing_layer2->SetIsDrawable(true);
EXPECT_TRUE(drawing_layer0->draws_content());
EXPECT_TRUE(drawing_layer1->draws_content());
EXPECT_TRUE(drawing_layer2->draws_content());
layer1->AddChild(drawing_layer0);
EXPECT_EQ(layer0->NumDescendantsThatDrawContent(), 1);
EXPECT_EQ(layer1->NumDescendantsThatDrawContent(), 1);
EXPECT_EQ(layer2->NumDescendantsThatDrawContent(), 0);
drawing_layer0->AddChild(drawing_layer1);
EXPECT_EQ(layer0->NumDescendantsThatDrawContent(), 2);
EXPECT_EQ(layer1->NumDescendantsThatDrawContent(), 2);
EXPECT_EQ(layer2->NumDescendantsThatDrawContent(), 0);
EXPECT_EQ(drawing_layer0->NumDescendantsThatDrawContent(), 1);
layer1->AddChild(drawing_layer2);
EXPECT_EQ(layer0->NumDescendantsThatDrawContent(), 3);
EXPECT_EQ(layer1->NumDescendantsThatDrawContent(), 3);
EXPECT_EQ(layer2->NumDescendantsThatDrawContent(), 0);
drawing_layer0->RemoveFromParent();
EXPECT_EQ(layer0->NumDescendantsThatDrawContent(), 1);
EXPECT_EQ(layer1->NumDescendantsThatDrawContent(), 1);
EXPECT_EQ(layer2->NumDescendantsThatDrawContent(), 0);
layer2->AddChild(drawing_layer0);
EXPECT_EQ(layer0->NumDescendantsThatDrawContent(), 3);
EXPECT_EQ(layer1->NumDescendantsThatDrawContent(), 1);
EXPECT_EQ(layer2->NumDescendantsThatDrawContent(), 2);
}
} // namespace cc::slim