diff options
author | Adrienne Walker <enne@chromium.org> | 2014-09-02 16:40:40 -0700 |
---|---|---|
committer | Adrienne Walker <enne@chromium.org> | 2014-09-02 23:44:39 +0000 |
commit | ed161531ce079ce4a467c4ad4e47dc56c48800c2 (patch) | |
tree | 861988d6cf15557f0697df5be1a8c983d1b4cf8f | |
parent | 7a0797a1fd207ab17d8c218384041beec6a3015e (diff) | |
download | chromium_src-ed161531ce079ce4a467c4ad4e47dc56c48800c2.zip chromium_src-ed161531ce079ce4a467c4ad4e47dc56c48800c2.tar.gz chromium_src-ed161531ce079ce4a467c4ad4e47dc56c48800c2.tar.bz2 |
cc: Don't infinitely throttle large raster tasks
Previously, if a raster task had a resource size that was larger than
the throttling limit for the raster worker, that task would never get
scheduled. This leads to starvation for that task, preventing tree
activation, and causing freezes.
The fix is to always allow such large tasks if it is the first task.
TBR=reveman@chromium.org
BUG=403446
Review URL: https://codereview.chromium.org/489293002
Cr-Commit-Position: refs/heads/master@{#291484}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@291484 0039d316-1c4b-4281-b951-d872f2087c98
(cherry picked from commit 604e202d3548b701900c3771f9517103bb91486c)
Review URL: https://codereview.chromium.org/534823002
Cr-Commit-Position: refs/branch-heads/2125@{#191}
Cr-Branched-From: b68026d94bda36dd106a3d91a098719f952a9477-refs/heads/master@{#290040}
-rw-r--r-- | cc/resources/pixel_buffer_raster_worker_pool.cc | 7 | ||||
-rw-r--r-- | cc/resources/raster_worker_pool_unittest.cc | 34 |
2 files changed, 35 insertions, 6 deletions
diff --git a/cc/resources/pixel_buffer_raster_worker_pool.cc b/cc/resources/pixel_buffer_raster_worker_pool.cc index d7554736..67ae593 100644 --- a/cc/resources/pixel_buffer_raster_worker_pool.cc +++ b/cc/resources/pixel_buffer_raster_worker_pool.cc @@ -515,10 +515,13 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { continue; } - // All raster tasks need to be throttled by bytes of pending uploads. + // All raster tasks need to be throttled by bytes of pending uploads, + // but if it's the only task allow it to complete no matter what its size, + // to prevent starvation of the task queue. size_t new_bytes_pending_upload = bytes_pending_upload; new_bytes_pending_upload += task->resource()->bytes(); - if (new_bytes_pending_upload > max_bytes_pending_upload_) { + if (new_bytes_pending_upload > max_bytes_pending_upload_ && + bytes_pending_upload) { did_throttle_raster_tasks = true; if (item.required_for_activation) did_throttle_raster_tasks_required_for_activation = true; diff --git a/cc/resources/raster_worker_pool_unittest.cc b/cc/resources/raster_worker_pool_unittest.cc index 3b43c09..2179161 100644 --- a/cc/resources/raster_worker_pool_unittest.cc +++ b/cc/resources/raster_worker_pool_unittest.cc @@ -27,6 +27,11 @@ namespace cc { namespace { +const size_t kMaxTransferBufferUsageBytes = 10000U; +// A resource of this dimension^2 * 4 must be greater than the above transfer +// buffer constant. +const size_t kLargeResourceDimension = 1000U; + enum RasterWorkerPoolType { RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER, RASTER_WORKER_POOL_TYPE_IMAGE, @@ -126,7 +131,7 @@ class RasterWorkerPoolTest RasterWorkerPool::GetTaskGraphRunner(), context_provider_.get(), resource_provider_.get(), - std::numeric_limits<size_t>::max()); + kMaxTransferBufferUsageBytes); break; case RASTER_WORKER_POOL_TYPE_IMAGE: raster_worker_pool_ = ImageRasterWorkerPool::Create( @@ -203,9 +208,7 @@ class RasterWorkerPoolTest raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue); } - void AppendTask(unsigned id) { - const gfx::Size size(1, 1); - + void AppendTask(unsigned id, const gfx::Size& size) { scoped_ptr<ScopedResource> resource( ScopedResource::Create(resource_provider_.get())); resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888); @@ -221,6 +224,8 @@ class RasterWorkerPoolTest &empty)); } + void AppendTask(unsigned id) { AppendTask(id, gfx::Size(1, 1)); } + void AppendBlockingTask(unsigned id, base::Lock* lock) { const gfx::Size size(1, 1); @@ -324,6 +329,27 @@ TEST_P(RasterWorkerPoolTest, FalseThrottling) { RunMessageLoopUntilAllTasksHaveCompleted(); } +TEST_P(RasterWorkerPoolTest, LargeResources) { + gfx::Size size(kLargeResourceDimension, kLargeResourceDimension); + + { + // Verify a resource of this size is larger than the transfer buffer. + scoped_ptr<ScopedResource> resource( + ScopedResource::Create(resource_provider_.get())); + resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888); + EXPECT_GE(resource->bytes(), kMaxTransferBufferUsageBytes); + } + + AppendTask(0u, size); + AppendTask(1u, size); + AppendTask(2u, size); + ScheduleTasks(); + + // This will time out if a resource that is larger than the throttle limit + // never gets scheduled. + RunMessageLoopUntilAllTasksHaveCompleted(); +} + INSTANTIATE_TEST_CASE_P(RasterWorkerPoolTests, RasterWorkerPoolTest, ::testing::Values(RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER, |