diff options
author | kenrb@chromium.org <kenrb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-23 20:52:16 +0000 |
---|---|---|
committer | kenrb@chromium.org <kenrb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-23 20:52:16 +0000 |
commit | bffc830292ebad36ce520e9dce03ecb7a21fd25a (patch) | |
tree | ff6a6e55730efc3b077a86b7e66427f5f1c1af3e /content | |
parent | d6ed71cb2587955d36fb7ec81dfc9bcd0c96dbf7 (diff) | |
download | chromium_src-bffc830292ebad36ce520e9dce03ecb7a21fd25a.zip chromium_src-bffc830292ebad36ce520e9dce03ecb7a21fd25a.tar.gz chromium_src-bffc830292ebad36ce520e9dce03ecb7a21fd25a.tar.bz2 |
Make out of process iframes draw when flag enabled.
This patch provides the final pieces to allow out of process iframes
to render in their embedding page when running under --site-per-process.
The --force-compositing-mode is also required unless using Aura.
BrowserPluginCompositingHelper has been renamed to
ChildFrameCompositingHelper and is now being used for both purposes.
The split code paths within the helper class will be merged when
BrowserPlugin is converted to use RenderFrame for IPC routing.
TBR=creis@chromium.org
BUG=325803
Review URL: https://codereview.chromium.org/136953003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@246682 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
28 files changed, 453 insertions, 165 deletions
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index e6b8d67..cbd96c3 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc @@ -1330,14 +1330,11 @@ void BrowserPluginGuest::OnExtendSelectionAndDelete( void BrowserPluginGuest::OnReclaimCompositorResources( int instance_id, - int route_id, - uint32 output_surface_id, - int renderer_host_id, - const cc::CompositorFrameAck& ack) { - RenderWidgetHostImpl::SendReclaimCompositorResources(route_id, - output_surface_id, - renderer_host_id, - ack); + const FrameHostMsg_ReclaimCompositorResources_Params& params) { + RenderWidgetHostImpl::SendReclaimCompositorResources(params.route_id, + params.output_surface_id, + params.renderer_host_id, + params.ack); } void BrowserPluginGuest::OnHandleInputEvent( diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h index 92a7c84..510231c 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.h +++ b/content/browser/browser_plugin/browser_plugin_guest.h @@ -47,6 +47,7 @@ struct BrowserPluginHostMsg_Attach_Params; struct BrowserPluginHostMsg_ResizeGuest_Params; struct FrameHostMsg_BuffersSwappedACK_Params; struct FrameHostMsg_CompositorFrameSwappedACK_Params; +struct FrameHostMsg_ReclaimCompositorResources_Params; struct ViewHostMsg_CreateWindow_Params; #if defined(OS_MACOSX) struct ViewHostMsg_ShowPopup_Params; @@ -405,11 +406,9 @@ class CONTENT_EXPORT BrowserPluginGuest const std::string& command); // Returns compositor resources reclaimed in the embedder to the guest. - void OnReclaimCompositorResources(int instance_id, - int route_id, - uint32 output_surface_id, - int renderer_host_id, - const cc::CompositorFrameAck& ack); + void OnReclaimCompositorResources( + int instance_id, + const FrameHostMsg_ReclaimCompositorResources_Params& params); // Overriden in tests. virtual void OnHandleInputEvent(int instance_id, diff --git a/content/browser/frame_host/cross_process_frame_connector.cc b/content/browser/frame_host/cross_process_frame_connector.cc index ef150be..98eb7bb 100644 --- a/content/browser/frame_host/cross_process_frame_connector.cc +++ b/content/browser/frame_host/cross_process_frame_connector.cc @@ -21,7 +21,7 @@ CrossProcessFrameConnector::CrossProcessFrameConnector( CrossProcessFrameConnector::~CrossProcessFrameConnector() { if (view_) - view_->set_cross_process_child_frame(NULL); + view_->set_cross_process_frame_connector(NULL); } bool CrossProcessFrameConnector::OnMessageReceived(const IPC::Message& msg) { @@ -30,23 +30,27 @@ bool CrossProcessFrameConnector::OnMessageReceived(const IPC::Message& msg) { IPC_BEGIN_MESSAGE_MAP_EX(CrossProcessFrameConnector, msg, msg_is_ok) IPC_MESSAGE_HANDLER(FrameHostMsg_BuffersSwappedACK, OnBuffersSwappedACK) + IPC_MESSAGE_HANDLER(FrameHostMsg_CompositorFrameSwappedACK, + OnCompositorFrameSwappedACK) + IPC_MESSAGE_HANDLER(FrameHostMsg_ReclaimCompositorResources, + OnReclaimCompositorResources) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP_EX() return handled; } -void CrossProcessFrameConnector::SetView( +void CrossProcessFrameConnector::set_view( RenderWidgetHostViewChildFrame* view) { // Detach ourselves from the previous |view_|. if (view_) - view_->set_cross_process_child_frame(NULL); + view_->set_cross_process_frame_connector(NULL); view_ = view; // Attach ourselves to the new view. if (view_) - view_->set_cross_process_child_frame(this); + view_->set_cross_process_frame_connector(this); } void CrossProcessFrameConnector::ChildFrameBuffersSwapped( @@ -67,11 +71,16 @@ void CrossProcessFrameConnector::ChildFrameBuffersSwapped( void CrossProcessFrameConnector::ChildFrameCompositorFrameSwapped( uint32 output_surface_id, + int host_id, + int route_id, scoped_ptr<cc::CompositorFrame> frame) { -} - -gfx::Rect CrossProcessFrameConnector::ChildFrameRect() { - return child_frame_rect_; + FrameMsg_CompositorFrameSwapped_Params params; + frame->AssignTo(¶ms.frame); + params.output_surface_id = output_surface_id; + params.producing_route_id = route_id; + params.producing_host_id = host_id; + frame_proxy_in_parent_renderer_->Send(new FrameMsg_CompositorFrameSwapped( + frame_proxy_in_parent_renderer_->routing_id(), params)); } void CrossProcessFrameConnector::OnBuffersSwappedACK( @@ -86,4 +95,24 @@ void CrossProcessFrameConnector::OnBuffersSwappedACK( // TODO(kenrb): Special case stuff for Win + Mac. } +void CrossProcessFrameConnector::OnCompositorFrameSwappedACK( + const FrameHostMsg_CompositorFrameSwappedACK_Params& params) { + RenderWidgetHostImpl::SendSwapCompositorFrameAck(params.producing_route_id, + params.output_surface_id, + params.producing_host_id, + params.ack); +} + +void CrossProcessFrameConnector::OnReclaimCompositorResources( + const FrameHostMsg_ReclaimCompositorResources_Params& params) { + RenderWidgetHostImpl::SendReclaimCompositorResources(params.route_id, + params.output_surface_id, + params.renderer_host_id, + params.ack); +} + +gfx::Rect CrossProcessFrameConnector::ChildFrameRect() { + return child_frame_rect_; +} + } // namespace content diff --git a/content/browser/frame_host/cross_process_frame_connector.h b/content/browser/frame_host/cross_process_frame_connector.h index e107acc..1dfb5d1 100644 --- a/content/browser/frame_host/cross_process_frame_connector.h +++ b/content/browser/frame_host/cross_process_frame_connector.h @@ -13,6 +13,8 @@ class Message; } struct FrameHostMsg_BuffersSwappedACK_Params; +struct FrameHostMsg_CompositorFrameSwappedACK_Params; +struct FrameHostMsg_ReclaimCompositorResources_Params; struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params; namespace content { @@ -41,11 +43,13 @@ class RenderWidgetHostViewChildFrame; // A2 - Swapped out RFH for frame 2 in process A // B2 - RFH for frame 2 in process B // -// B2, having a parent frame in a diferent process, will have a +// B2, having a parent frame in a different process, will have a // RenderWidgetHostViewChildFrame. This RenderWidgetHostViewChildFrame needs -// to communicate with A2 so that the painting logic in process A can -// composite B2's data with A1's. CrossProcessFrameConnector bridges between -// B2's RenderWidgetHostViewChildFrame and A2 to allow for this communication. +// to communicate with A2 because the embedding process is an abstract +// for the child frame -- it needs information necessary for compositing child +// frame textures, and also can pass platform messages such as view resizing. +// CrossProcessFrameConnector bridges between B2's +// RenderWidgetHostViewChildFrame and A2 to allow for this communication. // (Note: B1 is only mentioned for completeness. It is not needed in this // example.) // @@ -53,7 +57,6 @@ class RenderWidgetHostViewChildFrame; // RenderFrameHostManager. When a child frame swaps, SetChildFrameView() is // called to update to the new view. // -// TODO(kenrb): Double-check this comment's accuracy. class CrossProcessFrameConnector { public: // |frame_proxy_in_parent_renderer| corresponds to A2 in the example above. @@ -65,18 +68,19 @@ class CrossProcessFrameConnector { // |view| corresponds to B2's RenderWidgetHostViewChildFrame in the example // above. - void SetView(RenderWidgetHostViewChildFrame* view); + void set_view(RenderWidgetHostViewChildFrame* view); // 'Platform' functionality exposed to RenderWidgetHostViewChildFrame. // These methods can forward messages to the child frame proxy in the parent - // frame renderer or attempt to handle them within the browser process. + // frame's renderer or attempt to handle them within the browser process. void ChildFrameBuffersSwapped( const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, int gpu_host_id); - void ChildFrameCompositorFrameSwapped( - uint32 output_surface_id, - scoped_ptr<cc::CompositorFrame> frame); + void ChildFrameCompositorFrameSwapped(uint32 output_surface_id, + int host_id, + int route_id, + scoped_ptr<cc::CompositorFrame> frame); gfx::Rect ChildFrameRect(); @@ -84,6 +88,10 @@ class CrossProcessFrameConnector { // Handlers for messages received from the parent frame. void OnBuffersSwappedACK( const FrameHostMsg_BuffersSwappedACK_Params& params); + void OnCompositorFrameSwappedACK( + const FrameHostMsg_CompositorFrameSwappedACK_Params& params); + void OnReclaimCompositorResources( + const FrameHostMsg_ReclaimCompositorResources_Params& params); // The RenderFrameHost that routes messages to the parent frame's renderer // process. diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc index cca17fd..faafe5f 100644 --- a/content/browser/frame_host/frame_tree_node.cc +++ b/content/browser/frame_host/frame_tree_node.cc @@ -25,17 +25,17 @@ FrameTreeNode::FrameTreeNode(FrameTree* frame_tree, RenderFrameHostManager::Delegate* manager_delegate, int64 frame_id, const std::string& name) - : frame_tree_(frame_tree), - navigator_(navigator), - render_manager_(this, - render_frame_delegate, - render_view_delegate, - render_widget_delegate, - manager_delegate), - frame_tree_node_id_(next_frame_tree_node_id_++), - frame_id_(frame_id), - frame_name_(name) { -} + : frame_tree_(frame_tree), + navigator_(navigator), + render_manager_(this, + render_frame_delegate, + render_view_delegate, + render_widget_delegate, + manager_delegate), + frame_tree_node_id_(next_frame_tree_node_id_++), + frame_id_(frame_id), + frame_name_(name), + parent_(NULL) {} FrameTreeNode::~FrameTreeNode() { } @@ -54,6 +54,7 @@ void FrameTreeNode::AddChild(scoped_ptr<FrameTreeNode> child, render_manager_.current_host()->GetSiteInstance(), render_manager_.current_host()->GetRoutingID(), frame_routing_id); + child->set_parent(this); children_.push_back(child.release()); } @@ -65,8 +66,10 @@ void FrameTreeNode::RemoveChild(FrameTreeNode* child) { break; } - if (iter != children_.end()) + if (iter != children_.end()) { + (*iter)->set_parent(NULL); children_.erase(iter); + } } void FrameTreeNode::ResetForMainFrameSwap() { diff --git a/content/browser/frame_host/frame_tree_node.h b/content/browser/frame_host/frame_tree_node.h index e7b0800..bd9790c 100644 --- a/content/browser/frame_host/frame_tree_node.h +++ b/content/browser/frame_host/frame_tree_node.h @@ -84,6 +84,8 @@ class CONTENT_EXPORT FrameTreeNode { return children_.size(); } + FrameTreeNode* parent() const { return parent_; } + FrameTreeNode* child_at(size_t index) const { return children_[index]; } @@ -101,6 +103,8 @@ class CONTENT_EXPORT FrameTreeNode { } private: + void set_parent(FrameTreeNode* parent) { parent_ = parent; } + // The next available browser-global FrameTreeNode ID. static int64 next_frame_tree_node_id_; @@ -131,6 +135,10 @@ class CONTENT_EXPORT FrameTreeNode { // name generated internally in the DOM tree. std::string frame_name_; + // The parent node of this frame. NULL if this node is the root or if it has + // not yet been attached to the frame tree. + FrameTreeNode* parent_; + // The immediate children of this specific frame. ScopedVector<FrameTreeNode> children_; diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index a41c051..ee130b9 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc @@ -109,6 +109,10 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) { if (delegate_->OnMessageReceived(this, msg)) return true; + if (cross_process_frame_connector_ && + cross_process_frame_connector_->OnMessageReceived(msg)) + return true; + bool handled = true; bool msg_is_ok = true; IPC_BEGIN_MESSAGE_MAP_EX(RenderFrameHostImpl, msg, msg_is_ok) diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 885a6b6..5738861 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc @@ -11,6 +11,7 @@ #include "base/logging.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/devtools/render_view_devtools_agent_host.h" +#include "content/browser/frame_host/cross_process_frame_connector.h" #include "content/browser/frame_host/interstitial_page_impl.h" #include "content/browser/frame_host/navigation_controller_impl.h" #include "content/browser/frame_host/navigation_entry_impl.h" @@ -72,13 +73,16 @@ RenderFrameHostManager::RenderFrameHostManager( render_widget_delegate_(render_widget_delegate), render_frame_host_(NULL), pending_render_frame_host_(NULL), - interstitial_page_(NULL) { -} + interstitial_page_(NULL), + cross_process_frame_connector_(NULL) {} RenderFrameHostManager::~RenderFrameHostManager() { if (pending_render_frame_host_) CancelPending(); + if (cross_process_frame_connector_) + delete cross_process_frame_connector_; + // We should always have a current RenderFrameHost except in some tests. // TODO(creis): Now that we aren't using Shutdown, make render_frame_host_ and // RenderFrameHostMap use scoped_ptrs. @@ -173,7 +177,7 @@ RenderFrameHostImpl* RenderFrameHostManager::Navigate( // Note: we don't call InitRenderView here because we are navigating away // soon anyway, and we don't have the NavigationEntry for this host. delegate_->CreateRenderViewForRenderManager( - render_frame_host_->render_view_host(), MSG_ROUTING_NONE); + render_frame_host_->render_view_host(), MSG_ROUTING_NONE, NULL); } // If the renderer crashed, then try to create a new one to satisfy this @@ -858,16 +862,45 @@ int RenderFrameHostManager::CreateRenderFrame( // remove it from the list of swapped out hosts if it commits. RenderFrameHostImpl* new_render_frame_host = GetSwappedOutRenderFrameHost(instance); + + FrameTreeNode* parent_node = NULL; + if (frame_tree_node_) + parent_node = frame_tree_node_->parent(); + if (new_render_frame_host) { // Prevent the process from exiting while we're trying to use it. - if (!swapped_out) + if (!swapped_out) { new_render_frame_host->GetProcess()->AddPendingView(); + } else { + // Detect if this is a cross-process child frame that is navigating + // back to the same SiteInstance as its parent. + if (parent_node && cross_process_frame_connector_ && + render_frame_host_->GetSiteInstance() == parent_node-> + render_manager()->current_frame_host()->GetSiteInstance()) { + delete cross_process_frame_connector_; + cross_process_frame_connector_ = NULL; + } + } } else { // Create a new RenderFrameHost if we don't find an existing one. // TODO(creis): Make new_render_frame_host a scoped_ptr. new_render_frame_host = CreateRenderFrameHost(instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden); + if (parent_node && !cross_process_frame_connector_) { + // The proxy RenderFrameHost to the parent process is either the current + // RenderFrameHost, or it has been added to the swapped out list. + // TODO(kenrb): This will change when RenderFrameProxyHost is created. + RenderFrameHostImpl* proxy_to_parent = render_frame_host_; + if (render_frame_host_->render_view_host()->GetSiteInstance() != + parent_node->render_manager()->current_host()->GetSiteInstance()) { + GetSwappedOutRenderFrameHost( + parent_node->render_manager()->current_host()->GetSiteInstance()); + } + CHECK(proxy_to_parent); + cross_process_frame_connector_ = + new CrossProcessFrameConnector(proxy_to_parent); + } // If the new RFH is swapped out already, store it. Otherwise prevent the // process from exiting while we're trying to navigate in it. @@ -917,8 +950,8 @@ bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, } } - return delegate_->CreateRenderViewForRenderManager(render_view_host, - opener_route_id); + return delegate_->CreateRenderViewForRenderManager( + render_view_host, opener_route_id, cross_process_frame_connector_); } void RenderFrameHostManager::CommitPending() { @@ -980,7 +1013,7 @@ void RenderFrameHostManager::CommitPending() { if (!render_frame_host_->render_view_host()->GetView()) { delegate_->RenderProcessGoneFromRenderManager( render_frame_host_->render_view_host()); - } else if (!delegate_->IsHidden() && is_main_frame) { + } else if (!delegate_->IsHidden()) { render_frame_host_->render_view_host()->GetView()->Show(); } diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h index 4793990..a28cb08 100644 --- a/content/browser/frame_host/render_frame_host_manager.h +++ b/content/browser/frame_host/render_frame_host_manager.h @@ -19,6 +19,7 @@ namespace content { class BrowserContext; +class CrossProcessFrameConnector; class InterstitialPageImpl; class FrameTreeNode; class NavigationControllerImpl; @@ -60,7 +61,9 @@ class CONTENT_EXPORT RenderFrameHostManager // If you are attaching to an already-existing RenderView, you should call // InitWithExistingID. virtual bool CreateRenderViewForRenderManager( - RenderViewHost* render_view_host, int opener_route_id) = 0; + RenderViewHost* render_view_host, + int opener_route_id, + CrossProcessFrameConnector* cross_process_frame_connector) = 0; virtual void BeforeUnloadFiredFromRenderManager( bool proceed, const base::TimeTicks& proceed_time, bool* proceed_to_fire_unload) = 0; @@ -440,6 +443,13 @@ class CONTENT_EXPORT RenderFrameHostManager NotificationRegistrar registrar_; + // When |render_frame_host_| is in a different process from its parent in + // the frame tree, this class connects its associated RenderWidgetHostView + // to the proxy RenderFrameHost for the parent's renderer process. NULL + // when |render_frame_host_| is the frame tree root or is in the same + // process as its parent. + CrossProcessFrameConnector* cross_process_frame_connector_; + DISALLOW_COPY_AND_ASSIGN(RenderFrameHostManager); }; 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 9ee2439..9d5b70a 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 @@ -168,7 +168,6 @@ void RenderWidgetHostViewChildFrame::RenderProcessGone( } void RenderWidgetHostViewChildFrame::Destroy() { - // TODO(ajwong): Why did Ken destroy the |frame_connector_| here? frame_connector_ = NULL; host_->SetView(NULL); @@ -215,9 +214,13 @@ void RenderWidgetHostViewChildFrame::AcceleratedSurfacePostSubBuffer( void RenderWidgetHostViewChildFrame::OnSwapCompositorFrame( uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) { - if (frame_connector_) + if (frame_connector_) { frame_connector_->ChildFrameCompositorFrameSwapped( - output_surface_id, frame.Pass()); + output_surface_id, + host_->GetProcess()->GetID(), + host_->GetRoutingID(), + frame.Pass()); + } } void RenderWidgetHostViewChildFrame::GetScreenInfo( diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.h b/content/browser/frame_host/render_widget_host_view_child_frame.h index 07073e5..b9def32 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.h +++ b/content/browser/frame_host/render_widget_host_view_child_frame.h @@ -30,7 +30,7 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame explicit RenderWidgetHostViewChildFrame(RenderWidgetHost* widget); virtual ~RenderWidgetHostViewChildFrame(); - void set_cross_process_child_frame( + void set_cross_process_frame_connector( CrossProcessFrameConnector* frame_connector) { frame_connector_ = frame_connector; } diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 8fec4e0..35cb4b8 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -28,10 +28,12 @@ #include "content/browser/download/download_stats.h" #include "content/browser/download/mhtml_generation_manager.h" #include "content/browser/download/save_package.h" +#include "content/browser/frame_host/cross_process_frame_connector.h" #include "content/browser/frame_host/interstitial_page_impl.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/frame_host/navigator_impl.h" #include "content/browser/frame_host/render_frame_host_impl.h" +#include "content/browser/frame_host/render_widget_host_view_child_frame.h" #include "content/browser/host_zoom_map_impl.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/message_port_message_filter.h" @@ -3565,10 +3567,24 @@ NavigationEntry* } bool WebContentsImpl::CreateRenderViewForRenderManager( - RenderViewHost* render_view_host, int opener_route_id) { + RenderViewHost* render_view_host, + int opener_route_id, + CrossProcessFrameConnector* frame_connector) { TRACE_EVENT0("browser", "WebContentsImpl::CreateRenderViewForRenderManager"); // Can be NULL during tests. - RenderWidgetHostView* rwh_view = view_->CreateViewForWidget(render_view_host); + RenderWidgetHostView* rwh_view; + // TODO(kenrb): RenderWidgetHostViewChildFrame special casing is temporary + // until RenderWidgetHost is attached to RenderFrameHost. We need to special + // case this because RWH is still a base class of RenderViewHost, and child + // frame RWHVs are unique in that they do not have their own WebContents. + if (frame_connector) { + RenderWidgetHostViewChildFrame* rwh_view_child = + new RenderWidgetHostViewChildFrame(render_view_host); + frame_connector->set_view(rwh_view_child); + rwh_view = rwh_view_child; + } else { + rwh_view = view_->CreateViewForWidget(render_view_host); + } // Now that the RenderView has been created, we need to tell it its size. if (rwh_view) @@ -3614,7 +3630,8 @@ WebContentsImpl::GetJavaWebContents() { bool WebContentsImpl::CreateRenderViewForInitialEmptyDocument() { return CreateRenderViewForRenderManager(GetRenderViewHost(), - MSG_ROUTING_NONE); + MSG_ROUTING_NONE, + NULL); } #endif diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index f5cfd31..54c5545 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h @@ -491,7 +491,9 @@ class CONTENT_EXPORT WebContentsImpl // RenderFrameHostManager::Delegate ------------------------------------------ virtual bool CreateRenderViewForRenderManager( - RenderViewHost* render_view_host, int opener_route_id) OVERRIDE; + RenderViewHost* render_view_host, + int opener_route_id, + CrossProcessFrameConnector* frame_connector) OVERRIDE; virtual void BeforeUnloadFiredFromRenderManager( bool proceed, const base::TimeTicks& proceed_time, bool* proceed_to_fire_unload) OVERRIDE; diff --git a/content/common/browser_plugin/browser_plugin_messages.h b/content/common/browser_plugin/browser_plugin_messages.h index be34c7b..d57bdbe 100644 --- a/content/common/browser_plugin/browser_plugin_messages.h +++ b/content/common/browser_plugin/browser_plugin_messages.h @@ -228,12 +228,9 @@ IPC_MESSAGE_ROUTED3(BrowserPluginHostMsg_CopyFromCompositingSurfaceAck, // Notify the guest renderer that some resources given to the embededer // are not used any more. -IPC_MESSAGE_ROUTED5(BrowserPluginHostMsg_ReclaimCompositorResources, +IPC_MESSAGE_ROUTED2(BrowserPluginHostMsg_ReclaimCompositorResources, int /* instance_id */, - int /* route_id */, - uint32 /* output_surface_id */, - int /* renderer_host_id */, - cc::CompositorFrameAck /* ack */) + FrameHostMsg_ReclaimCompositorResources_Params /* params */) // When a BrowserPlugin has been removed from the embedder's DOM, it informs // the browser process to cleanup the guest. diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 0bba2b4..65d3907 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h @@ -159,6 +159,9 @@ IPC_MESSAGE_ROUTED1(FrameHostMsg_CompositorFrameSwappedACK, // Indicates that the current frame has swapped out, after a SwapOut message. IPC_MESSAGE_ROUTED0(FrameHostMsg_SwapOut_ACK) +IPC_MESSAGE_ROUTED1(FrameHostMsg_ReclaimCompositorResources, + FrameHostMsg_ReclaimCompositorResources_Params /* params */) + // Instructs the frame to swap out for a cross-site transition, including // running the unload event handler. Expects a SwapOut_ACK message when // finished. diff --git a/content/common/frame_param_macros.h b/content/common/frame_param_macros.h index ea1534d..2cd44e7 100644 --- a/content/common/frame_param_macros.h +++ b/content/common/frame_param_macros.h @@ -53,4 +53,11 @@ IPC_STRUCT_BEGIN(FrameHostMsg_CompositorFrameSwappedACK_Params) IPC_STRUCT_MEMBER(cc::CompositorFrameAck, ack) IPC_STRUCT_END() +IPC_STRUCT_BEGIN(FrameHostMsg_ReclaimCompositorResources_Params) + IPC_STRUCT_MEMBER(int, route_id) + IPC_STRUCT_MEMBER(uint32, output_surface_id) + IPC_STRUCT_MEMBER(int, renderer_host_id) + IPC_STRUCT_MEMBER(cc::CompositorFrameAck, ack) +IPC_STRUCT_END() + #endif // CONTENT_COMMON_FRAME_PARAM_MACROS_H_ diff --git a/content/common/swapped_out_messages.cc b/content/common/swapped_out_messages.cc index a6fdc25..e2e920e 100644 --- a/content/common/swapped_out_messages.cc +++ b/content/common/swapped_out_messages.cc @@ -40,6 +40,9 @@ bool SwappedOutMessages::CanSendWhileSwappedOut(const IPC::Message* msg) { case FrameHostMsg_SwapOut_ACK::ID: // Frame detach must occur after the RenderView has swapped out. case FrameHostMsg_Detach::ID: + case FrameHostMsg_CompositorFrameSwappedACK::ID: + case FrameHostMsg_BuffersSwappedACK::ID: + case FrameHostMsg_ReclaimCompositorResources::ID: return true; default: break; diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 7487d63..86aa9ea 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -94,8 +94,6 @@ 'renderer/browser_plugin/browser_plugin_backing_store.h', 'renderer/browser_plugin/browser_plugin_bindings.cc', 'renderer/browser_plugin/browser_plugin_bindings.h', - 'renderer/browser_plugin/browser_plugin_compositing_helper.cc', - 'renderer/browser_plugin/browser_plugin_compositing_helper.h', 'renderer/browser_plugin/browser_plugin_manager_factory.h', 'renderer/browser_plugin/browser_plugin_manager_impl.cc', 'renderer/browser_plugin/browser_plugin_manager_impl.h', @@ -103,6 +101,8 @@ 'renderer/browser_plugin/browser_plugin_manager.h', 'renderer/clipboard_utils.cc', 'renderer/clipboard_utils.h', + 'renderer/child_frame_compositing_helper.cc', + 'renderer/child_frame_compositing_helper.h', 'renderer/context_menu_params_builder.cc', 'renderer/context_menu_params_builder.h', 'renderer/cursor_utils.cc', diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index eb67048..4168e2e 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc @@ -17,8 +17,8 @@ #include "content/public/common/content_switches.h" #include "content/public/renderer/content_renderer_client.h" #include "content/renderer/browser_plugin/browser_plugin_bindings.h" -#include "content/renderer/browser_plugin/browser_plugin_compositing_helper.h" #include "content/renderer/browser_plugin/browser_plugin_manager.h" +#include "content/renderer/child_frame_compositing_helper.h" #include "content/renderer/cursor_utils.h" #include "content/renderer/drop_data_builder.h" #include "content/renderer/render_process_impl.h" @@ -916,10 +916,11 @@ void BrowserPlugin::EnableCompositing(bool enable) { current_damage_buffer_.reset(); if (!compositing_helper_.get()) { compositing_helper_ = - new BrowserPluginCompositingHelper(container_, - browser_plugin_manager(), - guest_instance_id_, - render_view_routing_id_); + ChildFrameCompositingHelper::CreateCompositingHelperForBrowserPlugin( + container_, + browser_plugin_manager(), + guest_instance_id_, + render_view_routing_id_); } } else { if (paint_ack_received_) { diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h index f93ebef..008964e 100644 --- a/content/renderer/browser_plugin/browser_plugin.h +++ b/content/renderer/browser_plugin/browser_plugin.h @@ -30,7 +30,7 @@ struct FrameMsg_BuffersSwapped_Params; namespace content { -class BrowserPluginCompositingHelper; +class ChildFrameCompositingHelper; class BrowserPluginManager; class MockBrowserPlugin; @@ -361,7 +361,7 @@ class CONTENT_EXPORT BrowserPlugin : // Used for HW compositing. bool compositing_enabled_; - scoped_refptr<BrowserPluginCompositingHelper> compositing_helper_; + scoped_refptr<ChildFrameCompositingHelper> compositing_helper_; // Used to identify the plugin to WebBindings. scoped_ptr<struct _NPP> npp_; diff --git a/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc b/content/renderer/child_frame_compositing_helper.cc index 89916e2..f98433a 100644 --- a/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc +++ b/content/renderer/child_frame_compositing_helper.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/renderer/browser_plugin/browser_plugin_compositing_helper.h" +#include "content/renderer/child_frame_compositing_helper.h" #include "cc/layers/delegated_frame_provider.h" #include "cc/layers/delegated_frame_resource_collection.h" @@ -17,9 +17,11 @@ #include "content/common/frame_messages.h" #include "content/common/gpu/client/context_provider_command_buffer.h" #include "content/renderer/browser_plugin/browser_plugin_manager.h" +#include "content/renderer/render_frame_impl.h" #include "content/renderer/render_thread_impl.h" #include "skia/ext/image_operations.h" #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" +#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" #include "third_party/khronos/GLES2/gl2.h" #include "ui/gfx/size_conversions.h" @@ -28,17 +30,37 @@ namespace content { -BrowserPluginCompositingHelper::SwapBuffersInfo::SwapBuffersInfo() +ChildFrameCompositingHelper::SwapBuffersInfo::SwapBuffersInfo() : route_id(0), output_surface_id(0), host_id(0), software_frame_id(0), - shared_memory(NULL) { + shared_memory(NULL) {} + +ChildFrameCompositingHelper* +ChildFrameCompositingHelper::CreateCompositingHelperForBrowserPlugin( + blink::WebPluginContainer* container, + BrowserPluginManager* manager, + int instance_id, + int host_routing_id) { + return new ChildFrameCompositingHelper( + container, NULL, manager, NULL, instance_id, host_routing_id); } -BrowserPluginCompositingHelper::BrowserPluginCompositingHelper( +ChildFrameCompositingHelper* +ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame( + blink::WebFrame* frame, + RenderFrameImpl* render_frame, + int host_routing_id) { + return new ChildFrameCompositingHelper( + NULL, frame, NULL, render_frame, 0, host_routing_id); +} + +ChildFrameCompositingHelper::ChildFrameCompositingHelper( blink::WebPluginContainer* container, + blink::WebFrame* frame, BrowserPluginManager* manager, + RenderFrameImpl* render_frame, int instance_id, int host_routing_id) : instance_id_(instance_id), @@ -51,20 +73,64 @@ BrowserPluginCompositingHelper::BrowserPluginCompositingHelper( software_ack_pending_(false), opaque_(true), container_(container), - browser_plugin_manager_(manager) { + frame_(frame), + browser_plugin_manager_(manager), + render_frame_(render_frame) {} + +ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {} + +void ChildFrameCompositingHelper::SendCompositorFrameSwappedACKToBrowser( + FrameHostMsg_CompositorFrameSwappedACK_Params& params) { + // This function will be removed when BrowserPluginManager is removed and + // BrowserPlugin is modified to use a RenderFrame. + if (browser_plugin_manager_) { + browser_plugin_manager_->Send( + new BrowserPluginHostMsg_CompositorFrameSwappedACK( + host_routing_id_, instance_id_, params)); + } else { + DCHECK(render_frame_); + render_frame_->Send( + new FrameHostMsg_CompositorFrameSwappedACK(host_routing_id_, params)); + } } -BrowserPluginCompositingHelper::~BrowserPluginCompositingHelper() { +void ChildFrameCompositingHelper::SendBuffersSwappedACKToBrowser( + FrameHostMsg_BuffersSwappedACK_Params& params) { + // This function will be removed when BrowserPluginManager is removed and + // BrowserPlugin is modified to use a RenderFrame. + if (browser_plugin_manager_) { + browser_plugin_manager_->Send(new BrowserPluginHostMsg_BuffersSwappedACK( + host_routing_id_, instance_id_, params)); + } else { + DCHECK(render_frame_); + render_frame_->Send( + new FrameHostMsg_BuffersSwappedACK(host_routing_id_, params)); + } } -void BrowserPluginCompositingHelper::CopyFromCompositingSurface( +void ChildFrameCompositingHelper::SendReclaimCompositorResourcesToBrowser( + FrameHostMsg_ReclaimCompositorResources_Params& params) { + // This function will be removed when BrowserPluginManager is removed and + // BrowserPlugin is modified to use a RenderFrame. + if (browser_plugin_manager_) { + browser_plugin_manager_->Send( + new BrowserPluginHostMsg_ReclaimCompositorResources( + host_routing_id_, instance_id_, params)); + } else { + DCHECK(render_frame_); + render_frame_->Send( + new FrameHostMsg_ReclaimCompositorResources(host_routing_id_, params)); + } +} + +void ChildFrameCompositingHelper::CopyFromCompositingSurface( int request_id, gfx::Rect source_rect, gfx::Size dest_size) { CHECK(background_layer_); scoped_ptr<cc::CopyOutputRequest> request = cc::CopyOutputRequest::CreateBitmapRequest(base::Bind( - &BrowserPluginCompositingHelper::CopyFromCompositingSurfaceHasResult, + &ChildFrameCompositingHelper::CopyFromCompositingSurfaceHasResult, this, request_id, dest_size)); @@ -72,7 +138,7 @@ void BrowserPluginCompositingHelper::CopyFromCompositingSurface( background_layer_->RequestCopyOfOutput(request.Pass()); } -void BrowserPluginCompositingHelper::DidCommitCompositorFrame() { +void ChildFrameCompositingHelper::DidCommitCompositorFrame() { if (software_ack_pending_) { FrameHostMsg_CompositorFrameSwappedACK_Params params; params.producing_host_id = last_host_id_; @@ -83,11 +149,7 @@ void BrowserPluginCompositingHelper::DidCommitCompositorFrame() { unacked_software_frames_.pop_back(); } - browser_plugin_manager_->Send( - new BrowserPluginHostMsg_CompositorFrameSwappedACK( - host_routing_id_, - instance_id_, - params)); + SendCompositorFrameSwappedACKToBrowser(params); software_ack_pending_ = false; } @@ -101,16 +163,12 @@ void BrowserPluginCompositingHelper::DidCommitCompositorFrame() { resource_collection_->TakeUnusedResourcesForChildCompositor( ¶ms.ack.resources); - browser_plugin_manager_->Send( - new BrowserPluginHostMsg_CompositorFrameSwappedACK( - host_routing_id_, - instance_id_, - params)); + SendCompositorFrameSwappedACKToBrowser(params); ack_pending_ = false; } -void BrowserPluginCompositingHelper::EnableCompositing(bool enable) { +void ChildFrameCompositingHelper::EnableCompositing(bool enable) { if (enable && !background_layer_.get()) { background_layer_ = cc::SolidColorLayer::Create(); background_layer_->SetMasksToBounds(true); @@ -119,10 +177,14 @@ void BrowserPluginCompositingHelper::EnableCompositing(bool enable) { web_layer_.reset(new webkit::WebLayerImpl(background_layer_)); } - container_->setWebLayer(enable ? web_layer_.get() : NULL); + if (container_) { + container_->setWebLayer(enable ? web_layer_.get() : NULL); + } else { + frame_->setRemoteWebLayer(enable ? web_layer_.get() : NULL); + } } -void BrowserPluginCompositingHelper::CheckSizeAndAdjustLayerProperties( +void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties( const gfx::Size& new_size, float device_scale_factor, cc::Layer* layer) { @@ -141,10 +203,9 @@ void BrowserPluginCompositingHelper::CheckSizeAndAdjustLayerProperties( background_layer_->SetIsDrawable(false); } -void BrowserPluginCompositingHelper::MailboxReleased( - SwapBuffersInfo mailbox, - unsigned sync_point, - bool lost_resource) { +void ChildFrameCompositingHelper::MailboxReleased(SwapBuffersInfo mailbox, + unsigned sync_point, + bool lost_resource) { if (mailbox.type == SOFTWARE_COMPOSITOR_FRAME) { delete mailbox.shared_memory; mailbox.shared_memory = NULL; @@ -180,11 +241,7 @@ void BrowserPluginCompositingHelper::MailboxReleased( params.gpu_route_id = mailbox.route_id; params.mailbox_name = mailbox_name; params.sync_point = sync_point; - browser_plugin_manager_->Send( - new BrowserPluginHostMsg_BuffersSwappedACK( - host_routing_id_, - instance_id_, - params)); + SendBuffersSwappedACKToBrowser(params); break; } case GL_COMPOSITOR_FRAME: { @@ -196,12 +253,7 @@ void BrowserPluginCompositingHelper::MailboxReleased( params.ack.gl_frame_data->mailbox = mailbox.name; params.ack.gl_frame_data->size = mailbox.size; params.ack.gl_frame_data->sync_point = sync_point; - - browser_plugin_manager_->Send( - new BrowserPluginHostMsg_CompositorFrameSwappedACK( - host_routing_id_, - instance_id_, - params)); + SendCompositorFrameSwappedACKToBrowser(params); break; } case SOFTWARE_COMPOSITOR_FRAME: @@ -209,7 +261,7 @@ void BrowserPluginCompositingHelper::MailboxReleased( } } -void BrowserPluginCompositingHelper::OnContainerDestroy() { +void ChildFrameCompositingHelper::OnContainerDestroy() { if (container_) container_->setWebLayer(NULL); container_ = NULL; @@ -227,7 +279,7 @@ void BrowserPluginCompositingHelper::OnContainerDestroy() { web_layer_.reset(); } -void BrowserPluginCompositingHelper::OnBuffersSwappedPrivate( +void ChildFrameCompositingHelper::OnBuffersSwappedPrivate( const SwapBuffersInfo& mailbox, unsigned sync_point, float device_scale_factor) { @@ -270,13 +322,12 @@ void BrowserPluginCompositingHelper::OnBuffersSwappedPrivate( // when a new buffer arrives. // Visually, this will either display a smaller part of the buffer // or introduce a gutter around it. - CheckSizeAndAdjustLayerProperties(mailbox.size, - device_scale_factor, - texture_layer_.get()); + CheckSizeAndAdjustLayerProperties( + mailbox.size, device_scale_factor, texture_layer_.get()); bool is_software_frame = mailbox.type == SOFTWARE_COMPOSITOR_FRAME; - bool current_mailbox_valid = is_software_frame ? - mailbox.shared_memory != NULL : !mailbox.name.IsZero(); + bool current_mailbox_valid = is_software_frame ? mailbox.shared_memory != NULL + : !mailbox.name.IsZero(); if (!is_software_frame && !last_mailbox_valid_) { SwapBuffersInfo empty_info = mailbox; empty_info.name.SetZero(); @@ -288,10 +339,11 @@ void BrowserPluginCompositingHelper::OnBuffersSwappedPrivate( cc::TextureMailbox texture_mailbox; scoped_ptr<cc::SingleReleaseCallback> release_callback; if (current_mailbox_valid) { - release_callback = cc::SingleReleaseCallback::Create( - base::Bind(&BrowserPluginCompositingHelper::MailboxReleased, - scoped_refptr<BrowserPluginCompositingHelper>(this), - mailbox)).Pass(); + release_callback = + cc::SingleReleaseCallback::Create( + base::Bind(&ChildFrameCompositingHelper::MailboxReleased, + scoped_refptr<ChildFrameCompositingHelper>(this), + mailbox)).Pass(); if (is_software_frame) texture_mailbox = cc::TextureMailbox(mailbox.shared_memory, mailbox.size); else @@ -304,7 +356,7 @@ void BrowserPluginCompositingHelper::OnBuffersSwappedPrivate( last_mailbox_valid_ = current_mailbox_valid; } -void BrowserPluginCompositingHelper::OnBuffersSwapped( +void ChildFrameCompositingHelper::OnBuffersSwapped( const gfx::Size& size, const std::string& mailbox_name, int gpu_route_id, @@ -320,11 +372,12 @@ void BrowserPluginCompositingHelper::OnBuffersSwapped( OnBuffersSwappedPrivate(swap_info, 0, device_scale_factor); } -void BrowserPluginCompositingHelper::OnCompositorFrameSwapped( +void ChildFrameCompositingHelper::OnCompositorFrameSwapped( scoped_ptr<cc::CompositorFrame> frame, int route_id, uint32 output_surface_id, int host_id) { + if (frame->gl_frame_data) { SwapBuffersInfo swap_info; swap_info.name = frame->gl_frame_data->mailbox; @@ -354,8 +407,7 @@ void BrowserPluginCompositingHelper::OnCompositorFrameSwapped( new base::SharedMemory(frame_data->handle, true)); const size_t size_in_bytes = 4 * frame_data->size.GetArea(); if (!shared_memory->Map(size_in_bytes)) { - LOG(ERROR) << "Failed to map shared memory of size " - << size_in_bytes; + LOG(ERROR) << "Failed to map shared memory of size " << size_in_bytes; // Send ACK right away. software_ack_pending_ = true; MailboxReleased(swap_info, 0, false); @@ -364,8 +416,7 @@ void BrowserPluginCompositingHelper::OnCompositorFrameSwapped( } swap_info.shared_memory = shared_memory.release(); - OnBuffersSwappedPrivate(swap_info, 0, - frame->metadata.device_scale_factor); + OnBuffersSwappedPrivate(swap_info, 0, frame->metadata.device_scale_factor); software_ack_pending_ = true; last_route_id_ = route_id; last_output_surface_id_ = output_surface_id; @@ -434,37 +485,34 @@ void BrowserPluginCompositingHelper::OnCompositorFrameSwapped( ack_pending_ = true; } -void BrowserPluginCompositingHelper::UpdateVisibility(bool visible) { +void ChildFrameCompositingHelper::UpdateVisibility(bool visible) { if (texture_layer_.get()) texture_layer_->SetIsDrawable(visible); if (delegated_layer_.get()) delegated_layer_->SetIsDrawable(visible); } -void BrowserPluginCompositingHelper::UnusedResourcesAreAvailable() { +void ChildFrameCompositingHelper::UnusedResourcesAreAvailable() { if (ack_pending_) return; SendReturnedDelegatedResources(); } -void BrowserPluginCompositingHelper::SendReturnedDelegatedResources() { - cc::CompositorFrameAck ack; +void ChildFrameCompositingHelper::SendReturnedDelegatedResources() { + FrameHostMsg_ReclaimCompositorResources_Params params; if (resource_collection_) - resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); - DCHECK(!ack.resources.empty()); + resource_collection_->TakeUnusedResourcesForChildCompositor( + ¶ms.ack.resources); + DCHECK(!params.ack.resources.empty()); - browser_plugin_manager_->Send( - new BrowserPluginHostMsg_ReclaimCompositorResources( - host_routing_id_, - instance_id_, - last_route_id_, - last_output_surface_id_, - last_host_id_, - ack)); + params.route_id = last_route_id_; + params.output_surface_id = last_output_surface_id_; + params.renderer_host_id = last_host_id_; + SendReclaimCompositorResourcesToBrowser(params); } -void BrowserPluginCompositingHelper::SetContentsOpaque(bool opaque) { +void ChildFrameCompositingHelper::SetContentsOpaque(bool opaque) { opaque_ = opaque; if (texture_layer_.get()) @@ -473,7 +521,7 @@ void BrowserPluginCompositingHelper::SetContentsOpaque(bool opaque) { delegated_layer_->SetContentsOpaque(opaque_); } -void BrowserPluginCompositingHelper::CopyFromCompositingSurfaceHasResult( +void ChildFrameCompositingHelper::CopyFromCompositingSurfaceHasResult( int request_id, gfx::Size dest_size, scoped_ptr<cc::CopyOutputResult> result) { @@ -483,15 +531,15 @@ void BrowserPluginCompositingHelper::CopyFromCompositingSurfaceHasResult( SkBitmap resized_bitmap; if (bitmap) { - resized_bitmap = skia::ImageOperations::Resize(*bitmap, - skia::ImageOperations::RESIZE_BEST, - dest_size.width(), - dest_size.height()); + resized_bitmap = + skia::ImageOperations::Resize(*bitmap, + skia::ImageOperations::RESIZE_BEST, + dest_size.width(), + dest_size.height()); } browser_plugin_manager_->Send( new BrowserPluginHostMsg_CopyFromCompositingSurfaceAck( - host_routing_id_, instance_id_, request_id, - resized_bitmap)); + host_routing_id_, instance_id_, request_id, resized_bitmap)); } } // namespace content diff --git a/content/renderer/browser_plugin/browser_plugin_compositing_helper.h b/content/renderer/child_frame_compositing_helper.h index 7f9a473..f543932 100644 --- a/content/renderer/browser_plugin/browser_plugin_compositing_helper.h +++ b/content/renderer/child_frame_compositing_helper.h @@ -1,9 +1,9 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_COMPOSITING_HELPER_H_ -#define CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_COMPOSITING_HELPER_H_ +#ifndef CONTENT_RENDERER_CHILD_FRAME_COMPOSITING_HELPER_H_ +#define CONTENT_RENDERER_CHILD_FRAME_COMPOSITING_HELPER_H_ #include <string> #include <vector> @@ -31,6 +31,7 @@ class DelegatedRendererLayer; } namespace blink { +class WebFrame; class WebPluginContainer; class WebLayer; } @@ -40,18 +41,29 @@ class Rect; class Size; } +struct FrameHostMsg_CompositorFrameSwappedACK_Params; +struct FrameHostMsg_BuffersSwappedACK_Params; +struct FrameHostMsg_ReclaimCompositorResources_Params; + namespace content { class BrowserPluginManager; +class RenderFrameImpl; -class CONTENT_EXPORT BrowserPluginCompositingHelper : - public base::RefCounted<BrowserPluginCompositingHelper>, - public cc::DelegatedFrameResourceCollectionClient { +class CONTENT_EXPORT ChildFrameCompositingHelper + : public base::RefCounted<ChildFrameCompositingHelper>, + public cc::DelegatedFrameResourceCollectionClient { public: - BrowserPluginCompositingHelper(blink::WebPluginContainer* container, - BrowserPluginManager* manager, - int instance_id, - int host_routing_id); + static ChildFrameCompositingHelper* CreateCompositingHelperForBrowserPlugin( + blink::WebPluginContainer* container, + BrowserPluginManager* manager, + int instance_id, + int host_routing_id); + static ChildFrameCompositingHelper* CreateCompositingHelperForRenderFrame( + blink::WebFrame* frame, + RenderFrameImpl* render_frame, + int host_routing_id); + void CopyFromCompositingSurface(int request_id, gfx::Rect source_rect, gfx::Size dest_size); @@ -75,8 +87,16 @@ class CONTENT_EXPORT BrowserPluginCompositingHelper : protected: // Friend RefCounted so that the dtor can be non-public. - friend class base::RefCounted<BrowserPluginCompositingHelper>; + friend class base::RefCounted<ChildFrameCompositingHelper>; + private: + ChildFrameCompositingHelper(blink::WebPluginContainer* container, + blink::WebFrame* frame, + BrowserPluginManager* manager, + RenderFrameImpl* render_frame, + int instance_id, + int host_routing_id); + enum SwapBuffersType { TEXTURE_IMAGE_TRANSPORT, GL_COMPOSITOR_FRAME, @@ -94,7 +114,13 @@ class CONTENT_EXPORT BrowserPluginCompositingHelper : unsigned software_frame_id; base::SharedMemory* shared_memory; }; - virtual ~BrowserPluginCompositingHelper(); + virtual ~ChildFrameCompositingHelper(); + void SendCompositorFrameSwappedACKToBrowser( + FrameHostMsg_CompositorFrameSwappedACK_Params& params); + void SendBuffersSwappedACKToBrowser( + FrameHostMsg_BuffersSwappedACK_Params& params); + void SendReclaimCompositorResourcesToBrowser( + FrameHostMsg_ReclaimCompositorResources_Params& params); void CheckSizeAndAdjustLayerProperties(const gfx::Size& new_size, float device_scale_factor, cc::Layer* layer); @@ -131,10 +157,14 @@ class CONTENT_EXPORT BrowserPluginCompositingHelper : scoped_refptr<cc::DelegatedRendererLayer> delegated_layer_; scoped_ptr<blink::WebLayer> web_layer_; blink::WebPluginContainer* container_; + blink::WebFrame* frame_; scoped_refptr<BrowserPluginManager> browser_plugin_manager_; + RenderFrameImpl* render_frame_; + + DISALLOW_COPY_AND_ASSIGN(ChildFrameCompositingHelper); }; } // namespace content -#endif // CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_COMPOSITING_HELPER_H_ +#endif // CONTENT_RENDERER_CHILD_FRAME_COMPOSITING_HELPER_H_ diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 81eae77..9d2e870 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc @@ -32,6 +32,7 @@ #include "content/renderer/accessibility/renderer_accessibility.h" #include "content/renderer/browser_plugin/browser_plugin.h" #include "content/renderer/browser_plugin/browser_plugin_manager.h" +#include "content/renderer/child_frame_compositing_helper.h" #include "content/renderer/internal_document_state_data.h" #include "content/renderer/npapi/plugin_channel_host.h" #include "content/renderer/render_thread_impl.h" @@ -387,6 +388,9 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) { bool msg_is_ok = true; IPC_BEGIN_MESSAGE_MAP_EX(RenderFrameImpl, msg, msg_is_ok) IPC_MESSAGE_HANDLER(FrameMsg_SwapOut, OnSwapOut) + IPC_MESSAGE_HANDLER(FrameMsg_BuffersSwapped, OnBuffersSwapped) + IPC_MESSAGE_HANDLER_GENERIC(FrameMsg_CompositorFrameSwapped, + OnCompositorFrameSwapped(msg)) IPC_END_MESSAGE_MAP_EX() if (!msg_is_ok) { @@ -428,11 +432,53 @@ void RenderFrameImpl::OnSwapOut() { // TODO(creis): Need to add a better way to do this that avoids running the // beforeunload handler. For now, we just run it a second time silently. render_view_->NavigateToSwappedOutURL(frame_); + + render_view_->RegisterSwappedOutChildFrame(this); } Send(new FrameHostMsg_SwapOut_ACK(routing_id_)); } +void RenderFrameImpl::OnBuffersSwapped( + const FrameMsg_BuffersSwapped_Params& params) { + if (!compositing_helper_.get()) { + compositing_helper_ = + ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame( + frame_, this, routing_id_); + compositing_helper_->EnableCompositing(true); + } + compositing_helper_->OnBuffersSwapped( + params.size, + params.mailbox_name, + params.gpu_route_id, + params.gpu_host_id, + render_view_->GetWebView()->deviceScaleFactor()); +} + +void RenderFrameImpl::OnCompositorFrameSwapped(const IPC::Message& message) { + FrameMsg_CompositorFrameSwapped::Param param; + if (!FrameMsg_CompositorFrameSwapped::Read(&message, ¶m)) + return; + scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame); + param.a.frame.AssignTo(frame.get()); + + if (!compositing_helper_.get()) { + compositing_helper_ = + ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame( + frame_, this, routing_id_); + compositing_helper_->EnableCompositing(true); + } + compositing_helper_->OnCompositorFrameSwapped(frame.Pass(), + param.a.producing_route_id, + param.a.output_surface_id, + param.a.producing_host_id); +} + +void RenderFrameImpl::DidCommitCompositorFrame() { + if (compositing_helper_) + compositing_helper_->DidCommitCompositorFrame(); +} + RenderView* RenderFrameImpl::GetRenderView() { return render_view_; } @@ -633,6 +679,8 @@ void RenderFrameImpl::frameDetached(blink::WebFrame* frame) { Send(new FrameHostMsg_Detach(routing_id_, parent_frame_id, frame->identifier())); + render_view_->UnregisterSwappedOutChildFrame(this); + // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be // sent before setting |is_detaching_| to true. In contrast, Observers // should only be notified afterwards so they cannot call back into here and diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index c09c18c..c86eb61 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h @@ -19,6 +19,8 @@ #include "third_party/WebKit/public/web/WebFrameClient.h" class TransportDIB; +struct FrameMsg_BuffersSwapped_Params; +struct FrameMsg_CompositorFrameSwapped_Params; namespace blink { class WebMouseEvent; @@ -33,6 +35,7 @@ class Rect; namespace content { +class ChildFrameCompositingHelper; class PepperPluginInstanceImpl; class RendererPpapiHost; class RenderFrameObserver; @@ -67,6 +70,10 @@ class CONTENT_EXPORT RenderFrameImpl return is_swapped_out_; } + // Out-of-process child frames receive a signal from RenderWidgetCompositor + // when a compositor frame has committed. + void DidCommitCompositorFrame(); + // TODO(jam): this is a temporary getter until all the code is transitioned // to using RenderFrame instead of RenderView. RenderViewImpl* render_view() { return render_view_; } @@ -318,6 +325,8 @@ class CONTENT_EXPORT RenderFrameImpl // The documentation for these functions should be in // content/common/*_messages.h for the message that the function is handling. void OnSwapOut(); + void OnBuffersSwapped(const FrameMsg_BuffersSwapped_Params& params); + void OnCompositorFrameSwapped(const IPC::Message& message); // Stores the WebFrame we are associated with. blink::WebFrame* frame_; @@ -338,6 +347,8 @@ class CONTENT_EXPORT RenderFrameImpl // All the registered observers. ObserverList<RenderFrameObserver> observers_; + scoped_refptr<ChildFrameCompositingHelper> compositing_helper_; + DISALLOW_COPY_AND_ASSIGN(RenderFrameImpl); }; diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 5197534..af78979 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -40,6 +40,7 @@ #include "content/renderer/ime_event_guard.h" #include "content/renderer/input/input_handler_manager.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" +#include "content/renderer/render_frame_impl.h" #include "content/renderer/render_process.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/renderer_webkitplatformsupport_impl.h" @@ -406,6 +407,7 @@ RenderWidget::~RenderWidget() { } current_paint_buf_ = NULL; } + // If we are swapped out, we have released already. if (!is_swapped_out_ && RenderProcess::current()) RenderProcess::current()->ReleaseProcess(); @@ -1897,6 +1899,8 @@ void RenderWidget::didBecomeReadyForAdditionalInput() { } void RenderWidget::DidCommitCompositorFrame() { + FOR_EACH_OBSERVER(RenderFrameImpl, swapped_out_frames_, + DidCommitCompositorFrame()); } void RenderWidget::didCommitAndDrawCompositorFrame() { @@ -2891,4 +2895,12 @@ RenderWidget::CreateGraphicsContext3D( return context.Pass(); } +void RenderWidget::RegisterSwappedOutChildFrame(RenderFrameImpl* frame) { + swapped_out_frames_.AddObserver(frame); +} + +void RenderWidget::UnregisterSwappedOutChildFrame(RenderFrameImpl* frame) { + swapped_out_frames_.RemoveObserver(frame); +} + } // namespace content diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index bed6e33..783e8f4 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h @@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/observer_list.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "cc/debug/rendering_stats_instrumentation.h" @@ -67,6 +68,7 @@ class Range; namespace content { class ExternalPopupMenu; class PepperPluginInstanceImpl; +class RenderFrameImpl; class RenderWidgetCompositor; class RenderWidgetTest; class ResizingModeSelector; @@ -113,6 +115,10 @@ class CONTENT_EXPORT RenderWidget bool is_fullscreen() const { return is_fullscreen_; } bool is_hidden() const { return is_hidden_; } + // Functions to track out-of-process frames for special notifications. + void RegisterSwappedOutChildFrame(RenderFrameImpl* frame); + void UnregisterSwappedOutChildFrame(RenderFrameImpl* frame); + // IPC::Listener virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; @@ -793,6 +799,10 @@ class CONTENT_EXPORT RenderWidget scoped_ptr<ResizingModeSelector> resizing_mode_selector_; + // A list of swapped out RenderFrames that need to be notified + // of compositing-related events (e.g. DidCommitCompositorFrame). + ObserverList<RenderFrameImpl> swapped_out_frames_; + DISALLOW_COPY_AND_ASSIGN(RenderWidget); }; diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc index a94a2bc..d645b31 100644 --- a/content/test/test_web_contents.cc +++ b/content/test/test_web_contents.cc @@ -7,6 +7,7 @@ #include <utility> #include "content/browser/browser_url_handler_impl.h" +#include "content/browser/frame_host/cross_process_frame_connector.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/site_instance_impl.h" @@ -91,7 +92,9 @@ WebPreferences TestWebContents::TestGetWebkitPrefs() { } bool TestWebContents::CreateRenderViewForRenderManager( - RenderViewHost* render_view_host, int opener_route_id) { + RenderViewHost* render_view_host, + int opener_route_id, + CrossProcessFrameConnector* frame_connector) { // This will go to a TestRenderViewHost. static_cast<RenderViewHostImpl*>( render_view_host)->CreateRenderView(base::string16(), diff --git a/content/test/test_web_contents.h b/content/test/test_web_contents.h index 3b9ccf4..fcdedeb 100644 --- a/content/test/test_web_contents.h +++ b/content/test/test_web_contents.h @@ -57,7 +57,9 @@ class TestWebContents : public WebContentsImpl, public WebContentsTester { // Prevent interaction with views. virtual bool CreateRenderViewForRenderManager( - RenderViewHost* render_view_host, int opener_route_id) OVERRIDE; + RenderViewHost* render_view_host, + int opener_route_id, + CrossProcessFrameConnector* frame_connector) OVERRIDE; virtual void UpdateRenderViewSizeForRenderManager() OVERRIDE {} // Returns a clone of this TestWebContents. The returned object is also a |