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.
5 #include "content/browser/frame_host/cross_process_frame_connector.h"
7 #include "cc/surfaces/surface.h"
8 #include "cc/surfaces/surface_manager.h"
9 #include "content/browser/compositor/surface_utils.h"
10 #include "content/browser/frame_host/frame_tree_node.h"
11 #include "content/browser/frame_host/render_frame_host_manager.h"
12 #include "content/browser/frame_host/render_frame_proxy_host.h"
13 #include "content/browser/frame_host/render_widget_host_view_child_frame.h"
14 #include "content/browser/renderer_host/render_view_host_impl.h"
15 #include "content/browser/renderer_host/render_widget_host_impl.h"
16 #include "content/browser/renderer_host/render_widget_host_view_base.h"
17 #include "content/common/frame_messages.h"
18 #include "content/common/gpu/gpu_messages.h"
19 #include "third_party/WebKit/public/web/WebInputEvent.h"
23 CrossProcessFrameConnector::CrossProcessFrameConnector(
24 RenderFrameProxyHost
* frame_proxy_in_parent_renderer
)
25 : frame_proxy_in_parent_renderer_(frame_proxy_in_parent_renderer
),
27 device_scale_factor_(1) {
30 CrossProcessFrameConnector::~CrossProcessFrameConnector() {
32 view_
->set_cross_process_frame_connector(NULL
);
35 bool CrossProcessFrameConnector::OnMessageReceived(const IPC::Message
& msg
) {
38 IPC_BEGIN_MESSAGE_MAP(CrossProcessFrameConnector
, msg
)
39 IPC_MESSAGE_HANDLER(FrameHostMsg_CompositorFrameSwappedACK
,
40 OnCompositorFrameSwappedACK
)
41 IPC_MESSAGE_HANDLER(FrameHostMsg_ReclaimCompositorResources
,
42 OnReclaimCompositorResources
)
43 IPC_MESSAGE_HANDLER(FrameHostMsg_ForwardInputEvent
, OnForwardInputEvent
)
44 IPC_MESSAGE_HANDLER(FrameHostMsg_FrameRectChanged
, OnFrameRectChanged
)
45 IPC_MESSAGE_HANDLER(FrameHostMsg_InitializeChildFrame
,
46 OnInitializeChildFrame
)
47 IPC_MESSAGE_HANDLER(FrameHostMsg_SatisfySequence
, OnSatisfySequence
)
48 IPC_MESSAGE_HANDLER(FrameHostMsg_RequireSequence
, OnRequireSequence
)
49 IPC_MESSAGE_UNHANDLED(handled
= false)
55 void CrossProcessFrameConnector::set_view(
56 RenderWidgetHostViewChildFrame
* view
) {
57 // Detach ourselves from the previous |view_|.
59 view_
->set_cross_process_frame_connector(NULL
);
63 // Attach ourselves to the new view and size it appropriately.
65 view_
->set_cross_process_frame_connector(this);
66 SetDeviceScaleFactor(device_scale_factor_
);
67 SetSize(child_frame_rect_
);
71 void CrossProcessFrameConnector::RenderProcessGone() {
72 frame_proxy_in_parent_renderer_
->Send(new FrameMsg_ChildFrameProcessGone(
73 frame_proxy_in_parent_renderer_
->GetRoutingID()));
76 void CrossProcessFrameConnector::ChildFrameCompositorFrameSwapped(
77 uint32 output_surface_id
,
80 scoped_ptr
<cc::CompositorFrame
> frame
) {
81 FrameMsg_CompositorFrameSwapped_Params params
;
82 frame
->AssignTo(¶ms
.frame
);
83 params
.output_surface_id
= output_surface_id
;
84 params
.producing_route_id
= route_id
;
85 params
.producing_host_id
= host_id
;
86 frame_proxy_in_parent_renderer_
->Send(new FrameMsg_CompositorFrameSwapped(
87 frame_proxy_in_parent_renderer_
->GetRoutingID(), params
));
90 void CrossProcessFrameConnector::SetChildFrameSurface(
91 const cc::SurfaceId
& surface_id
,
92 const gfx::Size
& frame_size
,
94 const cc::SurfaceSequence
& sequence
) {
95 frame_proxy_in_parent_renderer_
->Send(new FrameMsg_SetChildFrameSurface(
96 frame_proxy_in_parent_renderer_
->GetRoutingID(), surface_id
, frame_size
,
97 scale_factor
, sequence
));
100 void CrossProcessFrameConnector::OnSatisfySequence(
101 const cc::SurfaceSequence
& sequence
) {
102 std::vector
<uint32_t> sequences
;
103 sequences
.push_back(sequence
.sequence
);
104 cc::SurfaceManager
* manager
= GetSurfaceManager();
105 manager
->DidSatisfySequences(sequence
.id_namespace
, &sequences
);
108 void CrossProcessFrameConnector::OnRequireSequence(
109 const cc::SurfaceId
& id
,
110 const cc::SurfaceSequence
& sequence
) {
111 cc::SurfaceManager
* manager
= GetSurfaceManager();
112 cc::Surface
* surface
= manager
->GetSurfaceForId(id
);
114 LOG(ERROR
) << "Attempting to require callback on nonexistent surface";
117 surface
->AddDestructionDependency(sequence
);
120 void CrossProcessFrameConnector::OnCompositorFrameSwappedACK(
121 const FrameHostMsg_CompositorFrameSwappedACK_Params
& params
) {
122 RenderWidgetHostImpl::SendSwapCompositorFrameAck(params
.producing_route_id
,
123 params
.output_surface_id
,
124 params
.producing_host_id
,
128 void CrossProcessFrameConnector::OnReclaimCompositorResources(
129 const FrameHostMsg_ReclaimCompositorResources_Params
& params
) {
130 RenderWidgetHostImpl::SendReclaimCompositorResources(params
.route_id
,
131 params
.output_surface_id
,
132 params
.renderer_host_id
,
136 void CrossProcessFrameConnector::OnInitializeChildFrame(gfx::Rect frame_rect
,
137 float scale_factor
) {
138 if (scale_factor
!= device_scale_factor_
)
139 SetDeviceScaleFactor(scale_factor
);
141 if (!frame_rect
.size().IsEmpty())
145 gfx::Rect
CrossProcessFrameConnector::ChildFrameRect() {
146 return child_frame_rect_
;
149 void CrossProcessFrameConnector::GetScreenInfo(blink::WebScreenInfo
* results
) {
150 // Inner WebContents's root FrameTreeNode does not have a parent(), so
151 // GetRenderWidgetHostView() call below will fail.
152 // TODO(lazyboy): Fix this.
153 if (frame_proxy_in_parent_renderer_
->frame_tree_node()
155 ->ForInnerDelegate()) {
156 DCHECK(frame_proxy_in_parent_renderer_
->frame_tree_node()->IsMainFrame());
160 RenderWidgetHostView
* rwhv
=
161 frame_proxy_in_parent_renderer_
->GetRenderWidgetHostView();
163 static_cast<RenderWidgetHostViewBase
*>(rwhv
)->GetScreenInfo(results
);
166 void CrossProcessFrameConnector::OnForwardInputEvent(
167 const blink::WebInputEvent
* event
) {
171 RenderFrameHostManager
* manager
=
172 frame_proxy_in_parent_renderer_
->frame_tree_node()->render_manager();
173 RenderWidgetHostImpl
* parent_widget
=
174 manager
->ForInnerDelegate()
175 ? manager
->GetOuterRenderWidgetHostForKeyboardInput()
176 : frame_proxy_in_parent_renderer_
->GetRenderViewHost();
178 if (blink::WebInputEvent::isKeyboardEventType(event
->type
)) {
179 if (!parent_widget
->GetLastKeyboardEvent())
181 NativeWebKeyboardEvent
keyboard_event(
182 *parent_widget
->GetLastKeyboardEvent());
183 view_
->ProcessKeyboardEvent(keyboard_event
);
187 if (blink::WebInputEvent::isMouseEventType(event
->type
)) {
188 view_
->ProcessMouseEvent(*static_cast<const blink::WebMouseEvent
*>(event
));
192 if (event
->type
== blink::WebInputEvent::MouseWheel
) {
193 view_
->ProcessMouseWheelEvent(
194 *static_cast<const blink::WebMouseWheelEvent
*>(event
));
199 void CrossProcessFrameConnector::OnFrameRectChanged(
200 const gfx::Rect
& frame_rect
) {
201 if (!frame_rect
.size().IsEmpty())
205 void CrossProcessFrameConnector::SetDeviceScaleFactor(float scale_factor
) {
206 device_scale_factor_
= scale_factor
;
207 // The RenderWidgetHost is null in unit tests.
208 if (view_
&& view_
->GetRenderWidgetHost()) {
209 RenderWidgetHostImpl
* child_widget
=
210 RenderWidgetHostImpl::From(view_
->GetRenderWidgetHost());
211 child_widget
->NotifyScreenInfoChanged();
215 void CrossProcessFrameConnector::SetSize(gfx::Rect frame_rect
) {
216 child_frame_rect_
= frame_rect
;
218 view_
->SetSize(frame_rect
.size());
221 } // namespace content