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 "base/compiler_specific.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "cc/test/geometry_test_utils.h"
8 #include "skia/ext/pixel_ref_utils.h"
9 #include "skia/ext/refptr.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/skia/include/core/SkBitmap.h"
12 #include "third_party/skia/include/core/SkCanvas.h"
13 #include "third_party/skia/include/core/SkFlattenableBuffers.h"
14 #include "third_party/skia/include/core/SkPictureRecorder.h"
15 #include "third_party/skia/include/core/SkPixelRef.h"
16 #include "third_party/skia/include/core/SkPoint.h"
17 #include "third_party/skia/include/core/SkShader.h"
18 #include "third_party/skia/src/core/SkOrderedReadBuffer.h"
19 #include "ui/gfx/rect.h"
20 #include "ui/gfx/skia_util.h"
26 void CreateBitmap(gfx::Size size, const char* uri, SkBitmap* bitmap);
28 class TestDiscardableShader : public SkShader {
30 TestDiscardableShader() {
31 CreateBitmap(gfx::Size(50, 50), "discardable", &bitmap_);
34 TestDiscardableShader(SkReadBuffer& buffer) : SkShader(buffer) {
35 CreateBitmap(gfx::Size(50, 50), "discardable", &bitmap_);
38 virtual SkShader::BitmapType asABitmap(SkBitmap* bitmap,
40 TileMode xy[2]) const OVERRIDE {
43 return SkShader::kDefault_BitmapType;
46 // not indended to return an actual context. Just need to supply this.
47 virtual size_t contextSize() const OVERRIDE {
48 return sizeof(SkShader::Context);
51 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(TestDiscardableShader);
57 void CreateBitmap(gfx::Size size, const char* uri, SkBitmap* bitmap) {
58 bitmap->allocN32Pixels(size.width(), size.height());
59 bitmap->pixelRef()->setImmutable();
60 bitmap->pixelRef()->setURI(uri);
63 SkCanvas* StartRecording(SkPictureRecorder* recorder, gfx::Rect layer_rect) {
65 recorder->beginRecording(layer_rect.width(), layer_rect.height());
68 canvas->translate(-layer_rect.x(), -layer_rect.y());
69 canvas->clipRect(SkRect::MakeXYWH(
70 layer_rect.x(), layer_rect.y(), layer_rect.width(), layer_rect.height()));
75 SkPicture* StopRecording(SkPictureRecorder* recorder, SkCanvas* canvas) {
77 return recorder->endRecording();
82 TEST(PixelRefUtilsTest, DrawPaint) {
83 gfx::Rect layer_rect(0, 0, 256, 256);
85 SkPictureRecorder recorder;
86 SkCanvas* canvas = StartRecording(&recorder, layer_rect);
88 TestDiscardableShader first_shader;
90 first_paint.setShader(&first_shader);
92 TestDiscardableShader second_shader;
94 second_paint.setShader(&second_shader);
96 TestDiscardableShader third_shader;
98 third_paint.setShader(&third_shader);
100 canvas->drawPaint(first_paint);
101 canvas->clipRect(SkRect::MakeXYWH(34, 45, 56, 67));
102 canvas->drawPaint(second_paint);
103 // Total clip is now (34, 45, 56, 55)
104 canvas->clipRect(SkRect::MakeWH(100, 100));
105 canvas->drawPaint(third_paint);
107 skia::RefPtr<SkPicture> picture = skia::AdoptRef(StopRecording(&recorder, canvas));
109 std::vector<skia::PixelRefUtils::PositionPixelRef> pixel_refs;
110 skia::PixelRefUtils::GatherDiscardablePixelRefs(picture.get(), &pixel_refs);
112 EXPECT_EQ(3u, pixel_refs.size());
113 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 256, 256),
114 gfx::SkRectToRectF(pixel_refs[0].pixel_ref_rect));
115 EXPECT_FLOAT_RECT_EQ(gfx::RectF(34, 45, 56, 67),
116 gfx::SkRectToRectF(pixel_refs[1].pixel_ref_rect));
117 EXPECT_FLOAT_RECT_EQ(gfx::RectF(34, 45, 56, 55),
118 gfx::SkRectToRectF(pixel_refs[2].pixel_ref_rect));
121 TEST(PixelRefUtilsTest, DrawPoints) {
122 gfx::Rect layer_rect(0, 0, 256, 256);
124 SkPictureRecorder recorder;
125 SkCanvas* canvas = StartRecording(&recorder, layer_rect);
127 TestDiscardableShader first_shader;
129 first_paint.setShader(&first_shader);
131 TestDiscardableShader second_shader;
132 SkPaint second_paint;
133 second_paint.setShader(&second_shader);
135 TestDiscardableShader third_shader;
137 third_paint.setShader(&third_shader);
140 points[0].set(10, 10);
141 points[1].set(100, 20);
142 points[2].set(50, 100);
144 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, first_paint);
148 canvas->clipRect(SkRect::MakeWH(50, 50));
150 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, second_paint);
154 points[0].set(50, 55);
155 points[1].set(50, 55);
156 points[2].set(200, 200);
157 // (50, 55, 150, 145).
158 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, third_paint);
160 skia::RefPtr<SkPicture> picture = skia::AdoptRef(StopRecording(&recorder, canvas));
162 std::vector<skia::PixelRefUtils::PositionPixelRef> pixel_refs;
163 skia::PixelRefUtils::GatherDiscardablePixelRefs(picture.get(), &pixel_refs);
165 EXPECT_EQ(3u, pixel_refs.size());
166 EXPECT_FLOAT_RECT_EQ(gfx::RectF(10, 10, 90, 90),
167 gfx::SkRectToRectF(pixel_refs[0].pixel_ref_rect));
168 EXPECT_FLOAT_RECT_EQ(gfx::RectF(10, 10, 40, 40),
169 gfx::SkRectToRectF(pixel_refs[1].pixel_ref_rect));
170 EXPECT_FLOAT_RECT_EQ(gfx::RectF(50, 55, 150, 145),
171 gfx::SkRectToRectF(pixel_refs[2].pixel_ref_rect));
174 TEST(PixelRefUtilsTest, DrawRect) {
175 gfx::Rect layer_rect(0, 0, 256, 256);
177 SkPictureRecorder recorder;
178 SkCanvas* canvas = StartRecording(&recorder, layer_rect);
180 TestDiscardableShader first_shader;
182 first_paint.setShader(&first_shader);
184 TestDiscardableShader second_shader;
185 SkPaint second_paint;
186 second_paint.setShader(&second_shader);
188 TestDiscardableShader third_shader;
190 third_paint.setShader(&third_shader);
193 canvas->drawRect(SkRect::MakeXYWH(10, 20, 30, 40), first_paint);
197 canvas->translate(5, 17);
199 canvas->drawRect(SkRect::MakeXYWH(0, 33, 25, 35), second_paint);
203 canvas->clipRect(SkRect::MakeXYWH(50, 50, 50, 50));
204 canvas->translate(20, 20);
206 canvas->drawRect(SkRect::MakeXYWH(0, 0, 100, 100), third_paint);
208 skia::RefPtr<SkPicture> picture = skia::AdoptRef(StopRecording(&recorder, canvas));
210 std::vector<skia::PixelRefUtils::PositionPixelRef> pixel_refs;
211 skia::PixelRefUtils::GatherDiscardablePixelRefs(picture.get(), &pixel_refs);
213 EXPECT_EQ(3u, pixel_refs.size());
214 EXPECT_FLOAT_RECT_EQ(gfx::RectF(10, 20, 30, 40),
215 gfx::SkRectToRectF(pixel_refs[0].pixel_ref_rect));
216 EXPECT_FLOAT_RECT_EQ(gfx::RectF(5, 50, 25, 35),
217 gfx::SkRectToRectF(pixel_refs[1].pixel_ref_rect));
218 EXPECT_FLOAT_RECT_EQ(gfx::RectF(50, 50, 50, 50),
219 gfx::SkRectToRectF(pixel_refs[2].pixel_ref_rect));
222 TEST(PixelRefUtilsTest, DrawRRect) {
223 gfx::Rect layer_rect(0, 0, 256, 256);
225 SkPictureRecorder recorder;
226 SkCanvas* canvas = StartRecording(&recorder, layer_rect);
228 TestDiscardableShader first_shader;
230 first_paint.setShader(&first_shader);
232 TestDiscardableShader second_shader;
233 SkPaint second_paint;
234 second_paint.setShader(&second_shader);
236 TestDiscardableShader third_shader;
238 third_paint.setShader(&third_shader);
241 rrect.setRect(SkRect::MakeXYWH(10, 20, 30, 40));
244 canvas->drawRRect(rrect, first_paint);
248 canvas->translate(5, 17);
249 rrect.setRect(SkRect::MakeXYWH(0, 33, 25, 35));
251 canvas->drawRRect(rrect, second_paint);
255 canvas->clipRect(SkRect::MakeXYWH(50, 50, 50, 50));
256 canvas->translate(20, 20);
257 rrect.setRect(SkRect::MakeXYWH(0, 0, 100, 100));
259 canvas->drawRRect(rrect, third_paint);
261 skia::RefPtr<SkPicture> picture = skia::AdoptRef(StopRecording(&recorder, canvas));
263 std::vector<skia::PixelRefUtils::PositionPixelRef> pixel_refs;
264 skia::PixelRefUtils::GatherDiscardablePixelRefs(picture.get(), &pixel_refs);
266 EXPECT_EQ(3u, pixel_refs.size());
267 EXPECT_FLOAT_RECT_EQ(gfx::RectF(10, 20, 30, 40),
268 gfx::SkRectToRectF(pixel_refs[0].pixel_ref_rect));
269 EXPECT_FLOAT_RECT_EQ(gfx::RectF(5, 50, 25, 35),
270 gfx::SkRectToRectF(pixel_refs[1].pixel_ref_rect));
271 EXPECT_FLOAT_RECT_EQ(gfx::RectF(50, 50, 50, 50),
272 gfx::SkRectToRectF(pixel_refs[2].pixel_ref_rect));
275 TEST(PixelRefUtilsTest, DrawOval) {
276 gfx::Rect layer_rect(0, 0, 256, 256);
278 SkPictureRecorder recorder;
279 SkCanvas* canvas = StartRecording(&recorder, layer_rect);
281 TestDiscardableShader first_shader;
283 first_paint.setShader(&first_shader);
285 TestDiscardableShader second_shader;
286 SkPaint second_paint;
287 second_paint.setShader(&second_shader);
289 TestDiscardableShader third_shader;
291 third_paint.setShader(&third_shader);
295 canvas->scale(2, 0.5);
297 canvas->drawOval(SkRect::MakeXYWH(10, 20, 30, 40), first_paint);
302 canvas->translate(1, 2);
304 canvas->drawRect(SkRect::MakeXYWH(0, 33, 25, 35), second_paint);
308 canvas->clipRect(SkRect::MakeXYWH(50, 50, 50, 50));
309 canvas->translate(20, 20);
311 canvas->drawRect(SkRect::MakeXYWH(0, 0, 100, 100), third_paint);
313 skia::RefPtr<SkPicture> picture = skia::AdoptRef(StopRecording(&recorder, canvas));
315 std::vector<skia::PixelRefUtils::PositionPixelRef> pixel_refs;
316 skia::PixelRefUtils::GatherDiscardablePixelRefs(picture.get(), &pixel_refs);
318 EXPECT_EQ(3u, pixel_refs.size());
319 EXPECT_FLOAT_RECT_EQ(gfx::RectF(20, 10, 60, 20),
320 gfx::SkRectToRectF(pixel_refs[0].pixel_ref_rect));
321 EXPECT_FLOAT_RECT_EQ(gfx::RectF(1, 35, 25, 35),
322 gfx::SkRectToRectF(pixel_refs[1].pixel_ref_rect));
323 EXPECT_FLOAT_RECT_EQ(gfx::RectF(50, 50, 50, 50),
324 gfx::SkRectToRectF(pixel_refs[2].pixel_ref_rect));
327 TEST(PixelRefUtilsTest, DrawPath) {
328 gfx::Rect layer_rect(0, 0, 256, 256);
330 SkPictureRecorder recorder;
331 SkCanvas* canvas = StartRecording(&recorder, layer_rect);
333 TestDiscardableShader first_shader;
335 first_paint.setShader(&first_shader);
337 TestDiscardableShader second_shader;
338 SkPaint second_paint;
339 second_paint.setShader(&second_shader);
344 path.lineTo(22, 101);
347 canvas->drawPath(path, first_paint);
350 canvas->clipRect(SkRect::MakeWH(50, 50));
353 canvas->drawPath(path, second_paint);
357 skia::RefPtr<SkPicture> picture = skia::AdoptRef(StopRecording(&recorder, canvas));
359 std::vector<skia::PixelRefUtils::PositionPixelRef> pixel_refs;
360 skia::PixelRefUtils::GatherDiscardablePixelRefs(picture.get(), &pixel_refs);
362 EXPECT_EQ(2u, pixel_refs.size());
363 EXPECT_FLOAT_RECT_EQ(gfx::RectF(12, 13, 38, 88),
364 gfx::SkRectToRectF(pixel_refs[0].pixel_ref_rect));
365 EXPECT_FLOAT_RECT_EQ(gfx::RectF(12, 13, 38, 37),
366 gfx::SkRectToRectF(pixel_refs[1].pixel_ref_rect));
369 TEST(PixelRefUtilsTest, DrawBitmap) {
370 gfx::Rect layer_rect(0, 0, 256, 256);
372 SkPictureRecorder recorder;
373 SkCanvas* canvas = StartRecording(&recorder, layer_rect);
376 CreateBitmap(gfx::Size(50, 50), "discardable", &first);
378 CreateBitmap(gfx::Size(50, 50), "discardable", &second);
380 CreateBitmap(gfx::Size(50, 50), "discardable", &third);
382 CreateBitmap(gfx::Size(50, 1), "discardable", &fourth);
384 CreateBitmap(gfx::Size(10, 10), "discardable", &fifth);
389 canvas->drawBitmap(first, 0, 0);
390 canvas->translate(25, 0);
392 canvas->drawBitmap(second, 0, 0);
393 canvas->translate(0, 50);
395 canvas->drawBitmap(third, 25, 0);
400 canvas->translate(1, 0);
402 // At (1, 0), rotated 90 degrees
403 canvas->drawBitmap(fourth, 0, 0);
408 // At (0, 0), scaled by 5 and 6
409 canvas->drawBitmap(fifth, 0, 0);
411 skia::RefPtr<SkPicture> picture = skia::AdoptRef(StopRecording(&recorder, canvas));
413 std::vector<skia::PixelRefUtils::PositionPixelRef> pixel_refs;
414 skia::PixelRefUtils::GatherDiscardablePixelRefs(picture.get(), &pixel_refs);
416 EXPECT_EQ(5u, pixel_refs.size());
417 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 50, 50),
418 gfx::SkRectToRectF(pixel_refs[0].pixel_ref_rect));
419 EXPECT_FLOAT_RECT_EQ(gfx::RectF(25, 0, 50, 50),
420 gfx::SkRectToRectF(pixel_refs[1].pixel_ref_rect));
421 EXPECT_FLOAT_RECT_EQ(gfx::RectF(50, 50, 50, 50),
422 gfx::SkRectToRectF(pixel_refs[2].pixel_ref_rect));
423 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 1, 50),
424 gfx::SkRectToRectF(pixel_refs[3].pixel_ref_rect));
425 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 50, 60),
426 gfx::SkRectToRectF(pixel_refs[4].pixel_ref_rect));
430 TEST(PixelRefUtilsTest, DrawBitmapRect) {
431 gfx::Rect layer_rect(0, 0, 256, 256);
433 SkPictureRecorder recorder;
434 SkCanvas* canvas = StartRecording(&recorder, layer_rect);
437 CreateBitmap(gfx::Size(50, 50), "discardable", &first);
439 CreateBitmap(gfx::Size(50, 50), "discardable", &second);
441 CreateBitmap(gfx::Size(50, 50), "discardable", &third);
443 TestDiscardableShader first_shader;
445 first_paint.setShader(&first_shader);
447 SkPaint non_discardable_paint;
452 canvas->drawBitmapRect(
453 first, SkRect::MakeWH(100, 100), &non_discardable_paint);
454 canvas->translate(25, 0);
456 canvas->drawBitmapRect(
457 second, SkRect::MakeXYWH(50, 50, 10, 10), &non_discardable_paint);
458 canvas->translate(5, 50);
459 // (0, 30, 100, 100). One from bitmap, one from paint.
460 canvas->drawBitmapRect(
461 third, SkRect::MakeXYWH(-30, -20, 100, 100), &first_paint);
465 skia::RefPtr<SkPicture> picture = skia::AdoptRef(StopRecording(&recorder, canvas));
467 std::vector<skia::PixelRefUtils::PositionPixelRef> pixel_refs;
468 skia::PixelRefUtils::GatherDiscardablePixelRefs(picture.get(), &pixel_refs);
470 EXPECT_EQ(4u, pixel_refs.size());
471 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
472 gfx::SkRectToRectF(pixel_refs[0].pixel_ref_rect));
473 EXPECT_FLOAT_RECT_EQ(gfx::RectF(75, 50, 10, 10),
474 gfx::SkRectToRectF(pixel_refs[1].pixel_ref_rect));
475 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 30, 100, 100),
476 gfx::SkRectToRectF(pixel_refs[2].pixel_ref_rect));
477 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 30, 100, 100),
478 gfx::SkRectToRectF(pixel_refs[3].pixel_ref_rect));
481 TEST(PixelRefUtilsTest, DrawSprite) {
482 gfx::Rect layer_rect(0, 0, 256, 256);
484 SkPictureRecorder recorder;
485 SkCanvas* canvas = StartRecording(&recorder, layer_rect);
488 CreateBitmap(gfx::Size(50, 50), "discardable", &first);
490 CreateBitmap(gfx::Size(50, 50), "discardable", &second);
492 CreateBitmap(gfx::Size(50, 50), "discardable", &third);
494 CreateBitmap(gfx::Size(50, 50), "discardable", &fourth);
496 CreateBitmap(gfx::Size(50, 50), "discardable", &fifth);
500 // Sprites aren't affected by the current matrix.
503 canvas->drawSprite(first, 0, 0);
504 canvas->translate(25, 0);
506 canvas->drawSprite(second, 10, 0);
507 canvas->translate(0, 50);
509 canvas->drawSprite(third, 25, 0);
516 canvas->drawSprite(fourth, 0, 0);
520 TestDiscardableShader first_shader;
522 first_paint.setShader(&first_shader);
525 // (100, 100, 50, 50).
526 canvas->drawSprite(fifth, 100, 100, &first_paint);
528 skia::RefPtr<SkPicture> picture = skia::AdoptRef(StopRecording(&recorder, canvas));
530 std::vector<skia::PixelRefUtils::PositionPixelRef> pixel_refs;
531 skia::PixelRefUtils::GatherDiscardablePixelRefs(picture.get(), &pixel_refs);
533 EXPECT_EQ(6u, pixel_refs.size());
534 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 50, 50),
535 gfx::SkRectToRectF(pixel_refs[0].pixel_ref_rect));
536 EXPECT_FLOAT_RECT_EQ(gfx::RectF(10, 0, 50, 50),
537 gfx::SkRectToRectF(pixel_refs[1].pixel_ref_rect));
538 EXPECT_FLOAT_RECT_EQ(gfx::RectF(25, 0, 50, 50),
539 gfx::SkRectToRectF(pixel_refs[2].pixel_ref_rect));
540 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 50, 50),
541 gfx::SkRectToRectF(pixel_refs[3].pixel_ref_rect));
542 EXPECT_FLOAT_RECT_EQ(gfx::RectF(100, 100, 50, 50),
543 gfx::SkRectToRectF(pixel_refs[4].pixel_ref_rect));
544 EXPECT_FLOAT_RECT_EQ(gfx::RectF(100, 100, 50, 50),
545 gfx::SkRectToRectF(pixel_refs[5].pixel_ref_rect));
548 TEST(PixelRefUtilsTest, DrawText) {
549 gfx::Rect layer_rect(0, 0, 256, 256);
551 SkPictureRecorder recorder;
552 SkCanvas* canvas = StartRecording(&recorder, layer_rect);
554 TestDiscardableShader first_shader;
556 first_paint.setShader(&first_shader);
559 points[0].set(10, 50);
560 points[1].set(20, 50);
561 points[2].set(30, 50);
562 points[3].set(40, 50);
571 canvas->drawText("text", 4, 50, 50, first_paint);
572 canvas->drawPosText("text", 4, points, first_paint);
573 canvas->drawTextOnPath("text", 4, path, NULL, first_paint);
575 skia::RefPtr<SkPicture> picture = skia::AdoptRef(StopRecording(&recorder, canvas));
577 std::vector<skia::PixelRefUtils::PositionPixelRef> pixel_refs;
578 skia::PixelRefUtils::GatherDiscardablePixelRefs(picture.get(), &pixel_refs);
580 EXPECT_EQ(3u, pixel_refs.size());
583 TEST(PixelRefUtilsTest, DrawVertices) {
584 gfx::Rect layer_rect(0, 0, 256, 256);
586 SkPictureRecorder recorder;
587 SkCanvas* canvas = StartRecording(&recorder, layer_rect);
589 TestDiscardableShader first_shader;
591 first_paint.setShader(&first_shader);
593 TestDiscardableShader second_shader;
594 SkPaint second_paint;
595 second_paint.setShader(&second_shader);
597 TestDiscardableShader third_shader;
599 third_paint.setShader(&third_shader);
603 uint16_t indecies[3] = {0, 1, 2};
604 points[0].set(10, 10);
605 points[1].set(100, 20);
606 points[2].set(50, 100);
608 canvas->drawVertices(SkCanvas::kTriangles_VertexMode,
620 canvas->clipRect(SkRect::MakeWH(50, 50));
622 canvas->drawVertices(SkCanvas::kTriangles_VertexMode,
634 points[0].set(50, 55);
635 points[1].set(50, 55);
636 points[2].set(200, 200);
637 // (50, 55, 150, 145).
638 canvas->drawVertices(SkCanvas::kTriangles_VertexMode,
648 skia::RefPtr<SkPicture> picture = skia::AdoptRef(StopRecording(&recorder, canvas));
650 std::vector<skia::PixelRefUtils::PositionPixelRef> pixel_refs;
651 skia::PixelRefUtils::GatherDiscardablePixelRefs(picture.get(), &pixel_refs);
653 EXPECT_EQ(3u, pixel_refs.size());
654 EXPECT_FLOAT_RECT_EQ(gfx::RectF(10, 10, 90, 90),
655 gfx::SkRectToRectF(pixel_refs[0].pixel_ref_rect));
656 EXPECT_FLOAT_RECT_EQ(gfx::RectF(10, 10, 40, 40),
657 gfx::SkRectToRectF(pixel_refs[1].pixel_ref_rect));
658 EXPECT_FLOAT_RECT_EQ(gfx::RectF(50, 55, 150, 145),
659 gfx::SkRectToRectF(pixel_refs[2].pixel_ref_rect));