diff --git a/cc/resources/pixel_buffer_raster_worker_pool.cc b/cc/resources/pixel_buffer_raster_worker_pool.cc index d7554736942a6..67ae593bde0a5 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 49912379b3003..f93e0fc714308 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::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 resource( ScopedResource::Create(resource_provider_.get())); resource->Allocate(size, ResourceProvider::TextureHintImmutable, 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 resource( + ScopedResource::Create(resource_provider_.get())); + resource->Allocate(size, ResourceProvider::TextureHintImmutable, 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,