aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/skiaserve
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2016-01-27 11:07:23 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-01-27 11:07:23 -0800
commit609d97918788c077514f190b0f1087ccbd420f5d (patch)
treec611b6d47aeee78893f775765b94aa18e19d58fd /tools/skiaserve
parent440c5a98dee428c661b77d149e30c794d264b8cd (diff)
Wire up JsonCanvas in skiaserve
Diffstat (limited to 'tools/skiaserve')
-rw-r--r--tools/skiaserve/skiaserve.cpp146
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