OLD | NEW |
---|---|
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 "GrCaps.h" | 8 #include "GrCaps.h" |
9 #include "GrContextFactory.h" | 9 #include "GrContextFactory.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 } | 122 } |
123 } | 123 } |
124 png_set_filter(png, 0, PNG_NO_FILTERS); | 124 png_set_filter(png, 0, PNG_NO_FILTERS); |
125 png_set_rows(png, info_ptr, &rows[0]); | 125 png_set_rows(png, info_ptr, &rows[0]); |
126 png_set_write_fn(png, &out, write_png_callback, NULL); | 126 png_set_write_fn(png, &out, write_png_callback, NULL); |
127 png_write_png(png, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); | 127 png_write_png(png, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); |
128 png_destroy_write_struct(&png, NULL); | 128 png_destroy_write_struct(&png, NULL); |
129 sk_free(rows); | 129 sk_free(rows); |
130 } | 130 } |
131 | 131 |
132 SkBitmap* getBitmapFromCanvas(SkCanvas* canvas) { | |
133 SkBitmap* bmp = new SkBitmap(); | |
134 SkImageInfo info = SkImageInfo::Make(kImageWidth, kImageHeight, kRGBA_8888_S kColorType, | |
135 kOpaque_SkAlphaType); | |
136 bmp->setInfo(info); | |
137 if (!canvas->readPixels(bmp, 0, 0)) { | |
138 fprintf(stderr, "Can't read pixels\n"); | |
139 return nullptr; | |
140 } | |
141 return bmp; | |
142 } | |
143 | |
132 SkData* writeCanvasToPng(SkCanvas* canvas) { | 144 SkData* writeCanvasToPng(SkCanvas* canvas) { |
133 // capture pixels | 145 // capture pixels |
134 SkBitmap bmp; | 146 SkAutoTDelete<SkBitmap> bmp(getBitmapFromCanvas(canvas)); |
135 bmp.setInfo(canvas->imageInfo()); | 147 SkASSERT(bmp); |
136 if (!canvas->readPixels(&bmp, 0, 0)) { | |
137 fprintf(stderr, "Can't read pixels\n"); | |
138 return nullptr; | |
139 } | |
140 | 148 |
141 // write to png | 149 // write to png |
142 SkDynamicMemoryWStream buffer; | 150 SkDynamicMemoryWStream buffer; |
143 write_png((const png_bytep) bmp.getPixels(), bmp.width(), bmp.height(), buff er); | 151 write_png((const png_bytep) bmp->getPixels(), bmp->width(), bmp->height(), b uffer); |
144 return buffer.copyToData(); | 152 return buffer.copyToData(); |
145 } | 153 } |
146 | 154 |
147 SkCanvas* getCanvasFromRequest(Request* request) { | 155 SkCanvas* getCanvasFromRequest(Request* request) { |
148 GrContextFactory* factory = request->fContextFactory; | 156 GrContextFactory* factory = request->fContextFactory; |
149 SkGLContext* gl = factory->getContextInfo(GrContextFactory::kNative_GLContex tType, | 157 SkGLContext* gl = factory->getContextInfo(GrContextFactory::kNative_GLContex tType, |
150 GrContextFactory::kNone_GLContextO ptions).fGLContext; | 158 GrContextFactory::kNone_GLContextO ptions).fGLContext; |
151 gl->makeCurrent(); | 159 gl->makeCurrent(); |
152 SkASSERT(request->fDebugCanvas); | 160 SkASSERT(request->fDebugCanvas); |
153 SkCanvas* target = request->fSurface->getCanvas(); | 161 SkCanvas* target = request->fSurface->getCanvas(); |
154 return target; | 162 return target; |
155 } | 163 } |
156 | 164 |
157 SkData* setupAndDrawToCanvasReturnPng(Request* request, int n) { | 165 void drawToCanvas(Request* request, int n) { |
158 SkCanvas* target = getCanvasFromRequest(request); | 166 SkCanvas* target = getCanvasFromRequest(request); |
159 request->fDebugCanvas->drawTo(target, n); | 167 request->fDebugCanvas->drawTo(target, n); |
160 return writeCanvasToPng(target); | 168 } |
169 | |
170 SkData* drawToPng(Request* request, int n) { | |
171 drawToCanvas(request, n); | |
172 return writeCanvasToPng(getCanvasFromRequest(request)); | |
161 } | 173 } |
162 | 174 |
163 SkSurface* setupCpuSurface() { | 175 SkSurface* setupCpuSurface() { |
164 SkImageInfo info = SkImageInfo::Make(kImageWidth, kImageHeight, kN32_SkColor Type, | 176 SkImageInfo info = SkImageInfo::Make(kImageWidth, kImageHeight, kN32_SkColor Type, |
165 kPremul_SkAlphaType); | 177 kPremul_SkAlphaType); |
166 return SkSurface::NewRaster(info); | 178 return SkSurface::NewRaster(info); |
167 } | 179 } |
168 | 180 |
169 static const size_t kBufferSize = 1024; | 181 static const size_t kBufferSize = 1024; |
170 | 182 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
318 } | 330 } |
319 | 331 |
320 int n; | 332 int n; |
321 // /img or /img/N | 333 // /img or /img/N |
322 if (commands.count() == 1) { | 334 if (commands.count() == 1) { |
323 n = request->fDebugCanvas->getSize() - 1; | 335 n = request->fDebugCanvas->getSize() - 1; |
324 } else { | 336 } else { |
325 sscanf(commands[1].c_str(), "%d", &n); | 337 sscanf(commands[1].c_str(), "%d", &n); |
326 } | 338 } |
327 | 339 |
328 SkAutoTUnref<SkData> data(setupAndDrawToCanvasReturnPng(request, n)); | 340 SkAutoTUnref<SkData> data(drawToPng(request, n)); |
329 return SendData(connection, data, "image/png"); | 341 return SendData(connection, data, "image/png"); |
330 } | 342 } |
331 }; | 343 }; |
332 | 344 |
345 class BreakHandler : public UrlHandler { | |
346 public: | |
347 bool canHandle(const char* method, const char* url) override { | |
348 static const char* kBasePath = "/break"; | |
349 return 0 == strcmp(method, MHD_HTTP_METHOD_GET) && | |
350 0 == strncmp(url, kBasePath, strlen(kBasePath)); | |
351 } | |
352 | |
353 static SkColor getPixel(Request* request, int x, int y) { | |
354 SkCanvas* canvas = getCanvasFromRequest(request); | |
355 SkAutoTDelete<SkBitmap> bitmap(getBitmapFromCanvas(canvas)); | |
356 SkASSERT(bitmap); | |
357 bitmap->lockPixels(); | |
358 uint8_t* start = ((uint8_t*) bitmap->getPixels()) + (y * kImageWidth + x ) * 4; | |
359 SkColor result = SkColorSetARGB(start[3], start[0], start[1], start[2]); | |
360 bitmap->unlockPixels(); | |
361 return result; | |
362 } | |
363 | |
364 int handle(Request* request, MHD_Connection* connection, | |
365 const char* url, const char* method, | |
366 const char* upload_data, size_t* upload_data_size) override { | |
367 SkTArray<SkString> commands; | |
368 SkStrSplit(url, "/", &commands); | |
369 | |
370 if (!request->fPicture.get() || commands.count() != 4) { | |
371 return MHD_NO; | |
372 } | |
373 | |
374 // /break/<n>/<x>/<y> | |
375 int n; | |
376 sscanf(commands[1].c_str(), "%d", &n); | |
377 int x; | |
378 sscanf(commands[2].c_str(), "%d", &x); | |
379 int y; | |
380 sscanf(commands[3].c_str(), "%d", &y); | |
381 | |
382 drawToCanvas(request, n); | |
383 SkColor target = getPixel(request, x, y); | |
384 SkCanvas* canvas = getCanvasFromRequest(request); | |
385 Json::Value response(Json::objectValue); | |
386 Json::Value startColor(Json::arrayValue); | |
387 startColor.append(Json::Value(SkColorGetR(target))); | |
388 startColor.append(Json::Value(SkColorGetG(target))); | |
389 startColor.append(Json::Value(SkColorGetB(target))); | |
390 startColor.append(Json::Value(SkColorGetA(target))); | |
391 response["startColor"] = startColor; | |
392 response["endColor"] = startColor; | |
393 response["endOp"] = Json::Value(-1); | |
394 for (int i = n + 1; i < request->fDebugCanvas->getSize(); ++i) { | |
jcgregorio
2016/02/18 13:48:11
Actually can you wrap around? I.e. if you each the
| |
395 request->fDebugCanvas->getDrawCommandAt(i)->execute(canvas); | |
396 canvas->flush(); | |
397 SkColor current = getPixel(request, x, y); | |
398 if (current != target) { | |
399 Json::Value endColor(Json::arrayValue); | |
400 endColor.append(Json::Value(SkColorGetR(current))); | |
401 endColor.append(Json::Value(SkColorGetG(current))); | |
402 endColor.append(Json::Value(SkColorGetB(current))); | |
403 endColor.append(Json::Value(SkColorGetA(current))); | |
404 response["endColor"] = endColor; | |
405 response["endOp"] = Json::Value(i); | |
406 break; | |
407 } | |
408 } | |
409 SkDynamicMemoryWStream stream; | |
410 stream.writeText(Json::FastWriter().write(response).c_str()); | |
411 SkAutoTUnref<SkData> data(stream.copyToData()); | |
412 return SendData(connection, data, "application/json"); | |
413 } | |
414 }; | |
415 | |
333 /** | 416 /** |
334 Updates the clip visualization alpha. On all subsequent /img requests, the cl ip will be drawn in | 417 Updates the clip visualization alpha. On all subsequent /img requests, the cl ip will be drawn in |
335 black with the specified alpha. 0 = no visible clip, 255 = fully opaque clip. | 418 black with the specified alpha. 0 = no visible clip, 255 = fully opaque clip. |
336 */ | 419 */ |
337 class ClipAlphaHandler : public UrlHandler { | 420 class ClipAlphaHandler : public UrlHandler { |
338 public: | 421 public: |
339 bool canHandle(const char* method, const char* url) override { | 422 bool canHandle(const char* method, const char* url) override { |
340 static const char* kBasePath = "/clipAlpha/"; | 423 static const char* kBasePath = "/clipAlpha/"; |
341 return 0 == strcmp(method, MHD_HTTP_METHOD_POST) && | 424 return 0 == strcmp(method, MHD_HTTP_METHOD_POST) && |
342 0 == strncmp(url, kBasePath, strlen(kBasePath)); | 425 0 == strncmp(url, kBasePath, strlen(kBasePath)); |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
576 // Register handlers | 659 // Register handlers |
577 fHandlers.push_back(new RootHandler); | 660 fHandlers.push_back(new RootHandler); |
578 fHandlers.push_back(new PostHandler); | 661 fHandlers.push_back(new PostHandler); |
579 fHandlers.push_back(new ImgHandler); | 662 fHandlers.push_back(new ImgHandler); |
580 fHandlers.push_back(new ClipAlphaHandler); | 663 fHandlers.push_back(new ClipAlphaHandler); |
581 fHandlers.push_back(new CmdHandler); | 664 fHandlers.push_back(new CmdHandler); |
582 fHandlers.push_back(new InfoHandler); | 665 fHandlers.push_back(new InfoHandler); |
583 fHandlers.push_back(new DownloadHandler); | 666 fHandlers.push_back(new DownloadHandler); |
584 fHandlers.push_back(new DataHandler); | 667 fHandlers.push_back(new DataHandler); |
585 fHandlers.push_back(new FaviconHandler); | 668 fHandlers.push_back(new FaviconHandler); |
669 fHandlers.push_back(new BreakHandler); | |
586 } | 670 } |
587 | 671 |
588 ~UrlManager() { | 672 ~UrlManager() { |
589 for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; } | 673 for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; } |
590 } | 674 } |
591 | 675 |
592 // This is clearly not efficient for a large number of urls and handlers | 676 // This is clearly not efficient for a large number of urls and handlers |
593 int invoke(Request* request, MHD_Connection* connection, const char* url, co nst char* method, | 677 int invoke(Request* request, MHD_Connection* connection, const char* url, co nst char* method, |
594 const char* upload_data, size_t* upload_data_size) const { | 678 const char* upload_data, size_t* upload_data_size) const { |
595 for (int i = 0; i < fHandlers.count(); i++) { | 679 for (int i = 0; i < fHandlers.count(); i++) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
637 MHD_stop_daemon(daemon); | 721 MHD_stop_daemon(daemon); |
638 return 0; | 722 return 0; |
639 } | 723 } |
640 | 724 |
641 #if !defined SK_BUILD_FOR_IOS | 725 #if !defined SK_BUILD_FOR_IOS |
642 int main(int argc, char** argv) { | 726 int main(int argc, char** argv) { |
643 SkCommandLineFlags::Parse(argc, argv); | 727 SkCommandLineFlags::Parse(argc, argv); |
644 return skiaserve_main(); | 728 return skiaserve_main(); |
645 } | 729 } |
646 #endif | 730 #endif |
OLD | NEW |