1 // Copyright 2015 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 "base/run_loop.h"
6 #include "base/single_thread_task_runner.h"
7 #include "cc/test/fake_output_surface_client.h"
8 #include "cc/test/test_context_provider.h"
9 #include "cc/test/test_web_graphics_context_3d.h"
10 #include "content/browser/compositor/browser_compositor_output_surface.h"
11 #include "content/browser/compositor/browser_compositor_overlay_candidate_validator.h"
12 #include "content/browser/compositor/reflector_impl.h"
13 #include "content/browser/compositor/reflector_texture.h"
14 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/compositor/compositor.h"
17 #include "ui/compositor/layer.h"
18 #include "ui/compositor/test/context_factories_for_test.h"
20 #if defined(USE_OZONE)
21 #include "content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.h"
22 #include "ui/ozone/public/overlay_candidates_ozone.h"
23 #endif // defined(USE_OZONE)
27 class FakeTaskRunner
: public base::SingleThreadTaskRunner
{
31 bool PostNonNestableDelayedTask(const tracked_objects::Location
& from_here
,
32 const base::Closure
& task
,
33 base::TimeDelta delay
) override
{
36 bool PostDelayedTask(const tracked_objects::Location
& from_here
,
37 const base::Closure
& task
,
38 base::TimeDelta delay
) override
{
41 bool RunsTasksOnCurrentThread() const override
{ return true; }
44 ~FakeTaskRunner() override
{}
47 #if defined(USE_OZONE)
48 class TestOverlayCandidatesOzone
: public ui::OverlayCandidatesOzone
{
50 TestOverlayCandidatesOzone() {}
51 ~TestOverlayCandidatesOzone() override
{}
53 void CheckOverlaySupport(OverlaySurfaceCandidateList
* surfaces
) override
{
54 (*surfaces
)[0].overlay_handled
= true;
57 #endif // defined(USE_OZONE)
59 scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>
60 CreateTestValidatorOzone() {
61 #if defined(USE_OZONE)
62 return scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>(
63 new BrowserCompositorOverlayCandidateValidatorOzone(
64 0, scoped_ptr
<ui::OverlayCandidatesOzone
>(
65 new TestOverlayCandidatesOzone())));
68 #endif // defined(USE_OZONE)
71 class TestOutputSurface
: public BrowserCompositorOutputSurface
{
74 const scoped_refptr
<cc::ContextProvider
>& context_provider
,
75 const scoped_refptr
<ui::CompositorVSyncManager
>& vsync_manager
)
76 : BrowserCompositorOutputSurface(context_provider
,
79 CreateTestValidatorOzone().Pass()) {
80 surface_size_
= gfx::Size(256, 256);
81 device_scale_factor_
= 1.f
;
84 void SetFlip(bool flip
) { capabilities_
.flipped_output_surface
= flip
; }
86 void SwapBuffers(cc::CompositorFrame
* frame
) override
{}
88 void OnReflectorChanged() override
{
90 reflector_texture_
.reset();
92 reflector_texture_
.reset(new ReflectorTexture(context_provider()));
93 reflector_
->OnSourceTextureMailboxUpdated(reflector_texture_
->mailbox());
97 #if defined(OS_MACOSX)
98 void OnSurfaceDisplayed() override
{}
99 void SetSurfaceSuspendedForRecycle(bool suspended
) override
{}
100 bool SurfaceShouldNotShowFramesAfterSuspendForRecycle() const override
{
106 scoped_ptr
<ReflectorTexture
> reflector_texture_
;
109 const gfx::Rect
kSubRect(0, 0, 64, 64);
113 class ReflectorImplTest
: public testing::Test
{
115 void SetUp() override
{
116 bool enable_pixel_output
= false;
117 ui::ContextFactory
* context_factory
=
118 ui::InitializeContextFactoryForTests(enable_pixel_output
);
119 ImageTransportFactory::InitializeForUnitTests(
120 scoped_ptr
<ImageTransportFactory
>(
121 new NoTransportImageTransportFactory
));
122 message_loop_
.reset(new base::MessageLoop());
123 task_runner_
= message_loop_
->task_runner();
124 compositor_task_runner_
= new FakeTaskRunner();
126 new ui::Compositor(context_factory
, compositor_task_runner_
.get()));
127 compositor_
->SetAcceleratedWidgetAndStartCompositor(
128 gfx::kNullAcceleratedWidget
);
129 context_provider_
= cc::TestContextProvider::Create(
130 cc::TestWebGraphicsContext3D::Create().Pass());
132 scoped_ptr
<TestOutputSurface
>(
133 new TestOutputSurface(context_provider_
,
134 compositor_
->vsync_manager())).Pass();
135 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
137 root_layer_
.reset(new ui::Layer(ui::LAYER_SOLID_COLOR
));
138 compositor_
->SetRootLayer(root_layer_
.get());
139 mirroring_layer_
.reset(new ui::Layer(ui::LAYER_SOLID_COLOR
));
140 compositor_
->root_layer()->Add(mirroring_layer_
.get());
141 gfx::Size size
= output_surface_
->SurfaceSize();
142 mirroring_layer_
->SetBounds(gfx::Rect(size
.width(), size
.height()));
145 void SetUpReflector() {
146 reflector_
= make_scoped_ptr(
147 new ReflectorImpl(compositor_
.get(), mirroring_layer_
.get()));
148 reflector_
->OnSourceSurfaceReady(output_surface_
.get());
151 void TearDown() override
{
153 reflector_
->RemoveMirroringLayer(mirroring_layer_
.get());
154 cc::TextureMailbox mailbox
;
155 scoped_ptr
<cc::SingleReleaseCallback
> release
;
156 if (mirroring_layer_
->PrepareTextureMailbox(&mailbox
, &release
, false)) {
157 release
->Run(0, false);
160 ui::TerminateContextFactoryForTests();
161 ImageTransportFactory::Terminate();
164 void UpdateTexture() { reflector_
->OnSourcePostSubBuffer(kSubRect
); }
167 scoped_refptr
<base::SingleThreadTaskRunner
> compositor_task_runner_
;
168 scoped_refptr
<cc::ContextProvider
> context_provider_
;
169 cc::FakeOutputSurfaceClient output_surface_client_
;
170 scoped_ptr
<base::MessageLoop
> message_loop_
;
171 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner_
;
172 scoped_ptr
<ui::Compositor
> compositor_
;
173 scoped_ptr
<ui::Layer
> root_layer_
;
174 scoped_ptr
<ui::Layer
> mirroring_layer_
;
175 scoped_ptr
<ReflectorImpl
> reflector_
;
176 scoped_ptr
<TestOutputSurface
> output_surface_
;
180 TEST_F(ReflectorImplTest
, CheckNormalOutputSurface
) {
181 output_surface_
->SetFlip(false);
184 EXPECT_TRUE(mirroring_layer_
->TextureFlipped());
185 gfx::Rect expected_rect
=
186 kSubRect
+ gfx::Vector2d(0, output_surface_
->SurfaceSize().height()) -
187 gfx::Vector2d(0, kSubRect
.height());
188 EXPECT_EQ(expected_rect
, mirroring_layer_
->damaged_region());
191 TEST_F(ReflectorImplTest
, CheckInvertedOutputSurface
) {
192 output_surface_
->SetFlip(true);
195 EXPECT_FALSE(mirroring_layer_
->TextureFlipped());
196 EXPECT_EQ(kSubRect
, mirroring_layer_
->damaged_region());
199 #if defined(USE_OZONE)
200 TEST_F(ReflectorImplTest
, CheckOverlayNoReflector
) {
201 cc::OverlayCandidateList list
;
202 cc::OverlayCandidate plane_1
, plane_2
;
203 plane_1
.plane_z_order
= 0;
204 plane_2
.plane_z_order
= 1;
205 list
.push_back(plane_1
);
206 list
.push_back(plane_2
);
207 output_surface_
->GetOverlayCandidateValidator()->CheckOverlaySupport(&list
);
208 EXPECT_TRUE(list
[0].overlay_handled
);
211 TEST_F(ReflectorImplTest
, CheckOverlaySWMirroring
) {
213 cc::OverlayCandidateList list
;
214 cc::OverlayCandidate plane_1
, plane_2
;
215 plane_1
.plane_z_order
= 0;
216 plane_2
.plane_z_order
= 1;
217 list
.push_back(plane_1
);
218 list
.push_back(plane_2
);
219 output_surface_
->GetOverlayCandidateValidator()->CheckOverlaySupport(&list
);
220 EXPECT_FALSE(list
[0].overlay_handled
);
222 #endif // defined(USE_OZONE)
225 } // namespace content