Chromium Code Reviews| 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 | 129 |
| 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 : flipped_(flipped), | 131 : flipped_(flipped), |
| 128 size_(size), | 132 size_(size), |
| 129 device_scale_factor_(device_scale_factor) { | 133 device_scale_factor_(device_scale_factor) { |
| 130 } | 134 } |
| 131 | 135 |
| 132 Texture::~Texture() { | 136 Texture::~Texture() { |
| 133 } | 137 } |
| 134 | 138 |
| 139 CompositorLock::CompositorLock(Compositor* compositor) | |
| 140 : compositor_(compositor) { | |
| 141 MessageLoop::current()->PostDelayedTask( | |
| 142 FROM_HERE, | |
| 143 base::Bind(&CompositorLock::CancelLock, AsWeakPtr()), | |
| 144 base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)); | |
| 145 } | |
| 146 | |
| 147 CompositorLock::~CompositorLock() { | |
| 148 CancelLock(); | |
| 149 } | |
| 150 | |
| 151 void CompositorLock::CancelLock() { | |
| 152 if (!compositor_) | |
| 153 return; | |
| 154 compositor_->UnlockCompositor(); | |
| 155 compositor_ = NULL; | |
| 156 } | |
| 157 | |
| 135 Compositor::Compositor(CompositorDelegate* delegate, | 158 Compositor::Compositor(CompositorDelegate* delegate, |
| 136 gfx::AcceleratedWidget widget) | 159 gfx::AcceleratedWidget widget) |
| 137 : delegate_(delegate), | 160 : delegate_(delegate), |
| 138 root_layer_(NULL), | 161 root_layer_(NULL), |
| 139 widget_(widget), | 162 widget_(widget), |
| 140 swap_posted_(false), | 163 swap_posted_(false), |
| 141 device_scale_factor_(0.0f), | 164 device_scale_factor_(0.0f), |
| 142 last_started_frame_(0), | 165 last_started_frame_(0), |
| 143 last_ended_frame_(0), | 166 last_ended_frame_(0), |
| 144 disable_schedule_composite_(false) { | 167 disable_schedule_composite_(false), |
| 168 compositor_lock_(NULL) { | |
| 145 WebKit::WebCompositorSupport* compositor_support = | 169 WebKit::WebCompositorSupport* compositor_support = |
| 146 WebKit::Platform::current()->compositorSupport(); | 170 WebKit::Platform::current()->compositorSupport(); |
| 147 root_web_layer_.reset(compositor_support->createLayer()); | 171 root_web_layer_.reset(compositor_support->createLayer()); |
| 148 WebKit::WebLayerTreeView::Settings settings; | 172 WebKit::WebLayerTreeView::Settings settings; |
| 149 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 173 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 150 settings.showFPSCounter = | 174 settings.showFPSCounter = |
| 151 command_line->HasSwitch(switches::kUIShowFPSCounter); | 175 command_line->HasSwitch(switches::kUIShowFPSCounter); |
| 152 settings.showPlatformLayerTree = | 176 settings.showPlatformLayerTree = |
| 153 command_line->HasSwitch(switches::kUIShowLayerTree); | 177 command_line->HasSwitch(switches::kUIShowLayerTree); |
| 154 settings.refreshRate = | 178 settings.refreshRate = |
| 155 test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate; | 179 test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate; |
| 156 | 180 |
| 157 root_web_layer_->setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); | 181 root_web_layer_->setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); |
| 158 host_.reset(compositor_support->createLayerTreeView(this, *root_web_layer_, | 182 host_.reset(compositor_support->createLayerTreeView(this, *root_web_layer_, |
| 159 settings)); | 183 settings)); |
| 160 host_->setSurfaceReady(); | 184 host_->setSurfaceReady(); |
| 161 } | 185 } |
| 162 | 186 |
| 163 Compositor::~Compositor() { | 187 Compositor::~Compositor() { |
| 188 CancelCompositorLock(); | |
| 189 DCHECK(!compositor_lock_); | |
| 190 | |
| 164 // Don't call |CompositorDelegate::ScheduleDraw| from this point. | 191 // Don't call |CompositorDelegate::ScheduleDraw| from this point. |
| 165 delegate_ = NULL; | 192 delegate_ = NULL; |
| 166 if (root_layer_) | 193 if (root_layer_) |
| 167 root_layer_->SetCompositor(NULL); | 194 root_layer_->SetCompositor(NULL); |
| 168 | 195 |
| 169 // Stop all outstanding draws before telling the ContextFactory to tear | 196 // Stop all outstanding draws before telling the ContextFactory to tear |
| 170 // down any contexts that the |host_| may rely upon. | 197 // down any contexts that the |host_| may rely upon. |
| 171 host_.reset(); | 198 host_.reset(); |
| 172 | 199 |
| 173 if (!test_compositor_enabled) | 200 if (!test_compositor_enabled) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 223 void Compositor::SetHostHasTransparentBackground( | 250 void Compositor::SetHostHasTransparentBackground( |
| 224 bool host_has_transparent_background) { | 251 bool host_has_transparent_background) { |
| 225 host_->setHasTransparentBackground(host_has_transparent_background); | 252 host_->setHasTransparentBackground(host_has_transparent_background); |
| 226 } | 253 } |
| 227 | 254 |
| 228 void Compositor::Draw(bool force_clear) { | 255 void Compositor::Draw(bool force_clear) { |
| 229 if (!root_layer_) | 256 if (!root_layer_) |
| 230 return; | 257 return; |
| 231 | 258 |
| 232 last_started_frame_++; | 259 last_started_frame_++; |
| 233 if (!g_compositor_thread) | 260 if (!g_compositor_thread && !IsLocked()) { |
| 234 FOR_EACH_OBSERVER(CompositorObserver, | 261 // TODO(nduca): Temporary while compositor calls |
| 235 observer_list_, | 262 // compositeImmediately() directly. |
| 236 OnCompositingWillStart(this)); | 263 layout(); |
| 237 | 264 host_->composite(); |
| 238 // TODO(nduca): Temporary while compositor calls | 265 } |
| 239 // compositeImmediately() directly. | |
| 240 layout(); | |
| 241 host_->composite(); | |
| 242 if (!g_compositor_thread && !swap_posted_) | 266 if (!g_compositor_thread && !swap_posted_) |
| 243 NotifyEnd(); | 267 NotifyEnd(); |
| 244 } | 268 } |
| 245 | 269 |
| 246 void Compositor::ScheduleFullDraw() { | 270 void Compositor::ScheduleFullDraw() { |
| 247 host_->setNeedsRedraw(); | 271 host_->setNeedsRedraw(); |
| 248 } | 272 } |
| 249 | 273 |
| 250 bool Compositor::ReadPixels(SkBitmap* bitmap, | 274 bool Compositor::ReadPixels(SkBitmap* bitmap, |
| 251 const gfx::Rect& bounds_in_pixel) { | 275 const gfx::Rect& bounds_in_pixel) { |
| 252 if (bounds_in_pixel.right() > size().width() || | 276 if (bounds_in_pixel.right() > size().width() || |
| 253 bounds_in_pixel.bottom() > size().height()) | 277 bounds_in_pixel.bottom() > size().height()) |
| 254 return false; | 278 return false; |
| 255 bitmap->setConfig(SkBitmap::kARGB_8888_Config, | 279 bitmap->setConfig(SkBitmap::kARGB_8888_Config, |
| 256 bounds_in_pixel.width(), bounds_in_pixel.height()); | 280 bounds_in_pixel.width(), bounds_in_pixel.height()); |
| 257 bitmap->allocPixels(); | 281 bitmap->allocPixels(); |
| 258 SkAutoLockPixels lock_image(*bitmap); | 282 SkAutoLockPixels lock_image(*bitmap); |
| 259 unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels()); | 283 unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels()); |
| 284 CancelCompositorLock(); | |
| 260 return host_->compositeAndReadback(pixels, bounds_in_pixel); | 285 return host_->compositeAndReadback(pixels, bounds_in_pixel); |
| 261 } | 286 } |
| 262 | 287 |
| 263 void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) { | 288 void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) { |
| 264 DCHECK_GT(scale, 0); | 289 DCHECK_GT(scale, 0); |
| 265 if (size_in_pixel.IsEmpty() || scale <= 0) | 290 if (size_in_pixel.IsEmpty() || scale <= 0) |
| 266 return; | 291 return; |
| 267 size_ = size_in_pixel; | 292 size_ = size_in_pixel; |
| 268 host_->setViewportSize(size_in_pixel); | 293 host_->setViewportSize(size_in_pixel); |
| 269 root_web_layer_->setBounds(size_in_pixel); | 294 root_web_layer_->setBounds(size_in_pixel); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 280 } | 305 } |
| 281 | 306 |
| 282 void Compositor::RemoveObserver(CompositorObserver* observer) { | 307 void Compositor::RemoveObserver(CompositorObserver* observer) { |
| 283 observer_list_.RemoveObserver(observer); | 308 observer_list_.RemoveObserver(observer); |
| 284 } | 309 } |
| 285 | 310 |
| 286 bool Compositor::HasObserver(CompositorObserver* observer) { | 311 bool Compositor::HasObserver(CompositorObserver* observer) { |
| 287 return observer_list_.HasObserver(observer); | 312 return observer_list_.HasObserver(observer); |
| 288 } | 313 } |
| 289 | 314 |
| 290 bool Compositor::IsThreaded() const { | |
| 291 return g_compositor_thread != NULL; | |
| 292 } | |
| 293 | |
| 294 void Compositor::OnSwapBuffersPosted() { | 315 void Compositor::OnSwapBuffersPosted() { |
| 295 swap_posted_ = true; | 316 swap_posted_ = true; |
| 296 } | 317 } |
| 297 | 318 |
| 298 void Compositor::OnSwapBuffersComplete() { | 319 void Compositor::OnSwapBuffersComplete() { |
| 299 DCHECK(swap_posted_); | 320 DCHECK(swap_posted_); |
| 300 swap_posted_ = false; | 321 swap_posted_ = false; |
| 301 NotifyEnd(); | 322 NotifyEnd(); |
| 302 } | 323 } |
| 303 | 324 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 return new WebGraphicsContextToOutputSurfaceAdapter(test_context); | 398 return new WebGraphicsContextToOutputSurfaceAdapter(test_context); |
| 378 } else { | 399 } else { |
| 379 return new WebGraphicsContextToOutputSurfaceAdapter( | 400 return new WebGraphicsContextToOutputSurfaceAdapter( |
| 380 ContextFactory::GetInstance()->CreateContext(this)); | 401 ContextFactory::GetInstance()->CreateContext(this)); |
| 381 } | 402 } |
| 382 } | 403 } |
| 383 | 404 |
| 384 void Compositor::didRecreateOutputSurface(bool success) { | 405 void Compositor::didRecreateOutputSurface(bool success) { |
| 385 } | 406 } |
| 386 | 407 |
| 387 // Called once per draw in single-threaded compositor mode and potentially | |
| 388 // many times between draws in the multi-threaded compositor mode. | |
| 389 void Compositor::didCommit() { | 408 void Compositor::didCommit() { |
| 409 DCHECK(!IsLocked()); | |
| 390 FOR_EACH_OBSERVER(CompositorObserver, | 410 FOR_EACH_OBSERVER(CompositorObserver, |
| 391 observer_list_, | 411 observer_list_, |
| 392 OnCompositingDidCommit(this)); | 412 OnCompositingDidCommit(this)); |
| 393 } | 413 } |
| 394 | 414 |
| 395 void Compositor::didCommitAndDrawFrame() { | 415 void Compositor::didCommitAndDrawFrame() { |
| 396 // TODO(backer): Plumb through an earlier impl side will start. | |
| 397 if (g_compositor_thread) | |
| 398 FOR_EACH_OBSERVER(CompositorObserver, | |
| 399 observer_list_, | |
| 400 OnCompositingWillStart(this)); | |
| 401 | |
| 402 FOR_EACH_OBSERVER(CompositorObserver, | 416 FOR_EACH_OBSERVER(CompositorObserver, |
| 403 observer_list_, | 417 observer_list_, |
| 404 OnCompositingStarted(this)); | 418 OnCompositingStarted(this)); |
| 405 } | 419 } |
| 406 | 420 |
| 407 void Compositor::didCompleteSwapBuffers() { | 421 void Compositor::didCompleteSwapBuffers() { |
| 408 NotifyEnd(); | 422 NotifyEnd(); |
| 409 } | 423 } |
| 410 | 424 |
| 411 void Compositor::scheduleComposite() { | 425 void Compositor::scheduleComposite() { |
| 412 if (!disable_schedule_composite_) | 426 if (!disable_schedule_composite_) |
| 413 ScheduleDraw(); | 427 ScheduleDraw(); |
| 414 } | 428 } |
| 415 | 429 |
| 430 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { | |
| 431 if (!compositor_lock_) { | |
| 432 compositor_lock_ = new CompositorLock(this); | |
| 433 if (g_compositor_thread) | |
| 434 host_->setDeferCommits(true); | |
| 435 FOR_EACH_OBSERVER(CompositorObserver, | |
| 436 observer_list_, | |
| 437 OnCompositingLockStateChanged(this)); | |
| 438 } | |
| 439 return compositor_lock_; | |
| 440 } | |
| 441 | |
| 442 void Compositor::UnlockCompositor() { | |
| 443 DCHECK(compositor_lock_); | |
| 444 compositor_lock_ = NULL; | |
| 445 if (g_compositor_thread) | |
| 446 host_->setDeferCommits(false); | |
| 447 FOR_EACH_OBSERVER(CompositorObserver, | |
| 448 observer_list_, | |
| 449 OnCompositingLockStateChanged(this)); | |
| 450 } | |
| 451 | |
| 452 void Compositor::CancelCompositorLock() { | |
| 453 if (compositor_lock_) | |
| 454 UnlockCompositor(); | |
|
piman
2012/10/25 16:18:58
you really want compositor_lock_->Unlock() here (w
jonathan.backer
2012/10/25 16:38:11
Done.
| |
| 455 } | |
| 456 | |
| 416 void Compositor::NotifyEnd() { | 457 void Compositor::NotifyEnd() { |
| 417 last_ended_frame_++; | 458 last_ended_frame_++; |
| 418 FOR_EACH_OBSERVER(CompositorObserver, | 459 FOR_EACH_OBSERVER(CompositorObserver, |
| 419 observer_list_, | 460 observer_list_, |
| 420 OnCompositingEnded(this)); | 461 OnCompositingEnded(this)); |
| 421 } | 462 } |
| 422 | 463 |
| 423 COMPOSITOR_EXPORT void SetupTestCompositor() { | 464 COMPOSITOR_EXPORT void SetupTestCompositor() { |
| 424 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 465 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
| 425 switches::kDisableTestCompositor)) { | 466 switches::kDisableTestCompositor)) { |
| 426 test_compositor_enabled = true; | 467 test_compositor_enabled = true; |
| 427 } | 468 } |
| 428 #if defined(OS_CHROMEOS) | 469 #if defined(OS_CHROMEOS) |
| 429 // If the test is running on the chromeos envrionment (such as | 470 // If the test is running on the chromeos envrionment (such as |
| 430 // device or vm bots), use the real compositor. | 471 // device or vm bots), use the real compositor. |
| 431 if (base::chromeos::IsRunningOnChromeOS()) | 472 if (base::chromeos::IsRunningOnChromeOS()) |
| 432 test_compositor_enabled = false; | 473 test_compositor_enabled = false; |
| 433 #endif | 474 #endif |
| 434 } | 475 } |
| 435 | 476 |
| 436 COMPOSITOR_EXPORT void DisableTestCompositor() { | 477 COMPOSITOR_EXPORT void DisableTestCompositor() { |
| 437 test_compositor_enabled = false; | 478 test_compositor_enabled = false; |
| 438 } | 479 } |
| 439 | 480 |
| 440 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() { | 481 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() { |
| 441 return test_compositor_enabled; | 482 return test_compositor_enabled; |
| 442 } | 483 } |
| 443 | 484 |
| 444 } // namespace ui | 485 } // namespace ui |
| OLD | NEW |