blob: 30c696ccabcbab275ea15b40d045322f35046eb1 [file] [log] [blame]
// Copyright 2013 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/aura/software_output_device_ozone.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmapDevice.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/size.h"
#include "ui/gfx/skia_util.h"
#include "ui/gl/gl_implementation.h"
namespace {
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 gfx::AcceleratedWidget RealizeAcceleratedWidget(
gfx::AcceleratedWidget w) OVERRIDE { return w; }
virtual bool LoadEGLGLES2Bindings() OVERRIDE { return false; }
virtual bool AttemptToResizeAcceleratedWidget(
gfx::AcceleratedWidget w, const gfx::Rect& bounds) OVERRIDE {
device_ = skia::AdoptRef(new SkBitmapDevice(SkBitmap::kARGB_8888_Config,
bounds.width(),
bounds.height(),
true));
canvas_ = skia::AdoptRef(new SkCanvas(device_.get()));
return true;
}
virtual SkCanvas* GetCanvasForWidget(gfx::AcceleratedWidget w) OVERRIDE {
return canvas_.get();
}
virtual gfx::VSyncProvider* GetVSyncProvider(
gfx::AcceleratedWidget w) OVERRIDE {
return NULL;
}
private:
skia::RefPtr<SkBitmapDevice> device_;
skia::RefPtr<SkCanvas> canvas_;
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_;
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() {
CHECK(gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL));
message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_UI));
}
SoftwareOutputDeviceOzoneTest::~SoftwareOutputDeviceOzoneTest() {
}
void SoftwareOutputDeviceOzoneTest::SetUp() {
ui::InitializeContextFactoryForTests(false);
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();
}
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(SoftwareOutputDeviceOzoneTest, CheckCopyToBitmap) {
const gfx::Rect area(6, 4);
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);
SkBitmap bitmap;
output_device_->CopyToBitmap(area, &bitmap);
SkAutoLockPixels pixel_lock(bitmap);
// Check that the copied bitmap contains the same pixel values as what we
// painted.
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(SK_ColorWHITE, bitmap.getColor(j, i));
else
EXPECT_EQ(SK_ColorBLACK, bitmap.getColor(j, i));
}
}
}