blob: e5d2f09a99aad72b833b6c97988ad748a64c4482 [file] [log] [blame]
reed54dc4872016-09-13 08:09:45 -07001/*
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"
reed262052c2016-09-15 14:24:53 -070018#include "SkPictureRecorder.h"
reed54dc4872016-09-13 08:09:45 -070019
20static void drain(SkPipeDeserializer* deserial, SkDynamicMemoryWStream* stream) {
Mike Reed5df49342016-11-12 08:06:55 -060021 std::unique_ptr<SkCanvas> canvas = SkMakeNullCanvas();
reed54dc4872016-09-13 08:09:45 -070022 sk_sp<SkData> data = stream->detachAsData();
23 deserial->playback(data->data(), data->size(), canvas.get());
24}
25
reed54dc4872016-09-13 08:09:45 -070026static 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
reed7e3ba9f2016-09-13 17:25:19 -070048DEF_TEST(Pipe_image_draw_first, reporter) {
reed54dc4872016-09-13 08:09:45 -070049 sk_sp<SkImage> img = GetResourceAsImage("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
reed262052c2016-09-15 14:24:53 -070072 sk_sp<SkData> data = serializer.writeImage(img.get());
73 size_t offset2 = data->size();
reed54dc4872016-09-13 08:09:45 -070074 REPORTER_ASSERT(reporter, offset2 <= 32);
reed262052c2016-09-15 14:24:53 -070075 auto img1 = deserializer.readImage(data.get());
reed54dc4872016-09-13 08:09:45 -070076 REPORTER_ASSERT(reporter, deep_equal(img.get(), img1.get()));
77
78 // try serializing the same image directly (again), check that it is the same!
reed262052c2016-09-15 14:24:53 -070079 data = serializer.writeImage(img.get());
80 size_t offset3 = data->size();
reed54dc4872016-09-13 08:09:45 -070081 REPORTER_ASSERT(reporter, offset3 <= 32);
reed262052c2016-09-15 14:24:53 -070082 auto img2 = deserializer.readImage(data.get());
reed54dc4872016-09-13 08:09:45 -070083 REPORTER_ASSERT(reporter, img1.get() == img2.get());
84}
reed7e3ba9f2016-09-13 17:25:19 -070085
86DEF_TEST(Pipe_image_draw_second, reporter) {
87 sk_sp<SkImage> img = GetResourceAsImage("mandrill_128.png");
88 SkASSERT(img.get());
89
90 SkPipeSerializer serializer;
91 SkPipeDeserializer deserializer;
92 SkDynamicMemoryWStream stream;
93
reed262052c2016-09-15 14:24:53 -070094 sk_sp<SkData> data = serializer.writeImage(img.get());
95 size_t offset0 = data->size();
reed7e3ba9f2016-09-13 17:25:19 -070096 REPORTER_ASSERT(reporter, offset0 > 100); // the raw image must be sorta big
reed262052c2016-09-15 14:24:53 -070097 auto img1 = deserializer.readImage(data.get());
reed7e3ba9f2016-09-13 17:25:19 -070098
99 // The 2nd image should be nice and small
reed262052c2016-09-15 14:24:53 -0700100 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());
reed7e3ba9f2016-09-13 17:25:19 -0700105
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();
reed262052c2016-09-15 14:24:53 -0700111 REPORTER_ASSERT(reporter, offset2 <= 16);
112}
113
114DEF_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
156DEF_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);
reed7e3ba9f2016-09-13 17:25:19 -0700187}