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