OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "ui/compositor/compositor.h" | 5 #include "ui/compositor/compositor.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <deque> | 8 #include <deque> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 CancelLock(); | 54 CancelLock(); |
55 } | 55 } |
56 | 56 |
57 void CompositorLock::CancelLock() { | 57 void CompositorLock::CancelLock() { |
58 if (!compositor_) | 58 if (!compositor_) |
59 return; | 59 return; |
60 compositor_->UnlockCompositor(); | 60 compositor_->UnlockCompositor(); |
61 compositor_ = NULL; | 61 compositor_ = NULL; |
62 } | 62 } |
63 | 63 |
64 } // namespace ui | |
65 | |
66 namespace { | |
67 | |
68 } // namespace | |
69 | |
70 namespace ui { | |
71 | |
72 Compositor::Compositor(gfx::AcceleratedWidget widget, | 64 Compositor::Compositor(gfx::AcceleratedWidget widget, |
73 ui::ContextFactory* context_factory) | 65 ui::ContextFactory* context_factory) |
74 : context_factory_(context_factory), | 66 : context_factory_(context_factory), |
75 root_layer_(NULL), | 67 root_layer_(NULL), |
76 widget_(widget), | 68 widget_(widget), |
77 compositor_thread_loop_(context_factory->GetCompositorMessageLoop()), | 69 compositor_thread_loop_(context_factory->GetCompositorMessageLoop()), |
78 vsync_manager_(new CompositorVSyncManager()), | 70 vsync_manager_(new CompositorVSyncManager()), |
79 device_scale_factor_(0.0f), | 71 device_scale_factor_(0.0f), |
80 last_started_frame_(0), | |
81 last_ended_frame_(0), | |
82 disable_schedule_composite_(false), | 72 disable_schedule_composite_(false), |
83 compositor_lock_(NULL), | 73 compositor_lock_(NULL), |
84 defer_draw_scheduling_(false), | 74 layer_animator_collection_(this) { |
85 waiting_on_compositing_end_(false), | |
86 draw_on_compositing_end_(false), | |
87 swap_state_(SWAP_NONE), | |
88 layer_animator_collection_(this), | |
89 schedule_draw_factory_(this) { | |
90 root_web_layer_ = cc::Layer::Create(); | 75 root_web_layer_ = cc::Layer::Create(); |
91 | 76 |
92 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 77 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
93 | 78 |
94 cc::LayerTreeSettings settings; | 79 cc::LayerTreeSettings settings; |
95 settings.refresh_rate = | 80 settings.refresh_rate = |
96 context_factory_->DoesCreateTestContexts() | 81 context_factory_->DoesCreateTestContexts() |
97 ? kTestRefreshRate | 82 ? kTestRefreshRate |
98 : kDefaultRefreshRate; | 83 : kDefaultRefreshRate; |
99 settings.main_frame_before_draw_enabled = false; | 84 settings.main_frame_before_draw_enabled = false; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
168 root_layer_->SetCompositor(NULL); | 153 root_layer_->SetCompositor(NULL); |
169 | 154 |
170 // Stop all outstanding draws before telling the ContextFactory to tear | 155 // Stop all outstanding draws before telling the ContextFactory to tear |
171 // down any contexts that the |host_| may rely upon. | 156 // down any contexts that the |host_| may rely upon. |
172 host_.reset(); | 157 host_.reset(); |
173 | 158 |
174 context_factory_->RemoveCompositor(this); | 159 context_factory_->RemoveCompositor(this); |
175 } | 160 } |
176 | 161 |
177 void Compositor::ScheduleDraw() { | 162 void Compositor::ScheduleDraw() { |
178 if (compositor_thread_loop_) { | 163 host_->SetNeedsCommit(); |
179 host_->SetNeedsCommit(); | |
180 } else if (!defer_draw_scheduling_) { | |
181 defer_draw_scheduling_ = true; | |
182 base::MessageLoop::current()->PostTask( | |
183 FROM_HERE, | |
184 base::Bind(&Compositor::Draw, schedule_draw_factory_.GetWeakPtr())); | |
185 } | |
186 } | 164 } |
187 | 165 |
188 void Compositor::SetRootLayer(Layer* root_layer) { | 166 void Compositor::SetRootLayer(Layer* root_layer) { |
189 if (root_layer_ == root_layer) | 167 if (root_layer_ == root_layer) |
190 return; | 168 return; |
191 if (root_layer_) | 169 if (root_layer_) |
192 root_layer_->SetCompositor(NULL); | 170 root_layer_->SetCompositor(NULL); |
193 root_layer_ = root_layer; | 171 root_layer_ = root_layer; |
194 if (root_layer_ && !root_layer_->GetCompositor()) | 172 if (root_layer_ && !root_layer_->GetCompositor()) |
195 root_layer_->SetCompositor(this); | 173 root_layer_->SetCompositor(this); |
196 root_web_layer_->RemoveAllChildren(); | 174 root_web_layer_->RemoveAllChildren(); |
197 if (root_layer_) | 175 if (root_layer_) |
198 root_web_layer_->AddChild(root_layer_->cc_layer()); | 176 root_web_layer_->AddChild(root_layer_->cc_layer()); |
199 } | 177 } |
200 | 178 |
201 void Compositor::SetHostHasTransparentBackground( | 179 void Compositor::SetHostHasTransparentBackground( |
202 bool host_has_transparent_background) { | 180 bool host_has_transparent_background) { |
203 host_->set_has_transparent_background(host_has_transparent_background); | 181 host_->set_has_transparent_background(host_has_transparent_background); |
204 } | 182 } |
205 | 183 |
206 void Compositor::Draw() { | |
207 DCHECK(!compositor_thread_loop_); | |
208 | |
209 defer_draw_scheduling_ = false; | |
210 if (waiting_on_compositing_end_) { | |
211 draw_on_compositing_end_ = true; | |
212 return; | |
213 } | |
214 if (!root_layer_) | |
215 return; | |
216 | |
217 TRACE_EVENT_ASYNC_BEGIN0("ui", "Compositor::Draw", last_started_frame_ + 1); | |
218 | |
219 DCHECK_NE(swap_state_, SWAP_POSTED); | |
220 swap_state_ = SWAP_NONE; | |
221 | |
222 waiting_on_compositing_end_ = true; | |
223 last_started_frame_++; | |
224 if (!IsLocked()) { | |
225 // TODO(nduca): Temporary while compositor calls | |
226 // compositeImmediately() directly. | |
227 base::TimeTicks now = gfx::FrameTime::Now(); | |
228 Animate(now); | |
229 Layout(); | |
230 host_->Composite(now); | |
231 } | |
232 if (swap_state_ == SWAP_NONE) | |
233 NotifyEnd(); | |
234 } | |
235 | |
236 void Compositor::ScheduleFullRedraw() { | 184 void Compositor::ScheduleFullRedraw() { |
enne (OOO)
2014/07/25 21:20:31
content/browser/compositor/browser_compositor_view
| |
185 // TODO(enne): Some callers (mac) call this function expecting that it | |
186 // will also commit. This should probably just redraw the screen | |
187 // from damage and not commit. ScheduleDraw/ScheduleRedraw need | |
188 // better names. | |
237 host_->SetNeedsRedraw(); | 189 host_->SetNeedsRedraw(); |
190 host_->SetNeedsCommit(); | |
piman
2014/07/25 21:44:23
Could we fix mac instead? The other callers don't
enne (OOO)
2014/07/25 21:46:19
I'm putting up a follow up patch. Just tired of a
| |
238 } | 191 } |
239 | 192 |
240 void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) { | 193 void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) { |
194 // TODO(enne): Make this not commit. See ScheduleFullRedraw. | |
241 host_->SetNeedsRedrawRect(damage_rect); | 195 host_->SetNeedsRedrawRect(damage_rect); |
196 host_->SetNeedsCommit(); | |
242 } | 197 } |
243 | 198 |
244 void Compositor::FinishAllRendering() { | 199 void Compositor::FinishAllRendering() { |
245 host_->FinishAllRendering(); | 200 host_->FinishAllRendering(); |
246 } | 201 } |
247 | 202 |
248 void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) { | 203 void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) { |
249 scoped_ptr<cc::SwapPromise> swap_promise( | 204 scoped_ptr<cc::SwapPromise> swap_promise( |
250 new cc::LatencyInfoSwapPromise(latency_info)); | 205 new cc::LatencyInfoSwapPromise(latency_info)); |
251 host_->QueueSwapPromise(swap_promise.Pass()); | 206 host_->QueueSwapPromise(swap_promise.Pass()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
307 } | 262 } |
308 | 263 |
309 void Compositor::DidCommit() { | 264 void Compositor::DidCommit() { |
310 DCHECK(!IsLocked()); | 265 DCHECK(!IsLocked()); |
311 FOR_EACH_OBSERVER(CompositorObserver, | 266 FOR_EACH_OBSERVER(CompositorObserver, |
312 observer_list_, | 267 observer_list_, |
313 OnCompositingDidCommit(this)); | 268 OnCompositingDidCommit(this)); |
314 } | 269 } |
315 | 270 |
316 void Compositor::DidCommitAndDrawFrame() { | 271 void Compositor::DidCommitAndDrawFrame() { |
272 } | |
273 | |
274 void Compositor::DidCompleteSwapBuffers() { | |
275 // DidPostSwapBuffers is a SingleThreadProxy-only feature. Synthetically | |
276 // generate OnCompositingStarted messages for the threaded case so that | |
277 // OnCompositingStarted/OnCompositingEnded messages match. | |
278 if (compositor_thread_loop_) { | |
279 base::TimeTicks start_time = gfx::FrameTime::Now(); | |
280 FOR_EACH_OBSERVER(CompositorObserver, | |
281 observer_list_, | |
282 OnCompositingStarted(this, start_time)); | |
283 } | |
284 FOR_EACH_OBSERVER( | |
285 CompositorObserver, observer_list_, OnCompositingEnded(this)); | |
286 } | |
287 | |
288 void Compositor::DidPostSwapBuffers() { | |
317 base::TimeTicks start_time = gfx::FrameTime::Now(); | 289 base::TimeTicks start_time = gfx::FrameTime::Now(); |
318 FOR_EACH_OBSERVER(CompositorObserver, | 290 FOR_EACH_OBSERVER(CompositorObserver, |
319 observer_list_, | 291 observer_list_, |
320 OnCompositingStarted(this, start_time)); | 292 OnCompositingStarted(this, start_time)); |
321 } | 293 } |
322 | 294 |
323 void Compositor::DidCompleteSwapBuffers() { | |
324 if (compositor_thread_loop_) { | |
325 NotifyEnd(); | |
326 } else { | |
327 DCHECK_EQ(swap_state_, SWAP_POSTED); | |
328 NotifyEnd(); | |
329 swap_state_ = SWAP_COMPLETED; | |
330 } | |
331 } | |
332 | |
333 void Compositor::ScheduleComposite() { | |
334 if (!disable_schedule_composite_) | |
335 ScheduleDraw(); | |
336 } | |
337 | |
338 void Compositor::ScheduleAnimation() { | |
339 ScheduleComposite(); | |
340 } | |
341 | |
342 void Compositor::DidPostSwapBuffers() { | |
343 DCHECK(!compositor_thread_loop_); | |
344 DCHECK_EQ(swap_state_, SWAP_NONE); | |
345 swap_state_ = SWAP_POSTED; | |
346 } | |
347 | |
348 void Compositor::DidAbortSwapBuffers() { | 295 void Compositor::DidAbortSwapBuffers() { |
349 if (!compositor_thread_loop_) { | |
350 if (swap_state_ == SWAP_POSTED) { | |
351 NotifyEnd(); | |
352 swap_state_ = SWAP_COMPLETED; | |
353 } | |
354 } | |
355 | |
356 FOR_EACH_OBSERVER(CompositorObserver, | 296 FOR_EACH_OBSERVER(CompositorObserver, |
357 observer_list_, | 297 observer_list_, |
358 OnCompositingAborted(this)); | 298 OnCompositingAborted(this)); |
359 } | 299 } |
360 | 300 |
361 void Compositor::ScheduleAnimationForLayerCollection() { | 301 void Compositor::ScheduleAnimationForLayerCollection() { |
362 host_->SetNeedsAnimate(); | 302 host_->SetNeedsAnimate(); |
363 } | 303 } |
364 | 304 |
365 const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const { | 305 const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const { |
366 return host_->debug_state(); | 306 return host_->debug_state(); |
367 } | 307 } |
368 | 308 |
369 void Compositor::SetLayerTreeDebugState( | 309 void Compositor::SetLayerTreeDebugState( |
370 const cc::LayerTreeDebugState& debug_state) { | 310 const cc::LayerTreeDebugState& debug_state) { |
371 host_->SetDebugState(debug_state); | 311 host_->SetDebugState(debug_state); |
372 } | 312 } |
373 | 313 |
374 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { | 314 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { |
375 if (!compositor_lock_) { | 315 if (!compositor_lock_) { |
376 compositor_lock_ = new CompositorLock(this); | 316 compositor_lock_ = new CompositorLock(this); |
377 if (compositor_thread_loop_) | 317 host_->SetDeferCommits(true); |
378 host_->SetDeferCommits(true); | |
379 FOR_EACH_OBSERVER(CompositorObserver, | 318 FOR_EACH_OBSERVER(CompositorObserver, |
380 observer_list_, | 319 observer_list_, |
381 OnCompositingLockStateChanged(this)); | 320 OnCompositingLockStateChanged(this)); |
382 } | 321 } |
383 return compositor_lock_; | 322 return compositor_lock_; |
384 } | 323 } |
385 | 324 |
386 void Compositor::UnlockCompositor() { | 325 void Compositor::UnlockCompositor() { |
387 DCHECK(compositor_lock_); | 326 DCHECK(compositor_lock_); |
388 compositor_lock_ = NULL; | 327 compositor_lock_ = NULL; |
389 if (compositor_thread_loop_) | 328 host_->SetDeferCommits(false); |
390 host_->SetDeferCommits(false); | |
391 FOR_EACH_OBSERVER(CompositorObserver, | 329 FOR_EACH_OBSERVER(CompositorObserver, |
392 observer_list_, | 330 observer_list_, |
393 OnCompositingLockStateChanged(this)); | 331 OnCompositingLockStateChanged(this)); |
394 } | 332 } |
395 | 333 |
396 void Compositor::CancelCompositorLock() { | 334 void Compositor::CancelCompositorLock() { |
397 if (compositor_lock_) | 335 if (compositor_lock_) |
398 compositor_lock_->CancelLock(); | 336 compositor_lock_->CancelLock(); |
399 } | 337 } |
400 | 338 |
401 void Compositor::NotifyEnd() { | |
402 last_ended_frame_++; | |
403 TRACE_EVENT_ASYNC_END0("ui", "Compositor::Draw", last_ended_frame_); | |
404 waiting_on_compositing_end_ = false; | |
405 if (draw_on_compositing_end_) { | |
406 draw_on_compositing_end_ = false; | |
407 | |
408 // Call ScheduleDraw() instead of Draw() in order to allow other | |
409 // CompositorObservers to be notified before starting another | |
410 // draw cycle. | |
411 ScheduleDraw(); | |
412 } | |
413 FOR_EACH_OBSERVER(CompositorObserver, | |
414 observer_list_, | |
415 OnCompositingEnded(this)); | |
416 } | |
417 | |
418 } // namespace ui | 339 } // namespace ui |
OLD | NEW |