diff options
author | kbr@chromium.org <kbr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-24 00:52:38 +0000 |
---|---|---|
committer | kbr@chromium.org <kbr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-24 00:52:38 +0000 |
commit | afbee36d83e71dfe1dac945a268256281c1cee95 (patch) | |
tree | e7e593056cb1fc6893cd38590cc54ac0d8971c6f /cc/resources | |
parent | db01231e0efc97413ac41fb0625d56010189f2d5 (diff) | |
download | chromium_src-afbee36d83e71dfe1dac945a268256281c1cee95.zip chromium_src-afbee36d83e71dfe1dac945a268256281c1cee95.tar.gz chromium_src-afbee36d83e71dfe1dac945a268256281c1cee95.tar.bz2 |
Revert 272635 "cc: Examine layers to determine if we're ready to..."
Caused layout test failures and out-of-memory errors on several Mac
bots on the Blink waterfall. See Issue 375206.
BUG=375206
> 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
TBR=reveman@chromium.org
Review URL: https://codereview.chromium.org/301493002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272660 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/resources')
-rw-r--r-- | cc/resources/tile_manager.cc | 77 | ||||
-rw-r--r-- | cc/resources/tile_manager.h | 25 | ||||
-rw-r--r-- | cc/resources/tile_manager_perftest.cc | 2 | ||||
-rw-r--r-- | cc/resources/tile_manager_unittest.cc | 45 |
4 files changed, 59 insertions, 90 deletions
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc index 416c4e6..2b3e652 100644 --- a/cc/resources/tile_manager.cc +++ b/cc/resources/tile_manager.cc @@ -365,25 +365,24 @@ scoped_ptr<base::Value> RasterTaskCompletionStatsAsValue( // static scoped_ptr<TileManager> TileManager::Create( TileManagerClient* client, - base::SequencedTaskRunner* task_runner, ResourcePool* resource_pool, Rasterizer* rasterizer, + bool use_rasterize_on_demand, RenderingStatsInstrumentation* rendering_stats_instrumentation) { return make_scoped_ptr(new TileManager(client, - task_runner, resource_pool, rasterizer, + use_rasterize_on_demand, rendering_stats_instrumentation)); } TileManager::TileManager( TileManagerClient* client, - base::SequencedTaskRunner* task_runner, ResourcePool* resource_pool, Rasterizer* rasterizer, + bool use_rasterize_on_demand, RenderingStatsInstrumentation* rendering_stats_instrumentation) : client_(client), - task_runner_(task_runner), resource_pool_(resource_pool), rasterizer_(rasterizer), prioritized_tiles_dirty_(false), @@ -397,8 +396,7 @@ TileManager::TileManager( rendering_stats_instrumentation_(rendering_stats_instrumentation), did_initialize_visible_tile_(false), did_check_for_completed_tasks_since_last_schedule_tasks_(true), - check_if_ready_to_activate_pending_(false), - weak_ptr_factory_(this) { + use_rasterize_on_demand_(use_rasterize_on_demand) { rasterizer_->SetClient(this); } @@ -530,14 +528,12 @@ void TileManager::DidFinishRunningTasks() { // If we can't raster on demand, give up early (and don't activate). if (!allow_rasterize_on_demand) return; - - tile_version.set_rasterize_on_demand(); - client_->NotifyTileStateChanged(tile); + if (use_rasterize_on_demand_) + tile_version.set_rasterize_on_demand(); } } - DCHECK(IsReadyToActivate()); - ScheduleCheckIfReadyToActivate(); + client_->NotifyReadyToActivate(); } void TileManager::DidFinishRunningTasksRequiredForActivation() { @@ -549,7 +545,7 @@ void TileManager::DidFinishRunningTasksRequiredForActivation() { if (!all_tiles_required_for_activation_have_memory_) return; - ScheduleCheckIfReadyToActivate(); + client_->NotifyReadyToActivate(); } void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { @@ -668,7 +664,7 @@ void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { // can visit it. if (mts.bin == NEVER_BIN && !mts.tile_versions[mts.raster_mode].raster_task_) { - FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); + FreeResourcesForTile(tile); continue; } @@ -857,7 +853,7 @@ void TileManager::AssignGpuMemoryToTiles( // If the tile is not needed, free it up. if (mts.bin == NEVER_BIN) { - FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); + FreeResourcesForTile(tile); continue; } @@ -899,19 +895,14 @@ void TileManager::AssignGpuMemoryToTiles( // Tile is OOM. if (tile_bytes > tile_bytes_left || tile_resources > resources_left) { - bool was_ready_to_draw = tile->IsReadyToDraw(); - FreeResourcesForTile(tile); // This tile was already on screen and now its resources have been // released. In order to prevent checkerboarding, set this tile as // rasterize on demand immediately. - if (mts.visible_and_ready_to_draw) + if (mts.visible_and_ready_to_draw && use_rasterize_on_demand_) tile_version.set_rasterize_on_demand(); - if (was_ready_to_draw) - client_->NotifyTileStateChanged(tile); - oomed_soft = true; if (tile_uses_hard_limit) { oomed_hard = true; @@ -1006,14 +997,6 @@ 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( const TileVector& tiles_that_need_to_be_rasterized) { TRACE_EVENT1("cc", @@ -1206,11 +1189,11 @@ void TileManager::OnRasterTaskCompleted( ++resources_releasable_; } + client_->NotifyTileInitialized(tile); + FreeUnusedResourcesForTile(tile); if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f) did_initialize_visible_tile_ = true; - - client_->NotifyTileStateChanged(tile); } scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, @@ -1644,38 +1627,4 @@ void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) { 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 diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h index 0881e6f..cdc7d1e 100644 --- a/cc/resources/tile_manager.h +++ b/cc/resources/tile_manager.h @@ -30,15 +30,8 @@ class ResourceProvider; class CC_EXPORT TileManagerClient { public: - // Called when all tiles marked as required for activation are ready to draw. virtual void NotifyReadyToActivate() = 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; + virtual void NotifyTileInitialized(const Tile* tile) = 0; protected: virtual ~TileManagerClient() {} @@ -161,9 +154,9 @@ class CC_EXPORT TileManager : public RasterizerClient, static scoped_ptr<TileManager> Create( TileManagerClient* client, - base::SequencedTaskRunner* task_runner, ResourcePool* resource_pool, Rasterizer* rasterizer, + bool use_rasterize_on_demand, RenderingStatsInstrumentation* rendering_stats_instrumentation); virtual ~TileManager(); @@ -235,9 +228,9 @@ class CC_EXPORT TileManager : public RasterizerClient, protected: TileManager(TileManagerClient* client, - base::SequencedTaskRunner* task_runner, ResourcePool* resource_pool, Rasterizer* rasterizer, + bool use_rasterize_on_demand, RenderingStatsInstrumentation* rendering_stats_instrumentation); // Methods called by Tile @@ -283,7 +276,6 @@ class CC_EXPORT TileManager : public RasterizerClient, void FreeResourceForTile(Tile* tile, RasterMode mode); void FreeResourcesForTile(Tile* tile); void FreeUnusedResourcesForTile(Tile* tile); - void FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(Tile* tile); scoped_refptr<ImageDecodeTask> CreateImageDecodeTask(Tile* tile, SkPixelRef* pixel_ref); scoped_refptr<RasterTask> CreateRasterTask(Tile* tile); @@ -291,12 +283,7 @@ class CC_EXPORT TileManager : public RasterizerClient, void UpdatePrioritizedTileSetIfNeeded(); void CleanUpLayers(); - bool IsReadyToActivate() const; - void ScheduleCheckIfReadyToActivate(); - void CheckIfReadyToActivate(); - TileManagerClient* client_; - scoped_refptr<base::SequencedTaskRunner> task_runner_; ResourcePool* resource_pool_; Rasterizer* rasterizer_; GlobalStateThatImpactsTilePriority global_state_; @@ -336,6 +323,8 @@ class CC_EXPORT TileManager : public RasterizerClient, std::vector<Tile*> released_tiles_; + bool use_rasterize_on_demand_; + ResourceFormat resource_format_; // Queue used when scheduling raster tasks. @@ -345,10 +334,6 @@ class CC_EXPORT TileManager : public RasterizerClient, std::vector<PictureLayerImpl*> layers_; - bool check_if_ready_to_activate_pending_; - - base::WeakPtrFactory<TileManager> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(TileManager); }; diff --git a/cc/resources/tile_manager_perftest.cc b/cc/resources/tile_manager_perftest.cc index c7fa68f..22e7c66 100644 --- a/cc/resources/tile_manager_perftest.cc +++ b/cc/resources/tile_manager_perftest.cc @@ -293,7 +293,7 @@ class TileManagerPerfTest : public testing::Test, public TileManagerClient { // TileManagerClient implementation. virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; } - virtual void NotifyTileStateChanged(const Tile* tile) OVERRIDE {} + virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE {} TileManager* tile_manager() { return host_impl_.tile_manager(); } diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc index ce54d38..5a1837f 100644 --- a/cc/resources/tile_manager_unittest.cc +++ b/cc/resources/tile_manager_unittest.cc @@ -32,7 +32,8 @@ class TileManagerTest : public testing::TestWithParam<bool>, void Initialize(int max_tiles, TileMemoryLimitPolicy memory_limit_policy, - TreePriority tree_priority) { + TreePriority tree_priority, + bool allow_on_demand_raster = true) { output_surface_ = FakeOutputSurface::Create3d(); CHECK(output_surface_->BindToClient(&output_surface_client_)); @@ -42,8 +43,8 @@ class TileManagerTest : public testing::TestWithParam<bool>, false); resource_pool_ = ResourcePool::Create( resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888); - tile_manager_ = - make_scoped_ptr(new FakeTileManager(this, resource_pool_.get())); + tile_manager_ = make_scoped_ptr(new FakeTileManager( + this, resource_pool_.get(), allow_on_demand_raster)); memory_limit_policy_ = memory_limit_policy; max_tiles_ = max_tiles; @@ -84,7 +85,7 @@ class TileManagerTest : public testing::TestWithParam<bool>, // TileManagerClient implementation. virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; } - virtual void NotifyTileStateChanged(const Tile* tile) OVERRIDE {} + virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE {} TileVector CreateTilesWithSize(int count, TilePriority active_priority, @@ -613,6 +614,40 @@ TEST_P(TileManagerTest, RespectMemoryLimit) { 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, // as num_resources_limit. INSTANTIATE_TEST_CASE_P(TileManagerTests, @@ -719,7 +754,7 @@ class TileManagerTileIteratorTest : public testing::Test, // TileManagerClient implementation. virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; } - virtual void NotifyTileStateChanged(const Tile* tile) OVERRIDE {} + virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE {} TileManager* tile_manager() { return host_impl_.tile_manager(); } |