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

Side by Side Diff: ui/compositor/compositor.cc

Issue 638653003: Make ui::Compositor use ui::Scheduler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: mv DCHECK from DidCommit to BeginFrame Created 6 years, 2 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
« no previous file with comments | « ui/compositor/compositor.h ('k') | ui/compositor/layer_unittest.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 (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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 CancelLock(); 56 CancelLock();
57 } 57 }
58 58
59 void CompositorLock::CancelLock() { 59 void CompositorLock::CancelLock() {
60 if (!compositor_) 60 if (!compositor_)
61 return; 61 return;
62 compositor_->UnlockCompositor(); 62 compositor_->UnlockCompositor();
63 compositor_ = NULL; 63 compositor_ = NULL;
64 } 64 }
65 65
66 } // namespace ui
67
68 namespace {} // namespace
69
70 namespace ui {
71
72 class SatisfySwapPromise : public cc::SwapPromise { 66 class SatisfySwapPromise : public cc::SwapPromise {
73 public: 67 public:
74 explicit SatisfySwapPromise(uint32_t id) : id_(id) {} 68 explicit SatisfySwapPromise(uint32_t id) : id_(id) {}
75 69
76 private: 70 private:
77 virtual void DidSwap(cc::CompositorFrameMetadata* metadata) override { 71 virtual void DidSwap(cc::CompositorFrameMetadata* metadata) override {
78 metadata->satisfies_sequences.push_back(id_); 72 metadata->satisfies_sequences.push_back(id_);
79 } 73 }
80 74
81 virtual void DidNotSwap(DidNotSwapReason reason) override { 75 virtual void DidNotSwap(DidNotSwapReason reason) override {
82 // TODO(jbauman): Send to the SurfaceManager immediately. 76 // TODO(jbauman): Send to the SurfaceManager immediately.
83 DCHECK(false); 77 DCHECK(false);
84 } 78 }
85 virtual int64 TraceId() const override { return 0; } 79 virtual int64 TraceId() const override { return 0; }
86 uint32_t id_; 80 uint32_t id_;
87 }; 81 };
88 82
89 Compositor::Compositor(gfx::AcceleratedWidget widget, 83 Compositor::Compositor(gfx::AcceleratedWidget widget,
90 ui::ContextFactory* context_factory, 84 ui::ContextFactory* context_factory,
91 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 85 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
92 : context_factory_(context_factory), 86 : context_factory_(context_factory),
93 root_layer_(NULL), 87 root_layer_(NULL),
94 widget_(widget), 88 widget_(widget),
95 surface_id_allocator_(context_factory->CreateSurfaceIdAllocator()), 89 surface_id_allocator_(context_factory->CreateSurfaceIdAllocator()),
96 surface_sequence_number_(0), 90 surface_sequence_number_(0),
97 compositor_thread_loop_(context_factory->GetCompositorMessageLoop()), 91 compositor_thread_loop_(context_factory->GetCompositorMessageLoop()),
98 task_runner_(task_runner), 92 task_runner_(task_runner),
99 vsync_manager_(new CompositorVSyncManager()), 93 vsync_manager_(new CompositorVSyncManager()),
100 device_scale_factor_(0.0f), 94 device_scale_factor_(0.0f),
101 last_started_frame_(0),
102 last_ended_frame_(0),
103 disable_schedule_composite_(false), 95 disable_schedule_composite_(false),
104 compositor_lock_(NULL), 96 compositor_lock_(NULL),
105 defer_draw_scheduling_(false), 97 layer_animator_collection_(this) {
106 waiting_on_compositing_end_(false),
107 draw_on_compositing_end_(false),
108 swap_state_(SWAP_NONE),
109 layer_animator_collection_(this),
110 schedule_draw_factory_(this) {
111 root_web_layer_ = cc::Layer::Create(); 98 root_web_layer_ = cc::Layer::Create();
112 99
113 CommandLine* command_line = CommandLine::ForCurrentProcess(); 100 CommandLine* command_line = CommandLine::ForCurrentProcess();
114 101
115 cc::LayerTreeSettings settings; 102 cc::LayerTreeSettings settings;
116 settings.refresh_rate = 103 settings.refresh_rate =
117 context_factory_->DoesCreateTestContexts() 104 context_factory_->DoesCreateTestContexts()
118 ? kTestRefreshRate 105 ? kTestRefreshRate
119 : kDefaultRefreshRate; 106 : kDefaultRefreshRate;
120 settings.main_frame_before_activation_enabled = false; 107 settings.main_frame_before_activation_enabled = false;
(...skipping 27 matching lines...) Expand all
148 settings.initial_debug_state.show_occluding_rects = 135 settings.initial_debug_state.show_occluding_rects =
149 command_line->HasSwitch(cc::switches::kUIShowOccludingRects); 136 command_line->HasSwitch(cc::switches::kUIShowOccludingRects);
150 settings.initial_debug_state.show_non_occluding_rects = 137 settings.initial_debug_state.show_non_occluding_rects =
151 command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects); 138 command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects);
152 139
153 settings.initial_debug_state.SetRecordRenderingStats( 140 settings.initial_debug_state.SetRecordRenderingStats(
154 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking)); 141 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
155 142
156 settings.impl_side_painting = IsUIImplSidePaintingEnabled(); 143 settings.impl_side_painting = IsUIImplSidePaintingEnabled();
157 settings.use_zero_copy = IsUIZeroCopyEnabled(); 144 settings.use_zero_copy = IsUIZeroCopyEnabled();
158 settings.single_thread_proxy_scheduler = false;
159 145
160 base::TimeTicks before_create = base::TimeTicks::Now(); 146 base::TimeTicks before_create = base::TimeTicks::Now();
161 if (compositor_thread_loop_.get()) { 147 if (compositor_thread_loop_.get()) {
162 host_ = cc::LayerTreeHost::CreateThreaded( 148 host_ = cc::LayerTreeHost::CreateThreaded(
163 this, 149 this,
164 context_factory_->GetSharedBitmapManager(), 150 context_factory_->GetSharedBitmapManager(),
165 context_factory_->GetGpuMemoryBufferManager(), 151 context_factory_->GetGpuMemoryBufferManager(),
166 settings, 152 settings,
167 task_runner_, 153 task_runner_,
168 compositor_thread_loop_); 154 compositor_thread_loop_);
(...skipping 22 matching lines...) Expand all
191 root_layer_->SetCompositor(NULL); 177 root_layer_->SetCompositor(NULL);
192 178
193 // Stop all outstanding draws before telling the ContextFactory to tear 179 // Stop all outstanding draws before telling the ContextFactory to tear
194 // down any contexts that the |host_| may rely upon. 180 // down any contexts that the |host_| may rely upon.
195 host_.reset(); 181 host_.reset();
196 182
197 context_factory_->RemoveCompositor(this); 183 context_factory_->RemoveCompositor(this);
198 } 184 }
199 185
200 void Compositor::ScheduleDraw() { 186 void Compositor::ScheduleDraw() {
201 if (compositor_thread_loop_.get()) { 187 host_->SetNeedsCommit();
202 host_->SetNeedsCommit();
203 } else if (!defer_draw_scheduling_) {
204 defer_draw_scheduling_ = true;
205 task_runner_->PostTask(
206 FROM_HERE,
207 base::Bind(&Compositor::Draw, schedule_draw_factory_.GetWeakPtr()));
208 }
209 } 188 }
210 189
211 void Compositor::SetRootLayer(Layer* root_layer) { 190 void Compositor::SetRootLayer(Layer* root_layer) {
212 if (root_layer_ == root_layer) 191 if (root_layer_ == root_layer)
213 return; 192 return;
214 if (root_layer_) 193 if (root_layer_)
215 root_layer_->SetCompositor(NULL); 194 root_layer_->SetCompositor(NULL);
216 root_layer_ = root_layer; 195 root_layer_ = root_layer;
217 if (root_layer_ && !root_layer_->GetCompositor()) 196 if (root_layer_ && !root_layer_->GetCompositor())
218 root_layer_->SetCompositor(this); 197 root_layer_->SetCompositor(this);
219 root_web_layer_->RemoveAllChildren(); 198 root_web_layer_->RemoveAllChildren();
220 if (root_layer_) 199 if (root_layer_)
221 root_web_layer_->AddChild(root_layer_->cc_layer()); 200 root_web_layer_->AddChild(root_layer_->cc_layer());
222 } 201 }
223 202
224 void Compositor::SetHostHasTransparentBackground( 203 void Compositor::SetHostHasTransparentBackground(
225 bool host_has_transparent_background) { 204 bool host_has_transparent_background) {
226 host_->set_has_transparent_background(host_has_transparent_background); 205 host_->set_has_transparent_background(host_has_transparent_background);
227 } 206 }
228 207
229 void Compositor::Draw() {
230 DCHECK(!compositor_thread_loop_.get());
231
232 defer_draw_scheduling_ = false;
233 if (waiting_on_compositing_end_) {
234 draw_on_compositing_end_ = true;
235 return;
236 }
237 if (!root_layer_)
238 return;
239
240 TRACE_EVENT_ASYNC_BEGIN0("ui", "Compositor::Draw", last_started_frame_ + 1);
241
242 DCHECK_NE(swap_state_, SWAP_POSTED);
243 swap_state_ = SWAP_NONE;
244
245 waiting_on_compositing_end_ = true;
246 last_started_frame_++;
247 if (!IsLocked()) {
248 // TODO(nduca): Temporary while compositor calls
249 // compositeImmediately() directly.
250 cc::BeginFrameArgs args =
251 cc::BeginFrameArgs::Create(gfx::FrameTime::Now(),
252 base::TimeTicks(),
253 cc::BeginFrameArgs::DefaultInterval());
254 BeginMainFrame(args);
255 host_->Composite(args.frame_time);
256 }
257 if (swap_state_ == SWAP_NONE)
258 NotifyEnd();
259 }
260
261 void Compositor::ScheduleFullRedraw() { 208 void Compositor::ScheduleFullRedraw() {
209 // TODO(enne): Some callers (mac) call this function expecting that it
210 // will also commit. This should probably just redraw the screen
211 // from damage and not commit. ScheduleDraw/ScheduleRedraw need
212 // better names.
262 host_->SetNeedsRedraw(); 213 host_->SetNeedsRedraw();
214 host_->SetNeedsCommit();
263 } 215 }
264 216
265 void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) { 217 void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) {
218 // TODO(enne): Make this not commit. See ScheduleFullRedraw.
266 host_->SetNeedsRedrawRect(damage_rect); 219 host_->SetNeedsRedrawRect(damage_rect);
220 host_->SetNeedsCommit();
267 } 221 }
268 222
269 void Compositor::FinishAllRendering() { 223 void Compositor::FinishAllRendering() {
270 host_->FinishAllRendering(); 224 host_->FinishAllRendering();
271 } 225 }
272 226
273 void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) { 227 void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) {
274 scoped_ptr<cc::SwapPromise> swap_promise( 228 scoped_ptr<cc::SwapPromise> swap_promise(
275 new cc::LatencyInfoSwapPromise(latency_info)); 229 new cc::LatencyInfoSwapPromise(latency_info));
276 host_->QueueSwapPromise(swap_promise.Pass()); 230 host_->QueueSwapPromise(swap_promise.Pass());
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 void Compositor::RemoveAnimationObserver( 293 void Compositor::RemoveAnimationObserver(
340 CompositorAnimationObserver* observer) { 294 CompositorAnimationObserver* observer) {
341 animation_observer_list_.RemoveObserver(observer); 295 animation_observer_list_.RemoveObserver(observer);
342 } 296 }
343 297
344 bool Compositor::HasAnimationObserver(CompositorAnimationObserver* observer) { 298 bool Compositor::HasAnimationObserver(CompositorAnimationObserver* observer) {
345 return animation_observer_list_.HasObserver(observer); 299 return animation_observer_list_.HasObserver(observer);
346 } 300 }
347 301
348 void Compositor::BeginMainFrame(const cc::BeginFrameArgs& args) { 302 void Compositor::BeginMainFrame(const cc::BeginFrameArgs& args) {
303 // If a compositor lock is grabbed before BeginMainFrame, commit would be
304 // deferred. It is possible for compositor lock to be grabbed after
305 // BeginMainFrame, but then it is too late to stop commit and we will go
306 // through it anyway.
piman 2014/10/14 20:50:11 I think that's a problem... It means we'll flash d
danakj 2014/10/14 20:52:49 Once beginframe has happened the main thread has a
307 DCHECK(!IsLocked());
349 FOR_EACH_OBSERVER(CompositorAnimationObserver, 308 FOR_EACH_OBSERVER(CompositorAnimationObserver,
350 animation_observer_list_, 309 animation_observer_list_,
351 OnAnimationStep(args.frame_time)); 310 OnAnimationStep(args.frame_time));
352 if (animation_observer_list_.might_have_observers()) 311 if (animation_observer_list_.might_have_observers())
353 host_->SetNeedsAnimate(); 312 host_->SetNeedsAnimate();
354 } 313 }
355 314
356 void Compositor::Layout() { 315 void Compositor::Layout() {
357 // We're sending damage that will be addressed during this composite 316 // We're sending damage that will be addressed during this composite
358 // cycle, so we don't need to schedule another composite to address it. 317 // cycle, so we don't need to schedule another composite to address it.
359 disable_schedule_composite_ = true; 318 disable_schedule_composite_ = true;
360 if (root_layer_) 319 if (root_layer_)
361 root_layer_->SendDamagedRects(); 320 root_layer_->SendDamagedRects();
362 disable_schedule_composite_ = false; 321 disable_schedule_composite_ = false;
363 } 322 }
364 323
365 void Compositor::RequestNewOutputSurface(bool fallback) { 324 void Compositor::RequestNewOutputSurface(bool fallback) {
366 host_->SetOutputSurface( 325 host_->SetOutputSurface(
367 context_factory_->CreateOutputSurface(this, fallback)); 326 context_factory_->CreateOutputSurface(this, fallback));
368 } 327 }
369 328
370 void Compositor::DidCommit() { 329 void Compositor::DidCommit() {
371 DCHECK(!IsLocked());
372 FOR_EACH_OBSERVER(CompositorObserver, 330 FOR_EACH_OBSERVER(CompositorObserver,
373 observer_list_, 331 observer_list_,
374 OnCompositingDidCommit(this)); 332 OnCompositingDidCommit(this));
375 } 333 }
376 334
377 void Compositor::DidCommitAndDrawFrame() { 335 void Compositor::DidCommitAndDrawFrame() {
336 }
337
338 void Compositor::DidCompleteSwapBuffers() {
339 // DidPostSwapBuffers is a SingleThreadProxy-only feature. Synthetically
340 // generate OnCompositingStarted messages for the threaded case so that
341 // OnCompositingStarted/OnCompositingEnded messages match.
342 if (compositor_thread_loop_.get()) {
343 base::TimeTicks start_time = gfx::FrameTime::Now();
344 FOR_EACH_OBSERVER(CompositorObserver,
345 observer_list_,
346 OnCompositingStarted(this, start_time));
347 }
348 FOR_EACH_OBSERVER(
349 CompositorObserver, observer_list_, OnCompositingEnded(this));
350 }
351
352 void Compositor::DidPostSwapBuffers() {
378 base::TimeTicks start_time = gfx::FrameTime::Now(); 353 base::TimeTicks start_time = gfx::FrameTime::Now();
379 FOR_EACH_OBSERVER(CompositorObserver, 354 FOR_EACH_OBSERVER(CompositorObserver,
380 observer_list_, 355 observer_list_,
381 OnCompositingStarted(this, start_time)); 356 OnCompositingStarted(this, start_time));
382 } 357 }
383 358
384 void Compositor::DidCompleteSwapBuffers() {
385 if (compositor_thread_loop_.get()) {
386 NotifyEnd();
387 } else {
388 DCHECK_EQ(swap_state_, SWAP_POSTED);
389 NotifyEnd();
390 swap_state_ = SWAP_COMPLETED;
391 }
392 }
393
394 void Compositor::ScheduleComposite() {
395 if (!disable_schedule_composite_)
396 ScheduleDraw();
397 }
398
399 void Compositor::ScheduleAnimation() {
400 ScheduleComposite();
401 }
402
403 void Compositor::DidPostSwapBuffers() {
404 DCHECK(!compositor_thread_loop_.get());
405 DCHECK_EQ(swap_state_, SWAP_NONE);
406 swap_state_ = SWAP_POSTED;
407 }
408
409 void Compositor::DidAbortSwapBuffers() { 359 void Compositor::DidAbortSwapBuffers() {
410 if (!compositor_thread_loop_.get()) {
411 if (swap_state_ == SWAP_POSTED) {
412 NotifyEnd();
413 swap_state_ = SWAP_COMPLETED;
414 }
415 }
416
417 FOR_EACH_OBSERVER(CompositorObserver, 360 FOR_EACH_OBSERVER(CompositorObserver,
418 observer_list_, 361 observer_list_,
419 OnCompositingAborted(this)); 362 OnCompositingAborted(this));
420 } 363 }
421 364
422 const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const { 365 const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const {
423 return host_->debug_state(); 366 return host_->debug_state();
424 } 367 }
425 368
426 void Compositor::SetLayerTreeDebugState( 369 void Compositor::SetLayerTreeDebugState(
427 const cc::LayerTreeDebugState& debug_state) { 370 const cc::LayerTreeDebugState& debug_state) {
428 host_->SetDebugState(debug_state); 371 host_->SetDebugState(debug_state);
429 } 372 }
430 373
431 cc::SurfaceSequence Compositor::InsertSurfaceSequenceForNextFrame() { 374 cc::SurfaceSequence Compositor::InsertSurfaceSequenceForNextFrame() {
432 cc::SurfaceSequence sequence; 375 cc::SurfaceSequence sequence;
433 sequence.id_namespace = surface_id_allocator_->id_namespace(); 376 sequence.id_namespace = surface_id_allocator_->id_namespace();
434 sequence.sequence = ++surface_sequence_number_; 377 sequence.sequence = ++surface_sequence_number_;
435 scoped_ptr<cc::SwapPromise> promise( 378 scoped_ptr<cc::SwapPromise> promise(
436 new SatisfySwapPromise(surface_sequence_number_)); 379 new SatisfySwapPromise(surface_sequence_number_));
437 host_->QueueSwapPromise(promise.Pass()); 380 host_->QueueSwapPromise(promise.Pass());
438 return sequence; 381 return sequence;
439 } 382 }
440 383
441 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { 384 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
442 if (!compositor_lock_) { 385 if (!compositor_lock_) {
443 compositor_lock_ = new CompositorLock(this); 386 compositor_lock_ = new CompositorLock(this);
444 if (compositor_thread_loop_.get()) 387 host_->SetDeferCommits(true);
445 host_->SetDeferCommits(true);
446 FOR_EACH_OBSERVER(CompositorObserver, 388 FOR_EACH_OBSERVER(CompositorObserver,
447 observer_list_, 389 observer_list_,
448 OnCompositingLockStateChanged(this)); 390 OnCompositingLockStateChanged(this));
449 } 391 }
450 return compositor_lock_; 392 return compositor_lock_;
451 } 393 }
452 394
453 void Compositor::UnlockCompositor() { 395 void Compositor::UnlockCompositor() {
454 DCHECK(compositor_lock_); 396 DCHECK(compositor_lock_);
455 compositor_lock_ = NULL; 397 compositor_lock_ = NULL;
456 if (compositor_thread_loop_.get()) 398 host_->SetDeferCommits(false);
457 host_->SetDeferCommits(false);
458 FOR_EACH_OBSERVER(CompositorObserver, 399 FOR_EACH_OBSERVER(CompositorObserver,
459 observer_list_, 400 observer_list_,
460 OnCompositingLockStateChanged(this)); 401 OnCompositingLockStateChanged(this));
461 } 402 }
462 403
463 void Compositor::CancelCompositorLock() { 404 void Compositor::CancelCompositorLock() {
464 if (compositor_lock_) 405 if (compositor_lock_)
465 compositor_lock_->CancelLock(); 406 compositor_lock_->CancelLock();
466 } 407 }
467 408
468 void Compositor::NotifyEnd() {
469 last_ended_frame_++;
470 TRACE_EVENT_ASYNC_END0("ui", "Compositor::Draw", last_ended_frame_);
471 waiting_on_compositing_end_ = false;
472 if (draw_on_compositing_end_) {
473 draw_on_compositing_end_ = false;
474
475 // Call ScheduleDraw() instead of Draw() in order to allow other
476 // CompositorObservers to be notified before starting another
477 // draw cycle.
478 ScheduleDraw();
479 }
480 FOR_EACH_OBSERVER(
481 CompositorObserver, observer_list_, OnCompositingEnded(this));
482 }
483
484 } // namespace ui 409 } // namespace ui
OLDNEW
« no previous file with comments | « ui/compositor/compositor.h ('k') | ui/compositor/layer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698