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