2012-06-27 19:33:29 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2012 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
2014-06-19 19:32:29 +00:00
|
|
|
#include "BenchLogger.h"
|
2014-06-20 18:29:20 +00:00
|
|
|
#include "Timer.h"
|
2012-11-07 18:01:46 +00:00
|
|
|
#include "CopyTilesRenderer.h"
|
2014-06-19 19:32:29 +00:00
|
|
|
#include "CrashHandler.h"
|
2013-07-16 18:21:46 +00:00
|
|
|
#include "LazyDecodeBitmap.h"
|
2012-08-01 17:53:29 +00:00
|
|
|
#include "PictureBenchmark.h"
|
2013-03-04 16:41:06 +00:00
|
|
|
#include "PictureRenderingFlags.h"
|
2014-06-19 19:32:29 +00:00
|
|
|
#include "PictureResultsWriter.h"
|
2013-03-21 19:43:15 +00:00
|
|
|
#include "SkCommandLineFlags.h"
|
2014-05-29 17:10:24 +00:00
|
|
|
#include "SkData.h"
|
2013-12-05 18:31:42 +00:00
|
|
|
#include "SkDiscardableMemoryPool.h"
|
2012-09-10 20:29:13 +00:00
|
|
|
#include "SkGraphics.h"
|
Add the ability to provide function pointers to SkPicture serialization
and deserialization for encoding and decoding bitmaps.
Remove kForceFlattenBitmapPixels_Flag, which is no longer used.
When an SkOrderedReadBuffer needs to read a bitmap, if it does not
have an image decoder, use a dummy bitmap.
In GM, add a tolerance option for color differences, used when
testing picture serialization, so it can assume two images are the
same even though PNG encoding/decoding may have resulted in small
differences.
Create dummy implementations for SkImageDecoder and SkImageEncoder
functions in SkImageDecoder_empty so that a project that does not
want to include the images project it can still build.
Allow ports to build without images project.
In Mac's image encoder, copy 4444 to 8888 before encoding.
Add SkWriter32::reservePad, to provide a pointer to write non 4 byte
aligned data, padded with zeroes.
In bench_ and render_ pictures, pass decode function to SkPicture
creation from a stream.
BUG=https://code.google.com/p/skia/issues/detail?id=842
Review URL: https://codereview.appspot.com/6551071
git-svn-id: http://skia.googlecode.com/svn/trunk@5818 2bbb7eff-a529-9590-31e7-b0007b416f81
2012-10-04 21:46:08 +00:00
|
|
|
#include "SkImageDecoder.h"
|
2012-08-23 20:53:25 +00:00
|
|
|
#include "SkMath.h"
|
2012-06-27 19:33:29 +00:00
|
|
|
#include "SkOSFile.h"
|
|
|
|
#include "SkPicture.h"
|
|
|
|
#include "SkStream.h"
|
|
|
|
#include "picture_utils.h"
|
|
|
|
|
2014-06-19 19:32:29 +00:00
|
|
|
BenchLogger gLogger;
|
2014-05-29 17:10:24 +00:00
|
|
|
PictureResultsLoggerWriter gLogWriter(&gLogger);
|
|
|
|
PictureResultsMultiWriter gWriter;
|
2013-03-04 16:41:06 +00:00
|
|
|
|
|
|
|
// Flags used by this file, in alphabetical order.
|
2013-03-04 21:32:32 +00:00
|
|
|
DEFINE_bool(countRAM, false, "Count the RAM used for bitmap pixels in each skp file");
|
2013-03-04 16:41:06 +00:00
|
|
|
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.");
|
2014-05-29 17:10:24 +00:00
|
|
|
DEFINE_string(jsonLog, "", "Destination for writing JSON data.");
|
2013-03-04 16:41:06 +00:00
|
|
|
DEFINE_bool(min, false, "Print the minimum times (instead of average).");
|
2013-04-09 21:25:46 +00:00
|
|
|
DECLARE_string(readPath);
|
2013-03-04 16:41:06 +00:00
|
|
|
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.");
|
2013-12-18 17:25:33 +00:00
|
|
|
DEFINE_bool(purgeDecodedTex, false, "Purge decoded and GPU-uploaded textures "
|
|
|
|
"after each iteration.");
|
2013-08-02 16:09:10 +00:00
|
|
|
DEFINE_string(timers, "c", "[wcgWC]*: Display wall, cpu, gpu, truncated wall or truncated cpu time"
|
2013-03-04 16:41:06 +00:00
|
|
|
" for each picture.");
|
2013-03-04 19:56:21 +00:00
|
|
|
DEFINE_bool(trackDeferredCaching, false, "Only meaningful with --deferImageDecoding and "
|
2014-04-04 16:43:38 +00:00
|
|
|
"SK_LAZY_CACHE_STATS set to true. Report percentage of cache hits when using "
|
|
|
|
"deferred image decoding.");
|
2012-06-27 19:33:29 +00:00
|
|
|
|
2014-09-18 20:52:08 +00:00
|
|
|
#if GR_GPU_STATS
|
|
|
|
DEFINE_bool(gpuStats, false, "Only meaningful with gpu configurations. "
|
|
|
|
"Report some GPU call statistics.");
|
|
|
|
#endif
|
|
|
|
|
2014-10-09 11:59:19 +00:00
|
|
|
DEFINE_bool(mpd, false, "If true, use MultiPictureDraw to render.");
|
2014-04-11 15:54:14 +00:00
|
|
|
|
2014-06-26 18:26:40 +00:00
|
|
|
// 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.");
|
|
|
|
|
|
|
|
|
2012-11-06 21:26:13 +00:00
|
|
|
static char const * const gFilterTypes[] = {
|
|
|
|
"paint",
|
|
|
|
"point",
|
|
|
|
"line",
|
|
|
|
"bitmap",
|
|
|
|
"rect",
|
2013-01-22 13:54:52 +00:00
|
|
|
"oval",
|
2012-11-06 21:26:13 +00:00
|
|
|
"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",
|
2012-11-07 16:42:17 +00:00
|
|
|
"AAClip",
|
2012-11-06 21:26:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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) {
|
2013-03-04 16:41:06 +00:00
|
|
|
result += "\n\t\t";
|
2012-11-06 21:26:13 +00:00
|
|
|
len = result.size();
|
|
|
|
}
|
|
|
|
if (index < kFilterFlagsCount - 1) {
|
|
|
|
result += " | ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2014-04-04 16:43:38 +00:00
|
|
|
#if SK_LAZY_CACHE_STATS
|
2013-03-04 19:56:21 +00:00
|
|
|
static int32_t gTotalCacheHits;
|
|
|
|
static int32_t gTotalCacheMisses;
|
|
|
|
#endif
|
|
|
|
|
2012-09-17 18:26:06 +00:00
|
|
|
static bool run_single_benchmark(const SkString& inputPath,
|
2012-08-01 17:53:29 +00:00
|
|
|
sk_tools::PictureBenchmark& benchmark) {
|
2012-06-27 19:33:29 +00:00
|
|
|
SkFILEStream inputStream;
|
|
|
|
|
|
|
|
inputStream.setPath(inputPath.c_str());
|
|
|
|
if (!inputStream.isValid()) {
|
2012-09-07 15:21:18 +00:00
|
|
|
SkString err;
|
|
|
|
err.printf("Could not open file %s\n", inputPath.c_str());
|
|
|
|
gLogger.logError(err);
|
2012-09-17 18:26:06 +00:00
|
|
|
return false;
|
2012-06-27 19:33:29 +00:00
|
|
|
}
|
|
|
|
|
2013-12-05 18:31:42 +00:00
|
|
|
SkDiscardableMemoryPool* pool = SkGetGlobalDiscardableMemoryPool();
|
2013-03-04 21:32:32 +00:00
|
|
|
// Since the old picture has been deleted, all pixels should be cleared.
|
2013-12-05 18:31:42 +00:00
|
|
|
SkASSERT(pool->getRAMUsed() == 0);
|
2013-03-04 21:32:32 +00:00
|
|
|
if (FLAGS_countRAM) {
|
2013-12-05 18:31:42 +00:00
|
|
|
pool->setRAMBudget(SK_MaxU32);
|
|
|
|
// Set the limit to max, so all pixels will be kept
|
2013-03-04 21:32:32 +00:00
|
|
|
}
|
|
|
|
|
2013-06-28 21:32:00 +00:00
|
|
|
SkPicture::InstallPixelRefProc proc;
|
2013-03-04 16:41:06 +00:00
|
|
|
if (FLAGS_deferImageDecoding) {
|
2013-07-16 18:21:46 +00:00
|
|
|
proc = &sk_tools::LazyDecodeBitmap;
|
2013-02-22 21:38:35 +00:00
|
|
|
} else {
|
2013-06-28 21:32:00 +00:00
|
|
|
proc = &SkImageDecoder::DecodeMemory;
|
2013-02-22 21:38:35 +00:00
|
|
|
}
|
2013-06-28 21:32:00 +00:00
|
|
|
SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&inputStream, proc));
|
2013-02-22 21:38:35 +00:00
|
|
|
|
2015-08-27 14:41:13 +00:00
|
|
|
if (nullptr == picture.get()) {
|
2012-09-17 18:26:06 +00:00
|
|
|
SkString err;
|
|
|
|
err.printf("Could not read an SkPicture from %s\n", inputPath.c_str());
|
|
|
|
gLogger.logError(err);
|
|
|
|
return false;
|
|
|
|
}
|
2012-06-27 19:33:29 +00:00
|
|
|
|
2014-07-29 02:26:58 +00:00
|
|
|
SkString filename = SkOSPath::Basename(inputPath.c_str());
|
2012-08-21 17:57:59 +00:00
|
|
|
|
2015-06-26 18:45:03 +00:00
|
|
|
gWriter.bench(filename.c_str(),
|
|
|
|
SkScalarCeilToInt(picture->cullRect().width()),
|
2014-08-29 15:03:56 +00:00
|
|
|
SkScalarCeilToInt(picture->cullRect().height()));
|
2012-07-09 18:32:08 +00:00
|
|
|
|
2014-10-09 11:59:19 +00:00
|
|
|
benchmark.run(picture, FLAGS_mpd);
|
2013-03-04 19:56:21 +00:00
|
|
|
|
2014-04-04 16:43:38 +00:00
|
|
|
#if SK_LAZY_CACHE_STATS
|
2013-03-04 19:56:21 +00:00
|
|
|
if (FLAGS_trackDeferredCaching) {
|
2014-04-04 16:43:38 +00:00
|
|
|
int cacheHits = pool->getCacheHits();
|
|
|
|
int cacheMisses = pool->getCacheMisses();
|
|
|
|
pool->resetCacheHitsAndMisses();
|
2013-03-04 21:32:32 +00:00
|
|
|
SkString hitString;
|
|
|
|
hitString.printf("Cache hit rate: %f\n", (double) cacheHits / (cacheHits + cacheMisses));
|
|
|
|
gLogger.logProgress(hitString);
|
2013-03-04 19:56:21 +00:00
|
|
|
gTotalCacheHits += cacheHits;
|
|
|
|
gTotalCacheMisses += cacheMisses;
|
|
|
|
}
|
|
|
|
#endif
|
2013-03-04 21:32:32 +00:00
|
|
|
if (FLAGS_countRAM) {
|
|
|
|
SkString ramCount("RAM used for bitmaps: ");
|
2013-12-05 18:31:42 +00:00
|
|
|
size_t bytes = pool->getRAMUsed();
|
2013-03-04 21:32:32 +00:00
|
|
|
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);
|
|
|
|
}
|
2013-03-04 19:56:21 +00:00
|
|
|
|
2012-09-17 18:26:06 +00:00
|
|
|
return true;
|
2012-06-27 19:33:29 +00:00
|
|
|
}
|
|
|
|
|
2013-03-04 16:41:06 +00:00
|
|
|
static void setup_benchmark(sk_tools::PictureBenchmark* benchmark) {
|
2012-11-06 21:26:13 +00:00
|
|
|
sk_tools::PictureRenderer::DrawFilterFlags drawFilters[SkDrawFilter::kTypeCount];
|
|
|
|
sk_bzero(drawFilters, sizeof(drawFilters));
|
2013-03-04 16:41:06 +00:00
|
|
|
|
|
|
|
if (FLAGS_filter.count() > 0) {
|
|
|
|
const char* filters = FLAGS_filter[0];
|
|
|
|
const char* colon = strchr(filters, ':');
|
|
|
|
if (colon) {
|
2013-03-04 19:56:21 +00:00
|
|
|
int32_t type = -1;
|
2013-03-04 16:41:06 +00:00
|
|
|
size_t typeLen = colon - filters;
|
|
|
|
for (size_t tIndex = 0; tIndex < kFilterTypesCount; ++tIndex) {
|
|
|
|
if (typeLen == strlen(gFilterTypes[tIndex])
|
|
|
|
&& !strncmp(filters, gFilterTypes[tIndex], typeLen)) {
|
2013-03-04 19:56:21 +00:00
|
|
|
type = SkToS32(tIndex);
|
2013-03-04 16:41:06 +00:00
|
|
|
break;
|
2012-09-07 15:21:18 +00:00
|
|
|
}
|
2012-11-02 18:11:49 +00:00
|
|
|
}
|
2013-03-04 16:41:06 +00:00
|
|
|
if (type < 0) {
|
2012-11-02 18:11:49 +00:00
|
|
|
SkString err;
|
2013-03-04 16:41:06 +00:00
|
|
|
err.printf("Unknown type for --filter %s\n", filters);
|
2012-11-02 18:11:49 +00:00
|
|
|
gLogger.logError(err);
|
2013-03-04 16:41:06 +00:00
|
|
|
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;
|
2012-08-02 18:57:53 +00:00
|
|
|
}
|
2012-12-13 21:40:48 +00:00
|
|
|
}
|
2013-03-04 16:41:06 +00:00
|
|
|
if (flag < 0) {
|
2012-09-07 15:21:18 +00:00
|
|
|
SkString err;
|
2013-03-04 16:41:06 +00:00
|
|
|
err.printf("Unknown flag for --filter %s\n", filters);
|
2012-09-07 15:21:18 +00:00
|
|
|
gLogger.logError(err);
|
2013-03-04 16:41:06 +00:00
|
|
|
exit(-1);
|
2012-08-20 15:04:04 +00:00
|
|
|
}
|
2013-03-04 16:41:06 +00:00
|
|
|
for (int index = 0; index < SkDrawFilter::kTypeCount; ++index) {
|
|
|
|
if (type != SkDrawFilter::kTypeCount && index != type) {
|
|
|
|
continue;
|
2012-09-11 19:15:32 +00:00
|
|
|
}
|
2013-03-04 16:41:06 +00:00
|
|
|
drawFilters[index] = (sk_tools::PictureRenderer::DrawFilterFlags)
|
|
|
|
(drawFilters[index] | flag);
|
2012-09-11 19:15:32 +00:00
|
|
|
}
|
2012-06-27 19:33:29 +00:00
|
|
|
} else {
|
2013-03-04 16:41:06 +00:00
|
|
|
SkString err;
|
|
|
|
err.printf("Unknown arg for --filter %s : missing colon\n", filters);
|
|
|
|
gLogger.logError(err);
|
|
|
|
exit(-1);
|
2012-06-27 19:33:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-04 16:41:06 +00:00
|
|
|
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);
|
2012-09-20 14:42:33 +00:00
|
|
|
}
|
|
|
|
|
2013-03-04 16:41:06 +00:00
|
|
|
SkString errorString;
|
|
|
|
SkAutoTUnref<sk_tools::PictureRenderer> renderer(parseRenderer(errorString,
|
|
|
|
kBench_PictureTool));
|
|
|
|
|
|
|
|
if (errorString.size() > 0) {
|
|
|
|
gLogger.logError(errorString);
|
2012-11-02 18:11:49 +00:00
|
|
|
}
|
|
|
|
|
2015-08-27 14:41:13 +00:00
|
|
|
if (nullptr == renderer.get()) {
|
2013-03-04 16:41:06 +00:00
|
|
|
exit(-1);
|
2012-11-06 18:58:43 +00:00
|
|
|
}
|
|
|
|
|
2013-03-04 16:41:06 +00:00
|
|
|
if (FLAGS_timeIndividualTiles) {
|
|
|
|
sk_tools::TiledPictureRenderer* tiledRenderer = renderer->getTiledRenderer();
|
2015-08-27 14:41:13 +00:00
|
|
|
if (nullptr == tiledRenderer) {
|
2013-03-04 16:41:06 +00:00
|
|
|
gLogger.logError("--timeIndividualTiles requires tiled rendering.\n");
|
|
|
|
exit(-1);
|
2012-08-31 16:15:22 +00:00
|
|
|
}
|
2013-03-04 16:41:06 +00:00
|
|
|
if (!tiledRenderer->supportsTimingIndividualTiles()) {
|
|
|
|
gLogger.logError("This renderer does not support --timeIndividualTiles.\n");
|
|
|
|
exit(-1);
|
2012-09-20 14:42:33 +00:00
|
|
|
}
|
2013-03-04 16:41:06 +00:00
|
|
|
benchmark->setTimeIndividualTiles(true);
|
2012-06-27 19:33:29 +00:00
|
|
|
}
|
2012-08-01 17:53:29 +00:00
|
|
|
|
2013-12-18 17:25:33 +00:00
|
|
|
benchmark->setPurgeDecodedTex(FLAGS_purgeDecodedTex);
|
|
|
|
|
2013-04-09 21:25:46 +00:00
|
|
|
if (FLAGS_readPath.count() < 1) {
|
2013-03-04 16:41:06 +00:00
|
|
|
gLogger.logError(".skp files or directories are required.\n");
|
|
|
|
exit(-1);
|
2012-08-01 17:53:29 +00:00
|
|
|
}
|
2012-11-02 18:11:49 +00:00
|
|
|
|
2012-11-06 21:26:13 +00:00
|
|
|
renderer->setDrawFilters(drawFilters, filtersName(drawFilters));
|
2013-07-31 20:00:56 +00:00
|
|
|
if (FLAGS_logPerIter) {
|
|
|
|
benchmark->setTimerResultType(TimerData::kPerIter_Result);
|
|
|
|
} else if (FLAGS_min) {
|
|
|
|
benchmark->setTimerResultType(TimerData::kMin_Result);
|
|
|
|
} else {
|
|
|
|
benchmark->setTimerResultType(TimerData::kAvg_Result);
|
|
|
|
}
|
2012-11-02 21:28:12 +00:00
|
|
|
benchmark->setRenderer(renderer);
|
2013-03-04 16:41:06 +00:00
|
|
|
benchmark->setRepeats(FLAGS_repeat);
|
2014-05-29 17:10:24 +00:00
|
|
|
benchmark->setWriter(&gWriter);
|
2012-07-09 18:32:08 +00:00
|
|
|
}
|
|
|
|
|
2013-03-04 16:41:06 +00:00
|
|
|
static int process_input(const char* input,
|
2012-09-17 18:26:06 +00:00
|
|
|
sk_tools::PictureBenchmark& benchmark) {
|
2013-03-04 16:41:06 +00:00
|
|
|
SkString inputAsSkString(input);
|
|
|
|
SkOSFile::Iter iter(input, "skp");
|
2012-07-09 18:32:08 +00:00
|
|
|
SkString inputFilename;
|
2012-09-17 18:26:06 +00:00
|
|
|
int failures = 0;
|
2012-07-09 18:32:08 +00:00
|
|
|
if (iter.next(&inputFilename)) {
|
|
|
|
do {
|
2014-07-29 02:26:58 +00:00
|
|
|
SkString inputPath = SkOSPath::Join(input, inputFilename.c_str());
|
2012-09-19 17:28:29 +00:00
|
|
|
if (!run_single_benchmark(inputPath, benchmark)) {
|
2012-09-17 18:26:06 +00:00
|
|
|
++failures;
|
2012-09-19 17:28:29 +00:00
|
|
|
}
|
2012-07-09 18:32:08 +00:00
|
|
|
} while(iter.next(&inputFilename));
|
2013-03-04 16:41:06 +00:00
|
|
|
} else if (SkStrEndsWith(input, ".skp")) {
|
|
|
|
if (!run_single_benchmark(inputAsSkString, benchmark)) {
|
2012-09-17 18:26:06 +00:00
|
|
|
++failures;
|
2012-09-19 17:28:29 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
SkString warning;
|
2013-03-04 16:41:06 +00:00
|
|
|
warning.printf("Warning: skipping %s\n", input);
|
2012-09-19 17:28:29 +00:00
|
|
|
gLogger.logError(warning);
|
2012-07-09 18:32:08 +00:00
|
|
|
}
|
2012-09-17 18:26:06 +00:00
|
|
|
return failures;
|
2012-06-27 19:33:29 +00:00
|
|
|
}
|
|
|
|
|
2012-10-02 18:33:14 +00:00
|
|
|
int tool_main(int argc, char** argv);
|
|
|
|
int tool_main(int argc, char** argv) {
|
2014-06-18 18:44:15 +00:00
|
|
|
SetupCrashHandler();
|
2013-03-04 16:41:06 +00:00
|
|
|
SkString usage;
|
|
|
|
usage.printf("Time drawing .skp files.\n"
|
|
|
|
"\tPossible arguments for --filter: [%s]\n\t\t[%s]",
|
|
|
|
filterTypesUsage().c_str(), filterFlagsUsage().c_str());
|
2013-03-21 19:43:15 +00:00
|
|
|
SkCommandLineFlags::SetUsage(usage.c_str());
|
|
|
|
SkCommandLineFlags::Parse(argc, argv);
|
2013-03-04 16:41:06 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-29 17:10:24 +00:00
|
|
|
SkAutoTDelete<PictureJSONResultsWriter> jsonWriter;
|
|
|
|
if (FLAGS_jsonLog.count() == 1) {
|
2014-06-26 18:26:40 +00:00
|
|
|
SkASSERT(FLAGS_builderName.count() == 1 && FLAGS_gitHash.count() == 1);
|
2015-08-26 20:07:48 +00:00
|
|
|
jsonWriter.reset(new PictureJSONResultsWriter(FLAGS_jsonLog[0], FLAGS_builderName[0],
|
|
|
|
FLAGS_buildNumber, FLAGS_timestamp,
|
|
|
|
FLAGS_gitHash[0], FLAGS_gitNumber));
|
2014-05-29 17:10:24 +00:00
|
|
|
gWriter.add(jsonWriter.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
gWriter.add(&gLogWriter);
|
|
|
|
|
2013-03-04 16:41:06 +00:00
|
|
|
|
2012-09-10 20:29:13 +00:00
|
|
|
SkAutoGraphics ag;
|
2012-09-11 19:15:32 +00:00
|
|
|
|
|
|
|
sk_tools::PictureBenchmark benchmark;
|
2012-06-27 19:33:29 +00:00
|
|
|
|
2013-03-04 16:41:06 +00:00
|
|
|
setup_benchmark(&benchmark);
|
2012-06-27 19:33:29 +00:00
|
|
|
|
2012-09-17 18:26:06 +00:00
|
|
|
int failures = 0;
|
2013-04-09 21:25:46 +00:00
|
|
|
for (int i = 0; i < FLAGS_readPath.count(); ++i) {
|
|
|
|
failures += process_input(FLAGS_readPath[i], benchmark);
|
2012-09-17 18:26:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (failures != 0) {
|
|
|
|
SkString err;
|
|
|
|
err.printf("Failed to run %i benchmarks.\n", failures);
|
|
|
|
gLogger.logError(err);
|
|
|
|
return 1;
|
2012-06-27 19:33:29 +00:00
|
|
|
}
|
2014-04-04 16:43:38 +00:00
|
|
|
#if SK_LAZY_CACHE_STATS
|
2013-03-04 19:56:21 +00:00
|
|
|
if (FLAGS_trackDeferredCaching) {
|
|
|
|
SkDebugf("Total cache hit rate: %f\n",
|
|
|
|
(double) gTotalCacheHits / (gTotalCacheHits + gTotalCacheMisses));
|
|
|
|
}
|
|
|
|
#endif
|
2014-09-18 20:52:08 +00:00
|
|
|
|
2014-10-24 16:34:41 +00:00
|
|
|
#if GR_GPU_STATS && SK_SUPPORT_GPU
|
2014-09-18 20:52:08 +00:00
|
|
|
if (FLAGS_gpuStats && benchmark.renderer()->isUsingGpuDevice()) {
|
2015-02-03 02:26:03 +00:00
|
|
|
benchmark.renderer()->getGrContext()->printGpuStats();
|
2014-09-18 20:52:08 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-05-29 17:10:24 +00:00
|
|
|
gWriter.end();
|
2012-10-02 20:00:03 +00:00
|
|
|
return 0;
|
2012-06-27 19:33:29 +00:00
|
|
|
}
|
2012-10-02 18:33:14 +00:00
|
|
|
|
|
|
|
#if !defined SK_BUILD_FOR_IOS
|
|
|
|
int main(int argc, char * const argv[]) {
|
|
|
|
return tool_main(argc, (char**) argv);
|
|
|
|
}
|
|
|
|
#endif
|