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

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, 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 | Annotate | Revision Log
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/context_provider.h" 21 #include "cc/output/context_provider.h"
22 #include "cc/trees/layer_tree_host.h" 22 #include "cc/trees/layer_tree_host.h"
23 #include "third_party/skia/include/core/SkBitmap.h" 23 #include "third_party/skia/include/core/SkBitmap.h"
24 #include "ui/compositor/compositor_observer.h" 24 #include "ui/compositor/compositor_observer.h"
25 #include "ui/compositor/compositor_switches.h" 25 #include "ui/compositor/compositor_switches.h"
26 #include "ui/compositor/compositor_vsync_manager.h"
27 #include "ui/compositor/dip_util.h" 26 #include "ui/compositor/dip_util.h"
28 #include "ui/compositor/layer.h" 27 #include "ui/compositor/layer.h"
29 #include "ui/compositor/layer_animator_collection.h" 28 #include "ui/compositor/layer_animator_collection.h"
30 #include "ui/gfx/frame_time.h" 29 #include "ui/gfx/frame_time.h"
31 #include "ui/gl/gl_context.h" 30 #include "ui/gl/gl_context.h"
32 #include "ui/gl/gl_switches.h" 31 #include "ui/gl/gl_switches.h"
33 32
34 namespace { 33 namespace {
35 34
36 const double kDefaultRefreshRate = 60.0; 35 const double kDefaultRefreshRate = 60.0;
(...skipping 25 matching lines...) Expand all
62 } 61 }
63 62
64 Compositor::Compositor(gfx::AcceleratedWidget widget, 63 Compositor::Compositor(gfx::AcceleratedWidget widget,
65 ui::ContextFactory* context_factory, 64 ui::ContextFactory* context_factory,
66 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 65 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
67 : context_factory_(context_factory), 66 : context_factory_(context_factory),
68 root_layer_(NULL), 67 root_layer_(NULL),
69 widget_(widget), 68 widget_(widget),
70 compositor_thread_loop_(context_factory->GetCompositorMessageLoop()), 69 compositor_thread_loop_(context_factory->GetCompositorMessageLoop()),
71 task_runner_(task_runner), 70 task_runner_(task_runner),
72 vsync_manager_(new CompositorVSyncManager()),
73 device_scale_factor_(0.0f), 71 device_scale_factor_(0.0f),
74 disable_schedule_composite_(false), 72 disable_schedule_composite_(false),
75 compositor_lock_(NULL), 73 compositor_lock_(NULL),
76 layer_animator_collection_(this) { 74 layer_animator_collection_(this),
75 output_surface_lost_(true) {
77 root_web_layer_ = cc::Layer::Create(); 76 root_web_layer_ = cc::Layer::Create();
78 77
79 CommandLine* command_line = CommandLine::ForCurrentProcess(); 78 CommandLine* command_line = CommandLine::ForCurrentProcess();
80 79
81 cc::LayerTreeSettings settings; 80 cc::LayerTreeSettings settings;
82 settings.refresh_rate = 81 settings.refresh_rate =
83 context_factory_->DoesCreateTestContexts() 82 context_factory_->DoesCreateTestContexts()
84 ? kTestRefreshRate 83 ? kTestRefreshRate
85 : kDefaultRefreshRate; 84 : kDefaultRefreshRate;
86 settings.main_frame_before_draw_enabled = false; 85 settings.main_frame_before_draw_enabled = false;
87 settings.main_frame_before_activation_enabled = false; 86 settings.main_frame_before_activation_enabled = false;
88 settings.throttle_frame_production = 87 settings.throttle_frame_production =
89 !command_line->HasSwitch(switches::kDisableGpuVsync); 88 !command_line->HasSwitch(switches::kDisableGpuVsync);
89 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
brianderson 2014/09/04 18:45:46 Why !OS_CHROMOS?
90 settings.begin_frame_publisher = true;
91 #elif defined(OS_MACOSX)
92 // MacOSX only uses browser compositor when delegated rendering is used.
93 if (command_line->HasSwitch(switches::kEnableDelegatedRenderer)) {
piman 2014/09/04 20:56:38 This is a layering violation. Can this configurat
94 settings.begin_frame_publisher = true;
95 settings.begin_frame_receiver = true;
96 }
97 #endif
90 #if !defined(OS_MACOSX) 98 #if !defined(OS_MACOSX)
91 settings.partial_swap_enabled = 99 settings.partial_swap_enabled =
92 !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap); 100 !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap);
93 #endif 101 #endif
94 #if defined(OS_CHROMEOS) 102 #if defined(OS_CHROMEOS)
95 settings.per_tile_painting_enabled = true; 103 settings.per_tile_painting_enabled = true;
96 #endif 104 #endif
97 105
98 // These flags should be mirrored by renderer versions in content/renderer/. 106 // These flags should be mirrored by renderer versions in content/renderer/.
99 settings.initial_debug_state.show_debug_borders = 107 settings.initial_debug_state.show_debug_borders =
(...skipping 18 matching lines...) Expand all
118 command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects); 126 command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects);
119 127
120 settings.initial_debug_state.SetRecordRenderingStats( 128 settings.initial_debug_state.SetRecordRenderingStats(
121 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking)); 129 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
122 130
123 settings.impl_side_painting = IsUIImplSidePaintingEnabled(); 131 settings.impl_side_painting = IsUIImplSidePaintingEnabled();
124 settings.use_zero_copy = IsUIZeroCopyEnabled(); 132 settings.use_zero_copy = IsUIZeroCopyEnabled();
125 133
126 base::TimeTicks before_create = base::TimeTicks::Now(); 134 base::TimeTicks before_create = base::TimeTicks::Now();
127 if (compositor_thread_loop_) { 135 if (compositor_thread_loop_) {
136 // Unified BeginFrame scheduling is not used with threaded compositing.
137 DCHECK(!settings.begin_frame_publisher);
128 host_ = cc::LayerTreeHost::CreateThreaded( 138 host_ = cc::LayerTreeHost::CreateThreaded(
129 this, 139 this,
130 context_factory_->GetSharedBitmapManager(), 140 context_factory_->GetSharedBitmapManager(),
131 settings, 141 settings,
132 task_runner_, 142 task_runner_,
133 compositor_thread_loop_); 143 compositor_thread_loop_);
134 } else { 144 } else {
135 host_ = cc::LayerTreeHost::CreateSingleThreaded( 145 host_ = cc::LayerTreeHost::CreateSingleThreaded(
136 this, 146 this,
137 this, 147 this,
138 context_factory_->GetSharedBitmapManager(), 148 context_factory_->GetSharedBitmapManager(),
139 settings, 149 settings,
140 task_runner_); 150 task_runner_);
141 } 151 }
142 UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor", 152 UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor",
143 base::TimeTicks::Now() - before_create); 153 base::TimeTicks::Now() - before_create);
144 host_->SetRootLayer(root_web_layer_); 154 host_->SetRootLayer(root_web_layer_);
145 host_->SetLayerTreeHostClientReady(); 155 host_->SetLayerTreeHostClientReady();
146 } 156 }
147 157
148 Compositor::~Compositor() { 158 Compositor::~Compositor() {
149 TRACE_EVENT0("shutdown", "Compositor::destructor"); 159 TRACE_EVENT0("shutdown", "Compositor::destructor");
150 160
151 CancelCompositorLock(); 161 CancelCompositorLock();
152 DCHECK(!compositor_lock_); 162 DCHECK(!compositor_lock_);
153 163
164 DCHECK(!begin_frame_observer_list_.might_have_observers());
165
154 if (root_layer_) 166 if (root_layer_)
155 root_layer_->SetCompositor(NULL); 167 root_layer_->SetCompositor(NULL);
156 168
157 // Stop all outstanding draws before telling the ContextFactory to tear 169 // Stop all outstanding draws before telling the ContextFactory to tear
158 // down any contexts that the |host_| may rely upon. 170 // down any contexts that the |host_| may rely upon.
159 host_.reset(); 171 host_.reset();
160 172
161 context_factory_->RemoveCompositor(this); 173 context_factory_->RemoveCompositor(this);
162 } 174 }
163 175
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 if (root_layer_) 233 if (root_layer_)
222 root_layer_->OnDeviceScaleFactorChanged(scale); 234 root_layer_->OnDeviceScaleFactorChanged(scale);
223 } 235 }
224 } 236 }
225 237
226 void Compositor::SetBackgroundColor(SkColor color) { 238 void Compositor::SetBackgroundColor(SkColor color) {
227 host_->set_background_color(color); 239 host_->set_background_color(color);
228 ScheduleDraw(); 240 ScheduleDraw();
229 } 241 }
230 242
231 scoped_refptr<CompositorVSyncManager> Compositor::vsync_manager() const { 243 void Compositor::SetAuthoritativeVSyncInterval(
232 return vsync_manager_; 244 base::TimeDelta interval) const {
245 host_->SetAuthoritativeVSyncInterval(interval);
246 }
247
248 void Compositor::StartBeginFrame(const cc::BeginFrameArgs& args) const {
249 if (output_surface_lost_)
brianderson 2014/09/04 18:45:47 Hmm. Having to expose output_surface_lost_ to the
250 return;
251 task_runner_->PostTask(
brianderson 2014/09/04 18:45:46 Does this need to be a post task?
252 FROM_HERE,
253 base::Bind(&cc::OutputSurface::BeginFrame,
254 output_surface_weak_ptr_,
255 args));
233 } 256 }
234 257
235 void Compositor::AddObserver(CompositorObserver* observer) { 258 void Compositor::AddObserver(CompositorObserver* observer) {
236 observer_list_.AddObserver(observer); 259 observer_list_.AddObserver(observer);
237 } 260 }
238 261
239 void Compositor::RemoveObserver(CompositorObserver* observer) { 262 void Compositor::RemoveObserver(CompositorObserver* observer) {
240 observer_list_.RemoveObserver(observer); 263 observer_list_.RemoveObserver(observer);
241 } 264 }
242 265
243 bool Compositor::HasObserver(CompositorObserver* observer) { 266 bool Compositor::HasObserver(CompositorObserver* observer) {
244 return observer_list_.HasObserver(observer); 267 return observer_list_.HasObserver(observer);
245 } 268 }
246 269
247 void Compositor::AddAnimationObserver(CompositorAnimationObserver* observer) { 270 void Compositor::AddAnimationObserver(CompositorAnimationObserver* observer) {
248 animation_observer_list_.AddObserver(observer); 271 animation_observer_list_.AddObserver(observer);
249 host_->SetNeedsAnimate(); 272 host_->SetNeedsAnimate();
250 } 273 }
251 274
252 void Compositor::RemoveAnimationObserver( 275 void Compositor::RemoveAnimationObserver(
253 CompositorAnimationObserver* observer) { 276 CompositorAnimationObserver* observer) {
254 animation_observer_list_.RemoveObserver(observer); 277 animation_observer_list_.RemoveObserver(observer);
255 } 278 }
256 279
257 bool Compositor::HasAnimationObserver(CompositorAnimationObserver* observer) { 280 bool Compositor::HasAnimationObserver(CompositorAnimationObserver* observer) {
258 return animation_observer_list_.HasObserver(observer); 281 return animation_observer_list_.HasObserver(observer);
259 } 282 }
260 283
284 void Compositor::AddBeginFrameObserver(
285 CompositorBeginFrameObserver* observer,
286 const cc::BeginFrameArgs& last_begin_frame_args_sent_to_observer) {
287 bool need_begin_frame = false;
brianderson 2014/09/04 18:45:46 bool need_begin_frame = begin_frame_observer_list_
288 if (!begin_frame_observer_list_.might_have_observers()) {
289 need_begin_frame = true;
290 }
291
292 begin_frame_observer_list_.AddObserver(observer);
293
294 if (need_begin_frame) {
295 task_runner_->PostTask(
brianderson 2014/09/04 18:45:46 Does this need to be a PostTask?
296 FROM_HERE,
297 base::Bind(&Compositor::SetChildrenNeedBeginFrames,
298 base::Unretained(this),
299 true));
300 }
301
302 // If |last_begin_frame_args_| is still effective, send it to the new
303 // |observer| immediately.
304 if (!last_begin_frame_args_sent_to_observer.deadline.is_null() &&
305 last_begin_frame_args_sent_to_observer != last_begin_frame_args_ &&
306 last_begin_frame_args_.deadline > base::TimeTicks::Now())
307 observer->OnSendBeginFrame(last_begin_frame_args_);
308 }
309
310 void Compositor::RemoveBeginFrameObserver(
311 CompositorBeginFrameObserver* observer) {
312 DCHECK(begin_frame_observer_list_.might_have_observers());
313
314 begin_frame_observer_list_.RemoveObserver(observer);
315
316 if (!begin_frame_observer_list_.might_have_observers()) {
317 task_runner_->PostTask(
318 FROM_HERE,
319 base::Bind(&Compositor::SetChildrenNeedBeginFrames,
320 base::Unretained(this),
321 false));
322 }
323 }
324
261 void Compositor::Animate(base::TimeTicks frame_begin_time) { 325 void Compositor::Animate(base::TimeTicks frame_begin_time) {
262 FOR_EACH_OBSERVER(CompositorAnimationObserver, 326 FOR_EACH_OBSERVER(CompositorAnimationObserver,
263 animation_observer_list_, 327 animation_observer_list_,
264 OnAnimationStep(frame_begin_time)); 328 OnAnimationStep(frame_begin_time));
265 if (animation_observer_list_.might_have_observers()) 329 if (animation_observer_list_.might_have_observers())
266 host_->SetNeedsAnimate(); 330 host_->SetNeedsAnimate();
267 } 331 }
268 332
269 void Compositor::Layout() { 333 void Compositor::Layout() {
270 // We're sending damage that will be addressed during this composite 334 // We're sending damage that will be addressed during this composite
271 // cycle, so we don't need to schedule another composite to address it. 335 // cycle, so we don't need to schedule another composite to address it.
272 disable_schedule_composite_ = true; 336 disable_schedule_composite_ = true;
273 if (root_layer_) 337 if (root_layer_)
274 root_layer_->SendDamagedRects(); 338 root_layer_->SendDamagedRects();
275 disable_schedule_composite_ = false; 339 disable_schedule_composite_ = false;
276 } 340 }
277 341
278 scoped_ptr<cc::OutputSurface> Compositor::CreateOutputSurface(bool fallback) { 342 scoped_ptr<cc::OutputSurface> Compositor::CreateOutputSurface(bool fallback) {
279 return context_factory_->CreateOutputSurface(this, fallback); 343 scoped_ptr<cc::OutputSurface> output_surface =
344 context_factory_->CreateOutputSurface(this, fallback);
345 // Keep this here, but can be used when DidInitializeOutputSurface() is false.
346 DCHECK(!output_surface_weak_ptr_);
347 output_surface_weak_ptr_ = output_surface->GetWeakPtr();
piman 2014/09/04 20:56:38 This can't work when we use the compositor thread.
348 return output_surface.Pass();
349 }
350
351 void Compositor::DidInitializeOutputSurface() {
352 DCHECK(output_surface_weak_ptr_);
353 output_surface_lost_ = false;
354 }
355
356 void Compositor::DidLoseOutputSurface() {
357 output_surface_lost_ = true;
358 output_surface_weak_ptr_.reset();
280 } 359 }
281 360
282 void Compositor::DidCommit() { 361 void Compositor::DidCommit() {
283 DCHECK(!IsLocked()); 362 DCHECK(!IsLocked());
284 FOR_EACH_OBSERVER(CompositorObserver, 363 FOR_EACH_OBSERVER(CompositorObserver,
285 observer_list_, 364 observer_list_,
286 OnCompositingDidCommit(this)); 365 OnCompositingDidCommit(this));
287 } 366 }
288 367
289 void Compositor::DidCommitAndDrawFrame() { 368 void Compositor::DidCommitAndDrawFrame() {
290 } 369 }
291 370
292 void Compositor::DidCompleteSwapBuffers() { 371 void Compositor::DidCompleteSwapBuffers() {
293 // DidPostSwapBuffers is a SingleThreadProxy-only feature. Synthetically 372 // DidPostSwapBuffers is a SingleThreadProxy-only feature. Synthetically
294 // generate OnCompositingStarted messages for the threaded case so that 373 // generate OnCompositingStarted messages for the threaded case so that
295 // OnCompositingStarted/OnCompositingEnded messages match. 374 // OnCompositingStarted/OnCompositingEnded messages match.
296 if (compositor_thread_loop_) { 375 if (compositor_thread_loop_) {
297 base::TimeTicks start_time = gfx::FrameTime::Now(); 376 base::TimeTicks start_time = gfx::FrameTime::Now();
298 FOR_EACH_OBSERVER(CompositorObserver, 377 FOR_EACH_OBSERVER(CompositorObserver,
299 observer_list_, 378 observer_list_,
300 OnCompositingStarted(this, start_time)); 379 OnCompositingStarted(this, start_time));
301 } 380 }
302 FOR_EACH_OBSERVER( 381 FOR_EACH_OBSERVER(
303 CompositorObserver, observer_list_, OnCompositingEnded(this)); 382 CompositorObserver, observer_list_, OnCompositingEnded(this));
304 } 383 }
305 384
385 void Compositor::SendBeginFrameToChildren(
386 const cc::BeginFrameArgs& args) {
387 FOR_EACH_OBSERVER(CompositorBeginFrameObserver,
388 begin_frame_observer_list_,
389 OnSendBeginFrame(args));
390 last_begin_frame_args_ = args;
391 }
392
306 void Compositor::DidPostSwapBuffers() { 393 void Compositor::DidPostSwapBuffers() {
307 base::TimeTicks start_time = gfx::FrameTime::Now(); 394 base::TimeTicks start_time = gfx::FrameTime::Now();
308 FOR_EACH_OBSERVER(CompositorObserver, 395 FOR_EACH_OBSERVER(CompositorObserver,
309 observer_list_, 396 observer_list_,
310 OnCompositingStarted(this, start_time)); 397 OnCompositingStarted(this, start_time));
311 } 398 }
312 399
313 void Compositor::DidAbortSwapBuffers() { 400 void Compositor::DidAbortSwapBuffers() {
314 FOR_EACH_OBSERVER(CompositorObserver, 401 FOR_EACH_OBSERVER(CompositorObserver,
315 observer_list_, 402 observer_list_,
(...skipping 27 matching lines...) Expand all
343 FOR_EACH_OBSERVER(CompositorObserver, 430 FOR_EACH_OBSERVER(CompositorObserver,
344 observer_list_, 431 observer_list_,
345 OnCompositingLockStateChanged(this)); 432 OnCompositingLockStateChanged(this));
346 } 433 }
347 434
348 void Compositor::CancelCompositorLock() { 435 void Compositor::CancelCompositorLock() {
349 if (compositor_lock_) 436 if (compositor_lock_)
350 compositor_lock_->CancelLock(); 437 compositor_lock_->CancelLock();
351 } 438 }
352 439
440 void Compositor::SetChildrenNeedBeginFrames(bool need_begin_frame) {
441 host_->SetChildrenNeedBeginFrames(need_begin_frame);
442 }
443
353 } // namespace ui 444 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698