Rebase gpu_dev up to r5182
git-svn-id: http://skia.googlecode.com/svn/branches/gpu_dev@6187 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/Intersection/Simplify.cpp b/experimental/Intersection/Simplify.cpp
index 3ecb164..d5b4d9e 100644
--- a/experimental/Intersection/Simplify.cpp
+++ b/experimental/Intersection/Simplify.cpp
@@ -897,14 +897,14 @@
fEmpty = true;
fDefer[0] = fDefer[1] = pt;
}
-
+
void deferredMoveLine(const SkPoint& pt) {
if (!fHasMove) {
deferredMove(pt);
}
deferredLine(pt);
}
-
+
bool hasMove() const {
return fHasMove;
}
@@ -918,7 +918,7 @@
bool isClosed() const {
return !fEmpty && fFirstPt == fDefer[1];
}
-
+
void lineTo() {
if (fDefer[0] == fDefer[1]) {
return;
@@ -952,7 +952,7 @@
bool changedSlopes(const SkPoint& pt) const {
if (fDefer[0] == fDefer[1]) {
return false;
- }
+ }
SkScalar deferDx = fDefer[1].fX - fDefer[0].fX;
SkScalar deferDy = fDefer[1].fY - fDefer[0].fY;
SkScalar lineDx = pt.fX - fDefer[1].fX;
@@ -1205,7 +1205,7 @@
init(pts, SkPath::kCubic_Verb, operand);
fBounds.setCubicBounds(pts);
}
-
+
/* SkPoint */ void addCurveTo(int start, int end, PathWrapper& path, bool active) const {
SkPoint edge[4];
const SkPoint* ePtr;
@@ -1876,7 +1876,7 @@
SkASSERT(fDoneSpans <= fTs.count());
return fDoneSpans == fTs.count();
}
-
+
bool done(int min) const {
return fTs[min].fDone;
}
@@ -2250,7 +2250,7 @@
}
continue;
}
-
+
if (!maxWinding && (!foundAngle || foundDone2)) {
#if DEBUG_WINDING
if (foundAngle && foundDone2) {
@@ -2809,7 +2809,7 @@
} while (++index < fTs.count() && approximately_negative(fTs[index].fT - referenceT));
#endif
}
-
+
void markOneDone(const char* funName, int tIndex, int winding) {
Span* span = markOneWinding(funName, tIndex, winding);
if (!span) {
@@ -3511,7 +3511,7 @@
}
return false;
}
-
+
const SkPoint& end() const {
const Segment& segment = fSegments.back();
return segment.pts()[segment.verb()];
@@ -3635,7 +3635,7 @@
}
path.close();
}
-
+
void toPartialBackward(PathWrapper& path) const {
int segmentCount = fSegments.count();
for (int test = segmentCount - 1; test >= 0; --test) {
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index bf03214..54bbd8b 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -16,6 +16,7 @@
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
+#include "SkOSFile.h"
#include "SkPicture.h"
#include "SkRefCnt.h"
#include "SkStream.h"
@@ -64,13 +65,6 @@
const static ErrorBitfield ERROR_READING_REFERENCE_IMAGE = 0x08;
const static ErrorBitfield ERROR_WRITING_REFERENCE_IMAGE = 0x10;
-// TODO: This should be defined as "\\" on Windows, but this is the way this
-// file has been working for a long time. We can fix it later.
-const static char* PATH_SEPARATOR = "/";
-
-// If true, emit a messange when we can't find a reference image to compare
-static bool gNotifyMissingReadReference;
-
using namespace skiagm;
class Iter {
@@ -156,9 +150,20 @@
class GMMain {
public:
- static SkString make_name(const char shortName[], const char configName[]) {
- SkString name(shortName);
- name.appendf("_%s", configName);
+ GMMain() {
+ // Set default values of member variables, which tool_main()
+ // may override.
+ fNotifyMissingReadReference = true;
+ fUseFileHierarchy = false;
+ }
+
+ SkString make_name(const char shortName[], const char configName[]) {
+ SkString name;
+ if (fUseFileHierarchy) {
+ name.appendf("%s%c%s", configName, SkPATH_SEPARATOR, shortName);
+ } else {
+ name.appendf("%s_%s", shortName, configName);
+ }
return name;
}
@@ -167,12 +172,11 @@
const SkString& name,
const char suffix[]) {
SkString filename(path);
- if (filename.endsWith(PATH_SEPARATOR)) {
+ if (filename.endsWith(SkPATH_SEPARATOR)) {
filename.remove(filename.size() - 1, 1);
}
- filename.append(pathSuffix);
- filename.append(PATH_SEPARATOR);
- filename.appendf("%s.%s", name.c_str(), suffix);
+ filename.appendf("%s%c%s.%s", pathSuffix, SkPATH_SEPARATOR,
+ name.c_str(), suffix);
return filename;
}
@@ -489,7 +493,7 @@
// Returns a description of the difference between "bitmap" and
// the reference bitmap, or ERROR_READING_REFERENCE_IMAGE if
// unable to read the reference bitmap from disk.
- static ErrorBitfield compare_to_reference_image_on_disk(
+ ErrorBitfield compare_to_reference_image_on_disk(
const char readPath [], const SkString& name, SkBitmap &bitmap,
const char diffPath [], const char renderModeDescriptor []) {
SkString path = make_filename(readPath, "", name, "png");
@@ -503,7 +507,7 @@
diffPath,
renderModeDescriptor);
} else {
- if (gNotifyMissingReadReference) {
+ if (fNotifyMissingReadReference) {
fprintf(stderr, "FAILED to read %s\n", path.c_str());
}
return ERROR_READING_REFERENCE_IMAGE;
@@ -515,15 +519,15 @@
// both NULL (and thus no images are read from or written to disk).
// So I don't trust that the renderModeDescriptor is being used for
// anything other than debug output these days.
- static ErrorBitfield handle_test_results(GM* gm,
- const ConfigData& gRec,
- const char writePath [],
- const char readPath [],
- const char diffPath [],
- const char renderModeDescriptor [],
- SkBitmap& bitmap,
- SkDynamicMemoryWStream* pdf,
- const SkBitmap* referenceBitmap) {
+ ErrorBitfield handle_test_results(GM* gm,
+ const ConfigData& gRec,
+ const char writePath [],
+ const char readPath [],
+ const char diffPath [],
+ const char renderModeDescriptor [],
+ SkBitmap& bitmap,
+ SkDynamicMemoryWStream* pdf,
+ const SkBitmap* referenceBitmap) {
SkString name = make_name(gm->shortName(), gRec.fName);
ErrorBitfield retval = ERROR_NONE;
@@ -580,14 +584,14 @@
// Test: draw into a bitmap or pdf.
// Depending on flags, possibly compare to an expected image
// and possibly output a diff image if it fails to match.
- static ErrorBitfield test_drawing(GM* gm,
- const ConfigData& gRec,
- const char writePath [],
- const char readPath [],
- const char diffPath [],
- GrContext* context,
- GrRenderTarget* rt,
- SkBitmap* bitmap) {
+ ErrorBitfield test_drawing(GM* gm,
+ const ConfigData& gRec,
+ const char writePath [],
+ const char readPath [],
+ const char diffPath [],
+ GrContext* context,
+ GrRenderTarget* rt,
+ SkBitmap* bitmap) {
SkDynamicMemoryWStream document;
if (gRec.fBackend == kRaster_Backend ||
@@ -612,12 +616,12 @@
"", *bitmap, &document, NULL);
}
- static ErrorBitfield test_deferred_drawing(GM* gm,
- const ConfigData& gRec,
- const SkBitmap& referenceBitmap,
- const char diffPath [],
- GrContext* context,
- GrRenderTarget* rt) {
+ ErrorBitfield test_deferred_drawing(GM* gm,
+ const ConfigData& gRec,
+ const SkBitmap& referenceBitmap,
+ const char diffPath [],
+ GrContext* context,
+ GrRenderTarget* rt) {
SkDynamicMemoryWStream document;
if (gRec.fBackend == kRaster_Backend ||
@@ -635,11 +639,11 @@
return ERROR_NONE;
}
- static ErrorBitfield test_pipe_playback(GM* gm,
- const ConfigData& gRec,
- const SkBitmap& referenceBitmap,
- const char readPath [],
- const char diffPath []) {
+ ErrorBitfield test_pipe_playback(GM* gm,
+ const ConfigData& gRec,
+ const SkBitmap& referenceBitmap,
+ const char readPath [],
+ const char diffPath []) {
ErrorBitfield errors = ERROR_NONE;
for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) {
SkBitmap bitmap;
@@ -664,7 +668,7 @@
return errors;
}
- static ErrorBitfield test_tiled_pipe_playback(
+ ErrorBitfield test_tiled_pipe_playback(
GM* gm, const ConfigData& gRec, const SkBitmap& referenceBitmap,
const char readPath [], const char diffPath []) {
ErrorBitfield errors = ERROR_NONE;
@@ -690,6 +694,17 @@
}
return errors;
}
+
+ //
+ // member variables.
+ // They are public for now, to allow easier setting by tool_main().
+ //
+
+ // if true, emit a message when we can't find a reference image to compare
+ bool fNotifyMissingReadReference;
+
+ bool fUseFileHierarchy;
+
}; // end of GMMain class definition
#if SK_SUPPORT_GPU
@@ -734,8 +749,6 @@
static void usage(const char * argv0) {
SkDebugf("%s\n", argv0);
- SkDebugf(" [-w writePath] [-r readPath] [-d diffPath] [-i resourcePath]\n");
- SkDebugf(" [-wp writePicturePath]\n");
SkDebugf(" [--config ");
for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
if (i > 0) {
@@ -743,30 +756,37 @@
}
SkDebugf(gRec[i].fName);
}
- SkDebugf(" ]\n");
- SkDebugf(" [--noreplay] [--nopipe] [--noserialize] [--forceBWtext] [--nopdf] \n"
- " [--tiledPipe] \n"
- " [--nodeferred] [--match substring] [--notexturecache]\n"
- " [-h|--help]\n"
+ SkDebugf("]:\n run these configurations\n");
+ SkDebugf(
+// Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath").
+// It would probably be better if we allowed both yes-and-no settings for each
+// one, e.g.:
+// [--replay|--noreplay]: whether to exercise SkPicture replay; default is yes
+" [--nodeferred]: skip the deferred rendering test pass\n"
+" [--diffPath|-d <path>]: write difference images into this directory\n"
+" [--disable-missing-warning]: don't print a message to stderr if\n"
+" unable to read a reference image for any tests (NOT default behavior)\n"
+" [--enable-missing-warning]: print message to stderr (but don't fail) if\n"
+" unable to read a reference image for any tests (default behavior)\n"
+" [--forceBWtext]: disable text anti-aliasing\n"
+" [--help|-h]: show this help message\n"
+" [--hierarchy|--nohierarchy]: whether to use multilevel directory structure\n"
+" when reading/writing files; default is no\n"
+" [--match <substring>]: only run tests whose name includes this substring\n"
+" [--modulo <remainder> <divisor>]: only run tests for which \n"
+" testIndex %% divisor == remainder\n"
+" [--nopdf]: skip the pdf rendering test pass\n"
+" [--nopipe]: Skip SkGPipe replay\n"
+" [--readPath|-r <path>]: read reference images from this dir, and report\n"
+" any differences between those and the newly generated ones\n"
+" [--noreplay]: do not exercise SkPicture replay\n"
+" [--resourcePath|-i <path>]: directory that stores image resources\n"
+" [--noserialize]: do not exercise SkPicture serialization & deserialization\n"
+" [--notexturecache]: disable the gpu texture cache\n"
+" [--tiledPipe]: Exercise tiled SkGPipe replay\n"
+" [--writePath|-w <path>]: write rendered images into this directory\n"
+" [--writePicturePath|-wp <path>]: write .skp files into this directory\n"
);
- SkDebugf(" writePath: directory to write rendered images in.\n");
- SkDebugf(" writePicturePath: directory to write images to in .skp format.\n");
- SkDebugf(
- " readPath: directory to read reference images from;\n"
- " reports if any pixels mismatch between reference and new images\n");
- SkDebugf(" diffPath: directory to write difference images in.\n");
- SkDebugf(" resourcePath: directory that stores image resources.\n");
- SkDebugf(" --noreplay: do not exercise SkPicture replay.\n");
- SkDebugf(" --nopipe: Skip SkGPipe replay.\n");
- SkDebugf(" --tiledPipe: Exercise tiled SkGPipe replay.\n");
- SkDebugf(
- " --noserialize: do not exercise SkPicture serialization & deserialization.\n");
- SkDebugf(" --forceBWtext: disable text anti-aliasing.\n");
- SkDebugf(" --nopdf: skip the pdf rendering test pass.\n");
- SkDebugf(" --nodeferred: skip the deferred rendering test pass.\n");
- SkDebugf(" --match foo: will only run tests that substring match foo.\n");
- SkDebugf(" --notexturecache: disable the gpu texture cache.\n");
- SkDebugf(" -h|--help : Show this help message. \n");
}
static int findConfig(const char config[]) {
@@ -869,82 +889,13 @@
SkTDArray<size_t> configs;
bool userConfig = false;
- int moduloIndex = -1;
- int moduloCount = -1;
-
- gNotifyMissingReadReference = true;
+ int moduloRemainder = -1;
+ int moduloDivisor = -1;
const char* const commandName = argv[0];
char* const* stop = argv + argc;
for (++argv; argv < stop; ++argv) {
- if (strcmp(*argv, "-w") == 0) {
- argv++;
- if (argv < stop && **argv) {
- writePath = *argv;
- }
- } else if (strcmp(*argv, "-wp") == 0) {
- argv++;
- if (argv < stop && **argv) {
- writePicturePath = *argv;
- }
- } else if (strcmp(*argv, "-r") == 0) {
- argv++;
- if (argv < stop && **argv) {
- readPath = *argv;
- }
- } else if (strcmp(*argv, "-d") == 0) {
- argv++;
- if (argv < stop && **argv) {
- diffPath = *argv;
- }
- } else if (strcmp(*argv, "-i") == 0) {
- argv++;
- if (argv < stop && **argv) {
- resourcePath = *argv;
- }
- } else if (strcmp(*argv, "--forceBWtext") == 0) {
- gForceBWtext = true;
- } else if (strcmp(*argv, "--nopipe") == 0) {
- doPipe = false;
- } else if (strcmp(*argv, "--tiledPipe") == 0) {
- doTiledPipe = true;
- } else if (strcmp(*argv, "--noreplay") == 0) {
- doReplay = false;
- } else if (strcmp(*argv, "--nopdf") == 0) {
- doPDF = false;
- } else if (strcmp(*argv, "--nodeferred") == 0) {
- doDeferred = false;
- } else if (strcmp(*argv, "--modulo") == 0) {
- ++argv;
- if (argv >= stop) {
- continue;
- }
- moduloIndex = atoi(*argv);
-
- ++argv;
- if (argv >= stop) {
- continue;
- }
- moduloCount = atoi(*argv);
- } else if (strcmp(*argv, "--disable-missing-warning") == 0) {
- gNotifyMissingReadReference = false;
- } else if (strcmp(*argv, "--enable-missing-warning") == 0) {
- gNotifyMissingReadReference = true;
- } else if (strcmp(*argv, "--serialize") == 0) {
- // Leaving in this option so that a user need not modify
- // their command line arguments to still run.
- doSerialize = true;
- } else if (strcmp(*argv, "--noserialize") == 0) {
- doSerialize = false;
- } else if (strcmp(*argv, "--match") == 0) {
- ++argv;
- if (argv < stop && **argv) {
- // just record the ptr, no need for a deep copy
- *fMatches.append() = *argv;
- }
- } else if (strcmp(*argv, "--notexturecache") == 0) {
- disableTextureCache = true;
- } else if (strcmp(*argv, "--config") == 0) {
+ if (strcmp(*argv, "--config") == 0) {
argv++;
if (argv < stop) {
int index = findConfig(*argv);
@@ -963,9 +914,83 @@
usage(commandName);
return -1;
}
+ } else if (strcmp(*argv, "--nodeferred") == 0) {
+ doDeferred = false;
+ } else if ((0 == strcmp(*argv, "--diffPath")) ||
+ (0 == strcmp(*argv, "-d"))) {
+ argv++;
+ if (argv < stop && **argv) {
+ diffPath = *argv;
+ }
+ } else if (strcmp(*argv, "--disable-missing-warning") == 0) {
+ gmmain.fNotifyMissingReadReference = false;
+ } else if (strcmp(*argv, "--enable-missing-warning") == 0) {
+ gmmain.fNotifyMissingReadReference = true;
+ } else if (strcmp(*argv, "--forceBWtext") == 0) {
+ gForceBWtext = true;
} else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
usage(commandName);
return -1;
+ } else if (strcmp(*argv, "--hierarchy") == 0) {
+ gmmain.fUseFileHierarchy = true;
+ } else if (strcmp(*argv, "--nohierarchy") == 0) {
+ gmmain.fUseFileHierarchy = false;
+ } else if (strcmp(*argv, "--match") == 0) {
+ ++argv;
+ if (argv < stop && **argv) {
+ // just record the ptr, no need for a deep copy
+ *fMatches.append() = *argv;
+ }
+ } else if (strcmp(*argv, "--modulo") == 0) {
+ ++argv;
+ if (argv >= stop) {
+ continue;
+ }
+ moduloRemainder = atoi(*argv);
+
+ ++argv;
+ if (argv >= stop) {
+ continue;
+ }
+ moduloDivisor = atoi(*argv);
+ } else if (strcmp(*argv, "--nopdf") == 0) {
+ doPDF = false;
+ } else if (strcmp(*argv, "--nopipe") == 0) {
+ doPipe = false;
+ } else if ((0 == strcmp(*argv, "--readPath")) ||
+ (0 == strcmp(*argv, "-r"))) {
+ argv++;
+ if (argv < stop && **argv) {
+ readPath = *argv;
+ }
+ } else if (strcmp(*argv, "--noreplay") == 0) {
+ doReplay = false;
+ } else if ((0 == strcmp(*argv, "--resourcePath")) ||
+ (0 == strcmp(*argv, "-i"))) {
+ argv++;
+ if (argv < stop && **argv) {
+ resourcePath = *argv;
+ }
+ } else if (strcmp(*argv, "--serialize") == 0) {
+ doSerialize = true;
+ } else if (strcmp(*argv, "--noserialize") == 0) {
+ doSerialize = false;
+ } else if (strcmp(*argv, "--notexturecache") == 0) {
+ disableTextureCache = true;
+ } else if (strcmp(*argv, "--tiledPipe") == 0) {
+ doTiledPipe = true;
+ } else if ((0 == strcmp(*argv, "--writePath")) ||
+ (0 == strcmp(*argv, "-w"))) {
+ argv++;
+ if (argv < stop && **argv) {
+ writePath = *argv;
+ }
+ } else if ((0 == strcmp(*argv, "--writePicturePath")) ||
+ (0 == strcmp(*argv, "-wp"))) {
+ argv++;
+ if (argv < stop && **argv) {
+ writePicturePath = *argv;
+ }
} else {
usage(commandName);
return -1;
@@ -998,11 +1023,11 @@
fprintf(stderr, "reading resources from %s\n", resourcePath);
}
- if (moduloCount <= 0) {
- moduloIndex = -1;
+ if (moduloDivisor <= 0) {
+ moduloRemainder = -1;
}
- if (moduloIndex < 0 || moduloIndex >= moduloCount) {
- moduloIndex = -1;
+ if (moduloRemainder < 0 || moduloRemainder >= moduloDivisor) {
+ moduloRemainder = -1;
}
// Accumulate success of all tests.
@@ -1023,16 +1048,34 @@
int gmIndex = -1;
SkString moduloStr;
+ // If we will be writing out files, prepare subdirectories.
+ if (writePath) {
+ if (!sk_mkdir(writePath)) {
+ return -1;
+ }
+ if (gmmain.fUseFileHierarchy) {
+ for (int i = 0; i < configs.count(); i++) {
+ ConfigData config = gRec[configs[i]];
+ SkString subdir;
+ subdir.appendf("%s%c%s", writePath, SkPATH_SEPARATOR,
+ config.fName);
+ if (!sk_mkdir(subdir.c_str())) {
+ return -1;
+ }
+ }
+ }
+ }
+
Iter iter;
GM* gm;
while ((gm = iter.next()) != NULL) {
++gmIndex;
- if (moduloIndex >= 0) {
- if ((gmIndex % moduloCount) != moduloIndex) {
+ if (moduloRemainder >= 0) {
+ if ((gmIndex % moduloDivisor) != moduloRemainder) {
continue;
}
- moduloStr.printf("[%d.%d] ", gmIndex, moduloCount);
+ moduloStr.printf("[%d.%d] ", gmIndex, moduloDivisor);
}
const char* shortName = gm->shortName();
@@ -1050,6 +1093,7 @@
for (int i = 0; i < configs.count(); i++) {
ConfigData config = gRec[configs[i]];
+
// Skip any tests that we don't even need to try.
if ((kPDF_Backend == config.fBackend) &&
(!doPDF || (gmFlags & GM::kSkipPDF_Flag)))
diff --git a/gm/lighting.cpp b/gm/lighting.cpp
index 46474ab..9db34fd 100644
--- a/gm/lighting.cpp
+++ b/gm/lighting.cpp
@@ -47,6 +47,18 @@
make_bitmap();
fInitialized = true;
}
+ canvas->clear(0xFF101010);
+ SkPaint checkPaint;
+ checkPaint.setColor(0xFF202020);
+ for (int y = 0; y < HEIGHT; y += 16) {
+ for (int x = 0; x < WIDTH; x += 16) {
+ canvas->save();
+ canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
+ canvas->drawRect(SkRect::MakeXYWH(8, 0, 8, 8), checkPaint);
+ canvas->drawRect(SkRect::MakeXYWH(0, 8, 8, 8), checkPaint);
+ canvas->restore();
+ }
+ }
SkPoint3 pointLocation(0, 0, SkIntToScalar(10));
SkScalar azimuthRad = SkDegreesToRadians(SkIntToScalar(225));
SkScalar elevationRad = SkDegreesToRadians(SkIntToScalar(5));
diff --git a/gyp/common_variables.gypi b/gyp/common_variables.gypi
index 3d19e62..6acf5bc 100644
--- a/gyp/common_variables.gypi
+++ b/gyp/common_variables.gypi
@@ -81,6 +81,7 @@
'skia_scalar%': 'float',
'skia_mesa%': 0,
'skia_nv_path_rendering%': 0,
+ 'skia_texture_cache_mb_limit%': 0,
'skia_angle%': 0,
'skia_directwrite%': 0,
'skia_nacl%': 0,
@@ -97,6 +98,7 @@
'skia_scalar%': '<(skia_scalar)',
'skia_mesa%': '<(skia_mesa)',
'skia_nv_path_rendering%': '<(skia_nv_path_rendering)',
+ 'skia_texture_cache_mb_limit%': '<(skia_texture_cache_mb_limit)',
'skia_angle%': '<(skia_angle)',
'skia_arch_width%': '<(skia_arch_width)',
'skia_arch_type%': '<(skia_arch_type)',
diff --git a/gyp/gpu.gyp b/gyp/gpu.gyp
index 0dc84ee..9cb0698 100644
--- a/gyp/gpu.gyp
+++ b/gyp/gpu.gyp
@@ -71,6 +71,11 @@
],
},
}],
+ [ 'skia_texture_cache_mb_limit != 0', {
+ 'defines': [
+ 'GR_DEFAULT_TEXTURE_CACHE_MB_LIMIT=<(skia_texture_cache_mb_limit)',
+ ],
+ }],
],
'direct_dependent_settings': {
'conditions': [
diff --git a/include/core/SkOSFile.h b/include/core/SkOSFile.h
index b5477cd..79551ae 100644
--- a/include/core/SkOSFile.h
+++ b/include/core/SkOSFile.h
@@ -7,7 +7,8 @@
*/
-//
+// TODO: add unittests for all these operations
+
#ifndef SkOSFile_DEFINED
#define SkOSFile_DEFINED
@@ -24,6 +25,12 @@
kWrite_SkFILE_Flag = 0x02
};
+#ifdef _WIN32
+const static char SkPATH_SEPARATOR = '\\';
+#else
+const static char SkPATH_SEPARATOR = '/';
+#endif
+
SkFILE* sk_fopen(const char path[], SkFILE_Flags);
void sk_fclose(SkFILE*);
@@ -39,6 +46,17 @@
int sk_fseek( SkFILE*, size_t, int );
size_t sk_ftell( SkFILE* );
+// Returns true if something (file, directory, ???) exists at this path.
+bool sk_exists(const char *path);
+
+// Returns true if a directory exists at this path.
+bool sk_isdir(const char *path);
+
+// Create a new directory at this path; returns true if successful.
+// If the directory already existed, this will return true.
+// Description of the error, if any, will be written to stderr.
+bool sk_mkdir(const char* path);
+
class SkOSFile {
public:
class Iter {
@@ -79,4 +97,3 @@
};
#endif
-
diff --git a/include/core/SkString.h b/include/core/SkString.h
index 20f16c4..94dcf8b 100644
--- a/include/core/SkString.h
+++ b/include/core/SkString.h
@@ -15,18 +15,30 @@
/* Some helper functions for C strings
*/
-static bool SkStrStartsWith(const char string[], const char prefix[]) {
+static bool SkStrStartsWith(const char string[], const char prefixStr[]) {
SkASSERT(string);
- SkASSERT(prefix);
- return !strncmp(string, prefix, strlen(prefix));
+ SkASSERT(prefixStr);
+ return !strncmp(string, prefixStr, strlen(prefixStr));
}
-bool SkStrEndsWith(const char string[], const char suffix[]);
+static bool SkStrStartsWith(const char string[], const char prefixChar) {
+ SkASSERT(string);
+ return (prefixChar == *string);
+}
+
+bool SkStrEndsWith(const char string[], const char suffixStr[]);
+bool SkStrEndsWith(const char string[], const char suffixChar);
+
int SkStrStartsWithOneOf(const char string[], const char prefixes[]);
+
static bool SkStrContains(const char string[], const char substring[]) {
SkASSERT(string);
SkASSERT(substring);
return (NULL != strstr(string, substring));
}
+static bool SkStrContains(const char string[], const char subchar) {
+ SkASSERT(string);
+ return (NULL != strchr(string, subchar));
+}
#define SkStrAppendS32_MaxSize 11
char* SkStrAppendS32(char buffer[], int32_t);
@@ -82,15 +94,24 @@
bool equals(const char text[]) const;
bool equals(const char text[], size_t len) const;
- bool startsWith(const char prefix[]) const {
- return SkStrStartsWith(fRec->data(), prefix);
+ bool startsWith(const char prefixStr[]) const {
+ return SkStrStartsWith(fRec->data(), prefixStr);
}
- bool endsWith(const char suffix[]) const {
- return SkStrEndsWith(fRec->data(), suffix);
+ bool startsWith(const char prefixChar) const {
+ return SkStrStartsWith(fRec->data(), prefixChar);
+ }
+ bool endsWith(const char suffixStr[]) const {
+ return SkStrEndsWith(fRec->data(), suffixStr);
+ }
+ bool endsWith(const char suffixChar) const {
+ return SkStrEndsWith(fRec->data(), suffixChar);
}
bool contains(const char substring[]) const {
return SkStrContains(fRec->data(), substring);
}
+ bool contains(const char subchar) const {
+ return SkStrContains(fRec->data(), subchar);
+ }
friend bool operator==(const SkString& a, const SkString& b) {
return a.equals(b);
diff --git a/include/gpu/GrConfig.h b/include/gpu/GrConfig.h
index c61c34e..66d1c97 100644
--- a/include/gpu/GrConfig.h
+++ b/include/gpu/GrConfig.h
@@ -369,6 +369,15 @@
#define GR_GEOM_BUFFER_LOCK_THRESHOLD (1 << 15)
#endif
+/**
+ * GR_DEFAULT_TEXTURE_CACHE_MB_LIMIT gives a threshold (in megabytes) for the
+ * maximum size of the texture cache in vram. The value is only a default and
+ * can be overridden at runtime.
+ */
+#if !defined(GR_DEFAULT_TEXTURE_CACHE_MB_LIMIT)
+ #define GR_DEFAULT_TEXTURE_CACHE_MB_LIMIT 96
+#endif
+
///////////////////////////////////////////////////////////////////////////////
// tail section:
//
diff --git a/include/gpu/GrUserConfig.h b/include/gpu/GrUserConfig.h
index d514486..7b4e4bb 100644
--- a/include/gpu/GrUserConfig.h
+++ b/include/gpu/GrUserConfig.h
@@ -54,6 +54,12 @@
*/
//#define GR_GEOM_BUFFER_LOCK_THRESHOLD (1<<15)
+/**
+ * This gives a threshold in megabytes for the maximum size of the texture cache
+ * in vram. The value is only a default and can be overridden at runtime.
+ */
+//#define GR_DEFAULT_TEXTURE_CACHE_MB_LIMIT 96
+
///////////////////////////////////////////////////////////////////////////////
// Decide Ganesh types
diff --git a/src/core/SkString.cpp b/src/core/SkString.cpp
index fee614c..5d1b8ce 100644
--- a/src/core/SkString.cpp
+++ b/src/core/SkString.cpp
@@ -36,13 +36,23 @@
///////////////////////////////////////////////////////////////////////////////
-bool SkStrEndsWith(const char string[], const char suffix[]) {
+bool SkStrEndsWith(const char string[], const char suffixStr[]) {
SkASSERT(string);
- SkASSERT(suffix);
+ SkASSERT(suffixStr);
size_t strLen = strlen(string);
- size_t suffixLen = strlen(suffix);
+ size_t suffixLen = strlen(suffixStr);
return strLen >= suffixLen &&
- !strncmp(string + strLen - suffixLen, suffix, suffixLen);
+ !strncmp(string + strLen - suffixLen, suffixStr, suffixLen);
+}
+
+bool SkStrEndsWith(const char string[], const char suffixChar) {
+ SkASSERT(string);
+ size_t strLen = strlen(string);
+ if (0 == strLen) {
+ return false;
+ } else {
+ return (suffixChar == string[strLen-1]);
+ }
}
int SkStrStartsWithOneOf(const char string[], const char prefixes[]) {
@@ -602,4 +612,3 @@
#undef VSNPRINTF
#undef SNPRINTF
-
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 2f403c1..82e1f22 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -1282,7 +1282,8 @@
SkString lightBody;
lightBody.appendf("\tvec3 halfDir = vec3(normalize(surfaceToLight + vec3(0, 0, 1)));\n");
lightBody.appendf("\tfloat colorScale = %s * pow(dot(normal, halfDir), %s);\n", ks, shininess);
- lightBody.appendf("\treturn vec4(lightColor * clamp(colorScale, 0.0, 1.0), 1.0);\n");
+ lightBody.appendf("\tvec3 color = lightColor * clamp(colorScale, 0.0, 1.0);\n");
+ lightBody.appendf("\treturn vec4(color, max(max(color.r, color.g), color.b));\n");
builder->emitFunction(GrGLShaderBuilder::kFragment_ShaderType,
kVec4f_GrSLType,
"light",
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index b2733c2..900af8a 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -49,7 +49,7 @@
#endif
static const size_t MAX_TEXTURE_CACHE_COUNT = 2048;
-static const size_t MAX_TEXTURE_CACHE_BYTES = 96 * 1024 * 1024;
+static const size_t MAX_TEXTURE_CACHE_BYTES = GR_DEFAULT_TEXTURE_CACHE_MB_LIMIT * 1024 * 1024;
static const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 15;
static const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4;
diff --git a/src/ports/SkOSFile_stdio.cpp b/src/ports/SkOSFile_stdio.cpp
index 1254394..6c825b4 100644
--- a/src/ports/SkOSFile_stdio.cpp
+++ b/src/ports/SkOSFile_stdio.cpp
@@ -9,8 +9,17 @@
#include "SkOSFile.h"
-#include <stdio.h>
#include <errno.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifdef _WIN32
+#include <direct.h>
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
SkFILE* sk_fopen(const char path[], SkFILE_Flags flags)
{
@@ -98,3 +107,46 @@
::fclose((FILE*)f);
}
+bool sk_exists(const char *path)
+{
+#ifdef _WIN32
+ return (0 == _access(path, 0));
+#else
+ return (0 == access(path, 0));
+#endif
+}
+
+bool sk_isdir(const char *path)
+{
+ struct stat status;
+ if (0 != stat(path, &status)) {
+ return false;
+ }
+ return (status.st_mode & S_IFDIR);
+}
+
+bool sk_mkdir(const char* path)
+{
+ if (sk_isdir(path)) {
+ return true;
+ }
+ if (sk_exists(path)) {
+ fprintf(stderr,
+ "sk_mkdir: path '%s' already exists but is not a directory\n",
+ path);
+ return false;
+ }
+
+ int retval;
+#ifdef _WIN32
+ retval = _mkdir(path);
+#else
+ retval = mkdir(path, 0777);
+#endif
+ if (0 == retval) {
+ return true;
+ } else {
+ fprintf(stderr, "sk_mkdir: error %d creating dir '%s'\n", errno, path);
+ return false;
+ }
+}
diff --git a/tests/StringTest.cpp b/tests/StringTest.cpp
index 5ae718f..2c5026c 100644
--- a/tests/StringTest.cpp
+++ b/tests/StringTest.cpp
@@ -57,10 +57,14 @@
REPORTER_ASSERT(reporter, !a.equals("help"));
REPORTER_ASSERT(reporter, a.startsWith("hell"));
+ REPORTER_ASSERT(reporter, a.startsWith('h'));
REPORTER_ASSERT(reporter, !a.startsWith( "ell"));
+ REPORTER_ASSERT(reporter, !a.startsWith( 'e'));
REPORTER_ASSERT(reporter, a.startsWith(""));
REPORTER_ASSERT(reporter, a.endsWith("llo"));
+ REPORTER_ASSERT(reporter, a.endsWith('o'));
REPORTER_ASSERT(reporter, !a.endsWith("ll" ));
+ REPORTER_ASSERT(reporter, !a.endsWith('l'));
REPORTER_ASSERT(reporter, a.endsWith(""));
REPORTER_ASSERT(reporter, a.contains("he"));
REPORTER_ASSERT(reporter, a.contains("ll"));
@@ -68,6 +72,8 @@
REPORTER_ASSERT(reporter, a.contains("hello"));
REPORTER_ASSERT(reporter, !a.contains("hellohello"));
REPORTER_ASSERT(reporter, a.contains(""));
+ REPORTER_ASSERT(reporter, a.contains('e'));
+ REPORTER_ASSERT(reporter, !a.contains('z'));
SkString e(a);
SkString f("hello");
diff --git a/tools/rebaseline.py b/tools/rebaseline.py
new file mode 100755
index 0000000..f069108
--- /dev/null
+++ b/tools/rebaseline.py
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+
+'''
+Copyright 2012 Google Inc.
+
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+'''
+
+'''
+Rebaselines a single GM test, on all bots and all configurations.
+Must be run from an SVN checkout of the gm-expected directory.
+'''
+
+import os, subprocess, sys, tempfile
+
+pairs = [
+ ['base-shuttle-win7-intel-float',
+ 'Skia_Shuttle_Win7_Intel_Float_Release_32'],
+# ['base-shuttle-win7-intel-angle',
+# 'Skia_Shuttle_Win7_Intel_Float_ANGLE_Release_32'],
+# ['base-shuttle-win7-intel-directwrite',
+# 'Skia_Shuttle_Win7_Intel_Float_DirectWrite_Release_32'],
+ ['base-shuttle_ubuntu12_ati5770',
+ 'Skia_Shuttle_Ubuntu12_ATI5770_Float_Release_64'],
+ ['base-macmini',
+ 'Skia_Mac_Float_Release_32'],
+ ['base-macmini-lion-float',
+ 'Skia_MacMiniLion_Float_Release_32'],
+ ['base-android-galaxy-nexus',
+ 'Skia_GalaxyNexus_4-1_Float_Release_32'],
+ ['base-android-nexus-7',
+ 'Skia_Nexus7_4-1_Float_Release_32'],
+ ['base-android-nexus-s',
+ 'Skia_NexusS_4-1_Float_Release_32'],
+ ['base-android-xoom',
+ 'Skia_Xoom_4-1_Float_Release_32'],
+]
+
+if len(sys.argv) != 2:
+ print 'Usage: ' + os.path.basename(sys.argv[0]) + ' <testname>'
+ exit(1)
+
+testname = sys.argv[1]
+testtypes = [ '4444', '565', '8888', 'gpu', 'pdf' ]
+
+for pair in pairs:
+ print pair[0] + ':'
+ for testtype in testtypes:
+ infilename = testname + '_' + testtype + '.png'
+ print infilename
+
+ url = 'http://skia-autogen.googlecode.com/svn/gm-actual/' + pair[0] + '/' + pair[1] + '/' + pair[0] + '/' + infilename
+ cmd = [ 'curl', '--fail', '--silent', url ]
+ temp = tempfile.NamedTemporaryFile()
+ ret = subprocess.call(cmd, stdout=temp)
+ if ret != 0:
+ print 'Couldn\'t fetch ' + url
+ continue
+ outfilename = os.path.join(pair[0], infilename);
+ cmd = [ 'cp', temp.name, outfilename ]
+ subprocess.call(cmd);
+ cmd = [ 'svn', 'add', '--quiet', outfilename ]
+ subprocess.call(cmd)