diff options
author | jbauman <jbauman@chromium.org> | 2015-03-12 14:09:31 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-12 21:10:19 +0000 |
commit | ecee08ee7b6facd3c8ae2257abc9d83a19be705a (patch) | |
tree | 16c8e46769c41afccc46ca326a171ee5f6e74bc4 /content | |
parent | 5235011aa967a55221029e0558b8b7ce86bc88a4 (diff) | |
download | chromium_src-ecee08ee7b6facd3c8ae2257abc9d83a19be705a.zip chromium_src-ecee08ee7b6facd3c8ae2257abc9d83a19be705a.tar.gz chromium_src-ecee08ee7b6facd3c8ae2257abc9d83a19be705a.tar.bz2 |
Put renderer contents in separate Surface on Android
When Surfaces are enabled on Android (still disabled by default) put the renderer contents into its own Surface instead of using a delegated layer on the browser compositor. This causes it to be scheduled and aggregated directly through the Display, which should reduce CPU usage and latency.
BUG=334090,449319
Review URL: https://codereview.chromium.org/725943003
Cr-Commit-Position: refs/heads/master@{#320372}
Diffstat (limited to 'content')
4 files changed, 193 insertions, 58 deletions
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 65cb728..010f8e2 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc @@ -134,11 +134,6 @@ bool g_use_surface_manager = false; base::LazyInstance<cc::SurfaceManager> g_surface_manager = LAZY_INSTANCE_INITIALIZER; -cc::SurfaceManager* GetSurfaceManager() { - if (!g_use_surface_manager) - return nullptr; - return g_surface_manager.Pointer(); -} int g_surface_id_namespace = 0; @@ -162,12 +157,23 @@ bool CompositorImpl::IsInitialized() { return g_initialized; } +// static +cc::SurfaceManager* CompositorImpl::GetSurfaceManager() { + if (!g_use_surface_manager) + return nullptr; + return g_surface_manager.Pointer(); +} + +// static +scoped_ptr<cc::SurfaceIdAllocator> CompositorImpl::CreateSurfaceIdAllocator() { + return make_scoped_ptr(new cc::SurfaceIdAllocator(++g_surface_id_namespace)); +} + CompositorImpl::CompositorImpl(CompositorClient* client, gfx::NativeWindow root_window) : root_layer_(cc::Layer::Create()), resource_manager_(&ui_resource_provider_), - surface_id_allocator_( - new cc::SurfaceIdAllocator(++g_surface_id_namespace)), + surface_id_allocator_(CreateSurfaceIdAllocator()), has_transparent_background_(false), device_scale_factor_(1), window_(NULL), diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index 568dfd1..672a566 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h @@ -30,6 +30,7 @@ class Layer; class LayerTreeHost; class OnscreenDisplayClient; class SurfaceIdAllocator; +class SurfaceManager; } namespace content { @@ -49,6 +50,9 @@ class CONTENT_EXPORT CompositorImpl static bool IsInitialized(); + static cc::SurfaceManager* GetSurfaceManager(); + static scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator(); + void PopulateGpuCapabilities(gpu::Capabilities gpu_capabilities); private: diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 339fec9..d61000b7 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc @@ -21,12 +21,17 @@ #include "cc/layers/delegated_frame_provider.h" #include "cc/layers/delegated_renderer_layer.h" #include "cc/layers/layer.h" +#include "cc/layers/surface_layer.h" #include "cc/output/compositor_frame.h" #include "cc/output/compositor_frame_ack.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" #include "cc/output/viewport_selection_bound.h" #include "cc/resources/single_release_callback.h" +#include "cc/surfaces/surface.h" +#include "cc/surfaces/surface_factory.h" +#include "cc/surfaces/surface_id_allocator.h" +#include "cc/surfaces/surface_manager.h" #include "cc/trees/layer_tree_host.h" #include "content/browser/accessibility/browser_accessibility_manager_android.h" #include "content/browser/android/composited_touch_handle_drawable.h" @@ -87,6 +92,24 @@ namespace content { namespace { +void SatisfyCallback(cc::SurfaceManager* manager, + cc::SurfaceSequence sequence) { + std::vector<uint32_t> sequences; + sequences.push_back(sequence.sequence); + manager->DidSatisfySequences(sequence.id_namespace, &sequences); +} + +void RequireCallback(cc::SurfaceManager* manager, + cc::SurfaceId id, + cc::SurfaceSequence sequence) { + cc::Surface* surface = manager->GetSurfaceForId(id); + if (!surface) { + LOG(ERROR) << "Attempting to require callback on nonexistent surface"; + return; + } + surface->AddDestructionDependency(sequence); +} + const int kUndefinedOutputSurfaceId = -1; static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime"; @@ -380,6 +403,8 @@ RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() { DCHECK(readbacks_waiting_for_frame_.empty()); if (resource_collection_.get()) resource_collection_->SetClient(NULL); + DCHECK(!surface_factory_); + DCHECK(surface_id_.is_null()); } @@ -477,12 +502,22 @@ void RenderWidgetHostViewAndroid::GetScaledContentBitmap( src_subrect, dst_size, result_callback, color_type); } -scoped_refptr<cc::DelegatedRendererLayer> -RenderWidgetHostViewAndroid::CreateDelegatedLayerForFrameProvider() const { - DCHECK(frame_provider_.get()); - - scoped_refptr<cc::DelegatedRendererLayer> delegated_layer = - cc::DelegatedRendererLayer::Create(frame_provider_); +scoped_refptr<cc::Layer> RenderWidgetHostViewAndroid::CreateDelegatedLayer() + const { + scoped_refptr<cc::Layer> delegated_layer; + if (!surface_id_.is_null()) { + cc::SurfaceManager* manager = CompositorImpl::GetSurfaceManager(); + DCHECK(manager); + // manager must outlive compositors using it. + scoped_refptr<cc::SurfaceLayer> surface_layer = cc::SurfaceLayer::Create( + base::Bind(&SatisfyCallback, base::Unretained(manager)), + base::Bind(&RequireCallback, base::Unretained(manager))); + surface_layer->SetSurfaceId(surface_id_, 1.f, texture_size_in_layer_); + delegated_layer = surface_layer; + } else { + DCHECK(frame_provider_.get()); + delegated_layer = cc::DelegatedRendererLayer::Create(frame_provider_); + } delegated_layer->SetBounds(content_size_in_layer_); delegated_layer->SetIsDrawable(true); delegated_layer->SetContentsOpaque(true); @@ -596,7 +631,7 @@ void RenderWidgetHostViewAndroid::Hide() { // we need to cancel all requests AbortPendingReadbackRequests(); - RunAckCallbacks(); + RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED); if (!host_ || host_->is_hidden()) return; @@ -680,7 +715,7 @@ void RenderWidgetHostViewAndroid::ReleaseLocksOnSurface() { while (locks_on_frame_count_ > 0) { UnlockCompositingSurface(); } - RunAckCallbacks(); + RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED); } gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const { @@ -885,6 +920,13 @@ void RenderWidgetHostViewAndroid::Destroy() { RemoveLayers(); SetContentViewCore(NULL); + if (!surface_id_.is_null()) { + DCHECK(surface_factory_.get()); + surface_factory_->Destroy(surface_id_); + surface_id_ = cc::SurfaceId(); + } + surface_factory_.reset(); + // The RenderWidgetHost's destruction led here, so don't call it. host_ = NULL; @@ -975,13 +1017,13 @@ void RenderWidgetHostViewAndroid::CopyFromCompositingSurface( ui::WindowAndroidCompositor* compositor = content_view_core_->GetWindowAndroid()->GetCompositor(); DCHECK(compositor); - DCHECK(frame_provider_.get()); - scoped_refptr<cc::DelegatedRendererLayer> delegated_layer = - CreateDelegatedLayerForFrameProvider(); - delegated_layer->SetHideLayerAndSubtree(true); - compositor->AttachLayerForReadback(delegated_layer); + DCHECK(frame_provider_.get() || !surface_id_.is_null()); + scoped_refptr<cc::Layer> layer = CreateDelegatedLayer(); + DCHECK(layer); + layer->SetHideLayerAndSubtree(true); + compositor->AttachLayerForReadback(layer); - readback_layer = delegated_layer; + readback_layer = layer; request = cc::CopyOutputRequest::CreateRequest( base::Bind(&RenderWidgetHostViewAndroid:: PrepareTextureCopyOutputResultForDelegatedReadback, @@ -1025,6 +1067,8 @@ void RenderWidgetHostViewAndroid::SendDelegatedFrameAck( uint32 output_surface_id) { DCHECK(host_); cc::CompositorFrameAck ack; + if (!surface_returned_resources_.empty()) + ack.resources.swap(surface_returned_resources_); if (resource_collection_.get()) resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); host_->Send(new ViewMsg_SwapCompositorFrameAck(host_->GetRoutingID(), @@ -1033,60 +1077,101 @@ void RenderWidgetHostViewAndroid::SendDelegatedFrameAck( void RenderWidgetHostViewAndroid::SendReturnedDelegatedResources( uint32 output_surface_id) { - DCHECK(resource_collection_.get()); - + DCHECK(host_); cc::CompositorFrameAck ack; - resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); - DCHECK(!ack.resources.empty()); + if (!surface_returned_resources_.empty()) { + ack.resources.swap(surface_returned_resources_); + } else { + DCHECK(resource_collection_.get()); + resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); + } host_->Send(new ViewMsg_ReclaimCompositorResources(host_->GetRoutingID(), output_surface_id, ack)); } void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() { + DCHECK(surface_id_.is_null()); if (ack_callbacks_.size()) return; SendReturnedDelegatedResources(last_output_surface_id_); } +void RenderWidgetHostViewAndroid::ReturnResources( + const cc::ReturnedResourceArray& resources) { + if (resources.empty()) + return; + std::copy(resources.begin(), resources.end(), + std::back_inserter(surface_returned_resources_)); + if (!ack_callbacks_.size()) + SendReturnedDelegatedResources(last_output_surface_id_); +} + void RenderWidgetHostViewAndroid::DestroyDelegatedContent() { RemoveLayers(); frame_provider_ = NULL; + if (!surface_id_.is_null()) { + DCHECK(surface_factory_.get()); + surface_factory_->Destroy(surface_id_); + surface_id_ = cc::SurfaceId(); + } layer_ = NULL; // This gets called when ever any eviction, loosing resources, swapping // problems are encountered and so we abort any pending readbacks here. AbortPendingReadbackRequests(); } -void RenderWidgetHostViewAndroid::SwapDelegatedFrame( - uint32 output_surface_id, - scoped_ptr<cc::DelegatedFrameData> frame_data) { - bool has_content = !texture_size_in_layer_.IsEmpty(); +void RenderWidgetHostViewAndroid::CheckOutputSurfaceChanged( + uint32 output_surface_id) { + if (output_surface_id == last_output_surface_id_) + return; + // Drop the cc::DelegatedFrameResourceCollection so that we will not return + // any resources from the old output surface with the new output surface id. + if (resource_collection_.get()) { + resource_collection_->SetClient(NULL); + if (resource_collection_->LoseAllResources()) + SendReturnedDelegatedResources(last_output_surface_id_); + resource_collection_ = NULL; + } + DestroyDelegatedContent(); + surface_factory_.reset(); + if (!surface_returned_resources_.empty()) + SendReturnedDelegatedResources(last_output_surface_id_); - if (output_surface_id != last_output_surface_id_) { - // Drop the cc::DelegatedFrameResourceCollection so that we will not return - // any resources from the old output surface with the new output surface id. - if (resource_collection_.get()) { - resource_collection_->SetClient(NULL); - if (resource_collection_->LoseAllResources()) - SendReturnedDelegatedResources(last_output_surface_id_); - resource_collection_ = NULL; - } - DestroyDelegatedContent(); + last_output_surface_id_ = output_surface_id; +} - last_output_surface_id_ = output_surface_id; - } +void RenderWidgetHostViewAndroid::SubmitFrame( + scoped_ptr<cc::DelegatedFrameData> frame_data) { + cc::SurfaceManager* manager = CompositorImpl::GetSurfaceManager(); + if (manager) { + if (!surface_factory_) { + id_allocator_ = CompositorImpl::CreateSurfaceIdAllocator(); + surface_factory_ = make_scoped_ptr(new cc::SurfaceFactory(manager, this)); + } + if (surface_id_.is_null() || + texture_size_in_layer_ != current_surface_size_) { + RemoveLayers(); + if (!surface_id_.is_null()) + surface_factory_->Destroy(surface_id_); + surface_id_ = id_allocator_->GenerateId(); + surface_factory_->Create(surface_id_); + layer_ = CreateDelegatedLayer(); - // DelegatedRendererLayerImpl applies the inverse device_scale_factor of the - // renderer frame, assuming that the browser compositor will scale - // it back up to device scale. But on Android we put our browser layers in - // physical pixels and set our browser CC device_scale_factor to 1, so this - // suppresses the transform. This line may need to be removed when fixing - // http://crbug.com/384134 or http://crbug.com/310763 - frame_data->device_scale_factor = 1.0f; + DCHECK(layer_); - if (!has_content) { - DestroyDelegatedContent(); + current_surface_size_ = texture_size_in_layer_; + AttachLayers(); + } + scoped_ptr<cc::CompositorFrame> compositor_frame = + make_scoped_ptr(new cc::CompositorFrame()); + compositor_frame->delegated_frame_data = frame_data.Pass(); + + cc::SurfaceFactory::DrawCallback ack_callback = + base::Bind(&RenderWidgetHostViewAndroid::RunAckCallbacks, + weak_ptr_factory_.GetWeakPtr()); + surface_factory_->SubmitFrame(surface_id_, compositor_frame.Pass(), + ack_callback); } else { if (!resource_collection_.get()) { resource_collection_ = new cc::DelegatedFrameResourceCollection; @@ -1103,6 +1188,27 @@ void RenderWidgetHostViewAndroid::SwapDelegatedFrame( frame_provider_->SetFrameData(frame_data.Pass()); } } +} + +void RenderWidgetHostViewAndroid::SwapDelegatedFrame( + uint32 output_surface_id, + scoped_ptr<cc::DelegatedFrameData> frame_data) { + CheckOutputSurfaceChanged(output_surface_id); + bool has_content = !texture_size_in_layer_.IsEmpty(); + + // DelegatedRendererLayerImpl applies the inverse device_scale_factor of the + // renderer frame, assuming that the browser compositor will scale + // it back up to device scale. But on Android we put our browser layers in + // physical pixels and set our browser CC device_scale_factor to 1, so this + // suppresses the transform. This line may need to be removed when fixing + // http://crbug.com/384134 or http://crbug.com/310763 + frame_data->device_scale_factor = 1.0f; + + if (!has_content) { + DestroyDelegatedContent(); + } else { + SubmitFrame(frame_data.Pass()); + } if (layer_.get()) { layer_->SetIsDrawable(true); @@ -1118,7 +1224,7 @@ void RenderWidgetHostViewAndroid::SwapDelegatedFrame( ack_callbacks_.push(ack_callback); if (host_->is_hidden()) - RunAckCallbacks(); + RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED); } void RenderWidgetHostViewAndroid::ComputeContentsSize( @@ -1735,7 +1841,8 @@ void RenderWidgetHostViewAndroid::SetContentViewCore( } } -void RenderWidgetHostViewAndroid::RunAckCallbacks() { +void RenderWidgetHostViewAndroid::RunAckCallbacks( + cc::SurfaceDrawStatus status) { while (!ack_callbacks_.empty()) { ack_callbacks_.front().Run(); ack_callbacks_.pop(); @@ -1758,7 +1865,7 @@ void RenderWidgetHostViewAndroid::OnGestureEvent( } void RenderWidgetHostViewAndroid::OnCompositingDidCommit() { - RunAckCallbacks(); + RunAckCallbacks(cc::SurfaceDrawStatus::DRAWN); } void RenderWidgetHostViewAndroid::OnAttachCompositor() { @@ -1770,7 +1877,7 @@ void RenderWidgetHostViewAndroid::OnAttachCompositor() { void RenderWidgetHostViewAndroid::OnDetachCompositor() { DCHECK(content_view_core_); DCHECK(using_browser_compositor_); - RunAckCallbacks(); + RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED); overscroll_controller_.reset(); } diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index dd59242..e1cf270 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h @@ -16,6 +16,8 @@ #include "base/process/process.h" #include "cc/layers/delegated_frame_resource_collection.h" #include "cc/output/begin_frame_args.h" +#include "cc/surfaces/surface_factory_client.h" +#include "cc/surfaces/surface_id.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/renderer_host/delegated_frame_evictor.h" #include "content/browser/renderer_host/ime_adapter_android.h" @@ -39,6 +41,9 @@ class CopyOutputResult; class DelegatedFrameProvider; class DelegatedRendererLayer; class Layer; +class SurfaceFactory; +class SurfaceIdAllocator; +enum class SurfaceDrawStatus; } namespace blink { @@ -81,6 +86,7 @@ class ReadbackRequest { class CONTENT_EXPORT RenderWidgetHostViewAndroid : public RenderWidgetHostViewBase, public cc::DelegatedFrameResourceCollectionClient, + public cc::SurfaceFactoryClient, public ui::GestureProviderClient, public ui::WindowAndroidObserver, public DelegatedFrameEvictorClient, @@ -179,6 +185,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid // cc::DelegatedFrameResourceCollectionClient implementation. void UnusedResourcesAreAvailable() override; + // cc::SurfaceFactoryClient implementation. + void ReturnResources(const cc::ReturnedResourceArray& resources) override; + // ui::GestureProviderClient implementation. void OnGestureEvent(const ui::GestureEventData& gesture) override; @@ -243,8 +252,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid gfx::Rect src_subrect, ReadbackRequestCallback& result_callback); - scoped_refptr<cc::DelegatedRendererLayer> - CreateDelegatedLayerForFrameProvider() const; + scoped_refptr<cc::Layer> CreateDelegatedLayer() const; bool HasValidFrame() const; @@ -268,9 +276,11 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid static void OnContextLost(); private: - void RunAckCallbacks(); + void RunAckCallbacks(cc::SurfaceDrawStatus status); void DestroyDelegatedContent(); + void CheckOutputSurfaceChanged(uint32 output_surface_id); + void SubmitFrame(scoped_ptr<cc::DelegatedFrameData> frame_data); void SwapDelegatedFrame(uint32 output_surface_id, scoped_ptr<cc::DelegatedFrameData> frame_data); void SendDelegatedFrameAck(uint32 output_surface_id); @@ -336,6 +346,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid // The model object. RenderWidgetHostImpl* host_; + bool use_surfaces_; + // Used to control action dispatch at the next |OnVSync()| call. uint32 outstanding_vsync_requests_; @@ -351,7 +363,13 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection_; scoped_refptr<cc::DelegatedFrameProvider> frame_provider_; - scoped_refptr<cc::DelegatedRendererLayer> layer_; + scoped_refptr<cc::Layer> layer_; + + scoped_ptr<cc::SurfaceIdAllocator> id_allocator_; + scoped_ptr<cc::SurfaceFactory> surface_factory_; + cc::SurfaceId surface_id_; + gfx::Size current_surface_size_; + cc::ReturnedResourceArray surface_returned_resources_; // The most recent texture size that was pushed to the texture layer. gfx::Size texture_size_in_layer_; |