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