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