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

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: do not set disable_hi_res_timer_tasks_on_battery when testing Created 6 years 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
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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 ui::ContextFactory* context_factory, 68 ui::ContextFactory* context_factory,
69 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 69 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
70 : context_factory_(context_factory), 70 : context_factory_(context_factory),
71 root_layer_(NULL), 71 root_layer_(NULL),
72 widget_(widget), 72 widget_(widget),
73 surface_id_allocator_(context_factory->CreateSurfaceIdAllocator()), 73 surface_id_allocator_(context_factory->CreateSurfaceIdAllocator()),
74 compositor_thread_loop_(context_factory->GetCompositorMessageLoop()), 74 compositor_thread_loop_(context_factory->GetCompositorMessageLoop()),
75 task_runner_(task_runner), 75 task_runner_(task_runner),
76 vsync_manager_(new CompositorVSyncManager()), 76 vsync_manager_(new CompositorVSyncManager()),
77 device_scale_factor_(0.0f), 77 device_scale_factor_(0.0f),
78 last_started_frame_(0),
79 last_ended_frame_(0),
80 disable_schedule_composite_(false), 78 disable_schedule_composite_(false),
81 compositor_lock_(NULL), 79 compositor_lock_(NULL),
82 defer_draw_scheduling_(false),
83 waiting_on_compositing_end_(false),
84 draw_on_compositing_end_(false),
85 swap_state_(SWAP_NONE),
86 layer_animator_collection_(this), 80 layer_animator_collection_(this),
87 weak_ptr_factory_(this) { 81 weak_ptr_factory_(this) {
88 root_web_layer_ = cc::Layer::Create(); 82 root_web_layer_ = cc::Layer::Create();
89 83
90 CommandLine* command_line = CommandLine::ForCurrentProcess(); 84 CommandLine* command_line = CommandLine::ForCurrentProcess();
91 85
92 cc::LayerTreeSettings settings; 86 cc::LayerTreeSettings settings;
93 // When impl-side painting is enabled, this will ensure PictureLayers always 87 // When impl-side painting is enabled, this will ensure PictureLayers always
94 // can have LCD text, to match the previous behaviour with ContentLayers, 88 // can have LCD text, to match the previous behaviour with ContentLayers,
95 // where LCD-not-allowed notifications were ignored. 89 // where LCD-not-allowed notifications were ignored.
96 settings.layers_always_allowed_lcd_text = true; 90 settings.layers_always_allowed_lcd_text = true;
97 settings.renderer_settings.refresh_rate = 91 settings.renderer_settings.refresh_rate =
98 context_factory_->DoesCreateTestContexts() ? kTestRefreshRate 92 context_factory_->DoesCreateTestContexts() ? kTestRefreshRate
99 : kDefaultRefreshRate; 93 : kDefaultRefreshRate;
100 settings.main_frame_before_activation_enabled = false; 94 settings.main_frame_before_activation_enabled = false;
101 settings.throttle_frame_production = 95 settings.throttle_frame_production =
102 !command_line->HasSwitch(switches::kDisableGpuVsync); 96 !command_line->HasSwitch(switches::kDisableGpuVsync);
103 #if !defined(OS_MACOSX) 97 #if !defined(OS_MACOSX)
104 settings.renderer_settings.partial_swap_enabled = 98 settings.renderer_settings.partial_swap_enabled =
105 !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap); 99 !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap);
106 #endif 100 #endif
107 #if defined(OS_CHROMEOS) 101 #if defined(OS_CHROMEOS)
108 settings.per_tile_painting_enabled = true; 102 settings.per_tile_painting_enabled = true;
109 #endif 103 #endif
110 #if defined(OS_WIN) 104 #if defined(OS_WIN)
111 settings.disable_hi_res_timer_tasks_on_battery = true; 105 settings.disable_hi_res_timer_tasks_on_battery =
106 !context_factory_->DoesCreateTestContexts();
112 settings.renderer_settings.finish_rendering_on_resize = true; 107 settings.renderer_settings.finish_rendering_on_resize = true;
113 #endif 108 #endif
114 109
115 // These flags should be mirrored by renderer versions in content/renderer/. 110 // These flags should be mirrored by renderer versions in content/renderer/.
116 settings.initial_debug_state.show_debug_borders = 111 settings.initial_debug_state.show_debug_borders =
117 command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders); 112 command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders);
118 settings.initial_debug_state.show_fps_counter = 113 settings.initial_debug_state.show_fps_counter =
119 command_line->HasSwitch(cc::switches::kUIShowFPSCounter); 114 command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
120 settings.initial_debug_state.show_layer_animation_bounds_rects = 115 settings.initial_debug_state.show_layer_animation_bounds_rects =
121 command_line->HasSwitch(cc::switches::kUIShowLayerAnimationBounds); 116 command_line->HasSwitch(cc::switches::kUIShowLayerAnimationBounds);
(...skipping 10 matching lines...) Expand all
132 settings.initial_debug_state.show_occluding_rects = 127 settings.initial_debug_state.show_occluding_rects =
133 command_line->HasSwitch(cc::switches::kUIShowOccludingRects); 128 command_line->HasSwitch(cc::switches::kUIShowOccludingRects);
134 settings.initial_debug_state.show_non_occluding_rects = 129 settings.initial_debug_state.show_non_occluding_rects =
135 command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects); 130 command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects);
136 131
137 settings.initial_debug_state.SetRecordRenderingStats( 132 settings.initial_debug_state.SetRecordRenderingStats(
138 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking)); 133 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
139 134
140 settings.impl_side_painting = IsUIImplSidePaintingEnabled(); 135 settings.impl_side_painting = IsUIImplSidePaintingEnabled();
141 settings.use_zero_copy = IsUIZeroCopyEnabled(); 136 settings.use_zero_copy = IsUIZeroCopyEnabled();
142 settings.single_thread_proxy_scheduler = false;
143 137
144 base::TimeTicks before_create = base::TimeTicks::Now(); 138 base::TimeTicks before_create = base::TimeTicks::Now();
145 if (compositor_thread_loop_.get()) { 139 if (compositor_thread_loop_.get()) {
146 host_ = cc::LayerTreeHost::CreateThreaded( 140 host_ = cc::LayerTreeHost::CreateThreaded(
147 this, 141 this,
148 context_factory_->GetSharedBitmapManager(), 142 context_factory_->GetSharedBitmapManager(),
149 context_factory_->GetGpuMemoryBufferManager(), 143 context_factory_->GetGpuMemoryBufferManager(),
150 settings, 144 settings,
151 task_runner_, 145 task_runner_,
152 compositor_thread_loop_, 146 compositor_thread_loop_,
153 nullptr); 147 nullptr);
154 } else { 148 } else {
155 settings.main_thread_should_always_be_low_latency = true; 149 settings.main_thread_should_always_be_low_latency = true;
156
157 host_ = cc::LayerTreeHost::CreateSingleThreaded( 150 host_ = cc::LayerTreeHost::CreateSingleThreaded(
158 this, 151 this,
159 this, 152 this,
160 context_factory_->GetSharedBitmapManager(), 153 context_factory_->GetSharedBitmapManager(),
161 context_factory_->GetGpuMemoryBufferManager(), 154 context_factory_->GetGpuMemoryBufferManager(),
162 settings, 155 settings,
163 task_runner_, 156 task_runner_,
164 nullptr); 157 nullptr);
165 } 158 }
166 UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor", 159 UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor",
(...skipping 18 matching lines...) Expand all
185 178
186 context_factory_->RemoveCompositor(this); 179 context_factory_->RemoveCompositor(this);
187 } 180 }
188 181
189 void Compositor::SetOutputSurface( 182 void Compositor::SetOutputSurface(
190 scoped_ptr<cc::OutputSurface> output_surface) { 183 scoped_ptr<cc::OutputSurface> output_surface) {
191 host_->SetOutputSurface(output_surface.Pass()); 184 host_->SetOutputSurface(output_surface.Pass());
192 } 185 }
193 186
194 void Compositor::ScheduleDraw() { 187 void Compositor::ScheduleDraw() {
195 if (compositor_thread_loop_.get()) { 188 host_->SetNeedsCommit();
196 host_->SetNeedsCommit();
197 } else if (!defer_draw_scheduling_) {
198 defer_draw_scheduling_ = true;
199 task_runner_->PostTask(
200 FROM_HERE,
201 base::Bind(&Compositor::Draw, weak_ptr_factory_.GetWeakPtr()));
202 }
203 } 189 }
204 190
205 void Compositor::SetRootLayer(Layer* root_layer) { 191 void Compositor::SetRootLayer(Layer* root_layer) {
206 if (root_layer_ == root_layer) 192 if (root_layer_ == root_layer)
207 return; 193 return;
208 if (root_layer_) 194 if (root_layer_)
209 root_layer_->SetCompositor(NULL); 195 root_layer_->SetCompositor(NULL);
210 root_layer_ = root_layer; 196 root_layer_ = root_layer;
211 if (root_layer_ && !root_layer_->GetCompositor()) 197 if (root_layer_ && !root_layer_->GetCompositor())
212 root_layer_->SetCompositor(this); 198 root_layer_->SetCompositor(this);
213 root_web_layer_->RemoveAllChildren(); 199 root_web_layer_->RemoveAllChildren();
214 if (root_layer_) 200 if (root_layer_)
215 root_web_layer_->AddChild(root_layer_->cc_layer()); 201 root_web_layer_->AddChild(root_layer_->cc_layer());
216 } 202 }
217 203
218 void Compositor::SetHostHasTransparentBackground( 204 void Compositor::SetHostHasTransparentBackground(
219 bool host_has_transparent_background) { 205 bool host_has_transparent_background) {
220 host_->set_has_transparent_background(host_has_transparent_background); 206 host_->set_has_transparent_background(host_has_transparent_background);
221 } 207 }
222 208
223 void Compositor::Draw() {
224 DCHECK(!compositor_thread_loop_.get());
225
226 defer_draw_scheduling_ = false;
227 if (waiting_on_compositing_end_) {
228 draw_on_compositing_end_ = true;
229 return;
230 }
231 if (!root_layer_)
232 return;
233
234 TRACE_EVENT_ASYNC_BEGIN0("ui", "Compositor::Draw", last_started_frame_ + 1);
235
236 DCHECK_NE(swap_state_, SWAP_POSTED);
237 swap_state_ = SWAP_NONE;
238
239 waiting_on_compositing_end_ = true;
240 last_started_frame_++;
241 if (!IsLocked()) {
242 // TODO(nduca): Temporary while compositor calls
243 // compositeImmediately() directly.
244 cc::BeginFrameArgs args = cc::BeginFrameArgs::Create(
245 BEGINFRAME_FROM_HERE, gfx::FrameTime::Now(), base::TimeTicks(),
246 cc::BeginFrameArgs::DefaultInterval(), cc::BeginFrameArgs::SYNCHRONOUS);
247 BeginMainFrame(args);
248 host_->Composite(args.frame_time);
249 }
250 if (swap_state_ == SWAP_NONE)
251 NotifyEnd();
252 }
253
254 void Compositor::ScheduleFullRedraw() { 209 void Compositor::ScheduleFullRedraw() {
210 // TODO(enne): Some callers (mac) call this function expecting that it
211 // will also commit. This should probably just redraw the screen
212 // from damage and not commit. ScheduleDraw/ScheduleRedraw need
213 // better names.
255 host_->SetNeedsRedraw(); 214 host_->SetNeedsRedraw();
215 host_->SetNeedsCommit();
256 } 216 }
257 217
258 void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) { 218 void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) {
219 // TODO(enne): Make this not commit. See ScheduleFullRedraw.
259 host_->SetNeedsRedrawRect(damage_rect); 220 host_->SetNeedsRedrawRect(damage_rect);
221 host_->SetNeedsCommit();
260 } 222 }
261 223
262 void Compositor::DisableSwapUntilResize() { 224 void Compositor::DisableSwapUntilResize() {
263 host_->FinishAllRendering(); 225 host_->FinishAllRendering();
264 context_factory_->ResizeDisplay(this, gfx::Size()); 226 context_factory_->ResizeDisplay(this, gfx::Size());
265 } 227 }
266 228
267 void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) { 229 void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) {
268 scoped_ptr<cc::SwapPromise> swap_promise( 230 scoped_ptr<cc::SwapPromise> swap_promise(
269 new cc::LatencyInfoSwapPromise(latency_info)); 231 new cc::LatencyInfoSwapPromise(latency_info));
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 } 326 }
365 327
366 void Compositor::DidCommit() { 328 void Compositor::DidCommit() {
367 DCHECK(!IsLocked()); 329 DCHECK(!IsLocked());
368 FOR_EACH_OBSERVER(CompositorObserver, 330 FOR_EACH_OBSERVER(CompositorObserver,
369 observer_list_, 331 observer_list_,
370 OnCompositingDidCommit(this)); 332 OnCompositingDidCommit(this));
371 } 333 }
372 334
373 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, observer_list_,
345 OnCompositingStarted(this, start_time));
346 }
347 FOR_EACH_OBSERVER(CompositorObserver, observer_list_,
348 OnCompositingEnded(this));
349 }
350
351 void Compositor::DidPostSwapBuffers() {
374 base::TimeTicks start_time = gfx::FrameTime::Now(); 352 base::TimeTicks start_time = gfx::FrameTime::Now();
375 FOR_EACH_OBSERVER(CompositorObserver, 353 FOR_EACH_OBSERVER(CompositorObserver, observer_list_,
376 observer_list_,
377 OnCompositingStarted(this, start_time)); 354 OnCompositingStarted(this, start_time));
378 } 355 }
379 356
380 void Compositor::DidCompleteSwapBuffers() {
381 if (compositor_thread_loop_.get()) {
382 NotifyEnd();
383 } else {
384 DCHECK_EQ(swap_state_, SWAP_POSTED);
385 NotifyEnd();
386 swap_state_ = SWAP_COMPLETED;
387 }
388 }
389
390 void Compositor::ScheduleComposite() {
391 if (!disable_schedule_composite_)
392 ScheduleDraw();
393 }
394
395 void Compositor::ScheduleAnimation() {
396 ScheduleComposite();
397 }
398
399 void Compositor::DidPostSwapBuffers() {
400 DCHECK(!compositor_thread_loop_.get());
401 DCHECK_EQ(swap_state_, SWAP_NONE);
402 swap_state_ = SWAP_POSTED;
403 }
404
405 void Compositor::DidAbortSwapBuffers() { 357 void Compositor::DidAbortSwapBuffers() {
406 if (!compositor_thread_loop_.get()) {
407 if (swap_state_ == SWAP_POSTED) {
408 NotifyEnd();
409 swap_state_ = SWAP_COMPLETED;
410 }
411 }
412
413 FOR_EACH_OBSERVER(CompositorObserver, 358 FOR_EACH_OBSERVER(CompositorObserver,
414 observer_list_, 359 observer_list_,
415 OnCompositingAborted(this)); 360 OnCompositingAborted(this));
416 } 361 }
417 362
418 const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const { 363 const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const {
419 return host_->debug_state(); 364 return host_->debug_state();
420 } 365 }
421 366
422 void Compositor::SetLayerTreeDebugState( 367 void Compositor::SetLayerTreeDebugState(
423 const cc::LayerTreeDebugState& debug_state) { 368 const cc::LayerTreeDebugState& debug_state) {
424 host_->SetDebugState(debug_state); 369 host_->SetDebugState(debug_state);
425 } 370 }
426 371
427 const cc::RendererSettings& Compositor::GetRendererSettings() const { 372 const cc::RendererSettings& Compositor::GetRendererSettings() const {
428 return host_->settings().renderer_settings; 373 return host_->settings().renderer_settings;
429 } 374 }
430 375
431 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { 376 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
432 if (!compositor_lock_) { 377 if (!compositor_lock_) {
433 compositor_lock_ = new CompositorLock(this); 378 compositor_lock_ = new CompositorLock(this);
434 if (compositor_thread_loop_.get()) 379 host_->SetDeferCommits(true);
435 host_->SetDeferCommits(true);
436 FOR_EACH_OBSERVER(CompositorObserver, 380 FOR_EACH_OBSERVER(CompositorObserver,
437 observer_list_, 381 observer_list_,
438 OnCompositingLockStateChanged(this)); 382 OnCompositingLockStateChanged(this));
439 } 383 }
440 return compositor_lock_; 384 return compositor_lock_;
441 } 385 }
442 386
443 void Compositor::UnlockCompositor() { 387 void Compositor::UnlockCompositor() {
444 DCHECK(compositor_lock_); 388 DCHECK(compositor_lock_);
445 compositor_lock_ = NULL; 389 compositor_lock_ = NULL;
446 if (compositor_thread_loop_.get()) 390 host_->SetDeferCommits(false);
447 host_->SetDeferCommits(false);
448 FOR_EACH_OBSERVER(CompositorObserver, 391 FOR_EACH_OBSERVER(CompositorObserver,
449 observer_list_, 392 observer_list_,
450 OnCompositingLockStateChanged(this)); 393 OnCompositingLockStateChanged(this));
451 } 394 }
452 395
453 void Compositor::CancelCompositorLock() { 396 void Compositor::CancelCompositorLock() {
454 if (compositor_lock_) 397 if (compositor_lock_)
455 compositor_lock_->CancelLock(); 398 compositor_lock_->CancelLock();
456 } 399 }
457 400
458 void Compositor::NotifyEnd() {
459 last_ended_frame_++;
460 TRACE_EVENT_ASYNC_END0("ui", "Compositor::Draw", last_ended_frame_);
461 waiting_on_compositing_end_ = false;
462 if (draw_on_compositing_end_) {
463 draw_on_compositing_end_ = false;
464
465 // Call ScheduleDraw() instead of Draw() in order to allow other
466 // CompositorObservers to be notified before starting another
467 // draw cycle.
468 ScheduleDraw();
469 }
470 FOR_EACH_OBSERVER(
471 CompositorObserver, observer_list_, OnCompositingEnded(this));
472 }
473
474 } // namespace ui 401 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698