OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/layers/scrollbar_layer.h" | 5 #include "cc/layers/scrollbar_layer.h" |
6 | 6 |
| 7 #include "base/containers/hash_tables.h" |
7 #include "cc/animation/scrollbar_animation_controller.h" | 8 #include "cc/animation/scrollbar_animation_controller.h" |
8 #include "cc/layers/append_quads_data.h" | 9 #include "cc/layers/append_quads_data.h" |
9 #include "cc/layers/scrollbar_layer_impl.h" | 10 #include "cc/layers/scrollbar_layer_impl.h" |
10 #include "cc/quads/solid_color_draw_quad.h" | 11 #include "cc/quads/solid_color_draw_quad.h" |
11 #include "cc/resources/prioritized_resource_manager.h" | 12 #include "cc/resources/prioritized_resource_manager.h" |
12 #include "cc/resources/priority_calculator.h" | 13 #include "cc/resources/priority_calculator.h" |
13 #include "cc/resources/resource_update_queue.h" | 14 #include "cc/resources/resource_update_queue.h" |
14 #include "cc/test/fake_impl_proxy.h" | 15 #include "cc/test/fake_impl_proxy.h" |
15 #include "cc/test/fake_layer_tree_host.h" | 16 #include "cc/test/fake_layer_tree_host.h" |
16 #include "cc/test/fake_layer_tree_host_client.h" | 17 #include "cc/test/fake_layer_tree_host_client.h" |
17 #include "cc/test/fake_layer_tree_host_impl.h" | 18 #include "cc/test/fake_layer_tree_host_impl.h" |
18 #include "cc/test/fake_scrollbar.h" | 19 #include "cc/test/fake_scrollbar.h" |
19 #include "cc/test/geometry_test_utils.h" | 20 #include "cc/test/geometry_test_utils.h" |
20 #include "cc/test/layer_tree_test.h" | 21 #include "cc/test/layer_tree_test.h" |
21 #include "cc/test/mock_quad_culler.h" | 22 #include "cc/test/mock_quad_culler.h" |
22 #include "cc/test/test_web_graphics_context_3d.h" | 23 #include "cc/test/test_web_graphics_context_3d.h" |
| 24 #include "cc/trees/layer_tree_host.h" |
23 #include "cc/trees/layer_tree_impl.h" | 25 #include "cc/trees/layer_tree_impl.h" |
24 #include "cc/trees/single_thread_proxy.h" | 26 #include "cc/trees/single_thread_proxy.h" |
25 #include "cc/trees/tree_synchronizer.h" | 27 #include "cc/trees/tree_synchronizer.h" |
26 #include "testing/gmock/include/gmock/gmock.h" | 28 #include "testing/gmock/include/gmock/gmock.h" |
27 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
28 | 30 |
29 namespace cc { | 31 namespace cc { |
30 namespace { | 32 namespace { |
31 | 33 |
32 LayerImpl* LayerImplForScrollAreaAndScrollbar( | 34 LayerImpl* LayerImplForScrollAreaAndScrollbar( |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 int max_size = 0; | 396 int max_size = 0; |
395 context->getIntegerv(GL_MAX_TEXTURE_SIZE, &max_size); | 397 context->getIntegerv(GL_MAX_TEXTURE_SIZE, &max_size); |
396 SetScrollbarBounds(gfx::Size(max_size + 100, max_size + 100)); | 398 SetScrollbarBounds(gfx::Size(max_size + 100, max_size + 100)); |
397 RunTest(true, true, true); | 399 RunTest(true, true, true); |
398 } | 400 } |
399 | 401 |
400 class MockLayerTreeHost : public LayerTreeHost { | 402 class MockLayerTreeHost : public LayerTreeHost { |
401 public: | 403 public: |
402 MockLayerTreeHost(LayerTreeHostClient* client, | 404 MockLayerTreeHost(LayerTreeHostClient* client, |
403 const LayerTreeSettings& settings) | 405 const LayerTreeSettings& settings) |
404 : LayerTreeHost(client, settings) { | 406 : LayerTreeHost(client, settings), |
| 407 next_id_(1), |
| 408 total_ui_resource_created_(0), |
| 409 total_ui_resource_deleted_(0) { |
405 Initialize(NULL); | 410 Initialize(NULL); |
406 } | 411 } |
| 412 |
| 413 virtual UIResourceId CreateUIResource(UIResourceClient* content) OVERRIDE { |
| 414 total_ui_resource_created_++; |
| 415 UIResourceId nid = next_id_++; |
| 416 ui_resource_id_set_.insert(nid); |
| 417 return nid; |
| 418 } |
| 419 |
| 420 // Deletes a UI resource. May safely be called more than once. |
| 421 virtual void DeleteUIResource(UIResourceId id) OVERRIDE { |
| 422 UIResourceIdSet::iterator iter = ui_resource_id_set_.find(id); |
| 423 if (iter != ui_resource_id_set_.end()) { |
| 424 ui_resource_id_set_.erase(iter); |
| 425 total_ui_resource_deleted_++; |
| 426 } |
| 427 } |
| 428 |
| 429 size_t UIResourceCount() { return ui_resource_id_set_.size(); } |
| 430 int TotalUIResourceDeleted() { return total_ui_resource_deleted_; } |
| 431 int TotalUIResourceCreated() { return total_ui_resource_created_; } |
| 432 |
| 433 private: |
| 434 typedef base::hash_set<UIResourceId> UIResourceIdSet; |
| 435 UIResourceIdSet ui_resource_id_set_; |
| 436 int next_id_; |
| 437 int total_ui_resource_created_; |
| 438 int total_ui_resource_deleted_; |
407 }; | 439 }; |
408 | 440 |
409 | 441 |
410 class ScrollbarLayerTestResourceCreation : public testing::Test { | 442 class ScrollbarLayerTestResourceCreation : public testing::Test { |
411 public: | 443 public: |
412 ScrollbarLayerTestResourceCreation() | 444 ScrollbarLayerTestResourceCreation() |
413 : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {} | 445 : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {} |
414 | 446 |
415 void TestResourceUpload(size_t expected_resources) { | 447 void TestResourceUpload(int num_updates, |
| 448 size_t expected_resources, |
| 449 int expected_created, |
| 450 int expected_deleted) { |
416 layer_tree_host_.reset( | 451 layer_tree_host_.reset( |
417 new MockLayerTreeHost(&fake_client_, layer_tree_settings_)); | 452 new MockLayerTreeHost(&fake_client_, layer_tree_settings_)); |
418 | 453 |
419 scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, false)); | 454 scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, false)); |
420 scoped_refptr<Layer> layer_tree_root = Layer::Create(); | 455 scoped_refptr<Layer> layer_tree_root = Layer::Create(); |
421 scoped_refptr<Layer> content_layer = Layer::Create(); | 456 scoped_refptr<Layer> content_layer = Layer::Create(); |
422 scoped_refptr<Layer> scrollbar_layer = | 457 scoped_refptr<Layer> scrollbar_layer = |
423 ScrollbarLayer::Create(scrollbar.Pass(), layer_tree_root->id()); | 458 ScrollbarLayer::Create(scrollbar.Pass(), layer_tree_root->id()); |
424 layer_tree_root->AddChild(content_layer); | 459 layer_tree_root->AddChild(content_layer); |
425 layer_tree_root->AddChild(scrollbar_layer); | 460 layer_tree_root->AddChild(scrollbar_layer); |
(...skipping 11 matching lines...) Expand all Loading... |
437 content_layer->SetBounds(gfx::Size(100, 200)); | 472 content_layer->SetBounds(gfx::Size(100, 200)); |
438 scrollbar_layer->draw_properties().content_bounds = gfx::Size(100, 200); | 473 scrollbar_layer->draw_properties().content_bounds = gfx::Size(100, 200); |
439 scrollbar_layer->draw_properties().visible_content_rect = | 474 scrollbar_layer->draw_properties().visible_content_rect = |
440 gfx::Rect(0, 0, 100, 200); | 475 gfx::Rect(0, 0, 100, 200); |
441 scrollbar_layer->CreateRenderSurface(); | 476 scrollbar_layer->CreateRenderSurface(); |
442 scrollbar_layer->draw_properties().render_target = scrollbar_layer.get(); | 477 scrollbar_layer->draw_properties().render_target = scrollbar_layer.get(); |
443 | 478 |
444 testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); | 479 testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
445 EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get()); | 480 EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get()); |
446 | 481 |
447 PriorityCalculator calculator; | |
448 ResourceUpdateQueue queue; | 482 ResourceUpdateQueue queue; |
449 OcclusionTracker occlusion_tracker(gfx::Rect(), false); | 483 OcclusionTracker occlusion_tracker(gfx::Rect(), false); |
450 | 484 |
451 scrollbar_layer->SetTexturePriorities(calculator); | 485 for (int update_counter = 0; update_counter < num_updates; update_counter++) |
452 layer_tree_host_->contents_texture_manager()->PrioritizeTextures(); | 486 scrollbar_layer->Update(&queue, &occlusion_tracker); |
453 scrollbar_layer->Update(&queue, &occlusion_tracker); | 487 |
454 EXPECT_EQ(0u, queue.FullUploadSize()); | 488 // A non-solid-color scrollbar should have requested two textures. |
455 EXPECT_EQ(expected_resources, queue.PartialUploadSize()); | 489 // A solid-color scrollbar should have requested two textures. |
| 490 EXPECT_EQ(expected_resources, layer_tree_host_->UIResourceCount()); |
| 491 EXPECT_EQ(expected_created, layer_tree_host_->TotalUIResourceCreated()); |
| 492 EXPECT_EQ(expected_deleted, layer_tree_host_->TotalUIResourceDeleted()); |
456 | 493 |
457 testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); | 494 testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
458 | 495 |
459 scrollbar_layer->ClearRenderSurface(); | 496 scrollbar_layer->ClearRenderSurface(); |
460 } | 497 } |
461 | 498 |
462 protected: | 499 protected: |
463 FakeLayerTreeHostClient fake_client_; | 500 FakeLayerTreeHostClient fake_client_; |
464 LayerTreeSettings layer_tree_settings_; | 501 LayerTreeSettings layer_tree_settings_; |
465 scoped_ptr<MockLayerTreeHost> layer_tree_host_; | 502 scoped_ptr<MockLayerTreeHost> layer_tree_host_; |
466 }; | 503 }; |
467 | 504 |
468 TEST_F(ScrollbarLayerTestResourceCreation, ResourceUpload) { | 505 TEST_F(ScrollbarLayerTestResourceCreation, ResourceUpload) { |
469 layer_tree_settings_.solid_color_scrollbars = false; | 506 layer_tree_settings_.solid_color_scrollbars = false; |
470 TestResourceUpload(2); | 507 TestResourceUpload(0, 0, 0, 0); |
| 508 int num_updates[3] = {1, 5, 10}; |
| 509 for (int j = 0; j < 3; j++) { |
| 510 TestResourceUpload( |
| 511 num_updates[j], 2, num_updates[j] * 2, (num_updates[j] - 1) * 2); |
| 512 } |
471 } | 513 } |
472 | 514 |
473 TEST_F(ScrollbarLayerTestResourceCreation, SolidColorNoResourceUpload) { | 515 TEST_F(ScrollbarLayerTestResourceCreation, SolidColorNoResourceUpload) { |
474 layer_tree_settings_.solid_color_scrollbars = true; | 516 layer_tree_settings_.solid_color_scrollbars = true; |
475 TestResourceUpload(0); | 517 TestResourceUpload(0, 0, 0, 0); |
476 } | 518 TestResourceUpload(1, 0, 0, 0); |
477 | |
478 class ScaledScrollbarLayerTestResourceCreation : public testing::Test { | |
479 public: | |
480 ScaledScrollbarLayerTestResourceCreation() | |
481 : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {} | |
482 | |
483 void TestResourceUpload(size_t expected_resources, const float test_scale) { | |
484 layer_tree_host_.reset( | |
485 new MockLayerTreeHost(&fake_client_, layer_tree_settings_)); | |
486 | |
487 gfx::Point scrollbar_location(0, 185); | |
488 scoped_ptr<FakeScrollbar> scrollbar(new FakeScrollbar(false, true, false)); | |
489 scrollbar->set_location(scrollbar_location); | |
490 | |
491 scoped_refptr<Layer> layer_tree_root = Layer::Create(); | |
492 scoped_refptr<Layer> content_layer = Layer::Create(); | |
493 scoped_refptr<Layer> scrollbar_layer = | |
494 ScrollbarLayer::Create(scrollbar.PassAs<cc::Scrollbar>(), | |
495 layer_tree_root->id()); | |
496 layer_tree_root->AddChild(content_layer); | |
497 layer_tree_root->AddChild(scrollbar_layer); | |
498 | |
499 layer_tree_host_->InitializeOutputSurfaceIfNeeded(); | |
500 layer_tree_host_->contents_texture_manager()-> | |
501 SetMaxMemoryLimitBytes(1024 * 1024); | |
502 layer_tree_host_->SetRootLayer(layer_tree_root); | |
503 | |
504 scrollbar_layer->SetIsDrawable(true); | |
505 scrollbar_layer->SetBounds(gfx::Size(100, 15)); | |
506 scrollbar_layer->SetPosition(scrollbar_location); | |
507 layer_tree_root->SetBounds(gfx::Size(100, 200)); | |
508 content_layer->SetBounds(gfx::Size(100, 200)); | |
509 gfx::SizeF scaled_size = | |
510 gfx::ScaleSize(scrollbar_layer->bounds(), test_scale, test_scale); | |
511 gfx::PointF scaled_location = | |
512 gfx::ScalePoint(scrollbar_layer->position(), test_scale, test_scale); | |
513 scrollbar_layer->draw_properties().content_bounds = | |
514 gfx::Size(scaled_size.width(), scaled_size.height()); | |
515 scrollbar_layer->draw_properties().contents_scale_x = test_scale; | |
516 scrollbar_layer->draw_properties().contents_scale_y = test_scale; | |
517 scrollbar_layer->draw_properties().visible_content_rect = | |
518 gfx::Rect(scaled_location.x(), | |
519 scaled_location.y(), | |
520 scaled_size.width(), | |
521 scaled_size.height()); | |
522 scrollbar_layer->CreateRenderSurface(); | |
523 scrollbar_layer->draw_properties().render_target = scrollbar_layer.get(); | |
524 | |
525 testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); | |
526 EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get()); | |
527 | |
528 PriorityCalculator calculator; | |
529 ResourceUpdateQueue queue; | |
530 OcclusionTracker occlusion_tracker(gfx::Rect(), false); | |
531 | |
532 scrollbar_layer->SetTexturePriorities(calculator); | |
533 layer_tree_host_->contents_texture_manager()->PrioritizeTextures(); | |
534 scrollbar_layer->Update(&queue, &occlusion_tracker); | |
535 EXPECT_EQ(expected_resources, queue.PartialUploadSize()); | |
536 | |
537 // Verify that we have not generated any content uploads that are larger | |
538 // than their destination textures. | |
539 while (queue.HasMoreUpdates()) { | |
540 ResourceUpdate update = queue.TakeFirstPartialUpload(); | |
541 EXPECT_LE(update.texture->size().width(), | |
542 scrollbar_layer->content_bounds().width()); | |
543 EXPECT_LE(update.texture->size().height(), | |
544 scrollbar_layer->content_bounds().height()); | |
545 | |
546 EXPECT_LE(update.dest_offset.x() + update.content_rect.width(), | |
547 update.texture->size().width()); | |
548 EXPECT_LE(update.dest_offset.y() + update.content_rect.height(), | |
549 update.texture->size().height()); | |
550 } | |
551 | |
552 testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); | |
553 | |
554 scrollbar_layer->ClearRenderSurface(); | |
555 } | |
556 | |
557 protected: | |
558 FakeLayerTreeHostClient fake_client_; | |
559 LayerTreeSettings layer_tree_settings_; | |
560 scoped_ptr<MockLayerTreeHost> layer_tree_host_; | |
561 }; | |
562 | |
563 TEST_F(ScaledScrollbarLayerTestResourceCreation, ScaledResourceUpload) { | |
564 layer_tree_settings_.solid_color_scrollbars = false; | |
565 // Pick a test scale that moves the scrollbar's (non-zero) position to | |
566 // a non-pixel-aligned location. | |
567 TestResourceUpload(2, 1.41f); | |
568 } | 519 } |
569 | 520 |
570 } // namespace | 521 } // namespace |
571 } // namespace cc | 522 } // namespace cc |
OLD | NEW |