1 // Copyright 2013 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/aura/software_output_device_ozone.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/skia/include/core/SkBitmapDevice.h"
11 #include "ui/compositor/compositor.h"
12 #include "ui/compositor/test/context_factories_for_test.h"
13 #include "ui/gfx/ozone/surface_factory_ozone.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"
21 class MockSurfaceFactoryOzone
: public gfx::SurfaceFactoryOzone
{
23 MockSurfaceFactoryOzone() {}
24 virtual ~MockSurfaceFactoryOzone() {}
26 virtual HardwareState
InitializeHardware() OVERRIDE
{
27 return SurfaceFactoryOzone::INITIALIZED
;
30 virtual void ShutdownHardware() OVERRIDE
{}
31 virtual gfx::AcceleratedWidget
GetAcceleratedWidget() OVERRIDE
{ return 1; }
32 virtual gfx::AcceleratedWidget
RealizeAcceleratedWidget(
33 gfx::AcceleratedWidget w
) OVERRIDE
{ return w
; }
34 virtual bool LoadEGLGLES2Bindings(
35 AddGLLibraryCallback add_gl_library
,
36 SetGLGetProcAddressProcCallback set_gl_get_proc_address
) OVERRIDE
{
39 virtual bool AttemptToResizeAcceleratedWidget(
40 gfx::AcceleratedWidget w
, const gfx::Rect
& bounds
) OVERRIDE
{
41 device_
= skia::AdoptRef(new SkBitmapDevice(SkBitmap::kARGB_8888_Config
,
45 canvas_
= skia::AdoptRef(new SkCanvas(device_
.get()));
48 virtual SkCanvas
* GetCanvasForWidget(gfx::AcceleratedWidget w
) OVERRIDE
{
51 virtual scoped_ptr
<gfx::VSyncProvider
> CreateVSyncProvider(
52 gfx::AcceleratedWidget w
) OVERRIDE
{
53 return scoped_ptr
<gfx::VSyncProvider
>();
56 skia::RefPtr
<SkBitmapDevice
> device_
;
57 skia::RefPtr
<SkCanvas
> canvas_
;
59 DISALLOW_COPY_AND_ASSIGN(MockSurfaceFactoryOzone
);
64 class SoftwareOutputDeviceOzoneTest
: public testing::Test
{
66 SoftwareOutputDeviceOzoneTest();
67 virtual ~SoftwareOutputDeviceOzoneTest();
69 virtual void SetUp() OVERRIDE
;
70 virtual void TearDown() OVERRIDE
;
73 scoped_ptr
<content::SoftwareOutputDeviceOzone
> output_device_
;
76 scoped_ptr
<ui::Compositor
> compositor_
;
77 scoped_ptr
<base::MessageLoop
> message_loop_
;
78 scoped_ptr
<gfx::SurfaceFactoryOzone
> surface_factory_
;
80 DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceOzoneTest
);
83 SoftwareOutputDeviceOzoneTest::SoftwareOutputDeviceOzoneTest() {
84 CHECK(gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL
));
85 message_loop_
.reset(new base::MessageLoopForUI
);
88 SoftwareOutputDeviceOzoneTest::~SoftwareOutputDeviceOzoneTest() {
91 void SoftwareOutputDeviceOzoneTest::SetUp() {
92 ui::InitializeContextFactoryForTests(false);
93 ui::Compositor::Initialize();
95 surface_factory_
.reset(new MockSurfaceFactoryOzone());
96 gfx::SurfaceFactoryOzone::SetInstance(surface_factory_
.get());
98 const gfx::Size
size(500, 400);
99 compositor_
.reset(new ui::Compositor(
100 gfx::SurfaceFactoryOzone::GetInstance()->GetAcceleratedWidget()));
101 compositor_
->SetScaleAndSize(1.0f
, size
);
103 output_device_
.reset(new content::SoftwareOutputDeviceOzone(
105 output_device_
->Resize(size
);
108 void SoftwareOutputDeviceOzoneTest::TearDown() {
109 output_device_
.reset();
111 surface_factory_
.reset();
112 ui::TerminateContextFactoryForTests();
113 ui::Compositor::Terminate();
116 TEST_F(SoftwareOutputDeviceOzoneTest
, CheckClipAfterBeginPaint
) {
117 gfx::Rect
damage(10, 10, 100, 100);
118 SkCanvas
* canvas
= output_device_
->BeginPaint(damage
);
121 canvas
->getClipDeviceBounds(&sk_bounds
);
123 EXPECT_EQ(damage
.ToString(), gfx::SkIRectToRect(sk_bounds
).ToString());
126 TEST_F(SoftwareOutputDeviceOzoneTest
, CheckClipAfterSecondBeginPaint
) {
127 gfx::Rect
damage(10, 10, 100, 100);
128 SkCanvas
* canvas
= output_device_
->BeginPaint(damage
);
130 cc::SoftwareFrameData frame
;
131 output_device_
->EndPaint(&frame
);
133 damage
= gfx::Rect(100, 100, 100, 100);
134 canvas
= output_device_
->BeginPaint(damage
);
136 canvas
->getClipDeviceBounds(&sk_bounds
);
138 EXPECT_EQ(damage
.ToString(), gfx::SkIRectToRect(sk_bounds
).ToString());
141 TEST_F(SoftwareOutputDeviceOzoneTest
, CheckCorrectResizeBehavior
) {
142 gfx::Rect
damage(0, 0, 100, 100);
143 gfx::Size
size(200, 100);
145 output_device_
->Resize(size
);
147 SkCanvas
* canvas
= output_device_
->BeginPaint(damage
);
148 gfx::Size
canvas_size(canvas
->getDeviceSize().width(),
149 canvas
->getDeviceSize().height());
150 EXPECT_EQ(size
.ToString(), canvas_size
.ToString());
152 size
.SetSize(1000, 500);
154 output_device_
->Resize(size
);
156 canvas
= output_device_
->BeginPaint(damage
);
157 canvas_size
.SetSize(canvas
->getDeviceSize().width(),
158 canvas
->getDeviceSize().height());
159 EXPECT_EQ(size
.ToString(), canvas_size
.ToString());
163 TEST_F(SoftwareOutputDeviceOzoneTest
, CheckCopyToBitmap
) {
164 const gfx::Rect
area(6, 4);
165 output_device_
->Resize(area
.size());
166 SkCanvas
* canvas
= output_device_
->BeginPaint(area
);
168 // Clear the background to black.
169 canvas
->drawColor(SK_ColorBLACK
);
171 cc::SoftwareFrameData frame
;
172 output_device_
->EndPaint(&frame
);
174 // Draw a white rectangle.
175 gfx::Rect
damage(area
.width() / 2, area
.height() / 2);
176 canvas
= output_device_
->BeginPaint(damage
);
178 canvas
->drawColor(SK_ColorWHITE
);
180 output_device_
->EndPaint(&frame
);
183 output_device_
->CopyToBitmap(area
, &bitmap
);
185 SkAutoLockPixels
pixel_lock(bitmap
);
186 // Check that the copied bitmap contains the same pixel values as what we
188 for (int i
= 0; i
< area
.height(); ++i
) {
189 for (int j
= 0; j
< area
.width(); ++j
) {
190 if (j
< damage
.width() && i
< damage
.height())
191 EXPECT_EQ(SK_ColorWHITE
, bitmap
.getColor(j
, i
));
193 EXPECT_EQ(SK_ColorBLACK
, bitmap
.getColor(j
, i
));