OLD | NEW |
| (Empty) |
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/playback/raster_source.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include <memory> | |
10 | |
11 #include "cc/test/fake_recording_source.h" | |
12 #include "cc/test/skia_common.h" | |
13 #include "cc/tiles/software_image_decode_cache.h" | |
14 #include "testing/gtest/include/gtest/gtest.h" | |
15 #include "third_party/skia/include/core/SkPixelRef.h" | |
16 #include "third_party/skia/include/core/SkRefCnt.h" | |
17 #include "third_party/skia/include/core/SkShader.h" | |
18 #include "ui/gfx/geometry/rect.h" | |
19 #include "ui/gfx/geometry/size_conversions.h" | |
20 | |
21 namespace cc { | |
22 namespace { | |
23 | |
24 gfx::ColorSpace ColorSpaceForTesting() { | |
25 return gfx::ColorSpace(); | |
26 } | |
27 | |
28 TEST(RasterSourceTest, AnalyzeIsSolidUnscaled) { | |
29 gfx::Size layer_bounds(400, 400); | |
30 | |
31 std::unique_ptr<FakeRecordingSource> recording_source = | |
32 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); | |
33 | |
34 PaintFlags solid_flags; | |
35 SkColor solid_color = SkColorSetARGB(255, 12, 23, 34); | |
36 solid_flags.setColor(solid_color); | |
37 | |
38 SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67); | |
39 SkColor color = SK_ColorTRANSPARENT; | |
40 PaintFlags non_solid_flags; | |
41 bool is_solid_color = false; | |
42 non_solid_flags.setColor(non_solid_color); | |
43 | |
44 recording_source->add_draw_rect_with_flags(gfx::Rect(layer_bounds), | |
45 solid_flags); | |
46 recording_source->Rerecord(); | |
47 | |
48 scoped_refptr<RasterSource> raster = | |
49 RasterSource::CreateFromRecordingSource(recording_source.get(), false); | |
50 | |
51 // Ensure everything is solid. | |
52 for (int y = 0; y <= 300; y += 100) { | |
53 for (int x = 0; x <= 300; x += 100) { | |
54 gfx::Rect rect(x, y, 100, 100); | |
55 is_solid_color = raster->PerformSolidColorAnalysis(rect, 1.f, &color); | |
56 EXPECT_TRUE(is_solid_color) << rect.ToString(); | |
57 EXPECT_EQ(solid_color, color) << rect.ToString(); | |
58 } | |
59 } | |
60 | |
61 // Add one non-solid pixel and recreate the raster source. | |
62 recording_source->add_draw_rect_with_flags(gfx::Rect(50, 50, 1, 1), | |
63 non_solid_flags); | |
64 recording_source->Rerecord(); | |
65 raster = | |
66 RasterSource::CreateFromRecordingSource(recording_source.get(), false); | |
67 | |
68 color = SK_ColorTRANSPARENT; | |
69 is_solid_color = | |
70 raster->PerformSolidColorAnalysis(gfx::Rect(0, 0, 100, 100), 1.f, &color); | |
71 EXPECT_FALSE(is_solid_color); | |
72 | |
73 color = SK_ColorTRANSPARENT; | |
74 is_solid_color = raster->PerformSolidColorAnalysis( | |
75 gfx::Rect(100, 0, 100, 100), 1.f, &color); | |
76 EXPECT_TRUE(is_solid_color); | |
77 EXPECT_EQ(solid_color, color); | |
78 | |
79 // Boundaries should be clipped. | |
80 color = SK_ColorTRANSPARENT; | |
81 is_solid_color = raster->PerformSolidColorAnalysis( | |
82 gfx::Rect(350, 0, 100, 100), 1.f, &color); | |
83 EXPECT_TRUE(is_solid_color); | |
84 EXPECT_EQ(solid_color, color); | |
85 | |
86 color = SK_ColorTRANSPARENT; | |
87 is_solid_color = raster->PerformSolidColorAnalysis( | |
88 gfx::Rect(0, 350, 100, 100), 1.f, &color); | |
89 EXPECT_TRUE(is_solid_color); | |
90 EXPECT_EQ(solid_color, color); | |
91 | |
92 color = SK_ColorTRANSPARENT; | |
93 is_solid_color = raster->PerformSolidColorAnalysis( | |
94 gfx::Rect(350, 350, 100, 100), 1.f, &color); | |
95 EXPECT_TRUE(is_solid_color); | |
96 EXPECT_EQ(solid_color, color); | |
97 } | |
98 | |
99 TEST(RasterSourceTest, AnalyzeIsSolidScaled) { | |
100 gfx::Size layer_bounds(400, 400); | |
101 | |
102 std::unique_ptr<FakeRecordingSource> recording_source = | |
103 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); | |
104 | |
105 SkColor solid_color = SkColorSetARGB(255, 12, 23, 34); | |
106 SkColor color = SK_ColorTRANSPARENT; | |
107 PaintFlags solid_flags; | |
108 bool is_solid_color = false; | |
109 solid_flags.setColor(solid_color); | |
110 | |
111 SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67); | |
112 PaintFlags non_solid_flags; | |
113 non_solid_flags.setColor(non_solid_color); | |
114 | |
115 recording_source->add_draw_rect_with_flags(gfx::Rect(0, 0, 400, 400), | |
116 solid_flags); | |
117 recording_source->Rerecord(); | |
118 | |
119 scoped_refptr<RasterSource> raster = | |
120 RasterSource::CreateFromRecordingSource(recording_source.get(), false); | |
121 | |
122 // Ensure everything is solid. | |
123 for (int y = 0; y <= 30; y += 10) { | |
124 for (int x = 0; x <= 30; x += 10) { | |
125 gfx::Rect rect(x, y, 10, 10); | |
126 is_solid_color = raster->PerformSolidColorAnalysis(rect, 0.1f, &color); | |
127 EXPECT_TRUE(is_solid_color) << rect.ToString(); | |
128 EXPECT_EQ(color, solid_color) << rect.ToString(); | |
129 } | |
130 } | |
131 | |
132 // Add one non-solid pixel and recreate the raster source. | |
133 recording_source->add_draw_rect_with_flags(gfx::Rect(50, 50, 1, 1), | |
134 non_solid_flags); | |
135 recording_source->Rerecord(); | |
136 raster = | |
137 RasterSource::CreateFromRecordingSource(recording_source.get(), false); | |
138 | |
139 color = SK_ColorTRANSPARENT; | |
140 is_solid_color = | |
141 raster->PerformSolidColorAnalysis(gfx::Rect(0, 0, 10, 10), 0.1f, &color); | |
142 EXPECT_FALSE(is_solid_color); | |
143 | |
144 color = SK_ColorTRANSPARENT; | |
145 is_solid_color = | |
146 raster->PerformSolidColorAnalysis(gfx::Rect(10, 0, 10, 10), 0.1f, &color); | |
147 EXPECT_TRUE(is_solid_color); | |
148 EXPECT_EQ(color, solid_color); | |
149 | |
150 // Boundaries should be clipped. | |
151 color = SK_ColorTRANSPARENT; | |
152 is_solid_color = | |
153 raster->PerformSolidColorAnalysis(gfx::Rect(35, 0, 10, 10), 0.1f, &color); | |
154 EXPECT_TRUE(is_solid_color); | |
155 EXPECT_EQ(color, solid_color); | |
156 | |
157 color = SK_ColorTRANSPARENT; | |
158 is_solid_color = | |
159 raster->PerformSolidColorAnalysis(gfx::Rect(0, 35, 10, 10), 0.1f, &color); | |
160 EXPECT_TRUE(is_solid_color); | |
161 EXPECT_EQ(color, solid_color); | |
162 | |
163 color = SK_ColorTRANSPARENT; | |
164 is_solid_color = raster->PerformSolidColorAnalysis(gfx::Rect(35, 35, 10, 10), | |
165 0.1f, &color); | |
166 EXPECT_TRUE(is_solid_color); | |
167 EXPECT_EQ(color, solid_color); | |
168 } | |
169 | |
170 TEST(RasterSourceTest, AnalyzeIsSolidEmpty) { | |
171 gfx::Size layer_bounds(400, 400); | |
172 | |
173 std::unique_ptr<FakeRecordingSource> recording_source = | |
174 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); | |
175 recording_source->Rerecord(); | |
176 | |
177 scoped_refptr<RasterSource> raster = | |
178 RasterSource::CreateFromRecordingSource(recording_source.get(), false); | |
179 | |
180 SkColor color = SK_ColorTRANSPARENT; | |
181 bool is_solid_color = | |
182 raster->PerformSolidColorAnalysis(gfx::Rect(0, 0, 400, 400), 1.f, &color); | |
183 | |
184 EXPECT_TRUE(is_solid_color); | |
185 EXPECT_EQ(color, SkColorSetARGB(0, 0, 0, 0)); | |
186 } | |
187 | |
188 TEST(RasterSourceTest, PixelRefIteratorDiscardableRefsOneTile) { | |
189 gfx::Size layer_bounds(512, 512); | |
190 | |
191 std::unique_ptr<FakeRecordingSource> recording_source = | |
192 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); | |
193 | |
194 sk_sp<SkImage> discardable_image[2][2]; | |
195 discardable_image[0][0] = CreateDiscardableImage(gfx::Size(32, 32)); | |
196 discardable_image[0][1] = CreateDiscardableImage(gfx::Size(32, 32)); | |
197 discardable_image[1][1] = CreateDiscardableImage(gfx::Size(32, 32)); | |
198 | |
199 // Discardable pixel refs are found in the following cells: | |
200 // |---|---| | |
201 // | x | x | | |
202 // |---|---| | |
203 // | | x | | |
204 // |---|---| | |
205 recording_source->add_draw_image(discardable_image[0][0], gfx::Point(0, 0)); | |
206 recording_source->add_draw_image(discardable_image[0][1], gfx::Point(260, 0)); | |
207 recording_source->add_draw_image(discardable_image[1][1], | |
208 gfx::Point(260, 260)); | |
209 recording_source->SetGenerateDiscardableImagesMetadata(true); | |
210 recording_source->Rerecord(); | |
211 | |
212 scoped_refptr<RasterSource> raster = | |
213 RasterSource::CreateFromRecordingSource(recording_source.get(), false); | |
214 | |
215 // Tile sized iterators. These should find only one pixel ref. | |
216 { | |
217 std::vector<DrawImage> images; | |
218 raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), 1.f, &images); | |
219 EXPECT_EQ(1u, images.size()); | |
220 EXPECT_EQ(discardable_image[0][0], images[0].image()); | |
221 } | |
222 // Shifted tile sized iterators. These should find only one pixel ref. | |
223 { | |
224 std::vector<DrawImage> images; | |
225 raster->GetDiscardableImagesInRect(gfx::Rect(260, 260, 256, 256), 1.f, | |
226 &images); | |
227 EXPECT_EQ(1u, images.size()); | |
228 EXPECT_EQ(discardable_image[1][1], images[0].image()); | |
229 } | |
230 // Ensure there's no discardable pixel refs in the empty cell | |
231 { | |
232 std::vector<DrawImage> images; | |
233 raster->GetDiscardableImagesInRect(gfx::Rect(0, 256, 256, 256), 1.f, | |
234 &images); | |
235 EXPECT_EQ(0u, images.size()); | |
236 } | |
237 // Layer sized iterators. These should find three pixel ref. | |
238 { | |
239 std::vector<DrawImage> images; | |
240 raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 512, 512), 1.f, &images); | |
241 EXPECT_EQ(3u, images.size()); | |
242 EXPECT_EQ(discardable_image[0][0], images[0].image()); | |
243 EXPECT_EQ(discardable_image[0][1], images[1].image()); | |
244 EXPECT_EQ(discardable_image[1][1], images[2].image()); | |
245 } | |
246 } | |
247 | |
248 TEST(RasterSourceTest, RasterFullContents) { | |
249 gfx::Size layer_bounds(3, 5); | |
250 float contents_scale = 1.5f; | |
251 float raster_divisions = 2.f; | |
252 | |
253 std::unique_ptr<FakeRecordingSource> recording_source = | |
254 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); | |
255 recording_source->SetBackgroundColor(SK_ColorBLACK); | |
256 recording_source->SetClearCanvasWithDebugColor(false); | |
257 | |
258 // Because the caller sets content opaque, it also promises that it | |
259 // has at least filled in layer_bounds opaquely. | |
260 PaintFlags white_flags; | |
261 white_flags.setColor(SK_ColorWHITE); | |
262 recording_source->add_draw_rect_with_flags(gfx::Rect(layer_bounds), | |
263 white_flags); | |
264 recording_source->Rerecord(); | |
265 | |
266 scoped_refptr<RasterSource> raster = | |
267 RasterSource::CreateFromRecordingSource(recording_source.get(), false); | |
268 | |
269 gfx::Size content_bounds( | |
270 gfx::ScaleToCeiledSize(layer_bounds, contents_scale)); | |
271 | |
272 // Simulate drawing into different tiles at different offsets. | |
273 int step_x = std::ceil(content_bounds.width() / raster_divisions); | |
274 int step_y = std::ceil(content_bounds.height() / raster_divisions); | |
275 for (int offset_x = 0; offset_x < content_bounds.width(); | |
276 offset_x += step_x) { | |
277 for (int offset_y = 0; offset_y < content_bounds.height(); | |
278 offset_y += step_y) { | |
279 gfx::Rect content_rect(offset_x, offset_y, step_x, step_y); | |
280 content_rect.Intersect(gfx::Rect(content_bounds)); | |
281 | |
282 // Simulate a canvas rect larger than the content rect. Every pixel | |
283 // up to one pixel outside the content rect is guaranteed to be opaque. | |
284 // Outside of that is undefined. | |
285 gfx::Rect canvas_rect(content_rect); | |
286 canvas_rect.Inset(0, 0, -1, -1); | |
287 | |
288 SkBitmap bitmap; | |
289 bitmap.allocN32Pixels(canvas_rect.width(), canvas_rect.height()); | |
290 SkCanvas canvas(bitmap); | |
291 canvas.clear(SK_ColorTRANSPARENT); | |
292 | |
293 raster->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), canvas_rect, | |
294 canvas_rect, contents_scale, | |
295 RasterSource::PlaybackSettings()); | |
296 | |
297 SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); | |
298 int num_pixels = bitmap.width() * bitmap.height(); | |
299 bool all_white = true; | |
300 for (int i = 0; i < num_pixels; ++i) { | |
301 EXPECT_EQ(SkColorGetA(pixels[i]), 255u); | |
302 all_white &= (SkColorGetR(pixels[i]) == 255); | |
303 all_white &= (SkColorGetG(pixels[i]) == 255); | |
304 all_white &= (SkColorGetB(pixels[i]) == 255); | |
305 } | |
306 | |
307 // If the canvas doesn't extend past the edge of the content, | |
308 // it should be entirely white. Otherwise, the edge of the content | |
309 // will be non-white. | |
310 EXPECT_EQ(all_white, gfx::Rect(content_bounds).Contains(canvas_rect)); | |
311 } | |
312 } | |
313 } | |
314 | |
315 TEST(RasterSourceTest, RasterPartialContents) { | |
316 gfx::Size layer_bounds(3, 5); | |
317 float contents_scale = 1.5f; | |
318 | |
319 std::unique_ptr<FakeRecordingSource> recording_source = | |
320 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); | |
321 recording_source->SetBackgroundColor(SK_ColorGREEN); | |
322 recording_source->SetClearCanvasWithDebugColor(false); | |
323 | |
324 // First record everything as white. | |
325 PaintFlags white_flags; | |
326 white_flags.setColor(SK_ColorWHITE); | |
327 recording_source->add_draw_rect_with_flags(gfx::Rect(layer_bounds), | |
328 white_flags); | |
329 recording_source->Rerecord(); | |
330 | |
331 scoped_refptr<RasterSource> raster = | |
332 RasterSource::CreateFromRecordingSource(recording_source.get(), false); | |
333 | |
334 gfx::Size content_bounds( | |
335 gfx::ScaleToCeiledSize(layer_bounds, contents_scale)); | |
336 | |
337 SkBitmap bitmap; | |
338 bitmap.allocN32Pixels(content_bounds.width(), content_bounds.height()); | |
339 SkCanvas canvas(bitmap); | |
340 canvas.clear(SK_ColorTRANSPARENT); | |
341 | |
342 // Playback the full rect which should make everything white. | |
343 gfx::Rect raster_full_rect(content_bounds); | |
344 gfx::Rect playback_rect(content_bounds); | |
345 raster->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), raster_full_rect, | |
346 playback_rect, contents_scale, | |
347 RasterSource::PlaybackSettings()); | |
348 | |
349 { | |
350 SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); | |
351 for (int i = 0; i < bitmap.width(); ++i) { | |
352 for (int j = 0; j < bitmap.height(); ++j) { | |
353 SCOPED_TRACE(i); | |
354 SCOPED_TRACE(j); | |
355 EXPECT_EQ(255u, SkColorGetA(pixels[i + j * bitmap.width()])); | |
356 EXPECT_EQ(255u, SkColorGetR(pixels[i + j * bitmap.width()])); | |
357 EXPECT_EQ(255u, SkColorGetG(pixels[i + j * bitmap.width()])); | |
358 EXPECT_EQ(255u, SkColorGetB(pixels[i + j * bitmap.width()])); | |
359 } | |
360 } | |
361 } | |
362 | |
363 // Re-record everything as black. | |
364 PaintFlags black_flags; | |
365 black_flags.setColor(SK_ColorBLACK); | |
366 recording_source->add_draw_rect_with_flags(gfx::Rect(layer_bounds), | |
367 black_flags); | |
368 recording_source->Rerecord(); | |
369 | |
370 // Make a new RasterSource from the new recording. | |
371 raster = | |
372 RasterSource::CreateFromRecordingSource(recording_source.get(), false); | |
373 | |
374 // We're going to playback from "everything is black" into a smaller area, | |
375 // that touches the edge pixels of the recording. | |
376 playback_rect.Inset(1, 2, 0, 1); | |
377 raster->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), raster_full_rect, | |
378 playback_rect, contents_scale, | |
379 RasterSource::PlaybackSettings()); | |
380 | |
381 SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); | |
382 int num_black = 0; | |
383 int num_white = 0; | |
384 for (int i = 0; i < bitmap.width(); ++i) { | |
385 for (int j = 0; j < bitmap.height(); ++j) { | |
386 SCOPED_TRACE(j); | |
387 SCOPED_TRACE(i); | |
388 bool expect_black = playback_rect.Contains(i, j); | |
389 if (expect_black) { | |
390 EXPECT_EQ(255u, SkColorGetA(pixels[i + j * bitmap.width()])); | |
391 EXPECT_EQ(0u, SkColorGetR(pixels[i + j * bitmap.width()])); | |
392 EXPECT_EQ(0u, SkColorGetG(pixels[i + j * bitmap.width()])); | |
393 EXPECT_EQ(0u, SkColorGetB(pixels[i + j * bitmap.width()])); | |
394 ++num_black; | |
395 } else { | |
396 EXPECT_EQ(255u, SkColorGetA(pixels[i + j * bitmap.width()])); | |
397 EXPECT_EQ(255u, SkColorGetR(pixels[i + j * bitmap.width()])); | |
398 EXPECT_EQ(255u, SkColorGetG(pixels[i + j * bitmap.width()])); | |
399 EXPECT_EQ(255u, SkColorGetB(pixels[i + j * bitmap.width()])); | |
400 ++num_white; | |
401 } | |
402 } | |
403 } | |
404 EXPECT_GT(num_black, 0); | |
405 EXPECT_GT(num_white, 0); | |
406 } | |
407 | |
408 TEST(RasterSourceTest, RasterPartialClear) { | |
409 gfx::Size layer_bounds(3, 5); | |
410 gfx::Size partial_bounds(2, 4); | |
411 float contents_scale = 1.5f; | |
412 | |
413 std::unique_ptr<FakeRecordingSource> recording_source = | |
414 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); | |
415 recording_source->SetBackgroundColor(SK_ColorGREEN); | |
416 recording_source->SetRequiresClear(true); | |
417 recording_source->SetClearCanvasWithDebugColor(false); | |
418 | |
419 // First record everything as white. | |
420 const unsigned alpha_dark = 10u; | |
421 PaintFlags white_flags; | |
422 white_flags.setColor(SK_ColorWHITE); | |
423 white_flags.setAlpha(alpha_dark); | |
424 recording_source->add_draw_rect_with_flags(gfx::Rect(layer_bounds), | |
425 white_flags); | |
426 recording_source->Rerecord(); | |
427 | |
428 scoped_refptr<RasterSource> raster = | |
429 RasterSource::CreateFromRecordingSource(recording_source.get(), false); | |
430 | |
431 gfx::Size content_bounds( | |
432 gfx::ScaleToCeiledSize(layer_bounds, contents_scale)); | |
433 | |
434 SkBitmap bitmap; | |
435 bitmap.allocN32Pixels(content_bounds.width(), content_bounds.height()); | |
436 SkCanvas canvas(bitmap); | |
437 canvas.clear(SK_ColorTRANSPARENT); | |
438 | |
439 // Playback the full rect which should make everything light gray (alpha=10). | |
440 gfx::Rect raster_full_rect(content_bounds); | |
441 gfx::Rect playback_rect(content_bounds); | |
442 raster->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), raster_full_rect, | |
443 playback_rect, contents_scale, | |
444 RasterSource::PlaybackSettings()); | |
445 | |
446 { | |
447 SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); | |
448 for (int i = 0; i < bitmap.width(); ++i) { | |
449 for (int j = 0; j < bitmap.height(); ++j) { | |
450 SCOPED_TRACE(i); | |
451 SCOPED_TRACE(j); | |
452 EXPECT_EQ(alpha_dark, SkColorGetA(pixels[i + j * bitmap.width()])); | |
453 EXPECT_EQ(alpha_dark, SkColorGetR(pixels[i + j * bitmap.width()])); | |
454 EXPECT_EQ(alpha_dark, SkColorGetG(pixels[i + j * bitmap.width()])); | |
455 EXPECT_EQ(alpha_dark, SkColorGetB(pixels[i + j * bitmap.width()])); | |
456 } | |
457 } | |
458 } | |
459 | |
460 std::unique_ptr<FakeRecordingSource> recording_source_light = | |
461 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); | |
462 recording_source_light->SetBackgroundColor(SK_ColorGREEN); | |
463 recording_source_light->SetRequiresClear(true); | |
464 recording_source_light->SetClearCanvasWithDebugColor(false); | |
465 | |
466 // Record everything as a slightly lighter white. | |
467 const unsigned alpha_light = 18u; | |
468 white_flags.setAlpha(alpha_light); | |
469 recording_source_light->add_draw_rect_with_flags(gfx::Rect(layer_bounds), | |
470 white_flags); | |
471 recording_source_light->Rerecord(); | |
472 | |
473 // Make a new RasterSource from the new recording. | |
474 raster = RasterSource::CreateFromRecordingSource(recording_source_light.get(), | |
475 false); | |
476 | |
477 // We're going to playback from alpha(18) white rectangle into a smaller area | |
478 // of the recording resulting in a smaller lighter white rectangle over a | |
479 // darker white background rectangle. | |
480 playback_rect = | |
481 gfx::Rect(gfx::ScaleToCeiledSize(partial_bounds, contents_scale)); | |
482 raster->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), raster_full_rect, | |
483 playback_rect, contents_scale, | |
484 RasterSource::PlaybackSettings()); | |
485 | |
486 // Test that the whole playback_rect was cleared and repainted with new alpha. | |
487 SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); | |
488 for (int i = 0; i < playback_rect.width(); ++i) { | |
489 for (int j = 0; j < playback_rect.height(); ++j) { | |
490 SCOPED_TRACE(j); | |
491 SCOPED_TRACE(i); | |
492 EXPECT_EQ(alpha_light, SkColorGetA(pixels[i + j * bitmap.width()])); | |
493 EXPECT_EQ(alpha_light, SkColorGetR(pixels[i + j * bitmap.width()])); | |
494 EXPECT_EQ(alpha_light, SkColorGetG(pixels[i + j * bitmap.width()])); | |
495 EXPECT_EQ(alpha_light, SkColorGetB(pixels[i + j * bitmap.width()])); | |
496 } | |
497 } | |
498 } | |
499 | |
500 TEST(RasterSourceTest, RasterContentsTransparent) { | |
501 gfx::Size layer_bounds(5, 3); | |
502 float contents_scale = 0.5f; | |
503 | |
504 std::unique_ptr<FakeRecordingSource> recording_source = | |
505 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); | |
506 recording_source->SetBackgroundColor(SK_ColorTRANSPARENT); | |
507 recording_source->SetRequiresClear(true); | |
508 recording_source->SetClearCanvasWithDebugColor(false); | |
509 recording_source->Rerecord(); | |
510 | |
511 scoped_refptr<RasterSource> raster = | |
512 RasterSource::CreateFromRecordingSource(recording_source.get(), false); | |
513 gfx::Size content_bounds( | |
514 gfx::ScaleToCeiledSize(layer_bounds, contents_scale)); | |
515 | |
516 gfx::Rect canvas_rect(content_bounds); | |
517 canvas_rect.Inset(0, 0, -1, -1); | |
518 | |
519 SkBitmap bitmap; | |
520 bitmap.allocN32Pixels(canvas_rect.width(), canvas_rect.height()); | |
521 SkCanvas canvas(bitmap); | |
522 | |
523 raster->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), canvas_rect, | |
524 canvas_rect, contents_scale, | |
525 RasterSource::PlaybackSettings()); | |
526 | |
527 SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); | |
528 int num_pixels = bitmap.width() * bitmap.height(); | |
529 for (int i = 0; i < num_pixels; ++i) { | |
530 EXPECT_EQ(SkColorGetA(pixels[i]), 0u); | |
531 } | |
532 } | |
533 | |
534 TEST(RasterSourceTest, GetPictureMemoryUsageIncludesClientReportedMemory) { | |
535 const size_t kReportedMemoryUsageInBytes = 100 * 1024 * 1024; | |
536 gfx::Size layer_bounds(5, 3); | |
537 std::unique_ptr<FakeRecordingSource> recording_source = | |
538 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); | |
539 recording_source->set_reported_memory_usage(kReportedMemoryUsageInBytes); | |
540 recording_source->Rerecord(); | |
541 | |
542 scoped_refptr<RasterSource> raster = | |
543 RasterSource::CreateFromRecordingSource(recording_source.get(), false); | |
544 size_t total_memory_usage = raster->GetMemoryUsage(); | |
545 EXPECT_GE(total_memory_usage, kReportedMemoryUsageInBytes); | |
546 EXPECT_LT(total_memory_usage, 2 * kReportedMemoryUsageInBytes); | |
547 } | |
548 | |
549 TEST(RasterSourceTest, ImageHijackCanvasRespectsSharedCanvasTransform) { | |
550 gfx::Size size(100, 100); | |
551 | |
552 // Create a recording source that is filled with red and every corner is | |
553 // green (4x4 rects in the corner are green to account for blending when | |
554 // scaling). Note that we paint an image first, so that we can force image | |
555 // hijack canvas to be used. | |
556 std::unique_ptr<FakeRecordingSource> recording_source = | |
557 FakeRecordingSource::CreateFilledRecordingSource(size); | |
558 | |
559 // 1. Paint the image. | |
560 recording_source->add_draw_image(CreateDiscardableImage(gfx::Size(5, 5)), | |
561 gfx::Point(0, 0)); | |
562 | |
563 // 2. Cover everything in red. | |
564 PaintFlags flags; | |
565 flags.setColor(SK_ColorRED); | |
566 recording_source->add_draw_rect_with_flags(gfx::Rect(size), flags); | |
567 | |
568 // 3. Draw 4x4 green rects into every corner. | |
569 flags.setColor(SK_ColorGREEN); | |
570 recording_source->add_draw_rect_with_flags(gfx::Rect(0, 0, 4, 4), flags); | |
571 recording_source->add_draw_rect_with_flags( | |
572 gfx::Rect(size.width() - 4, 0, 4, 4), flags); | |
573 recording_source->add_draw_rect_with_flags( | |
574 gfx::Rect(0, size.height() - 4, 4, 4), flags); | |
575 recording_source->add_draw_rect_with_flags( | |
576 gfx::Rect(size.width() - 4, size.height() - 4, 4, 4), flags); | |
577 | |
578 recording_source->SetGenerateDiscardableImagesMetadata(true); | |
579 recording_source->Rerecord(); | |
580 | |
581 bool can_use_lcd = true; | |
582 scoped_refptr<RasterSource> raster_source = | |
583 recording_source->CreateRasterSource(can_use_lcd); | |
584 SoftwareImageDecodeCache controller( | |
585 ResourceFormat::RGBA_8888, | |
586 LayerTreeSettings().software_decoded_image_budget_bytes); | |
587 raster_source->set_image_decode_cache(&controller); | |
588 | |
589 SkBitmap bitmap; | |
590 bitmap.allocN32Pixels(size.width() * 0.5f, size.height() * 0.25f); | |
591 SkCanvas canvas(bitmap); | |
592 canvas.scale(0.5f, 0.25f); | |
593 | |
594 RasterSource::PlaybackSettings settings; | |
595 settings.playback_to_shared_canvas = true; | |
596 settings.use_image_hijack_canvas = true; | |
597 raster_source->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), | |
598 gfx::Rect(size), gfx::Rect(size), 1.f, | |
599 settings); | |
600 | |
601 EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(0, 0)); | |
602 EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(49, 0)); | |
603 EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(0, 24)); | |
604 EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(49, 24)); | |
605 for (int x = 0; x < 49; ++x) | |
606 EXPECT_EQ(SK_ColorRED, bitmap.getColor(x, 12)); | |
607 for (int y = 0; y < 24; ++y) | |
608 EXPECT_EQ(SK_ColorRED, bitmap.getColor(24, y)); | |
609 } | |
610 | |
611 } // namespace | |
612 } // namespace cc | |
OLD | NEW |