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