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 "content/browser/renderer_host/compositor_impl_android.h" | 5 #include "content/browser/renderer_host/compositor_impl_android.h" |
6 | 6 |
7 #include <android/bitmap.h> | 7 #include <android/bitmap.h> |
8 #include <android/native_window_jni.h> | 8 #include <android/native_window_jni.h> |
9 | 9 |
10 #include "base/android/jni_android.h" | 10 #include "base/android/jni_android.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 #include "third_party/khronos/GLES2/gl2ext.h" | 62 #include "third_party/khronos/GLES2/gl2ext.h" |
63 #include "third_party/skia/include/core/SkMallocPixelRef.h" | 63 #include "third_party/skia/include/core/SkMallocPixelRef.h" |
64 #include "ui/android/window_android.h" | 64 #include "ui/android/window_android.h" |
65 #include "ui/gfx/android/device_display_info.h" | 65 #include "ui/gfx/android/device_display_info.h" |
66 #include "ui/gfx/swap_result.h" | 66 #include "ui/gfx/swap_result.h" |
67 | 67 |
68 namespace content { | 68 namespace content { |
69 | 69 |
70 namespace { | 70 namespace { |
71 | 71 |
72 const unsigned int kMaxUiSwapBuffers = 1U; | |
73 const unsigned int kMaxDisplaySwapBuffers = 1U; | 72 const unsigned int kMaxDisplaySwapBuffers = 1U; |
74 | 73 |
75 // Used to override capabilities_.adjust_deadline_for_parent to false | 74 // Used to override capabilities_.adjust_deadline_for_parent to false |
76 class OutputSurfaceWithoutParent : public cc::OutputSurface, | 75 class OutputSurfaceWithoutParent : public cc::OutputSurface, |
77 public CompositorImpl::VSyncObserver { | 76 public CompositorImpl::VSyncObserver { |
78 public: | 77 public: |
79 OutputSurfaceWithoutParent( | 78 OutputSurfaceWithoutParent( |
80 CompositorImpl* compositor, | 79 CompositorImpl* compositor, |
81 const scoped_refptr<ContextProviderCommandBuffer>& context_provider, | 80 const scoped_refptr<ContextProviderCommandBuffer>& context_provider, |
82 const base::Callback<void(gpu::Capabilities)>& | 81 const base::Callback<void(gpu::Capabilities)>& |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 DCHECK(command_buffer_proxy); | 134 DCHECK(command_buffer_proxy); |
136 return command_buffer_proxy; | 135 return command_buffer_proxy; |
137 } | 136 } |
138 | 137 |
139 void OnSwapBuffersCompleted(const std::vector<ui::LatencyInfo>& latency_info, | 138 void OnSwapBuffersCompleted(const std::vector<ui::LatencyInfo>& latency_info, |
140 gfx::SwapResult result) { | 139 gfx::SwapResult result) { |
141 RenderWidgetHostImpl::CompositorFrameDrawn(latency_info); | 140 RenderWidgetHostImpl::CompositorFrameDrawn(latency_info); |
142 OutputSurface::OnSwapBuffersComplete(); | 141 OutputSurface::OnSwapBuffersComplete(); |
143 } | 142 } |
144 | 143 |
145 void OnUpdateVSyncParameters(base::TimeTicks timebase, | 144 void OnVSync(base::TimeTicks timebase, base::TimeDelta interval) override { |
146 base::TimeDelta interval) override { | |
147 CommitVSyncParameters(timebase, interval); | 145 CommitVSyncParameters(timebase, interval); |
148 } | 146 } |
149 | 147 |
150 CompositorImpl* compositor_; | 148 CompositorImpl* compositor_; |
151 base::Callback<void(gpu::Capabilities)> populate_gpu_capabilities_callback_; | 149 base::Callback<void(gpu::Capabilities)> populate_gpu_capabilities_callback_; |
152 base::CancelableCallback<void(const std::vector<ui::LatencyInfo>&, | 150 base::CancelableCallback<void(const std::vector<ui::LatencyInfo>&, |
153 gfx::SwapResult)> | 151 gfx::SwapResult)> |
154 swap_buffers_completion_callback_; | 152 swap_buffers_completion_callback_; |
155 scoped_ptr<cc::OverlayCandidateValidator> overlay_candidate_validator_; | 153 scoped_ptr<cc::OverlayCandidateValidator> overlay_candidate_validator_; |
156 }; | 154 }; |
157 | 155 |
| 156 class ExternalBeginFrameSource : public cc::BeginFrameSourceBase, |
| 157 public CompositorImpl::VSyncObserver { |
| 158 public: |
| 159 ExternalBeginFrameSource(CompositorImpl* compositor) |
| 160 : compositor_(compositor) { |
| 161 compositor_->AddObserver(this); |
| 162 } |
| 163 |
| 164 ~ExternalBeginFrameSource() override { |
| 165 compositor_->RemoveObserver(this); |
| 166 } |
| 167 |
| 168 // cc::BeginFrameSourceBase implementation: |
| 169 void OnNeedsBeginFramesChange( |
| 170 bool needs_begin_frames) override { |
| 171 compositor_->OnNeedsBeginFramesChange(needs_begin_frames); |
| 172 } |
| 173 |
| 174 // CompositorImpl::VSyncObserver implementation: |
| 175 void OnVSync(base::TimeTicks frame_time, |
| 176 base::TimeDelta vsync_period) override { |
| 177 CallOnBeginFrame(cc::BeginFrameArgs::Create( |
| 178 BEGINFRAME_FROM_HERE, frame_time, base::TimeTicks::Now(), vsync_period, |
| 179 cc::BeginFrameArgs::NORMAL)); |
| 180 } |
| 181 |
| 182 private: |
| 183 CompositorImpl* compositor_; |
| 184 }; |
| 185 |
158 static bool g_initialized = false; | 186 static bool g_initialized = false; |
159 | 187 |
160 bool g_use_surface_manager = false; | 188 bool g_use_surface_manager = false; |
161 base::LazyInstance<cc::SurfaceManager> g_surface_manager = | 189 base::LazyInstance<cc::SurfaceManager> g_surface_manager = |
162 LAZY_INSTANCE_INITIALIZER; | 190 LAZY_INSTANCE_INITIALIZER; |
163 | 191 |
164 int g_surface_id_namespace = 0; | 192 int g_surface_id_namespace = 0; |
165 | 193 |
166 class SingleThreadTaskGraphRunner : public cc::SingleThreadTaskGraphRunner { | 194 class SingleThreadTaskGraphRunner : public cc::SingleThreadTaskGraphRunner { |
167 public: | 195 public: |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 : root_layer_(cc::Layer::Create(Compositor::LayerSettings())), | 258 : root_layer_(cc::Layer::Create(Compositor::LayerSettings())), |
231 resource_manager_(root_window), | 259 resource_manager_(root_window), |
232 surface_id_allocator_(GetSurfaceManager() ? CreateSurfaceIdAllocator() | 260 surface_id_allocator_(GetSurfaceManager() ? CreateSurfaceIdAllocator() |
233 : nullptr), | 261 : nullptr), |
234 has_transparent_background_(false), | 262 has_transparent_background_(false), |
235 device_scale_factor_(1), | 263 device_scale_factor_(1), |
236 window_(NULL), | 264 window_(NULL), |
237 surface_id_(0), | 265 surface_id_(0), |
238 client_(client), | 266 client_(client), |
239 root_window_(root_window), | 267 root_window_(root_window), |
240 did_post_swapbuffers_(false), | |
241 ignore_schedule_composite_(false), | |
242 needs_composite_(false), | |
243 needs_animate_(false), | 268 needs_animate_(false), |
244 will_composite_immediately_(false), | |
245 composite_on_vsync_trigger_(DO_NOT_COMPOSITE), | |
246 pending_swapbuffers_(0U), | 269 pending_swapbuffers_(0U), |
247 num_successive_context_creation_failures_(0), | 270 num_successive_context_creation_failures_(0), |
248 output_surface_request_pending_(false), | 271 output_surface_request_pending_(false), |
| 272 needs_begin_frames_(false), |
249 weak_factory_(this) { | 273 weak_factory_(this) { |
250 DCHECK(client); | 274 DCHECK(client); |
251 DCHECK(root_window); | 275 DCHECK(root_window); |
252 root_window->AttachCompositor(this); | 276 root_window->AttachCompositor(this); |
253 CreateLayerTreeHost(); | 277 CreateLayerTreeHost(); |
254 resource_manager_.Init(host_.get()); | 278 resource_manager_.Init(host_.get()); |
255 } | 279 } |
256 | 280 |
257 CompositorImpl::~CompositorImpl() { | 281 CompositorImpl::~CompositorImpl() { |
258 root_window_->DetachCompositor(); | 282 root_window_->DetachCompositor(); |
259 // Clean-up any surface references. | 283 // Clean-up any surface references. |
260 SetSurface(NULL); | 284 SetSurface(NULL); |
261 } | 285 } |
262 | 286 |
263 void CompositorImpl::PostComposite(CompositingTrigger trigger) { | |
264 DCHECK(host_->visible()); | |
265 DCHECK(needs_composite_); | |
266 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY); | |
267 | |
268 if (will_composite_immediately_ || | |
269 (trigger == COMPOSITE_EVENTUALLY && WillComposite())) { | |
270 // We will already composite soon enough. | |
271 DCHECK(WillComposite()); | |
272 return; | |
273 } | |
274 | |
275 if (DidCompositeThisFrame()) { | |
276 DCHECK(!WillCompositeThisFrame()); | |
277 if (composite_on_vsync_trigger_ != COMPOSITE_IMMEDIATELY) { | |
278 composite_on_vsync_trigger_ = trigger; | |
279 root_window_->RequestVSyncUpdate(); | |
280 } | |
281 DCHECK(WillComposite()); | |
282 return; | |
283 } | |
284 | |
285 base::TimeDelta delay; | |
286 if (trigger == COMPOSITE_IMMEDIATELY) { | |
287 will_composite_immediately_ = true; | |
288 composite_on_vsync_trigger_ = DO_NOT_COMPOSITE; | |
289 } else { | |
290 DCHECK(!WillComposite()); | |
291 const base::TimeDelta estimated_composite_time = vsync_period_ / 4; | |
292 const base::TimeTicks now = base::TimeTicks::Now(); | |
293 | |
294 if (!last_vsync_.is_null() && (now - last_vsync_) < vsync_period_) { | |
295 base::TimeTicks next_composite = | |
296 last_vsync_ + vsync_period_ - estimated_composite_time; | |
297 if (next_composite < now) { | |
298 // It's too late, we will reschedule composite as needed on the next | |
299 // vsync. | |
300 composite_on_vsync_trigger_ = COMPOSITE_EVENTUALLY; | |
301 root_window_->RequestVSyncUpdate(); | |
302 DCHECK(WillComposite()); | |
303 return; | |
304 } | |
305 | |
306 delay = next_composite - now; | |
307 } | |
308 } | |
309 TRACE_EVENT2("cc,benchmark", "CompositorImpl::PostComposite", | |
310 "trigger", trigger, | |
311 "delay", delay.InMillisecondsF()); | |
312 | |
313 DCHECK(composite_on_vsync_trigger_ == DO_NOT_COMPOSITE); | |
314 if (current_composite_task_) | |
315 current_composite_task_->Cancel(); | |
316 | |
317 // Unretained because we cancel the task on shutdown. | |
318 current_composite_task_.reset(new base::CancelableClosure( | |
319 base::Bind(&CompositorImpl::Composite, base::Unretained(this), trigger))); | |
320 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
321 FROM_HERE, current_composite_task_->callback(), delay); | |
322 } | |
323 | |
324 void CompositorImpl::Composite(CompositingTrigger trigger) { | |
325 if (trigger == COMPOSITE_IMMEDIATELY) | |
326 will_composite_immediately_ = false; | |
327 | |
328 DCHECK(host_->visible()); | |
329 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY); | |
330 DCHECK(needs_composite_); | |
331 DCHECK(!DidCompositeThisFrame()); | |
332 | |
333 DCHECK_LE(pending_swapbuffers_, kMaxUiSwapBuffers); | |
334 // Swap Ack accounting is unreliable if the OutputSurface was lost. | |
335 // In that case still attempt to composite, which will cause creation of a | |
336 // new OutputSurface and reset pending_swapbuffers_. | |
337 if (pending_swapbuffers_ == kMaxUiSwapBuffers && | |
338 !host_->output_surface_lost()) { | |
339 TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit"); | |
340 return; | |
341 } | |
342 | |
343 // Reset state before Layout+Composite since that might create more | |
344 // requests to Composite that we need to respect. | |
345 needs_composite_ = false; | |
346 | |
347 // Only allow compositing once per vsync. | |
348 current_composite_task_->Cancel(); | |
349 DCHECK(DidCompositeThisFrame() && !WillComposite()); | |
350 | |
351 const base::TimeTicks frame_time = base::TimeTicks::Now(); | |
352 if (needs_animate_) { | |
353 base::AutoReset<bool> auto_reset_ignore_schedule( | |
354 &ignore_schedule_composite_, true); | |
355 needs_animate_ = false; | |
356 root_window_->Animate(frame_time); | |
357 } | |
358 | |
359 did_post_swapbuffers_ = false; | |
360 host_->Composite(frame_time); | |
361 if (did_post_swapbuffers_) | |
362 pending_swapbuffers_++; | |
363 | |
364 // Need to track vsync to avoid compositing more than once per frame. | |
365 root_window_->RequestVSyncUpdate(); | |
366 } | |
367 | |
368 ui::UIResourceProvider& CompositorImpl::GetUIResourceProvider() { | 287 ui::UIResourceProvider& CompositorImpl::GetUIResourceProvider() { |
369 return *this; | 288 return *this; |
370 } | 289 } |
371 | 290 |
372 ui::ResourceManager& CompositorImpl::GetResourceManager() { | 291 ui::ResourceManager& CompositorImpl::GetResourceManager() { |
373 return resource_manager_; | 292 return resource_manager_; |
374 } | 293 } |
375 | 294 |
376 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) { | 295 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) { |
377 if (subroot_layer_.get()) { | 296 if (subroot_layer_.get()) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 gfx::GLSurfaceHandle(surface_id_, gfx::NATIVE_DIRECT)); | 337 gfx::GLSurfaceHandle(surface_id_, gfx::NATIVE_DIRECT)); |
419 // Register first, SetVisible() might create an OutputSurface. | 338 // Register first, SetVisible() might create an OutputSurface. |
420 RegisterViewSurface(surface_id_, j_surface.obj()); | 339 RegisterViewSurface(surface_id_, j_surface.obj()); |
421 SetVisible(true); | 340 SetVisible(true); |
422 ANativeWindow_release(window); | 341 ANativeWindow_release(window); |
423 } | 342 } |
424 } | 343 } |
425 | 344 |
426 void CompositorImpl::CreateLayerTreeHost() { | 345 void CompositorImpl::CreateLayerTreeHost() { |
427 DCHECK(!host_); | 346 DCHECK(!host_); |
428 DCHECK(!WillCompositeThisFrame()); | |
429 | |
430 // Just in case, since we immediately hide the LTH in this function, | |
431 // and we do not want to end up with a pending Composite task when the | |
432 // host is hidden. | |
433 base::AutoReset<bool> auto_reset_ignore_schedule(&ignore_schedule_composite_, | |
434 true); | |
435 | 347 |
436 cc::LayerTreeSettings settings; | 348 cc::LayerTreeSettings settings; |
437 settings.renderer_settings.refresh_rate = 60.0; | 349 settings.renderer_settings.refresh_rate = 60.0; |
438 settings.renderer_settings.allow_antialiasing = false; | 350 settings.renderer_settings.allow_antialiasing = false; |
439 settings.renderer_settings.highp_threshold_min = 2048; | 351 settings.renderer_settings.highp_threshold_min = 2048; |
440 settings.use_zero_copy = true; | 352 settings.use_zero_copy = true; |
| 353 settings.use_external_begin_frame_source = true; |
441 | 354 |
442 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 355 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
443 settings.initial_debug_state.SetRecordRenderingStats( | 356 settings.initial_debug_state.SetRecordRenderingStats( |
444 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking)); | 357 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking)); |
445 if (command_line->HasSwitch(cc::switches::kDisableCompositorPropertyTrees)) | 358 if (command_line->HasSwitch(cc::switches::kDisableCompositorPropertyTrees)) |
446 settings.use_property_trees = false; | 359 settings.use_property_trees = false; |
447 // TODO(enne): Update this this compositor to use the scheduler. | 360 settings.single_thread_proxy_scheduler = true; |
448 settings.single_thread_proxy_scheduler = false; | |
449 | 361 |
450 settings.use_compositor_animation_timelines = !command_line->HasSwitch( | 362 settings.use_compositor_animation_timelines = !command_line->HasSwitch( |
451 switches::kDisableAndroidCompositorAnimationTimelines); | 363 switches::kDisableAndroidCompositorAnimationTimelines); |
452 | 364 |
453 cc::LayerTreeHost::InitParams params; | 365 cc::LayerTreeHost::InitParams params; |
454 params.client = this; | 366 params.client = this; |
455 params.shared_bitmap_manager = HostSharedBitmapManager::current(); | 367 params.shared_bitmap_manager = HostSharedBitmapManager::current(); |
456 params.gpu_memory_buffer_manager = BrowserGpuMemoryBufferManager::current(); | 368 params.gpu_memory_buffer_manager = BrowserGpuMemoryBufferManager::current(); |
457 params.task_graph_runner = g_task_graph_runner.Pointer(); | 369 params.task_graph_runner = g_task_graph_runner.Pointer(); |
458 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); | 370 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); |
459 params.settings = &settings; | 371 params.settings = &settings; |
| 372 params.external_begin_frame_source.reset(new ExternalBeginFrameSource(this)); |
460 host_ = cc::LayerTreeHost::CreateSingleThreaded(this, ¶ms); | 373 host_ = cc::LayerTreeHost::CreateSingleThreaded(this, ¶ms); |
461 DCHECK(!host_->visible()); | 374 DCHECK(!host_->visible()); |
462 host_->SetRootLayer(root_layer_); | 375 host_->SetRootLayer(root_layer_); |
463 host_->SetViewportSize(size_); | 376 host_->SetViewportSize(size_); |
464 host_->set_has_transparent_background(has_transparent_background_); | 377 host_->set_has_transparent_background(has_transparent_background_); |
465 host_->SetDeviceScaleFactor(device_scale_factor_); | 378 host_->SetDeviceScaleFactor(device_scale_factor_); |
466 | 379 |
467 if (needs_animate_) | 380 if (needs_animate_) |
468 host_->SetNeedsAnimate(); | 381 host_->SetNeedsAnimate(); |
469 } | 382 } |
470 | 383 |
471 void CompositorImpl::SetVisible(bool visible) { | 384 void CompositorImpl::SetVisible(bool visible) { |
472 TRACE_EVENT1("cc", "CompositorImpl::SetVisible", "visible", visible); | 385 TRACE_EVENT1("cc", "CompositorImpl::SetVisible", "visible", visible); |
473 if (!visible) { | 386 if (!visible) { |
474 DCHECK(host_->visible()); | 387 DCHECK(host_->visible()); |
475 // Look for any layers that were attached to the root for readback | |
476 // and are waiting for Composite() to happen. | |
477 bool readback_pending = false; | |
478 for (size_t i = 0; i < root_layer_->children().size(); ++i) { | |
479 if (root_layer_->children()[i]->HasCopyRequest()) { | |
480 readback_pending = true; | |
481 break; | |
482 } | |
483 } | |
484 if (readback_pending) { | |
485 base::AutoReset<bool> auto_reset_ignore_schedule( | |
486 &ignore_schedule_composite_, true); | |
487 host_->Composite(base::TimeTicks::Now()); | |
488 } | |
489 if (WillComposite()) | |
490 CancelComposite(); | |
491 host_->SetVisible(false); | 388 host_->SetVisible(false); |
492 if (!host_->output_surface_lost()) | 389 if (!host_->output_surface_lost()) |
493 host_->ReleaseOutputSurface(); | 390 host_->ReleaseOutputSurface(); |
494 pending_swapbuffers_ = 0; | 391 pending_swapbuffers_ = 0; |
495 needs_composite_ = false; | |
496 composite_on_vsync_trigger_ = DO_NOT_COMPOSITE; | |
497 establish_gpu_channel_timeout_.Stop(); | 392 establish_gpu_channel_timeout_.Stop(); |
498 display_client_.reset(); | 393 display_client_.reset(); |
499 if (current_composite_task_) { | |
500 current_composite_task_->Cancel(); | |
501 current_composite_task_.reset(); | |
502 } | |
503 } else { | 394 } else { |
504 host_->SetVisible(true); | 395 host_->SetVisible(true); |
505 if (output_surface_request_pending_) | 396 if (output_surface_request_pending_) |
506 RequestNewOutputSurface(); | 397 RequestNewOutputSurface(); |
507 SetNeedsComposite(); | |
508 } | 398 } |
509 } | 399 } |
510 | 400 |
511 void CompositorImpl::setDeviceScaleFactor(float factor) { | 401 void CompositorImpl::setDeviceScaleFactor(float factor) { |
512 device_scale_factor_ = factor; | 402 device_scale_factor_ = factor; |
513 if (host_) | 403 if (host_) |
514 host_->SetDeviceScaleFactor(factor); | 404 host_->SetDeviceScaleFactor(factor); |
515 } | 405 } |
516 | 406 |
517 void CompositorImpl::SetWindowBounds(const gfx::Size& size) { | 407 void CompositorImpl::SetWindowBounds(const gfx::Size& size) { |
(...skipping 10 matching lines...) Expand all Loading... |
528 | 418 |
529 void CompositorImpl::SetHasTransparentBackground(bool flag) { | 419 void CompositorImpl::SetHasTransparentBackground(bool flag) { |
530 has_transparent_background_ = flag; | 420 has_transparent_background_ = flag; |
531 if (host_) | 421 if (host_) |
532 host_->set_has_transparent_background(flag); | 422 host_->set_has_transparent_background(flag); |
533 } | 423 } |
534 | 424 |
535 void CompositorImpl::SetNeedsComposite() { | 425 void CompositorImpl::SetNeedsComposite() { |
536 if (!host_->visible()) | 426 if (!host_->visible()) |
537 return; | 427 return; |
538 DCHECK(!needs_composite_ || WillComposite()); | 428 host_->SetNeedsAnimate(); |
539 | |
540 needs_composite_ = true; | |
541 PostComposite(COMPOSITE_IMMEDIATELY); | |
542 } | 429 } |
543 | 430 |
544 static scoped_ptr<WebGraphicsContext3DCommandBufferImpl> | 431 static scoped_ptr<WebGraphicsContext3DCommandBufferImpl> |
545 CreateGpuProcessViewContext( | 432 CreateGpuProcessViewContext( |
546 const scoped_refptr<GpuChannelHost>& gpu_channel_host, | 433 const scoped_refptr<GpuChannelHost>& gpu_channel_host, |
547 const blink::WebGraphicsContext3D::Attributes attributes, | 434 const blink::WebGraphicsContext3D::Attributes attributes, |
548 int surface_id) { | 435 int surface_id) { |
549 GURL url("chrome://gpu/Compositor::createContext3D"); | 436 GURL url("chrome://gpu/Compositor::createContext3D"); |
550 static const size_t kBytesPerPixel = 4; | 437 static const size_t kBytesPerPixel = 4; |
551 gfx::DeviceDisplayInfo display_info; | 438 gfx::DeviceDisplayInfo display_info; |
(...skipping 13 matching lines...) Expand all Loading... |
565 new WebGraphicsContext3DCommandBufferImpl(surface_id, | 452 new WebGraphicsContext3DCommandBufferImpl(surface_id, |
566 url, | 453 url, |
567 gpu_channel_host.get(), | 454 gpu_channel_host.get(), |
568 attributes, | 455 attributes, |
569 lose_context_when_out_of_memory, | 456 lose_context_when_out_of_memory, |
570 limits, | 457 limits, |
571 NULL)); | 458 NULL)); |
572 } | 459 } |
573 | 460 |
574 void CompositorImpl::UpdateLayerTreeHost() { | 461 void CompositorImpl::UpdateLayerTreeHost() { |
575 base::AutoReset<bool> auto_reset_ignore_schedule(&ignore_schedule_composite_, | |
576 true); | |
577 client_->UpdateLayerTreeHost(); | 462 client_->UpdateLayerTreeHost(); |
| 463 if (needs_animate_) { |
| 464 needs_animate_ = false; |
| 465 root_window_->Animate(base::TimeTicks::Now()); |
| 466 } |
578 } | 467 } |
579 | 468 |
580 void CompositorImpl::OnGpuChannelEstablished() { | 469 void CompositorImpl::OnGpuChannelEstablished() { |
581 establish_gpu_channel_timeout_.Stop(); | 470 establish_gpu_channel_timeout_.Stop(); |
582 CreateOutputSurface(); | 471 CreateOutputSurface(); |
583 } | 472 } |
584 | 473 |
585 void CompositorImpl::OnGpuChannelTimeout() { | 474 void CompositorImpl::OnGpuChannelTimeout() { |
586 LOG(FATAL) << "Timed out waiting for GPU channel."; | 475 LOG(FATAL) << "Timed out waiting for GPU channel."; |
587 } | 476 } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 } | 586 } |
698 | 587 |
699 void CompositorImpl::DeleteUIResource(cc::UIResourceId resource_id) { | 588 void CompositorImpl::DeleteUIResource(cc::UIResourceId resource_id) { |
700 host_->DeleteUIResource(resource_id); | 589 host_->DeleteUIResource(resource_id); |
701 } | 590 } |
702 | 591 |
703 bool CompositorImpl::SupportsETC1NonPowerOfTwo() const { | 592 bool CompositorImpl::SupportsETC1NonPowerOfTwo() const { |
704 return gpu_capabilities_.texture_format_etc1_npot; | 593 return gpu_capabilities_.texture_format_etc1_npot; |
705 } | 594 } |
706 | 595 |
707 void CompositorImpl::ScheduleComposite() { | |
708 if (ignore_schedule_composite_ || !host_->visible()) | |
709 return; | |
710 | |
711 DCHECK(!needs_composite_ || WillComposite()); | |
712 needs_composite_ = true; | |
713 // We currently expect layer tree invalidations at most once per frame | |
714 // during normal operation and therefore try to composite immediately | |
715 // to minimize latency. | |
716 PostComposite(COMPOSITE_IMMEDIATELY); | |
717 } | |
718 | |
719 void CompositorImpl::ScheduleAnimation() { | |
720 needs_animate_ = true; | |
721 | |
722 if (!host_->visible()) | |
723 return; | |
724 | |
725 if (needs_composite_) { | |
726 DCHECK(WillComposite()); | |
727 return; | |
728 } | |
729 | |
730 TRACE_EVENT0("cc", "CompositorImpl::ScheduleAnimation"); | |
731 needs_composite_ = true; | |
732 PostComposite(COMPOSITE_EVENTUALLY); | |
733 } | |
734 | |
735 void CompositorImpl::DidPostSwapBuffers() { | 596 void CompositorImpl::DidPostSwapBuffers() { |
736 TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers"); | 597 TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers"); |
737 did_post_swapbuffers_ = true; | 598 pending_swapbuffers_++; |
738 } | 599 } |
739 | 600 |
740 void CompositorImpl::DidCompleteSwapBuffers() { | 601 void CompositorImpl::DidCompleteSwapBuffers() { |
741 TRACE_EVENT0("compositor", "CompositorImpl::DidCompleteSwapBuffers"); | 602 TRACE_EVENT0("compositor", "CompositorImpl::DidCompleteSwapBuffers"); |
742 DCHECK_GT(pending_swapbuffers_, 0U); | 603 DCHECK_GT(pending_swapbuffers_, 0U); |
743 if (pending_swapbuffers_-- == kMaxUiSwapBuffers && needs_composite_) | 604 pending_swapbuffers_--; |
744 PostComposite(COMPOSITE_IMMEDIATELY); | |
745 client_->OnSwapBuffersCompleted(pending_swapbuffers_); | 605 client_->OnSwapBuffersCompleted(pending_swapbuffers_); |
746 } | 606 } |
747 | 607 |
748 void CompositorImpl::DidAbortSwapBuffers() { | 608 void CompositorImpl::DidAbortSwapBuffers() { |
749 TRACE_EVENT0("compositor", "CompositorImpl::DidAbortSwapBuffers"); | 609 TRACE_EVENT0("compositor", "CompositorImpl::DidAbortSwapBuffers"); |
750 // This really gets called only once from | 610 // This really gets called only once from |
751 // SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() when the | 611 // SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() when the |
752 // context was lost. | 612 // context was lost. |
753 ScheduleComposite(); | 613 if (host_->visible()) |
| 614 host_->SetNeedsCommit(); |
754 client_->OnSwapBuffersCompleted(0); | 615 client_->OnSwapBuffersCompleted(0); |
755 } | 616 } |
756 | 617 |
757 void CompositorImpl::DidCommit() { | 618 void CompositorImpl::DidCommit() { |
758 root_window_->OnCompositingDidCommit(); | 619 root_window_->OnCompositingDidCommit(); |
759 } | 620 } |
760 | 621 |
761 void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) { | 622 void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) { |
762 root_layer_->AddChild(layer); | 623 root_layer_->AddChild(layer); |
763 } | 624 } |
764 | 625 |
765 void CompositorImpl::RequestCopyOfOutputOnRootLayer( | 626 void CompositorImpl::RequestCopyOfOutputOnRootLayer( |
766 scoped_ptr<cc::CopyOutputRequest> request) { | 627 scoped_ptr<cc::CopyOutputRequest> request) { |
767 root_layer_->RequestCopyOfOutput(request.Pass()); | 628 root_layer_->RequestCopyOfOutput(request.Pass()); |
768 } | 629 } |
769 | 630 |
770 void CompositorImpl::OnVSync(base::TimeTicks frame_time, | 631 void CompositorImpl::OnVSync(base::TimeTicks frame_time, |
771 base::TimeDelta vsync_period) { | 632 base::TimeDelta vsync_period) { |
772 vsync_period_ = vsync_period; | 633 FOR_EACH_OBSERVER(VSyncObserver, observer_list_, |
773 last_vsync_ = frame_time; | 634 OnVSync(frame_time, vsync_period)); |
| 635 if (needs_begin_frames_) |
| 636 root_window_->RequestVSyncUpdate(); |
| 637 } |
774 | 638 |
775 if (WillCompositeThisFrame()) { | 639 void CompositorImpl::OnNeedsBeginFramesChange(bool needs_begin_frames) { |
776 // We somehow missed the last vsync interval, so reschedule for deadline. | 640 if (needs_begin_frames_ == needs_begin_frames) |
777 // We cannot schedule immediately, or will get us out-of-phase with new | 641 return; |
778 // renderer frames. | |
779 CancelComposite(); | |
780 composite_on_vsync_trigger_ = COMPOSITE_EVENTUALLY; | |
781 } else { | |
782 current_composite_task_.reset(); | |
783 } | |
784 | 642 |
785 DCHECK(!DidCompositeThisFrame() && !WillCompositeThisFrame()); | 643 needs_begin_frames_ = needs_begin_frames; |
786 if (composite_on_vsync_trigger_ != DO_NOT_COMPOSITE) { | 644 if (needs_begin_frames_) |
787 CompositingTrigger trigger = composite_on_vsync_trigger_; | 645 root_window_->RequestVSyncUpdate(); |
788 composite_on_vsync_trigger_ = DO_NOT_COMPOSITE; | |
789 PostComposite(trigger); | |
790 } | |
791 | |
792 FOR_EACH_OBSERVER(VSyncObserver, observer_list_, | |
793 OnUpdateVSyncParameters(frame_time, vsync_period)); | |
794 } | 646 } |
795 | 647 |
796 void CompositorImpl::SetNeedsAnimate() { | 648 void CompositorImpl::SetNeedsAnimate() { |
797 needs_animate_ = true; | 649 needs_animate_ = true; |
798 if (!host_->visible()) | 650 if (!host_->visible()) |
799 return; | 651 return; |
800 | 652 |
801 host_->SetNeedsAnimate(); | 653 host_->SetNeedsAnimate(); |
802 } | 654 } |
803 | 655 |
804 } // namespace content | 656 } // namespace content |
OLD | NEW |