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_->Unlock(); | |
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 if (compositor_lock_) { | |
189 compositor_lock_->CancelLock(); | |
190 DCHECK(!compositor_lock_); | |
191 } | |
192 | |
164 // Don't call |CompositorDelegate::ScheduleDraw| from this point. | 193 // Don't call |CompositorDelegate::ScheduleDraw| from this point. |
165 delegate_ = NULL; | 194 delegate_ = NULL; |
166 if (root_layer_) | 195 if (root_layer_) |
167 root_layer_->SetCompositor(NULL); | 196 root_layer_->SetCompositor(NULL); |
168 | 197 |
169 // Stop all outstanding draws before telling the ContextFactory to tear | 198 // Stop all outstanding draws before telling the ContextFactory to tear |
170 // down any contexts that the |host_| may rely upon. | 199 // down any contexts that the |host_| may rely upon. |
171 host_.reset(); | 200 host_.reset(); |
172 | 201 |
173 if (!test_compositor_enabled) | 202 if (!test_compositor_enabled) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
223 void Compositor::SetHostHasTransparentBackground( | 252 void Compositor::SetHostHasTransparentBackground( |
224 bool host_has_transparent_background) { | 253 bool host_has_transparent_background) { |
225 host_->setHasTransparentBackground(host_has_transparent_background); | 254 host_->setHasTransparentBackground(host_has_transparent_background); |
226 } | 255 } |
227 | 256 |
228 void Compositor::Draw(bool force_clear) { | 257 void Compositor::Draw(bool force_clear) { |
229 if (!root_layer_) | 258 if (!root_layer_) |
230 return; | 259 return; |
231 | 260 |
232 last_started_frame_++; | 261 last_started_frame_++; |
233 if (!g_compositor_thread) | 262 if (!g_compositor_thread && !IsLocked()) { |
234 FOR_EACH_OBSERVER(CompositorObserver, | 263 // TODO(nduca): Temporary while compositor calls |
235 observer_list_, | 264 // compositeImmediately() directly. |
236 OnCompositingWillStart(this)); | 265 layout(); |
237 | 266 host_->composite(); |
238 // TODO(nduca): Temporary while compositor calls | 267 } |
239 // compositeImmediately() directly. | |
240 layout(); | |
241 host_->composite(); | |
242 if (!g_compositor_thread && !swap_posted_) | 268 if (!g_compositor_thread && !swap_posted_) |
243 NotifyEnd(); | 269 NotifyEnd(); |
244 } | 270 } |
245 | 271 |
246 void Compositor::ScheduleFullDraw() { | 272 void Compositor::ScheduleFullDraw() { |
247 host_->setNeedsRedraw(); | 273 host_->setNeedsRedraw(); |
248 } | 274 } |
249 | 275 |
250 bool Compositor::ReadPixels(SkBitmap* bitmap, | 276 bool Compositor::ReadPixels(SkBitmap* bitmap, |
251 const gfx::Rect& bounds_in_pixel) { | 277 const gfx::Rect& bounds_in_pixel) { |
252 if (bounds_in_pixel.right() > size().width() || | 278 if (bounds_in_pixel.right() > size().width() || |
253 bounds_in_pixel.bottom() > size().height()) | 279 bounds_in_pixel.bottom() > size().height()) |
254 return false; | 280 return false; |
255 bitmap->setConfig(SkBitmap::kARGB_8888_Config, | 281 bitmap->setConfig(SkBitmap::kARGB_8888_Config, |
256 bounds_in_pixel.width(), bounds_in_pixel.height()); | 282 bounds_in_pixel.width(), bounds_in_pixel.height()); |
257 bitmap->allocPixels(); | 283 bitmap->allocPixels(); |
258 SkAutoLockPixels lock_image(*bitmap); | 284 SkAutoLockPixels lock_image(*bitmap); |
259 unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels()); | 285 unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels()); |
286 Unlock(); | |
piman
2012/10/25 00:14:08
I think this should really be:
if (compositor_lock
jonathan.backer
2012/10/25 15:19:04
Done.
| |
260 return host_->compositeAndReadback(pixels, bounds_in_pixel); | 287 return host_->compositeAndReadback(pixels, bounds_in_pixel); |
261 } | 288 } |
262 | 289 |
263 void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) { | 290 void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) { |
264 DCHECK_GT(scale, 0); | 291 DCHECK_GT(scale, 0); |
265 if (size_in_pixel.IsEmpty() || scale <= 0) | 292 if (size_in_pixel.IsEmpty() || scale <= 0) |
266 return; | 293 return; |
267 size_ = size_in_pixel; | 294 size_ = size_in_pixel; |
268 host_->setViewportSize(size_in_pixel); | 295 host_->setViewportSize(size_in_pixel); |
269 root_web_layer_->setBounds(size_in_pixel); | 296 root_web_layer_->setBounds(size_in_pixel); |
(...skipping 10 matching lines...) Expand all Loading... | |
280 } | 307 } |
281 | 308 |
282 void Compositor::RemoveObserver(CompositorObserver* observer) { | 309 void Compositor::RemoveObserver(CompositorObserver* observer) { |
283 observer_list_.RemoveObserver(observer); | 310 observer_list_.RemoveObserver(observer); |
284 } | 311 } |
285 | 312 |
286 bool Compositor::HasObserver(CompositorObserver* observer) { | 313 bool Compositor::HasObserver(CompositorObserver* observer) { |
287 return observer_list_.HasObserver(observer); | 314 return observer_list_.HasObserver(observer); |
288 } | 315 } |
289 | 316 |
290 bool Compositor::IsThreaded() const { | |
291 return g_compositor_thread != NULL; | |
292 } | |
293 | |
294 void Compositor::OnSwapBuffersPosted() { | 317 void Compositor::OnSwapBuffersPosted() { |
295 swap_posted_ = true; | 318 swap_posted_ = true; |
296 } | 319 } |
297 | 320 |
298 void Compositor::OnSwapBuffersComplete() { | 321 void Compositor::OnSwapBuffersComplete() { |
299 DCHECK(swap_posted_); | 322 DCHECK(swap_posted_); |
300 swap_posted_ = false; | 323 swap_posted_ = false; |
301 NotifyEnd(); | 324 NotifyEnd(); |
302 } | 325 } |
303 | 326 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
377 return new WebGraphicsContextToOutputSurfaceAdapter(test_context); | 400 return new WebGraphicsContextToOutputSurfaceAdapter(test_context); |
378 } else { | 401 } else { |
379 return new WebGraphicsContextToOutputSurfaceAdapter( | 402 return new WebGraphicsContextToOutputSurfaceAdapter( |
380 ContextFactory::GetInstance()->CreateContext(this)); | 403 ContextFactory::GetInstance()->CreateContext(this)); |
381 } | 404 } |
382 } | 405 } |
383 | 406 |
384 void Compositor::didRecreateOutputSurface(bool success) { | 407 void Compositor::didRecreateOutputSurface(bool success) { |
385 } | 408 } |
386 | 409 |
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() { | 410 void Compositor::didCommit() { |
390 FOR_EACH_OBSERVER(CompositorObserver, | 411 if (!IsLocked()) { |
piman
2012/10/25 00:14:08
Is there actually a case where we'll call didCommi
jonathan.backer
2012/10/25 15:19:04
You are right. This is should no longer happen. I'
| |
391 observer_list_, | 412 FOR_EACH_OBSERVER(CompositorObserver, |
392 OnCompositingDidCommit(this)); | 413 observer_list_, |
414 OnCompositingDidCommit(this)); | |
415 } | |
393 } | 416 } |
394 | 417 |
395 void Compositor::didCommitAndDrawFrame() { | 418 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, | 419 FOR_EACH_OBSERVER(CompositorObserver, |
403 observer_list_, | 420 observer_list_, |
404 OnCompositingStarted(this)); | 421 OnCompositingStarted(this)); |
405 } | 422 } |
406 | 423 |
407 void Compositor::didCompleteSwapBuffers() { | 424 void Compositor::didCompleteSwapBuffers() { |
408 NotifyEnd(); | 425 NotifyEnd(); |
409 } | 426 } |
410 | 427 |
411 void Compositor::scheduleComposite() { | 428 void Compositor::scheduleComposite() { |
412 if (!disable_schedule_composite_) | 429 if (!disable_schedule_composite_) |
413 ScheduleDraw(); | 430 ScheduleDraw(); |
414 } | 431 } |
415 | 432 |
433 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { | |
434 if (!compositor_lock_) { | |
435 compositor_lock_ = new CompositorLock(this); | |
436 if (g_compositor_thread) | |
437 host_->setDeferCommits(true); | |
438 FOR_EACH_OBSERVER(CompositorObserver, | |
439 observer_list_, | |
440 OnCompositingLockStateChanged(this)); | |
441 } | |
442 return compositor_lock_; | |
443 } | |
444 | |
445 void Compositor::Unlock() { | |
446 DCHECK(compositor_lock_); | |
447 compositor_lock_ = NULL; | |
448 if (g_compositor_thread) | |
449 host_->setDeferCommits(false); | |
450 FOR_EACH_OBSERVER(CompositorObserver, | |
451 observer_list_, | |
452 OnCompositingLockStateChanged(this)); | |
453 } | |
454 | |
416 void Compositor::NotifyEnd() { | 455 void Compositor::NotifyEnd() { |
417 last_ended_frame_++; | 456 last_ended_frame_++; |
418 FOR_EACH_OBSERVER(CompositorObserver, | 457 FOR_EACH_OBSERVER(CompositorObserver, |
419 observer_list_, | 458 observer_list_, |
420 OnCompositingEnded(this)); | 459 OnCompositingEnded(this)); |
421 } | 460 } |
422 | 461 |
423 COMPOSITOR_EXPORT void SetupTestCompositor() { | 462 COMPOSITOR_EXPORT void SetupTestCompositor() { |
424 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 463 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
425 switches::kDisableTestCompositor)) { | 464 switches::kDisableTestCompositor)) { |
426 test_compositor_enabled = true; | 465 test_compositor_enabled = true; |
427 } | 466 } |
428 #if defined(OS_CHROMEOS) | 467 #if defined(OS_CHROMEOS) |
429 // If the test is running on the chromeos envrionment (such as | 468 // If the test is running on the chromeos envrionment (such as |
430 // device or vm bots), use the real compositor. | 469 // device or vm bots), use the real compositor. |
431 if (base::chromeos::IsRunningOnChromeOS()) | 470 if (base::chromeos::IsRunningOnChromeOS()) |
432 test_compositor_enabled = false; | 471 test_compositor_enabled = false; |
433 #endif | 472 #endif |
434 } | 473 } |
435 | 474 |
436 COMPOSITOR_EXPORT void DisableTestCompositor() { | 475 COMPOSITOR_EXPORT void DisableTestCompositor() { |
437 test_compositor_enabled = false; | 476 test_compositor_enabled = false; |
438 } | 477 } |
439 | 478 |
440 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() { | 479 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() { |
441 return test_compositor_enabled; | 480 return test_compositor_enabled; |
442 } | 481 } |
443 | 482 |
444 } // namespace ui | 483 } // namespace ui |
OLD | NEW |