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