scrollbar_layer_unittest.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
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 3// found in the LICENSE file. 4 5#include "cc/layers/scrollbar_layer.h" 6 7#include "cc/animation/scrollbar_animation_controller.h" 8#include "cc/layers/append_quads_data.h" 9#include "cc/layers/scrollbar_layer_impl.h" 10#include "cc/quads/solid_color_draw_quad.h" 11#include "cc/resources/prioritized_resource_manager.h" 12#include "cc/resources/priority_calculator.h" 13#include "cc/resources/resource_update_queue.h" 14#include "cc/test/fake_impl_proxy.h" 15#include "cc/test/fake_layer_tree_host_client.h" 16#include "cc/test/fake_layer_tree_host_impl.h" 17#include "cc/test/fake_scrollbar.h" 18#include "cc/test/geometry_test_utils.h" 19#include "cc/test/layer_tree_test.h" 20#include "cc/test/mock_quad_culler.h" 21#include "cc/test/test_web_graphics_context_3d.h" 22#include "cc/trees/layer_tree_impl.h" 23#include "cc/trees/single_thread_proxy.h" 24#include "cc/trees/tree_synchronizer.h" 25#include "testing/gmock/include/gmock/gmock.h" 26#include "testing/gtest/include/gtest/gtest.h" 27 28namespace cc { 29namespace { 30 31scoped_ptr<LayerImpl> LayerImplForScrollAreaAndScrollbar( 32 FakeLayerTreeHostImpl* host_impl, 33 scoped_ptr<Scrollbar> scrollbar, 34 bool reverse_order) { 35 scoped_refptr<Layer> layer_tree_root = Layer::Create(); 36 scoped_refptr<Layer> child1 = Layer::Create(); 37 scoped_refptr<Layer> child2 = 38 ScrollbarLayer::Create(scrollbar.Pass(), 39 child1->id()); 40 layer_tree_root->AddChild(child1); 41 layer_tree_root->InsertChild(child2, reverse_order ? 0 : 1); 42 scoped_ptr<LayerImpl> layer_impl = 43 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 44 scoped_ptr<LayerImpl>(), 45 host_impl->active_tree()); 46 TreeSynchronizer::PushProperties(layer_tree_root.get(), layer_impl.get()); 47 return layer_impl.Pass(); 48} 49 50TEST(ScrollbarLayerTest, ResolveScrollLayerPointer) { 51 FakeImplProxy proxy; 52 FakeLayerTreeHostImpl host_impl(&proxy); 53 54 { 55 scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); 56 scoped_ptr<LayerImpl> layer_impl_tree_root = 57 LayerImplForScrollAreaAndScrollbar( 58 &host_impl, scrollbar.Pass(), false); 59 60 LayerImpl* cc_child1 = layer_impl_tree_root->children()[0]; 61 ScrollbarLayerImpl* cc_child2 = static_cast<ScrollbarLayerImpl*>( 62 layer_impl_tree_root->children()[1]); 63 64 EXPECT_EQ(cc_child1->horizontal_scrollbar_layer(), cc_child2); 65 } 66 { 67 // another traverse order 68 scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); 69 scoped_ptr<LayerImpl> layer_impl_tree_root = 70 LayerImplForScrollAreaAndScrollbar( 71 &host_impl, scrollbar.Pass(), true); 72 73 ScrollbarLayerImpl* cc_child1 = static_cast<ScrollbarLayerImpl*>( 74 layer_impl_tree_root->children()[0]); 75 LayerImpl* cc_child2 = layer_impl_tree_root->children()[1]; 76 77 EXPECT_EQ(cc_child2->horizontal_scrollbar_layer(), cc_child1); 78 } 79} 80 81TEST(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) { 82 FakeImplProxy proxy; 83 FakeLayerTreeHostImpl host_impl(&proxy); 84 85 // Create and attach a non-overlay scrollbar. 86 scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); 87 scoped_ptr<LayerImpl> layer_impl_tree_root = 88 LayerImplForScrollAreaAndScrollbar(&host_impl, scrollbar.Pass(), false); 89 ScrollbarLayerImpl* scrollbar_layer_impl = 90 static_cast<ScrollbarLayerImpl*>(layer_impl_tree_root->children()[1]); 91 92 // When the scrollbar is not an overlay scrollbar, the scroll should be 93 // responded to on the main thread as the compositor does not yet implement 94 // scrollbar scrolling. 95 EXPECT_EQ(InputHandler::ScrollOnMainThread, 96 scrollbar_layer_impl->TryScroll(gfx::Point(0, 0), 97 InputHandler::Gesture)); 98 99 // Create and attach an overlay scrollbar. 100 scrollbar.reset(new FakeScrollbar(false, false, true)); 101 102 layer_impl_tree_root = 103 LayerImplForScrollAreaAndScrollbar(&host_impl, scrollbar.Pass(), false); 104 scrollbar_layer_impl = 105 static_cast<ScrollbarLayerImpl*>(layer_impl_tree_root->children()[1]); 106 107 // The user shouldn't be able to drag an overlay scrollbar and the scroll 108 // may be handled in the compositor. 109 EXPECT_EQ(InputHandler::ScrollIgnored, 110 scrollbar_layer_impl->TryScroll(gfx::Point(0, 0), 111 InputHandler::Gesture)); 112} 113 114TEST(ScrollbarLayerTest, ScrollOffsetSynchronization) { 115 FakeImplProxy proxy; 116 FakeLayerTreeHostImpl host_impl(&proxy); 117 118 scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); 119 scoped_refptr<Layer> layer_tree_root = Layer::Create(); 120 scoped_refptr<Layer> content_layer = Layer::Create(); 121 scoped_refptr<Layer> scrollbar_layer = 122 ScrollbarLayer::Create(scrollbar.Pass(), 123 layer_tree_root->id()); 124 layer_tree_root->AddChild(content_layer); 125 layer_tree_root->AddChild(scrollbar_layer); 126 127 layer_tree_root->SetScrollOffset(gfx::Vector2d(10, 20)); 128 layer_tree_root->SetMaxScrollOffset(gfx::Vector2d(30, 50)); 129 layer_tree_root->SetBounds(gfx::Size(100, 200)); 130 layer_tree_root->SavePaintProperties(); 131 content_layer->SetBounds(gfx::Size(100, 200)); 132 content_layer->SavePaintProperties(); 133 134 scoped_ptr<LayerImpl> layer_impl_tree_root = 135 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 136 scoped_ptr<LayerImpl>(), 137 host_impl.active_tree()); 138 TreeSynchronizer::PushProperties(layer_tree_root.get(), 139 layer_impl_tree_root.get()); 140 141 ScrollbarLayerImpl* cc_scrollbar_layer = 142 static_cast<ScrollbarLayerImpl*>(layer_impl_tree_root->children()[1]); 143 144 EXPECT_EQ(10.f, cc_scrollbar_layer->CurrentPos()); 145 EXPECT_EQ(30, cc_scrollbar_layer->Maximum()); 146 147 layer_tree_root->SetScrollOffset(gfx::Vector2d(100, 200)); 148 layer_tree_root->SetMaxScrollOffset(gfx::Vector2d(300, 500)); 149 layer_tree_root->SetBounds(gfx::Size(1000, 2000)); 150 layer_tree_root->SavePaintProperties(); 151 content_layer->SetBounds(gfx::Size(1000, 2000)); 152 content_layer->SavePaintProperties(); 153 154 ScrollbarAnimationController* scrollbar_controller = 155 layer_impl_tree_root->scrollbar_animation_controller(); 156 layer_impl_tree_root = 157 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 158 layer_impl_tree_root.Pass(), 159 host_impl.active_tree()); 160 TreeSynchronizer::PushProperties(layer_tree_root.get(), 161 layer_impl_tree_root.get()); 162 EXPECT_EQ(scrollbar_controller, 163 layer_impl_tree_root->scrollbar_animation_controller()); 164 165 EXPECT_EQ(100.f, cc_scrollbar_layer->CurrentPos()); 166 EXPECT_EQ(300, cc_scrollbar_layer->Maximum()); 167 168 layer_impl_tree_root->ScrollBy(gfx::Vector2d(12, 34)); 169 170 EXPECT_EQ(112.f, cc_scrollbar_layer->CurrentPos()); 171 EXPECT_EQ(300, cc_scrollbar_layer->Maximum()); 172} 173 174TEST(ScrollbarLayerTest, SolidColorDrawQuads) { 175 LayerTreeSettings layer_tree_settings; 176 layer_tree_settings.solid_color_scrollbars = true; 177 layer_tree_settings.solid_color_scrollbar_thickness_dip = 3; 178 FakeImplProxy proxy; 179 FakeLayerTreeHostImpl host_impl(layer_tree_settings, &proxy); 180 181 scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true)); 182 scoped_ptr<LayerImpl> layer_impl_tree_root = 183 LayerImplForScrollAreaAndScrollbar(&host_impl, scrollbar.Pass(), false); 184 ScrollbarLayerImpl* scrollbar_layer_impl = 185 static_cast<ScrollbarLayerImpl*>(layer_impl_tree_root->children()[1]); 186 scrollbar_layer_impl->set_thumb_thickness(3); 187 scrollbar_layer_impl->SetCurrentPos(10.f); 188 scrollbar_layer_impl->SetMaximum(100); 189 scrollbar_layer_impl->set_track_length(100); 190 scrollbar_layer_impl->set_visible_to_total_length_ratio(0.4f); 191 192 // Thickness should be overridden to 3. 193 { 194 MockQuadCuller quad_culler; 195 AppendQuadsData data; 196 scrollbar_layer_impl->AppendQuads(&quad_culler, &data); 197 198 const QuadList& quads = quad_culler.quad_list(); 199 ASSERT_EQ(1u, quads.size()); 200 EXPECT_EQ(DrawQuad::SOLID_COLOR, quads[0]->material); 201 EXPECT_RECT_EQ(gfx::Rect(6, 0, 40, 3), quads[0]->rect); 202 } 203 204 // Contents scale should scale the draw quad. 205 scrollbar_layer_impl->draw_properties().contents_scale_x = 2.f; 206 scrollbar_layer_impl->draw_properties().contents_scale_y = 2.f; 207 { 208 MockQuadCuller quad_culler; 209 AppendQuadsData data; 210 scrollbar_layer_impl->AppendQuads(&quad_culler, &data); 211 212 const QuadList& quads = quad_culler.quad_list(); 213 ASSERT_EQ(1u, quads.size()); 214 EXPECT_EQ(DrawQuad::SOLID_COLOR, quads[0]->material); 215 EXPECT_RECT_EQ(gfx::Rect(12, 0, 80, 6), quads[0]->rect); 216 } 217 scrollbar_layer_impl->draw_properties().contents_scale_x = 1.f; 218 scrollbar_layer_impl->draw_properties().contents_scale_y = 1.f; 219 220 // For solid color scrollbars, position and size should reflect the 221 // current viewport state. 222 scrollbar_layer_impl->set_visible_to_total_length_ratio(0.2f); 223 { 224 MockQuadCuller quad_culler; 225 AppendQuadsData data; 226 scrollbar_layer_impl->AppendQuads(&quad_culler, &data); 227 228 const QuadList& quads = quad_culler.quad_list(); 229 ASSERT_EQ(1u, quads.size()); 230 EXPECT_EQ(DrawQuad::SOLID_COLOR, quads[0]->material); 231 EXPECT_RECT_EQ(gfx::Rect(8, 0, 20, 3), quads[0]->rect); 232 } 233} 234 235TEST(ScrollbarLayerTest, LayerDrivenSolidColorDrawQuads) { 236 LayerTreeSettings layer_tree_settings; 237 layer_tree_settings.solid_color_scrollbars = true; 238 layer_tree_settings.solid_color_scrollbar_thickness_dip = 3; 239 FakeImplProxy proxy; 240 FakeLayerTreeHostImpl host_impl(layer_tree_settings, &proxy); 241 242 scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true)); 243 scoped_ptr<LayerImpl> layer_impl_tree_root = 244 LayerImplForScrollAreaAndScrollbar(&host_impl, scrollbar.Pass(), false); 245 ScrollbarLayerImpl* scrollbar_layer_impl = 246 static_cast<ScrollbarLayerImpl*>(layer_impl_tree_root->children()[1]); 247 248 scrollbar_layer_impl->set_thumb_thickness(3); 249 scrollbar_layer_impl->set_track_length(10); 250 scrollbar_layer_impl->SetCurrentPos(4.f); 251 scrollbar_layer_impl->SetMaximum(8); 252 253 layer_impl_tree_root->SetHorizontalScrollbarLayer(scrollbar_layer_impl); 254 layer_impl_tree_root->SetMaxScrollOffset(gfx::Vector2d(8, 8)); 255 layer_impl_tree_root->SetBounds(gfx::Size(2, 2)); 256 layer_impl_tree_root->ScrollBy(gfx::Vector2dF(4.f, 0.f)); 257 258 { 259 MockQuadCuller quad_culler; 260 AppendQuadsData data; 261 scrollbar_layer_impl->AppendQuads(&quad_culler, &data); 262 263 const QuadList& quads = quad_culler.quad_list(); 264 ASSERT_EQ(1u, quads.size()); 265 EXPECT_EQ(DrawQuad::SOLID_COLOR, quads[0]->material); 266 EXPECT_RECT_EQ(gfx::Rect(3, 0, 3, 3), quads[0]->rect); 267 } 268} 269 270class ScrollbarLayerSolidColorThumbTest : public testing::Test { 271 public: 272 ScrollbarLayerSolidColorThumbTest() { 273 LayerTreeSettings layer_tree_settings; 274 layer_tree_settings.solid_color_scrollbars = true; 275 host_impl_.reset(new FakeLayerTreeHostImpl(layer_tree_settings, &proxy_)); 276 277 horizontal_scrollbar_layer_ = ScrollbarLayerImpl::Create( 278 host_impl_->active_tree(), 1, HORIZONTAL); 279 vertical_scrollbar_layer_ = ScrollbarLayerImpl::Create( 280 host_impl_->active_tree(), 2, VERTICAL); 281 } 282 283 protected: 284 FakeImplProxy proxy_; 285 scoped_ptr<FakeLayerTreeHostImpl> host_impl_; 286 scoped_ptr<ScrollbarLayerImpl> horizontal_scrollbar_layer_; 287 scoped_ptr<ScrollbarLayerImpl> vertical_scrollbar_layer_; 288}; 289 290TEST_F(ScrollbarLayerSolidColorThumbTest, SolidColorThumbLength) { 291 horizontal_scrollbar_layer_->SetCurrentPos(0); 292 horizontal_scrollbar_layer_->SetMaximum(10); 293 horizontal_scrollbar_layer_->set_thumb_thickness(3); 294 295 // Simple case - one third of the scrollable area is visible, so the thumb 296 // should be one third as long as the track. 297 horizontal_scrollbar_layer_->set_visible_to_total_length_ratio(0.33f); 298 horizontal_scrollbar_layer_->set_track_length(100); 299 EXPECT_EQ(33, horizontal_scrollbar_layer_->ComputeThumbQuadRect().width()); 300 301 // The thumb's length should never be less than its thickness. 302 horizontal_scrollbar_layer_->set_visible_to_total_length_ratio(0.01f); 303 horizontal_scrollbar_layer_->set_track_length(100); 304 EXPECT_EQ(3, horizontal_scrollbar_layer_->ComputeThumbQuadRect().width()); 305} 306 307TEST_F(ScrollbarLayerSolidColorThumbTest, SolidColorThumbPosition) { 308 horizontal_scrollbar_layer_->set_track_length(100); 309 horizontal_scrollbar_layer_->set_visible_to_total_length_ratio(0.1f); 310 horizontal_scrollbar_layer_->set_thumb_thickness(3); 311 312 horizontal_scrollbar_layer_->SetCurrentPos(0); 313 horizontal_scrollbar_layer_->SetMaximum(100); 314 EXPECT_EQ(0, horizontal_scrollbar_layer_->ComputeThumbQuadRect().x()); 315 EXPECT_EQ(10, horizontal_scrollbar_layer_->ComputeThumbQuadRect().width()); 316 317 horizontal_scrollbar_layer_->SetCurrentPos(100); 318 // The thumb is 10px long and the track is 100px, so the maximum thumb 319 // position is 90px. 320 EXPECT_EQ(90, horizontal_scrollbar_layer_->ComputeThumbQuadRect().x()); 321 322 horizontal_scrollbar_layer_->SetCurrentPos(80); 323 // The scroll position is 80% of the maximum, so the thumb's position should 324 // be at 80% of its maximum or 72px. 325 EXPECT_EQ(72, horizontal_scrollbar_layer_->ComputeThumbQuadRect().x()); 326} 327 328TEST_F(ScrollbarLayerSolidColorThumbTest, SolidColorThumbVerticalAdjust) { 329 ScrollbarLayerImpl* layers[2] = 330 { horizontal_scrollbar_layer_.get(), vertical_scrollbar_layer_.get() }; 331 for (size_t i = 0; i < 2; ++i) { 332 layers[i]->set_track_length(100); 333 layers[i]->set_visible_to_total_length_ratio(0.2f); 334 layers[i]->set_thumb_thickness(3); 335 layers[i]->SetCurrentPos(25); 336 layers[i]->SetMaximum(100); 337 } 338 339 EXPECT_RECT_EQ(gfx::RectF(20.f, 0.f, 20.f, 3.f), 340 horizontal_scrollbar_layer_->ComputeThumbQuadRect()); 341 EXPECT_RECT_EQ(gfx::RectF(0.f, 20.f, 3.f, 20.f), 342 vertical_scrollbar_layer_->ComputeThumbQuadRect()); 343 344 horizontal_scrollbar_layer_->set_vertical_adjust(10.f); 345 vertical_scrollbar_layer_->set_vertical_adjust(10.f); 346 347 // The vertical adjustment factor has two effects: 348 // 1.) Moves the horizontal scrollbar down 349 // 2.) Increases the vertical scrollbar's effective track length which both 350 // increases the thumb's length and its position within the track. 351 EXPECT_RECT_EQ(gfx::Rect(20.f, 10.f, 20.f, 3.f), 352 horizontal_scrollbar_layer_->ComputeThumbQuadRect()); 353 EXPECT_RECT_EQ(gfx::Rect(0.f, 22, 3.f, 22.f), 354 vertical_scrollbar_layer_->ComputeThumbQuadRect()); 355} 356 357class ScrollbarLayerTestMaxTextureSize : public LayerTreeTest { 358 public: 359 ScrollbarLayerTestMaxTextureSize() {} 360 361 void SetScrollbarBounds(gfx::Size bounds) { bounds_ = bounds; } 362 363 virtual void BeginTest() OVERRIDE { 364 scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); 365 scrollbar_layer_ = ScrollbarLayer::Create(scrollbar.Pass(), 1); 366 scrollbar_layer_->SetLayerTreeHost(layer_tree_host()); 367 scrollbar_layer_->SetBounds(bounds_); 368 layer_tree_host()->root_layer()->AddChild(scrollbar_layer_); 369 370 scroll_layer_ = Layer::Create(); 371 scrollbar_layer_->SetScrollLayerId(scroll_layer_->id()); 372 layer_tree_host()->root_layer()->AddChild(scroll_layer_); 373 374 PostSetNeedsCommitToMainThread(); 375 } 376 377 virtual void DidCommitAndDrawFrame() OVERRIDE { 378 const int kMaxTextureSize = 379 layer_tree_host()->GetRendererCapabilities().max_texture_size; 380 381 // Check first that we're actually testing something. 382 EXPECT_GT(scrollbar_layer_->bounds().width(), kMaxTextureSize); 383 384 EXPECT_EQ(scrollbar_layer_->content_bounds().width(), 385 kMaxTextureSize - 1); 386 EXPECT_EQ(scrollbar_layer_->content_bounds().height(), 387 kMaxTextureSize - 1); 388 389 EndTest(); 390 } 391 392 virtual void AfterTest() OVERRIDE {} 393 394 private: 395 scoped_refptr<ScrollbarLayer> scrollbar_layer_; 396 scoped_refptr<Layer> scroll_layer_; 397 gfx::Size bounds_; 398}; 399 400TEST_F(ScrollbarLayerTestMaxTextureSize, DirectRenderer) { 401 scoped_ptr<TestWebGraphicsContext3D> context = 402 TestWebGraphicsContext3D::Create(); 403 int max_size = 0; 404 context->getIntegerv(GL_MAX_TEXTURE_SIZE, &max_size); 405 SetScrollbarBounds(gfx::Size(max_size + 100, max_size + 100)); 406 RunTest(true, false, true); 407} 408 409TEST_F(ScrollbarLayerTestMaxTextureSize, DelegatingRenderer) { 410 scoped_ptr<TestWebGraphicsContext3D> context = 411 TestWebGraphicsContext3D::Create(); 412 int max_size = 0; 413 context->getIntegerv(GL_MAX_TEXTURE_SIZE, &max_size); 414 SetScrollbarBounds(gfx::Size(max_size + 100, max_size + 100)); 415 RunTest(true, true, true); 416} 417 418class MockLayerTreeHost : public LayerTreeHost { 419 public: 420 MockLayerTreeHost(LayerTreeHostClient* client, 421 const LayerTreeSettings& settings) 422 : LayerTreeHost(client, settings) { 423 Initialize(scoped_ptr<Thread>()); 424 } 425}; 426 427 428class ScrollbarLayerTestResourceCreation : public testing::Test { 429 public: 430 ScrollbarLayerTestResourceCreation() 431 : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {} 432 433 void TestResourceUpload(size_t expected_resources) { 434 layer_tree_host_.reset( 435 new MockLayerTreeHost(&fake_client_, layer_tree_settings_)); 436 437 scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, false)); 438 scoped_refptr<Layer> layer_tree_root = Layer::Create(); 439 scoped_refptr<Layer> content_layer = Layer::Create(); 440 scoped_refptr<Layer> scrollbar_layer = 441 ScrollbarLayer::Create(scrollbar.Pass(), layer_tree_root->id()); 442 layer_tree_root->AddChild(content_layer); 443 layer_tree_root->AddChild(scrollbar_layer); 444 445 layer_tree_host_->InitializeOutputSurfaceIfNeeded(); 446 layer_tree_host_->contents_texture_manager()-> 447 SetMaxMemoryLimitBytes(1024 * 1024); 448 layer_tree_host_->SetRootLayer(layer_tree_root); 449 450 scrollbar_layer->SetIsDrawable(true); 451 scrollbar_layer->SetBounds(gfx::Size(100, 100)); 452 layer_tree_root->SetScrollOffset(gfx::Vector2d(10, 20)); 453 layer_tree_root->SetMaxScrollOffset(gfx::Vector2d(30, 50)); 454 layer_tree_root->SetBounds(gfx::Size(100, 200)); 455 content_layer->SetBounds(gfx::Size(100, 200)); 456 scrollbar_layer->draw_properties().content_bounds = gfx::Size(100, 200); 457 scrollbar_layer->draw_properties().visible_content_rect = 458 gfx::Rect(0, 0, 100, 200); 459 scrollbar_layer->CreateRenderSurface(); 460 scrollbar_layer->draw_properties().render_target = scrollbar_layer.get(); 461 462 testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 463 EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get()); 464 465 PriorityCalculator calculator; 466 ResourceUpdateQueue queue; 467 OcclusionTracker occlusion_tracker(gfx::Rect(), false); 468 469 scrollbar_layer->SetTexturePriorities(calculator); 470 layer_tree_host_->contents_texture_manager()->PrioritizeTextures(); 471 scrollbar_layer->Update(&queue, &occlusion_tracker, NULL); 472 EXPECT_EQ(0u, queue.FullUploadSize()); 473 EXPECT_EQ(expected_resources, queue.PartialUploadSize()); 474 475 testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 476 } 477 478 protected: 479 FakeLayerTreeHostClient fake_client_; 480 LayerTreeSettings layer_tree_settings_; 481 scoped_ptr<MockLayerTreeHost> layer_tree_host_; 482}; 483 484TEST_F(ScrollbarLayerTestResourceCreation, ResourceUpload) { 485 layer_tree_settings_.solid_color_scrollbars = false; 486 TestResourceUpload(2); 487} 488 489TEST_F(ScrollbarLayerTestResourceCreation, SolidColorNoResourceUpload) { 490 layer_tree_settings_.solid_color_scrollbars = true; 491 TestResourceUpload(0); 492} 493 494class ScaledScrollbarLayerTestResourceCreation : public testing::Test { 495 public: 496 ScaledScrollbarLayerTestResourceCreation() 497 : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {} 498 499 void TestResourceUpload(size_t expected_resources, const float test_scale) { 500 layer_tree_host_.reset( 501 new MockLayerTreeHost(&fake_client_, layer_tree_settings_)); 502 503 gfx::Point scrollbar_location(0, 185); 504 scoped_ptr<FakeScrollbar> scrollbar(new FakeScrollbar(false, true, false)); 505 scrollbar->set_location(scrollbar_location); 506 507 scoped_refptr<Layer> layer_tree_root = Layer::Create(); 508 scoped_refptr<Layer> content_layer = Layer::Create(); 509 scoped_refptr<Layer> scrollbar_layer = 510 ScrollbarLayer::Create(scrollbar.PassAs<cc::Scrollbar>(), 511 layer_tree_root->id()); 512 layer_tree_root->AddChild(content_layer); 513 layer_tree_root->AddChild(scrollbar_layer); 514 515 layer_tree_host_->InitializeOutputSurfaceIfNeeded(); 516 layer_tree_host_->contents_texture_manager()-> 517 SetMaxMemoryLimitBytes(1024 * 1024); 518 layer_tree_host_->SetRootLayer(layer_tree_root); 519 520 scrollbar_layer->SetIsDrawable(true); 521 scrollbar_layer->SetBounds(gfx::Size(100, 15)); 522 scrollbar_layer->SetPosition(scrollbar_location); 523 layer_tree_root->SetBounds(gfx::Size(100, 200)); 524 content_layer->SetBounds(gfx::Size(100, 200)); 525 gfx::SizeF scaled_size = 526 gfx::ScaleSize(scrollbar_layer->bounds(), test_scale, test_scale); 527 gfx::PointF scaled_location = 528 gfx::ScalePoint(scrollbar_layer->position(), test_scale, test_scale); 529 scrollbar_layer->draw_properties().content_bounds = 530 gfx::Size(scaled_size.width(), scaled_size.height()); 531 scrollbar_layer->draw_properties().contents_scale_x = test_scale; 532 scrollbar_layer->draw_properties().contents_scale_y = test_scale; 533 scrollbar_layer->draw_properties().visible_content_rect = 534 gfx::Rect(scaled_location.x(), 535 scaled_location.y(), 536 scaled_size.width(), 537 scaled_size.height()); 538 scrollbar_layer->CreateRenderSurface(); 539 scrollbar_layer->draw_properties().render_target = scrollbar_layer.get(); 540 541 testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 542 EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get()); 543 544 PriorityCalculator calculator; 545 ResourceUpdateQueue queue; 546 OcclusionTracker occlusion_tracker(gfx::Rect(), false); 547 548 scrollbar_layer->SetTexturePriorities(calculator); 549 layer_tree_host_->contents_texture_manager()->PrioritizeTextures(); 550 scrollbar_layer->Update(&queue, &occlusion_tracker, NULL); 551 EXPECT_EQ(expected_resources, queue.PartialUploadSize()); 552 553 // Verify that we have not generated any content uploads that are larger 554 // than their destination textures. 555 while (queue.HasMoreUpdates()) { 556 ResourceUpdate update = queue.TakeFirstPartialUpload(); 557 EXPECT_LE(update.texture->size().width(), 558 scrollbar_layer->content_bounds().width()); 559 EXPECT_LE(update.texture->size().height(), 560 scrollbar_layer->content_bounds().height()); 561 562 EXPECT_LE(update.dest_offset.x() + update.content_rect.width(), 563 update.texture->size().width()); 564 EXPECT_LE(update.dest_offset.y() + update.content_rect.height(), 565 update.texture->size().height()); 566 } 567 568 testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 569 } 570 571 protected: 572 FakeLayerTreeHostClient fake_client_; 573 LayerTreeSettings layer_tree_settings_; 574 scoped_ptr<MockLayerTreeHost> layer_tree_host_; 575}; 576 577TEST_F(ScaledScrollbarLayerTestResourceCreation, ScaledResourceUpload) { 578 layer_tree_settings_.solid_color_scrollbars = false; 579 // Pick a test scale that moves the scrollbar's (non-zero) position to 580 // a non-pixel-aligned location. 581 TestResourceUpload(2, 1.41f); 582} 583 584} // namespace 585} // namespace cc 586