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