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/render_frame_proxy_host.h"
11 #include "content/browser/frame_host/render_widget_host_view_child_frame.h"
12 #include "content/browser/renderer_host/render_view_host_impl.h"
13 #include "content/browser/renderer_host/render_widget_host_impl.h"
14 #include "content/browser/renderer_host/render_widget_host_view_base.h"
15 #include "content/common/frame_messages.h"
16 #include "content/common/gpu/gpu_messages.h"
17 #include "third_party/WebKit/public/web/WebInputEvent.h"
21 CrossProcessFrameConnector::CrossProcessFrameConnector(
22 RenderFrameProxyHost
* frame_proxy_in_parent_renderer
)
23 : frame_proxy_in_parent_renderer_(frame_proxy_in_parent_renderer
),
25 device_scale_factor_(1) {
28 CrossProcessFrameConnector::~CrossProcessFrameConnector() {
30 view_
->set_cross_process_frame_connector(NULL
);
33 bool CrossProcessFrameConnector::OnMessageReceived(const IPC::Message
& msg
) {
36 IPC_BEGIN_MESSAGE_MAP(CrossProcessFrameConnector
, msg
)
37 IPC_MESSAGE_HANDLER(FrameHostMsg_CompositorFrameSwappedACK
,
38 OnCompositorFrameSwappedACK
)
39 IPC_MESSAGE_HANDLER(FrameHostMsg_ReclaimCompositorResources
,
40 OnReclaimCompositorResources
)
41 IPC_MESSAGE_HANDLER(FrameHostMsg_ForwardInputEvent
, OnForwardInputEvent
)
42 IPC_MESSAGE_HANDLER(FrameHostMsg_InitializeChildFrame
,
43 OnInitializeChildFrame
)
44 IPC_MESSAGE_HANDLER(FrameHostMsg_SatisfySequence
, OnSatisfySequence
)
45 IPC_MESSAGE_HANDLER(FrameHostMsg_RequireSequence
, OnRequireSequence
)
46 IPC_MESSAGE_UNHANDLED(handled
= false)
52 void CrossProcessFrameConnector::set_view(
53 RenderWidgetHostViewChildFrame
* view
) {
54 // Detach ourselves from the previous |view_|.
56 view_
->set_cross_process_frame_connector(NULL
);
60 // Attach ourselves to the new view and size it appropriately.
62 view_
->set_cross_process_frame_connector(this);
63 SetDeviceScaleFactor(device_scale_factor_
);
64 SetSize(child_frame_rect_
);
68 void CrossProcessFrameConnector::RenderProcessGone() {
69 frame_proxy_in_parent_renderer_
->Send(new FrameMsg_ChildFrameProcessGone(
70 frame_proxy_in_parent_renderer_
->GetRoutingID()));
73 void CrossProcessFrameConnector::ChildFrameCompositorFrameSwapped(
74 uint32 output_surface_id
,
77 scoped_ptr
<cc::CompositorFrame
> frame
) {
78 FrameMsg_CompositorFrameSwapped_Params params
;
79 frame
->AssignTo(¶ms
.frame
);
80 params
.output_surface_id
= output_surface_id
;
81 params
.producing_route_id
= route_id
;
82 params
.producing_host_id
= host_id
;
83 frame_proxy_in_parent_renderer_
->Send(new FrameMsg_CompositorFrameSwapped(
84 frame_proxy_in_parent_renderer_
->GetRoutingID(), params
));
87 void CrossProcessFrameConnector::SetChildFrameSurface(
88 const cc::SurfaceId
& surface_id
,
89 const gfx::Size
& frame_size
,
91 const cc::SurfaceSequence
& sequence
) {
92 frame_proxy_in_parent_renderer_
->Send(new FrameMsg_SetChildFrameSurface(
93 frame_proxy_in_parent_renderer_
->GetRoutingID(), surface_id
, frame_size
,
94 scale_factor
, sequence
));
97 void CrossProcessFrameConnector::OnSatisfySequence(
98 const cc::SurfaceSequence
& sequence
) {
99 std::vector
<uint32_t> sequences
;
100 sequences
.push_back(sequence
.sequence
);
101 cc::SurfaceManager
* manager
= GetSurfaceManager();
102 manager
->DidSatisfySequences(sequence
.id_namespace
, &sequences
);
105 void CrossProcessFrameConnector::OnRequireSequence(
106 const cc::SurfaceId
& id
,
107 const cc::SurfaceSequence
& sequence
) {
108 cc::SurfaceManager
* manager
= GetSurfaceManager();
109 cc::Surface
* surface
= manager
->GetSurfaceForId(id
);
111 LOG(ERROR
) << "Attempting to require callback on nonexistent surface";
114 surface
->AddDestructionDependency(sequence
);
117 void CrossProcessFrameConnector::OnCompositorFrameSwappedACK(
118 const FrameHostMsg_CompositorFrameSwappedACK_Params
& params
) {
119 RenderWidgetHostImpl::SendSwapCompositorFrameAck(params
.producing_route_id
,
120 params
.output_surface_id
,
121 params
.producing_host_id
,
125 void CrossProcessFrameConnector::OnReclaimCompositorResources(
126 const FrameHostMsg_ReclaimCompositorResources_Params
& params
) {
127 RenderWidgetHostImpl::SendReclaimCompositorResources(params
.route_id
,
128 params
.output_surface_id
,
129 params
.renderer_host_id
,
133 void CrossProcessFrameConnector::OnInitializeChildFrame(gfx::Rect frame_rect
,
134 float scale_factor
) {
135 if (scale_factor
!= device_scale_factor_
)
136 SetDeviceScaleFactor(scale_factor
);
138 if (!frame_rect
.size().IsEmpty())
142 gfx::Rect
CrossProcessFrameConnector::ChildFrameRect() {
143 return child_frame_rect_
;
146 void CrossProcessFrameConnector::GetScreenInfo(blink::WebScreenInfo
* results
) {
147 RenderWidgetHostView
* rwhv
=
148 frame_proxy_in_parent_renderer_
->GetRenderWidgetHostView();
150 static_cast<RenderWidgetHostViewBase
*>(rwhv
)->GetScreenInfo(results
);
153 void CrossProcessFrameConnector::OnForwardInputEvent(
154 const blink::WebInputEvent
* event
) {
158 RenderWidgetHostImpl
* child_widget
=
159 RenderWidgetHostImpl::From(view_
->GetRenderWidgetHost());
160 RenderWidgetHostImpl
* parent_widget
=
161 frame_proxy_in_parent_renderer_
->GetRenderViewHost();
163 if (blink::WebInputEvent::isKeyboardEventType(event
->type
)) {
164 if (!parent_widget
->GetLastKeyboardEvent())
166 NativeWebKeyboardEvent
keyboard_event(
167 *parent_widget
->GetLastKeyboardEvent());
168 child_widget
->ForwardKeyboardEvent(keyboard_event
);
172 if (blink::WebInputEvent::isMouseEventType(event
->type
)) {
173 child_widget
->ForwardMouseEvent(
174 *static_cast<const blink::WebMouseEvent
*>(event
));
178 if (event
->type
== blink::WebInputEvent::MouseWheel
) {
179 child_widget
->ForwardWheelEvent(
180 *static_cast<const blink::WebMouseWheelEvent
*>(event
));
185 void CrossProcessFrameConnector::SetDeviceScaleFactor(float scale_factor
) {
186 device_scale_factor_
= scale_factor
;
187 // The RenderWidgetHost is null in unit tests.
188 if (view_
&& view_
->GetRenderWidgetHost()) {
189 RenderWidgetHostImpl
* child_widget
=
190 RenderWidgetHostImpl::From(view_
->GetRenderWidgetHost());
191 child_widget
->NotifyScreenInfoChanged();
195 void CrossProcessFrameConnector::SetSize(gfx::Rect frame_rect
) {
196 child_frame_rect_
= frame_rect
;
198 view_
->SetSize(frame_rect
.size());
201 } // namespace content