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

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

Issue 277713002: ui/compositor: move the browser compositor thread to the ContextFactory (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase, fix includes Created 6 years, 7 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/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"
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/memory/singleton.h"
14 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
15 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
16 #include "base/run_loop.h"
17 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
18 #include "base/sys_info.h" 16 #include "base/sys_info.h"
19 #include "base/threading/thread.h"
20 #include "base/threading/thread_restrictions.h"
21 #include "cc/base/latency_info_swap_promise.h" 17 #include "cc/base/latency_info_swap_promise.h"
22 #include "cc/base/switches.h" 18 #include "cc/base/switches.h"
23 #include "cc/input/input_handler.h" 19 #include "cc/input/input_handler.h"
24 #include "cc/layers/layer.h" 20 #include "cc/layers/layer.h"
25 #include "cc/output/context_provider.h" 21 #include "cc/output/context_provider.h"
26 #include "cc/trees/layer_tree_host.h" 22 #include "cc/trees/layer_tree_host.h"
27 #include "third_party/skia/include/core/SkBitmap.h" 23 #include "third_party/skia/include/core/SkBitmap.h"
28 #include "ui/compositor/compositor_observer.h" 24 #include "ui/compositor/compositor_observer.h"
29 #include "ui/compositor/compositor_switches.h" 25 #include "ui/compositor/compositor_switches.h"
30 #include "ui/compositor/compositor_vsync_manager.h" 26 #include "ui/compositor/compositor_vsync_manager.h"
31 #include "ui/compositor/dip_util.h" 27 #include "ui/compositor/dip_util.h"
32 #include "ui/compositor/layer.h" 28 #include "ui/compositor/layer.h"
33 #include "ui/gfx/frame_time.h" 29 #include "ui/gfx/frame_time.h"
34 #include "ui/gl/gl_context.h" 30 #include "ui/gl/gl_context.h"
35 #include "ui/gl/gl_switches.h" 31 #include "ui/gl/gl_switches.h"
36 32
37 namespace { 33 namespace {
38 34
39 const double kDefaultRefreshRate = 60.0; 35 const double kDefaultRefreshRate = 60.0;
40 const double kTestRefreshRate = 200.0; 36 const double kTestRefreshRate = 200.0;
41 37
42 bool g_compositor_initialized = false;
43 base::Thread* g_compositor_thread = NULL;
44
45 ui::ContextFactory* g_context_factory = NULL; 38 ui::ContextFactory* g_context_factory = NULL;
46 39
47 const int kCompositorLockTimeoutMs = 67; 40 const int kCompositorLockTimeoutMs = 67;
48 41
49 } // namespace 42 } // namespace
50 43
51 namespace ui { 44 namespace ui {
52 45
53 // static 46 // static
54 ContextFactory* ContextFactory::GetInstance() { 47 ContextFactory* ContextFactory::GetInstance() {
(...skipping 30 matching lines...) Expand all
85 78
86 namespace { 79 namespace {
87 80
88 } // namespace 81 } // namespace
89 82
90 namespace ui { 83 namespace ui {
91 84
92 Compositor::Compositor(gfx::AcceleratedWidget widget) 85 Compositor::Compositor(gfx::AcceleratedWidget widget)
93 : root_layer_(NULL), 86 : root_layer_(NULL),
94 widget_(widget), 87 widget_(widget),
88 compositor_thread_loop_(g_context_factory->GetCompositorMessageLoop()),
95 vsync_manager_(new CompositorVSyncManager()), 89 vsync_manager_(new CompositorVSyncManager()),
96 device_scale_factor_(0.0f), 90 device_scale_factor_(0.0f),
97 last_started_frame_(0), 91 last_started_frame_(0),
98 last_ended_frame_(0), 92 last_ended_frame_(0),
99 next_draw_is_resize_(false), 93 next_draw_is_resize_(false),
100 disable_schedule_composite_(false), 94 disable_schedule_composite_(false),
101 compositor_lock_(NULL), 95 compositor_lock_(NULL),
102 defer_draw_scheduling_(false), 96 defer_draw_scheduling_(false),
103 waiting_on_compositing_end_(false), 97 waiting_on_compositing_end_(false),
104 draw_on_compositing_end_(false), 98 draw_on_compositing_end_(false),
105 swap_state_(SWAP_NONE), 99 swap_state_(SWAP_NONE),
106 schedule_draw_factory_(this) { 100 schedule_draw_factory_(this) {
107 DCHECK(g_compositor_initialized)
108 << "Compositor::Initialize must be called before creating a Compositor.";
109
110 root_web_layer_ = cc::Layer::Create(); 101 root_web_layer_ = cc::Layer::Create();
111 root_web_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f)); 102 root_web_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
112 103
113 CommandLine* command_line = CommandLine::ForCurrentProcess(); 104 CommandLine* command_line = CommandLine::ForCurrentProcess();
114 105
115 cc::LayerTreeSettings settings; 106 cc::LayerTreeSettings settings;
116 settings.refresh_rate = 107 settings.refresh_rate =
117 ContextFactory::GetInstance()->DoesCreateTestContexts() 108 ContextFactory::GetInstance()->DoesCreateTestContexts()
118 ? kTestRefreshRate 109 ? kTestRefreshRate
119 : kDefaultRefreshRate; 110 : kDefaultRefreshRate;
(...skipping 29 matching lines...) Expand all
149 settings.initial_debug_state.show_non_occluding_rects = 140 settings.initial_debug_state.show_non_occluding_rects =
150 command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects); 141 command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects);
151 142
152 settings.initial_debug_state.SetRecordRenderingStats( 143 settings.initial_debug_state.SetRecordRenderingStats(
153 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking)); 144 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
154 145
155 settings.impl_side_painting = IsUIImplSidePaintingEnabled(); 146 settings.impl_side_painting = IsUIImplSidePaintingEnabled();
156 settings.use_zero_copy = IsUIZeroCopyEnabled(); 147 settings.use_zero_copy = IsUIZeroCopyEnabled();
157 148
158 base::TimeTicks before_create = base::TimeTicks::Now(); 149 base::TimeTicks before_create = base::TimeTicks::Now();
159 if (!!g_compositor_thread) { 150 if (compositor_thread_loop_) {
160 host_ = cc::LayerTreeHost::CreateThreaded( 151 host_ = cc::LayerTreeHost::CreateThreaded(
161 this, 152 this,
162 g_context_factory->GetSharedBitmapManager(), 153 g_context_factory->GetSharedBitmapManager(),
163 settings, 154 settings,
164 g_compositor_thread->message_loop_proxy()); 155 compositor_thread_loop_);
165 } else { 156 } else {
166 host_ = cc::LayerTreeHost::CreateSingleThreaded( 157 host_ = cc::LayerTreeHost::CreateSingleThreaded(
167 this, this, g_context_factory->GetSharedBitmapManager(), settings); 158 this, this, g_context_factory->GetSharedBitmapManager(), settings);
168 } 159 }
169 UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor", 160 UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor",
170 base::TimeTicks::Now() - before_create); 161 base::TimeTicks::Now() - before_create);
171 host_->SetRootLayer(root_web_layer_); 162 host_->SetRootLayer(root_web_layer_);
172 host_->SetLayerTreeHostClientReady(); 163 host_->SetLayerTreeHostClientReady();
173 } 164 }
174 165
175 Compositor::~Compositor() { 166 Compositor::~Compositor() {
176 TRACE_EVENT0("shutdown", "Compositor::destructor"); 167 TRACE_EVENT0("shutdown", "Compositor::destructor");
177 168
178 DCHECK(g_compositor_initialized);
179
180 CancelCompositorLock(); 169 CancelCompositorLock();
181 DCHECK(!compositor_lock_); 170 DCHECK(!compositor_lock_);
182 171
183 if (root_layer_) 172 if (root_layer_)
184 root_layer_->SetCompositor(NULL); 173 root_layer_->SetCompositor(NULL);
185 174
186 // Stop all outstanding draws before telling the ContextFactory to tear 175 // Stop all outstanding draws before telling the ContextFactory to tear
187 // down any contexts that the |host_| may rely upon. 176 // down any contexts that the |host_| may rely upon.
188 host_.reset(); 177 host_.reset();
189 178
190 ContextFactory::GetInstance()->RemoveCompositor(this); 179 ContextFactory::GetInstance()->RemoveCompositor(this);
191 } 180 }
192 181
193 // static
194 void Compositor::Initialize() {
195 #if defined(OS_CHROMEOS)
196 bool use_thread = !CommandLine::ForCurrentProcess()->HasSwitch(
197 switches::kUIDisableThreadedCompositing);
198 #else
199 bool use_thread = false;
200 #endif
201 if (use_thread) {
202 g_compositor_thread = new base::Thread("Browser Compositor");
203 g_compositor_thread->Start();
204 }
205
206 DCHECK(!g_compositor_initialized) << "Compositor initialized twice.";
207 g_compositor_initialized = true;
208 }
209
210 // static
211 bool Compositor::WasInitializedWithThread() {
212 DCHECK(g_compositor_initialized);
213 return !!g_compositor_thread;
214 }
215
216 // static
217 scoped_refptr<base::MessageLoopProxy> Compositor::GetCompositorMessageLoop() {
218 scoped_refptr<base::MessageLoopProxy> proxy;
219 if (g_compositor_thread)
220 proxy = g_compositor_thread->message_loop_proxy();
221 return proxy;
222 }
223
224 // static
225 void Compositor::Terminate() {
226 if (g_compositor_thread) {
227 g_compositor_thread->Stop();
228 delete g_compositor_thread;
229 g_compositor_thread = NULL;
230 }
231
232 DCHECK(g_compositor_initialized) << "Compositor::Initialize() didn't happen.";
233 g_compositor_initialized = false;
234 }
235
236 void Compositor::ScheduleDraw() { 182 void Compositor::ScheduleDraw() {
237 if (g_compositor_thread) { 183 if (compositor_thread_loop_) {
238 host_->Composite(gfx::FrameTime::Now()); 184 host_->Composite(gfx::FrameTime::Now());
239 } else if (!defer_draw_scheduling_) { 185 } else if (!defer_draw_scheduling_) {
240 defer_draw_scheduling_ = true; 186 defer_draw_scheduling_ = true;
241 base::MessageLoop::current()->PostTask( 187 base::MessageLoop::current()->PostTask(
242 FROM_HERE, 188 FROM_HERE,
243 base::Bind(&Compositor::Draw, schedule_draw_factory_.GetWeakPtr())); 189 base::Bind(&Compositor::Draw, schedule_draw_factory_.GetWeakPtr()));
244 } 190 }
245 } 191 }
246 192
247 void Compositor::SetRootLayer(Layer* root_layer) { 193 void Compositor::SetRootLayer(Layer* root_layer) {
248 if (root_layer_ == root_layer) 194 if (root_layer_ == root_layer)
249 return; 195 return;
250 if (root_layer_) 196 if (root_layer_)
251 root_layer_->SetCompositor(NULL); 197 root_layer_->SetCompositor(NULL);
252 root_layer_ = root_layer; 198 root_layer_ = root_layer;
253 if (root_layer_ && !root_layer_->GetCompositor()) 199 if (root_layer_ && !root_layer_->GetCompositor())
254 root_layer_->SetCompositor(this); 200 root_layer_->SetCompositor(this);
255 root_web_layer_->RemoveAllChildren(); 201 root_web_layer_->RemoveAllChildren();
256 if (root_layer_) 202 if (root_layer_)
257 root_web_layer_->AddChild(root_layer_->cc_layer()); 203 root_web_layer_->AddChild(root_layer_->cc_layer());
258 } 204 }
259 205
260 void Compositor::SetHostHasTransparentBackground( 206 void Compositor::SetHostHasTransparentBackground(
261 bool host_has_transparent_background) { 207 bool host_has_transparent_background) {
262 host_->set_has_transparent_background(host_has_transparent_background); 208 host_->set_has_transparent_background(host_has_transparent_background);
263 } 209 }
264 210
265 void Compositor::Draw() { 211 void Compositor::Draw() {
266 DCHECK(!g_compositor_thread); 212 DCHECK(!compositor_thread_loop_);
267 213
268 defer_draw_scheduling_ = false; 214 defer_draw_scheduling_ = false;
269 if (waiting_on_compositing_end_) { 215 if (waiting_on_compositing_end_) {
270 draw_on_compositing_end_ = true; 216 draw_on_compositing_end_ = true;
271 return; 217 return;
272 } 218 }
273 waiting_on_compositing_end_ = true; 219 waiting_on_compositing_end_ = true;
274 220
275 TRACE_EVENT_ASYNC_BEGIN0("ui", "Compositor::Draw", last_started_frame_ + 1); 221 TRACE_EVENT_ASYNC_BEGIN0("ui", "Compositor::Draw", last_started_frame_ + 1);
276 222
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 } 321 }
376 322
377 void Compositor::DidCommitAndDrawFrame() { 323 void Compositor::DidCommitAndDrawFrame() {
378 base::TimeTicks start_time = gfx::FrameTime::Now(); 324 base::TimeTicks start_time = gfx::FrameTime::Now();
379 FOR_EACH_OBSERVER(CompositorObserver, 325 FOR_EACH_OBSERVER(CompositorObserver,
380 observer_list_, 326 observer_list_,
381 OnCompositingStarted(this, start_time)); 327 OnCompositingStarted(this, start_time));
382 } 328 }
383 329
384 void Compositor::DidCompleteSwapBuffers() { 330 void Compositor::DidCompleteSwapBuffers() {
385 if (g_compositor_thread) { 331 if (compositor_thread_loop_) {
386 NotifyEnd(); 332 NotifyEnd();
387 } else { 333 } else {
388 DCHECK_EQ(swap_state_, SWAP_POSTED); 334 DCHECK_EQ(swap_state_, SWAP_POSTED);
389 NotifyEnd(); 335 NotifyEnd();
390 swap_state_ = SWAP_COMPLETED; 336 swap_state_ = SWAP_COMPLETED;
391 } 337 }
392 } 338 }
393 339
394 void Compositor::ScheduleComposite() { 340 void Compositor::ScheduleComposite() {
395 if (!disable_schedule_composite_) 341 if (!disable_schedule_composite_)
396 ScheduleDraw(); 342 ScheduleDraw();
397 } 343 }
398 344
399 void Compositor::ScheduleAnimation() { 345 void Compositor::ScheduleAnimation() {
400 ScheduleComposite(); 346 ScheduleComposite();
401 } 347 }
402 348
403 void Compositor::DidPostSwapBuffers() { 349 void Compositor::DidPostSwapBuffers() {
404 DCHECK(!g_compositor_thread); 350 DCHECK(!compositor_thread_loop_);
405 DCHECK_EQ(swap_state_, SWAP_NONE); 351 DCHECK_EQ(swap_state_, SWAP_NONE);
406 swap_state_ = SWAP_POSTED; 352 swap_state_ = SWAP_POSTED;
407 } 353 }
408 354
409 void Compositor::DidAbortSwapBuffers() { 355 void Compositor::DidAbortSwapBuffers() {
410 if (!g_compositor_thread) { 356 if (!compositor_thread_loop_) {
411 if (swap_state_ == SWAP_POSTED) { 357 if (swap_state_ == SWAP_POSTED) {
412 NotifyEnd(); 358 NotifyEnd();
413 swap_state_ = SWAP_COMPLETED; 359 swap_state_ = SWAP_COMPLETED;
414 } 360 }
415 } 361 }
416 362
417 FOR_EACH_OBSERVER(CompositorObserver, 363 FOR_EACH_OBSERVER(CompositorObserver,
418 observer_list_, 364 observer_list_,
419 OnCompositingAborted(this)); 365 OnCompositingAborted(this));
420 } 366 }
421 367
422 const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const { 368 const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const {
423 return host_->debug_state(); 369 return host_->debug_state();
424 } 370 }
425 371
426 void Compositor::SetLayerTreeDebugState( 372 void Compositor::SetLayerTreeDebugState(
427 const cc::LayerTreeDebugState& debug_state) { 373 const cc::LayerTreeDebugState& debug_state) {
428 host_->SetDebugState(debug_state); 374 host_->SetDebugState(debug_state);
429 } 375 }
430 376
431 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { 377 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
432 if (!compositor_lock_) { 378 if (!compositor_lock_) {
433 compositor_lock_ = new CompositorLock(this); 379 compositor_lock_ = new CompositorLock(this);
434 if (g_compositor_thread) 380 if (compositor_thread_loop_)
435 host_->SetDeferCommits(true); 381 host_->SetDeferCommits(true);
436 FOR_EACH_OBSERVER(CompositorObserver, 382 FOR_EACH_OBSERVER(CompositorObserver,
437 observer_list_, 383 observer_list_,
438 OnCompositingLockStateChanged(this)); 384 OnCompositingLockStateChanged(this));
439 } 385 }
440 return compositor_lock_; 386 return compositor_lock_;
441 } 387 }
442 388
443 void Compositor::UnlockCompositor() { 389 void Compositor::UnlockCompositor() {
444 DCHECK(compositor_lock_); 390 DCHECK(compositor_lock_);
445 compositor_lock_ = NULL; 391 compositor_lock_ = NULL;
446 if (g_compositor_thread) 392 if (compositor_thread_loop_)
447 host_->SetDeferCommits(false); 393 host_->SetDeferCommits(false);
448 FOR_EACH_OBSERVER(CompositorObserver, 394 FOR_EACH_OBSERVER(CompositorObserver,
449 observer_list_, 395 observer_list_,
450 OnCompositingLockStateChanged(this)); 396 OnCompositingLockStateChanged(this));
451 } 397 }
452 398
453 void Compositor::CancelCompositorLock() { 399 void Compositor::CancelCompositorLock() {
454 if (compositor_lock_) 400 if (compositor_lock_)
455 compositor_lock_->CancelLock(); 401 compositor_lock_->CancelLock();
456 } 402 }
457 403
458 void Compositor::NotifyEnd() { 404 void Compositor::NotifyEnd() {
459 last_ended_frame_++; 405 last_ended_frame_++;
460 TRACE_EVENT_ASYNC_END0("ui", "Compositor::Draw", last_ended_frame_); 406 TRACE_EVENT_ASYNC_END0("ui", "Compositor::Draw", last_ended_frame_);
461 waiting_on_compositing_end_ = false; 407 waiting_on_compositing_end_ = false;
462 if (draw_on_compositing_end_) { 408 if (draw_on_compositing_end_) {
463 draw_on_compositing_end_ = false; 409 draw_on_compositing_end_ = false;
464 410
465 // Call ScheduleDraw() instead of Draw() in order to allow other 411 // Call ScheduleDraw() instead of Draw() in order to allow other
466 // CompositorObservers to be notified before starting another 412 // CompositorObservers to be notified before starting another
467 // draw cycle. 413 // draw cycle.
468 ScheduleDraw(); 414 ScheduleDraw();
469 } 415 }
470 FOR_EACH_OBSERVER(CompositorObserver, 416 FOR_EACH_OBSERVER(CompositorObserver,
471 observer_list_, 417 observer_list_,
472 OnCompositingEnded(this)); 418 OnCompositingEnded(this));
473 } 419 }
474 420
475 } // namespace ui 421 } // 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