OLD | NEW |
---|---|
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 | 8 |
9 #include "base/bind.h" | |
9 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/message_loop.h" | |
10 #include "base/threading/thread_restrictions.h" | 12 #include "base/threading/thread_restrictions.h" |
11 #include "third_party/skia/include/core/SkBitmap.h" | 13 #include "third_party/skia/include/core/SkBitmap.h" |
12 #include "third_party/WebKit/Source/Platform/chromium/public/Platform.h" | 14 #include "third_party/WebKit/Source/Platform/chromium/public/Platform.h" |
13 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorSuppor t.h" | 15 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorSuppor t.h" |
14 #include "third_party/WebKit/Source/Platform/chromium/public/WebFloatPoint.h" | 16 #include "third_party/WebKit/Source/Platform/chromium/public/WebFloatPoint.h" |
15 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutput Surface.h" | 17 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutput Surface.h" |
16 #include "ui/compositor/compositor_observer.h" | 18 #include "ui/compositor/compositor_observer.h" |
17 #include "ui/compositor/compositor_switches.h" | 19 #include "ui/compositor/compositor_switches.h" |
18 #include "ui/compositor/dip_util.h" | 20 #include "ui/compositor/dip_util.h" |
19 #include "ui/compositor/layer.h" | 21 #include "ui/compositor/layer.h" |
(...skipping 13 matching lines...) Expand all Loading... | |
33 | 35 |
34 const double kDefaultRefreshRate = 60.0; | 36 const double kDefaultRefreshRate = 60.0; |
35 const double kTestRefreshRate = 100.0; | 37 const double kTestRefreshRate = 100.0; |
36 | 38 |
37 webkit_glue::WebThreadImpl* g_compositor_thread = NULL; | 39 webkit_glue::WebThreadImpl* g_compositor_thread = NULL; |
38 | 40 |
39 bool test_compositor_enabled = false; | 41 bool test_compositor_enabled = false; |
40 | 42 |
41 ui::ContextFactory* g_context_factory = NULL; | 43 ui::ContextFactory* g_context_factory = NULL; |
42 | 44 |
45 const int kCompositorLockTimeoutMs = 67; | |
46 | |
43 } // namespace | 47 } // namespace |
44 | 48 |
45 namespace ui { | 49 namespace ui { |
46 | 50 |
47 // static | 51 // static |
48 ContextFactory* ContextFactory::GetInstance() { | 52 ContextFactory* ContextFactory::GetInstance() { |
49 // We leak the shared resources so that we don't race with | 53 // We leak the shared resources so that we don't race with |
50 // the tear down of the gl_bindings. | 54 // the tear down of the gl_bindings. |
51 if (!g_context_factory) { | 55 if (!g_context_factory) { |
52 DVLOG(1) << "Using DefaultSharedResource"; | 56 DVLOG(1) << "Using DefaultSharedResource"; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor) | 130 Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor) |
127 : texture_id_(0), | 131 : texture_id_(0), |
128 flipped_(flipped), | 132 flipped_(flipped), |
129 size_(size), | 133 size_(size), |
130 device_scale_factor_(device_scale_factor) { | 134 device_scale_factor_(device_scale_factor) { |
131 } | 135 } |
132 | 136 |
133 Texture::~Texture() { | 137 Texture::~Texture() { |
134 } | 138 } |
135 | 139 |
140 CompositorLock::CompositorLock(Compositor* compositor) | |
141 : compositor_(compositor) { | |
142 MessageLoop::current()->PostDelayedTask( | |
143 FROM_HERE, | |
144 base::Bind(&CompositorLock::CancelLock, AsWeakPtr()), | |
145 base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)); | |
146 } | |
147 | |
148 CompositorLock::~CompositorLock() { | |
149 CancelLock(); | |
150 } | |
151 | |
152 void CompositorLock::CancelLock() { | |
153 if (!compositor_) | |
154 return; | |
155 compositor_->Unlock(); | |
156 compositor_ = NULL; | |
157 } | |
158 | |
136 Compositor::Compositor(CompositorDelegate* delegate, | 159 Compositor::Compositor(CompositorDelegate* delegate, |
137 gfx::AcceleratedWidget widget) | 160 gfx::AcceleratedWidget widget) |
138 : delegate_(delegate), | 161 : delegate_(delegate), |
139 root_layer_(NULL), | 162 root_layer_(NULL), |
140 widget_(widget), | 163 widget_(widget), |
141 swap_posted_(false), | 164 swap_posted_(false), |
142 device_scale_factor_(0.0f), | 165 device_scale_factor_(0.0f), |
143 last_started_frame_(0), | 166 last_started_frame_(0), |
144 last_ended_frame_(0), | 167 last_ended_frame_(0), |
145 disable_schedule_composite_(false) { | 168 disable_schedule_composite_(false), |
169 compositor_lock_(NULL) { | |
146 WebKit::WebCompositorSupport* compositor_support = | 170 WebKit::WebCompositorSupport* compositor_support = |
147 WebKit::Platform::current()->compositorSupport(); | 171 WebKit::Platform::current()->compositorSupport(); |
148 root_web_layer_.reset(compositor_support->createLayer()); | 172 root_web_layer_.reset(compositor_support->createLayer()); |
149 WebKit::WebLayerTreeView::Settings settings; | 173 WebKit::WebLayerTreeView::Settings settings; |
150 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 174 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
151 settings.showFPSCounter = | 175 settings.showFPSCounter = |
152 command_line->HasSwitch(switches::kUIShowFPSCounter); | 176 command_line->HasSwitch(switches::kUIShowFPSCounter); |
153 settings.showPlatformLayerTree = | 177 settings.showPlatformLayerTree = |
154 command_line->HasSwitch(switches::kUIShowLayerTree); | 178 command_line->HasSwitch(switches::kUIShowLayerTree); |
155 settings.refreshRate = | 179 settings.refreshRate = |
156 test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate; | 180 test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate; |
157 | 181 |
158 root_web_layer_->setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); | 182 root_web_layer_->setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); |
159 host_.reset(compositor_support->createLayerTreeView(this, *root_web_layer_, | 183 host_.reset(compositor_support->createLayerTreeView(this, *root_web_layer_, |
160 settings)); | 184 settings)); |
161 host_->setSurfaceReady(); | 185 host_->setSurfaceReady(); |
162 } | 186 } |
163 | 187 |
164 Compositor::~Compositor() { | 188 Compositor::~Compositor() { |
189 if (compositor_lock_) { | |
190 compositor_lock_->CancelLock(); | |
191 DCHECK(!compositor_lock_); | |
192 } | |
193 | |
165 // Don't call |CompositorDelegate::ScheduleDraw| from this point. | 194 // Don't call |CompositorDelegate::ScheduleDraw| from this point. |
166 delegate_ = NULL; | 195 delegate_ = NULL; |
167 if (root_layer_) | 196 if (root_layer_) |
168 root_layer_->SetCompositor(NULL); | 197 root_layer_->SetCompositor(NULL); |
169 | 198 |
170 // Stop all outstanding draws before telling the ContextFactory to tear | 199 // Stop all outstanding draws before telling the ContextFactory to tear |
171 // down any contexts that the |host_| may rely upon. | 200 // down any contexts that the |host_| may rely upon. |
172 host_.reset(); | 201 host_.reset(); |
173 | 202 |
174 if (!test_compositor_enabled) | 203 if (!test_compositor_enabled) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 void Compositor::SetHostHasTransparentBackground( | 253 void Compositor::SetHostHasTransparentBackground( |
225 bool host_has_transparent_background) { | 254 bool host_has_transparent_background) { |
226 host_->setHasTransparentBackground(host_has_transparent_background); | 255 host_->setHasTransparentBackground(host_has_transparent_background); |
227 } | 256 } |
228 | 257 |
229 void Compositor::Draw(bool force_clear) { | 258 void Compositor::Draw(bool force_clear) { |
230 if (!root_layer_) | 259 if (!root_layer_) |
231 return; | 260 return; |
232 | 261 |
233 last_started_frame_++; | 262 last_started_frame_++; |
234 if (!g_compositor_thread) | 263 |
264 // Fast track draw because visible state could not have changed. | |
piman
2012/10/17 21:26:32
There is a case where we may want to paint anyway,
jonathan.backer
2012/10/18 20:20:35
LayerAnimator::step on the window resize triggers
| |
265 if (!g_compositor_thread && IsLocked()) { | |
235 FOR_EACH_OBSERVER(CompositorObserver, | 266 FOR_EACH_OBSERVER(CompositorObserver, |
236 observer_list_, | 267 observer_list_, |
237 OnCompositingWillStart(this)); | 268 OnCompositingStarted(this)); |
269 } else { | |
270 // TODO(nduca): Temporary while compositor calls | |
271 // compositeImmediately() directly. | |
272 layout(); | |
273 host_->composite(); | |
274 } | |
238 | 275 |
239 // TODO(nduca): Temporary while compositor calls | |
240 // compositeImmediately() directly. | |
241 layout(); | |
242 host_->composite(); | |
243 if (!g_compositor_thread && !swap_posted_) | 276 if (!g_compositor_thread && !swap_posted_) |
244 NotifyEnd(); | 277 NotifyEnd(); |
245 } | 278 } |
246 | 279 |
247 void Compositor::ScheduleFullDraw() { | 280 void Compositor::ScheduleFullDraw() { |
248 host_->setNeedsRedraw(); | 281 host_->setNeedsRedraw(); |
249 } | 282 } |
250 | 283 |
251 bool Compositor::ReadPixels(SkBitmap* bitmap, | 284 bool Compositor::ReadPixels(SkBitmap* bitmap, |
252 const gfx::Rect& bounds_in_pixel) { | 285 const gfx::Rect& bounds_in_pixel) { |
(...skipping 28 matching lines...) Expand all Loading... | |
281 } | 314 } |
282 | 315 |
283 void Compositor::RemoveObserver(CompositorObserver* observer) { | 316 void Compositor::RemoveObserver(CompositorObserver* observer) { |
284 observer_list_.RemoveObserver(observer); | 317 observer_list_.RemoveObserver(observer); |
285 } | 318 } |
286 | 319 |
287 bool Compositor::HasObserver(CompositorObserver* observer) { | 320 bool Compositor::HasObserver(CompositorObserver* observer) { |
288 return observer_list_.HasObserver(observer); | 321 return observer_list_.HasObserver(observer); |
289 } | 322 } |
290 | 323 |
291 bool Compositor::IsThreaded() const { | |
292 return g_compositor_thread != NULL; | |
293 } | |
294 | |
295 void Compositor::OnSwapBuffersPosted() { | 324 void Compositor::OnSwapBuffersPosted() { |
296 swap_posted_ = true; | 325 swap_posted_ = true; |
297 } | 326 } |
298 | 327 |
299 void Compositor::OnSwapBuffersComplete() { | 328 void Compositor::OnSwapBuffersComplete() { |
300 DCHECK(swap_posted_); | 329 DCHECK(swap_posted_); |
301 swap_posted_ = false; | 330 swap_posted_ = false; |
302 NotifyEnd(); | 331 NotifyEnd(); |
303 } | 332 } |
304 | 333 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
378 return new WebGraphicsContextToOutputSurfaceAdapter(test_context); | 407 return new WebGraphicsContextToOutputSurfaceAdapter(test_context); |
379 } else { | 408 } else { |
380 return new WebGraphicsContextToOutputSurfaceAdapter( | 409 return new WebGraphicsContextToOutputSurfaceAdapter( |
381 ContextFactory::GetInstance()->CreateContext(this)); | 410 ContextFactory::GetInstance()->CreateContext(this)); |
382 } | 411 } |
383 } | 412 } |
384 | 413 |
385 void Compositor::didRecreateOutputSurface(bool success) { | 414 void Compositor::didRecreateOutputSurface(bool success) { |
386 } | 415 } |
387 | 416 |
388 // Called once per draw in single-threaded compositor mode and potentially | |
389 // many times between draws in the multi-threaded compositor mode. | |
390 void Compositor::didCommit() { | 417 void Compositor::didCommit() { |
391 FOR_EACH_OBSERVER(CompositorObserver, | 418 if (!IsLocked()) |
piman
2012/10/17 21:26:32
nit: style requires braces because the statement s
jonathan.backer
2012/10/18 20:20:35
Done.
| |
392 observer_list_, | 419 FOR_EACH_OBSERVER(CompositorObserver, |
393 OnCompositingDidCommit(this)); | 420 observer_list_, |
421 OnCompositingDidCommit(this)); | |
394 } | 422 } |
395 | 423 |
396 void Compositor::didCommitAndDrawFrame() { | 424 void Compositor::didCommitAndDrawFrame() { |
397 // TODO(backer): Plumb through an earlier impl side will start. | |
398 if (g_compositor_thread) | |
399 FOR_EACH_OBSERVER(CompositorObserver, | |
400 observer_list_, | |
401 OnCompositingWillStart(this)); | |
402 | |
403 FOR_EACH_OBSERVER(CompositorObserver, | 425 FOR_EACH_OBSERVER(CompositorObserver, |
404 observer_list_, | 426 observer_list_, |
405 OnCompositingStarted(this)); | 427 OnCompositingStarted(this)); |
406 } | 428 } |
407 | 429 |
408 void Compositor::didCompleteSwapBuffers() { | 430 void Compositor::didCompleteSwapBuffers() { |
409 NotifyEnd(); | 431 NotifyEnd(); |
410 } | 432 } |
411 | 433 |
412 void Compositor::scheduleComposite() { | 434 void Compositor::scheduleComposite() { |
413 if (!disable_schedule_composite_) | 435 if (!disable_schedule_composite_) |
414 ScheduleDraw(); | 436 ScheduleDraw(); |
415 } | 437 } |
416 | 438 |
439 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { | |
440 if (!compositor_lock_) { | |
441 compositor_lock_ = new CompositorLock(this); | |
442 root_web_layer_->setDeferUpdates(true); | |
443 FOR_EACH_OBSERVER(CompositorObserver, | |
444 observer_list_, | |
445 OnCompositingLockStateChanged(this)); | |
446 } | |
447 return compositor_lock_; | |
448 } | |
449 | |
450 void Compositor::Unlock() { | |
451 DCHECK(compositor_lock_); | |
452 compositor_lock_ = NULL; | |
453 root_web_layer_->setDeferUpdates(false); | |
454 FOR_EACH_OBSERVER(CompositorObserver, | |
455 observer_list_, | |
456 OnCompositingLockStateChanged(this)); | |
457 } | |
458 | |
417 void Compositor::NotifyEnd() { | 459 void Compositor::NotifyEnd() { |
418 last_ended_frame_++; | 460 last_ended_frame_++; |
419 FOR_EACH_OBSERVER(CompositorObserver, | 461 FOR_EACH_OBSERVER(CompositorObserver, |
420 observer_list_, | 462 observer_list_, |
421 OnCompositingEnded(this)); | 463 OnCompositingEnded(this)); |
422 } | 464 } |
423 | 465 |
424 COMPOSITOR_EXPORT void SetupTestCompositor() { | 466 COMPOSITOR_EXPORT void SetupTestCompositor() { |
425 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 467 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
426 switches::kDisableTestCompositor)) { | 468 switches::kDisableTestCompositor)) { |
427 test_compositor_enabled = true; | 469 test_compositor_enabled = true; |
428 } | 470 } |
429 #if defined(OS_CHROMEOS) | 471 #if defined(OS_CHROMEOS) |
430 // If the test is running on the chromeos envrionment (such as | 472 // If the test is running on the chromeos envrionment (such as |
431 // device or vm bots), use the real compositor. | 473 // device or vm bots), use the real compositor. |
432 if (base::chromeos::IsRunningOnChromeOS()) | 474 if (base::chromeos::IsRunningOnChromeOS()) |
433 test_compositor_enabled = false; | 475 test_compositor_enabled = false; |
434 #endif | 476 #endif |
435 } | 477 } |
436 | 478 |
437 COMPOSITOR_EXPORT void DisableTestCompositor() { | 479 COMPOSITOR_EXPORT void DisableTestCompositor() { |
438 test_compositor_enabled = false; | 480 test_compositor_enabled = false; |
439 } | 481 } |
440 | 482 |
441 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() { | 483 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() { |
442 return test_compositor_enabled; | 484 return test_compositor_enabled; |
443 } | 485 } |
444 | 486 |
445 } // namespace ui | 487 } // namespace ui |
OLD | NEW |