layer_unittest.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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.
4
5#include "base/basictypes.h"
6#include "base/bind.h"
7#include "base/compiler_specific.h"
8#include "base/file_util.h"
9#include "base/files/file_path.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/message_loop/message_loop.h"
12#include "base/path_service.h"
13#include "base/strings/string_util.h"
14#include "base/strings/stringprintf.h"
15#include "cc/layers/delegated_frame_provider.h"
16#include "cc/layers/delegated_frame_resource_collection.h"
17#include "cc/layers/layer.h"
18#include "cc/output/delegated_frame_data.h"
19#include "cc/test/pixel_test_utils.h"
20#include "testing/gtest/include/gtest/gtest.h"
21#include "ui/compositor/compositor_observer.h"
22#include "ui/compositor/layer.h"
23#include "ui/compositor/layer_animation_sequence.h"
24#include "ui/compositor/layer_animator.h"
25#include "ui/compositor/test/test_compositor_host.h"
26#include "ui/compositor/test/test_layers.h"
27#include "ui/gfx/canvas.h"
28#include "ui/gfx/codec/png_codec.h"
29#include "ui/gfx/gfx_paths.h"
30#include "ui/gfx/skia_util.h"
31
32using cc::MatchesPNGFile;
33
34namespace ui {
35
36namespace {
37
38// There are three test classes in here that configure the Compositor and
39// Layer's slightly differently:
40// - LayerWithNullDelegateTest uses NullLayerDelegate as the LayerDelegate. This
41//   is typically the base class you want to use.
42// - LayerWithDelegateTest uses LayerDelegate on the delegates.
43// - LayerWithRealCompositorTest when a real compositor is required for testing.
44//    - Slow because they bring up a window and run the real compositor. This
45//      is typically not what you want.
46
47class ColoredLayer : public Layer, public LayerDelegate {
48 public:
49  explicit ColoredLayer(SkColor color)
50      : Layer(LAYER_TEXTURED),
51        color_(color) {
52    set_delegate(this);
53  }
54
55  virtual ~ColoredLayer() { }
56
57  // Overridden from LayerDelegate:
58  virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
59    canvas->DrawColor(color_);
60  }
61
62  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
63  }
64
65  virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
66    return base::Closure();
67  }
68
69 private:
70  SkColor color_;
71};
72
73class LayerWithRealCompositorTest : public testing::Test {
74 public:
75  LayerWithRealCompositorTest() {
76    if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) {
77      test_data_directory_ = test_data_directory_.AppendASCII("compositor");
78    } else {
79      LOG(ERROR) << "Could not open test data directory.";
80    }
81  }
82  virtual ~LayerWithRealCompositorTest() {}
83
84  // Overridden from testing::Test:
85  virtual void SetUp() OVERRIDE {
86    bool allow_test_contexts = false;
87    Compositor::InitializeContextFactoryForTests(allow_test_contexts);
88    Compositor::Initialize();
89
90    const gfx::Rect host_bounds(10, 10, 500, 500);
91    window_.reset(TestCompositorHost::Create(host_bounds));
92    window_->Show();
93  }
94
95  virtual void TearDown() OVERRIDE {
96    window_.reset();
97    Compositor::Terminate();
98  }
99
100  Compositor* GetCompositor() {
101    return window_->GetCompositor();
102  }
103
104  Layer* CreateLayer(LayerType type) {
105    return new Layer(type);
106  }
107
108  Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
109    Layer* layer = new ColoredLayer(color);
110    layer->SetBounds(bounds);
111    return layer;
112  }
113
114  Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
115    Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
116    layer->SetBounds(bounds);
117    return layer;
118  }
119
120  void DrawTree(Layer* root) {
121    GetCompositor()->SetRootLayer(root);
122    GetCompositor()->ScheduleDraw();
123    WaitForDraw();
124  }
125
126  bool ReadPixels(SkBitmap* bitmap) {
127    return GetCompositor()->ReadPixels(bitmap,
128                                       gfx::Rect(GetCompositor()->size()));
129  }
130
131  void WaitForDraw() {
132    ui::DrawWaiterForTest::Wait(GetCompositor());
133  }
134
135  void WaitForCommit() {
136    ui::DrawWaiterForTest::WaitForCommit(GetCompositor());
137  }
138
139  // Invalidates the entire contents of the layer.
140  void SchedulePaintForLayer(Layer* layer) {
141    layer->SchedulePaint(
142        gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
143  }
144
145  const base::FilePath& test_data_directory() const {
146    return test_data_directory_;
147  }
148
149 private:
150  scoped_ptr<TestCompositorHost> window_;
151
152  // The root directory for test files.
153  base::FilePath test_data_directory_;
154
155  DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest);
156};
157
158// LayerDelegate that paints colors to the layer.
159class TestLayerDelegate : public LayerDelegate {
160 public:
161  explicit TestLayerDelegate() { reset(); }
162  virtual ~TestLayerDelegate() {}
163
164  void AddColor(SkColor color) {
165    colors_.push_back(color);
166  }
167
168  const gfx::Size& paint_size() const { return paint_size_; }
169  int color_index() const { return color_index_; }
170
171  std::string ToScaleString() const {
172    return base::StringPrintf("%.1f %.1f", scale_x_, scale_y_);
173  }
174
175  float device_scale_factor() const {
176    return device_scale_factor_;
177  }
178
179  // Overridden from LayerDelegate:
180  virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
181    SkIRect clip_bounds;
182    canvas->sk_canvas()->getClipDeviceBounds(&clip_bounds);
183    paint_size_ = gfx::Size(clip_bounds.width(), clip_bounds.height());
184    canvas->FillRect(gfx::Rect(paint_size_), colors_[color_index_]);
185    color_index_ = (color_index_ + 1) % static_cast<int>(colors_.size());
186    const SkMatrix& matrix = canvas->sk_canvas()->getTotalMatrix();
187    scale_x_ = matrix.getScaleX();
188    scale_y_ = matrix.getScaleY();
189  }
190
191  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
192    device_scale_factor_ = device_scale_factor;
193  }
194
195  virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
196    return base::Closure();
197  }
198
199  void reset() {
200    color_index_ = 0;
201    paint_size_.SetSize(0, 0);
202    scale_x_ = scale_y_ = 0.0f;
203    device_scale_factor_ = 0.0f;
204  }
205
206 private:
207  std::vector<SkColor> colors_;
208  int color_index_;
209  gfx::Size paint_size_;
210  float scale_x_;
211  float scale_y_;
212  float device_scale_factor_;
213
214  DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate);
215};
216
217// LayerDelegate that verifies that a layer was asked to update its canvas.
218class DrawTreeLayerDelegate : public LayerDelegate {
219 public:
220  DrawTreeLayerDelegate() : painted_(false) {}
221  virtual ~DrawTreeLayerDelegate() {}
222
223  void Reset() {
224    painted_ = false;
225  }
226
227  bool painted() const { return painted_; }
228
229 private:
230  // Overridden from LayerDelegate:
231  virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
232    painted_ = true;
233  }
234  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
235  }
236  virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
237    return base::Closure();
238  }
239
240  bool painted_;
241
242  DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate);
243};
244
245// The simplest possible layer delegate. Does nothing.
246class NullLayerDelegate : public LayerDelegate {
247 public:
248  NullLayerDelegate() {}
249  virtual ~NullLayerDelegate() {}
250
251 private:
252  // Overridden from LayerDelegate:
253  virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
254  }
255  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
256  }
257  virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
258    return base::Closure();
259  }
260
261  DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate);
262};
263
264// Remembers if it has been notified.
265class TestCompositorObserver : public CompositorObserver {
266 public:
267  TestCompositorObserver()
268      : committed_(false), started_(false), ended_(false), aborted_(false) {}
269
270  bool committed() const { return committed_; }
271  bool notified() const { return started_ && ended_; }
272  bool aborted() const { return aborted_; }
273
274  void Reset() {
275    committed_ = false;
276    started_ = false;
277    ended_ = false;
278    aborted_ = false;
279  }
280
281 private:
282  virtual void OnCompositingDidCommit(Compositor* compositor) OVERRIDE {
283    committed_ = true;
284  }
285
286  virtual void OnCompositingStarted(Compositor* compositor,
287                                    base::TimeTicks start_time) OVERRIDE {
288    started_ = true;
289  }
290
291  virtual void OnCompositingEnded(Compositor* compositor) OVERRIDE {
292    ended_ = true;
293  }
294
295  virtual void OnCompositingAborted(Compositor* compositor) OVERRIDE {
296    aborted_ = true;
297  }
298
299  virtual void OnCompositingLockStateChanged(Compositor* compositor) OVERRIDE {
300  }
301
302  virtual void OnUpdateVSyncParameters(Compositor* compositor,
303                                       base::TimeTicks timebase,
304                                       base::TimeDelta interval) OVERRIDE {
305  }
306
307  bool committed_;
308  bool started_;
309  bool ended_;
310  bool aborted_;
311
312  DISALLOW_COPY_AND_ASSIGN(TestCompositorObserver);
313};
314
315}  // namespace
316
317TEST_F(LayerWithRealCompositorTest, Draw) {
318  scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED,
319                                           gfx::Rect(20, 20, 50, 50)));
320  DrawTree(layer.get());
321}
322
323// Create this hierarchy:
324// L1 - red
325// +-- L2 - blue
326// |   +-- L3 - yellow
327// +-- L4 - magenta
328//
329TEST_F(LayerWithRealCompositorTest, Hierarchy) {
330  scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
331                                        gfx::Rect(20, 20, 400, 400)));
332  scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
333                                        gfx::Rect(10, 10, 350, 350)));
334  scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
335                                        gfx::Rect(5, 5, 25, 25)));
336  scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
337                                        gfx::Rect(300, 300, 100, 100)));
338
339  l1->Add(l2.get());
340  l1->Add(l4.get());
341  l2->Add(l3.get());
342
343  DrawTree(l1.get());
344}
345
346class LayerWithDelegateTest : public testing::Test, public CompositorDelegate {
347 public:
348  LayerWithDelegateTest() {}
349  virtual ~LayerWithDelegateTest() {}
350
351  // Overridden from testing::Test:
352  virtual void SetUp() OVERRIDE {
353    bool allow_test_contexts = true;
354    Compositor::InitializeContextFactoryForTests(allow_test_contexts);
355    Compositor::Initialize();
356    compositor_.reset(new Compositor(this, gfx::kNullAcceleratedWidget));
357    compositor_->SetScaleAndSize(1.0f, gfx::Size(1000, 1000));
358  }
359
360  virtual void TearDown() OVERRIDE {
361    compositor_.reset();
362    Compositor::Terminate();
363  }
364
365  Compositor* compositor() { return compositor_.get(); }
366
367  virtual Layer* CreateLayer(LayerType type) {
368    return new Layer(type);
369  }
370
371  Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
372    Layer* layer = new ColoredLayer(color);
373    layer->SetBounds(bounds);
374    return layer;
375  }
376
377  virtual Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
378    Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
379    layer->SetBounds(bounds);
380    return layer;
381  }
382
383  void DrawTree(Layer* root) {
384    compositor()->SetRootLayer(root);
385    Draw();
386  }
387
388  // Invalidates the entire contents of the layer.
389  void SchedulePaintForLayer(Layer* layer) {
390    layer->SchedulePaint(
391        gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
392  }
393
394  // Invokes DrawTree on the compositor.
395  void Draw() {
396    compositor()->ScheduleDraw();
397    WaitForDraw();
398  }
399
400  void WaitForDraw() {
401    DrawWaiterForTest::Wait(compositor());
402  }
403
404  void WaitForCommit() {
405    DrawWaiterForTest::WaitForCommit(compositor());
406  }
407
408  // CompositorDelegate overrides.
409  virtual void ScheduleDraw() OVERRIDE {
410    DCHECK(!ui::Compositor::WasInitializedWithThread());
411    if (compositor_) {
412      base::MessageLoop::current()->PostTask(
413          FROM_HERE, base::Bind(&Compositor::Draw, compositor_->AsWeakPtr()));
414    }
415  }
416
417 private:
418  scoped_ptr<Compositor> compositor_;
419
420  DISALLOW_COPY_AND_ASSIGN(LayerWithDelegateTest);
421};
422
423// L1
424//  +-- L2
425TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Simple) {
426  scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
427                                        gfx::Rect(20, 20, 400, 400)));
428  scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
429                                        gfx::Rect(10, 10, 350, 350)));
430  l1->Add(l2.get());
431  DrawTree(l1.get());
432
433  gfx::Point point1_in_l2_coords(5, 5);
434  Layer::ConvertPointToLayer(l2.get(), l1.get(), &point1_in_l2_coords);
435  gfx::Point point1_in_l1_coords(15, 15);
436  EXPECT_EQ(point1_in_l1_coords, point1_in_l2_coords);
437
438  gfx::Point point2_in_l1_coords(5, 5);
439  Layer::ConvertPointToLayer(l1.get(), l2.get(), &point2_in_l1_coords);
440  gfx::Point point2_in_l2_coords(-5, -5);
441  EXPECT_EQ(point2_in_l2_coords, point2_in_l1_coords);
442}
443
444// L1
445//  +-- L2
446//       +-- L3
447TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Medium) {
448  scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
449                                        gfx::Rect(20, 20, 400, 400)));
450  scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
451                                        gfx::Rect(10, 10, 350, 350)));
452  scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
453                                        gfx::Rect(10, 10, 100, 100)));
454  l1->Add(l2.get());
455  l2->Add(l3.get());
456  DrawTree(l1.get());
457
458  gfx::Point point1_in_l3_coords(5, 5);
459  Layer::ConvertPointToLayer(l3.get(), l1.get(), &point1_in_l3_coords);
460  gfx::Point point1_in_l1_coords(25, 25);
461  EXPECT_EQ(point1_in_l1_coords, point1_in_l3_coords);
462
463  gfx::Point point2_in_l1_coords(5, 5);
464  Layer::ConvertPointToLayer(l1.get(), l3.get(), &point2_in_l1_coords);
465  gfx::Point point2_in_l3_coords(-15, -15);
466  EXPECT_EQ(point2_in_l3_coords, point2_in_l1_coords);
467}
468
469TEST_F(LayerWithRealCompositorTest, Delegate) {
470  scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorBLACK,
471                                        gfx::Rect(20, 20, 400, 400)));
472  GetCompositor()->SetRootLayer(l1.get());
473  WaitForDraw();
474
475  TestLayerDelegate delegate;
476  l1->set_delegate(&delegate);
477  delegate.AddColor(SK_ColorWHITE);
478  delegate.AddColor(SK_ColorYELLOW);
479  delegate.AddColor(SK_ColorGREEN);
480
481  l1->SchedulePaint(gfx::Rect(0, 0, 400, 400));
482  WaitForDraw();
483
484  EXPECT_EQ(delegate.color_index(), 1);
485  EXPECT_EQ(delegate.paint_size(), l1->bounds().size());
486
487  l1->SchedulePaint(gfx::Rect(10, 10, 200, 200));
488  WaitForDraw();
489  EXPECT_EQ(delegate.color_index(), 2);
490  EXPECT_EQ(delegate.paint_size(), gfx::Size(200, 200));
491
492  l1->SchedulePaint(gfx::Rect(5, 5, 50, 50));
493  WaitForDraw();
494  EXPECT_EQ(delegate.color_index(), 0);
495  EXPECT_EQ(delegate.paint_size(), gfx::Size(50, 50));
496}
497
498TEST_F(LayerWithRealCompositorTest, DrawTree) {
499  scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
500                                        gfx::Rect(20, 20, 400, 400)));
501  scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
502                                        gfx::Rect(10, 10, 350, 350)));
503  scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
504                                        gfx::Rect(10, 10, 100, 100)));
505  l1->Add(l2.get());
506  l2->Add(l3.get());
507
508  GetCompositor()->SetRootLayer(l1.get());
509  WaitForDraw();
510
511  DrawTreeLayerDelegate d1;
512  l1->set_delegate(&d1);
513  DrawTreeLayerDelegate d2;
514  l2->set_delegate(&d2);
515  DrawTreeLayerDelegate d3;
516  l3->set_delegate(&d3);
517
518  l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
519  WaitForDraw();
520  EXPECT_FALSE(d1.painted());
521  EXPECT_TRUE(d2.painted());
522  EXPECT_FALSE(d3.painted());
523}
524
525// Tests no-texture Layers.
526// Create this hierarchy:
527// L1 - red
528// +-- L2 - NO TEXTURE
529// |   +-- L3 - yellow
530// +-- L4 - magenta
531//
532TEST_F(LayerWithRealCompositorTest, HierarchyNoTexture) {
533  scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
534                                        gfx::Rect(20, 20, 400, 400)));
535  scoped_ptr<Layer> l2(CreateNoTextureLayer(gfx::Rect(10, 10, 350, 350)));
536  scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
537                                        gfx::Rect(5, 5, 25, 25)));
538  scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
539                                        gfx::Rect(300, 300, 100, 100)));
540
541  l1->Add(l2.get());
542  l1->Add(l4.get());
543  l2->Add(l3.get());
544
545  GetCompositor()->SetRootLayer(l1.get());
546  WaitForDraw();
547
548  DrawTreeLayerDelegate d2;
549  l2->set_delegate(&d2);
550  DrawTreeLayerDelegate d3;
551  l3->set_delegate(&d3);
552
553  l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
554  l3->SchedulePaint(gfx::Rect(5, 5, 5, 5));
555  WaitForDraw();
556
557  // |d2| should not have received a paint notification since it has no texture.
558  EXPECT_FALSE(d2.painted());
559  // |d3| should have received a paint notification.
560  EXPECT_TRUE(d3.painted());
561}
562
563class LayerWithNullDelegateTest : public LayerWithDelegateTest {
564 public:
565  LayerWithNullDelegateTest() {}
566  virtual ~LayerWithNullDelegateTest() {}
567
568  virtual void SetUp() OVERRIDE {
569    LayerWithDelegateTest::SetUp();
570    default_layer_delegate_.reset(new NullLayerDelegate());
571  }
572
573  virtual Layer* CreateLayer(LayerType type) OVERRIDE {
574    Layer* layer = new Layer(type);
575    layer->set_delegate(default_layer_delegate_.get());
576    return layer;
577  }
578
579  Layer* CreateTextureRootLayer(const gfx::Rect& bounds) {
580    Layer* layer = CreateTextureLayer(bounds);
581    compositor()->SetRootLayer(layer);
582    return layer;
583  }
584
585  Layer* CreateTextureLayer(const gfx::Rect& bounds) {
586    Layer* layer = CreateLayer(LAYER_TEXTURED);
587    layer->SetBounds(bounds);
588    return layer;
589  }
590
591  virtual Layer* CreateNoTextureLayer(const gfx::Rect& bounds) OVERRIDE {
592    Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
593    layer->SetBounds(bounds);
594    return layer;
595  }
596
597 private:
598  scoped_ptr<NullLayerDelegate> default_layer_delegate_;
599
600  DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest);
601};
602
603class FakeTexture : public Texture {
604 public:
605  FakeTexture(bool flipped, const gfx::Size& size, float device_scale_factor)
606      : Texture(flipped, size, device_scale_factor) {}
607
608  virtual unsigned int PrepareTexture() OVERRIDE { return 0; }
609  virtual WebKit::WebGraphicsContext3D* HostContext3D() OVERRIDE {
610    return NULL;
611  }
612
613 protected:
614  virtual ~FakeTexture() {}
615};
616
617TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) {
618  scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
619                                        gfx::Rect(20, 20, 400, 400)));
620  l1->SetFillsBoundsOpaquely(true);
621  l1->SetForceRenderSurface(true);
622  l1->SetVisible(false);
623
624  EXPECT_EQ(gfx::PointF().ToString(),
625            l1->cc_layer()->anchor_point().ToString());
626  EXPECT_TRUE(l1->cc_layer()->DrawsContent());
627  EXPECT_TRUE(l1->cc_layer()->contents_opaque());
628  EXPECT_TRUE(l1->cc_layer()->force_render_surface());
629  EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
630
631  cc::Layer* before_layer = l1->cc_layer();
632
633  scoped_refptr<Texture> texture =
634      new FakeTexture(false, gfx::Size(10, 10), 1.f);
635  l1->SetExternalTexture(texture.get());
636
637  EXPECT_NE(before_layer, l1->cc_layer());
638
639  EXPECT_EQ(gfx::PointF().ToString(),
640            l1->cc_layer()->anchor_point().ToString());
641  EXPECT_TRUE(l1->cc_layer()->DrawsContent());
642  EXPECT_TRUE(l1->cc_layer()->contents_opaque());
643  EXPECT_TRUE(l1->cc_layer()->force_render_surface());
644  EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
645}
646
647// Various visibile/drawn assertions.
648TEST_F(LayerWithNullDelegateTest, Visibility) {
649  scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
650  scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
651  scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
652  l1->Add(l2.get());
653  l2->Add(l3.get());
654
655  NullLayerDelegate delegate;
656  l1->set_delegate(&delegate);
657  l2->set_delegate(&delegate);
658  l3->set_delegate(&delegate);
659
660  // Layers should initially be drawn.
661  EXPECT_TRUE(l1->IsDrawn());
662  EXPECT_TRUE(l2->IsDrawn());
663  EXPECT_TRUE(l3->IsDrawn());
664  EXPECT_FALSE(l1->cc_layer()->hide_layer_and_subtree());
665  EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
666  EXPECT_FALSE(l3->cc_layer()->hide_layer_and_subtree());
667
668  compositor()->SetRootLayer(l1.get());
669
670  Draw();
671
672  l1->SetVisible(false);
673  EXPECT_FALSE(l1->IsDrawn());
674  EXPECT_FALSE(l2->IsDrawn());
675  EXPECT_FALSE(l3->IsDrawn());
676  EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
677  EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
678  EXPECT_FALSE(l3->cc_layer()->hide_layer_and_subtree());
679
680  l3->SetVisible(false);
681  EXPECT_FALSE(l1->IsDrawn());
682  EXPECT_FALSE(l2->IsDrawn());
683  EXPECT_FALSE(l3->IsDrawn());
684  EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
685  EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
686  EXPECT_TRUE(l3->cc_layer()->hide_layer_and_subtree());
687
688  l1->SetVisible(true);
689  EXPECT_TRUE(l1->IsDrawn());
690  EXPECT_TRUE(l2->IsDrawn());
691  EXPECT_FALSE(l3->IsDrawn());
692  EXPECT_FALSE(l1->cc_layer()->hide_layer_and_subtree());
693  EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
694  EXPECT_TRUE(l3->cc_layer()->hide_layer_and_subtree());
695}
696
697// Checks that stacking-related methods behave as advertised.
698TEST_F(LayerWithNullDelegateTest, Stacking) {
699  scoped_ptr<Layer> root(new Layer(LAYER_NOT_DRAWN));
700  scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
701  scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
702  scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
703  l1->set_name("1");
704  l2->set_name("2");
705  l3->set_name("3");
706  root->Add(l3.get());
707  root->Add(l2.get());
708  root->Add(l1.get());
709
710  // Layers' children are stored in bottom-to-top order.
711  EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
712
713  root->StackAtTop(l3.get());
714  EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
715
716  root->StackAtTop(l1.get());
717  EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
718
719  root->StackAtTop(l1.get());
720  EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
721
722  root->StackAbove(l2.get(), l3.get());
723  EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
724
725  root->StackAbove(l1.get(), l3.get());
726  EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
727
728  root->StackAbove(l2.get(), l1.get());
729  EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
730
731  root->StackAtBottom(l2.get());
732  EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
733
734  root->StackAtBottom(l3.get());
735  EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
736
737  root->StackAtBottom(l3.get());
738  EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
739
740  root->StackBelow(l2.get(), l3.get());
741  EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
742
743  root->StackBelow(l1.get(), l3.get());
744  EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
745
746  root->StackBelow(l3.get(), l2.get());
747  EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
748
749  root->StackBelow(l3.get(), l2.get());
750  EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
751
752  root->StackBelow(l3.get(), l1.get());
753  EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
754}
755
756// Verifies SetBounds triggers the appropriate painting/drawing.
757TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) {
758  scoped_ptr<Layer> l1(CreateTextureLayer(gfx::Rect(0, 0, 200, 200)));
759  compositor()->SetRootLayer(l1.get());
760
761  Draw();
762
763  l1->SetBounds(gfx::Rect(5, 5, 200, 200));
764
765  // The CompositorDelegate (us) should have been told to draw for a move.
766  WaitForDraw();
767
768  l1->SetBounds(gfx::Rect(5, 5, 100, 100));
769
770  // The CompositorDelegate (us) should have been told to draw for a resize.
771  WaitForDraw();
772}
773
774// Checks that pixels are actually drawn to the screen with a read back.
775TEST_F(LayerWithRealCompositorTest, DrawPixels) {
776  gfx::Size viewport_size = GetCompositor()->size();
777
778  // The window should be some non-trivial size but may not be exactly
779  // 500x500 on all platforms/bots.
780  EXPECT_GE(viewport_size.width(), 200);
781  EXPECT_GE(viewport_size.height(), 200);
782
783  int blue_height = 10;
784
785  scoped_ptr<Layer> layer(
786      CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
787  scoped_ptr<Layer> layer2(
788      CreateColorLayer(SK_ColorBLUE,
789                       gfx::Rect(0, 0, viewport_size.width(), blue_height)));
790
791  layer->Add(layer2.get());
792
793  DrawTree(layer.get());
794
795  SkBitmap bitmap;
796  ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap, gfx::Rect(viewport_size)));
797  ASSERT_FALSE(bitmap.empty());
798
799  SkAutoLockPixels lock(bitmap);
800  for (int x = 0; x < viewport_size.width(); x++) {
801    for (int y = 0; y < viewport_size.height(); y++) {
802      SkColor actual_color = bitmap.getColor(x, y);
803      SkColor expected_color = y < blue_height ? SK_ColorBLUE : SK_ColorRED;
804      EXPECT_EQ(expected_color, actual_color)
805          << "Pixel error at x=" << x << " y=" << y << "; "
806          << "actual RGBA=("
807          << SkColorGetR(actual_color) << ","
808          << SkColorGetG(actual_color) << ","
809          << SkColorGetB(actual_color) << ","
810          << SkColorGetA(actual_color) << "); "
811          << "expected RGBA=("
812          << SkColorGetR(expected_color) << ","
813          << SkColorGetG(expected_color) << ","
814          << SkColorGetB(expected_color) << ","
815          << SkColorGetA(expected_color) << ")";
816    }
817  }
818}
819
820// Checks the logic around Compositor::SetRootLayer and Layer::SetCompositor.
821TEST_F(LayerWithRealCompositorTest, SetRootLayer) {
822  Compositor* compositor = GetCompositor();
823  scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
824                                        gfx::Rect(20, 20, 400, 400)));
825  scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
826                                        gfx::Rect(10, 10, 350, 350)));
827
828  EXPECT_EQ(NULL, l1->GetCompositor());
829  EXPECT_EQ(NULL, l2->GetCompositor());
830
831  compositor->SetRootLayer(l1.get());
832  EXPECT_EQ(compositor, l1->GetCompositor());
833
834  l1->Add(l2.get());
835  EXPECT_EQ(compositor, l2->GetCompositor());
836
837  l1->Remove(l2.get());
838  EXPECT_EQ(NULL, l2->GetCompositor());
839
840  l1->Add(l2.get());
841  EXPECT_EQ(compositor, l2->GetCompositor());
842
843  compositor->SetRootLayer(NULL);
844  EXPECT_EQ(NULL, l1->GetCompositor());
845  EXPECT_EQ(NULL, l2->GetCompositor());
846}
847
848// Checks that compositor observers are notified when:
849// - DrawTree is called,
850// - After ScheduleDraw is called, or
851// - Whenever SetBounds, SetOpacity or SetTransform are called.
852// TODO(vollick): could be reorganized into compositor_unittest.cc
853TEST_F(LayerWithRealCompositorTest, CompositorObservers) {
854  scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
855                                        gfx::Rect(20, 20, 400, 400)));
856  scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
857                                        gfx::Rect(10, 10, 350, 350)));
858  l1->Add(l2.get());
859  TestCompositorObserver observer;
860  GetCompositor()->AddObserver(&observer);
861
862  // Explicitly called DrawTree should cause the observers to be notified.
863  // NOTE: this call to DrawTree sets l1 to be the compositor's root layer.
864  DrawTree(l1.get());
865  EXPECT_TRUE(observer.notified());
866
867  // ScheduleDraw without any visible change should cause a commit.
868  observer.Reset();
869  l1->ScheduleDraw();
870  WaitForCommit();
871  EXPECT_TRUE(observer.committed());
872
873  // Moving, but not resizing, a layer should alert the observers.
874  observer.Reset();
875  l2->SetBounds(gfx::Rect(0, 0, 350, 350));
876  WaitForDraw();
877  EXPECT_TRUE(observer.notified());
878
879  // So should resizing a layer.
880  observer.Reset();
881  l2->SetBounds(gfx::Rect(0, 0, 400, 400));
882  WaitForDraw();
883  EXPECT_TRUE(observer.notified());
884
885  // Opacity changes should alert the observers.
886  observer.Reset();
887  l2->SetOpacity(0.5f);
888  WaitForDraw();
889  EXPECT_TRUE(observer.notified());
890
891  // So should setting the opacity back.
892  observer.Reset();
893  l2->SetOpacity(1.0f);
894  WaitForDraw();
895  EXPECT_TRUE(observer.notified());
896
897  // Setting the transform of a layer should alert the observers.
898  observer.Reset();
899  gfx::Transform transform;
900  transform.Translate(200.0, 200.0);
901  transform.Rotate(90.0);
902  transform.Translate(-200.0, -200.0);
903  l2->SetTransform(transform);
904  WaitForDraw();
905  EXPECT_TRUE(observer.notified());
906
907  // A change resulting in an aborted swap buffer should alert the observer
908  // and also signal an abort.
909  observer.Reset();
910  l2->SetOpacity(0.1f);
911  GetCompositor()->OnSwapBuffersAborted();
912  WaitForDraw();
913  EXPECT_TRUE(observer.notified());
914  EXPECT_TRUE(observer.aborted());
915
916  GetCompositor()->RemoveObserver(&observer);
917
918  // Opacity changes should no longer alert the removed observer.
919  observer.Reset();
920  l2->SetOpacity(0.5f);
921  WaitForDraw();
922
923  EXPECT_FALSE(observer.notified());
924}
925
926// Checks that modifying the hierarchy correctly affects final composite.
927TEST_F(LayerWithRealCompositorTest, ModifyHierarchy) {
928  GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
929
930  // l0
931  //  +-l11
932  //  | +-l21
933  //  +-l12
934  scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
935                                        gfx::Rect(0, 0, 50, 50)));
936  scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
937                                         gfx::Rect(0, 0, 25, 25)));
938  scoped_ptr<Layer> l21(CreateColorLayer(SK_ColorMAGENTA,
939                                         gfx::Rect(0, 0, 15, 15)));
940  scoped_ptr<Layer> l12(CreateColorLayer(SK_ColorBLUE,
941                                         gfx::Rect(10, 10, 25, 25)));
942
943  base::FilePath ref_img1 =
944      test_data_directory().AppendASCII("ModifyHierarchy1.png");
945  base::FilePath ref_img2 =
946      test_data_directory().AppendASCII("ModifyHierarchy2.png");
947  SkBitmap bitmap;
948
949  l0->Add(l11.get());
950  l11->Add(l21.get());
951  l0->Add(l12.get());
952  DrawTree(l0.get());
953  ASSERT_TRUE(ReadPixels(&bitmap));
954  ASSERT_FALSE(bitmap.empty());
955  // WritePNGFile(bitmap, ref_img1);
956  EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
957
958  l0->StackAtTop(l11.get());
959  DrawTree(l0.get());
960  ASSERT_TRUE(ReadPixels(&bitmap));
961  ASSERT_FALSE(bitmap.empty());
962  // WritePNGFile(bitmap, ref_img2);
963  EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
964
965  // should restore to original configuration
966  l0->StackAbove(l12.get(), l11.get());
967  DrawTree(l0.get());
968  ASSERT_TRUE(ReadPixels(&bitmap));
969  ASSERT_FALSE(bitmap.empty());
970  EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
971
972  // l11 back to front
973  l0->StackAtTop(l11.get());
974  DrawTree(l0.get());
975  ASSERT_TRUE(ReadPixels(&bitmap));
976  ASSERT_FALSE(bitmap.empty());
977  EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
978
979  // should restore to original configuration
980  l0->StackAbove(l12.get(), l11.get());
981  DrawTree(l0.get());
982  ASSERT_TRUE(ReadPixels(&bitmap));
983  ASSERT_FALSE(bitmap.empty());
984  EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
985
986  // l11 back to front
987  l0->StackAbove(l11.get(), l12.get());
988  DrawTree(l0.get());
989  ASSERT_TRUE(ReadPixels(&bitmap));
990  ASSERT_FALSE(bitmap.empty());
991  EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
992}
993
994// Opacity is rendered correctly.
995// Checks that modifying the hierarchy correctly affects final composite.
996TEST_F(LayerWithRealCompositorTest, Opacity) {
997  GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
998
999  // l0
1000  //  +-l11
1001  scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
1002                                        gfx::Rect(0, 0, 50, 50)));
1003  scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
1004                                         gfx::Rect(0, 0, 25, 25)));
1005
1006  base::FilePath ref_img = test_data_directory().AppendASCII("Opacity.png");
1007
1008  l11->SetOpacity(0.75);
1009  l0->Add(l11.get());
1010  DrawTree(l0.get());
1011  SkBitmap bitmap;
1012  ASSERT_TRUE(ReadPixels(&bitmap));
1013  ASSERT_FALSE(bitmap.empty());
1014  // WritePNGFile(bitmap, ref_img);
1015  EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true)));
1016}
1017
1018namespace {
1019
1020class SchedulePaintLayerDelegate : public LayerDelegate {
1021 public:
1022  SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {}
1023
1024  virtual ~SchedulePaintLayerDelegate() {}
1025
1026  void set_layer(Layer* layer) {
1027    layer_ = layer;
1028    layer_->set_delegate(this);
1029  }
1030
1031  void SetSchedulePaintRect(const gfx::Rect& rect) {
1032    schedule_paint_rect_ = rect;
1033  }
1034
1035  int GetPaintCountAndClear() {
1036    int value = paint_count_;
1037    paint_count_ = 0;
1038    return value;
1039  }
1040
1041  const gfx::RectF& last_clip_rect() const { return last_clip_rect_; }
1042
1043 private:
1044  // Overridden from LayerDelegate:
1045  virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
1046    paint_count_++;
1047    if (!schedule_paint_rect_.IsEmpty()) {
1048      layer_->SchedulePaint(schedule_paint_rect_);
1049      schedule_paint_rect_ = gfx::Rect();
1050    }
1051    SkRect sk_clip_rect;
1052    if (canvas->sk_canvas()->getClipBounds(&sk_clip_rect))
1053      last_clip_rect_ = gfx::SkRectToRectF(sk_clip_rect);
1054  }
1055
1056  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
1057  }
1058
1059  virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
1060    return base::Closure();
1061  }
1062
1063  int paint_count_;
1064  Layer* layer_;
1065  gfx::Rect schedule_paint_rect_;
1066  gfx::RectF last_clip_rect_;
1067
1068  DISALLOW_COPY_AND_ASSIGN(SchedulePaintLayerDelegate);
1069};
1070
1071}  // namespace
1072
1073// Verifies that if SchedulePaint is invoked during painting the layer is still
1074// marked dirty.
1075TEST_F(LayerWithDelegateTest, SchedulePaintFromOnPaintLayer) {
1076  scoped_ptr<Layer> root(CreateColorLayer(SK_ColorRED,
1077                                          gfx::Rect(0, 0, 500, 500)));
1078  SchedulePaintLayerDelegate child_delegate;
1079  scoped_ptr<Layer> child(CreateColorLayer(SK_ColorBLUE,
1080                                           gfx::Rect(0, 0, 200, 200)));
1081  child_delegate.set_layer(child.get());
1082
1083  root->Add(child.get());
1084
1085  SchedulePaintForLayer(root.get());
1086  DrawTree(root.get());
1087  child->SchedulePaint(gfx::Rect(0, 0, 20, 20));
1088  EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1089
1090  // Set a rect so that when OnPaintLayer() is invoked SchedulePaint is invoked
1091  // again.
1092  child_delegate.SetSchedulePaintRect(gfx::Rect(10, 10, 30, 30));
1093  WaitForCommit();
1094  EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1095
1096  // Because SchedulePaint() was invoked from OnPaintLayer() |child| should
1097  // still need to be painted.
1098  WaitForCommit();
1099  EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1100  EXPECT_TRUE(child_delegate.last_clip_rect().Contains(
1101                  gfx::Rect(10, 10, 30, 30)));
1102}
1103
1104TEST_F(LayerWithRealCompositorTest, ScaleUpDown) {
1105  scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1106                                          gfx::Rect(10, 20, 200, 220)));
1107  TestLayerDelegate root_delegate;
1108  root_delegate.AddColor(SK_ColorWHITE);
1109  root->set_delegate(&root_delegate);
1110
1111  scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1112                                        gfx::Rect(10, 20, 140, 180)));
1113  TestLayerDelegate l1_delegate;
1114  l1_delegate.AddColor(SK_ColorWHITE);
1115  l1->set_delegate(&l1_delegate);
1116
1117  GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1118  GetCompositor()->SetRootLayer(root.get());
1119  root->Add(l1.get());
1120  WaitForDraw();
1121
1122  EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1123  EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1124  gfx::Size size_in_pixel = root->cc_layer()->bounds();
1125  EXPECT_EQ("200x220", size_in_pixel.ToString());
1126  size_in_pixel = l1->cc_layer()->bounds();
1127  EXPECT_EQ("140x180", size_in_pixel.ToString());
1128  // No scale change, so no scale notification.
1129  EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
1130  EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1131
1132  EXPECT_EQ("200x220", root_delegate.paint_size().ToString());
1133  EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
1134
1135  // Scale up to 2.0. Changing scale doesn't change the bounds in DIP.
1136  GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1137  EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1138  EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1139  // Pixel size must have been scaled up.
1140  size_in_pixel = root->cc_layer()->bounds();
1141  EXPECT_EQ("400x440", size_in_pixel.ToString());
1142  size_in_pixel = l1->cc_layer()->bounds();
1143  EXPECT_EQ("280x360", size_in_pixel.ToString());
1144  // New scale factor must have been notified.
1145  EXPECT_EQ(2.0f, root_delegate.device_scale_factor());
1146  EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1147
1148  // Canvas size must have been scaled down up.
1149  WaitForDraw();
1150  EXPECT_EQ("400x440", root_delegate.paint_size().ToString());
1151  EXPECT_EQ("2.0 2.0", root_delegate.ToScaleString());
1152  EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
1153  EXPECT_EQ("2.0 2.0", l1_delegate.ToScaleString());
1154
1155  // Scale down back to 1.0f.
1156  GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1157  EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1158  EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1159  // Pixel size must have been scaled down.
1160  size_in_pixel = root->cc_layer()->bounds();
1161  EXPECT_EQ("200x220", size_in_pixel.ToString());
1162  size_in_pixel = l1->cc_layer()->bounds();
1163  EXPECT_EQ("140x180", size_in_pixel.ToString());
1164  // New scale factor must have been notified.
1165  EXPECT_EQ(1.0f, root_delegate.device_scale_factor());
1166  EXPECT_EQ(1.0f, l1_delegate.device_scale_factor());
1167
1168  // Canvas size must have been scaled down too.
1169  WaitForDraw();
1170  EXPECT_EQ("200x220", root_delegate.paint_size().ToString());
1171  EXPECT_EQ("1.0 1.0", root_delegate.ToScaleString());
1172  EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
1173  EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
1174
1175  root_delegate.reset();
1176  l1_delegate.reset();
1177  // Just changing the size shouldn't notify the scale change nor
1178  // trigger repaint.
1179  GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(1000, 1000));
1180  // No scale change, so no scale notification.
1181  EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
1182  EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1183  WaitForDraw();
1184  EXPECT_EQ("0x0", root_delegate.paint_size().ToString());
1185  EXPECT_EQ("0.0 0.0", root_delegate.ToScaleString());
1186  EXPECT_EQ("0x0", l1_delegate.paint_size().ToString());
1187  EXPECT_EQ("0.0 0.0", l1_delegate.ToScaleString());
1188}
1189
1190TEST_F(LayerWithRealCompositorTest, ScaleReparent) {
1191  scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1192                                          gfx::Rect(10, 20, 200, 220)));
1193  scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1194                                        gfx::Rect(10, 20, 140, 180)));
1195  TestLayerDelegate l1_delegate;
1196  l1_delegate.AddColor(SK_ColorWHITE);
1197  l1->set_delegate(&l1_delegate);
1198
1199  GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1200  GetCompositor()->SetRootLayer(root.get());
1201  WaitForDraw();
1202
1203  root->Add(l1.get());
1204  EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1205  gfx::Size size_in_pixel = l1->cc_layer()->bounds();
1206  EXPECT_EQ("140x180", size_in_pixel.ToString());
1207  EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1208
1209  WaitForDraw();
1210  EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
1211  EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
1212
1213  // Remove l1 from root and change the scale.
1214  root->Remove(l1.get());
1215  EXPECT_EQ(NULL, l1->parent());
1216  EXPECT_EQ(NULL, l1->GetCompositor());
1217  GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1218  // Sanity check on root and l1.
1219  EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1220  size_in_pixel = l1->cc_layer()->bounds();
1221  EXPECT_EQ("140x180", size_in_pixel.ToString());
1222
1223
1224  root->Add(l1.get());
1225  EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1226  size_in_pixel = l1->cc_layer()->bounds();
1227  EXPECT_EQ("280x360", size_in_pixel.ToString());
1228  EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1229  WaitForDraw();
1230  EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
1231  EXPECT_EQ("2.0 2.0", l1_delegate.ToScaleString());
1232}
1233
1234// Tests layer::set_scale_content(false).
1235TEST_F(LayerWithRealCompositorTest, NoScaleCanvas) {
1236  scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1237                                          gfx::Rect(10, 20, 200, 220)));
1238  scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1239                                        gfx::Rect(10, 20, 140, 180)));
1240  l1->set_scale_content(false);
1241  root->Add(l1.get());
1242  TestLayerDelegate l1_delegate;
1243  l1_delegate.AddColor(SK_ColorWHITE);
1244  l1->set_delegate(&l1_delegate);
1245
1246  GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1247  GetCompositor()->SetRootLayer(root.get());
1248  // Scale factor change is notified regardless of scale_content flag.
1249  EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1250
1251  WaitForDraw();
1252  EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
1253  EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
1254}
1255
1256// Verifies that when changing bounds on a layer that is invisible, and then
1257// made visible, the right thing happens:
1258// - if just a move, then no painting should happen.
1259// - if a resize, the layer should be repainted.
1260TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) {
1261  scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1262
1263  scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1264  child->SetBounds(gfx::Rect(0, 0, 500, 500));
1265  DrawTreeLayerDelegate delegate;
1266  child->set_delegate(&delegate);
1267  root->Add(child.get());
1268
1269  // Paint once for initial damage.
1270  child->SetVisible(true);
1271  DrawTree(root.get());
1272
1273  // Reset into invisible state.
1274  child->SetVisible(false);
1275  DrawTree(root.get());
1276  delegate.Reset();
1277
1278  // Move layer.
1279  child->SetBounds(gfx::Rect(200, 200, 500, 500));
1280  child->SetVisible(true);
1281  DrawTree(root.get());
1282  EXPECT_FALSE(delegate.painted());
1283
1284  // Reset into invisible state.
1285  child->SetVisible(false);
1286  DrawTree(root.get());
1287  delegate.Reset();
1288
1289  // Resize layer.
1290  child->SetBounds(gfx::Rect(200, 200, 400, 400));
1291  child->SetVisible(true);
1292  DrawTree(root.get());
1293  EXPECT_TRUE(delegate.painted());
1294}
1295
1296static scoped_ptr<cc::DelegatedFrameData> MakeFrameData(gfx::Size size) {
1297  scoped_ptr<cc::DelegatedFrameData> frame_data(new cc::DelegatedFrameData);
1298  scoped_ptr<cc::RenderPass> render_pass(cc::RenderPass::Create());
1299  render_pass->SetNew(cc::RenderPass::Id(1, 1),
1300                      gfx::Rect(size),
1301                      gfx::RectF(),
1302                      gfx::Transform());
1303  frame_data->render_pass_list.push_back(render_pass.Pass());
1304  return frame_data.Pass();
1305}
1306
1307TEST_F(LayerWithDelegateTest, DelegatedLayer) {
1308  scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1309
1310  scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1311
1312  child->SetBounds(gfx::Rect(0, 0, 10, 10));
1313  child->SetVisible(true);
1314  root->Add(child.get());
1315  DrawTree(root.get());
1316
1317  scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1318      new cc::DelegatedFrameResourceCollection;
1319  scoped_refptr<cc::DelegatedFrameProvider> frame_provider;
1320
1321  // Content matches layer size.
1322  frame_provider = new cc::DelegatedFrameProvider(
1323      resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
1324  child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
1325  EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1326            gfx::Size(10, 10).ToString());
1327
1328  // Content larger than layer.
1329  child->SetBounds(gfx::Rect(0, 0, 5, 5));
1330  EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1331            gfx::Size(5, 5).ToString());
1332
1333  // Content smaller than layer.
1334  child->SetBounds(gfx::Rect(0, 0, 10, 10));
1335  frame_provider = new cc::DelegatedFrameProvider(
1336      resource_collection.get(), MakeFrameData(gfx::Size(5, 5)));
1337  child->SetShowDelegatedContent(frame_provider, gfx::Size(5, 5));
1338  EXPECT_EQ(child->cc_layer()->bounds().ToString(), gfx::Size(5, 5).ToString());
1339
1340  // Hi-DPI content on low-DPI layer.
1341  frame_provider = new cc::DelegatedFrameProvider(
1342      resource_collection.get(), MakeFrameData(gfx::Size(20, 20)));
1343  child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
1344  EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1345            gfx::Size(10, 10).ToString());
1346
1347  // Hi-DPI content on hi-DPI layer.
1348  compositor()->SetScaleAndSize(2.f, gfx::Size(1000, 1000));
1349  EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1350            gfx::Size(20, 20).ToString());
1351
1352  // Low-DPI content on hi-DPI layer.
1353  frame_provider = new cc::DelegatedFrameProvider(
1354      resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
1355  child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
1356  EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1357            gfx::Size(20, 20).ToString());
1358}
1359
1360TEST_F(LayerWithDelegateTest, ExternalContent) {
1361  scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1362  scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1363
1364  child->SetBounds(gfx::Rect(0, 0, 10, 10));
1365  child->SetVisible(true);
1366  root->Add(child.get());
1367
1368  // The layer is already showing painted content, so the cc layer won't change.
1369  scoped_refptr<cc::Layer> before = child->cc_layer();
1370  child->SetShowPaintedContent();
1371  EXPECT_TRUE(child->cc_layer());
1372  EXPECT_EQ(before, child->cc_layer());
1373
1374  scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1375      new cc::DelegatedFrameResourceCollection;
1376  scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
1377      new cc::DelegatedFrameProvider(resource_collection.get(),
1378                                     MakeFrameData(gfx::Size(10, 10)));
1379
1380  // Showing delegated content changes the underlying cc layer.
1381  before = child->cc_layer();
1382  child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
1383  EXPECT_TRUE(child->cc_layer());
1384  EXPECT_NE(before, child->cc_layer());
1385
1386  // Changing to painted content should change the underlying cc layer.
1387  before = child->cc_layer();
1388  child->SetShowPaintedContent();
1389  EXPECT_TRUE(child->cc_layer());
1390  EXPECT_NE(before, child->cc_layer());
1391}
1392
1393// Tests Layer::AddThreadedAnimation and Layer::RemoveThreadedAnimation.
1394TEST_F(LayerWithRealCompositorTest, AddRemoveThreadedAnimations) {
1395  scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1396  scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
1397  scoped_ptr<Layer> l2(CreateLayer(LAYER_TEXTURED));
1398
1399  l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1400  l2->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1401
1402  EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1403
1404  // Trigger a threaded animation.
1405  l1->SetOpacity(0.5f);
1406
1407  EXPECT_TRUE(l1->HasPendingThreadedAnimations());
1408
1409  // Ensure we can remove a pending threaded animation.
1410  l1->GetAnimator()->StopAnimating();
1411
1412  EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1413
1414  // Trigger another threaded animation.
1415  l1->SetOpacity(0.2f);
1416
1417  EXPECT_TRUE(l1->HasPendingThreadedAnimations());
1418
1419  root->Add(l1.get());
1420  GetCompositor()->SetRootLayer(root.get());
1421
1422  // Now that l1 is part of a tree, it should have dispatched the pending
1423  // animation.
1424  EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1425
1426  // Ensure that l1 no longer holds on to animations.
1427  l1->SetOpacity(0.1f);
1428  EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1429
1430  // Ensure that adding a layer to an existing tree causes its pending
1431  // animations to get dispatched.
1432  l2->SetOpacity(0.5f);
1433  EXPECT_TRUE(l2->HasPendingThreadedAnimations());
1434
1435  l1->Add(l2.get());
1436  EXPECT_FALSE(l2->HasPendingThreadedAnimations());
1437}
1438
1439// Tests that in-progress threaded animations complete when a Layer's
1440// cc::Layer changes.
1441TEST_F(LayerWithRealCompositorTest, SwitchCCLayerAnimations) {
1442  scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1443  scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
1444  GetCompositor()->SetRootLayer(root.get());
1445  root->Add(l1.get());
1446
1447  l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1448
1449  EXPECT_FLOAT_EQ(l1->opacity(), 1.0f);
1450
1451  // Trigger a threaded animation.
1452  l1->SetOpacity(0.5f);
1453
1454  // Change l1's cc::Layer.
1455  l1->SwitchCCLayerForTest();
1456
1457  // Ensure that the opacity animation completed.
1458  EXPECT_FLOAT_EQ(l1->opacity(), 0.5f);
1459}
1460
1461}  // namespace ui
1462