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/fake_rendering_stats_instrumentation.h"
12#include "cc/test/skia_common.h"
13#include "testing/gtest/include/gtest/gtest.h"
14#include "third_party/skia/include/core/SkCanvas.h"
15#include "third_party/skia/include/core/SkDevice.h"
16#include "third_party/skia/include/core/SkGraphics.h"
17#include "third_party/skia/include/core/SkPixelRef.h"
18#include "third_party/skia/include/core/SkTileGridPicture.h"
19#include "ui/gfx/rect.h"
20#include "ui/gfx/skia_util.h"
21
22namespace cc {
23namespace {
24
25TEST(PictureTest, AsBase64String) {
26  SkGraphics::Init();
27
28  gfx::Rect layer_rect(100, 100);
29
30  SkTileGridPicture::TileGridInfo tile_grid_info;
31  tile_grid_info.fTileInterval = SkISize::Make(100, 100);
32  tile_grid_info.fMargin.setEmpty();
33  tile_grid_info.fOffset.setZero();
34
35  FakeContentLayerClient content_layer_client;
36  FakeRenderingStatsInstrumentation stats_instrumentation;
37
38  scoped_ptr<base::Value> tmp;
39
40  SkPaint red_paint;
41  red_paint.setColor(SkColorSetARGB(255, 255, 0, 0));
42  SkPaint green_paint;
43  green_paint.setColor(SkColorSetARGB(255, 0, 255, 0));
44
45  // Invalid picture (not a dict).
46  tmp.reset(new base::StringValue("abc!@#$%"));
47  scoped_refptr<Picture> invalid_picture =
48      Picture::CreateFromValue(tmp.get());
49  EXPECT_TRUE(!invalid_picture.get());
50
51  // Single full-size rect picture.
52  content_layer_client.add_draw_rect(layer_rect, red_paint);
53  scoped_refptr<Picture> one_rect_picture = Picture::Create(layer_rect);
54  one_rect_picture->Record(&content_layer_client,
55                           tile_grid_info,
56                           &stats_instrumentation);
57  scoped_ptr<base::Value> serialized_one_rect(
58      one_rect_picture->AsValue());
59
60  // Reconstruct the picture.
61  scoped_refptr<Picture> one_rect_picture_check =
62      Picture::CreateFromValue(serialized_one_rect.get());
63  EXPECT_TRUE(!!one_rect_picture_check.get());
64
65  // Check for equivalence.
66  unsigned char one_rect_buffer[4 * 100 * 100] = {0};
67  DrawPicture(one_rect_buffer, layer_rect, one_rect_picture);
68  unsigned char one_rect_buffer_check[4 * 100 * 100] = {0};
69  DrawPicture(one_rect_buffer_check, layer_rect, one_rect_picture_check);
70
71  EXPECT_EQ(one_rect_picture->LayerRect(),
72            one_rect_picture_check->LayerRect());
73  EXPECT_EQ(one_rect_picture->OpaqueRect(),
74            one_rect_picture_check->OpaqueRect());
75  EXPECT_TRUE(
76      memcmp(one_rect_buffer, one_rect_buffer_check, 4 * 100 * 100) == 0);
77
78  // Two rect picture.
79  content_layer_client.add_draw_rect(gfx::Rect(25, 25, 50, 50), green_paint);
80  scoped_refptr<Picture> two_rect_picture = Picture::Create(layer_rect);
81  two_rect_picture->Record(&content_layer_client,
82                           tile_grid_info,
83                           &stats_instrumentation);
84
85  scoped_ptr<base::Value> serialized_two_rect(
86      two_rect_picture->AsValue());
87
88  // Reconstruct the picture.
89  scoped_refptr<Picture> two_rect_picture_check =
90      Picture::CreateFromValue(serialized_two_rect.get());
91  EXPECT_TRUE(!!two_rect_picture_check.get());
92
93  // Check for equivalence.
94  unsigned char two_rect_buffer[4 * 100 * 100] = {0};
95  DrawPicture(two_rect_buffer, layer_rect, two_rect_picture);
96  unsigned char two_rect_buffer_check[4 * 100 * 100] = {0};
97  DrawPicture(two_rect_buffer_check, layer_rect, two_rect_picture_check);
98
99  EXPECT_EQ(two_rect_picture->LayerRect(),
100            two_rect_picture_check->LayerRect());
101  EXPECT_EQ(two_rect_picture->OpaqueRect(),
102            two_rect_picture_check->OpaqueRect());
103  EXPECT_TRUE(
104      memcmp(two_rect_buffer, two_rect_buffer_check, 4 * 100 * 100) == 0);
105}
106
107TEST(PictureTest, PixelRefIterator) {
108  gfx::Rect layer_rect(2048, 2048);
109
110  SkTileGridPicture::TileGridInfo tile_grid_info;
111  tile_grid_info.fTileInterval = SkISize::Make(512, 512);
112  tile_grid_info.fMargin.setEmpty();
113  tile_grid_info.fOffset.setZero();
114
115  FakeContentLayerClient content_layer_client;
116  FakeRenderingStatsInstrumentation stats_instrumentation;
117
118  // Lazy pixel refs are found in the following grids:
119  // |---|---|---|---|
120  // |   | x |   | x |
121  // |---|---|---|---|
122  // | x |   | x |   |
123  // |---|---|---|---|
124  // |   | x |   | x |
125  // |---|---|---|---|
126  // | x |   | x |   |
127  // |---|---|---|---|
128  SkBitmap lazy_bitmap[4][4];
129  for (int y = 0; y < 4; ++y) {
130    for (int x = 0; x < 4; ++x) {
131      if ((x + y) & 1) {
132        CreateBitmap(gfx::Size(500, 500), "lazy", &lazy_bitmap[y][x]);
133        SkPaint paint;
134        content_layer_client.add_draw_bitmap(
135            lazy_bitmap[y][x],
136            gfx::Point(x * 512 + 6, y * 512 + 6), paint);
137      }
138    }
139  }
140
141  scoped_refptr<Picture> picture = Picture::Create(layer_rect);
142  picture->Record(&content_layer_client,
143                  tile_grid_info,
144                  &stats_instrumentation);
145  picture->GatherPixelRefs(tile_grid_info, &stats_instrumentation);
146
147  // Default iterator does not have any pixel refs
148  {
149    Picture::PixelRefIterator iterator;
150    EXPECT_FALSE(iterator);
151  }
152  for (int y = 0; y < 4; ++y) {
153    for (int x = 0; x < 4; ++x) {
154      Picture::PixelRefIterator iterator(gfx::Rect(x * 512, y * 512, 500, 500),
155                                         picture.get());
156      if ((x + y) & 1) {
157        EXPECT_TRUE(iterator) << x << " " << y;
158        EXPECT_TRUE(*iterator == lazy_bitmap[y][x].pixelRef()) << x << " " << y;
159        EXPECT_FALSE(++iterator) << x << " " << y;
160      } else {
161        EXPECT_FALSE(iterator) << x << " " << y;
162      }
163    }
164  }
165  // Capture 4 pixel refs.
166  {
167    Picture::PixelRefIterator iterator(gfx::Rect(512, 512, 2048, 2048),
168                                       picture.get());
169    EXPECT_TRUE(iterator);
170    EXPECT_TRUE(*iterator == lazy_bitmap[1][2].pixelRef());
171    EXPECT_TRUE(++iterator);
172    EXPECT_TRUE(*iterator == lazy_bitmap[2][1].pixelRef());
173    EXPECT_TRUE(++iterator);
174    EXPECT_TRUE(*iterator == lazy_bitmap[2][3].pixelRef());
175    EXPECT_TRUE(++iterator);
176    EXPECT_TRUE(*iterator == lazy_bitmap[3][2].pixelRef());
177    EXPECT_FALSE(++iterator);
178  }
179
180  // Copy test.
181  Picture::PixelRefIterator iterator(gfx::Rect(512, 512, 2048, 2048),
182                                     picture.get());
183  EXPECT_TRUE(iterator);
184  EXPECT_TRUE(*iterator == lazy_bitmap[1][2].pixelRef());
185  EXPECT_TRUE(++iterator);
186  EXPECT_TRUE(*iterator == lazy_bitmap[2][1].pixelRef());
187
188  // copy now points to the same spot as iterator,
189  // but both can be incremented independently.
190  Picture::PixelRefIterator copy = iterator;
191  EXPECT_TRUE(++iterator);
192  EXPECT_TRUE(*iterator == lazy_bitmap[2][3].pixelRef());
193  EXPECT_TRUE(++iterator);
194  EXPECT_TRUE(*iterator == lazy_bitmap[3][2].pixelRef());
195  EXPECT_FALSE(++iterator);
196
197  EXPECT_TRUE(copy);
198  EXPECT_TRUE(*copy == lazy_bitmap[2][1].pixelRef());
199  EXPECT_TRUE(++copy);
200  EXPECT_TRUE(*copy == lazy_bitmap[2][3].pixelRef());
201  EXPECT_TRUE(++copy);
202  EXPECT_TRUE(*copy == lazy_bitmap[3][2].pixelRef());
203  EXPECT_FALSE(++copy);
204}
205
206TEST(PictureTest, PixelRefIteratorNonZeroLayer) {
207  gfx::Rect layer_rect(1024, 0, 2048, 2048);
208
209  SkTileGridPicture::TileGridInfo tile_grid_info;
210  tile_grid_info.fTileInterval = SkISize::Make(512, 512);
211  tile_grid_info.fMargin.setEmpty();
212  tile_grid_info.fOffset.setZero();
213
214  FakeContentLayerClient content_layer_client;
215  FakeRenderingStatsInstrumentation stats_instrumentation;
216
217  // Lazy pixel refs are found in the following grids:
218  // |---|---|---|---|
219  // |   | x |   | x |
220  // |---|---|---|---|
221  // | x |   | x |   |
222  // |---|---|---|---|
223  // |   | x |   | x |
224  // |---|---|---|---|
225  // | x |   | x |   |
226  // |---|---|---|---|
227  SkBitmap lazy_bitmap[4][4];
228  for (int y = 0; y < 4; ++y) {
229    for (int x = 0; x < 4; ++x) {
230      if ((x + y) & 1) {
231        CreateBitmap(gfx::Size(500, 500), "lazy", &lazy_bitmap[y][x]);
232        SkPaint paint;
233        content_layer_client.add_draw_bitmap(
234            lazy_bitmap[y][x],
235            gfx::Point(1024 + x * 512 + 6, y * 512 + 6), paint);
236      }
237    }
238  }
239
240  scoped_refptr<Picture> picture = Picture::Create(layer_rect);
241  picture->Record(&content_layer_client,
242                  tile_grid_info,
243                  &stats_instrumentation);
244  picture->GatherPixelRefs(tile_grid_info, &stats_instrumentation);
245
246  // Default iterator does not have any pixel refs
247  {
248    Picture::PixelRefIterator iterator;
249    EXPECT_FALSE(iterator);
250  }
251  for (int y = 0; y < 4; ++y) {
252    for (int x = 0; x < 4; ++x) {
253      Picture::PixelRefIterator iterator(
254          gfx::Rect(1024 + x * 512, y * 512, 500, 500), picture.get());
255      if ((x + y) & 1) {
256        EXPECT_TRUE(iterator) << x << " " << y;
257        EXPECT_TRUE(*iterator == lazy_bitmap[y][x].pixelRef());
258        EXPECT_FALSE(++iterator) << x << " " << y;
259      } else {
260        EXPECT_FALSE(iterator) << x << " " << y;
261      }
262    }
263  }
264  // Capture 4 pixel refs.
265  {
266    Picture::PixelRefIterator iterator(gfx::Rect(1024 + 512, 512, 2048, 2048),
267                                       picture.get());
268    EXPECT_TRUE(iterator);
269    EXPECT_TRUE(*iterator == lazy_bitmap[1][2].pixelRef());
270    EXPECT_TRUE(++iterator);
271    EXPECT_TRUE(*iterator == lazy_bitmap[2][1].pixelRef());
272    EXPECT_TRUE(++iterator);
273    EXPECT_TRUE(*iterator == lazy_bitmap[2][3].pixelRef());
274    EXPECT_TRUE(++iterator);
275    EXPECT_TRUE(*iterator == lazy_bitmap[3][2].pixelRef());
276    EXPECT_FALSE(++iterator);
277  }
278
279  // Copy test.
280  {
281    Picture::PixelRefIterator iterator(gfx::Rect(1024 + 512, 512, 2048, 2048),
282                                       picture.get());
283    EXPECT_TRUE(iterator);
284    EXPECT_TRUE(*iterator == lazy_bitmap[1][2].pixelRef());
285    EXPECT_TRUE(++iterator);
286    EXPECT_TRUE(*iterator == lazy_bitmap[2][1].pixelRef());
287
288    // copy now points to the same spot as iterator,
289    // but both can be incremented independently.
290    Picture::PixelRefIterator copy = iterator;
291    EXPECT_TRUE(++iterator);
292    EXPECT_TRUE(*iterator == lazy_bitmap[2][3].pixelRef());
293    EXPECT_TRUE(++iterator);
294    EXPECT_TRUE(*iterator == lazy_bitmap[3][2].pixelRef());
295    EXPECT_FALSE(++iterator);
296
297    EXPECT_TRUE(copy);
298    EXPECT_TRUE(*copy == lazy_bitmap[2][1].pixelRef());
299    EXPECT_TRUE(++copy);
300    EXPECT_TRUE(*copy == lazy_bitmap[2][3].pixelRef());
301    EXPECT_TRUE(++copy);
302    EXPECT_TRUE(*copy == lazy_bitmap[3][2].pixelRef());
303    EXPECT_FALSE(++copy);
304  }
305
306  // Non intersecting rects
307  {
308    Picture::PixelRefIterator iterator(gfx::Rect(0, 0, 1000, 1000),
309                                       picture.get());
310    EXPECT_FALSE(iterator);
311  }
312  {
313    Picture::PixelRefIterator iterator(gfx::Rect(3500, 0, 1000, 1000),
314                                       picture.get());
315    EXPECT_FALSE(iterator);
316  }
317  {
318    Picture::PixelRefIterator iterator(gfx::Rect(0, 1100, 1000, 1000),
319                                       picture.get());
320    EXPECT_FALSE(iterator);
321  }
322  {
323    Picture::PixelRefIterator iterator(gfx::Rect(3500, 1100, 1000, 1000),
324                                       picture.get());
325    EXPECT_FALSE(iterator);
326  }
327}
328
329TEST(PictureTest, PixelRefIteratorOnePixelQuery) {
330  gfx::Rect layer_rect(2048, 2048);
331
332  SkTileGridPicture::TileGridInfo tile_grid_info;
333  tile_grid_info.fTileInterval = SkISize::Make(512, 512);
334  tile_grid_info.fMargin.setEmpty();
335  tile_grid_info.fOffset.setZero();
336
337  FakeContentLayerClient content_layer_client;
338  FakeRenderingStatsInstrumentation stats_instrumentation;
339
340  // Lazy pixel refs are found in the following grids:
341  // |---|---|---|---|
342  // |   | x |   | x |
343  // |---|---|---|---|
344  // | x |   | x |   |
345  // |---|---|---|---|
346  // |   | x |   | x |
347  // |---|---|---|---|
348  // | x |   | x |   |
349  // |---|---|---|---|
350  SkBitmap lazy_bitmap[4][4];
351  for (int y = 0; y < 4; ++y) {
352    for (int x = 0; x < 4; ++x) {
353      if ((x + y) & 1) {
354        CreateBitmap(gfx::Size(500, 500), "lazy", &lazy_bitmap[y][x]);
355        SkPaint paint;
356        content_layer_client.add_draw_bitmap(
357            lazy_bitmap[y][x],
358            gfx::Point(x * 512 + 6, y * 512 + 6), paint);
359      }
360    }
361  }
362
363  scoped_refptr<Picture> picture = Picture::Create(layer_rect);
364  picture->Record(&content_layer_client,
365                  tile_grid_info,
366                  &stats_instrumentation);
367  picture->GatherPixelRefs(tile_grid_info, &stats_instrumentation);
368
369  for (int y = 0; y < 4; ++y) {
370    for (int x = 0; x < 4; ++x) {
371      Picture::PixelRefIterator iterator(
372          gfx::Rect(x * 512, y * 512 + 256, 1, 1), picture.get());
373      if ((x + y) & 1) {
374        EXPECT_TRUE(iterator) << x << " " << y;
375        EXPECT_TRUE(*iterator == lazy_bitmap[y][x].pixelRef());
376        EXPECT_FALSE(++iterator) << x << " " << y;
377      } else {
378        EXPECT_FALSE(iterator) << x << " " << y;
379      }
380    }
381  }
382}
383}  // namespace
384}  // namespace cc
385