Commit ca2c3ea5 authored by jbauman@chromium.org's avatar jbauman@chromium.org

Use Surfaces to hold delegated renderer contents.

With --use-surfaces, the frame data from a renderer is now put into a surface, and a SurfaceLayer is put in the browser compositor's layer tree. We still rely on the browser compositor redrawing to schedule a redraw of the entire surface tree.

Review URL: https://codereview.chromium.org/417943004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285786 0039d316-1c4b-4281-b951-d872f2087c98
parent f3b895e5
......@@ -11,6 +11,7 @@
#include "cc/output/copy_output_request.h"
#include "cc/resources/single_release_callback.h"
#include "cc/resources/texture_mailbox.h"
#include "cc/surfaces/surface_factory.h"
#include "content/browser/compositor/resize_lock.h"
#include "content/common/gpu/client/gl_helper.h"
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
......@@ -48,6 +49,8 @@ void DelegatedFrameHostClient::RequestCopyOfOutput(
DelegatedFrameHost::DelegatedFrameHost(DelegatedFrameHostClient* client)
: client_(client),
use_surfaces_(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseSurfaces)),
last_output_surface_id_(0),
pending_delegated_ack_count_(0),
skipped_frames_(false),
......@@ -333,23 +336,47 @@ void DelegatedFrameHost::SwapDelegatedFrame(
DCHECK(frame_data->resource_list.empty());
EvictDelegatedFrame();
} else {
if (!resource_collection_) {
resource_collection_ = new cc::DelegatedFrameResourceCollection;
resource_collection_->SetClient(this);
}
// If the physical frame size changes, we need a new |frame_provider_|. If
// the physical frame size is the same, but the size in DIP changed, we
// need to adjust the scale at which the frames will be drawn, and we do
// this by making a new |frame_provider_| also to ensure the scale change
// is presented in sync with the new frame content.
if (!frame_provider_.get() || frame_size != frame_provider_->frame_size() ||
frame_size_in_dip != current_frame_size_in_dip_) {
frame_provider_ = new cc::DelegatedFrameProvider(
resource_collection_.get(), frame_data.Pass());
client_->GetLayer()->SetShowDelegatedContent(frame_provider_.get(),
frame_size_in_dip);
if (use_surfaces_) {
if (!surface_factory_) {
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
cc::SurfaceManager* manager = factory->GetSurfaceManager();
id_allocator_ = factory->CreateSurfaceIdAllocator();
surface_factory_ =
make_scoped_ptr(new cc::SurfaceFactory(manager, this));
}
if (surface_id_.is_null() || frame_size != current_surface_size_ ||
frame_size_in_dip != current_frame_size_in_dip_) {
if (!surface_id_.is_null())
surface_factory_->Destroy(surface_id_);
surface_id_ = id_allocator_->GenerateId();
surface_factory_->Create(surface_id_, frame_size);
client_->GetLayer()->SetShowSurface(surface_id_, frame_size_in_dip);
current_surface_size_ = frame_size;
}
scoped_ptr<cc::CompositorFrame> compositor_frame =
make_scoped_ptr(new cc::CompositorFrame());
compositor_frame->delegated_frame_data = frame_data.Pass();
surface_factory_->SubmitFrame(surface_id_, compositor_frame.Pass());
} else {
frame_provider_->SetFrameData(frame_data.Pass());
if (!resource_collection_) {
resource_collection_ = new cc::DelegatedFrameResourceCollection;
resource_collection_->SetClient(this);
}
// If the physical frame size changes, we need a new |frame_provider_|. If
// the physical frame size is the same, but the size in DIP changed, we
// need to adjust the scale at which the frames will be drawn, and we do
// this by making a new |frame_provider_| also to ensure the scale change
// is presented in sync with the new frame content.
if (!frame_provider_.get() ||
frame_size != frame_provider_->frame_size() ||
frame_size_in_dip != current_frame_size_in_dip_) {
frame_provider_ = new cc::DelegatedFrameProvider(
resource_collection_.get(), frame_data.Pass());
client_->GetLayer()->SetShowDelegatedContent(frame_provider_.get(),
frame_size_in_dip);
} else {
frame_provider_->SetFrameData(frame_data.Pass());
}
}
}
released_front_lock_ = NULL;
......@@ -379,7 +406,7 @@ void DelegatedFrameHost::SwapDelegatedFrame(
output_surface_id));
}
DidReceiveFrameFromRenderer();
if (frame_provider_.get())
if (frame_provider_.get() || !surface_id_.is_null())
delegated_frame_evictor_->SwappedFrame(!host->is_hidden());
// Note: the frame may have been evicted immediately.
}
......@@ -387,6 +414,8 @@ void DelegatedFrameHost::SwapDelegatedFrame(
void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) {
RenderWidgetHostImpl* host = client_->GetHost();
cc::CompositorFrameAck ack;
if (!surface_returned_resources_.empty())
ack.resources.swap(surface_returned_resources_);
if (resource_collection_)
resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
RenderWidgetHostImpl::SendSwapCompositorFrameAck(host->GetRoutingID(),
......@@ -407,10 +436,14 @@ void DelegatedFrameHost::UnusedResourcesAreAvailable() {
void DelegatedFrameHost::SendReturnedDelegatedResources(
uint32 output_surface_id) {
RenderWidgetHostImpl* host = client_->GetHost();
DCHECK(resource_collection_);
cc::CompositorFrameAck ack;
resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
if (!surface_returned_resources_.empty()) {
ack.resources.swap(surface_returned_resources_);
} else {
DCHECK(resource_collection_);
resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
}
DCHECK(!ack.resources.empty());
RenderWidgetHostImpl::SendReclaimCompositorResources(
......@@ -420,9 +453,24 @@ void DelegatedFrameHost::SendReturnedDelegatedResources(
ack);
}
void DelegatedFrameHost::ReturnResources(
const cc::ReturnedResourceArray& resources) {
if (resources.empty())
return;
std::copy(resources.begin(),
resources.end(),
std::back_inserter(surface_returned_resources_));
if (!pending_delegated_ack_count_)
SendReturnedDelegatedResources(last_output_surface_id_);
}
void DelegatedFrameHost::EvictDelegatedFrame() {
client_->GetLayer()->SetShowPaintedContent();
frame_provider_ = NULL;
if (!surface_id_.is_null()) {
surface_factory_->Destroy(surface_id_);
surface_id_ = cc::SurfaceId();
}
delegated_frame_evictor_->DiscardedFrame();
}
......@@ -760,7 +808,7 @@ void DelegatedFrameHost::OnUpdateVSyncParameters(
void DelegatedFrameHost::OnLostResources() {
RenderWidgetHostImpl* host = client_->GetHost();
if (frame_provider_.get())
if (frame_provider_.get() || !surface_id_.is_null())
EvictDelegatedFrame();
idle_frame_subscriber_textures_.clear();
yuv_readback_pipeline_.reset();
......@@ -774,6 +822,8 @@ void DelegatedFrameHost::OnLostResources() {
DelegatedFrameHost::~DelegatedFrameHost() {
ImageTransportFactory::GetInstance()->RemoveObserver(this);
if (!surface_id_.is_null())
surface_factory_->Destroy(surface_id_);
if (resource_collection_.get())
resource_collection_->SetClient(NULL);
......@@ -825,12 +875,12 @@ void DelegatedFrameHost::RemovingFromWindow() {
}
void DelegatedFrameHost::LockResources() {
DCHECK(frame_provider_);
DCHECK(frame_provider_ || !surface_id_.is_null());
delegated_frame_evictor_->LockFrame();
}
void DelegatedFrameHost::UnlockResources() {
DCHECK(frame_provider_);
DCHECK(frame_provider_ || !surface_id_.is_null());
delegated_frame_evictor_->UnlockFrame();
}
......@@ -846,6 +896,9 @@ void DelegatedFrameHost::OnLayerRecreated(ui::Layer* old_layer,
new_layer->SetShowDelegatedContent(frame_provider_.get(),
current_frame_size_in_dip_);
}
if (!surface_id_.is_null()) {
new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_);
}
}
} // namespace content
......
......@@ -8,6 +8,7 @@
#include "cc/layers/delegated_frame_provider.h"
#include "cc/layers/delegated_frame_resource_collection.h"
#include "cc/output/copy_output_result.h"
#include "cc/surfaces/surface_factory_client.h"
#include "content/browser/compositor/image_transport_factory.h"
#include "content/browser/compositor/owned_mailbox.h"
#include "content/browser/renderer_host/delegated_frame_evictor.h"
......@@ -21,6 +22,10 @@
#include "ui/compositor/layer_owner_delegate.h"
#include "ui/gfx/rect_conversions.h"
namespace cc {
class SurfaceFactory;
}
namespace media {
class VideoFrame;
}
......@@ -72,6 +77,7 @@ class CONTENT_EXPORT DelegatedFrameHost
public ImageTransportFactoryObserver,
public DelegatedFrameEvictorClient,
public cc::DelegatedFrameResourceCollectionClient,
public cc::SurfaceFactoryClient,
public base::SupportsWeakPtr<DelegatedFrameHost> {
public:
DelegatedFrameHost(DelegatedFrameHostClient* client);
......@@ -212,10 +218,18 @@ class CONTENT_EXPORT DelegatedFrameHost
// cc::DelegatedFrameProviderClient implementation.
virtual void UnusedResourcesAreAvailable() OVERRIDE;
// cc::SurfaceFactoryClient implementation.
virtual void ReturnResources(
const cc::ReturnedResourceArray& resources) OVERRIDE;
void DidReceiveFrameFromRenderer();
DelegatedFrameHostClient* client_;
// True if this renders into a Surface, false if it renders into a delegated
// layer.
bool use_surfaces_;
std::vector<base::Closure> on_compositing_did_commit_callbacks_;
// The vsync manager we are observing for changes, if any.
......@@ -243,6 +257,13 @@ class CONTENT_EXPORT DelegatedFrameHost
// Provides delegated frame updates to the cc::DelegatedRendererLayer.
scoped_refptr<cc::DelegatedFrameProvider> frame_provider_;
// State for rendering into a Surface.
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_;
// This lock is the one waiting for a frame of the right size to come back
// from the renderer/GPU process. It is set from the moment the aura window
// got resized, to the moment we committed the renderer frame of the same
......
......@@ -315,6 +315,16 @@ gfx::GLSurfaceHandle GpuProcessTransportFactory::GetSharedSurfaceHandle() {
return handle;
}
scoped_ptr<cc::SurfaceIdAllocator>
GpuProcessTransportFactory::CreateSurfaceIdAllocator() {
return make_scoped_ptr(
new cc::SurfaceIdAllocator(next_surface_id_namespace_++));
}
cc::SurfaceManager* GpuProcessTransportFactory::GetSurfaceManager() {
return surface_manager_.get();
}
GLHelper* GpuProcessTransportFactory::GetGLHelper() {
if (!gl_helper_ && !per_compositor_data_.empty()) {
scoped_refptr<cc::ContextProvider> provider =
......
......@@ -60,6 +60,9 @@ class GpuProcessTransportFactory
// ImageTransportFactory implementation.
virtual ui::ContextFactory* GetContextFactory() OVERRIDE;
virtual gfx::GLSurfaceHandle GetSharedSurfaceHandle() OVERRIDE;
virtual scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator()
OVERRIDE;
virtual cc::SurfaceManager* GetSurfaceManager() OVERRIDE;
virtual GLHelper* GetGLHelper() OVERRIDE;
virtual void AddObserver(ImageTransportFactoryObserver* observer) OVERRIDE;
virtual void RemoveObserver(
......
......@@ -9,9 +9,14 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "cc/surfaces/surface_id_allocator.h"
#include "content/common/content_export.h"
#include "ui/gfx/native_widget_types.h"
namespace cc {
class SurfaceManager;
}
namespace gfx {
class Size;
}
......@@ -67,6 +72,8 @@ class CONTENT_EXPORT ImageTransportFactory {
virtual ui::ContextFactory* GetContextFactory() = 0;
virtual gfx::GLSurfaceHandle GetSharedSurfaceHandle() = 0;
virtual scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() = 0;
virtual cc::SurfaceManager* GetSurfaceManager() = 0;
// Gets a GLHelper instance, associated with the shared context. This
// GLHelper will get destroyed whenever the shared context is lost
......
......@@ -31,6 +31,15 @@ NoTransportImageTransportFactory::GetSharedSurfaceHandle() {
return gfx::GLSurfaceHandle();
}
scoped_ptr<cc::SurfaceIdAllocator>
NoTransportImageTransportFactory::CreateSurfaceIdAllocator() {
return scoped_ptr<cc::SurfaceIdAllocator>();
}
cc::SurfaceManager* NoTransportImageTransportFactory::GetSurfaceManager() {
return NULL;
}
GLHelper* NoTransportImageTransportFactory::GetGLHelper() {
if (!gl_helper_) {
context_provider_ = context_factory_->SharedMainThreadContextProvider();
......
......@@ -24,6 +24,9 @@ class NoTransportImageTransportFactory : public ImageTransportFactory {
// ImageTransportFactory implementation.
virtual ui::ContextFactory* GetContextFactory() OVERRIDE;
virtual gfx::GLSurfaceHandle GetSharedSurfaceHandle() OVERRIDE;
virtual scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator()
OVERRIDE;
virtual cc::SurfaceManager* GetSurfaceManager() OVERRIDE;
virtual GLHelper* GetGLHelper() OVERRIDE;
virtual void AddObserver(ImageTransportFactoryObserver* observer) OVERRIDE;
virtual void RemoveObserver(ImageTransportFactoryObserver* observer) OVERRIDE;
......
include_rules = [
"+cc",
"-cc/surfaces",
"+gpu/command_buffer/client/gles2_interface.h",
"+third_party/skia",
"+ui/gfx",
......
......@@ -17,6 +17,7 @@
#include "cc/layers/nine_patch_layer.h"
#include "cc/layers/picture_layer.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/layers/surface_layer.h"
#include "cc/layers/texture_layer.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/delegated_frame_data.h"
......@@ -496,6 +497,7 @@ void Layer::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) {
solid_color_layer_ = NULL;
texture_layer_ = NULL;
delegated_renderer_layer_ = NULL;
surface_layer_ = NULL;
cc_layer_->AddLayerAnimationEventObserver(this);
for (size_t i = 0; i < children_.size(); ++i) {
......@@ -564,6 +566,18 @@ void Layer::SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider,
RecomputeDrawsContentAndUVRect();
}
void Layer::SetShowSurface(cc::SurfaceId id, gfx::Size frame_size_in_dip) {
DCHECK_EQ(type_, LAYER_TEXTURED);
scoped_refptr<cc::SurfaceLayer> new_layer = cc::SurfaceLayer::Create();
new_layer->SetSurfaceId(id);
SwitchToLayer(new_layer);
surface_layer_ = new_layer;
frame_size_in_dip_ = frame_size_in_dip;
RecomputeDrawsContentAndUVRect();
}
void Layer::SetShowPaintedContent() {
if (content_layer_.get())
return;
......@@ -982,7 +996,7 @@ void Layer::RecomputeDrawsContentAndUVRect() {
static_cast<float>(size.width()) / frame_size_in_dip_.width(),
static_cast<float>(size.height()) / frame_size_in_dip_.height());
texture_layer_->SetUV(uv_top_left, uv_bottom_right);
} else if (delegated_renderer_layer_.get()) {
} else if (delegated_renderer_layer_.get() || surface_layer_.get()) {
size.SetToMin(frame_size_in_dip_);
}
cc_layer_->SetBounds(size);
......
......@@ -19,6 +19,7 @@
#include "cc/layers/layer_client.h"
#include "cc/layers/texture_layer_client.h"
#include "cc/resources/texture_mailbox.h"
#include "cc/surfaces/surface_id.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "ui/compositor/compositor.h"
......@@ -39,6 +40,7 @@ class Layer;
class NinePatchLayer;
class ResourceUpdateQueue;
class SolidColorLayer;
class SurfaceLayer;
class TextureLayer;
struct ReturnedResource;
typedef std::vector<ReturnedResource> ReturnedResourceArray;
......@@ -271,8 +273,12 @@ class COMPOSITOR_EXPORT Layer
void SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider,
gfx::Size frame_size_in_dip);
// Begins showing content from a surface with a particular id.
void SetShowSurface(cc::SurfaceId id, gfx::Size frame_size_in_dip);
bool has_external_content() {
return texture_layer_.get() || delegated_renderer_layer_.get();
return texture_layer_.get() || delegated_renderer_layer_.get() ||
surface_layer_.get();
}
void SetShowPaintedContent();
......@@ -486,6 +492,7 @@ class COMPOSITOR_EXPORT Layer
scoped_refptr<cc::TextureLayer> texture_layer_;
scoped_refptr<cc::SolidColorLayer> solid_color_layer_;
scoped_refptr<cc::DelegatedRendererLayer> delegated_renderer_layer_;
scoped_refptr<cc::SurfaceLayer> surface_layer_;
cc::Layer* cc_layer_;
// A cached copy of |Compositor::device_scale_factor()|.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment