software_output_device_ozone_unittest.cc revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
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.
4
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"
19
20namespace {
21
22class MockSurfaceOzone : public ui::SurfaceOzoneCanvas {
23 public:
24  MockSurfaceOzone() {}
25  virtual ~MockSurfaceOzone() {}
26
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())));
31  }
32  virtual skia::RefPtr<SkCanvas> GetCanvas() OVERRIDE {
33    return skia::SharePtr(surface_->getCanvas());
34  }
35  virtual void PresentCanvas(const gfx::Rect& damage) OVERRIDE {}
36  virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE {
37    return scoped_ptr<gfx::VSyncProvider>();
38  }
39
40 private:
41  skia::RefPtr<SkSurface> surface_;
42
43  DISALLOW_COPY_AND_ASSIGN(MockSurfaceOzone);
44};
45
46class MockSurfaceFactoryOzone : public ui::SurfaceFactoryOzone {
47 public:
48  MockSurfaceFactoryOzone() {}
49  virtual ~MockSurfaceFactoryOzone() {}
50
51  virtual HardwareState InitializeHardware() OVERRIDE {
52    return SurfaceFactoryOzone::INITIALIZED;
53  }
54
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 {
60    return false;
61  }
62  virtual scoped_ptr<ui::SurfaceOzoneCanvas> CreateCanvasForWidget(
63      gfx::AcceleratedWidget widget) OVERRIDE {
64    return make_scoped_ptr<ui::SurfaceOzoneCanvas>(new MockSurfaceOzone());
65  }
66
67 private:
68  DISALLOW_COPY_AND_ASSIGN(MockSurfaceFactoryOzone);
69};
70
71}  // namespace
72
73class SoftwareOutputDeviceOzoneTest : public testing::Test {
74 public:
75  SoftwareOutputDeviceOzoneTest();
76  virtual ~SoftwareOutputDeviceOzoneTest();
77
78  virtual void SetUp() OVERRIDE;
79  virtual void TearDown() OVERRIDE;
80
81 protected:
82  scoped_ptr<content::SoftwareOutputDeviceOzone> output_device_;
83  bool enable_pixel_output_;
84
85 private:
86  scoped_ptr<ui::Compositor> compositor_;
87  scoped_ptr<base::MessageLoop> message_loop_;
88  scoped_ptr<ui::SurfaceFactoryOzone> surface_factory_;
89
90  DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceOzoneTest);
91};
92
93SoftwareOutputDeviceOzoneTest::SoftwareOutputDeviceOzoneTest()
94    : enable_pixel_output_(false) {
95  message_loop_.reset(new base::MessageLoopForUI);
96}
97
98SoftwareOutputDeviceOzoneTest::~SoftwareOutputDeviceOzoneTest() {
99}
100
101void SoftwareOutputDeviceOzoneTest::SetUp() {
102  ui::ContextFactory* context_factory =
103      ui::InitializeContextFactoryForTests(enable_pixel_output_);
104
105  surface_factory_.reset(new MockSurfaceFactoryOzone());
106
107  const gfx::Size size(500, 400);
108  compositor_.reset(new ui::Compositor(
109      ui::SurfaceFactoryOzone::GetInstance()->GetAcceleratedWidget(),
110      context_factory));
111  compositor_->SetScaleAndSize(1.0f, size);
112
113  output_device_.reset(new content::SoftwareOutputDeviceOzone(
114      compositor_.get()));
115  output_device_->Resize(size, 1.f);
116}
117
118void SoftwareOutputDeviceOzoneTest::TearDown() {
119  output_device_.reset();
120  compositor_.reset();
121  surface_factory_.reset();
122  ui::TerminateContextFactoryForTests();
123}
124
125class SoftwareOutputDeviceOzonePixelTest
126    : public SoftwareOutputDeviceOzoneTest {
127 protected:
128  virtual void SetUp() OVERRIDE;
129};
130
131void SoftwareOutputDeviceOzonePixelTest::SetUp() {
132  enable_pixel_output_ = true;
133  SoftwareOutputDeviceOzoneTest::SetUp();
134}
135
136TEST_F(SoftwareOutputDeviceOzoneTest, CheckCorrectResizeBehavior) {
137  gfx::Rect damage(0, 0, 100, 100);
138  gfx::Size size(200, 100);
139  // Reduce size.
140  output_device_->Resize(size, 1.f);
141
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());
146
147  size.SetSize(1000, 500);
148  // Increase size.
149  output_device_->Resize(size, 1.f);
150
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());
155
156}
157
158TEST_F(SoftwareOutputDeviceOzonePixelTest, CheckCopyToBitmap) {
159  const int width = 6;
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);
164
165  // Clear the background to black.
166  canvas->drawColor(SK_ColorBLACK);
167
168  cc::SoftwareFrameData frame;
169  output_device_->EndPaint(&frame);
170
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);
175
176  canvas->drawColor(SK_ColorWHITE);
177
178  output_device_->EndPaint(&frame);
179
180  SkPMColor pixels[width * height];
181  output_device_->CopyToPixels(area, pixels);
182
183  // Check that the copied bitmap contains the same pixel values as what we
184  // painted.
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]);
191      else
192        EXPECT_EQ(black, pixels[i * area.width() + j]);
193    }
194  }
195}
196