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) { | |
joshualitt
2016/02/18 17:53:31
GetPixel
| |
354 SkCanvas* canvas = getCanvasFromRequest(request); | |
355 canvas->flush(); | |
356 SkAutoTDelete<SkBitmap> bitmap(getBitmapFromCanvas(canvas)); | |
357 SkASSERT(bitmap); | |
358 bitmap->lockPixels(); | |
359 uint8_t* start = ((uint8_t*) bitmap->getPixels()) + (y * kImageWidth + x ) * 4; | |
360 SkColor result = SkColorSetARGB(start[3], start[0], start[1], start[2]); | |
361 bitmap->unlockPixels(); | |
362 return result; | |
363 } | |
364 | |
365 int handle(Request* request, MHD_Connection* connection, | |
366 const char* url, const char* method, | |
367 const char* upload_data, size_t* upload_data_size) override { | |
368 SkTArray<SkString> commands; | |
369 SkStrSplit(url, "/", &commands); | |
370 | |
371 if (!request->fPicture.get() || commands.count() != 4) { | |
372 return MHD_NO; | |
373 } | |
374 | |
375 // /break/<n>/<x>/<y> | |
376 int n; | |
377 sscanf(commands[1].c_str(), "%d", &n); | |
378 int x; | |
379 sscanf(commands[2].c_str(), "%d", &x); | |
380 int y; | |
381 sscanf(commands[3].c_str(), "%d", &y); | |
382 | |
383 int count = request->fDebugCanvas->getSize(); | |
384 SkASSERT(n < count); | |
385 | |
386 SkCanvas* canvas = getCanvasFromRequest(request); | |
387 canvas->clear(SK_ColorWHITE); | |
388 int saveCount = canvas->save(); | |
389 for (int i = 0; i <= n; ++i) { | |
390 request->fDebugCanvas->getDrawCommandAt(i)->execute(canvas); | |
391 } | |
392 SkColor target = getPixel(request, x, y); | |
393 Json::Value response(Json::objectValue); | |
394 Json::Value startColor(Json::arrayValue); | |
395 startColor.append(Json::Value(SkColorGetR(target))); | |
396 startColor.append(Json::Value(SkColorGetG(target))); | |
397 startColor.append(Json::Value(SkColorGetB(target))); | |
398 startColor.append(Json::Value(SkColorGetA(target))); | |
399 response["startColor"] = startColor; | |
400 response["endColor"] = startColor; | |
401 response["endOp"] = Json::Value(n); | |
402 for (int i = n + 1; i < n + count; ++i) { | |
403 int index = i % count; | |
404 if (index == 0) { | |
405 // reset canvas for wraparound | |
406 canvas->restoreToCount(saveCount); | |
407 canvas->clear(SK_ColorWHITE); | |
408 saveCount = canvas->save(); | |
409 } | |
410 request->fDebugCanvas->getDrawCommandAt(index)->execute(canvas); | |
411 SkColor current = getPixel(request, x, y); | |
412 if (current != target) { | |
413 Json::Value endColor(Json::arrayValue); | |
414 endColor.append(Json::Value(SkColorGetR(current))); | |
415 endColor.append(Json::Value(SkColorGetG(current))); | |
416 endColor.append(Json::Value(SkColorGetB(current))); | |
417 endColor.append(Json::Value(SkColorGetA(current))); | |
418 response["endColor"] = endColor; | |
419 response["endOp"] = Json::Value(index); | |
420 break; | |
421 } | |
422 } | |
423 canvas->restoreToCount(saveCount); | |
424 SkDynamicMemoryWStream stream; | |
425 stream.writeText(Json::FastWriter().write(response).c_str()); | |
426 SkAutoTUnref<SkData> data(stream.copyToData()); | |
427 return SendData(connection, data, "application/json"); | |
428 } | |
429 }; | |
430 | |
333 /** | 431 /** |
334 Updates the clip visualization alpha. On all subsequent /img requests, the cl ip will be drawn in | 432 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. | 433 black with the specified alpha. 0 = no visible clip, 255 = fully opaque clip. |
336 */ | 434 */ |
337 class ClipAlphaHandler : public UrlHandler { | 435 class ClipAlphaHandler : public UrlHandler { |
338 public: | 436 public: |
339 bool canHandle(const char* method, const char* url) override { | 437 bool canHandle(const char* method, const char* url) override { |
340 static const char* kBasePath = "/clipAlpha/"; | 438 static const char* kBasePath = "/clipAlpha/"; |
341 return 0 == strcmp(method, MHD_HTTP_METHOD_POST) && | 439 return 0 == strcmp(method, MHD_HTTP_METHOD_POST) && |
342 0 == strncmp(url, kBasePath, strlen(kBasePath)); | 440 0 == strncmp(url, kBasePath, strlen(kBasePath)); |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
576 // Register handlers | 674 // Register handlers |
577 fHandlers.push_back(new RootHandler); | 675 fHandlers.push_back(new RootHandler); |
578 fHandlers.push_back(new PostHandler); | 676 fHandlers.push_back(new PostHandler); |
579 fHandlers.push_back(new ImgHandler); | 677 fHandlers.push_back(new ImgHandler); |
580 fHandlers.push_back(new ClipAlphaHandler); | 678 fHandlers.push_back(new ClipAlphaHandler); |
581 fHandlers.push_back(new CmdHandler); | 679 fHandlers.push_back(new CmdHandler); |
582 fHandlers.push_back(new InfoHandler); | 680 fHandlers.push_back(new InfoHandler); |
583 fHandlers.push_back(new DownloadHandler); | 681 fHandlers.push_back(new DownloadHandler); |
584 fHandlers.push_back(new DataHandler); | 682 fHandlers.push_back(new DataHandler); |
585 fHandlers.push_back(new FaviconHandler); | 683 fHandlers.push_back(new FaviconHandler); |
684 fHandlers.push_back(new BreakHandler); | |
586 } | 685 } |
587 | 686 |
588 ~UrlManager() { | 687 ~UrlManager() { |
589 for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; } | 688 for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; } |
590 } | 689 } |
591 | 690 |
592 // This is clearly not efficient for a large number of urls and handlers | 691 // 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, | 692 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 { | 693 const char* upload_data, size_t* upload_data_size) const { |
595 for (int i = 0; i < fHandlers.count(); i++) { | 694 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); | 736 MHD_stop_daemon(daemon); |
638 return 0; | 737 return 0; |
639 } | 738 } |
640 | 739 |
641 #if !defined SK_BUILD_FOR_IOS | 740 #if !defined SK_BUILD_FOR_IOS |
642 int main(int argc, char** argv) { | 741 int main(int argc, char** argv) { |
643 SkCommandLineFlags::Parse(argc, argv); | 742 SkCommandLineFlags::Parse(argc, argv); |
644 return skiaserve_main(); | 743 return skiaserve_main(); |
645 } | 744 } |
646 #endif | 745 #endif |
OLD | NEW |