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/skia/include/images/SkImageEncoder.h" | 14 #include "third_party/skia/include/images/SkImageEncoder.h" |
13 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoin t.h" | 15 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoin t.h" |
14 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" | 16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" |
15 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" | 17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" |
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositor.h" | 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositor.h" |
17 #include "ui/compositor/compositor_observer.h" | 19 #include "ui/compositor/compositor_observer.h" |
18 #include "ui/compositor/compositor_switches.h" | 20 #include "ui/compositor/compositor_switches.h" |
19 #include "ui/compositor/dip_util.h" | 21 #include "ui/compositor/dip_util.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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 | 126 |
123 Texture::Texture(bool flipped, const gfx::Size& size) | 127 Texture::Texture(bool flipped, const gfx::Size& size) |
124 : texture_id_(0), | 128 : texture_id_(0), |
125 flipped_(flipped), | 129 flipped_(flipped), |
126 size_(size) { | 130 size_(size) { |
127 } | 131 } |
128 | 132 |
129 Texture::~Texture() { | 133 Texture::~Texture() { |
130 } | 134 } |
131 | 135 |
136 CompositorLock::CompositorLock(Compositor* compositor) | |
137 : compositor_(compositor) { | |
138 MessageLoop::current()->PostDelayedTask( | |
139 FROM_HERE, | |
140 base::Bind(&CompositorLock::CancelLock, AsWeakPtr()), | |
141 base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)); | |
142 } | |
143 | |
144 CompositorLock::~CompositorLock() { | |
145 CancelLock(); | |
146 } | |
147 | |
148 void CompositorLock::CancelLock() { | |
149 if (!compositor_) | |
150 return; | |
151 compositor_->Unlock(); | |
152 compositor_ = NULL; | |
153 } | |
154 | |
132 Compositor::Compositor(CompositorDelegate* delegate, | 155 Compositor::Compositor(CompositorDelegate* delegate, |
133 gfx::AcceleratedWidget widget) | 156 gfx::AcceleratedWidget widget) |
134 : delegate_(delegate), | 157 : delegate_(delegate), |
135 root_layer_(NULL), | 158 root_layer_(NULL), |
136 widget_(widget), | 159 widget_(widget), |
137 root_web_layer_(WebKit::WebLayer::create()), | 160 root_web_layer_(WebKit::WebLayer::create()), |
138 swap_posted_(false), | 161 swap_posted_(false), |
139 device_scale_factor_(0.0f), | 162 device_scale_factor_(0.0f), |
140 last_started_frame_(0), | 163 last_started_frame_(0), |
141 last_ended_frame_(0), | 164 last_ended_frame_(0), |
142 disable_schedule_composite_(false) { | 165 disable_schedule_composite_(false), |
166 commits_allowed_(ENABLED_NEEDS_COMMIT), | |
167 compositor_lock_(NULL) { | |
143 WebKit::WebLayerTreeView::Settings settings; | 168 WebKit::WebLayerTreeView::Settings settings; |
144 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 169 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
145 settings.showFPSCounter = | 170 settings.showFPSCounter = |
146 command_line->HasSwitch(switches::kUIShowFPSCounter); | 171 command_line->HasSwitch(switches::kUIShowFPSCounter); |
147 settings.showPlatformLayerTree = | 172 settings.showPlatformLayerTree = |
148 command_line->HasSwitch(switches::kUIShowLayerTree); | 173 command_line->HasSwitch(switches::kUIShowLayerTree); |
149 settings.refreshRate = | 174 settings.refreshRate = |
150 test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate; | 175 test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate; |
151 | 176 |
152 #if !defined(WEBCOMPOSITOR_OWNS_SETTINGS) | 177 #if !defined(WEBCOMPOSITOR_OWNS_SETTINGS) |
153 settings.partialSwapEnabled = | 178 settings.partialSwapEnabled = |
154 command_line->HasSwitch(switches::kUIEnablePartialSwap); | 179 command_line->HasSwitch(switches::kUIEnablePartialSwap); |
155 settings.perTilePainting = | 180 settings.perTilePainting = |
156 command_line->HasSwitch(switches::kUIEnablePerTilePainting); | 181 command_line->HasSwitch(switches::kUIEnablePerTilePainting); |
157 #endif | 182 #endif |
158 | 183 |
159 host_.initialize(this, root_web_layer_, settings); | 184 host_.initialize(this, root_web_layer_, settings); |
160 host_.setSurfaceReady(); | 185 host_.setSurfaceReady(); |
161 root_web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); | 186 root_web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); |
162 } | 187 } |
163 | 188 |
164 Compositor::~Compositor() { | 189 Compositor::~Compositor() { |
190 if (compositor_lock_) { | |
191 compositor_lock_->CancelLock(); | |
192 DCHECK(!compositor_lock_); | |
193 } | |
194 | |
165 // Don't call |CompositorDelegate::ScheduleDraw| from this point. | 195 // Don't call |CompositorDelegate::ScheduleDraw| from this point. |
166 delegate_ = NULL; | 196 delegate_ = NULL; |
167 // There's a cycle between |root_web_layer_| and |host_|, which results in | 197 // There's a cycle between |root_web_layer_| and |host_|, which results in |
168 // leaking and/or crashing. Explicitly set the root layer to NULL so the cycle | 198 // leaking and/or crashing. Explicitly set the root layer to NULL so the cycle |
169 // is broken. | 199 // is broken. |
170 host_.setRootLayer(NULL); | 200 host_.setRootLayer(NULL); |
171 if (root_layer_) | 201 if (root_layer_) |
172 root_layer_->SetCompositor(NULL); | 202 root_layer_->SetCompositor(NULL); |
173 | 203 |
174 // Stop all outstanding draws before telling the ContextFactory to tear | 204 // Stop all outstanding draws before telling the ContextFactory to tear |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
223 root_web_layer_.removeAllChildren(); | 253 root_web_layer_.removeAllChildren(); |
224 if (root_layer_) | 254 if (root_layer_) |
225 root_web_layer_.addChild(root_layer_->web_layer()); | 255 root_web_layer_.addChild(root_layer_->web_layer()); |
226 } | 256 } |
227 | 257 |
228 void Compositor::Draw(bool force_clear) { | 258 void Compositor::Draw(bool force_clear) { |
229 if (!root_layer_) | 259 if (!root_layer_) |
230 return; | 260 return; |
231 | 261 |
232 last_started_frame_++; | 262 last_started_frame_++; |
233 if (!g_compositor_thread) | 263 if (!g_compositor_thread) { |
234 FOR_EACH_OBSERVER(CompositorObserver, | 264 FOR_EACH_OBSERVER(CompositorObserver, |
235 observer_list_, | 265 observer_list_, |
236 OnCompositingWillStart(this)); | 266 OnCompositingWillStart(this)); |
267 } | |
237 | 268 |
238 // TODO(nduca): Temporary while compositor calls | 269 // Fast track draw because visible state could not have changed. |
239 // compositeImmediately() directly. | 270 if (!g_compositor_thread && commits_allowed_ == DISABLED) { |
240 layout(); | 271 FOR_EACH_OBSERVER(CompositorObserver, |
241 host_.composite(); | 272 observer_list_, |
273 OnCompositingStarted(this)); | |
274 } else { | |
275 // TODO(nduca): Temporary while compositor calls | |
276 // compositeImmediately() directly. | |
277 layout(); | |
278 host_.composite(); | |
279 } | |
280 | |
242 if (!g_compositor_thread && !swap_posted_) | 281 if (!g_compositor_thread && !swap_posted_) |
243 NotifyEnd(); | 282 NotifyEnd(); |
244 } | 283 } |
245 | 284 |
246 void Compositor::ScheduleFullDraw() { | 285 void Compositor::ScheduleFullDraw() { |
247 host_.setNeedsRedraw(); | 286 host_.setNeedsRedraw(); |
248 } | 287 } |
249 | 288 |
250 bool Compositor::ReadPixels(SkBitmap* bitmap, | 289 bool Compositor::ReadPixels(SkBitmap* bitmap, |
251 const gfx::Rect& bounds_in_pixel) { | 290 const gfx::Rect& bounds_in_pixel) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 test_context->Initialize(); | 383 test_context->Initialize(); |
345 return test_context; | 384 return test_context; |
346 } else { | 385 } else { |
347 return ContextFactory::GetInstance()->CreateContext(this); | 386 return ContextFactory::GetInstance()->CreateContext(this); |
348 } | 387 } |
349 } | 388 } |
350 | 389 |
351 void Compositor::didRebindGraphicsContext(bool success) { | 390 void Compositor::didRebindGraphicsContext(bool success) { |
352 } | 391 } |
353 | 392 |
354 // Called once per draw in single-threaded compositor mode and potentially | |
355 // many times between draws in the multi-threaded compositor mode. | |
356 void Compositor::didCommit() { | 393 void Compositor::didCommit() { |
357 FOR_EACH_OBSERVER(CompositorObserver, | 394 if (commits_allowed_ != DISABLED) { |
358 observer_list_, | 395 FOR_EACH_OBSERVER(CompositorObserver, |
359 OnCompositingDidCommit(this)); | 396 observer_list_, |
397 OnCompositingDidCommit(this)); | |
398 } | |
399 | |
400 if (commits_allowed_ == DISABLED_PENDING_COMMIT) { | |
401 commits_allowed_ = DISABLED; | |
402 root_web_layer_.setDeferUpdates(true); | |
403 } | |
404 | |
405 if (commits_allowed_ == ENABLED_NEEDS_COMMIT) | |
406 commits_allowed_ = ENABLED_DID_COMMIT; | |
360 } | 407 } |
361 | 408 |
362 void Compositor::didCommitAndDrawFrame() { | 409 void Compositor::didCommitAndDrawFrame() { |
363 // TODO(backer): Plumb through an earlier impl side will start. | 410 // TODO(backer): Plumb through an earlier impl side will start. |
364 if (g_compositor_thread) | 411 if (g_compositor_thread) |
365 FOR_EACH_OBSERVER(CompositorObserver, | 412 FOR_EACH_OBSERVER(CompositorObserver, |
366 observer_list_, | 413 observer_list_, |
367 OnCompositingWillStart(this)); | 414 OnCompositingWillStart(this)); |
368 | 415 |
369 FOR_EACH_OBSERVER(CompositorObserver, | 416 FOR_EACH_OBSERVER(CompositorObserver, |
370 observer_list_, | 417 observer_list_, |
371 OnCompositingStarted(this)); | 418 OnCompositingStarted(this)); |
372 } | 419 } |
373 | 420 |
374 void Compositor::didCompleteSwapBuffers() { | 421 void Compositor::didCompleteSwapBuffers() { |
375 NotifyEnd(); | 422 NotifyEnd(); |
376 } | 423 } |
377 | 424 |
378 void Compositor::scheduleComposite() { | 425 void Compositor::scheduleComposite() { |
379 if (!disable_schedule_composite_) | 426 if (!disable_schedule_composite_) |
380 ScheduleDraw(); | 427 ScheduleDraw(); |
381 } | 428 } |
382 | 429 |
430 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { | |
431 if (!compositor_lock_) { | |
432 compositor_lock_ = new CompositorLock(this); | |
433 if (commits_allowed_ == ENABLED_NEEDS_COMMIT) { | |
434 commits_allowed_ = DISABLED_PENDING_COMMIT; | |
piman
2012/08/01 18:25:34
So, I think I understand why we're doing this - th
| |
435 } else { | |
436 commits_allowed_ = DISABLED; | |
437 root_web_layer_.setDeferUpdates(true); | |
438 } | |
439 } | |
440 return compositor_lock_; | |
441 } | |
442 | |
443 void Compositor::Unlock() { | |
444 DCHECK(compositor_lock_); | |
445 compositor_lock_ = NULL; | |
446 | |
447 commits_allowed_ = ENABLED_NEEDS_COMMIT; | |
448 root_web_layer_.setDeferUpdates(false); | |
449 } | |
450 | |
383 void Compositor::SwizzleRGBAToBGRAAndFlip(unsigned char* pixels, | 451 void Compositor::SwizzleRGBAToBGRAAndFlip(unsigned char* pixels, |
384 const gfx::Size& image_size) { | 452 const gfx::Size& image_size) { |
385 // Swizzle from RGBA to BGRA | 453 // Swizzle from RGBA to BGRA |
386 size_t bitmap_size = 4 * image_size.width() * image_size.height(); | 454 size_t bitmap_size = 4 * image_size.width() * image_size.height(); |
387 for (size_t i = 0; i < bitmap_size; i += 4) | 455 for (size_t i = 0; i < bitmap_size; i += 4) |
388 std::swap(pixels[i], pixels[i + 2]); | 456 std::swap(pixels[i], pixels[i + 2]); |
389 | 457 |
390 // Vertical flip to transform from GL co-ords | 458 // Vertical flip to transform from GL co-ords |
391 size_t row_size = 4 * image_size.width(); | 459 size_t row_size = 4 * image_size.width(); |
392 scoped_array<unsigned char> tmp_row(new unsigned char[row_size]); | 460 scoped_array<unsigned char> tmp_row(new unsigned char[row_size]); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
425 | 493 |
426 COMPOSITOR_EXPORT void DisableTestCompositor() { | 494 COMPOSITOR_EXPORT void DisableTestCompositor() { |
427 test_compositor_enabled = false; | 495 test_compositor_enabled = false; |
428 } | 496 } |
429 | 497 |
430 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() { | 498 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() { |
431 return test_compositor_enabled; | 499 return test_compositor_enabled; |
432 } | 500 } |
433 | 501 |
434 } // namespace ui | 502 } // namespace ui |
OLD | NEW |