#include "cc/tiles/picture_layer_tiling_set.h"
#include <map>
#include <vector>
#include "build/build_config.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_picture_layer_tiling_client.h"
#include "cc/test/fake_raster_source.h"
#include "cc/tiles/prioritized_tile.h"
#include "cc/trees/layer_tree_settings.h"
#include "components/viz/client/client_resource_provider.h"
#include "components/viz/test/fake_output_surface.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/size_conversions.h"
namespace cc {
namespace {
class TestablePictureLayerTilingSet : public PictureLayerTilingSet {
public:
TestablePictureLayerTilingSet(
WhichTree tree,
PictureLayerTilingClient* client,
int tiling_interest_area_padding,
float skewport_target_time_in_seconds,
int skewport_extrapolation_limit_in_screen_pixels,
float max_preraster_distance)
: PictureLayerTilingSet(tree,
client,
tiling_interest_area_padding,
skewport_target_time_in_seconds,
skewport_extrapolation_limit_in_screen_pixels,
max_preraster_distance) {}
using PictureLayerTilingSet::ComputeSkewport;
using PictureLayerTilingSet::ComputeSoonBorderRect;
using PictureLayerTilingSet::TilingsNeedUpdate;
};
std::unique_ptr<TestablePictureLayerTilingSet> CreateTilingSetWithSettings(
PictureLayerTilingClient* client,
const LayerTreeSettings& settings) {
return std::make_unique<TestablePictureLayerTilingSet>(
ACTIVE_TREE, client, settings.tiling_interest_area_padding,
settings.skewport_target_time_in_seconds,
settings.skewport_extrapolation_limit_in_screen_pixels,
settings.max_preraster_distance_in_screen_pixels);
}
std::unique_ptr<TestablePictureLayerTilingSet> CreateTilingSet(
PictureLayerTilingClient* client) {
return CreateTilingSetWithSettings(client, LayerTreeSettings());
}
TEST(PictureLayerTilingSetTest, TilingRange) {
FakePictureLayerTilingClient client;
gfx::Size layer_bounds(10, 10);
PictureLayerTilingSet::TilingRange higher_than_high_res_range(0, 0);
PictureLayerTilingSet::TilingRange high_res_range(0, 0);
PictureLayerTilingSet::TilingRange lower_than_high_res_range(0, 0);
PictureLayerTiling* high_res_tiling;
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
std::unique_ptr<TestablePictureLayerTilingSet> set_with_all_res =
CreateTilingSet(&client);
set_with_all_res->AddTiling(gfx::AxisTransform2d(2.0, gfx::Vector2dF()),
raster_source);
high_res_tiling =
set_with_all_res->AddTiling(gfx::AxisTransform2d(), raster_source);
high_res_tiling->set_resolution(HIGH_RESOLUTION);
set_with_all_res->AddTiling(gfx::AxisTransform2d(0.5, gfx::Vector2dF()),
raster_source);
set_with_all_res->AddTiling(gfx::AxisTransform2d(0.25, gfx::Vector2dF()),
raster_source);
higher_than_high_res_range = set_with_all_res->GetTilingRange(
PictureLayerTilingSet::HIGHER_THAN_HIGH_RES);
EXPECT_EQ(0u, higher_than_high_res_range.start);
EXPECT_EQ(1u, higher_than_high_res_range.end);
high_res_range =
set_with_all_res->GetTilingRange(PictureLayerTilingSet::HIGH_RES);
EXPECT_EQ(1u, high_res_range.start);
EXPECT_EQ(2u, high_res_range.end);
lower_than_high_res_range = set_with_all_res->GetTilingRange(
PictureLayerTilingSet::LOWER_THAN_HIGH_RES);
EXPECT_EQ(2u, lower_than_high_res_range.start);
EXPECT_EQ(4u, lower_than_high_res_range.end);
std::unique_ptr<TestablePictureLayerTilingSet> set_with_only_high_res =
CreateTilingSet(&client);
high_res_tiling =
set_with_only_high_res->AddTiling(gfx::AxisTransform2d(), raster_source);
high_res_tiling->set_resolution(HIGH_RESOLUTION);
higher_than_high_res_range = set_with_only_high_res->GetTilingRange(
PictureLayerTilingSet::HIGHER_THAN_HIGH_RES);
EXPECT_EQ(0u,
higher_than_high_res_range.end - higher_than_high_res_range.start);
high_res_range =
set_with_only_high_res->GetTilingRange(PictureLayerTilingSet::HIGH_RES);
EXPECT_EQ(0u, high_res_range.start);
EXPECT_EQ(1u, high_res_range.end);
lower_than_high_res_range = set_with_only_high_res->GetTilingRange(
PictureLayerTilingSet::LOWER_THAN_HIGH_RES);
EXPECT_EQ(0u,
lower_than_high_res_range.end - lower_than_high_res_range.start);
}
class PictureLayerTilingSetTestWithResources : public testing::Test {
public:
void RunTest(int num_tilings,
float min_scale,
float scale_increment,
float ideal_contents_scale,
float expected_scale) {
scoped_refptr<viz::TestContextProvider> context_provider =
viz::TestContextProvider::CreateRaster();
ASSERT_EQ(context_provider->BindToCurrentSequence(),
gpu::ContextResult::kSuccess);
std::unique_ptr<viz::ClientResourceProvider> resource_provider =
std::make_unique<viz::ClientResourceProvider>();
FakePictureLayerTilingClient client(resource_provider.get(),
context_provider.get());
client.SetTileSize(gfx::Size(256, 256));
gfx::Size layer_bounds(1000, 800);
std::unique_ptr<TestablePictureLayerTilingSet> set =
CreateTilingSet(&client);
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
float scale = min_scale;
for (int i = 0; i < num_tilings; ++i, scale += scale_increment) {
PictureLayerTiling* tiling = set->AddTiling(
gfx::AxisTransform2d(scale, gfx::Vector2dF()), raster_source);
tiling->set_resolution(HIGH_RESOLUTION);
tiling->CreateAllTilesForTesting();
std::vector<Tile*> tiles = tiling->AllTilesForTesting();
client.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
}
float max_contents_scale = scale;
gfx::Size content_bounds(
gfx::ScaleToCeiledSize(layer_bounds, max_contents_scale));
gfx::Rect content_rect(content_bounds);
Region remaining(content_rect);
for (auto iter =
set->Cover(content_rect, max_contents_scale, ideal_contents_scale);
iter; ++iter) {
gfx::Rect geometry_rect = iter.geometry_rect();
EXPECT_TRUE(content_rect.Contains(geometry_rect));
ASSERT_TRUE(remaining.Contains(geometry_rect));
remaining.Subtract(geometry_rect);
EXPECT_EQ(expected_scale, iter.CurrentTiling()->contents_scale_key());
if (num_tilings)
EXPECT_TRUE(*iter);
else
EXPECT_FALSE(*iter);
}
EXPECT_TRUE(remaining.IsEmpty());
}
};
TEST_F(PictureLayerTilingSetTestWithResources, NoTilings) {
RunTest(0, 0.f, 0.f, 2.f, 0.f);
}
TEST_F(PictureLayerTilingSetTestWithResources, OneTiling_Smaller) {
RunTest(1, 1.f, 0.f, 2.f, 1.f);
}
TEST_F(PictureLayerTilingSetTestWithResources, OneTiling_Larger) {
RunTest(1, 3.f, 0.f, 2.f, 3.f);
}
TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_Smaller) {
RunTest(2, 1.f, 1.f, 3.f, 2.f);
}
TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_SmallerEqual) {
RunTest(2, 1.f, 1.f, 2.f, 2.f);
}
TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_LargerEqual) {
RunTest(2, 1.f, 1.f, 1.f, 1.f);
}
TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_Larger) {
RunTest(2, 2.f, 8.f, 1.f, 2.f);
}
#if BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER)
#define MAYBE_ManyTilings_Equal DISABLED_ManyTilings_Equal
#else
#define MAYBE_ManyTilings_Equal ManyTilings_Equal
#endif
TEST_F(PictureLayerTilingSetTestWithResources, MAYBE_ManyTilings_Equal) {
RunTest(10, 1.f, 1.f, 5.f, 5.f);
}
#if BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER)
#define MAYBE_ManyTilings_NotEqual DISABLED_ManyTilings_NotEqual
#else
#define MAYBE_ManyTilings_NotEqual ManyTilings_NotEqual
#endif
TEST_F(PictureLayerTilingSetTestWithResources, MAYBE_ManyTilings_NotEqual) {
RunTest(10, 1.f, 1.f, 4.5f, 5.f);
}
TEST(PictureLayerTilingSetTest, TileSizeChange) {
FakePictureLayerTilingClient pending_client;
FakePictureLayerTilingClient active_client;
std::unique_ptr<PictureLayerTilingSet> pending_set =
PictureLayerTilingSet::Create(PENDING_TREE, &pending_client, 1000, 1.f,
1000, 1000.f);
std::unique_ptr<PictureLayerTilingSet> active_set =
PictureLayerTilingSet::Create(ACTIVE_TREE, &active_client, 1000, 1.f,
1000, 1000.f);
gfx::Size layer_bounds(100, 100);
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
gfx::Size tile_size1(10, 10);
gfx::Size tile_size2(30, 30);
gfx::Size tile_size3(20, 20);
pending_client.SetTileSize(tile_size1);
pending_set->AddTiling(gfx::AxisTransform2d(), raster_source);
EXPECT_EQ(tile_size1, pending_set->tiling_at(0)->tile_size());
pending_set->tiling_at(0)->set_resolution(HIGH_RESOLUTION);
active_client.set_twin_tiling_set(pending_set.get());
pending_set->UpdateTilePriorities(gfx::Rect(layer_bounds), 1.f, 1.0,
Occlusion(), false);
EXPECT_EQ(tile_size1, pending_set->tiling_at(0)->tile_size());
std::vector<Tile*> pending_tiles =
pending_set->tiling_at(0)->AllTilesForTesting();
EXPECT_GT(pending_tiles.size(), 0u);
for (auto* tile : pending_tiles) {
EXPECT_EQ(tile_size1, tile->content_rect().size());
}
pending_set->RemoveAllTilings();
pending_set->AddTiling(gfx::AxisTransform2d(), raster_source);
pending_set->tiling_at(0)->set_resolution(HIGH_RESOLUTION);
pending_client.SetTileSize(tile_size2);
pending_set->UpdateTilingsToCurrentRasterSourceForCommit(raster_source.get(),
Region(), 1.f, 1.f);
EXPECT_EQ(tile_size2, pending_set->tiling_at(0)->tile_size());
pending_set->UpdateTilePriorities(gfx::Rect(layer_bounds), 1.f, 2.0,
Occlusion(), false);
EXPECT_EQ(tile_size2, pending_set->tiling_at(0)->tile_size());
pending_tiles = pending_set->tiling_at(0)->AllTilesForTesting();
EXPECT_GT(pending_tiles.size(), 0u);
for (auto* tile : pending_tiles) {
EXPECT_EQ(tile_size2, tile->content_rect().size());
}
active_client.SetTileSize(tile_size2);
active_set->UpdateTilingsToCurrentRasterSourceForActivation(
raster_source.get(), pending_set.get(), Region(), 1.f, 1.f);
EXPECT_EQ(tile_size2, active_set->tiling_at(0)->tile_size());
std::vector<Tile*> active_tiles =
active_set->tiling_at(0)->AllTilesForTesting();
EXPECT_GT(active_tiles.size(), 0u);
for (auto* tile : active_tiles) {
EXPECT_EQ(tile_size2, tile->content_rect().size());
}
pending_client.SetTileSize(tile_size3);
pending_set->UpdateTilingsToCurrentRasterSourceForCommit(raster_source.get(),
Region(), 1.f, 1.f);
EXPECT_EQ(tile_size3, pending_set->tiling_at(0)->tile_size());
pending_set->UpdateTilePriorities(gfx::Rect(layer_bounds), 1.f, 3.0,
Occlusion(), false);
EXPECT_EQ(tile_size3, pending_set->tiling_at(0)->tile_size());
pending_tiles = pending_set->tiling_at(0)->AllTilesForTesting();
EXPECT_GT(pending_tiles.size(), 0u);
for (auto* tile : pending_tiles) {
EXPECT_EQ(tile_size3, tile->content_rect().size());
}
active_client.SetTileSize(tile_size3);
active_set->UpdateTilingsToCurrentRasterSourceForActivation(
raster_source.get(), pending_set.get(), Region(), 1.f, 1.f);
EXPECT_EQ(tile_size3, active_set->tiling_at(0)->tile_size());
active_tiles = active_set->tiling_at(0)->AllTilesForTesting();
EXPECT_GT(active_tiles.size(), 0u);
for (auto* tile : active_tiles) {
EXPECT_EQ(tile_size3, tile->content_rect().size());
}
active_client.set_twin_tiling_set(nullptr);
}
TEST(PictureLayerTilingSetTest, ModifyPendingTilingSetTwiceInOneVsync) {
FakePictureLayerTilingClient pending_client;
FakePictureLayerTilingClient active_client;
std::unique_ptr<PictureLayerTilingSet> pending_set =
PictureLayerTilingSet::Create(PENDING_TREE, &pending_client, 1000, 1.f,
1000, 1000.f);
std::unique_ptr<PictureLayerTilingSet> active_set =
PictureLayerTilingSet::Create(ACTIVE_TREE, &active_client, 1000, 1.f,
1000, 1000.f);
gfx::Size layer_bounds(100, 100);
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
gfx::Size tile_size1(10, 10);
gfx::Size tile_size2(30, 30);
pending_client.SetTileSize(tile_size1);
pending_set->AddTiling(gfx::AxisTransform2d(), raster_source);
EXPECT_EQ(tile_size1, pending_set->tiling_at(0)->tile_size());
pending_set->tiling_at(0)->set_resolution(HIGH_RESOLUTION);
active_client.set_twin_tiling_set(pending_set.get());
pending_set->UpdateTilePriorities(gfx::Rect(layer_bounds), 1.f, 1.0,
Occlusion(), false);
EXPECT_EQ(tile_size1, pending_set->tiling_at(0)->tile_size());
EXPECT_TRUE(pending_set->tiling_at(0)->has_tiles());
active_client.SetTileSize(tile_size1);
active_set->UpdateTilingsToCurrentRasterSourceForActivation(
raster_source.get(), pending_set.get(), Region(), 1.f, 1.f);
EXPECT_EQ(tile_size1, active_set->tiling_at(0)->tile_size());
EXPECT_TRUE(active_set->tiling_at(0)->has_tiles());
pending_client.SetTileSize(tile_size2);
pending_set->UpdateTilingsToCurrentRasterSourceForCommit(raster_source.get(),
Region(), 1.f, 1.f);
EXPECT_EQ(tile_size2, pending_set->tiling_at(0)->tile_size());
pending_set->UpdateTilePriorities(gfx::Rect(layer_bounds), 1.f, 1.0,
Occlusion(), false);
EXPECT_EQ(tile_size2, pending_set->tiling_at(0)->tile_size());
EXPECT_TRUE(pending_set->tiling_at(0)->has_tiles());
active_client.set_twin_tiling_set(nullptr);
}
TEST(PictureLayerTilingSetTest, MaxContentScale) {
FakePictureLayerTilingClient pending_client;
FakePictureLayerTilingClient active_client;
std::unique_ptr<PictureLayerTilingSet> pending_set =
PictureLayerTilingSet::Create(PENDING_TREE, &pending_client, 1000, 1.f,
1000, 1000.f);
std::unique_ptr<PictureLayerTilingSet> active_set =
PictureLayerTilingSet::Create(ACTIVE_TREE, &active_client, 1000, 1.f,
1000, 1000.f);
gfx::Size layer_bounds(100, 105);
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
pending_set->AddTiling(gfx::AxisTransform2d(), raster_source);
pending_set->AddTiling(gfx::AxisTransform2d(2.f, gfx::Vector2dF()),
raster_source);
pending_set->AddTiling(gfx::AxisTransform2d(3.f, gfx::Vector2dF()),
raster_source);
pending_set->tiling_at(0)->set_resolution(HIGH_RESOLUTION);
active_client.set_twin_tiling_set(pending_set.get());
float max_content_scale = 3.f;
pending_set->UpdateTilingsToCurrentRasterSourceForCommit(
raster_source.get(), Region(), 1.f, max_content_scale);
EXPECT_EQ(3u, pending_set->num_tilings());
active_set->UpdateTilingsToCurrentRasterSourceForActivation(
raster_source.get(), pending_set.get(), Region(), 1.f, max_content_scale);
EXPECT_EQ(3u, active_set->num_tilings());
max_content_scale = 2.9f;
pending_set->UpdateTilingsToCurrentRasterSourceForCommit(
raster_source.get(), Region(), 1.f, max_content_scale);
EXPECT_EQ(2u, pending_set->num_tilings());
pending_set->tiling_at(0)->set_resolution(HIGH_RESOLUTION);
active_set->UpdateTilingsToCurrentRasterSourceForActivation(
raster_source.get(), pending_set.get(), Region(), 1.f, max_content_scale);
EXPECT_EQ(2u, active_set->num_tilings());
active_client.set_twin_tiling_set(nullptr);
}
TEST(PictureLayerTilingSetTest, SkewportLimits) {
FakePictureLayerTilingClient client;
gfx::Rect viewport(0, 0, 100, 100);
gfx::Size layer_bounds(200, 200);
client.SetTileSize(gfx::Size(100, 100));
LayerTreeSettings settings;
settings.skewport_extrapolation_limit_in_screen_pixels = 75;
settings.tiling_interest_area_padding = 1000000;
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
std::unique_ptr<TestablePictureLayerTilingSet> tiling_set =
CreateTilingSetWithSettings(&client, settings);
EXPECT_FALSE(tiling_set->TilingsNeedUpdate(viewport, 1.0));
tiling_set->AddTiling(gfx::AxisTransform2d(), raster_source);
EXPECT_TRUE(tiling_set->TilingsNeedUpdate(viewport, 1.0));
tiling_set->UpdateTilePriorities(viewport, 1.f, 1.0, Occlusion(), true);
gfx::Rect down_skewport =
tiling_set->ComputeSkewport(gfx::Rect(0, 50, 100, 100), 1.5, 1.f);
EXPECT_EQ(0, down_skewport.x());
EXPECT_EQ(50, down_skewport.y());
EXPECT_EQ(100, down_skewport.width());
EXPECT_EQ(175, down_skewport.height());
EXPECT_TRUE(down_skewport.Contains(gfx::Rect(0, 50, 100, 100)));
gfx::Rect down_right_skewport =
tiling_set->ComputeSkewport(gfx::Rect(10, 50, 100, 100), 1.5, 1.f);
EXPECT_EQ(10, down_right_skewport.x());
EXPECT_EQ(50, down_right_skewport.y());
EXPECT_EQ(120, down_right_skewport.width());
EXPECT_EQ(175, down_right_skewport.height());
EXPECT_TRUE(down_right_skewport.Contains(gfx::Rect(10, 50, 100, 100)));
gfx::Rect left_skewport =
tiling_set->ComputeSkewport(gfx::Rect(-50, 0, 100, 100), 1.5, 1.f);
EXPECT_EQ(-125, left_skewport.x());
EXPECT_EQ(0, left_skewport.y());
EXPECT_EQ(175, left_skewport.width());
EXPECT_EQ(100, left_skewport.height());
EXPECT_TRUE(left_skewport.Contains(gfx::Rect(-50, 0, 100, 100)));
gfx::Rect expand_skewport =
tiling_set->ComputeSkewport(gfx::Rect(-50, -50, 200, 200), 1.5, 1.f);
EXPECT_EQ(-125, expand_skewport.x());
EXPECT_EQ(-125, expand_skewport.y());
EXPECT_EQ(350, expand_skewport.width());
EXPECT_EQ(350, expand_skewport.height());
EXPECT_TRUE(expand_skewport.Contains(gfx::Rect(-50, -50, 200, 200)));
gfx::Rect big_expand_skewport =
tiling_set->ComputeSkewport(gfx::Rect(-500, -500, 1500, 1500), 1.5, 1.f);
EXPECT_EQ(-575, big_expand_skewport.x());
EXPECT_EQ(-575, big_expand_skewport.y());
EXPECT_EQ(1650, big_expand_skewport.width());
EXPECT_EQ(1650, big_expand_skewport.height());
EXPECT_TRUE(big_expand_skewport.Contains(gfx::Rect(-500, -500, 1500, 1500)));
gfx::Rect shrink_viewport =
tiling_set->ComputeSkewport(gfx::Rect(0, 0, 100, 100), 1.5, 1.f);
EXPECT_EQ(0, shrink_viewport.x());
EXPECT_EQ(0, shrink_viewport.y());
EXPECT_EQ(100, shrink_viewport.width());
EXPECT_EQ(100, shrink_viewport.height());
gfx::Rect move_skewport_far =
tiling_set->ComputeSkewport(gfx::Rect(0, 5000, 100, 100), 1.5, 1.f);
EXPECT_EQ(0, move_skewport_far.x());
EXPECT_EQ(5000, move_skewport_far.y());
EXPECT_EQ(100, move_skewport_far.width());
EXPECT_EQ(175, move_skewport_far.height());
EXPECT_TRUE(move_skewport_far.Contains(gfx::Rect(0, 5000, 100, 100)));
}
TEST(PictureLayerTilingSetTest, ComputeSkewportExtremeCases) {
FakePictureLayerTilingClient client;
gfx::Size layer_bounds(200, 200);
client.SetTileSize(gfx::Size(100, 100));
LayerTreeSettings settings;
settings.tiling_interest_area_padding = 1000000000;
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
std::unique_ptr<TestablePictureLayerTilingSet> tiling_set =
CreateTilingSetWithSettings(&client, settings);
tiling_set->AddTiling(gfx::AxisTransform2d(), raster_source);
gfx::Rect viewport1(-1918, 255860, 4010, 2356);
gfx::Rect viewport2(-7088, -91738, 14212, 8350);
gfx::Rect viewport3(-12730024, -158883296, 24607540, 14454512);
double time = 1.0;
tiling_set->UpdateTilePriorities(viewport1, 1.f, time, Occlusion(), true);
time += 0.016;
EXPECT_TRUE(
tiling_set->ComputeSkewport(viewport2, time, 1.f).Contains(viewport2));
tiling_set->UpdateTilePriorities(viewport2, 1.f, time, Occlusion(), true);
time += 0.016;
EXPECT_TRUE(
tiling_set->ComputeSkewport(viewport3, time, 1.f).Contains(viewport3));
PictureLayerTiling* tiling = tiling_set->AddTiling(
gfx::AxisTransform2d(1000.f, gfx::Vector2dF()), raster_source);
EXPECT_TRUE(tiling_set->TilingsNeedUpdate(viewport3, time));
tiling_set->UpdateTilePriorities(viewport3, 1.f, time, Occlusion(), true);
EXPECT_TRUE(tiling->GetCurrentVisibleRectForTesting().IsEmpty());
}
TEST(PictureLayerTilingSetTest, ComputeSkewport) {
FakePictureLayerTilingClient client;
gfx::Rect viewport(0, 0, 100, 100);
gfx::Size layer_bounds(200, 200);
client.SetTileSize(gfx::Size(100, 100));
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
std::unique_ptr<TestablePictureLayerTilingSet> tiling_set =
CreateTilingSet(&client);
tiling_set->AddTiling(gfx::AxisTransform2d(), raster_source);
tiling_set->UpdateTilePriorities(viewport, 1.f, 1.0, Occlusion(), true);
gfx::Rect down_skewport =
tiling_set->ComputeSkewport(gfx::Rect(0, 50, 100, 100), 1.5, 1.f);
EXPECT_EQ(0, down_skewport.x());
EXPECT_EQ(50, down_skewport.y());
EXPECT_EQ(100, down_skewport.width());
EXPECT_EQ(200, down_skewport.height());
gfx::Rect shrink_skewport =
tiling_set->ComputeSkewport(gfx::Rect(25, 25, 50, 50), 1.5, 1.f);
EXPECT_EQ(25, shrink_skewport.x());
EXPECT_EQ(25, shrink_skewport.y());
EXPECT_EQ(50, shrink_skewport.width());
EXPECT_EQ(50, shrink_skewport.height());
gfx::Rect down_right_skewport =
tiling_set->ComputeSkewport(gfx::Rect(10, 50, 100, 100), 1.5, 1.f);
EXPECT_EQ(10, down_right_skewport.x());
EXPECT_EQ(50, down_right_skewport.y());
EXPECT_EQ(120, down_right_skewport.width());
EXPECT_EQ(200, down_right_skewport.height());
gfx::Rect left_skewport =
tiling_set->ComputeSkewport(gfx::Rect(-20, 0, 100, 100), 1.5, 1.f);
EXPECT_EQ(-60, left_skewport.x());
EXPECT_EQ(0, left_skewport.y());
EXPECT_EQ(140, left_skewport.width());
EXPECT_EQ(100, left_skewport.height());
gfx::Rect expanded_skewport =
tiling_set->ComputeSkewport(gfx::Rect(-5, -5, 110, 110), 1.2, 1.f);
EXPECT_EQ(-30, expanded_skewport.x());
EXPECT_EQ(-30, expanded_skewport.y());
EXPECT_EQ(160, expanded_skewport.width());
EXPECT_EQ(160, expanded_skewport.height());
}
TEST(PictureLayerTilingSetTest, SkewportThroughUpdateTilePriorities) {
FakePictureLayerTilingClient client;
gfx::Rect viewport(0, 0, 100, 100);
gfx::Size layer_bounds(200, 200);
client.SetTileSize(gfx::Size(100, 100));
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
std::unique_ptr<TestablePictureLayerTilingSet> tiling_set =
CreateTilingSet(&client);
tiling_set->AddTiling(gfx::AxisTransform2d(), raster_source);
tiling_set->UpdateTilePriorities(viewport, 1.f, 1.0, Occlusion(), true);
gfx::Rect viewport_50 = gfx::Rect(0, 50, 100, 100);
gfx::Rect skewport_50 = tiling_set->ComputeSkewport(viewport_50, 1.5, 1.f);
EXPECT_EQ(gfx::Rect(0, 50, 100, 200), skewport_50);
tiling_set->UpdateTilePriorities(viewport_50, 1.f, 1.5, Occlusion(), true);
gfx::Rect viewport_100 = gfx::Rect(0, 100, 100, 100);
gfx::Rect skewport_100 = tiling_set->ComputeSkewport(viewport_100, 2.0, 1.f);
EXPECT_EQ(gfx::Rect(0, 100, 100, 200), skewport_100);
tiling_set->UpdateTilePriorities(viewport_100, 1.f, 2.0, Occlusion(), true);
gfx::Rect result = tiling_set->ComputeSkewport(viewport_100, 2.5, 1.f);
EXPECT_EQ(gfx::Rect(0, 100, 100, 150), result);
tiling_set->UpdateTilePriorities(viewport_100, 1.f, 2.5, Occlusion(), true);
result = tiling_set->ComputeSkewport(viewport_100, 3.0, 1.f);
EXPECT_EQ(viewport_100, result);
tiling_set->UpdateTilePriorities(viewport_100, 1.f, 3.0, Occlusion(), true);
gfx::Rect viewport_150 = gfx::Rect(0, 150, 100, 100);
gfx::Rect skewport_150 = tiling_set->ComputeSkewport(viewport_150, 3.5, 1.f);
EXPECT_EQ(gfx::Rect(0, 150, 100, 150), skewport_150);
tiling_set->UpdateTilePriorities(viewport_150, 1.f, 3.5, Occlusion(), true);
gfx::Rect viewport_200 = gfx::Rect(0, 200, 100, 100);
gfx::Rect skewport_200 = tiling_set->ComputeSkewport(viewport_200, 3.5, 1.f);
EXPECT_EQ(gfx::Rect(0, 200, 100, 300), skewport_200);
tiling_set->UpdateTilePriorities(viewport_150, 1.f, 3.5, Occlusion(), true);
EXPECT_EQ(gfx::Rect(0, 200, 100, 300), skewport_200);
tiling_set->UpdateTilePriorities(viewport_150, 1.f, 3.5, Occlusion(), true);
EXPECT_EQ(gfx::Rect(0, 200, 100, 300), skewport_200);
tiling_set->UpdateTilePriorities(viewport_200, 1.f, 3.5, Occlusion(), true);
gfx::Rect viewport_250 = gfx::Rect(0, 250, 100, 100);
gfx::Rect skewport_250 = tiling_set->ComputeSkewport(viewport_250, 3.5, 1.f);
EXPECT_EQ(viewport_250, skewport_250);
tiling_set->UpdateTilePriorities(viewport_250, 1.f, 3.5, Occlusion(), true);
}
TEST(PictureLayerTilingTest, ViewportDistanceWithScale) {
FakePictureLayerTilingClient client;
gfx::Rect viewport(0, 0, 100, 100);
gfx::Size layer_bounds(1500, 1500);
client.SetTileSize(gfx::Size(10, 10));
LayerTreeSettings settings;
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
std::unique_ptr<TestablePictureLayerTilingSet> tiling_set =
CreateTilingSet(&client);
auto* tiling = tiling_set->AddTiling(
gfx::AxisTransform2d(0.25f, gfx::Vector2dF()), raster_source);
tiling->set_resolution(HIGH_RESOLUTION);
gfx::Rect viewport_in_content_space =
gfx::ScaleToEnclosedRect(viewport, 0.25f);
tiling_set->UpdateTilePriorities(viewport, 1.f, 1.0, Occlusion(), true);
auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting();
gfx::Rect soon_border_rect_in_content_space =
tiling_set->ComputeSoonBorderRect(viewport, 1.f);
soon_border_rect_in_content_space =
gfx::ScaleToEnclosedRect(soon_border_rect_in_content_space, 0.25f);
for (int i = 0; i < 47; ++i) {
for (int j = 0; j < 47; ++j) {
EXPECT_TRUE(tiling->TileAt(i, j)) << "i: " << i << " j: " << j;
}
}
for (int i = 0; i < 47; ++i) {
EXPECT_FALSE(tiling->TileAt(i, 47)) << "i: " << i;
EXPECT_FALSE(tiling->TileAt(47, i)) << "i: " << i;
}
bool have_now = false;
bool have_eventually = false;
bool have_soon = false;
for (int i = 0; i < 47; ++i) {
for (int j = 0; j < 47; ++j) {
Tile* tile = tiling->TileAt(i, j);
PrioritizedTile prioritized_tile = prioritized_tiles[tile];
TilePriority priority = prioritized_tile.priority();
gfx::Rect tile_rect = tiling->TilingDataForTesting().TileBounds(i, j);
if (viewport_in_content_space.Intersects(tile_rect)) {
EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
have_now = true;
} else if (soon_border_rect_in_content_space.Intersects(tile_rect)) {
EXPECT_EQ(TilePriority::SOON, priority.priority_bin);
have_soon = true;
} else {
EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin);
EXPECT_GT(priority.distance_to_visible, 0.f);
have_eventually = true;
}
}
}
EXPECT_TRUE(have_now);
EXPECT_TRUE(have_soon);
EXPECT_TRUE(have_eventually);
EXPECT_EQ(tiling->TileAt(5, 1)->content_rect().ToString(), "40,8 10x10");
TilePriority priority = prioritized_tiles[tiling->TileAt(5, 1)].priority();
EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible);
priority = prioritized_tiles[tiling->TileAt(2, 5)].priority();
EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible);
priority = prioritized_tiles[tiling->TileAt(3, 4)].priority();
EXPECT_FLOAT_EQ(40.f, priority.distance_to_visible);
viewport = gfx::Rect(0, 40, 100, 100);
viewport_in_content_space = gfx::ScaleToEnclosedRect(viewport, 0.25f);
gfx::Rect skewport_in_content_space =
tiling_set->ComputeSkewport(viewport, 2.0, 1.f);
skewport_in_content_space =
gfx::ScaleToEnclosedRect(skewport_in_content_space, 0.25f);
soon_border_rect_in_content_space =
tiling_set->ComputeSoonBorderRect(viewport, 1.f);
soon_border_rect_in_content_space =
gfx::ScaleToEnclosedRect(soon_border_rect_in_content_space, 0.25f);
EXPECT_EQ(0, skewport_in_content_space.x());
EXPECT_EQ(10, skewport_in_content_space.y());
EXPECT_EQ(25, skewport_in_content_space.width());
EXPECT_EQ(35, skewport_in_content_space.height());
EXPECT_TRUE(tiling_set->TilingsNeedUpdate(viewport, 2.0));
tiling_set->UpdateTilePriorities(viewport, 1.f, 2.0, Occlusion(), true);
prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting();
have_now = false;
have_eventually = false;
have_soon = false;
for (int i = 0; i < 47; ++i) {
for (int j = 0; j < 47; ++j) {
Tile* tile = tiling->TileAt(i, j);
priority = prioritized_tiles[tile].priority();
gfx::Rect tile_rect = tiling->TilingDataForTesting().TileBounds(i, j);
if (viewport_in_content_space.Intersects(tile_rect)) {
EXPECT_EQ(TilePriority::NOW, priority.priority_bin) << "i: " << i
<< " j: " << j;
EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible) << "i: " << i
<< " j: " << j;
have_now = true;
} else if (skewport_in_content_space.Intersects(tile_rect) ||
soon_border_rect_in_content_space.Intersects(tile_rect)) {
EXPECT_EQ(TilePriority::SOON, priority.priority_bin) << "i: " << i
<< " j: " << j;
EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i
<< " j: " << j;
have_soon = true;
} else {
EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin)
<< "i: " << i << " j: " << j;
EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i
<< " j: " << j;
have_eventually = true;
}
}
}
EXPECT_TRUE(have_now);
EXPECT_TRUE(have_soon);
EXPECT_TRUE(have_eventually);
priority = prioritized_tiles[tiling->TileAt(5, 1)].priority();
EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible);
priority = prioritized_tiles[tiling->TileAt(2, 5)].priority();
EXPECT_FLOAT_EQ(28.f, priority.distance_to_visible);
priority = prioritized_tiles[tiling->TileAt(3, 4)].priority();
EXPECT_FLOAT_EQ(4.f, priority.distance_to_visible);
tiling_set->UpdateTilePriorities(viewport, 2.0f, 3.0, Occlusion(), true);
prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting();
priority = prioritized_tiles[tiling->TileAt(5, 1)].priority();
EXPECT_FLOAT_EQ(136.f, priority.distance_to_visible);
priority = prioritized_tiles[tiling->TileAt(2, 5)].priority();
EXPECT_FLOAT_EQ(56.f, priority.distance_to_visible);
priority = prioritized_tiles[tiling->TileAt(3, 4)].priority();
EXPECT_FLOAT_EQ(8.f, priority.distance_to_visible);
tiling = tiling_set->AddTiling(gfx::AxisTransform2d(0.2f, gfx::Vector2dF()),
raster_source);
tiling->set_resolution(HIGH_RESOLUTION);
tiling_set->UpdateTilePriorities(viewport, 1.0f, 4.0, Occlusion(), true);
prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting();
priority = prioritized_tiles[tiling->TileAt(5, 1)].priority();
EXPECT_FLOAT_EQ(110.f, priority.distance_to_visible);
priority = prioritized_tiles[tiling->TileAt(2, 5)].priority();
EXPECT_FLOAT_EQ(70.f, priority.distance_to_visible);
priority = prioritized_tiles[tiling->TileAt(3, 4)].priority();
EXPECT_FLOAT_EQ(60.f, priority.distance_to_visible);
tiling_set->UpdateTilePriorities(viewport, 0.5f, 5.0, Occlusion(), true);
prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting();
priority = prioritized_tiles[tiling->TileAt(5, 1)].priority();
EXPECT_FLOAT_EQ(55.f, priority.distance_to_visible);
priority = prioritized_tiles[tiling->TileAt(2, 5)].priority();
EXPECT_FLOAT_EQ(35.f, priority.distance_to_visible);
priority = prioritized_tiles[tiling->TileAt(3, 4)].priority();
EXPECT_FLOAT_EQ(30.f, priority.distance_to_visible);
}
TEST(PictureLayerTilingTest, InvalidateAfterComputeTilePriorityRects) {
FakePictureLayerTilingClient pending_client;
pending_client.SetTileSize(gfx::Size(100, 100));
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(gfx::Size(100, 100));
std::unique_ptr<TestablePictureLayerTilingSet> tiling_set =
CreateTilingSet(&pending_client);
auto* pending_tiling =
tiling_set->AddTiling(gfx::AxisTransform2d(), raster_source);
pending_tiling->set_resolution(HIGH_RESOLUTION);
double time = 1.;
gfx::Rect viewport(0, 0, 100, 100);
EXPECT_TRUE(
tiling_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true));
EXPECT_FALSE(
tiling_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true));
tiling_set->Invalidate(Region());
EXPECT_TRUE(
tiling_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true));
}
TEST(PictureLayerTilingTest, InvalidateAfterUpdateRasterSourceForCommit) {
FakePictureLayerTilingClient pending_client;
FakePictureLayerTilingClient active_client;
std::unique_ptr<PictureLayerTilingSet> pending_set =
PictureLayerTilingSet::Create(PENDING_TREE, &pending_client, 1000, 1.f,
1000, 1000.f);
std::unique_ptr<PictureLayerTilingSet> active_set =
PictureLayerTilingSet::Create(ACTIVE_TREE, &active_client, 1000, 1.f,
1000, 1000.f);
gfx::Size layer_bounds(100, 100);
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
auto* pending_tiling =
pending_set->AddTiling(gfx::AxisTransform2d(), raster_source);
pending_tiling->set_resolution(HIGH_RESOLUTION);
active_client.set_twin_tiling_set(pending_set.get());
double time = 1.;
gfx::Rect viewport(0, 0, 100, 100);
pending_set->UpdateTilingsToCurrentRasterSourceForCommit(raster_source,
Region(), 1.f, 1.f);
EXPECT_TRUE(pending_set->UpdateTilePriorities(viewport, 1.f, time,
Occlusion(), true));
EXPECT_FALSE(
active_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true));
active_set->UpdateTilingsToCurrentRasterSourceForActivation(
raster_source, pending_set.get(), Region(), 1.f, 1.f);
EXPECT_FALSE(pending_set->UpdateTilePriorities(viewport, 1.f, time,
Occlusion(), true));
EXPECT_TRUE(
active_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true));
pending_set->UpdateTilingsToCurrentRasterSourceForCommit(raster_source,
Region(), 1.f, 1.f);
EXPECT_TRUE(pending_set->UpdateTilePriorities(viewport, 1.f, time,
Occlusion(), true));
EXPECT_FALSE(
active_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true));
active_client.set_twin_tiling_set(nullptr);
}
TEST(PictureLayerTilingSetTest, TilingTranslationChanges) {
gfx::Size tile_size(64, 64);
FakePictureLayerTilingClient pending_client;
FakePictureLayerTilingClient active_client;
pending_client.SetTileSize(tile_size);
active_client.SetTileSize(tile_size);
std::unique_ptr<PictureLayerTilingSet> pending_set =
PictureLayerTilingSet::Create(PENDING_TREE, &pending_client, 0, 1.f, 0,
0.f);
std::unique_ptr<PictureLayerTilingSet> active_set =
PictureLayerTilingSet::Create(ACTIVE_TREE, &active_client, 0, 1.f, 0,
0.f);
active_client.set_twin_tiling_set(pending_set.get());
gfx::Size layer_bounds(100, 100);
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
gfx::AxisTransform2d raster_transform1(1.f, gfx::Vector2dF(0.25f, 0.25f));
pending_set->AddTiling(raster_transform1, raster_source);
pending_set->tiling_at(0)->set_resolution(HIGH_RESOLUTION);
pending_set->UpdateTilePriorities(gfx::Rect(layer_bounds), 1.f, 1.0,
Occlusion(), false);
EXPECT_EQ(4u, pending_set->tiling_at(0)->AllTilesForTesting().size());
active_set->UpdateTilingsToCurrentRasterSourceForActivation(
raster_source.get(), pending_set.get(), Region(), 1.f, 1.f);
ASSERT_EQ(1u, active_set->num_tilings());
EXPECT_EQ(active_set->tiling_at(0)->raster_transform(), raster_transform1);
EXPECT_EQ(4u, active_set->tiling_at(0)->AllTilesForTesting().size());
gfx::AxisTransform2d raster_transform2(1.f, gfx::Vector2dF(0.75f, 0.75f));
pending_set->RemoveAllTilings();
pending_set->AddTiling(raster_transform2, raster_source);
pending_set->tiling_at(0)->set_resolution(HIGH_RESOLUTION);
pending_set->UpdateTilePriorities(gfx::Rect(1, 1), 1.f, 1.0, Occlusion(),
false);
EXPECT_EQ(1u, pending_set->tiling_at(0)->AllTilesForTesting().size());
active_set->UpdateTilingsToCurrentRasterSourceForActivation(
raster_source.get(), pending_set.get(), Region(), 1.f, 1.f);
ASSERT_EQ(1u, active_set->num_tilings());
EXPECT_EQ(active_set->tiling_at(0)->raster_transform(), raster_transform2);
EXPECT_EQ(1u, active_set->tiling_at(0)->AllTilesForTesting().size());
active_client.set_twin_tiling_set(nullptr);
}
TEST(PictureLayerTilingSetTest, LcdChanges) {
gfx::Size tile_size(64, 64);
FakePictureLayerTilingClient pending_client;
FakePictureLayerTilingClient active_client;
pending_client.SetTileSize(tile_size);
active_client.SetTileSize(tile_size);
std::unique_ptr<PictureLayerTilingSet> pending_set =
PictureLayerTilingSet::Create(PENDING_TREE, &pending_client, 0, 1.f, 0,
0.f);
std::unique_ptr<PictureLayerTilingSet> active_set =
PictureLayerTilingSet::Create(ACTIVE_TREE, &active_client, 0, 1.f, 0,
0.f);
active_client.set_twin_tiling_set(pending_set.get());
pending_client.set_twin_tiling_set(active_set.get());
gfx::Size layer_bounds(100, 100);
scoped_refptr<FakeRasterSource> raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
const bool with_lcd_text = true;
const bool without_lcd_text = false;
gfx::AxisTransform2d raster_transform(1.f, gfx::Vector2dF());
pending_set->AddTiling(raster_transform, raster_source, with_lcd_text);
pending_set->tiling_at(0)->set_resolution(HIGH_RESOLUTION);
pending_set->UpdateTilePriorities(gfx::Rect(layer_bounds), 1.f, 1.0,
Occlusion(), false);
EXPECT_EQ(4u, pending_set->tiling_at(0)->AllTilesForTesting().size());
active_set->UpdateTilingsToCurrentRasterSourceForActivation(
raster_source.get(), pending_set.get(), Region(), 1.f, 1.f);
ASSERT_EQ(1u, active_set->num_tilings());
EXPECT_EQ(4u, active_set->tiling_at(0)->AllTilesForTesting().size());
pending_set->RemoveAllTilings();
pending_set->AddTiling(raster_transform, raster_source, without_lcd_text);
pending_set->tiling_at(0)->set_resolution(HIGH_RESOLUTION);
pending_set->UpdateTilePriorities(gfx::Rect(layer_bounds), 1.f, 1.0,
Occlusion(), false);
EXPECT_EQ(4u, pending_set->tiling_at(0)->AllTilesForTesting().size());
active_client.set_twin_tiling_set(nullptr);
pending_client.set_twin_tiling_set(nullptr);
}
}
}