1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/renderer/render_frame_proxy.h" 6 7 #include <map> 8 9 #include "base/lazy_instance.h" 10 #include "content/common/frame_messages.h" 11 #include "content/common/swapped_out_messages.h" 12 #include "content/renderer/child_frame_compositing_helper.h" 13 #include "content/renderer/render_frame_impl.h" 14 #include "content/renderer/render_thread_impl.h" 15 #include "content/renderer/render_view_impl.h" 16 #include "third_party/WebKit/public/web/WebView.h" 17 18 namespace content { 19 20 namespace { 21 22 typedef std::map<int, RenderFrameProxy*> RoutingIDProxyMap; 23 static base::LazyInstance<RoutingIDProxyMap> g_routing_id_proxy_map = 24 LAZY_INSTANCE_INITIALIZER; 25 26 } // namespace 27 28 // static 29 RenderFrameProxy* RenderFrameProxy::CreateFrameProxy(int routing_id, 30 int frame_routing_id) { 31 DCHECK_NE(routing_id, MSG_ROUTING_NONE); 32 RenderFrameProxy* proxy = new RenderFrameProxy(routing_id, frame_routing_id); 33 return proxy; 34 } 35 36 // static 37 RenderFrameProxy* RenderFrameProxy::FromRoutingID(int32 routing_id) { 38 RoutingIDProxyMap* proxies = g_routing_id_proxy_map.Pointer(); 39 RoutingIDProxyMap::iterator it = proxies->find(routing_id); 40 return it == proxies->end() ? NULL : it->second; 41 } 42 43 RenderFrameProxy::RenderFrameProxy(int routing_id, int frame_routing_id) 44 : routing_id_(routing_id), 45 frame_routing_id_(frame_routing_id) { 46 std::pair<RoutingIDProxyMap::iterator, bool> result = 47 g_routing_id_proxy_map.Get().insert(std::make_pair(routing_id_, this)); 48 CHECK(result.second) << "Inserting a duplicate item."; 49 RenderThread::Get()->AddRoute(routing_id_, this); 50 51 render_frame_ = RenderFrameImpl::FromRoutingID(frame_routing_id); 52 CHECK(render_frame_); 53 render_frame_->render_view()->RegisterRenderFrameProxy(this); 54 } 55 56 RenderFrameProxy::~RenderFrameProxy() { 57 render_frame_->render_view()->UnregisterRenderFrameProxy(this); 58 RenderThread::Get()->RemoveRoute(routing_id_); 59 g_routing_id_proxy_map.Get().erase(routing_id_); 60 } 61 62 blink::WebFrame* RenderFrameProxy::GetWebFrame() { 63 return render_frame_->GetWebFrame(); 64 } 65 66 void RenderFrameProxy::DidCommitCompositorFrame() { 67 if (compositing_helper_) 68 compositing_helper_->DidCommitCompositorFrame(); 69 } 70 71 bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) { 72 bool handled = true; 73 IPC_BEGIN_MESSAGE_MAP(RenderFrameProxy, msg) 74 IPC_MESSAGE_HANDLER(FrameMsg_DeleteProxy, OnDeleteProxy) 75 IPC_MESSAGE_HANDLER(FrameMsg_ChildFrameProcessGone, OnChildFrameProcessGone) 76 IPC_MESSAGE_HANDLER(FrameMsg_BuffersSwapped, OnBuffersSwapped) 77 IPC_MESSAGE_HANDLER_GENERIC(FrameMsg_CompositorFrameSwapped, 78 OnCompositorFrameSwapped(msg)) 79 IPC_MESSAGE_UNHANDLED(handled = false) 80 IPC_END_MESSAGE_MAP() 81 82 if (!handled) 83 return render_frame_->OnMessageReceived(msg); 84 85 return handled; 86 } 87 88 bool RenderFrameProxy::Send(IPC::Message* message) { 89 if (!SwappedOutMessages::CanSendWhileSwappedOut(message)) { 90 delete message; 91 return false; 92 } 93 message->set_routing_id(routing_id_); 94 return RenderThread::Get()->Send(message); 95 } 96 97 void RenderFrameProxy::OnDeleteProxy() { 98 RenderFrameImpl* render_frame = 99 RenderFrameImpl::FromRoutingID(frame_routing_id_); 100 CHECK(render_frame); 101 render_frame->set_render_frame_proxy(NULL); 102 103 delete this; 104 } 105 106 void RenderFrameProxy::OnChildFrameProcessGone() { 107 if (compositing_helper_) 108 compositing_helper_->ChildFrameGone(); 109 } 110 111 void RenderFrameProxy::OnBuffersSwapped( 112 const FrameMsg_BuffersSwapped_Params& params) { 113 if (!compositing_helper_.get()) { 114 compositing_helper_ = 115 ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame( 116 GetWebFrame(), this, routing_id_); 117 compositing_helper_->EnableCompositing(true); 118 } 119 compositing_helper_->OnBuffersSwapped( 120 params.size, 121 params.mailbox, 122 params.gpu_route_id, 123 params.gpu_host_id, 124 render_frame_->render_view()->GetWebView()->deviceScaleFactor()); 125 } 126 127 void RenderFrameProxy::OnCompositorFrameSwapped(const IPC::Message& message) { 128 FrameMsg_CompositorFrameSwapped::Param param; 129 if (!FrameMsg_CompositorFrameSwapped::Read(&message, ¶m)) 130 return; 131 132 scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame); 133 param.a.frame.AssignTo(frame.get()); 134 135 if (!compositing_helper_.get()) { 136 compositing_helper_ = 137 ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame( 138 GetWebFrame(), this, routing_id_); 139 compositing_helper_->EnableCompositing(true); 140 } 141 compositing_helper_->OnCompositorFrameSwapped(frame.Pass(), 142 param.a.producing_route_id, 143 param.a.output_surface_id, 144 param.a.producing_host_id, 145 param.a.shared_memory_handle); 146 } 147 148 } // namespace 149