Commit 9f350118 authored by reveman@chromium.org's avatar reveman@chromium.org

cc: Examine layers to determine if we're ready to activate.

This introduces a new mechanism for determining when
we're ready to activate the pending tree. The tile
priority is still used to determine when it's worth
waking up the compositor thread and evaluating if
we can activate. However, the actual check that
determines if we're ready to activate doesn't rely
on the state of scheduled raster tasks but is a
synchronous call on each layer.

The result is a pending tree activation mechanism that
is much easier to debug and validate for correctness,
while still providing the performance benefits of the
old mechanism by taking the "required to activate" field
of the tile priority into account when scheduling tasks.
 
BUG=375206
TEST=cc_unittests --gtest_filter=PictureLayerImplTest.AllTilesRequiredForActivationAreReadyToDraw

Review URL: https://codereview.chromium.org/287643004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272635 0039d316-1c4b-4281-b951-d872f2087c98
parent 048b61c2
...@@ -188,7 +188,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, ...@@ -188,7 +188,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
virtual RenderPass::Id NextContributingRenderPassId(RenderPass::Id id) const; virtual RenderPass::Id NextContributingRenderPassId(RenderPass::Id id) const;
virtual void UpdateTilePriorities() {} virtual void UpdateTilePriorities() {}
virtual void NotifyTileInitialized(const Tile* tile) {} virtual void NotifyTileStateChanged(const Tile* tile) {}
virtual ScrollbarLayerImplBase* ToScrollbarLayer(); virtual ScrollbarLayerImplBase* ToScrollbarLayer();
......
...@@ -233,7 +233,8 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink, ...@@ -233,7 +233,8 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
// unused can be considered for removal. // unused can be considered for removal.
std::vector<PictureLayerTiling*> seen_tilings; std::vector<PictureLayerTiling*> seen_tilings;
bool had_checkerboard_quads = false; size_t missing_tile_count = 0u;
size_t on_demand_missing_tile_count = 0u;
for (PictureLayerTilingSet::CoverageIterator iter( for (PictureLayerTilingSet::CoverageIterator iter(
tilings_.get(), contents_scale_x(), rect, ideal_contents_scale_); tilings_.get(), contents_scale_x(), rect, ideal_contents_scale_);
iter; iter;
...@@ -247,8 +248,75 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink, ...@@ -247,8 +248,75 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
append_quads_data->visible_content_area += append_quads_data->visible_content_area +=
visible_geometry_rect.width() * visible_geometry_rect.height(); visible_geometry_rect.width() * visible_geometry_rect.height();
if (!*iter || !iter->IsReadyToDraw()) { scoped_ptr<DrawQuad> draw_quad;
had_checkerboard_quads = true; if (*iter && iter->IsReadyToDraw()) {
const ManagedTileState::TileVersion& tile_version =
iter->GetTileVersionForDrawing();
switch (tile_version.mode()) {
case ManagedTileState::TileVersion::RESOURCE_MODE: {
gfx::RectF texture_rect = iter.texture_rect();
gfx::Rect opaque_rect = iter->opaque_rect();
opaque_rect.Intersect(geometry_rect);
if (iter->contents_scale() != ideal_contents_scale_)
append_quads_data->had_incomplete_tile = true;
scoped_ptr<TileDrawQuad> quad = TileDrawQuad::Create();
quad->SetNew(shared_quad_state,
geometry_rect,
opaque_rect,
visible_geometry_rect,
tile_version.get_resource_id(),
texture_rect,
iter.texture_size(),
tile_version.contents_swizzled());
draw_quad = quad.PassAs<DrawQuad>();
break;
}
case ManagedTileState::TileVersion::PICTURE_PILE_MODE: {
if (!layer_tree_impl()
->GetRendererCapabilities()
.allow_rasterize_on_demand) {
++on_demand_missing_tile_count;
break;
}
gfx::RectF texture_rect = iter.texture_rect();
gfx::Rect opaque_rect = iter->opaque_rect();
opaque_rect.Intersect(geometry_rect);
ResourceProvider* resource_provider =
layer_tree_impl()->resource_provider();
ResourceFormat format =
resource_provider->memory_efficient_texture_format();
scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
quad->SetNew(shared_quad_state,
geometry_rect,
opaque_rect,
visible_geometry_rect,
texture_rect,
iter.texture_size(),
format,
iter->content_rect(),
iter->contents_scale(),
pile_);
draw_quad = quad.PassAs<DrawQuad>();
break;
}
case ManagedTileState::TileVersion::SOLID_COLOR_MODE: {
scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
quad->SetNew(shared_quad_state,
geometry_rect,
visible_geometry_rect,
tile_version.get_solid_color(),
false);
draw_quad = quad.PassAs<DrawQuad>();
break;
}
}
}
if (!draw_quad) {
if (draw_checkerboard_for_missing_tiles()) { if (draw_checkerboard_for_missing_tiles()) {
scoped_ptr<CheckerboardDrawQuad> quad = CheckerboardDrawQuad::Create(); scoped_ptr<CheckerboardDrawQuad> quad = CheckerboardDrawQuad::Create();
SkColor color = DebugColors::DefaultCheckerboardColor(); SkColor color = DebugColors::DefaultCheckerboardColor();
...@@ -270,69 +338,10 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink, ...@@ -270,69 +338,10 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
append_quads_data->had_incomplete_tile = true; append_quads_data->had_incomplete_tile = true;
append_quads_data->approximated_visible_content_area += append_quads_data->approximated_visible_content_area +=
visible_geometry_rect.width() * visible_geometry_rect.height(); visible_geometry_rect.width() * visible_geometry_rect.height();
++missing_tile_count;
continue; continue;
} }
const ManagedTileState::TileVersion& tile_version =
iter->GetTileVersionForDrawing();
scoped_ptr<DrawQuad> draw_quad;
switch (tile_version.mode()) {
case ManagedTileState::TileVersion::RESOURCE_MODE: {
gfx::RectF texture_rect = iter.texture_rect();
gfx::Rect opaque_rect = iter->opaque_rect();
opaque_rect.Intersect(geometry_rect);
if (iter->contents_scale() != ideal_contents_scale_)
append_quads_data->had_incomplete_tile = true;
scoped_ptr<TileDrawQuad> quad = TileDrawQuad::Create();
quad->SetNew(shared_quad_state,
geometry_rect,
opaque_rect,
visible_geometry_rect,
tile_version.get_resource_id(),
texture_rect,
iter.texture_size(),
tile_version.contents_swizzled());
draw_quad = quad.PassAs<DrawQuad>();
break;
}
case ManagedTileState::TileVersion::PICTURE_PILE_MODE: {
gfx::RectF texture_rect = iter.texture_rect();
gfx::Rect opaque_rect = iter->opaque_rect();
opaque_rect.Intersect(geometry_rect);
ResourceProvider* resource_provider =
layer_tree_impl()->resource_provider();
ResourceFormat format =
resource_provider->memory_efficient_texture_format();
scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
quad->SetNew(shared_quad_state,
geometry_rect,
opaque_rect,
visible_geometry_rect,
texture_rect,
iter.texture_size(),
format,
iter->content_rect(),
iter->contents_scale(),
pile_);
draw_quad = quad.PassAs<DrawQuad>();
break;
}
case ManagedTileState::TileVersion::SOLID_COLOR_MODE: {
scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
quad->SetNew(shared_quad_state,
geometry_rect,
visible_geometry_rect,
tile_version.get_solid_color(),
false);
draw_quad = quad.PassAs<DrawQuad>();
break;
}
}
DCHECK(draw_quad);
quad_sink->Append(draw_quad.Pass()); quad_sink->Append(draw_quad.Pass());
if (iter->priority(ACTIVE_TREE).resolution != HIGH_RESOLUTION) { if (iter->priority(ACTIVE_TREE).resolution != HIGH_RESOLUTION) {
...@@ -344,10 +353,14 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink, ...@@ -344,10 +353,14 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
seen_tilings.push_back(iter.CurrentTiling()); seen_tilings.push_back(iter.CurrentTiling());
} }
if (had_checkerboard_quads) { if (missing_tile_count) {
TRACE_EVENT_INSTANT0("cc", TRACE_EVENT_INSTANT2("cc",
"PictureLayerImpl::AppendQuads checkerboard", "PictureLayerImpl::AppendQuads checkerboard",
TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_SCOPE_THREAD,
"missing_tile_count",
missing_tile_count,
"on_demand_missing_tile_count",
on_demand_missing_tile_count);
} }
// Aggressively remove any tilings that are not seen to save memory. Note // Aggressively remove any tilings that are not seen to save memory. Note
...@@ -429,7 +442,7 @@ void PictureLayerImpl::UpdateTilePriorities() { ...@@ -429,7 +442,7 @@ void PictureLayerImpl::UpdateTilePriorities() {
layer_tree_impl()->DidModifyTilePriorities(); layer_tree_impl()->DidModifyTilePriorities();
} }
void PictureLayerImpl::NotifyTileInitialized(const Tile* tile) { void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) {
if (layer_tree_impl()->IsActiveTree()) { if (layer_tree_impl()->IsActiveTree()) {
gfx::RectF layer_damage_rect = gfx::RectF layer_damage_rect =
gfx::ScaleRect(tile->content_rect(), 1.f / tile->contents_scale()); gfx::ScaleRect(tile->content_rect(), 1.f / tile->contents_scale());
...@@ -1354,6 +1367,37 @@ bool PictureLayerImpl::IsOnActiveOrPendingTree() const { ...@@ -1354,6 +1367,37 @@ bool PictureLayerImpl::IsOnActiveOrPendingTree() const {
return !layer_tree_impl()->IsRecycleTree(); return !layer_tree_impl()->IsRecycleTree();
} }
bool PictureLayerImpl::AllTilesRequiredForActivationAreReadyToDraw() const {
if (!layer_tree_impl()->IsPendingTree())
return true;
if (!tilings_)
return true;
for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
PictureLayerTiling* tiling = tilings_->tiling_at(i);
if (tiling->resolution() != HIGH_RESOLUTION &&
tiling->resolution() != LOW_RESOLUTION)
continue;
gfx::Rect rect(visible_content_rect());
for (PictureLayerTiling::CoverageIterator iter(
tiling, contents_scale_x(), rect);
iter;
++iter) {
const Tile* tile = *iter;
// A null tile (i.e. missing recording) can just be skipped.
if (!tile)
continue;
if (tile->required_for_activation() && !tile->IsReadyToDraw())
return false;
}
}
return true;
}
PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator() PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator()
: layer_(NULL) {} : layer_(NULL) {}
......
...@@ -92,7 +92,7 @@ class CC_EXPORT PictureLayerImpl ...@@ -92,7 +92,7 @@ class CC_EXPORT PictureLayerImpl
virtual void AppendQuads(QuadSink* quad_sink, virtual void AppendQuads(QuadSink* quad_sink,
AppendQuadsData* append_quads_data) OVERRIDE; AppendQuadsData* append_quads_data) OVERRIDE;
virtual void UpdateTilePriorities() OVERRIDE; virtual void UpdateTilePriorities() OVERRIDE;
virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE; virtual void NotifyTileStateChanged(const Tile* tile) OVERRIDE;
virtual void DidBecomeActive() OVERRIDE; virtual void DidBecomeActive() OVERRIDE;
virtual void DidBeginTracing() OVERRIDE; virtual void DidBeginTracing() OVERRIDE;
virtual void ReleaseResources() OVERRIDE; virtual void ReleaseResources() OVERRIDE;
...@@ -136,6 +136,7 @@ class CC_EXPORT PictureLayerImpl ...@@ -136,6 +136,7 @@ class CC_EXPORT PictureLayerImpl
PictureLayerImpl* GetTwinLayer() { return twin_layer_; } PictureLayerImpl* GetTwinLayer() { return twin_layer_; }
WhichTree GetTree() const; WhichTree GetTree() const;
bool IsOnActiveOrPendingTree() const; bool IsOnActiveOrPendingTree() const;
bool AllTilesRequiredForActivationAreReadyToDraw() const;
protected: protected:
friend class LayerRasterTileIterator; friend class LayerRasterTileIterator;
......
...@@ -2391,5 +2391,61 @@ TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) { ...@@ -2391,5 +2391,61 @@ TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) {
EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f); EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f);
} }
TEST_F(PictureLayerImplTest, LowResReadyToDrawNotEnoughToActivate) {
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
// Make sure some tiles are not shared.
pending_layer_->set_invalidation(gfx::Rect(gfx::Point(50, 50), tile_size));
CreateHighLowResAndSetAllTilesVisible();
active_layer_->SetAllTilesReady();
pending_layer_->MarkVisibleResourcesAsRequired();
// All pending layer tiles required are not ready.
EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
// Initialize all low-res tiles.
pending_layer_->SetAllTilesReadyInTiling(pending_layer_->LowResTiling());
// Low-res tiles should not be enough.
EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
// Initialize remaining tiles.
pending_layer_->SetAllTilesReady();
EXPECT_TRUE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
}
TEST_F(PictureLayerImplTest, HighResReadyToDrawNotEnoughToActivate) {
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
// Make sure some tiles are not shared.
pending_layer_->set_invalidation(gfx::Rect(gfx::Point(50, 50), tile_size));
CreateHighLowResAndSetAllTilesVisible();
active_layer_->SetAllTilesReady();
pending_layer_->MarkVisibleResourcesAsRequired();
// All pending layer tiles required are not ready.
EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
// Initialize all high-res tiles.
pending_layer_->SetAllTilesReadyInTiling(pending_layer_->HighResTiling());
// High-res tiles should not be enough.
EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
// Initialize remaining tiles.
pending_layer_->SetAllTilesReady();
EXPECT_TRUE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
}
} // namespace } // namespace
} // namespace cc } // namespace cc
...@@ -365,24 +365,25 @@ scoped_ptr<base::Value> RasterTaskCompletionStatsAsValue( ...@@ -365,24 +365,25 @@ scoped_ptr<base::Value> RasterTaskCompletionStatsAsValue(
// static // static
scoped_ptr<TileManager> TileManager::Create( scoped_ptr<TileManager> TileManager::Create(
TileManagerClient* client, TileManagerClient* client,
base::SequencedTaskRunner* task_runner,
ResourcePool* resource_pool, ResourcePool* resource_pool,
Rasterizer* rasterizer, Rasterizer* rasterizer,
bool use_rasterize_on_demand,
RenderingStatsInstrumentation* rendering_stats_instrumentation) { RenderingStatsInstrumentation* rendering_stats_instrumentation) {
return make_scoped_ptr(new TileManager(client, return make_scoped_ptr(new TileManager(client,
task_runner,
resource_pool, resource_pool,
rasterizer, rasterizer,
use_rasterize_on_demand,
rendering_stats_instrumentation)); rendering_stats_instrumentation));
} }
TileManager::TileManager( TileManager::TileManager(
TileManagerClient* client, TileManagerClient* client,
base::SequencedTaskRunner* task_runner,
ResourcePool* resource_pool, ResourcePool* resource_pool,
Rasterizer* rasterizer, Rasterizer* rasterizer,
bool use_rasterize_on_demand,
RenderingStatsInstrumentation* rendering_stats_instrumentation) RenderingStatsInstrumentation* rendering_stats_instrumentation)
: client_(client), : client_(client),
task_runner_(task_runner),
resource_pool_(resource_pool), resource_pool_(resource_pool),
rasterizer_(rasterizer), rasterizer_(rasterizer),
prioritized_tiles_dirty_(false), prioritized_tiles_dirty_(false),
...@@ -396,7 +397,8 @@ TileManager::TileManager( ...@@ -396,7 +397,8 @@ TileManager::TileManager(
rendering_stats_instrumentation_(rendering_stats_instrumentation), rendering_stats_instrumentation_(rendering_stats_instrumentation),
did_initialize_visible_tile_(false), did_initialize_visible_tile_(false),
did_check_for_completed_tasks_since_last_schedule_tasks_(true), did_check_for_completed_tasks_since_last_schedule_tasks_(true),
use_rasterize_on_demand_(use_rasterize_on_demand) { check_if_ready_to_activate_pending_(false),
weak_ptr_factory_(this) {
rasterizer_->SetClient(this); rasterizer_->SetClient(this);
} }
...@@ -528,12 +530,14 @@ void TileManager::DidFinishRunningTasks() { ...@@ -528,12 +530,14 @@ void TileManager::DidFinishRunningTasks() {
// If we can't raster on demand, give up early (and don't activate). // If we can't raster on demand, give up early (and don't activate).
if (!allow_rasterize_on_demand) if (!allow_rasterize_on_demand)
return; return;
if (use_rasterize_on_demand_)
tile_version.set_rasterize_on_demand(); tile_version.set_rasterize_on_demand();
client_->NotifyTileStateChanged(tile);
} }
} }
client_->NotifyReadyToActivate(); DCHECK(IsReadyToActivate());
ScheduleCheckIfReadyToActivate();
} }
void TileManager::DidFinishRunningTasksRequiredForActivation() { void TileManager::DidFinishRunningTasksRequiredForActivation() {
...@@ -545,7 +549,7 @@ void TileManager::DidFinishRunningTasksRequiredForActivation() { ...@@ -545,7 +549,7 @@ void TileManager::DidFinishRunningTasksRequiredForActivation() {
if (!all_tiles_required_for_activation_have_memory_) if (!all_tiles_required_for_activation_have_memory_)
return; return;
client_->NotifyReadyToActivate(); ScheduleCheckIfReadyToActivate();
} }
void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) {
...@@ -664,7 +668,7 @@ void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { ...@@ -664,7 +668,7 @@ void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) {
// can visit it. // can visit it.
if (mts.bin == NEVER_BIN && if (mts.bin == NEVER_BIN &&
!mts.tile_versions[mts.raster_mode].raster_task_) { !mts.tile_versions[mts.raster_mode].raster_task_) {
FreeResourcesForTile(tile); FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
continue; continue;
} }
...@@ -853,7 +857,7 @@ void TileManager::AssignGpuMemoryToTiles( ...@@ -853,7 +857,7 @@ void TileManager::AssignGpuMemoryToTiles(
// If the tile is not needed, free it up. // If the tile is not needed, free it up.
if (mts.bin == NEVER_BIN) { if (mts.bin == NEVER_BIN) {
FreeResourcesForTile(tile); FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
continue; continue;
} }
...@@ -895,14 +899,19 @@ void TileManager::AssignGpuMemoryToTiles( ...@@ -895,14 +899,19 @@ void TileManager::AssignGpuMemoryToTiles(
// Tile is OOM. // Tile is OOM.
if (tile_bytes > tile_bytes_left || tile_resources > resources_left) { if (tile_bytes > tile_bytes_left || tile_resources > resources_left) {
bool was_ready_to_draw = tile->IsReadyToDraw();
FreeResourcesForTile(tile); FreeResourcesForTile(tile);
// This tile was already on screen and now its resources have been // This tile was already on screen and now its resources have been
// released. In order to prevent checkerboarding, set this tile as // released. In order to prevent checkerboarding, set this tile as
// rasterize on demand immediately. // rasterize on demand immediately.
if (mts.visible_and_ready_to_draw && use_rasterize_on_demand_) if (mts.visible_and_ready_to_draw)
tile_version.set_rasterize_on_demand(); tile_version.set_rasterize_on_demand();
if (was_ready_to_draw)
client_->NotifyTileStateChanged(tile);
oomed_soft = true; oomed_soft = true;
if (tile_uses_hard_limit) { if (tile_uses_hard_limit) {
oomed_hard = true; oomed_hard = true;
...@@ -997,6 +1006,14 @@ void TileManager::FreeUnusedResourcesForTile(Tile* tile) { ...@@ -997,6 +1006,14 @@ void TileManager::FreeUnusedResourcesForTile(Tile* tile) {
} }
} }
void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(
Tile* tile) {
bool was_ready_to_draw = tile->IsReadyToDraw();
FreeResourcesForTile(tile);
if (was_ready_to_draw)
client_->NotifyTileStateChanged(tile);
}
void TileManager::ScheduleTasks( void TileManager::ScheduleTasks(
const TileVector& tiles_that_need_to_be_rasterized) { const TileVector& tiles_that_need_to_be_rasterized) {
TRACE_EVENT1("cc", TRACE_EVENT1("cc",
...@@ -1189,11 +1206,11 @@ void TileManager::OnRasterTaskCompleted( ...@@ -1189,11 +1206,11 @@ void TileManager::OnRasterTaskCompleted(
++resources_releasable_; ++resources_releasable_;
} }
client_->NotifyTileInitialized(tile);
FreeUnusedResourcesForTile(tile); FreeUnusedResourcesForTile(tile);
if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f) if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f)
did_initialize_visible_tile_ = true; did_initialize_visible_tile_ = true;
client_->NotifyTileStateChanged(tile);
} }
scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile,
...@@ -1627,4 +1644,38 @@ void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) { ...@@ -1627,4 +1644,38 @@ void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) {
rasterizer_->SetClient(this); rasterizer_->SetClient(this);
} }
bool TileManager::IsReadyToActivate() const {
for (std::vector<PictureLayerImpl*>::const_iterator it = layers_.begin();
it != layers_.end();
++it) {
if (!(*it)->AllTilesRequiredForActivationAreReadyToDraw())
return false;
}
return true;
}
void TileManager::ScheduleCheckIfReadyToActivate() {
if (check_if_ready_to_activate_pending_)
return;
task_runner_->PostTask(FROM_HERE,
base::Bind(&TileManager::CheckIfReadyToActivate,
weak_ptr_factory_.GetWeakPtr()));
check_if_ready_to_activate_pending_ = true;
}
void TileManager::CheckIfReadyToActivate() {
TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate");
DCHECK(check_if_ready_to_activate_pending_);
check_if_ready_to_activate_pending_ = false;
rasterizer_->CheckForCompletedTasks();
did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
if (IsReadyToActivate())
client_->NotifyReadyToActivate();
}
} // namespace cc } // namespace cc
...@@ -30,8 +30,15 @@ class ResourceProvider; ...@@ -30,8 +30,15 @@ class ResourceProvider;
class CC_EXPORT TileManagerClient { class CC_EXPORT TileManagerClient {
public: public:
// Called when all tiles marked as required for activation are ready to draw.
virtual void NotifyReadyToActivate() = 0; virtual void NotifyReadyToActivate() = 0;
virtual void NotifyTileInitialized(const Tile* tile) = 0;
// Called when the visible representation of a tile might have changed. Some
// examples are:
// - Tile version initialized.
// - Tile resources freed.
// - Tile marked for on-demand raster.
virtual void NotifyTileStateChanged(const Tile* tile) = 0;
protected: protected:
virtual ~TileManagerClient() {} virtual ~TileManagerClient() {}
...@@ -154,9 +161,9 @@ class CC_EXPORT TileManager : public RasterizerClient, ...@@ -154,9 +161,9 @@ class CC_EXPORT TileManager : public RasterizerClient,
static scoped_ptr<TileManager> Create( static scoped_ptr<TileManager> Create(
TileManagerClient* client, TileManagerClient* client,
base::SequencedTaskRunner* task_runner,
ResourcePool* resource_pool, ResourcePool* resource_pool,
Rasterizer* rasterizer, Rasterizer* rasterizer,
bool use_rasterize_on_demand,
RenderingStatsInstrumentation* rendering_stats_instrumentation); RenderingStatsInstrumentation* rendering_stats_instrumentation);
virtual ~TileManager(); virtual ~TileManager();
...@@ -228,9 +235,9 @@ class CC_EXPORT TileManager : public RasterizerClient, ...@@ -228,9 +235,9 @@ class CC_EXPORT TileManager : public RasterizerClient,
protected: protected:
TileManager(TileManagerClient* client, TileManager(TileManagerClient* client,
base::SequencedTaskRunner* task_runner,
ResourcePool* resource_pool, ResourcePool* resource_pool,
Rasterizer* rasterizer, Rasterizer* rasterizer,
bool use_rasterize_on_demand,
RenderingStatsInstrumentation* rendering_stats_instrumentation); RenderingStatsInstrumentation* rendering_stats_instrumentation);
// Methods called by Tile // Methods called by Tile
...@@ -276,6 +283,7 @@ class CC_EXPORT TileManager : public RasterizerClient, ...@@ -276,6 +283,7 @@ class CC_EXPORT TileManager : public RasterizerClient,
void FreeResourceForTile(Tile* tile, RasterMode mode); void FreeResourceForTile(Tile* tile, RasterMode mode);
void FreeResourcesForTile(Tile* tile); void FreeResourcesForTile(Tile* tile);
void FreeUnusedResourcesForTile(Tile* tile); void FreeUnusedResourcesForTile(Tile* tile);
void FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(Tile* tile);
scoped_refptr<ImageDecodeTask> CreateImageDecodeTask(Tile* tile, scoped_refptr<ImageDecodeTask> CreateImageDecodeTask(Tile* tile,
SkPixelRef* pixel_ref); SkPixelRef* pixel_ref);
scoped_refptr<RasterTask> CreateRasterTask(Tile* tile); scoped_refptr<RasterTask> CreateRasterTask(Tile* tile);
...@@ -283,7 +291,12 @@ class CC_EXPORT TileManager : public RasterizerClient, ...@@ -283,7 +291,12 @@ class CC_EXPORT TileManager : public RasterizerClient,
void UpdatePrioritizedTileSetIfNeeded(); void UpdatePrioritizedTileSetIfNeeded();
void CleanUpLayers(); void CleanUpLayers();
bool IsReadyToActivate() const;
void ScheduleCheckIfReadyToActivate();
void CheckIfReadyToActivate();
TileManagerClient* client_; TileManagerClient* client_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
ResourcePool* resource_pool_; ResourcePool* resource_pool_;
Rasterizer* rasterizer_; Rasterizer* rasterizer_;
GlobalStateThatImpactsTilePriority global_state_; GlobalStateThatImpactsTilePriority global_state_;
...@@ -323,8 +336,6 @@ class CC_EXPORT TileManager : public RasterizerClient, ...@@ -323,8 +336,6 @@ class CC_EXPORT TileManager : public RasterizerClient,
std::vector<Tile*> released_tiles_; std::vector<Tile*> released_tiles_;
bool use_rasterize_on_demand_;
ResourceFormat resource_format_; ResourceFormat resource_format_;
// Queue used when scheduling raster tasks. // Queue used when scheduling raster tasks.
...@@ -334,6 +345,10 @@ class CC_EXPORT TileManager : public RasterizerClient, ...@@ -334,6 +345,10 @@ class CC_EXPORT TileManager : public RasterizerClient,
std::vector<PictureLayerImpl*> layers_; std::vector<PictureLayerImpl*> layers_;
bool check_if_ready_to_activate_pending_;
base::WeakPtrFactory<TileManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(TileManager); DISALLOW_COPY_AND_ASSIGN(TileManager);
}; };
......
...@@ -293,7 +293,7 @@ class TileManagerPerfTest : public testing::Test, public TileManagerClient { ...@@ -293,7 +293,7 @@ class TileManagerPerfTest : public testing::Test, public TileManagerClient {
// TileManagerClient implementation. // TileManagerClient implementation.
virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; } virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; }
virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE {} virtual void NotifyTileStateChanged(const Tile* tile) OVERRIDE {}
TileManager* tile_manager() { return host_impl_.tile_manager(); } TileManager* tile_manager() { return host_impl_.tile_manager(); }
......
...@@ -32,8 +32,7 @@ class TileManagerTest : public testing::TestWithParam<bool>, ...@@ -32,8 +32,7 @@ class TileManagerTest : public testing::TestWithParam<bool>,
void Initialize(int max_tiles, void Initialize(int max_tiles,
TileMemoryLimitPolicy memory_limit_policy, TileMemoryLimitPolicy memory_limit_policy,
TreePriority tree_priority, TreePriority tree_priority) {
bool allow_on_demand_raster = true) {
output_surface_ = FakeOutputSurface::Create3d(); output_surface_ = FakeOutputSurface::Create3d();
CHECK(output_surface_->BindToClient(&output_surface_client_)); CHECK(output_surface_->BindToClient(&output_surface_client_));
...@@ -43,8 +42,8 @@ class TileManagerTest : public testing::TestWithParam<bool>, ...@@ -43,8 +42,8 @@ class TileManagerTest : public testing::TestWithParam<bool>,
false); false);
resource_pool_ = ResourcePool::Create( resource_pool_ = ResourcePool::Create(
resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888); resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888);
tile_manager_ = make_scoped_ptr(new FakeTileManager( tile_manager_ =
this, resource_pool_.get(), allow_on_demand_raster)); make_scoped_ptr(new FakeTileManager(this, resource_pool_.get()));
memory_limit_policy_ = memory_limit_policy; memory_limit_policy_ = memory_limit_policy;
max_tiles_ = max_tiles; max_tiles_ = max_tiles;
...@@ -85,7 +84,7 @@ class TileManagerTest : public testing::TestWithParam<bool>, ...@@ -85,7 +84,7 @@ class TileManagerTest : public testing::TestWithParam<bool>,
// TileManagerClient implementation. // TileManagerClient implementation.
virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; } virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; }
virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE {} virtual void NotifyTileStateChanged(const Tile* tile) OVERRIDE {}
TileVector CreateTilesWithSize(int count, TileVector CreateTilesWithSize(int count,
TilePriority active_priority, TilePriority active_priority,
...@@ -614,40 +613,6 @@ TEST_P(TileManagerTest, RespectMemoryLimit) { ...@@ -614,40 +613,6 @@ TEST_P(TileManagerTest, RespectMemoryLimit) {
EXPECT_LE(memory_allocated_bytes, global_state_.hard_memory_limit_in_bytes); EXPECT_LE(memory_allocated_bytes, global_state_.hard_memory_limit_in_bytes);
} }
TEST_P(TileManagerTest, AllowRasterizeOnDemand) {
// Not enough memory to initialize tiles required for activation.
Initialize(0, ALLOW_ANYTHING, SAME_PRIORITY_FOR_BOTH_TREES);
TileVector tiles =
CreateTiles(2, TilePriority(), TilePriorityRequiredForActivation());
tile_manager()->AssignMemoryToTiles(global_state_);
// This should make required tiles ready to draw by marking them as
// required tiles for on-demand raster.
tile_manager()->DidFinishRunningTasksForTesting();
EXPECT_TRUE(ready_to_activate());
for (TileVector::iterator it = tiles.begin(); it != tiles.end(); ++it)
EXPECT_TRUE((*it)->IsReadyToDraw());
}
TEST_P(TileManagerTest, PreventRasterizeOnDemand) {
// Not enough memory to initialize tiles required for activation.
Initialize(0, ALLOW_ANYTHING, SAME_PRIORITY_FOR_BOTH_TREES, false);
TileVector tiles =
CreateTiles(2, TilePriority(), TilePriorityRequiredForActivation());
tile_manager()->AssignMemoryToTiles(global_state_);
// This should make required tiles ready to draw by marking them as
// required tiles for on-demand raster.
tile_manager()->DidFinishRunningTasksForTesting();
EXPECT_TRUE(ready_to_activate());
for (TileVector::iterator it = tiles.begin(); it != tiles.end(); ++it)
EXPECT_FALSE((*it)->IsReadyToDraw());
}
// If true, the max tile limit should be applied as bytes; if false, // If true, the max tile limit should be applied as bytes; if false,
// as num_resources_limit. // as num_resources_limit.
INSTANTIATE_TEST_CASE_P(TileManagerTests, INSTANTIATE_TEST_CASE_P(TileManagerTests,
...@@ -754,7 +719,7 @@ class TileManagerTileIteratorTest : public testing::Test, ...@@ -754,7 +719,7 @@ class TileManagerTileIteratorTest : public testing::Test,
// TileManagerClient implementation. // TileManagerClient implementation.
virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; } virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; }
virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE {} virtual void NotifyTileStateChanged(const Tile* tile) OVERRIDE {}
TileManager* tile_manager() { return host_impl_.tile_manager(); } TileManager* tile_manager() { return host_impl_.tile_manager(); }
......
...@@ -63,26 +63,17 @@ base::LazyInstance<FakeRasterizerImpl> g_fake_rasterizer = ...@@ -63,26 +63,17 @@ base::LazyInstance<FakeRasterizerImpl> g_fake_rasterizer =
FakeTileManager::FakeTileManager(TileManagerClient* client) FakeTileManager::FakeTileManager(TileManagerClient* client)
: TileManager(client, : TileManager(client,
base::MessageLoopProxy::current(),
NULL, NULL,
g_fake_rasterizer.Pointer(), g_fake_rasterizer.Pointer(),
true,
NULL) {} NULL) {}
FakeTileManager::FakeTileManager(TileManagerClient* client, FakeTileManager::FakeTileManager(TileManagerClient* client,
ResourcePool* resource_pool) ResourcePool* resource_pool)
: TileManager(client, : TileManager(client,
base::MessageLoopProxy::current(),
resource_pool, resource_pool,
g_fake_rasterizer.Pointer(), g_fake_rasterizer.Pointer(),
true,
NULL) {}
FakeTileManager::FakeTileManager(TileManagerClient* client,
ResourcePool* resource_pool,
bool allow_on_demand_raster)
: TileManager(client,
resource_pool,
g_fake_rasterizer.Pointer(),
allow_on_demand_raster,
NULL) {} NULL) {}
FakeTileManager::~FakeTileManager() {} FakeTileManager::~FakeTileManager() {}
......
...@@ -16,9 +16,6 @@ class FakeTileManager : public TileManager { ...@@ -16,9 +16,6 @@ class FakeTileManager : public TileManager {
public: public:
explicit FakeTileManager(TileManagerClient* client); explicit FakeTileManager(TileManagerClient* client);
FakeTileManager(TileManagerClient* client, ResourcePool* resource_pool); FakeTileManager(TileManagerClient* client, ResourcePool* resource_pool);
FakeTileManager(TileManagerClient* client,
ResourcePool* resource_pool,
bool allow_on_demand_raster);
virtual ~FakeTileManager(); virtual ~FakeTileManager();
bool HasBeenAssignedMemory(Tile* tile); bool HasBeenAssignedMemory(Tile* tile);
......
...@@ -15,7 +15,7 @@ class FakeTileManagerClient : public TileManagerClient { ...@@ -15,7 +15,7 @@ class FakeTileManagerClient : public TileManagerClient {
// TileManagerClient implementation. // TileManagerClient implementation.
virtual void NotifyReadyToActivate() OVERRIDE {} virtual void NotifyReadyToActivate() OVERRIDE {}
virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE {} virtual void NotifyTileStateChanged(const Tile* tile) OVERRIDE {}
}; };
} // namespace cc } // namespace cc
......
...@@ -1240,21 +1240,21 @@ void LayerTreeHostImpl::NotifyReadyToActivate() { ...@@ -1240,21 +1240,21 @@ void LayerTreeHostImpl::NotifyReadyToActivate() {
client_->NotifyReadyToActivate(); client_->NotifyReadyToActivate();
} }
void LayerTreeHostImpl::NotifyTileInitialized(const Tile* tile) { void LayerTreeHostImpl::NotifyTileStateChanged(const Tile* tile) {
TRACE_EVENT0("cc", "LayerTreeHostImpl::NotifyTileInitialized"); TRACE_EVENT0("cc", "LayerTreeHostImpl::NotifyTileStateChanged");
if (active_tree_) { if (active_tree_) {
LayerImpl* layer_impl = LayerImpl* layer_impl =
active_tree_->FindActiveTreeLayerById(tile->layer_id()); active_tree_->FindActiveTreeLayerById(tile->layer_id());
if (layer_impl) if (layer_impl)
layer_impl->NotifyTileInitialized(tile); layer_impl->NotifyTileStateChanged(tile);
} }
if (pending_tree_) { if (pending_tree_) {
LayerImpl* layer_impl = LayerImpl* layer_impl =
pending_tree_->FindPendingTreeLayerById(tile->layer_id()); pending_tree_->FindPendingTreeLayerById(tile->layer_id());
if (layer_impl) if (layer_impl)
layer_impl->NotifyTileInitialized(tile); layer_impl->NotifyTileStateChanged(tile);
} }
} }
...@@ -1922,9 +1922,9 @@ void LayerTreeHostImpl::CreateAndSetTileManager() { ...@@ -1922,9 +1922,9 @@ void LayerTreeHostImpl::CreateAndSetTileManager() {
tile_manager_ = tile_manager_ =
TileManager::Create(this, TileManager::Create(this,
proxy_->ImplThreadTaskRunner(),
resource_pool_.get(), resource_pool_.get(),
raster_worker_pool_->AsRasterizer(), raster_worker_pool_->AsRasterizer(),
GetRendererCapabilities().allow_rasterize_on_demand,
rendering_stats_instrumentation_); rendering_stats_instrumentation_);
UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy()); UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy());
......
...@@ -232,7 +232,7 @@ class CC_EXPORT LayerTreeHostImpl ...@@ -232,7 +232,7 @@ class CC_EXPORT LayerTreeHostImpl
// TileManagerClient implementation. // TileManagerClient implementation.
virtual void NotifyReadyToActivate() OVERRIDE; virtual void NotifyReadyToActivate() OVERRIDE;
virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE; virtual void NotifyTileStateChanged(const Tile* tile) OVERRIDE;
// ScrollbarAnimationControllerClient implementation. // ScrollbarAnimationControllerClient implementation.
virtual void PostDelayedScrollbarFade(const base::Closure& start_fade, virtual void PostDelayedScrollbarFade(const base::Closure& start_fade,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment