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 last_commit_id_(0), |
166 disable_schedule_composite_(false), | |
167 updates_allowed_(ENABLED_NEEDS_UPDATE), | |
168 compositor_lock_(NULL) { | |
143 WebKit::WebLayerTreeView::Settings settings; | 169 WebKit::WebLayerTreeView::Settings settings; |
144 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 170 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
145 settings.showFPSCounter = | 171 settings.showFPSCounter = |
146 command_line->HasSwitch(switches::kUIShowFPSCounter); | 172 command_line->HasSwitch(switches::kUIShowFPSCounter); |
147 settings.showPlatformLayerTree = | 173 settings.showPlatformLayerTree = |
148 command_line->HasSwitch(switches::kUIShowLayerTree); | 174 command_line->HasSwitch(switches::kUIShowLayerTree); |
149 settings.refreshRate = | 175 settings.refreshRate = |
150 test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate; | 176 test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate; |
151 | 177 |
152 #if !defined(WEBCOMPOSITOR_OWNS_SETTINGS) | 178 #if !defined(WEBCOMPOSITOR_OWNS_SETTINGS) |
153 settings.partialSwapEnabled = | 179 settings.partialSwapEnabled = |
154 command_line->HasSwitch(switches::kUIEnablePartialSwap); | 180 command_line->HasSwitch(switches::kUIEnablePartialSwap); |
155 settings.perTilePainting = | 181 settings.perTilePainting = |
156 command_line->HasSwitch(switches::kUIEnablePerTilePainting); | 182 command_line->HasSwitch(switches::kUIEnablePerTilePainting); |
157 #endif | 183 #endif |
158 | 184 |
159 host_.initialize(this, root_web_layer_, settings); | 185 host_.initialize(this, root_web_layer_, settings); |
160 host_.setSurfaceReady(); | 186 host_.setSurfaceReady(); |
161 root_web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); | 187 root_web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); |
162 } | 188 } |
163 | 189 |
164 Compositor::~Compositor() { | 190 Compositor::~Compositor() { |
191 if (compositor_lock_) { | |
192 compositor_lock_->CancelLock(); | |
193 DCHECK(!compositor_lock_); | |
194 } | |
195 | |
165 // Don't call |CompositorDelegate::ScheduleDraw| from this point. | 196 // Don't call |CompositorDelegate::ScheduleDraw| from this point. |
166 delegate_ = NULL; | 197 delegate_ = NULL; |
167 // There's a cycle between |root_web_layer_| and |host_|, which results in | 198 // 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 | 199 // leaking and/or crashing. Explicitly set the root layer to NULL so the cycle |
169 // is broken. | 200 // is broken. |
170 host_.setRootLayer(NULL); | 201 host_.setRootLayer(NULL); |
171 if (root_layer_) | 202 if (root_layer_) |
172 root_layer_->SetCompositor(NULL); | 203 root_layer_->SetCompositor(NULL); |
173 | 204 |
174 // Stop all outstanding draws before telling the ContextFactory to tear | 205 // 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(); | 254 root_web_layer_.removeAllChildren(); |
224 if (root_layer_) | 255 if (root_layer_) |
225 root_web_layer_.addChild(root_layer_->web_layer()); | 256 root_web_layer_.addChild(root_layer_->web_layer()); |
226 } | 257 } |
227 | 258 |
228 void Compositor::Draw(bool force_clear) { | 259 void Compositor::Draw(bool force_clear) { |
229 if (!root_layer_) | 260 if (!root_layer_) |
230 return; | 261 return; |
231 | 262 |
232 last_started_frame_++; | 263 last_started_frame_++; |
233 if (!g_compositor_thread) | 264 |
234 FOR_EACH_OBSERVER(CompositorObserver, | 265 // Fast track draw because visible state could not have changed. |
235 observer_list_, | 266 if (!g_compositor_thread && updates_allowed_ == DISABLED) { |
236 OnCompositingWillStart(this)); | 267 NotifyEnd(); |
piman
2012/07/31 23:42:17
Should we also send the OnCompositingStarted callb
jonathan.backer
2012/08/01 17:22:43
Done.
| |
268 return; | |
269 } | |
237 | 270 |
238 // TODO(nduca): Temporary while compositor calls | 271 // TODO(nduca): Temporary while compositor calls |
239 // compositeImmediately() directly. | 272 // compositeImmediately() directly. |
240 layout(); | 273 layout(); |
241 host_.composite(); | 274 host_.composite(); |
242 if (!g_compositor_thread && !swap_posted_) | 275 if (!g_compositor_thread && !swap_posted_) |
243 NotifyEnd(); | 276 NotifyEnd(); |
244 } | 277 } |
245 | 278 |
246 void Compositor::ScheduleFullDraw() { | 279 void Compositor::ScheduleFullDraw() { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
290 } | 323 } |
291 | 324 |
292 void Compositor::RemoveObserver(CompositorObserver* observer) { | 325 void Compositor::RemoveObserver(CompositorObserver* observer) { |
293 observer_list_.RemoveObserver(observer); | 326 observer_list_.RemoveObserver(observer); |
294 } | 327 } |
295 | 328 |
296 bool Compositor::HasObserver(CompositorObserver* observer) { | 329 bool Compositor::HasObserver(CompositorObserver* observer) { |
297 return observer_list_.HasObserver(observer); | 330 return observer_list_.HasObserver(observer); |
298 } | 331 } |
299 | 332 |
300 bool Compositor::IsThreaded() const { | |
301 return g_compositor_thread != NULL; | |
302 } | |
303 | |
304 void Compositor::OnSwapBuffersPosted() { | 333 void Compositor::OnSwapBuffersPosted() { |
305 swap_posted_ = true; | 334 swap_posted_ = true; |
306 } | 335 } |
307 | 336 |
308 void Compositor::OnSwapBuffersComplete() { | 337 void Compositor::OnSwapBuffersComplete() { |
309 DCHECK(swap_posted_); | 338 DCHECK(swap_posted_); |
310 swap_posted_ = false; | 339 swap_posted_ = false; |
311 NotifyEnd(); | 340 NotifyEnd(); |
312 } | 341 } |
313 | 342 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
347 return ContextFactory::GetInstance()->CreateContext(this); | 376 return ContextFactory::GetInstance()->CreateContext(this); |
348 } | 377 } |
349 } | 378 } |
350 | 379 |
351 void Compositor::didRebindGraphicsContext(bool success) { | 380 void Compositor::didRebindGraphicsContext(bool success) { |
352 } | 381 } |
353 | 382 |
354 // Called once per draw in single-threaded compositor mode and potentially | 383 // Called once per draw in single-threaded compositor mode and potentially |
355 // many times between draws in the multi-threaded compositor mode. | 384 // many times between draws in the multi-threaded compositor mode. |
356 void Compositor::didCommit() { | 385 void Compositor::didCommit() { |
357 FOR_EACH_OBSERVER(CompositorObserver, | 386 if (updates_allowed_ != DISABLED) |
358 observer_list_, | 387 last_commit_id_++; |
359 OnCompositingDidCommit(this)); | 388 |
389 if (updates_allowed_ == DISABLED_PENDING_UPDATE) { | |
390 updates_allowed_ = DISABLED; | |
391 root_web_layer_.setDeferUpdates(true); | |
392 } | |
393 | |
394 if (updates_allowed_ == ENABLED_NEEDS_UPDATE) | |
395 updates_allowed_ = ENABLED_DID_UPDATE; | |
360 } | 396 } |
361 | 397 |
362 void Compositor::didCommitAndDrawFrame() { | 398 void Compositor::didCommitAndDrawFrame() { |
363 // TODO(backer): Plumb through an earlier impl side will start. | |
364 if (g_compositor_thread) | |
365 FOR_EACH_OBSERVER(CompositorObserver, | |
366 observer_list_, | |
367 OnCompositingWillStart(this)); | |
368 | |
369 FOR_EACH_OBSERVER(CompositorObserver, | 399 FOR_EACH_OBSERVER(CompositorObserver, |
370 observer_list_, | 400 observer_list_, |
371 OnCompositingStarted(this)); | 401 OnCompositingStarted(this)); |
372 } | 402 } |
373 | 403 |
374 void Compositor::didCompleteSwapBuffers() { | 404 void Compositor::didCompleteSwapBuffers() { |
375 NotifyEnd(); | 405 NotifyEnd(); |
376 } | 406 } |
377 | 407 |
378 void Compositor::scheduleComposite() { | 408 void Compositor::scheduleComposite() { |
379 if (!disable_schedule_composite_) | 409 if (!disable_schedule_composite_) |
380 ScheduleDraw(); | 410 ScheduleDraw(); |
381 } | 411 } |
382 | 412 |
413 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { | |
414 if (!compositor_lock_) { | |
415 compositor_lock_ = new CompositorLock(this); | |
416 if (updates_allowed_ == ENABLED_NEEDS_UPDATE) { | |
417 updates_allowed_ = DISABLED_PENDING_UPDATE; | |
418 } else { | |
419 updates_allowed_ = DISABLED; | |
420 root_web_layer_.setDeferUpdates(true); | |
421 } | |
422 } | |
423 return compositor_lock_; | |
424 } | |
425 | |
426 void Compositor::Unlock() { | |
427 DCHECK(compositor_lock_); | |
428 compositor_lock_ = NULL; | |
429 | |
430 updates_allowed_ = ENABLED_NEEDS_UPDATE; | |
431 root_web_layer_.setDeferUpdates(false); | |
432 } | |
433 | |
383 void Compositor::SwizzleRGBAToBGRAAndFlip(unsigned char* pixels, | 434 void Compositor::SwizzleRGBAToBGRAAndFlip(unsigned char* pixels, |
384 const gfx::Size& image_size) { | 435 const gfx::Size& image_size) { |
385 // Swizzle from RGBA to BGRA | 436 // Swizzle from RGBA to BGRA |
386 size_t bitmap_size = 4 * image_size.width() * image_size.height(); | 437 size_t bitmap_size = 4 * image_size.width() * image_size.height(); |
387 for (size_t i = 0; i < bitmap_size; i += 4) | 438 for (size_t i = 0; i < bitmap_size; i += 4) |
388 std::swap(pixels[i], pixels[i + 2]); | 439 std::swap(pixels[i], pixels[i + 2]); |
389 | 440 |
390 // Vertical flip to transform from GL co-ords | 441 // Vertical flip to transform from GL co-ords |
391 size_t row_size = 4 * image_size.width(); | 442 size_t row_size = 4 * image_size.width(); |
392 scoped_array<unsigned char> tmp_row(new unsigned char[row_size]); | 443 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 | 476 |
426 COMPOSITOR_EXPORT void DisableTestCompositor() { | 477 COMPOSITOR_EXPORT void DisableTestCompositor() { |
427 test_compositor_enabled = false; | 478 test_compositor_enabled = false; |
428 } | 479 } |
429 | 480 |
430 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() { | 481 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() { |
431 return test_compositor_enabled; | 482 return test_compositor_enabled; |
432 } | 483 } |
433 | 484 |
434 } // namespace ui | 485 } // namespace ui |
OLD | NEW |