Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/render_frame_proxy.h" | 5 #include "content/renderer/render_frame_proxy.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "content/common/frame_messages.h" | 10 #include "content/common/frame_messages.h" |
| 11 #include "content/common/swapped_out_messages.h" | 11 #include "content/common/swapped_out_messages.h" |
| 12 #include "content/renderer/child_frame_compositing_helper.h" | 12 #include "content/renderer/child_frame_compositing_helper.h" |
| 13 #include "content/renderer/render_frame_impl.h" | 13 #include "content/renderer/render_frame_impl.h" |
| 14 #include "content/renderer/render_thread_impl.h" | 14 #include "content/renderer/render_thread_impl.h" |
| 15 #include "content/renderer/render_view_impl.h" | 15 #include "content/renderer/render_view_impl.h" |
| 16 #include "third_party/WebKit/public/web/WebView.h" | 16 #include "third_party/WebKit/public/web/WebView.h" |
| 17 | 17 |
| 18 namespace content { | 18 namespace content { |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 // Facilitates lookup of RenderFrameProxy by routing_id. | |
| 22 typedef std::map<int, RenderFrameProxy*> RoutingIDProxyMap; | 23 typedef std::map<int, RenderFrameProxy*> RoutingIDProxyMap; |
| 23 static base::LazyInstance<RoutingIDProxyMap> g_routing_id_proxy_map = | 24 static base::LazyInstance<RoutingIDProxyMap> g_routing_id_proxy_map = |
| 24 LAZY_INSTANCE_INITIALIZER; | 25 LAZY_INSTANCE_INITIALIZER; |
| 25 | 26 |
| 27 // Facilitates lookup of RenderFrameProxy by WebFrame. | |
| 28 typedef std::map<blink::WebFrame*, RenderFrameProxy*> FrameMap; | |
| 29 base::LazyInstance<FrameMap> g_frame_map = LAZY_INSTANCE_INITIALIZER; | |
| 30 | |
| 26 } // namespace | 31 } // namespace |
| 27 | 32 |
| 28 // static | 33 // static |
| 29 RenderFrameProxy* RenderFrameProxy::CreateFrameProxy(int routing_id, | 34 RenderFrameProxy* RenderFrameProxy::CreateProxyToReplaceFrame( |
| 30 int frame_routing_id) { | 35 int routing_id, |
| 31 DCHECK_NE(routing_id, MSG_ROUTING_NONE); | 36 int frame_routing_id) { |
|
dcheng
2014/07/15 18:44:14
Is there any particular reason to use a routing ID
ncarter (slow)
2014/07/16 01:13:52
Good suggestion. Done.
| |
| 32 RenderFrameProxy* proxy = new RenderFrameProxy(routing_id, frame_routing_id); | 37 CHECK_NE(routing_id, MSG_ROUTING_NONE); |
| 33 return proxy; | 38 CHECK_NE(frame_routing_id, MSG_ROUTING_NONE); |
| 39 | |
| 40 scoped_ptr<RenderFrameProxy> proxy( | |
| 41 new RenderFrameProxy(routing_id, frame_routing_id)); | |
| 42 RenderFrameImpl* render_frame = | |
| 43 RenderFrameImpl::FromRoutingID(frame_routing_id); | |
| 44 CHECK(render_frame); | |
| 45 #if 0 | |
| 46 // TODO(nick): Enable this code when we're ready to create WebRemoteFrames. | |
| 47 blink::WebRemoteFrame* web_frame = NULL; | |
| 48 if (render_frame->GetWebFrame()->parent() && | |
| 49 render_frame->GetWebFrame()->parent()->isWebRemoteFrame()) { | |
| 50 blink::WebRemoteFrame* parent_web_frame = | |
| 51 render_frame->GetWebFrame()->parent()->toWebRemoteFrame(); | |
| 52 web_frame = parent_web_frame->createRemoteChild("", proxy.get()); | |
|
dcheng
2014/07/15 18:44:14
Could we pre-emptively plumb the frame name throug
ncarter (slow)
2014/07/16 01:13:52
Since this is #if 0'ed code, I have no way to test
| |
| 53 } else { | |
| 54 web_frame = blink::WebRemoteFrame::create(proxy.get()); | |
| 55 } | |
| 56 #else | |
| 57 blink::WebFrame* web_frame = render_frame->GetWebFrame(); | |
| 58 #endif | |
| 59 proxy->Init(web_frame, render_frame->render_view()); | |
| 60 return proxy.release(); | |
| 61 } | |
| 62 | |
| 63 RenderFrameProxy* RenderFrameProxy::CreateFrameProxy( | |
| 64 int routing_id, | |
| 65 int parent_routing_id, | |
| 66 int render_view_routing_id) { | |
|
dcheng
2014/07/15 18:44:14
Similar question: can/should we pass in a RemoteFr
ncarter (slow)
2014/07/16 01:13:52
The code that calls this just has raw IDs from an
| |
| 67 scoped_ptr<RenderFrameProxy> proxy( | |
| 68 new RenderFrameProxy(routing_id, MSG_ROUTING_NONE)); | |
| 69 RenderViewImpl* render_view = NULL; | |
| 70 blink::WebRemoteFrame* web_frame = NULL; | |
| 71 if (parent_routing_id == MSG_ROUTING_NONE) { | |
| 72 // Create a top level frame. | |
| 73 render_view = RenderViewImpl::FromRoutingID(render_view_routing_id); | |
| 74 web_frame = blink::WebRemoteFrame::create(proxy.get()); | |
| 75 render_view->webview()->setMainFrame(web_frame); | |
| 76 } else { | |
| 77 // Create a frame under an existing parent. The parent is always expected to | |
| 78 // be a RenderFrameProxy, because navigations initiated by local frames | |
| 79 // should not wind up here. | |
| 80 RenderFrameProxy* parent = | |
| 81 RenderFrameProxy::FromRoutingID(parent_routing_id); | |
| 82 CHECK(parent); | |
| 83 CHECK(parent->web_frame()->isWebRemoteFrame()); | |
| 84 web_frame = parent->web_frame()->toWebRemoteFrame()->createRemoteChild( | |
| 85 "", proxy.get()); | |
| 86 render_view = parent->render_view(); | |
| 87 } | |
| 88 | |
| 89 proxy->Init(web_frame, render_view); | |
| 90 | |
| 91 return proxy.release(); | |
| 34 } | 92 } |
| 35 | 93 |
| 36 // static | 94 // static |
| 37 RenderFrameProxy* RenderFrameProxy::FromRoutingID(int32 routing_id) { | 95 RenderFrameProxy* RenderFrameProxy::FromRoutingID(int32 routing_id) { |
| 38 RoutingIDProxyMap* proxies = g_routing_id_proxy_map.Pointer(); | 96 RoutingIDProxyMap* proxies = g_routing_id_proxy_map.Pointer(); |
| 39 RoutingIDProxyMap::iterator it = proxies->find(routing_id); | 97 RoutingIDProxyMap::iterator it = proxies->find(routing_id); |
| 40 return it == proxies->end() ? NULL : it->second; | 98 return it == proxies->end() ? NULL : it->second; |
| 41 } | 99 } |
| 42 | 100 |
| 101 // static | |
| 102 RenderFrameProxy* RenderFrameProxy::FromWebFrame(blink::WebFrame* web_frame) { | |
| 103 FrameMap::iterator iter = g_frame_map.Get().find(web_frame); | |
| 104 if (iter != g_frame_map.Get().end()) { | |
| 105 RenderFrameProxy* proxy = iter->second; | |
| 106 DCHECK_EQ(web_frame, proxy->web_frame()); | |
| 107 return proxy; | |
| 108 } | |
| 109 return NULL; | |
| 110 } | |
| 111 | |
| 43 RenderFrameProxy::RenderFrameProxy(int routing_id, int frame_routing_id) | 112 RenderFrameProxy::RenderFrameProxy(int routing_id, int frame_routing_id) |
| 44 : routing_id_(routing_id), | 113 : routing_id_(routing_id), |
| 45 frame_routing_id_(frame_routing_id) { | 114 frame_routing_id_(frame_routing_id), |
| 115 web_frame_(NULL), | |
| 116 render_view_(NULL) { | |
| 46 std::pair<RoutingIDProxyMap::iterator, bool> result = | 117 std::pair<RoutingIDProxyMap::iterator, bool> result = |
| 47 g_routing_id_proxy_map.Get().insert(std::make_pair(routing_id_, this)); | 118 g_routing_id_proxy_map.Get().insert(std::make_pair(routing_id_, this)); |
| 48 CHECK(result.second) << "Inserting a duplicate item."; | 119 CHECK(result.second) << "Inserting a duplicate item."; |
| 49 RenderThread::Get()->AddRoute(routing_id_, this); | 120 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 } | 121 } |
| 55 | 122 |
| 56 RenderFrameProxy::~RenderFrameProxy() { | 123 RenderFrameProxy::~RenderFrameProxy() { |
| 57 render_frame_->render_view()->UnregisterRenderFrameProxy(this); | 124 render_view()->UnregisterRenderFrameProxy(this); |
| 125 | |
| 126 FrameMap::iterator it = g_frame_map.Get().find(web_frame_); | |
| 127 CHECK(it != g_frame_map.Get().end()); | |
| 128 CHECK_EQ(it->second, this); | |
| 129 g_frame_map.Get().erase(it); | |
| 130 | |
| 58 RenderThread::Get()->RemoveRoute(routing_id_); | 131 RenderThread::Get()->RemoveRoute(routing_id_); |
| 59 g_routing_id_proxy_map.Get().erase(routing_id_); | 132 g_routing_id_proxy_map.Get().erase(routing_id_); |
| 133 | |
| 134 // TODO(nick): Call close unconditionally when web_frame() is always remote. | |
| 135 if (web_frame()->isWebRemoteFrame()) | |
| 136 web_frame()->close(); | |
| 60 } | 137 } |
| 61 | 138 |
| 62 blink::WebFrame* RenderFrameProxy::GetWebFrame() { | 139 void RenderFrameProxy::Init(blink::WebFrame* web_frame, |
| 63 return render_frame_->GetWebFrame(); | 140 RenderViewImpl* render_view) { |
| 141 CHECK(web_frame); | |
| 142 CHECK(render_view); | |
| 143 | |
| 144 web_frame_ = web_frame; | |
| 145 render_view_ = render_view; | |
| 146 | |
| 147 // TODO(nick): Should all RenderFrameProxies remain observers of their views? | |
| 148 render_view_->RegisterRenderFrameProxy(this); | |
| 149 | |
| 150 std::pair<FrameMap::iterator, bool> result = | |
| 151 g_frame_map.Get().insert(std::make_pair(web_frame_, this)); | |
| 152 CHECK(result.second) << "Inserted a duplicate item."; | |
| 64 } | 153 } |
| 65 | 154 |
| 66 void RenderFrameProxy::DidCommitCompositorFrame() { | 155 void RenderFrameProxy::DidCommitCompositorFrame() { |
| 67 if (compositing_helper_) | 156 if (compositing_helper_) |
| 68 compositing_helper_->DidCommitCompositorFrame(); | 157 compositing_helper_->DidCommitCompositorFrame(); |
| 69 } | 158 } |
| 70 | 159 |
| 71 bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) { | 160 bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) { |
| 72 bool handled = true; | 161 bool handled = true; |
| 73 IPC_BEGIN_MESSAGE_MAP(RenderFrameProxy, msg) | 162 IPC_BEGIN_MESSAGE_MAP(RenderFrameProxy, msg) |
| 74 IPC_MESSAGE_HANDLER(FrameMsg_DeleteProxy, OnDeleteProxy) | 163 IPC_MESSAGE_HANDLER(FrameMsg_DeleteProxy, OnDeleteProxy) |
| 75 IPC_MESSAGE_HANDLER(FrameMsg_ChildFrameProcessGone, OnChildFrameProcessGone) | 164 IPC_MESSAGE_HANDLER(FrameMsg_ChildFrameProcessGone, OnChildFrameProcessGone) |
| 76 IPC_MESSAGE_HANDLER(FrameMsg_BuffersSwapped, OnBuffersSwapped) | 165 IPC_MESSAGE_HANDLER(FrameMsg_BuffersSwapped, OnBuffersSwapped) |
| 77 IPC_MESSAGE_HANDLER_GENERIC(FrameMsg_CompositorFrameSwapped, | 166 IPC_MESSAGE_HANDLER_GENERIC(FrameMsg_CompositorFrameSwapped, |
| 78 OnCompositorFrameSwapped(msg)) | 167 OnCompositorFrameSwapped(msg)) |
| 79 IPC_MESSAGE_UNHANDLED(handled = false) | 168 IPC_MESSAGE_UNHANDLED(handled = false) |
| 80 IPC_END_MESSAGE_MAP() | 169 IPC_END_MESSAGE_MAP() |
| 81 | 170 |
| 82 if (!handled) | 171 RenderFrameImpl* render_frame = |
| 83 return render_frame_->OnMessageReceived(msg); | 172 RenderFrameImpl::FromRoutingID(frame_routing_id_); |
| 173 if (!handled && render_frame) | |
| 174 return render_frame->OnMessageReceived(msg); | |
| 84 | 175 |
| 85 return handled; | 176 return handled; |
| 86 } | 177 } |
| 87 | 178 |
| 88 bool RenderFrameProxy::Send(IPC::Message* message) { | 179 bool RenderFrameProxy::Send(IPC::Message* message) { |
| 89 if (!SwappedOutMessages::CanSendWhileSwappedOut(message)) { | 180 if (!SwappedOutMessages::CanSendWhileSwappedOut(message)) { |
| 90 delete message; | 181 delete message; |
| 91 return false; | 182 return false; |
| 92 } | 183 } |
| 93 message->set_routing_id(routing_id_); | 184 message->set_routing_id(routing_id_); |
| 94 return RenderThread::Get()->Send(message); | 185 return RenderThread::Get()->Send(message); |
| 95 } | 186 } |
| 96 | 187 |
| 97 void RenderFrameProxy::OnDeleteProxy() { | 188 void RenderFrameProxy::OnDeleteProxy() { |
| 98 RenderFrameImpl* render_frame = | 189 RenderFrameImpl* render_frame = |
| 99 RenderFrameImpl::FromRoutingID(frame_routing_id_); | 190 RenderFrameImpl::FromRoutingID(frame_routing_id_); |
| 100 CHECK(render_frame); | 191 |
| 101 render_frame->set_render_frame_proxy(NULL); | 192 if (render_frame) |
| 193 render_frame->set_render_frame_proxy(NULL); | |
| 102 | 194 |
| 103 delete this; | 195 delete this; |
| 104 } | 196 } |
| 105 | 197 |
| 106 void RenderFrameProxy::OnChildFrameProcessGone() { | 198 void RenderFrameProxy::OnChildFrameProcessGone() { |
| 107 if (compositing_helper_) | 199 if (compositing_helper_) |
| 108 compositing_helper_->ChildFrameGone(); | 200 compositing_helper_->ChildFrameGone(); |
| 109 } | 201 } |
| 110 | 202 |
| 111 void RenderFrameProxy::OnBuffersSwapped( | 203 void RenderFrameProxy::OnBuffersSwapped( |
| 112 const FrameMsg_BuffersSwapped_Params& params) { | 204 const FrameMsg_BuffersSwapped_Params& params) { |
| 113 if (!compositing_helper_.get()) { | 205 if (!compositing_helper_) { |
| 114 compositing_helper_ = | 206 compositing_helper_ = |
| 115 ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame( | 207 ChildFrameCompositingHelper::CreateForRenderFrameProxy(this); |
| 116 GetWebFrame(), this, routing_id_); | |
| 117 compositing_helper_->EnableCompositing(true); | 208 compositing_helper_->EnableCompositing(true); |
| 118 } | 209 } |
| 119 compositing_helper_->OnBuffersSwapped( | 210 compositing_helper_->OnBuffersSwapped( |
| 120 params.size, | 211 params.size, |
| 121 params.mailbox, | 212 params.mailbox, |
| 122 params.gpu_route_id, | 213 params.gpu_route_id, |
| 123 params.gpu_host_id, | 214 params.gpu_host_id, |
| 124 render_frame_->render_view()->GetWebView()->deviceScaleFactor()); | 215 web_frame()->view()->deviceScaleFactor()); |
| 125 } | 216 } |
| 126 | 217 |
| 127 void RenderFrameProxy::OnCompositorFrameSwapped(const IPC::Message& message) { | 218 void RenderFrameProxy::OnCompositorFrameSwapped(const IPC::Message& message) { |
| 128 FrameMsg_CompositorFrameSwapped::Param param; | 219 FrameMsg_CompositorFrameSwapped::Param param; |
| 129 if (!FrameMsg_CompositorFrameSwapped::Read(&message, ¶m)) | 220 if (!FrameMsg_CompositorFrameSwapped::Read(&message, ¶m)) |
| 130 return; | 221 return; |
| 131 | 222 |
| 132 scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame); | 223 scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame); |
| 133 param.a.frame.AssignTo(frame.get()); | 224 param.a.frame.AssignTo(frame.get()); |
| 134 | 225 |
| 135 if (!compositing_helper_.get()) { | 226 if (!compositing_helper_) { |
| 136 compositing_helper_ = | 227 compositing_helper_ = |
| 137 ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame( | 228 ChildFrameCompositingHelper::CreateForRenderFrameProxy(this); |
| 138 GetWebFrame(), this, routing_id_); | |
| 139 compositing_helper_->EnableCompositing(true); | 229 compositing_helper_->EnableCompositing(true); |
| 140 } | 230 } |
| 141 compositing_helper_->OnCompositorFrameSwapped(frame.Pass(), | 231 compositing_helper_->OnCompositorFrameSwapped(frame.Pass(), |
| 142 param.a.producing_route_id, | 232 param.a.producing_route_id, |
| 143 param.a.output_surface_id, | 233 param.a.output_surface_id, |
| 144 param.a.producing_host_id, | 234 param.a.producing_host_id, |
| 145 param.a.shared_memory_handle); | 235 param.a.shared_memory_handle); |
| 146 } | 236 } |
| 147 | 237 |
| 148 } // namespace | 238 } // namespace |
| OLD | NEW |