blob: 0649ec9cbdcdb789b3192f3b1f6ddedff61f89c9 [file] [log] [blame]
Mike Kleina8a51ce2018-01-09 12:34:11 -05001/*
2 * Copyright 2018 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
Herb Derby4f505f92018-01-09 12:34:11 -05008#include <chrono>
Mike Kleina8a51ce2018-01-09 12:34:11 -05009#include <err.h>
Mike Kleina8a51ce2018-01-09 12:34:11 -050010#include <iostream>
Herb Derby97be88f2018-03-21 16:23:49 -040011#include <memory>
12#include <string>
Mike Kleina8a51ce2018-01-09 12:34:11 -050013#include <sys/types.h>
Herb Derby67c47f22018-02-07 17:47:59 -050014#include <sys/uio.h>
Mike Kleina8a51ce2018-01-09 12:34:11 -050015#include <sys/wait.h>
Herb Derby97be88f2018-03-21 16:23:49 -040016#include <thread>
Mike Kleina8a51ce2018-01-09 12:34:11 -050017#include <unistd.h>
Herb Derby97be88f2018-03-21 16:23:49 -040018
Herb Derbyb2922f62018-01-26 16:47:54 -050019#include "SkRemoteGlyphCache.h"
Herb Derby97be88f2018-03-21 16:23:49 -040020#include "SkGraphics.h"
21#include "SkSurface.h"
Mike Kleina8a51ce2018-01-09 12:34:11 -050022
Herb Derby97be88f2018-03-21 16:23:49 -040023static std::string gSkpName;
Herb Derby9d021822018-02-02 12:54:55 -050024static bool gUseGpu = true;
25static bool gPurgeFontCaches = true;
26static bool gUseProcess = true;
27
Herb Derby76d69b42018-03-15 17:34:40 -040028
Herb Derby97be88f2018-03-21 16:23:49 -040029class ReadWriteTransport : public SkTransport {
Herb Derby67c47f22018-02-07 17:47:59 -050030public:
Herb Derby97be88f2018-03-21 16:23:49 -040031 ReadWriteTransport(int readFd, int writeFd) : fReadFd{readFd}, fWriteFd{writeFd} {}
32 ~ReadWriteTransport() override {
33 close(fWriteFd);
34 close(fReadFd);
Herb Derby67c47f22018-02-07 17:47:59 -050035 }
Herb Derby97be88f2018-03-21 16:23:49 -040036 IOResult write(const void* buffer, size_t size) override {
37 ssize_t writeSize = ::write(fWriteFd, buffer, size);
38 if (writeSize < 0) {
39 err(1,"Failed write %zu", size);
Herb Derby67c47f22018-02-07 17:47:59 -050040 return kFail;
41 }
42 return kSuccess;
43 }
44
Herb Derby97be88f2018-03-21 16:23:49 -040045 std::tuple<size_t, IOResult> read(void* buffer, size_t size) override {
46 ssize_t readSize = ::read(fReadFd, buffer, size);
47 if (readSize < 0) {
48 err(1,"Failed read %zu", size);
49 return {size, kFail};
Herb Derby67c47f22018-02-07 17:47:59 -050050 }
Herb Derby97be88f2018-03-21 16:23:49 -040051 return {readSize, kSuccess};
Herb Derby67c47f22018-02-07 17:47:59 -050052 }
53
Herb Derby67c47f22018-02-07 17:47:59 -050054private:
Herb Derby67c47f22018-02-07 17:47:59 -050055 const int fReadFd,
56 fWriteFd;
Herb Derby67c47f22018-02-07 17:47:59 -050057};
58
Herb Derby97be88f2018-03-21 16:23:49 -040059static void prime_cache_spec(const SkIRect& bounds,
60 const SkSurfaceProps& props,
61 const SkPicture& pic,
62 SkStrikeCacheDifferenceSpec* strikeDifference) {
63 SkMatrix deviceMatrix = SkMatrix::I();
Herb Derbyca9c8792018-02-02 17:33:26 -050064
Herb Derby97be88f2018-03-21 16:23:49 -040065 SkTextBlobCacheDiffCanvas filter(
66 bounds.width(), bounds.height(), deviceMatrix, props,
67 SkScalerContextFlags::kFakeGammaAndBoostContrast,
68 strikeDifference);
Mike Kleina8a51ce2018-01-09 12:34:11 -050069
Herb Derby97be88f2018-03-21 16:23:49 -040070 pic.playback(&filter);
Herb Derby67c47f22018-02-07 17:47:59 -050071}
72
Herb Derby67c47f22018-02-07 17:47:59 -050073static void final_draw(std::string outFilename,
Herb Derby97be88f2018-03-21 16:23:49 -040074 SkTransport* transport,
Herb Derby67c47f22018-02-07 17:47:59 -050075 SkDeserialProcs* procs,
76 SkData* picData,
Herb Derby97be88f2018-03-21 16:23:49 -040077 SkStrikeClient* client) {
Herb Derby67c47f22018-02-07 17:47:59 -050078
79 auto pic = SkPicture::MakeFromData(picData, procs);
Herb Derby4f505f92018-01-09 12:34:11 -050080
81 auto cullRect = pic->cullRect();
82 auto r = cullRect.round();
Herb Derby4f505f92018-01-09 12:34:11 -050083
Herb Derbyd08c6822018-01-09 12:34:11 -050084 auto s = SkSurface::MakeRasterN32Premul(r.width(), r.height());
Herb Derby4f505f92018-01-09 12:34:11 -050085 auto c = s->getCanvas();
Herb Derby67c47f22018-02-07 17:47:59 -050086 auto picUnderTest = SkPicture::MakeFromData(picData, procs);
Herb Derbyd08c6822018-01-09 12:34:11 -050087
Herb Derby67c47f22018-02-07 17:47:59 -050088 SkMatrix deviceMatrix = SkMatrix::I();
Herb Derby67c47f22018-02-07 17:47:59 -050089
Herb Derby97be88f2018-03-21 16:23:49 -040090 SkStrikeCacheDifferenceSpec strikeDifference;
91 SkTextBlobCacheDiffCanvas filter(
92 r.width(), r.height(), deviceMatrix, s->props(),
93 SkScalerContextFlags::kFakeGammaAndBoostContrast,
94 &strikeDifference);
95
96 if (client != nullptr) {
Herb Derby67c47f22018-02-07 17:47:59 -050097 for (int i = 0; i < 0; i++) {
98 auto start = std::chrono::high_resolution_clock::now();
Herb Derby97be88f2018-03-21 16:23:49 -040099
100
101 SkStrikeCacheDifferenceSpec strikeDifference;
102
103 prime_cache_spec(r, s->props(), *picUnderTest, &strikeDifference);
104
105 client->primeStrikeCache(strikeDifference);
Herb Derby67c47f22018-02-07 17:47:59 -0500106
107 auto end = std::chrono::high_resolution_clock::now();
108 std::chrono::duration<double> elapsed_seconds = end - start;
109 (void)elapsed_seconds;
110 if (i == 0) {
Herb Derby97be88f2018-03-21 16:23:49 -0400111 std::cout << "filter time: " << elapsed_seconds.count() * 1e6 << std::endl;
Herb Derby67c47f22018-02-07 17:47:59 -0500112 }
113 }
114 }
Herb Derbyd08c6822018-01-09 12:34:11 -0500115
Herb Derby9d021822018-02-02 12:54:55 -0500116 std::chrono::duration<double> total_seconds{0.0};
Herb Derby97be88f2018-03-21 16:23:49 -0400117 for (int i = 0; i < 1; i++) { // 20
Herb Derby9d021822018-02-02 12:54:55 -0500118 if (gPurgeFontCaches) {
119 SkGraphics::PurgeFontCache();
120 }
121 auto start = std::chrono::high_resolution_clock::now();
Herb Derby97be88f2018-03-21 16:23:49 -0400122 if (client != nullptr) {
123 SkStrikeCacheDifferenceSpec strikeDifference;
124 prime_cache_spec(r, s->props(), *picUnderTest, &strikeDifference);
125 client->primeStrikeCache(strikeDifference);
Herb Derby67c47f22018-02-07 17:47:59 -0500126 }
Herb Derbyd08c6822018-01-09 12:34:11 -0500127 c->drawPicture(picUnderTest);
Herb Derby9d021822018-02-02 12:54:55 -0500128 auto end = std::chrono::high_resolution_clock::now();
129 std::chrono::duration<double> elapsed_seconds = end-start;
130 total_seconds += elapsed_seconds;
Herb Derbyd08c6822018-01-09 12:34:11 -0500131 }
Herb Derby4f505f92018-01-09 12:34:11 -0500132
Herb Derby9d021822018-02-02 12:54:55 -0500133 std::cout << "useProcess: " << gUseProcess
134 << " useGPU: " << gUseGpu
135 << " purgeCache: " << gPurgeFontCaches << std::endl;
Herb Derby67c47f22018-02-07 17:47:59 -0500136 fprintf(stderr, "%s use GPU %s elapsed time %8.6f s\n", gSkpName.c_str(),
137 gUseGpu ? "true" : "false", total_seconds.count());
Herb Derby4f505f92018-01-09 12:34:11 -0500138
139 auto i = s->makeImageSnapshot();
140 auto data = i->encodeToData();
141 SkFILEWStream f(outFilename.c_str());
142 f.write(data->data(), data->size());
143}
144
Mike Kleina8a51ce2018-01-09 12:34:11 -0500145static void gpu(int readFd, int writeFd) {
146
Herb Derby97be88f2018-03-21 16:23:49 -0400147 ReadWriteTransport rwTransport{readFd, writeFd};
Mike Kleina8a51ce2018-01-09 12:34:11 -0500148
Herb Derby97be88f2018-03-21 16:23:49 -0400149 auto picData = rwTransport.readSkData();
Herb Derby67c47f22018-02-07 17:47:59 -0500150 if (picData == nullptr) {
151 return;
Mike Kleina8a51ce2018-01-09 12:34:11 -0500152 }
153
Herb Derby97be88f2018-03-21 16:23:49 -0400154 SkStrikeClient client{&rwTransport};
155
Herb Derby67c47f22018-02-07 17:47:59 -0500156 SkDeserialProcs procs;
Herb Derby97be88f2018-03-21 16:23:49 -0400157 client.prepareDeserializeProcs(&procs);
Herb Derby67c47f22018-02-07 17:47:59 -0500158
Herb Derby97be88f2018-03-21 16:23:49 -0400159 final_draw("test.png", &rwTransport, &procs, picData.get(), &client);
Herb Derby76d69b42018-03-15 17:34:40 -0400160
Herb Derby97be88f2018-03-21 16:23:49 -0400161 printf("GPU is exiting\n");
Mike Kleina8a51ce2018-01-09 12:34:11 -0500162}
163
Herb Derbyb2922f62018-01-26 16:47:54 -0500164static int renderer(
165 const std::string& skpName, int readFd, int writeFd)
166{
Herb Derby97be88f2018-03-21 16:23:49 -0400167 ReadWriteTransport rwTransport{readFd, writeFd};
168 SkStrikeServer server{&rwTransport};
Mike Kleina8a51ce2018-01-09 12:34:11 -0500169
Herb Derby67c47f22018-02-07 17:47:59 -0500170 auto skpData = SkData::MakeFromFileName(skpName.c_str());
171 std::cout << "skp stream is " << skpData->size() << " bytes long " << std::endl;
Herb Derby4f505f92018-01-09 12:34:11 -0500172
Mike Kleina8a51ce2018-01-09 12:34:11 -0500173 SkSerialProcs procs;
Herb Derby9d021822018-02-02 12:54:55 -0500174 sk_sp<SkData> stream;
175 if (gUseGpu) {
Herb Derby67c47f22018-02-07 17:47:59 -0500176 auto pic = SkPicture::MakeFromData(skpData.get());
Herb Derby97be88f2018-03-21 16:23:49 -0400177 server.prepareSerializeProcs(&procs);
Herb Derby9d021822018-02-02 12:54:55 -0500178 stream = pic->serialize(&procs);
Herb Derby97be88f2018-03-21 16:23:49 -0400179
180 if (rwTransport.writeSkData(*stream) == SkTransport::kFail) {
181 return 1;
182 }
183
184 std::cout << "Waiting for scaler context ops." << std::endl;
185
186 return server.serve();
Herb Derby9d021822018-02-02 12:54:55 -0500187 } else {
Herb Derby67c47f22018-02-07 17:47:59 -0500188 stream = skpData;
Herb Derby97be88f2018-03-21 16:23:49 -0400189 final_draw("test-correct.png", &rwTransport, nullptr, stream.get(), nullptr);
Herb Derby4f505f92018-01-09 12:34:11 -0500190 return 0;
191 }
Mike Kleina8a51ce2018-01-09 12:34:11 -0500192}
193
Herb Derbyd08c6822018-01-09 12:34:11 -0500194
Mike Kleina8a51ce2018-01-09 12:34:11 -0500195int main(int argc, char** argv) {
Herb Derby67c47f22018-02-07 17:47:59 -0500196 std::string skpName = argc > 1 ? std::string{argv[1]} : std::string{"skps/desk_nytimes.skp"};
Herb Derby9d021822018-02-02 12:54:55 -0500197 int mode = argc > 2 ? atoi(argv[2]) : -1;
Mike Kleina8a51ce2018-01-09 12:34:11 -0500198 printf("skp: %s\n", skpName.c_str());
199
Herb Derby67c47f22018-02-07 17:47:59 -0500200 gSkpName = skpName;
201
Herb Derby97be88f2018-03-21 16:23:49 -0400202 enum direction : int {kRead = 0, kWrite = 1};
203
204
Mike Kleina8a51ce2018-01-09 12:34:11 -0500205 int render_to_gpu[2],
206 gpu_to_render[2];
207
Herb Derby9d021822018-02-02 12:54:55 -0500208 for (int m = 0; m < 8; m++) {
209 int r = pipe(render_to_gpu);
210 if (r < 0) {
211 perror("Can't write picture from render to GPU ");
212 return 1;
Herb Derbyd08c6822018-01-09 12:34:11 -0500213 }
Herb Derby9d021822018-02-02 12:54:55 -0500214 r = pipe(gpu_to_render);
215 if (r < 0) {
216 perror("Can't write picture from render to GPU ");
217 return 1;
218 }
219
220 gPurgeFontCaches = (m & 4) == 4;
221 gUseGpu = (m & 2) == 2;
222 gUseProcess = (m & 1) == 1;
223
224 if (mode >= 0 && mode < 8 && mode != m) {
225 continue;
226 }
227
228 if (gUseProcess) {
229 pid_t child = fork();
230 SkGraphics::Init();
231
232 if (child == 0) {
Herb Derby97be88f2018-03-21 16:23:49 -0400233 close(gpu_to_render[kRead]);
234 close(render_to_gpu[kWrite]);
235 gpu(render_to_gpu[kRead], gpu_to_render[kWrite]);
Herb Derby9d021822018-02-02 12:54:55 -0500236 } else {
Herb Derby97be88f2018-03-21 16:23:49 -0400237 close(render_to_gpu[kRead]);
238 close(gpu_to_render[kWrite]);
239 renderer(skpName, gpu_to_render[kRead], render_to_gpu[kWrite]);
Herb Derby9d021822018-02-02 12:54:55 -0500240 waitpid(child, nullptr, 0);
241 }
242 } else {
243 SkGraphics::Init();
244 std::thread(gpu, render_to_gpu[kRead], gpu_to_render[kWrite]).detach();
245 renderer(skpName, gpu_to_render[kRead], render_to_gpu[kWrite]);
246 }
Mike Kleina8a51ce2018-01-09 12:34:11 -0500247 }
248
Mike Kleina8a51ce2018-01-09 12:34:11 -0500249 return 0;
250}
251