1// Copyright 2013 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.h" 6 7#include "base/memory/ref_counted.h" 8#include "base/memory/scoped_ptr.h" 9#include "base/values.h" 10#include "cc/test/fake_content_layer_client.h" 11#include "cc/test/skia_common.h" 12#include "testing/gtest/include/gtest/gtest.h" 13#include "third_party/skia/include/core/SkBBHFactory.h" 14#include "third_party/skia/include/core/SkCanvas.h" 15#include "third_party/skia/include/core/SkGraphics.h" 16#include "third_party/skia/include/core/SkPixelRef.h" 17#include "ui/gfx/rect.h" 18#include "ui/gfx/skia_util.h" 19 20namespace cc { 21namespace { 22 23TEST(PictureTest, AsBase64String) { 24 SkGraphics::Init(); 25 26 gfx::Rect layer_rect(100, 100); 27 28 SkTileGridFactory::TileGridInfo tile_grid_info; 29 tile_grid_info.fTileInterval = SkISize::Make(100, 100); 30 tile_grid_info.fMargin.setEmpty(); 31 tile_grid_info.fOffset.setZero(); 32 33 FakeContentLayerClient content_layer_client; 34 35 scoped_ptr<base::Value> tmp; 36 37 SkPaint red_paint; 38 red_paint.setColor(SkColorSetARGB(255, 255, 0, 0)); 39 SkPaint green_paint; 40 green_paint.setColor(SkColorSetARGB(255, 0, 255, 0)); 41 42 // Invalid picture (not a dict). 43 tmp.reset(new base::StringValue("abc!@#$%")); 44 scoped_refptr<Picture> invalid_picture = 45 Picture::CreateFromValue(tmp.get()); 46 EXPECT_FALSE(invalid_picture.get()); 47 48 Picture::RecordingMode kRecordingModes[] = {Picture::RECORD_NORMALLY, 49 Picture::RECORD_WITH_SKRECORD}; 50 51 // Single full-size rect picture. 52 content_layer_client.add_draw_rect(layer_rect, red_paint); 53 54 for (size_t i = 0; i < arraysize(kRecordingModes); ++i) { 55 scoped_refptr<Picture> one_rect_picture = 56 Picture::Create(layer_rect, 57 &content_layer_client, 58 tile_grid_info, 59 false, 60 0, 61 kRecordingModes[i]); 62 scoped_ptr<base::Value> serialized_one_rect(one_rect_picture->AsValue()); 63 64 // Reconstruct the picture. 65 scoped_refptr<Picture> one_rect_picture_check = 66 Picture::CreateFromValue(serialized_one_rect.get()); 67 EXPECT_TRUE(!!one_rect_picture_check.get()); 68 69 // Check for equivalence. 70 unsigned char one_rect_buffer[4 * 100 * 100] = {0}; 71 DrawPicture(one_rect_buffer, layer_rect, one_rect_picture); 72 unsigned char one_rect_buffer_check[4 * 100 * 100] = {0}; 73 DrawPicture(one_rect_buffer_check, layer_rect, one_rect_picture_check); 74 75 EXPECT_EQ(one_rect_picture->LayerRect(), 76 one_rect_picture_check->LayerRect()); 77 EXPECT_EQ(one_rect_picture->OpaqueRect(), 78 one_rect_picture_check->OpaqueRect()); 79 EXPECT_TRUE(memcmp(one_rect_buffer, one_rect_buffer_check, 4 * 100 * 100) == 80 0); 81 } 82 83 // Two rect picture. 84 content_layer_client.add_draw_rect(gfx::Rect(25, 25, 50, 50), green_paint); 85 86 for (size_t i = 0; i < arraysize(kRecordingModes); ++i) { 87 scoped_refptr<Picture> two_rect_picture = 88 Picture::Create(layer_rect, 89 &content_layer_client, 90 tile_grid_info, 91 false, 92 0, 93 Picture::RECORD_NORMALLY); 94 95 scoped_ptr<base::Value> serialized_two_rect(two_rect_picture->AsValue()); 96 97 // Reconstruct the picture. 98 scoped_refptr<Picture> two_rect_picture_check = 99 Picture::CreateFromValue(serialized_two_rect.get()); 100 EXPECT_TRUE(!!two_rect_picture_check.get()); 101 102 // Check for equivalence. 103 unsigned char two_rect_buffer[4 * 100 * 100] = {0}; 104 DrawPicture(two_rect_buffer, layer_rect, two_rect_picture); 105 unsigned char two_rect_buffer_check[4 * 100 * 100] = {0}; 106 DrawPicture(two_rect_buffer_check, layer_rect, two_rect_picture_check); 107 108 EXPECT_EQ(two_rect_picture->LayerRect(), 109 two_rect_picture_check->LayerRect()); 110 EXPECT_EQ(two_rect_picture->OpaqueRect(), 111 two_rect_picture_check->OpaqueRect()); 112 EXPECT_TRUE(memcmp(two_rect_buffer, two_rect_buffer_check, 4 * 100 * 100) == 113 0); 114 } 115} 116 117TEST(PictureTest, PixelRefIterator) { 118 gfx::Rect layer_rect(2048, 2048); 119 120 SkTileGridFactory::TileGridInfo tile_grid_info; 121 tile_grid_info.fTileInterval = SkISize::Make(512, 512); 122 tile_grid_info.fMargin.setEmpty(); 123 tile_grid_info.fOffset.setZero(); 124 125 FakeContentLayerClient content_layer_client; 126 127 // Discardable pixel refs are found in the following grids: 128 // |---|---|---|---| 129 // | | x | | x | 130 // |---|---|---|---| 131 // | x | | x | | 132 // |---|---|---|---| 133 // | | x | | x | 134 // |---|---|---|---| 135 // | x | | x | | 136 // |---|---|---|---| 137 SkBitmap discardable_bitmap[4][4]; 138 for (int y = 0; y < 4; ++y) { 139 for (int x = 0; x < 4; ++x) { 140 if ((x + y) & 1) { 141 CreateBitmap( 142 gfx::Size(500, 500), "discardable", &discardable_bitmap[y][x]); 143 SkPaint paint; 144 content_layer_client.add_draw_bitmap( 145 discardable_bitmap[y][x], 146 gfx::Point(x * 512 + 6, y * 512 + 6), paint); 147 } 148 } 149 } 150 151 scoped_refptr<Picture> picture = Picture::Create(layer_rect, 152 &content_layer_client, 153 tile_grid_info, 154 true, 155 0, 156 Picture::RECORD_NORMALLY); 157 158 // Default iterator does not have any pixel refs 159 { 160 Picture::PixelRefIterator iterator; 161 EXPECT_FALSE(iterator); 162 } 163 for (int y = 0; y < 4; ++y) { 164 for (int x = 0; x < 4; ++x) { 165 Picture::PixelRefIterator iterator(gfx::Rect(x * 512, y * 512, 500, 500), 166 picture.get()); 167 if ((x + y) & 1) { 168 EXPECT_TRUE(iterator) << x << " " << y; 169 EXPECT_TRUE(*iterator == discardable_bitmap[y][x].pixelRef()) << x << 170 " " << y; 171 EXPECT_FALSE(++iterator) << x << " " << y; 172 } else { 173 EXPECT_FALSE(iterator) << x << " " << y; 174 } 175 } 176 } 177 // Capture 4 pixel refs. 178 { 179 Picture::PixelRefIterator iterator(gfx::Rect(512, 512, 2048, 2048), 180 picture.get()); 181 EXPECT_TRUE(iterator); 182 EXPECT_TRUE(*iterator == discardable_bitmap[1][2].pixelRef()); 183 EXPECT_TRUE(++iterator); 184 EXPECT_TRUE(*iterator == discardable_bitmap[2][1].pixelRef()); 185 EXPECT_TRUE(++iterator); 186 EXPECT_TRUE(*iterator == discardable_bitmap[2][3].pixelRef()); 187 EXPECT_TRUE(++iterator); 188 EXPECT_TRUE(*iterator == discardable_bitmap[3][2].pixelRef()); 189 EXPECT_FALSE(++iterator); 190 } 191 192 // Copy test. 193 Picture::PixelRefIterator iterator(gfx::Rect(512, 512, 2048, 2048), 194 picture.get()); 195 EXPECT_TRUE(iterator); 196 EXPECT_TRUE(*iterator == discardable_bitmap[1][2].pixelRef()); 197 EXPECT_TRUE(++iterator); 198 EXPECT_TRUE(*iterator == discardable_bitmap[2][1].pixelRef()); 199 200 // copy now points to the same spot as iterator, 201 // but both can be incremented independently. 202 Picture::PixelRefIterator copy = iterator; 203 EXPECT_TRUE(++iterator); 204 EXPECT_TRUE(*iterator == discardable_bitmap[2][3].pixelRef()); 205 EXPECT_TRUE(++iterator); 206 EXPECT_TRUE(*iterator == discardable_bitmap[3][2].pixelRef()); 207 EXPECT_FALSE(++iterator); 208 209 EXPECT_TRUE(copy); 210 EXPECT_TRUE(*copy == discardable_bitmap[2][1].pixelRef()); 211 EXPECT_TRUE(++copy); 212 EXPECT_TRUE(*copy == discardable_bitmap[2][3].pixelRef()); 213 EXPECT_TRUE(++copy); 214 EXPECT_TRUE(*copy == discardable_bitmap[3][2].pixelRef()); 215 EXPECT_FALSE(++copy); 216} 217 218TEST(PictureTest, PixelRefIteratorNonZeroLayer) { 219 gfx::Rect layer_rect(1024, 0, 2048, 2048); 220 221 SkTileGridFactory::TileGridInfo tile_grid_info; 222 tile_grid_info.fTileInterval = SkISize::Make(512, 512); 223 tile_grid_info.fMargin.setEmpty(); 224 tile_grid_info.fOffset.setZero(); 225 226 FakeContentLayerClient content_layer_client; 227 228 // Discardable pixel refs are found in the following grids: 229 // |---|---|---|---| 230 // | | x | | x | 231 // |---|---|---|---| 232 // | x | | x | | 233 // |---|---|---|---| 234 // | | x | | x | 235 // |---|---|---|---| 236 // | x | | x | | 237 // |---|---|---|---| 238 SkBitmap discardable_bitmap[4][4]; 239 for (int y = 0; y < 4; ++y) { 240 for (int x = 0; x < 4; ++x) { 241 if ((x + y) & 1) { 242 CreateBitmap( 243 gfx::Size(500, 500), "discardable", &discardable_bitmap[y][x]); 244 SkPaint paint; 245 content_layer_client.add_draw_bitmap( 246 discardable_bitmap[y][x], 247 gfx::Point(1024 + x * 512 + 6, y * 512 + 6), paint); 248 } 249 } 250 } 251 252 scoped_refptr<Picture> picture = Picture::Create(layer_rect, 253 &content_layer_client, 254 tile_grid_info, 255 true, 256 0, 257 Picture::RECORD_NORMALLY); 258 259 // Default iterator does not have any pixel refs 260 { 261 Picture::PixelRefIterator iterator; 262 EXPECT_FALSE(iterator); 263 } 264 for (int y = 0; y < 4; ++y) { 265 for (int x = 0; x < 4; ++x) { 266 Picture::PixelRefIterator iterator( 267 gfx::Rect(1024 + x * 512, y * 512, 500, 500), picture.get()); 268 if ((x + y) & 1) { 269 EXPECT_TRUE(iterator) << x << " " << y; 270 EXPECT_TRUE(*iterator == discardable_bitmap[y][x].pixelRef()); 271 EXPECT_FALSE(++iterator) << x << " " << y; 272 } else { 273 EXPECT_FALSE(iterator) << x << " " << y; 274 } 275 } 276 } 277 // Capture 4 pixel refs. 278 { 279 Picture::PixelRefIterator iterator(gfx::Rect(1024 + 512, 512, 2048, 2048), 280 picture.get()); 281 EXPECT_TRUE(iterator); 282 EXPECT_TRUE(*iterator == discardable_bitmap[1][2].pixelRef()); 283 EXPECT_TRUE(++iterator); 284 EXPECT_TRUE(*iterator == discardable_bitmap[2][1].pixelRef()); 285 EXPECT_TRUE(++iterator); 286 EXPECT_TRUE(*iterator == discardable_bitmap[2][3].pixelRef()); 287 EXPECT_TRUE(++iterator); 288 EXPECT_TRUE(*iterator == discardable_bitmap[3][2].pixelRef()); 289 EXPECT_FALSE(++iterator); 290 } 291 292 // Copy test. 293 { 294 Picture::PixelRefIterator iterator(gfx::Rect(1024 + 512, 512, 2048, 2048), 295 picture.get()); 296 EXPECT_TRUE(iterator); 297 EXPECT_TRUE(*iterator == discardable_bitmap[1][2].pixelRef()); 298 EXPECT_TRUE(++iterator); 299 EXPECT_TRUE(*iterator == discardable_bitmap[2][1].pixelRef()); 300 301 // copy now points to the same spot as iterator, 302 // but both can be incremented independently. 303 Picture::PixelRefIterator copy = iterator; 304 EXPECT_TRUE(++iterator); 305 EXPECT_TRUE(*iterator == discardable_bitmap[2][3].pixelRef()); 306 EXPECT_TRUE(++iterator); 307 EXPECT_TRUE(*iterator == discardable_bitmap[3][2].pixelRef()); 308 EXPECT_FALSE(++iterator); 309 310 EXPECT_TRUE(copy); 311 EXPECT_TRUE(*copy == discardable_bitmap[2][1].pixelRef()); 312 EXPECT_TRUE(++copy); 313 EXPECT_TRUE(*copy == discardable_bitmap[2][3].pixelRef()); 314 EXPECT_TRUE(++copy); 315 EXPECT_TRUE(*copy == discardable_bitmap[3][2].pixelRef()); 316 EXPECT_FALSE(++copy); 317 } 318 319 // Non intersecting rects 320 { 321 Picture::PixelRefIterator iterator(gfx::Rect(0, 0, 1000, 1000), 322 picture.get()); 323 EXPECT_FALSE(iterator); 324 } 325 { 326 Picture::PixelRefIterator iterator(gfx::Rect(3500, 0, 1000, 1000), 327 picture.get()); 328 EXPECT_FALSE(iterator); 329 } 330 { 331 Picture::PixelRefIterator iterator(gfx::Rect(0, 1100, 1000, 1000), 332 picture.get()); 333 EXPECT_FALSE(iterator); 334 } 335 { 336 Picture::PixelRefIterator iterator(gfx::Rect(3500, 1100, 1000, 1000), 337 picture.get()); 338 EXPECT_FALSE(iterator); 339 } 340} 341 342TEST(PictureTest, PixelRefIteratorOnePixelQuery) { 343 gfx::Rect layer_rect(2048, 2048); 344 345 SkTileGridFactory::TileGridInfo tile_grid_info; 346 tile_grid_info.fTileInterval = SkISize::Make(512, 512); 347 tile_grid_info.fMargin.setEmpty(); 348 tile_grid_info.fOffset.setZero(); 349 350 FakeContentLayerClient content_layer_client; 351 352 // Discardable pixel refs are found in the following grids: 353 // |---|---|---|---| 354 // | | x | | x | 355 // |---|---|---|---| 356 // | x | | x | | 357 // |---|---|---|---| 358 // | | x | | x | 359 // |---|---|---|---| 360 // | x | | x | | 361 // |---|---|---|---| 362 SkBitmap discardable_bitmap[4][4]; 363 for (int y = 0; y < 4; ++y) { 364 for (int x = 0; x < 4; ++x) { 365 if ((x + y) & 1) { 366 CreateBitmap( 367 gfx::Size(500, 500), "discardable", &discardable_bitmap[y][x]); 368 SkPaint paint; 369 content_layer_client.add_draw_bitmap( 370 discardable_bitmap[y][x], 371 gfx::Point(x * 512 + 6, y * 512 + 6), paint); 372 } 373 } 374 } 375 376 scoped_refptr<Picture> picture = Picture::Create(layer_rect, 377 &content_layer_client, 378 tile_grid_info, 379 true, 380 0, 381 Picture::RECORD_NORMALLY); 382 383 for (int y = 0; y < 4; ++y) { 384 for (int x = 0; x < 4; ++x) { 385 Picture::PixelRefIterator iterator( 386 gfx::Rect(x * 512, y * 512 + 256, 1, 1), picture.get()); 387 if ((x + y) & 1) { 388 EXPECT_TRUE(iterator) << x << " " << y; 389 EXPECT_TRUE(*iterator == discardable_bitmap[y][x].pixelRef()); 390 EXPECT_FALSE(++iterator) << x << " " << y; 391 } else { 392 EXPECT_FALSE(iterator) << x << " " << y; 393 } 394 } 395 } 396} 397 398TEST(PictureTest, CreateFromSkpValue) { 399 SkGraphics::Init(); 400 401 gfx::Rect layer_rect(100, 200); 402 403 SkTileGridFactory::TileGridInfo tile_grid_info; 404 tile_grid_info.fTileInterval = SkISize::Make(100, 200); 405 tile_grid_info.fMargin.setEmpty(); 406 tile_grid_info.fOffset.setZero(); 407 408 FakeContentLayerClient content_layer_client; 409 410 scoped_ptr<base::Value> tmp; 411 412 SkPaint red_paint; 413 red_paint.setColor(SkColorSetARGB(255, 255, 0, 0)); 414 SkPaint green_paint; 415 green_paint.setColor(SkColorSetARGB(255, 0, 255, 0)); 416 417 // Invalid picture (not a dict). 418 tmp.reset(new base::StringValue("abc!@#$%")); 419 scoped_refptr<Picture> invalid_picture = 420 Picture::CreateFromSkpValue(tmp.get()); 421 EXPECT_TRUE(!invalid_picture.get()); 422 423 // Single full-size rect picture. 424 content_layer_client.add_draw_rect(layer_rect, red_paint); 425 scoped_refptr<Picture> one_rect_picture = 426 Picture::Create(layer_rect, 427 &content_layer_client, 428 tile_grid_info, 429 false, 430 0, 431 Picture::RECORD_NORMALLY); 432 scoped_ptr<base::Value> serialized_one_rect( 433 one_rect_picture->AsValue()); 434 435 const base::DictionaryValue* value = NULL; 436 EXPECT_TRUE(serialized_one_rect->GetAsDictionary(&value)); 437 438 // Decode the picture from base64. 439 const base::Value* skp_value; 440 EXPECT_TRUE(value->Get("skp64", &skp_value)); 441 442 // Reconstruct the picture. 443 scoped_refptr<Picture> one_rect_picture_check = 444 Picture::CreateFromSkpValue(skp_value); 445 EXPECT_TRUE(!!one_rect_picture_check.get()); 446 447 EXPECT_EQ(100, one_rect_picture_check->LayerRect().width()); 448 EXPECT_EQ(200, one_rect_picture_check->LayerRect().height()); 449 EXPECT_EQ(100, one_rect_picture_check->OpaqueRect().width()); 450 EXPECT_EQ(200, one_rect_picture_check->OpaqueRect().height()); 451} 452 453TEST(PictureTest, RecordingModes) { 454 SkGraphics::Init(); 455 456 gfx::Rect layer_rect(100, 200); 457 458 SkTileGridFactory::TileGridInfo tile_grid_info; 459 tile_grid_info.fTileInterval = SkISize::Make(100, 200); 460 tile_grid_info.fMargin.setEmpty(); 461 tile_grid_info.fOffset.setZero(); 462 463 FakeContentLayerClient content_layer_client; 464 EXPECT_EQ(NULL, content_layer_client.last_canvas()); 465 466 scoped_refptr<Picture> picture = Picture::Create(layer_rect, 467 &content_layer_client, 468 tile_grid_info, 469 false, 470 0, 471 Picture::RECORD_NORMALLY); 472 EXPECT_TRUE(content_layer_client.last_canvas() != NULL); 473 EXPECT_EQ(ContentLayerClient::GRAPHICS_CONTEXT_ENABLED, 474 content_layer_client.last_context_status()); 475 EXPECT_TRUE(picture); 476 477 picture = Picture::Create(layer_rect, 478 &content_layer_client, 479 tile_grid_info, 480 false, 481 0, 482 Picture::RECORD_WITH_SK_NULL_CANVAS); 483 EXPECT_TRUE(content_layer_client.last_canvas() != NULL); 484 EXPECT_EQ(ContentLayerClient::GRAPHICS_CONTEXT_ENABLED, 485 content_layer_client.last_context_status()); 486 EXPECT_TRUE(picture); 487 488 picture = Picture::Create(layer_rect, 489 &content_layer_client, 490 tile_grid_info, 491 false, 492 0, 493 Picture::RECORD_WITH_PAINTING_DISABLED); 494 EXPECT_TRUE(content_layer_client.last_canvas() != NULL); 495 EXPECT_EQ(ContentLayerClient::GRAPHICS_CONTEXT_DISABLED, 496 content_layer_client.last_context_status()); 497 EXPECT_TRUE(picture); 498 499 picture = Picture::Create(layer_rect, 500 &content_layer_client, 501 tile_grid_info, 502 false, 503 0, 504 Picture::RECORD_WITH_SKRECORD); 505 EXPECT_TRUE(content_layer_client.last_canvas() != NULL); 506 EXPECT_TRUE(picture); 507 508 EXPECT_EQ(4, Picture::RECORDING_MODE_COUNT); 509} 510 511} // namespace 512} // namespace cc 513