| Index: tools/bench_pictures_main.cpp
|
| diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp
|
| deleted file mode 100644
|
| index 79cce56dca11e90fd44aeced22517451880e116c..0000000000000000000000000000000000000000
|
| --- a/tools/bench_pictures_main.cpp
|
| +++ /dev/null
|
| @@ -1,481 +0,0 @@
|
| -/*
|
| - * Copyright 2012 Google Inc.
|
| - *
|
| - * Use of this source code is governed by a BSD-style license that can be
|
| - * found in the LICENSE file.
|
| - */
|
| -
|
| -#include "BenchLogger.h"
|
| -#include "Timer.h"
|
| -#include "CopyTilesRenderer.h"
|
| -#include "CrashHandler.h"
|
| -#include "LazyDecodeBitmap.h"
|
| -#include "PictureBenchmark.h"
|
| -#include "PictureRenderingFlags.h"
|
| -#include "PictureResultsWriter.h"
|
| -#include "SkCommandLineFlags.h"
|
| -#include "SkData.h"
|
| -#include "SkDiscardableMemoryPool.h"
|
| -#include "SkGraphics.h"
|
| -#include "SkImageDecoder.h"
|
| -#include "SkMath.h"
|
| -#include "SkOSFile.h"
|
| -#include "SkPicture.h"
|
| -#include "SkStream.h"
|
| -#include "picture_utils.h"
|
| -
|
| -BenchLogger gLogger;
|
| -PictureResultsLoggerWriter gLogWriter(&gLogger);
|
| -PictureResultsMultiWriter gWriter;
|
| -
|
| -// Flags used by this file, in alphabetical order.
|
| -DEFINE_bool(countRAM, false, "Count the RAM used for bitmap pixels in each skp file");
|
| -DECLARE_bool(deferImageDecoding);
|
| -DEFINE_string(filter, "",
|
| - "type:flag : Enable canvas filtering to disable a paint flag, "
|
| - "use no blur or low quality blur, or use no hinting or "
|
| - "slight hinting. For all flags except AAClip, specify the "
|
| - "type of primitive to effect, or choose all. for AAClip "
|
| - "alone, the filter affects all clips independent of type. "
|
| - "Specific flags are listed above.");
|
| -DEFINE_string(logFile, "", "Destination for writing log output, in addition to stdout.");
|
| -DEFINE_bool(logPerIter, false, "Log each repeat timer instead of mean.");
|
| -DEFINE_string(jsonLog, "", "Destination for writing JSON data.");
|
| -DEFINE_bool(min, false, "Print the minimum times (instead of average).");
|
| -DECLARE_string(readPath);
|
| -DEFINE_int32(repeat, 1, "Set the number of times to repeat each test.");
|
| -DEFINE_bool(timeIndividualTiles, false, "Report times for drawing individual tiles, rather than "
|
| - "times for drawing the whole page. Requires tiled rendering.");
|
| -DEFINE_bool(purgeDecodedTex, false, "Purge decoded and GPU-uploaded textures "
|
| - "after each iteration.");
|
| -DEFINE_string(timers, "c", "[wcgWC]*: Display wall, cpu, gpu, truncated wall or truncated cpu time"
|
| - " for each picture.");
|
| -DEFINE_bool(trackDeferredCaching, false, "Only meaningful with --deferImageDecoding and "
|
| - "SK_LAZY_CACHE_STATS set to true. Report percentage of cache hits when using "
|
| - "deferred image decoding.");
|
| -
|
| -#if GR_GPU_STATS
|
| -DEFINE_bool(gpuStats, false, "Only meaningful with gpu configurations. "
|
| - "Report some GPU call statistics.");
|
| -#endif
|
| -
|
| -DEFINE_bool(mpd, false, "If true, use MultiPictureDraw to render.");
|
| -
|
| -// Buildbot-specific parameters
|
| -DEFINE_string(builderName, "", "Name of the builder this is running on.");
|
| -DEFINE_int32(buildNumber, -1, "Build number of the build this test is running on");
|
| -DEFINE_int32(timestamp, 0, "Timestamp of the revision of Skia being tested.");
|
| -DEFINE_string(gitHash, "", "Commit hash of the revision of Skia being run.");
|
| -DEFINE_int32(gitNumber, -1, "Git number of the revision of Skia being run.");
|
| -
|
| -
|
| -static char const * const gFilterTypes[] = {
|
| - "paint",
|
| - "point",
|
| - "line",
|
| - "bitmap",
|
| - "rect",
|
| - "oval",
|
| - "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",
|
| - "AAClip",
|
| -};
|
| -
|
| -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\t\t";
|
| - len = result.size();
|
| - }
|
| - if (index < kFilterFlagsCount - 1) {
|
| - result += " | ";
|
| - }
|
| - }
|
| - return result;
|
| -}
|
| -
|
| -#if SK_LAZY_CACHE_STATS
|
| -static int32_t gTotalCacheHits;
|
| -static int32_t gTotalCacheMisses;
|
| -#endif
|
| -
|
| -static bool run_single_benchmark(const SkString& inputPath,
|
| - sk_tools::PictureBenchmark& benchmark) {
|
| - SkFILEStream inputStream;
|
| -
|
| - inputStream.setPath(inputPath.c_str());
|
| - if (!inputStream.isValid()) {
|
| - SkString err;
|
| - err.printf("Could not open file %s\n", inputPath.c_str());
|
| - gLogger.logError(err);
|
| - return false;
|
| - }
|
| -
|
| - SkDiscardableMemoryPool* pool = SkGetGlobalDiscardableMemoryPool();
|
| - // Since the old picture has been deleted, all pixels should be cleared.
|
| - SkASSERT(pool->getRAMUsed() == 0);
|
| - if (FLAGS_countRAM) {
|
| - pool->setRAMBudget(SK_MaxU32);
|
| - // Set the limit to max, so all pixels will be kept
|
| - }
|
| -
|
| - SkPicture::InstallPixelRefProc proc;
|
| - if (FLAGS_deferImageDecoding) {
|
| - proc = &sk_tools::LazyDecodeBitmap;
|
| - } else {
|
| - proc = &SkImageDecoder::DecodeMemory;
|
| - }
|
| - SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&inputStream, proc));
|
| -
|
| - if (nullptr == picture.get()) {
|
| - SkString err;
|
| - err.printf("Could not read an SkPicture from %s\n", inputPath.c_str());
|
| - gLogger.logError(err);
|
| - return false;
|
| - }
|
| -
|
| - SkString filename = SkOSPath::Basename(inputPath.c_str());
|
| -
|
| - gWriter.bench(filename.c_str(),
|
| - SkScalarCeilToInt(picture->cullRect().width()),
|
| - SkScalarCeilToInt(picture->cullRect().height()));
|
| -
|
| - benchmark.run(picture, FLAGS_mpd);
|
| -
|
| -#if SK_LAZY_CACHE_STATS
|
| - if (FLAGS_trackDeferredCaching) {
|
| - int cacheHits = pool->getCacheHits();
|
| - int cacheMisses = pool->getCacheMisses();
|
| - pool->resetCacheHitsAndMisses();
|
| - SkString hitString;
|
| - hitString.printf("Cache hit rate: %f\n", (double) cacheHits / (cacheHits + cacheMisses));
|
| - gLogger.logProgress(hitString);
|
| - gTotalCacheHits += cacheHits;
|
| - gTotalCacheMisses += cacheMisses;
|
| - }
|
| -#endif
|
| - if (FLAGS_countRAM) {
|
| - SkString ramCount("RAM used for bitmaps: ");
|
| - size_t bytes = pool->getRAMUsed();
|
| - if (bytes > 1024) {
|
| - size_t kb = bytes / 1024;
|
| - if (kb > 1024) {
|
| - size_t mb = kb / 1024;
|
| - ramCount.appendf("%zi MB\n", mb);
|
| - } else {
|
| - ramCount.appendf("%zi KB\n", kb);
|
| - }
|
| - } else {
|
| - ramCount.appendf("%zi bytes\n", bytes);
|
| - }
|
| - gLogger.logProgress(ramCount);
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -static void setup_benchmark(sk_tools::PictureBenchmark* benchmark) {
|
| - sk_tools::PictureRenderer::DrawFilterFlags drawFilters[SkDrawFilter::kTypeCount];
|
| - sk_bzero(drawFilters, sizeof(drawFilters));
|
| -
|
| - if (FLAGS_filter.count() > 0) {
|
| - const char* filters = FLAGS_filter[0];
|
| - const char* colon = strchr(filters, ':');
|
| - if (colon) {
|
| - int32_t type = -1;
|
| - size_t typeLen = colon - filters;
|
| - for (size_t tIndex = 0; tIndex < kFilterTypesCount; ++tIndex) {
|
| - if (typeLen == strlen(gFilterTypes[tIndex])
|
| - && !strncmp(filters, gFilterTypes[tIndex], typeLen)) {
|
| - type = SkToS32(tIndex);
|
| - break;
|
| - }
|
| - }
|
| - if (type < 0) {
|
| - SkString err;
|
| - err.printf("Unknown type for --filter %s\n", filters);
|
| - gLogger.logError(err);
|
| - exit(-1);
|
| - }
|
| - int flag = -1;
|
| - size_t flagLen = strlen(filters) - 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", filters);
|
| - gLogger.logError(err);
|
| - exit(-1);
|
| - }
|
| - 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", filters);
|
| - gLogger.logError(err);
|
| - exit(-1);
|
| - }
|
| - }
|
| -
|
| - if (FLAGS_timers.count() > 0) {
|
| - size_t index = 0;
|
| - bool timerWall = false;
|
| - bool truncatedTimerWall = false;
|
| - bool timerCpu = false;
|
| - bool truncatedTimerCpu = false;
|
| - bool timerGpu = false;
|
| - while (index < strlen(FLAGS_timers[0])) {
|
| - switch (FLAGS_timers[0][index]) {
|
| - case 'w':
|
| - timerWall = true;
|
| - break;
|
| - case 'c':
|
| - timerCpu = true;
|
| - break;
|
| - case 'W':
|
| - truncatedTimerWall = true;
|
| - break;
|
| - case 'C':
|
| - truncatedTimerCpu = true;
|
| - break;
|
| - case 'g':
|
| - timerGpu = true;
|
| - break;
|
| - default:
|
| - SkDebugf("mystery character\n");
|
| - break;
|
| - }
|
| - index++;
|
| - }
|
| - benchmark->setTimersToShow(timerWall, truncatedTimerWall, timerCpu, truncatedTimerCpu,
|
| - timerGpu);
|
| - }
|
| -
|
| - SkString errorString;
|
| - SkAutoTUnref<sk_tools::PictureRenderer> renderer(parseRenderer(errorString,
|
| - kBench_PictureTool));
|
| -
|
| - if (errorString.size() > 0) {
|
| - gLogger.logError(errorString);
|
| - }
|
| -
|
| - if (nullptr == renderer.get()) {
|
| - exit(-1);
|
| - }
|
| -
|
| - if (FLAGS_timeIndividualTiles) {
|
| - sk_tools::TiledPictureRenderer* tiledRenderer = renderer->getTiledRenderer();
|
| - if (nullptr == tiledRenderer) {
|
| - gLogger.logError("--timeIndividualTiles requires tiled rendering.\n");
|
| - exit(-1);
|
| - }
|
| - if (!tiledRenderer->supportsTimingIndividualTiles()) {
|
| - gLogger.logError("This renderer does not support --timeIndividualTiles.\n");
|
| - exit(-1);
|
| - }
|
| - benchmark->setTimeIndividualTiles(true);
|
| - }
|
| -
|
| - benchmark->setPurgeDecodedTex(FLAGS_purgeDecodedTex);
|
| -
|
| - if (FLAGS_readPath.count() < 1) {
|
| - gLogger.logError(".skp files or directories are required.\n");
|
| - exit(-1);
|
| - }
|
| -
|
| - renderer->setDrawFilters(drawFilters, filtersName(drawFilters));
|
| - if (FLAGS_logPerIter) {
|
| - benchmark->setTimerResultType(TimerData::kPerIter_Result);
|
| - } else if (FLAGS_min) {
|
| - benchmark->setTimerResultType(TimerData::kMin_Result);
|
| - } else {
|
| - benchmark->setTimerResultType(TimerData::kAvg_Result);
|
| - }
|
| - benchmark->setRenderer(renderer);
|
| - benchmark->setRepeats(FLAGS_repeat);
|
| - benchmark->setWriter(&gWriter);
|
| -}
|
| -
|
| -static int process_input(const char* input,
|
| - sk_tools::PictureBenchmark& benchmark) {
|
| - SkString inputAsSkString(input);
|
| - SkOSFile::Iter iter(input, "skp");
|
| - SkString inputFilename;
|
| - int failures = 0;
|
| - if (iter.next(&inputFilename)) {
|
| - do {
|
| - SkString inputPath = SkOSPath::Join(input, inputFilename.c_str());
|
| - if (!run_single_benchmark(inputPath, benchmark)) {
|
| - ++failures;
|
| - }
|
| - } while(iter.next(&inputFilename));
|
| - } else if (SkStrEndsWith(input, ".skp")) {
|
| - if (!run_single_benchmark(inputAsSkString, benchmark)) {
|
| - ++failures;
|
| - }
|
| - } else {
|
| - SkString warning;
|
| - warning.printf("Warning: skipping %s\n", input);
|
| - gLogger.logError(warning);
|
| - }
|
| - return failures;
|
| -}
|
| -
|
| -int tool_main(int argc, char** argv);
|
| -int tool_main(int argc, char** argv) {
|
| - SetupCrashHandler();
|
| - SkString usage;
|
| - usage.printf("Time drawing .skp files.\n"
|
| - "\tPossible arguments for --filter: [%s]\n\t\t[%s]",
|
| - filterTypesUsage().c_str(), filterFlagsUsage().c_str());
|
| - SkCommandLineFlags::SetUsage(usage.c_str());
|
| - SkCommandLineFlags::Parse(argc, argv);
|
| -
|
| - if (FLAGS_repeat < 1) {
|
| - SkString error;
|
| - error.printf("--repeats must be >= 1. Was %i\n", FLAGS_repeat);
|
| - gLogger.logError(error);
|
| - exit(-1);
|
| - }
|
| -
|
| - if (FLAGS_logFile.count() == 1) {
|
| - if (!gLogger.SetLogFile(FLAGS_logFile[0])) {
|
| - SkString str;
|
| - str.printf("Could not open %s for writing.\n", FLAGS_logFile[0]);
|
| - gLogger.logError(str);
|
| - // TODO(borenet): We're disabling this for now, due to
|
| - // write-protected Android devices. The very short-term
|
| - // solution is to ignore the fact that we have no log file.
|
| - //exit(-1);
|
| - }
|
| - }
|
| -
|
| - SkAutoTDelete<PictureJSONResultsWriter> jsonWriter;
|
| - if (FLAGS_jsonLog.count() == 1) {
|
| - SkASSERT(FLAGS_builderName.count() == 1 && FLAGS_gitHash.count() == 1);
|
| - jsonWriter.reset(new PictureJSONResultsWriter(FLAGS_jsonLog[0], FLAGS_builderName[0],
|
| - FLAGS_buildNumber, FLAGS_timestamp,
|
| - FLAGS_gitHash[0], FLAGS_gitNumber));
|
| - gWriter.add(jsonWriter.get());
|
| - }
|
| -
|
| - gWriter.add(&gLogWriter);
|
| -
|
| -
|
| - SkAutoGraphics ag;
|
| -
|
| - sk_tools::PictureBenchmark benchmark;
|
| -
|
| - setup_benchmark(&benchmark);
|
| -
|
| - int failures = 0;
|
| - for (int i = 0; i < FLAGS_readPath.count(); ++i) {
|
| - failures += process_input(FLAGS_readPath[i], benchmark);
|
| - }
|
| -
|
| - if (failures != 0) {
|
| - SkString err;
|
| - err.printf("Failed to run %i benchmarks.\n", failures);
|
| - gLogger.logError(err);
|
| - return 1;
|
| - }
|
| -#if SK_LAZY_CACHE_STATS
|
| - if (FLAGS_trackDeferredCaching) {
|
| - SkDebugf("Total cache hit rate: %f\n",
|
| - (double) gTotalCacheHits / (gTotalCacheHits + gTotalCacheMisses));
|
| - }
|
| -#endif
|
| -
|
| -#if GR_GPU_STATS && SK_SUPPORT_GPU
|
| - if (FLAGS_gpuStats && benchmark.renderer()->isUsingGpuDevice()) {
|
| - benchmark.renderer()->getGrContext()->printGpuStats();
|
| - }
|
| -#endif
|
| -
|
| - gWriter.end();
|
| - return 0;
|
| -}
|
| -
|
| -#if !defined SK_BUILD_FOR_IOS
|
| -int main(int argc, char * const argv[]) {
|
| - return tool_main(argc, (char**) argv);
|
| -}
|
| -#endif
|
|
|