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/SkDevice.h"
11 #include "third_party/skia/include/core/SkSurface.h"
12 #include "ui/compositor/compositor.h"
13 #include "ui/compositor/test/context_factories_for_test.h"
14 #include "ui/gfx/size.h"
15 #include "ui/gfx/skia_util.h"
16 #include "ui/gfx/vsync_provider.h"
17 #include "ui/gl/gl_implementation.h"
18 #include "ui/ozone/public/surface_factory_ozone.h"
19 #include "ui/ozone/public/surface_ozone_canvas.h"
23 class MockSurfaceOzone
: public ui::SurfaceOzoneCanvas
{
26 virtual ~MockSurfaceOzone() {}
28 // ui::SurfaceOzoneCanvas overrides:
29 virtual void ResizeCanvas(const gfx::Size
& size
) OVERRIDE
{
30 surface_
= skia::AdoptRef(SkSurface::NewRaster(
31 SkImageInfo::MakeN32Premul(size
.width(), size
.height())));
33 virtual skia::RefPtr
<SkCanvas
> GetCanvas() OVERRIDE
{
34 return skia::SharePtr(surface_
->getCanvas());
36 virtual void PresentCanvas(const gfx::Rect
& damage
) OVERRIDE
{}
37 virtual scoped_ptr
<gfx::VSyncProvider
> CreateVSyncProvider() OVERRIDE
{
38 return scoped_ptr
<gfx::VSyncProvider
>();
42 skia::RefPtr
<SkSurface
> surface_
;
44 DISALLOW_COPY_AND_ASSIGN(MockSurfaceOzone
);
47 class MockSurfaceFactoryOzone
: public ui::SurfaceFactoryOzone
{
49 MockSurfaceFactoryOzone() {}
50 virtual ~MockSurfaceFactoryOzone() {}
52 virtual bool LoadEGLGLES2Bindings(
53 AddGLLibraryCallback add_gl_library
,
54 SetGLGetProcAddressProcCallback set_gl_get_proc_address
) OVERRIDE
{
57 virtual scoped_ptr
<ui::SurfaceOzoneCanvas
> CreateCanvasForWidget(
58 gfx::AcceleratedWidget widget
) OVERRIDE
{
59 return make_scoped_ptr
<ui::SurfaceOzoneCanvas
>(new MockSurfaceOzone());
63 DISALLOW_COPY_AND_ASSIGN(MockSurfaceFactoryOzone
);
68 class SoftwareOutputDeviceOzoneTest
: public testing::Test
{
70 SoftwareOutputDeviceOzoneTest();
71 virtual ~SoftwareOutputDeviceOzoneTest();
73 virtual void SetUp() OVERRIDE
;
74 virtual void TearDown() OVERRIDE
;
77 scoped_ptr
<content::SoftwareOutputDeviceOzone
> output_device_
;
78 bool enable_pixel_output_
;
81 scoped_ptr
<ui::Compositor
> compositor_
;
82 scoped_ptr
<base::MessageLoop
> message_loop_
;
83 scoped_ptr
<ui::SurfaceFactoryOzone
> surface_factory_
;
85 DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceOzoneTest
);
88 SoftwareOutputDeviceOzoneTest::SoftwareOutputDeviceOzoneTest()
89 : enable_pixel_output_(false) {
90 message_loop_
.reset(new base::MessageLoopForUI
);
93 SoftwareOutputDeviceOzoneTest::~SoftwareOutputDeviceOzoneTest() {
96 void SoftwareOutputDeviceOzoneTest::SetUp() {
97 ui::ContextFactory
* context_factory
=
98 ui::InitializeContextFactoryForTests(enable_pixel_output_
);
100 surface_factory_
.reset(new MockSurfaceFactoryOzone());
102 const gfx::Size
size(500, 400);
103 const gfx::AcceleratedWidget kTestAcceleratedWidget
= 1;
105 new ui::Compositor(kTestAcceleratedWidget
,
107 base::MessageLoopProxy::current()));
108 compositor_
->SetScaleAndSize(1.0f
, size
);
110 output_device_
.reset(new content::SoftwareOutputDeviceOzone(
112 output_device_
->Resize(size
, 1.f
);
115 void SoftwareOutputDeviceOzoneTest::TearDown() {
116 output_device_
.reset();
118 surface_factory_
.reset();
119 ui::TerminateContextFactoryForTests();
122 class SoftwareOutputDeviceOzonePixelTest
123 : public SoftwareOutputDeviceOzoneTest
{
125 virtual void SetUp() OVERRIDE
;
128 void SoftwareOutputDeviceOzonePixelTest::SetUp() {
129 enable_pixel_output_
= true;
130 SoftwareOutputDeviceOzoneTest::SetUp();
133 TEST_F(SoftwareOutputDeviceOzoneTest
, CheckCorrectResizeBehavior
) {
134 gfx::Rect
damage(0, 0, 100, 100);
135 gfx::Size
size(200, 100);
137 output_device_
->Resize(size
, 1.f
);
139 SkCanvas
* canvas
= output_device_
->BeginPaint(damage
);
140 gfx::Size
canvas_size(canvas
->getDeviceSize().width(),
141 canvas
->getDeviceSize().height());
142 EXPECT_EQ(size
.ToString(), canvas_size
.ToString());
144 size
.SetSize(1000, 500);
146 output_device_
->Resize(size
, 1.f
);
148 canvas
= output_device_
->BeginPaint(damage
);
149 canvas_size
.SetSize(canvas
->getDeviceSize().width(),
150 canvas
->getDeviceSize().height());
151 EXPECT_EQ(size
.ToString(), canvas_size
.ToString());
155 TEST_F(SoftwareOutputDeviceOzonePixelTest
, CheckCopyToBitmap
) {
157 const int height
= 4;
158 const gfx::Rect
area(width
, height
);
159 output_device_
->Resize(area
.size(), 1.f
);
160 SkCanvas
* canvas
= output_device_
->BeginPaint(area
);
162 // Clear the background to black.
163 canvas
->drawColor(SK_ColorBLACK
);
165 cc::SoftwareFrameData frame
;
166 output_device_
->EndPaint(&frame
);
168 // Draw a white rectangle.
169 gfx::Rect
damage(area
.width() / 2, area
.height() / 2);
170 canvas
= output_device_
->BeginPaint(damage
);
171 canvas
->clipRect(gfx::RectToSkRect(damage
), SkRegion::kReplace_Op
);
173 canvas
->drawColor(SK_ColorWHITE
);
175 output_device_
->EndPaint(&frame
);
177 SkPMColor pixels
[width
* height
];
178 output_device_
->CopyToPixels(area
, pixels
);
180 // Check that the copied bitmap contains the same pixel values as what we
182 const SkPMColor white
= SkPreMultiplyColor(SK_ColorWHITE
);
183 const SkPMColor black
= SkPreMultiplyColor(SK_ColorBLACK
);
184 for (int i
= 0; i
< area
.height(); ++i
) {
185 for (int j
= 0; j
< area
.width(); ++j
) {
186 if (j
< damage
.width() && i
< damage
.height())
187 EXPECT_EQ(white
, pixels
[i
* area
.width() + j
]);
189 EXPECT_EQ(black
, pixels
[i
* area
.width() + j
]);