summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorjbauman <jbauman@chromium.org>2015-03-12 14:09:31 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-12 21:10:19 +0000
commitecee08ee7b6facd3c8ae2257abc9d83a19be705a (patch)
tree16c8e46769c41afccc46ca326a171ee5f6e74bc4 /content
parent5235011aa967a55221029e0558b8b7ce86bc88a4 (diff)
downloadchromium_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')
-rw-r--r--content/browser/renderer_host/compositor_impl_android.cc20
-rw-r--r--content/browser/renderer_host/compositor_impl_android.h4
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc201
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.h26
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_;