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/render_widget_host_view_child_frame.h"
7 #include "base/basictypes.h"
8 #include "base/message_loop/message_loop.h"
9 #include "cc/surfaces/surface.h"
10 #include "cc/surfaces/surface_factory.h"
11 #include "cc/surfaces/surface_manager.h"
12 #include "cc/surfaces/surface_sequence.h"
13 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
14 #include "content/browser/frame_host/cross_process_frame_connector.h"
15 #include "content/browser/gpu/compositor_util.h"
16 #include "content/browser/gpu/gpu_surface_tracker.h"
17 #include "content/browser/renderer_host/render_widget_host_delegate.h"
18 #include "content/browser/renderer_host/render_widget_host_impl.h"
19 #include "content/common/view_messages.h"
20 #include "content/public/browser/render_widget_host_view.h"
21 #include "content/public/test/mock_render_process_host.h"
22 #include "content/public/test/test_browser_context.h"
23 #include "content/test/test_render_view_host.h"
24 #include "testing/gtest/include/gtest/gtest.h"
28 class MockRenderWidgetHostDelegate
: public RenderWidgetHostDelegate
{
30 MockRenderWidgetHostDelegate() {}
31 ~MockRenderWidgetHostDelegate() override
{}
33 void Cut() override
{}
34 void Copy() override
{}
35 void Paste() override
{}
36 void SelectAll() override
{}
39 class MockCrossProcessFrameConnector
: public CrossProcessFrameConnector
{
41 MockCrossProcessFrameConnector()
42 : CrossProcessFrameConnector(nullptr),
43 last_scale_factor_received_(0.f
),
44 received_delegated_frame_(false) {}
45 ~MockCrossProcessFrameConnector() override
{}
47 void ChildFrameCompositorFrameSwapped(
48 uint32 output_surface_id
,
51 scoped_ptr
<cc::CompositorFrame
> frame
) override
{
52 received_delegated_frame_
= true;
53 last_frame_size_received_
=
54 frame
->delegated_frame_data
->render_pass_list
.back()
56 last_scale_factor_received_
= frame
->metadata
.device_scale_factor
;
59 void SetChildFrameSurface(const cc::SurfaceId
& surface_id
,
60 const gfx::Size
& frame_size
,
62 const cc::SurfaceSequence
& sequence
) override
{
63 last_surface_id_received_
= surface_id
;
64 last_frame_size_received_
= frame_size
;
65 last_scale_factor_received_
= scale_factor
;
68 cc::SurfaceId last_surface_id_received_
;
69 gfx::Size last_frame_size_received_
;
70 float last_scale_factor_received_
;
72 bool received_delegated_frame_
;
77 class RenderWidgetHostViewChildFrameTest
: public testing::Test
{
79 RenderWidgetHostViewChildFrameTest() {}
81 void SetUp() override
{
82 browser_context_
.reset(new TestBrowserContext
);
84 // ImageTransportFactory doesn't exist on Android.
85 #if !defined(OS_ANDROID)
86 ImageTransportFactory::InitializeForUnitTests(
87 make_scoped_ptr(new NoTransportImageTransportFactory
));
90 MockRenderProcessHost
* process_host
=
91 new MockRenderProcessHost(browser_context_
.get());
92 int32 routing_id
= process_host
->GetNextRoutingID();
93 int32 surface_id
= GpuSurfaceTracker::Get()->AddSurfaceForRenderer(
94 process_host
->GetID(), routing_id
);
95 widget_host_
= new RenderWidgetHostImpl(&delegate_
, process_host
,
96 routing_id
, surface_id
, false);
97 view_
= new RenderWidgetHostViewChildFrame(widget_host_
);
99 test_frame_connector_
= new MockCrossProcessFrameConnector();
100 view_
->set_cross_process_frame_connector(test_frame_connector_
);
103 void TearDown() override
{
107 delete test_frame_connector_
;
109 browser_context_
.reset();
111 message_loop_
.DeleteSoon(FROM_HERE
, browser_context_
.release());
112 message_loop_
.RunUntilIdle();
113 #if !defined(OS_ANDROID)
114 ImageTransportFactory::Terminate();
118 cc::SurfaceId
surface_id() { return view_
->surface_id_
; }
121 base::MessageLoopForUI message_loop_
;
122 scoped_ptr
<BrowserContext
> browser_context_
;
123 MockRenderWidgetHostDelegate delegate_
;
125 // Tests should set these to NULL if they've already triggered their
127 RenderWidgetHostImpl
* widget_host_
;
128 RenderWidgetHostViewChildFrame
* view_
;
129 MockCrossProcessFrameConnector
* test_frame_connector_
;
132 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewChildFrameTest
);
135 scoped_ptr
<cc::CompositorFrame
> CreateDelegatedFrame(float scale_factor
,
137 const gfx::Rect
& damage
) {
138 scoped_ptr
<cc::CompositorFrame
> frame(new cc::CompositorFrame
);
139 frame
->metadata
.device_scale_factor
= scale_factor
;
140 frame
->delegated_frame_data
.reset(new cc::DelegatedFrameData
);
142 scoped_ptr
<cc::RenderPass
> pass
= cc::RenderPass::Create();
143 pass
->SetNew(cc::RenderPassId(1, 1), gfx::Rect(size
), damage
,
145 frame
->delegated_frame_data
->render_pass_list
.push_back(pass
.Pass());
149 TEST_F(RenderWidgetHostViewChildFrameTest
, VisibilityTest
) {
151 ASSERT_TRUE(view_
->IsShowing());
154 ASSERT_FALSE(view_
->IsShowing());
157 // Verify that OnSwapCompositorFrame behavior is correct when a delegated
158 // frame is received from a renderer process.
159 TEST_F(RenderWidgetHostViewChildFrameTest
, SwapCompositorFrame
) {
160 gfx::Size
view_size(100, 100);
161 gfx::Rect
view_rect(view_size
);
162 float scale_factor
= 1.f
;
164 view_
->SetSize(view_size
);
167 view_
->OnSwapCompositorFrame(
168 0, CreateDelegatedFrame(scale_factor
, view_size
, view_rect
));
170 if (UseSurfacesEnabled()) {
171 cc::SurfaceId id
= surface_id();
173 #if !defined(OS_ANDROID)
174 ImageTransportFactory
* factory
= ImageTransportFactory::GetInstance();
175 cc::SurfaceManager
* manager
= factory
->GetSurfaceManager();
176 cc::Surface
* surface
= manager
->GetSurfaceForId(id
);
177 EXPECT_TRUE(surface
);
178 // There should be a SurfaceSequence created by the RWHVChildFrame.
179 EXPECT_EQ(1u, surface
->GetDestructionDependencyCount());
182 // Surface ID should have been passed to CrossProcessFrameConnector to
183 // be sent to the embedding renderer.
184 EXPECT_EQ(id
, test_frame_connector_
->last_surface_id_received_
);
185 EXPECT_EQ(view_size
, test_frame_connector_
->last_frame_size_received_
);
186 EXPECT_EQ(scale_factor
,
187 test_frame_connector_
->last_scale_factor_received_
);
190 EXPECT_TRUE(test_frame_connector_
->received_delegated_frame_
);
191 EXPECT_EQ(view_size
, test_frame_connector_
->last_frame_size_received_
);
192 EXPECT_EQ(scale_factor
, test_frame_connector_
->last_scale_factor_received_
);
196 } // namespace content