diff options
author | joshualitt <joshualitt@chromium.org> | 2016-03-10 13:29:36 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-10 13:29:36 -0800 |
commit | ae47aeeda09408989223291c54d12b2a98fa2b12 (patch) | |
tree | f34e151d3ec1c575e5f26f8158be081cbaca88c2 | |
parent | bd73ffb83022f1f6b1997e2a91c049949e88a8a2 (diff) |
Fix some bugs and performance issues with skiaserve
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1777203003
Review URL: https://codereview.chromium.org/1777203003
-rw-r--r-- | src/gpu/GrAuditTrail.cpp | 11 | ||||
-rw-r--r-- | tools/debugger/SkDebugCanvas.cpp | 84 | ||||
-rw-r--r-- | tools/debugger/SkDebugCanvas.h | 7 | ||||
-rw-r--r-- | tools/skiaserve/Request.cpp | 86 | ||||
-rw-r--r-- | tools/skiaserve/Request.h | 4 |
5 files changed, 108 insertions, 84 deletions
diff --git a/src/gpu/GrAuditTrail.cpp b/src/gpu/GrAuditTrail.cpp index 21b7a29251..353d90183c 100644 --- a/src/gpu/GrAuditTrail.cpp +++ b/src/gpu/GrAuditTrail.cpp @@ -147,14 +147,13 @@ void GrAuditTrail::JsonifyTArray(SkString* json, const char* name, const T& arra json->appendf(","); } json->appendf("\"%s\": [", name); + const char* separator = ""; for (int i = 0; i < array.count(); i++) { // Handle sentinel nullptrs - if (!array[i]) { - continue; - } - json->append(array[i]->toJson()); - if (i < array.count() - 1) { - json->append(","); + if (array[i]) { + json->appendf("%s", separator); + json->append(array[i]->toJson()); + separator = ","; } } json->append("]"); diff --git a/tools/debugger/SkDebugCanvas.cpp b/tools/debugger/SkDebugCanvas.cpp index 7bb70c2940..cf2652cce4 100644 --- a/tools/debugger/SkDebugCanvas.cpp +++ b/tools/debugger/SkDebugCanvas.cpp @@ -226,16 +226,10 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index, int m) { } // If we have a GPU backend we can also visualize the batching information -#if SK_SUPPORT_GPU GrAuditTrail* at = nullptr; - GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget(); - if (rt && (fDrawGpuBatchBounds || m != -1)) { - GrContext* ctx = rt->getContext(); - if (ctx) { - at = ctx->getAuditTrail(); - } + if (fDrawGpuBatchBounds || m != -1) { + at = this->getAuditTrail(canvas); } -#endif for (int i = 0; i <= index; i++) { if (i == index && fFilter) { @@ -375,11 +369,9 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index, int m) { canvas->drawRect(batch.fBounds, paint); } } - - at->fullReset(); } - #endif + this->cleanupAuditTrail(canvas); } void SkDebugCanvas::deleteDrawCommandAt(int index) { @@ -417,32 +409,55 @@ SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() { return fCommandVector; } -Json::Value SkDebugCanvas::toJSON(UrlDataManager& urlDataManager, int n, SkCanvas* canvas) { +GrAuditTrail* SkDebugCanvas::getAuditTrail(SkCanvas* canvas) { + GrAuditTrail* at = nullptr; #if SK_SUPPORT_GPU GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget(); - GrAuditTrail* at = nullptr; if (rt) { GrContext* ctx = rt->getContext(); - if(ctx) { + if (ctx) { at = ctx->getAuditTrail(); + } + } +#endif + return at; +} - // loop over all of the commands and draw them, this is to collect reordering - // information - for (int i = 0; i < this->getSize() && i <= n; i++) { - GrAuditTrail::AutoCollectBatches enable(at, i); - fCommandVector[i]->execute(canvas); - } +void SkDebugCanvas::drawAndCollectBatches(int n, SkCanvas* canvas) { + GrAuditTrail* at = this->getAuditTrail(canvas); + if (at) { +#if SK_SUPPORT_GPU + // loop over all of the commands and draw them, this is to collect reordering + // information + for (int i = 0; i < this->getSize() && i <= n; i++) { + GrAuditTrail::AutoCollectBatches enable(at, i); + fCommandVector[i]->execute(canvas); + } - // in case there is some kind of global reordering - { - GrAuditTrail::AutoEnable ae(at); - canvas->flush(); - } + // in case there is some kind of global reordering + { + GrAuditTrail::AutoEnable ae(at); + canvas->flush(); } +#endif } +} + +void SkDebugCanvas::cleanupAuditTrail(SkCanvas* canvas) { + GrAuditTrail* at = this->getAuditTrail(canvas); + if (at) { +#if SK_SUPPORT_GPU + GrAuditTrail::AutoEnable ae(at); + at->fullReset(); #endif + } +} + +Json::Value SkDebugCanvas::toJSON(UrlDataManager& urlDataManager, int n, SkCanvas* canvas) { + this->drawAndCollectBatches(n, canvas); // now collect json + GrAuditTrail* at = this->getAuditTrail(canvas); Json::Value result = Json::Value(Json::objectValue); result[SKDEBUGCANVAS_ATTRIBUTE_VERSION] = Json::Value(SKDEBUGCANVAS_VERSION); Json::Value commands = Json::Value(Json::arrayValue); @@ -460,14 +475,25 @@ Json::Value SkDebugCanvas::toJSON(UrlDataManager& urlDataManager, int n, SkCanva } #endif } + this->cleanupAuditTrail(canvas); + result[SKDEBUGCANVAS_ATTRIBUTE_COMMANDS] = commands; + return result; +} + +Json::Value SkDebugCanvas::toJSONBatchList(int n, SkCanvas* canvas) { + this->drawAndCollectBatches(n, canvas); + + Json::Value parsedFromString; + GrAuditTrail* at = this->getAuditTrail(canvas); #if SK_SUPPORT_GPU if (at) { - GrAuditTrail::AutoEnable ae(at); - at->fullReset(); + GrAuditTrail::AutoManageBatchList enable(at); + Json::Reader reader; + SkAssertResult(reader.parse(at->toJson().c_str(), parsedFromString)); } #endif - result[SKDEBUGCANVAS_ATTRIBUTE_COMMANDS] = commands; - return result; + this->cleanupAuditTrail(canvas); + return parsedFromString; } void SkDebugCanvas::updatePaintFilterCanvas() { diff --git a/tools/debugger/SkDebugCanvas.h b/tools/debugger/SkDebugCanvas.h index 7379698f20..fa02874779 100644 --- a/tools/debugger/SkDebugCanvas.h +++ b/tools/debugger/SkDebugCanvas.h @@ -19,6 +19,7 @@ #include "SkTArray.h" #include "UrlDataManager.h" +class GrAuditTrail; class SkNWayCanvas; class SK_API SkDebugCanvas : public SkCanvas { @@ -160,6 +161,8 @@ public: */ Json::Value toJSON(UrlDataManager& urlDataManager, int n, SkCanvas*); + Json::Value toJSONBatchList(int n, SkCanvas*); + //////////////////////////////////////////////////////////////////////////////// // Inherited from SkCanvas //////////////////////////////////////////////////////////////////////////////// @@ -284,7 +287,11 @@ private: void outputPointsCommon(const SkPoint* pts, int count); void outputScalar(SkScalar num); + GrAuditTrail* getAuditTrail(SkCanvas*); + void updatePaintFilterCanvas(); + void drawAndCollectBatches(int n, SkCanvas*); + void cleanupAuditTrail(SkCanvas*); typedef SkCanvas INHERITED; }; diff --git a/tools/skiaserve/Request.cpp b/tools/skiaserve/Request.cpp index 2d956c90f7..a058075410 100644 --- a/tools/skiaserve/Request.cpp +++ b/tools/skiaserve/Request.cpp @@ -12,6 +12,9 @@ #include "SkPictureRecorder.h" #include "SkPixelSerializer.h" +static int kDefaultWidth = 1920; +static int kDefaultHeight = 1080; + 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); @@ -59,7 +62,7 @@ Request::Request(SkString rootUrl) SkBitmap* Request::getBitmapFromCanvas(SkCanvas* canvas) { SkBitmap* bmp = new SkBitmap(); - SkIRect bounds = fPicture->cullRect().roundOut(); + SkIRect bounds = this->getBounds(); SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), kRGBA_8888_SkColorType, kOpaque_SkAlphaType); bmp->setInfo(info); @@ -108,7 +111,7 @@ SkData* Request::drawToPng(int n, int m) { SkData* Request::writeOutSkp() { // Playback into picture recorder - SkIRect bounds = fPicture->cullRect().roundOut(); + SkIRect bounds = this->getBounds(); SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(bounds.width(), bounds.height()); @@ -124,17 +127,41 @@ SkData* Request::writeOutSkp() { return outStream.copyToData(); } +GrContext* Request::getContext() { + return fContextFactory->get(GrContextFactory::kNative_GLContextType, + GrContextFactory::kNone_GLContextOptions); +} + +SkIRect Request::getBounds() { + SkIRect bounds; + if (fPicture) { + bounds = fPicture->cullRect().roundOut(); + if (fGPUEnabled) { + int maxRTSize = this->getContext()->caps()->maxRenderTargetSize(); + bounds = SkIRect::MakeWH(SkTMin(bounds.width(), maxRTSize), + SkTMin(bounds.height(), maxRTSize)); + } + } else { + bounds = SkIRect::MakeWH(kDefaultWidth, kDefaultHeight); + } + + // We clip to kDefaultWidth / kDefaultHeight for performance reasons + // TODO make this configurable + bounds = SkIRect::MakeWH(SkTMin(bounds.width(), kDefaultWidth), + SkTMin(bounds.height(), kDefaultHeight)); + return bounds; +} + SkSurface* Request::createCPUSurface() { - SkIRect bounds = fPicture->cullRect().roundOut(); + SkIRect bounds = this->getBounds(); SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), kN32_SkColorType, kPremul_SkAlphaType); return SkSurface::NewRaster(info); } SkSurface* Request::createGPUSurface() { - GrContext* context = fContextFactory->get(GrContextFactory::kNative_GLContextType, - GrContextFactory::kNone_GLContextOptions); - SkIRect bounds = fPicture->cullRect().roundOut(); + GrContext* context = this->getContext(); + SkIRect bounds = this->getBounds(); SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), kN32_SkColorType, kPremul_SkAlphaType); uint32_t flags = 0; @@ -167,8 +194,11 @@ bool Request::initPictureFromStream(SkStream* stream) { return false; } + // reinitialize canvas with the new picture dimensions + this->enableGPU(fGPUEnabled); + // pour picture into debug canvas - SkIRect bounds = fPicture->cullRect().roundOut(); + SkIRect bounds = this->getBounds(); fDebugCanvas.reset(new SkDebugCanvas(bounds.width(), bounds.height())); fDebugCanvas->drawPicture(fPicture); @@ -178,28 +208,6 @@ bool Request::initPictureFromStream(SkStream* stream) { return true; } -GrAuditTrail* Request::getAuditTrail(SkCanvas* canvas) { - GrAuditTrail* at = nullptr; -#if SK_SUPPORT_GPU - GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget(); - if (rt) { - GrContext* ctx = rt->getContext(); - if (ctx) { - at = ctx->getAuditTrail(); - } - } -#endif - return at; -} - -void Request::cleanupAuditTrail(SkCanvas* canvas) { - GrAuditTrail* at = this->getAuditTrail(canvas); - if (at) { - GrAuditTrail::AutoEnable ae(at); - at->fullReset(); - } -} - SkData* Request::getJsonOps(int n) { SkCanvas* canvas = this->getCanvas(); Json::Value root = fDebugCanvas->toJSON(fUrlDataManager, n, canvas); @@ -208,8 +216,6 @@ SkData* Request::getJsonOps(int n) { SkDynamicMemoryWStream stream; stream.writeText(Json::FastWriter().write(root).c_str()); - this->cleanupAuditTrail(canvas); - return stream.copyToData(); } @@ -217,24 +223,10 @@ SkData* Request::getJsonBatchList(int n) { SkCanvas* canvas = this->getCanvas(); SkASSERT(fGPUEnabled); - // TODO if this is inefficient we could add a method to GrAuditTrail which takes - // a Json::Value and is only compiled in this file - Json::Value parsedFromString; -#if SK_SUPPORT_GPU - // we use the toJSON method on debug canvas, but then just ignore the results and pull - // the information we care about from the audit trail - fDebugCanvas->toJSON(fUrlDataManager, n, canvas); - - GrAuditTrail* at = this->getAuditTrail(canvas); - GrAuditTrail::AutoManageBatchList enable(at); - Json::Reader reader; - SkDEBUGCODE(bool parsingSuccessful = )reader.parse(at->toJson().c_str(), - parsedFromString); - SkASSERT(parsingSuccessful); -#endif + Json::Value result = fDebugCanvas->toJSONBatchList(n, canvas); SkDynamicMemoryWStream stream; - stream.writeText(Json::FastWriter().write(parsedFromString).c_str()); + stream.writeText(Json::FastWriter().write(result).c_str()); return stream.copyToData(); } diff --git a/tools/skiaserve/Request.h b/tools/skiaserve/Request.h index 0a2b17a401..95e7f1568c 100644 --- a/tools/skiaserve/Request.h +++ b/tools/skiaserve/Request.h @@ -61,8 +61,8 @@ private: void drawToCanvas(int n, int m = -1); SkSurface* createCPUSurface(); SkSurface* createGPUSurface(); - GrAuditTrail* getAuditTrail(SkCanvas*); - void cleanupAuditTrail(SkCanvas*); + SkIRect getBounds(); + GrContext* getContext(); SkAutoTUnref<SkPicture> fPicture; SkAutoTDelete<GrContextFactory> fContextFactory; |