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 "base/memory/scoped_ptr.h"
6 #include "base/message_loop/message_loop.h"
7 #include "cc/output/software_frame_data.h"
8 #include "content/browser/compositor/software_output_device_ozone.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/skia/include/core/SkSurface.h"
11 #include "ui/compositor/compositor.h"
12 #include "ui/compositor/test/context_factories_for_test.h"
13 #include "ui/gfx/size.h"
14 #include "ui/gfx/skia_util.h"
15 #include "ui/gfx/vsync_provider.h"
16 #include "ui/gl/gl_implementation.h"
17 #include "ui/ozone/public/surface_factory_ozone.h"
18 #include "ui/ozone/public/surface_ozone_canvas.h"
22 class MockSurfaceOzone
: public ui::SurfaceOzoneCanvas
{
25 virtual ~MockSurfaceOzone() {}
27 // ui::SurfaceOzoneCanvas overrides:
28 virtual void ResizeCanvas(const gfx::Size
& size
) OVERRIDE
{
29 surface_
= skia::AdoptRef(SkSurface::NewRaster(
30 SkImageInfo::MakeN32Premul(size
.width(), size
.height())));
32 virtual skia::RefPtr
<SkCanvas
> GetCanvas() OVERRIDE
{
33 return skia::SharePtr(surface_
->getCanvas());
35 virtual void PresentCanvas(const gfx::Rect
& damage
) OVERRIDE
{}
36 virtual scoped_ptr
<gfx::VSyncProvider
> CreateVSyncProvider() OVERRIDE
{
37 return scoped_ptr
<gfx::VSyncProvider
>();
41 skia::RefPtr
<SkSurface
> surface_
;
43 DISALLOW_COPY_AND_ASSIGN(MockSurfaceOzone
);
46 class MockSurfaceFactoryOzone
: public ui::SurfaceFactoryOzone
{
48 MockSurfaceFactoryOzone() {}
49 virtual ~MockSurfaceFactoryOzone() {}
51 virtual HardwareState
InitializeHardware() OVERRIDE
{
52 return SurfaceFactoryOzone::INITIALIZED
;
55 virtual void ShutdownHardware() OVERRIDE
{}
56 virtual gfx::AcceleratedWidget
GetAcceleratedWidget() OVERRIDE
{ return 1; }
57 virtual bool LoadEGLGLES2Bindings(
58 AddGLLibraryCallback add_gl_library
,
59 SetGLGetProcAddressProcCallback set_gl_get_proc_address
) OVERRIDE
{
62 virtual scoped_ptr
<ui::SurfaceOzoneCanvas
> CreateCanvasForWidget(
63 gfx::AcceleratedWidget widget
) OVERRIDE
{
64 return make_scoped_ptr
<ui::SurfaceOzoneCanvas
>(new MockSurfaceOzone());
68 DISALLOW_COPY_AND_ASSIGN(MockSurfaceFactoryOzone
);
73 class SoftwareOutputDeviceOzoneTest
: public testing::Test
{
75 SoftwareOutputDeviceOzoneTest();
76 virtual ~SoftwareOutputDeviceOzoneTest();
78 virtual void SetUp() OVERRIDE
;
79 virtual void TearDown() OVERRIDE
;
82 scoped_ptr
<content::SoftwareOutputDeviceOzone
> output_device_
;
83 bool enable_pixel_output_
;
86 scoped_ptr
<ui::Compositor
> compositor_
;
87 scoped_ptr
<base::MessageLoop
> message_loop_
;
88 scoped_ptr
<ui::SurfaceFactoryOzone
> surface_factory_
;
90 DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceOzoneTest
);
93 SoftwareOutputDeviceOzoneTest::SoftwareOutputDeviceOzoneTest()
94 : enable_pixel_output_(false) {
95 message_loop_
.reset(new base::MessageLoopForUI
);
98 SoftwareOutputDeviceOzoneTest::~SoftwareOutputDeviceOzoneTest() {
101 void SoftwareOutputDeviceOzoneTest::SetUp() {
102 ui::ContextFactory
* context_factory
=
103 ui::InitializeContextFactoryForTests(enable_pixel_output_
);
105 surface_factory_
.reset(new MockSurfaceFactoryOzone());
107 const gfx::Size
size(500, 400);
108 compositor_
.reset(new ui::Compositor(
109 ui::SurfaceFactoryOzone::GetInstance()->GetAcceleratedWidget(),
111 compositor_
->SetScaleAndSize(1.0f
, size
);
113 output_device_
.reset(new content::SoftwareOutputDeviceOzone(
115 output_device_
->Resize(size
, 1.f
);
118 void SoftwareOutputDeviceOzoneTest::TearDown() {
119 output_device_
.reset();
121 surface_factory_
.reset();
122 ui::TerminateContextFactoryForTests();
125 class SoftwareOutputDeviceOzonePixelTest
126 : public SoftwareOutputDeviceOzoneTest
{
128 virtual void SetUp() OVERRIDE
;
131 void SoftwareOutputDeviceOzonePixelTest::SetUp() {
132 enable_pixel_output_
= true;
133 SoftwareOutputDeviceOzoneTest::SetUp();
136 TEST_F(SoftwareOutputDeviceOzoneTest
, CheckCorrectResizeBehavior
) {
137 gfx::Rect
damage(0, 0, 100, 100);
138 gfx::Size
size(200, 100);
140 output_device_
->Resize(size
, 1.f
);
142 SkCanvas
* canvas
= output_device_
->BeginPaint(damage
);
143 gfx::Size
canvas_size(canvas
->getDeviceSize().width(),
144 canvas
->getDeviceSize().height());
145 EXPECT_EQ(size
.ToString(), canvas_size
.ToString());
147 size
.SetSize(1000, 500);
149 output_device_
->Resize(size
, 1.f
);
151 canvas
= output_device_
->BeginPaint(damage
);
152 canvas_size
.SetSize(canvas
->getDeviceSize().width(),
153 canvas
->getDeviceSize().height());
154 EXPECT_EQ(size
.ToString(), canvas_size
.ToString());
158 TEST_F(SoftwareOutputDeviceOzonePixelTest
, CheckCopyToBitmap
) {
160 const int height
= 4;
161 const gfx::Rect
area(width
, height
);
162 output_device_
->Resize(area
.size(), 1.f
);
163 SkCanvas
* canvas
= output_device_
->BeginPaint(area
);
165 // Clear the background to black.
166 canvas
->drawColor(SK_ColorBLACK
);
168 cc::SoftwareFrameData frame
;
169 output_device_
->EndPaint(&frame
);
171 // Draw a white rectangle.
172 gfx::Rect
damage(area
.width() / 2, area
.height() / 2);
173 canvas
= output_device_
->BeginPaint(damage
);
174 canvas
->clipRect(gfx::RectToSkRect(damage
), SkRegion::kReplace_Op
);
176 canvas
->drawColor(SK_ColorWHITE
);
178 output_device_
->EndPaint(&frame
);
180 SkPMColor pixels
[width
* height
];
181 output_device_
->CopyToPixels(area
, pixels
);
183 // Check that the copied bitmap contains the same pixel values as what we
185 const SkPMColor white
= SkPreMultiplyColor(SK_ColorWHITE
);
186 const SkPMColor black
= SkPreMultiplyColor(SK_ColorBLACK
);
187 for (int i
= 0; i
< area
.height(); ++i
) {
188 for (int j
= 0; j
< area
.width(); ++j
) {
189 if (j
< damage
.width() && i
< damage
.height())
190 EXPECT_EQ(white
, pixels
[i
* area
.width() + j
]);
192 EXPECT_EQ(black
, pixels
[i
* area
.width() + j
]);