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