diff options
author | joshualitt <joshualitt@chromium.org> | 2016-01-27 11:07:23 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-27 11:07:23 -0800 |
commit | 609d97918788c077514f190b0f1087ccbd420f5d (patch) | |
tree | c611b6d47aeee78893f775765b94aa18e19d58fd /tools/skiaserve | |
parent | 440c5a98dee428c661b77d149e30c794d264b8cd (diff) |
Wire up JsonCanvas in skiaserve
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1640333002
Review URL: https://codereview.chromium.org/1640333002
Diffstat (limited to 'tools/skiaserve')
-rw-r--r-- | tools/skiaserve/skiaserve.cpp | 146 |
1 files changed, 87 insertions, 59 deletions
diff --git a/tools/skiaserve/skiaserve.cpp b/tools/skiaserve/skiaserve.cpp index aa6d803264..fa98d79287 100644 --- a/tools/skiaserve/skiaserve.cpp +++ b/tools/skiaserve/skiaserve.cpp @@ -9,6 +9,7 @@ #include "GrContextFactory.h" #include "SkCanvas.h" #include "SkCommandLineFlags.h" +#include "SkJSONCanvas.h" #include "SkPicture.h" #include "SkStream.h" #include "SkSurface.h" @@ -32,8 +33,44 @@ DEFINE_bool(useTemplate, true, "whether or not to use the skdebugger template st static const int kImageWidth = 1920; static const int kImageHeight = 1080; +// TODO move to template file +SkString generateTemplate(SkString source) { + SkString debuggerTemplate; + debuggerTemplate.appendf( + "<!DOCTYPE html>\n" + "<html>\n" + "<head>\n" + " <title>SkDebugger</title>\n" + " <meta charset=\"utf-8\" />\n" + " <meta http-equiv=\"X-UA-Compatible\" content=\"IE=egde,chrome=1\">\n" + " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" + " <script src=\"%s/res/js/core.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n" + " <link href=\"%s/res/vul/elements.html\" rel=\"import\" />\n" + "</head>\n" + "<body class=\"fullbleed layout vertical\">\n" + " <debugger-app-sk>This is the app." + " </debugger-app-sk>\n" + "</body>\n" + "</html>", source.c_str(), source.c_str()); + return debuggerTemplate; + +} + +struct UploadContext { + SkDynamicMemoryWStream fStream; + MHD_PostProcessor* fPostProcessor; + MHD_Connection* connection; +}; + +struct Request { + Request() : fUploadContext(nullptr) {} + UploadContext* fUploadContext; + SkAutoTUnref<SkData> fPNG; + SkAutoTUnref<SkPicture> fPicture; +}; + // TODO factor this out into functions, also handle CPU path -SkData* setupAndDrawToCanvas(SkStream* stream, SkString* error) { +bool setupAndDrawToCanvas(Request* request, SkString* error) { GrContextOptions grContextOpts; SkAutoTDelete<GrContextFactory> factory(new GrContextFactory(grContextOpts)); @@ -55,65 +92,32 @@ SkData* setupAndDrawToCanvas(SkStream* stream, SkString* error) { gl->makeCurrent(); // draw - SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream)); - if (pic.get() == nullptr) { + request->fPicture.reset( + SkPicture::CreateFromStream(request->fUploadContext->fStream.detachAsStream())); + if (!request->fPicture.get()) { error->appendf("Could not create picture from stream.\n"); - return nullptr; + return false; } SkCanvas* canvas = surface->getCanvas(); - canvas->drawPicture(pic); + canvas->drawPicture(request->fPicture); // capture pixels SkBitmap bmp; bmp.setInfo(canvas->imageInfo()); if (!canvas->readPixels(&bmp, 0, 0)) { error->appendf("Can't read canvas pixels.\n"); - return nullptr; + return false; } // write to png - SkData* data = SkImageEncoder::EncodeData(bmp, SkImageEncoder::kPNG_Type, 100); - if (!data) { + request->fPNG.reset(SkImageEncoder::EncodeData(bmp, SkImageEncoder::kPNG_Type, 100)); + if (!request->fPNG) { error->appendf("Can't encode a PNG.\n"); - return nullptr; + return false; } - return data; + return true; } -// TODO move to template file -SkString generateTemplate(SkString source) { - SkString debuggerTemplate; - debuggerTemplate.appendf( - "<!DOCTYPE html>\n" - "<html>\n" - "<head>\n" - " <title>SkDebugger</title>\n" - " <meta charset=\"utf-8\" />\n" - " <meta http-equiv=\"X-UA-Compatible\" content=\"IE=egde,chrome=1\">\n" - " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" - " <script src=\"%s/res/js/core.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n" - " <link href=\"%s/res/vul/elements.html\" rel=\"import\" />\n" - "</head>\n" - "<body class=\"fullbleed layout vertical\">\n" - " <debugger-app-sk>This is the app." - " </debugger-app-sk>\n" - "</body>\n" - "</html>", source.c_str(), source.c_str()); - return debuggerTemplate; - -} - -struct UploadContext { - SkDynamicMemoryWStream stream; - MHD_PostProcessor* pp; - MHD_Connection* connection; -}; - -struct Request { - Request() : fUploadContext(nullptr) {} - UploadContext* fUploadContext; - SkAutoTUnref<SkData> fPNG; -}; static const size_t kBufferSize = 1024; @@ -124,23 +128,34 @@ static int process_upload_data(void* cls, enum MHD_ValueKind kind, struct UploadContext* uc = reinterpret_cast<UploadContext*>(cls); if (0 != size) { - uc->stream.write(data, size); + uc->fStream.write(data, size); } return MHD_YES; } -static int SendImage(MHD_Connection* connection, const SkData* data) { +static int SendData(MHD_Connection* connection, const SkData* data, const char* type) { MHD_Response* response = MHD_create_response_from_buffer(data->size(), const_cast<void*>(data->data()), MHD_RESPMEM_MUST_COPY); - MHD_add_response_header(response, "Content-Type", "image/png"); + MHD_add_response_header(response, "Content-Type", type); int ret = MHD_queue_response(connection, MHD_HTTP_OK, response); MHD_destroy_response(response); return ret; } -static int SendTemplate(MHD_Connection* connection) { +static int SendJSON(MHD_Connection* connection, SkPicture* picture) { + SkDynamicMemoryWStream stream; + SkAutoTUnref<SkJSONCanvas> jsonCanvas(new SkJSONCanvas(kImageWidth, kImageHeight, stream)); + jsonCanvas->drawPicture(picture); + jsonCanvas->finish(); + + SkAutoTUnref<SkData> data(stream.copyToData()); + return SendData(connection, data, "application/json"); +} + +static int SendTemplate(MHD_Connection* connection, bool redirect = false, + const char* redirectUrl = nullptr) { SkString debuggerTemplate = generateTemplate(SkString("http://debugger.skia.org")); MHD_Response* response = MHD_create_response_from_buffer( @@ -148,6 +163,11 @@ static int SendTemplate(MHD_Connection* connection) { (void*) const_cast<char*>(debuggerTemplate.c_str()), MHD_RESPMEM_MUST_COPY); + if (redirect) { + MHD_add_response_header (response, "Location", redirectUrl); + } + + int ret = MHD_queue_response(connection, MHD_HTTP_OK, response); MHD_destroy_response(response); return ret; @@ -170,8 +190,9 @@ int postHandler(Request* request, MHD_Connection* connection, // TODO make this a method on request uc = new UploadContext; uc->connection = connection; - uc->pp = MHD_create_post_processor(connection, kBufferSize, &process_upload_data, uc); - SkASSERT(uc->pp); + uc->fPostProcessor = MHD_create_post_processor(connection, kBufferSize, + &process_upload_data, uc); + SkASSERT(uc->fPostProcessor); request->fUploadContext = uc; return MHD_YES; @@ -179,33 +200,39 @@ int postHandler(Request* request, MHD_Connection* connection, // in process upload if (0 != *upload_data_size) { - SkASSERT(uc->pp); - MHD_post_process(uc->pp, upload_data, *upload_data_size); + SkASSERT(uc->fPostProcessor); + MHD_post_process(uc->fPostProcessor, upload_data, *upload_data_size); *upload_data_size = 0; return MHD_YES; } // end of upload - MHD_destroy_post_processor(uc->pp); - uc->pp = nullptr; + MHD_destroy_post_processor(uc->fPostProcessor); + uc->fPostProcessor = nullptr; // TODO response SkString error; - SkData* data = setupAndDrawToCanvas(uc->stream.detachAsStream(), &error); - if (!data) { + if (!setupAndDrawToCanvas(request, &error)) { // TODO send error return MHD_YES; } - request->fPNG.reset(data); - return SendTemplate(connection); + return SendTemplate(connection, true, "/"); } int imgHandler(Request* request, MHD_Connection* connection, const char* upload_data, size_t* upload_data_size) { if (request->fPNG.get()) { SkData* data = request->fPNG.get(); - return SendImage(connection, data); + return SendData(connection, data, "image/png"); + } + return MHD_NO; +} + +int infoHandler(Request* request, MHD_Connection* connection, + const char* upload_data, size_t* upload_data_size) { + if (request->fPicture.get()) { + return SendJSON(connection, request->fPicture); } return MHD_NO; } @@ -217,6 +244,7 @@ public: fHandlers.push_back({MHD_HTTP_METHOD_GET, "/", rootHandler}); fHandlers.push_back({MHD_HTTP_METHOD_POST, "/new", postHandler}); fHandlers.push_back({MHD_HTTP_METHOD_GET, "/img", imgHandler}); + //fHandlers.push_back({MHD_HTTP_METHOD_GET, "/cmd", infoHandler}); } // This is clearly not efficient for a large number of urls and handlers |