summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrienne Walker <enne@chromium.org>2014-09-02 16:40:40 -0700
committerAdrienne Walker <enne@chromium.org>2014-09-02 23:44:39 +0000
commited161531ce079ce4a467c4ad4e47dc56c48800c2 (patch)
tree861988d6cf15557f0697df5be1a8c983d1b4cf8f
parent7a0797a1fd207ab17d8c218384041beec6a3015e (diff)
downloadchromium_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.cc7
-rw-r--r--cc/resources/raster_worker_pool_unittest.cc34
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,