aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-11-06 21:26:13 +0000
committerGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-11-06 21:26:13 +0000
commita36223764466c964ed1035bf6f152ba55168f61e (patch)
treebe58da51627b604ee271cb4beacd1d9d6606a840 /tools
parent9daf96afb34313842d8d2c4abca73d954d2e9005 (diff)
add draw filter option to picture_bench
Option allows adding a draw filter option per type or for all types. All SkPaint flags may be filtered, plus disabling blur and setting the hint level. Review URL: https://codereview.appspot.com/6816092 git-svn-id: http://skia.googlecode.com/svn/trunk@6318 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'tools')
-rw-r--r--tools/PictureRenderer.cpp42
-rw-r--r--tools/PictureRenderer.h26
-rw-r--r--tools/bench_pictures_main.cpp160
3 files changed, 219 insertions, 9 deletions
diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp
index cb68f396a3..59ba680842 100644
--- a/tools/PictureRenderer.cpp
+++ b/tools/PictureRenderer.cpp
@@ -16,6 +16,7 @@
#endif
#include "SkGraphics.h"
#include "SkImageEncoder.h"
+#include "SkMaskFilter.h"
#include "SkMatrix.h"
#include "SkPicture.h"
#include "SkRTree.h"
@@ -51,25 +52,58 @@ void PictureRenderer::init(SkPicture* pict) {
fCanvas.reset(this->setupCanvas());
}
+class FlagsDrawFilter : public SkDrawFilter {
+public:
+ FlagsDrawFilter(PictureRenderer::DrawFilterFlags* flags) :
+ fFlags(flags) {}
+
+ virtual void filter(SkPaint* paint, Type t) {
+ paint->setFlags(paint->getFlags() & ~fFlags[t] & SkPaint::kAllFlags);
+ if (PictureRenderer::kBlur_DrawFilterFlag & fFlags[t]) {
+ SkMaskFilter* maskFilter = paint->getMaskFilter();
+ SkMaskFilter::BlurInfo blurInfo;
+ if (maskFilter && maskFilter->asABlur(&blurInfo)) {
+ paint->setMaskFilter(NULL);
+ }
+ }
+ if (PictureRenderer::kHinting_DrawFilterFlag & fFlags[t]) {
+ paint->setHinting(SkPaint::kNo_Hinting);
+ } else if (PictureRenderer::kSlightHinting_DrawFilterFlag & fFlags[t]) {
+ paint->setHinting(SkPaint::kSlight_Hinting);
+ }
+ }
+
+private:
+ PictureRenderer::DrawFilterFlags* fFlags;
+};
+
+static SkCanvas* setUpFilter(SkCanvas* canvas, PictureRenderer::DrawFilterFlags* drawFilters) {
+ if (drawFilters && !canvas->getDrawFilter()) {
+ canvas->setDrawFilter(SkNEW_ARGS(FlagsDrawFilter, (drawFilters)))->unref();
+ }
+ return canvas;
+}
+
SkCanvas* PictureRenderer::setupCanvas() {
return this->setupCanvas(fPicture->width(), fPicture->height());
}
SkCanvas* PictureRenderer::setupCanvas(int width, int height) {
+ SkCanvas* canvas;
switch(fDeviceType) {
case kBitmap_DeviceType: {
SkBitmap bitmap;
sk_tools::setup_bitmap(&bitmap, width, height);
- return SkNEW_ARGS(SkCanvas, (bitmap));
- break;
+ canvas = SkNEW_ARGS(SkCanvas, (bitmap));
+ return setUpFilter(canvas, fDrawFilters);
}
#if SK_SUPPORT_GPU
case kGPU_DeviceType: {
SkAutoTUnref<SkGpuDevice> device(SkNEW_ARGS(SkGpuDevice,
(fGrContext, SkBitmap::kARGB_8888_Config,
width, height)));
- return SkNEW_ARGS(SkCanvas, (device.get()));
- break;
+ canvas = SkNEW_ARGS(SkCanvas, (device.get()));
+ return setUpFilter(canvas, fDrawFilters);
}
#endif
default:
diff --git a/tools/PictureRenderer.h b/tools/PictureRenderer.h
index ec18428252..53aa114325 100644
--- a/tools/PictureRenderer.h
+++ b/tools/PictureRenderer.h
@@ -1,4 +1,4 @@
-/*
+*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
@@ -9,6 +9,7 @@
#define PictureRenderer_DEFINED
#include "SkCountdown.h"
+#include "SkDrawFilter.h"
#include "SkMath.h"
#include "SkPicture.h"
#include "SkRect.h"
@@ -46,6 +47,20 @@ public:
kTileGrid_BBoxHierarchyType,
};
+ // this uses SkPaint::Flags as a base and adds additional flags
+ enum DrawFilterFlags {
+ kNone_DrawFilterFlag = 0,
+ kBlur_DrawFilterFlag = 0x4000,
+ kHinting_DrawFilterFlag = 0x8000, // toggles between no hinting and normal hinting
+ kSlightHinting_DrawFilterFlag = 0x10000, // toggles between slight and normal hinting
+ };
+
+ SK_COMPILE_ASSERT(!(kBlur_DrawFilterFlag & SkPaint::kAllFlags), blur_flag_must_be_greater);
+ SK_COMPILE_ASSERT(!(kHinting_DrawFilterFlag & SkPaint::kAllFlags),
+ hinting_flag_must_be_greater);
+ SK_COMPILE_ASSERT(!(kSlightHinting_DrawFilterFlag & SkPaint::kAllFlags),
+ slight_hinting_flag_must_be_greater);
+
/**
* Called with each new SkPicture to render.
*/
@@ -80,6 +95,11 @@ public:
fDeviceType = deviceType;
}
+ void setDrawFilters(DrawFilterFlags* filters, const SkString& configName) {
+ fDrawFilters = filters;
+ fDrawFiltersConfig = configName;
+ }
+
void setBBoxHierarchyType(BBoxHierarchyType bbhType) {
fBBoxHierarchyType = bbhType;
}
@@ -112,6 +132,7 @@ public:
config.append("_gpu");
}
#endif
+ config.append(fDrawFiltersConfig.c_str());
return config;
}
@@ -137,6 +158,7 @@ public:
: fPicture(NULL)
, fDeviceType(kBitmap_DeviceType)
, fBBoxHierarchyType(kNone_BBoxHierarchyType)
+ , fDrawFilters(NULL)
, fGridWidth(0)
, fGridHeight(0)
#if SK_SUPPORT_GPU
@@ -155,6 +177,8 @@ protected:
SkPicture* fPicture;
SkDeviceTypes fDeviceType;
BBoxHierarchyType fBBoxHierarchyType;
+ DrawFilterFlags* fDrawFilters;
+ SkString fDrawFiltersConfig;
int fGridWidth, fGridHeight; // used when fBBoxHierarchyType is TileGrid
#if SK_SUPPORT_GPU
diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp
index f0f908dfd0..569a0a5006 100644
--- a/tools/bench_pictures_main.cpp
+++ b/tools/bench_pictures_main.cpp
@@ -20,6 +20,97 @@
const int DEFAULT_REPEATS = 1;
+static char const * const gFilterTypes[] = {
+ "paint",
+ "point",
+ "line",
+ "bitmap",
+ "rect",
+ "path",
+ "text",
+ "all",
+};
+
+static const size_t kFilterTypesCount = sizeof(gFilterTypes) / sizeof(gFilterTypes[0]);
+
+static char const * const gFilterFlags[] = {
+ "antiAlias",
+ "filterBitmap",
+ "dither",
+ "underlineText",
+ "strikeThruText",
+ "fakeBoldText",
+ "linearText",
+ "subpixelText",
+ "devKernText",
+ "LCDRenderText",
+ "embeddedBitmapText",
+ "autoHinting",
+ "verticalText",
+ "genA8FromLCD",
+ "blur",
+ "hinting",
+ "slightHinting",
+};
+
+static const size_t kFilterFlagsCount = sizeof(gFilterFlags) / sizeof(gFilterFlags[0]);
+
+static SkString filtersName(sk_tools::PictureRenderer::DrawFilterFlags* drawFilters) {
+ int all = drawFilters[0];
+ size_t tIndex;
+ for (tIndex = 1; tIndex < SkDrawFilter::kTypeCount; ++tIndex) {
+ all &= drawFilters[tIndex];
+ }
+ SkString result;
+ for (size_t fIndex = 0; fIndex < kFilterFlagsCount; ++fIndex) {
+ SkString types;
+ if (all & (1 << fIndex)) {
+ types = gFilterTypes[SkDrawFilter::kTypeCount];
+ } else {
+ for (tIndex = 0; tIndex < SkDrawFilter::kTypeCount; ++tIndex) {
+ if (drawFilters[tIndex] & (1 << fIndex)) {
+ types += gFilterTypes[tIndex];
+ }
+ }
+ }
+ if (!types.size()) {
+ continue;
+ }
+ result += "_";
+ result += types;
+ result += ".";
+ result += gFilterFlags[fIndex];
+ }
+ return result;
+}
+
+static SkString filterTypesUsage() {
+ SkString result;
+ for (size_t index = 0; index < kFilterTypesCount; ++index) {
+ result += gFilterTypes[index];
+ if (index < kFilterTypesCount - 1) {
+ result += " | ";
+ }
+ }
+ return result;
+}
+
+static SkString filterFlagsUsage() {
+ SkString result;
+ size_t len = 0;
+ for (size_t index = 0; index < kFilterFlagsCount; ++index) {
+ result += gFilterFlags[index];
+ if (result.size() - len >= 72) {
+ result += "\n ";
+ len = result.size();
+ }
+ if (index < kFilterFlagsCount - 1) {
+ result += " | ";
+ }
+ }
+ return result;
+}
+
static void usage(const char* argv0) {
SkDebugf("SkPicture benchmarking tool\n");
SkDebugf("\n"
@@ -36,9 +127,10 @@ static void usage(const char* argv0) {
#if SK_SUPPORT_GPU
" | gpu"
#endif
-"]"
-, argv0);
- SkDebugf("\n\n");
+"]\n"
+" [--filter [%s]:\n [%s]]\n"
+, argv0, filterTypesUsage().c_str(), filterFlagsUsage().c_str());
+ SkDebugf("\n");
SkDebugf(
" inputDir: A list of directories and files to use as input. Files are\n"
" expected to have the .skp extension.\n\n"
@@ -49,7 +141,7 @@ static void usage(const char* argv0) {
SkDebugf(" --timers [wcgWC]* : "
"Display wall, cpu, gpu, truncated wall or truncated cpu time for each picture.\n");
SkDebugf(
-" --mode pow2tile minWidht height[] | record | simple\n"
+" --mode pow2tile minWidth height[] | record | simple\n"
" | tile width[] height[] | playbackCreation:\n"
" Run in the corresponding mode.\n"
" Default is simple.\n");
@@ -101,6 +193,11 @@ static void usage(const char* argv0) {
" --repeat: "
"Set the number of times to repeat each test."
" Default is %i.\n", DEFAULT_REPEATS);
+ SkDebugf(
+" --filter type:flag : ");
+ SkDebugf(
+"Enable canvas filtering to disable a paint flag,\n"
+" disable blur, or use less hinting.\n");
}
SkBenchLogger gLogger;
@@ -175,6 +272,8 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>*
bool gridSupported = false;
sk_tools::PictureRenderer::BBoxHierarchyType bbhType =
sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
+ sk_tools::PictureRenderer::DrawFilterFlags drawFilters[SkDrawFilter::kTypeCount];
+ sk_bzero(drawFilters, sizeof(drawFilters));
for (++argv; argv < stop; ++argv) {
if (0 == strcmp(*argv, "--repeat")) {
++argv;
@@ -368,6 +467,58 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>*
gLogger.logError("Missing arg for --logPerIter\n");
PRINT_USAGE_AND_EXIT;
}
+ } else if (0 == strcmp(*argv, "--filter")) {
+ ++argv;
+ if (argv < stop) {
+ const char* colon = strchr(*argv, ':');
+ if (colon) {
+ int type = -1;
+ size_t typeLen = colon - *argv;
+ for (size_t tIndex = 0; tIndex < kFilterTypesCount; ++tIndex) {
+ if (typeLen == strlen(gFilterTypes[tIndex])
+ && !strncmp(*argv, gFilterTypes[tIndex], typeLen)) {
+ type = tIndex;
+ break;
+ }
+ }
+ if (type < 0) {
+ SkString err;
+ err.printf("Unknown type for --filter %s\n", *argv);
+ gLogger.logError(err);
+ PRINT_USAGE_AND_EXIT;
+ }
+ int flag = -1;
+ size_t flagLen = strlen(*argv) - typeLen - 1;
+ for (size_t fIndex = 0; fIndex < kFilterFlagsCount; ++fIndex) {
+ if (flagLen == strlen(gFilterFlags[fIndex])
+ && !strncmp(colon + 1, gFilterFlags[fIndex], flagLen)) {
+ flag = 1 << fIndex;
+ break;
+ }
+ }
+ if (flag < 0) {
+ SkString err;
+ err.printf("Unknown flag for --filter %s\n", *argv);
+ gLogger.logError(err);
+ PRINT_USAGE_AND_EXIT;
+ }
+ for (int index = 0; index < SkDrawFilter::kTypeCount; ++index) {
+ if (type != SkDrawFilter::kTypeCount && index != type) {
+ continue;
+ }
+ drawFilters[index] = (sk_tools::PictureRenderer::DrawFilterFlags)
+ (drawFilters[index] | flag);
+ }
+ } else {
+ SkString err;
+ err.printf("Unknown arg for --filter %s : missing colon\n", *argv);
+ gLogger.logError(err);
+ PRINT_USAGE_AND_EXIT;
+ }
+ } else {
+ gLogger.logError("Missing arg for --filter\n");
+ PRINT_USAGE_AND_EXIT;
+ }
} else if (0 == strcmp(*argv, "--help") || 0 == strcmp(*argv, "-h")) {
PRINT_USAGE_AND_EXIT;
} else {
@@ -471,6 +622,7 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>*
}
renderer->setBBoxHierarchyType(bbhType);
+ renderer->setDrawFilters(drawFilters, filtersName(drawFilters));
renderer->setGridSize(gridWidth, gridHeight);
benchmark->setRenderer(renderer);
benchmark->setRepeats(repeats);