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

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

Issue 423773002: Unified BeginFrame scheduling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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 | Annotate | Revision Log
« 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 19 matching lines...) Expand all
57 56
58 void CompositorLock::CancelLock() { 57 void CompositorLock::CancelLock() {
59 if (!compositor_) 58 if (!compositor_)
60 return; 59 return;
61 compositor_->UnlockCompositor(); 60 compositor_->UnlockCompositor();
62 compositor_ = NULL; 61 compositor_ = NULL;
63 } 62 }
64 63
65 } // namespace ui 64 } // namespace ui
66 65
67 namespace {} // namespace
68
69 namespace ui { 66 namespace ui {
70 67
71 Compositor::Compositor(gfx::AcceleratedWidget widget, 68 Compositor::Compositor(gfx::AcceleratedWidget widget,
72 ui::ContextFactory* context_factory, 69 ui::ContextFactory* context_factory,
73 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 70 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
74 : context_factory_(context_factory), 71 : context_factory_(context_factory),
75 root_layer_(NULL), 72 root_layer_(NULL),
76 widget_(widget), 73 widget_(widget),
77 compositor_thread_loop_(context_factory->GetCompositorMessageLoop()), 74 compositor_thread_loop_(context_factory->GetCompositorMessageLoop()),
78 task_runner_(task_runner), 75 task_runner_(task_runner),
79 vsync_manager_(new CompositorVSyncManager()),
80 device_scale_factor_(0.0f), 76 device_scale_factor_(0.0f),
81 last_started_frame_(0), 77 last_started_frame_(0),
82 last_ended_frame_(0), 78 last_ended_frame_(0),
83 disable_schedule_composite_(false), 79 disable_schedule_composite_(false),
84 compositor_lock_(NULL), 80 compositor_lock_(NULL),
85 defer_draw_scheduling_(false), 81 defer_draw_scheduling_(false),
86 waiting_on_compositing_end_(false), 82 waiting_on_compositing_end_(false),
87 draw_on_compositing_end_(false), 83 draw_on_compositing_end_(false),
88 swap_state_(SWAP_NONE), 84 swap_state_(SWAP_NONE),
89 layer_animator_collection_(this), 85 layer_animator_collection_(this),
90 schedule_draw_factory_(this) { 86 schedule_draw_factory_(this),
87 output_surface_lost_(true) {
91 root_web_layer_ = cc::Layer::Create(); 88 root_web_layer_ = cc::Layer::Create();
92 89
93 CommandLine* command_line = CommandLine::ForCurrentProcess(); 90 CommandLine* command_line = CommandLine::ForCurrentProcess();
94 91
95 cc::LayerTreeSettings settings; 92 cc::LayerTreeSettings settings;
96 settings.refresh_rate = 93 settings.refresh_rate =
97 context_factory_->DoesCreateTestContexts() 94 context_factory_->DoesCreateTestContexts()
98 ? kTestRefreshRate 95 ? kTestRefreshRate
99 : kDefaultRefreshRate; 96 : kDefaultRefreshRate;
100 settings.main_frame_before_draw_enabled = false; 97 settings.main_frame_before_draw_enabled = false;
101 settings.main_frame_before_activation_enabled = false; 98 settings.main_frame_before_activation_enabled = false;
102 settings.throttle_frame_production = 99 settings.throttle_frame_production =
103 !command_line->HasSwitch(switches::kDisableGpuVsync); 100 !command_line->HasSwitch(switches::kDisableGpuVsync);
104 #if !defined(OS_MACOSX) 101 #if !defined(OS_MACOSX)
105 settings.partial_swap_enabled = 102 settings.partial_swap_enabled =
106 !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap); 103 !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap);
104 settings.begin_frame_publisher =
105 command_line->HasSwitch(cc::switches::kEnableBeginFrameScheduling);
107 #endif 106 #endif
108 #if defined(OS_CHROMEOS) 107 #if defined(OS_CHROMEOS)
109 settings.per_tile_painting_enabled = true; 108 settings.per_tile_painting_enabled = true;
110 #endif 109 #endif
111 110
112 // These flags should be mirrored by renderer versions in content/renderer/. 111 // These flags should be mirrored by renderer versions in content/renderer/.
113 settings.initial_debug_state.show_debug_borders = 112 settings.initial_debug_state.show_debug_borders =
114 command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders); 113 command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders);
115 settings.initial_debug_state.show_fps_counter = 114 settings.initial_debug_state.show_fps_counter =
116 command_line->HasSwitch(cc::switches::kUIShowFPSCounter); 115 command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
(...skipping 16 matching lines...) Expand all
133 132
134 settings.initial_debug_state.SetRecordRenderingStats( 133 settings.initial_debug_state.SetRecordRenderingStats(
135 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking)); 134 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
136 135
137 settings.impl_side_painting = IsUIImplSidePaintingEnabled(); 136 settings.impl_side_painting = IsUIImplSidePaintingEnabled();
138 settings.use_zero_copy = IsUIZeroCopyEnabled(); 137 settings.use_zero_copy = IsUIZeroCopyEnabled();
139 settings.single_thread_proxy_scheduler = false; 138 settings.single_thread_proxy_scheduler = false;
140 139
141 base::TimeTicks before_create = base::TimeTicks::Now(); 140 base::TimeTicks before_create = base::TimeTicks::Now();
142 if (compositor_thread_loop_.get()) { 141 if (compositor_thread_loop_.get()) {
142 // Unified BeginFrame scheduling is not used with threaded compositing.
143 DCHECK(!settings.begin_frame_publisher);
143 host_ = cc::LayerTreeHost::CreateThreaded( 144 host_ = cc::LayerTreeHost::CreateThreaded(
144 this, 145 this,
145 context_factory_->GetSharedBitmapManager(), 146 context_factory_->GetSharedBitmapManager(),
146 settings, 147 settings,
147 task_runner_, 148 task_runner_,
148 compositor_thread_loop_); 149 compositor_thread_loop_);
149 } else { 150 } else {
150 host_ = cc::LayerTreeHost::CreateSingleThreaded( 151 host_ = cc::LayerTreeHost::CreateSingleThreaded(
151 this, 152 this,
152 this, 153 this,
153 context_factory_->GetSharedBitmapManager(), 154 context_factory_->GetSharedBitmapManager(),
154 settings, 155 settings,
155 task_runner_); 156 task_runner_);
156 } 157 }
157 UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor", 158 UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor",
158 base::TimeTicks::Now() - before_create); 159 base::TimeTicks::Now() - before_create);
159 host_->SetRootLayer(root_web_layer_); 160 host_->SetRootLayer(root_web_layer_);
160 host_->SetLayerTreeHostClientReady(); 161 host_->SetLayerTreeHostClientReady();
161 } 162 }
162 163
163 Compositor::~Compositor() { 164 Compositor::~Compositor() {
164 TRACE_EVENT0("shutdown", "Compositor::destructor"); 165 TRACE_EVENT0("shutdown", "Compositor::destructor");
165 166
166 CancelCompositorLock(); 167 CancelCompositorLock();
167 DCHECK(!compositor_lock_); 168 DCHECK(!compositor_lock_);
168 169
170 DCHECK(!begin_frame_observer_list_.might_have_observers());
171
169 if (root_layer_) 172 if (root_layer_)
170 root_layer_->SetCompositor(NULL); 173 root_layer_->SetCompositor(NULL);
171 174
172 // Stop all outstanding draws before telling the ContextFactory to tear 175 // Stop all outstanding draws before telling the ContextFactory to tear
173 // down any contexts that the |host_| may rely upon. 176 // down any contexts that the |host_| may rely upon.
174 host_.reset(); 177 host_.reset();
175 178
176 context_factory_->RemoveCompositor(this); 179 context_factory_->RemoveCompositor(this);
177 } 180 }
178 181
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 275
273 void Compositor::SetBackgroundColor(SkColor color) { 276 void Compositor::SetBackgroundColor(SkColor color) {
274 host_->set_background_color(color); 277 host_->set_background_color(color);
275 ScheduleDraw(); 278 ScheduleDraw();
276 } 279 }
277 280
278 void Compositor::SetVisible(bool visible) { 281 void Compositor::SetVisible(bool visible) {
279 host_->SetVisible(visible); 282 host_->SetVisible(visible);
280 } 283 }
281 284
282 scoped_refptr<CompositorVSyncManager> Compositor::vsync_manager() const { 285 void Compositor::SetAuthoritativeVSyncInterval(base::TimeDelta interval) const {
283 return vsync_manager_; 286 host_->SetAuthoritativeVSyncInterval(interval);
287 }
288
289 void Compositor::StartBeginFrame(const cc::BeginFrameArgs& args) const {
290 if (output_surface_lost_)
291 return;
292 task_runner_->PostTask(
293 FROM_HERE,
294 base::Bind(
295 &cc::OutputSurface::BeginFrame, output_surface_weak_ptr_, args));
284 } 296 }
285 297
286 void Compositor::AddObserver(CompositorObserver* observer) { 298 void Compositor::AddObserver(CompositorObserver* observer) {
287 #if defined(OS_MACOSX) 299 #if defined(OS_MACOSX)
288 // Debugging instrumentation for crbug.com/401630. 300 // Debugging instrumentation for crbug.com/401630.
289 // TODO(ccameron): remove this. 301 // TODO(ccameron): remove this.
290 CHECK(observer); 302 CHECK(observer);
291 if (!observer_list_.HasObserver(observer)) 303 if (!observer_list_.HasObserver(observer))
292 observer->observing_count_ += 1; 304 observer->observing_count_ += 1;
293 #endif 305 #endif
(...skipping 23 matching lines...) Expand all
317 329
318 void Compositor::RemoveAnimationObserver( 330 void Compositor::RemoveAnimationObserver(
319 CompositorAnimationObserver* observer) { 331 CompositorAnimationObserver* observer) {
320 animation_observer_list_.RemoveObserver(observer); 332 animation_observer_list_.RemoveObserver(observer);
321 } 333 }
322 334
323 bool Compositor::HasAnimationObserver(CompositorAnimationObserver* observer) { 335 bool Compositor::HasAnimationObserver(CompositorAnimationObserver* observer) {
324 return animation_observer_list_.HasObserver(observer); 336 return animation_observer_list_.HasObserver(observer);
325 } 337 }
326 338
339 void Compositor::AddBeginFrameObserver(
340 CompositorBeginFrameObserver* observer,
341 const cc::BeginFrameArgs& last_begin_frame_args_sent_to_observer) {
342 bool need_begin_frame = false;
343 if (!begin_frame_observer_list_.might_have_observers()) {
344 need_begin_frame = true;
345 }
346
347 begin_frame_observer_list_.AddObserver(observer);
348
349 if (need_begin_frame) {
350 task_runner_->PostTask(FROM_HERE,
351 base::Bind(&Compositor::SetChildrenNeedBeginFrames,
352 base::Unretained(this),
353 true));
354 }
355
356 // If |last_begin_frame_args_| is still effective, send it to the new
357 // |observer| immediately.
358 if (!last_begin_frame_args_sent_to_observer.deadline.is_null() &&
359 last_begin_frame_args_sent_to_observer != last_begin_frame_args_ &&
360 last_begin_frame_args_.deadline > base::TimeTicks::Now())
361 observer->OnSendBeginFrame(last_begin_frame_args_);
362 }
363
364 void Compositor::RemoveBeginFrameObserver(
365 CompositorBeginFrameObserver* observer) {
366 DCHECK(begin_frame_observer_list_.might_have_observers());
367
368 begin_frame_observer_list_.RemoveObserver(observer);
369
370 if (!begin_frame_observer_list_.might_have_observers()) {
371 task_runner_->PostTask(FROM_HERE,
372 base::Bind(&Compositor::SetChildrenNeedBeginFrames,
373 base::Unretained(this),
374 false));
375 }
376 }
377
327 void Compositor::BeginMainFrame(const cc::BeginFrameArgs& args) { 378 void Compositor::BeginMainFrame(const cc::BeginFrameArgs& args) {
328 FOR_EACH_OBSERVER(CompositorAnimationObserver, 379 FOR_EACH_OBSERVER(CompositorAnimationObserver,
329 animation_observer_list_, 380 animation_observer_list_,
330 OnAnimationStep(args.frame_time)); 381 OnAnimationStep(args.frame_time));
331 if (animation_observer_list_.might_have_observers()) 382 if (animation_observer_list_.might_have_observers())
332 host_->SetNeedsAnimate(); 383 host_->SetNeedsAnimate();
333 } 384 }
334 385
335 void Compositor::Layout() { 386 void Compositor::Layout() {
336 // We're sending damage that will be addressed during this composite 387 // 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. 388 // cycle, so we don't need to schedule another composite to address it.
338 disable_schedule_composite_ = true; 389 disable_schedule_composite_ = true;
339 if (root_layer_) 390 if (root_layer_)
340 root_layer_->SendDamagedRects(); 391 root_layer_->SendDamagedRects();
341 disable_schedule_composite_ = false; 392 disable_schedule_composite_ = false;
342 } 393 }
343 394
344 scoped_ptr<cc::OutputSurface> Compositor::CreateOutputSurface(bool fallback) { 395 scoped_ptr<cc::OutputSurface> Compositor::CreateOutputSurface(bool fallback) {
345 return context_factory_->CreateOutputSurface(this, fallback); 396 scoped_ptr<cc::OutputSurface> output_surface =
397 context_factory_->CreateOutputSurface(this, fallback);
398 // Keep this here, but can be used when DidInitializeOutputSurface() is false.
399 DCHECK(!output_surface_weak_ptr_);
400 output_surface_weak_ptr_ = output_surface->GetWeakPtr();
401 return output_surface.Pass();
402 }
403
404 void Compositor::DidInitializeOutputSurface() {
405 DCHECK(output_surface_weak_ptr_);
406 output_surface_lost_ = false;
407 }
408
409 void Compositor::DidLoseOutputSurface() {
410 output_surface_lost_ = true;
411 output_surface_weak_ptr_.reset();
346 } 412 }
347 413
348 void Compositor::DidCommit() { 414 void Compositor::DidCommit() {
349 DCHECK(!IsLocked()); 415 DCHECK(!IsLocked());
350 FOR_EACH_OBSERVER(CompositorObserver, 416 FOR_EACH_OBSERVER(CompositorObserver,
351 observer_list_, 417 observer_list_,
352 OnCompositingDidCommit(this)); 418 OnCompositingDidCommit(this));
353 } 419 }
354 420
355 void Compositor::DidCommitAndDrawFrame() { 421 void Compositor::DidCommitAndDrawFrame() {
(...skipping 15 matching lines...) Expand all
371 437
372 void Compositor::ScheduleComposite() { 438 void Compositor::ScheduleComposite() {
373 if (!disable_schedule_composite_) 439 if (!disable_schedule_composite_)
374 ScheduleDraw(); 440 ScheduleDraw();
375 } 441 }
376 442
377 void Compositor::ScheduleAnimation() { 443 void Compositor::ScheduleAnimation() {
378 ScheduleComposite(); 444 ScheduleComposite();
379 } 445 }
380 446
447 void Compositor::SendBeginFrameToChildren(const cc::BeginFrameArgs& args) {
448 FOR_EACH_OBSERVER(CompositorBeginFrameObserver,
449 begin_frame_observer_list_,
450 OnSendBeginFrame(args));
451 last_begin_frame_args_ = args;
452 }
453
381 void Compositor::DidPostSwapBuffers() { 454 void Compositor::DidPostSwapBuffers() {
382 DCHECK(!compositor_thread_loop_.get()); 455 DCHECK(!compositor_thread_loop_.get());
383 DCHECK_EQ(swap_state_, SWAP_NONE); 456 DCHECK_EQ(swap_state_, SWAP_NONE);
384 swap_state_ = SWAP_POSTED; 457 swap_state_ = SWAP_POSTED;
385 } 458 }
386 459
387 void Compositor::DidAbortSwapBuffers() { 460 void Compositor::DidAbortSwapBuffers() {
388 if (!compositor_thread_loop_.get()) { 461 if (!compositor_thread_loop_.get()) {
389 if (swap_state_ == SWAP_POSTED) { 462 if (swap_state_ == SWAP_POSTED) {
390 NotifyEnd(); 463 NotifyEnd();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 515
443 // Call ScheduleDraw() instead of Draw() in order to allow other 516 // Call ScheduleDraw() instead of Draw() in order to allow other
444 // CompositorObservers to be notified before starting another 517 // CompositorObservers to be notified before starting another
445 // draw cycle. 518 // draw cycle.
446 ScheduleDraw(); 519 ScheduleDraw();
447 } 520 }
448 FOR_EACH_OBSERVER( 521 FOR_EACH_OBSERVER(
449 CompositorObserver, observer_list_, OnCompositingEnded(this)); 522 CompositorObserver, observer_list_, OnCompositingEnded(this));
450 } 523 }
451 524
525 void Compositor::SetChildrenNeedBeginFrames(bool need_begin_frame) {
526 host_->SetChildrenNeedBeginFrames(need_begin_frame);
527 }
528
452 } // namespace ui 529 } // 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