software_output_device_ozone_unittest.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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/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" 19 20namespace { 21 22class MockSurfaceOzone : public gfx::SurfaceOzoneCanvas { 23 public: 24 MockSurfaceOzone() {} 25 virtual ~MockSurfaceOzone() {} 26 27 // gfx::SurfaceOzoneCanvas overrides: 28 virtual bool ResizeCanvas(const gfx::Size& size) OVERRIDE { 29 surface_ = skia::AdoptRef(SkSurface::NewRaster( 30 SkImageInfo::MakeN32Premul(size.width(), size.height()))); 31 return true; 32 } 33 virtual skia::RefPtr<SkCanvas> GetCanvas() OVERRIDE { 34 return skia::SharePtr(surface_->getCanvas()); 35 } 36 virtual bool PresentCanvas() OVERRIDE { 37 NOTIMPLEMENTED(); 38 return true; 39 } 40 virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE { 41 return scoped_ptr<gfx::VSyncProvider>(); 42 } 43 44 private: 45 skia::RefPtr<SkSurface> surface_; 46 47 DISALLOW_COPY_AND_ASSIGN(MockSurfaceOzone); 48}; 49 50class MockSurfaceFactoryOzone : public gfx::SurfaceFactoryOzone { 51 public: 52 MockSurfaceFactoryOzone() {} 53 virtual ~MockSurfaceFactoryOzone() {} 54 55 virtual HardwareState InitializeHardware() OVERRIDE { 56 return SurfaceFactoryOzone::INITIALIZED; 57 } 58 59 virtual void ShutdownHardware() OVERRIDE {} 60 virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE { return 1; } 61 virtual bool LoadEGLGLES2Bindings( 62 AddGLLibraryCallback add_gl_library, 63 SetGLGetProcAddressProcCallback set_gl_get_proc_address) OVERRIDE { 64 return false; 65 } 66 virtual scoped_ptr<gfx::SurfaceOzoneCanvas> CreateCanvasForWidget( 67 gfx::AcceleratedWidget widget) OVERRIDE { 68 return make_scoped_ptr<gfx::SurfaceOzoneCanvas>(new MockSurfaceOzone()); 69 } 70 71 private: 72 DISALLOW_COPY_AND_ASSIGN(MockSurfaceFactoryOzone); 73}; 74 75} // namespace 76 77class SoftwareOutputDeviceOzoneTest : public testing::Test { 78 public: 79 SoftwareOutputDeviceOzoneTest(); 80 virtual ~SoftwareOutputDeviceOzoneTest(); 81 82 virtual void SetUp() OVERRIDE; 83 virtual void TearDown() OVERRIDE; 84 85 protected: 86 scoped_ptr<content::SoftwareOutputDeviceOzone> output_device_; 87 bool enable_pixel_output_; 88 89 private: 90 scoped_ptr<ui::Compositor> compositor_; 91 scoped_ptr<base::MessageLoop> message_loop_; 92 scoped_ptr<gfx::SurfaceFactoryOzone> surface_factory_; 93 94 DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceOzoneTest); 95}; 96 97SoftwareOutputDeviceOzoneTest::SoftwareOutputDeviceOzoneTest() 98 : enable_pixel_output_(false) { 99 message_loop_.reset(new base::MessageLoopForUI); 100} 101 102SoftwareOutputDeviceOzoneTest::~SoftwareOutputDeviceOzoneTest() { 103} 104 105void SoftwareOutputDeviceOzoneTest::SetUp() { 106 ui::InitializeContextFactoryForTests(enable_pixel_output_); 107 ui::Compositor::Initialize(); 108 109 surface_factory_.reset(new MockSurfaceFactoryOzone()); 110 gfx::SurfaceFactoryOzone::SetInstance(surface_factory_.get()); 111 112 const gfx::Size size(500, 400); 113 compositor_.reset(new ui::Compositor( 114 gfx::SurfaceFactoryOzone::GetInstance()->GetAcceleratedWidget())); 115 compositor_->SetScaleAndSize(1.0f, size); 116 117 output_device_.reset(new content::SoftwareOutputDeviceOzone( 118 compositor_.get())); 119 output_device_->Resize(size); 120} 121 122void SoftwareOutputDeviceOzoneTest::TearDown() { 123 output_device_.reset(); 124 compositor_.reset(); 125 surface_factory_.reset(); 126 ui::TerminateContextFactoryForTests(); 127 ui::Compositor::Terminate(); 128} 129 130class SoftwareOutputDeviceOzonePixelTest 131 : public SoftwareOutputDeviceOzoneTest { 132 protected: 133 virtual void SetUp() OVERRIDE; 134}; 135 136void SoftwareOutputDeviceOzonePixelTest::SetUp() { 137 enable_pixel_output_ = true; 138 SoftwareOutputDeviceOzoneTest::SetUp(); 139} 140 141TEST_F(SoftwareOutputDeviceOzoneTest, CheckClipAfterBeginPaint) { 142 gfx::Rect damage(10, 10, 100, 100); 143 SkCanvas* canvas = output_device_->BeginPaint(damage); 144 145 SkIRect sk_bounds; 146 canvas->getClipDeviceBounds(&sk_bounds); 147 148 EXPECT_EQ(damage.ToString(), gfx::SkIRectToRect(sk_bounds).ToString()); 149} 150 151TEST_F(SoftwareOutputDeviceOzoneTest, CheckClipAfterSecondBeginPaint) { 152 gfx::Rect damage(10, 10, 100, 100); 153 SkCanvas* canvas = output_device_->BeginPaint(damage); 154 155 cc::SoftwareFrameData frame; 156 output_device_->EndPaint(&frame); 157 158 damage = gfx::Rect(100, 100, 100, 100); 159 canvas = output_device_->BeginPaint(damage); 160 SkIRect sk_bounds; 161 canvas->getClipDeviceBounds(&sk_bounds); 162 163 EXPECT_EQ(damage.ToString(), gfx::SkIRectToRect(sk_bounds).ToString()); 164} 165 166TEST_F(SoftwareOutputDeviceOzoneTest, CheckCorrectResizeBehavior) { 167 gfx::Rect damage(0, 0, 100, 100); 168 gfx::Size size(200, 100); 169 // Reduce size. 170 output_device_->Resize(size); 171 172 SkCanvas* canvas = output_device_->BeginPaint(damage); 173 gfx::Size canvas_size(canvas->getDeviceSize().width(), 174 canvas->getDeviceSize().height()); 175 EXPECT_EQ(size.ToString(), canvas_size.ToString()); 176 177 size.SetSize(1000, 500); 178 // Increase size. 179 output_device_->Resize(size); 180 181 canvas = output_device_->BeginPaint(damage); 182 canvas_size.SetSize(canvas->getDeviceSize().width(), 183 canvas->getDeviceSize().height()); 184 EXPECT_EQ(size.ToString(), canvas_size.ToString()); 185 186} 187 188TEST_F(SoftwareOutputDeviceOzonePixelTest, CheckCopyToBitmap) { 189 const int width = 6; 190 const int height = 4; 191 const gfx::Rect area(width, height); 192 output_device_->Resize(area.size()); 193 SkCanvas* canvas = output_device_->BeginPaint(area); 194 195 // Clear the background to black. 196 canvas->drawColor(SK_ColorBLACK); 197 198 cc::SoftwareFrameData frame; 199 output_device_->EndPaint(&frame); 200 201 // Draw a white rectangle. 202 gfx::Rect damage(area.width() / 2, area.height() / 2); 203 canvas = output_device_->BeginPaint(damage); 204 205 canvas->drawColor(SK_ColorWHITE); 206 207 output_device_->EndPaint(&frame); 208 209 SkPMColor pixels[width * height]; 210 output_device_->CopyToPixels(area, pixels); 211 212 // Check that the copied bitmap contains the same pixel values as what we 213 // painted. 214 const SkPMColor white = SkPreMultiplyColor(SK_ColorWHITE); 215 const SkPMColor black = SkPreMultiplyColor(SK_ColorBLACK); 216 for (int i = 0; i < area.height(); ++i) { 217 for (int j = 0; j < area.width(); ++j) { 218 if (j < damage.width() && i < damage.height()) 219 EXPECT_EQ(white, pixels[i * area.width() + j]); 220 else 221 EXPECT_EQ(black, pixels[i * area.width() + j]); 222 } 223 } 224} 225