summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-08 16:02:31 +0000
committerreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-08 16:02:31 +0000
commite451b807a2f5e6b3aa59ea8f6f8412e49bffa7c6 (patch)
tree381049ec712f61220e2e42ddfb804e17b34e58ca /cc
parent5846d586eb27ff30cfe7d2a1098169b373e149c5 (diff)
downloadchromium_src-e451b807a2f5e6b3aa59ea8f6f8412e49bffa7c6.zip
chromium_src-e451b807a2f5e6b3aa59ea8f6f8412e49bffa7c6.tar.gz
chromium_src-e451b807a2f5e6b3aa59ea8f6f8412e49bffa7c6.tar.bz2
cc: Remove task completion check interval from WorkerPool.
This moves the task completion check interval into the PixelBufferRasterWorkerPool and allows ImageRasterWorkerPool to run at full speed. BUG=246185 TEST= Review URL: https://chromiumcodereview.appspot.com/16527005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@205064 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/base/worker_pool.cc84
-rw-r--r--cc/base/worker_pool.h23
-rw-r--r--cc/base/worker_pool_perftest.cc10
-rw-r--r--cc/base/worker_pool_unittest.cc22
-rw-r--r--cc/resources/image_raster_worker_pool.cc10
-rw-r--r--cc/resources/image_raster_worker_pool.h7
-rw-r--r--cc/resources/pixel_buffer_raster_worker_pool.cc126
-rw-r--r--cc/resources/pixel_buffer_raster_worker_pool.h13
-rw-r--r--cc/resources/raster_worker_pool.cc7
9 files changed, 113 insertions, 189 deletions
diff --git a/cc/base/worker_pool.cc b/cc/base/worker_pool.cc
index 46eeb31..024372e 100644
--- a/cc/base/worker_pool.cc
+++ b/cc/base/worker_pool.cc
@@ -100,9 +100,7 @@ bool WorkerPoolTask::HasCompleted() const {
// by |lock_|.
class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate {
public:
- Inner(WorkerPool* worker_pool,
- size_t num_threads,
- const std::string& thread_name_prefix);
+ Inner(size_t num_threads, const std::string& thread_name_prefix);
virtual ~Inner();
void Shutdown();
@@ -116,8 +114,8 @@ class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate {
// ScheduleTasks().
void ScheduleTasks(internal::WorkerPoolTask* root);
- // Collect all completed tasks in |completed_tasks|. Returns true if idle.
- bool CollectCompletedTasks(TaskDeque* completed_tasks);
+ // Collect all completed tasks in |completed_tasks|.
+ void CollectCompletedTasks(TaskDeque* completed_tasks);
private:
class ScheduledTask {
@@ -148,11 +146,6 @@ class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate {
static void BuildScheduledTaskMap(
internal::WorkerPoolTask* root, ScheduledTaskMap* scheduled_tasks);
- // Collect all completed tasks by swapping the contents of
- // |completed_tasks| and |completed_tasks_|. Lock must be acquired
- // before calling this function. Returns true if idle.
- bool CollectCompletedTasksWithLockAcquired(TaskDeque* completed_tasks);
-
// Overridden from base::DelegateSimpleThread:
virtual void Run() OVERRIDE;
@@ -195,9 +188,8 @@ class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate {
DISALLOW_COPY_AND_ASSIGN(Inner);
};
-WorkerPool::Inner::Inner(WorkerPool* worker_pool,
- size_t num_threads,
- const std::string& thread_name_prefix)
+WorkerPool::Inner::Inner(
+ size_t num_threads, const std::string& thread_name_prefix)
: lock_(),
has_ready_to_run_tasks_cv_(&lock_),
next_thread_index_(0),
@@ -324,20 +316,11 @@ void WorkerPool::Inner::ScheduleTasks(internal::WorkerPoolTask* root) {
}
}
-bool WorkerPool::Inner::CollectCompletedTasks(TaskDeque* completed_tasks) {
+void WorkerPool::Inner::CollectCompletedTasks(TaskDeque* completed_tasks) {
base::AutoLock lock(lock_);
- return CollectCompletedTasksWithLockAcquired(completed_tasks);
-}
-
-bool WorkerPool::Inner::CollectCompletedTasksWithLockAcquired(
- TaskDeque* completed_tasks) {
- lock_.AssertAcquired();
-
DCHECK_EQ(0u, completed_tasks->size());
completed_tasks->swap(completed_tasks_);
-
- return running_tasks_.empty() && pending_tasks_.empty();
}
void WorkerPool::Inner::Run() {
@@ -477,16 +460,9 @@ void WorkerPool::Inner::BuildScheduledTaskMap(
}
WorkerPool::WorkerPool(size_t num_threads,
- base::TimeDelta check_for_completed_tasks_delay,
const std::string& thread_name_prefix)
- : client_(NULL),
- origin_loop_(base::MessageLoopProxy::current()),
- check_for_completed_tasks_delay_(check_for_completed_tasks_delay),
- check_for_completed_tasks_pending_(false),
- in_dispatch_completion_callbacks_(false),
- inner_(make_scoped_ptr(new Inner(this,
- num_threads,
- thread_name_prefix))) {
+ : in_dispatch_completion_callbacks_(false),
+ inner_(make_scoped_ptr(new Inner(num_threads, thread_name_prefix))) {
}
WorkerPool::~WorkerPool() {
@@ -498,23 +474,6 @@ void WorkerPool::Shutdown() {
DCHECK(!in_dispatch_completion_callbacks_);
inner_->Shutdown();
-
- TaskDeque completed_tasks;
- inner_->CollectCompletedTasks(&completed_tasks);
- DispatchCompletionCallbacks(&completed_tasks);
-}
-
-void WorkerPool::ScheduleCheckForCompletedTasks() {
- if (check_for_completed_tasks_pending_)
- return;
- check_for_completed_tasks_callback_.Reset(
- base::Bind(&WorkerPool::CheckForCompletedTasks,
- base::Unretained(this)));
- origin_loop_->PostDelayedTask(
- FROM_HERE,
- check_for_completed_tasks_callback_.callback(),
- check_for_completed_tasks_delay_);
- check_for_completed_tasks_pending_ = true;
}
void WorkerPool::CheckForCompletedTasks() {
@@ -522,40 +481,27 @@ void WorkerPool::CheckForCompletedTasks() {
DCHECK(!in_dispatch_completion_callbacks_);
- check_for_completed_tasks_callback_.Cancel();
- check_for_completed_tasks_pending_ = false;
-
TaskDeque completed_tasks;
-
- // Schedule another check for completed tasks if not idle.
- if (!inner_->CollectCompletedTasks(&completed_tasks))
- ScheduleCheckForCompletedTasks();
-
+ inner_->CollectCompletedTasks(&completed_tasks);
DispatchCompletionCallbacks(&completed_tasks);
}
void WorkerPool::DispatchCompletionCallbacks(TaskDeque* completed_tasks) {
TRACE_EVENT0("cc", "WorkerPool::DispatchCompletionCallbacks");
- // Early out when |completed_tasks| is empty to prevent unnecessary
- // call to DidFinishDispatchingWorkerPoolCompletionCallbacks().
- if (completed_tasks->empty())
- return;
-
// Worker pool instance is not reentrant while processing completed tasks.
in_dispatch_completion_callbacks_ = true;
while (!completed_tasks->empty()) {
- scoped_refptr<internal::WorkerPoolTask> task = completed_tasks->front();
- completed_tasks->pop_front();
+ internal::WorkerPoolTask* task = completed_tasks->front();
+
task->DidComplete();
task->DispatchCompletionCallback();
+
+ completed_tasks->pop_front();
}
in_dispatch_completion_callbacks_ = false;
-
- DCHECK(client_);
- client_->DidFinishDispatchingWorkerPoolCompletionCallbacks();
}
void WorkerPool::ScheduleTasks(internal::WorkerPoolTask* root) {
@@ -563,10 +509,6 @@ void WorkerPool::ScheduleTasks(internal::WorkerPoolTask* root) {
DCHECK(!in_dispatch_completion_callbacks_);
- // Schedule check for completed tasks.
- if (root)
- ScheduleCheckForCompletedTasks();
-
inner_->ScheduleTasks(root);
}
diff --git a/cc/base/worker_pool.h b/cc/base/worker_pool.h
index 758302c..047023f 100644
--- a/cc/base/worker_pool.h
+++ b/cc/base/worker_pool.h
@@ -55,14 +55,6 @@ class CC_EXPORT WorkerPoolTask
} // namespace internal
-class CC_EXPORT WorkerPoolClient {
- public:
- virtual void DidFinishDispatchingWorkerPoolCompletionCallbacks() = 0;
-
- protected:
- virtual ~WorkerPoolClient() {}
-};
-
// A worker thread pool that runs tasks provided by task graph and
// guarantees completion of all pending tasks at shutdown.
class CC_EXPORT WorkerPool {
@@ -73,18 +65,11 @@ class CC_EXPORT WorkerPool {
// completed.
virtual void Shutdown();
- // Set a new client.
- void SetClient(WorkerPoolClient* client) {
- client_ = client;
- }
-
// Force a check for completed tasks.
virtual void CheckForCompletedTasks();
protected:
- WorkerPool(size_t num_threads,
- base::TimeDelta check_for_completed_tasks_delay,
- const std::string& thread_name_prefix);
+ WorkerPool(size_t num_threads, const std::string& thread_name_prefix);
void ScheduleTasks(internal::WorkerPoolTask* root);
@@ -94,14 +79,8 @@ class CC_EXPORT WorkerPool {
typedef std::deque<scoped_refptr<internal::WorkerPoolTask> > TaskDeque;
- void ScheduleCheckForCompletedTasks();
void DispatchCompletionCallbacks(TaskDeque* completed_tasks);
- WorkerPoolClient* client_;
- scoped_refptr<base::MessageLoopProxy> origin_loop_;
- base::CancelableClosure check_for_completed_tasks_callback_;
- base::TimeDelta check_for_completed_tasks_delay_;
- bool check_for_completed_tasks_pending_;
bool in_dispatch_completion_callbacks_;
// Hide the gory details of the worker pool in |inner_|.
diff --git a/cc/base/worker_pool_perftest.cc b/cc/base/worker_pool_perftest.cc
index c203526..2fd07d9 100644
--- a/cc/base/worker_pool_perftest.cc
+++ b/cc/base/worker_pool_perftest.cc
@@ -61,7 +61,7 @@ class PerfControlTaskImpl : public internal::WorkerPoolTask {
class PerfWorkerPool : public WorkerPool {
public:
- PerfWorkerPool() : WorkerPool(1, base::TimeDelta::FromDays(1024), "test") {}
+ PerfWorkerPool() : WorkerPool(1, "test") {}
virtual ~PerfWorkerPool() {}
static scoped_ptr<PerfWorkerPool> Create() {
@@ -73,23 +73,19 @@ class PerfWorkerPool : public WorkerPool {
}
};
-class WorkerPoolPerfTest : public testing::Test,
- public WorkerPoolClient {
+class WorkerPoolPerfTest : public testing::Test {
public:
WorkerPoolPerfTest() : num_runs_(0) {}
// Overridden from testing::Test:
virtual void SetUp() OVERRIDE {
worker_pool_ = PerfWorkerPool::Create();
- worker_pool_->SetClient(this);
}
virtual void TearDown() OVERRIDE {
worker_pool_->Shutdown();
+ worker_pool_->CheckForCompletedTasks();
}
- // Overridden from WorkerPoolClient:
- virtual void DidFinishDispatchingWorkerPoolCompletionCallbacks() OVERRIDE {}
-
void EndTest() {
elapsed_ = base::TimeTicks::HighResNow() - start_time_;
}
diff --git a/cc/base/worker_pool_unittest.cc b/cc/base/worker_pool_unittest.cc
index 9dfe565..fd50ae7 100644
--- a/cc/base/worker_pool_unittest.cc
+++ b/cc/base/worker_pool_unittest.cc
@@ -46,7 +46,7 @@ class FakeTaskImpl : public internal::WorkerPoolTask {
class FakeWorkerPool : public WorkerPool {
public:
- FakeWorkerPool() : WorkerPool(1, base::TimeDelta::FromDays(1024), "test") {}
+ FakeWorkerPool() : WorkerPool(1, "test") {}
virtual ~FakeWorkerPool() {}
static scoped_ptr<FakeWorkerPool> Create() {
@@ -89,10 +89,9 @@ class FakeWorkerPool : public WorkerPool {
scoped_ptr<CompletionEvent> scheduled_tasks_completion_;
};
-class WorkerPoolTest : public testing::Test,
- public WorkerPoolClient {
+class WorkerPoolTest : public testing::Test {
public:
- WorkerPoolTest() : finish_dispatching_completion_callbacks_count_(0) {}
+ WorkerPoolTest() {}
virtual ~WorkerPoolTest() {}
// Overridden from testing::Test:
@@ -103,19 +102,14 @@ class WorkerPoolTest : public testing::Test,
worker_pool_->Shutdown();
}
- // Overridden from WorkerPoolClient:
- virtual void DidFinishDispatchingWorkerPoolCompletionCallbacks() OVERRIDE {
- ++finish_dispatching_completion_callbacks_count_;
- }
-
void Reset() {
worker_pool_ = FakeWorkerPool::Create();
- worker_pool_->SetClient(this);
}
void RunAllTasksAndReset() {
worker_pool_->WaitForTasksToComplete();
worker_pool_->Shutdown();
+ worker_pool_->CheckForCompletedTasks();
Reset();
}
@@ -139,21 +133,15 @@ class WorkerPoolTest : public testing::Test,
return on_task_completed_ids_;
}
- unsigned finish_dispatching_completion_callbacks_count() {
- return finish_dispatching_completion_callbacks_count_;
- }
-
private:
scoped_ptr<FakeWorkerPool> worker_pool_;
std::vector<unsigned> run_task_ids_;
std::vector<unsigned> on_task_completed_ids_;
- unsigned finish_dispatching_completion_callbacks_count_;
};
TEST_F(WorkerPoolTest, Basic) {
EXPECT_EQ(0u, run_task_ids().size());
EXPECT_EQ(0u, on_task_completed_ids().size());
- EXPECT_EQ(0u, finish_dispatching_completion_callbacks_count());
worker_pool()->ScheduleTasks(
base::Bind(&WorkerPoolTest::RunTask, base::Unretained(this), 0u),
@@ -164,7 +152,6 @@ TEST_F(WorkerPoolTest, Basic) {
EXPECT_EQ(1u, run_task_ids().size());
EXPECT_EQ(1u, on_task_completed_ids().size());
- EXPECT_EQ(1u, finish_dispatching_completion_callbacks_count());
worker_pool()->ScheduleTasks(
base::Bind(&WorkerPoolTest::RunTask, base::Unretained(this), 0u),
@@ -175,7 +162,6 @@ TEST_F(WorkerPoolTest, Basic) {
EXPECT_EQ(3u, run_task_ids().size());
EXPECT_EQ(3u, on_task_completed_ids().size());
- EXPECT_EQ(2u, finish_dispatching_completion_callbacks_count());
}
TEST_F(WorkerPoolTest, Dependencies) {
diff --git a/cc/resources/image_raster_worker_pool.cc b/cc/resources/image_raster_worker_pool.cc
index 4ce87df..6d11526 100644
--- a/cc/resources/image_raster_worker_pool.cc
+++ b/cc/resources/image_raster_worker_pool.cc
@@ -60,8 +60,6 @@ class ImageWorkerPoolTaskImpl : public internal::WorkerPoolTask {
ImageRasterWorkerPool::ImageRasterWorkerPool(
ResourceProvider* resource_provider, size_t num_threads)
: RasterWorkerPool(resource_provider, num_threads) {
- // TODO(reveman): Remove WorkerPool client interface.
- WorkerPool::SetClient(this);
}
ImageRasterWorkerPool::~ImageRasterWorkerPool() {
@@ -136,14 +134,10 @@ void ImageRasterWorkerPool::OnRasterTaskCompleted(
if (!was_canceled)
task->DidRun();
- DidCompleteRasterTask(task);
- image_tasks_.erase(task);
-}
-
-void ImageRasterWorkerPool::DidCompleteRasterTask(
- internal::RasterWorkerPoolTask* task) {
task->DidComplete();
task->DispatchCompletionCallback();
+
+ image_tasks_.erase(task);
}
} // namespace cc
diff --git a/cc/resources/image_raster_worker_pool.h b/cc/resources/image_raster_worker_pool.h
index 0d4c23b..453b3a3 100644
--- a/cc/resources/image_raster_worker_pool.h
+++ b/cc/resources/image_raster_worker_pool.h
@@ -9,8 +9,7 @@
namespace cc {
-class CC_EXPORT ImageRasterWorkerPool : public RasterWorkerPool,
- public WorkerPoolClient {
+class CC_EXPORT ImageRasterWorkerPool : public RasterWorkerPool {
public:
virtual ~ImageRasterWorkerPool();
@@ -27,12 +26,8 @@ class CC_EXPORT ImageRasterWorkerPool : public RasterWorkerPool,
ImageRasterWorkerPool(ResourceProvider* resource_provider,
size_t num_threads);
- // Overridden from WorkerPoolClient:
- virtual void DidFinishDispatchingWorkerPoolCompletionCallbacks() OVERRIDE {}
-
void OnRasterTaskCompleted(
scoped_refptr<internal::RasterWorkerPoolTask> task, bool was_canceled);
- void DidCompleteRasterTask(internal::RasterWorkerPoolTask* task);
TaskMap image_tasks_;
diff --git a/cc/resources/pixel_buffer_raster_worker_pool.cc b/cc/resources/pixel_buffer_raster_worker_pool.cc
index c5d0941..e23c9d6 100644
--- a/cc/resources/pixel_buffer_raster_worker_pool.cc
+++ b/cc/resources/pixel_buffer_raster_worker_pool.cc
@@ -77,6 +77,8 @@ const size_t kMaxPendingUploadBytes = 100 * 1024 * 1024;
const size_t kMaxPendingUploads = 1000;
#endif
+const int kCheckForCompletedRasterTasksDelayMs = 6;
+
} // namespace
PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
@@ -84,29 +86,31 @@ PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
size_t num_threads) : RasterWorkerPool(resource_provider, num_threads),
bytes_pending_upload_(0),
has_performed_uploads_since_last_flush_(false),
+ check_for_completed_raster_tasks_pending_(false),
weak_ptr_factory_(this),
schedule_more_tasks_count_(0) {
- // TODO(reveman): Remove WorkerPool client interface.
- WorkerPool::SetClient(this);
}
PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
+ DCHECK(!check_for_completed_raster_tasks_pending_);
DCHECK_EQ(0u, pixel_buffer_tasks_.size());
DCHECK_EQ(0u, tasks_with_pending_upload_.size());
+ DCHECK_EQ(0u, completed_tasks_.size());
}
void PixelBufferRasterWorkerPool::Shutdown() {
RasterWorkerPool::Shutdown();
+ CheckForCompletedRasterTasks();
AbortPendingUploads();
for (TaskMap::iterator it = pixel_buffer_tasks_.begin();
it != pixel_buffer_tasks_.end(); ++it) {
internal::RasterWorkerPoolTask* task = it->first;
- DCHECK(!it->second);
+ internal::WorkerPoolTask* pixel_buffer_task = it->second;
- // Everything else has been canceled.
- DidCompleteRasterTask(task);
+ // All inactive tasks needs to be canceled.
+ if (!pixel_buffer_task)
+ completed_tasks_.push_back(task);
}
- pixel_buffer_tasks_.clear();
// Cancel any pending OnRasterFinished callback.
weak_ptr_factory_.InvalidateWeakPtrs();
}
@@ -136,20 +140,19 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) {
pixel_buffer_tasks_.erase(task);
}
- // Transfer active pixel buffer tasks to |new_pixel_buffer_tasks|
- // and cancel any remaining tasks.
+ // Transfer remaining pixel buffer tasks to |new_pixel_buffer_tasks|
+ // and cancel all remaining inactive tasks.
for (TaskMap::iterator it = pixel_buffer_tasks_.begin();
it != pixel_buffer_tasks_.end(); ++it) {
internal::RasterWorkerPoolTask* task = it->first;
+ internal::WorkerPoolTask* pixel_buffer_task = it->second;
// Move task to |new_pixel_buffer_tasks|
- if (it->second) {
- new_pixel_buffer_tasks[task] = it->second;
- continue;
- }
+ new_pixel_buffer_tasks[task] = pixel_buffer_task;
- // Everything else can be canceled.
- DidCompleteRasterTask(task);
+ // Inactive task can be canceled.
+ if (!pixel_buffer_task)
+ completed_tasks_.push_back(task);
}
pixel_buffer_tasks_.swap(new_pixel_buffer_tasks);
@@ -160,28 +163,19 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) {
void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
- WorkerPool::CheckForCompletedTasks();
-
- while (!tasks_with_pending_upload_.empty()) {
- internal::RasterWorkerPoolTask* task = tasks_with_pending_upload_.front();
-
- // Uploads complete in the order they are issued.
- if (!resource_provider()->DidSetPixelsComplete(task->resource()->id()))
- break;
+ CheckForCompletedRasterTasks();
- // It's now safe to release the pixel buffer and the shared memory.
- resource_provider()->ReleasePixelBuffer(task->resource()->id());
+ while (!completed_tasks_.empty()) {
+ internal::RasterWorkerPoolTask* task = completed_tasks_.front();
+ DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end());
- bytes_pending_upload_ -= task->resource()->bytes();
-
- task->DidRun();
- DidCompleteRasterTask(task);
pixel_buffer_tasks_.erase(task);
- tasks_with_pending_upload_.pop_front();
- }
+ task->DidComplete();
+ task->DispatchCompletionCallback();
- ScheduleMoreTasks();
+ completed_tasks_.pop_front();
+ }
}
bool PixelBufferRasterWorkerPool::ForceUploadToComplete(
@@ -198,13 +192,54 @@ bool PixelBufferRasterWorkerPool::ForceUploadToComplete(
return false;
}
-void PixelBufferRasterWorkerPool::
- DidFinishDispatchingWorkerPoolCompletionCallbacks() {
- // If a flush is needed, do it now before starting to dispatch more tasks.
+void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() {
+ if (check_for_completed_raster_tasks_pending_)
+ return;
+
+ check_for_completed_raster_tasks_callback_.Reset(
+ base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks,
+ base::Unretained(this)));
+ base::MessageLoopProxy::current()->PostDelayedTask(
+ FROM_HERE,
+ check_for_completed_raster_tasks_callback_.callback(),
+ base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs));
+ check_for_completed_raster_tasks_pending_ = true;
+}
+
+void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
+ TRACE_EVENT0(
+ "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
+
+ check_for_completed_raster_tasks_callback_.Cancel();
+ check_for_completed_raster_tasks_pending_ = false;
+
+ WorkerPool::CheckForCompletedTasks();
+
if (has_performed_uploads_since_last_flush_) {
resource_provider()->ShallowFlushIfSupported();
has_performed_uploads_since_last_flush_ = false;
}
+
+ while (!tasks_with_pending_upload_.empty()) {
+ internal::RasterWorkerPoolTask* task = tasks_with_pending_upload_.front();
+ DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end());
+
+ // Uploads complete in the order they are issued.
+ if (!resource_provider()->DidSetPixelsComplete(task->resource()->id()))
+ break;
+
+ // It's now safe to release the pixel buffer and the shared memory.
+ resource_provider()->ReleasePixelBuffer(task->resource()->id());
+
+ bytes_pending_upload_ -= task->resource()->bytes();
+
+ task->DidRun();
+ completed_tasks_.push_back(task);
+
+ tasks_with_pending_upload_.pop_front();
+ }
+
+ ScheduleMoreTasks();
}
bool PixelBufferRasterWorkerPool::CanScheduleRasterTask(
@@ -267,6 +302,9 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
++schedule_more_tasks_count_;
+ // We need to make sure not to schedule a check for completed raster
+ // tasks when |tasks| is empty as that would cause us to never stop
+ // checking.
if (tasks.empty()) {
ScheduleRasterTasks(RootTask());
return;
@@ -280,6 +318,11 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
schedule_more_tasks_count_)),
&tasks);
ScheduleRasterTasks(root);
+
+ // At least one task that could need an upload is now pending, schedule
+ // a check for completed raster tasks to ensure this upload is dispatched
+ // without too much latency.
+ ScheduleCheckForCompletedRasterTasks();
}
void PixelBufferRasterWorkerPool::OnRasterTaskCompleted(
@@ -301,8 +344,7 @@ void PixelBufferRasterWorkerPool::OnRasterTaskCompleted(
if (!was_canceled)
task->DidRun();
- DidCompleteRasterTask(task);
- pixel_buffer_tasks_.erase(task);
+ completed_tasks_.push_back(task);
return;
}
@@ -316,6 +358,7 @@ void PixelBufferRasterWorkerPool::OnRasterTaskCompleted(
void PixelBufferRasterWorkerPool::AbortPendingUploads() {
while (!tasks_with_pending_upload_.empty()) {
internal::RasterWorkerPoolTask* task = tasks_with_pending_upload_.front();
+ DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end());
resource_provider()->AbortSetPixels(task->resource()->id());
resource_provider()->ReleasePixelBuffer(task->resource()->id());
@@ -323,19 +366,12 @@ void PixelBufferRasterWorkerPool::AbortPendingUploads() {
bytes_pending_upload_ -= task->resource()->bytes();
// Need to run the reply callback even though task was aborted.
- DidCompleteRasterTask(task);
- pixel_buffer_tasks_.erase(task);
+ completed_tasks_.push_back(task);
tasks_with_pending_upload_.pop_front();
}
}
-void PixelBufferRasterWorkerPool::DidCompleteRasterTask(
- internal::RasterWorkerPoolTask* task) {
- task->DidComplete();
- task->DispatchCompletionCallback();
-}
-
void PixelBufferRasterWorkerPool::OnRasterFinished(
int64 schedule_more_tasks_count) {
TRACE_EVENT1("cc",
@@ -346,7 +382,7 @@ void PixelBufferRasterWorkerPool::OnRasterFinished(
// tasks needed since last time ScheduleMoreTasks() was called. This
// reduces latency when processing only a small number of raster tasks.
if (schedule_more_tasks_count_ == schedule_more_tasks_count)
- CheckForCompletedTasks();
+ CheckForCompletedRasterTasks();
}
// static
diff --git a/cc/resources/pixel_buffer_raster_worker_pool.h b/cc/resources/pixel_buffer_raster_worker_pool.h
index 0a519c7..7c718ff 100644
--- a/cc/resources/pixel_buffer_raster_worker_pool.h
+++ b/cc/resources/pixel_buffer_raster_worker_pool.h
@@ -6,13 +6,13 @@
#define CC_RESOURCES_PIXEL_BUFFER_RASTER_WORKER_POOL_H_
#include <deque>
+#include <set>
#include "cc/resources/raster_worker_pool.h"
namespace cc {
-class CC_EXPORT PixelBufferRasterWorkerPool : public RasterWorkerPool,
- public WorkerPoolClient {
+class CC_EXPORT PixelBufferRasterWorkerPool : public RasterWorkerPool {
public:
virtual ~PixelBufferRasterWorkerPool();
@@ -34,9 +34,8 @@ class CC_EXPORT PixelBufferRasterWorkerPool : public RasterWorkerPool,
PixelBufferRasterWorkerPool(ResourceProvider* resource_provider,
size_t num_threads);
- // Overridden from WorkerPoolClient:
- virtual void DidFinishDispatchingWorkerPoolCompletionCallbacks() OVERRIDE;
-
+ void CheckForCompletedRasterTasks();
+ void ScheduleCheckForCompletedRasterTasks();
bool CanScheduleRasterTask(internal::RasterWorkerPoolTask* task);
void ScheduleMoreTasks();
void OnRasterTaskCompleted(
@@ -55,10 +54,12 @@ class CC_EXPORT PixelBufferRasterWorkerPool : public RasterWorkerPool,
typedef std::deque<scoped_refptr<internal::RasterWorkerPoolTask> > TaskDeque;
TaskDeque tasks_with_pending_upload_;
+ TaskDeque completed_tasks_;
size_t bytes_pending_upload_;
bool has_performed_uploads_since_last_flush_;
- bool did_dispatch_completion_callback_;
+ base::CancelableClosure check_for_completed_raster_tasks_callback_;
+ bool check_for_completed_raster_tasks_pending_;
base::WeakPtrFactory<PixelBufferRasterWorkerPool> weak_ptr_factory_;
int64 schedule_more_tasks_count_;
diff --git a/cc/resources/raster_worker_pool.cc b/cc/resources/raster_worker_pool.cc
index b275644..091f0ee8 100644
--- a/cc/resources/raster_worker_pool.cc
+++ b/cc/resources/raster_worker_pool.cc
@@ -84,8 +84,6 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask {
const char* kWorkerThreadNamePrefix = "CompositorRaster";
-const int kCheckForCompletedTasksDelayMs = 6;
-
} // namespace
namespace internal {
@@ -200,10 +198,7 @@ RasterWorkerPool::RootTask::~RootTask() {
RasterWorkerPool::RasterWorkerPool(ResourceProvider* resource_provider,
size_t num_threads)
- : WorkerPool(
- num_threads,
- base::TimeDelta::FromMilliseconds(kCheckForCompletedTasksDelayMs),
- kWorkerThreadNamePrefix),
+ : WorkerPool(num_threads, kWorkerThreadNamePrefix),
resource_provider_(resource_provider) {
}