• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "Resources.h"
9 #include "SkCanvas.h"
10 #include "SkPipe.h"
11 #include "SkPaint.h"
12 #include "SkStream.h"
13 #include "SkSurface.h"
14 #include "Test.h"
15 
16 #include "SkNullCanvas.h"
17 #include "SkAutoPixmapStorage.h"
18 #include "SkPictureRecorder.h"
19 
drain(SkPipeDeserializer * deserial,SkDynamicMemoryWStream * stream)20 static void drain(SkPipeDeserializer* deserial, SkDynamicMemoryWStream* stream) {
21     std::unique_ptr<SkCanvas> canvas = SkMakeNullCanvas();
22     sk_sp<SkData> data = stream->detachAsData();
23     deserial->playback(data->data(), data->size(), canvas.get());
24 }
25 
deep_equal(SkImage * a,SkImage * b)26 static bool deep_equal(SkImage* a, SkImage* b) {
27     if (a->width() != b->width() || a->height() != b->height()) {
28         return false;
29     }
30 
31     const SkImageInfo info = SkImageInfo::MakeN32Premul(a->width(), a->height());
32     SkAutoPixmapStorage pmapA, pmapB;
33     pmapA.alloc(info);
34     pmapB.alloc(info);
35 
36     if (!a->readPixels(pmapA, 0, 0) || !b->readPixels(pmapB, 0, 0)) {
37         return false;
38     }
39 
40     for (int y = 0; y < info.height(); ++y) {
41         if (memcmp(pmapA.addr32(0, y), pmapB.addr32(0, y), info.width() * sizeof(SkPMColor))) {
42             return false;
43         }
44     }
45     return true;
46 }
47 
DEF_TEST(Pipe_image_draw_first,reporter)48 DEF_TEST(Pipe_image_draw_first, reporter) {
49     sk_sp<SkImage> img = GetResourceAsImage("images/mandrill_128.png");
50     SkASSERT(img.get());
51 
52     SkPipeSerializer serializer;
53     SkPipeDeserializer deserializer;
54 
55     SkDynamicMemoryWStream stream;
56     SkCanvas* wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
57     wc->drawImage(img, 0, 0, nullptr);
58     serializer.endWrite();
59     size_t offset0 = stream.bytesWritten();
60     REPORTER_ASSERT(reporter, offset0 > 100);   // the raw image must be sorta big
61     drain(&deserializer, &stream);
62 
63     // try drawing the same image again -- it should be much smaller
64     wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
65     wc->drawImage(img, 0, 0, nullptr);
66     size_t offset1 = stream.bytesWritten();
67     serializer.endWrite();
68     REPORTER_ASSERT(reporter, offset1 <= 32);
69     drain(&deserializer, &stream);
70 
71     // try serializing the same image directly, again it should be small
72     sk_sp<SkData> data = serializer.writeImage(img.get());
73     size_t offset2 = data->size();
74     REPORTER_ASSERT(reporter, offset2 <= 32);
75     auto img1 = deserializer.readImage(data.get());
76     REPORTER_ASSERT(reporter, deep_equal(img.get(), img1.get()));
77 
78     // try serializing the same image directly (again), check that it is the same!
79     data = serializer.writeImage(img.get());
80     size_t offset3 = data->size();
81     REPORTER_ASSERT(reporter, offset3 <= 32);
82     auto img2 = deserializer.readImage(data.get());
83     REPORTER_ASSERT(reporter, img1.get() == img2.get());
84 }
85 
DEF_TEST(Pipe_image_draw_second,reporter)86 DEF_TEST(Pipe_image_draw_second, reporter) {
87     sk_sp<SkImage> img = GetResourceAsImage("images/mandrill_128.png");
88     SkASSERT(img.get());
89 
90     SkPipeSerializer serializer;
91     SkPipeDeserializer deserializer;
92     SkDynamicMemoryWStream stream;
93 
94     sk_sp<SkData> data = serializer.writeImage(img.get());
95     size_t offset0 = data->size();
96     REPORTER_ASSERT(reporter, offset0 > 100);   // the raw image must be sorta big
97     auto img1 = deserializer.readImage(data.get());
98 
99     // The 2nd image should be nice and small
100     data = serializer.writeImage(img.get());
101     size_t offset1 = data->size();
102     REPORTER_ASSERT(reporter, offset1 <= 16);
103     auto img2 = deserializer.readImage(data.get());
104     REPORTER_ASSERT(reporter, img1.get() == img2.get());
105 
106     // Now try drawing the image, it should also be small
107     SkCanvas* wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
108     wc->drawImage(img, 0, 0, nullptr);
109     serializer.endWrite();
110     size_t offset2 = stream.bytesWritten();
111     REPORTER_ASSERT(reporter, offset2 <= 16);
112 }
113 
DEF_TEST(Pipe_picture_draw_first,reporter)114 DEF_TEST(Pipe_picture_draw_first, reporter) {
115     sk_sp<SkPicture> picture = []() {
116         SkPictureRecorder rec;
117         SkCanvas* c = rec.beginRecording(SkRect::MakeWH(100, 100));
118         for (int i = 0; i < 100; ++i) {
119             c->drawColor(i);
120         }
121         return rec.finishRecordingAsPicture();
122     }();
123     SkPipeSerializer serializer;
124     SkPipeDeserializer deserializer;
125 
126     SkDynamicMemoryWStream stream;
127     SkCanvas* wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
128     wc->drawPicture(picture);
129     serializer.endWrite();
130     size_t offset0 = stream.bytesWritten();
131     REPORTER_ASSERT(reporter, offset0 > 100);   // the raw picture must be sorta big
132     drain(&deserializer, &stream);
133 
134     // try drawing the same picture again -- it should be much smaller
135     wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
136     wc->drawPicture(picture);
137     size_t offset1 = stream.bytesWritten();
138     serializer.endWrite();
139     REPORTER_ASSERT(reporter, offset1 <= 16);
140     drain(&deserializer, &stream);
141 
142     // try writing the picture directly, it should also be small
143     sk_sp<SkData> data = serializer.writePicture(picture.get());
144     size_t offset2 = data->size();
145     REPORTER_ASSERT(reporter, offset2 <= 16);
146     auto pic1 = deserializer.readPicture(data.get());
147 
148     // try writing the picture directly, it should also be small
149     data = serializer.writePicture(picture.get());
150     size_t offset3 = data->size();
151     REPORTER_ASSERT(reporter, offset3 == offset2);
152     auto pic2 = deserializer.readPicture(data.get());
153     REPORTER_ASSERT(reporter, pic1.get() == pic2.get());
154 }
155 
DEF_TEST(Pipe_picture_draw_second,reporter)156 DEF_TEST(Pipe_picture_draw_second, reporter) {
157     sk_sp<SkPicture> picture = []() {
158         SkPictureRecorder rec;
159         SkCanvas* c = rec.beginRecording(SkRect::MakeWH(100, 100));
160         for (int i = 0; i < 100; ++i) {
161             c->drawColor(i);
162         }
163         return rec.finishRecordingAsPicture();
164     }();
165     SkPipeSerializer serializer;
166     SkPipeDeserializer deserializer;
167     SkDynamicMemoryWStream stream;
168 
169     sk_sp<SkData> data = serializer.writePicture(picture.get());
170     size_t offset0 = data->size();
171     REPORTER_ASSERT(reporter, offset0 > 100);   // the raw picture must be sorta big
172     auto pic1 = deserializer.readPicture(data.get());
173 
174     // The 2nd picture should be nice and small
175     data = serializer.writePicture(picture.get());
176     size_t offset1 = data->size();
177     REPORTER_ASSERT(reporter, offset1 <= 16);
178     auto pic2 = deserializer.readPicture(data.get());
179     SkASSERT(pic1.get() == pic2.get());
180 
181     // Now try drawing the image, it should also be small
182     SkCanvas* wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
183     wc->drawPicture(picture);
184     serializer.endWrite();
185     size_t offset2 = stream.bytesWritten();
186     REPORTER_ASSERT(reporter, offset2 <= 16);
187 }
188