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/resources/picture_layer_tiling.h" 6 7 #include <limits> 8 9 #include "cc/base/math_util.h" 10 #include "cc/resources/picture_layer_tiling_set.h" 11 #include "cc/test/fake_picture_layer_tiling_client.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "ui/gfx/rect_conversions.h" 14 #include "ui/gfx/size_conversions.h" 15 16 namespace cc { 17 namespace { 18 19 static gfx::Rect ViewportInLayerSpace( 20 const gfx::Transform& transform, 21 gfx::Size device_viewport) { 22 23 gfx::Transform inverse; 24 if (!transform.GetInverse(&inverse)) 25 return gfx::Rect(); 26 27 gfx::RectF viewport_in_layer_space = MathUtil::ProjectClippedRect( 28 inverse, gfx::RectF(gfx::Point(0, 0), device_viewport)); 29 30 return ToEnclosingRect(viewport_in_layer_space); 31 } 32 33 class TestablePictureLayerTiling : public PictureLayerTiling { 34 public: 35 using PictureLayerTiling::SetLiveTilesRect; 36 using PictureLayerTiling::TileAt; 37 38 static scoped_ptr<TestablePictureLayerTiling> Create( 39 float contents_scale, 40 gfx::Size layer_bounds, 41 PictureLayerTilingClient* client) { 42 return make_scoped_ptr(new TestablePictureLayerTiling( 43 contents_scale, 44 layer_bounds, 45 client)); 46 } 47 48 protected: 49 TestablePictureLayerTiling(float contents_scale, 50 gfx::Size layer_bounds, 51 PictureLayerTilingClient* client) 52 : PictureLayerTiling(contents_scale, layer_bounds, client) { } 53 }; 54 55 class PictureLayerTilingIteratorTest : public testing::Test { 56 public: 57 PictureLayerTilingIteratorTest() {} 58 virtual ~PictureLayerTilingIteratorTest() {} 59 60 void Initialize(gfx::Size tile_size, 61 float contents_scale, 62 gfx::Size layer_bounds) { 63 client_.SetTileSize(tile_size); 64 tiling_ = TestablePictureLayerTiling::Create(contents_scale, 65 layer_bounds, 66 &client_); 67 } 68 69 void SetLiveRectAndVerifyTiles(gfx::Rect live_tiles_rect) { 70 tiling_->SetLiveTilesRect(live_tiles_rect); 71 72 std::vector<Tile*> tiles = tiling_->AllTilesForTesting(); 73 for (std::vector<Tile*>::iterator iter = tiles.begin(); 74 iter != tiles.end(); 75 ++iter) { 76 EXPECT_TRUE(live_tiles_rect.Intersects((*iter)->content_rect())); 77 } 78 } 79 80 void VerifyTilesExactlyCoverRect( 81 float rect_scale, 82 gfx::Rect request_rect, 83 gfx::Rect expect_rect) { 84 EXPECT_TRUE(request_rect.Contains(expect_rect)); 85 86 // Iterators are not valid if this ratio is too large (i.e. the 87 // tiling is too high-res for a low-res destination rect.) This is an 88 // artifact of snapping geometry to integer coordinates and then mapping 89 // back to floating point texture coordinates. 90 float dest_to_contents_scale = tiling_->contents_scale() / rect_scale; 91 ASSERT_LE(dest_to_contents_scale, 2.0); 92 93 Region remaining = expect_rect; 94 for (PictureLayerTiling::CoverageIterator 95 iter(tiling_.get(), rect_scale, request_rect); 96 iter; 97 ++iter) { 98 // Geometry cannot overlap previous geometry at all 99 gfx::Rect geometry = iter.geometry_rect(); 100 EXPECT_TRUE(expect_rect.Contains(geometry)); 101 EXPECT_TRUE(remaining.Contains(geometry)); 102 remaining.Subtract(geometry); 103 104 // Sanity check that texture coords are within the texture rect. 105 gfx::RectF texture_rect = iter.texture_rect(); 106 EXPECT_GE(texture_rect.x(), 0); 107 EXPECT_GE(texture_rect.y(), 0); 108 EXPECT_LE(texture_rect.right(), client_.TileSize().width()); 109 EXPECT_LE(texture_rect.bottom(), client_.TileSize().height()); 110 111 EXPECT_EQ(iter.texture_size(), client_.TileSize()); 112 } 113 114 // The entire rect must be filled by geometry from the tiling. 115 EXPECT_TRUE(remaining.IsEmpty()); 116 } 117 118 void VerifyTilesExactlyCoverRect(float rect_scale, gfx::Rect rect) { 119 VerifyTilesExactlyCoverRect(rect_scale, rect, rect); 120 } 121 122 void VerifyTiles( 123 float rect_scale, 124 gfx::Rect rect, 125 base::Callback<void(Tile* tile, gfx::Rect geometry_rect)> callback) { 126 VerifyTiles(tiling_.get(), 127 rect_scale, 128 rect, 129 callback); 130 } 131 132 void VerifyTiles( 133 PictureLayerTiling* tiling, 134 float rect_scale, 135 gfx::Rect rect, 136 base::Callback<void(Tile* tile, gfx::Rect geometry_rect)> callback) { 137 Region remaining = rect; 138 for (PictureLayerTiling::CoverageIterator iter(tiling, rect_scale, rect); 139 iter; 140 ++iter) { 141 remaining.Subtract(iter.geometry_rect()); 142 callback.Run(*iter, iter.geometry_rect()); 143 } 144 EXPECT_TRUE(remaining.IsEmpty()); 145 } 146 147 void VerifyTilesCoverNonContainedRect(float rect_scale, gfx::Rect dest_rect) { 148 float dest_to_contents_scale = tiling_->contents_scale() / rect_scale; 149 gfx::Rect clamped_rect = gfx::ScaleToEnclosingRect( 150 tiling_->ContentRect(), 1.f / dest_to_contents_scale); 151 clamped_rect.Intersect(dest_rect); 152 VerifyTilesExactlyCoverRect(rect_scale, dest_rect, clamped_rect); 153 } 154 155 protected: 156 FakePictureLayerTilingClient client_; 157 scoped_ptr<TestablePictureLayerTiling> tiling_; 158 159 private: 160 DISALLOW_COPY_AND_ASSIGN(PictureLayerTilingIteratorTest); 161 }; 162 163 TEST_F(PictureLayerTilingIteratorTest, LiveTilesExactlyCoverLiveTileRect) { 164 Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801)); 165 SetLiveRectAndVerifyTiles(gfx::Rect(100, 100)); 166 SetLiveRectAndVerifyTiles(gfx::Rect(101, 99)); 167 SetLiveRectAndVerifyTiles(gfx::Rect(1099, 1)); 168 SetLiveRectAndVerifyTiles(gfx::Rect(1, 801)); 169 SetLiveRectAndVerifyTiles(gfx::Rect(1099, 1)); 170 SetLiveRectAndVerifyTiles(gfx::Rect(201, 800)); 171 } 172 173 TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsNoScale) { 174 Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801)); 175 VerifyTilesExactlyCoverRect(1, gfx::Rect()); 176 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1099, 801)); 177 VerifyTilesExactlyCoverRect(1, gfx::Rect(52, 83, 789, 412)); 178 179 // With borders, a size of 3x3 = 1 pixel of content. 180 Initialize(gfx::Size(3, 3), 1, gfx::Size(10, 10)); 181 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1, 1)); 182 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 2, 2)); 183 VerifyTilesExactlyCoverRect(1, gfx::Rect(1, 1, 2, 2)); 184 VerifyTilesExactlyCoverRect(1, gfx::Rect(3, 2, 5, 2)); 185 } 186 187 TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsTilingScale) { 188 Initialize(gfx::Size(200, 100), 2.0f, gfx::Size(1005, 2010)); 189 VerifyTilesExactlyCoverRect(1, gfx::Rect()); 190 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010)); 191 VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381)); 192 193 Initialize(gfx::Size(3, 3), 2.0f, gfx::Size(10, 10)); 194 VerifyTilesExactlyCoverRect(1, gfx::Rect()); 195 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1, 1)); 196 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 2, 2)); 197 VerifyTilesExactlyCoverRect(1, gfx::Rect(1, 1, 2, 2)); 198 VerifyTilesExactlyCoverRect(1, gfx::Rect(3, 2, 5, 2)); 199 200 Initialize(gfx::Size(100, 200), 0.5f, gfx::Size(1005, 2010)); 201 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010)); 202 VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381)); 203 204 Initialize(gfx::Size(150, 250), 0.37f, gfx::Size(1005, 2010)); 205 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010)); 206 VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381)); 207 208 Initialize(gfx::Size(312, 123), 0.01f, gfx::Size(1005, 2010)); 209 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010)); 210 VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381)); 211 } 212 213 TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsBothScale) { 214 Initialize(gfx::Size(50, 50), 4.0f, gfx::Size(800, 600)); 215 VerifyTilesExactlyCoverRect(2.0f, gfx::Rect()); 216 VerifyTilesExactlyCoverRect(2.0f, gfx::Rect(0, 0, 1600, 1200)); 217 VerifyTilesExactlyCoverRect(2.0f, gfx::Rect(512, 365, 253, 182)); 218 219 float scale = 6.7f; 220 gfx::Size bounds(800, 600); 221 gfx::Rect full_rect(gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale))); 222 Initialize(gfx::Size(256, 512), 5.2f, bounds); 223 VerifyTilesExactlyCoverRect(scale, full_rect); 224 VerifyTilesExactlyCoverRect(scale, gfx::Rect(2014, 1579, 867, 1033)); 225 } 226 227 TEST_F(PictureLayerTilingIteratorTest, IteratorEmptyRect) { 228 Initialize(gfx::Size(100, 100), 1.0f, gfx::Size(800, 600)); 229 230 gfx::Rect empty; 231 PictureLayerTiling::CoverageIterator iter(tiling_.get(), 1.0f, empty); 232 EXPECT_FALSE(iter); 233 } 234 235 TEST_F(PictureLayerTilingIteratorTest, NonIntersectingRect) { 236 Initialize(gfx::Size(100, 100), 1.0f, gfx::Size(800, 600)); 237 gfx::Rect non_intersecting(1000, 1000, 50, 50); 238 PictureLayerTiling::CoverageIterator iter(tiling_.get(), 1, non_intersecting); 239 EXPECT_FALSE(iter); 240 } 241 242 TEST_F(PictureLayerTilingIteratorTest, LayerEdgeTextureCoordinates) { 243 Initialize(gfx::Size(300, 300), 1.0f, gfx::Size(256, 256)); 244 // All of these sizes are 256x256, scaled and ceiled. 245 VerifyTilesExactlyCoverRect(1.0f, gfx::Rect(0, 0, 256, 256)); 246 VerifyTilesExactlyCoverRect(0.8f, gfx::Rect(0, 0, 205, 205)); 247 VerifyTilesExactlyCoverRect(1.2f, gfx::Rect(0, 0, 308, 308)); 248 } 249 250 TEST_F(PictureLayerTilingIteratorTest, NonContainedDestRect) { 251 Initialize(gfx::Size(100, 100), 1.0f, gfx::Size(400, 400)); 252 253 // Too large in all dimensions 254 VerifyTilesCoverNonContainedRect(1.0f, gfx::Rect(-1000, -1000, 2000, 2000)); 255 VerifyTilesCoverNonContainedRect(1.5f, gfx::Rect(-1000, -1000, 2000, 2000)); 256 VerifyTilesCoverNonContainedRect(0.5f, gfx::Rect(-1000, -1000, 2000, 2000)); 257 258 // Partially covering content, but too large 259 VerifyTilesCoverNonContainedRect(1.0f, gfx::Rect(-1000, 100, 2000, 100)); 260 VerifyTilesCoverNonContainedRect(1.5f, gfx::Rect(-1000, 100, 2000, 100)); 261 VerifyTilesCoverNonContainedRect(0.5f, gfx::Rect(-1000, 100, 2000, 100)); 262 } 263 264 TEST(PictureLayerTilingTest, ExpandRectEqual) { 265 gfx::Rect in(40, 50, 100, 200); 266 gfx::Rect bounds(-1000, -1000, 10000, 10000); 267 int64 target_area = 100 * 200; 268 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 269 in, target_area, bounds, NULL); 270 EXPECT_EQ(in.ToString(), out.ToString()); 271 } 272 273 TEST(PictureLayerTilingTest, ExpandRectSmaller) { 274 gfx::Rect in(40, 50, 100, 200); 275 gfx::Rect bounds(-1000, -1000, 10000, 10000); 276 int64 target_area = 100 * 100; 277 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 278 in, target_area, bounds, NULL); 279 EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y()); 280 EXPECT_EQ(out.right() - in.right(), in.x() - out.x()); 281 EXPECT_EQ(out.width() - in.width(), out.height() - in.height()); 282 EXPECT_NEAR(100 * 100, out.width() * out.height(), 50); 283 EXPECT_TRUE(bounds.Contains(out)); 284 } 285 286 TEST(PictureLayerTilingTest, ExpandRectUnbounded) { 287 gfx::Rect in(40, 50, 100, 200); 288 gfx::Rect bounds(-1000, -1000, 10000, 10000); 289 int64 target_area = 200 * 200; 290 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 291 in, target_area, bounds, NULL); 292 EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y()); 293 EXPECT_EQ(out.right() - in.right(), in.x() - out.x()); 294 EXPECT_EQ(out.width() - in.width(), out.height() - in.height()); 295 EXPECT_NEAR(200 * 200, out.width() * out.height(), 100); 296 EXPECT_TRUE(bounds.Contains(out)); 297 } 298 299 TEST(PictureLayerTilingTest, ExpandRectBoundedSmaller) { 300 gfx::Rect in(40, 50, 100, 200); 301 gfx::Rect bounds(50, 60, 40, 30); 302 int64 target_area = 200 * 200; 303 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 304 in, target_area, bounds, NULL); 305 EXPECT_EQ(bounds.ToString(), out.ToString()); 306 } 307 308 TEST(PictureLayerTilingTest, ExpandRectBoundedEqual) { 309 gfx::Rect in(40, 50, 100, 200); 310 gfx::Rect bounds = in; 311 int64 target_area = 200 * 200; 312 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 313 in, target_area, bounds, NULL); 314 EXPECT_EQ(bounds.ToString(), out.ToString()); 315 } 316 317 TEST(PictureLayerTilingTest, ExpandRectBoundedSmallerStretchVertical) { 318 gfx::Rect in(40, 50, 100, 200); 319 gfx::Rect bounds(45, 0, 90, 300); 320 int64 target_area = 200 * 200; 321 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 322 in, target_area, bounds, NULL); 323 EXPECT_EQ(bounds.ToString(), out.ToString()); 324 } 325 326 TEST(PictureLayerTilingTest, ExpandRectBoundedEqualStretchVertical) { 327 gfx::Rect in(40, 50, 100, 200); 328 gfx::Rect bounds(40, 0, 100, 300); 329 int64 target_area = 200 * 200; 330 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 331 in, target_area, bounds, NULL); 332 EXPECT_EQ(bounds.ToString(), out.ToString()); 333 } 334 335 TEST(PictureLayerTilingTest, ExpandRectBoundedSmallerStretchHorizontal) { 336 gfx::Rect in(40, 50, 100, 200); 337 gfx::Rect bounds(0, 55, 180, 190); 338 int64 target_area = 200 * 200; 339 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 340 in, target_area, bounds, NULL); 341 EXPECT_EQ(bounds.ToString(), out.ToString()); 342 } 343 344 TEST(PictureLayerTilingTest, ExpandRectBoundedEqualStretchHorizontal) { 345 gfx::Rect in(40, 50, 100, 200); 346 gfx::Rect bounds(0, 50, 180, 200); 347 int64 target_area = 200 * 200; 348 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 349 in, target_area, bounds, NULL); 350 EXPECT_EQ(bounds.ToString(), out.ToString()); 351 } 352 353 TEST(PictureLayerTilingTest, ExpandRectBoundedLeft) { 354 gfx::Rect in(40, 50, 100, 200); 355 gfx::Rect bounds(20, -1000, 10000, 10000); 356 int64 target_area = 200 * 200; 357 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 358 in, target_area, bounds, NULL); 359 EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y()); 360 EXPECT_EQ(out.bottom() - in.bottom(), out.right() - in.right()); 361 EXPECT_LE(out.width() * out.height(), target_area); 362 EXPECT_GT(out.width() * out.height(), 363 target_area - out.width() - out.height() * 2); 364 EXPECT_TRUE(bounds.Contains(out)); 365 } 366 367 TEST(PictureLayerTilingTest, ExpandRectBoundedRight) { 368 gfx::Rect in(40, 50, 100, 200); 369 gfx::Rect bounds(-1000, -1000, 1000+120, 10000); 370 int64 target_area = 200 * 200; 371 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 372 in, target_area, bounds, NULL); 373 EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y()); 374 EXPECT_EQ(out.bottom() - in.bottom(), in.x() - out.x()); 375 EXPECT_LE(out.width() * out.height(), target_area); 376 EXPECT_GT(out.width() * out.height(), 377 target_area - out.width() - out.height() * 2); 378 EXPECT_TRUE(bounds.Contains(out)); 379 } 380 381 TEST(PictureLayerTilingTest, ExpandRectBoundedTop) { 382 gfx::Rect in(40, 50, 100, 200); 383 gfx::Rect bounds(-1000, 30, 10000, 10000); 384 int64 target_area = 200 * 200; 385 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 386 in, target_area, bounds, NULL); 387 EXPECT_EQ(out.right() - in.right(), in.x() - out.x()); 388 EXPECT_EQ(out.right() - in.right(), out.bottom() - in.bottom()); 389 EXPECT_LE(out.width() * out.height(), target_area); 390 EXPECT_GT(out.width() * out.height(), 391 target_area - out.width() * 2 - out.height()); 392 EXPECT_TRUE(bounds.Contains(out)); 393 } 394 395 TEST(PictureLayerTilingTest, ExpandRectBoundedBottom) { 396 gfx::Rect in(40, 50, 100, 200); 397 gfx::Rect bounds(-1000, -1000, 10000, 1000 + 220); 398 int64 target_area = 200 * 200; 399 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 400 in, target_area, bounds, NULL); 401 EXPECT_EQ(out.right() - in.right(), in.x() - out.x()); 402 EXPECT_EQ(out.right() - in.right(), in.y() - out.y()); 403 EXPECT_LE(out.width() * out.height(), target_area); 404 EXPECT_GT(out.width() * out.height(), 405 target_area - out.width() * 2 - out.height()); 406 EXPECT_TRUE(bounds.Contains(out)); 407 } 408 409 TEST(PictureLayerTilingTest, ExpandRectSquishedHorizontally) { 410 gfx::Rect in(40, 50, 100, 200); 411 gfx::Rect bounds(0, -4000, 100+40+20, 100000); 412 int64 target_area = 400 * 400; 413 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 414 in, target_area, bounds, NULL); 415 EXPECT_EQ(20, out.right() - in.right()); 416 EXPECT_EQ(40, in.x() - out.x()); 417 EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y()); 418 EXPECT_LE(out.width() * out.height(), target_area); 419 EXPECT_GT(out.width() * out.height(), 420 target_area - out.width() * 2); 421 EXPECT_TRUE(bounds.Contains(out)); 422 } 423 424 TEST(PictureLayerTilingTest, ExpandRectSquishedVertically) { 425 gfx::Rect in(40, 50, 100, 200); 426 gfx::Rect bounds(-4000, 0, 100000, 200+50+30); 427 int64 target_area = 400 * 400; 428 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 429 in, target_area, bounds, NULL); 430 EXPECT_EQ(30, out.bottom() - in.bottom()); 431 EXPECT_EQ(50, in.y() - out.y()); 432 EXPECT_EQ(out.right() - in.right(), in.x() - out.x()); 433 EXPECT_LE(out.width() * out.height(), target_area); 434 EXPECT_GT(out.width() * out.height(), 435 target_area - out.height() * 2); 436 EXPECT_TRUE(bounds.Contains(out)); 437 } 438 439 TEST(PictureLayerTilingTest, ExpandRectOutOfBoundsFarAway) { 440 gfx::Rect in(400, 500, 100, 200); 441 gfx::Rect bounds(0, 0, 10, 10); 442 int64 target_area = 400 * 400; 443 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 444 in, target_area, bounds, NULL); 445 EXPECT_TRUE(out.IsEmpty()); 446 } 447 448 TEST(PictureLayerTilingTest, ExpandRectOutOfBoundsExpandedFullyCover) { 449 gfx::Rect in(40, 50, 100, 100); 450 gfx::Rect bounds(0, 0, 10, 10); 451 int64 target_area = 400 * 400; 452 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 453 in, target_area, bounds, NULL); 454 EXPECT_EQ(bounds.ToString(), out.ToString()); 455 } 456 457 TEST(PictureLayerTilingTest, ExpandRectOutOfBoundsExpandedPartlyCover) { 458 gfx::Rect in(600, 600, 100, 100); 459 gfx::Rect bounds(0, 0, 500, 500); 460 int64 target_area = 400 * 400; 461 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 462 in, target_area, bounds, NULL); 463 EXPECT_EQ(bounds.right(), out.right()); 464 EXPECT_EQ(bounds.bottom(), out.bottom()); 465 EXPECT_LE(out.width() * out.height(), target_area); 466 EXPECT_GT(out.width() * out.height(), 467 target_area - out.width() - out.height()); 468 EXPECT_TRUE(bounds.Contains(out)); 469 } 470 471 TEST(PictureLayerTilingTest, EmptyStartingRect) { 472 // If a layer has a non-invertible transform, then the starting rect 473 // for the layer would be empty. 474 gfx::Rect in(40, 40, 0, 0); 475 gfx::Rect bounds(0, 0, 10, 10); 476 int64 target_area = 400 * 400; 477 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( 478 in, target_area, bounds, NULL); 479 EXPECT_TRUE(out.IsEmpty()); 480 } 481 482 static void TileExists(bool exists, Tile* tile, gfx::Rect geometry_rect) { 483 EXPECT_EQ(exists, tile != NULL) << geometry_rect.ToString(); 484 } 485 486 TEST_F(PictureLayerTilingIteratorTest, TilesExist) { 487 gfx::Size layer_bounds(1099, 801); 488 Initialize(gfx::Size(100, 100), 1.f, layer_bounds); 489 VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds)); 490 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false)); 491 492 tiling_->UpdateTilePriorities( 493 ACTIVE_TREE, 494 layer_bounds, // device viewport 495 gfx::Rect(layer_bounds), // viewport in layer space 496 gfx::Rect(layer_bounds), // visible content rect 497 layer_bounds, // last layer bounds 498 layer_bounds, // current layer bounds 499 1.f, // last contents scale 500 1.f, // current contents scale 501 gfx::Transform(), // last screen transform 502 gfx::Transform(), // current screen transform 503 1.0, // current frame time 504 10000); // max tiles in tile manager 505 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true)); 506 507 // Make the viewport rect empty. All tiles are killed and become zombies. 508 tiling_->UpdateTilePriorities( 509 ACTIVE_TREE, 510 layer_bounds, // device viewport 511 gfx::Rect(), // viewport in layer space 512 gfx::Rect(), // visible content rect 513 layer_bounds, // last layer bounds 514 layer_bounds, // current layer bounds 515 1.f, // last contents scale 516 1.f, // current contents scale 517 gfx::Transform(), // last screen transform 518 gfx::Transform(), // current screen transform 519 2.0, // current frame time 520 10000); // max tiles in tile manager 521 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false)); 522 } 523 524 TEST_F(PictureLayerTilingIteratorTest, TilesExistGiantViewport) { 525 gfx::Size layer_bounds(1099, 801); 526 Initialize(gfx::Size(100, 100), 1.f, layer_bounds); 527 VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds)); 528 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false)); 529 530 gfx::Rect giant_rect(-10000000, -10000000, 1000000000, 1000000000); 531 532 tiling_->UpdateTilePriorities( 533 ACTIVE_TREE, 534 layer_bounds, // device viewport 535 giant_rect, // viewport in layer space 536 gfx::Rect(layer_bounds), // visible content rect 537 layer_bounds, // last layer bounds 538 layer_bounds, // current layer bounds 539 1.f, // last contents scale 540 1.f, // current contents scale 541 gfx::Transform(), // last screen transform 542 gfx::Transform(), // current screen transform 543 1.0, // current frame time 544 10000); // max tiles in tile manager 545 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true)); 546 547 // If the visible content rect is empty, it should still have live tiles. 548 tiling_->UpdateTilePriorities( 549 ACTIVE_TREE, 550 layer_bounds, // device viewport 551 giant_rect, // viewport in layer space 552 gfx::Rect(), // visible content rect 553 layer_bounds, // last layer bounds 554 layer_bounds, // current layer bounds 555 1.f, // last contents scale 556 1.f, // current contents scale 557 gfx::Transform(), // last screen transform 558 gfx::Transform(), // current screen transform 559 2.0, // current frame time 560 10000); // max tiles in tile manager 561 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true)); 562 } 563 564 TEST_F(PictureLayerTilingIteratorTest, TilesExistOutsideViewport) { 565 gfx::Size layer_bounds(1099, 801); 566 Initialize(gfx::Size(100, 100), 1.f, layer_bounds); 567 VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds)); 568 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false)); 569 570 // This rect does not intersect with the layer, as the layer is outside the 571 // viewport. 572 gfx::Rect viewport_rect(1100, 0, 1000, 1000); 573 EXPECT_FALSE(viewport_rect.Intersects(gfx::Rect(layer_bounds))); 574 575 tiling_->UpdateTilePriorities( 576 ACTIVE_TREE, 577 layer_bounds, // device viewport 578 viewport_rect, // viewport in layer space 579 gfx::Rect(), // visible content rect 580 layer_bounds, // last layer bounds 581 layer_bounds, // current layer bounds 582 1.f, // last contents scale 583 1.f, // current contents scale 584 gfx::Transform(), // last screen transform 585 gfx::Transform(), // current screen transform 586 1.0, // current frame time 587 10000); // max tiles in tile manager 588 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true)); 589 } 590 591 static void TilesIntersectingRectExist(gfx::Rect rect, 592 bool intersect_exists, 593 Tile* tile, 594 gfx::Rect geometry_rect) { 595 bool intersects = rect.Intersects(geometry_rect); 596 bool expected_exists = intersect_exists ? intersects : !intersects; 597 EXPECT_EQ(expected_exists, tile != NULL) 598 << "Rects intersecting " << rect.ToString() << " should exist. " 599 << "Current tile rect is " << geometry_rect.ToString(); 600 } 601 602 TEST_F(PictureLayerTilingIteratorTest, 603 TilesExistLargeViewportAndLayerWithSmallVisibleArea) { 604 gfx::Size layer_bounds(10000, 10000); 605 Initialize(gfx::Size(100, 100), 1.f, layer_bounds); 606 VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds)); 607 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false)); 608 609 gfx::Rect visible_rect(8000, 8000, 50, 50); 610 611 tiling_->UpdateTilePriorities( 612 ACTIVE_TREE, 613 layer_bounds, // device viewport 614 gfx::Rect(layer_bounds), // viewport in layer space 615 visible_rect, // visible content rect 616 layer_bounds, // last layer bounds 617 layer_bounds, // current layer bounds 618 1.f, // last contents scale 619 1.f, // current contents scale 620 gfx::Transform(), // last screen transform 621 gfx::Transform(), // current screen transform 622 1.0, // current frame time 623 1); // max tiles in tile manager 624 VerifyTiles(1.f, 625 gfx::Rect(layer_bounds), 626 base::Bind(&TilesIntersectingRectExist, visible_rect, true)); 627 } 628 629 static void CountExistingTiles(int *count, 630 Tile* tile, 631 gfx::Rect geometry_rect) { 632 if (tile != NULL) 633 ++(*count); 634 } 635 636 TEST_F(PictureLayerTilingIteratorTest, 637 TilesExistLargeViewportAndLayerWithLargeVisibleArea) { 638 gfx::Size layer_bounds(10000, 10000); 639 Initialize(gfx::Size(100, 100), 1.f, layer_bounds); 640 VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds)); 641 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false)); 642 643 tiling_->UpdateTilePriorities( 644 ACTIVE_TREE, 645 layer_bounds, // device viewport 646 gfx::Rect(layer_bounds), // viewport in layer space 647 gfx::Rect(layer_bounds), // visible content rect 648 layer_bounds, // last layer bounds 649 layer_bounds, // current layer bounds 650 1.f, // last contents scale 651 1.f, // current contents scale 652 gfx::Transform(), // last screen transform 653 gfx::Transform(), // current screen transform 654 1.0, // current frame time 655 1); // max tiles in tile manager 656 657 int num_tiles = 0; 658 VerifyTiles(1.f, 659 gfx::Rect(layer_bounds), 660 base::Bind(&CountExistingTiles, &num_tiles)); 661 // If we're making a rect the size of one tile, it can only overlap up to 4 662 // tiles depending on its position. 663 EXPECT_LE(num_tiles, 4); 664 VerifyTiles(1.f, gfx::Rect(), base::Bind(&TileExists, false)); 665 } 666 667 TEST_F(PictureLayerTilingIteratorTest, AddTilingsToMatchScale) { 668 gfx::Size layer_bounds(1099, 801); 669 gfx::Size tile_size(100, 100); 670 671 client_.SetTileSize(tile_size); 672 673 PictureLayerTilingSet active_set(&client_, layer_bounds); 674 675 active_set.AddTiling(1.f); 676 677 VerifyTiles(active_set.tiling_at(0), 678 1.f, 679 gfx::Rect(layer_bounds), 680 base::Bind(&TileExists, false)); 681 682 active_set.UpdateTilePriorities( 683 PENDING_TREE, 684 layer_bounds, // device viewport 685 gfx::Rect(layer_bounds), // viewport in layer space 686 gfx::Rect(layer_bounds), // visible content rect 687 layer_bounds, // last layer bounds 688 layer_bounds, // current layer bounds 689 1.f, // last contents scale 690 1.f, // current contents scale 691 gfx::Transform(), // last screen transform 692 gfx::Transform(), // current screen transform 693 1.0, // current frame time 694 10000); // max tiles in tile manager 695 696 // The active tiling has tiles now. 697 VerifyTiles(active_set.tiling_at(0), 698 1.f, 699 gfx::Rect(layer_bounds), 700 base::Bind(&TileExists, true)); 701 702 // Add the same tilings to the pending set. 703 PictureLayerTilingSet pending_set(&client_, layer_bounds); 704 Region invalidation; 705 pending_set.SyncTilings(active_set, layer_bounds, invalidation, 0.f); 706 707 // The pending tiling starts with no tiles. 708 VerifyTiles(pending_set.tiling_at(0), 709 1.f, 710 gfx::Rect(layer_bounds), 711 base::Bind(&TileExists, false)); 712 713 // UpdateTilePriorities on the pending tiling at the same frame time. The 714 // pending tiling should get tiles. 715 pending_set.UpdateTilePriorities( 716 PENDING_TREE, 717 layer_bounds, // device viewport 718 gfx::Rect(layer_bounds), // viewport in layer space 719 gfx::Rect(layer_bounds), // visible content rect 720 layer_bounds, // last layer bounds 721 layer_bounds, // current layer bounds 722 1.f, // last contents scale 723 1.f, // current contents scale 724 gfx::Transform(), // last screen transform 725 gfx::Transform(), // current screen transform 726 1.0, // current frame time 727 10000); // max tiles in tile manager 728 729 VerifyTiles(pending_set.tiling_at(0), 730 1.f, 731 gfx::Rect(layer_bounds), 732 base::Bind(&TileExists, true)); 733 } 734 735 TEST(UpdateTilePrioritiesTest, VisibleTiles) { 736 // The TilePriority of visible tiles should have zero distance_to_visible 737 // and time_to_visible. 738 739 FakePictureLayerTilingClient client; 740 scoped_ptr<TestablePictureLayerTiling> tiling; 741 742 gfx::Size device_viewport(800, 600); 743 gfx::Rect visible_layer_rect(0, 0, 200, 200); 744 gfx::Size last_layer_bounds(200, 200); 745 gfx::Size current_layer_bounds(200, 200); 746 float last_layer_contents_scale = 1.f; 747 float current_layer_contents_scale = 1.f; 748 gfx::Transform last_screen_transform; 749 gfx::Transform current_screen_transform; 750 double current_frame_time_in_seconds = 1.0; 751 size_t max_tiles_for_interest_area = 10000; 752 753 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( 754 current_screen_transform, device_viewport); 755 756 client.SetTileSize(gfx::Size(100, 100)); 757 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale 758 current_layer_bounds, 759 &client); 760 761 tiling->UpdateTilePriorities( 762 ACTIVE_TREE, 763 device_viewport, 764 viewport_in_layer_space, 765 visible_layer_rect, 766 last_layer_bounds, 767 current_layer_bounds, 768 last_layer_contents_scale, 769 current_layer_contents_scale, 770 last_screen_transform, 771 current_screen_transform, 772 current_frame_time_in_seconds, 773 max_tiles_for_interest_area); 774 775 ASSERT_TRUE(tiling->TileAt(0, 0)); 776 ASSERT_TRUE(tiling->TileAt(0, 1)); 777 ASSERT_TRUE(tiling->TileAt(1, 0)); 778 ASSERT_TRUE(tiling->TileAt(1, 1)); 779 780 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); 781 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels); 782 EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds); 783 784 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); 785 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels); 786 EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds); 787 788 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); 789 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels); 790 EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds); 791 792 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); 793 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels); 794 EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds); 795 } 796 797 TEST(UpdateTilePrioritiesTest, OffscreenTiles) { 798 // The TilePriority of offscreen tiles (without movement) should have nonzero 799 // distance_to_visible and infinite time_to_visible. 800 801 FakePictureLayerTilingClient client; 802 scoped_ptr<TestablePictureLayerTiling> tiling; 803 804 gfx::Size device_viewport(800, 600); 805 gfx::Rect visible_layer_rect(0, 0, 0, 0); // offscreen; nothing is visible. 806 gfx::Size last_layer_bounds(200, 200); 807 gfx::Size current_layer_bounds(200, 200); 808 float last_layer_contents_scale = 1.f; 809 float current_layer_contents_scale = 1.f; 810 gfx::Transform last_screen_transform; 811 gfx::Transform current_screen_transform; 812 double current_frame_time_in_seconds = 1.0; 813 size_t max_tiles_for_interest_area = 10000; 814 815 current_screen_transform.Translate(850, 0); 816 last_screen_transform = current_screen_transform; 817 818 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( 819 current_screen_transform, device_viewport); 820 821 client.SetTileSize(gfx::Size(100, 100)); 822 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale 823 current_layer_bounds, 824 &client); 825 826 tiling->UpdateTilePriorities( 827 ACTIVE_TREE, 828 device_viewport, 829 viewport_in_layer_space, 830 visible_layer_rect, 831 last_layer_bounds, 832 current_layer_bounds, 833 last_layer_contents_scale, 834 current_layer_contents_scale, 835 last_screen_transform, 836 current_screen_transform, 837 current_frame_time_in_seconds, 838 max_tiles_for_interest_area); 839 840 ASSERT_TRUE(tiling->TileAt(0, 0)); 841 ASSERT_TRUE(tiling->TileAt(0, 1)); 842 ASSERT_TRUE(tiling->TileAt(1, 0)); 843 ASSERT_TRUE(tiling->TileAt(1, 1)); 844 845 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); 846 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 847 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 848 priority.time_to_visible_in_seconds); 849 850 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); 851 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 852 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 853 priority.time_to_visible_in_seconds); 854 855 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); 856 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 857 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 858 priority.time_to_visible_in_seconds); 859 860 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); 861 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 862 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 863 priority.time_to_visible_in_seconds); 864 865 // Furthermore, in this scenario tiles on the right hand side should have a 866 // larger distance to visible. 867 TilePriority left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); 868 TilePriority right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); 869 EXPECT_GT(right.distance_to_visible_in_pixels, 870 left.distance_to_visible_in_pixels); 871 872 left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); 873 right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); 874 EXPECT_GT(right.distance_to_visible_in_pixels, 875 left.distance_to_visible_in_pixels); 876 } 877 878 TEST(UpdateTilePrioritiesTest, PartiallyOffscreenLayer) { 879 // Sanity check that a layer with some tiles visible and others offscreen has 880 // correct TilePriorities for each tile. 881 882 FakePictureLayerTilingClient client; 883 scoped_ptr<TestablePictureLayerTiling> tiling; 884 885 gfx::Size device_viewport(800, 600); 886 gfx::Rect visible_layer_rect(0, 0, 100, 100); // only top quarter. 887 gfx::Size last_layer_bounds(200, 200); 888 gfx::Size current_layer_bounds(200, 200); 889 float last_layer_contents_scale = 1.f; 890 float current_layer_contents_scale = 1.f; 891 gfx::Transform last_screen_transform; 892 gfx::Transform current_screen_transform; 893 double current_frame_time_in_seconds = 1.0; 894 size_t max_tiles_for_interest_area = 10000; 895 896 current_screen_transform.Translate(705, 505); 897 last_screen_transform = current_screen_transform; 898 899 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( 900 current_screen_transform, device_viewport); 901 902 client.SetTileSize(gfx::Size(100, 100)); 903 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale 904 current_layer_bounds, 905 &client); 906 907 tiling->UpdateTilePriorities( 908 ACTIVE_TREE, 909 device_viewport, 910 viewport_in_layer_space, 911 visible_layer_rect, 912 last_layer_bounds, 913 current_layer_bounds, 914 last_layer_contents_scale, 915 current_layer_contents_scale, 916 last_screen_transform, 917 current_screen_transform, 918 current_frame_time_in_seconds, 919 max_tiles_for_interest_area); 920 921 ASSERT_TRUE(tiling->TileAt(0, 0)); 922 ASSERT_TRUE(tiling->TileAt(0, 1)); 923 ASSERT_TRUE(tiling->TileAt(1, 0)); 924 ASSERT_TRUE(tiling->TileAt(1, 1)); 925 926 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); 927 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels); 928 EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds); 929 930 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); 931 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 932 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 933 priority.time_to_visible_in_seconds); 934 935 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); 936 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 937 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 938 priority.time_to_visible_in_seconds); 939 940 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); 941 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 942 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 943 priority.time_to_visible_in_seconds); 944 } 945 946 TEST(UpdateTilePrioritiesTest, PartiallyOffscreenRotatedLayer) { 947 // Each tile of a layer may be affected differently by a transform; Check 948 // that UpdateTilePriorities correctly accounts for the transform between 949 // layer space and screen space. 950 951 FakePictureLayerTilingClient client; 952 scoped_ptr<TestablePictureLayerTiling> tiling; 953 954 gfx::Size device_viewport(800, 600); 955 gfx::Rect visible_layer_rect(0, 0, 100, 100); // only top-left quarter. 956 gfx::Size last_layer_bounds(200, 200); 957 gfx::Size current_layer_bounds(200, 200); 958 float last_layer_contents_scale = 1.f; 959 float current_layer_contents_scale = 1.f; 960 gfx::Transform last_screen_transform; 961 gfx::Transform current_screen_transform; 962 double current_frame_time_in_seconds = 1.0; 963 size_t max_tiles_for_interest_area = 10000; 964 965 // A diagonally rotated layer that is partially off the bottom of the screen. 966 // In this configuration, only the top-left tile would be visible. 967 current_screen_transform.Translate(400, 550); 968 current_screen_transform.RotateAboutZAxis(45); 969 last_screen_transform = current_screen_transform; 970 971 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( 972 current_screen_transform, device_viewport); 973 974 client.SetTileSize(gfx::Size(100, 100)); 975 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale 976 current_layer_bounds, 977 &client); 978 979 tiling->UpdateTilePriorities( 980 ACTIVE_TREE, 981 device_viewport, 982 viewport_in_layer_space, 983 visible_layer_rect, 984 last_layer_bounds, 985 current_layer_bounds, 986 last_layer_contents_scale, 987 current_layer_contents_scale, 988 last_screen_transform, 989 current_screen_transform, 990 current_frame_time_in_seconds, 991 max_tiles_for_interest_area); 992 993 ASSERT_TRUE(tiling->TileAt(0, 0)); 994 ASSERT_TRUE(tiling->TileAt(0, 1)); 995 ASSERT_TRUE(tiling->TileAt(1, 0)); 996 ASSERT_TRUE(tiling->TileAt(1, 1)); 997 998 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); 999 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels); 1000 EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds); 1001 1002 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); 1003 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1004 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 1005 priority.time_to_visible_in_seconds); 1006 1007 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); 1008 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1009 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 1010 priority.time_to_visible_in_seconds); 1011 1012 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); 1013 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1014 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 1015 priority.time_to_visible_in_seconds); 1016 1017 // Furthermore, in this scenario the bottom-right tile should have the larger 1018 // distance to visible. 1019 TilePriority top_left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); 1020 TilePriority top_right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); 1021 TilePriority bottom_left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); 1022 TilePriority bottom_right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); 1023 EXPECT_GT(top_right.distance_to_visible_in_pixels, 1024 top_left.distance_to_visible_in_pixels); 1025 EXPECT_GT(bottom_left.distance_to_visible_in_pixels, 1026 top_left.distance_to_visible_in_pixels); 1027 1028 EXPECT_GT(bottom_right.distance_to_visible_in_pixels, 1029 bottom_left.distance_to_visible_in_pixels); 1030 EXPECT_GT(bottom_right.distance_to_visible_in_pixels, 1031 top_right.distance_to_visible_in_pixels); 1032 } 1033 1034 TEST(UpdateTilePrioritiesTest, PerspectiveLayer) { 1035 // Perspective transforms need to take a different code path. 1036 // This test checks tile priorities of a perspective layer. 1037 1038 FakePictureLayerTilingClient client; 1039 scoped_ptr<TestablePictureLayerTiling> tiling; 1040 1041 gfx::Size device_viewport(800, 600); 1042 gfx::Rect visible_layer_rect(0, 0, 0, 0); // offscreen. 1043 gfx::Size last_layer_bounds(200, 200); 1044 gfx::Size current_layer_bounds(200, 200); 1045 float last_layer_contents_scale = 1.f; 1046 float current_layer_contents_scale = 1.f; 1047 gfx::Transform last_screen_transform; 1048 gfx::Transform current_screen_transform; 1049 double current_frame_time_in_seconds = 1.0; 1050 size_t max_tiles_for_interest_area = 10000; 1051 1052 // A 3d perspective layer rotated about its Y axis, translated to almost 1053 // fully offscreen. The left side will appear closer (i.e. larger in 2d) than 1054 // the right side, so the top-left tile will technically be closer than the 1055 // top-right. 1056 1057 // Translate layer to offscreen 1058 current_screen_transform.Translate(400.0, 630.0); 1059 // Apply perspective about the center of the layer 1060 current_screen_transform.Translate(100.0, 100.0); 1061 current_screen_transform.ApplyPerspectiveDepth(100.0); 1062 current_screen_transform.RotateAboutYAxis(10.0); 1063 current_screen_transform.Translate(-100.0, -100.0); 1064 last_screen_transform = current_screen_transform; 1065 1066 // Sanity check that this transform wouldn't cause w<0 clipping. 1067 bool clipped; 1068 MathUtil::MapQuad(current_screen_transform, 1069 gfx::QuadF(gfx::RectF(0, 0, 200, 200)), 1070 &clipped); 1071 ASSERT_FALSE(clipped); 1072 1073 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( 1074 current_screen_transform, device_viewport); 1075 1076 client.SetTileSize(gfx::Size(100, 100)); 1077 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale 1078 current_layer_bounds, 1079 &client); 1080 1081 tiling->UpdateTilePriorities( 1082 ACTIVE_TREE, 1083 device_viewport, 1084 viewport_in_layer_space, 1085 visible_layer_rect, 1086 last_layer_bounds, 1087 current_layer_bounds, 1088 last_layer_contents_scale, 1089 current_layer_contents_scale, 1090 last_screen_transform, 1091 current_screen_transform, 1092 current_frame_time_in_seconds, 1093 max_tiles_for_interest_area); 1094 1095 ASSERT_TRUE(tiling->TileAt(0, 0)); 1096 ASSERT_TRUE(tiling->TileAt(0, 1)); 1097 ASSERT_TRUE(tiling->TileAt(1, 0)); 1098 ASSERT_TRUE(tiling->TileAt(1, 1)); 1099 1100 // All tiles will have a positive distance_to_visible 1101 // and an infinite time_to_visible. 1102 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); 1103 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1104 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 1105 priority.time_to_visible_in_seconds); 1106 1107 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); 1108 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1109 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 1110 priority.time_to_visible_in_seconds); 1111 1112 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); 1113 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1114 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 1115 priority.time_to_visible_in_seconds); 1116 1117 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); 1118 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1119 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 1120 priority.time_to_visible_in_seconds); 1121 1122 // Furthermore, in this scenario the top-left distance_to_visible 1123 // will be smallest, followed by top-right. The bottom layers 1124 // will of course be further than the top layers. 1125 TilePriority top_left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); 1126 TilePriority top_right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); 1127 TilePriority bottom_left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); 1128 TilePriority bottom_right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); 1129 EXPECT_GT(top_right.distance_to_visible_in_pixels, 1130 top_left.distance_to_visible_in_pixels); 1131 1132 EXPECT_GT(bottom_right.distance_to_visible_in_pixels, 1133 top_right.distance_to_visible_in_pixels); 1134 1135 EXPECT_GT(bottom_left.distance_to_visible_in_pixels, 1136 top_left.distance_to_visible_in_pixels); 1137 } 1138 1139 TEST(UpdateTilePrioritiesTest, PerspectiveLayerClippedByW) { 1140 // Perspective transforms need to take a different code path. 1141 // This test checks tile priorities of a perspective layer. 1142 1143 FakePictureLayerTilingClient client; 1144 scoped_ptr<TestablePictureLayerTiling> tiling; 1145 1146 gfx::Size device_viewport(800, 600); 1147 gfx::Rect visible_layer_rect(0, 0, 0, 0); // offscreen. 1148 gfx::Size last_layer_bounds(200, 200); 1149 gfx::Size current_layer_bounds(200, 200); 1150 float last_layer_contents_scale = 1.f; 1151 float current_layer_contents_scale = 1.f; 1152 gfx::Transform last_screen_transform; 1153 gfx::Transform current_screen_transform; 1154 double current_frame_time_in_seconds = 1.0; 1155 size_t max_tiles_for_interest_area = 10000; 1156 1157 // A 3d perspective layer rotated about its Y axis, translated to almost 1158 // fully offscreen. The left side will appear closer (i.e. larger in 2d) than 1159 // the right side, so the top-left tile will technically be closer than the 1160 // top-right. 1161 1162 // Translate layer to offscreen 1163 current_screen_transform.Translate(400.0, 970.0); 1164 // Apply perspective and rotation about the center of the layer 1165 current_screen_transform.Translate(100.0, 100.0); 1166 current_screen_transform.ApplyPerspectiveDepth(10.0); 1167 current_screen_transform.RotateAboutYAxis(10.0); 1168 current_screen_transform.Translate(-100.0, -100.0); 1169 last_screen_transform = current_screen_transform; 1170 1171 // Sanity check that this transform does cause w<0 clipping for the left side 1172 // of the layer, but not the right side. 1173 bool clipped; 1174 MathUtil::MapQuad(current_screen_transform, 1175 gfx::QuadF(gfx::RectF(0, 0, 100, 200)), 1176 &clipped); 1177 ASSERT_TRUE(clipped); 1178 1179 MathUtil::MapQuad(current_screen_transform, 1180 gfx::QuadF(gfx::RectF(100, 0, 100, 200)), 1181 &clipped); 1182 ASSERT_FALSE(clipped); 1183 1184 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( 1185 current_screen_transform, device_viewport); 1186 1187 client.SetTileSize(gfx::Size(100, 100)); 1188 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale 1189 current_layer_bounds, 1190 &client); 1191 1192 tiling->UpdateTilePriorities( 1193 ACTIVE_TREE, 1194 device_viewport, 1195 viewport_in_layer_space, 1196 visible_layer_rect, 1197 last_layer_bounds, 1198 current_layer_bounds, 1199 last_layer_contents_scale, 1200 current_layer_contents_scale, 1201 last_screen_transform, 1202 current_screen_transform, 1203 current_frame_time_in_seconds, 1204 max_tiles_for_interest_area); 1205 1206 ASSERT_TRUE(tiling->TileAt(0, 0)); 1207 ASSERT_TRUE(tiling->TileAt(0, 1)); 1208 ASSERT_TRUE(tiling->TileAt(1, 0)); 1209 ASSERT_TRUE(tiling->TileAt(1, 1)); 1210 1211 // Left-side tiles will be clipped by the transform, so we have to assume 1212 // they are visible just in case. 1213 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); 1214 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels); 1215 EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds); 1216 1217 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); 1218 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels); 1219 EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds); 1220 1221 // Right-side tiles will have a positive distance_to_visible 1222 // and an infinite time_to_visible. 1223 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); 1224 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1225 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 1226 priority.time_to_visible_in_seconds); 1227 1228 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); 1229 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1230 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 1231 priority.time_to_visible_in_seconds); 1232 } 1233 1234 TEST(UpdateTilePrioritiesTest, BasicMotion) { 1235 // Test that time_to_visible is computed correctly when 1236 // there is some motion. 1237 1238 FakePictureLayerTilingClient client; 1239 scoped_ptr<TestablePictureLayerTiling> tiling; 1240 1241 gfx::Size device_viewport(800, 600); 1242 gfx::Rect visible_layer_rect(0, 0, 0, 0); 1243 gfx::Size last_layer_bounds(200, 200); 1244 gfx::Size current_layer_bounds(200, 200); 1245 float last_layer_contents_scale = 1.f; 1246 float current_layer_contents_scale = 1.f; 1247 gfx::Transform last_screen_transform; 1248 gfx::Transform current_screen_transform; 1249 double last_frame_time_in_seconds = 1.0; 1250 double current_frame_time_in_seconds = 2.0; 1251 size_t max_tiles_for_interest_area = 10000; 1252 1253 // Offscreen layer is coming closer to viewport at 1000 pixels per second. 1254 current_screen_transform.Translate(1800, 0); 1255 last_screen_transform.Translate(2800, 0); 1256 1257 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( 1258 current_screen_transform, device_viewport); 1259 1260 client.SetTileSize(gfx::Size(100, 100)); 1261 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale 1262 current_layer_bounds, 1263 &client); 1264 1265 // previous ("last") frame 1266 tiling->UpdateTilePriorities( 1267 ACTIVE_TREE, 1268 device_viewport, 1269 viewport_in_layer_space, 1270 visible_layer_rect, 1271 last_layer_bounds, 1272 last_layer_bounds, 1273 last_layer_contents_scale, 1274 last_layer_contents_scale, 1275 last_screen_transform, 1276 last_screen_transform, 1277 last_frame_time_in_seconds, 1278 max_tiles_for_interest_area); 1279 1280 // current frame 1281 tiling->UpdateTilePriorities( 1282 ACTIVE_TREE, 1283 device_viewport, 1284 viewport_in_layer_space, 1285 visible_layer_rect, 1286 last_layer_bounds, 1287 current_layer_bounds, 1288 last_layer_contents_scale, 1289 current_layer_contents_scale, 1290 last_screen_transform, 1291 current_screen_transform, 1292 current_frame_time_in_seconds, 1293 max_tiles_for_interest_area); 1294 1295 ASSERT_TRUE(tiling->TileAt(0, 0)); 1296 ASSERT_TRUE(tiling->TileAt(0, 1)); 1297 ASSERT_TRUE(tiling->TileAt(1, 0)); 1298 ASSERT_TRUE(tiling->TileAt(1, 1)); 1299 1300 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); 1301 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1302 EXPECT_FLOAT_EQ(1.f, 1303 priority.time_to_visible_in_seconds); 1304 1305 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); 1306 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1307 EXPECT_FLOAT_EQ(1.f, 1308 priority.time_to_visible_in_seconds); 1309 1310 // time_to_visible for the right hand side layers needs an extra 0.099 1311 // seconds because this tile is 99 pixels further away. 1312 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); 1313 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1314 EXPECT_FLOAT_EQ(1.099f, 1315 priority.time_to_visible_in_seconds); 1316 1317 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); 1318 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1319 EXPECT_FLOAT_EQ(1.099f, 1320 priority.time_to_visible_in_seconds); 1321 } 1322 1323 TEST(UpdateTilePrioritiesTest, RotationMotion) { 1324 // Each tile of a layer may be affected differently by a transform; Check 1325 // that UpdateTilePriorities correctly accounts for the transform between 1326 // layer space and screen space. 1327 1328 FakePictureLayerTilingClient client; 1329 scoped_ptr<TestablePictureLayerTiling> tiling; 1330 1331 gfx::Size device_viewport(800, 600); 1332 gfx::Rect visible_layer_rect(0, 0, 0, 0); // offscren. 1333 gfx::Size last_layer_bounds(200, 200); 1334 gfx::Size current_layer_bounds(200, 200); 1335 float last_layer_contents_scale = 1.f; 1336 float current_layer_contents_scale = 1.f; 1337 gfx::Transform last_screen_transform; 1338 gfx::Transform current_screen_transform; 1339 double last_frame_time_in_seconds = 1.0; 1340 double current_frame_time_in_seconds = 2.0; 1341 size_t max_tiles_for_interest_area = 10000; 1342 1343 // Rotation motion is set up specifically so that: 1344 // - rotation occurs about the center of the layer 1345 // - the top-left tile becomes visible on rotation 1346 // - the top-right tile will have an infinite time_to_visible 1347 // because it is rotating away from viewport. 1348 // - bottom-left layer will have a positive non-zero time_to_visible 1349 // because it is rotating toward the viewport. 1350 current_screen_transform.Translate(400, 550); 1351 current_screen_transform.RotateAboutZAxis(45); 1352 1353 last_screen_transform.Translate(400, 550); 1354 1355 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( 1356 current_screen_transform, device_viewport); 1357 1358 client.SetTileSize(gfx::Size(100, 100)); 1359 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale 1360 current_layer_bounds, 1361 &client); 1362 1363 // previous ("last") frame 1364 tiling->UpdateTilePriorities( 1365 ACTIVE_TREE, 1366 device_viewport, 1367 viewport_in_layer_space, 1368 visible_layer_rect, 1369 last_layer_bounds, 1370 last_layer_bounds, 1371 last_layer_contents_scale, 1372 last_layer_contents_scale, 1373 last_screen_transform, 1374 last_screen_transform, 1375 last_frame_time_in_seconds, 1376 max_tiles_for_interest_area); 1377 1378 // current frame 1379 tiling->UpdateTilePriorities( 1380 ACTIVE_TREE, 1381 device_viewport, 1382 viewport_in_layer_space, 1383 visible_layer_rect, 1384 last_layer_bounds, 1385 current_layer_bounds, 1386 last_layer_contents_scale, 1387 current_layer_contents_scale, 1388 last_screen_transform, 1389 current_screen_transform, 1390 current_frame_time_in_seconds, 1391 max_tiles_for_interest_area); 1392 1393 ASSERT_TRUE(tiling->TileAt(0, 0)); 1394 ASSERT_TRUE(tiling->TileAt(0, 1)); 1395 ASSERT_TRUE(tiling->TileAt(1, 0)); 1396 ASSERT_TRUE(tiling->TileAt(1, 1)); 1397 1398 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); 1399 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels); 1400 EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds); 1401 1402 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); 1403 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1404 EXPECT_GT(priority.time_to_visible_in_seconds, 0.f); 1405 1406 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); 1407 EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f); 1408 EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(), 1409 priority.time_to_visible_in_seconds); 1410 } 1411 1412 } // namespace 1413 } // namespace cc 1414