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/ozone/surface_factory_ozone.h"
14 #include "ui/gfx/ozone/surface_ozone_canvas.h"
15 #include "ui/gfx/size.h"
16 #include "ui/gfx/skia_util.h"
17 #include "ui/gfx/vsync_provider.h"
18 #include "ui/gl/gl_implementation.h"
22 class MockSurfaceOzone : public gfx::SurfaceOzoneCanvas {
25 virtual ~MockSurfaceOzone() {}
27 // gfx::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 gfx::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<gfx::SurfaceOzoneCanvas> CreateCanvasForWidget(
63 gfx::AcceleratedWidget widget) OVERRIDE {
64 return make_scoped_ptr<gfx::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<gfx::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::InitializeContextFactoryForTests(enable_pixel_output_);
103 ui::Compositor::Initialize();
105 surface_factory_.reset(new MockSurfaceFactoryOzone());
106 gfx::SurfaceFactoryOzone::SetInstance(surface_factory_.get());
108 const gfx::Size size(500, 400);
109 compositor_.reset(new ui::Compositor(
110 gfx::SurfaceFactoryOzone::GetInstance()->GetAcceleratedWidget()));
111 compositor_->SetScaleAndSize(1.0f, size);
113 output_device_.reset(new content::SoftwareOutputDeviceOzone(
115 output_device_->Resize(size);
118 void SoftwareOutputDeviceOzoneTest::TearDown() {
119 output_device_.reset();
121 surface_factory_.reset();
122 ui::TerminateContextFactoryForTests();
123 ui::Compositor::Terminate();
126 class SoftwareOutputDeviceOzonePixelTest
127 : public SoftwareOutputDeviceOzoneTest {
129 virtual void SetUp() OVERRIDE;
132 void SoftwareOutputDeviceOzonePixelTest::SetUp() {
133 enable_pixel_output_ = true;
134 SoftwareOutputDeviceOzoneTest::SetUp();
137 TEST_F(SoftwareOutputDeviceOzoneTest, CheckCorrectResizeBehavior) {
138 gfx::Rect damage(0, 0, 100, 100);
139 gfx::Size size(200, 100);
141 output_device_->Resize(size);
143 SkCanvas* canvas = output_device_->BeginPaint(damage);
144 gfx::Size canvas_size(canvas->getDeviceSize().width(),
145 canvas->getDeviceSize().height());
146 EXPECT_EQ(size.ToString(), canvas_size.ToString());
148 size.SetSize(1000, 500);
150 output_device_->Resize(size);
152 canvas = output_device_->BeginPaint(damage);
153 canvas_size.SetSize(canvas->getDeviceSize().width(),
154 canvas->getDeviceSize().height());
155 EXPECT_EQ(size.ToString(), canvas_size.ToString());
159 TEST_F(SoftwareOutputDeviceOzonePixelTest, CheckCopyToBitmap) {
161 const int height = 4;
162 const gfx::Rect area(width, height);
163 output_device_->Resize(area.size());
164 SkCanvas* canvas = output_device_->BeginPaint(area);
166 // Clear the background to black.
167 canvas->drawColor(SK_ColorBLACK);
169 cc::SoftwareFrameData frame;
170 output_device_->EndPaint(&frame);
172 // Draw a white rectangle.
173 gfx::Rect damage(area.width() / 2, area.height() / 2);
174 canvas = output_device_->BeginPaint(damage);
175 canvas->clipRect(gfx::RectToSkRect(damage), SkRegion::kReplace_Op);
177 canvas->drawColor(SK_ColorWHITE);
179 output_device_->EndPaint(&frame);
181 SkPMColor pixels[width * height];
182 output_device_->CopyToPixels(area, pixels);
184 // Check that the copied bitmap contains the same pixel values as what we
186 const SkPMColor white = SkPreMultiplyColor(SK_ColorWHITE);
187 const SkPMColor black = SkPreMultiplyColor(SK_ColorBLACK);
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(white, pixels[i * area.width() + j]);
193 EXPECT_EQ(black, pixels[i * area.width() + j]);