Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ui / compositor / layer_unittest.cc
blob7b96199ab56a4d59e1d4ee1e9542df8322b4ecb8
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/compiler_specific.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/json/json_reader.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/path_service.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/trace_event/trace_event.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/paint_context.h"
31 #include "ui/compositor/paint_recorder.h"
32 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
33 #include "ui/compositor/scoped_layer_animation_settings.h"
34 #include "ui/compositor/test/context_factories_for_test.h"
35 #include "ui/compositor/test/draw_waiter_for_test.h"
36 #include "ui/compositor/test/test_compositor_host.h"
37 #include "ui/compositor/test/test_layers.h"
38 #include "ui/gfx/canvas.h"
39 #include "ui/gfx/codec/png_codec.h"
40 #include "ui/gfx/gfx_paths.h"
41 #include "ui/gfx/skia_util.h"
43 using cc::MatchesPNGFile;
45 namespace ui {
47 namespace {
49 // There are three test classes in here that configure the Compositor and
50 // Layer's slightly differently:
51 // - LayerWithNullDelegateTest uses NullLayerDelegate as the LayerDelegate. This
52 // is typically the base class you want to use.
53 // - LayerWithDelegateTest uses LayerDelegate on the delegates.
54 // - LayerWithRealCompositorTest when a real compositor is required for testing.
55 // - Slow because they bring up a window and run the real compositor. This
56 // is typically not what you want.
58 class ColoredLayer : public Layer, public LayerDelegate {
59 public:
60 explicit ColoredLayer(SkColor color)
61 : Layer(LAYER_TEXTURED),
62 color_(color) {
63 set_delegate(this);
66 ~ColoredLayer() override {}
68 // Overridden from LayerDelegate:
69 void OnPaintLayer(const ui::PaintContext& context) override {
70 ui::PaintRecorder recorder(context, size());
71 recorder.canvas()->DrawColor(color_);
74 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
76 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
78 base::Closure PrepareForLayerBoundsChange() override {
79 return base::Closure();
82 private:
83 SkColor color_;
86 class LayerWithRealCompositorTest : public testing::Test {
87 public:
88 LayerWithRealCompositorTest() {
89 if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) {
90 test_data_directory_ = test_data_directory_.AppendASCII("compositor");
91 } else {
92 LOG(ERROR) << "Could not open test data directory.";
95 ~LayerWithRealCompositorTest() override {}
97 // Overridden from testing::Test:
98 void SetUp() override {
99 bool enable_pixel_output = true;
100 ui::ContextFactory* context_factory =
101 InitializeContextFactoryForTests(enable_pixel_output);
103 const gfx::Rect host_bounds(10, 10, 500, 500);
104 compositor_host_.reset(
105 TestCompositorHost::Create(host_bounds, context_factory));
106 compositor_host_->Show();
109 void TearDown() override {
110 ResetCompositor();
111 TerminateContextFactoryForTests();
114 Compositor* GetCompositor() { return compositor_host_->GetCompositor(); }
116 void ResetCompositor() {
117 compositor_host_.reset();
120 Layer* CreateLayer(LayerType type) {
121 return new Layer(type);
124 Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
125 Layer* layer = new ColoredLayer(color);
126 layer->SetBounds(bounds);
127 return layer;
130 Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
131 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
132 layer->SetBounds(bounds);
133 return layer;
136 void DrawTree(Layer* root) {
137 GetCompositor()->SetRootLayer(root);
138 GetCompositor()->ScheduleDraw();
139 WaitForSwap();
142 void ReadPixels(SkBitmap* bitmap) {
143 ReadPixels(bitmap, gfx::Rect(GetCompositor()->size()));
146 void ReadPixels(SkBitmap* bitmap, gfx::Rect source_rect) {
147 scoped_refptr<ReadbackHolder> holder(new ReadbackHolder);
148 scoped_ptr<cc::CopyOutputRequest> request =
149 cc::CopyOutputRequest::CreateBitmapRequest(
150 base::Bind(&ReadbackHolder::OutputRequestCallback, holder));
151 request->set_area(source_rect);
153 GetCompositor()->root_layer()->RequestCopyOfOutput(request.Pass());
155 // Wait for copy response. This needs to wait as the compositor could
156 // be in the middle of a draw right now, and the commit with the
157 // copy output request may not be done on the first draw.
158 for (int i = 0; i < 2; i++) {
159 GetCompositor()->ScheduleFullRedraw();
160 WaitForDraw();
163 // Waits for the callback to finish run and return result.
164 holder->WaitForReadback();
166 *bitmap = holder->result();
169 void WaitForDraw() {
170 ui::DrawWaiterForTest::WaitForCompositingStarted(GetCompositor());
173 void WaitForSwap() {
174 DrawWaiterForTest::WaitForCompositingEnded(GetCompositor());
177 void WaitForCommit() {
178 ui::DrawWaiterForTest::WaitForCommit(GetCompositor());
181 // Invalidates the entire contents of the layer.
182 void SchedulePaintForLayer(Layer* layer) {
183 layer->SchedulePaint(
184 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
187 const base::FilePath& test_data_directory() const {
188 return test_data_directory_;
191 private:
192 class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> {
193 public:
194 ReadbackHolder() : run_loop_(new base::RunLoop) {}
196 void OutputRequestCallback(scoped_ptr<cc::CopyOutputResult> result) {
197 result_ = result->TakeBitmap();
198 run_loop_->Quit();
201 void WaitForReadback() { run_loop_->Run(); }
203 const SkBitmap& result() const { return *result_; }
205 private:
206 friend class base::RefCountedThreadSafe<ReadbackHolder>;
208 virtual ~ReadbackHolder() {}
210 scoped_ptr<SkBitmap> result_;
211 scoped_ptr<base::RunLoop> run_loop_;
214 scoped_ptr<TestCompositorHost> compositor_host_;
216 // The root directory for test files.
217 base::FilePath test_data_directory_;
219 DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest);
222 // LayerDelegate that paints colors to the layer.
223 class TestLayerDelegate : public LayerDelegate {
224 public:
225 TestLayerDelegate() { reset(); }
226 ~TestLayerDelegate() override {}
228 void AddColor(SkColor color) {
229 colors_.push_back(color);
232 int color_index() const { return color_index_; }
234 float device_scale_factor() const {
235 return device_scale_factor_;
238 void set_layer_bounds(const gfx::Rect& layer_bounds) {
239 layer_bounds_ = layer_bounds;
242 // Overridden from LayerDelegate:
243 void OnPaintLayer(const ui::PaintContext& context) override {
244 ui::PaintRecorder recorder(context, layer_bounds_.size());
245 recorder.canvas()->DrawColor(colors_[color_index_]);
246 color_index_ = (color_index_ + 1) % static_cast<int>(colors_.size());
249 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
251 void OnDeviceScaleFactorChanged(float device_scale_factor) override {
252 device_scale_factor_ = device_scale_factor;
255 base::Closure PrepareForLayerBoundsChange() override {
256 return base::Closure();
259 void reset() {
260 color_index_ = 0;
261 device_scale_factor_ = 0.0f;
264 private:
265 std::vector<SkColor> colors_;
266 int color_index_;
267 float device_scale_factor_;
268 gfx::Rect layer_bounds_;
270 DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate);
273 // LayerDelegate that verifies that a layer was asked to update its canvas.
274 class DrawTreeLayerDelegate : public LayerDelegate {
275 public:
276 DrawTreeLayerDelegate(const gfx::Rect& layer_bounds)
277 : painted_(false), layer_bounds_(layer_bounds) {}
278 ~DrawTreeLayerDelegate() override {}
280 void Reset() {
281 painted_ = false;
284 bool painted() const { return painted_; }
286 private:
287 // Overridden from LayerDelegate:
288 void OnPaintLayer(const ui::PaintContext& context) override {
289 painted_ = true;
290 ui::PaintRecorder recorder(context, layer_bounds_.size());
291 recorder.canvas()->DrawColor(SK_ColorWHITE);
293 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
294 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
295 base::Closure PrepareForLayerBoundsChange() override {
296 return base::Closure();
299 bool painted_;
300 const gfx::Rect layer_bounds_;
302 DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate);
305 // The simplest possible layer delegate. Does nothing.
306 class NullLayerDelegate : public LayerDelegate {
307 public:
308 NullLayerDelegate() {}
309 ~NullLayerDelegate() override {}
311 private:
312 // Overridden from LayerDelegate:
313 void OnPaintLayer(const ui::PaintContext& context) override {}
314 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
315 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
316 base::Closure PrepareForLayerBoundsChange() override {
317 return base::Closure();
320 DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate);
323 // Remembers if it has been notified.
324 class TestCompositorObserver : public CompositorObserver {
325 public:
326 TestCompositorObserver()
327 : committed_(false), started_(false), ended_(false), aborted_(false) {}
329 bool committed() const { return committed_; }
330 bool notified() const { return started_ && ended_; }
331 bool aborted() const { return aborted_; }
333 void Reset() {
334 committed_ = false;
335 started_ = false;
336 ended_ = false;
337 aborted_ = false;
340 private:
341 void OnCompositingDidCommit(Compositor* compositor) override {
342 committed_ = true;
345 void OnCompositingStarted(Compositor* compositor,
346 base::TimeTicks start_time) override {
347 started_ = true;
350 void OnCompositingEnded(Compositor* compositor) override { ended_ = true; }
352 void OnCompositingAborted(Compositor* compositor) override {
353 aborted_ = true;
356 void OnCompositingLockStateChanged(Compositor* compositor) override {}
358 void OnCompositingShuttingDown(Compositor* compositor) override {}
360 bool committed_;
361 bool started_;
362 bool ended_;
363 bool aborted_;
365 DISALLOW_COPY_AND_ASSIGN(TestCompositorObserver);
368 class TestCompositorAnimationObserver : public CompositorAnimationObserver {
369 public:
370 explicit TestCompositorAnimationObserver(ui::Compositor* compositor)
371 : compositor_(compositor),
372 animation_step_count_(0),
373 shutdown_(false) {
374 DCHECK(compositor_);
375 compositor_->AddAnimationObserver(this);
378 ~TestCompositorAnimationObserver() override {
379 if (compositor_)
380 compositor_->RemoveAnimationObserver(this);
383 size_t animation_step_count() const { return animation_step_count_; }
384 bool shutdown() const { return shutdown_; }
386 private:
387 void OnAnimationStep(base::TimeTicks timestamp) override {
388 ++animation_step_count_;
391 void OnCompositingShuttingDown(Compositor* compositor) override {
392 DCHECK_EQ(compositor_, compositor);
393 compositor_->RemoveAnimationObserver(this);
394 compositor_ = nullptr;
395 shutdown_ = true;
398 ui::Compositor* compositor_;
399 size_t animation_step_count_;
400 bool shutdown_;
402 DISALLOW_COPY_AND_ASSIGN(TestCompositorAnimationObserver);
405 } // namespace
407 TEST_F(LayerWithRealCompositorTest, Draw) {
408 scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED,
409 gfx::Rect(20, 20, 50, 50)));
410 DrawTree(layer.get());
413 // Create this hierarchy:
414 // L1 - red
415 // +-- L2 - blue
416 // | +-- L3 - yellow
417 // +-- L4 - magenta
419 TEST_F(LayerWithRealCompositorTest, Hierarchy) {
420 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
421 gfx::Rect(20, 20, 400, 400)));
422 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
423 gfx::Rect(10, 10, 350, 350)));
424 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
425 gfx::Rect(5, 5, 25, 25)));
426 scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
427 gfx::Rect(300, 300, 100, 100)));
429 l1->Add(l2.get());
430 l1->Add(l4.get());
431 l2->Add(l3.get());
433 DrawTree(l1.get());
436 class LayerWithDelegateTest : public testing::Test {
437 public:
438 LayerWithDelegateTest() {}
439 ~LayerWithDelegateTest() override {}
441 // Overridden from testing::Test:
442 void SetUp() override {
443 bool enable_pixel_output = false;
444 ui::ContextFactory* context_factory =
445 InitializeContextFactoryForTests(enable_pixel_output);
447 const gfx::Rect host_bounds(1000, 1000);
448 compositor_host_.reset(TestCompositorHost::Create(host_bounds,
449 context_factory));
450 compositor_host_->Show();
453 void TearDown() override {
454 compositor_host_.reset();
455 TerminateContextFactoryForTests();
458 Compositor* compositor() { return compositor_host_->GetCompositor(); }
460 virtual Layer* CreateLayer(LayerType type) {
461 return new Layer(type);
464 Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
465 Layer* layer = new ColoredLayer(color);
466 layer->SetBounds(bounds);
467 return layer;
470 virtual Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
471 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
472 layer->SetBounds(bounds);
473 return layer;
476 void DrawTree(Layer* root) {
477 compositor()->SetRootLayer(root);
478 Draw();
481 // Invalidates the entire contents of the layer.
482 void SchedulePaintForLayer(Layer* layer) {
483 layer->SchedulePaint(
484 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
487 // Invokes DrawTree on the compositor.
488 void Draw() {
489 compositor()->ScheduleDraw();
490 WaitForDraw();
493 void WaitForDraw() {
494 DrawWaiterForTest::WaitForCompositingStarted(compositor());
497 void WaitForCommit() {
498 DrawWaiterForTest::WaitForCommit(compositor());
501 private:
502 scoped_ptr<TestCompositorHost> compositor_host_;
504 DISALLOW_COPY_AND_ASSIGN(LayerWithDelegateTest);
507 // L1
508 // +-- L2
509 TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Simple) {
510 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
511 gfx::Rect(20, 20, 400, 400)));
512 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
513 gfx::Rect(10, 10, 350, 350)));
514 l1->Add(l2.get());
515 DrawTree(l1.get());
517 gfx::Point point1_in_l2_coords(5, 5);
518 Layer::ConvertPointToLayer(l2.get(), l1.get(), &point1_in_l2_coords);
519 gfx::Point point1_in_l1_coords(15, 15);
520 EXPECT_EQ(point1_in_l1_coords, point1_in_l2_coords);
522 gfx::Point point2_in_l1_coords(5, 5);
523 Layer::ConvertPointToLayer(l1.get(), l2.get(), &point2_in_l1_coords);
524 gfx::Point point2_in_l2_coords(-5, -5);
525 EXPECT_EQ(point2_in_l2_coords, point2_in_l1_coords);
528 // L1
529 // +-- L2
530 // +-- L3
531 TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Medium) {
532 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
533 gfx::Rect(20, 20, 400, 400)));
534 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
535 gfx::Rect(10, 10, 350, 350)));
536 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
537 gfx::Rect(10, 10, 100, 100)));
538 l1->Add(l2.get());
539 l2->Add(l3.get());
540 DrawTree(l1.get());
542 gfx::Point point1_in_l3_coords(5, 5);
543 Layer::ConvertPointToLayer(l3.get(), l1.get(), &point1_in_l3_coords);
544 gfx::Point point1_in_l1_coords(25, 25);
545 EXPECT_EQ(point1_in_l1_coords, point1_in_l3_coords);
547 gfx::Point point2_in_l1_coords(5, 5);
548 Layer::ConvertPointToLayer(l1.get(), l3.get(), &point2_in_l1_coords);
549 gfx::Point point2_in_l3_coords(-15, -15);
550 EXPECT_EQ(point2_in_l3_coords, point2_in_l1_coords);
553 TEST_F(LayerWithRealCompositorTest, Delegate) {
554 // This test makes sure that whenever paint happens at a layer, its layer
555 // delegate gets the paint, which in this test update its color and
556 // |color_index|.
557 scoped_ptr<Layer> l1(
558 CreateColorLayer(SK_ColorBLACK, gfx::Rect(20, 20, 400, 400)));
559 GetCompositor()->SetRootLayer(l1.get());
560 WaitForDraw();
562 TestLayerDelegate delegate;
563 l1->set_delegate(&delegate);
564 delegate.set_layer_bounds(l1->bounds());
565 delegate.AddColor(SK_ColorWHITE);
566 delegate.AddColor(SK_ColorYELLOW);
567 delegate.AddColor(SK_ColorGREEN);
569 l1->SchedulePaint(gfx::Rect(0, 0, 400, 400));
570 WaitForDraw();
571 // Test that paint happened at layer delegate.
572 EXPECT_EQ(1, delegate.color_index());
574 l1->SchedulePaint(gfx::Rect(10, 10, 200, 200));
575 WaitForDraw();
576 // Test that paint happened at layer delegate.
577 EXPECT_EQ(2, delegate.color_index());
579 l1->SchedulePaint(gfx::Rect(5, 5, 50, 50));
580 WaitForDraw();
581 // Test that paint happened at layer delegate.
582 EXPECT_EQ(0, delegate.color_index());
585 TEST_F(LayerWithRealCompositorTest, DrawTree) {
586 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
587 gfx::Rect(20, 20, 400, 400)));
588 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
589 gfx::Rect(10, 10, 350, 350)));
590 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
591 gfx::Rect(10, 10, 100, 100)));
592 l1->Add(l2.get());
593 l2->Add(l3.get());
595 GetCompositor()->SetRootLayer(l1.get());
596 WaitForDraw();
598 DrawTreeLayerDelegate d1(l1->bounds());
599 l1->set_delegate(&d1);
600 DrawTreeLayerDelegate d2(l2->bounds());
601 l2->set_delegate(&d2);
602 DrawTreeLayerDelegate d3(l3->bounds());
603 l3->set_delegate(&d3);
605 l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
606 WaitForDraw();
607 EXPECT_FALSE(d1.painted());
608 EXPECT_TRUE(d2.painted());
609 EXPECT_FALSE(d3.painted());
612 // Tests no-texture Layers.
613 // Create this hierarchy:
614 // L1 - red
615 // +-- L2 - NO TEXTURE
616 // | +-- L3 - yellow
617 // +-- L4 - magenta
619 TEST_F(LayerWithRealCompositorTest, HierarchyNoTexture) {
620 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
621 gfx::Rect(20, 20, 400, 400)));
622 scoped_ptr<Layer> l2(CreateNoTextureLayer(gfx::Rect(10, 10, 350, 350)));
623 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
624 gfx::Rect(5, 5, 25, 25)));
625 scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
626 gfx::Rect(300, 300, 100, 100)));
628 l1->Add(l2.get());
629 l1->Add(l4.get());
630 l2->Add(l3.get());
632 GetCompositor()->SetRootLayer(l1.get());
633 WaitForDraw();
635 DrawTreeLayerDelegate d2(l2->bounds());
636 l2->set_delegate(&d2);
637 DrawTreeLayerDelegate d3(l3->bounds());
638 l3->set_delegate(&d3);
640 l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
641 l3->SchedulePaint(gfx::Rect(5, 5, 5, 5));
642 WaitForDraw();
644 // |d2| should not have received a paint notification since it has no texture.
645 EXPECT_FALSE(d2.painted());
646 // |d3| should have received a paint notification.
647 EXPECT_TRUE(d3.painted());
650 class LayerWithNullDelegateTest : public LayerWithDelegateTest {
651 public:
652 LayerWithNullDelegateTest() {}
653 ~LayerWithNullDelegateTest() override {}
655 void SetUp() override {
656 LayerWithDelegateTest::SetUp();
657 default_layer_delegate_.reset(new NullLayerDelegate());
660 Layer* CreateLayer(LayerType type) override {
661 Layer* layer = new Layer(type);
662 layer->set_delegate(default_layer_delegate_.get());
663 return layer;
666 Layer* CreateTextureRootLayer(const gfx::Rect& bounds) {
667 Layer* layer = CreateTextureLayer(bounds);
668 compositor()->SetRootLayer(layer);
669 return layer;
672 Layer* CreateTextureLayer(const gfx::Rect& bounds) {
673 Layer* layer = CreateLayer(LAYER_TEXTURED);
674 layer->SetBounds(bounds);
675 return layer;
678 Layer* CreateNoTextureLayer(const gfx::Rect& bounds) override {
679 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
680 layer->SetBounds(bounds);
681 return layer;
684 private:
685 scoped_ptr<NullLayerDelegate> default_layer_delegate_;
687 DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest);
690 TEST_F(LayerWithNullDelegateTest, EscapedDebugNames) {
691 scoped_ptr<Layer> layer(CreateLayer(LAYER_NOT_DRAWN));
692 std::string name = "\"\'\\/\b\f\n\r\t\n";
693 layer->set_name(name);
694 scoped_refptr<base::trace_event::ConvertableToTraceFormat> debug_info =
695 layer->TakeDebugInfo();
696 EXPECT_TRUE(debug_info.get());
697 std::string json;
698 debug_info->AppendAsTraceFormat(&json);
699 base::JSONReader json_reader;
700 scoped_ptr<base::Value> debug_info_value(json_reader.ReadToValue(json));
701 EXPECT_TRUE(debug_info_value);
702 EXPECT_TRUE(debug_info_value->IsType(base::Value::TYPE_DICTIONARY));
703 base::DictionaryValue* dictionary = 0;
704 EXPECT_TRUE(debug_info_value->GetAsDictionary(&dictionary));
705 std::string roundtrip;
706 EXPECT_TRUE(dictionary->GetString("layer_name", &roundtrip));
707 EXPECT_EQ(name, roundtrip);
710 void ReturnMailbox(bool* run, uint32 sync_point, bool is_lost) {
711 *run = true;
714 TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) {
715 scoped_ptr<Layer> l1(CreateLayer(LAYER_SOLID_COLOR));
716 l1->SetFillsBoundsOpaquely(true);
717 l1->SetForceRenderSurface(true);
718 l1->SetVisible(false);
719 l1->SetBounds(gfx::Rect(4, 5));
721 EXPECT_EQ(gfx::Point3F(), l1->cc_layer_for_testing()->transform_origin());
722 EXPECT_TRUE(l1->cc_layer_for_testing()->DrawsContent());
723 EXPECT_TRUE(l1->cc_layer_for_testing()->contents_opaque());
724 EXPECT_TRUE(l1->cc_layer_for_testing()->force_render_surface());
725 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
726 EXPECT_EQ(gfx::Size(4, 5), l1->cc_layer_for_testing()->bounds());
728 cc::Layer* before_layer = l1->cc_layer_for_testing();
730 bool callback1_run = false;
731 cc::TextureMailbox mailbox(gpu::Mailbox::Generate(), 0, 0);
732 l1->SetTextureMailbox(mailbox, cc::SingleReleaseCallback::Create(
733 base::Bind(ReturnMailbox, &callback1_run)),
734 gfx::Size(10, 10));
736 EXPECT_NE(before_layer, l1->cc_layer_for_testing());
738 EXPECT_EQ(gfx::Point3F(), l1->cc_layer_for_testing()->transform_origin());
739 EXPECT_TRUE(l1->cc_layer_for_testing()->DrawsContent());
740 EXPECT_TRUE(l1->cc_layer_for_testing()->contents_opaque());
741 EXPECT_TRUE(l1->cc_layer_for_testing()->force_render_surface());
742 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
743 EXPECT_EQ(gfx::Size(4, 5), l1->cc_layer_for_testing()->bounds());
744 EXPECT_FALSE(callback1_run);
746 bool callback2_run = false;
747 mailbox = cc::TextureMailbox(gpu::Mailbox::Generate(), 0, 0);
748 l1->SetTextureMailbox(mailbox, cc::SingleReleaseCallback::Create(
749 base::Bind(ReturnMailbox, &callback2_run)),
750 gfx::Size(10, 10));
751 EXPECT_TRUE(callback1_run);
752 EXPECT_FALSE(callback2_run);
754 // Show solid color instead.
755 l1->SetShowSolidColorContent();
756 EXPECT_EQ(gfx::Point3F(), l1->cc_layer_for_testing()->transform_origin());
757 EXPECT_TRUE(l1->cc_layer_for_testing()->DrawsContent());
758 EXPECT_TRUE(l1->cc_layer_for_testing()->contents_opaque());
759 EXPECT_TRUE(l1->cc_layer_for_testing()->force_render_surface());
760 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
761 EXPECT_EQ(gfx::Size(4, 5), l1->cc_layer_for_testing()->bounds());
762 EXPECT_TRUE(callback2_run);
764 before_layer = l1->cc_layer_for_testing();
766 // Back to a texture, without changing the bounds of the layer or the texture.
767 bool callback3_run = false;
768 mailbox = cc::TextureMailbox(gpu::Mailbox::Generate(), 0, 0);
769 l1->SetTextureMailbox(mailbox, cc::SingleReleaseCallback::Create(
770 base::Bind(ReturnMailbox, &callback3_run)),
771 gfx::Size(10, 10));
773 EXPECT_NE(before_layer, l1->cc_layer_for_testing());
775 EXPECT_EQ(gfx::Point3F(), l1->cc_layer_for_testing()->transform_origin());
776 EXPECT_TRUE(l1->cc_layer_for_testing()->DrawsContent());
777 EXPECT_TRUE(l1->cc_layer_for_testing()->contents_opaque());
778 EXPECT_TRUE(l1->cc_layer_for_testing()->force_render_surface());
779 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
780 EXPECT_EQ(gfx::Size(4, 5), l1->cc_layer_for_testing()->bounds());
781 EXPECT_FALSE(callback3_run);
783 // Release the on |l1| mailbox to clean up the test.
784 l1->SetShowSolidColorContent();
787 // Various visibile/drawn assertions.
788 TEST_F(LayerWithNullDelegateTest, Visibility) {
789 scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
790 scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
791 scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
792 l1->Add(l2.get());
793 l2->Add(l3.get());
795 NullLayerDelegate delegate;
796 l1->set_delegate(&delegate);
797 l2->set_delegate(&delegate);
798 l3->set_delegate(&delegate);
800 // Layers should initially be drawn.
801 EXPECT_TRUE(l1->IsDrawn());
802 EXPECT_TRUE(l2->IsDrawn());
803 EXPECT_TRUE(l3->IsDrawn());
804 EXPECT_FALSE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
805 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
806 EXPECT_FALSE(l3->cc_layer_for_testing()->hide_layer_and_subtree());
808 compositor()->SetRootLayer(l1.get());
810 Draw();
812 l1->SetVisible(false);
813 EXPECT_FALSE(l1->IsDrawn());
814 EXPECT_FALSE(l2->IsDrawn());
815 EXPECT_FALSE(l3->IsDrawn());
816 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
817 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
818 EXPECT_FALSE(l3->cc_layer_for_testing()->hide_layer_and_subtree());
820 l3->SetVisible(false);
821 EXPECT_FALSE(l1->IsDrawn());
822 EXPECT_FALSE(l2->IsDrawn());
823 EXPECT_FALSE(l3->IsDrawn());
824 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
825 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
826 EXPECT_TRUE(l3->cc_layer_for_testing()->hide_layer_and_subtree());
828 l1->SetVisible(true);
829 EXPECT_TRUE(l1->IsDrawn());
830 EXPECT_TRUE(l2->IsDrawn());
831 EXPECT_FALSE(l3->IsDrawn());
832 EXPECT_FALSE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
833 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
834 EXPECT_TRUE(l3->cc_layer_for_testing()->hide_layer_and_subtree());
837 // Checks that stacking-related methods behave as advertised.
838 TEST_F(LayerWithNullDelegateTest, Stacking) {
839 scoped_ptr<Layer> root(new Layer(LAYER_NOT_DRAWN));
840 scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
841 scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
842 scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
843 l1->set_name("1");
844 l2->set_name("2");
845 l3->set_name("3");
846 root->Add(l3.get());
847 root->Add(l2.get());
848 root->Add(l1.get());
850 // Layers' children are stored in bottom-to-top order.
851 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
853 root->StackAtTop(l3.get());
854 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
856 root->StackAtTop(l1.get());
857 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
859 root->StackAtTop(l1.get());
860 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
862 root->StackAbove(l2.get(), l3.get());
863 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
865 root->StackAbove(l1.get(), l3.get());
866 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
868 root->StackAbove(l2.get(), l1.get());
869 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
871 root->StackAtBottom(l2.get());
872 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
874 root->StackAtBottom(l3.get());
875 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
877 root->StackAtBottom(l3.get());
878 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
880 root->StackBelow(l2.get(), l3.get());
881 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
883 root->StackBelow(l1.get(), l3.get());
884 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
886 root->StackBelow(l3.get(), l2.get());
887 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
889 root->StackBelow(l3.get(), l2.get());
890 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
892 root->StackBelow(l3.get(), l1.get());
893 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
896 // Verifies SetBounds triggers the appropriate painting/drawing.
897 TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) {
898 scoped_ptr<Layer> l1(CreateTextureLayer(gfx::Rect(0, 0, 200, 200)));
899 compositor()->SetRootLayer(l1.get());
901 Draw();
903 l1->SetBounds(gfx::Rect(5, 5, 200, 200));
905 // The CompositorDelegate (us) should have been told to draw for a move.
906 WaitForDraw();
908 l1->SetBounds(gfx::Rect(5, 5, 100, 100));
910 // The CompositorDelegate (us) should have been told to draw for a resize.
911 WaitForDraw();
914 void ExpectRgba(int x, int y, SkColor expected_color, SkColor actual_color) {
915 EXPECT_EQ(expected_color, actual_color)
916 << "Pixel error at x=" << x << " y=" << y << "; "
917 << "actual RGBA=("
918 << SkColorGetR(actual_color) << ","
919 << SkColorGetG(actual_color) << ","
920 << SkColorGetB(actual_color) << ","
921 << SkColorGetA(actual_color) << "); "
922 << "expected RGBA=("
923 << SkColorGetR(expected_color) << ","
924 << SkColorGetG(expected_color) << ","
925 << SkColorGetB(expected_color) << ","
926 << SkColorGetA(expected_color) << ")";
929 // Checks that pixels are actually drawn to the screen with a read back.
930 TEST_F(LayerWithRealCompositorTest, DrawPixels) {
931 gfx::Size viewport_size = GetCompositor()->size();
933 // The window should be some non-trivial size but may not be exactly
934 // 500x500 on all platforms/bots.
935 EXPECT_GE(viewport_size.width(), 200);
936 EXPECT_GE(viewport_size.height(), 200);
938 int blue_height = 10;
940 scoped_ptr<Layer> layer(
941 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
942 scoped_ptr<Layer> layer2(
943 CreateColorLayer(SK_ColorBLUE,
944 gfx::Rect(0, 0, viewport_size.width(), blue_height)));
946 layer->Add(layer2.get());
948 DrawTree(layer.get());
950 SkBitmap bitmap;
951 ReadPixels(&bitmap, gfx::Rect(viewport_size));
952 ASSERT_FALSE(bitmap.empty());
954 SkAutoLockPixels lock(bitmap);
955 for (int x = 0; x < viewport_size.width(); x++) {
956 for (int y = 0; y < viewport_size.height(); y++) {
957 SkColor actual_color = bitmap.getColor(x, y);
958 SkColor expected_color = y < blue_height ? SK_ColorBLUE : SK_ColorRED;
959 ExpectRgba(x, y, expected_color, actual_color);
964 // Checks that drawing a layer with transparent pixels is blended correctly
965 // with the lower layer.
966 TEST_F(LayerWithRealCompositorTest, DrawAlphaBlendedPixels) {
967 gfx::Size viewport_size = GetCompositor()->size();
969 int test_size = 200;
970 EXPECT_GE(viewport_size.width(), test_size);
971 EXPECT_GE(viewport_size.height(), test_size);
973 // Blue with a wee bit of transparency.
974 SkColor blue_with_alpha = SkColorSetARGBInline(40, 10, 20, 200);
975 SkColor blend_color = SkColorSetARGBInline(255, 216, 3, 32);
977 scoped_ptr<Layer> background_layer(
978 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
979 scoped_ptr<Layer> foreground_layer(
980 CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size)));
982 // This must be set to false for layers with alpha to be blended correctly.
983 foreground_layer->SetFillsBoundsOpaquely(false);
985 background_layer->Add(foreground_layer.get());
986 DrawTree(background_layer.get());
988 SkBitmap bitmap;
989 ReadPixels(&bitmap, gfx::Rect(viewport_size));
990 ASSERT_FALSE(bitmap.empty());
992 SkAutoLockPixels lock(bitmap);
993 for (int x = 0; x < test_size; x++) {
994 for (int y = 0; y < test_size; y++) {
995 SkColor actual_color = bitmap.getColor(x, y);
996 ExpectRgba(x, y, blend_color, actual_color);
1001 // Checks that using the AlphaShape filter applied to a layer with
1002 // transparency, alpha-blends properly with the layer below.
1003 TEST_F(LayerWithRealCompositorTest, DrawAlphaThresholdFilterPixels) {
1004 gfx::Size viewport_size = GetCompositor()->size();
1006 int test_size = 200;
1007 EXPECT_GE(viewport_size.width(), test_size);
1008 EXPECT_GE(viewport_size.height(), test_size);
1010 int blue_height = 10;
1011 SkColor blue_with_alpha = SkColorSetARGBInline(40, 0, 0, 255);
1012 SkColor blend_color = SkColorSetARGBInline(255, 215, 0, 40);
1014 scoped_ptr<Layer> background_layer(
1015 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
1016 scoped_ptr<Layer> foreground_layer(
1017 CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size)));
1019 // Add a shape to restrict the visible part of the layer.
1020 SkRegion shape;
1021 shape.setRect(0, 0, viewport_size.width(), blue_height);
1022 foreground_layer->SetAlphaShape(make_scoped_ptr(new SkRegion(shape)));
1024 foreground_layer->SetFillsBoundsOpaquely(false);
1026 background_layer->Add(foreground_layer.get());
1027 DrawTree(background_layer.get());
1029 SkBitmap bitmap;
1030 ReadPixels(&bitmap, gfx::Rect(viewport_size));
1031 ASSERT_FALSE(bitmap.empty());
1033 SkAutoLockPixels lock(bitmap);
1034 for (int x = 0; x < test_size; x++) {
1035 for (int y = 0; y < test_size; y++) {
1036 SkColor actual_color = bitmap.getColor(x, y);
1037 ExpectRgba(x, y, actual_color,
1038 y < blue_height ? blend_color : SK_ColorRED);
1043 // Checks the logic around Compositor::SetRootLayer and Layer::SetCompositor.
1044 TEST_F(LayerWithRealCompositorTest, SetRootLayer) {
1045 Compositor* compositor = GetCompositor();
1046 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
1047 gfx::Rect(20, 20, 400, 400)));
1048 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
1049 gfx::Rect(10, 10, 350, 350)));
1051 EXPECT_EQ(NULL, l1->GetCompositor());
1052 EXPECT_EQ(NULL, l2->GetCompositor());
1054 compositor->SetRootLayer(l1.get());
1055 EXPECT_EQ(compositor, l1->GetCompositor());
1057 l1->Add(l2.get());
1058 EXPECT_EQ(compositor, l2->GetCompositor());
1060 l1->Remove(l2.get());
1061 EXPECT_EQ(NULL, l2->GetCompositor());
1063 l1->Add(l2.get());
1064 EXPECT_EQ(compositor, l2->GetCompositor());
1066 compositor->SetRootLayer(NULL);
1067 EXPECT_EQ(NULL, l1->GetCompositor());
1068 EXPECT_EQ(NULL, l2->GetCompositor());
1071 // Checks that compositor observers are notified when:
1072 // - DrawTree is called,
1073 // - After ScheduleDraw is called, or
1074 // - Whenever SetBounds, SetOpacity or SetTransform are called.
1075 // TODO(vollick): could be reorganized into compositor_unittest.cc
1076 TEST_F(LayerWithRealCompositorTest, CompositorObservers) {
1077 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
1078 gfx::Rect(20, 20, 400, 400)));
1079 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
1080 gfx::Rect(10, 10, 350, 350)));
1081 l1->Add(l2.get());
1082 TestCompositorObserver observer;
1083 GetCompositor()->AddObserver(&observer);
1085 // Explicitly called DrawTree should cause the observers to be notified.
1086 // NOTE: this call to DrawTree sets l1 to be the compositor's root layer.
1087 DrawTree(l1.get());
1088 EXPECT_TRUE(observer.notified());
1090 // ScheduleDraw without any visible change should cause a commit.
1091 observer.Reset();
1092 l1->ScheduleDraw();
1093 WaitForCommit();
1094 EXPECT_TRUE(observer.committed());
1096 // Moving, but not resizing, a layer should alert the observers.
1097 observer.Reset();
1098 l2->SetBounds(gfx::Rect(0, 0, 350, 350));
1099 WaitForSwap();
1100 EXPECT_TRUE(observer.notified());
1102 // So should resizing a layer.
1103 observer.Reset();
1104 l2->SetBounds(gfx::Rect(0, 0, 400, 400));
1105 WaitForSwap();
1106 EXPECT_TRUE(observer.notified());
1108 // Opacity changes should alert the observers.
1109 observer.Reset();
1110 l2->SetOpacity(0.5f);
1111 WaitForSwap();
1112 EXPECT_TRUE(observer.notified());
1114 // So should setting the opacity back.
1115 observer.Reset();
1116 l2->SetOpacity(1.0f);
1117 WaitForSwap();
1118 EXPECT_TRUE(observer.notified());
1120 // Setting the transform of a layer should alert the observers.
1121 observer.Reset();
1122 gfx::Transform transform;
1123 transform.Translate(200.0, 200.0);
1124 transform.Rotate(90.0);
1125 transform.Translate(-200.0, -200.0);
1126 l2->SetTransform(transform);
1127 WaitForSwap();
1128 EXPECT_TRUE(observer.notified());
1130 // A change resulting in an aborted swap buffer should alert the observer
1131 // and also signal an abort.
1132 observer.Reset();
1133 l2->SetOpacity(0.1f);
1134 GetCompositor()->DidAbortSwapBuffers();
1135 WaitForSwap();
1136 EXPECT_TRUE(observer.notified());
1137 EXPECT_TRUE(observer.aborted());
1139 GetCompositor()->RemoveObserver(&observer);
1141 // Opacity changes should no longer alert the removed observer.
1142 observer.Reset();
1143 l2->SetOpacity(0.5f);
1144 WaitForSwap();
1146 EXPECT_FALSE(observer.notified());
1149 // Checks that modifying the hierarchy correctly affects final composite.
1150 TEST_F(LayerWithRealCompositorTest, ModifyHierarchy) {
1151 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
1153 // l0
1154 // +-l11
1155 // | +-l21
1156 // +-l12
1157 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
1158 gfx::Rect(0, 0, 50, 50)));
1159 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
1160 gfx::Rect(0, 0, 25, 25)));
1161 scoped_ptr<Layer> l21(CreateColorLayer(SK_ColorMAGENTA,
1162 gfx::Rect(0, 0, 15, 15)));
1163 scoped_ptr<Layer> l12(CreateColorLayer(SK_ColorBLUE,
1164 gfx::Rect(10, 10, 25, 25)));
1166 base::FilePath ref_img1 =
1167 test_data_directory().AppendASCII("ModifyHierarchy1.png");
1168 base::FilePath ref_img2 =
1169 test_data_directory().AppendASCII("ModifyHierarchy2.png");
1170 SkBitmap bitmap;
1172 l0->Add(l11.get());
1173 l11->Add(l21.get());
1174 l0->Add(l12.get());
1175 DrawTree(l0.get());
1176 ReadPixels(&bitmap);
1177 ASSERT_FALSE(bitmap.empty());
1178 // WritePNGFile(bitmap, ref_img1);
1179 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1181 l0->StackAtTop(l11.get());
1182 DrawTree(l0.get());
1183 ReadPixels(&bitmap);
1184 ASSERT_FALSE(bitmap.empty());
1185 // WritePNGFile(bitmap, ref_img2);
1186 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1188 // should restore to original configuration
1189 l0->StackAbove(l12.get(), l11.get());
1190 DrawTree(l0.get());
1191 ReadPixels(&bitmap);
1192 ASSERT_FALSE(bitmap.empty());
1193 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1195 // l11 back to front
1196 l0->StackAtTop(l11.get());
1197 DrawTree(l0.get());
1198 ReadPixels(&bitmap);
1199 ASSERT_FALSE(bitmap.empty());
1200 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1202 // should restore to original configuration
1203 l0->StackAbove(l12.get(), l11.get());
1204 DrawTree(l0.get());
1205 ReadPixels(&bitmap);
1206 ASSERT_FALSE(bitmap.empty());
1207 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1209 // l11 back to front
1210 l0->StackAbove(l11.get(), l12.get());
1211 DrawTree(l0.get());
1212 ReadPixels(&bitmap);
1213 ASSERT_FALSE(bitmap.empty());
1214 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1217 // Opacity is rendered correctly.
1218 // Checks that modifying the hierarchy correctly affects final composite.
1219 TEST_F(LayerWithRealCompositorTest, Opacity) {
1220 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
1222 // l0
1223 // +-l11
1224 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
1225 gfx::Rect(0, 0, 50, 50)));
1226 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
1227 gfx::Rect(0, 0, 25, 25)));
1229 base::FilePath ref_img = test_data_directory().AppendASCII("Opacity.png");
1231 l11->SetOpacity(0.75);
1232 l0->Add(l11.get());
1233 DrawTree(l0.get());
1234 SkBitmap bitmap;
1235 ReadPixels(&bitmap);
1236 ASSERT_FALSE(bitmap.empty());
1237 // WritePNGFile(bitmap, ref_img);
1238 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true)));
1241 namespace {
1243 class SchedulePaintLayerDelegate : public LayerDelegate {
1244 public:
1245 SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {}
1247 ~SchedulePaintLayerDelegate() override {}
1249 void set_layer(Layer* layer) {
1250 layer_ = layer;
1251 layer_->set_delegate(this);
1254 void SetSchedulePaintRect(const gfx::Rect& rect) {
1255 schedule_paint_rect_ = rect;
1258 int GetPaintCountAndClear() {
1259 int value = paint_count_;
1260 paint_count_ = 0;
1261 return value;
1264 const gfx::Rect& last_clip_rect() const { return last_clip_rect_; }
1266 private:
1267 // Overridden from LayerDelegate:
1268 void OnPaintLayer(const ui::PaintContext& context) override {
1269 paint_count_++;
1270 if (!schedule_paint_rect_.IsEmpty()) {
1271 layer_->SchedulePaint(schedule_paint_rect_);
1272 schedule_paint_rect_ = gfx::Rect();
1274 last_clip_rect_ = context.InvalidationForTesting();
1277 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
1279 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
1281 base::Closure PrepareForLayerBoundsChange() override {
1282 return base::Closure();
1285 int paint_count_;
1286 Layer* layer_;
1287 gfx::Rect schedule_paint_rect_;
1288 gfx::Rect last_clip_rect_;
1290 DISALLOW_COPY_AND_ASSIGN(SchedulePaintLayerDelegate);
1293 } // namespace
1295 // Verifies that if SchedulePaint is invoked during painting the layer is still
1296 // marked dirty.
1297 TEST_F(LayerWithDelegateTest, SchedulePaintFromOnPaintLayer) {
1298 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorRED,
1299 gfx::Rect(0, 0, 500, 500)));
1300 SchedulePaintLayerDelegate child_delegate;
1301 scoped_ptr<Layer> child(CreateColorLayer(SK_ColorBLUE,
1302 gfx::Rect(0, 0, 200, 200)));
1303 child_delegate.set_layer(child.get());
1305 root->Add(child.get());
1307 SchedulePaintForLayer(root.get());
1308 DrawTree(root.get());
1309 child->SchedulePaint(gfx::Rect(0, 0, 20, 20));
1310 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1312 // Set a rect so that when OnPaintLayer() is invoked SchedulePaint is invoked
1313 // again.
1314 child_delegate.SetSchedulePaintRect(gfx::Rect(10, 10, 30, 30));
1315 WaitForCommit();
1316 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1318 // Because SchedulePaint() was invoked from OnPaintLayer() |child| should
1319 // still need to be painted.
1320 WaitForCommit();
1321 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1322 EXPECT_TRUE(child_delegate.last_clip_rect().Contains(
1323 gfx::Rect(10, 10, 30, 30)));
1326 TEST_F(LayerWithRealCompositorTest, ScaleUpDown) {
1327 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1328 gfx::Rect(10, 20, 200, 220)));
1329 TestLayerDelegate root_delegate;
1330 root_delegate.AddColor(SK_ColorWHITE);
1331 root->set_delegate(&root_delegate);
1332 root_delegate.set_layer_bounds(root->bounds());
1334 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1335 gfx::Rect(10, 20, 140, 180)));
1336 TestLayerDelegate l1_delegate;
1337 l1_delegate.AddColor(SK_ColorWHITE);
1338 l1->set_delegate(&l1_delegate);
1339 l1_delegate.set_layer_bounds(l1->bounds());
1341 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1342 GetCompositor()->SetRootLayer(root.get());
1343 root->Add(l1.get());
1344 WaitForDraw();
1346 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1347 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1348 gfx::Size cc_bounds_size = root->cc_layer_for_testing()->bounds();
1349 EXPECT_EQ("200x220", cc_bounds_size.ToString());
1350 cc_bounds_size = l1->cc_layer_for_testing()->bounds();
1351 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1352 // No scale change, so no scale notification.
1353 EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
1354 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1356 // Scale up to 2.0. Changing scale doesn't change the bounds in DIP.
1357 GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1358 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1359 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1360 // CC layer should still match the UI layer bounds.
1361 cc_bounds_size = root->cc_layer_for_testing()->bounds();
1362 EXPECT_EQ("200x220", cc_bounds_size.ToString());
1363 cc_bounds_size = l1->cc_layer_for_testing()->bounds();
1364 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1365 // New scale factor must have been notified. Make sure painting happens at
1366 // right scale.
1367 EXPECT_EQ(2.0f, root_delegate.device_scale_factor());
1368 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1370 // Scale down back to 1.0f.
1371 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1372 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1373 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1374 // CC layer should still match the UI layer bounds.
1375 cc_bounds_size = root->cc_layer_for_testing()->bounds();
1376 EXPECT_EQ("200x220", cc_bounds_size.ToString());
1377 cc_bounds_size = l1->cc_layer_for_testing()->bounds();
1378 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1379 // New scale factor must have been notified. Make sure painting happens at
1380 // right scale.
1381 EXPECT_EQ(1.0f, root_delegate.device_scale_factor());
1382 EXPECT_EQ(1.0f, l1_delegate.device_scale_factor());
1384 root_delegate.reset();
1385 l1_delegate.reset();
1386 // Just changing the size shouldn't notify the scale change nor
1387 // trigger repaint.
1388 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(1000, 1000));
1389 // No scale change, so no scale notification.
1390 EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
1391 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1394 TEST_F(LayerWithRealCompositorTest, ScaleReparent) {
1395 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1396 gfx::Rect(10, 20, 200, 220)));
1397 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1398 gfx::Rect(10, 20, 140, 180)));
1399 TestLayerDelegate l1_delegate;
1400 l1_delegate.AddColor(SK_ColorWHITE);
1401 l1->set_delegate(&l1_delegate);
1402 l1_delegate.set_layer_bounds(l1->bounds());
1404 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1405 GetCompositor()->SetRootLayer(root.get());
1407 root->Add(l1.get());
1408 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1409 gfx::Size cc_bounds_size = l1->cc_layer_for_testing()->bounds();
1410 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1411 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1413 // Remove l1 from root and change the scale.
1414 root->Remove(l1.get());
1415 EXPECT_EQ(NULL, l1->parent());
1416 EXPECT_EQ(NULL, l1->GetCompositor());
1417 GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1418 // Sanity check on root and l1.
1419 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1420 cc_bounds_size = l1->cc_layer_for_testing()->bounds();
1421 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1423 root->Add(l1.get());
1424 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1425 cc_bounds_size = l1->cc_layer_for_testing()->bounds();
1426 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1427 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1430 // Verifies that when changing bounds on a layer that is invisible, and then
1431 // made visible, the right thing happens:
1432 // - if just a move, then no painting should happen.
1433 // - if a resize, the layer should be repainted.
1434 TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) {
1435 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1437 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1438 child->SetBounds(gfx::Rect(0, 0, 500, 500));
1439 DrawTreeLayerDelegate delegate(child->bounds());
1440 child->set_delegate(&delegate);
1441 root->Add(child.get());
1443 // Paint once for initial damage.
1444 child->SetVisible(true);
1445 DrawTree(root.get());
1447 // Reset into invisible state.
1448 child->SetVisible(false);
1449 DrawTree(root.get());
1450 delegate.Reset();
1452 // Move layer.
1453 child->SetBounds(gfx::Rect(200, 200, 500, 500));
1454 child->SetVisible(true);
1455 DrawTree(root.get());
1456 EXPECT_FALSE(delegate.painted());
1458 // Reset into invisible state.
1459 child->SetVisible(false);
1460 DrawTree(root.get());
1461 delegate.Reset();
1463 // Resize layer.
1464 child->SetBounds(gfx::Rect(200, 200, 400, 400));
1465 child->SetVisible(true);
1466 DrawTree(root.get());
1467 EXPECT_TRUE(delegate.painted());
1470 static scoped_ptr<cc::DelegatedFrameData> MakeFrameData(gfx::Size size) {
1471 scoped_ptr<cc::DelegatedFrameData> frame_data(new cc::DelegatedFrameData);
1472 scoped_ptr<cc::RenderPass> render_pass(cc::RenderPass::Create());
1473 render_pass->SetNew(
1474 cc::RenderPassId(1, 1), gfx::Rect(size), gfx::Rect(), gfx::Transform());
1475 frame_data->render_pass_list.push_back(render_pass.Pass());
1476 return frame_data.Pass();
1479 TEST_F(LayerWithDelegateTest, DelegatedLayer) {
1480 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1482 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1484 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1485 child->SetVisible(true);
1486 root->Add(child.get());
1487 DrawTree(root.get());
1489 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1490 new cc::DelegatedFrameResourceCollection;
1491 scoped_refptr<cc::DelegatedFrameProvider> frame_provider;
1493 // Content matches layer size.
1494 frame_provider = new cc::DelegatedFrameProvider(
1495 resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
1496 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1497 EXPECT_EQ(child->cc_layer_for_testing()->bounds().ToString(),
1498 gfx::Size(10, 10).ToString());
1500 // Content larger than layer.
1501 child->SetBounds(gfx::Rect(0, 0, 5, 5));
1502 EXPECT_EQ(child->cc_layer_for_testing()->bounds().ToString(),
1503 gfx::Size(5, 5).ToString());
1505 // Content smaller than layer.
1506 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1507 frame_provider = new cc::DelegatedFrameProvider(
1508 resource_collection.get(), MakeFrameData(gfx::Size(5, 5)));
1509 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(5, 5));
1510 EXPECT_EQ(child->cc_layer_for_testing()->bounds().ToString(),
1511 gfx::Size(5, 5).ToString());
1513 // Hi-DPI content on low-DPI layer.
1514 frame_provider = new cc::DelegatedFrameProvider(
1515 resource_collection.get(), MakeFrameData(gfx::Size(20, 20)));
1516 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1517 EXPECT_EQ(child->cc_layer_for_testing()->bounds().ToString(),
1518 gfx::Size(10, 10).ToString());
1520 // Hi-DPI content on hi-DPI layer.
1521 compositor()->SetScaleAndSize(2.f, gfx::Size(1000, 1000));
1522 EXPECT_EQ(child->cc_layer_for_testing()->bounds().ToString(),
1523 gfx::Size(10, 10).ToString());
1525 // Low-DPI content on hi-DPI layer.
1526 frame_provider = new cc::DelegatedFrameProvider(
1527 resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
1528 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1529 EXPECT_EQ(child->cc_layer_for_testing()->bounds().ToString(),
1530 gfx::Size(10, 10).ToString());
1533 TEST_F(LayerWithDelegateTest, ExternalContent) {
1534 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1535 scoped_ptr<Layer> child(CreateLayer(LAYER_SOLID_COLOR));
1537 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1538 child->SetVisible(true);
1539 root->Add(child.get());
1541 // The layer is already showing solid color content, so the cc layer won't
1542 // change.
1543 scoped_refptr<cc::Layer> before = child->cc_layer_for_testing();
1544 child->SetShowSolidColorContent();
1545 EXPECT_TRUE(child->cc_layer_for_testing());
1546 EXPECT_EQ(before.get(), child->cc_layer_for_testing());
1548 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1549 new cc::DelegatedFrameResourceCollection;
1550 scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
1551 new cc::DelegatedFrameProvider(resource_collection.get(),
1552 MakeFrameData(gfx::Size(10, 10)));
1554 // Showing delegated content changes the underlying cc layer.
1555 before = child->cc_layer_for_testing();
1556 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1557 EXPECT_TRUE(child->cc_layer_for_testing());
1558 EXPECT_NE(before.get(), child->cc_layer_for_testing());
1560 // Changing to painted content should change the underlying cc layer.
1561 before = child->cc_layer_for_testing();
1562 child->SetShowSolidColorContent();
1563 EXPECT_TRUE(child->cc_layer_for_testing());
1564 EXPECT_NE(before.get(), child->cc_layer_for_testing());
1567 // Verifies that layer filters still attached after changing implementation
1568 // layer.
1569 TEST_F(LayerWithDelegateTest, LayerFiltersSurvival) {
1570 scoped_ptr<Layer> layer(CreateLayer(LAYER_TEXTURED));
1571 layer->SetBounds(gfx::Rect(0, 0, 10, 10));
1572 EXPECT_TRUE(layer->cc_layer_for_testing());
1573 EXPECT_EQ(0u, layer->cc_layer_for_testing()->filters().size());
1575 layer->SetLayerGrayscale(0.5f);
1576 EXPECT_EQ(layer->layer_grayscale(), 0.5f);
1577 EXPECT_EQ(1u, layer->cc_layer_for_testing()->filters().size());
1579 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1580 new cc::DelegatedFrameResourceCollection;
1581 scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
1582 new cc::DelegatedFrameProvider(resource_collection.get(),
1583 MakeFrameData(gfx::Size(10, 10)));
1585 // Showing delegated content changes the underlying cc layer.
1586 scoped_refptr<cc::Layer> before = layer->cc_layer_for_testing();
1587 layer->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1588 EXPECT_EQ(layer->layer_grayscale(), 0.5f);
1589 EXPECT_TRUE(layer->cc_layer_for_testing());
1590 EXPECT_NE(before.get(), layer->cc_layer_for_testing());
1591 EXPECT_EQ(1u, layer->cc_layer_for_testing()->filters().size());
1594 // Tests Layer::AddThreadedAnimation and Layer::RemoveThreadedAnimation.
1595 TEST_F(LayerWithRealCompositorTest, AddRemoveThreadedAnimations) {
1596 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1597 scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
1598 scoped_ptr<Layer> l2(CreateLayer(LAYER_TEXTURED));
1600 l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1601 l2->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1603 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1605 // Trigger a threaded animation.
1606 l1->SetOpacity(0.5f);
1608 EXPECT_TRUE(l1->HasPendingThreadedAnimations());
1610 // Ensure we can remove a pending threaded animation.
1611 l1->GetAnimator()->StopAnimating();
1613 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1615 // Trigger another threaded animation.
1616 l1->SetOpacity(0.2f);
1618 EXPECT_TRUE(l1->HasPendingThreadedAnimations());
1620 root->Add(l1.get());
1621 GetCompositor()->SetRootLayer(root.get());
1623 // Now that l1 is part of a tree, it should have dispatched the pending
1624 // animation.
1625 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1627 // Ensure that l1 no longer holds on to animations.
1628 l1->SetOpacity(0.1f);
1629 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1631 // Ensure that adding a layer to an existing tree causes its pending
1632 // animations to get dispatched.
1633 l2->SetOpacity(0.5f);
1634 EXPECT_TRUE(l2->HasPendingThreadedAnimations());
1636 l1->Add(l2.get());
1637 EXPECT_FALSE(l2->HasPendingThreadedAnimations());
1640 // Tests that in-progress threaded animations complete when a Layer's
1641 // cc::Layer changes.
1642 TEST_F(LayerWithRealCompositorTest, SwitchCCLayerAnimations) {
1643 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1644 scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
1645 GetCompositor()->SetRootLayer(root.get());
1646 root->Add(l1.get());
1648 l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1650 EXPECT_FLOAT_EQ(l1->opacity(), 1.0f);
1652 // Trigger a threaded animation.
1653 l1->SetOpacity(0.5f);
1655 // Change l1's cc::Layer.
1656 l1->SwitchCCLayerForTest();
1658 // Ensure that the opacity animation completed.
1659 EXPECT_FLOAT_EQ(l1->opacity(), 0.5f);
1662 // Tests that when a LAYER_SOLID_COLOR has its CC layer switched, that
1663 // opaqueness and color set while not animating, are maintained.
1664 TEST_F(LayerWithRealCompositorTest, SwitchCCLayerSolidColorNotAnimating) {
1665 SkColor transparent = SK_ColorTRANSPARENT;
1666 scoped_ptr<Layer> root(CreateLayer(LAYER_SOLID_COLOR));
1667 GetCompositor()->SetRootLayer(root.get());
1668 root->SetFillsBoundsOpaquely(false);
1669 root->SetColor(transparent);
1671 EXPECT_FALSE(root->fills_bounds_opaquely());
1672 EXPECT_FALSE(
1673 root->GetAnimator()->IsAnimatingProperty(LayerAnimationElement::COLOR));
1674 EXPECT_EQ(transparent, root->background_color());
1675 EXPECT_EQ(transparent, root->GetTargetColor());
1677 // Changing the underlying layer should not affect targets.
1678 root->SwitchCCLayerForTest();
1680 EXPECT_FALSE(root->fills_bounds_opaquely());
1681 EXPECT_FALSE(
1682 root->GetAnimator()->IsAnimatingProperty(LayerAnimationElement::COLOR));
1683 EXPECT_EQ(transparent, root->background_color());
1684 EXPECT_EQ(transparent, root->GetTargetColor());
1687 // Tests that when a LAYER_SOLID_COLOR has its CC layer switched during an
1688 // animation of its opaquness and color, that both the current values, and the
1689 // targets are maintained.
1690 TEST_F(LayerWithRealCompositorTest, SwitchCCLayerSolidColorWhileAnimating) {
1691 SkColor transparent = SK_ColorTRANSPARENT;
1692 scoped_ptr<Layer> root(CreateLayer(LAYER_SOLID_COLOR));
1693 GetCompositor()->SetRootLayer(root.get());
1694 root->SetColor(SK_ColorBLACK);
1696 EXPECT_TRUE(root->fills_bounds_opaquely());
1697 EXPECT_EQ(SK_ColorBLACK, root->GetTargetColor());
1699 scoped_ptr<ui::ScopedAnimationDurationScaleMode> long_duration_animation(
1700 new ui::ScopedAnimationDurationScaleMode(
1701 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION));
1703 ui::ScopedLayerAnimationSettings animation(root->GetAnimator());
1704 animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
1705 root->SetFillsBoundsOpaquely(false);
1706 root->SetColor(transparent);
1709 EXPECT_TRUE(root->fills_bounds_opaquely());
1710 EXPECT_TRUE(
1711 root->GetAnimator()->IsAnimatingProperty(LayerAnimationElement::COLOR));
1712 EXPECT_EQ(SK_ColorBLACK, root->background_color());
1713 EXPECT_EQ(transparent, root->GetTargetColor());
1715 // Changing the underlying layer should not affect targets.
1716 root->SwitchCCLayerForTest();
1718 EXPECT_TRUE(root->fills_bounds_opaquely());
1719 EXPECT_TRUE(
1720 root->GetAnimator()->IsAnimatingProperty(LayerAnimationElement::COLOR));
1721 EXPECT_EQ(SK_ColorBLACK, root->background_color());
1722 EXPECT_EQ(transparent, root->GetTargetColor());
1724 // End all animations.
1725 root->GetAnimator()->StopAnimating();
1726 EXPECT_FALSE(root->fills_bounds_opaquely());
1727 EXPECT_FALSE(
1728 root->GetAnimator()->IsAnimatingProperty(LayerAnimationElement::COLOR));
1729 EXPECT_EQ(transparent, root->background_color());
1730 EXPECT_EQ(transparent, root->GetTargetColor());
1733 // Tests that the animators in the layer tree is added to the
1734 // animator-collection when the root-layer is set to the compositor.
1735 TEST_F(LayerWithDelegateTest, RootLayerAnimatorsInCompositor) {
1736 scoped_ptr<Layer> root(CreateLayer(LAYER_SOLID_COLOR));
1737 scoped_ptr<Layer> child(CreateColorLayer(SK_ColorRED, gfx::Rect(10, 10)));
1738 child->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1739 child->SetOpacity(0.5f);
1740 root->Add(child.get());
1742 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
1743 compositor()->SetRootLayer(root.get());
1744 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1747 // Tests that adding/removing a layer adds/removes the animator from its entire
1748 // subtree from the compositor's animator-collection.
1749 TEST_F(LayerWithDelegateTest, AddRemoveLayerUpdatesAnimatorsFromSubtree) {
1750 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1751 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1752 scoped_ptr<Layer> grandchild(CreateColorLayer(SK_ColorRED,
1753 gfx::Rect(10, 10)));
1754 root->Add(child.get());
1755 child->Add(grandchild.get());
1756 compositor()->SetRootLayer(root.get());
1758 grandchild->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1759 grandchild->SetOpacity(0.5f);
1760 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1762 root->Remove(child.get());
1763 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
1765 root->Add(child.get());
1766 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1769 TEST_F(LayerWithDelegateTest, DestroyingLayerRemovesTheAnimatorFromCollection) {
1770 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1771 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1772 root->Add(child.get());
1773 compositor()->SetRootLayer(root.get());
1775 child->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1776 child->SetOpacity(0.5f);
1777 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1779 child.reset();
1780 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
1783 namespace {
1785 std::string Vector2dFTo100thPercisionString(const gfx::Vector2dF& vector) {
1786 return base::StringPrintf("%.2f %0.2f", vector.x(), vector.y());
1789 } // namespace
1791 TEST_F(LayerWithRealCompositorTest, SnapLayerToPixels) {
1792 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1793 scoped_ptr<Layer> c1(CreateLayer(LAYER_TEXTURED));
1794 scoped_ptr<Layer> c11(CreateLayer(LAYER_TEXTURED));
1796 GetCompositor()->SetScaleAndSize(1.25f, gfx::Size(100, 100));
1797 GetCompositor()->SetRootLayer(root.get());
1798 root->Add(c1.get());
1799 c1->Add(c11.get());
1801 root->SetBounds(gfx::Rect(0, 0, 100, 100));
1802 c1->SetBounds(gfx::Rect(1, 1, 10, 10));
1803 c11->SetBounds(gfx::Rect(1, 1, 10, 10));
1804 SnapLayerToPhysicalPixelBoundary(root.get(), c11.get());
1805 // 0.5 at 1.25 scale : (1 - 0.25 + 0.25) / 1.25 = 0.4
1806 EXPECT_EQ("0.40 0.40",
1807 Vector2dFTo100thPercisionString(c11->subpixel_position_offset()));
1809 GetCompositor()->SetScaleAndSize(1.5f, gfx::Size(100, 100));
1810 SnapLayerToPhysicalPixelBoundary(root.get(), c11.get());
1811 // c11 must already be aligned at 1.5 scale.
1812 EXPECT_EQ("0.00 0.00",
1813 Vector2dFTo100thPercisionString(c11->subpixel_position_offset()));
1815 c11->SetBounds(gfx::Rect(2, 2, 10, 10));
1816 SnapLayerToPhysicalPixelBoundary(root.get(), c11.get());
1817 // c11 is now off the pixel.
1818 // 0.5 / 1.5 = 0.333...
1819 EXPECT_EQ("0.33 0.33",
1820 Vector2dFTo100thPercisionString(c11->subpixel_position_offset()));
1823 class FrameDamageCheckingDelegate : public TestLayerDelegate {
1824 public:
1825 FrameDamageCheckingDelegate() : delegated_frame_damage_called_(false) {}
1827 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {
1828 delegated_frame_damage_called_ = true;
1829 delegated_frame_damage_rect_ = damage_rect_in_dip;
1832 const gfx::Rect& delegated_frame_damage_rect() const {
1833 return delegated_frame_damage_rect_;
1835 bool delegated_frame_damage_called() const {
1836 return delegated_frame_damage_called_;
1839 private:
1840 gfx::Rect delegated_frame_damage_rect_;
1841 bool delegated_frame_damage_called_;
1843 DISALLOW_COPY_AND_ASSIGN(FrameDamageCheckingDelegate);
1846 TEST(LayerDelegateTest, DelegatedFrameDamage) {
1847 scoped_ptr<Layer> layer(new Layer(LAYER_TEXTURED));
1848 gfx::Rect damage_rect(2, 1, 5, 3);
1850 FrameDamageCheckingDelegate delegate;
1851 layer->set_delegate(&delegate);
1852 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1853 new cc::DelegatedFrameResourceCollection;
1854 scoped_refptr<cc::DelegatedFrameProvider> frame_provider(
1855 new cc::DelegatedFrameProvider(resource_collection.get(),
1856 MakeFrameData(gfx::Size(10, 10))));
1857 layer->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1859 EXPECT_FALSE(delegate.delegated_frame_damage_called());
1860 layer->OnDelegatedFrameDamage(damage_rect);
1861 EXPECT_TRUE(delegate.delegated_frame_damage_called());
1862 EXPECT_EQ(damage_rect, delegate.delegated_frame_damage_rect());
1865 TEST_F(LayerWithRealCompositorTest, CompositorAnimationObserverTest) {
1866 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1868 root->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1870 TestCompositorAnimationObserver animation_observer(GetCompositor());
1871 EXPECT_EQ(0u, animation_observer.animation_step_count());
1873 root->SetOpacity(0.5f);
1874 WaitForSwap();
1875 EXPECT_EQ(1u, animation_observer.animation_step_count());
1877 EXPECT_FALSE(animation_observer.shutdown());
1878 ResetCompositor();
1879 EXPECT_TRUE(animation_observer.shutdown());
1882 } // namespace ui