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/renderer_host/render_widget_host_delegate.h"
17 #include "content/browser/renderer_host/render_widget_host_impl.h"
18 #include "content/common/view_messages.h"
19 #include "content/public/browser/render_widget_host_view.h"
20 #include "content/public/test/mock_render_process_host.h"
21 #include "content/public/test/test_browser_context.h"
22 #include "content/test/test_render_view_host.h"
23 #include "testing/gtest/include/gtest/gtest.h"
27 class MockRenderWidgetHostDelegate
: public RenderWidgetHostDelegate
{
29 MockRenderWidgetHostDelegate() {}
30 ~MockRenderWidgetHostDelegate() override
{}
33 class MockCrossProcessFrameConnector
: public CrossProcessFrameConnector
{
35 MockCrossProcessFrameConnector()
36 : CrossProcessFrameConnector(nullptr),
37 last_scale_factor_received_(0.f
),
38 received_delegated_frame_(false) {}
39 ~MockCrossProcessFrameConnector() override
{}
41 void ChildFrameCompositorFrameSwapped(
42 uint32 output_surface_id
,
45 scoped_ptr
<cc::CompositorFrame
> frame
) override
{
46 received_delegated_frame_
= true;
47 last_frame_size_received_
=
48 frame
->delegated_frame_data
->render_pass_list
.back()
50 last_scale_factor_received_
= frame
->metadata
.device_scale_factor
;
53 void SetChildFrameSurface(const cc::SurfaceId
& surface_id
,
54 const gfx::Size
& frame_size
,
56 const cc::SurfaceSequence
& sequence
) override
{
57 last_surface_id_received_
= surface_id
;
58 last_frame_size_received_
= frame_size
;
59 last_scale_factor_received_
= scale_factor
;
62 cc::SurfaceId last_surface_id_received_
;
63 gfx::Size last_frame_size_received_
;
64 float last_scale_factor_received_
;
66 bool received_delegated_frame_
;
71 class RenderWidgetHostViewChildFrameTest
: public testing::Test
{
73 RenderWidgetHostViewChildFrameTest() {}
75 void SetUp() override
{
76 browser_context_
.reset(new TestBrowserContext
);
78 // ImageTransportFactory doesn't exist on Android.
79 #if !defined(OS_ANDROID)
80 ImageTransportFactory::InitializeForUnitTests(
81 scoped_ptr
<ImageTransportFactory
>(
82 new NoTransportImageTransportFactory
));
85 MockRenderProcessHost
* process_host
=
86 new MockRenderProcessHost(browser_context_
.get());
87 widget_host_
= new RenderWidgetHostImpl(
88 &delegate_
, process_host
, MSG_ROUTING_NONE
, false);
89 view_
= new RenderWidgetHostViewChildFrame(widget_host_
);
91 test_frame_connector_
= new MockCrossProcessFrameConnector();
92 view_
->set_cross_process_frame_connector(test_frame_connector_
);
95 void TearDown() override
{
99 delete test_frame_connector_
;
101 browser_context_
.reset();
103 message_loop_
.DeleteSoon(FROM_HERE
, browser_context_
.release());
104 message_loop_
.RunUntilIdle();
105 #if !defined(OS_ANDROID)
106 ImageTransportFactory::Terminate();
110 cc::SurfaceId
surface_id() { return view_
->surface_id_
; }
113 base::MessageLoopForUI message_loop_
;
114 scoped_ptr
<BrowserContext
> browser_context_
;
115 MockRenderWidgetHostDelegate delegate_
;
117 // Tests should set these to NULL if they've already triggered their
119 RenderWidgetHostImpl
* widget_host_
;
120 RenderWidgetHostViewChildFrame
* view_
;
121 MockCrossProcessFrameConnector
* test_frame_connector_
;
124 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewChildFrameTest
);
127 scoped_ptr
<cc::CompositorFrame
> CreateDelegatedFrame(float scale_factor
,
129 const gfx::Rect
& damage
) {
130 scoped_ptr
<cc::CompositorFrame
> frame(new cc::CompositorFrame
);
131 frame
->metadata
.device_scale_factor
= scale_factor
;
132 frame
->delegated_frame_data
.reset(new cc::DelegatedFrameData
);
134 scoped_ptr
<cc::RenderPass
> pass
= cc::RenderPass::Create();
135 pass
->SetNew(cc::RenderPassId(1, 1), gfx::Rect(size
), damage
,
137 frame
->delegated_frame_data
->render_pass_list
.push_back(pass
.Pass());
141 TEST_F(RenderWidgetHostViewChildFrameTest
, VisibilityTest
) {
143 ASSERT_TRUE(view_
->IsShowing());
146 ASSERT_FALSE(view_
->IsShowing());
149 // Verify that OnSwapCompositorFrame behavior is correct when a delegated
150 // frame is received from a renderer process.
151 TEST_F(RenderWidgetHostViewChildFrameTest
, SwapCompositorFrame
) {
152 gfx::Size
view_size(100, 100);
153 gfx::Rect
view_rect(view_size
);
154 float scale_factor
= 1.f
;
156 view_
->SetSize(view_size
);
159 view_
->OnSwapCompositorFrame(
160 0, CreateDelegatedFrame(scale_factor
, view_size
, view_rect
));
162 if (UseSurfacesEnabled()) {
163 cc::SurfaceId id
= surface_id();
165 #if !defined(OS_ANDROID)
166 ImageTransportFactory
* factory
= ImageTransportFactory::GetInstance();
167 cc::SurfaceManager
* manager
= factory
->GetSurfaceManager();
168 cc::Surface
* surface
= manager
->GetSurfaceForId(id
);
169 EXPECT_TRUE(surface
);
170 // There should be a SurfaceSequence created by the RWHVChildFrame.
171 EXPECT_EQ(1u, surface
->GetDestructionDependencyCount());
174 // Surface ID should have been passed to CrossProcessFrameConnector to
175 // be sent to the embedding renderer.
176 EXPECT_EQ(id
, test_frame_connector_
->last_surface_id_received_
);
177 EXPECT_EQ(view_size
, test_frame_connector_
->last_frame_size_received_
);
178 EXPECT_EQ(scale_factor
,
179 test_frame_connector_
->last_scale_factor_received_
);
182 EXPECT_TRUE(test_frame_connector_
->received_delegated_frame_
);
183 EXPECT_EQ(view_size
, test_frame_connector_
->last_frame_size_received_
);
184 EXPECT_EQ(scale_factor
, test_frame_connector_
->last_scale_factor_received_
);
188 } // namespace content