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 "base/memory/scoped_ptr.h"
6#include "cc/test/fake_picture_pile_impl.h"
7#include "cc/test/fake_rendering_stats_instrumentation.h"
8#include "cc/test/skia_common.h"
9#include "skia/ext/refptr.h"
10#include "testing/gtest/include/gtest/gtest.h"
11#include "third_party/skia/include/core/SkPixelRef.h"
12#include "third_party/skia/include/core/SkShader.h"
13#include "ui/gfx/rect.h"
14#include "ui/gfx/size_conversions.h"
15
16namespace cc {
17namespace {
18
19TEST(PicturePileImplTest, AnalyzeIsSolidUnscaled) {
20  gfx::Size tile_size(100, 100);
21  gfx::Size layer_bounds(400, 400);
22
23  scoped_refptr<FakePicturePileImpl> pile =
24      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
25
26  SkColor solid_color = SkColorSetARGB(255, 12, 23, 34);
27  SkPaint solid_paint;
28  solid_paint.setColor(solid_color);
29
30  SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67);
31  SkPaint non_solid_paint;
32  non_solid_paint.setColor(non_solid_color);
33
34  pile->add_draw_rect_with_paint(gfx::Rect(0, 0, 400, 400), solid_paint);
35  pile->RerecordPile();
36
37  // Ensure everything is solid
38  for (int y = 0; y <= 300; y += 100) {
39    for (int x = 0; x <= 300; x += 100) {
40      PicturePileImpl::Analysis analysis;
41      gfx::Rect rect(x, y, 100, 100);
42      pile->AnalyzeInRect(rect, 1.0, &analysis);
43      EXPECT_TRUE(analysis.is_solid_color) << rect.ToString();
44      EXPECT_EQ(analysis.solid_color, solid_color) << rect.ToString();
45    }
46  }
47
48  // One pixel non solid
49  pile->add_draw_rect_with_paint(gfx::Rect(50, 50, 1, 1), non_solid_paint);
50  pile->RerecordPile();
51
52  PicturePileImpl::Analysis analysis;
53  pile->AnalyzeInRect(gfx::Rect(0, 0, 100, 100), 1.0, &analysis);
54  EXPECT_FALSE(analysis.is_solid_color);
55
56  pile->AnalyzeInRect(gfx::Rect(100, 0, 100, 100), 1.0, &analysis);
57  EXPECT_TRUE(analysis.is_solid_color);
58  EXPECT_EQ(analysis.solid_color, solid_color);
59
60  // Boundaries should be clipped
61  analysis.is_solid_color = false;
62  pile->AnalyzeInRect(gfx::Rect(350, 0, 100, 100), 1.0, &analysis);
63  EXPECT_TRUE(analysis.is_solid_color);
64  EXPECT_EQ(analysis.solid_color, solid_color);
65
66  analysis.is_solid_color = false;
67  pile->AnalyzeInRect(gfx::Rect(0, 350, 100, 100), 1.0, &analysis);
68  EXPECT_TRUE(analysis.is_solid_color);
69  EXPECT_EQ(analysis.solid_color, solid_color);
70
71  analysis.is_solid_color = false;
72  pile->AnalyzeInRect(gfx::Rect(350, 350, 100, 100), 1.0, &analysis);
73  EXPECT_TRUE(analysis.is_solid_color);
74  EXPECT_EQ(analysis.solid_color, solid_color);
75}
76
77TEST(PicturePileImplTest, AnalyzeIsSolidScaled) {
78  gfx::Size tile_size(100, 100);
79  gfx::Size layer_bounds(400, 400);
80
81  scoped_refptr<FakePicturePileImpl> pile =
82      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
83
84  SkColor solid_color = SkColorSetARGB(255, 12, 23, 34);
85  SkPaint solid_paint;
86  solid_paint.setColor(solid_color);
87
88  SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67);
89  SkPaint non_solid_paint;
90  non_solid_paint.setColor(non_solid_color);
91
92  pile->add_draw_rect_with_paint(gfx::Rect(0, 0, 400, 400), solid_paint);
93  pile->RerecordPile();
94
95  // Ensure everything is solid
96  for (int y = 0; y <= 30; y += 10) {
97    for (int x = 0; x <= 30; x += 10) {
98      PicturePileImpl::Analysis analysis;
99      gfx::Rect rect(x, y, 10, 10);
100      pile->AnalyzeInRect(rect, 0.1f, &analysis);
101      EXPECT_TRUE(analysis.is_solid_color) << rect.ToString();
102      EXPECT_EQ(analysis.solid_color, solid_color) << rect.ToString();
103    }
104  }
105
106  // One pixel non solid
107  pile->add_draw_rect_with_paint(gfx::Rect(50, 50, 1, 1), non_solid_paint);
108  pile->RerecordPile();
109
110  PicturePileImpl::Analysis analysis;
111  pile->AnalyzeInRect(gfx::Rect(0, 0, 10, 10), 0.1f, &analysis);
112  EXPECT_FALSE(analysis.is_solid_color);
113
114  pile->AnalyzeInRect(gfx::Rect(10, 0, 10, 10), 0.1f, &analysis);
115  EXPECT_TRUE(analysis.is_solid_color);
116  EXPECT_EQ(analysis.solid_color, solid_color);
117
118  // Boundaries should be clipped
119  analysis.is_solid_color = false;
120  pile->AnalyzeInRect(gfx::Rect(35, 0, 10, 10), 0.1f, &analysis);
121  EXPECT_TRUE(analysis.is_solid_color);
122  EXPECT_EQ(analysis.solid_color, solid_color);
123
124  analysis.is_solid_color = false;
125  pile->AnalyzeInRect(gfx::Rect(0, 35, 10, 10), 0.1f, &analysis);
126  EXPECT_TRUE(analysis.is_solid_color);
127  EXPECT_EQ(analysis.solid_color, solid_color);
128
129  analysis.is_solid_color = false;
130  pile->AnalyzeInRect(gfx::Rect(35, 35, 10, 10), 0.1f, &analysis);
131  EXPECT_TRUE(analysis.is_solid_color);
132  EXPECT_EQ(analysis.solid_color, solid_color);
133}
134
135TEST(PicturePileImplTest, AnalyzeIsSolidEmpty) {
136  gfx::Size tile_size(100, 100);
137  gfx::Size layer_bounds(400, 400);
138
139  scoped_refptr<FakePicturePileImpl> pile =
140      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
141  PicturePileImpl::Analysis analysis;
142  EXPECT_FALSE(analysis.is_solid_color);
143
144  pile->AnalyzeInRect(gfx::Rect(0, 0, 400, 400), 1.f, &analysis);
145
146  EXPECT_TRUE(analysis.is_solid_color);
147  EXPECT_EQ(analysis.solid_color, SkColorSetARGB(0, 0, 0, 0));
148}
149
150TEST(PicturePileImplTest, PixelRefIteratorEmpty) {
151  gfx::Size tile_size(128, 128);
152  gfx::Size layer_bounds(256, 256);
153
154  // Create a filled pile with no recording.
155  scoped_refptr<FakePicturePileImpl> pile =
156      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
157
158  // Tile sized iterators.
159  {
160    PicturePileImpl::PixelRefIterator iterator(
161        gfx::Rect(0, 0, 128, 128), 1.0, pile.get());
162    EXPECT_FALSE(iterator);
163  }
164  {
165    PicturePileImpl::PixelRefIterator iterator(
166        gfx::Rect(0, 0, 256, 256), 2.0, pile.get());
167    EXPECT_FALSE(iterator);
168  }
169  {
170    PicturePileImpl::PixelRefIterator iterator(
171        gfx::Rect(0, 0, 64, 64), 0.5, pile.get());
172    EXPECT_FALSE(iterator);
173  }
174  // Shifted tile sized iterators.
175  {
176    PicturePileImpl::PixelRefIterator iterator(
177        gfx::Rect(140, 140, 128, 128), 1.0, pile.get());
178    EXPECT_FALSE(iterator);
179  }
180  {
181    PicturePileImpl::PixelRefIterator iterator(
182        gfx::Rect(280, 280, 256, 256), 2.0, pile.get());
183    EXPECT_FALSE(iterator);
184  }
185  {
186    PicturePileImpl::PixelRefIterator iterator(
187        gfx::Rect(70, 70, 64, 64), 0.5, pile.get());
188    EXPECT_FALSE(iterator);
189  }
190  // Layer sized iterators.
191  {
192    PicturePileImpl::PixelRefIterator iterator(
193        gfx::Rect(0, 0, 256, 256), 1.0, pile.get());
194    EXPECT_FALSE(iterator);
195  }
196  {
197    PicturePileImpl::PixelRefIterator iterator(
198        gfx::Rect(0, 0, 512, 512), 2.0, pile.get());
199    EXPECT_FALSE(iterator);
200  }
201  {
202    PicturePileImpl::PixelRefIterator iterator(
203        gfx::Rect(0, 0, 128, 128), 0.5, pile.get());
204    EXPECT_FALSE(iterator);
205  }
206}
207
208TEST(PicturePileImplTest, PixelRefIteratorNoDiscardableRefs) {
209  gfx::Size tile_size(128, 128);
210  gfx::Size layer_bounds(256, 256);
211
212  scoped_refptr<FakePicturePileImpl> pile =
213      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
214
215  SkPaint simple_paint;
216  simple_paint.setColor(SkColorSetARGB(255, 12, 23, 34));
217
218  SkBitmap non_discardable_bitmap;
219  CreateBitmap(gfx::Size(128, 128), "notdiscardable", &non_discardable_bitmap);
220
221  pile->add_draw_rect_with_paint(gfx::Rect(0, 0, 256, 256), simple_paint);
222  pile->add_draw_rect_with_paint(gfx::Rect(128, 128, 512, 512), simple_paint);
223  pile->add_draw_rect_with_paint(gfx::Rect(512, 0, 256, 256), simple_paint);
224  pile->add_draw_rect_with_paint(gfx::Rect(0, 512, 256, 256), simple_paint);
225  pile->add_draw_bitmap(non_discardable_bitmap, gfx::Point(128, 0));
226  pile->add_draw_bitmap(non_discardable_bitmap, gfx::Point(0, 128));
227  pile->add_draw_bitmap(non_discardable_bitmap, gfx::Point(150, 150));
228
229  pile->RerecordPile();
230
231  // Tile sized iterators.
232  {
233    PicturePileImpl::PixelRefIterator iterator(
234        gfx::Rect(0, 0, 128, 128), 1.0, pile.get());
235    EXPECT_FALSE(iterator);
236  }
237  {
238    PicturePileImpl::PixelRefIterator iterator(
239        gfx::Rect(0, 0, 256, 256), 2.0, pile.get());
240    EXPECT_FALSE(iterator);
241  }
242  {
243    PicturePileImpl::PixelRefIterator iterator(
244        gfx::Rect(0, 0, 64, 64), 0.5, pile.get());
245    EXPECT_FALSE(iterator);
246  }
247  // Shifted tile sized iterators.
248  {
249    PicturePileImpl::PixelRefIterator iterator(
250        gfx::Rect(140, 140, 128, 128), 1.0, pile.get());
251    EXPECT_FALSE(iterator);
252  }
253  {
254    PicturePileImpl::PixelRefIterator iterator(
255        gfx::Rect(280, 280, 256, 256), 2.0, pile.get());
256    EXPECT_FALSE(iterator);
257  }
258  {
259    PicturePileImpl::PixelRefIterator iterator(
260        gfx::Rect(70, 70, 64, 64), 0.5, pile.get());
261    EXPECT_FALSE(iterator);
262  }
263  // Layer sized iterators.
264  {
265    PicturePileImpl::PixelRefIterator iterator(
266        gfx::Rect(0, 0, 256, 256), 1.0, pile.get());
267    EXPECT_FALSE(iterator);
268  }
269  {
270    PicturePileImpl::PixelRefIterator iterator(
271        gfx::Rect(0, 0, 512, 512), 2.0, pile.get());
272    EXPECT_FALSE(iterator);
273  }
274  {
275    PicturePileImpl::PixelRefIterator iterator(
276        gfx::Rect(0, 0, 128, 128), 0.5, pile.get());
277    EXPECT_FALSE(iterator);
278  }
279}
280
281TEST(PicturePileImplTest, PixelRefIteratorDiscardableRefs) {
282  gfx::Size tile_size(128, 128);
283  gfx::Size layer_bounds(256, 256);
284
285  scoped_refptr<FakePicturePileImpl> pile =
286      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
287
288  SkBitmap discardable_bitmap[2][2];
289  CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[0][0]);
290  CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[1][0]);
291  CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[1][1]);
292
293  // Discardable pixel refs are found in the following cells:
294  // |---|---|
295  // | x |   |
296  // |---|---|
297  // | x | x |
298  // |---|---|
299  pile->add_draw_bitmap(discardable_bitmap[0][0], gfx::Point(0, 0));
300  pile->add_draw_bitmap(discardable_bitmap[1][0], gfx::Point(0, 130));
301  pile->add_draw_bitmap(discardable_bitmap[1][1], gfx::Point(140, 140));
302
303  pile->RerecordPile();
304
305  // Tile sized iterators. These should find only one pixel ref.
306  {
307    PicturePileImpl::PixelRefIterator iterator(
308        gfx::Rect(0, 0, 128, 128), 1.0, pile.get());
309    EXPECT_TRUE(iterator);
310    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
311    EXPECT_FALSE(++iterator);
312  }
313  {
314    PicturePileImpl::PixelRefIterator iterator(
315        gfx::Rect(0, 0, 256, 256), 2.0, pile.get());
316    EXPECT_TRUE(iterator);
317    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
318    EXPECT_FALSE(++iterator);
319  }
320  {
321    PicturePileImpl::PixelRefIterator iterator(
322        gfx::Rect(0, 0, 64, 64), 0.5, pile.get());
323    EXPECT_TRUE(iterator);
324    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
325    EXPECT_FALSE(++iterator);
326  }
327  // Shifted tile sized iterators. These should find only one pixel ref.
328  {
329    PicturePileImpl::PixelRefIterator iterator(
330        gfx::Rect(140, 140, 128, 128), 1.0, pile.get());
331    EXPECT_TRUE(iterator);
332    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
333    EXPECT_FALSE(++iterator);
334  }
335  {
336    PicturePileImpl::PixelRefIterator iterator(
337        gfx::Rect(280, 280, 256, 256), 2.0, pile.get());
338    EXPECT_TRUE(iterator);
339    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
340    EXPECT_FALSE(++iterator);
341  }
342  {
343    PicturePileImpl::PixelRefIterator iterator(
344        gfx::Rect(70, 70, 64, 64), 0.5, pile.get());
345    EXPECT_TRUE(iterator);
346    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
347    EXPECT_FALSE(++iterator);
348  }
349  // Ensure there's no discardable pixel refs in the empty cell
350  {
351    PicturePileImpl::PixelRefIterator iterator(
352        gfx::Rect(140, 0, 128, 128), 1.0, pile.get());
353    EXPECT_FALSE(iterator);
354  }
355  // Layer sized iterators. These should find all 3 pixel refs.
356  {
357    PicturePileImpl::PixelRefIterator iterator(
358        gfx::Rect(0, 0, 256, 256), 1.0, pile.get());
359    EXPECT_TRUE(iterator);
360    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
361    EXPECT_TRUE(++iterator);
362    EXPECT_TRUE(*iterator == discardable_bitmap[1][0].pixelRef());
363    EXPECT_TRUE(++iterator);
364    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
365    EXPECT_FALSE(++iterator);
366  }
367  {
368    PicturePileImpl::PixelRefIterator iterator(
369        gfx::Rect(0, 0, 512, 512), 2.0, pile.get());
370    EXPECT_TRUE(iterator);
371    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
372    EXPECT_TRUE(++iterator);
373    EXPECT_TRUE(*iterator == discardable_bitmap[1][0].pixelRef());
374    EXPECT_TRUE(++iterator);
375    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
376    EXPECT_FALSE(++iterator);
377  }
378  {
379    PicturePileImpl::PixelRefIterator iterator(
380        gfx::Rect(0, 0, 128, 128), 0.5, pile.get());
381    EXPECT_TRUE(iterator);
382    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
383    EXPECT_TRUE(++iterator);
384    EXPECT_TRUE(*iterator == discardable_bitmap[1][0].pixelRef());
385    EXPECT_TRUE(++iterator);
386    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
387    EXPECT_FALSE(++iterator);
388  }
389}
390
391TEST(PicturePileImplTest, PixelRefIteratorDiscardableRefsOneTile) {
392  gfx::Size tile_size(256, 256);
393  gfx::Size layer_bounds(512, 512);
394
395  scoped_refptr<FakePicturePileImpl> pile =
396      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
397
398  SkBitmap discardable_bitmap[2][2];
399  CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[0][0]);
400  CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[0][1]);
401  CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[1][1]);
402
403  // Discardable pixel refs are found in the following cells:
404  // |---|---|
405  // | x | x |
406  // |---|---|
407  // |   | x |
408  // |---|---|
409  pile->add_draw_bitmap(discardable_bitmap[0][0], gfx::Point(0, 0));
410  pile->add_draw_bitmap(discardable_bitmap[0][1], gfx::Point(260, 0));
411  pile->add_draw_bitmap(discardable_bitmap[1][1], gfx::Point(260, 260));
412
413  pile->RerecordPile();
414
415  // Tile sized iterators. These should find only one pixel ref.
416  {
417    PicturePileImpl::PixelRefIterator iterator(
418        gfx::Rect(0, 0, 256, 256), 1.0, pile.get());
419    EXPECT_TRUE(iterator);
420    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
421    EXPECT_FALSE(++iterator);
422  }
423  {
424    PicturePileImpl::PixelRefIterator iterator(
425        gfx::Rect(0, 0, 512, 512), 2.0, pile.get());
426    EXPECT_TRUE(iterator);
427    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
428    EXPECT_FALSE(++iterator);
429  }
430  {
431    PicturePileImpl::PixelRefIterator iterator(
432        gfx::Rect(0, 0, 128, 128), 0.5, pile.get());
433    EXPECT_TRUE(iterator);
434    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
435    EXPECT_FALSE(++iterator);
436  }
437  // Shifted tile sized iterators. These should find only one pixel ref.
438  {
439    PicturePileImpl::PixelRefIterator iterator(
440        gfx::Rect(260, 260, 256, 256), 1.0, pile.get());
441    EXPECT_TRUE(iterator);
442    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
443    EXPECT_FALSE(++iterator);
444  }
445  {
446    PicturePileImpl::PixelRefIterator iterator(
447        gfx::Rect(520, 520, 512, 512), 2.0, pile.get());
448    EXPECT_TRUE(iterator);
449    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
450    EXPECT_FALSE(++iterator);
451  }
452  {
453    PicturePileImpl::PixelRefIterator iterator(
454        gfx::Rect(130, 130, 128, 128), 0.5, pile.get());
455    EXPECT_TRUE(iterator);
456    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
457    EXPECT_FALSE(++iterator);
458  }
459  // Ensure there's no discardable pixel refs in the empty cell
460  {
461    PicturePileImpl::PixelRefIterator iterator(
462        gfx::Rect(0, 256, 256, 256), 1.0, pile.get());
463    EXPECT_FALSE(iterator);
464  }
465  // Layer sized iterators. These should find three pixel ref.
466  {
467    PicturePileImpl::PixelRefIterator iterator(
468        gfx::Rect(0, 0, 512, 512), 1.0, pile.get());
469    EXPECT_TRUE(iterator);
470    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
471    EXPECT_TRUE(++iterator);
472    EXPECT_TRUE(*iterator == discardable_bitmap[0][1].pixelRef());
473    EXPECT_TRUE(++iterator);
474    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
475    EXPECT_FALSE(++iterator);
476  }
477  {
478    PicturePileImpl::PixelRefIterator iterator(
479        gfx::Rect(0, 0, 1024, 1024), 2.0, pile.get());
480    EXPECT_TRUE(iterator);
481    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
482    EXPECT_TRUE(++iterator);
483    EXPECT_TRUE(*iterator == discardable_bitmap[0][1].pixelRef());
484    EXPECT_TRUE(++iterator);
485    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
486    EXPECT_FALSE(++iterator);
487  }
488  {
489    PicturePileImpl::PixelRefIterator iterator(
490        gfx::Rect(0, 0, 256, 256), 0.5, pile.get());
491    EXPECT_TRUE(iterator);
492    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
493    EXPECT_TRUE(++iterator);
494    EXPECT_TRUE(*iterator == discardable_bitmap[0][1].pixelRef());
495    EXPECT_TRUE(++iterator);
496    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
497    EXPECT_FALSE(++iterator);
498  }
499
500  // Copy test.
501  PicturePileImpl::PixelRefIterator iterator(
502      gfx::Rect(0, 0, 512, 512), 1.0, pile.get());
503  EXPECT_TRUE(iterator);
504  EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
505  EXPECT_TRUE(++iterator);
506  EXPECT_TRUE(*iterator == discardable_bitmap[0][1].pixelRef());
507
508  // copy now points to the same spot as iterator,
509  // but both can be incremented independently.
510  PicturePileImpl::PixelRefIterator copy = iterator;
511  EXPECT_TRUE(++iterator);
512  EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
513  EXPECT_FALSE(++iterator);
514
515  EXPECT_TRUE(copy);
516  EXPECT_TRUE(*copy == discardable_bitmap[0][1].pixelRef());
517  EXPECT_TRUE(++copy);
518  EXPECT_TRUE(*copy == discardable_bitmap[1][1].pixelRef());
519  EXPECT_FALSE(++copy);
520}
521
522TEST(PicturePileImplTest, PixelRefIteratorDiscardableRefsBaseNonDiscardable) {
523  gfx::Size tile_size(256, 256);
524  gfx::Size layer_bounds(512, 512);
525
526  scoped_refptr<FakePicturePileImpl> pile =
527      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
528
529  SkBitmap non_discardable_bitmap;
530  CreateBitmap(gfx::Size(512, 512), "notdiscardable", &non_discardable_bitmap);
531
532  SkBitmap discardable_bitmap[2][2];
533  CreateBitmap(gfx::Size(128, 128), "discardable", &discardable_bitmap[0][0]);
534  CreateBitmap(gfx::Size(128, 128), "discardable", &discardable_bitmap[0][1]);
535  CreateBitmap(gfx::Size(128, 128), "discardable", &discardable_bitmap[1][1]);
536
537  // One large non-discardable bitmap covers the whole grid.
538  // Discardable pixel refs are found in the following cells:
539  // |---|---|
540  // | x | x |
541  // |---|---|
542  // |   | x |
543  // |---|---|
544  pile->add_draw_bitmap(non_discardable_bitmap, gfx::Point(0, 0));
545  pile->add_draw_bitmap(discardable_bitmap[0][0], gfx::Point(0, 0));
546  pile->add_draw_bitmap(discardable_bitmap[0][1], gfx::Point(260, 0));
547  pile->add_draw_bitmap(discardable_bitmap[1][1], gfx::Point(260, 260));
548
549  pile->RerecordPile();
550
551  // Tile sized iterators. These should find only one pixel ref.
552  {
553    PicturePileImpl::PixelRefIterator iterator(
554        gfx::Rect(0, 0, 256, 256), 1.0, pile.get());
555    EXPECT_TRUE(iterator);
556    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
557    EXPECT_FALSE(++iterator);
558  }
559  {
560    PicturePileImpl::PixelRefIterator iterator(
561        gfx::Rect(0, 0, 512, 512), 2.0, pile.get());
562    EXPECT_TRUE(iterator);
563    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
564    EXPECT_FALSE(++iterator);
565  }
566  {
567    PicturePileImpl::PixelRefIterator iterator(
568        gfx::Rect(0, 0, 128, 128), 0.5, pile.get());
569    EXPECT_TRUE(iterator);
570    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
571    EXPECT_FALSE(++iterator);
572  }
573  // Shifted tile sized iterators. These should find only one pixel ref.
574  {
575    PicturePileImpl::PixelRefIterator iterator(
576        gfx::Rect(260, 260, 256, 256), 1.0, pile.get());
577    EXPECT_TRUE(iterator);
578    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
579    EXPECT_FALSE(++iterator);
580  }
581  {
582    PicturePileImpl::PixelRefIterator iterator(
583        gfx::Rect(520, 520, 512, 512), 2.0, pile.get());
584    EXPECT_TRUE(iterator);
585    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
586    EXPECT_FALSE(++iterator);
587  }
588  {
589    PicturePileImpl::PixelRefIterator iterator(
590        gfx::Rect(130, 130, 128, 128), 0.5, pile.get());
591    EXPECT_TRUE(iterator);
592    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
593    EXPECT_FALSE(++iterator);
594  }
595  // Ensure there's no discardable pixel refs in the empty cell
596  {
597    PicturePileImpl::PixelRefIterator iterator(
598        gfx::Rect(0, 256, 256, 256), 1.0, pile.get());
599    EXPECT_FALSE(iterator);
600  }
601  // Layer sized iterators. These should find three pixel ref.
602  {
603    PicturePileImpl::PixelRefIterator iterator(
604        gfx::Rect(0, 0, 512, 512), 1.0, pile.get());
605    EXPECT_TRUE(iterator);
606    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
607    EXPECT_TRUE(++iterator);
608    EXPECT_TRUE(*iterator == discardable_bitmap[0][1].pixelRef());
609    EXPECT_TRUE(++iterator);
610    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
611    EXPECT_FALSE(++iterator);
612  }
613  {
614    PicturePileImpl::PixelRefIterator iterator(
615        gfx::Rect(0, 0, 1024, 1024), 2.0, pile.get());
616    EXPECT_TRUE(iterator);
617    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
618    EXPECT_TRUE(++iterator);
619    EXPECT_TRUE(*iterator == discardable_bitmap[0][1].pixelRef());
620    EXPECT_TRUE(++iterator);
621    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
622    EXPECT_FALSE(++iterator);
623  }
624  {
625    PicturePileImpl::PixelRefIterator iterator(
626        gfx::Rect(0, 0, 256, 256), 0.5, pile.get());
627    EXPECT_TRUE(iterator);
628    EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef());
629    EXPECT_TRUE(++iterator);
630    EXPECT_TRUE(*iterator == discardable_bitmap[0][1].pixelRef());
631    EXPECT_TRUE(++iterator);
632    EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef());
633    EXPECT_FALSE(++iterator);
634  }
635}
636
637class FullContentsTest : public ::testing::TestWithParam<bool> {};
638
639TEST_P(FullContentsTest, RasterFullContents) {
640  gfx::Size tile_size(1000, 1000);
641  gfx::Size layer_bounds(3, 5);
642  float contents_scale = 1.5f;
643  float raster_divisions = 2.f;
644  // Param in this case is whether the content is fully opaque
645  // or just filled completely. For this test they should behave the same.
646  bool contents_opaque = GetParam();
647  bool fills_content = !GetParam();
648
649  scoped_refptr<FakePicturePileImpl> pile =
650      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
651  // Because the caller sets content opaque, it also promises that it
652  // has at least filled in layer_bounds opaquely.
653  SkPaint white_paint;
654  white_paint.setColor(SK_ColorWHITE);
655  pile->add_draw_rect_with_paint(gfx::Rect(layer_bounds), white_paint);
656
657  pile->SetMinContentsScale(contents_scale);
658  pile->set_background_color(SK_ColorBLACK);
659  pile->set_contents_opaque(contents_opaque);
660  pile->set_contents_fill_bounds_completely(fills_content);
661  pile->set_clear_canvas_with_debug_color(false);
662  pile->RerecordPile();
663
664  gfx::Size content_bounds(
665      gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)));
666
667  // Simulate drawing into different tiles at different offsets.
668  int step_x = std::ceil(content_bounds.width() / raster_divisions);
669  int step_y = std::ceil(content_bounds.height() / raster_divisions);
670  for (int offset_x = 0; offset_x < content_bounds.width();
671       offset_x += step_x) {
672    for (int offset_y = 0; offset_y < content_bounds.height();
673         offset_y += step_y) {
674      gfx::Rect content_rect(offset_x, offset_y, step_x, step_y);
675      content_rect.Intersect(gfx::Rect(content_bounds));
676
677      // Simulate a canvas rect larger than the content rect.  Every pixel
678      // up to one pixel outside the content rect is guaranteed to be opaque.
679      // Outside of that is undefined.
680      gfx::Rect canvas_rect(content_rect);
681      canvas_rect.Inset(0, 0, -1, -1);
682
683      SkBitmap bitmap;
684      bitmap.allocN32Pixels(canvas_rect.width(), canvas_rect.height());
685      SkCanvas canvas(bitmap);
686      canvas.clear(SK_ColorTRANSPARENT);
687
688      FakeRenderingStatsInstrumentation rendering_stats_instrumentation;
689
690      pile->RasterToBitmap(&canvas,
691                           canvas_rect,
692                           contents_scale,
693                           &rendering_stats_instrumentation);
694
695      SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
696      int num_pixels = bitmap.width() * bitmap.height();
697      bool all_white = true;
698      for (int i = 0; i < num_pixels; ++i) {
699        EXPECT_EQ(SkColorGetA(pixels[i]), 255u);
700        all_white &= (SkColorGetR(pixels[i]) == 255);
701        all_white &= (SkColorGetG(pixels[i]) == 255);
702        all_white &= (SkColorGetB(pixels[i]) == 255);
703      }
704
705      // If the canvas doesn't extend past the edge of the content,
706      // it should be entirely white. Otherwise, the edge of the content
707      // will be non-white.
708      EXPECT_EQ(all_white, gfx::Rect(content_bounds).Contains(canvas_rect));
709    }
710  }
711}
712
713INSTANTIATE_TEST_CASE_P(PicturePileImpl,
714                        FullContentsTest,
715                        ::testing::Values(false, true));
716
717TEST(PicturePileImpl, RasterContentsTransparent) {
718  gfx::Size tile_size(1000, 1000);
719  gfx::Size layer_bounds(5, 3);
720  float contents_scale = 0.5f;
721
722  scoped_refptr<FakePicturePileImpl> pile =
723      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
724  pile->set_background_color(SK_ColorTRANSPARENT);
725  pile->set_contents_opaque(false);
726  pile->SetMinContentsScale(contents_scale);
727  pile->set_clear_canvas_with_debug_color(false);
728  pile->RerecordPile();
729
730  gfx::Size content_bounds(
731      gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)));
732
733  gfx::Rect canvas_rect(content_bounds);
734  canvas_rect.Inset(0, 0, -1, -1);
735
736  SkBitmap bitmap;
737  bitmap.allocN32Pixels(canvas_rect.width(), canvas_rect.height());
738  SkCanvas canvas(bitmap);
739
740  FakeRenderingStatsInstrumentation rendering_stats_instrumentation;
741  pile->RasterToBitmap(
742      &canvas, canvas_rect, contents_scale, &rendering_stats_instrumentation);
743
744  SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
745  int num_pixels = bitmap.width() * bitmap.height();
746  for (int i = 0; i < num_pixels; ++i) {
747    EXPECT_EQ(SkColorGetA(pixels[i]), 0u);
748  }
749}
750
751class OverlapTest : public ::testing::TestWithParam<float> {
752 public:
753  static float MinContentsScale() { return 1.f / 4.f; }
754};
755
756TEST_P(OverlapTest, NoOverlap) {
757  gfx::Size tile_size(10, 10);
758  gfx::Size layer_bounds(30, 30);
759  gfx::Size bigger_than_layer_bounds(300, 300);
760  float contents_scale = GetParam();
761  // Pick an opaque color to not have to deal with premultiplication off-by-one.
762  SkColor test_color = SkColorSetARGB(255, 45, 56, 67);
763
764  scoped_refptr<FakePicturePileImpl> pile =
765      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
766  pile->set_background_color(SK_ColorTRANSPARENT);
767  pile->set_contents_opaque(false);
768  pile->SetMinContentsScale(MinContentsScale());
769  pile->set_clear_canvas_with_debug_color(true);
770  SkPaint color_paint;
771  color_paint.setColor(test_color);
772  // Additive paint, so that if two paints overlap, the color will change.
773  color_paint.setXfermodeMode(SkXfermode::kPlus_Mode);
774  // Paint outside the layer to make sure that blending works.
775  pile->add_draw_rect_with_paint(gfx::RectF(bigger_than_layer_bounds),
776                                 color_paint);
777  pile->RerecordPile();
778
779  gfx::Size content_bounds(
780      gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)));
781
782  SkBitmap bitmap;
783  bitmap.allocN32Pixels(content_bounds.width(), content_bounds.height());
784  SkCanvas canvas(bitmap);
785
786  FakeRenderingStatsInstrumentation rendering_stats_instrumentation;
787  pile->RasterToBitmap(&canvas,
788                       gfx::Rect(content_bounds),
789                       contents_scale,
790                       &rendering_stats_instrumentation);
791
792  for (int y = 0; y < bitmap.height(); y++) {
793    for (int x = 0; x < bitmap.width(); x++) {
794      SkColor color = bitmap.getColor(x, y);
795      EXPECT_EQ(SkColorGetR(test_color), SkColorGetR(color)) << "x: " << x
796                                                             << ", y: " << y;
797      EXPECT_EQ(SkColorGetG(test_color), SkColorGetG(color)) << "x: " << x
798                                                             << ", y: " << y;
799      EXPECT_EQ(SkColorGetB(test_color), SkColorGetB(color)) << "x: " << x
800                                                             << ", y: " << y;
801      EXPECT_EQ(SkColorGetA(test_color), SkColorGetA(color)) << "x: " << x
802                                                             << ", y: " << y;
803      if (test_color != color)
804        break;
805    }
806  }
807}
808
809INSTANTIATE_TEST_CASE_P(PicturePileImpl,
810                        OverlapTest,
811                        ::testing::Values(1.f, 0.873f, 1.f / 4.f, 4.f));
812
813TEST(PicturePileImplTest, PixelRefIteratorBorders) {
814  // 3 tile width / 1 tile height pile
815  gfx::Size tile_size(128, 128);
816  gfx::Size layer_bounds(320, 128);
817
818  // Fake picture pile impl uses a tile grid the size of the tile.  So,
819  // any iteration that intersects with a tile will return all pixel refs
820  // inside of it.
821  scoped_refptr<FakePicturePileImpl> pile =
822      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
823  pile->SetMinContentsScale(0.5f);
824
825  // Bitmaps 0-2 are exactly on tiles 0-2, so that they overlap the borders
826  // of adjacent tiles.
827  gfx::Rect bitmap_rects[] = {pile->tiling().TileBounds(0, 0),
828                              pile->tiling().TileBounds(1, 0),
829                              pile->tiling().TileBounds(2, 0), };
830  SkBitmap discardable_bitmap[arraysize(bitmap_rects)];
831
832  for (size_t i = 0; i < arraysize(bitmap_rects); ++i) {
833    CreateBitmap(bitmap_rects[i].size(), "discardable", &discardable_bitmap[i]);
834    pile->add_draw_bitmap(discardable_bitmap[i], bitmap_rects[i].origin());
835  }
836
837  // Sanity check that bitmaps 0-2 intersect the borders of their adjacent
838  // tiles, but not the actual tiles.
839  EXPECT_TRUE(
840      bitmap_rects[0].Intersects(pile->tiling().TileBoundsWithBorder(1, 0)));
841  EXPECT_FALSE(bitmap_rects[0].Intersects(pile->tiling().TileBounds(1, 0)));
842  EXPECT_TRUE(
843      bitmap_rects[1].Intersects(pile->tiling().TileBoundsWithBorder(0, 0)));
844  EXPECT_FALSE(bitmap_rects[1].Intersects(pile->tiling().TileBounds(0, 0)));
845  EXPECT_TRUE(
846      bitmap_rects[1].Intersects(pile->tiling().TileBoundsWithBorder(2, 0)));
847  EXPECT_FALSE(bitmap_rects[1].Intersects(pile->tiling().TileBounds(2, 0)));
848  EXPECT_TRUE(
849      bitmap_rects[2].Intersects(pile->tiling().TileBoundsWithBorder(1, 0)));
850  EXPECT_FALSE(bitmap_rects[2].Intersects(pile->tiling().TileBounds(1, 0)));
851
852  pile->RerecordPile();
853
854  // Tile-sized iterators.
855  {
856    // Because tile 0's borders extend onto tile 1, it will include both
857    // bitmap 0 and 1.  However, it should *not* include bitmap 2.
858    PicturePileImpl::PixelRefIterator iterator(
859        pile->tiling().TileBounds(0, 0), 1.f, pile.get());
860    EXPECT_TRUE(iterator);
861    EXPECT_TRUE(*iterator == discardable_bitmap[0].pixelRef());
862    EXPECT_TRUE(++iterator);
863    EXPECT_TRUE(*iterator == discardable_bitmap[1].pixelRef());
864    EXPECT_FALSE(++iterator);
865  }
866  {
867    // Tile 1 + borders hits all bitmaps.
868    PicturePileImpl::PixelRefIterator iterator(
869        pile->tiling().TileBounds(1, 0), 1.f, pile.get());
870    EXPECT_TRUE(iterator);
871    EXPECT_TRUE(*iterator == discardable_bitmap[0].pixelRef());
872    EXPECT_TRUE(++iterator);
873    EXPECT_TRUE(*iterator == discardable_bitmap[1].pixelRef());
874    EXPECT_TRUE(++iterator);
875    EXPECT_TRUE(*iterator == discardable_bitmap[2].pixelRef());
876    EXPECT_FALSE(++iterator);
877  }
878  {
879    // Tile 2 should not include bitmap 0, which is only on tile 0 and the
880    // borders of tile 1.
881    PicturePileImpl::PixelRefIterator iterator(
882        pile->tiling().TileBounds(2, 0), 1.f, pile.get());
883    EXPECT_TRUE(iterator);
884    EXPECT_TRUE(*iterator == discardable_bitmap[1].pixelRef());
885    EXPECT_TRUE(++iterator);
886    EXPECT_TRUE(*iterator == discardable_bitmap[2].pixelRef());
887    EXPECT_FALSE(++iterator);
888  }
889}
890
891}  // namespace
892}  // namespace cc
893