Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: tools/skiaserve/Request.cpp

Issue 1777203003: Fix some bugs and performance issues with skiaserve (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: cleanup Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/skiaserve/Request.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "Request.h" 8 #include "Request.h"
9 9
10 #include "png.h" 10 #include "png.h"
11 11
12 #include "SkPictureRecorder.h" 12 #include "SkPictureRecorder.h"
13 #include "SkPixelSerializer.h" 13 #include "SkPixelSerializer.h"
14 14
15 static int kDefaultWidth = 1920;
16 static int kDefaultHeight = 1080;
17
15 static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t l ength) { 18 static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t l ength) {
16 SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr); 19 SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr);
17 out->write(data, length); 20 out->write(data, length);
18 } 21 }
19 22
20 static void write_png(const png_bytep rgba, png_uint_32 width, png_uint_32 heigh t, SkWStream& out) { 23 static void write_png(const png_bytep rgba, png_uint_32 width, png_uint_32 heigh t, SkWStream& out) {
21 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 24 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
22 SkASSERT(png != nullptr); 25 SkASSERT(png != nullptr);
23 png_infop info_ptr = png_create_info_struct(png); 26 png_infop info_ptr = png_create_info_struct(png);
24 SkASSERT(info_ptr != nullptr); 27 SkASSERT(info_ptr != nullptr);
(...skipping 27 matching lines...) Expand all
52 : fUploadContext(nullptr) 55 : fUploadContext(nullptr)
53 , fUrlDataManager(rootUrl) 56 , fUrlDataManager(rootUrl)
54 , fGPUEnabled(false) { 57 , fGPUEnabled(false) {
55 // create surface 58 // create surface
56 GrContextOptions grContextOpts; 59 GrContextOptions grContextOpts;
57 fContextFactory.reset(new GrContextFactory(grContextOpts)); 60 fContextFactory.reset(new GrContextFactory(grContextOpts));
58 } 61 }
59 62
60 SkBitmap* Request::getBitmapFromCanvas(SkCanvas* canvas) { 63 SkBitmap* Request::getBitmapFromCanvas(SkCanvas* canvas) {
61 SkBitmap* bmp = new SkBitmap(); 64 SkBitmap* bmp = new SkBitmap();
62 SkIRect bounds = fPicture->cullRect().roundOut(); 65 SkIRect bounds = this->getBounds();
63 SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), 66 SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(),
64 kRGBA_8888_SkColorType, kOpaque_SkAlpha Type); 67 kRGBA_8888_SkColorType, kOpaque_SkAlpha Type);
65 bmp->setInfo(info); 68 bmp->setInfo(info);
66 if (!canvas->readPixels(bmp, 0, 0)) { 69 if (!canvas->readPixels(bmp, 0, 0)) {
67 fprintf(stderr, "Can't read pixels\n"); 70 fprintf(stderr, "Can't read pixels\n");
68 return nullptr; 71 return nullptr;
69 } 72 }
70 return bmp; 73 return bmp;
71 } 74 }
72 75
(...skipping 28 matching lines...) Expand all
101 fDebugCanvas->drawTo(target, n, m); 104 fDebugCanvas->drawTo(target, n, m);
102 } 105 }
103 106
104 SkData* Request::drawToPng(int n, int m) { 107 SkData* Request::drawToPng(int n, int m) {
105 this->drawToCanvas(n, m); 108 this->drawToCanvas(n, m);
106 return writeCanvasToPng(this->getCanvas()); 109 return writeCanvasToPng(this->getCanvas());
107 } 110 }
108 111
109 SkData* Request::writeOutSkp() { 112 SkData* Request::writeOutSkp() {
110 // Playback into picture recorder 113 // Playback into picture recorder
111 SkIRect bounds = fPicture->cullRect().roundOut(); 114 SkIRect bounds = this->getBounds();
112 SkPictureRecorder recorder; 115 SkPictureRecorder recorder;
113 SkCanvas* canvas = recorder.beginRecording(bounds.width(), bounds.height()); 116 SkCanvas* canvas = recorder.beginRecording(bounds.width(), bounds.height());
114 117
115 fDebugCanvas->draw(canvas); 118 fDebugCanvas->draw(canvas);
116 119
117 SkAutoTUnref<SkPicture> picture(recorder.endRecording()); 120 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
118 121
119 SkDynamicMemoryWStream outStream; 122 SkDynamicMemoryWStream outStream;
120 123
121 SkAutoTUnref<SkPixelSerializer> serializer(SkImageEncoder::CreatePixelSerial izer()); 124 SkAutoTUnref<SkPixelSerializer> serializer(SkImageEncoder::CreatePixelSerial izer());
122 picture->serialize(&outStream, serializer); 125 picture->serialize(&outStream, serializer);
123 126
124 return outStream.copyToData(); 127 return outStream.copyToData();
125 } 128 }
126 129
130 GrContext* Request::getContext() {
131 return fContextFactory->get(GrContextFactory::kNative_GLContextType,
132 GrContextFactory::kNone_GLContextOptions);
133 }
134
135 SkIRect Request::getBounds() {
136 SkIRect bounds;
137 if (fPicture) {
138 bounds = fPicture->cullRect().roundOut();
139 if (fGPUEnabled) {
140 int maxRTSize = this->getContext()->caps()->maxRenderTargetSize();
141 bounds = SkIRect::MakeWH(SkTMin(bounds.width(), maxRTSize),
142 SkTMin(bounds.height(), maxRTSize));
143 }
144 } else {
145 bounds = SkIRect::MakeWH(kDefaultWidth, kDefaultHeight);
146 }
147
148 // We clip to kDefaultWidth / kDefaultHeight for performance reasons
149 // TODO make this configurable
150 bounds = SkIRect::MakeWH(SkTMin(bounds.width(), kDefaultWidth),
151 SkTMin(bounds.height(), kDefaultHeight));
152 return bounds;
153 }
154
127 SkSurface* Request::createCPUSurface() { 155 SkSurface* Request::createCPUSurface() {
128 SkIRect bounds = fPicture->cullRect().roundOut(); 156 SkIRect bounds = this->getBounds();
129 SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), kN32_S kColorType, 157 SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), kN32_S kColorType,
130 kPremul_SkAlphaType); 158 kPremul_SkAlphaType);
131 return SkSurface::NewRaster(info); 159 return SkSurface::NewRaster(info);
132 } 160 }
133 161
134 SkSurface* Request::createGPUSurface() { 162 SkSurface* Request::createGPUSurface() {
135 GrContext* context = fContextFactory->get(GrContextFactory::kNative_GLContex tType, 163 GrContext* context = this->getContext();
136 GrContextFactory::kNone_GLContextO ptions); 164 SkIRect bounds = this->getBounds();
137 SkIRect bounds = fPicture->cullRect().roundOut();
138 SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), 165 SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(),
139 kN32_SkColorType, kPremul_SkAlphaType); 166 kN32_SkColorType, kPremul_SkAlphaType);
140 uint32_t flags = 0; 167 uint32_t flags = 0;
141 SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); 168 SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
142 SkSurface* surface = SkSurface::NewRenderTarget(context, SkBudgeted::kNo, in fo, 0, 169 SkSurface* surface = SkSurface::NewRenderTarget(context, SkBudgeted::kNo, in fo, 0,
143 &props); 170 &props);
144 return surface; 171 return surface;
145 } 172 }
146 173
147 bool Request::enableGPU(bool enable) { 174 bool Request::enableGPU(bool enable) {
(...skipping 12 matching lines...) Expand all
160 } 187 }
161 188
162 bool Request::initPictureFromStream(SkStream* stream) { 189 bool Request::initPictureFromStream(SkStream* stream) {
163 // parse picture from stream 190 // parse picture from stream
164 fPicture.reset(SkPicture::CreateFromStream(stream)); 191 fPicture.reset(SkPicture::CreateFromStream(stream));
165 if (!fPicture.get()) { 192 if (!fPicture.get()) {
166 fprintf(stderr, "Could not create picture from stream.\n"); 193 fprintf(stderr, "Could not create picture from stream.\n");
167 return false; 194 return false;
168 } 195 }
169 196
197 // reinitialize canvas with the new picture dimensions
198 this->enableGPU(fGPUEnabled);
199
170 // pour picture into debug canvas 200 // pour picture into debug canvas
171 SkIRect bounds = fPicture->cullRect().roundOut(); 201 SkIRect bounds = this->getBounds();
172 fDebugCanvas.reset(new SkDebugCanvas(bounds.width(), bounds.height())); 202 fDebugCanvas.reset(new SkDebugCanvas(bounds.width(), bounds.height()));
173 fDebugCanvas->drawPicture(fPicture); 203 fDebugCanvas->drawPicture(fPicture);
174 204
175 // for some reason we need to 'flush' the debug canvas by drawing all of the ops 205 // for some reason we need to 'flush' the debug canvas by drawing all of the ops
176 fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp()); 206 fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp());
177 this->getCanvas()->flush(); 207 this->getCanvas()->flush();
178 return true; 208 return true;
179 } 209 }
180 210
181 GrAuditTrail* Request::getAuditTrail(SkCanvas* canvas) {
182 GrAuditTrail* at = nullptr;
183 #if SK_SUPPORT_GPU
184 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
185 if (rt) {
186 GrContext* ctx = rt->getContext();
187 if (ctx) {
188 at = ctx->getAuditTrail();
189 }
190 }
191 #endif
192 return at;
193 }
194
195 void Request::cleanupAuditTrail(SkCanvas* canvas) {
196 GrAuditTrail* at = this->getAuditTrail(canvas);
197 if (at) {
198 GrAuditTrail::AutoEnable ae(at);
199 at->fullReset();
200 }
201 }
202
203 SkData* Request::getJsonOps(int n) { 211 SkData* Request::getJsonOps(int n) {
204 SkCanvas* canvas = this->getCanvas(); 212 SkCanvas* canvas = this->getCanvas();
205 Json::Value root = fDebugCanvas->toJSON(fUrlDataManager, n, canvas); 213 Json::Value root = fDebugCanvas->toJSON(fUrlDataManager, n, canvas);
206 root["mode"] = Json::Value(fGPUEnabled ? "gpu" : "cpu"); 214 root["mode"] = Json::Value(fGPUEnabled ? "gpu" : "cpu");
207 root["drawGpuBatchBounds"] = Json::Value(fDebugCanvas->getDrawGpuBatchBounds ()); 215 root["drawGpuBatchBounds"] = Json::Value(fDebugCanvas->getDrawGpuBatchBounds ());
208 SkDynamicMemoryWStream stream; 216 SkDynamicMemoryWStream stream;
209 stream.writeText(Json::FastWriter().write(root).c_str()); 217 stream.writeText(Json::FastWriter().write(root).c_str());
210 218
211 this->cleanupAuditTrail(canvas);
212
213 return stream.copyToData(); 219 return stream.copyToData();
214 } 220 }
215 221
216 SkData* Request::getJsonBatchList(int n) { 222 SkData* Request::getJsonBatchList(int n) {
217 SkCanvas* canvas = this->getCanvas(); 223 SkCanvas* canvas = this->getCanvas();
218 SkASSERT(fGPUEnabled); 224 SkASSERT(fGPUEnabled);
219 225
220 // TODO if this is inefficient we could add a method to GrAuditTrail which t akes 226 Json::Value result = fDebugCanvas->toJSONBatchList(n, canvas);
221 // a Json::Value and is only compiled in this file
222 Json::Value parsedFromString;
223 #if SK_SUPPORT_GPU
224 // we use the toJSON method on debug canvas, but then just ignore the result s and pull
225 // the information we care about from the audit trail
226 fDebugCanvas->toJSON(fUrlDataManager, n, canvas);
227
228 GrAuditTrail* at = this->getAuditTrail(canvas);
229 GrAuditTrail::AutoManageBatchList enable(at);
230 Json::Reader reader;
231 SkDEBUGCODE(bool parsingSuccessful = )reader.parse(at->toJson().c_str(),
232 parsedFromString);
233 SkASSERT(parsingSuccessful);
234 #endif
235 227
236 SkDynamicMemoryWStream stream; 228 SkDynamicMemoryWStream stream;
237 stream.writeText(Json::FastWriter().write(parsedFromString).c_str()); 229 stream.writeText(Json::FastWriter().write(result).c_str());
238 230
239 return stream.copyToData(); 231 return stream.copyToData();
240 } 232 }
241 233
242 SkData* Request::getJsonInfo(int n) { 234 SkData* Request::getJsonInfo(int n) {
243 // drawTo 235 // drawTo
244 SkAutoTUnref<SkSurface> surface(this->createCPUSurface()); 236 SkAutoTUnref<SkSurface> surface(this->createCPUSurface());
245 SkCanvas* canvas = surface->getCanvas(); 237 SkCanvas* canvas = surface->getCanvas();
246 238
247 // TODO this is really slow and we should cache the matrix and clip 239 // TODO this is really slow and we should cache the matrix and clip
(...skipping 17 matching lines...) Expand all
265 canvas->flush(); 257 canvas->flush();
266 SkAutoTDelete<SkBitmap> bitmap(this->getBitmapFromCanvas(canvas)); 258 SkAutoTDelete<SkBitmap> bitmap(this->getBitmapFromCanvas(canvas));
267 SkASSERT(bitmap); 259 SkASSERT(bitmap);
268 bitmap->lockPixels(); 260 bitmap->lockPixels();
269 uint8_t* start = ((uint8_t*) bitmap->getPixels()) + (y * bitmap->width() + x ) * 4; 261 uint8_t* start = ((uint8_t*) bitmap->getPixels()) + (y * bitmap->width() + x ) * 4;
270 SkColor result = SkColorSetARGB(start[3], start[0], start[1], start[2]); 262 SkColor result = SkColorSetARGB(start[3], start[0], start[1], start[2]);
271 bitmap->unlockPixels(); 263 bitmap->unlockPixels();
272 return result; 264 return result;
273 } 265 }
274 266
OLDNEW
« no previous file with comments | « tools/skiaserve/Request.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698