Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(651)

Unified Diff: cc/worker_pool.cc

Issue 12194015: cc: Rasterize cheap tiles immediately (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Post a task to run cheap tasks. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« cc/raster_worker_pool.cc ('K') | « cc/worker_pool.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/worker_pool.cc
diff --git a/cc/worker_pool.cc b/cc/worker_pool.cc
index ea572d9b7d29631f26ce27ee0e18fb074cdb647f..437ffe12fbf8590ab9b7565e1d38c3d8354c8b8a 100644
--- a/cc/worker_pool.cc
+++ b/cc/worker_pool.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include "base/bind.h"
+#include "base/debug/trace_event.h"
#include "base/stl_util.h"
#include "base/stringprintf.h"
@@ -31,6 +32,8 @@ class WorkerPoolTaskImpl : public internal::WorkerPoolTask {
base::subtle::Release_Store(&completed_, 1);
}
+ virtual void DeferToThread(base::Thread* thread) OVERRIDE {}
+
private:
WorkerPool::Callback task_;
};
@@ -45,6 +48,12 @@ const int kNumPendingTasksPerWorker = 40;
const int kCheckForCompletedTasksDelayMs = 6;
+// Limits for the total number of cheap tasks we are allowed to perform
+// during a single frame and the time spent running those tasks.
+// TODO(skyostil): Determine these limits more dynamically.
+const int kMaxCheapTaskCount = 6;
+const int kMaxCheapTaskMs = kCheckForCompletedTasksDelayMs;
+
} // namespace
namespace internal {
@@ -153,7 +162,11 @@ WorkerPool::WorkerPool(WorkerPoolClient* client, size_t num_threads)
shutdown_(false),
check_for_completed_tasks_pending_(false),
idle_callback_(
- base::Bind(&WorkerPool::OnIdle, weak_ptr_factory_.GetWeakPtr())) {
+ base::Bind(&WorkerPool::OnIdle, weak_ptr_factory_.GetWeakPtr())),
+ cheap_task_callback_(
+ base::Bind(&WorkerPool::RunCheapTasks,
+ weak_ptr_factory_.GetWeakPtr())),
+ run_cheap_tasks_pending_(false) {
const std::string thread_name_prefix = kWorkerThreadNamePrefix;
while (workers_.size() < num_threads) {
int thread_number = workers_.size() + 1;
@@ -176,6 +189,9 @@ void WorkerPool::Shutdown() {
DCHECK(!shutdown_);
shutdown_ = true;
+ if (run_cheap_tasks_pending_)
+ RunCheapTasks();
+
for (WorkerVector::iterator it = workers_.begin();
it != workers_.end(); it++) {
Worker* worker = *it;
@@ -200,6 +216,11 @@ bool WorkerPool::IsBusy() {
}
void WorkerPool::SetRecordRenderingStats(bool record_rendering_stats) {
+ if (record_rendering_stats)
+ cheap_rendering_stats_.reset(new RenderingStats);
+ else
+ cheap_rendering_stats_.reset();
+
for (WorkerVector::iterator it = workers_.begin();
it != workers_.end(); ++it) {
Worker* worker = *it;
@@ -212,6 +233,16 @@ void WorkerPool::GetRenderingStats(RenderingStats* stats) {
stats->totalPixelsRasterized = 0;
stats->totalDeferredImageDecodeCount = 0;
stats->totalDeferredImageDecodeTime = base::TimeDelta();
+ if (cheap_rendering_stats_) {
+ stats->totalRasterizeTime +=
+ cheap_rendering_stats_->totalRasterizeTime;
+ stats->totalPixelsRasterized +=
+ cheap_rendering_stats_->totalPixelsRasterized;
+ stats->totalDeferredImageDecodeCount +=
+ cheap_rendering_stats_->totalDeferredImageDecodeCount;
+ stats->totalDeferredImageDecodeTime +=
+ cheap_rendering_stats_->totalDeferredImageDecodeTime;
+ }
for (WorkerVector::iterator it = workers_.begin();
it != workers_.end(); ++it) {
Worker* worker = *it;
@@ -261,6 +292,7 @@ void WorkerPool::OnWorkCompletedOnWorkerThread() {
}
void WorkerPool::OnIdle() {
reveman 2013/02/14 21:10:49 do we need to make sure this is not called when we
Sami 2013/02/15 16:41:22 Good point. I made it a no-op if there are pending
+ TRACE_EVENT0("cc", "WorkerPool::OnIdle");
if (base::subtle::Acquire_Load(&pending_task_count_) == 0) {
check_for_completed_tasks_callback_.Cancel();
CheckForCompletedTasks();
@@ -268,6 +300,7 @@ void WorkerPool::OnIdle() {
}
void WorkerPool::CheckForCompletedTasks() {
+ TRACE_EVENT0("cc", "WorkerPool::CheckForCompletedTasks");
check_for_completed_tasks_pending_ = false;
for (WorkerVector::iterator it = workers_.begin();
@@ -300,4 +333,44 @@ void WorkerPool::SortWorkersIfNeeded() {
workers_need_sorting_ = false;
}
+bool WorkerPool::CanPostCheapTask() const {
+ return pending_cheap_tasks_.size() < kMaxCheapTaskCount;
+}
+
+void WorkerPool::PostCheapTask(scoped_ptr<internal::WorkerPoolTask> task) {
+ DCHECK(CanPostCheapTask());
+ pending_cheap_tasks_.push_back(task.Pass());
+ if (!run_cheap_tasks_pending_) {
+ origin_loop_->PostTask(FROM_HERE, cheap_task_callback_);
reveman 2013/02/14 21:10:49 Please add a ScheduleRunCheapTasks(). And you'll n
Sami 2013/02/15 16:41:22 Done. See below for why I didn't add the ScheduleC
+ run_cheap_tasks_pending_ = true;
+ }
+}
+
+void WorkerPool::RunCheapTasks() {
+ // Run as many cheap tasks as we can within the time limit.
+ TRACE_EVENT0("cc", "WorkerPool::RunCheapTasks");
+ base::TimeTicks deadline = base::TimeTicks::Now() +
+ base::TimeDelta::FromMilliseconds(kMaxCheapTaskMs);
reveman 2013/02/14 21:10:49 Should the deadline for cheap tasks not be somethi
Sami 2013/02/15 16:41:22 I'm not sure that's ideal. One of the sites this o
+ while (pending_cheap_tasks_.size()) {
+ scoped_ptr<internal::WorkerPoolTask> task =
+ pending_cheap_tasks_.take_front();
+ task->Run(cheap_rendering_stats_.get());
+ task->DidComplete();
reveman 2013/02/14 21:10:49 Can we have this DidComplete call be done by Check
Sami 2013/02/15 16:41:22 Good idea, I've moved the DidComplete() check to C
+ if (base::TimeTicks::Now() >= deadline) {
+ TRACE_EVENT_INSTANT0("cc", "WorkerPool::RunCheapTasks out of time");
+ break;
+ }
+ }
+
+ // Defer remaining tasks to worker threads.
+ while (pending_cheap_tasks_.size()) {
+ scoped_ptr<internal::WorkerPoolTask> task =
+ pending_cheap_tasks_.take_front();
+ Worker* worker = GetWorkerForNextTask();
+ task->DeferToThread(worker);
reveman 2013/02/14 21:10:49 move DeferToThread into PostTask if possible.
Sami 2013/02/15 16:41:22 Done.
+ worker->PostTask(task.Pass());
+ }
+ run_cheap_tasks_pending_ = false;
+}
+
} // namespace cc
« cc/raster_worker_pool.cc ('K') | « cc/worker_pool.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698