| Index: bench/benchmain.cpp
|
| diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp
|
| index 472d4b95dc48724d458071ea3fc8da6f9f89c931..289d5cb0a24a03e4264b215244865b44dc920385 100644
|
| --- a/bench/benchmain.cpp
|
| +++ b/bench/benchmain.cpp
|
| @@ -6,47 +6,37 @@
|
| * found in the LICENSE file.
|
| */
|
|
|
| -
|
| -#include "BenchTimer.h"
|
| -
|
| #if SK_SUPPORT_GPU
|
| #include "GrContext.h"
|
| #include "GrContextFactory.h"
|
| -#include "gl/GrGLDefines.h"
|
| #include "GrRenderTarget.h"
|
| #include "SkGpuDevice.h"
|
| +#include "gl/GrGLDefines.h"
|
| #else
|
| class GrContext;
|
| #endif // SK_SUPPORT_GPU
|
|
|
| +#include "BenchTimer.h"
|
| #include "SkBenchLogger.h"
|
| #include "SkBenchmark.h"
|
| #include "SkBitmapDevice.h"
|
| #include "SkCanvas.h"
|
| #include "SkCommandLineFlags.h"
|
| #include "SkDeferredCanvas.h"
|
| -#include "SkColorPriv.h"
|
| #include "SkGraphics.h"
|
| #include "SkImageEncoder.h"
|
| -#include "SkNWayCanvas.h"
|
| +#include "SkOSFile.h"
|
| #include "SkPicture.h"
|
| #include "SkString.h"
|
| -#include "SkTArray.h"
|
| -#include "TimerData.h"
|
| -
|
| -enum benchModes {
|
| - kNormal_benchModes,
|
| - kDeferred_benchModes,
|
| - kDeferredSilent_benchModes,
|
| - kRecord_benchModes,
|
| - kPictureRecord_benchModes
|
| -};
|
|
|
| -#ifdef SK_DEBUG
|
| -static const bool kDebugOnly = true;
|
| -#else
|
| -static const bool kDebugOnly = false;
|
| -#endif
|
| +enum BenchMode {
|
| + kNormal_BenchMode,
|
| + kDeferred_BenchMode,
|
| + kDeferredSilent_BenchMode,
|
| + kRecord_BenchMode,
|
| + kPictureRecord_BenchMode
|
| +};
|
| +const char* BenchMode_Name[] = { "normal", "deferred", "deferredSilent", "record", "picturerecord" };
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| @@ -58,43 +48,21 @@ static void erase(SkBitmap& bm) {
|
| }
|
| }
|
|
|
| -#if 0
|
| -static bool equal(const SkBitmap& bm1, const SkBitmap& bm2) {
|
| - if (bm1.width() != bm2.width() ||
|
| - bm1.height() != bm2.height() ||
|
| - bm1.config() != bm2.config()) {
|
| - return false;
|
| - }
|
| -
|
| - size_t pixelBytes = bm1.width() * bm1.bytesPerPixel();
|
| - for (int y = 0; y < bm1.height(); y++) {
|
| - if (memcmp(bm1.getAddr(0, y), bm2.getAddr(0, y), pixelBytes)) {
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| -}
|
| -#endif
|
| -
|
| class Iter {
|
| public:
|
| - Iter(void* param) {
|
| - fBench = BenchRegistry::Head();
|
| - fParam = param;
|
| - }
|
| + Iter() : fBench(BenchRegistry::Head()) {}
|
|
|
| SkBenchmark* next() {
|
| if (fBench) {
|
| BenchRegistry::Factory f = fBench->factory();
|
| fBench = fBench->next();
|
| - return f(fParam);
|
| + return f(NULL);
|
| }
|
| return NULL;
|
| }
|
|
|
| private:
|
| const BenchRegistry* fBench;
|
| - void* fParam;
|
| };
|
|
|
| class AutoPrePostDraw {
|
| @@ -144,13 +112,12 @@ static void saveFile(const char name[], const char config[], const char dir[],
|
| }
|
| }
|
|
|
| - SkString str;
|
| - make_filename(name, &str);
|
| - str.appendf("_%s.png", config);
|
| - str.prepend(dir);
|
| - ::remove(str.c_str());
|
| - SkImageEncoder::EncodeFile(str.c_str(), copy, SkImageEncoder::kPNG_Type,
|
| - 100);
|
| + SkString filename;
|
| + make_filename(name, &filename);
|
| + filename.appendf("_%s.png", config);
|
| + SkString path = SkOSPath::SkPathJoin(dir, filename.c_str());
|
| + ::remove(path.c_str());
|
| + SkImageEncoder::EncodeFile(path.c_str(), copy, SkImageEncoder::kPNG_Type, 100);
|
| }
|
|
|
| static void performClip(SkCanvas* canvas, int w, int h) {
|
| @@ -184,14 +151,6 @@ static void performScale(SkCanvas* canvas, int w, int h) {
|
| canvas->translate(-x, -y);
|
| }
|
|
|
| -static bool parse_bool_arg(char * const* argv, char* const* stop, bool* var) {
|
| - if (argv < stop) {
|
| - *var = atoi(*argv) != 0;
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| enum Backend {
|
| kNonRendering_Backend,
|
| kRaster_Backend,
|
| @@ -237,111 +196,82 @@ static SkBaseDevice* make_device(SkBitmap::Config config, const SkIPoint& size,
|
| #if SK_SUPPORT_GPU
|
| GrContextFactory gContextFactory;
|
| typedef GrContextFactory::GLContextType GLContextType;
|
| -static const GLContextType kDontCareGLCtxType = GrContextFactory::kNative_GLContextType;
|
| +static const GLContextType kNative = GrContextFactory::kNative_GLContextType;
|
| +#if SK_ANGLE
|
| +static const GLContextType kANGLE = GrContextFactory::kANGLE_GLContextType;
|
| +#else
|
| +static const GLContextType kANGLE = kNative;
|
| +#endif
|
| +static const GLContextType kDebug = GrContextFactory::kDebug_GLContextType;
|
| +static const GLContextType kNull = GrContextFactory::kNull_GLContextType;
|
| #else
|
| typedef int GLContextType;
|
| -static const GLContextType kDontCareGLCtxType = 0;
|
| +static const GLContextType kNative = 0, kANGLE = 0, kDebug = 0, kNull = 0;
|
| +#endif
|
| +
|
| +#ifdef SK_DEBUG
|
| +static const bool kIsDebug = true;
|
| +#else
|
| +static const bool kIsDebug = false;
|
| #endif
|
|
|
| -static const struct {
|
| - SkBitmap::Config fConfig;
|
| - const char* fName;
|
| - int fSampleCnt;
|
| - Backend fBackend;
|
| - GLContextType fContextType;
|
| - bool fRunByDefault;
|
| +static const struct Config {
|
| + SkBitmap::Config config;
|
| + const char* name;
|
| + int sampleCount;
|
| + Backend backend;
|
| + GLContextType contextType;
|
| + bool runByDefault;
|
| } gConfigs[] = {
|
| - { SkBitmap::kNo_Config, "NONRENDERING", 0, kNonRendering_Backend, kDontCareGLCtxType, true },
|
| - { SkBitmap::kARGB_8888_Config, "8888", 0, kRaster_Backend, kDontCareGLCtxType, true },
|
| - { SkBitmap::kRGB_565_Config, "565", 0, kRaster_Backend, kDontCareGLCtxType, true },
|
| + { SkBitmap::kNo_Config, "NONRENDERING", 0, kNonRendering_Backend, kNative, true},
|
| + { SkBitmap::kARGB_8888_Config, "8888", 0, kRaster_Backend, kNative, true},
|
| + { SkBitmap::kRGB_565_Config, "565", 0, kRaster_Backend, kNative, true},
|
| #if SK_SUPPORT_GPU
|
| - { SkBitmap::kARGB_8888_Config, "GPU", 0, kGPU_Backend, GrContextFactory::kNative_GLContextType, true },
|
| - { SkBitmap::kARGB_8888_Config, "MSAA4", 4, kGPU_Backend, GrContextFactory::kNative_GLContextType, false },
|
| - { SkBitmap::kARGB_8888_Config, "MSAA16", 16, kGPU_Backend, GrContextFactory::kNative_GLContextType, false },
|
| + { SkBitmap::kARGB_8888_Config, "GPU", 0, kGPU_Backend, kNative, true},
|
| + { SkBitmap::kARGB_8888_Config, "MSAA4", 4, kGPU_Backend, kNative, false},
|
| + { SkBitmap::kARGB_8888_Config, "MSAA16", 16, kGPU_Backend, kNative, false},
|
| #if SK_ANGLE
|
| - { SkBitmap::kARGB_8888_Config, "ANGLE", 0, kGPU_Backend, GrContextFactory::kANGLE_GLContextType, true },
|
| + { SkBitmap::kARGB_8888_Config, "ANGLE", 0, kGPU_Backend, kANGLE, true},
|
| #endif // SK_ANGLE
|
| - { SkBitmap::kARGB_8888_Config, "Debug", 0, kGPU_Backend, GrContextFactory::kDebug_GLContextType, kDebugOnly },
|
| - { SkBitmap::kARGB_8888_Config, "NULLGPU", 0, kGPU_Backend, GrContextFactory::kNull_GLContextType, true },
|
| + { SkBitmap::kARGB_8888_Config, "Debug", 0, kGPU_Backend, kDebug, kIsDebug},
|
| + { SkBitmap::kARGB_8888_Config, "NULLGPU", 0, kGPU_Backend, kNull, true},
|
| #endif // SK_SUPPORT_GPU
|
| };
|
|
|
| -static int findConfig(const char config[]) {
|
| - for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) {
|
| - if (!strcmp(config, gConfigs[i].fName)) {
|
| - return i;
|
| - }
|
| - }
|
| - return -1;
|
| -}
|
| -
|
| -static void help() {
|
| - SkString configsStr;
|
| - static const size_t kConfigCount = SK_ARRAY_COUNT(gConfigs);
|
| - for (size_t i = 0; i < kConfigCount; ++i) {
|
| - configsStr.appendf("%s%s", gConfigs[i].fName, ((i == kConfigCount - 1) ? "" : "|"));
|
| - }
|
| -
|
| - SkDebugf("Usage: bench [-o outDir] [--repeat nr] [--logPerIter] "
|
| - "[--timers [wcgWC]*] [--rotate]\n"
|
| - " [--scale] [--clip] [--min] [--forceAA 1|0] [--forceFilter 1|0]\n"
|
| - " [--forceDither 1|0] [--forceBlend 1|0]"
|
| -#if SK_SUPPORT_GPU
|
| - " [--gpuCacheSize <bytes> <count>]"
|
| -#endif
|
| - "\n"
|
| - " [--strokeWidth width] [--match name]\n"
|
| - " [--mode normal|deferred|deferredSilent|record|picturerecord]\n"
|
| - " [--config ");
|
| - SkDebugf("%s]\n", configsStr.c_str());
|
| - SkDebugf(" [-Dfoo bar] [--logFile filename] [-h|--help]");
|
| - SkDebugf("\n\n");
|
| - SkDebugf(" -o outDir : Image of each bench will be put in outDir.\n");
|
| - SkDebugf(" --repeat nr : Each bench repeats for nr times.\n");
|
| - SkDebugf(" --logPerIter : "
|
| - "Log each repeat timer instead of mean, default is disabled.\n");
|
| - SkDebugf(" --timers [wcgWC]* : "
|
| - "Display wall, cpu, gpu, truncated wall or truncated cpu time for each bench.\n");
|
| - SkDebugf(" --rotate : Rotate before each bench runs.\n");
|
| - SkDebugf(" --scale : Scale before each bench runs.\n");
|
| - SkDebugf(" --clip : Clip before each bench runs.\n");
|
| - SkDebugf(" --min : Print the minimum times (instead of average).\n");
|
| - SkDebugf(" --forceAA 1|0 : "
|
| - "Enable/disable anti-aliased, default is enabled.\n");
|
| - SkDebugf(" --forceFilter 1|0 : "
|
| - "Enable/disable bitmap filtering, default is disabled.\n");
|
| - SkDebugf(" --forceDither 1|0 : "
|
| - "Enable/disable dithering, default is disabled.\n");
|
| - SkDebugf(" --forceBlend 1|0 : "
|
| - "Enable/disable dithering, default is disabled.\n");
|
| -#if SK_SUPPORT_GPU
|
| - SkDebugf(" --gpuCacheSize <bytes> <count>: "
|
| - "limits gpu cache to bytes size or object count.\n");
|
| - SkDebugf(" -1 for either value means use the default. 0 for either disables the cache.\n");
|
| -#endif
|
| - SkDebugf(" --strokeWidth width : The width for path stroke.\n");
|
| - SkDebugf(" --match [~][^]substring[$] [...] of test name to run.\n"
|
| - " Multiple matches may be separated by spaces.\n"
|
| - " ~ causes a matching test to always be skipped\n"
|
| - " ^ requires the start of the test to match\n"
|
| - " $ requires the end of the test to match\n"
|
| - " ^ and $ requires an exact match\n"
|
| - " If a test does not match any list entry,\n"
|
| - " it is skipped unless some list entry starts with ~\n");
|
| - SkDebugf(" --mode normal|deferred|deferredSilent|record|picturerecord :\n"
|
| - " Run in the corresponding mode\n"
|
| - " normal, Use a normal canvas to draw to;\n"
|
| - " deferred, Use a deferrred canvas when drawing;\n"
|
| - " deferredSilent, deferred with silent playback;\n"
|
| - " record, Benchmark the time to record to an SkPicture;\n"
|
| - " picturerecord, Benchmark the time to do record from a \n"
|
| - " SkPicture to a SkPicture.\n");
|
| - SkDebugf(" --logFile filename : destination for writing log output, in addition to stdout.\n");
|
| - SkDebugf(" --config %s:\n", configsStr.c_str());
|
| - SkDebugf(" Run bench in corresponding config mode.\n");
|
| - SkDebugf(" -Dfoo bar : Add extra definition to bench.\n");
|
| - SkDebugf(" -h|--help : Show this help message.\n");
|
| -}
|
| +DEFINE_string(outDir, "", "If given, image of each bench will be put in outDir.");
|
| +DEFINE_string(timers, "cg", "Timers to display. "
|
| + "Options: w(all) W(all, truncated) c(pu) C(pu, truncated) g(pu)");
|
| +
|
| +DEFINE_bool(rotate, false, "Rotate canvas before bench run?");
|
| +DEFINE_bool(scale, false, "Scale canvas before bench run?");
|
| +DEFINE_bool(clip, false, "Clip canvas before bench run?");
|
| +
|
| +DEFINE_bool(forceAA, true, "Force anti-aliasing?");
|
| +DEFINE_bool(forceFilter, false, "Force bitmap filtering?");
|
| +DEFINE_string(forceDither, "default", "Force dithering: true, false, or default?");
|
| +DEFINE_bool(forceBlend, false, "Force alpha blending?");
|
| +
|
| +DEFINE_int32(gpuCacheBytes, -1, "GPU cache size limit in bytes. 0 to disable cache.");
|
| +DEFINE_int32(gpuCacheCount, -1, "GPU cache size limit in object count. 0 to disable cache.");
|
| +
|
| +DEFINE_string(match, "", "[~][^]substring[$] [...] of test name to run.\n"
|
| + "Multiple matches may be separated by spaces.\n"
|
| + "~ causes a matching test to always be skipped\n"
|
| + "^ requires the start of the test to match\n"
|
| + "$ requires the end of the test to match\n"
|
| + "^ and $ requires an exact match\n"
|
| + "If a test does not match any list entry,\n"
|
| + "it is skipped unless some list entry starts with ~\n");
|
| +DEFINE_string(mode, "normal",
|
| + "normal: draw to a normal canvas;\n"
|
| + "deferred: draw to a deferred canvas;\n"
|
| + "deferredSilent: deferred with silent playback;\n"
|
| + "record: draw to an SkPicture;\n"
|
| + "picturerecord: draw from an SkPicture to an SkPicture.\n");
|
| +DEFINE_string(config, "", "Run configs given. If empty, runs the defaults set in gConfigs.");
|
| +DEFINE_string(logFile, "", "Also write stdout here.");
|
| +DEFINE_int32(benchMs, 20, "Target time in ms to run each benchmark config.");
|
| +DEFINE_string(timeFormat, "%9.2f", "Format to print results, in milliseconds per 1000 loops.");
|
|
|
| int tool_main(int argc, char** argv);
|
| int tool_main(int argc, char** argv) {
|
| @@ -349,289 +279,79 @@ int tool_main(int argc, char** argv) {
|
| gPrintInstCount = true;
|
| #endif
|
| SkAutoGraphics ag;
|
| + SkCommandLineFlags::Parse(argc, argv);
|
|
|
| - SkTDict<const char*> defineDict(1024);
|
| - int repeatDraw = 1;
|
| -
|
| - int forceAlpha = 0xFF;
|
| - bool forceAA = true;
|
| - bool forceFilter = false;
|
| - SkTriState::State forceDither = SkTriState::kDefault;
|
| + // First, parse some flags.
|
|
|
| - static const uint32_t kDefaultTimerTypes = TimerData::kCpu_Flag | TimerData::kGpu_Flag;
|
| - static const TimerData::Result kDefaultTimerResult = TimerData::kAvg_Result;
|
| - uint32_t timerTypes = kDefaultTimerTypes;
|
| - TimerData::Result timerResult = kDefaultTimerResult;
|
| + SkBenchLogger logger;
|
| + if (FLAGS_logFile.count()) {
|
| + logger.SetLogFile(FLAGS_logFile[0]);
|
| + }
|
|
|
| - bool doScale = false;
|
| - bool doRotate = false;
|
| - bool doClip = false;
|
| - bool hasStrokeWidth = false;
|
| + const uint8_t alpha = FLAGS_forceBlend ? 0x80 : 0xFF;
|
| + SkTriState::State dither = SkTriState::kDefault;
|
| + for (size_t i = 0; i < 3; i++) {
|
| + if (strcmp(SkTriState::Name[i], FLAGS_forceDither[0]) == 0) {
|
| + dither = static_cast<SkTriState::State>(i);
|
| + }
|
| + }
|
|
|
| -#if SK_SUPPORT_GPU
|
| - struct {
|
| - int fBytes;
|
| - int fCount;
|
| - } gpuCacheSize = { -1, -1 }; // -1s mean use the default
|
| -#endif
|
| + BenchMode benchMode = kNormal_BenchMode;
|
| + for (size_t i = 0; i < SK_ARRAY_COUNT(BenchMode_Name); i++) {
|
| + if (strcmp(FLAGS_mode[0], BenchMode_Name[i]) == 0) {
|
| + benchMode = static_cast<BenchMode>(i);
|
| + }
|
| + }
|
|
|
| - float strokeWidth;
|
| - SkTDArray<const char*> fMatches;
|
| - benchModes benchMode = kNormal_benchModes;
|
| - SkString perIterTimeformat("%.2f");
|
| - SkString normalTimeFormat("%6.2f");
|
| -
|
| - SkString outDir;
|
| - SkBitmap::Config outConfig = SkBitmap::kNo_Config;
|
| - const char* configName = "";
|
| - Backend backend = kRaster_Backend; // for warning
|
| - int sampleCount = 0;
|
| SkTDArray<int> configs;
|
| - bool userConfig = false;
|
| -
|
| - SkBenchLogger logger;
|
| -
|
| - char* const* stop = argv + argc;
|
| - for (++argv; argv < stop; ++argv) {
|
| - if (strcmp(*argv, "-o") == 0) {
|
| - argv++;
|
| - if (argv < stop && **argv) {
|
| - outDir.set(*argv);
|
| - if (outDir.c_str()[outDir.size() - 1] != '/') {
|
| - outDir.append("/");
|
| - }
|
| - }
|
| - } else if (strcmp(*argv, "--repeat") == 0) {
|
| - argv++;
|
| - if (argv < stop) {
|
| - repeatDraw = atoi(*argv);
|
| - if (repeatDraw < 1) {
|
| - repeatDraw = 1;
|
| - }
|
| - } else {
|
| - logger.logError("missing arg for --repeat\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - } else if (strcmp(*argv, "--logPerIter") == 0) {
|
| - timerResult = TimerData::kPerIter_Result;
|
| - } else if (strcmp(*argv, "--timers") == 0) {
|
| - argv++;
|
| - if (argv < stop) {
|
| - timerTypes = 0;
|
| - for (char* t = *argv; *t; ++t) {
|
| - switch (*t) {
|
| - case 'w': timerTypes |= TimerData::kWall_Flag; break;
|
| - case 'c': timerTypes |= TimerData::kCpu_Flag; break;
|
| - case 'W': timerTypes |= TimerData::kTruncatedWall_Flag; break;
|
| - case 'C': timerTypes |= TimerData::kTruncatedCpu_Flag; break;
|
| - case 'g': timerTypes |= TimerData::kGpu_Flag; break;
|
| - }
|
| - }
|
| - } else {
|
| - logger.logError("missing arg for --timers\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - } else if (!strcmp(*argv, "--rotate")) {
|
| - doRotate = true;
|
| - } else if (!strcmp(*argv, "--scale")) {
|
| - doScale = true;
|
| - } else if (!strcmp(*argv, "--clip")) {
|
| - doClip = true;
|
| - } else if (!strcmp(*argv, "--min")) {
|
| - timerResult = TimerData::kMin_Result;
|
| - } else if (strcmp(*argv, "--forceAA") == 0) {
|
| - if (!parse_bool_arg(++argv, stop, &forceAA)) {
|
| - logger.logError("missing arg for --forceAA\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - } else if (strcmp(*argv, "--forceFilter") == 0) {
|
| - if (!parse_bool_arg(++argv, stop, &forceFilter)) {
|
| - logger.logError("missing arg for --forceFilter\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - } else if (strcmp(*argv, "--forceDither") == 0) {
|
| - bool tmp;
|
| - if (!parse_bool_arg(++argv, stop, &tmp)) {
|
| - logger.logError("missing arg for --forceDither\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - forceDither = tmp ? SkTriState::kTrue : SkTriState::kFalse;
|
| - } else if (strcmp(*argv, "--forceBlend") == 0) {
|
| - bool wantAlpha = false;
|
| - if (!parse_bool_arg(++argv, stop, &wantAlpha)) {
|
| - logger.logError("missing arg for --forceBlend\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - forceAlpha = wantAlpha ? 0x80 : 0xFF;
|
| -#if SK_SUPPORT_GPU
|
| - } else if (strcmp(*argv, "--gpuCacheSize") == 0) {
|
| - if (stop - argv > 2) {
|
| - gpuCacheSize.fBytes = atoi(*++argv);
|
| - gpuCacheSize.fCount = atoi(*++argv);
|
| - } else {
|
| - SkDebugf("missing arg for --gpuCacheSize\n");
|
| - help();
|
| - return -1;
|
| - }
|
| -#endif
|
| - } else if (strcmp(*argv, "--mode") == 0) {
|
| - argv++;
|
| - if (argv < stop) {
|
| - if (strcmp(*argv, "normal") == 0) {
|
| - benchMode = kNormal_benchModes;
|
| - } else if (strcmp(*argv, "deferred") == 0) {
|
| - benchMode = kDeferred_benchModes;
|
| - } else if (strcmp(*argv, "deferredSilent") == 0) {
|
| - benchMode = kDeferredSilent_benchModes;
|
| - } else if (strcmp(*argv, "record") == 0) {
|
| - benchMode = kRecord_benchModes;
|
| - } else if (strcmp(*argv, "picturerecord") == 0) {
|
| - benchMode = kPictureRecord_benchModes;
|
| - } else {
|
| - logger.logError("bad arg for --mode\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - } else {
|
| - logger.logError("missing arg for --mode\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - } else if (strcmp(*argv, "--strokeWidth") == 0) {
|
| - argv++;
|
| - if (argv < stop) {
|
| - const char *strokeWidthStr = *argv;
|
| - if (sscanf(strokeWidthStr, "%f", &strokeWidth) != 1) {
|
| - logger.logError("bad arg for --strokeWidth\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - hasStrokeWidth = true;
|
| - } else {
|
| - logger.logError("missing arg for --strokeWidth\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - } else if (strcmp(*argv, "--match") == 0) {
|
| - argv++;
|
| - while (argv < stop && (*argv)[0] != '-') {
|
| - *fMatches.append() = *argv++;
|
| - }
|
| - argv--;
|
| - if (!fMatches.count()) {
|
| - logger.logError("missing arg for --match\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - } else if (strcmp(*argv, "--config") == 0) {
|
| - argv++;
|
| - if (argv < stop) {
|
| - int index = findConfig(*argv);
|
| - if (index >= 0) {
|
| - *configs.append() = index;
|
| - userConfig = true;
|
| - } else {
|
| - SkString str;
|
| - str.printf("unrecognized config %s\n", *argv);
|
| - logger.logError(str);
|
| - help();
|
| - return -1;
|
| - }
|
| - } else {
|
| - logger.logError("missing arg for --config\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - } else if (strcmp(*argv, "--logFile") == 0) {
|
| - argv++;
|
| - if (argv < stop) {
|
| - if (!logger.SetLogFile(*argv)) {
|
| - SkString str;
|
| - str.printf("Could not open %s for writing.", *argv);
|
| - logger.logError(str);
|
| - return -1;
|
| - }
|
| - } else {
|
| - logger.logError("missing arg for --logFile\n");
|
| - help();
|
| - return -1;
|
| - }
|
| - } else if (strlen(*argv) > 2 && strncmp(*argv, "-D", 2) == 0) {
|
| - argv++;
|
| - if (argv < stop) {
|
| - defineDict.set(argv[-1] + 2, *argv);
|
| - } else {
|
| - logger.logError("incomplete '-Dfoo bar' definition\n");
|
| - help();
|
| - return -1;
|
| + // Try user-given configs first.
|
| + for (int i = 0; i < FLAGS_config.count(); i++) {
|
| + for (size_t j = 0; j < SK_ARRAY_COUNT(gConfigs); j++) {
|
| + if (0 == strcmp(FLAGS_config[i], gConfigs[j].name)) {
|
| + *configs.append() = j;
|
| }
|
| - } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
|
| - help();
|
| - return 0;
|
| - } else {
|
| - SkString str;
|
| - str.printf("unrecognized arg %s\n", *argv);
|
| - logger.logError(str);
|
| - help();
|
| - return -1;
|
| }
|
| }
|
| - if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)
|
| - && !outDir.isEmpty()) {
|
| - logger.logError("'--mode record' and '--mode picturerecord' are not"
|
| - " compatible with -o.\n");
|
| - return -1;
|
| - }
|
| - if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) {
|
| - perIterTimeformat.set("%.4f");
|
| - normalTimeFormat.set("%6.4f");
|
| - }
|
| - if (!userConfig) {
|
| - // if no config is specified by user, add the default configs
|
| - for (unsigned int i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
|
| - if (gConfigs[i].fRunByDefault) {
|
| + // If there weren't any, fill in with defaults.
|
| + if (configs.count() == 0) {
|
| + for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
|
| + if (gConfigs[i].runByDefault) {
|
| *configs.append() = i;
|
| }
|
| }
|
| }
|
| - if (kNormal_benchModes != benchMode) {
|
| + // Filter out things we can't run.
|
| + if (kNormal_BenchMode != benchMode) {
|
| // Non-rendering configs only run in normal mode
|
| for (int i = 0; i < configs.count(); ++i) {
|
| - int configIdx = configs[i];
|
| - if (kNonRendering_Backend == gConfigs[configIdx].fBackend) {
|
| + const Config& config = gConfigs[configs[i]];
|
| + if (kNonRendering_Backend == config.backend) {
|
| configs.remove(i, 1);
|
| --i;
|
| }
|
| }
|
| }
|
| -
|
| #if SK_SUPPORT_GPU
|
| for (int i = 0; i < configs.count(); ++i) {
|
| - int configIdx = configs[i];
|
| + const Config& config = gConfigs[configs[i]];
|
|
|
| - if (kGPU_Backend == gConfigs[configIdx].fBackend && gConfigs[configIdx].fSampleCnt > 0) {
|
| - GrContext* context = gContextFactory.get(gConfigs[configIdx].fContextType);
|
| + if (kGPU_Backend == config.backend) {
|
| + GrContext* context = gContextFactory.get(config.contextType);
|
| if (NULL == context) {
|
| SkString error;
|
| error.printf("Error creating GrContext for config %s. Config will be skipped.\n",
|
| - gConfigs[configIdx].fName);
|
| - logger.logError(error.c_str());
|
| + config.name);
|
| + logger.logError(error);
|
| configs.remove(i);
|
| --i;
|
| continue;
|
| }
|
| - if (gConfigs[configIdx].fSampleCnt > context->getMaxSampleCount()){
|
| + if (config.sampleCount > context->getMaxSampleCount()){
|
| SkString error;
|
| error.printf("Sample count (%d) for config %s is unsupported. "
|
| "Config will be skipped.\n",
|
| - gConfigs[configIdx].fSampleCnt, gConfigs[configIdx].fName);
|
| - logger.logError(error.c_str());
|
| + config.sampleCount, config.name);
|
| + logger.logError(error);
|
| configs.remove(i);
|
| --i;
|
| continue;
|
| @@ -640,334 +360,272 @@ int tool_main(int argc, char** argv) {
|
| }
|
| #endif
|
|
|
| - // report our current settings
|
| - {
|
| - SkString str;
|
| - const char* deferredMode = benchMode == kDeferred_benchModes ? "yes" :
|
| - (benchMode == kDeferredSilent_benchModes ? "silent" : "no");
|
| - str.printf("skia bench: alpha=0x%02X antialias=%d filter=%d "
|
| - "deferred=%s logperiter=%d",
|
| - forceAlpha, forceAA, forceFilter, deferredMode,
|
| - TimerData::kPerIter_Result == timerResult);
|
| - str.appendf(" rotate=%d scale=%d clip=%d min=%d",
|
| - doRotate, doScale, doClip, TimerData::kMin_Result == timerResult);
|
| - str.appendf(" record=%d picturerecord=%d",
|
| - benchMode == kRecord_benchModes,
|
| - benchMode == kPictureRecord_benchModes);
|
| - const char * ditherName;
|
| - switch (forceDither) {
|
| - case SkTriState::kDefault: ditherName = "default"; break;
|
| - case SkTriState::kTrue: ditherName = "true"; break;
|
| - case SkTriState::kFalse: ditherName = "false"; break;
|
| - default: ditherName = "<invalid>"; break;
|
| - }
|
| - str.appendf(" dither=%s", ditherName);
|
| -
|
| - if (hasStrokeWidth) {
|
| - str.appendf(" strokeWidth=%f", strokeWidth);
|
| - } else {
|
| - str.append(" strokeWidth=none");
|
| - }
|
| -
|
| -#if defined(SK_SCALAR_IS_FLOAT)
|
| - str.append(" scalar=float");
|
| -#elif defined(SK_SCALAR_IS_FIXED)
|
| - str.append(" scalar=fixed");
|
| + // All flags should be parsed now. Report our settings.
|
| + if (kIsDebug) {
|
| + logger.logError("bench was built in Debug mode, so we're going to hide the times."
|
| + " It's for your own good!\n");
|
| + }
|
| + SkString str("skia bench:");
|
| + str.appendf(" mode=%s", FLAGS_mode[0]);
|
| + str.appendf(" alpha=0x%02X antialias=%d filter=%d dither=%s",
|
| + alpha, FLAGS_forceAA, FLAGS_forceFilter, SkTriState::Name[dither]);
|
| + str.appendf(" rotate=%d scale=%d clip=%d", FLAGS_rotate, FLAGS_scale, FLAGS_clip);
|
| +
|
| +#if defined(SK_SCALAR_IS_FIXED)
|
| + str.append(" scalar=fixed");
|
| +#else
|
| + str.append(" scalar=float");
|
| #endif
|
|
|
| #if defined(SK_BUILD_FOR_WIN32)
|
| - str.append(" system=WIN32");
|
| + str.append(" system=WIN32");
|
| #elif defined(SK_BUILD_FOR_MAC)
|
| - str.append(" system=MAC");
|
| + str.append(" system=MAC");
|
| #elif defined(SK_BUILD_FOR_ANDROID)
|
| - str.append(" system=ANDROID");
|
| + str.append(" system=ANDROID");
|
| #elif defined(SK_BUILD_FOR_UNIX)
|
| - str.append(" system=UNIX");
|
| + str.append(" system=UNIX");
|
| #else
|
| - str.append(" system=other");
|
| + str.append(" system=other");
|
| #endif
|
|
|
| #if defined(SK_DEBUG)
|
| - str.append(" DEBUG");
|
| + str.append(" DEBUG");
|
| #endif
|
| - str.append("\n");
|
| - logger.logProgress(str);
|
| - }
|
| + str.append("\n");
|
| + logger.logProgress(str);
|
| +
|
|
|
| - SkTArray<BenchTimer*> timers(SK_ARRAY_COUNT(gConfigs));
|
| + // Set texture cache limits if non-default.
|
| for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
|
| #if SK_SUPPORT_GPU
|
| - SkGLContextHelper* glCtx = NULL;
|
| - if (kGPU_Backend == gConfigs[i].fBackend) {
|
| - GrContext* context = gContextFactory.get(gConfigs[i].fContextType);
|
| - if (NULL != context) {
|
| - // Set the user specified cache limits if non-default.
|
| - size_t bytes;
|
| - int count;
|
| - context->getTextureCacheLimits(&count, &bytes);
|
| - if (-1 != gpuCacheSize.fBytes) {
|
| - bytes = static_cast<size_t>(gpuCacheSize.fBytes);
|
| - }
|
| - if (-1 != gpuCacheSize.fCount) {
|
| - count = gpuCacheSize.fCount;
|
| - }
|
| - context->setTextureCacheLimits(count, bytes);
|
| - }
|
| - glCtx = gContextFactory.getGLContext(gConfigs[i].fContextType);
|
| + const Config& config = gConfigs[i];
|
| + if (kGPU_Backend != config.backend) {
|
| + continue;
|
| }
|
| - timers.push_back(SkNEW_ARGS(BenchTimer, (glCtx)));
|
| -#else
|
| - timers.push_back(SkNEW(BenchTimer));
|
| + GrContext* context = gContextFactory.get(config.contextType);
|
| + if (NULL == context) {
|
| + continue;
|
| + }
|
| +
|
| + size_t bytes;
|
| + int count;
|
| + context->getTextureCacheLimits(&count, &bytes);
|
| + if (-1 != FLAGS_gpuCacheBytes) {
|
| + bytes = static_cast<size_t>(FLAGS_gpuCacheBytes);
|
| + }
|
| + if (-1 != FLAGS_gpuCacheCount) {
|
| + count = FLAGS_gpuCacheCount;
|
| + }
|
| + context->setTextureCacheLimits(count, bytes);
|
| #endif
|
| }
|
|
|
| - Iter iter(&defineDict);
|
| + // Find the longest name of the benches we're going to run to make the output pretty.
|
| + Iter names;
|
| SkBenchmark* bench;
|
| - while ((bench = iter.next()) != NULL) {
|
| + int longestName = 0;
|
| + while ((bench = names.next()) != NULL) {
|
| SkAutoTUnref<SkBenchmark> benchUnref(bench);
|
| -
|
| - SkIPoint dim = bench->getSize();
|
| - if (dim.fX <= 0 || dim.fY <= 0) {
|
| + if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) {
|
| continue;
|
| }
|
| + const int length = strlen(bench->getName());
|
| + longestName = length > longestName ? length : longestName;
|
| + }
|
|
|
| - bench->setForceAlpha(forceAlpha);
|
| - bench->setForceAA(forceAA);
|
| - bench->setForceFilter(forceFilter);
|
| - bench->setDither(forceDither);
|
| - if (hasStrokeWidth) {
|
| - bench->setStrokeWidth(strokeWidth);
|
| - }
|
| -
|
| - // only run benchmarks if their name contains matchStr
|
| - if (SkCommandLineFlags::ShouldSkip(fMatches, bench->getName())) {
|
| + // Run each bench in each configuration it supports and we asked for.
|
| + Iter iter;
|
| + while ((bench = iter.next()) != NULL) {
|
| + SkAutoTUnref<SkBenchmark> benchUnref(bench);
|
| + if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) {
|
| continue;
|
| }
|
|
|
| - bool loggedBenchStart = false;
|
| -
|
| + bench->setForceAlpha(alpha);
|
| + bench->setForceAA(FLAGS_forceAA);
|
| + bench->setForceFilter(FLAGS_forceFilter);
|
| + bench->setDither(dither);
|
| AutoPrePostDraw appd(bench);
|
|
|
| - for (int x = 0; x < configs.count(); ++x) {
|
| - int configIndex = configs[x];
|
| -
|
| - bool setupFailed = false;
|
| + bool loggedBenchName = false;
|
| + for (int i = 0; i < configs.count(); ++i) {
|
| + const int configIndex = configs[i];
|
| + const Config& config = gConfigs[configIndex];
|
|
|
| - if (kNonRendering_Backend == gConfigs[configIndex].fBackend) {
|
| - if (bench->isRendering()) {
|
| - continue;
|
| - }
|
| - } else {
|
| - if (!bench->isRendering()) {
|
| - continue;
|
| - }
|
| + if ((kNonRendering_Backend == config.backend) == bench->isRendering()) {
|
| + continue;
|
| }
|
|
|
| - outConfig = gConfigs[configIndex].fConfig;
|
| - configName = gConfigs[configIndex].fName;
|
| - backend = gConfigs[configIndex].fBackend;
|
| - sampleCount = gConfigs[configIndex].fSampleCnt;
|
| GrContext* context = NULL;
|
| - BenchTimer* timer = timers[configIndex];
|
| -
|
| #if SK_SUPPORT_GPU
|
| SkGLContextHelper* glContext = NULL;
|
| - if (kGPU_Backend == backend) {
|
| - context = gContextFactory.get(gConfigs[configIndex].fContextType);
|
| + if (kGPU_Backend == config.backend) {
|
| + context = gContextFactory.get(config.contextType);
|
| if (NULL == context) {
|
| continue;
|
| }
|
| - glContext = gContextFactory.getGLContext(gConfigs[configIndex].fContextType);
|
| + glContext = gContextFactory.getGLContext(config.contextType);
|
| }
|
| #endif
|
| - SkBaseDevice* device = NULL;
|
| - SkCanvas* canvas = NULL;
|
| - SkPicture pictureRecordFrom;
|
| - SkPicture pictureRecordTo;
|
| -
|
| - if (kNonRendering_Backend != backend) {
|
| - device = make_device(outConfig, dim, backend, sampleCount, context);
|
| - if (NULL == device) {
|
| + SkAutoTUnref<SkBaseDevice> device;
|
| + SkAutoTUnref<SkCanvas> canvas;
|
| + SkPicture recordFrom, recordTo;
|
| + const SkIPoint dim = bench->getSize();
|
| +
|
| + const SkPicture::RecordingFlags kRecordFlags =
|
| + SkPicture::kUsePathBoundsForClip_RecordingFlag;
|
| +
|
| + if (kNonRendering_Backend != config.backend) {
|
| + device.reset(make_device(config.config,
|
| + dim,
|
| + config.backend,
|
| + config.sampleCount,
|
| + context));
|
| + if (!device.get()) {
|
| SkString error;
|
| - error.printf("Device creation failure for config %s. Will skip.\n", configName);
|
| - logger.logError(error.c_str());
|
| - setupFailed = true;
|
| - } else {
|
| - switch(benchMode) {
|
| - case kDeferredSilent_benchModes:
|
| - case kDeferred_benchModes:
|
| - canvas = SkDeferredCanvas::Create(device);
|
| - break;
|
| - case kRecord_benchModes:
|
| - canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
|
| - SkPicture::kUsePathBoundsForClip_RecordingFlag);
|
| - canvas->ref();
|
| - break;
|
| - case kPictureRecord_benchModes: {
|
| - // This sets up picture-to-picture recording.
|
| - // The C++ drawing calls for the benchmark are recorded into
|
| - // pictureRecordFrom. As the benchmark, we will time how
|
| - // long it takes to playback pictureRecordFrom into
|
| - // pictureRecordTo.
|
| - SkCanvas* tempCanvas = pictureRecordFrom.beginRecording(dim.fX, dim.fY,
|
| - SkPicture::kUsePathBoundsForClip_RecordingFlag);
|
| - bench->draw(tempCanvas);
|
| - pictureRecordFrom.endRecording();
|
| - canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
|
| - SkPicture::kUsePathBoundsForClip_RecordingFlag);
|
| - canvas->ref();
|
| - break;
|
| - }
|
| - case kNormal_benchModes:
|
| - canvas = new SkCanvas(device);
|
| - break;
|
| - default:
|
| - SkASSERT(0);
|
| - }
|
| - device->unref();
|
| - canvas->clear(SK_ColorWHITE);
|
| - }
|
| - }
|
| - SkAutoUnref canvasUnref(canvas);
|
| - if (!setupFailed) {
|
| - if (NULL != canvas) {
|
| - if (doClip) {
|
| - performClip(canvas, dim.fX, dim.fY);
|
| - }
|
| - if (doScale) {
|
| - performScale(canvas, dim.fX, dim.fY);
|
| - }
|
| - if (doRotate) {
|
| - performRotate(canvas, dim.fX, dim.fY);
|
| - }
|
| + error.printf("Device creation failure for config %s. Will skip.\n", config.name);
|
| + logger.logError(error);
|
| + continue;
|
| }
|
|
|
| - if (!loggedBenchStart) {
|
| - loggedBenchStart = true;
|
| - SkString str;
|
| - str.printf("running bench [%d %d] %28s", dim.fX, dim.fY, bench->getName());
|
| - logger.logProgress(str);
|
| + switch(benchMode) {
|
| + case kDeferredSilent_BenchMode:
|
| + case kDeferred_BenchMode:
|
| + canvas.reset(SkDeferredCanvas::Create(device.get()));
|
| + break;
|
| + case kRecord_BenchMode:
|
| + canvas.reset(SkRef(recordTo.beginRecording(dim.fX, dim.fY, kRecordFlags)));
|
| + break;
|
| + case kPictureRecord_BenchMode:
|
| + bench->draw(recordFrom.beginRecording(dim.fX, dim.fY, kRecordFlags));
|
| + recordFrom.endRecording();
|
| + canvas.reset(SkRef(recordTo.beginRecording(dim.fX, dim.fY, kRecordFlags)));
|
| + break;
|
| + case kNormal_BenchMode:
|
| + canvas.reset(new SkCanvas(device.get()));
|
| + break;
|
| + default:
|
| + SkASSERT(false);
|
| }
|
| + }
|
|
|
| - // warm up caches if needed
|
| - if (repeatDraw > 1 && NULL != canvas) {
|
| -#if SK_SUPPORT_GPU
|
| - // purge the GPU resources to reduce variance
|
| - if (NULL != context) {
|
| - context->freeGpuResources();
|
| - }
|
| -#endif
|
| - SkAutoCanvasRestore acr(canvas, true);
|
| - if (benchMode == kPictureRecord_benchModes) {
|
| - pictureRecordFrom.draw(canvas);
|
| - } else {
|
| - bench->draw(canvas);
|
| - }
|
| -
|
| - if (kDeferredSilent_benchModes == benchMode) {
|
| - static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
|
| - } else {
|
| - canvas->flush();
|
| - }
|
| -#if SK_SUPPORT_GPU
|
| - if (NULL != context) {
|
| - context->flush();
|
| - SK_GL(*glContext, Finish());
|
| - }
|
| -#endif
|
| - }
|
| + if (NULL != canvas) {
|
| + canvas->clear(SK_ColorWHITE);
|
| + if (FLAGS_clip) { performClip(canvas, dim.fX, dim.fY); }
|
| + if (FLAGS_scale) { performScale(canvas, dim.fX, dim.fY); }
|
| + if (FLAGS_rotate) { performRotate(canvas, dim.fX, dim.fY); }
|
| + }
|
| +
|
| + if (!loggedBenchName) {
|
| + loggedBenchName = true;
|
| + SkString str;
|
| + str.printf("running bench [%3d %3d] %*s ",
|
| + dim.fX, dim.fY, longestName, bench->getName());
|
| + logger.logProgress(str);
|
| + }
|
|
|
| - // record timer values for each repeat, and their sum
|
| - TimerData timerData(repeatDraw);
|
| - for (int i = 0; i < repeatDraw; i++) {
|
| - if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) {
|
| - // This will clear the recorded commands so that they do not
|
| - // accumulate.
|
| - canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
|
| - SkPicture::kUsePathBoundsForClip_RecordingFlag);
|
| - }
|
| -
|
| - timer->start(bench->getDurationScale());
|
| - if (NULL != canvas) {
|
| - canvas->save();
|
| - }
|
| - if (benchMode == kPictureRecord_benchModes) {
|
| - pictureRecordFrom.draw(canvas);
|
| - } else {
|
| - bench->draw(canvas);
|
| - }
|
| -
|
| - if (kDeferredSilent_benchModes == benchMode) {
|
| - static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
|
| - } else if (NULL != canvas) {
|
| - canvas->flush();
|
| - }
|
| -
|
| - if (NULL != canvas) {
|
| - canvas->restore();
|
| - }
|
| -
|
| - // stop the truncated timer after the last canvas call but
|
| - // don't wait for all the GL calls to complete
|
| - timer->truncatedEnd();
|
| #if SK_SUPPORT_GPU
|
| - if (NULL != glContext) {
|
| - context->flush();
|
| - SK_GL(*glContext, Finish());
|
| - }
|
| + SkGLContextHelper* contextHelper = NULL;
|
| + if (kGPU_Backend == config.backend) {
|
| + contextHelper = gContextFactory.getGLContext(config.contextType);
|
| + }
|
| + BenchTimer timer(contextHelper);
|
| +#else
|
| + BenchTimer timer;
|
| #endif
|
| - // stop the inclusive and gpu timers once all the GL calls
|
| - // have completed
|
| - timer->end();
|
|
|
| - SkAssertResult(timerData.appendTimes(timer));
|
| + bench->setLoops(0);
|
| + do {
|
| + // Ramp up 1 -> 4 -> 16 -> ... -> ~1 billion.
|
| + const int loops = bench->getLoops();
|
| + if (loops >= (1<<30)) {
|
| + // If you find it takes more than a billion loops to get up to 20ms of runtime,
|
| + // you've got a computer clocked at several THz or have a broken benchmark. ;)
|
| + // "1B ought to be enough for anybody."
|
| + SkString str;
|
| + str.printf("Can't ramp %s to %dms.\n", bench->getName(), FLAGS_benchMs);
|
| + logger.logError(str);
|
| + break;
|
| + }
|
| + bench->setLoops(loops == 0 ? 1 : loops * 4);
|
| +
|
| + if ((benchMode == kRecord_BenchMode || benchMode == kPictureRecord_BenchMode)) {
|
| + // Clear the recorded commands so that they do not accumulate.
|
| + canvas.reset(recordTo.beginRecording(dim.fX, dim.fY, kRecordFlags));
|
| + }
|
|
|
| + timer.start();
|
| + if (NULL != canvas) {
|
| + canvas->save();
|
| }
|
| - const char* timeFormat;
|
| - if (repeatDraw > 1 && TimerData::kPerIter_Result == timerResult) {
|
| - timeFormat = perIterTimeformat.c_str();
|
| + if (benchMode == kPictureRecord_BenchMode) {
|
| + recordFrom.draw(canvas);
|
| } else {
|
| - timeFormat = normalTimeFormat.c_str();
|
| + bench->draw(canvas);
|
| }
|
| - uint32_t filteredTimerTypes = timerTypes;
|
| - if (NULL == context) {
|
| - filteredTimerTypes &= ~TimerData::kGpu_Flag;
|
| +
|
| + if (kDeferredSilent_BenchMode == benchMode) {
|
| + static_cast<SkDeferredCanvas*>(canvas.get())->silentFlush();
|
| + } else if (NULL != canvas) {
|
| + canvas->flush();
|
| + }
|
| +
|
| + if (NULL != canvas) {
|
| + canvas->restore();
|
| + }
|
| +
|
| +
|
| + // Stop truncated timers before GL calls complete, and stop the full timers after.
|
| + timer.truncatedEnd();
|
| +#if SK_SUPPORT_GPU
|
| + if (NULL != glContext) {
|
| + context->flush();
|
| + SK_GL(*glContext, Finish());
|
| }
|
| - SkString result = timerData.getResult(timeFormat,
|
| - timerResult,
|
| - configName,
|
| - filteredTimerTypes);
|
| - logger.logProgress(result);
|
| -
|
| - if (outDir.size() > 0 && kNonRendering_Backend != backend) {
|
| - saveFile(bench->getName(), configName, outDir.c_str(),
|
| - device->accessBitmap(false));
|
| +#endif
|
| + timer.end();
|
| + } while (!kIsDebug && timer.fWall < FLAGS_benchMs); // One loop only in debug mode.
|
| +
|
| + if (FLAGS_outDir.count() && kNonRendering_Backend != config.backend) {
|
| + saveFile(bench->getName(),
|
| + config.name,
|
| + FLAGS_outDir[0],
|
| + device->accessBitmap(false));
|
| + }
|
| +
|
| + if (kIsDebug) {
|
| + // Let's not mislead ourselves by looking at Debug build bench times!
|
| + continue;
|
| + }
|
| +
|
| + // Normalize to ms per 1000 iterations.
|
| + const double normalize = 1000.0 / bench->getLoops();
|
| + const struct { char shortName; const char* longName; double ms; } times[] = {
|
| + {'w', "msecs", normalize * timer.fWall},
|
| + {'W', "Wmsecs", normalize * timer.fTruncatedWall},
|
| + {'c', "cmsecs", normalize * timer.fCpu},
|
| + {'C', "Cmsecs", normalize * timer.fTruncatedCpu},
|
| + {'g', "gmsecs", normalize * timer.fGpu},
|
| + };
|
| +
|
| + SkString result;
|
| + result.appendf(" %s:", config.name);
|
| + for (size_t i = 0; i < SK_ARRAY_COUNT(times); i++) {
|
| + if (strchr(FLAGS_timers[0], times[i].shortName) && times[i].ms > 0) {
|
| + result.appendf(" %s = ", times[i].longName);
|
| + result.appendf(FLAGS_timeFormat[0], times[i].ms);
|
| }
|
| }
|
| + logger.logProgress(result);
|
| }
|
| - if (loggedBenchStart) {
|
| - logger.logProgress(SkString("\n"));
|
| + if (loggedBenchName) {
|
| + logger.logProgress("\n");
|
| }
|
| }
|
| #if SK_SUPPORT_GPU
|
| -#if GR_CACHE_STATS
|
| - for (int i = 0; i <= GrContextFactory::kLastGLContextType; ++i) {
|
| - GrContextFactory::GLContextType ctxType = (GrContextFactory::GLContextType)i;
|
| - GrContext* context = gContextFactory.get(ctxType);
|
| - if (NULL != context) {
|
| - SkDebugf("Cache Stats for %s context:\n", GrContextFactory::GLContextTypeName(ctxType));
|
| - context->printCacheStats();
|
| - SkDebugf("\n");
|
| - }
|
| - }
|
| -#endif
|
| - // Destroy the GrContext before the inst tracking printing at main() exit occurs.
|
| gContextFactory.destroyContexts();
|
| #endif
|
| - for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
|
| - SkDELETE(timers[i]);
|
| - }
|
| -
|
| return 0;
|
| }
|
|
|
|
|