Chromium Code Reviews| 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["endOp"] = Json::Value(Json::nullValue); | |
|
jcgregorio
2016/02/17 21:29:17
Can you make this -1? That way endOp is always a n
| |
| 393 for (int i = n + 1; i < request->fDebugCanvas->getSize(); ++i) { | |
| 394 request->fDebugCanvas->getDrawCommandAt(i)->execute(canvas); | |
| 395 canvas->flush(); | |
| 396 SkColor current = getPixel(request, x, y); | |
| 397 if (current != target) { | |
| 398 Json::Value endColor(Json::arrayValue); | |
| 399 endColor.append(Json::Value(SkColorGetR(current))); | |
| 400 endColor.append(Json::Value(SkColorGetG(current))); | |
| 401 endColor.append(Json::Value(SkColorGetB(current))); | |
| 402 endColor.append(Json::Value(SkColorGetA(current))); | |
| 403 response["endColor"] = endColor; | |
| 404 response["endOp"] = Json::Value(i); | |
| 405 break; | |
| 406 } | |
| 407 } | |
| 408 SkDynamicMemoryWStream stream; | |
| 409 stream.writeText(Json::FastWriter().write(response).c_str()); | |
| 410 SkAutoTUnref<SkData> data(stream.copyToData()); | |
| 411 return SendData(connection, data, "application/json"); | |
| 412 } | |
| 413 }; | |
| 414 | |
| 333 /** | 415 /** |
| 334 Updates the clip visualization alpha. On all subsequent /img requests, the cl ip will be drawn in | 416 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. | 417 black with the specified alpha. 0 = no visible clip, 255 = fully opaque clip. |
| 336 */ | 418 */ |
| 337 class ClipAlphaHandler : public UrlHandler { | 419 class ClipAlphaHandler : public UrlHandler { |
| 338 public: | 420 public: |
| 339 bool canHandle(const char* method, const char* url) override { | 421 bool canHandle(const char* method, const char* url) override { |
| 340 static const char* kBasePath = "/clipAlpha/"; | 422 static const char* kBasePath = "/clipAlpha/"; |
| 341 return 0 == strcmp(method, MHD_HTTP_METHOD_POST) && | 423 return 0 == strcmp(method, MHD_HTTP_METHOD_POST) && |
| 342 0 == strncmp(url, kBasePath, strlen(kBasePath)); | 424 0 == strncmp(url, kBasePath, strlen(kBasePath)); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 // Register handlers | 658 // Register handlers |
| 577 fHandlers.push_back(new RootHandler); | 659 fHandlers.push_back(new RootHandler); |
| 578 fHandlers.push_back(new PostHandler); | 660 fHandlers.push_back(new PostHandler); |
| 579 fHandlers.push_back(new ImgHandler); | 661 fHandlers.push_back(new ImgHandler); |
| 580 fHandlers.push_back(new ClipAlphaHandler); | 662 fHandlers.push_back(new ClipAlphaHandler); |
| 581 fHandlers.push_back(new CmdHandler); | 663 fHandlers.push_back(new CmdHandler); |
| 582 fHandlers.push_back(new InfoHandler); | 664 fHandlers.push_back(new InfoHandler); |
| 583 fHandlers.push_back(new DownloadHandler); | 665 fHandlers.push_back(new DownloadHandler); |
| 584 fHandlers.push_back(new DataHandler); | 666 fHandlers.push_back(new DataHandler); |
| 585 fHandlers.push_back(new FaviconHandler); | 667 fHandlers.push_back(new FaviconHandler); |
| 668 fHandlers.push_back(new BreakHandler); | |
| 586 } | 669 } |
| 587 | 670 |
| 588 ~UrlManager() { | 671 ~UrlManager() { |
| 589 for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; } | 672 for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; } |
| 590 } | 673 } |
| 591 | 674 |
| 592 // This is clearly not efficient for a large number of urls and handlers | 675 // 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, | 676 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 { | 677 const char* upload_data, size_t* upload_data_size) const { |
| 595 for (int i = 0; i < fHandlers.count(); i++) { | 678 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); | 720 MHD_stop_daemon(daemon); |
| 638 return 0; | 721 return 0; |
| 639 } | 722 } |
| 640 | 723 |
| 641 #if !defined SK_BUILD_FOR_IOS | 724 #if !defined SK_BUILD_FOR_IOS |
| 642 int main(int argc, char** argv) { | 725 int main(int argc, char** argv) { |
| 643 SkCommandLineFlags::Parse(argc, argv); | 726 SkCommandLineFlags::Parse(argc, argv); |
| 644 return skiaserve_main(); | 727 return skiaserve_main(); |
| 645 } | 728 } |
| 646 #endif | 729 #endif |
| OLD | NEW |