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" |
11 #include "SkCommandLineFlags.h" | 11 #include "SkCommandLineFlags.h" |
12 #include "SkDebugCanvas.h" | 12 #include "SkDebugCanvas.h" |
13 #include "SkJSONCanvas.h" | 13 #include "SkJSONCanvas.h" |
14 #include "SkJSONCPP.h" | 14 #include "SkJSONCPP.h" |
15 #include "SkPicture.h" | 15 #include "SkPicture.h" |
16 #include "SkPictureRecorder.h" | 16 #include "SkPictureRecorder.h" |
17 #include "SkPixelSerializer.h" | 17 #include "SkPixelSerializer.h" |
18 #include "SkStream.h" | 18 #include "SkStream.h" |
19 #include "SkSurface.h" | 19 #include "SkSurface.h" |
20 | 20 |
| 21 #include "UrlDataManager.h" |
| 22 |
21 #include <sys/socket.h> | 23 #include <sys/socket.h> |
22 #include <microhttpd.h> | 24 #include <microhttpd.h> |
23 | 25 |
24 // To get image decoders linked in we have to do the below magic | 26 // To get image decoders linked in we have to do the below magic |
25 #include "SkForceLinking.h" | 27 #include "SkForceLinking.h" |
26 #include "SkImageDecoder.h" | 28 #include "SkImageDecoder.h" |
27 __SK_FORCE_IMAGE_DECODER_LINKING; | 29 __SK_FORCE_IMAGE_DECODER_LINKING; |
28 | 30 |
29 DEFINE_string(source, "https://debugger.skia.org", "Where to load the web UI fro
m."); | 31 DEFINE_string(source, "https://debugger.skia.org", "Where to load the web UI fro
m."); |
30 DEFINE_int32(port, 8888, "The port to listen on."); | 32 DEFINE_int32(port, 8888, "The port to listen on."); |
(...skipping 25 matching lines...) Expand all Loading... |
56 | 58 |
57 } | 59 } |
58 | 60 |
59 struct UploadContext { | 61 struct UploadContext { |
60 SkDynamicMemoryWStream fStream; | 62 SkDynamicMemoryWStream fStream; |
61 MHD_PostProcessor* fPostProcessor; | 63 MHD_PostProcessor* fPostProcessor; |
62 MHD_Connection* connection; | 64 MHD_Connection* connection; |
63 }; | 65 }; |
64 | 66 |
65 struct Request { | 67 struct Request { |
66 Request() : fUploadContext(nullptr) {} | 68 Request(SkString rootUrl) : fUploadContext(nullptr), fUrlDataManager(rootUrl
) {} |
67 UploadContext* fUploadContext; | 69 UploadContext* fUploadContext; |
68 SkAutoTUnref<SkPicture> fPicture; | 70 SkAutoTUnref<SkPicture> fPicture; |
69 SkAutoTUnref<SkDebugCanvas> fDebugCanvas; | 71 SkAutoTUnref<SkDebugCanvas> fDebugCanvas; |
| 72 UrlDataManager fUrlDataManager; |
70 }; | 73 }; |
71 | 74 |
72 // TODO factor this out into functions, also handle CPU path | 75 // TODO factor this out into functions, also handle CPU path |
73 SkSurface* setupSurface(GrContextFactory* factory) { | 76 SkSurface* setupSurface(GrContextFactory* factory) { |
74 GrContext* context = factory->get(GrContextFactory::kNative_GLContextType, | 77 GrContext* context = factory->get(GrContextFactory::kNative_GLContextType, |
75 GrContextFactory::kNone_GLContextOptions); | 78 GrContextFactory::kNone_GLContextOptions); |
76 int maxRTSize = context->caps()->maxRenderTargetSize(); | 79 int maxRTSize = context->caps()->maxRenderTargetSize(); |
77 SkImageInfo info = SkImageInfo::Make(SkTMin(kImageWidth, maxRTSize), | 80 SkImageInfo info = SkImageInfo::Make(SkTMin(kImageWidth, maxRTSize), |
78 SkTMin(kImageHeight, maxRTSize), | 81 SkTMin(kImageHeight, maxRTSize), |
79 kN32_SkColorType, kPremul_SkAlphaType); | 82 kN32_SkColorType, kPremul_SkAlphaType); |
(...skipping 12 matching lines...) Expand all Loading... |
92 SkData* writeCanvasToPng(SkCanvas* canvas) { | 95 SkData* writeCanvasToPng(SkCanvas* canvas) { |
93 // capture pixels | 96 // capture pixels |
94 SkBitmap bmp; | 97 SkBitmap bmp; |
95 bmp.setInfo(canvas->imageInfo()); | 98 bmp.setInfo(canvas->imageInfo()); |
96 if (!canvas->readPixels(&bmp, 0, 0)) { | 99 if (!canvas->readPixels(&bmp, 0, 0)) { |
97 fprintf(stderr, "Can't read pixels\n"); | 100 fprintf(stderr, "Can't read pixels\n"); |
98 return nullptr; | 101 return nullptr; |
99 } | 102 } |
100 | 103 |
101 // write to png | 104 // write to png |
| 105 // TODO encoding to png can be quite slow, we should investigate bmp |
102 SkData* png = SkImageEncoder::EncodeData(bmp, SkImageEncoder::kPNG_Type, 100
); | 106 SkData* png = SkImageEncoder::EncodeData(bmp, SkImageEncoder::kPNG_Type, 100
); |
103 if (!png) { | 107 if (!png) { |
104 fprintf(stderr, "Can't encode to png\n"); | 108 fprintf(stderr, "Can't encode to png\n"); |
105 return nullptr; | 109 return nullptr; |
106 } | 110 } |
107 return png; | 111 return png; |
108 } | 112 } |
109 | 113 |
110 SkData* setupAndDrawToCanvasReturnPng(SkDebugCanvas* debugCanvas, int n) { | 114 SkData* setupAndDrawToCanvasReturnPng(SkDebugCanvas* debugCanvas, int n) { |
111 GrContextOptions grContextOpts; | 115 GrContextOptions grContextOpts; |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 info["ClipRect"] = SkJSONCanvas::MakeIRect(clip); | 408 info["ClipRect"] = SkJSONCanvas::MakeIRect(clip); |
405 | 409 |
406 std::string json = Json::FastWriter().write(info); | 410 std::string json = Json::FastWriter().write(info); |
407 | 411 |
408 // We don't want the null terminator so strlen is correct | 412 // We don't want the null terminator so strlen is correct |
409 SkAutoTUnref<SkData> data(SkData::NewWithCopy(json.c_str(), strlen(json.
c_str()))); | 413 SkAutoTUnref<SkData> data(SkData::NewWithCopy(json.c_str(), strlen(json.
c_str()))); |
410 return SendData(connection, data, "application/json"); | 414 return SendData(connection, data, "application/json"); |
411 } | 415 } |
412 }; | 416 }; |
413 | 417 |
| 418 class DataHandler : public UrlHandler { |
| 419 public: |
| 420 bool canHandle(const char* method, const char* url) override { |
| 421 static const char* kBaseUrl = "/data"; |
| 422 return 0 == strcmp(method, MHD_HTTP_METHOD_GET) && |
| 423 0 == strncmp(url, kBaseUrl, strlen(kBaseUrl)); |
| 424 } |
| 425 |
| 426 int handle(Request* request, MHD_Connection* connection, |
| 427 const char* url, const char* method, |
| 428 const char* upload_data, size_t* upload_data_size) override { |
| 429 SkTArray<SkString> commands; |
| 430 SkStrSplit(url, "/", &commands); |
| 431 |
| 432 if (!request->fPicture.get() || commands.count() != 2) { |
| 433 return MHD_NO; |
| 434 } |
| 435 |
| 436 SkAutoTUnref<UrlDataManager::UrlData> urlData( |
| 437 SkRef(request->fUrlDataManager.getDataFromUrl(SkString(url)))); |
| 438 |
| 439 if (urlData) { |
| 440 return SendData(connection, urlData->fData.get(), urlData->fContentT
ype.c_str()); |
| 441 } |
| 442 return MHD_NO; |
| 443 } |
| 444 }; |
414 | 445 |
415 class RootHandler : public UrlHandler { | 446 class RootHandler : public UrlHandler { |
416 public: | 447 public: |
417 bool canHandle(const char* method, const char* url) override { | 448 bool canHandle(const char* method, const char* url) override { |
418 return 0 == strcmp(method, MHD_HTTP_METHOD_GET) && | 449 return 0 == strcmp(method, MHD_HTTP_METHOD_GET) && |
419 0 == strcmp(url, "/"); | 450 0 == strcmp(url, "/"); |
420 } | 451 } |
421 | 452 |
422 int handle(Request* request, MHD_Connection* connection, | 453 int handle(Request* request, MHD_Connection* connection, |
423 const char* url, const char* method, | 454 const char* url, const char* method, |
424 const char* upload_data, size_t* upload_data_size) override { | 455 const char* upload_data, size_t* upload_data_size) override { |
425 return SendTemplate(connection); | 456 return SendTemplate(connection); |
426 } | 457 } |
427 }; | 458 }; |
428 | 459 |
429 class UrlManager { | 460 class UrlManager { |
430 public: | 461 public: |
431 UrlManager() { | 462 UrlManager() { |
432 // Register handlers | 463 // Register handlers |
433 fHandlers.push_back(new RootHandler); | 464 fHandlers.push_back(new RootHandler); |
434 fHandlers.push_back(new PostHandler); | 465 fHandlers.push_back(new PostHandler); |
435 fHandlers.push_back(new ImgHandler); | 466 fHandlers.push_back(new ImgHandler); |
436 fHandlers.push_back(new CmdHandler); | 467 fHandlers.push_back(new CmdHandler); |
437 fHandlers.push_back(new InfoHandler); | 468 fHandlers.push_back(new InfoHandler); |
438 fHandlers.push_back(new DownloadHandler); | 469 fHandlers.push_back(new DownloadHandler); |
| 470 fHandlers.push_back(new DataHandler); |
439 } | 471 } |
440 | 472 |
441 ~UrlManager() { | 473 ~UrlManager() { |
442 for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; } | 474 for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; } |
443 } | 475 } |
444 | 476 |
445 // This is clearly not efficient for a large number of urls and handlers | 477 // This is clearly not efficient for a large number of urls and handlers |
446 int invoke(Request* request, MHD_Connection* connection, const char* url, co
nst char* method, | 478 int invoke(Request* request, MHD_Connection* connection, const char* url, co
nst char* method, |
447 const char* upload_data, size_t* upload_data_size) const { | 479 const char* upload_data, size_t* upload_data_size) const { |
448 for (int i = 0; i < fHandlers.count(); i++) { | 480 for (int i = 0; i < fHandlers.count(); i++) { |
(...skipping 20 matching lines...) Expand all Loading... |
469 Request* request = reinterpret_cast<Request*>(cls); | 501 Request* request = reinterpret_cast<Request*>(cls); |
470 int result = kUrlManager.invoke(request, connection, url, method, upload_dat
a, | 502 int result = kUrlManager.invoke(request, connection, url, method, upload_dat
a, |
471 upload_data_size); | 503 upload_data_size); |
472 if (MHD_NO == result) { | 504 if (MHD_NO == result) { |
473 fprintf(stderr, "Invalid method and / or url: %s %s)\n", method, url); | 505 fprintf(stderr, "Invalid method and / or url: %s %s)\n", method, url); |
474 } | 506 } |
475 return result; | 507 return result; |
476 } | 508 } |
477 | 509 |
478 int skiaserve_main() { | 510 int skiaserve_main() { |
479 Request request; // This simple server has one request | 511 Request request(SkString("/data")); // This simple server has one request |
480 struct MHD_Daemon* daemon; | 512 struct MHD_Daemon* daemon; |
481 // TODO Add option to bind this strictly to an address, e.g. localhost, for
security. | 513 // TODO Add option to bind this strictly to an address, e.g. localhost, for
security. |
482 daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, FLAGS_port, nullptr, nu
llptr, | 514 daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, FLAGS_port, nullptr, nu
llptr, |
483 &answer_to_connection, &request, | 515 &answer_to_connection, &request, |
484 MHD_OPTION_END); | 516 MHD_OPTION_END); |
485 if (NULL == daemon) { | 517 if (NULL == daemon) { |
486 return 1; | 518 return 1; |
487 } | 519 } |
488 | 520 |
489 getchar(); | 521 getchar(); |
490 MHD_stop_daemon(daemon); | 522 MHD_stop_daemon(daemon); |
491 return 0; | 523 return 0; |
492 } | 524 } |
493 | 525 |
494 #if !defined SK_BUILD_FOR_IOS | 526 #if !defined SK_BUILD_FOR_IOS |
495 int main(int argc, char** argv) { | 527 int main(int argc, char** argv) { |
496 SkCommandLineFlags::Parse(argc, argv); | 528 SkCommandLineFlags::Parse(argc, argv); |
497 return skiaserve_main(); | 529 return skiaserve_main(); |
498 } | 530 } |
499 #endif | 531 #endif |
OLD | NEW |