root/content/browser/compositor/software_output_device_ozone_unittest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. InitializeCanvas
  2. ResizeCanvas
  3. GetCanvas
  4. InitializeHardware
  5. ShutdownHardware
  6. GetAcceleratedWidget
  7. LoadEGLGLES2Bindings
  8. CreateSurfaceForWidget
  9. SetUp
  10. TearDown
  11. SetUp
  12. TEST_F
  13. TEST_F
  14. TEST_F
  15. TEST_F

// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "cc/output/software_frame_data.h"
#include "content/browser/compositor/software_output_device_ozone.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/test/context_factories_for_test.h"
#include "ui/gfx/ozone/surface_factory_ozone.h"
#include "ui/gfx/ozone/surface_ozone_base.h"
#include "ui/gfx/size.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/vsync_provider.h"
#include "ui/gl/gl_implementation.h"

namespace {

class MockSurfaceOzone : public gfx::SurfaceOzoneBase {
 public:
  MockSurfaceOzone() {}
  virtual ~MockSurfaceOzone() {}

  // gfx::SurfaceOzoneBase overrides:
  virtual bool InitializeCanvas() OVERRIDE { return true; }
  virtual bool ResizeCanvas(const gfx::Size& size) OVERRIDE {
    surface_ = skia::AdoptRef(SkSurface::NewRaster(
        SkImageInfo::MakeN32Premul(size.width(), size.height())));
    return true;
  }
  virtual skia::RefPtr<SkCanvas> GetCanvas() OVERRIDE {
    return skia::SharePtr(surface_->getCanvas());
  }

 private:
  skia::RefPtr<SkSurface> surface_;

  DISALLOW_COPY_AND_ASSIGN(MockSurfaceOzone);
};

class MockSurfaceFactoryOzone : public gfx::SurfaceFactoryOzone {
 public:
  MockSurfaceFactoryOzone() {}
  virtual ~MockSurfaceFactoryOzone() {}

  virtual HardwareState InitializeHardware() OVERRIDE {
    return SurfaceFactoryOzone::INITIALIZED;
  }

  virtual void ShutdownHardware() OVERRIDE {}
  virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE { return 1; }
  virtual bool LoadEGLGLES2Bindings(
      AddGLLibraryCallback add_gl_library,
      SetGLGetProcAddressProcCallback set_gl_get_proc_address) OVERRIDE {
    return false;
  }
  virtual scoped_ptr<gfx::SurfaceOzone> CreateSurfaceForWidget(
      gfx::AcceleratedWidget widget) OVERRIDE {
    return make_scoped_ptr<gfx::SurfaceOzone>(new MockSurfaceOzone());
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(MockSurfaceFactoryOzone);
};

}  // namespace

class SoftwareOutputDeviceOzoneTest : public testing::Test {
 public:
  SoftwareOutputDeviceOzoneTest();
  virtual ~SoftwareOutputDeviceOzoneTest();

  virtual void SetUp() OVERRIDE;
  virtual void TearDown() OVERRIDE;

 protected:
  scoped_ptr<content::SoftwareOutputDeviceOzone> output_device_;
  bool enable_pixel_output_;

 private:
  scoped_ptr<ui::Compositor> compositor_;
  scoped_ptr<base::MessageLoop> message_loop_;
  scoped_ptr<gfx::SurfaceFactoryOzone> surface_factory_;

  DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceOzoneTest);
};

SoftwareOutputDeviceOzoneTest::SoftwareOutputDeviceOzoneTest()
    : enable_pixel_output_(false) {
  message_loop_.reset(new base::MessageLoopForUI);
}

SoftwareOutputDeviceOzoneTest::~SoftwareOutputDeviceOzoneTest() {
}

void SoftwareOutputDeviceOzoneTest::SetUp() {
  ui::InitializeContextFactoryForTests(enable_pixel_output_);
  ui::Compositor::Initialize();

  surface_factory_.reset(new MockSurfaceFactoryOzone());
  gfx::SurfaceFactoryOzone::SetInstance(surface_factory_.get());

  const gfx::Size size(500, 400);
  compositor_.reset(new ui::Compositor(
      gfx::SurfaceFactoryOzone::GetInstance()->GetAcceleratedWidget()));
  compositor_->SetScaleAndSize(1.0f, size);

  output_device_.reset(new content::SoftwareOutputDeviceOzone(
      compositor_.get()));
  output_device_->Resize(size);
}

void SoftwareOutputDeviceOzoneTest::TearDown() {
  output_device_.reset();
  compositor_.reset();
  surface_factory_.reset();
  ui::TerminateContextFactoryForTests();
  ui::Compositor::Terminate();
}

class SoftwareOutputDeviceOzonePixelTest
    : public SoftwareOutputDeviceOzoneTest {
 protected:
  virtual void SetUp() OVERRIDE;
};

void SoftwareOutputDeviceOzonePixelTest::SetUp() {
  enable_pixel_output_ = true;
  SoftwareOutputDeviceOzoneTest::SetUp();
}

TEST_F(SoftwareOutputDeviceOzoneTest, CheckClipAfterBeginPaint) {
  gfx::Rect damage(10, 10, 100, 100);
  SkCanvas* canvas = output_device_->BeginPaint(damage);

  SkIRect sk_bounds;
  canvas->getClipDeviceBounds(&sk_bounds);

  EXPECT_EQ(damage.ToString(), gfx::SkIRectToRect(sk_bounds).ToString());
}

TEST_F(SoftwareOutputDeviceOzoneTest, CheckClipAfterSecondBeginPaint) {
  gfx::Rect damage(10, 10, 100, 100);
  SkCanvas* canvas = output_device_->BeginPaint(damage);

  cc::SoftwareFrameData frame;
  output_device_->EndPaint(&frame);

  damage = gfx::Rect(100, 100, 100, 100);
  canvas = output_device_->BeginPaint(damage);
  SkIRect sk_bounds;
  canvas->getClipDeviceBounds(&sk_bounds);

  EXPECT_EQ(damage.ToString(), gfx::SkIRectToRect(sk_bounds).ToString());
}

TEST_F(SoftwareOutputDeviceOzoneTest, CheckCorrectResizeBehavior) {
  gfx::Rect damage(0, 0, 100, 100);
  gfx::Size size(200, 100);
  // Reduce size.
  output_device_->Resize(size);

  SkCanvas* canvas = output_device_->BeginPaint(damage);
  gfx::Size canvas_size(canvas->getDeviceSize().width(),
                        canvas->getDeviceSize().height());
  EXPECT_EQ(size.ToString(), canvas_size.ToString());

  size.SetSize(1000, 500);
  // Increase size.
  output_device_->Resize(size);

  canvas = output_device_->BeginPaint(damage);
  canvas_size.SetSize(canvas->getDeviceSize().width(),
                      canvas->getDeviceSize().height());
  EXPECT_EQ(size.ToString(), canvas_size.ToString());

}

TEST_F(SoftwareOutputDeviceOzonePixelTest, CheckCopyToBitmap) {
  const int width = 6;
  const int height = 4;
  const gfx::Rect area(width, height);
  output_device_->Resize(area.size());
  SkCanvas* canvas = output_device_->BeginPaint(area);

  // Clear the background to black.
  canvas->drawColor(SK_ColorBLACK);

  cc::SoftwareFrameData frame;
  output_device_->EndPaint(&frame);

  // Draw a white rectangle.
  gfx::Rect damage(area.width() / 2, area.height() / 2);
  canvas = output_device_->BeginPaint(damage);

  canvas->drawColor(SK_ColorWHITE);

  output_device_->EndPaint(&frame);

  SkPMColor pixels[width * height];
  output_device_->CopyToPixels(area, pixels);

  // Check that the copied bitmap contains the same pixel values as what we
  // painted.
  const SkPMColor white = SkPreMultiplyColor(SK_ColorWHITE);
  const SkPMColor black = SkPreMultiplyColor(SK_ColorBLACK);
  for (int i = 0; i < area.height(); ++i) {
    for (int j = 0; j < area.width(); ++j) {
      if (j < damage.width() && i < damage.height())
        EXPECT_EQ(white, pixels[i * area.width() + j]);
      else
        EXPECT_EQ(black, pixels[i * area.width() + j]);
    }
  }
}

/* [<][>][^][v][top][bottom][index][help] */