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/copy_output_request.h"
21 #include "cc/output/copy_output_result.h"
22 #include "cc/output/delegated_frame_data.h"
23 #include "cc/test/pixel_test_utils.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/compositor/compositor_observer.h"
26 #include "ui/compositor/layer.h"
27 #include "ui/compositor/layer_animation_sequence.h"
28 #include "ui/compositor/layer_animator.h"
29 #include "ui/compositor/test/context_factories_for_test.h"
30 #include "ui/compositor/test/draw_waiter_for_test.h"
31 #include "ui/compositor/test/test_compositor_host.h"
32 #include "ui/compositor/test/test_layers.h"
33 #include "ui/gfx/canvas.h"
34 #include "ui/gfx/codec/png_codec.h"
35 #include "ui/gfx/gfx_paths.h"
36 #include "ui/gfx/skia_util.h"
38 using cc::MatchesPNGFile;
44 // There are three test classes in here that configure the Compositor and
45 // Layer's slightly differently:
46 // - LayerWithNullDelegateTest uses NullLayerDelegate as the LayerDelegate. This
47 // is typically the base class you want to use.
48 // - LayerWithDelegateTest uses LayerDelegate on the delegates.
49 // - LayerWithRealCompositorTest when a real compositor is required for testing.
50 // - Slow because they bring up a window and run the real compositor. This
51 // is typically not what you want.
53 class ColoredLayer : public Layer, public LayerDelegate {
55 explicit ColoredLayer(SkColor color)
56 : Layer(LAYER_TEXTURED),
61 virtual ~ColoredLayer() { }
63 // Overridden from LayerDelegate:
64 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
65 canvas->DrawColor(color_);
68 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
71 virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
72 return base::Closure();
79 class LayerWithRealCompositorTest : public testing::Test {
81 LayerWithRealCompositorTest() {
82 if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) {
83 test_data_directory_ = test_data_directory_.AppendASCII("compositor");
85 LOG(ERROR) << "Could not open test data directory.";
88 virtual ~LayerWithRealCompositorTest() {}
90 // Overridden from testing::Test:
91 virtual void SetUp() OVERRIDE {
92 bool allow_test_contexts = false;
93 InitializeContextFactoryForTests(allow_test_contexts);
94 Compositor::Initialize();
96 const gfx::Rect host_bounds(10, 10, 500, 500);
97 window_.reset(TestCompositorHost::Create(host_bounds));
101 virtual void TearDown() OVERRIDE {
103 TerminateContextFactoryForTests();
104 Compositor::Terminate();
107 Compositor* GetCompositor() {
108 return window_->GetCompositor();
111 Layer* CreateLayer(LayerType type) {
112 return new Layer(type);
115 Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
116 Layer* layer = new ColoredLayer(color);
117 layer->SetBounds(bounds);
121 Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
122 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
123 layer->SetBounds(bounds);
127 void DrawTree(Layer* root) {
128 GetCompositor()->SetRootLayer(root);
129 GetCompositor()->ScheduleDraw();
133 bool ReadPixels(SkBitmap* bitmap) {
134 return ReadPixels(bitmap, gfx::Rect(GetCompositor()->size()));
137 bool ReadPixels(SkBitmap* bitmap, gfx::Rect source_rect) {
138 scoped_refptr<ReadbackHolder> holder(new ReadbackHolder);
139 scoped_ptr<cc::CopyOutputRequest> request =
140 cc::CopyOutputRequest::CreateBitmapRequest(
141 base::Bind(&ReadbackHolder::OutputRequestCallback, holder));
142 request->set_area(source_rect);
144 GetCompositor()->root_layer()->RequestCopyOfOutput(request.Pass());
146 // Wait for copy response. This needs to wait as the compositor could
147 // be in the middle of a draw right now, and the commit with the
148 // copy output request may not be done on the first draw.
149 for (int i = 0; i < 2; i++) {
150 GetCompositor()->ScheduleDraw();
154 if (holder->completed()) {
155 *bitmap = holder->result();
159 // Callback never called.
165 ui::DrawWaiterForTest::Wait(GetCompositor());
168 void WaitForCommit() {
169 ui::DrawWaiterForTest::WaitForCommit(GetCompositor());
172 // Invalidates the entire contents of the layer.
173 void SchedulePaintForLayer(Layer* layer) {
174 layer->SchedulePaint(
175 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
178 const base::FilePath& test_data_directory() const {
179 return test_data_directory_;
183 class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> {
185 ReadbackHolder() : completed_(false) {}
187 void OutputRequestCallback(scoped_ptr<cc::CopyOutputResult> result) {
189 result_ = result->TakeBitmap();
192 bool completed() const {
195 const SkBitmap& result() const { return *result_; }
198 friend class base::RefCountedThreadSafe<ReadbackHolder>;
200 virtual ~ReadbackHolder() {}
202 scoped_ptr<SkBitmap> result_;
206 scoped_ptr<TestCompositorHost> window_;
208 // The root directory for test files.
209 base::FilePath test_data_directory_;
211 DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest);
214 // LayerDelegate that paints colors to the layer.
215 class TestLayerDelegate : public LayerDelegate {
217 explicit TestLayerDelegate() { reset(); }
218 virtual ~TestLayerDelegate() {}
220 void AddColor(SkColor color) {
221 colors_.push_back(color);
224 const gfx::Size& paint_size() const { return paint_size_; }
225 int color_index() const { return color_index_; }
227 std::string ToScaleString() const {
228 return base::StringPrintf("%.1f %.1f", scale_x_, scale_y_);
231 float device_scale_factor() const {
232 return device_scale_factor_;
235 // Overridden from LayerDelegate:
236 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
237 gfx::ImageSkiaRep contents = canvas->ExtractImageRep();
238 paint_size_ = gfx::Size(contents.pixel_width(), contents.pixel_height());
239 canvas->FillRect(gfx::Rect(paint_size_), colors_[color_index_]);
240 color_index_ = (color_index_ + 1) % static_cast<int>(colors_.size());
241 const SkMatrix& matrix = canvas->sk_canvas()->getTotalMatrix();
242 scale_x_ = matrix.getScaleX();
243 scale_y_ = matrix.getScaleY();
246 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
247 device_scale_factor_ = device_scale_factor;
250 virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
251 return base::Closure();
256 paint_size_.SetSize(0, 0);
257 scale_x_ = scale_y_ = 0.0f;
258 device_scale_factor_ = 0.0f;
262 std::vector<SkColor> colors_;
264 gfx::Size paint_size_;
267 float device_scale_factor_;
269 DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate);
272 // LayerDelegate that verifies that a layer was asked to update its canvas.
273 class DrawTreeLayerDelegate : public LayerDelegate {
275 DrawTreeLayerDelegate() : painted_(false) {}
276 virtual ~DrawTreeLayerDelegate() {}
282 bool painted() const { return painted_; }
285 // Overridden from LayerDelegate:
286 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
289 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
291 virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
292 return base::Closure();
297 DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate);
300 // The simplest possible layer delegate. Does nothing.
301 class NullLayerDelegate : public LayerDelegate {
303 NullLayerDelegate() {}
304 virtual ~NullLayerDelegate() {}
307 // Overridden from LayerDelegate:
308 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
310 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
312 virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
313 return base::Closure();
316 DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate);
319 // Remembers if it has been notified.
320 class TestCompositorObserver : public CompositorObserver {
322 TestCompositorObserver()
323 : committed_(false), started_(false), ended_(false), aborted_(false) {}
325 bool committed() const { return committed_; }
326 bool notified() const { return started_ && ended_; }
327 bool aborted() const { return aborted_; }
337 virtual void OnCompositingDidCommit(Compositor* compositor) OVERRIDE {
341 virtual void OnCompositingStarted(Compositor* compositor,
342 base::TimeTicks start_time) OVERRIDE {
346 virtual void OnCompositingEnded(Compositor* compositor) OVERRIDE {
350 virtual void OnCompositingAborted(Compositor* compositor) OVERRIDE {
354 virtual void OnCompositingLockStateChanged(Compositor* compositor) OVERRIDE {
362 DISALLOW_COPY_AND_ASSIGN(TestCompositorObserver);
367 TEST_F(LayerWithRealCompositorTest, Draw) {
368 scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED,
369 gfx::Rect(20, 20, 50, 50)));
370 DrawTree(layer.get());
373 // Create this hierarchy:
379 TEST_F(LayerWithRealCompositorTest, Hierarchy) {
380 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
381 gfx::Rect(20, 20, 400, 400)));
382 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
383 gfx::Rect(10, 10, 350, 350)));
384 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
385 gfx::Rect(5, 5, 25, 25)));
386 scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
387 gfx::Rect(300, 300, 100, 100)));
396 class LayerWithDelegateTest : public testing::Test {
398 LayerWithDelegateTest() {}
399 virtual ~LayerWithDelegateTest() {}
401 // Overridden from testing::Test:
402 virtual void SetUp() OVERRIDE {
403 bool allow_test_contexts = true;
404 InitializeContextFactoryForTests(allow_test_contexts);
405 Compositor::Initialize();
406 compositor_.reset(new Compositor(gfx::kNullAcceleratedWidget));
407 compositor_->SetScaleAndSize(1.0f, gfx::Size(1000, 1000));
410 virtual void TearDown() OVERRIDE {
412 TerminateContextFactoryForTests();
413 Compositor::Terminate();
416 Compositor* compositor() { return compositor_.get(); }
418 virtual Layer* CreateLayer(LayerType type) {
419 return new Layer(type);
422 Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
423 Layer* layer = new ColoredLayer(color);
424 layer->SetBounds(bounds);
428 virtual Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
429 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
430 layer->SetBounds(bounds);
434 void DrawTree(Layer* root) {
435 compositor()->SetRootLayer(root);
439 // Invalidates the entire contents of the layer.
440 void SchedulePaintForLayer(Layer* layer) {
441 layer->SchedulePaint(
442 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
445 // Invokes DrawTree on the compositor.
447 compositor()->ScheduleDraw();
452 DrawWaiterForTest::Wait(compositor());
455 void WaitForCommit() {
456 DrawWaiterForTest::WaitForCommit(compositor());
460 scoped_ptr<Compositor> compositor_;
462 DISALLOW_COPY_AND_ASSIGN(LayerWithDelegateTest);
467 TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Simple) {
468 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
469 gfx::Rect(20, 20, 400, 400)));
470 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
471 gfx::Rect(10, 10, 350, 350)));
475 gfx::Point point1_in_l2_coords(5, 5);
476 Layer::ConvertPointToLayer(l2.get(), l1.get(), &point1_in_l2_coords);
477 gfx::Point point1_in_l1_coords(15, 15);
478 EXPECT_EQ(point1_in_l1_coords, point1_in_l2_coords);
480 gfx::Point point2_in_l1_coords(5, 5);
481 Layer::ConvertPointToLayer(l1.get(), l2.get(), &point2_in_l1_coords);
482 gfx::Point point2_in_l2_coords(-5, -5);
483 EXPECT_EQ(point2_in_l2_coords, point2_in_l1_coords);
489 TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Medium) {
490 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
491 gfx::Rect(20, 20, 400, 400)));
492 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
493 gfx::Rect(10, 10, 350, 350)));
494 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
495 gfx::Rect(10, 10, 100, 100)));
500 gfx::Point point1_in_l3_coords(5, 5);
501 Layer::ConvertPointToLayer(l3.get(), l1.get(), &point1_in_l3_coords);
502 gfx::Point point1_in_l1_coords(25, 25);
503 EXPECT_EQ(point1_in_l1_coords, point1_in_l3_coords);
505 gfx::Point point2_in_l1_coords(5, 5);
506 Layer::ConvertPointToLayer(l1.get(), l3.get(), &point2_in_l1_coords);
507 gfx::Point point2_in_l3_coords(-15, -15);
508 EXPECT_EQ(point2_in_l3_coords, point2_in_l1_coords);
511 TEST_F(LayerWithRealCompositorTest, Delegate) {
512 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorBLACK,
513 gfx::Rect(20, 20, 400, 400)));
514 GetCompositor()->SetRootLayer(l1.get());
517 TestLayerDelegate delegate;
518 l1->set_delegate(&delegate);
519 delegate.AddColor(SK_ColorWHITE);
520 delegate.AddColor(SK_ColorYELLOW);
521 delegate.AddColor(SK_ColorGREEN);
523 l1->SchedulePaint(gfx::Rect(0, 0, 400, 400));
526 EXPECT_EQ(delegate.color_index(), 1);
527 EXPECT_EQ(delegate.paint_size(), l1->bounds().size());
529 l1->SchedulePaint(gfx::Rect(10, 10, 200, 200));
531 EXPECT_EQ(delegate.color_index(), 2);
532 EXPECT_EQ(delegate.paint_size(), gfx::Size(200, 200));
534 l1->SchedulePaint(gfx::Rect(5, 5, 50, 50));
536 EXPECT_EQ(delegate.color_index(), 0);
537 EXPECT_EQ(delegate.paint_size(), gfx::Size(50, 50));
540 TEST_F(LayerWithRealCompositorTest, DrawTree) {
541 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
542 gfx::Rect(20, 20, 400, 400)));
543 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
544 gfx::Rect(10, 10, 350, 350)));
545 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
546 gfx::Rect(10, 10, 100, 100)));
550 GetCompositor()->SetRootLayer(l1.get());
553 DrawTreeLayerDelegate d1;
554 l1->set_delegate(&d1);
555 DrawTreeLayerDelegate d2;
556 l2->set_delegate(&d2);
557 DrawTreeLayerDelegate d3;
558 l3->set_delegate(&d3);
560 l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
562 EXPECT_FALSE(d1.painted());
563 EXPECT_TRUE(d2.painted());
564 EXPECT_FALSE(d3.painted());
567 // Tests no-texture Layers.
568 // Create this hierarchy:
570 // +-- L2 - NO TEXTURE
574 TEST_F(LayerWithRealCompositorTest, HierarchyNoTexture) {
575 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
576 gfx::Rect(20, 20, 400, 400)));
577 scoped_ptr<Layer> l2(CreateNoTextureLayer(gfx::Rect(10, 10, 350, 350)));
578 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
579 gfx::Rect(5, 5, 25, 25)));
580 scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
581 gfx::Rect(300, 300, 100, 100)));
587 GetCompositor()->SetRootLayer(l1.get());
590 DrawTreeLayerDelegate d2;
591 l2->set_delegate(&d2);
592 DrawTreeLayerDelegate d3;
593 l3->set_delegate(&d3);
595 l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
596 l3->SchedulePaint(gfx::Rect(5, 5, 5, 5));
599 // |d2| should not have received a paint notification since it has no texture.
600 EXPECT_FALSE(d2.painted());
601 // |d3| should have received a paint notification.
602 EXPECT_TRUE(d3.painted());
605 class LayerWithNullDelegateTest : public LayerWithDelegateTest {
607 LayerWithNullDelegateTest() {}
608 virtual ~LayerWithNullDelegateTest() {}
610 virtual void SetUp() OVERRIDE {
611 LayerWithDelegateTest::SetUp();
612 default_layer_delegate_.reset(new NullLayerDelegate());
615 virtual Layer* CreateLayer(LayerType type) OVERRIDE {
616 Layer* layer = new Layer(type);
617 layer->set_delegate(default_layer_delegate_.get());
621 Layer* CreateTextureRootLayer(const gfx::Rect& bounds) {
622 Layer* layer = CreateTextureLayer(bounds);
623 compositor()->SetRootLayer(layer);
627 Layer* CreateTextureLayer(const gfx::Rect& bounds) {
628 Layer* layer = CreateLayer(LAYER_TEXTURED);
629 layer->SetBounds(bounds);
633 virtual Layer* CreateNoTextureLayer(const gfx::Rect& bounds) OVERRIDE {
634 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
635 layer->SetBounds(bounds);
640 scoped_ptr<NullLayerDelegate> default_layer_delegate_;
642 DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest);
645 class FakeTexture : public Texture {
647 FakeTexture(bool flipped, const gfx::Size& size, float device_scale_factor)
648 : Texture(flipped, size, device_scale_factor) {}
650 virtual unsigned int PrepareTexture() OVERRIDE { return 0; }
653 virtual ~FakeTexture() {}
656 TEST_F(LayerWithNullDelegateTest, EscapedDebugNames) {
657 scoped_ptr<Layer> layer(CreateLayer(LAYER_NOT_DRAWN));
658 std::string name = "\"\'\\/\b\f\n\r\t\n";
659 layer->set_name(name);
660 scoped_refptr<base::debug::ConvertableToTraceFormat> debug_info =
661 layer->TakeDebugInfo();
662 EXPECT_TRUE(!!debug_info);
664 debug_info->AppendAsTraceFormat(&json);
665 base::JSONReader json_reader;
666 scoped_ptr<base::Value> debug_info_value(json_reader.ReadToValue(json));
667 EXPECT_TRUE(!!debug_info_value);
668 EXPECT_TRUE(debug_info_value->IsType(base::Value::TYPE_DICTIONARY));
669 base::DictionaryValue* dictionary = 0;
670 EXPECT_TRUE(debug_info_value->GetAsDictionary(&dictionary));
671 std::string roundtrip;
672 EXPECT_TRUE(dictionary->GetString("layer_name", &roundtrip));
673 EXPECT_EQ(name, roundtrip);
676 TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) {
677 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
678 gfx::Rect(20, 20, 400, 400)));
679 l1->SetFillsBoundsOpaquely(true);
680 l1->SetForceRenderSurface(true);
681 l1->SetVisible(false);
683 EXPECT_EQ(gfx::PointF().ToString(),
684 l1->cc_layer()->anchor_point().ToString());
685 EXPECT_TRUE(l1->cc_layer()->DrawsContent());
686 EXPECT_TRUE(l1->cc_layer()->contents_opaque());
687 EXPECT_TRUE(l1->cc_layer()->force_render_surface());
688 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
690 cc::Layer* before_layer = l1->cc_layer();
692 scoped_refptr<Texture> texture =
693 new FakeTexture(false, gfx::Size(10, 10), 1.f);
694 l1->SetExternalTexture(texture.get());
696 EXPECT_NE(before_layer, l1->cc_layer());
698 EXPECT_EQ(gfx::PointF().ToString(),
699 l1->cc_layer()->anchor_point().ToString());
700 EXPECT_TRUE(l1->cc_layer()->DrawsContent());
701 EXPECT_TRUE(l1->cc_layer()->contents_opaque());
702 EXPECT_TRUE(l1->cc_layer()->force_render_surface());
703 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
706 // Various visibile/drawn assertions.
707 TEST_F(LayerWithNullDelegateTest, Visibility) {
708 scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
709 scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
710 scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
714 NullLayerDelegate delegate;
715 l1->set_delegate(&delegate);
716 l2->set_delegate(&delegate);
717 l3->set_delegate(&delegate);
719 // Layers should initially be drawn.
720 EXPECT_TRUE(l1->IsDrawn());
721 EXPECT_TRUE(l2->IsDrawn());
722 EXPECT_TRUE(l3->IsDrawn());
723 EXPECT_FALSE(l1->cc_layer()->hide_layer_and_subtree());
724 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
725 EXPECT_FALSE(l3->cc_layer()->hide_layer_and_subtree());
727 compositor()->SetRootLayer(l1.get());
731 l1->SetVisible(false);
732 EXPECT_FALSE(l1->IsDrawn());
733 EXPECT_FALSE(l2->IsDrawn());
734 EXPECT_FALSE(l3->IsDrawn());
735 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
736 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
737 EXPECT_FALSE(l3->cc_layer()->hide_layer_and_subtree());
739 l3->SetVisible(false);
740 EXPECT_FALSE(l1->IsDrawn());
741 EXPECT_FALSE(l2->IsDrawn());
742 EXPECT_FALSE(l3->IsDrawn());
743 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
744 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
745 EXPECT_TRUE(l3->cc_layer()->hide_layer_and_subtree());
747 l1->SetVisible(true);
748 EXPECT_TRUE(l1->IsDrawn());
749 EXPECT_TRUE(l2->IsDrawn());
750 EXPECT_FALSE(l3->IsDrawn());
751 EXPECT_FALSE(l1->cc_layer()->hide_layer_and_subtree());
752 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
753 EXPECT_TRUE(l3->cc_layer()->hide_layer_and_subtree());
756 // Checks that stacking-related methods behave as advertised.
757 TEST_F(LayerWithNullDelegateTest, Stacking) {
758 scoped_ptr<Layer> root(new Layer(LAYER_NOT_DRAWN));
759 scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
760 scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
761 scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
769 // Layers' children are stored in bottom-to-top order.
770 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
772 root->StackAtTop(l3.get());
773 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
775 root->StackAtTop(l1.get());
776 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
778 root->StackAtTop(l1.get());
779 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
781 root->StackAbove(l2.get(), l3.get());
782 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
784 root->StackAbove(l1.get(), l3.get());
785 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
787 root->StackAbove(l2.get(), l1.get());
788 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
790 root->StackAtBottom(l2.get());
791 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
793 root->StackAtBottom(l3.get());
794 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
796 root->StackAtBottom(l3.get());
797 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
799 root->StackBelow(l2.get(), l3.get());
800 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
802 root->StackBelow(l1.get(), l3.get());
803 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
805 root->StackBelow(l3.get(), l2.get());
806 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
808 root->StackBelow(l3.get(), l2.get());
809 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
811 root->StackBelow(l3.get(), l1.get());
812 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
815 // Verifies SetBounds triggers the appropriate painting/drawing.
816 TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) {
817 scoped_ptr<Layer> l1(CreateTextureLayer(gfx::Rect(0, 0, 200, 200)));
818 compositor()->SetRootLayer(l1.get());
822 l1->SetBounds(gfx::Rect(5, 5, 200, 200));
824 // The CompositorDelegate (us) should have been told to draw for a move.
827 l1->SetBounds(gfx::Rect(5, 5, 100, 100));
829 // The CompositorDelegate (us) should have been told to draw for a resize.
833 // Checks that pixels are actually drawn to the screen with a read back.
834 TEST_F(LayerWithRealCompositorTest, DrawPixels) {
835 gfx::Size viewport_size = GetCompositor()->size();
837 // The window should be some non-trivial size but may not be exactly
838 // 500x500 on all platforms/bots.
839 EXPECT_GE(viewport_size.width(), 200);
840 EXPECT_GE(viewport_size.height(), 200);
842 int blue_height = 10;
844 scoped_ptr<Layer> layer(
845 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
846 scoped_ptr<Layer> layer2(
847 CreateColorLayer(SK_ColorBLUE,
848 gfx::Rect(0, 0, viewport_size.width(), blue_height)));
850 layer->Add(layer2.get());
852 DrawTree(layer.get());
855 ASSERT_TRUE(ReadPixels(&bitmap, gfx::Rect(viewport_size)));
856 ASSERT_FALSE(bitmap.empty());
858 SkAutoLockPixels lock(bitmap);
859 for (int x = 0; x < viewport_size.width(); x++) {
860 for (int y = 0; y < viewport_size.height(); y++) {
861 SkColor actual_color = bitmap.getColor(x, y);
862 SkColor expected_color = y < blue_height ? SK_ColorBLUE : SK_ColorRED;
863 EXPECT_EQ(expected_color, actual_color)
864 << "Pixel error at x=" << x << " y=" << y << "; "
866 << SkColorGetR(actual_color) << ","
867 << SkColorGetG(actual_color) << ","
868 << SkColorGetB(actual_color) << ","
869 << SkColorGetA(actual_color) << "); "
871 << SkColorGetR(expected_color) << ","
872 << SkColorGetG(expected_color) << ","
873 << SkColorGetB(expected_color) << ","
874 << SkColorGetA(expected_color) << ")";
879 // Checks the logic around Compositor::SetRootLayer and Layer::SetCompositor.
880 TEST_F(LayerWithRealCompositorTest, SetRootLayer) {
881 Compositor* compositor = GetCompositor();
882 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
883 gfx::Rect(20, 20, 400, 400)));
884 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
885 gfx::Rect(10, 10, 350, 350)));
887 EXPECT_EQ(NULL, l1->GetCompositor());
888 EXPECT_EQ(NULL, l2->GetCompositor());
890 compositor->SetRootLayer(l1.get());
891 EXPECT_EQ(compositor, l1->GetCompositor());
894 EXPECT_EQ(compositor, l2->GetCompositor());
896 l1->Remove(l2.get());
897 EXPECT_EQ(NULL, l2->GetCompositor());
900 EXPECT_EQ(compositor, l2->GetCompositor());
902 compositor->SetRootLayer(NULL);
903 EXPECT_EQ(NULL, l1->GetCompositor());
904 EXPECT_EQ(NULL, l2->GetCompositor());
907 // Checks that compositor observers are notified when:
908 // - DrawTree is called,
909 // - After ScheduleDraw is called, or
910 // - Whenever SetBounds, SetOpacity or SetTransform are called.
911 // TODO(vollick): could be reorganized into compositor_unittest.cc
912 TEST_F(LayerWithRealCompositorTest, CompositorObservers) {
913 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
914 gfx::Rect(20, 20, 400, 400)));
915 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
916 gfx::Rect(10, 10, 350, 350)));
918 TestCompositorObserver observer;
919 GetCompositor()->AddObserver(&observer);
921 // Explicitly called DrawTree should cause the observers to be notified.
922 // NOTE: this call to DrawTree sets l1 to be the compositor's root layer.
924 EXPECT_TRUE(observer.notified());
926 // ScheduleDraw without any visible change should cause a commit.
930 EXPECT_TRUE(observer.committed());
932 // Moving, but not resizing, a layer should alert the observers.
934 l2->SetBounds(gfx::Rect(0, 0, 350, 350));
936 EXPECT_TRUE(observer.notified());
938 // So should resizing a layer.
940 l2->SetBounds(gfx::Rect(0, 0, 400, 400));
942 EXPECT_TRUE(observer.notified());
944 // Opacity changes should alert the observers.
946 l2->SetOpacity(0.5f);
948 EXPECT_TRUE(observer.notified());
950 // So should setting the opacity back.
952 l2->SetOpacity(1.0f);
954 EXPECT_TRUE(observer.notified());
956 // Setting the transform of a layer should alert the observers.
958 gfx::Transform transform;
959 transform.Translate(200.0, 200.0);
960 transform.Rotate(90.0);
961 transform.Translate(-200.0, -200.0);
962 l2->SetTransform(transform);
964 EXPECT_TRUE(observer.notified());
966 // A change resulting in an aborted swap buffer should alert the observer
967 // and also signal an abort.
969 l2->SetOpacity(0.1f);
970 GetCompositor()->DidAbortSwapBuffers();
972 EXPECT_TRUE(observer.notified());
973 EXPECT_TRUE(observer.aborted());
975 GetCompositor()->RemoveObserver(&observer);
977 // Opacity changes should no longer alert the removed observer.
979 l2->SetOpacity(0.5f);
982 EXPECT_FALSE(observer.notified());
985 // Checks that modifying the hierarchy correctly affects final composite.
986 TEST_F(LayerWithRealCompositorTest, ModifyHierarchy) {
987 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
993 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
994 gfx::Rect(0, 0, 50, 50)));
995 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
996 gfx::Rect(0, 0, 25, 25)));
997 scoped_ptr<Layer> l21(CreateColorLayer(SK_ColorMAGENTA,
998 gfx::Rect(0, 0, 15, 15)));
999 scoped_ptr<Layer> l12(CreateColorLayer(SK_ColorBLUE,
1000 gfx::Rect(10, 10, 25, 25)));
1002 base::FilePath ref_img1 =
1003 test_data_directory().AppendASCII("ModifyHierarchy1.png");
1004 base::FilePath ref_img2 =
1005 test_data_directory().AppendASCII("ModifyHierarchy2.png");
1009 l11->Add(l21.get());
1012 ASSERT_TRUE(ReadPixels(&bitmap));
1013 ASSERT_FALSE(bitmap.empty());
1014 // WritePNGFile(bitmap, ref_img1);
1015 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1017 l0->StackAtTop(l11.get());
1019 ASSERT_TRUE(ReadPixels(&bitmap));
1020 ASSERT_FALSE(bitmap.empty());
1021 // WritePNGFile(bitmap, ref_img2);
1022 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1024 // should restore to original configuration
1025 l0->StackAbove(l12.get(), l11.get());
1027 ASSERT_TRUE(ReadPixels(&bitmap));
1028 ASSERT_FALSE(bitmap.empty());
1029 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1031 // l11 back to front
1032 l0->StackAtTop(l11.get());
1034 ASSERT_TRUE(ReadPixels(&bitmap));
1035 ASSERT_FALSE(bitmap.empty());
1036 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1038 // should restore to original configuration
1039 l0->StackAbove(l12.get(), l11.get());
1041 ASSERT_TRUE(ReadPixels(&bitmap));
1042 ASSERT_FALSE(bitmap.empty());
1043 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1045 // l11 back to front
1046 l0->StackAbove(l11.get(), l12.get());
1048 ASSERT_TRUE(ReadPixels(&bitmap));
1049 ASSERT_FALSE(bitmap.empty());
1050 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1053 // Opacity is rendered correctly.
1054 // Checks that modifying the hierarchy correctly affects final composite.
1055 TEST_F(LayerWithRealCompositorTest, Opacity) {
1056 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
1060 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
1061 gfx::Rect(0, 0, 50, 50)));
1062 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
1063 gfx::Rect(0, 0, 25, 25)));
1065 base::FilePath ref_img = test_data_directory().AppendASCII("Opacity.png");
1067 l11->SetOpacity(0.75);
1071 ASSERT_TRUE(ReadPixels(&bitmap));
1072 ASSERT_FALSE(bitmap.empty());
1073 // WritePNGFile(bitmap, ref_img);
1074 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true)));
1079 class SchedulePaintLayerDelegate : public LayerDelegate {
1081 SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {}
1083 virtual ~SchedulePaintLayerDelegate() {}
1085 void set_layer(Layer* layer) {
1087 layer_->set_delegate(this);
1090 void SetSchedulePaintRect(const gfx::Rect& rect) {
1091 schedule_paint_rect_ = rect;
1094 int GetPaintCountAndClear() {
1095 int value = paint_count_;
1100 const gfx::RectF& last_clip_rect() const { return last_clip_rect_; }
1103 // Overridden from LayerDelegate:
1104 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
1106 if (!schedule_paint_rect_.IsEmpty()) {
1107 layer_->SchedulePaint(schedule_paint_rect_);
1108 schedule_paint_rect_ = gfx::Rect();
1110 SkRect sk_clip_rect;
1111 if (canvas->sk_canvas()->getClipBounds(&sk_clip_rect))
1112 last_clip_rect_ = gfx::SkRectToRectF(sk_clip_rect);
1115 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
1118 virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
1119 return base::Closure();
1124 gfx::Rect schedule_paint_rect_;
1125 gfx::RectF last_clip_rect_;
1127 DISALLOW_COPY_AND_ASSIGN(SchedulePaintLayerDelegate);
1132 // Verifies that if SchedulePaint is invoked during painting the layer is still
1134 TEST_F(LayerWithDelegateTest, SchedulePaintFromOnPaintLayer) {
1135 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorRED,
1136 gfx::Rect(0, 0, 500, 500)));
1137 SchedulePaintLayerDelegate child_delegate;
1138 scoped_ptr<Layer> child(CreateColorLayer(SK_ColorBLUE,
1139 gfx::Rect(0, 0, 200, 200)));
1140 child_delegate.set_layer(child.get());
1142 root->Add(child.get());
1144 SchedulePaintForLayer(root.get());
1145 DrawTree(root.get());
1146 child->SchedulePaint(gfx::Rect(0, 0, 20, 20));
1147 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1149 // Set a rect so that when OnPaintLayer() is invoked SchedulePaint is invoked
1151 child_delegate.SetSchedulePaintRect(gfx::Rect(10, 10, 30, 30));
1153 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1155 // Because SchedulePaint() was invoked from OnPaintLayer() |child| should
1156 // still need to be painted.
1158 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1159 EXPECT_TRUE(child_delegate.last_clip_rect().Contains(
1160 gfx::Rect(10, 10, 30, 30)));
1163 TEST_F(LayerWithRealCompositorTest, ScaleUpDown) {
1164 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1165 gfx::Rect(10, 20, 200, 220)));
1166 TestLayerDelegate root_delegate;
1167 root_delegate.AddColor(SK_ColorWHITE);
1168 root->set_delegate(&root_delegate);
1170 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1171 gfx::Rect(10, 20, 140, 180)));
1172 TestLayerDelegate l1_delegate;
1173 l1_delegate.AddColor(SK_ColorWHITE);
1174 l1->set_delegate(&l1_delegate);
1176 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1177 GetCompositor()->SetRootLayer(root.get());
1178 root->Add(l1.get());
1181 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1182 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1183 gfx::Size size_in_pixel = root->cc_layer()->bounds();
1184 EXPECT_EQ("200x220", size_in_pixel.ToString());
1185 size_in_pixel = l1->cc_layer()->bounds();
1186 EXPECT_EQ("140x180", size_in_pixel.ToString());
1187 // No scale change, so no scale notification.
1188 EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
1189 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1191 EXPECT_EQ("200x220", root_delegate.paint_size().ToString());
1192 EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
1194 // Scale up to 2.0. Changing scale doesn't change the bounds in DIP.
1195 GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1196 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1197 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1198 // Pixel size must have been scaled up.
1199 size_in_pixel = root->cc_layer()->bounds();
1200 EXPECT_EQ("400x440", size_in_pixel.ToString());
1201 size_in_pixel = l1->cc_layer()->bounds();
1202 EXPECT_EQ("280x360", size_in_pixel.ToString());
1203 // New scale factor must have been notified.
1204 EXPECT_EQ(2.0f, root_delegate.device_scale_factor());
1205 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1207 // Canvas size must have been scaled down up.
1209 EXPECT_EQ("400x440", root_delegate.paint_size().ToString());
1210 EXPECT_EQ("2.0 2.0", root_delegate.ToScaleString());
1211 EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
1212 EXPECT_EQ("2.0 2.0", l1_delegate.ToScaleString());
1214 // Scale down back to 1.0f.
1215 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1216 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1217 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1218 // Pixel size must have been scaled down.
1219 size_in_pixel = root->cc_layer()->bounds();
1220 EXPECT_EQ("200x220", size_in_pixel.ToString());
1221 size_in_pixel = l1->cc_layer()->bounds();
1222 EXPECT_EQ("140x180", size_in_pixel.ToString());
1223 // New scale factor must have been notified.
1224 EXPECT_EQ(1.0f, root_delegate.device_scale_factor());
1225 EXPECT_EQ(1.0f, l1_delegate.device_scale_factor());
1227 // Canvas size must have been scaled down too.
1229 EXPECT_EQ("200x220", root_delegate.paint_size().ToString());
1230 EXPECT_EQ("1.0 1.0", root_delegate.ToScaleString());
1231 EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
1232 EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
1234 root_delegate.reset();
1235 l1_delegate.reset();
1236 // Just changing the size shouldn't notify the scale change nor
1238 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(1000, 1000));
1239 // No scale change, so no scale notification.
1240 EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
1241 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1243 EXPECT_EQ("0x0", root_delegate.paint_size().ToString());
1244 EXPECT_EQ("0.0 0.0", root_delegate.ToScaleString());
1245 EXPECT_EQ("0x0", l1_delegate.paint_size().ToString());
1246 EXPECT_EQ("0.0 0.0", l1_delegate.ToScaleString());
1249 TEST_F(LayerWithRealCompositorTest, ScaleReparent) {
1250 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1251 gfx::Rect(10, 20, 200, 220)));
1252 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1253 gfx::Rect(10, 20, 140, 180)));
1254 TestLayerDelegate l1_delegate;
1255 l1_delegate.AddColor(SK_ColorWHITE);
1256 l1->set_delegate(&l1_delegate);
1258 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1259 GetCompositor()->SetRootLayer(root.get());
1262 root->Add(l1.get());
1263 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1264 gfx::Size size_in_pixel = l1->cc_layer()->bounds();
1265 EXPECT_EQ("140x180", size_in_pixel.ToString());
1266 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1269 EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
1270 EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
1272 // Remove l1 from root and change the scale.
1273 root->Remove(l1.get());
1274 EXPECT_EQ(NULL, l1->parent());
1275 EXPECT_EQ(NULL, l1->GetCompositor());
1276 GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1277 // Sanity check on root and l1.
1278 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1279 size_in_pixel = l1->cc_layer()->bounds();
1280 EXPECT_EQ("140x180", size_in_pixel.ToString());
1283 root->Add(l1.get());
1284 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1285 size_in_pixel = l1->cc_layer()->bounds();
1286 EXPECT_EQ("280x360", size_in_pixel.ToString());
1287 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1289 EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
1290 EXPECT_EQ("2.0 2.0", l1_delegate.ToScaleString());
1293 // Tests layer::set_scale_content(false).
1294 TEST_F(LayerWithRealCompositorTest, NoScaleCanvas) {
1295 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1296 gfx::Rect(10, 20, 200, 220)));
1297 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1298 gfx::Rect(10, 20, 140, 180)));
1299 l1->set_scale_content(false);
1300 root->Add(l1.get());
1301 TestLayerDelegate l1_delegate;
1302 l1_delegate.AddColor(SK_ColorWHITE);
1303 l1->set_delegate(&l1_delegate);
1305 GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1306 GetCompositor()->SetRootLayer(root.get());
1307 // Scale factor change is notified regardless of scale_content flag.
1308 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1311 EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
1312 EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
1315 // Verifies that when changing bounds on a layer that is invisible, and then
1316 // made visible, the right thing happens:
1317 // - if just a move, then no painting should happen.
1318 // - if a resize, the layer should be repainted.
1319 TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) {
1320 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1322 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1323 child->SetBounds(gfx::Rect(0, 0, 500, 500));
1324 DrawTreeLayerDelegate delegate;
1325 child->set_delegate(&delegate);
1326 root->Add(child.get());
1328 // Paint once for initial damage.
1329 child->SetVisible(true);
1330 DrawTree(root.get());
1332 // Reset into invisible state.
1333 child->SetVisible(false);
1334 DrawTree(root.get());
1338 child->SetBounds(gfx::Rect(200, 200, 500, 500));
1339 child->SetVisible(true);
1340 DrawTree(root.get());
1341 EXPECT_FALSE(delegate.painted());
1343 // Reset into invisible state.
1344 child->SetVisible(false);
1345 DrawTree(root.get());
1349 child->SetBounds(gfx::Rect(200, 200, 400, 400));
1350 child->SetVisible(true);
1351 DrawTree(root.get());
1352 EXPECT_TRUE(delegate.painted());
1355 static scoped_ptr<cc::DelegatedFrameData> MakeFrameData(gfx::Size size) {
1356 scoped_ptr<cc::DelegatedFrameData> frame_data(new cc::DelegatedFrameData);
1357 scoped_ptr<cc::RenderPass> render_pass(cc::RenderPass::Create());
1358 render_pass->SetNew(cc::RenderPass::Id(1, 1),
1362 frame_data->render_pass_list.push_back(render_pass.Pass());
1363 return frame_data.Pass();
1366 TEST_F(LayerWithDelegateTest, DelegatedLayer) {
1367 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1369 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1371 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1372 child->SetVisible(true);
1373 root->Add(child.get());
1374 DrawTree(root.get());
1376 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1377 new cc::DelegatedFrameResourceCollection;
1378 scoped_refptr<cc::DelegatedFrameProvider> frame_provider;
1380 // Content matches layer size.
1381 frame_provider = new cc::DelegatedFrameProvider(
1382 resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
1383 child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
1384 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1385 gfx::Size(10, 10).ToString());
1387 // Content larger than layer.
1388 child->SetBounds(gfx::Rect(0, 0, 5, 5));
1389 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1390 gfx::Size(5, 5).ToString());
1392 // Content smaller than layer.
1393 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1394 frame_provider = new cc::DelegatedFrameProvider(
1395 resource_collection.get(), MakeFrameData(gfx::Size(5, 5)));
1396 child->SetShowDelegatedContent(frame_provider, gfx::Size(5, 5));
1397 EXPECT_EQ(child->cc_layer()->bounds().ToString(), gfx::Size(5, 5).ToString());
1399 // Hi-DPI content on low-DPI layer.
1400 frame_provider = new cc::DelegatedFrameProvider(
1401 resource_collection.get(), MakeFrameData(gfx::Size(20, 20)));
1402 child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
1403 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1404 gfx::Size(10, 10).ToString());
1406 // Hi-DPI content on hi-DPI layer.
1407 compositor()->SetScaleAndSize(2.f, gfx::Size(1000, 1000));
1408 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1409 gfx::Size(20, 20).ToString());
1411 // Low-DPI content on hi-DPI layer.
1412 frame_provider = new cc::DelegatedFrameProvider(
1413 resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
1414 child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
1415 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1416 gfx::Size(20, 20).ToString());
1419 TEST_F(LayerWithDelegateTest, ExternalContent) {
1420 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1421 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1423 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1424 child->SetVisible(true);
1425 root->Add(child.get());
1427 // The layer is already showing painted content, so the cc layer won't change.
1428 scoped_refptr<cc::Layer> before = child->cc_layer();
1429 child->SetShowPaintedContent();
1430 EXPECT_TRUE(child->cc_layer());
1431 EXPECT_EQ(before, child->cc_layer());
1433 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1434 new cc::DelegatedFrameResourceCollection;
1435 scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
1436 new cc::DelegatedFrameProvider(resource_collection.get(),
1437 MakeFrameData(gfx::Size(10, 10)));
1439 // Showing delegated content changes the underlying cc layer.
1440 before = child->cc_layer();
1441 child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
1442 EXPECT_TRUE(child->cc_layer());
1443 EXPECT_NE(before, child->cc_layer());
1445 // Changing to painted content should change the underlying cc layer.
1446 before = child->cc_layer();
1447 child->SetShowPaintedContent();
1448 EXPECT_TRUE(child->cc_layer());
1449 EXPECT_NE(before, child->cc_layer());
1452 // Tests Layer::AddThreadedAnimation and Layer::RemoveThreadedAnimation.
1453 TEST_F(LayerWithRealCompositorTest, AddRemoveThreadedAnimations) {
1454 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1455 scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
1456 scoped_ptr<Layer> l2(CreateLayer(LAYER_TEXTURED));
1458 l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1459 l2->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1461 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1463 // Trigger a threaded animation.
1464 l1->SetOpacity(0.5f);
1466 EXPECT_TRUE(l1->HasPendingThreadedAnimations());
1468 // Ensure we can remove a pending threaded animation.
1469 l1->GetAnimator()->StopAnimating();
1471 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1473 // Trigger another threaded animation.
1474 l1->SetOpacity(0.2f);
1476 EXPECT_TRUE(l1->HasPendingThreadedAnimations());
1478 root->Add(l1.get());
1479 GetCompositor()->SetRootLayer(root.get());
1481 // Now that l1 is part of a tree, it should have dispatched the pending
1483 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1485 // Ensure that l1 no longer holds on to animations.
1486 l1->SetOpacity(0.1f);
1487 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1489 // Ensure that adding a layer to an existing tree causes its pending
1490 // animations to get dispatched.
1491 l2->SetOpacity(0.5f);
1492 EXPECT_TRUE(l2->HasPendingThreadedAnimations());
1495 EXPECT_FALSE(l2->HasPendingThreadedAnimations());
1498 // Tests that in-progress threaded animations complete when a Layer's
1499 // cc::Layer changes.
1500 TEST_F(LayerWithRealCompositorTest, SwitchCCLayerAnimations) {
1501 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1502 scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
1503 GetCompositor()->SetRootLayer(root.get());
1504 root->Add(l1.get());
1506 l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1508 EXPECT_FLOAT_EQ(l1->opacity(), 1.0f);
1510 // Trigger a threaded animation.
1511 l1->SetOpacity(0.5f);
1513 // Change l1's cc::Layer.
1514 l1->SwitchCCLayerForTest();
1516 // Ensure that the opacity animation completed.
1517 EXPECT_FLOAT_EQ(l1->opacity(), 0.5f);