cc: Adding DidFinishImplFrame to LTHI.
[chromium-blink-merge.git] / cc / resources / display_item_list_unittest.cc
blob2efc7ff149b2c89d4e8ae5d57d4c993b7d2513d8
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/resources/display_item_list.h"
7 #include <vector>
9 #include "cc/output/filter_operation.h"
10 #include "cc/output/filter_operations.h"
11 #include "cc/resources/clip_display_item.h"
12 #include "cc/resources/drawing_display_item.h"
13 #include "cc/resources/filter_display_item.h"
14 #include "cc/resources/transform_display_item.h"
15 #include "cc/test/skia_common.h"
16 #include "skia/ext/refptr.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "third_party/skia/include/core/SkCanvas.h"
20 #include "third_party/skia/include/core/SkColor.h"
21 #include "third_party/skia/include/core/SkPictureRecorder.h"
22 #include "third_party/skia/include/effects/SkBitmapSource.h"
23 #include "third_party/skia/include/utils/SkPictureUtils.h"
24 #include "ui/gfx/geometry/rect_conversions.h"
25 #include "ui/gfx/skia_util.h"
27 namespace cc {
29 TEST(DisplayItemListTest, SingleDrawingItem) {
30 gfx::Rect layer_rect(100, 100);
31 SkPictureRecorder recorder;
32 skia::RefPtr<SkCanvas> canvas;
33 skia::RefPtr<SkPicture> picture;
34 SkPaint blue_paint;
35 blue_paint.setColor(SK_ColorBLUE);
36 SkPaint red_paint;
37 red_paint.setColor(SK_ColorRED);
38 unsigned char pixels[4 * 100 * 100] = {0};
39 const bool use_cached_picture = true;
40 scoped_refptr<DisplayItemList> list =
41 DisplayItemList::Create(layer_rect, use_cached_picture);
43 gfx::PointF offset(8.f, 9.f);
44 gfx::RectF recording_rect(offset, layer_rect.size());
45 canvas = skia::SharePtr(
46 recorder.beginRecording(gfx::RectFToSkRect(recording_rect)));
47 canvas->translate(offset.x(), offset.y());
48 canvas->drawRectCoords(0.f, 0.f, 60.f, 60.f, red_paint);
49 canvas->drawRectCoords(50.f, 50.f, 75.f, 75.f, blue_paint);
50 picture = skia::AdoptRef(recorder.endRecordingAsPicture());
51 list->AppendItem(DrawingDisplayItem::Create(picture));
52 list->CreateAndCacheSkPicture();
53 DrawDisplayList(pixels, layer_rect, list);
55 SkBitmap expected_bitmap;
56 unsigned char expected_pixels[4 * 100 * 100] = {0};
57 SkImageInfo info =
58 SkImageInfo::MakeN32Premul(layer_rect.width(), layer_rect.height());
59 expected_bitmap.installPixels(info, expected_pixels, info.minRowBytes());
60 SkCanvas expected_canvas(expected_bitmap);
61 expected_canvas.clipRect(gfx::RectToSkRect(layer_rect));
62 expected_canvas.drawRectCoords(0.f + offset.x(), 0.f + offset.y(),
63 60.f + offset.x(), 60.f + offset.y(),
64 red_paint);
65 expected_canvas.drawRectCoords(50.f + offset.x(), 50.f + offset.y(),
66 75.f + offset.x(), 75.f + offset.y(),
67 blue_paint);
69 EXPECT_EQ(0, memcmp(pixels, expected_pixels, 4 * 100 * 100));
72 TEST(DisplayItemListTest, ClipItem) {
73 gfx::Rect layer_rect(100, 100);
74 SkPictureRecorder recorder;
75 skia::RefPtr<SkCanvas> canvas;
76 skia::RefPtr<SkPicture> picture;
77 SkPaint blue_paint;
78 blue_paint.setColor(SK_ColorBLUE);
79 SkPaint red_paint;
80 red_paint.setColor(SK_ColorRED);
81 unsigned char pixels[4 * 100 * 100] = {0};
82 const bool use_cached_picture = true;
83 scoped_refptr<DisplayItemList> list =
84 DisplayItemList::Create(layer_rect, use_cached_picture);
86 gfx::PointF first_offset(8.f, 9.f);
87 gfx::RectF first_recording_rect(first_offset, layer_rect.size());
88 canvas = skia::SharePtr(
89 recorder.beginRecording(gfx::RectFToSkRect(first_recording_rect)));
90 canvas->translate(first_offset.x(), first_offset.y());
91 canvas->drawRectCoords(0.f, 0.f, 60.f, 60.f, red_paint);
92 picture = skia::AdoptRef(recorder.endRecordingAsPicture());
93 list->AppendItem(DrawingDisplayItem::Create(picture));
95 gfx::Rect clip_rect(60, 60, 10, 10);
96 list->AppendItem(ClipDisplayItem::Create(clip_rect, std::vector<SkRRect>()));
98 gfx::PointF second_offset(2.f, 3.f);
99 gfx::RectF second_recording_rect(second_offset, layer_rect.size());
100 canvas = skia::SharePtr(
101 recorder.beginRecording(gfx::RectFToSkRect(second_recording_rect)));
102 canvas->translate(second_offset.x(), second_offset.y());
103 canvas->drawRectCoords(50.f, 50.f, 75.f, 75.f, blue_paint);
104 picture = skia::AdoptRef(recorder.endRecordingAsPicture());
105 list->AppendItem(DrawingDisplayItem::Create(picture));
107 list->AppendItem(EndClipDisplayItem::Create());
108 list->CreateAndCacheSkPicture();
110 DrawDisplayList(pixels, layer_rect, list);
112 SkBitmap expected_bitmap;
113 unsigned char expected_pixels[4 * 100 * 100] = {0};
114 SkImageInfo info =
115 SkImageInfo::MakeN32Premul(layer_rect.width(), layer_rect.height());
116 expected_bitmap.installPixels(info, expected_pixels, info.minRowBytes());
117 SkCanvas expected_canvas(expected_bitmap);
118 expected_canvas.clipRect(gfx::RectToSkRect(layer_rect));
119 expected_canvas.drawRectCoords(0.f + first_offset.x(), 0.f + first_offset.y(),
120 60.f + first_offset.x(),
121 60.f + first_offset.y(), red_paint);
122 expected_canvas.clipRect(gfx::RectToSkRect(clip_rect));
123 expected_canvas.drawRectCoords(
124 50.f + second_offset.x(), 50.f + second_offset.y(),
125 75.f + second_offset.x(), 75.f + second_offset.y(), blue_paint);
127 EXPECT_EQ(0, memcmp(pixels, expected_pixels, 4 * 100 * 100));
130 TEST(DisplayItemListTest, TransformItem) {
131 gfx::Rect layer_rect(100, 100);
132 SkPictureRecorder recorder;
133 skia::RefPtr<SkCanvas> canvas;
134 skia::RefPtr<SkPicture> picture;
135 SkPaint blue_paint;
136 blue_paint.setColor(SK_ColorBLUE);
137 SkPaint red_paint;
138 red_paint.setColor(SK_ColorRED);
139 unsigned char pixels[4 * 100 * 100] = {0};
140 const bool use_cached_picture = true;
141 scoped_refptr<DisplayItemList> list =
142 DisplayItemList::Create(layer_rect, use_cached_picture);
144 gfx::PointF first_offset(8.f, 9.f);
145 gfx::RectF first_recording_rect(first_offset, layer_rect.size());
146 canvas = skia::SharePtr(
147 recorder.beginRecording(gfx::RectFToSkRect(first_recording_rect)));
148 canvas->translate(first_offset.x(), first_offset.y());
149 canvas->drawRectCoords(0.f, 0.f, 60.f, 60.f, red_paint);
150 picture = skia::AdoptRef(recorder.endRecordingAsPicture());
151 list->AppendItem(DrawingDisplayItem::Create(picture));
153 gfx::Transform transform;
154 transform.Rotate(45.0);
155 list->AppendItem(TransformDisplayItem::Create(transform));
157 gfx::PointF second_offset(2.f, 3.f);
158 gfx::RectF second_recording_rect(second_offset, layer_rect.size());
159 canvas = skia::SharePtr(
160 recorder.beginRecording(gfx::RectFToSkRect(second_recording_rect)));
161 canvas->translate(second_offset.x(), second_offset.y());
162 canvas->drawRectCoords(50.f, 50.f, 75.f, 75.f, blue_paint);
163 picture = skia::AdoptRef(recorder.endRecordingAsPicture());
164 list->AppendItem(DrawingDisplayItem::Create(picture));
166 list->AppendItem(EndTransformDisplayItem::Create());
167 list->CreateAndCacheSkPicture();
169 DrawDisplayList(pixels, layer_rect, list);
171 SkBitmap expected_bitmap;
172 unsigned char expected_pixels[4 * 100 * 100] = {0};
173 SkImageInfo info =
174 SkImageInfo::MakeN32Premul(layer_rect.width(), layer_rect.height());
175 expected_bitmap.installPixels(info, expected_pixels, info.minRowBytes());
176 SkCanvas expected_canvas(expected_bitmap);
177 expected_canvas.clipRect(gfx::RectToSkRect(layer_rect));
178 expected_canvas.drawRectCoords(0.f + first_offset.x(), 0.f + first_offset.y(),
179 60.f + first_offset.x(),
180 60.f + first_offset.y(), red_paint);
181 expected_canvas.setMatrix(transform.matrix());
182 expected_canvas.drawRectCoords(
183 50.f + second_offset.x(), 50.f + second_offset.y(),
184 75.f + second_offset.x(), 75.f + second_offset.y(), blue_paint);
186 EXPECT_EQ(0, memcmp(pixels, expected_pixels, 4 * 100 * 100));
189 TEST(DisplayItemListTest, FilterItem) {
190 gfx::Rect layer_rect(100, 100);
191 FilterOperations filters;
192 unsigned char pixels[4 * 100 * 100] = {0};
193 const bool use_cached_picture = true;
194 scoped_refptr<DisplayItemList> list =
195 DisplayItemList::Create(layer_rect, use_cached_picture);
197 SkBitmap source_bitmap;
198 source_bitmap.allocN32Pixels(50, 50);
199 SkCanvas source_canvas(source_bitmap);
200 source_canvas.clear(SkColorSetRGB(128, 128, 128));
202 // For most SkImageFilters, the |dst| bounds computed by computeFastBounds are
203 // dependent on the provided |src| bounds. This means, for example, that
204 // translating |src| results in a corresponding translation of |dst|. But this
205 // is not the case for all SkImageFilters; for some of them (e.g.
206 // SkBitmapSource), the computation of |dst| in computeFastBounds doesn't
207 // involve |src| at all. Incorrectly assuming such a relationship (e.g. by
208 // translating |dst| after it is computed by computeFastBounds, rather than
209 // translating |src| before it provided to computedFastBounds) can cause
210 // incorrect clipping of filter output. To test for this, we include an
211 // SkBitmapSource filter in |filters|. Here, |src| is |filter_bounds|, defined
212 // below.
213 skia::RefPtr<SkImageFilter> image_filter =
214 skia::AdoptRef(SkBitmapSource::Create(source_bitmap));
215 filters.Append(FilterOperation::CreateReferenceFilter(image_filter));
216 filters.Append(FilterOperation::CreateBrightnessFilter(0.5f));
217 gfx::RectF filter_bounds(10.f, 10.f, 50.f, 50.f);
218 list->AppendItem(FilterDisplayItem::Create(filters, filter_bounds));
219 list->AppendItem(EndFilterDisplayItem::Create());
220 list->CreateAndCacheSkPicture();
222 DrawDisplayList(pixels, layer_rect, list);
224 SkBitmap expected_bitmap;
225 unsigned char expected_pixels[4 * 100 * 100] = {0};
226 SkPaint paint;
227 paint.setColor(SkColorSetRGB(64, 64, 64));
228 SkImageInfo info =
229 SkImageInfo::MakeN32Premul(layer_rect.width(), layer_rect.height());
230 expected_bitmap.installPixels(info, expected_pixels, info.minRowBytes());
231 SkCanvas expected_canvas(expected_bitmap);
232 expected_canvas.drawRect(RectFToSkRect(filter_bounds), paint);
234 EXPECT_EQ(0, memcmp(pixels, expected_pixels, 4 * 100 * 100));
237 TEST(DisplayItemListTest, CompactingItems) {
238 gfx::Rect layer_rect(100, 100);
239 SkPictureRecorder recorder;
240 skia::RefPtr<SkCanvas> canvas;
241 skia::RefPtr<SkPicture> picture;
242 SkPaint blue_paint;
243 blue_paint.setColor(SK_ColorBLUE);
244 SkPaint red_paint;
245 red_paint.setColor(SK_ColorRED);
246 unsigned char pixels[4 * 100 * 100] = {0};
248 gfx::PointF offset(8.f, 9.f);
249 gfx::RectF recording_rect(offset, layer_rect.size());
251 bool use_cached_picture = false;
252 scoped_refptr<DisplayItemList> list_without_caching =
253 DisplayItemList::Create(layer_rect, use_cached_picture);
255 canvas = skia::SharePtr(
256 recorder.beginRecording(gfx::RectFToSkRect(recording_rect)));
257 canvas->translate(offset.x(), offset.y());
258 canvas->drawRectCoords(0.f, 0.f, 60.f, 60.f, red_paint);
259 canvas->drawRectCoords(50.f, 50.f, 75.f, 75.f, blue_paint);
260 picture = skia::AdoptRef(recorder.endRecordingAsPicture());
261 list_without_caching->AppendItem(DrawingDisplayItem::Create(picture));
262 DrawDisplayList(pixels, layer_rect, list_without_caching);
264 unsigned char expected_pixels[4 * 100 * 100] = {0};
265 use_cached_picture = true;
266 scoped_refptr<DisplayItemList> list_with_caching =
267 DisplayItemList::Create(layer_rect, use_cached_picture);
268 list_with_caching->AppendItem(DrawingDisplayItem::Create(picture));
269 list_with_caching->CreateAndCacheSkPicture();
270 DrawDisplayList(expected_pixels, layer_rect, list_with_caching);
272 EXPECT_EQ(0, memcmp(pixels, expected_pixels, 4 * 100 * 100));
275 TEST(DisplayItemListTest, PictureMemoryUsage) {
276 scoped_refptr<DisplayItemList> list;
277 size_t memory_usage;
279 // Make an SkPicture whose size is known.
280 gfx::Rect layer_rect(100, 100);
281 SkPictureRecorder recorder;
282 SkPaint blue_paint;
283 blue_paint.setColor(SK_ColorBLUE);
284 SkCanvas* canvas = recorder.beginRecording(gfx::RectFToSkRect(layer_rect));
285 for (int i = 0; i < 100; i++)
286 canvas->drawPaint(blue_paint);
287 skia::RefPtr<SkPicture> picture =
288 skia::AdoptRef(recorder.endRecordingAsPicture());
289 size_t picture_size = SkPictureUtils::ApproximateBytesUsed(picture.get());
290 ASSERT_GE(picture_size, 100 * sizeof(SkPaint));
291 ASSERT_LE(picture_size, 200 * sizeof(SkPaint));
293 // Using a cached picture, we should get about the right size.
294 list = DisplayItemList::Create(layer_rect, true);
295 list->AppendItem(DrawingDisplayItem::Create(picture));
296 list->CreateAndCacheSkPicture();
297 memory_usage = list->PictureMemoryUsage();
298 EXPECT_GE(memory_usage, picture_size);
299 EXPECT_LE(memory_usage, 2 * picture_size);
301 // Using no cached picture, we should still get the right size.
302 list = DisplayItemList::Create(layer_rect, false);
303 list->AppendItem(DrawingDisplayItem::Create(picture));
304 memory_usage = list->PictureMemoryUsage();
305 EXPECT_GE(memory_usage, picture_size);
306 EXPECT_LE(memory_usage, 2 * picture_size);
308 // To avoid double counting, we expect zero size to be computed if both the
309 // picture and items are retained (currently this only happens due to certain
310 // categories being traced).
311 list = new DisplayItemList(layer_rect, true, true);
312 list->AppendItem(DrawingDisplayItem::Create(picture));
313 list->CreateAndCacheSkPicture();
314 memory_usage = list->PictureMemoryUsage();
315 EXPECT_EQ(static_cast<size_t>(0), memory_usage);
318 } // namespace cc