aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2016-03-10 13:29:36 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-03-10 13:29:36 -0800
commitae47aeeda09408989223291c54d12b2a98fa2b12 (patch)
treef34e151d3ec1c575e5f26f8158be081cbaca88c2
parentbd73ffb83022f1f6b1997e2a91c049949e88a8a2 (diff)
Fix some bugs and performance issues with skiaserve
-rw-r--r--src/gpu/GrAuditTrail.cpp11
-rw-r--r--tools/debugger/SkDebugCanvas.cpp84
-rw-r--r--tools/debugger/SkDebugCanvas.h7
-rw-r--r--tools/skiaserve/Request.cpp86
-rw-r--r--tools/skiaserve/Request.h4
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;