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

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

Issue 548153004: Unified BeginFrame scheduling (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: git cl format Created 6 years, 3 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/compositor.gyp » ('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"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
16 #include "base/sys_info.h" 16 #include "base/sys_info.h"
17 #include "cc/base/latency_info_swap_promise.h" 17 #include "cc/base/latency_info_swap_promise.h"
18 #include "cc/base/switches.h" 18 #include "cc/base/switches.h"
19 #include "cc/input/input_handler.h" 19 #include "cc/input/input_handler.h"
20 #include "cc/layers/layer.h" 20 #include "cc/layers/layer.h"
21 #include "cc/output/begin_frame_args.h" 21 #include "cc/output/begin_frame_args.h"
22 #include "cc/output/context_provider.h" 22 #include "cc/output/context_provider.h"
23 #include "cc/trees/layer_tree_host.h" 23 #include "cc/trees/layer_tree_host.h"
24 #include "third_party/skia/include/core/SkBitmap.h" 24 #include "third_party/skia/include/core/SkBitmap.h"
25 #include "ui/compositor/compositor_observer.h" 25 #include "ui/compositor/compositor_observer.h"
26 #include "ui/compositor/compositor_switches.h" 26 #include "ui/compositor/compositor_switches.h"
27 #include "ui/compositor/compositor_vsync_manager.h"
28 #include "ui/compositor/dip_util.h" 27 #include "ui/compositor/dip_util.h"
29 #include "ui/compositor/layer.h" 28 #include "ui/compositor/layer.h"
30 #include "ui/compositor/layer_animator_collection.h" 29 #include "ui/compositor/layer_animator_collection.h"
31 #include "ui/gfx/frame_time.h" 30 #include "ui/gfx/frame_time.h"
32 #include "ui/gl/gl_context.h" 31 #include "ui/gl/gl_context.h"
33 #include "ui/gl/gl_switches.h" 32 #include "ui/gl/gl_switches.h"
34 33
35 namespace { 34 namespace {
36 35
37 const double kDefaultRefreshRate = 60.0; 36 const double kDefaultRefreshRate = 60.0;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 namespace ui { 68 namespace ui {
70 69
71 Compositor::Compositor(gfx::AcceleratedWidget widget, 70 Compositor::Compositor(gfx::AcceleratedWidget widget,
72 ui::ContextFactory* context_factory, 71 ui::ContextFactory* context_factory,
73 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 72 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
74 : context_factory_(context_factory), 73 : context_factory_(context_factory),
75 root_layer_(NULL), 74 root_layer_(NULL),
76 widget_(widget), 75 widget_(widget),
77 compositor_thread_loop_(context_factory->GetCompositorMessageLoop()), 76 compositor_thread_loop_(context_factory->GetCompositorMessageLoop()),
78 task_runner_(task_runner), 77 task_runner_(task_runner),
79 vsync_manager_(new CompositorVSyncManager()),
80 device_scale_factor_(0.0f), 78 device_scale_factor_(0.0f),
81 last_started_frame_(0), 79 last_started_frame_(0),
82 last_ended_frame_(0), 80 last_ended_frame_(0),
83 disable_schedule_composite_(false), 81 disable_schedule_composite_(false),
84 compositor_lock_(NULL), 82 compositor_lock_(NULL),
85 defer_draw_scheduling_(false), 83 defer_draw_scheduling_(false),
86 waiting_on_compositing_end_(false), 84 waiting_on_compositing_end_(false),
87 draw_on_compositing_end_(false), 85 draw_on_compositing_end_(false),
88 swap_state_(SWAP_NONE), 86 swap_state_(SWAP_NONE),
89 layer_animator_collection_(this), 87 layer_animator_collection_(this),
90 schedule_draw_factory_(this) { 88 schedule_draw_factory_(this),
89 output_surface_lost_(true) {
91 root_web_layer_ = cc::Layer::Create(); 90 root_web_layer_ = cc::Layer::Create();
92 91
93 CommandLine* command_line = CommandLine::ForCurrentProcess(); 92 CommandLine* command_line = CommandLine::ForCurrentProcess();
94 93
95 cc::LayerTreeSettings settings; 94 cc::LayerTreeSettings settings;
96 settings.refresh_rate = 95 settings.refresh_rate =
97 context_factory_->DoesCreateTestContexts() 96 context_factory_->DoesCreateTestContexts()
98 ? kTestRefreshRate 97 ? kTestRefreshRate
99 : kDefaultRefreshRate; 98 : kDefaultRefreshRate;
100 settings.main_frame_before_draw_enabled = false; 99 settings.main_frame_before_draw_enabled = false;
101 settings.main_frame_before_activation_enabled = false; 100 settings.main_frame_before_activation_enabled = false;
102 settings.throttle_frame_production = 101 settings.throttle_frame_production =
103 !command_line->HasSwitch(switches::kDisableGpuVsync); 102 !command_line->HasSwitch(switches::kDisableGpuVsync);
103 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
104 settings.begin_frame_publisher = true;
105 #elif defined(OS_MACOSX)
106 // MacOSX only uses browser compositor when delegated rendering is used.
107 if (command_line->HasSwitch(switches::kEnableDelegatedRenderer)) {
108 settings.begin_frame_publisher = true;
109 settings.begin_frame_receiver = true;
110 }
111 #endif
104 #if !defined(OS_MACOSX) 112 #if !defined(OS_MACOSX)
105 settings.partial_swap_enabled = 113 settings.partial_swap_enabled =
106 !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap); 114 !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap);
107 #endif 115 #endif
108 #if defined(OS_CHROMEOS) 116 #if defined(OS_CHROMEOS)
109 settings.per_tile_painting_enabled = true; 117 settings.per_tile_painting_enabled = true;
110 #endif 118 #endif
111 119
112 // These flags should be mirrored by renderer versions in content/renderer/. 120 // These flags should be mirrored by renderer versions in content/renderer/.
113 settings.initial_debug_state.show_debug_borders = 121 settings.initial_debug_state.show_debug_borders =
(...skipping 19 matching lines...) Expand all
133 141
134 settings.initial_debug_state.SetRecordRenderingStats( 142 settings.initial_debug_state.SetRecordRenderingStats(
135 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking)); 143 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
136 144
137 settings.impl_side_painting = IsUIImplSidePaintingEnabled(); 145 settings.impl_side_painting = IsUIImplSidePaintingEnabled();
138 settings.use_zero_copy = IsUIZeroCopyEnabled(); 146 settings.use_zero_copy = IsUIZeroCopyEnabled();
139 settings.single_thread_proxy_scheduler = false; 147 settings.single_thread_proxy_scheduler = false;
140 148
141 base::TimeTicks before_create = base::TimeTicks::Now(); 149 base::TimeTicks before_create = base::TimeTicks::Now();
142 if (compositor_thread_loop_.get()) { 150 if (compositor_thread_loop_.get()) {
151 // Unified BeginFrame scheduling is not used with threaded compositing.
152 DCHECK(!settings.begin_frame_publisher);
143 host_ = cc::LayerTreeHost::CreateThreaded( 153 host_ = cc::LayerTreeHost::CreateThreaded(
144 this, 154 this,
145 context_factory_->GetSharedBitmapManager(), 155 context_factory_->GetSharedBitmapManager(),
146 settings, 156 settings,
147 task_runner_, 157 task_runner_,
148 compositor_thread_loop_); 158 compositor_thread_loop_);
149 } else { 159 } else {
150 host_ = cc::LayerTreeHost::CreateSingleThreaded( 160 host_ = cc::LayerTreeHost::CreateSingleThreaded(
151 this, 161 this,
152 this, 162 this,
153 context_factory_->GetSharedBitmapManager(), 163 context_factory_->GetSharedBitmapManager(),
154 settings, 164 settings,
155 task_runner_); 165 task_runner_);
156 } 166 }
157 UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor", 167 UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor",
158 base::TimeTicks::Now() - before_create); 168 base::TimeTicks::Now() - before_create);
159 host_->SetRootLayer(root_web_layer_); 169 host_->SetRootLayer(root_web_layer_);
160 host_->SetLayerTreeHostClientReady(); 170 host_->SetLayerTreeHostClientReady();
161 } 171 }
162 172
163 Compositor::~Compositor() { 173 Compositor::~Compositor() {
164 TRACE_EVENT0("shutdown", "Compositor::destructor"); 174 TRACE_EVENT0("shutdown", "Compositor::destructor");
165 175
166 CancelCompositorLock(); 176 CancelCompositorLock();
167 DCHECK(!compositor_lock_); 177 DCHECK(!compositor_lock_);
168 178
179 DCHECK(!begin_frame_observer_list_.might_have_observers());
180
169 if (root_layer_) 181 if (root_layer_)
170 root_layer_->SetCompositor(NULL); 182 root_layer_->SetCompositor(NULL);
171 183
172 // Stop all outstanding draws before telling the ContextFactory to tear 184 // Stop all outstanding draws before telling the ContextFactory to tear
173 // down any contexts that the |host_| may rely upon. 185 // down any contexts that the |host_| may rely upon.
174 host_.reset(); 186 host_.reset();
175 187
176 context_factory_->RemoveCompositor(this); 188 context_factory_->RemoveCompositor(this);
177 } 189 }
178 190
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 284
273 void Compositor::SetBackgroundColor(SkColor color) { 285 void Compositor::SetBackgroundColor(SkColor color) {
274 host_->set_background_color(color); 286 host_->set_background_color(color);
275 ScheduleDraw(); 287 ScheduleDraw();
276 } 288 }
277 289
278 void Compositor::SetVisible(bool visible) { 290 void Compositor::SetVisible(bool visible) {
279 host_->SetVisible(visible); 291 host_->SetVisible(visible);
280 } 292 }
281 293
282 scoped_refptr<CompositorVSyncManager> Compositor::vsync_manager() const { 294 void Compositor::SetAuthoritativeVSyncInterval(base::TimeDelta interval) const {
283 return vsync_manager_; 295 host_->SetAuthoritativeVSyncInterval(interval);
296 }
297
298 void Compositor::StartBeginFrame(const cc::BeginFrameArgs& args) const {
299 if (output_surface_lost_)
300 return;
301 task_runner_->PostTask(
302 FROM_HERE,
303 base::Bind(
304 &cc::OutputSurface::BeginFrame, output_surface_weak_ptr_, args));
284 } 305 }
285 306
286 void Compositor::AddObserver(CompositorObserver* observer) { 307 void Compositor::AddObserver(CompositorObserver* observer) {
287 #if defined(OS_MACOSX) 308 #if defined(OS_MACOSX)
288 // Debugging instrumentation for crbug.com/401630. 309 // Debugging instrumentation for crbug.com/401630.
289 // TODO(ccameron): remove this. 310 // TODO(ccameron): remove this.
290 CHECK(observer); 311 CHECK(observer);
291 if (!observer_list_.HasObserver(observer)) 312 if (!observer_list_.HasObserver(observer))
292 observer->observing_count_ += 1; 313 observer->observing_count_ += 1;
293 #endif 314 #endif
(...skipping 23 matching lines...) Expand all
317 338
318 void Compositor::RemoveAnimationObserver( 339 void Compositor::RemoveAnimationObserver(
319 CompositorAnimationObserver* observer) { 340 CompositorAnimationObserver* observer) {
320 animation_observer_list_.RemoveObserver(observer); 341 animation_observer_list_.RemoveObserver(observer);
321 } 342 }
322 343
323 bool Compositor::HasAnimationObserver(CompositorAnimationObserver* observer) { 344 bool Compositor::HasAnimationObserver(CompositorAnimationObserver* observer) {
324 return animation_observer_list_.HasObserver(observer); 345 return animation_observer_list_.HasObserver(observer);
325 } 346 }
326 347
348 void Compositor::AddBeginFrameObserver(
349 CompositorBeginFrameObserver* observer,
350 const cc::BeginFrameArgs& last_begin_frame_args_sent_to_observer) {
351 bool need_begin_frame = false;
352 if (!begin_frame_observer_list_.might_have_observers()) {
353 need_begin_frame = true;
354 }
355
356 begin_frame_observer_list_.AddObserver(observer);
357
358 if (need_begin_frame) {
359 task_runner_->PostTask(FROM_HERE,
360 base::Bind(&Compositor::SetChildrenNeedBeginFrames,
361 base::Unretained(this),
362 true));
363 }
364
365 // If |last_begin_frame_args_| is still effective, send it to the new
366 // |observer| immediately.
367 if (!last_begin_frame_args_sent_to_observer.deadline.is_null() &&
368 last_begin_frame_args_sent_to_observer != last_begin_frame_args_ &&
369 last_begin_frame_args_.deadline > base::TimeTicks::Now())
370 observer->OnSendBeginFrame(last_begin_frame_args_);
371 }
372
373 void Compositor::RemoveBeginFrameObserver(
374 CompositorBeginFrameObserver* observer) {
375 DCHECK(begin_frame_observer_list_.might_have_observers());
376
377 begin_frame_observer_list_.RemoveObserver(observer);
378
379 if (!begin_frame_observer_list_.might_have_observers()) {
380 task_runner_->PostTask(FROM_HERE,
381 base::Bind(&Compositor::SetChildrenNeedBeginFrames,
382 base::Unretained(this),
383 false));
384 }
385 }
386
327 void Compositor::BeginMainFrame(const cc::BeginFrameArgs& args) { 387 void Compositor::BeginMainFrame(const cc::BeginFrameArgs& args) {
328 FOR_EACH_OBSERVER(CompositorAnimationObserver, 388 FOR_EACH_OBSERVER(CompositorAnimationObserver,
329 animation_observer_list_, 389 animation_observer_list_,
330 OnAnimationStep(args.frame_time)); 390 OnAnimationStep(args.frame_time));
331 if (animation_observer_list_.might_have_observers()) 391 if (animation_observer_list_.might_have_observers())
332 host_->SetNeedsAnimate(); 392 host_->SetNeedsAnimate();
333 } 393 }
334 394
335 void Compositor::Layout() { 395 void Compositor::Layout() {
336 // We're sending damage that will be addressed during this composite 396 // We're sending damage that will be addressed during this composite
337 // cycle, so we don't need to schedule another composite to address it. 397 // cycle, so we don't need to schedule another composite to address it.
338 disable_schedule_composite_ = true; 398 disable_schedule_composite_ = true;
339 if (root_layer_) 399 if (root_layer_)
340 root_layer_->SendDamagedRects(); 400 root_layer_->SendDamagedRects();
341 disable_schedule_composite_ = false; 401 disable_schedule_composite_ = false;
342 } 402 }
343 403
344 scoped_ptr<cc::OutputSurface> Compositor::CreateOutputSurface(bool fallback) { 404 scoped_ptr<cc::OutputSurface> Compositor::CreateOutputSurface(bool fallback) {
345 return context_factory_->CreateOutputSurface(this, fallback); 405 scoped_ptr<cc::OutputSurface> output_surface =
406 context_factory_->CreateOutputSurface(this, fallback);
407 // Keep this here, but can be used when DidInitializeOutputSurface() is false.
408 DCHECK(!output_surface_weak_ptr_);
409 output_surface_weak_ptr_ = output_surface->GetWeakPtr();
410 return output_surface.Pass();
411 }
412
413 void Compositor::DidInitializeOutputSurface() {
414 DCHECK(output_surface_weak_ptr_);
415 output_surface_lost_ = false;
416 }
417
418 void Compositor::DidLoseOutputSurface() {
419 output_surface_lost_ = true;
420 output_surface_weak_ptr_.reset();
346 } 421 }
347 422
348 void Compositor::DidCommit() { 423 void Compositor::DidCommit() {
349 DCHECK(!IsLocked()); 424 DCHECK(!IsLocked());
350 FOR_EACH_OBSERVER(CompositorObserver, 425 FOR_EACH_OBSERVER(CompositorObserver,
351 observer_list_, 426 observer_list_,
352 OnCompositingDidCommit(this)); 427 OnCompositingDidCommit(this));
353 } 428 }
354 429
355 void Compositor::DidCommitAndDrawFrame() { 430 void Compositor::DidCommitAndDrawFrame() {
(...skipping 15 matching lines...) Expand all
371 446
372 void Compositor::ScheduleComposite() { 447 void Compositor::ScheduleComposite() {
373 if (!disable_schedule_composite_) 448 if (!disable_schedule_composite_)
374 ScheduleDraw(); 449 ScheduleDraw();
375 } 450 }
376 451
377 void Compositor::ScheduleAnimation() { 452 void Compositor::ScheduleAnimation() {
378 ScheduleComposite(); 453 ScheduleComposite();
379 } 454 }
380 455
456 void Compositor::SendBeginFrameToChildren(const cc::BeginFrameArgs& args) {
457 FOR_EACH_OBSERVER(CompositorBeginFrameObserver,
458 begin_frame_observer_list_,
459 OnSendBeginFrame(args));
460 last_begin_frame_args_ = args;
461 }
462
381 void Compositor::DidPostSwapBuffers() { 463 void Compositor::DidPostSwapBuffers() {
382 DCHECK(!compositor_thread_loop_.get()); 464 DCHECK(!compositor_thread_loop_.get());
383 DCHECK_EQ(swap_state_, SWAP_NONE); 465 DCHECK_EQ(swap_state_, SWAP_NONE);
384 swap_state_ = SWAP_POSTED; 466 swap_state_ = SWAP_POSTED;
385 } 467 }
386 468
387 void Compositor::DidAbortSwapBuffers() { 469 void Compositor::DidAbortSwapBuffers() {
388 if (!compositor_thread_loop_.get()) { 470 if (!compositor_thread_loop_.get()) {
389 if (swap_state_ == SWAP_POSTED) { 471 if (swap_state_ == SWAP_POSTED) {
390 NotifyEnd(); 472 NotifyEnd();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 524
443 // Call ScheduleDraw() instead of Draw() in order to allow other 525 // Call ScheduleDraw() instead of Draw() in order to allow other
444 // CompositorObservers to be notified before starting another 526 // CompositorObservers to be notified before starting another
445 // draw cycle. 527 // draw cycle.
446 ScheduleDraw(); 528 ScheduleDraw();
447 } 529 }
448 FOR_EACH_OBSERVER( 530 FOR_EACH_OBSERVER(
449 CompositorObserver, observer_list_, OnCompositingEnded(this)); 531 CompositorObserver, observer_list_, OnCompositingEnded(this));
450 } 532 }
451 533
534 void Compositor::SetChildrenNeedBeginFrames(bool need_begin_frame) {
535 host_->SetChildrenNeedBeginFrames(need_begin_frame);
536 }
537
452 } // namespace ui 538 } // namespace ui
OLDNEW
« no previous file with comments | « ui/compositor/compositor.h ('k') | ui/compositor/compositor.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698