1 // Copyright (c) 2012 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.
5 #include "base/basictypes.h"
7 #include "base/compiler_specific.h"
8 #include "base/debug/trace_event.h"
9 #include "base/file_util.h"
10 #include "base/files/file_path.h"
11 #include "base/json/json_reader.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/path_service.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "cc/layers/delegated_frame_provider.h"
18 #include "cc/layers/delegated_frame_resource_collection.h"
19 #include "cc/layers/layer.h"
20 #include "cc/output/delegated_frame_data.h"
21 #include "cc/test/pixel_test_utils.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/compositor/compositor_observer.h"
24 #include "ui/compositor/layer.h"
25 #include "ui/compositor/layer_animation_sequence.h"
26 #include "ui/compositor/layer_animator.h"
27 #include "ui/compositor/test/context_factories_for_test.h"
28 #include "ui/compositor/test/draw_waiter_for_test.h"
29 #include "ui/compositor/test/test_compositor_host.h"
30 #include "ui/compositor/test/test_layers.h"
31 #include "ui/gfx/canvas.h"
32 #include "ui/gfx/codec/png_codec.h"
33 #include "ui/gfx/gfx_paths.h"
34 #include "ui/gfx/skia_util.h"
36 using cc::MatchesPNGFile;
42 // There are three test classes in here that configure the Compositor and
43 // Layer's slightly differently:
44 // - LayerWithNullDelegateTest uses NullLayerDelegate as the LayerDelegate. This
45 // is typically the base class you want to use.
46 // - LayerWithDelegateTest uses LayerDelegate on the delegates.
47 // - LayerWithRealCompositorTest when a real compositor is required for testing.
48 // - Slow because they bring up a window and run the real compositor. This
49 // is typically not what you want.
51 class ColoredLayer : public Layer, public LayerDelegate {
53 explicit ColoredLayer(SkColor color)
54 : Layer(LAYER_TEXTURED),
59 virtual ~ColoredLayer() { }
61 // Overridden from LayerDelegate:
62 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
63 canvas->DrawColor(color_);
66 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
69 virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
70 return base::Closure();
77 class LayerWithRealCompositorTest : public testing::Test {
79 LayerWithRealCompositorTest() {
80 if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) {
81 test_data_directory_ = test_data_directory_.AppendASCII("compositor");
83 LOG(ERROR) << "Could not open test data directory.";
86 virtual ~LayerWithRealCompositorTest() {}
88 // Overridden from testing::Test:
89 virtual void SetUp() OVERRIDE {
90 bool allow_test_contexts = false;
91 InitializeContextFactoryForTests(allow_test_contexts);
92 Compositor::Initialize();
94 const gfx::Rect host_bounds(10, 10, 500, 500);
95 window_.reset(TestCompositorHost::Create(host_bounds));
99 virtual void TearDown() OVERRIDE {
101 TerminateContextFactoryForTests();
102 Compositor::Terminate();
105 Compositor* GetCompositor() {
106 return window_->GetCompositor();
109 Layer* CreateLayer(LayerType type) {
110 return new Layer(type);
113 Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
114 Layer* layer = new ColoredLayer(color);
115 layer->SetBounds(bounds);
119 Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
120 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
121 layer->SetBounds(bounds);
125 void DrawTree(Layer* root) {
126 GetCompositor()->SetRootLayer(root);
127 GetCompositor()->ScheduleDraw();
131 bool ReadPixels(SkBitmap* bitmap) {
132 return GetCompositor()->ReadPixels(bitmap,
133 gfx::Rect(GetCompositor()->size()));
137 ui::DrawWaiterForTest::Wait(GetCompositor());
140 void WaitForCommit() {
141 ui::DrawWaiterForTest::WaitForCommit(GetCompositor());
144 // Invalidates the entire contents of the layer.
145 void SchedulePaintForLayer(Layer* layer) {
146 layer->SchedulePaint(
147 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
150 const base::FilePath& test_data_directory() const {
151 return test_data_directory_;
155 scoped_ptr<TestCompositorHost> window_;
157 // The root directory for test files.
158 base::FilePath test_data_directory_;
160 DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest);
163 // LayerDelegate that paints colors to the layer.
164 class TestLayerDelegate : public LayerDelegate {
166 explicit TestLayerDelegate() { reset(); }
167 virtual ~TestLayerDelegate() {}
169 void AddColor(SkColor color) {
170 colors_.push_back(color);
173 const gfx::Size& paint_size() const { return paint_size_; }
174 int color_index() const { return color_index_; }
176 std::string ToScaleString() const {
177 return base::StringPrintf("%.1f %.1f", scale_x_, scale_y_);
180 float device_scale_factor() const {
181 return device_scale_factor_;
184 // Overridden from LayerDelegate:
185 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
186 gfx::ImageSkiaRep contents = canvas->ExtractImageRep();
187 paint_size_ = gfx::Size(contents.pixel_width(), contents.pixel_height());
188 canvas->FillRect(gfx::Rect(paint_size_), colors_[color_index_]);
189 color_index_ = (color_index_ + 1) % static_cast<int>(colors_.size());
190 const SkMatrix& matrix = canvas->sk_canvas()->getTotalMatrix();
191 scale_x_ = matrix.getScaleX();
192 scale_y_ = matrix.getScaleY();
195 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
196 device_scale_factor_ = device_scale_factor;
199 virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
200 return base::Closure();
205 paint_size_.SetSize(0, 0);
206 scale_x_ = scale_y_ = 0.0f;
207 device_scale_factor_ = 0.0f;
211 std::vector<SkColor> colors_;
213 gfx::Size paint_size_;
216 float device_scale_factor_;
218 DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate);
221 // LayerDelegate that verifies that a layer was asked to update its canvas.
222 class DrawTreeLayerDelegate : public LayerDelegate {
224 DrawTreeLayerDelegate() : painted_(false) {}
225 virtual ~DrawTreeLayerDelegate() {}
231 bool painted() const { return painted_; }
234 // Overridden from LayerDelegate:
235 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
238 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
240 virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
241 return base::Closure();
246 DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate);
249 // The simplest possible layer delegate. Does nothing.
250 class NullLayerDelegate : public LayerDelegate {
252 NullLayerDelegate() {}
253 virtual ~NullLayerDelegate() {}
256 // Overridden from LayerDelegate:
257 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
259 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
261 virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
262 return base::Closure();
265 DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate);
268 // Remembers if it has been notified.
269 class TestCompositorObserver : public CompositorObserver {
271 TestCompositorObserver()
272 : committed_(false), started_(false), ended_(false), aborted_(false) {}
274 bool committed() const { return committed_; }
275 bool notified() const { return started_ && ended_; }
276 bool aborted() const { return aborted_; }
286 virtual void OnCompositingDidCommit(Compositor* compositor) OVERRIDE {
290 virtual void OnCompositingStarted(Compositor* compositor,
291 base::TimeTicks start_time) OVERRIDE {
295 virtual void OnCompositingEnded(Compositor* compositor) OVERRIDE {
299 virtual void OnCompositingAborted(Compositor* compositor) OVERRIDE {
303 virtual void OnCompositingLockStateChanged(Compositor* compositor) OVERRIDE {
306 virtual void OnUpdateVSyncParameters(Compositor* compositor,
307 base::TimeTicks timebase,
308 base::TimeDelta interval) OVERRIDE {
316 DISALLOW_COPY_AND_ASSIGN(TestCompositorObserver);
321 TEST_F(LayerWithRealCompositorTest, Draw) {
322 scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED,
323 gfx::Rect(20, 20, 50, 50)));
324 DrawTree(layer.get());
327 // Create this hierarchy:
333 TEST_F(LayerWithRealCompositorTest, Hierarchy) {
334 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
335 gfx::Rect(20, 20, 400, 400)));
336 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
337 gfx::Rect(10, 10, 350, 350)));
338 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
339 gfx::Rect(5, 5, 25, 25)));
340 scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
341 gfx::Rect(300, 300, 100, 100)));
350 class LayerWithDelegateTest : public testing::Test {
352 LayerWithDelegateTest() {}
353 virtual ~LayerWithDelegateTest() {}
355 // Overridden from testing::Test:
356 virtual void SetUp() OVERRIDE {
357 bool allow_test_contexts = true;
358 InitializeContextFactoryForTests(allow_test_contexts);
359 Compositor::Initialize();
360 compositor_.reset(new Compositor(gfx::kNullAcceleratedWidget));
361 compositor_->SetScaleAndSize(1.0f, gfx::Size(1000, 1000));
364 virtual void TearDown() OVERRIDE {
366 TerminateContextFactoryForTests();
367 Compositor::Terminate();
370 Compositor* compositor() { return compositor_.get(); }
372 virtual Layer* CreateLayer(LayerType type) {
373 return new Layer(type);
376 Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
377 Layer* layer = new ColoredLayer(color);
378 layer->SetBounds(bounds);
382 virtual Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
383 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
384 layer->SetBounds(bounds);
388 void DrawTree(Layer* root) {
389 compositor()->SetRootLayer(root);
393 // Invalidates the entire contents of the layer.
394 void SchedulePaintForLayer(Layer* layer) {
395 layer->SchedulePaint(
396 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
399 // Invokes DrawTree on the compositor.
401 compositor()->ScheduleDraw();
406 DrawWaiterForTest::Wait(compositor());
409 void WaitForCommit() {
410 DrawWaiterForTest::WaitForCommit(compositor());
414 scoped_ptr<Compositor> compositor_;
416 DISALLOW_COPY_AND_ASSIGN(LayerWithDelegateTest);
421 TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Simple) {
422 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
423 gfx::Rect(20, 20, 400, 400)));
424 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
425 gfx::Rect(10, 10, 350, 350)));
429 gfx::Point point1_in_l2_coords(5, 5);
430 Layer::ConvertPointToLayer(l2.get(), l1.get(), &point1_in_l2_coords);
431 gfx::Point point1_in_l1_coords(15, 15);
432 EXPECT_EQ(point1_in_l1_coords, point1_in_l2_coords);
434 gfx::Point point2_in_l1_coords(5, 5);
435 Layer::ConvertPointToLayer(l1.get(), l2.get(), &point2_in_l1_coords);
436 gfx::Point point2_in_l2_coords(-5, -5);
437 EXPECT_EQ(point2_in_l2_coords, point2_in_l1_coords);
443 TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Medium) {
444 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
445 gfx::Rect(20, 20, 400, 400)));
446 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
447 gfx::Rect(10, 10, 350, 350)));
448 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
449 gfx::Rect(10, 10, 100, 100)));
454 gfx::Point point1_in_l3_coords(5, 5);
455 Layer::ConvertPointToLayer(l3.get(), l1.get(), &point1_in_l3_coords);
456 gfx::Point point1_in_l1_coords(25, 25);
457 EXPECT_EQ(point1_in_l1_coords, point1_in_l3_coords);
459 gfx::Point point2_in_l1_coords(5, 5);
460 Layer::ConvertPointToLayer(l1.get(), l3.get(), &point2_in_l1_coords);
461 gfx::Point point2_in_l3_coords(-15, -15);
462 EXPECT_EQ(point2_in_l3_coords, point2_in_l1_coords);
465 TEST_F(LayerWithRealCompositorTest, Delegate) {
466 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorBLACK,
467 gfx::Rect(20, 20, 400, 400)));
468 GetCompositor()->SetRootLayer(l1.get());
471 TestLayerDelegate delegate;
472 l1->set_delegate(&delegate);
473 delegate.AddColor(SK_ColorWHITE);
474 delegate.AddColor(SK_ColorYELLOW);
475 delegate.AddColor(SK_ColorGREEN);
477 l1->SchedulePaint(gfx::Rect(0, 0, 400, 400));
480 EXPECT_EQ(delegate.color_index(), 1);
481 EXPECT_EQ(delegate.paint_size(), l1->bounds().size());
483 l1->SchedulePaint(gfx::Rect(10, 10, 200, 200));
485 EXPECT_EQ(delegate.color_index(), 2);
486 EXPECT_EQ(delegate.paint_size(), gfx::Size(200, 200));
488 l1->SchedulePaint(gfx::Rect(5, 5, 50, 50));
490 EXPECT_EQ(delegate.color_index(), 0);
491 EXPECT_EQ(delegate.paint_size(), gfx::Size(50, 50));
494 TEST_F(LayerWithRealCompositorTest, DrawTree) {
495 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
496 gfx::Rect(20, 20, 400, 400)));
497 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
498 gfx::Rect(10, 10, 350, 350)));
499 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
500 gfx::Rect(10, 10, 100, 100)));
504 GetCompositor()->SetRootLayer(l1.get());
507 DrawTreeLayerDelegate d1;
508 l1->set_delegate(&d1);
509 DrawTreeLayerDelegate d2;
510 l2->set_delegate(&d2);
511 DrawTreeLayerDelegate d3;
512 l3->set_delegate(&d3);
514 l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
516 EXPECT_FALSE(d1.painted());
517 EXPECT_TRUE(d2.painted());
518 EXPECT_FALSE(d3.painted());
521 // Tests no-texture Layers.
522 // Create this hierarchy:
524 // +-- L2 - NO TEXTURE
528 TEST_F(LayerWithRealCompositorTest, HierarchyNoTexture) {
529 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
530 gfx::Rect(20, 20, 400, 400)));
531 scoped_ptr<Layer> l2(CreateNoTextureLayer(gfx::Rect(10, 10, 350, 350)));
532 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
533 gfx::Rect(5, 5, 25, 25)));
534 scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
535 gfx::Rect(300, 300, 100, 100)));
541 GetCompositor()->SetRootLayer(l1.get());
544 DrawTreeLayerDelegate d2;
545 l2->set_delegate(&d2);
546 DrawTreeLayerDelegate d3;
547 l3->set_delegate(&d3);
549 l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
550 l3->SchedulePaint(gfx::Rect(5, 5, 5, 5));
553 // |d2| should not have received a paint notification since it has no texture.
554 EXPECT_FALSE(d2.painted());
555 // |d3| should have received a paint notification.
556 EXPECT_TRUE(d3.painted());
559 class LayerWithNullDelegateTest : public LayerWithDelegateTest {
561 LayerWithNullDelegateTest() {}
562 virtual ~LayerWithNullDelegateTest() {}
564 virtual void SetUp() OVERRIDE {
565 LayerWithDelegateTest::SetUp();
566 default_layer_delegate_.reset(new NullLayerDelegate());
569 virtual Layer* CreateLayer(LayerType type) OVERRIDE {
570 Layer* layer = new Layer(type);
571 layer->set_delegate(default_layer_delegate_.get());
575 Layer* CreateTextureRootLayer(const gfx::Rect& bounds) {
576 Layer* layer = CreateTextureLayer(bounds);
577 compositor()->SetRootLayer(layer);
581 Layer* CreateTextureLayer(const gfx::Rect& bounds) {
582 Layer* layer = CreateLayer(LAYER_TEXTURED);
583 layer->SetBounds(bounds);
587 virtual Layer* CreateNoTextureLayer(const gfx::Rect& bounds) OVERRIDE {
588 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
589 layer->SetBounds(bounds);
594 scoped_ptr<NullLayerDelegate> default_layer_delegate_;
596 DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest);
599 class FakeTexture : public Texture {
601 FakeTexture(bool flipped, const gfx::Size& size, float device_scale_factor)
602 : Texture(flipped, size, device_scale_factor) {}
604 virtual unsigned int PrepareTexture() OVERRIDE { return 0; }
607 virtual ~FakeTexture() {}
610 TEST_F(LayerWithNullDelegateTest, EscapedDebugNames) {
611 scoped_ptr<Layer> layer(CreateLayer(LAYER_NOT_DRAWN));
612 std::string name = "\"\'\\/\b\f\n\r\t\n";
613 layer->set_name(name);
614 scoped_refptr<base::debug::ConvertableToTraceFormat> debug_info =
615 layer->TakeDebugInfo();
616 EXPECT_TRUE(!!debug_info);
618 debug_info->AppendAsTraceFormat(&json);
619 base::JSONReader json_reader;
620 scoped_ptr<base::Value> debug_info_value(json_reader.ReadToValue(json));
621 EXPECT_TRUE(!!debug_info_value);
622 EXPECT_TRUE(debug_info_value->IsType(base::Value::TYPE_DICTIONARY));
623 base::DictionaryValue* dictionary = 0;
624 EXPECT_TRUE(debug_info_value->GetAsDictionary(&dictionary));
625 std::string roundtrip;
626 EXPECT_TRUE(dictionary->GetString("layer_name", &roundtrip));
627 EXPECT_EQ(name, roundtrip);
630 TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) {
631 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
632 gfx::Rect(20, 20, 400, 400)));
633 l1->SetFillsBoundsOpaquely(true);
634 l1->SetForceRenderSurface(true);
635 l1->SetVisible(false);
637 EXPECT_EQ(gfx::PointF().ToString(),
638 l1->cc_layer()->anchor_point().ToString());
639 EXPECT_TRUE(l1->cc_layer()->DrawsContent());
640 EXPECT_TRUE(l1->cc_layer()->contents_opaque());
641 EXPECT_TRUE(l1->cc_layer()->force_render_surface());
642 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
644 cc::Layer* before_layer = l1->cc_layer();
646 scoped_refptr<Texture> texture =
647 new FakeTexture(false, gfx::Size(10, 10), 1.f);
648 l1->SetExternalTexture(texture.get());
650 EXPECT_NE(before_layer, l1->cc_layer());
652 EXPECT_EQ(gfx::PointF().ToString(),
653 l1->cc_layer()->anchor_point().ToString());
654 EXPECT_TRUE(l1->cc_layer()->DrawsContent());
655 EXPECT_TRUE(l1->cc_layer()->contents_opaque());
656 EXPECT_TRUE(l1->cc_layer()->force_render_surface());
657 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
660 // Various visibile/drawn assertions.
661 TEST_F(LayerWithNullDelegateTest, Visibility) {
662 scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
663 scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
664 scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
668 NullLayerDelegate delegate;
669 l1->set_delegate(&delegate);
670 l2->set_delegate(&delegate);
671 l3->set_delegate(&delegate);
673 // Layers should initially be drawn.
674 EXPECT_TRUE(l1->IsDrawn());
675 EXPECT_TRUE(l2->IsDrawn());
676 EXPECT_TRUE(l3->IsDrawn());
677 EXPECT_FALSE(l1->cc_layer()->hide_layer_and_subtree());
678 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
679 EXPECT_FALSE(l3->cc_layer()->hide_layer_and_subtree());
681 compositor()->SetRootLayer(l1.get());
685 l1->SetVisible(false);
686 EXPECT_FALSE(l1->IsDrawn());
687 EXPECT_FALSE(l2->IsDrawn());
688 EXPECT_FALSE(l3->IsDrawn());
689 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
690 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
691 EXPECT_FALSE(l3->cc_layer()->hide_layer_and_subtree());
693 l3->SetVisible(false);
694 EXPECT_FALSE(l1->IsDrawn());
695 EXPECT_FALSE(l2->IsDrawn());
696 EXPECT_FALSE(l3->IsDrawn());
697 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
698 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
699 EXPECT_TRUE(l3->cc_layer()->hide_layer_and_subtree());
701 l1->SetVisible(true);
702 EXPECT_TRUE(l1->IsDrawn());
703 EXPECT_TRUE(l2->IsDrawn());
704 EXPECT_FALSE(l3->IsDrawn());
705 EXPECT_FALSE(l1->cc_layer()->hide_layer_and_subtree());
706 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
707 EXPECT_TRUE(l3->cc_layer()->hide_layer_and_subtree());
710 // Checks that stacking-related methods behave as advertised.
711 TEST_F(LayerWithNullDelegateTest, Stacking) {
712 scoped_ptr<Layer> root(new Layer(LAYER_NOT_DRAWN));
713 scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
714 scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
715 scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
723 // Layers' children are stored in bottom-to-top order.
724 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
726 root->StackAtTop(l3.get());
727 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
729 root->StackAtTop(l1.get());
730 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
732 root->StackAtTop(l1.get());
733 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
735 root->StackAbove(l2.get(), l3.get());
736 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
738 root->StackAbove(l1.get(), l3.get());
739 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
741 root->StackAbove(l2.get(), l1.get());
742 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
744 root->StackAtBottom(l2.get());
745 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
747 root->StackAtBottom(l3.get());
748 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
750 root->StackAtBottom(l3.get());
751 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
753 root->StackBelow(l2.get(), l3.get());
754 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
756 root->StackBelow(l1.get(), l3.get());
757 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
759 root->StackBelow(l3.get(), l2.get());
760 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
762 root->StackBelow(l3.get(), l2.get());
763 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
765 root->StackBelow(l3.get(), l1.get());
766 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
769 // Verifies SetBounds triggers the appropriate painting/drawing.
770 TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) {
771 scoped_ptr<Layer> l1(CreateTextureLayer(gfx::Rect(0, 0, 200, 200)));
772 compositor()->SetRootLayer(l1.get());
776 l1->SetBounds(gfx::Rect(5, 5, 200, 200));
778 // The CompositorDelegate (us) should have been told to draw for a move.
781 l1->SetBounds(gfx::Rect(5, 5, 100, 100));
783 // The CompositorDelegate (us) should have been told to draw for a resize.
787 // Checks that pixels are actually drawn to the screen with a read back.
788 TEST_F(LayerWithRealCompositorTest, DrawPixels) {
789 gfx::Size viewport_size = GetCompositor()->size();
791 // The window should be some non-trivial size but may not be exactly
792 // 500x500 on all platforms/bots.
793 EXPECT_GE(viewport_size.width(), 200);
794 EXPECT_GE(viewport_size.height(), 200);
796 int blue_height = 10;
798 scoped_ptr<Layer> layer(
799 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
800 scoped_ptr<Layer> layer2(
801 CreateColorLayer(SK_ColorBLUE,
802 gfx::Rect(0, 0, viewport_size.width(), blue_height)));
804 layer->Add(layer2.get());
806 DrawTree(layer.get());
809 ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap, gfx::Rect(viewport_size)));
810 ASSERT_FALSE(bitmap.empty());
812 SkAutoLockPixels lock(bitmap);
813 for (int x = 0; x < viewport_size.width(); x++) {
814 for (int y = 0; y < viewport_size.height(); y++) {
815 SkColor actual_color = bitmap.getColor(x, y);
816 SkColor expected_color = y < blue_height ? SK_ColorBLUE : SK_ColorRED;
817 EXPECT_EQ(expected_color, actual_color)
818 << "Pixel error at x=" << x << " y=" << y << "; "
820 << SkColorGetR(actual_color) << ","
821 << SkColorGetG(actual_color) << ","
822 << SkColorGetB(actual_color) << ","
823 << SkColorGetA(actual_color) << "); "
825 << SkColorGetR(expected_color) << ","
826 << SkColorGetG(expected_color) << ","
827 << SkColorGetB(expected_color) << ","
828 << SkColorGetA(expected_color) << ")";
833 // Checks the logic around Compositor::SetRootLayer and Layer::SetCompositor.
834 TEST_F(LayerWithRealCompositorTest, SetRootLayer) {
835 Compositor* compositor = GetCompositor();
836 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
837 gfx::Rect(20, 20, 400, 400)));
838 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
839 gfx::Rect(10, 10, 350, 350)));
841 EXPECT_EQ(NULL, l1->GetCompositor());
842 EXPECT_EQ(NULL, l2->GetCompositor());
844 compositor->SetRootLayer(l1.get());
845 EXPECT_EQ(compositor, l1->GetCompositor());
848 EXPECT_EQ(compositor, l2->GetCompositor());
850 l1->Remove(l2.get());
851 EXPECT_EQ(NULL, l2->GetCompositor());
854 EXPECT_EQ(compositor, l2->GetCompositor());
856 compositor->SetRootLayer(NULL);
857 EXPECT_EQ(NULL, l1->GetCompositor());
858 EXPECT_EQ(NULL, l2->GetCompositor());
861 // Checks that compositor observers are notified when:
862 // - DrawTree is called,
863 // - After ScheduleDraw is called, or
864 // - Whenever SetBounds, SetOpacity or SetTransform are called.
865 // TODO(vollick): could be reorganized into compositor_unittest.cc
866 TEST_F(LayerWithRealCompositorTest, CompositorObservers) {
867 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
868 gfx::Rect(20, 20, 400, 400)));
869 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
870 gfx::Rect(10, 10, 350, 350)));
872 TestCompositorObserver observer;
873 GetCompositor()->AddObserver(&observer);
875 // Explicitly called DrawTree should cause the observers to be notified.
876 // NOTE: this call to DrawTree sets l1 to be the compositor's root layer.
878 EXPECT_TRUE(observer.notified());
880 // ScheduleDraw without any visible change should cause a commit.
884 EXPECT_TRUE(observer.committed());
886 // Moving, but not resizing, a layer should alert the observers.
888 l2->SetBounds(gfx::Rect(0, 0, 350, 350));
890 EXPECT_TRUE(observer.notified());
892 // So should resizing a layer.
894 l2->SetBounds(gfx::Rect(0, 0, 400, 400));
896 EXPECT_TRUE(observer.notified());
898 // Opacity changes should alert the observers.
900 l2->SetOpacity(0.5f);
902 EXPECT_TRUE(observer.notified());
904 // So should setting the opacity back.
906 l2->SetOpacity(1.0f);
908 EXPECT_TRUE(observer.notified());
910 // Setting the transform of a layer should alert the observers.
912 gfx::Transform transform;
913 transform.Translate(200.0, 200.0);
914 transform.Rotate(90.0);
915 transform.Translate(-200.0, -200.0);
916 l2->SetTransform(transform);
918 EXPECT_TRUE(observer.notified());
920 // A change resulting in an aborted swap buffer should alert the observer
921 // and also signal an abort.
923 l2->SetOpacity(0.1f);
924 GetCompositor()->DidAbortSwapBuffers();
926 EXPECT_TRUE(observer.notified());
927 EXPECT_TRUE(observer.aborted());
929 GetCompositor()->RemoveObserver(&observer);
931 // Opacity changes should no longer alert the removed observer.
933 l2->SetOpacity(0.5f);
936 EXPECT_FALSE(observer.notified());
939 // Checks that modifying the hierarchy correctly affects final composite.
940 TEST_F(LayerWithRealCompositorTest, ModifyHierarchy) {
941 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
947 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
948 gfx::Rect(0, 0, 50, 50)));
949 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
950 gfx::Rect(0, 0, 25, 25)));
951 scoped_ptr<Layer> l21(CreateColorLayer(SK_ColorMAGENTA,
952 gfx::Rect(0, 0, 15, 15)));
953 scoped_ptr<Layer> l12(CreateColorLayer(SK_ColorBLUE,
954 gfx::Rect(10, 10, 25, 25)));
956 base::FilePath ref_img1 =
957 test_data_directory().AppendASCII("ModifyHierarchy1.png");
958 base::FilePath ref_img2 =
959 test_data_directory().AppendASCII("ModifyHierarchy2.png");
966 ASSERT_TRUE(ReadPixels(&bitmap));
967 ASSERT_FALSE(bitmap.empty());
968 // WritePNGFile(bitmap, ref_img1);
969 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
971 l0->StackAtTop(l11.get());
973 ASSERT_TRUE(ReadPixels(&bitmap));
974 ASSERT_FALSE(bitmap.empty());
975 // WritePNGFile(bitmap, ref_img2);
976 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
978 // should restore to original configuration
979 l0->StackAbove(l12.get(), l11.get());
981 ASSERT_TRUE(ReadPixels(&bitmap));
982 ASSERT_FALSE(bitmap.empty());
983 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
986 l0->StackAtTop(l11.get());
988 ASSERT_TRUE(ReadPixels(&bitmap));
989 ASSERT_FALSE(bitmap.empty());
990 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
992 // should restore to original configuration
993 l0->StackAbove(l12.get(), l11.get());
995 ASSERT_TRUE(ReadPixels(&bitmap));
996 ASSERT_FALSE(bitmap.empty());
997 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1000 l0->StackAbove(l11.get(), l12.get());
1002 ASSERT_TRUE(ReadPixels(&bitmap));
1003 ASSERT_FALSE(bitmap.empty());
1004 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1007 // Opacity is rendered correctly.
1008 // Checks that modifying the hierarchy correctly affects final composite.
1009 TEST_F(LayerWithRealCompositorTest, Opacity) {
1010 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
1014 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
1015 gfx::Rect(0, 0, 50, 50)));
1016 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
1017 gfx::Rect(0, 0, 25, 25)));
1019 base::FilePath ref_img = test_data_directory().AppendASCII("Opacity.png");
1021 l11->SetOpacity(0.75);
1025 ASSERT_TRUE(ReadPixels(&bitmap));
1026 ASSERT_FALSE(bitmap.empty());
1027 // WritePNGFile(bitmap, ref_img);
1028 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true)));
1033 class SchedulePaintLayerDelegate : public LayerDelegate {
1035 SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {}
1037 virtual ~SchedulePaintLayerDelegate() {}
1039 void set_layer(Layer* layer) {
1041 layer_->set_delegate(this);
1044 void SetSchedulePaintRect(const gfx::Rect& rect) {
1045 schedule_paint_rect_ = rect;
1048 int GetPaintCountAndClear() {
1049 int value = paint_count_;
1054 const gfx::RectF& last_clip_rect() const { return last_clip_rect_; }
1057 // Overridden from LayerDelegate:
1058 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
1060 if (!schedule_paint_rect_.IsEmpty()) {
1061 layer_->SchedulePaint(schedule_paint_rect_);
1062 schedule_paint_rect_ = gfx::Rect();
1064 SkRect sk_clip_rect;
1065 if (canvas->sk_canvas()->getClipBounds(&sk_clip_rect))
1066 last_clip_rect_ = gfx::SkRectToRectF(sk_clip_rect);
1069 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
1072 virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
1073 return base::Closure();
1078 gfx::Rect schedule_paint_rect_;
1079 gfx::RectF last_clip_rect_;
1081 DISALLOW_COPY_AND_ASSIGN(SchedulePaintLayerDelegate);
1086 // Verifies that if SchedulePaint is invoked during painting the layer is still
1088 TEST_F(LayerWithDelegateTest, SchedulePaintFromOnPaintLayer) {
1089 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorRED,
1090 gfx::Rect(0, 0, 500, 500)));
1091 SchedulePaintLayerDelegate child_delegate;
1092 scoped_ptr<Layer> child(CreateColorLayer(SK_ColorBLUE,
1093 gfx::Rect(0, 0, 200, 200)));
1094 child_delegate.set_layer(child.get());
1096 root->Add(child.get());
1098 SchedulePaintForLayer(root.get());
1099 DrawTree(root.get());
1100 child->SchedulePaint(gfx::Rect(0, 0, 20, 20));
1101 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1103 // Set a rect so that when OnPaintLayer() is invoked SchedulePaint is invoked
1105 child_delegate.SetSchedulePaintRect(gfx::Rect(10, 10, 30, 30));
1107 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1109 // Because SchedulePaint() was invoked from OnPaintLayer() |child| should
1110 // still need to be painted.
1112 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1113 EXPECT_TRUE(child_delegate.last_clip_rect().Contains(
1114 gfx::Rect(10, 10, 30, 30)));
1117 TEST_F(LayerWithRealCompositorTest, ScaleUpDown) {
1118 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1119 gfx::Rect(10, 20, 200, 220)));
1120 TestLayerDelegate root_delegate;
1121 root_delegate.AddColor(SK_ColorWHITE);
1122 root->set_delegate(&root_delegate);
1124 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1125 gfx::Rect(10, 20, 140, 180)));
1126 TestLayerDelegate l1_delegate;
1127 l1_delegate.AddColor(SK_ColorWHITE);
1128 l1->set_delegate(&l1_delegate);
1130 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1131 GetCompositor()->SetRootLayer(root.get());
1132 root->Add(l1.get());
1135 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1136 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1137 gfx::Size size_in_pixel = root->cc_layer()->bounds();
1138 EXPECT_EQ("200x220", size_in_pixel.ToString());
1139 size_in_pixel = l1->cc_layer()->bounds();
1140 EXPECT_EQ("140x180", size_in_pixel.ToString());
1141 // No scale change, so no scale notification.
1142 EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
1143 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1145 EXPECT_EQ("200x220", root_delegate.paint_size().ToString());
1146 EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
1148 // Scale up to 2.0. Changing scale doesn't change the bounds in DIP.
1149 GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1150 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1151 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1152 // Pixel size must have been scaled up.
1153 size_in_pixel = root->cc_layer()->bounds();
1154 EXPECT_EQ("400x440", size_in_pixel.ToString());
1155 size_in_pixel = l1->cc_layer()->bounds();
1156 EXPECT_EQ("280x360", size_in_pixel.ToString());
1157 // New scale factor must have been notified.
1158 EXPECT_EQ(2.0f, root_delegate.device_scale_factor());
1159 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1161 // Canvas size must have been scaled down up.
1163 EXPECT_EQ("400x440", root_delegate.paint_size().ToString());
1164 EXPECT_EQ("2.0 2.0", root_delegate.ToScaleString());
1165 EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
1166 EXPECT_EQ("2.0 2.0", l1_delegate.ToScaleString());
1168 // Scale down back to 1.0f.
1169 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1170 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1171 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1172 // Pixel size must have been scaled down.
1173 size_in_pixel = root->cc_layer()->bounds();
1174 EXPECT_EQ("200x220", size_in_pixel.ToString());
1175 size_in_pixel = l1->cc_layer()->bounds();
1176 EXPECT_EQ("140x180", size_in_pixel.ToString());
1177 // New scale factor must have been notified.
1178 EXPECT_EQ(1.0f, root_delegate.device_scale_factor());
1179 EXPECT_EQ(1.0f, l1_delegate.device_scale_factor());
1181 // Canvas size must have been scaled down too.
1183 EXPECT_EQ("200x220", root_delegate.paint_size().ToString());
1184 EXPECT_EQ("1.0 1.0", root_delegate.ToScaleString());
1185 EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
1186 EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
1188 root_delegate.reset();
1189 l1_delegate.reset();
1190 // Just changing the size shouldn't notify the scale change nor
1192 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(1000, 1000));
1193 // No scale change, so no scale notification.
1194 EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
1195 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1197 EXPECT_EQ("0x0", root_delegate.paint_size().ToString());
1198 EXPECT_EQ("0.0 0.0", root_delegate.ToScaleString());
1199 EXPECT_EQ("0x0", l1_delegate.paint_size().ToString());
1200 EXPECT_EQ("0.0 0.0", l1_delegate.ToScaleString());
1203 TEST_F(LayerWithRealCompositorTest, ScaleReparent) {
1204 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1205 gfx::Rect(10, 20, 200, 220)));
1206 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1207 gfx::Rect(10, 20, 140, 180)));
1208 TestLayerDelegate l1_delegate;
1209 l1_delegate.AddColor(SK_ColorWHITE);
1210 l1->set_delegate(&l1_delegate);
1212 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1213 GetCompositor()->SetRootLayer(root.get());
1216 root->Add(l1.get());
1217 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1218 gfx::Size size_in_pixel = l1->cc_layer()->bounds();
1219 EXPECT_EQ("140x180", size_in_pixel.ToString());
1220 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1223 EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
1224 EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
1226 // Remove l1 from root and change the scale.
1227 root->Remove(l1.get());
1228 EXPECT_EQ(NULL, l1->parent());
1229 EXPECT_EQ(NULL, l1->GetCompositor());
1230 GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1231 // Sanity check on root and l1.
1232 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1233 size_in_pixel = l1->cc_layer()->bounds();
1234 EXPECT_EQ("140x180", size_in_pixel.ToString());
1237 root->Add(l1.get());
1238 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1239 size_in_pixel = l1->cc_layer()->bounds();
1240 EXPECT_EQ("280x360", size_in_pixel.ToString());
1241 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1243 EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
1244 EXPECT_EQ("2.0 2.0", l1_delegate.ToScaleString());
1247 // Tests layer::set_scale_content(false).
1248 TEST_F(LayerWithRealCompositorTest, NoScaleCanvas) {
1249 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1250 gfx::Rect(10, 20, 200, 220)));
1251 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1252 gfx::Rect(10, 20, 140, 180)));
1253 l1->set_scale_content(false);
1254 root->Add(l1.get());
1255 TestLayerDelegate l1_delegate;
1256 l1_delegate.AddColor(SK_ColorWHITE);
1257 l1->set_delegate(&l1_delegate);
1259 GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1260 GetCompositor()->SetRootLayer(root.get());
1261 // Scale factor change is notified regardless of scale_content flag.
1262 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1265 EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
1266 EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
1269 // Verifies that when changing bounds on a layer that is invisible, and then
1270 // made visible, the right thing happens:
1271 // - if just a move, then no painting should happen.
1272 // - if a resize, the layer should be repainted.
1273 TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) {
1274 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1276 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1277 child->SetBounds(gfx::Rect(0, 0, 500, 500));
1278 DrawTreeLayerDelegate delegate;
1279 child->set_delegate(&delegate);
1280 root->Add(child.get());
1282 // Paint once for initial damage.
1283 child->SetVisible(true);
1284 DrawTree(root.get());
1286 // Reset into invisible state.
1287 child->SetVisible(false);
1288 DrawTree(root.get());
1292 child->SetBounds(gfx::Rect(200, 200, 500, 500));
1293 child->SetVisible(true);
1294 DrawTree(root.get());
1295 EXPECT_FALSE(delegate.painted());
1297 // Reset into invisible state.
1298 child->SetVisible(false);
1299 DrawTree(root.get());
1303 child->SetBounds(gfx::Rect(200, 200, 400, 400));
1304 child->SetVisible(true);
1305 DrawTree(root.get());
1306 EXPECT_TRUE(delegate.painted());
1309 static scoped_ptr<cc::DelegatedFrameData> MakeFrameData(gfx::Size size) {
1310 scoped_ptr<cc::DelegatedFrameData> frame_data(new cc::DelegatedFrameData);
1311 scoped_ptr<cc::RenderPass> render_pass(cc::RenderPass::Create());
1312 render_pass->SetNew(cc::RenderPass::Id(1, 1),
1316 frame_data->render_pass_list.push_back(render_pass.Pass());
1317 return frame_data.Pass();
1320 TEST_F(LayerWithDelegateTest, DelegatedLayer) {
1321 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1323 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1325 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1326 child->SetVisible(true);
1327 root->Add(child.get());
1328 DrawTree(root.get());
1330 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1331 new cc::DelegatedFrameResourceCollection;
1332 scoped_refptr<cc::DelegatedFrameProvider> frame_provider;
1334 // Content matches layer size.
1335 frame_provider = new cc::DelegatedFrameProvider(
1336 resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
1337 child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
1338 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1339 gfx::Size(10, 10).ToString());
1341 // Content larger than layer.
1342 child->SetBounds(gfx::Rect(0, 0, 5, 5));
1343 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1344 gfx::Size(5, 5).ToString());
1346 // Content smaller than layer.
1347 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1348 frame_provider = new cc::DelegatedFrameProvider(
1349 resource_collection.get(), MakeFrameData(gfx::Size(5, 5)));
1350 child->SetShowDelegatedContent(frame_provider, gfx::Size(5, 5));
1351 EXPECT_EQ(child->cc_layer()->bounds().ToString(), gfx::Size(5, 5).ToString());
1353 // Hi-DPI content on low-DPI layer.
1354 frame_provider = new cc::DelegatedFrameProvider(
1355 resource_collection.get(), MakeFrameData(gfx::Size(20, 20)));
1356 child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
1357 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1358 gfx::Size(10, 10).ToString());
1360 // Hi-DPI content on hi-DPI layer.
1361 compositor()->SetScaleAndSize(2.f, gfx::Size(1000, 1000));
1362 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1363 gfx::Size(20, 20).ToString());
1365 // Low-DPI content on hi-DPI layer.
1366 frame_provider = new cc::DelegatedFrameProvider(
1367 resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
1368 child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
1369 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1370 gfx::Size(20, 20).ToString());
1373 TEST_F(LayerWithDelegateTest, ExternalContent) {
1374 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1375 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1377 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1378 child->SetVisible(true);
1379 root->Add(child.get());
1381 // The layer is already showing painted content, so the cc layer won't change.
1382 scoped_refptr<cc::Layer> before = child->cc_layer();
1383 child->SetShowPaintedContent();
1384 EXPECT_TRUE(child->cc_layer());
1385 EXPECT_EQ(before, child->cc_layer());
1387 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1388 new cc::DelegatedFrameResourceCollection;
1389 scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
1390 new cc::DelegatedFrameProvider(resource_collection.get(),
1391 MakeFrameData(gfx::Size(10, 10)));
1393 // Showing delegated content changes the underlying cc layer.
1394 before = child->cc_layer();
1395 child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
1396 EXPECT_TRUE(child->cc_layer());
1397 EXPECT_NE(before, child->cc_layer());
1399 // Changing to painted content should change the underlying cc layer.
1400 before = child->cc_layer();
1401 child->SetShowPaintedContent();
1402 EXPECT_TRUE(child->cc_layer());
1403 EXPECT_NE(before, child->cc_layer());
1406 // Tests Layer::AddThreadedAnimation and Layer::RemoveThreadedAnimation.
1407 TEST_F(LayerWithRealCompositorTest, AddRemoveThreadedAnimations) {
1408 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1409 scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
1410 scoped_ptr<Layer> l2(CreateLayer(LAYER_TEXTURED));
1412 l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1413 l2->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1415 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1417 // Trigger a threaded animation.
1418 l1->SetOpacity(0.5f);
1420 EXPECT_TRUE(l1->HasPendingThreadedAnimations());
1422 // Ensure we can remove a pending threaded animation.
1423 l1->GetAnimator()->StopAnimating();
1425 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1427 // Trigger another threaded animation.
1428 l1->SetOpacity(0.2f);
1430 EXPECT_TRUE(l1->HasPendingThreadedAnimations());
1432 root->Add(l1.get());
1433 GetCompositor()->SetRootLayer(root.get());
1435 // Now that l1 is part of a tree, it should have dispatched the pending
1437 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1439 // Ensure that l1 no longer holds on to animations.
1440 l1->SetOpacity(0.1f);
1441 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1443 // Ensure that adding a layer to an existing tree causes its pending
1444 // animations to get dispatched.
1445 l2->SetOpacity(0.5f);
1446 EXPECT_TRUE(l2->HasPendingThreadedAnimations());
1449 EXPECT_FALSE(l2->HasPendingThreadedAnimations());
1452 // Tests that in-progress threaded animations complete when a Layer's
1453 // cc::Layer changes.
1454 TEST_F(LayerWithRealCompositorTest, SwitchCCLayerAnimations) {
1455 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1456 scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
1457 GetCompositor()->SetRootLayer(root.get());
1458 root->Add(l1.get());
1460 l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1462 EXPECT_FLOAT_EQ(l1->opacity(), 1.0f);
1464 // Trigger a threaded animation.
1465 l1->SetOpacity(0.5f);
1467 // Change l1's cc::Layer.
1468 l1->SwitchCCLayerForTest();
1470 // Ensure that the opacity animation completed.
1471 EXPECT_FLOAT_EQ(l1->opacity(), 0.5f);