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

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

Issue 134623005: Make SingleThreadProxy a SchedulerClient (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix tests; remove weak_ptr_ Created 6 years, 10 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"
(...skipping 21 matching lines...) Expand all
32 #include "ui/compositor/layer.h" 32 #include "ui/compositor/layer.h"
33 #include "ui/gfx/frame_time.h" 33 #include "ui/gfx/frame_time.h"
34 #include "ui/gl/gl_context.h" 34 #include "ui/gl/gl_context.h"
35 #include "ui/gl/gl_switches.h" 35 #include "ui/gl/gl_switches.h"
36 36
37 namespace { 37 namespace {
38 38
39 const double kDefaultRefreshRate = 60.0; 39 const double kDefaultRefreshRate = 60.0;
40 const double kTestRefreshRate = 200.0; 40 const double kTestRefreshRate = 200.0;
41 41
42 enum SwapType {
43 DRAW_SWAP,
44 };
45
46 bool g_compositor_initialized = false; 42 bool g_compositor_initialized = false;
47 base::Thread* g_compositor_thread = NULL; 43 base::Thread* g_compositor_thread = NULL;
48 44
49 ui::ContextFactory* g_context_factory = NULL; 45 ui::ContextFactory* g_context_factory = NULL;
50 46
51 const int kCompositorLockTimeoutMs = 67; 47 const int kCompositorLockTimeoutMs = 67;
52 48
53 class PendingSwap {
54 public:
55 PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps);
56 ~PendingSwap();
57
58 SwapType type() const { return type_; }
59 bool posted() const { return posted_; }
60
61 private:
62 friend class ui::PostedSwapQueue;
63
64 SwapType type_;
65 bool posted_;
66 ui::PostedSwapQueue* posted_swaps_;
67
68 DISALLOW_COPY_AND_ASSIGN(PendingSwap);
69 };
70
71 } // namespace 49 } // namespace
72 50
73 namespace ui { 51 namespace ui {
74 52
75 // static 53 // static
76 ContextFactory* ContextFactory::GetInstance() { 54 ContextFactory* ContextFactory::GetInstance() {
77 DCHECK(g_context_factory); 55 DCHECK(g_context_factory);
78 return g_context_factory; 56 return g_context_factory;
79 } 57 }
80 58
(...skipping 27 matching lines...) Expand all
108 CancelLock(); 86 CancelLock();
109 } 87 }
110 88
111 void CompositorLock::CancelLock() { 89 void CompositorLock::CancelLock() {
112 if (!compositor_) 90 if (!compositor_)
113 return; 91 return;
114 compositor_->UnlockCompositor(); 92 compositor_->UnlockCompositor();
115 compositor_ = NULL; 93 compositor_ = NULL;
116 } 94 }
117 95
118 class PostedSwapQueue {
119 public:
120 PostedSwapQueue() : pending_swap_(NULL) {
121 }
122
123 ~PostedSwapQueue() {
124 DCHECK(!pending_swap_);
125 }
126
127 SwapType NextPostedSwap() const {
128 return queue_.front();
129 }
130
131 bool AreSwapsPosted() const {
132 return !queue_.empty();
133 }
134
135 int NumSwapsPosted(SwapType type) const {
136 int count = 0;
137 for (std::deque<SwapType>::const_iterator it = queue_.begin();
138 it != queue_.end(); ++it) {
139 if (*it == type)
140 count++;
141 }
142 return count;
143 }
144
145 void PostSwap() {
146 DCHECK(pending_swap_);
147 queue_.push_back(pending_swap_->type());
148 pending_swap_->posted_ = true;
149 }
150
151 void EndSwap() {
152 queue_.pop_front();
153 }
154
155 private:
156 friend class ::PendingSwap;
157
158 PendingSwap* pending_swap_;
159 std::deque<SwapType> queue_;
160
161 DISALLOW_COPY_AND_ASSIGN(PostedSwapQueue);
162 };
163
164 } // namespace ui 96 } // namespace ui
165 97
166 namespace {
167
168 PendingSwap::PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps)
169 : type_(type), posted_(false), posted_swaps_(posted_swaps) {
170 // Only one pending swap in flight.
171 DCHECK_EQ(static_cast<PendingSwap*>(NULL), posted_swaps_->pending_swap_);
172 posted_swaps_->pending_swap_ = this;
173 }
174
175 PendingSwap::~PendingSwap() {
176 DCHECK_EQ(this, posted_swaps_->pending_swap_);
177 posted_swaps_->pending_swap_ = NULL;
178 }
179
180 } // namespace
181
182 namespace ui { 98 namespace ui {
183 99
184 Compositor::Compositor(gfx::AcceleratedWidget widget) 100 Compositor::Compositor(gfx::AcceleratedWidget widget)
185 : root_layer_(NULL), 101 : root_layer_(NULL),
186 widget_(widget), 102 widget_(widget),
187 vsync_manager_(new CompositorVSyncManager()), 103 vsync_manager_(new CompositorVSyncManager()),
188 posted_swaps_(new PostedSwapQueue()),
189 device_scale_factor_(0.0f), 104 device_scale_factor_(0.0f),
190 last_started_frame_(0), 105 last_started_frame_(0),
191 last_ended_frame_(0), 106 last_ended_frame_(0),
192 next_draw_is_resize_(false),
193 disable_schedule_composite_(false), 107 disable_schedule_composite_(false),
194 compositor_lock_(NULL), 108 compositor_lock_(NULL),
195 defer_draw_scheduling_(false),
196 waiting_on_compositing_end_(false),
197 draw_on_compositing_end_(false),
198 schedule_draw_factory_(this) { 109 schedule_draw_factory_(this) {
199 DCHECK(g_compositor_initialized) 110 DCHECK(g_compositor_initialized)
200 << "Compositor::Initialize must be called before creating a Compositor."; 111 << "Compositor::Initialize must be called before creating a Compositor.";
201 112
202 root_web_layer_ = cc::Layer::Create(); 113 root_web_layer_ = cc::Layer::Create();
203 root_web_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f)); 114 root_web_layer_->SetAnchorPoint(gfx::PointF());
204 115
205 CommandLine* command_line = CommandLine::ForCurrentProcess(); 116 CommandLine* command_line = CommandLine::ForCurrentProcess();
206 117
207 cc::LayerTreeSettings settings; 118 cc::LayerTreeSettings settings;
208 settings.refresh_rate = 119 settings.refresh_rate =
209 ContextFactory::GetInstance()->DoesCreateTestContexts() 120 ContextFactory::GetInstance()->DoesCreateTestContexts()
210 ? kTestRefreshRate 121 ? kTestRefreshRate
211 : kDefaultRefreshRate; 122 : kDefaultRefreshRate;
212 settings.partial_swap_enabled = 123 settings.partial_swap_enabled =
213 !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap); 124 !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 if (g_compositor_thread) { 218 if (g_compositor_thread) {
308 g_compositor_thread->Stop(); 219 g_compositor_thread->Stop();
309 delete g_compositor_thread; 220 delete g_compositor_thread;
310 g_compositor_thread = NULL; 221 g_compositor_thread = NULL;
311 } 222 }
312 223
313 DCHECK(g_compositor_initialized) << "Compositor::Initialize() didn't happen."; 224 DCHECK(g_compositor_initialized) << "Compositor::Initialize() didn't happen.";
314 g_compositor_initialized = false; 225 g_compositor_initialized = false;
315 } 226 }
316 227
317 void Compositor::ScheduleDraw() { 228 void Compositor::ScheduleDraw() { host_->SetNeedsCommit(); }
318 if (g_compositor_thread) {
319 host_->Composite(gfx::FrameTime::Now());
320 } else if (!defer_draw_scheduling_) {
321 defer_draw_scheduling_ = true;
322 base::MessageLoop::current()->PostTask(
323 FROM_HERE,
324 base::Bind(&Compositor::Draw, schedule_draw_factory_.GetWeakPtr()));
325 }
326 }
327 229
328 void Compositor::SetRootLayer(Layer* root_layer) { 230 void Compositor::SetRootLayer(Layer* root_layer) {
329 if (root_layer_ == root_layer) 231 if (root_layer_ == root_layer)
330 return; 232 return;
331 if (root_layer_) 233 if (root_layer_)
332 root_layer_->SetCompositor(NULL); 234 root_layer_->SetCompositor(NULL);
333 root_layer_ = root_layer; 235 root_layer_ = root_layer;
334 if (root_layer_ && !root_layer_->GetCompositor()) 236 if (root_layer_ && !root_layer_->GetCompositor())
335 root_layer_->SetCompositor(this); 237 root_layer_->SetCompositor(this);
336 root_web_layer_->RemoveAllChildren(); 238 root_web_layer_->RemoveAllChildren();
337 if (root_layer_) 239 if (root_layer_)
338 root_web_layer_->AddChild(root_layer_->cc_layer()); 240 root_web_layer_->AddChild(root_layer_->cc_layer());
339 } 241 }
340 242
341 void Compositor::SetHostHasTransparentBackground( 243 void Compositor::SetHostHasTransparentBackground(
342 bool host_has_transparent_background) { 244 bool host_has_transparent_background) {
343 host_->set_has_transparent_background(host_has_transparent_background); 245 host_->set_has_transparent_background(host_has_transparent_background);
344 } 246 }
345 247
346 void Compositor::Draw() {
347 DCHECK(!g_compositor_thread);
348
349 defer_draw_scheduling_ = false;
350 if (waiting_on_compositing_end_) {
351 draw_on_compositing_end_ = true;
352 return;
353 }
354 waiting_on_compositing_end_ = true;
355
356 TRACE_EVENT_ASYNC_BEGIN0("ui", "Compositor::Draw", last_started_frame_ + 1);
357
358 if (!root_layer_)
359 return;
360
361 last_started_frame_++;
362 PendingSwap pending_swap(DRAW_SWAP, posted_swaps_.get());
363 if (!IsLocked()) {
364 // TODO(nduca): Temporary while compositor calls
365 // compositeImmediately() directly.
366 Layout();
367 host_->Composite(gfx::FrameTime::Now());
368
369 #if defined(OS_WIN)
370 // While we resize, we are usually a few frames behind. By blocking
371 // the UI thread here we minize the area that is mis-painted, specially
372 // in the non-client area. See RenderWidgetHostViewAura::SetBounds for
373 // more details and bug 177115.
374 if (next_draw_is_resize_ && (last_ended_frame_ > 1)) {
375 next_draw_is_resize_ = false;
376 host_->FinishAllRendering();
377 }
378 #endif
379
380 }
381 if (!pending_swap.posted())
382 NotifyEnd();
383 }
384
385 void Compositor::ScheduleFullRedraw() { 248 void Compositor::ScheduleFullRedraw() {
386 host_->SetNeedsRedraw(); 249 host_->SetNeedsRedraw();
387 } 250 }
388 251
389 void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) { 252 void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) {
390 host_->SetNeedsRedrawRect(damage_rect); 253 host_->SetNeedsRedrawRect(damage_rect);
391 } 254 }
392 255
393 void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) { 256 void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) {
394 scoped_ptr<cc::SwapPromise> swap_promise( 257 scoped_ptr<cc::SwapPromise> swap_promise(
395 new cc::LatencyInfoSwapPromise(latency_info)); 258 new cc::LatencyInfoSwapPromise(latency_info));
396 host_->QueueSwapPromise(swap_promise.Pass()); 259 host_->QueueSwapPromise(swap_promise.Pass());
397 } 260 }
398 261
399 void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) { 262 void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) {
400 DCHECK_GT(scale, 0); 263 DCHECK_GT(scale, 0);
401 if (!size_in_pixel.IsEmpty()) { 264 if (!size_in_pixel.IsEmpty()) {
402 size_ = size_in_pixel; 265 size_ = size_in_pixel;
403 host_->SetViewportSize(size_in_pixel); 266 host_->SetViewportSize(size_in_pixel);
404 root_web_layer_->SetBounds(size_in_pixel); 267 root_web_layer_->SetBounds(size_in_pixel);
405
406 next_draw_is_resize_ = true;
407 } 268 }
408 if (device_scale_factor_ != scale) { 269 if (device_scale_factor_ != scale) {
409 device_scale_factor_ = scale; 270 device_scale_factor_ = scale;
410 if (root_layer_) 271 if (root_layer_)
411 root_layer_->OnDeviceScaleFactorChanged(scale); 272 root_layer_->OnDeviceScaleFactorChanged(scale);
412 } 273 }
413 } 274 }
414 275
415 void Compositor::SetBackgroundColor(SkColor color) { 276 void Compositor::SetBackgroundColor(SkColor color) {
416 host_->set_background_color(color); 277 host_->set_background_color(color);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 } 315 }
455 316
456 void Compositor::DidCommitAndDrawFrame() { 317 void Compositor::DidCommitAndDrawFrame() {
457 base::TimeTicks start_time = gfx::FrameTime::Now(); 318 base::TimeTicks start_time = gfx::FrameTime::Now();
458 FOR_EACH_OBSERVER(CompositorObserver, 319 FOR_EACH_OBSERVER(CompositorObserver,
459 observer_list_, 320 observer_list_,
460 OnCompositingStarted(this, start_time)); 321 OnCompositingStarted(this, start_time));
461 } 322 }
462 323
463 void Compositor::DidCompleteSwapBuffers() { 324 void Compositor::DidCompleteSwapBuffers() {
464 if (g_compositor_thread) { 325 last_ended_frame_++;
465 NotifyEnd(); 326 TRACE_EVENT_ASYNC_END0("ui", "Compositor::Draw", last_ended_frame_);
466 } else { 327 FOR_EACH_OBSERVER(
467 DCHECK(posted_swaps_->AreSwapsPosted()); 328 CompositorObserver, observer_list_, OnCompositingEnded(this));
468 DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP));
469 if (posted_swaps_->NextPostedSwap() == DRAW_SWAP)
470 NotifyEnd();
471 posted_swaps_->EndSwap();
472 }
473 } 329 }
474 330
475 scoped_refptr<cc::ContextProvider> Compositor::OffscreenContextProvider() { 331 scoped_refptr<cc::ContextProvider> Compositor::OffscreenContextProvider() {
476 return ContextFactory::GetInstance()->OffscreenCompositorContextProvider(); 332 return ContextFactory::GetInstance()->OffscreenCompositorContextProvider();
477 } 333 }
478 334
479 void Compositor::ScheduleComposite() { 335 void Compositor::ScheduleComposite() {
480 if (!disable_schedule_composite_) 336 if (!disable_schedule_composite_)
481 ScheduleDraw(); 337 ScheduleDraw();
482 } 338 }
483 339
484 void Compositor::ScheduleAnimation() { 340 void Compositor::ScheduleAnimation() {
485 ScheduleComposite(); 341 ScheduleComposite();
486 } 342 }
487 343
488 void Compositor::DidPostSwapBuffers() { 344 void Compositor::DidPostSwapBuffers() {
489 DCHECK(!g_compositor_thread);
490 posted_swaps_->PostSwap();
491 } 345 }
492 346
493 void Compositor::DidAbortSwapBuffers() { 347 void Compositor::DidAbortSwapBuffers() {
494 if (!g_compositor_thread) {
495 DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP));
496
497 // We've just lost the context, so unwind all posted_swaps.
498 while (posted_swaps_->AreSwapsPosted()) {
499 if (posted_swaps_->NextPostedSwap() == DRAW_SWAP)
500 NotifyEnd();
501 posted_swaps_->EndSwap();
502 }
503 }
504
505 FOR_EACH_OBSERVER(CompositorObserver, 348 FOR_EACH_OBSERVER(CompositorObserver,
506 observer_list_, 349 observer_list_,
507 OnCompositingAborted(this)); 350 OnCompositingAborted(this));
508 } 351 }
509 352
510 const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const { 353 const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const {
511 return host_->debug_state(); 354 return host_->debug_state();
512 } 355 }
513 356
514 void Compositor::SetLayerTreeDebugState( 357 void Compositor::SetLayerTreeDebugState(
515 const cc::LayerTreeDebugState& debug_state) { 358 const cc::LayerTreeDebugState& debug_state) {
516 host_->SetDebugState(debug_state); 359 host_->SetDebugState(debug_state);
517 } 360 }
518 361
519 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { 362 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
520 if (!compositor_lock_) { 363 if (!compositor_lock_) {
521 compositor_lock_ = new CompositorLock(this); 364 compositor_lock_ = new CompositorLock(this);
522 if (g_compositor_thread) 365 host_->SetDeferCommits(true);
523 host_->SetDeferCommits(true);
524 FOR_EACH_OBSERVER(CompositorObserver, 366 FOR_EACH_OBSERVER(CompositorObserver,
525 observer_list_, 367 observer_list_,
526 OnCompositingLockStateChanged(this)); 368 OnCompositingLockStateChanged(this));
527 } 369 }
528 return compositor_lock_; 370 return compositor_lock_;
529 } 371 }
530 372
531 void Compositor::UnlockCompositor() { 373 void Compositor::UnlockCompositor() {
532 DCHECK(compositor_lock_); 374 DCHECK(compositor_lock_);
533 compositor_lock_ = NULL; 375 compositor_lock_ = NULL;
534 if (g_compositor_thread) 376 host_->SetDeferCommits(false);
535 host_->SetDeferCommits(false);
536 FOR_EACH_OBSERVER(CompositorObserver, 377 FOR_EACH_OBSERVER(CompositorObserver,
537 observer_list_, 378 observer_list_,
538 OnCompositingLockStateChanged(this)); 379 OnCompositingLockStateChanged(this));
539 } 380 }
540 381
541 void Compositor::CancelCompositorLock() { 382 void Compositor::CancelCompositorLock() {
542 if (compositor_lock_) 383 if (compositor_lock_)
543 compositor_lock_->CancelLock(); 384 compositor_lock_->CancelLock();
544 } 385 }
545 386
546 void Compositor::NotifyEnd() {
547 last_ended_frame_++;
548 TRACE_EVENT_ASYNC_END0("ui", "Compositor::Draw", last_ended_frame_);
549 waiting_on_compositing_end_ = false;
550 if (draw_on_compositing_end_) {
551 draw_on_compositing_end_ = false;
552
553 // Call ScheduleDraw() instead of Draw() in order to allow other
554 // CompositorObservers to be notified before starting another
555 // draw cycle.
556 ScheduleDraw();
557 }
558 FOR_EACH_OBSERVER(CompositorObserver,
559 observer_list_,
560 OnCompositingEnded(this));
561 }
562
563 } // namespace ui 387 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698