OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/resources/raster_worker_pool.h" | 5 #include "cc/resources/raster_worker_pool.h" |
6 | 6 |
7 #include "cc/resources/picture_pile_impl.h" | 7 #include "cc/resources/picture_pile_impl.h" |
8 | 8 |
9 namespace cc { | 9 namespace cc { |
10 | 10 |
11 namespace { | 11 namespace { |
12 | 12 |
13 class RasterWorkerPoolTaskImpl : public internal::WorkerPoolTask { | 13 class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { |
14 public: | 14 public: |
15 RasterWorkerPoolTaskImpl(PicturePileImpl* picture_pile, | 15 RasterWorkerPoolTaskImpl(const base::Closure& callback, |
16 const RasterWorkerPool::RasterCallback& task, | 16 const internal::RasterWorkerPoolTask::Reply& reply) |
17 const base::Closure& reply) | 17 : internal::RasterWorkerPoolTask(reply), |
18 : internal::WorkerPoolTask(reply), | 18 callback_(callback) { |
19 } | |
20 | |
21 // Overridden from internal::WorkerPoolTask: | |
22 virtual void RunOnThread(unsigned thread_index) OVERRIDE { | |
23 WillRun(); | |
24 callback_.Run(); | |
25 DidRun(); | |
26 } | |
27 | |
28 private: | |
29 virtual ~RasterWorkerPoolTaskImpl() {} | |
30 | |
31 const base::Closure callback_; | |
32 }; | |
33 | |
34 class RasterWorkerPoolPictureTaskImpl : public internal::RasterWorkerPoolTask { | |
35 public: | |
36 RasterWorkerPoolPictureTaskImpl( | |
37 PicturePileImpl* picture_pile, | |
38 const RasterWorkerPool::PictureTask::Callback& callback, | |
39 const internal::RasterWorkerPoolTask::Reply& reply) | |
40 : internal::RasterWorkerPoolTask(reply), | |
19 picture_pile_(picture_pile), | 41 picture_pile_(picture_pile), |
20 task_(task) { | 42 callback_(callback) { |
21 DCHECK(picture_pile_); | 43 DCHECK(picture_pile_); |
22 } | 44 } |
23 | 45 |
46 // Overridden from internal::WorkerPoolTask: | |
24 virtual void RunOnThread(unsigned thread_index) OVERRIDE { | 47 virtual void RunOnThread(unsigned thread_index) OVERRIDE { |
25 task_.Run(picture_pile_->GetCloneForDrawingOnThread(thread_index)); | 48 WillRun(); |
49 callback_.Run(picture_pile_->GetCloneForDrawingOnThread(thread_index)); | |
50 DidRun(); | |
26 } | 51 } |
27 | 52 |
28 private: | 53 private: |
54 virtual ~RasterWorkerPoolPictureTaskImpl() {} | |
55 | |
29 scoped_refptr<PicturePileImpl> picture_pile_; | 56 scoped_refptr<PicturePileImpl> picture_pile_; |
30 RasterWorkerPool::RasterCallback task_; | 57 RasterWorkerPool::PictureTask::Callback callback_; |
58 }; | |
59 | |
60 class RasterWorkerPoolTaskQueueImpl : public internal::WorkerPoolTaskGraph { | |
61 public: | |
62 typedef std::deque<scoped_refptr<internal::RasterWorkerPoolTask> > TaskDeque; | |
63 | |
64 explicit RasterWorkerPoolTaskQueueImpl(TaskDeque* tasks) { | |
65 tasks->swap(tasks_); | |
66 } | |
67 virtual ~RasterWorkerPoolTaskQueueImpl() {} | |
68 | |
69 // Overridden from internal::WorkerPoolTaskGraph: | |
70 virtual bool HasMoreTasks() OVERRIDE { | |
71 return !tasks_.empty(); | |
72 } | |
73 virtual bool HasTask(internal::WorkerPoolTask* task) OVERRIDE { | |
74 // TODO(reveman): Use hash if size of |tasks_| gets large. | |
75 return std::find(tasks_.begin(), tasks_.end(), task) != tasks_.end(); | |
76 } | |
vmpstr
2013/05/06 18:05:51
nit: I kinda prefer blank lines between these func
reveman
2013/05/06 21:36:27
I avoid the use of a blank line here to make it cl
| |
77 virtual internal::WorkerPoolTask* TopTask() OVERRIDE { | |
78 return tasks_.front(); | |
79 } | |
80 virtual scoped_refptr<internal::WorkerPoolTask> TakeTask( | |
81 internal::WorkerPoolTask* task) OVERRIDE { | |
82 scoped_refptr<internal::WorkerPoolTask> reference = task; | |
83 | |
84 // Note: This is efficient when removing the top task, which is | |
85 // the most common use case of TakeTask(). | |
86 TaskDeque::iterator it = std::find(tasks_.begin(), tasks_.end(), task); | |
vmpstr
2013/05/06 18:05:51
can you DCHECK that it != tasks_.end. It would see
reveman
2013/05/06 21:36:27
I allowed task to not always be in tasks_ for effi
| |
87 if (it != tasks_.end()) | |
88 tasks_.erase(it); | |
89 | |
90 return reference; | |
91 } | |
92 | |
93 private: | |
94 TaskDeque tasks_; | |
31 }; | 95 }; |
32 | 96 |
33 const char* kWorkerThreadNamePrefix = "CompositorRaster"; | 97 const char* kWorkerThreadNamePrefix = "CompositorRaster"; |
34 | 98 |
35 const int kCheckForCompletedTasksDelayMs = 6; | 99 const int kCheckForCompletedTasksDelayMs = 6; |
36 | 100 |
37 } // namespace | 101 } // namespace |
38 | 102 |
103 namespace internal { | |
104 | |
105 RasterWorkerPoolTask::RasterWorkerPoolTask(const Reply& reply) | |
106 : reply_(reply), | |
107 did_schedule_(false), | |
108 did_run_(false), | |
109 did_complete_(false) { | |
110 } | |
111 | |
112 RasterWorkerPoolTask::~RasterWorkerPoolTask() { | |
113 DCHECK_EQ(did_schedule_, did_complete_); | |
114 DCHECK(!did_run_ || did_schedule_); | |
115 DCHECK(!did_run_ || did_complete_); | |
116 } | |
117 | |
118 void RasterWorkerPoolTask::DispatchCompletionCallback() { | |
119 DCHECK(did_schedule_); | |
120 DCHECK(!did_complete_); | |
121 did_complete_ = true; | |
122 reply_.Run(!did_run_); | |
123 } | |
124 | |
125 void RasterWorkerPoolTask::DidSchedule() { | |
126 DCHECK(!did_complete_); | |
127 did_schedule_ = true; | |
128 } | |
129 | |
130 void RasterWorkerPoolTask::WillRun() { | |
131 DCHECK(!did_complete_); | |
132 DCHECK(!did_run_); | |
133 } | |
134 | |
135 void RasterWorkerPoolTask::DidRun() { | |
136 did_run_ = true; | |
137 } | |
138 | |
139 } // namespace internal | |
140 | |
141 RasterWorkerPool::Task::Queue::Queue() { | |
142 } | |
143 | |
144 RasterWorkerPool::Task::Queue::~Queue() { | |
145 } | |
146 | |
147 void RasterWorkerPool::Task::Queue::Append(const Task& task) { | |
148 DCHECK(!task.is_null()); | |
149 DCHECK(std::find(tasks_.begin(), | |
150 tasks_.end(), | |
151 task.internal_) == tasks_.end()); | |
152 tasks_.push_back(task.internal_); | |
153 } | |
154 | |
155 RasterWorkerPool::Task::Task() { | |
156 } | |
157 | |
158 RasterWorkerPool::Task::Task(const base::Closure& callback, | |
159 const Reply& reply) | |
160 : internal_(new RasterWorkerPoolTaskImpl(callback, reply)) { | |
161 } | |
162 | |
163 RasterWorkerPool::Task::Task( | |
164 scoped_refptr<internal::RasterWorkerPoolTask> internal) | |
165 : internal_(internal) { | |
166 } | |
167 | |
168 RasterWorkerPool::Task::~Task() { | |
169 } | |
170 | |
171 void RasterWorkerPool::Task::Reset() { | |
172 internal_ = NULL; | |
173 } | |
174 | |
175 RasterWorkerPool::PictureTask::PictureTask(PicturePileImpl* picture_pile, | |
176 const Callback& callback, | |
177 const Reply& reply) | |
178 : RasterWorkerPool::Task(new RasterWorkerPoolPictureTaskImpl(picture_pile, | |
179 callback, | |
180 reply)) { | |
181 } | |
182 | |
39 RasterWorkerPool::RasterWorkerPool( | 183 RasterWorkerPool::RasterWorkerPool( |
40 WorkerPoolClient* client, size_t num_threads) : WorkerPool( | 184 WorkerPoolClient* client, size_t num_threads) : WorkerPool( |
41 client, | 185 client, |
42 num_threads, | 186 num_threads, |
43 base::TimeDelta::FromMilliseconds(kCheckForCompletedTasksDelayMs), | 187 base::TimeDelta::FromMilliseconds(kCheckForCompletedTasksDelayMs), |
44 kWorkerThreadNamePrefix) { | 188 kWorkerThreadNamePrefix) { |
45 } | 189 } |
46 | 190 |
47 RasterWorkerPool::~RasterWorkerPool() { | 191 RasterWorkerPool::~RasterWorkerPool() { |
48 } | 192 } |
49 | 193 |
50 void RasterWorkerPool::PostRasterTaskAndReply(PicturePileImpl* picture_pile, | 194 void RasterWorkerPool::ScheduleTasks(Task::Queue* queue) { |
51 const RasterCallback& task, | 195 // Note: DidSchedule() is only used for DCHECKs. |
52 const base::Closure& reply) { | 196 for (Task::Queue::Deque::iterator it = queue->tasks_.begin(); |
53 PostTask(make_scoped_ptr(new RasterWorkerPoolTaskImpl( | 197 it != queue->tasks_.end(); |
54 picture_pile, | 198 ++it) { |
55 task, | 199 internal::RasterWorkerPoolTask* task = *it; |
56 reply)).PassAs<internal::WorkerPoolTask>()); | 200 task->DidSchedule(); |
201 } | |
202 | |
203 WorkerPool::ScheduleTasks( | |
204 make_scoped_ptr( | |
205 new RasterWorkerPoolTaskQueueImpl( | |
206 &queue->tasks_)).PassAs<internal::WorkerPoolTaskGraph>()); | |
57 } | 207 } |
58 | 208 |
59 } // namespace cc | 209 } // namespace cc |
OLD | NEW |