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