| 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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 surface_id_(0), | 174 surface_id_(0), |
| 175 client_(client), | 175 client_(client), |
| 176 root_window_(root_window), | 176 root_window_(root_window), |
| 177 did_post_swapbuffers_(false), | 177 did_post_swapbuffers_(false), |
| 178 ignore_schedule_composite_(false), | 178 ignore_schedule_composite_(false), |
| 179 needs_composite_(false), | 179 needs_composite_(false), |
| 180 needs_animate_(false), | 180 needs_animate_(false), |
| 181 will_composite_immediately_(false), | 181 will_composite_immediately_(false), |
| 182 composite_on_vsync_trigger_(DO_NOT_COMPOSITE), | 182 composite_on_vsync_trigger_(DO_NOT_COMPOSITE), |
| 183 pending_swapbuffers_(0U), | 183 pending_swapbuffers_(0U), |
| 184 defer_composite_for_gpu_channel_(false), | 184 num_successive_context_creation_failures_(0), |
| 185 weak_factory_(this) { | 185 weak_factory_(this) { |
| 186 DCHECK(client); | 186 DCHECK(client); |
| 187 DCHECK(root_window); | 187 DCHECK(root_window); |
| 188 root_window->AttachCompositor(this); | 188 root_window->AttachCompositor(this); |
| 189 } | 189 } |
| 190 | 190 |
| 191 CompositorImpl::~CompositorImpl() { | 191 CompositorImpl::~CompositorImpl() { |
| 192 root_window_->DetachCompositor(); | 192 root_window_->DetachCompositor(); |
| 193 // Clean-up any surface references. | 193 // Clean-up any surface references. |
| 194 SetSurface(NULL); | 194 SetSurface(NULL); |
| 195 } | 195 } |
| 196 | 196 |
| 197 void CompositorImpl::PostComposite(CompositingTrigger trigger) { | 197 void CompositorImpl::PostComposite(CompositingTrigger trigger) { |
| 198 DCHECK(needs_composite_); | 198 DCHECK(needs_composite_); |
| 199 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY); | 199 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY); |
| 200 | 200 |
| 201 if (defer_composite_for_gpu_channel_ || will_composite_immediately_ || | 201 if (will_composite_immediately_ || |
| 202 (trigger == COMPOSITE_EVENTUALLY && WillComposite())) { | 202 (trigger == COMPOSITE_EVENTUALLY && WillComposite())) { |
| 203 // We will already composite soon enough. | 203 // We will already composite soon enough. |
| 204 DCHECK(WillComposite()); | 204 DCHECK(WillComposite()); |
| 205 return; | 205 return; |
| 206 } | 206 } |
| 207 | 207 |
| 208 if (DidCompositeThisFrame()) { | 208 if (DidCompositeThisFrame()) { |
| 209 DCHECK(!WillCompositeThisFrame()); | 209 DCHECK(!WillCompositeThisFrame()); |
| 210 if (composite_on_vsync_trigger_ != COMPOSITE_IMMEDIATELY) { | 210 if (composite_on_vsync_trigger_ != COMPOSITE_IMMEDIATELY) { |
| 211 composite_on_vsync_trigger_ = trigger; | 211 composite_on_vsync_trigger_ = trigger; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 if (current_composite_task_) | 247 if (current_composite_task_) |
| 248 current_composite_task_->Cancel(); | 248 current_composite_task_->Cancel(); |
| 249 | 249 |
| 250 // Unretained because we cancel the task on shutdown. | 250 // Unretained because we cancel the task on shutdown. |
| 251 current_composite_task_.reset(new base::CancelableClosure( | 251 current_composite_task_.reset(new base::CancelableClosure( |
| 252 base::Bind(&CompositorImpl::Composite, base::Unretained(this), trigger))); | 252 base::Bind(&CompositorImpl::Composite, base::Unretained(this), trigger))); |
| 253 base::MessageLoop::current()->PostDelayedTask( | 253 base::MessageLoop::current()->PostDelayedTask( |
| 254 FROM_HERE, current_composite_task_->callback(), delay); | 254 FROM_HERE, current_composite_task_->callback(), delay); |
| 255 } | 255 } |
| 256 | 256 |
| 257 void CompositorImpl::OnGpuChannelEstablished() { | |
| 258 defer_composite_for_gpu_channel_ = false; | |
| 259 | |
| 260 if (host_) | |
| 261 PostComposite(COMPOSITE_IMMEDIATELY); | |
| 262 } | |
| 263 | |
| 264 void CompositorImpl::Composite(CompositingTrigger trigger) { | 257 void CompositorImpl::Composite(CompositingTrigger trigger) { |
| 265 if (trigger == COMPOSITE_IMMEDIATELY) | 258 if (trigger == COMPOSITE_IMMEDIATELY) |
| 266 will_composite_immediately_ = false; | 259 will_composite_immediately_ = false; |
| 267 | 260 |
| 268 BrowserGpuChannelHostFactory* factory = | |
| 269 BrowserGpuChannelHostFactory::instance(); | |
| 270 if (!factory->GetGpuChannel() || factory->GetGpuChannel()->IsLost()) { | |
| 271 CauseForGpuLaunch cause = | |
| 272 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE; | |
| 273 factory->EstablishGpuChannel( | |
| 274 cause, base::Bind(&CompositorImpl::OnGpuChannelEstablished, | |
| 275 weak_factory_.GetWeakPtr())); | |
| 276 DCHECK(!defer_composite_for_gpu_channel_); | |
| 277 defer_composite_for_gpu_channel_ = true; | |
| 278 current_composite_task_.reset(); | |
| 279 return; | |
| 280 } | |
| 281 | |
| 282 DCHECK(host_); | 261 DCHECK(host_); |
| 283 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY); | 262 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY); |
| 284 DCHECK(needs_composite_); | 263 DCHECK(needs_composite_); |
| 285 DCHECK(!DidCompositeThisFrame()); | 264 DCHECK(!DidCompositeThisFrame()); |
| 286 | 265 |
| 287 DCHECK_LE(pending_swapbuffers_, kMaxSwapBuffers); | 266 DCHECK_LE(pending_swapbuffers_, kMaxSwapBuffers); |
| 288 if (pending_swapbuffers_ == kMaxSwapBuffers) { | 267 // Swap Ack accounting is unreliable if the OutputSurface was lost. |
| 268 // In that case still attempt to composite, which will cause creation of a |
| 269 // new OutputSurface and reset pending_swapbuffers_. |
| 270 if (pending_swapbuffers_ == kMaxSwapBuffers && |
| 271 !host_->output_surface_lost()) { |
| 289 TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit"); | 272 TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit"); |
| 290 return; | 273 return; |
| 291 } | 274 } |
| 292 | 275 |
| 293 // Reset state before Layout+Composite since that might create more | 276 // Reset state before Layout+Composite since that might create more |
| 294 // requests to Composite that we need to respect. | 277 // requests to Composite that we need to respect. |
| 295 needs_composite_ = false; | 278 needs_composite_ = false; |
| 296 | 279 |
| 297 // Only allow compositing once per vsync. | 280 // Only allow compositing once per vsync. |
| 298 current_composite_task_->Cancel(); | 281 current_composite_task_->Cancel(); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 SetWindowSurface(window); | 365 SetWindowSurface(window); |
| 383 ANativeWindow_release(window); | 366 ANativeWindow_release(window); |
| 384 RegisterViewSurface(surface_id_, j_surface.obj()); | 367 RegisterViewSurface(surface_id_, j_surface.obj()); |
| 385 } | 368 } |
| 386 } | 369 } |
| 387 | 370 |
| 388 void CompositorImpl::CreateLayerTreeHost() { | 371 void CompositorImpl::CreateLayerTreeHost() { |
| 389 DCHECK(!host_); | 372 DCHECK(!host_); |
| 390 DCHECK(!WillCompositeThisFrame()); | 373 DCHECK(!WillCompositeThisFrame()); |
| 391 needs_composite_ = false; | 374 needs_composite_ = false; |
| 392 defer_composite_for_gpu_channel_ = false; | |
| 393 pending_swapbuffers_ = 0; | 375 pending_swapbuffers_ = 0; |
| 394 cc::LayerTreeSettings settings; | 376 cc::LayerTreeSettings settings; |
| 395 settings.renderer_settings.refresh_rate = 60.0; | 377 settings.renderer_settings.refresh_rate = 60.0; |
| 396 settings.renderer_settings.allow_antialiasing = false; | 378 settings.renderer_settings.allow_antialiasing = false; |
| 397 settings.renderer_settings.highp_threshold_min = 2048; | 379 settings.renderer_settings.highp_threshold_min = 2048; |
| 398 settings.impl_side_painting = false; | 380 settings.impl_side_painting = false; |
| 399 settings.calculate_top_controls_position = false; | 381 settings.calculate_top_controls_position = false; |
| 400 | 382 |
| 401 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 383 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 402 settings.initial_debug_state.SetRecordRenderingStats( | 384 settings.initial_debug_state.SetRecordRenderingStats( |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 } | 422 } |
| 441 if (readback_pending) { | 423 if (readback_pending) { |
| 442 ignore_schedule_composite_ = true; | 424 ignore_schedule_composite_ = true; |
| 443 host_->Composite(base::TimeTicks::Now()); | 425 host_->Composite(base::TimeTicks::Now()); |
| 444 ignore_schedule_composite_ = false; | 426 ignore_schedule_composite_ = false; |
| 445 } | 427 } |
| 446 if (WillComposite()) | 428 if (WillComposite()) |
| 447 CancelComposite(); | 429 CancelComposite(); |
| 448 ui_resource_provider_.SetLayerTreeHost(NULL); | 430 ui_resource_provider_.SetLayerTreeHost(NULL); |
| 449 host_.reset(); | 431 host_.reset(); |
| 432 output_surface_task_for_host_.reset(); |
| 450 display_client_.reset(); | 433 display_client_.reset(); |
| 451 if (current_composite_task_) { | 434 if (current_composite_task_) { |
| 452 current_composite_task_->Cancel(); | 435 current_composite_task_->Cancel(); |
| 453 current_composite_task_.reset(); | 436 current_composite_task_.reset(); |
| 454 } | 437 } |
| 455 } else if (!host_) { | 438 } else if (!host_) { |
| 456 CreateLayerTreeHost(); | 439 CreateLayerTreeHost(); |
| 457 ui_resource_provider_.SetLayerTreeHost(host_.get()); | 440 ui_resource_provider_.SetLayerTreeHost(host_.get()); |
| 458 } | 441 } |
| 459 } | 442 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 NULL)); | 506 NULL)); |
| 524 } | 507 } |
| 525 | 508 |
| 526 void CompositorImpl::Layout() { | 509 void CompositorImpl::Layout() { |
| 527 ignore_schedule_composite_ = true; | 510 ignore_schedule_composite_ = true; |
| 528 client_->Layout(); | 511 client_->Layout(); |
| 529 ignore_schedule_composite_ = false; | 512 ignore_schedule_composite_ = false; |
| 530 } | 513 } |
| 531 | 514 |
| 532 void CompositorImpl::RequestNewOutputSurface() { | 515 void CompositorImpl::RequestNewOutputSurface() { |
| 533 // SetVisible(false) can happen (destroying the host_) between when this | |
| 534 // function is posted and when it is handled. An output surface will get | |
| 535 // re-requested when the host is recreated. | |
| 536 if (!host_.get()) | |
| 537 return; | |
| 538 | |
| 539 BrowserGpuChannelHostFactory* factory = | 516 BrowserGpuChannelHostFactory* factory = |
| 540 BrowserGpuChannelHostFactory::instance(); | 517 BrowserGpuChannelHostFactory::instance(); |
| 541 if (!factory->GetGpuChannel() || factory->GetGpuChannel()->IsLost()) { | 518 if (!factory->GetGpuChannel() || factory->GetGpuChannel()->IsLost()) { |
| 542 CauseForGpuLaunch cause = | 519 CauseForGpuLaunch cause = |
| 543 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE; | 520 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE; |
| 544 factory->EstablishGpuChannel( | 521 output_surface_task_for_host_.reset(new base::CancelableClosure(base::Bind( |
| 545 cause, | 522 &CompositorImpl::CreateOutputSurface, base::Unretained(this)))); |
| 546 base::Bind(&CompositorImpl::CreateOutputSurface, | 523 factory->EstablishGpuChannel(cause, |
| 547 weak_factory_.GetWeakPtr())); | 524 output_surface_task_for_host_->callback()); |
| 548 return; | 525 return; |
| 549 } | 526 } |
| 550 | 527 |
| 551 CreateOutputSurface(); | 528 CreateOutputSurface(); |
| 552 } | 529 } |
| 553 | 530 |
| 531 void CompositorImpl::DidInitializeOutputSurface() { |
| 532 num_successive_context_creation_failures_ = 0; |
| 533 } |
| 534 |
| 554 void CompositorImpl::DidFailToInitializeOutputSurface() { | 535 void CompositorImpl::DidFailToInitializeOutputSurface() { |
| 555 RequestNewOutputSurface(); | 536 RequestNewOutputSurface(); |
| 537 LOG(ERROR) << "Failed to init OutputSurface for compositor."; |
| 538 LOG_IF(FATAL, ++num_successive_context_creation_failures_ >= 3) |
| 539 << "Too many context creation failures. Giving up... "; |
| 556 } | 540 } |
| 557 | 541 |
| 558 void CompositorImpl::CreateOutputSurface() { | 542 void CompositorImpl::CreateOutputSurface() { |
| 559 // This function will get called again when the compositor becomes visible. | |
| 560 if (!host_.get()) | |
| 561 return; | |
| 562 | |
| 563 blink::WebGraphicsContext3D::Attributes attrs; | 543 blink::WebGraphicsContext3D::Attributes attrs; |
| 564 attrs.shareResources = true; | 544 attrs.shareResources = true; |
| 565 attrs.noAutomaticFlushes = true; | 545 attrs.noAutomaticFlushes = true; |
| 566 pending_swapbuffers_ = 0; | 546 pending_swapbuffers_ = 0; |
| 567 | 547 |
| 568 DCHECK(window_); | 548 DCHECK(window_); |
| 569 DCHECK(surface_id_); | 549 DCHECK(surface_id_); |
| 570 | 550 |
| 571 scoped_refptr<ContextProviderCommandBuffer> context_provider; | 551 scoped_refptr<ContextProviderCommandBuffer> context_provider; |
| 572 BrowserGpuChannelHostFactory* factory = | 552 BrowserGpuChannelHostFactory* factory = |
| 573 BrowserGpuChannelHostFactory::instance(); | 553 BrowserGpuChannelHostFactory::instance(); |
| 574 scoped_refptr<GpuChannelHost> gpu_channel_host = factory->GetGpuChannel(); | 554 scoped_refptr<GpuChannelHost> gpu_channel_host = factory->GetGpuChannel(); |
| 575 if (gpu_channel_host.get() && !gpu_channel_host->IsLost()) { | 555 if (gpu_channel_host.get() && !gpu_channel_host->IsLost()) { |
| 576 context_provider = ContextProviderCommandBuffer::Create( | 556 context_provider = ContextProviderCommandBuffer::Create( |
| 577 CreateGpuProcessViewContext(gpu_channel_host, attrs, surface_id_), | 557 CreateGpuProcessViewContext(gpu_channel_host, attrs, surface_id_), |
| 578 "BrowserCompositor"); | 558 "BrowserCompositor"); |
| 579 } | 559 } |
| 580 if (!context_provider.get()) { | 560 if (!context_provider.get()) { |
| 581 LOG(ERROR) << "Failed to create 3D context for compositor."; | 561 LOG(ERROR) << "Failed to create 3D context for compositor."; |
| 562 LOG_IF(FATAL, ++num_successive_context_creation_failures_ >= 3) |
| 563 << "Too many context creation failures. Giving up... "; |
| 564 output_surface_task_for_host_.reset(new base::CancelableClosure(base::Bind( |
| 565 &CompositorImpl::RequestNewOutputSurface, base::Unretained(this)))); |
| 582 base::MessageLoopProxy::current()->PostTask( | 566 base::MessageLoopProxy::current()->PostTask( |
| 583 FROM_HERE, base::Bind(&CompositorImpl::RequestNewOutputSurface, | 567 FROM_HERE, output_surface_task_for_host_->callback()); |
| 584 weak_factory_.GetWeakPtr())); | |
| 585 return; | 568 return; |
| 586 } | 569 } |
| 587 | 570 |
| 588 scoped_ptr<cc::OutputSurface> real_output_surface( | 571 scoped_ptr<cc::OutputSurface> real_output_surface( |
| 589 new OutputSurfaceWithoutParent(context_provider, | 572 new OutputSurfaceWithoutParent(context_provider, |
| 590 weak_factory_.GetWeakPtr())); | 573 weak_factory_.GetWeakPtr())); |
| 591 | 574 |
| 592 cc::SurfaceManager* manager = GetSurfaceManager(); | 575 cc::SurfaceManager* manager = GetSurfaceManager(); |
| 593 if (manager) { | 576 if (manager) { |
| 594 display_client_.reset(new cc::OnscreenDisplayClient( | 577 display_client_.reset(new cc::OnscreenDisplayClient( |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 | 682 |
| 700 void CompositorImpl::SetNeedsAnimate() { | 683 void CompositorImpl::SetNeedsAnimate() { |
| 701 needs_animate_ = true; | 684 needs_animate_ = true; |
| 702 if (!host_) | 685 if (!host_) |
| 703 return; | 686 return; |
| 704 | 687 |
| 705 host_->SetNeedsAnimate(); | 688 host_->SetNeedsAnimate(); |
| 706 } | 689 } |
| 707 | 690 |
| 708 } // namespace content | 691 } // namespace content |
| OLD | NEW |