| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/compositor/delegated_frame_host.h" | 5 #include "content/browser/compositor/delegated_frame_host.h" |
| 6 | 6 |
| 7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "cc/output/compositor_frame.h" | 9 #include "cc/output/compositor_frame.h" |
| 10 #include "cc/output/compositor_frame_ack.h" | 10 #include "cc/output/compositor_frame_ack.h" |
| 11 #include "cc/output/copy_output_request.h" | 11 #include "cc/output/copy_output_request.h" |
| 12 #include "cc/resources/single_release_callback.h" | 12 #include "cc/resources/single_release_callback.h" |
| 13 #include "cc/resources/texture_mailbox.h" | 13 #include "cc/resources/texture_mailbox.h" |
| 14 #include "cc/surfaces/surface_factory.h" |
| 14 #include "content/browser/compositor/resize_lock.h" | 15 #include "content/browser/compositor/resize_lock.h" |
| 15 #include "content/common/gpu/client/gl_helper.h" | 16 #include "content/common/gpu/client/gl_helper.h" |
| 16 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" | 17 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
| 17 #include "content/public/common/content_switches.h" | 18 #include "content/public/common/content_switches.h" |
| 18 #include "media/base/video_frame.h" | 19 #include "media/base/video_frame.h" |
| 19 #include "media/base/video_util.h" | 20 #include "media/base/video_util.h" |
| 20 #include "skia/ext/image_operations.h" | 21 #include "skia/ext/image_operations.h" |
| 21 | 22 |
| 22 namespace content { | 23 namespace content { |
| 23 | 24 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 41 void DelegatedFrameHostClient::RequestCopyOfOutput( | 42 void DelegatedFrameHostClient::RequestCopyOfOutput( |
| 42 scoped_ptr<cc::CopyOutputRequest> request) { | 43 scoped_ptr<cc::CopyOutputRequest> request) { |
| 43 GetDelegatedFrameHost()->RequestCopyOfOutput(request.Pass()); | 44 GetDelegatedFrameHost()->RequestCopyOfOutput(request.Pass()); |
| 44 } | 45 } |
| 45 | 46 |
| 46 //////////////////////////////////////////////////////////////////////////////// | 47 //////////////////////////////////////////////////////////////////////////////// |
| 47 // DelegatedFrameHost | 48 // DelegatedFrameHost |
| 48 | 49 |
| 49 DelegatedFrameHost::DelegatedFrameHost(DelegatedFrameHostClient* client) | 50 DelegatedFrameHost::DelegatedFrameHost(DelegatedFrameHostClient* client) |
| 50 : client_(client), | 51 : client_(client), |
| 52 use_surfaces_(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 53 switches::kUseSurfaces)), |
| 51 last_output_surface_id_(0), | 54 last_output_surface_id_(0), |
| 52 pending_delegated_ack_count_(0), | 55 pending_delegated_ack_count_(0), |
| 53 skipped_frames_(false), | 56 skipped_frames_(false), |
| 54 can_lock_compositor_(YES_CAN_LOCK), | 57 can_lock_compositor_(YES_CAN_LOCK), |
| 55 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { | 58 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { |
| 56 ImageTransportFactory::GetInstance()->AddObserver(this); | 59 ImageTransportFactory::GetInstance()->AddObserver(this); |
| 57 } | 60 } |
| 58 | 61 |
| 59 void DelegatedFrameHost::WasShown() { | 62 void DelegatedFrameHost::WasShown() { |
| 60 delegated_frame_evictor_->SetVisible(true); | 63 delegated_frame_evictor_->SetVisible(true); |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 SendReturnedDelegatedResources(last_output_surface_id_); | 329 SendReturnedDelegatedResources(last_output_surface_id_); |
| 327 | 330 |
| 328 resource_collection_ = NULL; | 331 resource_collection_ = NULL; |
| 329 } | 332 } |
| 330 last_output_surface_id_ = output_surface_id; | 333 last_output_surface_id_ = output_surface_id; |
| 331 } | 334 } |
| 332 if (frame_size.IsEmpty()) { | 335 if (frame_size.IsEmpty()) { |
| 333 DCHECK(frame_data->resource_list.empty()); | 336 DCHECK(frame_data->resource_list.empty()); |
| 334 EvictDelegatedFrame(); | 337 EvictDelegatedFrame(); |
| 335 } else { | 338 } else { |
| 336 if (!resource_collection_) { | 339 if (use_surfaces_) { |
| 337 resource_collection_ = new cc::DelegatedFrameResourceCollection; | 340 if (!surface_factory_) { |
| 338 resource_collection_->SetClient(this); | 341 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
| 339 } | 342 cc::SurfaceManager* manager = factory->GetSurfaceManager(); |
| 340 // If the physical frame size changes, we need a new |frame_provider_|. If | 343 id_allocator_ = factory->CreateSurfaceIdAllocator(); |
| 341 // the physical frame size is the same, but the size in DIP changed, we | 344 surface_factory_ = |
| 342 // need to adjust the scale at which the frames will be drawn, and we do | 345 make_scoped_ptr(new cc::SurfaceFactory(manager, this)); |
| 343 // this by making a new |frame_provider_| also to ensure the scale change | 346 } |
| 344 // is presented in sync with the new frame content. | 347 if (surface_id_.is_null() || frame_size != current_surface_size_ || |
| 345 if (!frame_provider_.get() || frame_size != frame_provider_->frame_size() || | 348 frame_size_in_dip != current_frame_size_in_dip_) { |
| 346 frame_size_in_dip != current_frame_size_in_dip_) { | 349 if (!surface_id_.is_null()) |
| 347 frame_provider_ = new cc::DelegatedFrameProvider( | 350 surface_factory_->Destroy(surface_id_); |
| 348 resource_collection_.get(), frame_data.Pass()); | 351 surface_id_ = id_allocator_->GenerateId(); |
| 349 client_->GetLayer()->SetShowDelegatedContent(frame_provider_.get(), | 352 surface_factory_->Create(surface_id_, frame_size); |
| 350 frame_size_in_dip); | 353 client_->GetLayer()->SetShowSurface(surface_id_, frame_size_in_dip); |
| 354 current_surface_size_ = frame_size; |
| 355 } |
| 356 scoped_ptr<cc::CompositorFrame> compositor_frame = |
| 357 make_scoped_ptr(new cc::CompositorFrame()); |
| 358 compositor_frame->delegated_frame_data = frame_data.Pass(); |
| 359 surface_factory_->SubmitFrame(surface_id_, compositor_frame.Pass()); |
| 351 } else { | 360 } else { |
| 352 frame_provider_->SetFrameData(frame_data.Pass()); | 361 if (!resource_collection_) { |
| 362 resource_collection_ = new cc::DelegatedFrameResourceCollection; |
| 363 resource_collection_->SetClient(this); |
| 364 } |
| 365 // If the physical frame size changes, we need a new |frame_provider_|. If |
| 366 // the physical frame size is the same, but the size in DIP changed, we |
| 367 // need to adjust the scale at which the frames will be drawn, and we do |
| 368 // this by making a new |frame_provider_| also to ensure the scale change |
| 369 // is presented in sync with the new frame content. |
| 370 if (!frame_provider_.get() || |
| 371 frame_size != frame_provider_->frame_size() || |
| 372 frame_size_in_dip != current_frame_size_in_dip_) { |
| 373 frame_provider_ = new cc::DelegatedFrameProvider( |
| 374 resource_collection_.get(), frame_data.Pass()); |
| 375 client_->GetLayer()->SetShowDelegatedContent(frame_provider_.get(), |
| 376 frame_size_in_dip); |
| 377 } else { |
| 378 frame_provider_->SetFrameData(frame_data.Pass()); |
| 379 } |
| 353 } | 380 } |
| 354 } | 381 } |
| 355 released_front_lock_ = NULL; | 382 released_front_lock_ = NULL; |
| 356 current_frame_size_in_dip_ = frame_size_in_dip; | 383 current_frame_size_in_dip_ = frame_size_in_dip; |
| 357 CheckResizeLock(); | 384 CheckResizeLock(); |
| 358 | 385 |
| 359 client_->SchedulePaintInRect(damage_rect_in_dip); | 386 client_->SchedulePaintInRect(damage_rect_in_dip); |
| 360 | 387 |
| 361 pending_delegated_ack_count_++; | 388 pending_delegated_ack_count_++; |
| 362 | 389 |
| 363 ui::Compositor* compositor = client_->GetCompositor(); | 390 ui::Compositor* compositor = client_->GetCompositor(); |
| 364 if (!compositor) { | 391 if (!compositor) { |
| 365 SendDelegatedFrameAck(output_surface_id); | 392 SendDelegatedFrameAck(output_surface_id); |
| 366 } else { | 393 } else { |
| 367 std::vector<ui::LatencyInfo>::const_iterator it; | 394 std::vector<ui::LatencyInfo>::const_iterator it; |
| 368 for (it = latency_info.begin(); it != latency_info.end(); ++it) | 395 for (it = latency_info.begin(); it != latency_info.end(); ++it) |
| 369 compositor->SetLatencyInfo(*it); | 396 compositor->SetLatencyInfo(*it); |
| 370 // If we've previously skipped any latency infos add them. | 397 // If we've previously skipped any latency infos add them. |
| 371 for (it = skipped_latency_info_list_.begin(); | 398 for (it = skipped_latency_info_list_.begin(); |
| 372 it != skipped_latency_info_list_.end(); | 399 it != skipped_latency_info_list_.end(); |
| 373 ++it) | 400 ++it) |
| 374 compositor->SetLatencyInfo(*it); | 401 compositor->SetLatencyInfo(*it); |
| 375 skipped_latency_info_list_.clear(); | 402 skipped_latency_info_list_.clear(); |
| 376 AddOnCommitCallbackAndDisableLocks( | 403 AddOnCommitCallbackAndDisableLocks( |
| 377 base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, | 404 base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, |
| 378 AsWeakPtr(), | 405 AsWeakPtr(), |
| 379 output_surface_id)); | 406 output_surface_id)); |
| 380 } | 407 } |
| 381 DidReceiveFrameFromRenderer(); | 408 DidReceiveFrameFromRenderer(); |
| 382 if (frame_provider_.get()) | 409 if (frame_provider_.get() || !surface_id_.is_null()) |
| 383 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); | 410 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); |
| 384 // Note: the frame may have been evicted immediately. | 411 // Note: the frame may have been evicted immediately. |
| 385 } | 412 } |
| 386 | 413 |
| 387 void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { | 414 void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { |
| 388 RenderWidgetHostImpl* host = client_->GetHost(); | 415 RenderWidgetHostImpl* host = client_->GetHost(); |
| 389 cc::CompositorFrameAck ack; | 416 cc::CompositorFrameAck ack; |
| 417 if (!surface_returned_resources_.empty()) |
| 418 ack.resources.swap(surface_returned_resources_); |
| 390 if (resource_collection_) | 419 if (resource_collection_) |
| 391 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); | 420 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); |
| 392 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host->GetRoutingID(), | 421 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host->GetRoutingID(), |
| 393 output_surface_id, | 422 output_surface_id, |
| 394 host->GetProcess()->GetID(), | 423 host->GetProcess()->GetID(), |
| 395 ack); | 424 ack); |
| 396 DCHECK_GT(pending_delegated_ack_count_, 0); | 425 DCHECK_GT(pending_delegated_ack_count_, 0); |
| 397 pending_delegated_ack_count_--; | 426 pending_delegated_ack_count_--; |
| 398 } | 427 } |
| 399 | 428 |
| 400 void DelegatedFrameHost::UnusedResourcesAreAvailable() { | 429 void DelegatedFrameHost::UnusedResourcesAreAvailable() { |
| 401 if (pending_delegated_ack_count_) | 430 if (pending_delegated_ack_count_) |
| 402 return; | 431 return; |
| 403 | 432 |
| 404 SendReturnedDelegatedResources(last_output_surface_id_); | 433 SendReturnedDelegatedResources(last_output_surface_id_); |
| 405 } | 434 } |
| 406 | 435 |
| 407 void DelegatedFrameHost::SendReturnedDelegatedResources( | 436 void DelegatedFrameHost::SendReturnedDelegatedResources( |
| 408 uint32 output_surface_id) { | 437 uint32 output_surface_id) { |
| 409 RenderWidgetHostImpl* host = client_->GetHost(); | 438 RenderWidgetHostImpl* host = client_->GetHost(); |
| 410 DCHECK(resource_collection_); | |
| 411 | 439 |
| 412 cc::CompositorFrameAck ack; | 440 cc::CompositorFrameAck ack; |
| 413 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); | 441 if (!surface_returned_resources_.empty()) { |
| 442 ack.resources.swap(surface_returned_resources_); |
| 443 } else { |
| 444 DCHECK(resource_collection_); |
| 445 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); |
| 446 } |
| 414 DCHECK(!ack.resources.empty()); | 447 DCHECK(!ack.resources.empty()); |
| 415 | 448 |
| 416 RenderWidgetHostImpl::SendReclaimCompositorResources( | 449 RenderWidgetHostImpl::SendReclaimCompositorResources( |
| 417 host->GetRoutingID(), | 450 host->GetRoutingID(), |
| 418 output_surface_id, | 451 output_surface_id, |
| 419 host->GetProcess()->GetID(), | 452 host->GetProcess()->GetID(), |
| 420 ack); | 453 ack); |
| 421 } | 454 } |
| 422 | 455 |
| 456 void DelegatedFrameHost::ReturnResources( |
| 457 const cc::ReturnedResourceArray& resources) { |
| 458 if (resources.empty()) |
| 459 return; |
| 460 std::copy(resources.begin(), |
| 461 resources.end(), |
| 462 std::back_inserter(surface_returned_resources_)); |
| 463 if (!pending_delegated_ack_count_) |
| 464 SendReturnedDelegatedResources(last_output_surface_id_); |
| 465 } |
| 466 |
| 423 void DelegatedFrameHost::EvictDelegatedFrame() { | 467 void DelegatedFrameHost::EvictDelegatedFrame() { |
| 424 client_->GetLayer()->SetShowPaintedContent(); | 468 client_->GetLayer()->SetShowPaintedContent(); |
| 425 frame_provider_ = NULL; | 469 frame_provider_ = NULL; |
| 470 if (!surface_id_.is_null()) { |
| 471 surface_factory_->Destroy(surface_id_); |
| 472 surface_id_ = cc::SurfaceId(); |
| 473 } |
| 426 delegated_frame_evictor_->DiscardedFrame(); | 474 delegated_frame_evictor_->DiscardedFrame(); |
| 427 } | 475 } |
| 428 | 476 |
| 429 // static | 477 // static |
| 430 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( | 478 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( |
| 431 const gfx::Size& dst_size_in_pixel, | 479 const gfx::Size& dst_size_in_pixel, |
| 432 const SkColorType color_type, | 480 const SkColorType color_type, |
| 433 const base::Callback<void(bool, const SkBitmap&)>& callback, | 481 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 434 scoped_ptr<cc::CopyOutputResult> result) { | 482 scoped_ptr<cc::CopyOutputResult> result) { |
| 435 if (result->IsEmpty() || result->size().IsEmpty()) { | 483 if (result->IsEmpty() || result->size().IsEmpty()) { |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 RenderWidgetHostImpl* host = client_->GetHost(); | 801 RenderWidgetHostImpl* host = client_->GetHost(); |
| 754 if (client_->IsVisible()) | 802 if (client_->IsVisible()) |
| 755 host->UpdateVSyncParameters(timebase, interval); | 803 host->UpdateVSyncParameters(timebase, interval); |
| 756 } | 804 } |
| 757 | 805 |
| 758 //////////////////////////////////////////////////////////////////////////////// | 806 //////////////////////////////////////////////////////////////////////////////// |
| 759 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: | 807 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: |
| 760 | 808 |
| 761 void DelegatedFrameHost::OnLostResources() { | 809 void DelegatedFrameHost::OnLostResources() { |
| 762 RenderWidgetHostImpl* host = client_->GetHost(); | 810 RenderWidgetHostImpl* host = client_->GetHost(); |
| 763 if (frame_provider_.get()) | 811 if (frame_provider_.get() || !surface_id_.is_null()) |
| 764 EvictDelegatedFrame(); | 812 EvictDelegatedFrame(); |
| 765 idle_frame_subscriber_textures_.clear(); | 813 idle_frame_subscriber_textures_.clear(); |
| 766 yuv_readback_pipeline_.reset(); | 814 yuv_readback_pipeline_.reset(); |
| 767 | 815 |
| 768 host->ScheduleComposite(); | 816 host->ScheduleComposite(); |
| 769 } | 817 } |
| 770 | 818 |
| 771 //////////////////////////////////////////////////////////////////////////////// | 819 //////////////////////////////////////////////////////////////////////////////// |
| 772 // DelegatedFrameHost, private: | 820 // DelegatedFrameHost, private: |
| 773 | 821 |
| 774 DelegatedFrameHost::~DelegatedFrameHost() { | 822 DelegatedFrameHost::~DelegatedFrameHost() { |
| 775 ImageTransportFactory::GetInstance()->RemoveObserver(this); | 823 ImageTransportFactory::GetInstance()->RemoveObserver(this); |
| 776 | 824 |
| 825 if (!surface_id_.is_null()) |
| 826 surface_factory_->Destroy(surface_id_); |
| 777 if (resource_collection_.get()) | 827 if (resource_collection_.get()) |
| 778 resource_collection_->SetClient(NULL); | 828 resource_collection_->SetClient(NULL); |
| 779 | 829 |
| 780 DCHECK(!vsync_manager_); | 830 DCHECK(!vsync_manager_); |
| 781 } | 831 } |
| 782 | 832 |
| 783 void DelegatedFrameHost::RunOnCommitCallbacks() { | 833 void DelegatedFrameHost::RunOnCommitCallbacks() { |
| 784 for (std::vector<base::Closure>::const_iterator | 834 for (std::vector<base::Closure>::const_iterator |
| 785 it = on_compositing_did_commit_callbacks_.begin(); | 835 it = on_compositing_did_commit_callbacks_.begin(); |
| 786 it != on_compositing_did_commit_callbacks_.end(); ++it) { | 836 it != on_compositing_did_commit_callbacks_.end(); ++it) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 if (compositor && compositor->HasObserver(this)) | 868 if (compositor && compositor->HasObserver(this)) |
| 819 compositor->RemoveObserver(this); | 869 compositor->RemoveObserver(this); |
| 820 | 870 |
| 821 if (vsync_manager_) { | 871 if (vsync_manager_) { |
| 822 vsync_manager_->RemoveObserver(this); | 872 vsync_manager_->RemoveObserver(this); |
| 823 vsync_manager_ = NULL; | 873 vsync_manager_ = NULL; |
| 824 } | 874 } |
| 825 } | 875 } |
| 826 | 876 |
| 827 void DelegatedFrameHost::LockResources() { | 877 void DelegatedFrameHost::LockResources() { |
| 828 DCHECK(frame_provider_); | 878 DCHECK(frame_provider_ || !surface_id_.is_null()); |
| 829 delegated_frame_evictor_->LockFrame(); | 879 delegated_frame_evictor_->LockFrame(); |
| 830 } | 880 } |
| 831 | 881 |
| 832 void DelegatedFrameHost::UnlockResources() { | 882 void DelegatedFrameHost::UnlockResources() { |
| 833 DCHECK(frame_provider_); | 883 DCHECK(frame_provider_ || !surface_id_.is_null()); |
| 834 delegated_frame_evictor_->UnlockFrame(); | 884 delegated_frame_evictor_->UnlockFrame(); |
| 835 } | 885 } |
| 836 | 886 |
| 837 //////////////////////////////////////////////////////////////////////////////// | 887 //////////////////////////////////////////////////////////////////////////////// |
| 838 // DelegatedFrameHost, ui::LayerOwnerDelegate implementation: | 888 // DelegatedFrameHost, ui::LayerOwnerDelegate implementation: |
| 839 | 889 |
| 840 void DelegatedFrameHost::OnLayerRecreated(ui::Layer* old_layer, | 890 void DelegatedFrameHost::OnLayerRecreated(ui::Layer* old_layer, |
| 841 ui::Layer* new_layer) { | 891 ui::Layer* new_layer) { |
| 842 // The new_layer is the one that will be used by our Window, so that's the one | 892 // The new_layer is the one that will be used by our Window, so that's the one |
| 843 // that should keep our frame. old_layer will be returned to the | 893 // that should keep our frame. old_layer will be returned to the |
| 844 // RecreateLayer caller, and should have a copy. | 894 // RecreateLayer caller, and should have a copy. |
| 845 if (frame_provider_.get()) { | 895 if (frame_provider_.get()) { |
| 846 new_layer->SetShowDelegatedContent(frame_provider_.get(), | 896 new_layer->SetShowDelegatedContent(frame_provider_.get(), |
| 847 current_frame_size_in_dip_); | 897 current_frame_size_in_dip_); |
| 848 } | 898 } |
| 899 if (!surface_id_.is_null()) { |
| 900 new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); |
| 901 } |
| 849 } | 902 } |
| 850 | 903 |
| 851 } // namespace content | 904 } // namespace content |
| 852 | 905 |
| OLD | NEW |