| Index: content/browser/frame_host/render_widget_host_view_child_frame.cc
|
| diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc
|
| index b8fdb0193d5800ad2867f95a5c1dc74014bf1828..e4ced729db79c6dcd942b564fd1f86c14b661300 100644
|
| --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc
|
| +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
|
| @@ -4,8 +4,13 @@
|
|
|
| #include "content/browser/frame_host/render_widget_host_view_child_frame.h"
|
|
|
| +#include "cc/surfaces/surface.h"
|
| +#include "cc/surfaces/surface_factory.h"
|
| +#include "cc/surfaces/surface_manager.h"
|
| +#include "cc/surfaces/surface_sequence.h"
|
| #include "content/browser/accessibility/browser_accessibility_manager.h"
|
| #include "content/browser/frame_host/cross_process_frame_connector.h"
|
| +#include "content/browser/gpu/compositor_util.h"
|
| #include "content/browser/renderer_host/render_widget_host_impl.h"
|
| #include "content/common/gpu/gpu_messages.h"
|
| #include "content/common/view_messages.h"
|
| @@ -16,11 +21,26 @@ namespace content {
|
| RenderWidgetHostViewChildFrame::RenderWidgetHostViewChildFrame(
|
| RenderWidgetHost* widget_host)
|
| : host_(RenderWidgetHostImpl::From(widget_host)),
|
| - frame_connector_(NULL) {
|
| + use_surfaces_(UseSurfacesEnabled()),
|
| + next_surface_sequence_(1u),
|
| + last_output_surface_id_(0),
|
| + current_surface_scale_factor_(1.f),
|
| + ack_pending_count_(0),
|
| + frame_connector_(NULL),
|
| + weak_factory_(this) {
|
| +#if !defined(OS_ANDROID)
|
| + if (use_surfaces_) {
|
| + ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
|
| + id_allocator_ = factory->GetContextFactory()->CreateSurfaceIdAllocator();
|
| + }
|
| +#endif // !defined(OS_ANDROID)
|
| +
|
| host_->SetView(this);
|
| }
|
|
|
| RenderWidgetHostViewChildFrame::~RenderWidgetHostViewChildFrame() {
|
| + if (!surface_id_.is_null())
|
| + surface_factory_->Destroy(surface_id_);
|
| }
|
|
|
| void RenderWidgetHostViewChildFrame::InitAsChild(
|
| @@ -186,17 +206,92 @@ void RenderWidgetHostViewChildFrame::UnlockCompositingSurface() {
|
| }
|
| #endif
|
|
|
| +void RenderWidgetHostViewChildFrame::SurfaceDrawn(uint32 output_surface_id,
|
| + cc::SurfaceDrawStatus drawn) {
|
| + cc::CompositorFrameAck ack;
|
| + DCHECK(ack_pending_count_ > 0);
|
| + if (!surface_returned_resources_.empty())
|
| + ack.resources.swap(surface_returned_resources_);
|
| + if (host_) {
|
| + host_->Send(new ViewMsg_SwapCompositorFrameAck(host_->GetRoutingID(),
|
| + output_surface_id, ack));
|
| + }
|
| + ack_pending_count_--;
|
| +}
|
| +
|
| void RenderWidgetHostViewChildFrame::OnSwapCompositorFrame(
|
| uint32 output_surface_id,
|
| scoped_ptr<cc::CompositorFrame> frame) {
|
| last_scroll_offset_ = frame->metadata.root_scroll_offset;
|
| - if (frame_connector_) {
|
| +
|
| + if (!frame_connector_)
|
| + return;
|
| +
|
| + // When not using surfaces, the frame just gets proxied to
|
| + // the embedder's renderer to be composited.
|
| + if (!frame->delegated_frame_data || !use_surfaces_) {
|
| frame_connector_->ChildFrameCompositorFrameSwapped(
|
| output_surface_id,
|
| host_->GetProcess()->GetID(),
|
| host_->GetRoutingID(),
|
| frame.Pass());
|
| + return;
|
| + }
|
| +
|
| +#if !defined(OS_ANDROID)
|
| + cc::RenderPass* root_pass =
|
| + frame->delegated_frame_data->render_pass_list.back();
|
| +
|
| + gfx::Size frame_size = root_pass->output_rect.size();
|
| + float scale_factor = frame->metadata.device_scale_factor;
|
| +
|
| + // Check whether we need to recreate the cc::Surface, which means the child
|
| + // frame renderer has changed its output surface, or size, or scale factor.
|
| + if (output_surface_id != last_output_surface_id_ && surface_factory_) {
|
| + surface_factory_->Destroy(surface_id_);
|
| + surface_factory_.reset();
|
| + }
|
| + if (output_surface_id != last_output_surface_id_ ||
|
| + frame_size != current_surface_size_ ||
|
| + scale_factor != current_surface_scale_factor_) {
|
| + if (surface_factory_ && !surface_id_.is_null())
|
| + surface_factory_->Destroy(surface_id_);
|
| + surface_id_ = cc::SurfaceId();
|
| + last_output_surface_id_ = output_surface_id;
|
| + current_surface_size_ = frame_size;
|
| + current_surface_scale_factor_ = scale_factor;
|
| }
|
| +
|
| + if (!surface_factory_) {
|
| + ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
|
| + cc::SurfaceManager* manager = factory->GetSurfaceManager();
|
| + surface_factory_ = make_scoped_ptr(new cc::SurfaceFactory(manager, this));
|
| + }
|
| +
|
| + if (surface_id_.is_null()) {
|
| + surface_id_ = id_allocator_->GenerateId();
|
| + surface_factory_->Create(surface_id_);
|
| +
|
| + ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
|
| + cc::SurfaceSequence sequence = cc::SurfaceSequence(
|
| + id_allocator_->id_namespace(), next_surface_sequence_++);
|
| + // The renderer process will satisfy this dependency when it creates a
|
| + // SurfaceLayer.
|
| + factory->GetSurfaceManager()
|
| + ->GetSurfaceForId(surface_id_)
|
| + ->AddDestructionDependency(sequence);
|
| + frame_connector_->SetChildFrameSurface(surface_id_, frame_size,
|
| + scale_factor, sequence);
|
| + }
|
| +
|
| + cc::SurfaceFactory::DrawCallback ack_callback =
|
| + base::Bind(&RenderWidgetHostViewChildFrame::SurfaceDrawn, AsWeakPtr(),
|
| + output_surface_id);
|
| + ack_pending_count_++;
|
| + // If this value grows very large, something is going wrong.
|
| + DCHECK(ack_pending_count_ < 1000);
|
| + surface_factory_->SubmitFrame(surface_id_, frame.Pass(), ack_callback);
|
| +#endif // !defined(OS_ANDROID)
|
| }
|
|
|
| void RenderWidgetHostViewChildFrame::GetScreenInfo(
|
| @@ -223,9 +318,10 @@ void RenderWidgetHostViewChildFrame::UnlockMouse() {
|
| }
|
|
|
| uint32_t RenderWidgetHostViewChildFrame::GetSurfaceIdNamespace() {
|
| - // TODO(kenrb): Create SurfaceFactory here when RWHVChildFrame
|
| - // gets compositor surface support.
|
| - return 0;
|
| + if (!use_surfaces_)
|
| + return 0;
|
| +
|
| + return id_allocator_->id_namespace();
|
| }
|
|
|
| #if defined(OS_MACOSX)
|
| @@ -301,6 +397,25 @@ gfx::NativeViewId RenderWidgetHostViewChildFrame::GetParentForWindowlessPlugin()
|
| }
|
| #endif // defined(OS_WIN)
|
|
|
| +// cc::SurfaceFactoryClient implementation.
|
| +void RenderWidgetHostViewChildFrame::ReturnResources(
|
| + const cc::ReturnedResourceArray& resources) {
|
| + if (resources.empty())
|
| + return;
|
| +
|
| + if (!ack_pending_count_ && host_) {
|
| + cc::CompositorFrameAck ack;
|
| + std::copy(resources.begin(), resources.end(),
|
| + std::back_inserter(ack.resources));
|
| + host_->Send(new ViewMsg_ReclaimCompositorResources(
|
| + host_->GetRoutingID(), last_output_surface_id_, ack));
|
| + return;
|
| + }
|
| +
|
| + std::copy(resources.begin(), resources.end(),
|
| + std::back_inserter(surface_returned_resources_));
|
| +}
|
| +
|
| BrowserAccessibilityManager*
|
| RenderWidgetHostViewChildFrame::CreateBrowserAccessibilityManager(
|
| BrowserAccessibilityDelegate* delegate) {
|
|
|