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

Side by Side Diff: cc/worker_pool.cc

Issue 12095053: cc: Avoid expensive RenderingStats collection. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/worker_pool.h ('k') | content/browser/web_contents/web_contents_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/worker_pool.h" 5 #include "cc/worker_pool.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "base/stringprintf.h" 11 #include "base/stringprintf.h"
12 12
13 #if defined(OS_ANDROID) 13 #if defined(OS_ANDROID)
14 // TODO(epenner): Move thread priorities to base. (crbug.com/170549) 14 // TODO(epenner): Move thread priorities to base. (crbug.com/170549)
15 #include <sys/resource.h> 15 #include <sys/resource.h>
16 #endif 16 #endif
17 17
18 namespace cc { 18 namespace cc {
19 19
20 namespace { 20 namespace {
21 21
22 class WorkerPoolTaskImpl : public internal::WorkerPoolTask { 22 class WorkerPoolTaskImpl : public internal::WorkerPoolTask {
23 public: 23 public:
24 WorkerPoolTaskImpl(const WorkerPool::Callback& task, 24 WorkerPoolTaskImpl(const WorkerPool::Callback& task,
25 const base::Closure& reply) 25 const base::Closure& reply)
26 : internal::WorkerPoolTask(reply), 26 : internal::WorkerPoolTask(reply),
27 task_(task) {} 27 task_(task) {}
28 28
29 virtual void Run() OVERRIDE { 29 virtual void Run(RenderingStats* rendering_stats) OVERRIDE {
30 task_.Run(&rendering_stats_); 30 task_.Run(rendering_stats);
31 } 31 }
32 32
33 private: 33 private:
34 WorkerPool::Callback task_; 34 WorkerPool::Callback task_;
35 }; 35 };
36 36
37 const char* kWorkerThreadNamePrefix = "Compositor"; 37 const char* kWorkerThreadNamePrefix = "Compositor";
38 38
39 // Allow two pending tasks per worker. This keeps resource usage 39 // Allow two pending tasks per worker. This keeps resource usage
40 // low while making sure workers aren't unnecessarily idle. 40 // low while making sure workers aren't unnecessarily idle.
41 const int kNumPendingTasksPerWorker = 2; 41 const int kNumPendingTasksPerWorker = 2;
42 42
43 } // namespace 43 } // namespace
44 44
45 namespace internal { 45 namespace internal {
46 46
47 WorkerPoolTask::WorkerPoolTask(const base::Closure& reply) 47 WorkerPoolTask::WorkerPoolTask(const base::Closure& reply)
48 : reply_(reply) { 48 : reply_(reply) {
49 } 49 }
50 50
51 WorkerPoolTask::~WorkerPoolTask() { 51 WorkerPoolTask::~WorkerPoolTask() {
52 } 52 }
53 53
54 void WorkerPoolTask::Completed() { 54 void WorkerPoolTask::Completed() {
55 reply_.Run(); 55 reply_.Run();
56 } 56 }
57 57
58 } // namespace internal 58 } // namespace internal
59 59
60 WorkerPool::Worker::Worker(WorkerPool* worker_pool, const std::string name) 60 WorkerPool::Worker::Worker(
61 WorkerPool* worker_pool,
62 const std::string name,
63 scoped_ptr<RenderingStats> rendering_stats)
61 : base::Thread(name.c_str()), 64 : base::Thread(name.c_str()),
62 worker_pool_(worker_pool), 65 worker_pool_(worker_pool),
63 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 66 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
67 rendering_stats_(rendering_stats.Pass()) {
64 Start(); 68 Start();
65 DCHECK(IsRunning()); 69 DCHECK(IsRunning());
66 } 70 }
67 71
68 WorkerPool::Worker::~Worker() { 72 WorkerPool::Worker::~Worker() {
69 DCHECK(!IsRunning()); 73 DCHECK(!IsRunning());
70 DCHECK_EQ(pending_tasks_.size(), 0); 74 DCHECK_EQ(pending_tasks_.size(), 0);
71 } 75 }
72 76
73 void WorkerPool::Worker::StopAfterCompletingAllPendingTasks() { 77 void WorkerPool::Worker::StopAfterCompletingAllPendingTasks() {
74 // Signals the thread to exit and returns once all pending tasks have run. 78 // Signals the thread to exit and returns once all pending tasks have run.
75 Stop(); 79 Stop();
76 80
77 // Complete all pending tasks. The Stop() call above guarantees that 81 // Complete all pending tasks. The Stop() call above guarantees that
78 // all tasks have finished running. 82 // all tasks have finished running.
79 while (!pending_tasks_.empty()) 83 while (!pending_tasks_.empty())
80 OnTaskCompleted(); 84 OnTaskCompleted();
81 85
82 // Cancel all pending replies. 86 // Cancel all pending replies.
83 weak_ptr_factory_.InvalidateWeakPtrs(); 87 weak_ptr_factory_.InvalidateWeakPtrs();
84 } 88 }
85 89
86 void WorkerPool::Worker::PostTask(scoped_ptr<internal::WorkerPoolTask> task) { 90 void WorkerPool::Worker::PostTask(scoped_ptr<internal::WorkerPoolTask> task) {
87 DCHECK_LT(num_pending_tasks(), kNumPendingTasksPerWorker); 91 DCHECK_LT(num_pending_tasks(), kNumPendingTasksPerWorker);
88 92
89 message_loop_proxy()->PostTaskAndReply( 93 message_loop_proxy()->PostTaskAndReply(
90 FROM_HERE, 94 FROM_HERE,
91 base::Bind(&Worker::RunTask, base::Unretained(task.get())), 95 base::Bind(&Worker::RunTask,
96 base::Unretained(task.get()),
97 base::Unretained(rendering_stats_.get())),
92 base::Bind(&Worker::OnTaskCompleted, weak_ptr_factory_.GetWeakPtr())); 98 base::Bind(&Worker::OnTaskCompleted, weak_ptr_factory_.GetWeakPtr()));
93 99
94 pending_tasks_.push_back(task.Pass()); 100 pending_tasks_.push_back(task.Pass());
95 101
96 worker_pool_->DidNumPendingTasksChange(); 102 worker_pool_->DidNumPendingTasksChange();
97 } 103 }
98 104
99 void WorkerPool::Worker::Init() { 105 void WorkerPool::Worker::Init() {
100 #if defined(OS_ANDROID) 106 #if defined(OS_ANDROID)
101 // TODO(epenner): Move thread priorities to base. (crbug.com/170549) 107 // TODO(epenner): Move thread priorities to base. (crbug.com/170549)
102 int nice_value = 10; // Idle priority. 108 int nice_value = 10; // Idle priority.
103 setpriority(PRIO_PROCESS, base::PlatformThread::CurrentId(), nice_value); 109 setpriority(PRIO_PROCESS, base::PlatformThread::CurrentId(), nice_value);
104 #endif 110 #endif
105 } 111 }
106 112
107 // static 113 // static
108 void WorkerPool::Worker::RunTask(internal::WorkerPoolTask* task) { 114 void WorkerPool::Worker::RunTask(
109 task->Run(); 115 internal::WorkerPoolTask* task, RenderingStats* rendering_stats) {
116 task->Run(rendering_stats);
110 } 117 }
111 118
112 void WorkerPool::Worker::OnTaskCompleted() { 119 void WorkerPool::Worker::OnTaskCompleted() {
113 CHECK(!pending_tasks_.empty()); 120 CHECK(!pending_tasks_.empty());
114 121
115 scoped_ptr<internal::WorkerPoolTask> task = pending_tasks_.take_front(); 122 scoped_ptr<internal::WorkerPoolTask> task = pending_tasks_.take_front();
116
117 task->Completed(); 123 task->Completed();
118 124
119 rendering_stats_.totalRasterizeTime +=
120 task->rendering_stats().totalRasterizeTime;
121 rendering_stats_.totalPixelsRasterized +=
122 task->rendering_stats().totalPixelsRasterized;
123 rendering_stats_.totalDeferredImageDecodeTime +=
124 task->rendering_stats().totalDeferredImageDecodeTime;
125 rendering_stats_.totalDeferredImageDecodeCount +=
126 task->rendering_stats().totalDeferredImageDecodeCount;
127
128 worker_pool_->DidNumPendingTasksChange(); 125 worker_pool_->DidNumPendingTasksChange();
129 } 126 }
130 127
131 WorkerPool::WorkerPool(size_t num_threads) 128 WorkerPool::WorkerPool(size_t num_threads, bool record_rendering_stats)
132 : workers_need_sorting_(false), 129 : workers_need_sorting_(false),
133 shutdown_(false) { 130 shutdown_(false) {
134 const std::string thread_name_prefix = kWorkerThreadNamePrefix; 131 const std::string thread_name_prefix = kWorkerThreadNamePrefix;
135 while (workers_.size() < num_threads) { 132 while (workers_.size() < num_threads) {
136 int thread_number = workers_.size() + 1; 133 int thread_number = workers_.size() + 1;
137 workers_.push_back( 134 scoped_ptr<RenderingStats> rendering_stats = record_rendering_stats ?
138 new Worker(this, 135 make_scoped_ptr(new RenderingStats) : scoped_ptr<RenderingStats>();
139 thread_name_prefix + 136 workers_.push_back(new Worker(
140 StringPrintf("Worker%d", thread_number).c_str())); 137 this,
138 thread_name_prefix + StringPrintf("Worker%d", thread_number).c_str(),
139 rendering_stats.Pass()));
141 } 140 }
142 } 141 }
143 142
144 WorkerPool::~WorkerPool() { 143 WorkerPool::~WorkerPool() {
145 Shutdown(); 144 Shutdown();
146 STLDeleteElements(&workers_); 145 STLDeleteElements(&workers_);
147 } 146 }
148 147
149 void WorkerPool::Shutdown() { 148 void WorkerPool::Shutdown() {
150 DCHECK(!shutdown_); 149 DCHECK(!shutdown_);
(...skipping 23 matching lines...) Expand all
174 } 173 }
175 174
176 void WorkerPool::GetRenderingStats(RenderingStats* stats) { 175 void WorkerPool::GetRenderingStats(RenderingStats* stats) {
177 stats->totalRasterizeTime = base::TimeDelta(); 176 stats->totalRasterizeTime = base::TimeDelta();
178 stats->totalPixelsRasterized = 0; 177 stats->totalPixelsRasterized = 0;
179 stats->totalDeferredImageDecodeCount = 0; 178 stats->totalDeferredImageDecodeCount = 0;
180 stats->totalDeferredImageDecodeTime = base::TimeDelta(); 179 stats->totalDeferredImageDecodeTime = base::TimeDelta();
181 for (WorkerVector::iterator it = workers_.begin(); 180 for (WorkerVector::iterator it = workers_.begin();
182 it != workers_.end(); ++it) { 181 it != workers_.end(); ++it) {
183 Worker* worker = *it; 182 Worker* worker = *it;
183 CHECK(worker->rendering_stats());
184 stats->totalRasterizeTime += 184 stats->totalRasterizeTime +=
185 worker->rendering_stats().totalRasterizeTime; 185 worker->rendering_stats()->totalRasterizeTime;
186 stats->totalPixelsRasterized += 186 stats->totalPixelsRasterized +=
187 worker->rendering_stats().totalPixelsRasterized; 187 worker->rendering_stats()->totalPixelsRasterized;
188 stats->totalDeferredImageDecodeCount += 188 stats->totalDeferredImageDecodeCount +=
189 worker->rendering_stats().totalDeferredImageDecodeCount; 189 worker->rendering_stats()->totalDeferredImageDecodeCount;
190 stats->totalDeferredImageDecodeTime += 190 stats->totalDeferredImageDecodeTime +=
191 worker->rendering_stats().totalDeferredImageDecodeTime; 191 worker->rendering_stats()->totalDeferredImageDecodeTime;
192 } 192 }
193 } 193 }
194 194
195 WorkerPool::Worker* WorkerPool::GetWorkerForNextTask() { 195 WorkerPool::Worker* WorkerPool::GetWorkerForNextTask() {
196 CHECK(!shutdown_); 196 CHECK(!shutdown_);
197 SortWorkersIfNeeded(); 197 SortWorkersIfNeeded();
198 return workers_.front(); 198 return workers_.front();
199 } 199 }
200 200
201 void WorkerPool::DidNumPendingTasksChange() { 201 void WorkerPool::DidNumPendingTasksChange() {
202 workers_need_sorting_ = true; 202 workers_need_sorting_ = true;
203 } 203 }
204 204
205 void WorkerPool::SortWorkersIfNeeded() { 205 void WorkerPool::SortWorkersIfNeeded() {
206 if (!workers_need_sorting_) 206 if (!workers_need_sorting_)
207 return; 207 return;
208 208
209 std::sort(workers_.begin(), workers_.end(), NumPendingTasksComparator()); 209 std::sort(workers_.begin(), workers_.end(), NumPendingTasksComparator());
210 workers_need_sorting_ = false; 210 workers_need_sorting_ = false;
211 } 211 }
212 212
213 } // namespace cc 213 } // namespace cc
OLDNEW
« no previous file with comments | « cc/worker_pool.h ('k') | content/browser/web_contents/web_contents_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698