aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/skiaserve
diff options
context:
space:
mode:
authorGravatar ethannicholas <ethannicholas@google.com>2016-02-19 08:40:59 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-02-19 08:40:59 -0800
commit85fca851e621d18db9b0cb5dc47878a77310ef15 (patch)
tree04af5bb41c258f39a6c23bbc599ee2c79f08698f /tools/skiaserve
parentdf7bb471e5455dece2784a970d9ae50d3ab0ca75 (diff)
added /enableGPU command to skiaserve
Diffstat (limited to 'tools/skiaserve')
-rw-r--r--tools/skiaserve/skiaserve.cpp94
1 files changed, 70 insertions, 24 deletions
diff --git a/tools/skiaserve/skiaserve.cpp b/tools/skiaserve/skiaserve.cpp
index 85f3e1e693..18a522a4c1 100644
--- a/tools/skiaserve/skiaserve.cpp
+++ b/tools/skiaserve/skiaserve.cpp
@@ -76,23 +76,6 @@ struct Request {
UrlDataManager fUrlDataManager;
};
-// TODO factor this out into functions, also handle CPU path
-SkSurface* setupSurface(GrContextFactory* factory) {
- GrContext* context = factory->get(GrContextFactory::kNative_GLContextType,
- GrContextFactory::kNone_GLContextOptions);
- int maxRTSize = context->caps()->maxRenderTargetSize();
- SkImageInfo info = SkImageInfo::Make(SkTMin(kImageWidth, maxRTSize),
- SkTMin(kImageHeight, maxRTSize),
- kN32_SkColorType, kPremul_SkAlphaType);
- uint32_t flags = 0;
- SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
- SkSurface* surface = SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0,
- &props);
- SkASSERT(surface);
-
- return surface;
-}
-
static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr);
out->write(data, length);
@@ -172,12 +155,26 @@ SkData* drawToPng(Request* request, int n) {
return writeCanvasToPng(getCanvasFromRequest(request));
}
-SkSurface* setupCpuSurface() {
+SkSurface* createCPUSurface() {
SkImageInfo info = SkImageInfo::Make(kImageWidth, kImageHeight, kN32_SkColorType,
kPremul_SkAlphaType);
return SkSurface::NewRaster(info);
}
+SkSurface* createGPUSurface(Request* request) {
+ GrContext* context = request->fContextFactory->get(GrContextFactory::kNative_GLContextType,
+ GrContextFactory::kNone_GLContextOptions);
+ int maxRTSize = context->caps()->maxRenderTargetSize();
+ SkImageInfo info = SkImageInfo::Make(SkTMin(kImageWidth, maxRTSize),
+ SkTMin(kImageHeight, maxRTSize),
+ kN32_SkColorType, kPremul_SkAlphaType);
+ uint32_t flags = 0;
+ SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
+ SkSurface* surface = SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0,
+ &props);
+ return surface;
+}
+
static const size_t kBufferSize = 1024;
static int process_upload_data(void* cls, enum MHD_ValueKind kind,
@@ -204,6 +201,15 @@ static int SendOK(MHD_Connection* connection) {
return ret;
}
+static int SendError(MHD_Connection* connection, const char* msg) {
+ MHD_Response* response = MHD_create_response_from_buffer(strlen(msg),
+ (void*) msg,
+ MHD_RESPMEM_PERSISTENT);
+ int ret = MHD_queue_response(connection, 500, response);
+ MHD_destroy_response(response);
+ return ret;
+}
+
static int SendData(MHD_Connection* connection, const SkData* data, const char* type,
bool setContentDisposition = false, const char* dispositionString = nullptr) {
MHD_Response* response = MHD_create_response_from_buffer(data->size(),
@@ -458,6 +464,44 @@ public:
}
};
+/**
+ Controls whether GPU rendering is enabled. Posting to /enableGPU/1 turns GPU on, /enableGPU/0
+ disables it.
+ */
+class EnableGPUHandler : public UrlHandler {
+public:
+ bool canHandle(const char* method, const char* url) override {
+ static const char* kBasePath = "/enableGPU/";
+ return 0 == strcmp(method, MHD_HTTP_METHOD_POST) &&
+ 0 == strncmp(url, kBasePath, strlen(kBasePath));
+ }
+
+ int handle(Request* request, MHD_Connection* connection,
+ const char* url, const char* method,
+ const char* upload_data, size_t* upload_data_size) override {
+ SkTArray<SkString> commands;
+ SkStrSplit(url, "/", &commands);
+
+ if (commands.count() != 2) {
+ return MHD_NO;
+ }
+
+ int enable;
+ sscanf(commands[1].c_str(), "%d", &enable);
+
+ if (enable) {
+ SkSurface* surface = createGPUSurface(request);
+ if (surface) {
+ request->fSurface.reset(surface);
+ return SendOK(connection);
+ }
+ return SendError(connection, "Unable to create GPU surface");
+ }
+ request->fSurface.reset(createCPUSurface());
+ return SendOK(connection);
+ }
+};
+
class PostHandler : public UrlHandler {
public:
bool canHandle(const char* method, const char* url) override {
@@ -503,11 +547,6 @@ public:
return MHD_NO;
}
- // create surface
- GrContextOptions grContextOpts;
- request->fContextFactory.reset(new GrContextFactory(grContextOpts));
- request->fSurface.reset(setupSurface(request->fContextFactory.get()));
-
// pour picture into debug canvas
request->fDebugCanvas.reset(new SkDebugCanvas(kImageWidth, kImageHeight));
request->fDebugCanvas->drawPicture(request->fPicture);
@@ -575,7 +614,7 @@ public:
}
// drawTo
- SkAutoTUnref<SkSurface> surface(setupCpuSurface());
+ SkAutoTUnref<SkSurface> surface(createCPUSurface());
SkCanvas* canvas = surface->getCanvas();
int n;
@@ -676,6 +715,7 @@ public:
fHandlers.push_back(new PostHandler);
fHandlers.push_back(new ImgHandler);
fHandlers.push_back(new ClipAlphaHandler);
+ fHandlers.push_back(new EnableGPUHandler);
fHandlers.push_back(new CmdHandler);
fHandlers.push_back(new InfoHandler);
fHandlers.push_back(new DownloadHandler);
@@ -723,6 +763,12 @@ int answer_to_connection(void* cls, struct MHD_Connection* connection,
int skiaserve_main() {
Request request(SkString("/data")); // This simple server has one request
+
+ // create surface
+ GrContextOptions grContextOpts;
+ request.fContextFactory.reset(new GrContextFactory(grContextOpts));
+ request.fSurface.reset(createCPUSurface());
+
struct MHD_Daemon* daemon;
// TODO Add option to bind this strictly to an address, e.g. localhost, for security.
daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, FLAGS_port, nullptr, nullptr,