diff options
author | brianosman <brianosman@google.com> | 2016-04-19 10:16:53 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-04-19 10:16:53 -0700 |
commit | 7831295c63b57efca6e4331b9d66df66985ca805 (patch) | |
tree | 8d73be4e52023b5898a3334e4e432103a4615734 | |
parent | 1bf3e71ad06a318613ccc09e1cf47d3c2465b23c (diff) |
Adding support for playback to L32/S32/F16 canvas.
Playback of my test GM works correctly on both raster and GPU, in all three modes.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1893393002
Review URL: https://codereview.chromium.org/1893393002
-rw-r--r-- | gyp/skiaserve.gyp | 1 | ||||
-rw-r--r-- | tools/skiaserve/Request.cpp | 69 | ||||
-rw-r--r-- | tools/skiaserve/Request.h | 2 | ||||
-rw-r--r-- | tools/skiaserve/skiaserve.cpp | 1 | ||||
-rw-r--r-- | tools/skiaserve/urlhandlers/ColorModeHandler.cpp | 42 | ||||
-rw-r--r-- | tools/skiaserve/urlhandlers/UrlHandler.h | 13 |
6 files changed, 111 insertions, 17 deletions
diff --git a/gyp/skiaserve.gyp b/gyp/skiaserve.gyp index 32b73f7c9c..658b4d168b 100644 --- a/gyp/skiaserve.gyp +++ b/gyp/skiaserve.gyp @@ -40,6 +40,7 @@ 'microhttpd.gyp:microhttpd', 'skia_lib.gyp:skia_lib', 'tools.gyp:crash_handler', + 'tools.gyp:picture_utils', 'tools.gyp:proc_stats', 'tools.gyp:resources', 'tools.gyp:url_data_manager', diff --git a/tools/skiaserve/Request.cpp b/tools/skiaserve/Request.cpp index 7534b1df98..58aca84b53 100644 --- a/tools/skiaserve/Request.cpp +++ b/tools/skiaserve/Request.cpp @@ -9,6 +9,7 @@ #include "SkPictureRecorder.h" #include "SkPixelSerializer.h" +#include "picture_utils.h" using namespace sk_gpu_test; @@ -19,7 +20,8 @@ static int kDefaultHeight = 1080; Request::Request(SkString rootUrl) : fUploadContext(nullptr) , fUrlDataManager(rootUrl) - , fGPUEnabled(false) { + , fGPUEnabled(false) + , fColorMode(0) { // create surface #if SK_SUPPORT_GPU GrContextOptions grContextOpts; @@ -39,10 +41,7 @@ Request::~Request() { SkBitmap* Request::getBitmapFromCanvas(SkCanvas* canvas) { SkBitmap* bmp = new SkBitmap(); - SkIRect bounds = this->getBounds(); - SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), - kRGBA_8888_SkColorType, kOpaque_SkAlphaType); - bmp->setInfo(info); + bmp->setInfo(canvas->imageInfo()); if (!canvas->readPixels(bmp, 0, 0)) { fprintf(stderr, "Can't read pixels\n"); return nullptr; @@ -55,9 +54,14 @@ SkData* Request::writeCanvasToPng(SkCanvas* canvas) { SkAutoTDelete<SkBitmap> bmp(this->getBitmapFromCanvas(canvas)); SkASSERT(bmp); + // Convert to format suitable for PNG output + sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(*bmp); + SkASSERT(encodedBitmap.get()); + // write to png SkDynamicMemoryWStream buffer; - SkDrawCommand::WritePNG((const png_bytep) bmp->getPixels(), bmp->width(), bmp->height(), + SkDrawCommand::WritePNG((const png_bytep) encodedBitmap->writable_data(), + bmp->width(), bmp->height(), buffer); return buffer.copyToData(); } @@ -138,25 +142,50 @@ SkIRect Request::getBounds() { return bounds; } +namespace { + +struct ColorAndProfile { + SkColorType fColorType; + SkColorProfileType fProfileType; + bool fGammaCorrect; +}; + +ColorAndProfile ColorModes[] = { + { kN32_SkColorType, kLinear_SkColorProfileType, false }, + { kN32_SkColorType, kSRGB_SkColorProfileType, true }, + { kRGBA_F16_SkColorType, kLinear_SkColorProfileType, true }, +}; + +} + SkSurface* Request::createCPUSurface() { SkIRect bounds = this->getBounds(); - SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), kN32_SkColorType, - kPremul_SkAlphaType); - return SkSurface::MakeRaster(info).release(); + ColorAndProfile cap = ColorModes[fColorMode]; + SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), cap.fColorType, + kPremul_SkAlphaType, cap.fProfileType); + uint32_t flags = cap.fGammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0; + SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); + return SkSurface::MakeRaster(info, &props).release(); } SkSurface* Request::createGPUSurface() { GrContext* context = this->getContext(); SkIRect bounds = this->getBounds(); - SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), - kN32_SkColorType, kPremul_SkAlphaType); - uint32_t flags = 0; + ColorAndProfile cap = ColorModes[fColorMode]; + SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), cap.fColorType, + kPremul_SkAlphaType, cap.fProfileType); + uint32_t flags = cap.fGammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0; SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); SkSurface* surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0, &props).release(); return surface; } +bool Request::setColorMode(int mode) { + fColorMode = mode; + return enableGPU(fGPUEnabled); +} + bool Request::enableGPU(bool enable) { if (enable) { SkSurface* surface = this->createGPUSurface(); @@ -167,8 +196,10 @@ bool Request::enableGPU(bool enable) { // When we switch to GPU, there seems to be some mystery draws in the canvas. So we // draw once to flush the pipe // TODO understand what is actually happening here - fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp()); - this->getCanvas()->flush(); + if (fDebugCanvas) { + fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp()); + this->getCanvas()->flush(); + } return true; } @@ -206,6 +237,7 @@ SkData* Request::getJsonOps(int n) { Json::Value root = fDebugCanvas->toJSON(fUrlDataManager, n, canvas); root["mode"] = Json::Value(fGPUEnabled ? "gpu" : "cpu"); root["drawGpuBatchBounds"] = Json::Value(fDebugCanvas->getDrawGpuBatchBounds()); + root["colorMode"] = Json::Value(fColorMode); SkDynamicMemoryWStream stream; stream.writeText(Json::FastWriter().write(root).c_str()); @@ -250,9 +282,12 @@ SkColor Request::getPixel(int x, int y) { canvas->flush(); SkAutoTDelete<SkBitmap> bitmap(this->getBitmapFromCanvas(canvas)); SkASSERT(bitmap); - bitmap->lockPixels(); - uint8_t* start = ((uint8_t*) bitmap->getPixels()) + (y * bitmap->width() + x) * 4; + + // Convert to format suitable for inspection + sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(*bitmap); + SkASSERT(encodedBitmap.get()); + + const uint8_t* start = encodedBitmap->bytes() + ((y * bitmap->width() + x) * 4); SkColor result = SkColorSetARGB(start[3], start[0], start[1], start[2]); - bitmap->unlockPixels(); return result; } diff --git a/tools/skiaserve/Request.h b/tools/skiaserve/Request.h index d19c2ba801..f3af6b72ee 100644 --- a/tools/skiaserve/Request.h +++ b/tools/skiaserve/Request.h @@ -41,6 +41,7 @@ struct Request { SkCanvas* getCanvas(); SkBitmap* getBitmapFromCanvas(SkCanvas* canvas); bool enableGPU(bool enable); + bool setColorMode(int mode); bool hasPicture() const { return SkToBool(fPicture.get()); } int getLastOp() const { return fDebugCanvas->getSize() - 1; } @@ -74,6 +75,7 @@ private: sk_gpu_test::GrContextFactory* fContextFactory; SkAutoTUnref<SkSurface> fSurface; bool fGPUEnabled; + int fColorMode; }; #endif diff --git a/tools/skiaserve/skiaserve.cpp b/tools/skiaserve/skiaserve.cpp index fd96251b86..e71be0f31e 100644 --- a/tools/skiaserve/skiaserve.cpp +++ b/tools/skiaserve/skiaserve.cpp @@ -39,6 +39,7 @@ public: fHandlers.push_back(new BreakHandler); fHandlers.push_back(new BatchesHandler); fHandlers.push_back(new BatchBoundsHandler); + fHandlers.push_back(new ColorModeHandler); } ~UrlManager() { diff --git a/tools/skiaserve/urlhandlers/ColorModeHandler.cpp b/tools/skiaserve/urlhandlers/ColorModeHandler.cpp new file mode 100644 index 0000000000..25cdf7dce9 --- /dev/null +++ b/tools/skiaserve/urlhandlers/ColorModeHandler.cpp @@ -0,0 +1,42 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "UrlHandler.h" + +#include "microhttpd.h" +#include "../Request.h" +#include "../Response.h" + +using namespace Response; + +bool ColorModeHandler::canHandle(const char* method, const char* url) { + static const char* kBasePath = "/colorMode/"; + return 0 == strcmp(method, MHD_HTTP_METHOD_POST) && + 0 == strncmp(url, kBasePath, strlen(kBasePath)); +} + +int ColorModeHandler::handle(Request* request, MHD_Connection* connection, + const char* url, const char* method, + const char* upload_data, size_t* upload_data_size) { + SkTArray<SkString> commands; + SkStrSplit(url, "/", &commands); + + if (commands.count() != 2) { + return MHD_NO; + } + + int mode; + if (1 != sscanf(commands[1].c_str(), "%d", &mode)) { + return MHD_NO; + } + + bool success = request->setColorMode(mode); + if (!success) { + return SendError(connection, "Unable to create requested surface"); + } + return SendOK(connection); +} diff --git a/tools/skiaserve/urlhandlers/UrlHandler.h b/tools/skiaserve/urlhandlers/UrlHandler.h index 02a07b0d14..adbdcb9aa2 100644 --- a/tools/skiaserve/urlhandlers/UrlHandler.h +++ b/tools/skiaserve/urlhandlers/UrlHandler.h @@ -128,3 +128,16 @@ public: const char* url, const char* method, const char* upload_data, size_t* upload_data_size) override; }; + +/** + * Controls how rendering is performed (L32, S32, F16). + * Posting to /colorMode/0 turns on L32, /colorMode/1 turns on sRGB, + * /colorMode/2 turns on FP16. + */ +class ColorModeHandler : public UrlHandler { +public: + bool canHandle(const char* method, const char* url) override; + int handle(Request* request, MHD_Connection* connection, + const char* url, const char* method, + const char* upload_data, size_t* upload_data_size) override; +}; |