| Index: ui/gfx/compositor/layer_unittest.cc
|
| diff --git a/ui/gfx/compositor/layer_unittest.cc b/ui/gfx/compositor/layer_unittest.cc
|
| deleted file mode 100644
|
| index 65805fd6b01a3c7079f6fbb6996dd1ac843449b9..0000000000000000000000000000000000000000
|
| --- a/ui/gfx/compositor/layer_unittest.cc
|
| +++ /dev/null
|
| @@ -1,1024 +0,0 @@
|
| -// Copyright (c) 2012 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/basictypes.h"
|
| -#include "base/compiler_specific.h"
|
| -#include "base/file_path.h"
|
| -#include "base/file_util.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/path_service.h"
|
| -#include "base/string_util.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -#include "ui/gfx/canvas.h"
|
| -#include "ui/gfx/codec/png_codec.h"
|
| -#include "ui/gfx/compositor/compositor_observer.h"
|
| -#include "ui/gfx/compositor/layer.h"
|
| -#include "ui/gfx/compositor/layer_animation_sequence.h"
|
| -#include "ui/gfx/compositor/test/test_compositor_host.h"
|
| -#include "ui/gfx/gfx_paths.h"
|
| -#include "ui/gfx/skia_util.h"
|
| -
|
| -#include "ui/gfx/compositor/compositor_setup.h"
|
| -
|
| -namespace ui {
|
| -
|
| -namespace {
|
| -
|
| -// Encodes a bitmap into a PNG and write to disk. Returns true on success. The
|
| -// parent directory does not have to exist.
|
| -bool WritePNGFile(const SkBitmap& bitmap, const FilePath& file_path) {
|
| - std::vector<unsigned char> png_data;
|
| - if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data) &&
|
| - file_util::CreateDirectory(file_path.DirName())) {
|
| - char* data = reinterpret_cast<char*>(&png_data[0]);
|
| - int size = static_cast<int>(png_data.size());
|
| - return file_util::WriteFile(file_path, data, size) == size;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -// Reads and decodes a PNG image to a bitmap. Returns true on success. The PNG
|
| -// should have been encoded using |gfx::PNGCodec::Encode|.
|
| -bool ReadPNGFile(const FilePath& file_path, SkBitmap* bitmap) {
|
| - DCHECK(bitmap);
|
| - std::string png_data;
|
| - return file_util::ReadFileToString(file_path, &png_data) &&
|
| - gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&png_data[0]),
|
| - png_data.length(),
|
| - bitmap);
|
| -}
|
| -
|
| -// Compares with a PNG file on disk, and returns true if it is the same as
|
| -// the given image. |ref_img_path| is absolute.
|
| -bool IsSameAsPNGFile(const SkBitmap& gen_bmp, FilePath ref_img_path) {
|
| - SkBitmap ref_bmp;
|
| - if (!ReadPNGFile(ref_img_path, &ref_bmp)) {
|
| - LOG(ERROR) << "Cannot read reference image: " << ref_img_path.value();
|
| - return false;
|
| - }
|
| -
|
| - if (ref_bmp.width() != gen_bmp.width() ||
|
| - ref_bmp.height() != gen_bmp.height()) {
|
| - LOG(ERROR)
|
| - << "Dimensions do not match (Expected) vs (Actual):"
|
| - << "(" << ref_bmp.width() << "x" << ref_bmp.height()
|
| - << ") vs. "
|
| - << "(" << gen_bmp.width() << "x" << gen_bmp.height() << ")";
|
| - return false;
|
| - }
|
| -
|
| - // Compare pixels and create a simple diff image.
|
| - int diff_pixels_count = 0;
|
| - SkAutoLockPixels lock_bmp(gen_bmp);
|
| - SkAutoLockPixels lock_ref_bmp(ref_bmp);
|
| - // The reference images were saved with no alpha channel. Use the mask to
|
| - // set alpha to 0.
|
| - uint32_t kAlphaMask = 0x00FFFFFF;
|
| - for (int x = 0; x < gen_bmp.width(); ++x) {
|
| - for (int y = 0; y < gen_bmp.height(); ++y) {
|
| - if ((*gen_bmp.getAddr32(x, y) & kAlphaMask) !=
|
| - (*ref_bmp.getAddr32(x, y) & kAlphaMask)) {
|
| - ++diff_pixels_count;
|
| - }
|
| - }
|
| - }
|
| -
|
| - if (diff_pixels_count != 0) {
|
| - LOG(ERROR) << "Images differ by pixel count: " << diff_pixels_count;
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -// Returns a comma-separated list of the names of |layer|'s children in
|
| -// bottom-to-top stacking order.
|
| -std::string GetLayerChildrenNames(const Layer& layer) {
|
| - std::string names;
|
| - for (std::vector<Layer*>::const_iterator it = layer.children().begin();
|
| - it != layer.children().end(); ++it) {
|
| - if (!names.empty())
|
| - names += ",";
|
| - names += (*it)->name();
|
| - }
|
| - return names;
|
| -}
|
| -
|
| -
|
| -// There are three test classes in here that configure the Compositor and
|
| -// Layer's slightly differently:
|
| -// - LayerWithNullDelegateTest uses NullLayerDelegate as the LayerDelegate. This
|
| -// is typically the base class you want to use.
|
| -// - LayerWithDelegateTest uses LayerDelegate on the delegates.
|
| -// - LayerWithRealCompositorTest when a real compositor is required for testing.
|
| -// - Slow because they bring up a window and run the real compositor. This
|
| -// is typically not what you want.
|
| -
|
| -class ColoredLayer : public Layer, public LayerDelegate {
|
| - public:
|
| - explicit ColoredLayer(SkColor color)
|
| - : Layer(LAYER_TEXTURED),
|
| - color_(color) {
|
| - set_delegate(this);
|
| - }
|
| -
|
| - virtual ~ColoredLayer() { }
|
| -
|
| - // Overridden from LayerDelegate:
|
| - virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
|
| - canvas->DrawColor(color_);
|
| - }
|
| -
|
| - private:
|
| - SkColor color_;
|
| -};
|
| -
|
| -class LayerWithRealCompositorTest : public testing::Test {
|
| - public:
|
| - LayerWithRealCompositorTest() {
|
| - if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) {
|
| - test_data_directory_ = test_data_directory_.AppendASCII("compositor");
|
| - } else {
|
| - LOG(ERROR) << "Could not open test data directory.";
|
| - }
|
| - }
|
| - virtual ~LayerWithRealCompositorTest() {}
|
| -
|
| - // Overridden from testing::Test:
|
| - virtual void SetUp() OVERRIDE {
|
| - DisableTestCompositor();
|
| - const gfx::Rect host_bounds(10, 10, 500, 500);
|
| - window_.reset(TestCompositorHost::Create(host_bounds));
|
| - window_->Show();
|
| - }
|
| -
|
| - virtual void TearDown() OVERRIDE {
|
| - }
|
| -
|
| - Compositor* GetCompositor() {
|
| - return window_->GetCompositor();
|
| - }
|
| -
|
| - Layer* CreateLayer(LayerType type) {
|
| - return new Layer(type);
|
| - }
|
| -
|
| - Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
|
| - Layer* layer = new ColoredLayer(color);
|
| - layer->SetBounds(bounds);
|
| - return layer;
|
| - }
|
| -
|
| - Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
|
| - Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
|
| - layer->SetBounds(bounds);
|
| - return layer;
|
| - }
|
| -
|
| - void DrawTree(Layer* root) {
|
| - GetCompositor()->SetRootLayer(root);
|
| - GetCompositor()->Draw(false);
|
| - }
|
| -
|
| - bool ReadPixels(SkBitmap* bitmap) {
|
| - return GetCompositor()->ReadPixels(bitmap,
|
| - gfx::Rect(GetCompositor()->size()));
|
| - }
|
| -
|
| - void RunPendingMessages() {
|
| - MessageLoopForUI::current()->RunAllPending();
|
| - }
|
| -
|
| - // Invalidates the entire contents of the layer.
|
| - void SchedulePaintForLayer(Layer* layer) {
|
| - layer->SchedulePaint(
|
| - gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
|
| - }
|
| -
|
| - const FilePath& test_data_directory() const { return test_data_directory_; }
|
| -
|
| - private:
|
| - scoped_ptr<TestCompositorHost> window_;
|
| -
|
| - // The root directory for test files.
|
| - FilePath test_data_directory_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest);
|
| -};
|
| -
|
| -// LayerDelegate that paints colors to the layer.
|
| -class TestLayerDelegate : public LayerDelegate {
|
| - public:
|
| - explicit TestLayerDelegate() : color_index_(0) {}
|
| - virtual ~TestLayerDelegate() {}
|
| -
|
| - void AddColor(SkColor color) {
|
| - colors_.push_back(color);
|
| - }
|
| -
|
| - const gfx::Size& paint_size() const { return paint_size_; }
|
| - int color_index() const { return color_index_; }
|
| -
|
| - // Overridden from LayerDelegate:
|
| - virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
|
| - SkBitmap contents = canvas->ExtractBitmap();
|
| - paint_size_ = gfx::Size(contents.width(), contents.height());
|
| - canvas->FillRect(gfx::Rect(paint_size_), colors_[color_index_]);
|
| - color_index_ = (color_index_ + 1) % static_cast<int>(colors_.size());
|
| - }
|
| -
|
| - private:
|
| - std::vector<SkColor> colors_;
|
| - int color_index_;
|
| - gfx::Size paint_size_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate);
|
| -};
|
| -
|
| -// LayerDelegate that verifies that a layer was asked to update its canvas.
|
| -class DrawTreeLayerDelegate : public LayerDelegate {
|
| - public:
|
| - DrawTreeLayerDelegate() : painted_(false) {}
|
| - virtual ~DrawTreeLayerDelegate() {}
|
| -
|
| - void Reset() {
|
| - painted_ = false;
|
| - }
|
| -
|
| - bool painted() const { return painted_; }
|
| -
|
| - private:
|
| - // Overridden from LayerDelegate:
|
| - virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
|
| - painted_ = true;
|
| - }
|
| -
|
| - bool painted_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate);
|
| -};
|
| -
|
| -// The simplest possible layer delegate. Does nothing.
|
| -class NullLayerDelegate : public LayerDelegate {
|
| - public:
|
| - NullLayerDelegate() {}
|
| - virtual ~NullLayerDelegate() {}
|
| -
|
| - private:
|
| - // Overridden from LayerDelegate:
|
| - virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
|
| - }
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate);
|
| -};
|
| -
|
| -// Remembers if it has been notified.
|
| -class TestCompositorObserver : public CompositorObserver {
|
| - public:
|
| - TestCompositorObserver() : started_(false), ended_(false) {}
|
| -
|
| - bool notified() const { return started_ && ended_; }
|
| -
|
| - void Reset() {
|
| - started_ = false;
|
| - ended_ = false;
|
| - }
|
| -
|
| - private:
|
| - virtual void OnCompositingStarted(Compositor* compositor) OVERRIDE {
|
| - started_ = true;
|
| - }
|
| -
|
| - virtual void OnCompositingEnded(Compositor* compositor) OVERRIDE {
|
| - ended_ = true;
|
| - }
|
| -
|
| - bool started_;
|
| - bool ended_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TestCompositorObserver);
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -#if defined(OS_WIN)
|
| -// These are disabled on windows as they don't run correctly on the buildbot.
|
| -// Reenable once we move to the real compositor.
|
| -#define MAYBE_Delegate DISABLED_Delegate
|
| -#define MAYBE_Draw DISABLED_Draw
|
| -#define MAYBE_DrawTree DISABLED_DrawTree
|
| -#define MAYBE_Hierarchy DISABLED_Hierarchy
|
| -#define MAYBE_HierarchyNoTexture DISABLED_HierarchyNoTexture
|
| -#define MAYBE_DrawPixels DISABLED_DrawPixels
|
| -#define MAYBE_SetRootLayer DISABLED_SetRootLayer
|
| -#define MAYBE_CompositorObservers DISABLED_CompositorObservers
|
| -#define MAYBE_ModifyHierarchy DISABLED_ModifyHierarchy
|
| -#define MAYBE_Opacity DISABLED_Opacity
|
| -#else
|
| -#define MAYBE_Delegate DISABLED_Delegate
|
| -#define MAYBE_Draw Draw
|
| -#define MAYBE_DrawTree DISABLED_DrawTree
|
| -#define MAYBE_Hierarchy Hierarchy
|
| -#define MAYBE_HierarchyNoTexture DISABLED_HierarchyNoTexture
|
| -#define MAYBE_DrawPixels DrawPixels
|
| -#define MAYBE_SetRootLayer SetRootLayer
|
| -#define MAYBE_CompositorObservers DISABLED_CompositorObservers
|
| -#define MAYBE_ModifyHierarchy ModifyHierarchy
|
| -#define MAYBE_Opacity Opacity
|
| -#endif
|
| -
|
| -TEST_F(LayerWithRealCompositorTest, MAYBE_Draw) {
|
| - scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED,
|
| - gfx::Rect(20, 20, 50, 50)));
|
| - DrawTree(layer.get());
|
| -}
|
| -
|
| -// Create this hierarchy:
|
| -// L1 - red
|
| -// +-- L2 - blue
|
| -// | +-- L3 - yellow
|
| -// +-- L4 - magenta
|
| -//
|
| -TEST_F(LayerWithRealCompositorTest, MAYBE_Hierarchy) {
|
| - scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
|
| - gfx::Rect(20, 20, 400, 400)));
|
| - scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
|
| - gfx::Rect(10, 10, 350, 350)));
|
| - scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
|
| - gfx::Rect(5, 5, 25, 25)));
|
| - scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
|
| - gfx::Rect(300, 300, 100, 100)));
|
| -
|
| - l1->Add(l2.get());
|
| - l1->Add(l4.get());
|
| - l2->Add(l3.get());
|
| -
|
| - DrawTree(l1.get());
|
| -}
|
| -
|
| -class LayerWithDelegateTest : public testing::Test, public CompositorDelegate {
|
| - public:
|
| - LayerWithDelegateTest() : schedule_draw_invoked_(false) {}
|
| - virtual ~LayerWithDelegateTest() {}
|
| -
|
| - // Overridden from testing::Test:
|
| - virtual void SetUp() OVERRIDE {
|
| - ui::SetupTestCompositor();
|
| - compositor_.reset(new Compositor(
|
| - this, gfx::kNullAcceleratedWidget, gfx::Size(1000, 1000)));
|
| - }
|
| -
|
| - virtual void TearDown() OVERRIDE {
|
| - }
|
| -
|
| - Compositor* compositor() { return compositor_.get(); }
|
| -
|
| - virtual Layer* CreateLayer(LayerType type) {
|
| - return new Layer(type);
|
| - }
|
| -
|
| - Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
|
| - Layer* layer = new ColoredLayer(color);
|
| - layer->SetBounds(bounds);
|
| - return layer;
|
| - }
|
| -
|
| - virtual Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
|
| - Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
|
| - layer->SetBounds(bounds);
|
| - return layer;
|
| - }
|
| -
|
| - void DrawTree(Layer* root) {
|
| - compositor()->SetRootLayer(root);
|
| - compositor()->Draw(false);
|
| - }
|
| -
|
| - // Invalidates the entire contents of the layer.
|
| - void SchedulePaintForLayer(Layer* layer) {
|
| - layer->SchedulePaint(
|
| - gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
|
| - }
|
| -
|
| - // Invokes DrawTree on the compositor.
|
| - void Draw() {
|
| - compositor_->Draw(false);
|
| - }
|
| -
|
| - // CompositorDelegate overrides.
|
| - virtual void ScheduleDraw() OVERRIDE {
|
| - schedule_draw_invoked_ = true;
|
| - }
|
| -
|
| - protected:
|
| - // Set to true when ScheduleDraw (CompositorDelegate override) is invoked.
|
| - bool schedule_draw_invoked_;
|
| -
|
| - private:
|
| - scoped_ptr<Compositor> compositor_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(LayerWithDelegateTest);
|
| -};
|
| -
|
| -// L1
|
| -// +-- L2
|
| -TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Simple) {
|
| - scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
|
| - gfx::Rect(20, 20, 400, 400)));
|
| - scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
|
| - gfx::Rect(10, 10, 350, 350)));
|
| - l1->Add(l2.get());
|
| - DrawTree(l1.get());
|
| -
|
| - gfx::Point point1_in_l2_coords(5, 5);
|
| - Layer::ConvertPointToLayer(l2.get(), l1.get(), &point1_in_l2_coords);
|
| - gfx::Point point1_in_l1_coords(15, 15);
|
| - EXPECT_EQ(point1_in_l1_coords, point1_in_l2_coords);
|
| -
|
| - gfx::Point point2_in_l1_coords(5, 5);
|
| - Layer::ConvertPointToLayer(l1.get(), l2.get(), &point2_in_l1_coords);
|
| - gfx::Point point2_in_l2_coords(-5, -5);
|
| - EXPECT_EQ(point2_in_l2_coords, point2_in_l1_coords);
|
| -}
|
| -
|
| -// L1
|
| -// +-- L2
|
| -// +-- L3
|
| -TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Medium) {
|
| - scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
|
| - gfx::Rect(20, 20, 400, 400)));
|
| - scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
|
| - gfx::Rect(10, 10, 350, 350)));
|
| - scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
|
| - gfx::Rect(10, 10, 100, 100)));
|
| - l1->Add(l2.get());
|
| - l2->Add(l3.get());
|
| - DrawTree(l1.get());
|
| -
|
| - gfx::Point point1_in_l3_coords(5, 5);
|
| - Layer::ConvertPointToLayer(l3.get(), l1.get(), &point1_in_l3_coords);
|
| - gfx::Point point1_in_l1_coords(25, 25);
|
| - EXPECT_EQ(point1_in_l1_coords, point1_in_l3_coords);
|
| -
|
| - gfx::Point point2_in_l1_coords(5, 5);
|
| - Layer::ConvertPointToLayer(l1.get(), l3.get(), &point2_in_l1_coords);
|
| - gfx::Point point2_in_l3_coords(-15, -15);
|
| - EXPECT_EQ(point2_in_l3_coords, point2_in_l1_coords);
|
| -}
|
| -
|
| -TEST_F(LayerWithRealCompositorTest, MAYBE_Delegate) {
|
| - scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorBLACK,
|
| - gfx::Rect(20, 20, 400, 400)));
|
| - GetCompositor()->SetRootLayer(l1.get());
|
| - RunPendingMessages();
|
| -
|
| - TestLayerDelegate delegate;
|
| - l1->set_delegate(&delegate);
|
| - delegate.AddColor(SK_ColorWHITE);
|
| - delegate.AddColor(SK_ColorYELLOW);
|
| - delegate.AddColor(SK_ColorGREEN);
|
| -
|
| - l1->SchedulePaint(gfx::Rect(0, 0, 400, 400));
|
| - RunPendingMessages();
|
| - EXPECT_EQ(delegate.color_index(), 1);
|
| - EXPECT_EQ(delegate.paint_size(), l1->bounds().size());
|
| -
|
| - l1->SchedulePaint(gfx::Rect(10, 10, 200, 200));
|
| - RunPendingMessages();
|
| - EXPECT_EQ(delegate.color_index(), 2);
|
| - EXPECT_EQ(delegate.paint_size(), gfx::Size(200, 200));
|
| -
|
| - l1->SchedulePaint(gfx::Rect(5, 5, 50, 50));
|
| - RunPendingMessages();
|
| - EXPECT_EQ(delegate.color_index(), 0);
|
| - EXPECT_EQ(delegate.paint_size(), gfx::Size(50, 50));
|
| -}
|
| -
|
| -TEST_F(LayerWithRealCompositorTest, MAYBE_DrawTree) {
|
| - scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
|
| - gfx::Rect(20, 20, 400, 400)));
|
| - scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
|
| - gfx::Rect(10, 10, 350, 350)));
|
| - scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
|
| - gfx::Rect(10, 10, 100, 100)));
|
| - l1->Add(l2.get());
|
| - l2->Add(l3.get());
|
| -
|
| - GetCompositor()->SetRootLayer(l1.get());
|
| - RunPendingMessages();
|
| -
|
| - DrawTreeLayerDelegate d1;
|
| - l1->set_delegate(&d1);
|
| - DrawTreeLayerDelegate d2;
|
| - l2->set_delegate(&d2);
|
| - DrawTreeLayerDelegate d3;
|
| - l3->set_delegate(&d3);
|
| -
|
| - l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
|
| - RunPendingMessages();
|
| - EXPECT_FALSE(d1.painted());
|
| - EXPECT_TRUE(d2.painted());
|
| - EXPECT_FALSE(d3.painted());
|
| -}
|
| -
|
| -// Tests no-texture Layers.
|
| -// Create this hierarchy:
|
| -// L1 - red
|
| -// +-- L2 - NO TEXTURE
|
| -// | +-- L3 - yellow
|
| -// +-- L4 - magenta
|
| -//
|
| -TEST_F(LayerWithRealCompositorTest, MAYBE_HierarchyNoTexture) {
|
| - scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
|
| - gfx::Rect(20, 20, 400, 400)));
|
| - scoped_ptr<Layer> l2(CreateNoTextureLayer(gfx::Rect(10, 10, 350, 350)));
|
| - scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
|
| - gfx::Rect(5, 5, 25, 25)));
|
| - scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
|
| - gfx::Rect(300, 300, 100, 100)));
|
| -
|
| - l1->Add(l2.get());
|
| - l1->Add(l4.get());
|
| - l2->Add(l3.get());
|
| -
|
| - GetCompositor()->SetRootLayer(l1.get());
|
| - RunPendingMessages();
|
| -
|
| - DrawTreeLayerDelegate d2;
|
| - l2->set_delegate(&d2);
|
| - DrawTreeLayerDelegate d3;
|
| - l3->set_delegate(&d3);
|
| -
|
| - l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
|
| - l3->SchedulePaint(gfx::Rect(5, 5, 5, 5));
|
| - RunPendingMessages();
|
| -
|
| - // |d2| should not have received a paint notification since it has no texture.
|
| - EXPECT_FALSE(d2.painted());
|
| - // |d3| should have received a paint notification.
|
| - EXPECT_TRUE(d3.painted());
|
| -}
|
| -
|
| -class LayerWithNullDelegateTest : public LayerWithDelegateTest {
|
| - public:
|
| - LayerWithNullDelegateTest() {}
|
| - virtual ~LayerWithNullDelegateTest() {}
|
| -
|
| - // Overridden from testing::Test:
|
| - virtual void SetUp() OVERRIDE {
|
| - LayerWithDelegateTest::SetUp();
|
| - default_layer_delegate_.reset(new NullLayerDelegate());
|
| - }
|
| -
|
| - virtual void TearDown() OVERRIDE {
|
| - }
|
| -
|
| - Layer* CreateLayer(LayerType type) OVERRIDE {
|
| - Layer* layer = new Layer(type);
|
| - layer->set_delegate(default_layer_delegate_.get());
|
| - return layer;
|
| - }
|
| -
|
| - Layer* CreateTextureRootLayer(const gfx::Rect& bounds) {
|
| - Layer* layer = CreateTextureLayer(bounds);
|
| - compositor()->SetRootLayer(layer);
|
| - return layer;
|
| - }
|
| -
|
| - Layer* CreateTextureLayer(const gfx::Rect& bounds) {
|
| - Layer* layer = CreateLayer(LAYER_TEXTURED);
|
| - layer->SetBounds(bounds);
|
| - return layer;
|
| - }
|
| -
|
| - Layer* CreateNoTextureLayer(const gfx::Rect& bounds) OVERRIDE {
|
| - Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
|
| - layer->SetBounds(bounds);
|
| - return layer;
|
| - }
|
| -
|
| - void RunPendingMessages() {
|
| - MessageLoopForUI::current()->RunAllPending();
|
| - }
|
| -
|
| - private:
|
| - scoped_ptr<NullLayerDelegate> default_layer_delegate_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest);
|
| -};
|
| -
|
| -// Various visibile/drawn assertions.
|
| -TEST_F(LayerWithNullDelegateTest, Visibility) {
|
| - scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
|
| - scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
|
| - scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
|
| - l1->Add(l2.get());
|
| - l2->Add(l3.get());
|
| -
|
| - NullLayerDelegate delegate;
|
| - l1->set_delegate(&delegate);
|
| - l2->set_delegate(&delegate);
|
| - l3->set_delegate(&delegate);
|
| -
|
| - // Layers should initially be drawn.
|
| - EXPECT_TRUE(l1->IsDrawn());
|
| - EXPECT_TRUE(l2->IsDrawn());
|
| - EXPECT_TRUE(l3->IsDrawn());
|
| - EXPECT_EQ(1.f, l1->web_layer().opacity());
|
| - EXPECT_EQ(1.f, l2->web_layer().opacity());
|
| - EXPECT_EQ(1.f, l3->web_layer().opacity());
|
| -
|
| - compositor()->SetRootLayer(l1.get());
|
| -
|
| - Draw();
|
| -
|
| - l1->SetVisible(false);
|
| - EXPECT_FALSE(l1->IsDrawn());
|
| - EXPECT_FALSE(l2->IsDrawn());
|
| - EXPECT_FALSE(l3->IsDrawn());
|
| - EXPECT_EQ(0.f, l1->web_layer().opacity());
|
| -
|
| - l3->SetVisible(false);
|
| - EXPECT_FALSE(l1->IsDrawn());
|
| - EXPECT_FALSE(l2->IsDrawn());
|
| - EXPECT_FALSE(l3->IsDrawn());
|
| - EXPECT_EQ(0.f, l3->web_layer().opacity());
|
| -
|
| - l1->SetVisible(true);
|
| - EXPECT_TRUE(l1->IsDrawn());
|
| - EXPECT_TRUE(l2->IsDrawn());
|
| - EXPECT_FALSE(l3->IsDrawn());
|
| - EXPECT_EQ(1.f, l1->web_layer().opacity());
|
| -}
|
| -
|
| -// Checks that stacking-related methods behave as advertised.
|
| -TEST_F(LayerWithNullDelegateTest, Stacking) {
|
| - scoped_ptr<Layer> root(new Layer(LAYER_NOT_DRAWN));
|
| - scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
|
| - scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
|
| - scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
|
| - l1->set_name("1");
|
| - l2->set_name("2");
|
| - l3->set_name("3");
|
| - root->Add(l3.get());
|
| - root->Add(l2.get());
|
| - root->Add(l1.get());
|
| -
|
| - // Layers' children are stored in bottom-to-top order.
|
| - EXPECT_EQ("3,2,1", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackAtTop(l3.get());
|
| - EXPECT_EQ("2,1,3", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackAtTop(l1.get());
|
| - EXPECT_EQ("2,3,1", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackAtTop(l1.get());
|
| - EXPECT_EQ("2,3,1", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackAbove(l2.get(), l3.get());
|
| - EXPECT_EQ("3,2,1", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackAbove(l1.get(), l3.get());
|
| - EXPECT_EQ("3,1,2", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackAbove(l2.get(), l1.get());
|
| - EXPECT_EQ("3,1,2", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackAtBottom(l2.get());
|
| - EXPECT_EQ("2,3,1", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackAtBottom(l3.get());
|
| - EXPECT_EQ("3,2,1", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackAtBottom(l3.get());
|
| - EXPECT_EQ("3,2,1", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackBelow(l2.get(), l3.get());
|
| - EXPECT_EQ("2,3,1", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackBelow(l1.get(), l3.get());
|
| - EXPECT_EQ("2,1,3", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackBelow(l3.get(), l2.get());
|
| - EXPECT_EQ("3,2,1", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackBelow(l3.get(), l2.get());
|
| - EXPECT_EQ("3,2,1", GetLayerChildrenNames(*root.get()));
|
| -
|
| - root->StackBelow(l3.get(), l1.get());
|
| - EXPECT_EQ("2,3,1", GetLayerChildrenNames(*root.get()));
|
| -}
|
| -
|
| -// Verifies SetBounds triggers the appropriate painting/drawing.
|
| -TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) {
|
| - scoped_ptr<Layer> l1(CreateTextureLayer(gfx::Rect(0, 0, 200, 200)));
|
| - compositor()->SetRootLayer(l1.get());
|
| -
|
| - Draw();
|
| -
|
| - schedule_draw_invoked_ = false;
|
| - l1->SetBounds(gfx::Rect(5, 5, 200, 200));
|
| -
|
| - // The CompositorDelegate (us) should have been told to draw for a move.
|
| - EXPECT_TRUE(schedule_draw_invoked_);
|
| -
|
| - schedule_draw_invoked_ = false;
|
| - l1->SetBounds(gfx::Rect(5, 5, 100, 100));
|
| -
|
| - // The CompositorDelegate (us) should have been told to draw for a resize.
|
| - EXPECT_TRUE(schedule_draw_invoked_);
|
| -}
|
| -
|
| -// Checks that pixels are actually drawn to the screen with a read back.
|
| -TEST_F(LayerWithRealCompositorTest, MAYBE_DrawPixels) {
|
| - scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED,
|
| - gfx::Rect(0, 0, 500, 500)));
|
| - scoped_ptr<Layer> layer2(CreateColorLayer(SK_ColorBLUE,
|
| - gfx::Rect(0, 0, 500, 10)));
|
| -
|
| - layer->Add(layer2.get());
|
| -
|
| - DrawTree(layer.get());
|
| -
|
| - SkBitmap bitmap;
|
| - gfx::Size size = GetCompositor()->size();
|
| - ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap,
|
| - gfx::Rect(0, 10,
|
| - size.width(), size.height() - 10)));
|
| - ASSERT_FALSE(bitmap.empty());
|
| -
|
| - SkAutoLockPixels lock(bitmap);
|
| - bool is_all_red = true;
|
| - for (int x = 0; is_all_red && x < 500; x++)
|
| - for (int y = 0; is_all_red && y < 490; y++)
|
| - is_all_red = is_all_red && (bitmap.getColor(x, y) == SK_ColorRED);
|
| -
|
| - EXPECT_TRUE(is_all_red);
|
| -}
|
| -
|
| -// Checks the logic around Compositor::SetRootLayer and Layer::SetCompositor.
|
| -TEST_F(LayerWithRealCompositorTest, MAYBE_SetRootLayer) {
|
| - Compositor* compositor = GetCompositor();
|
| - scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
|
| - gfx::Rect(20, 20, 400, 400)));
|
| - scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
|
| - gfx::Rect(10, 10, 350, 350)));
|
| -
|
| - EXPECT_EQ(NULL, l1->GetCompositor());
|
| - EXPECT_EQ(NULL, l2->GetCompositor());
|
| -
|
| - compositor->SetRootLayer(l1.get());
|
| - EXPECT_EQ(compositor, l1->GetCompositor());
|
| -
|
| - l1->Add(l2.get());
|
| - EXPECT_EQ(compositor, l2->GetCompositor());
|
| -
|
| - l1->Remove(l2.get());
|
| - EXPECT_EQ(NULL, l2->GetCompositor());
|
| -
|
| - l1->Add(l2.get());
|
| - EXPECT_EQ(compositor, l2->GetCompositor());
|
| -
|
| - compositor->SetRootLayer(NULL);
|
| - EXPECT_EQ(NULL, l1->GetCompositor());
|
| - EXPECT_EQ(NULL, l2->GetCompositor());
|
| -}
|
| -
|
| -// Checks that compositor observers are notified when:
|
| -// - DrawTree is called,
|
| -// - After ScheduleDraw is called, or
|
| -// - Whenever SetBounds, SetOpacity or SetTransform are called.
|
| -// TODO(vollick): could be reorganized into compositor_unittest.cc
|
| -TEST_F(LayerWithRealCompositorTest, MAYBE_CompositorObservers) {
|
| - scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
|
| - gfx::Rect(20, 20, 400, 400)));
|
| - scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
|
| - gfx::Rect(10, 10, 350, 350)));
|
| - l1->Add(l2.get());
|
| - TestCompositorObserver observer;
|
| - GetCompositor()->AddObserver(&observer);
|
| -
|
| - // Explicitly called DrawTree should cause the observers to be notified.
|
| - // NOTE: this call to DrawTree sets l1 to be the compositor's root layer.
|
| - DrawTree(l1.get());
|
| - RunPendingMessages();
|
| - EXPECT_TRUE(observer.notified());
|
| -
|
| - // As should scheduling a draw and waiting.
|
| - observer.Reset();
|
| - l1->ScheduleDraw();
|
| - RunPendingMessages();
|
| - EXPECT_TRUE(observer.notified());
|
| -
|
| - // Moving, but not resizing, a layer should alert the observers.
|
| - observer.Reset();
|
| - l2->SetBounds(gfx::Rect(0, 0, 350, 350));
|
| - RunPendingMessages();
|
| - EXPECT_TRUE(observer.notified());
|
| -
|
| - // So should resizing a layer.
|
| - observer.Reset();
|
| - l2->SetBounds(gfx::Rect(0, 0, 400, 400));
|
| - RunPendingMessages();
|
| - EXPECT_TRUE(observer.notified());
|
| -
|
| - // Opacity changes should alert the observers.
|
| - observer.Reset();
|
| - l2->SetOpacity(0.5f);
|
| - RunPendingMessages();
|
| - EXPECT_TRUE(observer.notified());
|
| -
|
| - // So should setting the opacity back.
|
| - observer.Reset();
|
| - l2->SetOpacity(1.0f);
|
| - RunPendingMessages();
|
| - EXPECT_TRUE(observer.notified());
|
| -
|
| - // Setting the transform of a layer should alert the observers.
|
| - observer.Reset();
|
| - Transform transform;
|
| - transform.ConcatTranslate(-200, -200);
|
| - transform.ConcatRotate(90.0f);
|
| - transform.ConcatTranslate(200, 200);
|
| - l2->SetTransform(transform);
|
| - RunPendingMessages();
|
| - EXPECT_TRUE(observer.notified());
|
| -
|
| - GetCompositor()->RemoveObserver(&observer);
|
| -
|
| - // Opacity changes should no longer alert the removed observer.
|
| - observer.Reset();
|
| - l2->SetOpacity(0.5f);
|
| - RunPendingMessages();
|
| - EXPECT_FALSE(observer.notified());
|
| -}
|
| -
|
| -// Checks that modifying the hierarchy correctly affects final composite.
|
| -TEST_F(LayerWithRealCompositorTest, MAYBE_ModifyHierarchy) {
|
| - GetCompositor()->WidgetSizeChanged(gfx::Size(50, 50));
|
| -
|
| - // l0
|
| - // +-l11
|
| - // | +-l21
|
| - // +-l12
|
| - scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
|
| - gfx::Rect(0, 0, 50, 50)));
|
| - scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
|
| - gfx::Rect(0, 0, 25, 25)));
|
| - scoped_ptr<Layer> l21(CreateColorLayer(SK_ColorMAGENTA,
|
| - gfx::Rect(0, 0, 15, 15)));
|
| - scoped_ptr<Layer> l12(CreateColorLayer(SK_ColorBLUE,
|
| - gfx::Rect(10, 10, 25, 25)));
|
| -
|
| - FilePath ref_img1 = test_data_directory().AppendASCII("ModifyHierarchy1.png");
|
| - FilePath ref_img2 = test_data_directory().AppendASCII("ModifyHierarchy2.png");
|
| - SkBitmap bitmap;
|
| -
|
| - l0->Add(l11.get());
|
| - l11->Add(l21.get());
|
| - l0->Add(l12.get());
|
| - DrawTree(l0.get());
|
| - ASSERT_TRUE(ReadPixels(&bitmap));
|
| - ASSERT_FALSE(bitmap.empty());
|
| - // WritePNGFile(bitmap, ref_img1);
|
| - EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img1));
|
| -
|
| - l0->StackAtTop(l11.get());
|
| - DrawTree(l0.get());
|
| - ASSERT_TRUE(ReadPixels(&bitmap));
|
| - ASSERT_FALSE(bitmap.empty());
|
| - // WritePNGFile(bitmap, ref_img2);
|
| - EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2));
|
| -
|
| - // l11 is already at the front, should have no effect.
|
| - l0->StackAtTop(l11.get());
|
| - DrawTree(l0.get());
|
| - ASSERT_TRUE(ReadPixels(&bitmap));
|
| - ASSERT_FALSE(bitmap.empty());
|
| - EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2));
|
| -
|
| - // l11 is already at the front, should have no effect.
|
| - l0->StackAbove(l11.get(), l12.get());
|
| - DrawTree(l0.get());
|
| - ASSERT_TRUE(ReadPixels(&bitmap));
|
| - ASSERT_FALSE(bitmap.empty());
|
| - EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2));
|
| -
|
| - // should restore to original configuration
|
| - l0->StackAbove(l12.get(), l11.get());
|
| - DrawTree(l0.get());
|
| - ASSERT_TRUE(ReadPixels(&bitmap));
|
| - ASSERT_FALSE(bitmap.empty());
|
| - EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img1));
|
| -}
|
| -
|
| -// Opacity is rendered correctly.
|
| -// Checks that modifying the hierarchy correctly affects final composite.
|
| -TEST_F(LayerWithRealCompositorTest, MAYBE_Opacity) {
|
| - GetCompositor()->WidgetSizeChanged(gfx::Size(50, 50));
|
| -
|
| - // l0
|
| - // +-l11
|
| - scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
|
| - gfx::Rect(0, 0, 50, 50)));
|
| - scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
|
| - gfx::Rect(0, 0, 25, 25)));
|
| -
|
| - FilePath ref_img = test_data_directory().AppendASCII("Opacity.png");
|
| -
|
| - l11->SetOpacity(0.75);
|
| - l0->Add(l11.get());
|
| - DrawTree(l0.get());
|
| - SkBitmap bitmap;
|
| - ASSERT_TRUE(ReadPixels(&bitmap));
|
| - ASSERT_FALSE(bitmap.empty());
|
| - // WritePNGFile(bitmap, ref_img);
|
| - EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img));
|
| -}
|
| -
|
| -namespace {
|
| -
|
| -class SchedulePaintLayerDelegate : public LayerDelegate {
|
| - public:
|
| - SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {}
|
| -
|
| - virtual ~SchedulePaintLayerDelegate() {}
|
| -
|
| - void set_layer(Layer* layer) {
|
| - layer_ = layer;
|
| - layer_->set_delegate(this);
|
| - }
|
| -
|
| - void SetSchedulePaintRect(const gfx::Rect& rect) {
|
| - schedule_paint_rect_ = rect;
|
| - }
|
| -
|
| - int GetPaintCountAndClear() {
|
| - int value = paint_count_;
|
| - paint_count_ = 0;
|
| - return value;
|
| - }
|
| -
|
| - const gfx::Rect& last_clip_rect() const { return last_clip_rect_; }
|
| -
|
| - private:
|
| - // Overridden from LayerDelegate:
|
| - virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
|
| - paint_count_++;
|
| - if (!schedule_paint_rect_.IsEmpty()) {
|
| - layer_->SchedulePaint(schedule_paint_rect_);
|
| - schedule_paint_rect_ = gfx::Rect();
|
| - }
|
| - SkRect sk_clip_rect;
|
| - if (canvas->sk_canvas()->getClipBounds(&sk_clip_rect))
|
| - last_clip_rect_ = gfx::SkRectToRect(sk_clip_rect);
|
| - }
|
| -
|
| - int paint_count_;
|
| - Layer* layer_;
|
| - gfx::Rect schedule_paint_rect_;
|
| - gfx::Rect last_clip_rect_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(SchedulePaintLayerDelegate);
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -// Verifies that if SchedulePaint is invoked during painting the layer is still
|
| -// marked dirty.
|
| -TEST_F(LayerWithDelegateTest, SchedulePaintFromOnPaintLayer) {
|
| - scoped_ptr<Layer> root(CreateColorLayer(SK_ColorRED,
|
| - gfx::Rect(0, 0, 500, 500)));
|
| - SchedulePaintLayerDelegate child_delegate;
|
| - scoped_ptr<Layer> child(CreateColorLayer(SK_ColorBLUE,
|
| - gfx::Rect(0, 0, 200, 200)));
|
| - child_delegate.set_layer(child.get());
|
| -
|
| - root->Add(child.get());
|
| -
|
| - SchedulePaintForLayer(root.get());
|
| - DrawTree(root.get());
|
| - schedule_draw_invoked_ = false;
|
| - child->SchedulePaint(gfx::Rect(0, 0, 20, 20));
|
| - child_delegate.GetPaintCountAndClear();
|
| - EXPECT_TRUE(schedule_draw_invoked_);
|
| - schedule_draw_invoked_ = false;
|
| - // Set a rect so that when OnPaintLayer() is invoked SchedulePaint is invoked
|
| - // again.
|
| - child_delegate.SetSchedulePaintRect(gfx::Rect(10, 10, 30, 30));
|
| - DrawTree(root.get());
|
| - // |child| should have been painted once.
|
| - EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
|
| - // ScheduleDraw() should have been invoked.
|
| - EXPECT_TRUE(schedule_draw_invoked_);
|
| - // Because SchedulePaint() was invoked from OnPaintLayer() |child| should
|
| - // still need to be painted.
|
| - DrawTree(root.get());
|
| - EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
|
| - EXPECT_TRUE(child_delegate.last_clip_rect().Contains(
|
| - gfx::Rect(10, 10, 30, 30)));
|
| -}
|
| -
|
| -} // namespace ui
|
|
|