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

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

Issue 21052007: aura: Clean up compositor initialization/destruction. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleanupcompositor: Created 7 years, 4 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"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 namespace { 43 namespace {
44 44
45 const double kDefaultRefreshRate = 60.0; 45 const double kDefaultRefreshRate = 60.0;
46 const double kTestRefreshRate = 200.0; 46 const double kTestRefreshRate = 200.0;
47 47
48 enum SwapType { 48 enum SwapType {
49 DRAW_SWAP, 49 DRAW_SWAP,
50 READPIXELS_SWAP, 50 READPIXELS_SWAP,
51 }; 51 };
52 52
53 bool g_compositor_initialized = false;
53 base::Thread* g_compositor_thread = NULL; 54 base::Thread* g_compositor_thread = NULL;
54 55
55 bool g_test_compositor_enabled = false;
56
57 ui::ContextFactory* g_implicit_factory = NULL; 56 ui::ContextFactory* g_implicit_factory = NULL;
58 ui::ContextFactory* g_context_factory = NULL; 57 ui::ContextFactory* g_context_factory = NULL;
59 58
60 const int kCompositorLockTimeoutMs = 67; 59 const int kCompositorLockTimeoutMs = 67;
61 60
62 class PendingSwap { 61 class PendingSwap {
63 public: 62 public:
64 PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps); 63 PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps);
65 ~PendingSwap(); 64 ~PendingSwap();
66 65
67 SwapType type() const { return type_; } 66 SwapType type() const { return type_; }
68 bool posted() const { return posted_; } 67 bool posted() const { return posted_; }
69 68
70 private: 69 private:
71 friend class ui::PostedSwapQueue; 70 friend class ui::PostedSwapQueue;
72 71
73 SwapType type_; 72 SwapType type_;
74 bool posted_; 73 bool posted_;
75 ui::PostedSwapQueue* posted_swaps_; 74 ui::PostedSwapQueue* posted_swaps_;
76 75
77 DISALLOW_COPY_AND_ASSIGN(PendingSwap); 76 DISALLOW_COPY_AND_ASSIGN(PendingSwap);
78 }; 77 };
79 78
80 void SetupImplicitFactory() {
81 // We leak the implicit factory so that we don't race with the tear down of
82 // the gl_bindings.
83 DCHECK(!g_context_factory);
84 DCHECK(!g_implicit_factory);
85 if (g_test_compositor_enabled) {
86 g_implicit_factory = new ui::TestContextFactory;
87 } else {
88 DVLOG(1) << "Using DefaultContextFactory";
89 scoped_ptr<ui::DefaultContextFactory> instance(
90 new ui::DefaultContextFactory());
91 if (instance->Initialize())
92 g_implicit_factory = instance.release();
93 }
94 g_context_factory = g_implicit_factory;
95 }
96
97 void ResetImplicitFactory() {
98 if (!g_implicit_factory || g_context_factory != g_implicit_factory)
99 return;
100 delete g_implicit_factory;
101 g_implicit_factory = NULL;
102 g_context_factory = NULL;
103 }
104
105 } // namespace 79 } // namespace
106 80
107 namespace ui { 81 namespace ui {
108 82
109 // static 83 // static
110 ContextFactory* ContextFactory::GetInstance() { 84 ContextFactory* ContextFactory::GetInstance() {
111 if (!g_context_factory) 85 DCHECK(g_context_factory);
112 SetupImplicitFactory();
113 return g_context_factory; 86 return g_context_factory;
114 } 87 }
115 88
116 // static 89 // static
117 void ContextFactory::SetInstance(ContextFactory* instance) { 90 void ContextFactory::SetInstance(ContextFactory* instance) {
118 g_context_factory = instance; 91 g_context_factory = instance;
119 } 92 }
120 93
121 DefaultContextFactory::DefaultContextFactory() { 94 DefaultContextFactory::DefaultContextFactory() {
122 } 95 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 !offscreen_contexts_compositor_thread_->DestroyedOnMainThread()) { 146 !offscreen_contexts_compositor_thread_->DestroyedOnMainThread()) {
174 offscreen_contexts_compositor_thread_ = 147 offscreen_contexts_compositor_thread_ =
175 ContextProviderFromContextFactory::CreateForOffscreen(this); 148 ContextProviderFromContextFactory::CreateForOffscreen(this);
176 } 149 }
177 return offscreen_contexts_compositor_thread_; 150 return offscreen_contexts_compositor_thread_;
178 } 151 }
179 152
180 void DefaultContextFactory::RemoveCompositor(Compositor* compositor) { 153 void DefaultContextFactory::RemoveCompositor(Compositor* compositor) {
181 } 154 }
182 155
156 bool DefaultContextFactory::UsesTestContexts() { return false; }
157
183 scoped_ptr<WebKit::WebGraphicsContext3D> 158 scoped_ptr<WebKit::WebGraphicsContext3D>
184 DefaultContextFactory::CreateContextCommon(Compositor* compositor, 159 DefaultContextFactory::CreateContextCommon(Compositor* compositor,
185 bool offscreen) { 160 bool offscreen) {
186 DCHECK(offscreen || compositor); 161 DCHECK(offscreen || compositor);
187 WebKit::WebGraphicsContext3D::Attributes attrs; 162 WebKit::WebGraphicsContext3D::Attributes attrs;
188 attrs.depth = false; 163 attrs.depth = false;
189 attrs.stencil = false; 164 attrs.stencil = false;
190 attrs.antialias = false; 165 attrs.antialias = false;
191 attrs.shareResources = true; 166 attrs.shareResources = true;
192 using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl; 167 using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 offscreen_contexts_compositor_thread_->DestroyedOnMainThread()) { 216 offscreen_contexts_compositor_thread_->DestroyedOnMainThread()) {
242 offscreen_contexts_compositor_thread_ = 217 offscreen_contexts_compositor_thread_ =
243 ContextProviderFromContextFactory::CreateForOffscreen(this); 218 ContextProviderFromContextFactory::CreateForOffscreen(this);
244 } 219 }
245 return offscreen_contexts_compositor_thread_; 220 return offscreen_contexts_compositor_thread_;
246 } 221 }
247 222
248 void TestContextFactory::RemoveCompositor(Compositor* compositor) { 223 void TestContextFactory::RemoveCompositor(Compositor* compositor) {
249 } 224 }
250 225
226 bool TestContextFactory::UsesTestContexts() { return true; }
227
251 Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor) 228 Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor)
252 : size_(size), 229 : size_(size),
253 flipped_(flipped), 230 flipped_(flipped),
254 device_scale_factor_(device_scale_factor) { 231 device_scale_factor_(device_scale_factor) {
255 } 232 }
256 233
257 Texture::~Texture() { 234 Texture::~Texture() {
258 } 235 }
259 236
260 std::string Texture::Produce() { 237 std::string Texture::Produce() {
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 : delegate_(delegate), 380 : delegate_(delegate),
404 root_layer_(NULL), 381 root_layer_(NULL),
405 widget_(widget), 382 widget_(widget),
406 posted_swaps_(new PostedSwapQueue()), 383 posted_swaps_(new PostedSwapQueue()),
407 device_scale_factor_(0.0f), 384 device_scale_factor_(0.0f),
408 last_started_frame_(0), 385 last_started_frame_(0),
409 last_ended_frame_(0), 386 last_ended_frame_(0),
410 next_draw_is_resize_(false), 387 next_draw_is_resize_(false),
411 disable_schedule_composite_(false), 388 disable_schedule_composite_(false),
412 compositor_lock_(NULL) { 389 compositor_lock_(NULL) {
390 DCHECK(g_compositor_initialized)
391 << "Compositor::Initialize must be called before creating a Compositor";
392
413 root_web_layer_ = cc::Layer::Create(); 393 root_web_layer_ = cc::Layer::Create();
414 root_web_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f)); 394 root_web_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
415 395
416 CommandLine* command_line = CommandLine::ForCurrentProcess(); 396 CommandLine* command_line = CommandLine::ForCurrentProcess();
417 397
418 cc::LayerTreeSettings settings; 398 cc::LayerTreeSettings settings;
419 settings.refresh_rate = 399 settings.refresh_rate = ContextFactory::GetInstance()->UsesTestContexts()
420 g_test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate; 400 ? kTestRefreshRate
401 : kDefaultRefreshRate;
421 settings.partial_swap_enabled = 402 settings.partial_swap_enabled =
422 !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap); 403 !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap);
423 settings.per_tile_painting_enabled = 404 settings.per_tile_painting_enabled =
424 command_line->HasSwitch(cc::switches::kUIEnablePerTilePainting); 405 command_line->HasSwitch(cc::switches::kUIEnablePerTilePainting);
425 406
426 // These flags should be mirrored by renderer versions in content/renderer/. 407 // These flags should be mirrored by renderer versions in content/renderer/.
427 settings.initial_debug_state.show_debug_borders = 408 settings.initial_debug_state.show_debug_borders =
428 command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders); 409 command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders);
429 settings.initial_debug_state.show_fps_counter = 410 settings.initial_debug_state.show_fps_counter =
430 command_line->HasSwitch(cc::switches::kUIShowFPSCounter); 411 command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
(...skipping 14 matching lines...) Expand all
445 426
446 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner = 427 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner =
447 g_compositor_thread ? g_compositor_thread->message_loop_proxy() : NULL; 428 g_compositor_thread ? g_compositor_thread->message_loop_proxy() : NULL;
448 429
449 host_ = cc::LayerTreeHost::Create(this, settings, compositor_task_runner); 430 host_ = cc::LayerTreeHost::Create(this, settings, compositor_task_runner);
450 host_->SetRootLayer(root_web_layer_); 431 host_->SetRootLayer(root_web_layer_);
451 host_->SetLayerTreeHostClientReady(); 432 host_->SetLayerTreeHostClientReady();
452 } 433 }
453 434
454 Compositor::~Compositor() { 435 Compositor::~Compositor() {
436 DCHECK(g_compositor_initialized);
437
455 CancelCompositorLock(); 438 CancelCompositorLock();
456 DCHECK(!compositor_lock_); 439 DCHECK(!compositor_lock_);
457 440
458 // Don't call |CompositorDelegate::ScheduleDraw| from this point. 441 // Don't call |CompositorDelegate::ScheduleDraw| from this point.
459 delegate_ = NULL; 442 delegate_ = NULL;
460 if (root_layer_) 443 if (root_layer_)
461 root_layer_->SetCompositor(NULL); 444 root_layer_->SetCompositor(NULL);
462 445
463 // Stop all outstanding draws before telling the ContextFactory to tear 446 // Stop all outstanding draws before telling the ContextFactory to tear
464 // down any contexts that the |host_| may rely upon. 447 // down any contexts that the |host_| may rely upon.
465 host_.reset(); 448 host_.reset();
466 449
467 ContextFactory::GetInstance()->RemoveCompositor(this); 450 ContextFactory::GetInstance()->RemoveCompositor(this);
468 } 451 }
469 452
470 // static 453 // static
454 void Compositor::InitializeContextFactoryForTests(bool allow_test_contexts) {
455 DCHECK(!g_context_factory) << "ContextFactory already initialized";
456 DCHECK(!g_implicit_factory) << "ContextFactory for tests already initialized";
457
458 bool use_test_contexts = true;
459
460 // Always use test contexts unless the disable command line flag is used.
461 CommandLine* command_line = CommandLine::ForCurrentProcess();
462 if (command_line->HasSwitch(switches::kDisableTestCompositor))
danakj 2013/07/31 01:32:51 I don't know if we really need to honor command li
piman 2013/07/31 07:01:48 The "test compositor" is an optimization for the b
463 use_test_contexts = false;
464
465 #if defined(OS_CHROMEOS)
466 // If the test is running on the chromeos envrionment (such as
467 // device or vm bots), always use real contexts.
468 if (base::chromeos::IsRunningOnChromeOS())
469 use_test_contexts = false;
470 #endif
471
472 if (!allow_test_contexts)
473 use_test_contexts = false;
474
475 // We leak the implicit factory so that we don't race with the tear down of
476 // the gl_bindings.
piman 2013/07/31 07:01:48 nit: I guess we don't leak it any more...
477 if (use_test_contexts) {
478 g_implicit_factory = new ui::TestContextFactory;
479 } else {
480 DVLOG(1) << "Using DefaultContextFactory";
481 scoped_ptr<ui::DefaultContextFactory> instance(
482 new ui::DefaultContextFactory());
483 if (instance->Initialize())
484 g_implicit_factory = instance.release();
485 }
486 g_context_factory = g_implicit_factory;
487 }
488
489 // static
471 void Compositor::Initialize() { 490 void Compositor::Initialize() {
472 #if defined(OS_CHROMEOS) 491 #if defined(OS_CHROMEOS)
473 bool use_thread = !CommandLine::ForCurrentProcess()->HasSwitch( 492 bool use_thread = !CommandLine::ForCurrentProcess()->HasSwitch(
474 switches::kUIDisableThreadedCompositing); 493 switches::kUIDisableThreadedCompositing);
475 #else 494 #else
476 bool use_thread = 495 bool use_thread =
477 CommandLine::ForCurrentProcess()->HasSwitch( 496 CommandLine::ForCurrentProcess()->HasSwitch(
478 switches::kUIEnableThreadedCompositing) && 497 switches::kUIEnableThreadedCompositing) &&
479 !CommandLine::ForCurrentProcess()->HasSwitch( 498 !CommandLine::ForCurrentProcess()->HasSwitch(
480 switches::kUIDisableThreadedCompositing); 499 switches::kUIDisableThreadedCompositing);
481 #endif 500 #endif
482 if (use_thread) { 501 if (use_thread) {
483 g_compositor_thread = new base::Thread("Browser Compositor"); 502 g_compositor_thread = new base::Thread("Browser Compositor");
484 g_compositor_thread->Start(); 503 g_compositor_thread->Start();
485 } 504 }
505
506 DCHECK(!g_compositor_initialized) << "Compositor initialized twice.";
507 g_compositor_initialized = true;
486 } 508 }
487 509
488 // static 510 // static
489 bool Compositor::WasInitializedWithThread() { 511 bool Compositor::WasInitializedWithThread() {
490 return !!g_compositor_thread; 512 return !!g_compositor_thread;
491 } 513 }
492 514
493 // static 515 // static
494 scoped_refptr<base::MessageLoopProxy> Compositor::GetCompositorMessageLoop() { 516 scoped_refptr<base::MessageLoopProxy> Compositor::GetCompositorMessageLoop() {
495 scoped_refptr<base::MessageLoopProxy> proxy; 517 scoped_refptr<base::MessageLoopProxy> proxy;
496 if (g_compositor_thread) 518 if (g_compositor_thread)
497 proxy = g_compositor_thread->message_loop_proxy(); 519 proxy = g_compositor_thread->message_loop_proxy();
498 return proxy; 520 return proxy;
499 } 521 }
500 522
501 // static 523 // static
502 void Compositor::Terminate() { 524 void Compositor::Terminate() {
525 if (g_context_factory) {
526 if (g_implicit_factory) {
527 delete g_implicit_factory;
528 g_implicit_factory = NULL;
529 }
530 g_context_factory = NULL;
531 }
532
503 if (g_compositor_thread) { 533 if (g_compositor_thread) {
534 DCHECK(!g_context_factory)
535 << "The ContextFactory should not outlive the compositor thread.";
504 g_compositor_thread->Stop(); 536 g_compositor_thread->Stop();
505 delete g_compositor_thread; 537 delete g_compositor_thread;
506 g_compositor_thread = NULL; 538 g_compositor_thread = NULL;
507 } 539 }
540
541 DCHECK(g_compositor_initialized) << "Compositor::Initialize() didn't happen";
542 g_compositor_initialized = false;
508 } 543 }
509 544
510 void Compositor::ScheduleDraw() { 545 void Compositor::ScheduleDraw() {
511 if (g_compositor_thread) 546 if (g_compositor_thread)
512 host_->Composite(base::TimeTicks::Now()); 547 host_->Composite(base::TimeTicks::Now());
513 else if (delegate_) 548 else if (delegate_)
514 delegate_->ScheduleDraw(); 549 delegate_->ScheduleDraw();
515 } 550 }
516 551
517 void Compositor::SetRootLayer(Layer* root_layer) { 552 void Compositor::SetRootLayer(Layer* root_layer) {
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 compositor_lock_->CancelLock(); 779 compositor_lock_->CancelLock();
745 } 780 }
746 781
747 void Compositor::NotifyEnd() { 782 void Compositor::NotifyEnd() {
748 last_ended_frame_++; 783 last_ended_frame_++;
749 FOR_EACH_OBSERVER(CompositorObserver, 784 FOR_EACH_OBSERVER(CompositorObserver,
750 observer_list_, 785 observer_list_,
751 OnCompositingEnded(this)); 786 OnCompositingEnded(this));
752 } 787 }
753 788
754 COMPOSITOR_EXPORT void SetupTestCompositor() {
755 if (!CommandLine::ForCurrentProcess()->HasSwitch(
756 switches::kDisableTestCompositor)) {
757 g_test_compositor_enabled = true;
758 }
759 #if defined(OS_CHROMEOS)
760 // If the test is running on the chromeos envrionment (such as
761 // device or vm bots), use the real compositor.
762 if (base::chromeos::IsRunningOnChromeOS())
763 g_test_compositor_enabled = false;
764 #endif
765 ResetImplicitFactory();
766 }
767
768 COMPOSITOR_EXPORT void DisableTestCompositor() {
769 ResetImplicitFactory();
770 g_test_compositor_enabled = false;
771 }
772
773 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() {
774 return g_test_compositor_enabled;
775 }
776
777 } // namespace ui 789 } // 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