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.
5 #include "cc/resources/picture.h"
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/SkCanvas.h"
14 #include "third_party/skia/include/core/SkGraphics.h"
15 #include "third_party/skia/include/core/SkPixelRef.h"
16 #include "third_party/skia/include/core/SkTileGridPicture.h"
17 #include "ui/gfx/rect.h"
18 #include "ui/gfx/skia_util.h"
23 TEST(PictureTest
, AsBase64String
) {
26 gfx::Rect
layer_rect(100, 100);
28 SkTileGridPicture::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();
33 FakeContentLayerClient content_layer_client
;
35 scoped_ptr
<base::Value
> tmp
;
38 red_paint
.setColor(SkColorSetARGB(255, 255, 0, 0));
40 green_paint
.setColor(SkColorSetARGB(255, 0, 255, 0));
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_TRUE(!invalid_picture
.get());
48 // Single full-size rect picture.
49 content_layer_client
.add_draw_rect(layer_rect
, red_paint
);
50 scoped_refptr
<Picture
> one_rect_picture
= Picture::Create(
51 layer_rect
, &content_layer_client
, tile_grid_info
, false, 0);
52 scoped_ptr
<base::Value
> serialized_one_rect(
53 one_rect_picture
->AsValue());
55 // Reconstruct the picture.
56 scoped_refptr
<Picture
> one_rect_picture_check
=
57 Picture::CreateFromValue(serialized_one_rect
.get());
58 EXPECT_TRUE(!!one_rect_picture_check
.get());
60 // Check for equivalence.
61 unsigned char one_rect_buffer
[4 * 100 * 100] = {0};
62 DrawPicture(one_rect_buffer
, layer_rect
, one_rect_picture
);
63 unsigned char one_rect_buffer_check
[4 * 100 * 100] = {0};
64 DrawPicture(one_rect_buffer_check
, layer_rect
, one_rect_picture_check
);
66 EXPECT_EQ(one_rect_picture
->LayerRect(),
67 one_rect_picture_check
->LayerRect());
68 EXPECT_EQ(one_rect_picture
->OpaqueRect(),
69 one_rect_picture_check
->OpaqueRect());
71 memcmp(one_rect_buffer
, one_rect_buffer_check
, 4 * 100 * 100) == 0);
74 content_layer_client
.add_draw_rect(gfx::Rect(25, 25, 50, 50), green_paint
);
75 scoped_refptr
<Picture
> two_rect_picture
= Picture::Create(
76 layer_rect
, &content_layer_client
, tile_grid_info
, false, 0);
78 scoped_ptr
<base::Value
> serialized_two_rect(
79 two_rect_picture
->AsValue());
81 // Reconstruct the picture.
82 scoped_refptr
<Picture
> two_rect_picture_check
=
83 Picture::CreateFromValue(serialized_two_rect
.get());
84 EXPECT_TRUE(!!two_rect_picture_check
.get());
86 // Check for equivalence.
87 unsigned char two_rect_buffer
[4 * 100 * 100] = {0};
88 DrawPicture(two_rect_buffer
, layer_rect
, two_rect_picture
);
89 unsigned char two_rect_buffer_check
[4 * 100 * 100] = {0};
90 DrawPicture(two_rect_buffer_check
, layer_rect
, two_rect_picture_check
);
92 EXPECT_EQ(two_rect_picture
->LayerRect(),
93 two_rect_picture_check
->LayerRect());
94 EXPECT_EQ(two_rect_picture
->OpaqueRect(),
95 two_rect_picture_check
->OpaqueRect());
97 memcmp(two_rect_buffer
, two_rect_buffer_check
, 4 * 100 * 100) == 0);
100 TEST(PictureTest
, PixelRefIterator
) {
101 gfx::Rect
layer_rect(2048, 2048);
103 SkTileGridPicture::TileGridInfo tile_grid_info
;
104 tile_grid_info
.fTileInterval
= SkISize::Make(512, 512);
105 tile_grid_info
.fMargin
.setEmpty();
106 tile_grid_info
.fOffset
.setZero();
108 FakeContentLayerClient content_layer_client
;
110 // Discardable pixel refs are found in the following grids:
120 SkBitmap discardable_bitmap
[4][4];
121 for (int y
= 0; y
< 4; ++y
) {
122 for (int x
= 0; x
< 4; ++x
) {
125 gfx::Size(500, 500), "discardable", &discardable_bitmap
[y
][x
]);
127 content_layer_client
.add_draw_bitmap(
128 discardable_bitmap
[y
][x
],
129 gfx::Point(x
* 512 + 6, y
* 512 + 6), paint
);
134 scoped_refptr
<Picture
> picture
= Picture::Create(
135 layer_rect
, &content_layer_client
, tile_grid_info
, true, 0);
137 // Default iterator does not have any pixel refs
139 Picture::PixelRefIterator iterator
;
140 EXPECT_FALSE(iterator
);
142 for (int y
= 0; y
< 4; ++y
) {
143 for (int x
= 0; x
< 4; ++x
) {
144 Picture::PixelRefIterator
iterator(gfx::Rect(x
* 512, y
* 512, 500, 500),
147 EXPECT_TRUE(iterator
) << x
<< " " << y
;
148 EXPECT_TRUE(*iterator
== discardable_bitmap
[y
][x
].pixelRef()) << x
<<
150 EXPECT_FALSE(++iterator
) << x
<< " " << y
;
152 EXPECT_FALSE(iterator
) << x
<< " " << y
;
156 // Capture 4 pixel refs.
158 Picture::PixelRefIterator
iterator(gfx::Rect(512, 512, 2048, 2048),
160 EXPECT_TRUE(iterator
);
161 EXPECT_TRUE(*iterator
== discardable_bitmap
[1][2].pixelRef());
162 EXPECT_TRUE(++iterator
);
163 EXPECT_TRUE(*iterator
== discardable_bitmap
[2][1].pixelRef());
164 EXPECT_TRUE(++iterator
);
165 EXPECT_TRUE(*iterator
== discardable_bitmap
[2][3].pixelRef());
166 EXPECT_TRUE(++iterator
);
167 EXPECT_TRUE(*iterator
== discardable_bitmap
[3][2].pixelRef());
168 EXPECT_FALSE(++iterator
);
172 Picture::PixelRefIterator
iterator(gfx::Rect(512, 512, 2048, 2048),
174 EXPECT_TRUE(iterator
);
175 EXPECT_TRUE(*iterator
== discardable_bitmap
[1][2].pixelRef());
176 EXPECT_TRUE(++iterator
);
177 EXPECT_TRUE(*iterator
== discardable_bitmap
[2][1].pixelRef());
179 // copy now points to the same spot as iterator,
180 // but both can be incremented independently.
181 Picture::PixelRefIterator copy
= iterator
;
182 EXPECT_TRUE(++iterator
);
183 EXPECT_TRUE(*iterator
== discardable_bitmap
[2][3].pixelRef());
184 EXPECT_TRUE(++iterator
);
185 EXPECT_TRUE(*iterator
== discardable_bitmap
[3][2].pixelRef());
186 EXPECT_FALSE(++iterator
);
189 EXPECT_TRUE(*copy
== discardable_bitmap
[2][1].pixelRef());
191 EXPECT_TRUE(*copy
== discardable_bitmap
[2][3].pixelRef());
193 EXPECT_TRUE(*copy
== discardable_bitmap
[3][2].pixelRef());
194 EXPECT_FALSE(++copy
);
197 TEST(PictureTest
, PixelRefIteratorNonZeroLayer
) {
198 gfx::Rect
layer_rect(1024, 0, 2048, 2048);
200 SkTileGridPicture::TileGridInfo tile_grid_info
;
201 tile_grid_info
.fTileInterval
= SkISize::Make(512, 512);
202 tile_grid_info
.fMargin
.setEmpty();
203 tile_grid_info
.fOffset
.setZero();
205 FakeContentLayerClient content_layer_client
;
207 // Discardable pixel refs are found in the following grids:
217 SkBitmap discardable_bitmap
[4][4];
218 for (int y
= 0; y
< 4; ++y
) {
219 for (int x
= 0; x
< 4; ++x
) {
222 gfx::Size(500, 500), "discardable", &discardable_bitmap
[y
][x
]);
224 content_layer_client
.add_draw_bitmap(
225 discardable_bitmap
[y
][x
],
226 gfx::Point(1024 + x
* 512 + 6, y
* 512 + 6), paint
);
231 scoped_refptr
<Picture
> picture
= Picture::Create(
232 layer_rect
, &content_layer_client
, tile_grid_info
, true, 0);
234 // Default iterator does not have any pixel refs
236 Picture::PixelRefIterator iterator
;
237 EXPECT_FALSE(iterator
);
239 for (int y
= 0; y
< 4; ++y
) {
240 for (int x
= 0; x
< 4; ++x
) {
241 Picture::PixelRefIterator
iterator(
242 gfx::Rect(1024 + x
* 512, y
* 512, 500, 500), picture
.get());
244 EXPECT_TRUE(iterator
) << x
<< " " << y
;
245 EXPECT_TRUE(*iterator
== discardable_bitmap
[y
][x
].pixelRef());
246 EXPECT_FALSE(++iterator
) << x
<< " " << y
;
248 EXPECT_FALSE(iterator
) << x
<< " " << y
;
252 // Capture 4 pixel refs.
254 Picture::PixelRefIterator
iterator(gfx::Rect(1024 + 512, 512, 2048, 2048),
256 EXPECT_TRUE(iterator
);
257 EXPECT_TRUE(*iterator
== discardable_bitmap
[1][2].pixelRef());
258 EXPECT_TRUE(++iterator
);
259 EXPECT_TRUE(*iterator
== discardable_bitmap
[2][1].pixelRef());
260 EXPECT_TRUE(++iterator
);
261 EXPECT_TRUE(*iterator
== discardable_bitmap
[2][3].pixelRef());
262 EXPECT_TRUE(++iterator
);
263 EXPECT_TRUE(*iterator
== discardable_bitmap
[3][2].pixelRef());
264 EXPECT_FALSE(++iterator
);
269 Picture::PixelRefIterator
iterator(gfx::Rect(1024 + 512, 512, 2048, 2048),
271 EXPECT_TRUE(iterator
);
272 EXPECT_TRUE(*iterator
== discardable_bitmap
[1][2].pixelRef());
273 EXPECT_TRUE(++iterator
);
274 EXPECT_TRUE(*iterator
== discardable_bitmap
[2][1].pixelRef());
276 // copy now points to the same spot as iterator,
277 // but both can be incremented independently.
278 Picture::PixelRefIterator copy
= iterator
;
279 EXPECT_TRUE(++iterator
);
280 EXPECT_TRUE(*iterator
== discardable_bitmap
[2][3].pixelRef());
281 EXPECT_TRUE(++iterator
);
282 EXPECT_TRUE(*iterator
== discardable_bitmap
[3][2].pixelRef());
283 EXPECT_FALSE(++iterator
);
286 EXPECT_TRUE(*copy
== discardable_bitmap
[2][1].pixelRef());
288 EXPECT_TRUE(*copy
== discardable_bitmap
[2][3].pixelRef());
290 EXPECT_TRUE(*copy
== discardable_bitmap
[3][2].pixelRef());
291 EXPECT_FALSE(++copy
);
294 // Non intersecting rects
296 Picture::PixelRefIterator
iterator(gfx::Rect(0, 0, 1000, 1000),
298 EXPECT_FALSE(iterator
);
301 Picture::PixelRefIterator
iterator(gfx::Rect(3500, 0, 1000, 1000),
303 EXPECT_FALSE(iterator
);
306 Picture::PixelRefIterator
iterator(gfx::Rect(0, 1100, 1000, 1000),
308 EXPECT_FALSE(iterator
);
311 Picture::PixelRefIterator
iterator(gfx::Rect(3500, 1100, 1000, 1000),
313 EXPECT_FALSE(iterator
);
317 TEST(PictureTest
, PixelRefIteratorOnePixelQuery
) {
318 gfx::Rect
layer_rect(2048, 2048);
320 SkTileGridPicture::TileGridInfo tile_grid_info
;
321 tile_grid_info
.fTileInterval
= SkISize::Make(512, 512);
322 tile_grid_info
.fMargin
.setEmpty();
323 tile_grid_info
.fOffset
.setZero();
325 FakeContentLayerClient content_layer_client
;
327 // Discardable pixel refs are found in the following grids:
337 SkBitmap discardable_bitmap
[4][4];
338 for (int y
= 0; y
< 4; ++y
) {
339 for (int x
= 0; x
< 4; ++x
) {
342 gfx::Size(500, 500), "discardable", &discardable_bitmap
[y
][x
]);
344 content_layer_client
.add_draw_bitmap(
345 discardable_bitmap
[y
][x
],
346 gfx::Point(x
* 512 + 6, y
* 512 + 6), paint
);
351 scoped_refptr
<Picture
> picture
= Picture::Create(
352 layer_rect
, &content_layer_client
, tile_grid_info
, true, 0);
354 for (int y
= 0; y
< 4; ++y
) {
355 for (int x
= 0; x
< 4; ++x
) {
356 Picture::PixelRefIterator
iterator(
357 gfx::Rect(x
* 512, y
* 512 + 256, 1, 1), picture
.get());
359 EXPECT_TRUE(iterator
) << x
<< " " << y
;
360 EXPECT_TRUE(*iterator
== discardable_bitmap
[y
][x
].pixelRef());
361 EXPECT_FALSE(++iterator
) << x
<< " " << y
;
363 EXPECT_FALSE(iterator
) << x
<< " " << y
;
369 TEST(PictureTest
, CreateFromSkpValue
) {
372 gfx::Rect
layer_rect(100, 200);
374 SkTileGridPicture::TileGridInfo tile_grid_info
;
375 tile_grid_info
.fTileInterval
= SkISize::Make(100, 200);
376 tile_grid_info
.fMargin
.setEmpty();
377 tile_grid_info
.fOffset
.setZero();
379 FakeContentLayerClient content_layer_client
;
381 scoped_ptr
<base::Value
> tmp
;
384 red_paint
.setColor(SkColorSetARGB(255, 255, 0, 0));
386 green_paint
.setColor(SkColorSetARGB(255, 0, 255, 0));
388 // Invalid picture (not a dict).
389 tmp
.reset(new base::StringValue("abc!@#$%"));
390 scoped_refptr
<Picture
> invalid_picture
=
391 Picture::CreateFromSkpValue(tmp
.get());
392 EXPECT_TRUE(!invalid_picture
.get());
394 // Single full-size rect picture.
395 content_layer_client
.add_draw_rect(layer_rect
, red_paint
);
396 scoped_refptr
<Picture
> one_rect_picture
= Picture::Create(
397 layer_rect
, &content_layer_client
, tile_grid_info
, false, 0);
398 scoped_ptr
<base::Value
> serialized_one_rect(
399 one_rect_picture
->AsValue());
401 const base::DictionaryValue
* value
= NULL
;
402 EXPECT_TRUE(serialized_one_rect
->GetAsDictionary(&value
));
404 // Decode the picture from base64.
405 const base::Value
* skp_value
;
406 EXPECT_TRUE(value
->Get("skp64", &skp_value
));
408 // Reconstruct the picture.
409 scoped_refptr
<Picture
> one_rect_picture_check
=
410 Picture::CreateFromSkpValue(skp_value
);
411 EXPECT_TRUE(!!one_rect_picture_check
.get());
413 EXPECT_EQ(100, one_rect_picture_check
->LayerRect().width());
414 EXPECT_EQ(200, one_rect_picture_check
->LayerRect().height());
415 EXPECT_EQ(100, one_rect_picture_check
->OpaqueRect().width());
416 EXPECT_EQ(200, one_rect_picture_check
->OpaqueRect().height());