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