Skip to content

Commit

Permalink
cc: Don't infinitely throttle large raster tasks
Browse files Browse the repository at this point in the history
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.

[email protected]
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 604e202)

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

Cr-Commit-Position: refs/branch-heads/2125@{crosswalk-project#191}
Cr-Branched-From: b68026d-refs/heads/master@{#290040}
  • Loading branch information
quisquous committed Sep 2, 2014
1 parent 7a0797a commit ed16153
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
7 changes: 5 additions & 2 deletions cc/resources/pixel_buffer_raster_worker_pool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
34 changes: 30 additions & 4 deletions cc/resources/raster_worker_pool_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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);
Expand All @@ -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);

Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit ed16153

Please sign in to comment.