This source file includes following definitions.
- color_
- OnPaintLayer
- OnDeviceScaleFactorChanged
- PrepareForLayerBoundsChange
- SetUp
- TearDown
- GetCompositor
- CreateLayer
- CreateColorLayer
- CreateNoTextureLayer
- DrawTree
- ReadPixels
- ReadPixels
- WaitForDraw
- WaitForCommit
- SchedulePaintForLayer
- test_data_directory
- OutputRequestCallback
- completed
- result
- AddColor
- paint_size
- color_index
- ToScaleString
- device_scale_factor
- OnPaintLayer
- OnDeviceScaleFactorChanged
- PrepareForLayerBoundsChange
- reset
- Reset
- painted
- OnPaintLayer
- OnDeviceScaleFactorChanged
- PrepareForLayerBoundsChange
- OnPaintLayer
- OnDeviceScaleFactorChanged
- PrepareForLayerBoundsChange
- aborted_
- committed
- notified
- aborted
- Reset
- OnCompositingDidCommit
- OnCompositingStarted
- OnCompositingEnded
- OnCompositingAborted
- OnCompositingLockStateChanged
- TEST_F
- TEST_F
- SetUp
- TearDown
- compositor
- CreateLayer
- CreateColorLayer
- CreateNoTextureLayer
- DrawTree
- SchedulePaintForLayer
- Draw
- WaitForDraw
- WaitForCommit
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- SetUp
- CreateLayer
- CreateTextureRootLayer
- CreateTextureLayer
- CreateNoTextureLayer
- PrepareTexture
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- layer_
- set_layer
- SetSchedulePaintRect
- GetPaintCountAndClear
- last_clip_rect
- OnPaintLayer
- OnDeviceScaleFactorChanged
- PrepareForLayerBoundsChange
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- MakeFrameData
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/debug/trace_event.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/json/json_reader.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "cc/layers/delegated_frame_provider.h"
#include "cc/layers/delegated_frame_resource_collection.h"
#include "cc/layers/layer.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
#include "cc/output/delegated_frame_data.h"
#include "cc/test/pixel_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/compositor/compositor_observer.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_sequence.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/test/context_factories_for_test.h"
#include "ui/compositor/test/draw_waiter_for_test.h"
#include "ui/compositor/test/test_compositor_host.h"
#include "ui/compositor/test/test_layers.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/gfx_paths.h"
#include "ui/gfx/skia_util.h"
using cc::MatchesPNGFile;
namespace ui {
namespace {
class ColoredLayer : public Layer, public LayerDelegate {
public:
explicit ColoredLayer(SkColor color)
: Layer(LAYER_TEXTURED),
color_(color) {
set_delegate(this);
}
virtual ~ColoredLayer() { }
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
canvas->DrawColor(color_);
}
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
}
virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
return base::Closure();
}
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() {}
virtual void SetUp() OVERRIDE {
bool enable_pixel_output = true;
InitializeContextFactoryForTests(enable_pixel_output);
Compositor::Initialize();
const gfx::Rect host_bounds(10, 10, 500, 500);
compositor_host_.reset(TestCompositorHost::Create(host_bounds));
compositor_host_->Show();
}
virtual void TearDown() OVERRIDE {
compositor_host_.reset();
TerminateContextFactoryForTests();
Compositor::Terminate();
}
Compositor* GetCompositor() { return compositor_host_->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()->ScheduleDraw();
WaitForDraw();
}
bool ReadPixels(SkBitmap* bitmap) {
return ReadPixels(bitmap, gfx::Rect(GetCompositor()->size()));
}
bool ReadPixels(SkBitmap* bitmap, gfx::Rect source_rect) {
scoped_refptr<ReadbackHolder> holder(new ReadbackHolder);
scoped_ptr<cc::CopyOutputRequest> request =
cc::CopyOutputRequest::CreateBitmapRequest(
base::Bind(&ReadbackHolder::OutputRequestCallback, holder));
request->set_area(source_rect);
GetCompositor()->root_layer()->RequestCopyOfOutput(request.Pass());
for (int i = 0; i < 2; i++) {
GetCompositor()->ScheduleDraw();
WaitForDraw();
}
if (holder->completed()) {
*bitmap = holder->result();
return true;
}
NOTREACHED();
return false;
}
void WaitForDraw() {
ui::DrawWaiterForTest::Wait(GetCompositor());
}
void WaitForCommit() {
ui::DrawWaiterForTest::WaitForCommit(GetCompositor());
}
void SchedulePaintForLayer(Layer* layer) {
layer->SchedulePaint(
gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
}
const base::FilePath& test_data_directory() const {
return test_data_directory_;
}
private:
class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> {
public:
ReadbackHolder() : completed_(false) {}
void OutputRequestCallback(scoped_ptr<cc::CopyOutputResult> result) {
DCHECK(!completed_);
result_ = result->TakeBitmap();
completed_ = true;
}
bool completed() const {
return completed_;
};
const SkBitmap& result() const { return *result_; }
private:
friend class base::RefCountedThreadSafe<ReadbackHolder>;
virtual ~ReadbackHolder() {}
scoped_ptr<SkBitmap> result_;
bool completed_;
};
scoped_ptr<TestCompositorHost> compositor_host_;
base::FilePath test_data_directory_;
DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest);
};
class TestLayerDelegate : public LayerDelegate {
public:
explicit TestLayerDelegate() { reset(); }
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_; }
std::string ToScaleString() const {
return base::StringPrintf("%.1f %.1f", scale_x_, scale_y_);
}
float device_scale_factor() const {
return device_scale_factor_;
}
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
SkISize size = canvas->sk_canvas()->getBaseLayerSize();
paint_size_ = gfx::Size(size.width(), size.height());
canvas->FillRect(gfx::Rect(paint_size_), colors_[color_index_]);
color_index_ = (color_index_ + 1) % static_cast<int>(colors_.size());
const SkMatrix& matrix = canvas->sk_canvas()->getTotalMatrix();
scale_x_ = matrix.getScaleX();
scale_y_ = matrix.getScaleY();
}
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
device_scale_factor_ = device_scale_factor;
}
virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
return base::Closure();
}
void reset() {
color_index_ = 0;
paint_size_.SetSize(0, 0);
scale_x_ = scale_y_ = 0.0f;
device_scale_factor_ = 0.0f;
}
private:
std::vector<SkColor> colors_;
int color_index_;
gfx::Size paint_size_;
float scale_x_;
float scale_y_;
float device_scale_factor_;
DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate);
};
class DrawTreeLayerDelegate : public LayerDelegate {
public:
DrawTreeLayerDelegate() : painted_(false) {}
virtual ~DrawTreeLayerDelegate() {}
void Reset() {
painted_ = false;
}
bool painted() const { return painted_; }
private:
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
painted_ = true;
}
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
}
virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
return base::Closure();
}
bool painted_;
DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate);
};
class NullLayerDelegate : public LayerDelegate {
public:
NullLayerDelegate() {}
virtual ~NullLayerDelegate() {}
private:
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
}
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
}
virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
return base::Closure();
}
DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate);
};
class TestCompositorObserver : public CompositorObserver {
public:
TestCompositorObserver()
: committed_(false), started_(false), ended_(false), aborted_(false) {}
bool committed() const { return committed_; }
bool notified() const { return started_ && ended_; }
bool aborted() const { return aborted_; }
void Reset() {
committed_ = false;
started_ = false;
ended_ = false;
aborted_ = false;
}
private:
virtual void OnCompositingDidCommit(Compositor* compositor) OVERRIDE {
committed_ = true;
}
virtual void OnCompositingStarted(Compositor* compositor,
base::TimeTicks start_time) OVERRIDE {
started_ = true;
}
virtual void OnCompositingEnded(Compositor* compositor) OVERRIDE {
ended_ = true;
}
virtual void OnCompositingAborted(Compositor* compositor) OVERRIDE {
aborted_ = true;
}
virtual void OnCompositingLockStateChanged(Compositor* compositor) OVERRIDE {
}
bool committed_;
bool started_;
bool ended_;
bool aborted_;
DISALLOW_COPY_AND_ASSIGN(TestCompositorObserver);
};
}
TEST_F(LayerWithRealCompositorTest, Draw) {
scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED,
gfx::Rect(20, 20, 50, 50)));
DrawTree(layer.get());
}
TEST_F(LayerWithRealCompositorTest, 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:
LayerWithDelegateTest() {}
virtual ~LayerWithDelegateTest() {}
virtual void SetUp() OVERRIDE {
bool enable_pixel_output = false;
InitializeContextFactoryForTests(enable_pixel_output);
Compositor::Initialize();
const gfx::Rect host_bounds(1000, 1000);
compositor_host_.reset(TestCompositorHost::Create(host_bounds));
compositor_host_->Show();
}
virtual void TearDown() OVERRIDE {
compositor_host_.reset();
TerminateContextFactoryForTests();
Compositor::Terminate();
}
Compositor* compositor() { return compositor_host_->GetCompositor(); }
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);
Draw();
}
void SchedulePaintForLayer(Layer* layer) {
layer->SchedulePaint(
gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
}
void Draw() {
compositor()->ScheduleDraw();
WaitForDraw();
}
void WaitForDraw() {
DrawWaiterForTest::Wait(compositor());
}
void WaitForCommit() {
DrawWaiterForTest::WaitForCommit(compositor());
}
private:
scoped_ptr<TestCompositorHost> compositor_host_;
DISALLOW_COPY_AND_ASSIGN(LayerWithDelegateTest);
};
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);
}
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, Delegate) {
scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorBLACK,
gfx::Rect(20, 20, 400, 400)));
GetCompositor()->SetRootLayer(l1.get());
WaitForDraw();
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));
WaitForDraw();
EXPECT_EQ(delegate.color_index(), 1);
EXPECT_EQ(delegate.paint_size(), l1->bounds().size());
l1->SchedulePaint(gfx::Rect(10, 10, 200, 200));
WaitForDraw();
EXPECT_EQ(delegate.color_index(), 2);
EXPECT_EQ(delegate.paint_size(), gfx::Size(200, 200));
l1->SchedulePaint(gfx::Rect(5, 5, 50, 50));
WaitForDraw();
EXPECT_EQ(delegate.color_index(), 0);
EXPECT_EQ(delegate.paint_size(), gfx::Size(50, 50));
}
TEST_F(LayerWithRealCompositorTest, 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());
WaitForDraw();
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));
WaitForDraw();
EXPECT_FALSE(d1.painted());
EXPECT_TRUE(d2.painted());
EXPECT_FALSE(d3.painted());
}
TEST_F(LayerWithRealCompositorTest, 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());
WaitForDraw();
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));
WaitForDraw();
EXPECT_FALSE(d2.painted());
EXPECT_TRUE(d3.painted());
}
class LayerWithNullDelegateTest : public LayerWithDelegateTest {
public:
LayerWithNullDelegateTest() {}
virtual ~LayerWithNullDelegateTest() {}
virtual void SetUp() OVERRIDE {
LayerWithDelegateTest::SetUp();
default_layer_delegate_.reset(new NullLayerDelegate());
}
virtual 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;
}
virtual Layer* CreateNoTextureLayer(const gfx::Rect& bounds) OVERRIDE {
Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
layer->SetBounds(bounds);
return layer;
}
private:
scoped_ptr<NullLayerDelegate> default_layer_delegate_;
DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest);
};
class FakeTexture : public Texture {
public:
FakeTexture(bool flipped, const gfx::Size& size, float device_scale_factor)
: Texture(flipped, size, device_scale_factor) {}
virtual unsigned int PrepareTexture() OVERRIDE { return 0; }
protected:
virtual ~FakeTexture() {}
};
TEST_F(LayerWithNullDelegateTest, EscapedDebugNames) {
scoped_ptr<Layer> layer(CreateLayer(LAYER_NOT_DRAWN));
std::string name = "\"\'\\/\b\f\n\r\t\n";
layer->set_name(name);
scoped_refptr<base::debug::ConvertableToTraceFormat> debug_info =
layer->TakeDebugInfo();
EXPECT_TRUE(!!debug_info);
std::string json;
debug_info->AppendAsTraceFormat(&json);
base::JSONReader json_reader;
scoped_ptr<base::Value> debug_info_value(json_reader.ReadToValue(json));
EXPECT_TRUE(!!debug_info_value);
EXPECT_TRUE(debug_info_value->IsType(base::Value::TYPE_DICTIONARY));
base::DictionaryValue* dictionary = 0;
EXPECT_TRUE(debug_info_value->GetAsDictionary(&dictionary));
std::string roundtrip;
EXPECT_TRUE(dictionary->GetString("layer_name", &roundtrip));
EXPECT_EQ(name, roundtrip);
}
TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) {
scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
gfx::Rect(20, 20, 400, 400)));
l1->SetFillsBoundsOpaquely(true);
l1->SetForceRenderSurface(true);
l1->SetVisible(false);
EXPECT_EQ(gfx::PointF().ToString(),
l1->cc_layer()->anchor_point().ToString());
EXPECT_TRUE(l1->cc_layer()->DrawsContent());
EXPECT_TRUE(l1->cc_layer()->contents_opaque());
EXPECT_TRUE(l1->cc_layer()->force_render_surface());
EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
cc::Layer* before_layer = l1->cc_layer();
scoped_refptr<Texture> texture =
new FakeTexture(false, gfx::Size(10, 10), 1.f);
l1->SetExternalTexture(texture.get());
EXPECT_NE(before_layer, l1->cc_layer());
EXPECT_EQ(gfx::PointF().ToString(),
l1->cc_layer()->anchor_point().ToString());
EXPECT_TRUE(l1->cc_layer()->DrawsContent());
EXPECT_TRUE(l1->cc_layer()->contents_opaque());
EXPECT_TRUE(l1->cc_layer()->force_render_surface());
EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
}
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);
EXPECT_TRUE(l1->IsDrawn());
EXPECT_TRUE(l2->IsDrawn());
EXPECT_TRUE(l3->IsDrawn());
EXPECT_FALSE(l1->cc_layer()->hide_layer_and_subtree());
EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
EXPECT_FALSE(l3->cc_layer()->hide_layer_and_subtree());
compositor()->SetRootLayer(l1.get());
Draw();
l1->SetVisible(false);
EXPECT_FALSE(l1->IsDrawn());
EXPECT_FALSE(l2->IsDrawn());
EXPECT_FALSE(l3->IsDrawn());
EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
EXPECT_FALSE(l3->cc_layer()->hide_layer_and_subtree());
l3->SetVisible(false);
EXPECT_FALSE(l1->IsDrawn());
EXPECT_FALSE(l2->IsDrawn());
EXPECT_FALSE(l3->IsDrawn());
EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
EXPECT_TRUE(l3->cc_layer()->hide_layer_and_subtree());
l1->SetVisible(true);
EXPECT_TRUE(l1->IsDrawn());
EXPECT_TRUE(l2->IsDrawn());
EXPECT_FALSE(l3->IsDrawn());
EXPECT_FALSE(l1->cc_layer()->hide_layer_and_subtree());
EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
EXPECT_TRUE(l3->cc_layer()->hide_layer_and_subtree());
}
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());
EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
root->StackAtTop(l3.get());
EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
root->StackAtTop(l1.get());
EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
root->StackAtTop(l1.get());
EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
root->StackAbove(l2.get(), l3.get());
EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
root->StackAbove(l1.get(), l3.get());
EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
root->StackAbove(l2.get(), l1.get());
EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
root->StackAtBottom(l2.get());
EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
root->StackAtBottom(l3.get());
EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
root->StackAtBottom(l3.get());
EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
root->StackBelow(l2.get(), l3.get());
EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
root->StackBelow(l1.get(), l3.get());
EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
root->StackBelow(l3.get(), l2.get());
EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
root->StackBelow(l3.get(), l2.get());
EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
root->StackBelow(l3.get(), l1.get());
EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
}
TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) {
scoped_ptr<Layer> l1(CreateTextureLayer(gfx::Rect(0, 0, 200, 200)));
compositor()->SetRootLayer(l1.get());
Draw();
l1->SetBounds(gfx::Rect(5, 5, 200, 200));
WaitForDraw();
l1->SetBounds(gfx::Rect(5, 5, 100, 100));
WaitForDraw();
}
TEST_F(LayerWithRealCompositorTest, DrawPixels) {
gfx::Size viewport_size = GetCompositor()->size();
EXPECT_GE(viewport_size.width(), 200);
EXPECT_GE(viewport_size.height(), 200);
int blue_height = 10;
scoped_ptr<Layer> layer(
CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
scoped_ptr<Layer> layer2(
CreateColorLayer(SK_ColorBLUE,
gfx::Rect(0, 0, viewport_size.width(), blue_height)));
layer->Add(layer2.get());
DrawTree(layer.get());
SkBitmap bitmap;
ASSERT_TRUE(ReadPixels(&bitmap, gfx::Rect(viewport_size)));
ASSERT_FALSE(bitmap.empty());
SkAutoLockPixels lock(bitmap);
for (int x = 0; x < viewport_size.width(); x++) {
for (int y = 0; y < viewport_size.height(); y++) {
SkColor actual_color = bitmap.getColor(x, y);
SkColor expected_color = y < blue_height ? SK_ColorBLUE : SK_ColorRED;
EXPECT_EQ(expected_color, actual_color)
<< "Pixel error at x=" << x << " y=" << y << "; "
<< "actual RGBA=("
<< SkColorGetR(actual_color) << ","
<< SkColorGetG(actual_color) << ","
<< SkColorGetB(actual_color) << ","
<< SkColorGetA(actual_color) << "); "
<< "expected RGBA=("
<< SkColorGetR(expected_color) << ","
<< SkColorGetG(expected_color) << ","
<< SkColorGetB(expected_color) << ","
<< SkColorGetA(expected_color) << ")";
}
}
}
TEST_F(LayerWithRealCompositorTest, 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());
}
TEST_F(LayerWithRealCompositorTest, 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);
DrawTree(l1.get());
EXPECT_TRUE(observer.notified());
observer.Reset();
l1->ScheduleDraw();
WaitForCommit();
EXPECT_TRUE(observer.committed());
observer.Reset();
l2->SetBounds(gfx::Rect(0, 0, 350, 350));
WaitForDraw();
EXPECT_TRUE(observer.notified());
observer.Reset();
l2->SetBounds(gfx::Rect(0, 0, 400, 400));
WaitForDraw();
EXPECT_TRUE(observer.notified());
observer.Reset();
l2->SetOpacity(0.5f);
WaitForDraw();
EXPECT_TRUE(observer.notified());
observer.Reset();
l2->SetOpacity(1.0f);
WaitForDraw();
EXPECT_TRUE(observer.notified());
observer.Reset();
gfx::Transform transform;
transform.Translate(200.0, 200.0);
transform.Rotate(90.0);
transform.Translate(-200.0, -200.0);
l2->SetTransform(transform);
WaitForDraw();
EXPECT_TRUE(observer.notified());
observer.Reset();
l2->SetOpacity(0.1f);
GetCompositor()->DidAbortSwapBuffers();
WaitForDraw();
EXPECT_TRUE(observer.notified());
EXPECT_TRUE(observer.aborted());
GetCompositor()->RemoveObserver(&observer);
observer.Reset();
l2->SetOpacity(0.5f);
WaitForDraw();
EXPECT_FALSE(observer.notified());
}
TEST_F(LayerWithRealCompositorTest, ModifyHierarchy) {
GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
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)));
base::FilePath ref_img1 =
test_data_directory().AppendASCII("ModifyHierarchy1.png");
base::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());
EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
l0->StackAtTop(l11.get());
DrawTree(l0.get());
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
l0->StackAbove(l12.get(), l11.get());
DrawTree(l0.get());
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
l0->StackAtTop(l11.get());
DrawTree(l0.get());
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
l0->StackAbove(l12.get(), l11.get());
DrawTree(l0.get());
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
l0->StackAbove(l11.get(), l12.get());
DrawTree(l0.get());
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
}
TEST_F(LayerWithRealCompositorTest, Opacity) {
GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
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)));
base::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());
EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true)));
}
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::RectF& last_clip_rect() const { return last_clip_rect_; }
private:
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::SkRectToRectF(sk_clip_rect);
}
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
}
virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
return base::Closure();
}
int paint_count_;
Layer* layer_;
gfx::Rect schedule_paint_rect_;
gfx::RectF last_clip_rect_;
DISALLOW_COPY_AND_ASSIGN(SchedulePaintLayerDelegate);
};
}
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());
child->SchedulePaint(gfx::Rect(0, 0, 20, 20));
EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
child_delegate.SetSchedulePaintRect(gfx::Rect(10, 10, 30, 30));
WaitForCommit();
EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
WaitForCommit();
EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
EXPECT_TRUE(child_delegate.last_clip_rect().Contains(
gfx::Rect(10, 10, 30, 30)));
}
TEST_F(LayerWithRealCompositorTest, ScaleUpDown) {
scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
gfx::Rect(10, 20, 200, 220)));
TestLayerDelegate root_delegate;
root_delegate.AddColor(SK_ColorWHITE);
root->set_delegate(&root_delegate);
scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
gfx::Rect(10, 20, 140, 180)));
TestLayerDelegate l1_delegate;
l1_delegate.AddColor(SK_ColorWHITE);
l1->set_delegate(&l1_delegate);
GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
GetCompositor()->SetRootLayer(root.get());
root->Add(l1.get());
WaitForDraw();
EXPECT_EQ("10,20 200x220", root->bounds().ToString());
EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
gfx::Size size_in_pixel = root->cc_layer()->bounds();
EXPECT_EQ("200x220", size_in_pixel.ToString());
size_in_pixel = l1->cc_layer()->bounds();
EXPECT_EQ("140x180", size_in_pixel.ToString());
EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
EXPECT_EQ("200x220", root_delegate.paint_size().ToString());
EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
EXPECT_EQ("10,20 200x220", root->bounds().ToString());
EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
size_in_pixel = root->cc_layer()->bounds();
EXPECT_EQ("400x440", size_in_pixel.ToString());
size_in_pixel = l1->cc_layer()->bounds();
EXPECT_EQ("280x360", size_in_pixel.ToString());
EXPECT_EQ(2.0f, root_delegate.device_scale_factor());
EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
WaitForDraw();
EXPECT_EQ("400x440", root_delegate.paint_size().ToString());
EXPECT_EQ("2.0 2.0", root_delegate.ToScaleString());
EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
EXPECT_EQ("2.0 2.0", l1_delegate.ToScaleString());
GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
EXPECT_EQ("10,20 200x220", root->bounds().ToString());
EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
size_in_pixel = root->cc_layer()->bounds();
EXPECT_EQ("200x220", size_in_pixel.ToString());
size_in_pixel = l1->cc_layer()->bounds();
EXPECT_EQ("140x180", size_in_pixel.ToString());
EXPECT_EQ(1.0f, root_delegate.device_scale_factor());
EXPECT_EQ(1.0f, l1_delegate.device_scale_factor());
WaitForDraw();
EXPECT_EQ("200x220", root_delegate.paint_size().ToString());
EXPECT_EQ("1.0 1.0", root_delegate.ToScaleString());
EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
root_delegate.reset();
l1_delegate.reset();
GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(1000, 1000));
EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
WaitForDraw();
EXPECT_EQ("0x0", root_delegate.paint_size().ToString());
EXPECT_EQ("0.0 0.0", root_delegate.ToScaleString());
EXPECT_EQ("0x0", l1_delegate.paint_size().ToString());
EXPECT_EQ("0.0 0.0", l1_delegate.ToScaleString());
}
TEST_F(LayerWithRealCompositorTest, ScaleReparent) {
scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
gfx::Rect(10, 20, 200, 220)));
scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
gfx::Rect(10, 20, 140, 180)));
TestLayerDelegate l1_delegate;
l1_delegate.AddColor(SK_ColorWHITE);
l1->set_delegate(&l1_delegate);
GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
GetCompositor()->SetRootLayer(root.get());
WaitForDraw();
root->Add(l1.get());
EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
gfx::Size size_in_pixel = l1->cc_layer()->bounds();
EXPECT_EQ("140x180", size_in_pixel.ToString());
EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
WaitForDraw();
EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
root->Remove(l1.get());
EXPECT_EQ(NULL, l1->parent());
EXPECT_EQ(NULL, l1->GetCompositor());
GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
EXPECT_EQ("10,20 200x220", root->bounds().ToString());
size_in_pixel = l1->cc_layer()->bounds();
EXPECT_EQ("140x180", size_in_pixel.ToString());
root->Add(l1.get());
EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
size_in_pixel = l1->cc_layer()->bounds();
EXPECT_EQ("280x360", size_in_pixel.ToString());
EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
WaitForDraw();
EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
EXPECT_EQ("2.0 2.0", l1_delegate.ToScaleString());
}
TEST_F(LayerWithRealCompositorTest, NoScaleCanvas) {
scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
gfx::Rect(10, 20, 200, 220)));
scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
gfx::Rect(10, 20, 140, 180)));
l1->set_scale_content(false);
root->Add(l1.get());
TestLayerDelegate l1_delegate;
l1_delegate.AddColor(SK_ColorWHITE);
l1->set_delegate(&l1_delegate);
GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
GetCompositor()->SetRootLayer(root.get());
EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
WaitForDraw();
EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
}
TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) {
scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
child->SetBounds(gfx::Rect(0, 0, 500, 500));
DrawTreeLayerDelegate delegate;
child->set_delegate(&delegate);
root->Add(child.get());
child->SetVisible(true);
DrawTree(root.get());
child->SetVisible(false);
DrawTree(root.get());
delegate.Reset();
child->SetBounds(gfx::Rect(200, 200, 500, 500));
child->SetVisible(true);
DrawTree(root.get());
EXPECT_FALSE(delegate.painted());
child->SetVisible(false);
DrawTree(root.get());
delegate.Reset();
child->SetBounds(gfx::Rect(200, 200, 400, 400));
child->SetVisible(true);
DrawTree(root.get());
EXPECT_TRUE(delegate.painted());
}
static scoped_ptr<cc::DelegatedFrameData> MakeFrameData(gfx::Size size) {
scoped_ptr<cc::DelegatedFrameData> frame_data(new cc::DelegatedFrameData);
scoped_ptr<cc::RenderPass> render_pass(cc::RenderPass::Create());
render_pass->SetNew(cc::RenderPass::Id(1, 1),
gfx::Rect(size),
gfx::RectF(),
gfx::Transform());
frame_data->render_pass_list.push_back(render_pass.Pass());
return frame_data.Pass();
}
TEST_F(LayerWithDelegateTest, DelegatedLayer) {
scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
child->SetBounds(gfx::Rect(0, 0, 10, 10));
child->SetVisible(true);
root->Add(child.get());
DrawTree(root.get());
scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
new cc::DelegatedFrameResourceCollection;
scoped_refptr<cc::DelegatedFrameProvider> frame_provider;
frame_provider = new cc::DelegatedFrameProvider(
resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
EXPECT_EQ(child->cc_layer()->bounds().ToString(),
gfx::Size(10, 10).ToString());
child->SetBounds(gfx::Rect(0, 0, 5, 5));
EXPECT_EQ(child->cc_layer()->bounds().ToString(),
gfx::Size(5, 5).ToString());
child->SetBounds(gfx::Rect(0, 0, 10, 10));
frame_provider = new cc::DelegatedFrameProvider(
resource_collection.get(), MakeFrameData(gfx::Size(5, 5)));
child->SetShowDelegatedContent(frame_provider, gfx::Size(5, 5));
EXPECT_EQ(child->cc_layer()->bounds().ToString(), gfx::Size(5, 5).ToString());
frame_provider = new cc::DelegatedFrameProvider(
resource_collection.get(), MakeFrameData(gfx::Size(20, 20)));
child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
EXPECT_EQ(child->cc_layer()->bounds().ToString(),
gfx::Size(10, 10).ToString());
compositor()->SetScaleAndSize(2.f, gfx::Size(1000, 1000));
EXPECT_EQ(child->cc_layer()->bounds().ToString(),
gfx::Size(20, 20).ToString());
frame_provider = new cc::DelegatedFrameProvider(
resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
EXPECT_EQ(child->cc_layer()->bounds().ToString(),
gfx::Size(20, 20).ToString());
}
TEST_F(LayerWithDelegateTest, ExternalContent) {
scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
child->SetBounds(gfx::Rect(0, 0, 10, 10));
child->SetVisible(true);
root->Add(child.get());
scoped_refptr<cc::Layer> before = child->cc_layer();
child->SetShowPaintedContent();
EXPECT_TRUE(child->cc_layer());
EXPECT_EQ(before, child->cc_layer());
scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
new cc::DelegatedFrameResourceCollection;
scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
new cc::DelegatedFrameProvider(resource_collection.get(),
MakeFrameData(gfx::Size(10, 10)));
before = child->cc_layer();
child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
EXPECT_TRUE(child->cc_layer());
EXPECT_NE(before, child->cc_layer());
before = child->cc_layer();
child->SetShowPaintedContent();
EXPECT_TRUE(child->cc_layer());
EXPECT_NE(before, child->cc_layer());
}
TEST_F(LayerWithRealCompositorTest, AddRemoveThreadedAnimations) {
scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
scoped_ptr<Layer> l2(CreateLayer(LAYER_TEXTURED));
l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
l2->SetAnimator(LayerAnimator::CreateImplicitAnimator());
EXPECT_FALSE(l1->HasPendingThreadedAnimations());
l1->SetOpacity(0.5f);
EXPECT_TRUE(l1->HasPendingThreadedAnimations());
l1->GetAnimator()->StopAnimating();
EXPECT_FALSE(l1->HasPendingThreadedAnimations());
l1->SetOpacity(0.2f);
EXPECT_TRUE(l1->HasPendingThreadedAnimations());
root->Add(l1.get());
GetCompositor()->SetRootLayer(root.get());
EXPECT_FALSE(l1->HasPendingThreadedAnimations());
l1->SetOpacity(0.1f);
EXPECT_FALSE(l1->HasPendingThreadedAnimations());
l2->SetOpacity(0.5f);
EXPECT_TRUE(l2->HasPendingThreadedAnimations());
l1->Add(l2.get());
EXPECT_FALSE(l2->HasPendingThreadedAnimations());
}
TEST_F(LayerWithRealCompositorTest, SwitchCCLayerAnimations) {
scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
GetCompositor()->SetRootLayer(root.get());
root->Add(l1.get());
l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
EXPECT_FLOAT_EQ(l1->opacity(), 1.0f);
l1->SetOpacity(0.5f);
l1->SwitchCCLayerForTest();
EXPECT_FLOAT_EQ(l1->opacity(), 0.5f);
}
}