#include "cc/test/test_web_graphics_context_3d.h"
#include "cc/trees/layer_tree_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
namespace cc {
namespace {
public:
explicit MockCanvas(int w, int h) : SkCanvas(w, h) {}
- virtual void drawRect(const SkRect& rect, const SkPaint& paint) OVERRIDE {
+ void drawRect(const SkRect& rect, const SkPaint& paint) override {
// Capture calls before SkCanvas quickReject() kicks in.
rects_.push_back(rect);
}
: proxy_(base::MessageLoopProxy::current()),
host_impl_(LowResTilingsSettings(), &proxy_, &shared_bitmap_manager_),
id_(7),
- pending_layer_(NULL),
- old_pending_layer_(NULL),
- active_layer_(NULL) {}
+ pending_layer_(nullptr),
+ old_pending_layer_(nullptr),
+ active_layer_(nullptr) {}
explicit PictureLayerImplTest(const LayerTreeSettings& settings)
: proxy_(base::MessageLoopProxy::current()),
virtual ~PictureLayerImplTest() {
}
- virtual void SetUp() OVERRIDE {
+ virtual void SetUp() override {
InitializeRenderer();
}
virtual void InitializeRenderer() {
- host_impl_.InitializeRenderer(
- FakeOutputSurface::Create3d().PassAs<OutputSurface>());
+ host_impl_.InitializeRenderer(FakeOutputSurface::Create3d());
}
void SetupDefaultTrees(const gfx::Size& layer_bounds) {
CHECK(!host_impl_.pending_tree());
CHECK(host_impl_.recycle_tree());
old_pending_layer_ = pending_layer_;
- pending_layer_ = NULL;
+ pending_layer_ = nullptr;
active_layer_ = static_cast<FakePictureLayerImpl*>(
host_impl_.active_tree()->LayerById(id_));
}
host_impl_.CreatePendingTree();
host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.f, 0.25f, 100.f);
LayerTreeImpl* pending_tree = host_impl_.pending_tree();
- // Clear recycled tree.
- pending_tree->DetachLayerTree();
- scoped_ptr<FakePictureLayerImpl> pending_layer =
- FakePictureLayerImpl::CreateWithPile(pending_tree, id_, pile);
- pending_layer->SetDrawsContent(true);
- pending_tree->SetRootLayer(pending_layer.PassAs<LayerImpl>());
+ // Steal from the recycled tree.
+ scoped_ptr<LayerImpl> old_pending_root = pending_tree->DetachLayerTree();
+ DCHECK_IMPLIES(old_pending_root, old_pending_root->id() == id_);
+
+ scoped_ptr<FakePictureLayerImpl> pending_layer;
+ if (old_pending_root) {
+ pending_layer.reset(
+ static_cast<FakePictureLayerImpl*>(old_pending_root.release()));
+ pending_layer->SetPile(pile);
+ } else {
+ pending_layer =
+ FakePictureLayerImpl::CreateWithPile(pending_tree, id_, pile);
+ pending_layer->SetDrawsContent(true);
+ }
+ // The bounds() just mirror the pile size.
+ pending_layer->SetBounds(pending_layer->pile()->tiling_size());
+ pending_tree->SetRootLayer(pending_layer.Pass());
pending_layer_ = static_cast<FakePictureLayerImpl*>(
host_impl_.pending_tree()->LayerById(id_));
iter;
++iter) {
EXPECT_TRUE(*iter);
- EXPECT_EQ(pile, iter->picture_pile());
+ EXPECT_EQ(pile, iter->raster_source());
}
}
std::vector<SkRect>::const_iterator rect_iter = rects.begin();
for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) {
MockCanvas mock_canvas(1000, 1000);
- active_pile->RasterDirect(
- &mock_canvas, (*tile_iter)->content_rect(), 1.0f, NULL);
+ active_pile->RasterDirect(&mock_canvas, (*tile_iter)->content_rect(),
+ 1.0f);
// This test verifies that when drawing the contents of a specific tile
// at content scale 1.0, the playback canvas never receives content from
viewport_rect_for_tile_priority,
transform_for_tile_priority,
resourceless_software_draw);
- active_layer_->draw_properties().visible_content_rect = viewport;
- active_layer_->draw_properties().screen_space_transform = transform;
- active_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
+ host_impl_.active_tree()->UpdateDrawProperties();
gfx::Rect viewport_rect_for_tile_priority_in_view_space =
viewport_rect_for_tile_priority;
- // Verify the viewport rect for tile priority is used in picture layer impl.
- EXPECT_EQ(active_layer_->viewport_rect_for_tile_priority(),
- viewport_rect_for_tile_priority_in_view_space);
-
// Verify the viewport rect for tile priority is used in picture layer tiling.
+ EXPECT_EQ(viewport_rect_for_tile_priority_in_view_space,
+ active_layer_->GetViewportForTilePriorityInContentSpace());
PictureLayerTilingSet* tilings = active_layer_->tilings();
for (size_t i = 0; i < tilings->num_tilings(); i++) {
PictureLayerTiling* tiling = tilings->tiling_at(i);
viewport_rect_for_tile_priority,
transform_for_tile_priority,
resourceless_software_draw);
- active_layer_->draw_properties().visible_content_rect = viewport;
- active_layer_->draw_properties().screen_space_transform = transform;
- active_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
+ host_impl_.active_tree()->UpdateDrawProperties();
gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization);
bool success = transform_for_tile_priority.GetInverse(&screen_to_view);
gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
screen_to_view, viewport_rect_for_tile_priority));
- // Verify the viewport rect for tile priority is used in PictureLayerImpl.
- EXPECT_EQ(active_layer_->viewport_rect_for_tile_priority(),
- viewport_rect_for_tile_priority_in_view_space);
-
+ EXPECT_EQ(viewport_rect_for_tile_priority_in_view_space,
+ active_layer_->GetViewportForTilePriorityInContentSpace());
tilings = active_layer_->tilings();
for (size_t i = 0; i < tilings->num_tilings(); i++) {
PictureLayerTiling* tiling = tilings->tiling_at(i);
gfx::Rect visible_rect_for_tile_priority =
active_layer_->visible_rect_for_tile_priority();
EXPECT_FALSE(visible_rect_for_tile_priority.IsEmpty());
- gfx::Rect viewport_rect_for_tile_priority =
- active_layer_->viewport_rect_for_tile_priority();
- EXPECT_FALSE(viewport_rect_for_tile_priority.IsEmpty());
gfx::Transform screen_space_transform_for_tile_priority =
- active_layer_->screen_space_transform_for_tile_priority();
+ active_layer_->screen_space_transform();
// Expand viewport and set it as invalid for prioritizing tiles.
// Should update viewport and transform, but not update visible rect.
resourceless_software_draw);
active_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
- // Viewport and transform for tile priority are updated.
- EXPECT_EQ(viewport, active_layer_->viewport_rect_for_tile_priority());
- EXPECT_TRANSFORMATION_MATRIX_EQ(
- transform, active_layer_->screen_space_transform_for_tile_priority());
+ // Transform for tile priority is updated.
+ EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
+ active_layer_->screen_space_transform());
// Visible rect for tile priority retains old value.
EXPECT_EQ(visible_rect_for_tile_priority,
active_layer_->visible_rect_for_tile_priority());
resourceless_software_draw);
active_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
- EXPECT_TRANSFORMATION_MATRIX_EQ(
- transform, active_layer_->screen_space_transform_for_tile_priority());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
+ active_layer_->screen_space_transform());
EXPECT_EQ(viewport, active_layer_->visible_rect_for_tile_priority());
-
- // Match the reverse translate in |transform|.
- EXPECT_EQ(viewport - gfx::Vector2d(1, 1),
- active_layer_->viewport_rect_for_tile_priority());
}
TEST_F(PictureLayerImplTest, ClonePartialInvalidation) {
EXPECT_TRUE(*iter);
EXPECT_FALSE(iter.geometry_rect().IsEmpty());
if (iter.geometry_rect().Intersects(content_invalidation))
- EXPECT_EQ(pending_pile.get(), iter->picture_pile());
+ EXPECT_EQ(pending_pile.get(), iter->raster_source());
else
- EXPECT_EQ(active_pile.get(), iter->picture_pile());
+ EXPECT_EQ(active_pile.get(), iter->raster_source());
}
}
}
iter.geometry_rect().bottom() >= active_content_bounds.height() ||
active_tiles[0]->content_rect().size() !=
pending_tiles[0]->content_rect().size()) {
- EXPECT_EQ(pending_pile.get(), iter->picture_pile());
+ EXPECT_EQ(pending_pile.get(), iter->raster_source());
} else {
- EXPECT_EQ(active_pile.get(), iter->picture_pile());
+ EXPECT_EQ(active_pile.get(), iter->raster_source());
}
}
}
++iter) {
EXPECT_FALSE(iter.full_tile_geometry_rect().IsEmpty());
// Ensure there is a recording for this tile.
- bool in_pending = pending_pile->CanRaster(tiling->contents_scale(),
- iter.full_tile_geometry_rect());
- bool in_active = active_pile->CanRaster(tiling->contents_scale(),
- iter.full_tile_geometry_rect());
+ bool in_pending = pending_pile->CoversRect(iter.full_tile_geometry_rect(),
+ tiling->contents_scale());
+ bool in_active = active_pile->CoversRect(iter.full_tile_geometry_rect(),
+ tiling->contents_scale());
if (in_pending && !in_active)
- EXPECT_EQ(pending_pile.get(), iter->picture_pile());
+ EXPECT_EQ(pending_pile.get(), iter->raster_source());
else if (in_active)
- EXPECT_EQ(active_pile.get(), iter->picture_pile());
+ EXPECT_EQ(active_pile.get(), iter->raster_source());
else
EXPECT_FALSE(*iter);
}
EXPECT_BOTH_EQ(LowResTiling()->contents_scale(), low_res_factor);
EXPECT_BOTH_EQ(num_tilings(), 2u);
- // Page scale animation, new high res, but not new low res because animating.
+ // Page scale animation, new high res, but no low res. We still have
+ // a tiling at the previous scale, it's just not marked as low res.
contents_scale = 2.f;
page_scale = 2.f;
maximum_animation_scale = 2.f;
maximum_animation_scale,
animating_transform);
EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f);
- EXPECT_BOTH_EQ(LowResTiling()->contents_scale(), low_res_factor);
+ EXPECT_FALSE(active_layer_->LowResTiling());
+ EXPECT_FALSE(pending_layer_->LowResTiling());
EXPECT_BOTH_EQ(num_tilings(), 3u);
// Stop animating, new low res gets created for final page scale.
}
TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) {
- gfx::Size tile_size(host_impl_.settings().default_tile_size);
- SetupDefaultTrees(tile_size);
+ gfx::Size layer_bounds(host_impl_.settings().default_tile_size);
+ gfx::Size tile_size(100, 100);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+ SetupTrees(pending_pile, active_pile);
float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
float device_scale = 1.f;
ResetTilingsAndRasterScales();
// Mask layers dont create low res since they always fit on one tile.
- pending_layer_->pile()->set_is_mask(true);
- active_layer_->pile()->set_is_mask(true);
+ pending_pile->SetIsMask(true);
+ active_pile->SetIsMask(true);
SetContentsScaleOnBothLayers(contents_scale,
device_scale,
page_scale,
scoped_refptr<FakePicturePileImpl> valid_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1000, 1000));
- valid_pile->set_is_mask(true);
+ valid_pile->SetIsMask(true);
SetupPendingTree(valid_pile);
SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
// Mask layers have a tiling with a single tile in it.
EXPECT_EQ(1u, active_layer_->HighResTiling()->AllTilesForTesting().size());
// The mask resource exists.
- EXPECT_NE(0u, active_layer_->ContentsResourceId());
+ ResourceProvider::ResourceId mask_resource_id;
+ gfx::Size mask_texture_size;
+ active_layer_->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
+ EXPECT_NE(0u, mask_resource_id);
+ EXPECT_EQ(mask_texture_size, active_layer_->bounds());
// Resize larger than the max texture size.
int max_texture_size = host_impl_.GetRendererCapabilities().max_texture_size;
scoped_refptr<FakePicturePileImpl> huge_pile =
FakePicturePileImpl::CreateFilledPile(
tile_size, gfx::Size(max_texture_size + 1, 10));
- huge_pile->set_is_mask(true);
+ huge_pile->SetIsMask(true);
SetupPendingTree(huge_pile);
SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
// Mask layers have a tiling, but there should be no tiles in it.
EXPECT_EQ(0u, active_layer_->HighResTiling()->AllTilesForTesting().size());
// The mask resource is empty.
- EXPECT_EQ(0u, active_layer_->ContentsResourceId());
+ active_layer_->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
+ EXPECT_EQ(0u, mask_resource_id);
+}
+
+TEST_F(PictureLayerImplTest, ScaledMaskLayer) {
+ gfx::Size tile_size(100, 100);
+
+ scoped_refptr<FakePicturePileImpl> valid_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1000, 1000));
+ valid_pile->SetIsMask(true);
+ SetupPendingTree(valid_pile);
+
+ float ideal_contents_scale = 1.3f;
+ SetupDrawPropertiesAndUpdateTiles(
+ pending_layer_, ideal_contents_scale, 1.f, 1.f, 1.f, false);
+ EXPECT_EQ(ideal_contents_scale,
+ pending_layer_->HighResTiling()->contents_scale());
+ EXPECT_EQ(1u, pending_layer_->num_tilings());
+
+ pending_layer_->HighResTiling()->CreateAllTilesForTesting();
+ host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(
+ pending_layer_->HighResTiling()->AllTilesForTesting());
+
+ ActivateTree();
+
+ // Mask layers have a tiling with a single tile in it.
+ EXPECT_EQ(1u, active_layer_->HighResTiling()->AllTilesForTesting().size());
+ // The mask resource exists.
+ ResourceProvider::ResourceId mask_resource_id;
+ gfx::Size mask_texture_size;
+ active_layer_->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
+ EXPECT_NE(0u, mask_resource_id);
+ gfx::Size expected_mask_texture_size = gfx::ToCeiledSize(
+ gfx::ScaleSize(active_layer_->bounds(), ideal_contents_scale));
+ EXPECT_EQ(mask_texture_size, expected_mask_texture_size);
}
TEST_F(PictureLayerImplTest, ReleaseResources) {
TestWebGraphicsContext3D::Create();
context->set_max_texture_size(140);
host_impl_.DidLoseOutputSurface();
- host_impl_.InitializeRenderer(FakeOutputSurface::Create3d(
- context.Pass()).PassAs<OutputSurface>());
+ host_impl_.InitializeRenderer(
+ FakeOutputSurface::Create3d(context.Pass()).Pass());
SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings());
TestWebGraphicsContext3D::Create();
context->set_max_texture_size(140);
host_impl_.DidLoseOutputSurface();
- host_impl_.InitializeRenderer(FakeOutputSurface::Create3d(
- context.Pass()).PassAs<OutputSurface>());
+ host_impl_.InitializeRenderer(
+ FakeOutputSurface::Create3d(context.Pass()).Pass());
SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
ASSERT_LE(1u, pending_layer_->tilings()->num_tilings());
}
TEST_F(PictureLayerImplTest, DisallowTileDrawQuads) {
- MockOcclusionTracker<LayerImpl> occlusion_tracker;
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
gfx::Size tile_size(400, 400);
AddDefaultTilingsWithInvalidation(invalidation);
AppendQuadsData data;
- active_layer_->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, NULL);
- active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
- active_layer_->DidDraw(NULL);
+ active_layer_->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr);
+ active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+ active_layer_->DidDraw(nullptr);
ASSERT_EQ(1U, render_pass->quad_list.size());
EXPECT_EQ(DrawQuad::PICTURE_CONTENT,
render_pass->quad_list.front()->material);
}
-TEST_F(PictureLayerImplTest, MarkRequiredNullTiles) {
- gfx::Size tile_size(100, 100);
- gfx::Size layer_bounds(1000, 1000);
+TEST_F(PictureLayerImplTest, SolidColorLayerHasVisibleFullCoverage) {
+ scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+
+ gfx::Size tile_size(1000, 1000);
+ gfx::Size layer_bounds(1500, 1500);
+ gfx::Rect visible_rect(250, 250, 1000, 1000);
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
- // Layers with entirely empty piles can't get tilings.
- pending_pile->AddRecordingAt(0, 0);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
- SetupPendingTree(pending_pile);
+ pending_pile->set_is_solid_color(true);
+ active_pile->set_is_solid_color(true);
- ASSERT_TRUE(pending_layer_->CanHaveTilings());
- pending_layer_->AddTiling(1.0f);
- pending_layer_->AddTiling(2.0f);
+ SetupTrees(pending_pile, active_pile);
- // It should be safe to call this (and MarkVisibleResourcesAsRequired)
- // on a layer with no recordings.
- host_impl_.pending_tree()->UpdateDrawProperties();
- pending_layer_->MarkVisibleResourcesAsRequired();
+ active_layer_->draw_properties().visible_content_rect = visible_rect;
+
+ AppendQuadsData data;
+ active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+ active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+ active_layer_->DidDraw(nullptr);
+
+ Region remaining = visible_rect;
+ for (const auto& quad : render_pass->quad_list) {
+ EXPECT_TRUE(visible_rect.Contains(quad->rect));
+ EXPECT_TRUE(remaining.Contains(quad->rect));
+ remaining.Subtract(quad->rect);
+ }
+
+ EXPECT_TRUE(remaining.IsEmpty());
}
TEST_F(PictureLayerImplTest, TileScalesWithSolidColorPile) {
ASSERT_TRUE(pending_layer_->CanHaveTilings());
PictureLayerTiling* tiling = pending_layer_->AddTiling(1.f);
host_impl_.pending_tree()->UpdateDrawProperties();
- EXPECT_EQ(tiling->resolution(), HIGH_RESOLUTION);
EXPECT_EQ(viewport, pending_layer_->visible_rect_for_tile_priority());
- // Fake set priorities.
- for (PictureLayerTiling::CoverageIterator iter(
- tiling, pending_layer_->contents_scale_x(), gfx::Rect(layer_bounds));
- iter;
- ++iter) {
- if (!*iter)
- continue;
- Tile* tile = *iter;
- TilePriority priority;
- priority.resolution = HIGH_RESOLUTION;
- gfx::Rect tile_bounds = iter.geometry_rect();
- if (pending_layer_->visible_rect_for_tile_priority().Intersects(
- tile_bounds)) {
- priority.priority_bin = TilePriority::NOW;
- priority.distance_to_visible = 0.f;
- } else {
- priority.priority_bin = TilePriority::SOON;
- priority.distance_to_visible = 1.f;
- }
- tile->SetPriority(PENDING_TREE, priority);
- }
-
- pending_layer_->MarkVisibleResourcesAsRequired();
+ base::TimeTicks time_ticks;
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(time_ticks));
+ pending_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
+ EXPECT_EQ(HIGH_RESOLUTION, tiling->resolution());
int num_visible = 0;
int num_offscreen = 0;
- for (PictureLayerTiling::CoverageIterator iter(
- tiling, pending_layer_->contents_scale_x(), gfx::Rect(layer_bounds));
- iter;
+ for (PictureLayerTiling::TilingRasterTileIterator iter(tiling); iter;
++iter) {
- if (!*iter)
- continue;
const Tile* tile = *iter;
+ DCHECK(tile);
if (tile->priority(PENDING_TREE).distance_to_visible == 0.f) {
EXPECT_TRUE(tile->required_for_activation());
num_visible++;
CreateBeginFrameArgsForTesting(time_ticks));
pending_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
- pending_layer_->MarkVisibleResourcesAsRequired();
-
// Intersect the two rects. Any tile outside should not be required for
// activation.
gfx::Rect viewport_for_tile_priority =
if (viewport_for_tile_priority.Intersects(iter.geometry_rect())) {
num_inside++;
// Mark everything in viewport for tile priority as ready to draw.
- ManagedTileState::TileVersion& tile_version =
- tile->GetTileVersionForTesting(
- tile->DetermineRasterModeForTree(PENDING_TREE));
- tile_version.SetSolidColorForTesting(SK_ColorRED);
+ ManagedTileState::DrawInfo& draw_info = tile->draw_info();
+ draw_info.SetSolidColorForTesting(SK_ColorRED);
} else {
num_outside++;
EXPECT_FALSE(tile->required_for_activation());
host_impl_.active_tree()->UpdateDrawProperties();
active_layer_->draw_properties().visible_content_rect = visible_content_rect;
- MockOcclusionTracker<LayerImpl> occlusion_tracker;
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
AppendQuadsData data;
- active_layer_->WillDraw(DRAW_MODE_SOFTWARE, NULL);
- active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
- active_layer_->DidDraw(NULL);
+ active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+ active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+ active_layer_->DidDraw(nullptr);
// All tiles in activation rect is ready to draw.
EXPECT_EQ(0u, data.num_missing_tiles);
EXPECT_EQ(0u, data.num_incomplete_tiles);
+ EXPECT_FALSE(active_layer_->only_used_low_res_last_append_quads());
}
TEST_F(PictureLayerImplTest, HighResTileIsComplete) {
active_layer_->tilings()->tiling_at(0)->AllTilesForTesting();
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
- MockOcclusionTracker<LayerImpl> occlusion_tracker;
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
AppendQuadsData data;
- active_layer_->WillDraw(DRAW_MODE_SOFTWARE, NULL);
- active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
- active_layer_->DidDraw(NULL);
+ active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+ active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+ active_layer_->DidDraw(nullptr);
// All high res tiles drew, nothing was incomplete.
EXPECT_EQ(9u, render_pass->quad_list.size());
EXPECT_EQ(0u, data.num_missing_tiles);
EXPECT_EQ(0u, data.num_incomplete_tiles);
+ EXPECT_FALSE(active_layer_->only_used_low_res_last_append_quads());
+}
+
+TEST_F(PictureLayerImplTest, HighResTileIsIncomplete) {
+ base::TimeTicks time_ticks;
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(time_ticks));
+
+ gfx::Size tile_size(100, 100);
+ gfx::Size layer_bounds(200, 200);
+
+ host_impl_.SetViewportSize(layer_bounds);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ SetupPendingTree(pending_pile);
+ ActivateTree();
+
+ active_layer_->set_fixed_tile_size(tile_size);
+ host_impl_.active_tree()->UpdateDrawProperties();
+
+ scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+ AppendQuadsData data;
+ active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+ active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+ active_layer_->DidDraw(nullptr);
+
+ EXPECT_EQ(1u, render_pass->quad_list.size());
+ EXPECT_EQ(1u, data.num_missing_tiles);
+ EXPECT_EQ(0u, data.num_incomplete_tiles);
+ EXPECT_TRUE(active_layer_->only_used_low_res_last_append_quads());
+}
+
+TEST_F(PictureLayerImplTest, HighResTileIsIncompleteLowResComplete) {
+ base::TimeTicks time_ticks;
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(time_ticks));
+
+ gfx::Size tile_size(100, 100);
+ gfx::Size layer_bounds(200, 200);
+
+ host_impl_.SetViewportSize(layer_bounds);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ SetupPendingTree(pending_pile);
+ ActivateTree();
+
+ active_layer_->set_fixed_tile_size(tile_size);
+ host_impl_.active_tree()->UpdateDrawProperties();
+ std::vector<Tile*> low_tiles =
+ active_layer_->tilings()->tiling_at(1)->AllTilesForTesting();
+ host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(low_tiles);
+
+ scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+ AppendQuadsData data;
+ active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+ active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+ active_layer_->DidDraw(nullptr);
+
+ EXPECT_EQ(1u, render_pass->quad_list.size());
+ EXPECT_EQ(0u, data.num_missing_tiles);
+ EXPECT_EQ(1u, data.num_incomplete_tiles);
+ EXPECT_TRUE(active_layer_->only_used_low_res_last_append_quads());
}
TEST_F(PictureLayerImplTest, LowResTileIsIncomplete) {
active_layer_->tilings()->tiling_at(1)->AllTilesForTesting();
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(low_tiles);
- MockOcclusionTracker<LayerImpl> occlusion_tracker;
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
AppendQuadsData data;
- active_layer_->WillDraw(DRAW_MODE_SOFTWARE, NULL);
- active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
- active_layer_->DidDraw(NULL);
+ active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+ active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+ active_layer_->DidDraw(nullptr);
// The missing high res tile was replaced by a low res tile.
EXPECT_EQ(9u, render_pass->quad_list.size());
EXPECT_EQ(0u, data.num_missing_tiles);
EXPECT_EQ(1u, data.num_incomplete_tiles);
+ EXPECT_FALSE(active_layer_->only_used_low_res_last_append_quads());
}
TEST_F(PictureLayerImplTest,
active_layer_->HighResTiling()->AllTilesForTesting();
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(high_tiles);
- MockOcclusionTracker<LayerImpl> occlusion_tracker;
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
AppendQuadsData data;
- active_layer_->WillDraw(DRAW_MODE_SOFTWARE, NULL);
- active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
- active_layer_->DidDraw(NULL);
+ active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+ active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+ active_layer_->DidDraw(nullptr);
// All high res tiles drew, and the one ideal res tile drew.
ASSERT_GT(render_pass->quad_list.size(), 9u);
// Neither the high res nor the ideal tiles were considered as incomplete.
EXPECT_EQ(0u, data.num_missing_tiles);
EXPECT_EQ(0u, data.num_incomplete_tiles);
+ EXPECT_FALSE(active_layer_->only_used_low_res_last_append_quads());
}
TEST_F(PictureLayerImplTest, HighResRequiredWhenUnsharedActiveAllReady) {
// No shared tiles and all active tiles ready, so pending can only
// activate with all high res tiles.
- pending_layer_->MarkVisibleResourcesAsRequired();
+ pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+ pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
AssertAllTilesRequired(pending_layer_->HighResTiling());
AssertNoTilesRequired(pending_layer_->LowResTiling());
}
// When high res are required, even if the active tree is not ready,
// the high res tiles must be ready.
- host_impl_.active_tree()->SetRequiresHighResToDraw();
- pending_layer_->MarkVisibleResourcesAsRequired();
+ host_impl_.SetRequiresHighResToDraw();
+
+ pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+ pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
AssertAllTilesRequired(pending_layer_->HighResTiling());
AssertNoTilesRequired(pending_layer_->LowResTiling());
}
-TEST_F(PictureLayerImplTest, NothingRequiredIfAllHighResTilesShared) {
+TEST_F(PictureLayerImplTest, AllHighResRequiredEvenIfShared) {
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
EXPECT_FALSE(some_active_tile->IsReadyToDraw());
// All tiles shared (no invalidation), so even though the active tree's
- // tiles aren't ready, there is nothing required.
- pending_layer_->MarkVisibleResourcesAsRequired();
+ // tiles aren't ready, the high res tiles are required for activation.
+ pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+ pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
+ AssertAllTilesRequired(pending_layer_->HighResTiling());
+ AssertNoTilesRequired(pending_layer_->LowResTiling());
+}
+
+TEST_F(PictureLayerImplTest, DisallowRequiredForActivation) {
+ gfx::Size layer_bounds(400, 400);
+ gfx::Size tile_size(100, 100);
+ SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
+
+ CreateHighLowResAndSetAllTilesVisible();
+
+ Tile* some_active_tile =
+ active_layer_->HighResTiling()->AllTilesForTesting()[0];
+ EXPECT_FALSE(some_active_tile->IsReadyToDraw());
+
+ pending_layer_->HighResTiling()->set_can_require_tiles_for_activation(false);
+ pending_layer_->LowResTiling()->set_can_require_tiles_for_activation(false);
+
+ // If we disallow required for activation, no tiles can be required.
+ pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+ pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
AssertNoTilesRequired(pending_layer_->HighResTiling());
AssertNoTilesRequired(pending_layer_->LowResTiling());
}
// Since the active layer has no tiles at all, the pending layer doesn't
// need content in order to activate.
- pending_layer_->MarkVisibleResourcesAsRequired();
+ pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+ pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
AssertNoTilesRequired(pending_layer_->HighResTiling());
AssertNoTilesRequired(pending_layer_->LowResTiling());
}
// to the case where there is no active layer, to avoid flashing content.
// This can happen if a layer exists for a while and switches from
// not being able to have content to having content.
- pending_layer_->MarkVisibleResourcesAsRequired();
+ pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+ pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
AssertAllTilesRequired(pending_layer_->HighResTiling());
AssertNoTilesRequired(pending_layer_->LowResTiling());
}
pending_layer_->SetBounds(pending_layer_bounds);
CreateHighLowResAndSetAllTilesVisible();
+ // TODO(vmpstr): This is confusing. Rework the test to create different bounds
+ // on different trees instead of fudging tilings.
+ pending_layer_->HighResTiling()->ComputeTilePriorityRects(
+ PENDING_TREE, gfx::Rect(pending_layer_bounds), 1.f, 1.f, Occlusion());
+ pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
active_layer_->SetAllTilesReady();
// Since the active layer has different bounds, the pending layer needs all
// high res tiles in order to activate.
- pending_layer_->MarkVisibleResourcesAsRequired();
+ pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+ pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
AssertAllTilesRequired(pending_layer_->HighResTiling());
AssertNoTilesRequired(pending_layer_->LowResTiling());
}
scoped_ptr<FakePictureLayerImpl> pending_layer =
FakePictureLayerImpl::CreateWithPile(pending_tree, id_, pending_pile);
pending_layer->SetDrawsContent(true);
- pending_tree->SetRootLayer(pending_layer.PassAs<LayerImpl>());
+ pending_tree->SetRootLayer(pending_layer.Pass());
pending_layer_ = static_cast<FakePictureLayerImpl*>(
host_impl_.pending_tree()->LayerById(id_));
EXPECT_FALSE(active_layer_->needs_post_commit_initialization());
}
+TEST_F(PictureLayerImplTest, ShareTilesOnNextFrame) {
+ SetupDefaultTrees(gfx::Size(1500, 1500));
+
+ PictureLayerTiling* tiling = pending_layer_->AddTiling(1.f);
+ gfx::Rect first_invalidate = tiling->TilingDataForTesting().TileBounds(0, 0);
+ first_invalidate.Inset(tiling->TilingDataForTesting().border_texels(),
+ tiling->TilingDataForTesting().border_texels());
+ gfx::Rect second_invalidate = tiling->TilingDataForTesting().TileBounds(1, 1);
+ second_invalidate.Inset(tiling->TilingDataForTesting().border_texels(),
+ tiling->TilingDataForTesting().border_texels());
+
+ // Make a pending tree with an invalidated raster tile 0,0.
+ tiling->CreateAllTilesForTesting();
+ pending_layer_->set_invalidation(first_invalidate);
+
+ // Activate and make a pending tree with an invalidated raster tile 1,1.
+ ActivateTree();
+
+ host_impl_.CreatePendingTree();
+ pending_layer_ = static_cast<FakePictureLayerImpl*>(
+ host_impl_.pending_tree()->root_layer());
+ pending_layer_->set_invalidation(second_invalidate);
+
+ PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0);
+ PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0);
+
+ pending_tiling->CreateAllTilesForTesting();
+
+ // Tile 0,0 should be shared, but tile 1,1 should not be.
+ EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
+ EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0));
+ EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1));
+ EXPECT_NE(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1));
+ EXPECT_TRUE(pending_tiling->TileAt(0, 0)->is_shared());
+ EXPECT_TRUE(pending_tiling->TileAt(1, 0)->is_shared());
+ EXPECT_TRUE(pending_tiling->TileAt(0, 1)->is_shared());
+ EXPECT_FALSE(pending_tiling->TileAt(1, 1)->is_shared());
+
+ // Drop the tiles on the active tree and recreate them. The same tiles
+ // should be shared or not.
+ active_tiling->ComputeTilePriorityRects(
+ ACTIVE_TREE, gfx::Rect(), 1.f, 1.0, Occlusion());
+ EXPECT_TRUE(active_tiling->AllTilesForTesting().empty());
+ active_tiling->CreateAllTilesForTesting();
+
+ // Tile 0,0 should be shared, but tile 1,1 should not be.
+ EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
+ EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0));
+ EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1));
+ EXPECT_NE(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1));
+ EXPECT_TRUE(pending_tiling->TileAt(0, 0)->is_shared());
+ EXPECT_TRUE(pending_tiling->TileAt(1, 0)->is_shared());
+ EXPECT_TRUE(pending_tiling->TileAt(0, 1)->is_shared());
+ EXPECT_FALSE(pending_tiling->TileAt(1, 1)->is_shared());
+}
+
TEST_F(PictureLayerImplTest, ShareTilesOnSync) {
SetupDefaultTrees(gfx::Size(1500, 1500));
AddDefaultTilingsWithInvalidation(gfx::Rect());
}
TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) {
- SetupDefaultTrees(gfx::Size(10, 10));
+ gfx::Size tile_size(100, 100);
+
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(10, 10));
+ SetupPendingTree(active_pile);
+ ActivateTree();
host_impl_.active_tree()->UpdateDrawProperties();
EXPECT_FALSE(host_impl_.active_tree()->needs_update_draw_properties());
SetupDrawPropertiesAndUpdateTiles(
active_layer_, 0.5f, 0.5f, 0.5f, 0.5f, false);
active_layer_->tilings()->RemoveAllTilings();
- PictureLayerTiling* tiling = active_layer_->tilings()->AddTiling(0.5f);
- active_layer_->tilings()->AddTiling(1.5f);
- active_layer_->tilings()->AddTiling(0.25f);
+ PictureLayerTiling* tiling = active_layer_->AddTiling(0.5f);
+ active_layer_->AddTiling(1.5f);
+ active_layer_->AddTiling(0.25f);
tiling->set_resolution(HIGH_RESOLUTION);
// Sanity checks.
// 1.0f). Note that we should also ensure that the pending layer needs post
// commit initialization, since this is what would happen during commit. In
// other words we want the pending layer to sync from the active layer.
- pending_layer_->SetBounds(gfx::Size(1, 1));
- pending_layer_->SetNeedsPostCommitInitialization();
- pending_layer_->set_twin_layer(NULL);
- active_layer_->set_twin_layer(NULL);
- EXPECT_TRUE(pending_layer_->needs_post_commit_initialization());
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1, 1));
+ SetupPendingTree(pending_pile);
// Update the draw properties: sync from active tree should happen here.
host_impl_.pending_tree()->UpdateDrawProperties();
+ EXPECT_FALSE(pending_layer_->needs_post_commit_initialization());
// Another sanity check.
ASSERT_EQ(1.f, pending_layer_->MinimumContentsScale());
class DeferredInitPictureLayerImplTest : public PictureLayerImplTest {
public:
- virtual void InitializeRenderer() OVERRIDE {
+ void InitializeRenderer() override {
bool delegated_rendering = false;
- host_impl_.InitializeRenderer(
- FakeOutputSurface::CreateDeferredGL(
- scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
- delegated_rendering).PassAs<OutputSurface>());
+ host_impl_.InitializeRenderer(FakeOutputSurface::CreateDeferredGL(
+ scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
+ delegated_rendering));
}
- virtual void SetUp() OVERRIDE {
+ virtual void SetUp() override {
PictureLayerImplTest::SetUp();
// Create some default active and pending trees.
maximum_animation_scale,
animating_transform);
EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 4.f);
-
- static_cast<FakePicturePileImpl*>(pending_layer_->pile())->set_has_text(true);
- static_cast<FakePicturePileImpl*>(active_layer_->pile())->set_has_text(true);
-
- // Since we're GPU-rasterizing but have text, starting an animation should
- // cause tiling resolution to get set to the maximum animation scale.
- animating_transform = true;
- contents_scale = 2.f;
- maximum_animation_scale = 3.f;
-
- SetContentsScaleOnBothLayers(contents_scale,
- device_scale,
- page_scale,
- maximum_animation_scale,
- animating_transform);
- EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f);
-
- // Further changes to scale during the animation should not cause a new
- // high-res tiling to get created.
- contents_scale = 4.f;
- maximum_animation_scale = 5.f;
-
- SetContentsScaleOnBothLayers(contents_scale,
- device_scale,
- page_scale,
- maximum_animation_scale,
- animating_transform);
- EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f);
-
- // Once we stop animating, a new high-res tiling should be created.
- animating_transform = false;
-
- SetContentsScaleOnBothLayers(contents_scale,
- device_scale,
- page_scale,
- maximum_animation_scale,
- animating_transform);
- EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 4.f);
}
TEST_F(PictureLayerImplTest, LayerRasterTileIterator) {
EXPECT_TRUE(reached_prepaint);
EXPECT_EQ(0u, non_ideal_tile_count);
- EXPECT_EQ(1u, low_res_tile_count);
+ EXPECT_EQ(0u, low_res_tile_count);
EXPECT_EQ(16u, high_res_tile_count);
EXPECT_EQ(low_res_tile_count + high_res_tile_count + non_ideal_tile_count,
unique_tiles.size());
tile_it != high_res_tiles.end();
++tile_it) {
Tile* tile = *tile_it;
- ManagedTileState::TileVersion& tile_version =
- tile->GetTileVersionForTesting(
- tile->DetermineRasterModeForTree(ACTIVE_TREE));
- tile_version.SetSolidColorForTesting(SK_ColorRED);
+ ManagedTileState::DrawInfo& draw_info = tile->draw_info();
+ draw_info.SetSolidColorForTesting(SK_ColorRED);
}
non_ideal_tile_count = 0;
low_res_tile_count = 0;
high_res_tile_count = 0;
- for (it = PictureLayerImpl::LayerRasterTileIterator(pending_layer_, false);
- it;
+ for (it = PictureLayerImpl::LayerRasterTileIterator(pending_layer_, true); it;
++it) {
Tile* tile = *it;
TilePriority priority = tile->priority(PENDING_TREE);
++iter) {
if (mark_required) {
number_of_marked_tiles++;
- iter->MarkRequiredForActivation();
+ iter->set_required_for_activation(true);
} else {
number_of_unmarked_tiles++;
}
float expected_scales[] = {2.0f, 0.3f, 0.7f, low_res_factor, 1.0f};
size_t scale_index = 0;
bool reached_visible = false;
- Tile* last_tile = NULL;
+ Tile* last_tile = nullptr;
for (it = PictureLayerImpl::LayerEvictionTileIterator(
pending_layer_, SAME_PRIORITY_FOR_BOTH_TREES);
it;
CreateHighLowResAndSetAllTilesVisible();
active_layer_->SetAllTilesReady();
- pending_layer_->MarkVisibleResourcesAsRequired();
// All pending layer tiles required are not ready.
EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
CreateHighLowResAndSetAllTilesVisible();
active_layer_->SetAllTilesReady();
- pending_layer_->MarkVisibleResourcesAsRequired();
// All pending layer tiles required are not ready.
EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
// And all the low-res tiles in the pending layer.
pending_layer_->SetAllTilesReadyInTiling(pending_layer_->LowResTiling());
- pending_layer_->MarkVisibleResourcesAsRequired();
-
// The unshared high-res tiles are not ready, so we cannot activate.
EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
// Initialize all high-res tiles in the active layer.
active_layer_->SetAllTilesReadyInTiling(active_layer_->HighResTiling());
- pending_layer_->MarkVisibleResourcesAsRequired();
-
// The unshared high-res tiles are not ready, so we cannot activate.
EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
pending_layer_->tilings()->tiling_at(0)->contents_scale());
}
-TEST_F(NoLowResPictureLayerImplTest, MarkRequiredNullTiles) {
- gfx::Size tile_size(100, 100);
- gfx::Size layer_bounds(1000, 1000);
-
- scoped_refptr<FakePicturePileImpl> pending_pile =
- FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
- // Layers with entirely empty piles can't get tilings.
- pending_pile->AddRecordingAt(0, 0);
-
- SetupPendingTree(pending_pile);
-
- ASSERT_TRUE(pending_layer_->CanHaveTilings());
- pending_layer_->AddTiling(1.0f);
- pending_layer_->AddTiling(2.0f);
-
- // It should be safe to call this (and MarkVisibleResourcesAsRequired)
- // on a layer with no recordings.
- host_impl_.pending_tree()->UpdateDrawProperties();
- pending_layer_->MarkVisibleResourcesAsRequired();
-}
-
-TEST_F(NoLowResPictureLayerImplTest, NothingRequiredIfAllHighResTilesShared) {
+TEST_F(NoLowResPictureLayerImplTest, AllHighResRequiredEvenIfShared) {
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
// All tiles shared (no invalidation), so even though the active tree's
// tiles aren't ready, there is nothing required.
- pending_layer_->MarkVisibleResourcesAsRequired();
- AssertNoTilesRequired(pending_layer_->HighResTiling());
- if (host_impl_.settings().create_low_res_tiling) {
+ pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+ if (host_impl_.settings().create_low_res_tiling)
+ pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
+ AssertAllTilesRequired(pending_layer_->HighResTiling());
+ if (host_impl_.settings().create_low_res_tiling)
AssertNoTilesRequired(pending_layer_->LowResTiling());
- }
}
TEST_F(NoLowResPictureLayerImplTest, NothingRequiredIfActiveMissingTiles) {
// Since the active layer has no tiles at all, the pending layer doesn't
// need content in order to activate.
- pending_layer_->MarkVisibleResourcesAsRequired();
+ pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+ if (host_impl_.settings().create_low_res_tiling)
+ pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
AssertNoTilesRequired(pending_layer_->HighResTiling());
if (host_impl_.settings().create_low_res_tiling)
AssertNoTilesRequired(pending_layer_->LowResTiling());
gfx::Rect visible_rect_for_tile_priority =
active_layer_->visible_rect_for_tile_priority();
EXPECT_FALSE(visible_rect_for_tile_priority.IsEmpty());
- gfx::Rect viewport_rect_for_tile_priority =
- active_layer_->viewport_rect_for_tile_priority();
- EXPECT_FALSE(viewport_rect_for_tile_priority.IsEmpty());
gfx::Transform screen_space_transform_for_tile_priority =
- active_layer_->screen_space_transform_for_tile_priority();
+ active_layer_->screen_space_transform();
// Expand viewport and set it as invalid for prioritizing tiles.
// Should update viewport and transform, but not update visible rect.
resourceless_software_draw);
active_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
- // Viewport and transform for tile priority are updated.
- EXPECT_EQ(viewport, active_layer_->viewport_rect_for_tile_priority());
- EXPECT_TRANSFORMATION_MATRIX_EQ(
- transform, active_layer_->screen_space_transform_for_tile_priority());
+ // Transform for tile priority is updated.
+ EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
+ active_layer_->screen_space_transform());
// Visible rect for tile priority retains old value.
EXPECT_EQ(visible_rect_for_tile_priority,
active_layer_->visible_rect_for_tile_priority());
resourceless_software_draw);
active_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
- EXPECT_TRANSFORMATION_MATRIX_EQ(
- transform, active_layer_->screen_space_transform_for_tile_priority());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
+ active_layer_->screen_space_transform());
EXPECT_EQ(viewport, active_layer_->visible_rect_for_tile_priority());
-
- // Match the reverse translate in |transform|.
- EXPECT_EQ(viewport - gfx::Vector2d(1, 1),
- active_layer_->viewport_rect_for_tile_priority());
}
TEST_F(NoLowResPictureLayerImplTest, CleanUpTilings) {
}
TEST_F(PictureLayerImplTest, SharedQuadStateContainsMaxTilingScale) {
- MockOcclusionTracker<LayerImpl> occlusion_tracker;
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
gfx::Size tile_size(400, 400);
SK_MScalar1 / max_contents_scale);
AppendQuadsData data;
- active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
+ active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
// SharedQuadState should have be of size 1, as we are doing AppenQuad once.
EXPECT_EQ(1u, render_pass->shared_quad_state_list.size());
// The content_to_target_transform should be scaled by the
// MaximumTilingContentsScale on the layer.
EXPECT_EQ(scaled_draw_transform.ToString(),
- render_pass->shared_quad_state_list[0]
+ render_pass->shared_quad_state_list.front()
->content_to_target_transform.ToString());
// The content_bounds should be scaled by the
// MaximumTilingContentsScale on the layer.
- EXPECT_EQ(gfx::Size(2500u, 5000u).ToString(),
- render_pass->shared_quad_state_list[0]->content_bounds.ToString());
+ EXPECT_EQ(
+ gfx::Size(2500u, 5000u).ToString(),
+ render_pass->shared_quad_state_list.front()->content_bounds.ToString());
// The visible_content_rect should be scaled by the
// MaximumTilingContentsScale on the layer.
- EXPECT_EQ(
- gfx::Rect(0u, 0u, 2500u, 5000u).ToString(),
- render_pass->shared_quad_state_list[0]->visible_content_rect.ToString());
+ EXPECT_EQ(gfx::Rect(0u, 0u, 2500u, 5000u).ToString(),
+ render_pass->shared_quad_state_list.front()
+ ->visible_content_rect.ToString());
}
TEST_F(PictureLayerImplTest, UpdateTilesForMasksWithNoVisibleContent) {
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, bounds);
- pending_pile->set_is_mask(true);
+ pending_pile->SetIsMask(true);
scoped_ptr<FakePictureLayerImpl> mask = FakePictureLayerImpl::CreateWithPile(
host_impl_.pending_tree(), 3, pending_pile);
mask->SetDrawsContent(true);
FakePictureLayerImpl* pending_mask_content = mask.get();
- layer_with_mask->SetMaskLayer(mask.PassAs<LayerImpl>());
+ layer_with_mask->SetMaskLayer(mask.Pass());
scoped_ptr<FakePictureLayerImpl> child_of_layer_with_mask =
FakePictureLayerImpl::Create(host_impl_.pending_tree(), 4);
child_of_layer_with_mask->SetContentBounds(bounds);
child_of_layer_with_mask->SetDrawsContent(true);
- layer_with_mask->AddChild(child_of_layer_with_mask.PassAs<LayerImpl>());
+ layer_with_mask->AddChild(child_of_layer_with_mask.Pass());
- root->AddChild(layer_with_mask.PassAs<LayerImpl>());
+ root->AddChild(layer_with_mask.Pass());
host_impl_.pending_tree()->SetRootLayer(root.Pass());
public:
PictureLayerImplTestWithDelegatingRenderer() : PictureLayerImplTest() {}
- virtual void InitializeRenderer() OVERRIDE {
- host_impl_.InitializeRenderer(
- FakeOutputSurface::CreateDelegating3d().PassAs<OutputSurface>());
+ void InitializeRenderer() override {
+ host_impl_.InitializeRenderer(FakeOutputSurface::CreateDelegating3d());
}
};
host_impl_.SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
host_impl_.ManageTiles();
- MockOcclusionTracker<LayerImpl> occlusion_tracker;
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
AppendQuadsData data;
- active_layer_->WillDraw(DRAW_MODE_HARDWARE, NULL);
- active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
- active_layer_->DidDraw(NULL);
+ active_layer_->WillDraw(DRAW_MODE_HARDWARE, nullptr);
+ active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+ active_layer_->DidDraw(nullptr);
// Even when OOM, quads should be produced, and should be different material
// from quads with resource.
++priority_count) {
TreePriority tree_priority = static_cast<TreePriority>(priority_count);
size_t occluded_tile_count = 0u;
- Tile* last_tile = NULL;
+ Tile* last_tile = nullptr;
for (PictureLayerImpl::LayerEvictionTileIterator it =
PictureLayerImpl::LayerEvictionTileIterator(layer,
if (tile_is_visible)
unoccluded_tile_count++;
}
- EXPECT_EQ(unoccluded_tile_count, 25 + 4);
+ EXPECT_EQ(unoccluded_tile_count, 25);
// Partial occlusion.
pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 1));
if (tile_is_visible)
unoccluded_tile_count++;
}
- EXPECT_EQ(unoccluded_tile_count, 20 + 2);
+ EXPECT_EQ(20, unoccluded_tile_count);
// Full occlusion.
layer1->SetPosition(gfx::Point(0, 0));
for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
+ tiling->UpdateAllTilePrioritiesForTesting();
occluded_tile_count = 0;
for (PictureLayerTiling::CoverageIterator iter(
for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
+ tiling->UpdateAllTilePrioritiesForTesting();
occluded_tile_count = 0;
for (PictureLayerTiling::CoverageIterator iter(
}
switch (i) {
case 0:
- EXPECT_EQ(occluded_tile_count, 25);
+ EXPECT_EQ(25, occluded_tile_count);
break;
case 1:
- EXPECT_EQ(occluded_tile_count, 4);
+ EXPECT_EQ(4, occluded_tile_count);
break;
default:
NOTREACHED();
tilings.begin();
tiling_iterator != tilings.end();
++tiling_iterator) {
+ (*tiling_iterator)->UpdateAllTilePrioritiesForTesting();
std::vector<Tile*> tiles = (*tiling_iterator)->AllTilesForTesting();
occluded_tile_count = 0;
for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
+ tiling->UpdateAllTilePrioritiesForTesting();
for (PictureLayerTiling::CoverageIterator iter(
tiling,
// All tiles are unoccluded on the pending tree.
EXPECT_FALSE(tile->is_occluded(PENDING_TREE));
- Tile* twin_tile =
- pending_layer_->GetTwinTiling(tiling)->TileAt(iter.i(), iter.j());
+ Tile* twin_tile = pending_layer_->GetPendingOrActiveTwinTiling(tiling)
+ ->TileAt(iter.i(), iter.j());
gfx::Rect scaled_content_rect = ScaleToEnclosingRect(
tile->content_rect(), 1.0f / tile->contents_scale());
continue;
const Tile* tile = *iter;
- Tile* twin_tile =
- active_layer_->GetTwinTiling(tiling)->TileAt(iter.i(), iter.j());
+ Tile* twin_tile = active_layer_->GetPendingOrActiveTwinTiling(tiling)
+ ->TileAt(iter.i(), iter.j());
gfx::Rect scaled_content_rect = ScaleToEnclosingRect(
tile->content_rect(), 1.0f / tile->contents_scale());
for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
tiling->CreateAllTilesForTesting();
+ tiling->UpdateAllTilePrioritiesForTesting();
size_t occluded_tile_count_on_pending = 0u;
size_t occluded_tile_count_on_active = 0u;
for (size_t i = 0; i < active_layer_->num_tilings(); ++i) {
PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i);
tiling->CreateAllTilesForTesting();
+ tiling->UpdateAllTilePrioritiesForTesting();
size_t occluded_tile_count_on_pending = 0u;
size_t occluded_tile_count_on_active = 0u;
total_expected_occluded_tile_count);
}
+TEST_F(PictureLayerImplTest, PendingOrActiveTwinLayer) {
+ gfx::Size tile_size(102, 102);
+ gfx::Size layer_bounds(1000, 1000);
+
+ scoped_refptr<FakePicturePileImpl> pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ SetupPendingTree(pile);
+ EXPECT_FALSE(pending_layer_->GetPendingOrActiveTwinLayer());
+
+ ActivateTree();
+ EXPECT_FALSE(active_layer_->GetPendingOrActiveTwinLayer());
+
+ SetupPendingTree(pile);
+ EXPECT_TRUE(pending_layer_->GetPendingOrActiveTwinLayer());
+ EXPECT_TRUE(active_layer_->GetPendingOrActiveTwinLayer());
+ EXPECT_EQ(pending_layer_, active_layer_->GetPendingOrActiveTwinLayer());
+ EXPECT_EQ(active_layer_, pending_layer_->GetPendingOrActiveTwinLayer());
+
+ ActivateTree();
+ EXPECT_FALSE(active_layer_->GetPendingOrActiveTwinLayer());
+
+ // Make an empty pending tree.
+ host_impl_.CreatePendingTree();
+ host_impl_.pending_tree()->DetachLayerTree();
+ EXPECT_FALSE(active_layer_->GetPendingOrActiveTwinLayer());
+}
+
TEST_F(PictureLayerImplTest, RecycledTwinLayer) {
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
EXPECT_TRUE(active_layer_->GetRecycledTwinLayer());
EXPECT_EQ(old_pending_layer_, active_layer_->GetRecycledTwinLayer());
- host_impl_.ResetRecycleTreeForTesting();
+ // Make an empty pending tree.
+ host_impl_.CreatePendingTree();
+ host_impl_.pending_tree()->DetachLayerTree();
EXPECT_FALSE(active_layer_->GetRecycledTwinLayer());
}
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
}
- MockOcclusionTracker<LayerImpl> occlusion_tracker;
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
AppendQuadsData data;
- active_layer_->WillDraw(DRAW_MODE_SOFTWARE, NULL);
- active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
- active_layer_->DidDraw(NULL);
+ active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+ active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+ active_layer_->DidDraw(nullptr);
DrawQuad::Material expected = test_for_solid
? DrawQuad::Material::SOLID_COLOR
EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
}
+TEST_F(PictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) {
+ base::TimeTicks time_ticks;
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(time_ticks));
+
+ gfx::Size tile_size(100, 100);
+ gfx::Size layer_bounds(400, 4000);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+ SetupTrees(pending_pile, active_pile);
+
+ Region invalidation;
+ gfx::Rect viewport = gfx::Rect(0, 0, 100, 100);
+ gfx::Transform transform;
+
+ host_impl_.SetRequiresHighResToDraw();
+
+ // Update tiles.
+ pending_layer_->draw_properties().visible_content_rect = viewport;
+ pending_layer_->draw_properties().screen_space_transform = transform;
+ SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
+ pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+
+ // Ensure we can't activate.
+ EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
+
+ // Now in the same frame, move the viewport (this can happen during
+ // animation).
+ viewport = gfx::Rect(0, 2000, 100, 100);
+
+ // Update tiles.
+ pending_layer_->draw_properties().visible_content_rect = viewport;
+ pending_layer_->draw_properties().screen_space_transform = transform;
+ SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
+ pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+
+ // Make sure all viewport tiles (viewport from the tiling) are ready to draw.
+ std::vector<Tile*> tiles;
+ for (PictureLayerTiling::CoverageIterator iter(
+ pending_layer_->HighResTiling(),
+ 1.f,
+ pending_layer_->HighResTiling()->GetCurrentVisibleRectForTesting());
+ iter;
+ ++iter) {
+ if (*iter)
+ tiles.push_back(*iter);
+ }
+
+ host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
+
+ // Ensure we can activate.
+ EXPECT_TRUE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
+}
+
+class TileSizeSettings : public ImplSidePaintingSettings {
+ public:
+ TileSizeSettings() {
+ default_tile_size = gfx::Size(100, 100);
+ max_untiled_layer_size = gfx::Size(200, 200);
+ }
+};
+
+class TileSizeTest : public PictureLayerImplTest {
+ public:
+ TileSizeTest() : PictureLayerImplTest(TileSizeSettings()) {}
+};
+
+TEST_F(TileSizeTest, TileSizes) {
+ host_impl_.CreatePendingTree();
+
+ LayerTreeImpl* pending_tree = host_impl_.pending_tree();
+ scoped_ptr<FakePictureLayerImpl> layer =
+ FakePictureLayerImpl::Create(pending_tree, id_);
+
+ host_impl_.SetViewportSize(gfx::Size(1000, 1000));
+ gfx::Size result;
+
+ host_impl_.SetUseGpuRasterization(false);
+
+ // Default tile-size for large layers.
+ result = layer->CalculateTileSize(gfx::Size(10000, 10000));
+ EXPECT_EQ(result.width(), 100);
+ EXPECT_EQ(result.height(), 100);
+ // Don't tile and round-up, when under max_untiled_layer_size.
+ result = layer->CalculateTileSize(gfx::Size(42, 42));
+ EXPECT_EQ(result.width(), 64);
+ EXPECT_EQ(result.height(), 64);
+ result = layer->CalculateTileSize(gfx::Size(191, 191));
+ EXPECT_EQ(result.width(), 192);
+ EXPECT_EQ(result.height(), 192);
+ result = layer->CalculateTileSize(gfx::Size(199, 199));
+ EXPECT_EQ(result.width(), 200);
+ EXPECT_EQ(result.height(), 200);
+
+ // Gpu-rasterization uses 25% viewport-height tiles.
+ // The +2's below are for border texels.
+ host_impl_.SetUseGpuRasterization(true);
+ host_impl_.SetViewportSize(gfx::Size(2000, 2000));
+ result = layer->CalculateTileSize(gfx::Size(10000, 10000));
+ EXPECT_EQ(result.width(), 2000);
+ EXPECT_EQ(result.height(), 500 + 2);
+
+ // Clamp and round-up, when smaller than viewport.
+ // Tile-height doubles to 50% when width shrinks to <= 50%.
+ host_impl_.SetViewportSize(gfx::Size(1000, 1000));
+ result = layer->CalculateTileSize(gfx::Size(447, 10000));
+ EXPECT_EQ(result.width(), 448);
+ EXPECT_EQ(result.height(), 500 + 2);
+
+ // Largest layer is 50% of viewport width (rounded up), and
+ // 50% of viewport in height.
+ result = layer->CalculateTileSize(gfx::Size(447, 400));
+ EXPECT_EQ(result.width(), 448);
+ EXPECT_EQ(result.height(), 448);
+ result = layer->CalculateTileSize(gfx::Size(500, 499));
+ EXPECT_EQ(result.width(), 512);
+ EXPECT_EQ(result.height(), 500 + 2);
+}
+
} // namespace
} // namespace cc