Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / cc / resources / picture_pile_impl_unittest.cc
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
16 namespace cc {
17 namespace {
18
19 TEST(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
77 TEST(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
135 TEST(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
150 TEST(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
208 TEST(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
281 TEST(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
391 TEST(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
522 TEST(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
637 class FullContentsTest : public ::testing::TestWithParam<bool> {};
638
639 TEST_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
713 INSTANTIATE_TEST_CASE_P(PicturePileImpl,
714                         FullContentsTest,
715                         ::testing::Values(false, true));
716
717 TEST(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
751 class OverlapTest : public ::testing::TestWithParam<float> {
752  public:
753   static float MinContentsScale() { return 1.f / 4.f; }
754 };
755
756 TEST_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.setConfig(SkBitmap::kARGB_8888_Config,
784                    content_bounds.width(),
785                    content_bounds.height());
786   bitmap.allocPixels();
787   SkCanvas canvas(bitmap);
788
789   FakeRenderingStatsInstrumentation rendering_stats_instrumentation;
790   pile->RasterToBitmap(&canvas,
791                        gfx::Rect(content_bounds),
792                        contents_scale,
793                        &rendering_stats_instrumentation);
794
795   for (int y = 0; y < bitmap.height(); y++) {
796     for (int x = 0; x < bitmap.width(); x++) {
797       SkColor color = bitmap.getColor(x, y);
798       EXPECT_EQ(SkColorGetR(test_color), SkColorGetR(color)) << "x: " << x
799                                                              << ", y: " << y;
800       EXPECT_EQ(SkColorGetG(test_color), SkColorGetG(color)) << "x: " << x
801                                                              << ", y: " << y;
802       EXPECT_EQ(SkColorGetB(test_color), SkColorGetB(color)) << "x: " << x
803                                                              << ", y: " << y;
804       EXPECT_EQ(SkColorGetA(test_color), SkColorGetA(color)) << "x: " << x
805                                                              << ", y: " << y;
806       if (test_color != color)
807         break;
808     }
809   }
810 }
811
812 INSTANTIATE_TEST_CASE_P(PicturePileImpl,
813                         OverlapTest,
814                         ::testing::Values(1.f, 0.873f, 1.f / 4.f, 4.f));
815
816 TEST(PicturePileImplTest, PixelRefIteratorBorders) {
817   // 3 tile width / 1 tile height pile
818   gfx::Size tile_size(128, 128);
819   gfx::Size layer_bounds(320, 128);
820
821   // Fake picture pile impl uses a tile grid the size of the tile.  So,
822   // any iteration that intersects with a tile will return all pixel refs
823   // inside of it.
824   scoped_refptr<FakePicturePileImpl> pile =
825       FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
826   pile->SetMinContentsScale(0.5f);
827
828   // Bitmaps 0-2 are exactly on tiles 0-2, so that they overlap the borders
829   // of adjacent tiles.
830   gfx::Rect bitmap_rects[] = {pile->tiling().TileBounds(0, 0),
831                               pile->tiling().TileBounds(1, 0),
832                               pile->tiling().TileBounds(2, 0), };
833   SkBitmap discardable_bitmap[arraysize(bitmap_rects)];
834
835   for (size_t i = 0; i < arraysize(bitmap_rects); ++i) {
836     CreateBitmap(bitmap_rects[i].size(), "discardable", &discardable_bitmap[i]);
837     pile->add_draw_bitmap(discardable_bitmap[i], bitmap_rects[i].origin());
838   }
839
840   // Sanity check that bitmaps 0-2 intersect the borders of their adjacent
841   // tiles, but not the actual tiles.
842   EXPECT_TRUE(
843       bitmap_rects[0].Intersects(pile->tiling().TileBoundsWithBorder(1, 0)));
844   EXPECT_FALSE(bitmap_rects[0].Intersects(pile->tiling().TileBounds(1, 0)));
845   EXPECT_TRUE(
846       bitmap_rects[1].Intersects(pile->tiling().TileBoundsWithBorder(0, 0)));
847   EXPECT_FALSE(bitmap_rects[1].Intersects(pile->tiling().TileBounds(0, 0)));
848   EXPECT_TRUE(
849       bitmap_rects[1].Intersects(pile->tiling().TileBoundsWithBorder(2, 0)));
850   EXPECT_FALSE(bitmap_rects[1].Intersects(pile->tiling().TileBounds(2, 0)));
851   EXPECT_TRUE(
852       bitmap_rects[2].Intersects(pile->tiling().TileBoundsWithBorder(1, 0)));
853   EXPECT_FALSE(bitmap_rects[2].Intersects(pile->tiling().TileBounds(1, 0)));
854
855   pile->RerecordPile();
856
857   // Tile-sized iterators.
858   {
859     // Because tile 0's borders extend onto tile 1, it will include both
860     // bitmap 0 and 1.  However, it should *not* include bitmap 2.
861     PicturePileImpl::PixelRefIterator iterator(
862         pile->tiling().TileBounds(0, 0), 1.f, pile.get());
863     EXPECT_TRUE(iterator);
864     EXPECT_TRUE(*iterator == discardable_bitmap[0].pixelRef());
865     EXPECT_TRUE(++iterator);
866     EXPECT_TRUE(*iterator == discardable_bitmap[1].pixelRef());
867     EXPECT_FALSE(++iterator);
868   }
869   {
870     // Tile 1 + borders hits all bitmaps.
871     PicturePileImpl::PixelRefIterator iterator(
872         pile->tiling().TileBounds(1, 0), 1.f, pile.get());
873     EXPECT_TRUE(iterator);
874     EXPECT_TRUE(*iterator == discardable_bitmap[0].pixelRef());
875     EXPECT_TRUE(++iterator);
876     EXPECT_TRUE(*iterator == discardable_bitmap[1].pixelRef());
877     EXPECT_TRUE(++iterator);
878     EXPECT_TRUE(*iterator == discardable_bitmap[2].pixelRef());
879     EXPECT_FALSE(++iterator);
880   }
881   {
882     // Tile 2 should not include bitmap 0, which is only on tile 0 and the
883     // borders of tile 1.
884     PicturePileImpl::PixelRefIterator iterator(
885         pile->tiling().TileBounds(2, 0), 1.f, pile.get());
886     EXPECT_TRUE(iterator);
887     EXPECT_TRUE(*iterator == discardable_bitmap[1].pixelRef());
888     EXPECT_TRUE(++iterator);
889     EXPECT_TRUE(*iterator == discardable_bitmap[2].pixelRef());
890     EXPECT_FALSE(++iterator);
891   }
892 }
893
894 }  // namespace
895 }  // namespace cc