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