Sanitizing source files in Housekeeper-Nightly

git-svn-id: http://skia.googlecode.com/svn/trunk@12427 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
skia.committer@gmail.com 2013-12-02 13:36:22 +00:00
parent 742058f0ca
commit 5b39f5ba9c
126 changed files with 1360 additions and 916 deletions

3
DEPS
View File

@ -10,7 +10,8 @@ use_relative_paths = True
deps = {
# DEPS using https://chromium.googlesource.com are pulled from chromium @ r205199
# (see https://chromium.googlesource.com/chromium/chromium/+/c59bfa8ef877f45bfa859669053859857af1d279)
"third_party/externals/angle" : "https://chromium.googlesource.com/external/angleproject.git",
# NOTE: Angle has been reverted to http://angleproject.googlecode.com/svn/trunk@1268
"third_party/externals/angle" : "https://chromium.googlesource.com/external/angleproject.git@e574e26f48223a6718feab841b4a7720785b497a",
"third_party/externals/fontconfig" : "https://skia.googlesource.com/third_party/fontconfig.git@2.10.93",
"third_party/externals/freetype" : "https://skia.googlesource.com/third_party/freetype2.git@VER-2-5-0-1",
"third_party/externals/gyp" : "https://chromium.googlesource.com/external/gyp.git@d0176c0a2a9e558662905c328c3aa93fd25bbf12",

View File

@ -6,7 +6,6 @@
#include "SkCommandLineFlags.h"
#include "SkForceLinking.h"
#include "SkGraphics.h"
#include "SkString.h"
#include "gm.h"
#include "DMReporter.h"
@ -40,6 +39,19 @@ DEFINE_string(config, "8888 gpu",
__SK_FORCE_IMAGE_DECODER_LINKING;
// Split str on any characters in delimiters into out. (Think, strtok with a sane API.)
static void split(const char* str, const char* delimiters, SkTArray<SkString>* out) {
const char* end = str + strlen(str);
while (str != end) {
// Find a token.
const size_t len = strcspn(str, delimiters);
out->push_back().set(str, len);
str += len;
// Skip any delimiters.
str += strspn(str, delimiters);
}
}
// "FooBar" -> "foobar". Obviously, ASCII only.
static SkString lowercase(SkString s) {
for (size_t i = 0; i < s.size(); i++) {
@ -122,7 +134,7 @@ int tool_main(int argc, char** argv) {
GM::SetResourcePath(FLAGS_resources[0]);
SkTArray<SkString> configs;
for (int i = 0; i < FLAGS_config.count(); i++) {
SkStrSplit(FLAGS_config[i], ", ", &configs);
split(FLAGS_config[i], ", ", &configs);
}
SkTDArray<GMRegistry::Factory> gms;

21
dm/DMComparisonTask.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "DMComparisonTask.h"
#include "DMUtil.h"
namespace DM {
ComparisonTask::ComparisonTask(const Task& parent,
skiagm::Expectations expectations,
SkBitmap bitmap)
: Task(parent)
, fName(parent.name()) // Masquerade as parent so failures are attributed to it.
, fExpectations(expectations)
, fBitmap(bitmap)
{}
void ComparisonTask::draw() {
if (!MeetsExpectations(fExpectations, fBitmap)) {
this->fail();
}
}
} // namespace DM

31
dm/DMComparisonTask.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef DMComparisonTask_DEFINED
#define DMComparisonTask_DEFINED
#include "DMTask.h"
#include "SkBitmap.h"
#include "SkString.h"
#include "gm_expectations.h"
namespace DM {
// We use ComparisonTask to move CPU-bound comparison work of GpuTasks back to
// the main thread pool, where we probably have more threads available.
class ComparisonTask : public Task {
public:
ComparisonTask(const Task& parent, skiagm::Expectations, SkBitmap);
virtual void draw() SK_OVERRIDE;
virtual bool usesGpu() const SK_OVERRIDE { return false; }
virtual bool shouldSkip() const SK_OVERRIDE { return false; }
virtual SkString name() const SK_OVERRIDE { return fName; }
private:
const SkString fName;
const skiagm::Expectations fExpectations;
const SkBitmap fBitmap;
};
} // namespace DM
#endif // DMComparisonTask_DEFINED

View File

@ -1,9 +1,7 @@
#include "DMCpuTask.h"
#include "DMChecksumTask.h"
#include "DMPipeTask.h"
#include "DMReplayTask.h"
#include "DMSerializeTask.h"
#include "DMTileGridTask.h"
#include "DMUtil.h"
#include "DMWriteTask.h"
@ -32,19 +30,19 @@ void CpuTask::draw() {
fGM->draw(&canvas);
canvas.flush();
#define SPAWN(ChildTask, ...) this->spawnChild(SkNEW_ARGS(ChildTask, (*this, __VA_ARGS__)))
SPAWN(ChecksumTask, fExpectations, bitmap);
if (!MeetsExpectations(fExpectations, bitmap)) {
this->fail();
}
SPAWN(PipeTask, fGMFactory(NULL), bitmap, false, false);
SPAWN(PipeTask, fGMFactory(NULL), bitmap, true, false);
SPAWN(PipeTask, fGMFactory(NULL), bitmap, true, true);
SPAWN(ReplayTask, fGMFactory(NULL), bitmap, false);
SPAWN(ReplayTask, fGMFactory(NULL), bitmap, true);
SPAWN(SerializeTask, fGMFactory(NULL), bitmap);
SPAWN(TileGridTask, fGMFactory(NULL), bitmap, SkISize::Make(16,16));
this->spawnChild(SkNEW_ARGS(PipeTask, (*this, fGMFactory(NULL), bitmap, false, false)));
this->spawnChild(SkNEW_ARGS(PipeTask, (*this, fGMFactory(NULL), bitmap, true, false)));
this->spawnChild(SkNEW_ARGS(PipeTask, (*this, fGMFactory(NULL), bitmap, true, true)));
SPAWN(WriteTask, bitmap);
#undef SPAWN
this->spawnChild(SkNEW_ARGS(ReplayTask, (*this, fGMFactory(NULL), bitmap, true)));
this->spawnChild(SkNEW_ARGS(ReplayTask, (*this, fGMFactory(NULL), bitmap, false)));
this->spawnChild(SkNEW_ARGS(SerializeTask, (*this, fGMFactory(NULL), bitmap)));
this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
}
bool CpuTask::shouldSkip() const {

View File

@ -1,6 +1,6 @@
#include "DMGpuTask.h"
#include "DMChecksumTask.h"
#include "DMComparisonTask.h"
#include "DMUtil.h"
#include "DMWriteTask.h"
#include "SkCommandLineFlags.h"
@ -60,7 +60,9 @@ void GpuTask::draw() {
gr->printCacheStats();
#endif
this->spawnChild(SkNEW_ARGS(ChecksumTask, (*this, fExpectations, bitmap)));
// We offload checksum comparison to the main CPU threadpool.
// This cuts run time by about 30%.
this->spawnChild(SkNEW_ARGS(ComparisonTask, (*this, fExpectations, bitmap)));
this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
}

View File

@ -6,7 +6,7 @@
#include "SkCommandLineFlags.h"
#include "SkGPipe.h"
DEFINE_bool(pipe, true, "If true, check several pipe variants against the reference bitmap.");
DEFINE_bool(pipe, false, "If true, check several pipe variants against the reference bitmap.");
namespace DM {

View File

@ -5,8 +5,8 @@
#include "SkCommandLineFlags.h"
#include "SkPicture.h"
DEFINE_bool(replay, true, "If true, run picture replay tests.");
DEFINE_bool(rtree, true, "If true, run picture replay tests with an rtree.");
DEFINE_bool(replay, false, "If true, run picture replay tests.");
DEFINE_bool(rtree, false, "If true, run picture replay tests with an rtree.");
namespace DM {

View File

@ -15,8 +15,8 @@ class ReplayTask : public Task {
public:
ReplayTask(const Task& parent, // ReplayTask must be a child task. Pass its parent here.
skiagm::GM*, // GM to run through a picture. Takes ownership.
SkBitmap reference, // Bitmap to compare picture replay results to.
skiagm::GM*, // GM to run through a pipe. Takes ownership.
SkBitmap reference, // Bitmap to compare pipe results to.
bool useRTree); // Record with an RTree?
virtual void draw() SK_OVERRIDE;

View File

@ -12,7 +12,7 @@ void Reporter::updateStatusLine() const {
}
SkString status;
status.printf("\r\033[K%d tasks left", this->started() - this->finished());
status.printf("\r\033[K%d / %d", this->finished(), this->started());
const int failed = this->failed();
if (failed > 0) {
status.appendf(", %d failed", failed);

View File

@ -6,7 +6,7 @@
#include "SkPicture.h"
#include "SkPixelRef.h"
DEFINE_bool(serialize, true, "If true, run picture serialization tests.");
DEFINE_bool(serialize, false, "If true, run picture serialization tests.");
namespace DM {

View File

@ -8,15 +8,14 @@
namespace DM {
Task::Task(Reporter* reporter, TaskRunner* taskRunner)
: fReporter(reporter), fTaskRunner(taskRunner), fDepth(0) {
: fReporter(reporter), fTaskRunner(taskRunner) {
fReporter->start();
}
Task::Task(const Task& parent)
: INHERITED(parent)
, fReporter(parent.fReporter)
, fTaskRunner(parent.fTaskRunner)
, fDepth(parent.depth()+1) {
Task::Task(const Task& that)
: INHERITED(that)
, fReporter(that.fReporter)
, fTaskRunner(that.fTaskRunner) {
fReporter->start();
}

View File

@ -18,7 +18,7 @@ class TaskRunner;
class Task : public SkRunnable {
public:
Task(Reporter* reporter, TaskRunner* taskRunner);
Task(const Task& parent);
Task(const Task& that);
virtual ~Task();
void run() SK_OVERRIDE;
@ -28,10 +28,6 @@ public:
virtual bool shouldSkip() const = 0;
virtual SkString name() const = 0;
// Returns the number of parents above this task.
// Top-level tasks return 0, their children 1, and so on.
int depth() const { return fDepth; }
protected:
void spawnChild(Task* task);
void fail();
@ -40,7 +36,6 @@ private:
// Both unowned.
Reporter* fReporter;
TaskRunner* fTaskRunner;
int fDepth;
typedef SkRunnable INHERITED;
};

View File

@ -15,9 +15,18 @@ SkString Png(SkString s) {
return s;
}
bool MeetsExpectations(const skiagm::Expectations& expectations, const SkBitmap bitmap) {
if (expectations.ignoreFailure() || expectations.empty()) {
return true;
}
const skiagm::GmResultDigest digest(bitmap);
return expectations.match(digest);
}
void RecordPicture(skiagm::GM* gm, SkPicture* picture, uint32_t recordFlags) {
const SkISize size = gm->getISize();
SkCanvas* canvas = picture->beginRecording(size.width(), size.height(), recordFlags);
SkCanvas* canvas = picture->beginRecording(SkScalarCeilToInt(gm->width()),
SkScalarCeilToInt(gm->height()),
recordFlags);
canvas->concat(gm->getInitialTransform());
gm->draw(canvas);
canvas->flush();
@ -25,8 +34,7 @@ void RecordPicture(skiagm::GM* gm, SkPicture* picture, uint32_t recordFlags) {
}
void SetupBitmap(const SkBitmap::Config config, skiagm::GM* gm, SkBitmap* bitmap) {
const SkISize size = gm->getISize();
bitmap->setConfig(config, size.width(), size.height());
bitmap->setConfig(config, SkScalarCeilToInt(gm->width()), SkScalarCeilToInt(gm->height()));
bitmap->allocPixels();
bitmap->eraseColor(0x00000000);
}

View File

@ -15,6 +15,9 @@ SkString UnderJoin(const char* a, const char* b);
// Png("a") -> "a.png"
SkString Png(SkString s);
// Roughly, expectations.match(GmResultDigest(bitmap)), but calculates the digest lazily.
bool MeetsExpectations(const skiagm::Expectations& expectations, const SkBitmap bitmap);
// Draw gm to picture. Passes recordFlags to SkPicture::beginRecording().
void RecordPicture(skiagm::GM* gm, SkPicture* picture, uint32_t recordFlags = 0);

View File

@ -3,54 +3,41 @@
#include "DMUtil.h"
#include "SkCommandLineFlags.h"
#include "SkImageEncoder.h"
#include "SkString.h"
#include <string.h>
DEFINE_string2(writePath, w, "", "If set, write GMs here as .pngs.");
namespace DM {
WriteTask::WriteTask(const Task& parent, SkBitmap bitmap) : Task(parent), fBitmap(bitmap) {
const int suffixes = parent.depth() + 1;
const char* name = parent.name().c_str();
SkTArray<SkString> split;
SkStrSplit(name, "_", &split);
int totalSuffixLength = 0;
for (int i = 0; i < suffixes; i++) {
// We're splitting off suffixes from the back to front.
fSuffixes.push_back(split[split.count()-i-1]);
totalSuffixLength += fSuffixes.back().size() + 1;
}
fGmName.set(name, strlen(name)-totalSuffixLength);
}
WriteTask::WriteTask(const Task& parent, SkBitmap bitmap)
: Task(parent)
, fBitmap(bitmap) {
// Split parent's name <gmName>_<config> into gmName and config.
const char* parentName = parent.name().c_str();
const char* fromLastUnderscore = strrchr(parentName, '_');
const ptrdiff_t gmNameLength = fromLastUnderscore - parentName;
void WriteTask::makeDirOrFail(SkString dir) {
if (!sk_mkdir(dir.c_str())) {
this->fail();
}
fConfig.set(fromLastUnderscore+1);
fGmName.set(parentName, gmNameLength);
}
void WriteTask::draw() {
SkString dir(FLAGS_writePath[0]);
this->makeDirOrFail(dir);
for (int i = 0; i < fSuffixes.count(); i++) {
dir = SkOSPath::SkPathJoin(dir.c_str(), fSuffixes[i].c_str());
this->makeDirOrFail(dir);
}
if (!SkImageEncoder::EncodeFile(Png(SkOSPath::SkPathJoin(dir.c_str(), fGmName.c_str())).c_str(),
const char* root = FLAGS_writePath[0];
const SkString dir = SkOSPath::SkPathJoin(root, fConfig.c_str());
if (!sk_mkdir(root) ||
!sk_mkdir(dir.c_str()) ||
!SkImageEncoder::EncodeFile(Png(SkOSPath::SkPathJoin(dir.c_str(), fGmName.c_str())).c_str(),
fBitmap,
SkImageEncoder::kPNG_Type,
100/*quality*/)) {
100/*quality*/))
{
this->fail();
}
}
SkString WriteTask::name() const {
SkString name("writing ");
for (int i = 0; i < fSuffixes.count(); i++) {
name.appendf("%s/", fSuffixes[i].c_str());
}
name.append(fGmName.c_str());
return name;
return SkStringPrintf("writing %s/%s.png", fConfig.c_str(), fGmName.c_str());
}
bool WriteTask::shouldSkip() const {

View File

@ -4,7 +4,6 @@
#include "DMTask.h"
#include "SkBitmap.h"
#include "SkString.h"
#include "SkTArray.h"
// Writes a bitmap to a file.
@ -13,8 +12,7 @@ namespace DM {
class WriteTask : public Task {
public:
WriteTask(const Task& parent, // WriteTask must be a child Task. Pass its parent here.
SkBitmap bitmap); // Bitmap to write.
WriteTask(const Task& parent, SkBitmap bitmap);
virtual void draw() SK_OVERRIDE;
virtual bool usesGpu() const SK_OVERRIDE { return false; }
@ -22,11 +20,9 @@ public:
virtual SkString name() const SK_OVERRIDE;
private:
SkTArray<SkString> fSuffixes;
SkString fConfig;
SkString fGmName;
const SkBitmap fBitmap;
void makeDirOrFail(SkString dir);
};
} // namespace DM

View File

@ -7,6 +7,7 @@ Current approximate list of missing features:
--writePicturePath
--deferred
--tiledGrid
DM's design is based around Tasks and a TaskRunner.

View File

@ -2095,18 +2095,24 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
16101291896048576683
2789357359936426897
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
6958362917585628191
11420474396559742656
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -2095,18 +2095,24 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
16101291896048576683
2789357359936426897
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
6958362917585628191
11420474396559742656
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -2634,27 +2634,36 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
7789211976036245847
2481797737367594615
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
12063547141229638542
8086938262113983689
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
8512582036956628519
10512095643464253945
]
],
"bugs": [
1759
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -2634,28 +2634,37 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
7789211976036245847
2481797737367594615
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
12063547141229638542
8086938262113983689
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
8512582036956628519
10512095643464253945
]
],
"reviewed-by-human": true
"bugs": [
1759
],
"reviewed-by-human": false
},
"complexclip2_565.png": {
"allowed-digests": [

View File

@ -3214,36 +3214,48 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
16101291896048576683
2789357359936426897
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
6958362917585628191
11420474396559742656
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
17182697123061500145
12902148816415894358
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_msaa4.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
17182697123061500145
12902148816415894358
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -3214,36 +3214,48 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
16101291896048576683
2789357359936426897
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
6958362917585628191
11420474396559742656
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
17182697123061500145
12902148816415894358
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_msaa4.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
17182697123061500145
12902148816415894358
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -2437,27 +2437,36 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
16101291896048576683
2789357359936426897
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
6958362917585628191
11420474396559742656
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
829525110335272310
6811779909537199081
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -2437,27 +2437,36 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
16101291896048576683
2789357359936426897
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
6958362917585628191
11420474396559742656
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
829525110335272310
6811779909537199081
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -2125,18 +2125,24 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
7322753158848112633
2407516010050573816
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
13587257461703619696
5735401648209592903
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -2125,18 +2125,24 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
7322753158848112633
2407516010050573816
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
13587257461703619696
5735401648209592903
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -2485,27 +2485,36 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
7322753158848112633
2407516010050573816
]
],
"bugs": [
1759
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
13587257461703619696
5735401648209592903
]
],
"bugs": [
1759
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
10584626711301986223
16722577663537717052
]
],
"bugs": [
1759
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -2485,28 +2485,37 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
7322753158848112633
2407516010050573816
]
],
"reviewed-by-human": true
"bugs": [
1759
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
13587257461703619696
5735401648209592903
]
],
"reviewed-by-human": true
"bugs": [
1759
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
10584626711301986223
16722577663537717052
]
],
"reviewed-by-human": true
"bugs": [
1759
],
"reviewed-by-human": false
},
"complexclip2_565.png": {
"allowed-digests": [

View File

@ -1900,19 +1900,25 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
4055619075226987340
10175733445319554072
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
4557992853592297566
2036989462359391258
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {
"allowed-digests": [

View File

@ -1900,18 +1900,24 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
4055619075226987340
10175733445319554072
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
4557992853592297566
2036989462359391258
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -1900,19 +1900,25 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
4723751871359287410
7633944210736451677
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
16275740961157987318
2594983628740042115
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {
"allowed-digests": [

View File

@ -1900,18 +1900,24 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
4723751871359287410
7633944210736451677
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
16275740961157987318
2594983628740042115
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -1900,18 +1900,24 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
4055619075226987340
10175733445319554072
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
4557992853592297566
2036989462359391258
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -1900,18 +1900,24 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
4055619075226987340
10175733445319554072
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
4557992853592297566
2036989462359391258
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"complexclip2_565.png": {

View File

@ -4588,9 +4588,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
15826989673456070846
3224501961775566147
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-mac.png": {

View File

@ -4048,9 +4048,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
15826989673456070846
3224501961775566147
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-mac.png": {

View File

@ -4588,10 +4588,13 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
15826989673456070846
3224501961775566147
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-mac.png": {
"allowed-digests": [

View File

@ -3724,9 +3724,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
15826989673456070846
3224501961775566147
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-mac.png": {

View File

@ -4927,9 +4927,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
15826989673456070846
3224501961775566147
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-mac.png": {

View File

@ -4483,10 +4483,13 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
15826989673456070846
3224501961775566147
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-mac.png": {
"allowed-digests": [

View File

@ -4927,9 +4927,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
15826989673456070846
3224501961775566147
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-mac.png": {

View File

@ -4075,9 +4075,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
15826989673456070846
3224501961775566147
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-mac.png": {

View File

@ -4789,10 +4789,13 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
15826989673456070846
3224501961775566147
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-mac.png": {
"allowed-digests": [

View File

@ -4513,9 +4513,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
15826989673456070846
3224501961775566147
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-mac.png": {

View File

@ -4789,9 +4789,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
15826989673456070846
3224501961775566147
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-mac.png": {

View File

@ -4378,9 +4378,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
15826989673456070846
3224501961775566147
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-mac.png": {

View File

@ -3502,27 +3502,36 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
14602262721761630857
11405847735693538070
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
3481217777013051559
4978814888142061167
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
16802525720487425080
10275865613222220507
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {

View File

@ -3502,27 +3502,36 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
14602262721761630857
11405847735693538070
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
3481217777013051559
4978814888142061167
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
16802525720487425080
10275865613222220507
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {

View File

@ -3502,28 +3502,37 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
14602262721761630857
11405847735693538070
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
3481217777013051559
4978814888142061167
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
16802525720487425080
10275865613222220507
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {
"allowed-digests": [

View File

@ -3502,27 +3502,36 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
14602262721761630857
11405847735693538070
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
3481217777013051559
4978814888142061167
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
16802525720487425080
10275865613222220507
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {

View File

@ -3142,18 +3142,24 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
14602262721761630857
11405847735693538070
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
3481217777013051559
4978814888142061167
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {

View File

@ -3832,28 +3832,37 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
14602262721761630857
11405847735693538070
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_8888.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
3481217777013051559
4978814888142061167
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
16802525720487425080
1439955102723765584
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {
"allowed-digests": [

View File

@ -1149,11 +1149,9 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
12587234088162094708
8745200028676261652
]
],
"ignore-failure": true,
"reviewed-by-human": true
]
},
"bleed_gpu.png": {
"allowed-digests": [
@ -4686,18 +4684,24 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
16744651928576717976
11235313591528676486
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
16744651928576717976
11235313591528676486
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {
@ -5936,8 +5940,10 @@
12241316569839901585
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"downsamplebitmap_checkerboard_high_512_256_gpu.png": {
"allowed-digests": [
@ -6054,8 +6060,10 @@
12241316569839901585
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
"allowed-digests": [
@ -6172,8 +6180,10 @@
13919524755191883787
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"downsamplebitmap_image_high_mandrill_512.png_gpu.png": {
"allowed-digests": [
@ -6290,8 +6300,10 @@
13919524755191883787
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
"allowed-digests": [
@ -6408,8 +6420,10 @@
3631077966779184085
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"downsamplebitmap_text_high_72.00pt_gpu.png": {
"allowed-digests": [
@ -6526,8 +6540,10 @@
3631077966779184085
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"downsamplebitmap_text_medium_72.00pt_gpu.png": {
"allowed-digests": [
@ -7166,8 +7182,10 @@
8650483291288564728
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"filterbitmap_checkerboard_192_192_gpu.png": {
"allowed-digests": [
@ -7584,8 +7602,10 @@
7154075947687660440
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"filterbitmap_image_mandrill_256.png_gpu.png": {
"allowed-digests": [
@ -7702,8 +7722,10 @@
14830136006359090292
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"filterbitmap_image_mandrill_512.png_gpu.png": {
"allowed-digests": [

View File

@ -3541,9 +3541,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
14984702717513096997
2373323581539004655
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {

View File

@ -3523,9 +3523,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
16744651928576717976
11235313591528676486
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {

View File

@ -1149,11 +1149,9 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
12587234088162094708
8745200028676261652
]
],
"ignore-failure": true,
"reviewed-by-human": true
]
},
"bleed_gpu.png": {
"allowed-digests": [
@ -4686,18 +4684,24 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
16744651928576717976
11235313591528676486
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_gpu.png": {
"allowed-digests": [
[
"bitmap-64bitMD5",
16744651928576717976
11235313591528676486
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {
@ -5936,8 +5940,10 @@
12241316569839901585
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"downsamplebitmap_checkerboard_high_512_256_gpu.png": {
"allowed-digests": [
@ -6054,8 +6060,10 @@
12241316569839901585
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
"allowed-digests": [
@ -6172,8 +6180,10 @@
13919524755191883787
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"downsamplebitmap_image_high_mandrill_512.png_gpu.png": {
"allowed-digests": [
@ -6290,8 +6300,10 @@
13919524755191883787
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
"allowed-digests": [
@ -6408,8 +6420,10 @@
3631077966779184085
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"downsamplebitmap_text_high_72.00pt_gpu.png": {
"allowed-digests": [
@ -6526,8 +6540,10 @@
3631077966779184085
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"downsamplebitmap_text_medium_72.00pt_gpu.png": {
"allowed-digests": [
@ -7166,8 +7182,10 @@
8650483291288564728
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"filterbitmap_checkerboard_192_192_gpu.png": {
"allowed-digests": [
@ -7584,8 +7602,10 @@
7154075947687660440
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"filterbitmap_image_mandrill_256.png_gpu.png": {
"allowed-digests": [
@ -7702,8 +7722,10 @@
14830136006359090292
]
],
"ignore-failure": true,
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"filterbitmap_image_mandrill_512.png_gpu.png": {
"allowed-digests": [

View File

@ -3541,10 +3541,13 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
13257802686942423930
7353287899127074472
]
],
"reviewed-by-human": true
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {
"allowed-digests": [

View File

@ -3523,9 +3523,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
16744651928576717976
11235313591528676486
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {

View File

@ -3523,9 +3523,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
16744651928576717976
11235313591528676486
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {

View File

@ -3523,9 +3523,12 @@
"allowed-digests": [
[
"bitmap-64bitMD5",
16744651928576717976
11235313591528676486
]
],
"bugs": [
1578
],
"reviewed-by-human": false
},
"colortype_pdf-poppler.png": {

View File

@ -11,6 +11,7 @@ namespace skiagm {
static const char* gConfigNames[] = {
"unknown config",
"A1",
"A8",
"Index8",
"565",

View File

@ -47,6 +47,7 @@ static SkScalar draw_set(SkCanvas* c, const SkBitmap& bm, SkScalar x,
static const char* gConfigNames[] = {
"unknown config",
"A1",
"A8",
"Index8",
"565",

View File

@ -19,10 +19,8 @@ import posixpath
import re
import shutil
import socket
import subprocess
import sys
import thread
import threading
import time
import urlparse
@ -44,6 +42,8 @@ import results
ACTUALS_SVN_REPO = 'http://skia-autogen.googlecode.com/svn/gm-actual'
PATHSPLIT_RE = re.compile('/([^/]+)/(.+)')
TRUNK_DIRECTORY = os.path.dirname(os.path.dirname(os.path.dirname(
os.path.realpath(__file__))))
EXPECTATIONS_DIR = os.path.join(TRUNK_DIRECTORY, 'expectations', 'gm')
GENERATED_IMAGES_ROOT = os.path.join(PARENT_DIRECTORY, 'static',
'generated-images')
@ -67,29 +67,6 @@ _HTTP_HEADER_CONTENT_TYPE = 'Content-Type'
_SERVER = None # This gets filled in by main()
def _run_command(args, directory):
"""Runs a command and returns stdout as a single string.
Args:
args: the command to run, as a list of arguments
directory: directory within which to run the command
Returns: stdout, as a string
Raises an Exception if the command failed (exited with nonzero return code).
"""
logging.debug('_run_command: %s in directory %s' % (args, directory))
proc = subprocess.Popen(args, cwd=directory,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(stdout, stderr) = proc.communicate()
if proc.returncode is not 0:
raise Exception('command "%s" failed in dir "%s": %s' %
(args, directory, stderr))
return stdout
def _get_routable_ip_address():
"""Returns routable IP address of this host (the IP address of its network
interface that would be used for most traffic, not its localhost
@ -100,7 +77,6 @@ def _get_routable_ip_address():
sock.close()
return host
def _create_svn_checkout(dir_path, repo_url):
"""Creates local checkout of an SVN repository at the specified directory
path, returning an svn.Svn object referring to the local checkout.
@ -144,87 +120,69 @@ class Server(object):
self._actuals_repo = _create_svn_checkout(
dir_path=actuals_dir, repo_url=ACTUALS_SVN_REPO)
# Reentrant lock that must be held whenever updating EITHER of:
# 1. self._results
# 2. the expected or actual results on local disk
self.results_rlock = threading.RLock()
# self._results will be filled in by calls to update_results()
self._results = None
# We only update the expectations dir if the server was run with a
# nonzero --reload argument; otherwise, we expect the user to maintain
# her own expectations as she sees fit.
#
# TODO(epoger): Use git instead of svn to update the expectations dir, since
# the Skia repo is moving to git.
# When we make that change, we will have to update the entire workspace,
# not just the expectations dir, because git only operates on the repo
# as a whole.
# And since Skia uses depot_tools to manage its dependencies, we will have
# to run "gclient sync" rather than a raw "git pull".
if reload_seconds:
self._expectations_repo = svn.Svn(EXPECTATIONS_DIR)
else:
self._expectations_repo = None
@property
def results(self):
""" Returns the most recently generated results, or None if update_results()
has not been called yet. """
return self._results
@property
def is_exported(self):
""" Returns true iff HTTP clients on other hosts are allowed to access
this server. """
return self._export
@property
def is_editable(self):
""" Returns true iff HTTP clients are allowed to submit new baselines. """
return self._editable
@property
def reload_seconds(self):
""" Returns the result reload period in seconds, or 0 if we don't reload
results. """
return self._reload_seconds
def update_results(self):
""" Create or update self._results, based on the expectations in
""" Create or update self.results, based on the expectations in
EXPECTATIONS_DIR and the latest actuals from skia-autogen.
We hold self.results_rlock while we do this, to guarantee that no other
thread attempts to update either self._results or the underlying files at
the same time.
"""
with self.results_rlock:
logging.info('Updating actual GM results in %s from SVN repo %s ...' % (
self._actuals_dir, ACTUALS_SVN_REPO))
self._actuals_repo.Update('.')
# We only update the expectations dir if the server was run with a
# nonzero --reload argument; otherwise, we expect the user to maintain
# her own expectations as she sees fit.
#
# Because the Skia repo is moving from SVN to git, and git does not
# support updating a single directory tree, we have to update the entire
# repo checkout.
#
# Because Skia uses depot_tools, we have to update using "gclient sync"
# instead of raw git (or SVN) update. Happily, this will work whether
# the checkout was created using git or SVN.
if self._reload_seconds:
logging.info(
'Updating expected GM results in %s by syncing Skia repo ...' %
EXPECTATIONS_DIR)
_run_command(['gclient', 'sync'], TRUNK_DIRECTORY)
logging.info('Updating actual GM results in %s from SVN repo %s ...' % (
self._actuals_dir, ACTUALS_SVN_REPO))
self._actuals_repo.Update('.')
if self._expectations_repo:
logging.info(
'Updating expected GM results in %s ...' % EXPECTATIONS_DIR)
self._expectations_repo.Update('.')
logging.info(
('Parsing results from actuals in %s and expectations in %s, '
+ 'and generating pixel diffs (may take a while) ...') % (
self._actuals_dir, EXPECTATIONS_DIR))
self._results = results.Results(
actuals_root=self._actuals_dir,
expected_root=EXPECTATIONS_DIR,
generated_images_root=GENERATED_IMAGES_ROOT)
+ 'and generating pixel diffs (may take a while) ...') % (
self._actuals_dir, EXPECTATIONS_DIR))
self.results = results.Results(
actuals_root=self._actuals_dir,
expected_root=EXPECTATIONS_DIR,
generated_images_root=GENERATED_IMAGES_ROOT)
def _result_reloader(self):
""" Reload results at the appropriate interval. This never exits, so it
should be run in its own thread.
""" If --reload argument was specified, reload results at the appropriate
interval.
"""
while True:
while self._reload_seconds:
time.sleep(self._reload_seconds)
self.update_results()
def run(self):
self.update_results()
if self._reload_seconds:
thread.start_new_thread(self._result_reloader, ())
thread.start_new_thread(self._result_reloader, ())
if self._export:
server_address = ('', self._port)
@ -298,9 +256,9 @@ class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
# We only return these timestamps if the --reload argument was passed;
# otherwise, we have no idea when the expectations were last updated
# (we allow the user to maintain her own expectations as she sees fit).
'timeUpdated': time_updated if _SERVER.reload_seconds else None,
'timeUpdated': time_updated if _SERVER.reload_seconds() else None,
'timeNextUpdateAvailable': (
(time_updated+_SERVER.reload_seconds) if _SERVER.reload_seconds
(time_updated+_SERVER.reload_seconds()) if _SERVER.reload_seconds()
else None),
# The type we passed to get_results_of_type()
@ -311,10 +269,10 @@ class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
'dataHash': str(hash(repr(response_dict['testData']))),
# Whether the server will accept edits back.
'isEditable': _SERVER.is_editable,
'isEditable': _SERVER.is_editable(),
# Whether the service is accessible from other hosts.
'isExported': _SERVER.is_exported,
'isExported': _SERVER.is_exported(),
}
self.send_json_dict(response_dict)
except:
@ -385,7 +343,7 @@ class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
Raises an Exception if there were any problems.
"""
if not _SERVER.is_editable:
if not _SERVER.is_editable():
raise Exception('this server is not running in --editable mode')
content_type = self.headers[_HTTP_HEADER_CONTENT_TYPE]
@ -399,23 +357,22 @@ class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
logging.debug('do_POST_edits: received new GM expectations data [%s]' %
data)
# Update the results on disk with the information we received from the
# client.
# We must hold _SERVER.results_rlock while we do this, to guarantee that
# no other thread updates expectations (from the Skia repo) while we are
# updating them (using the info we received from the client).
with _SERVER.results_rlock:
oldResultsType = data['oldResultsType']
oldResults = _SERVER.results.get_results_of_type(oldResultsType)
oldResultsHash = str(hash(repr(oldResults['testData'])))
if oldResultsHash != data['oldResultsHash']:
raise Exception('results of type "%s" changed while the client was '
'making modifications. The client should reload the '
'results and submit the modifications again.' %
oldResultsType)
_SERVER.results.edit_expectations(data['modifications'])
# Read the updated results back from disk.
_SERVER.update_results()
# Since we must make multiple calls to the Results object, grab a
# reference to it in case it is updated to point at a new Results
# object within another thread.
results_obj = _SERVER.results
oldResultsType = data['oldResultsType']
oldResults = results_obj.get_results_of_type(oldResultsType)
oldResultsHash = str(hash(repr(oldResults['testData'])))
if oldResultsHash != data['oldResultsHash']:
raise Exception('results of type "%s" changed while the client was '
'making modifications. The client should reload the '
'results and submit the modifications again.' %
oldResultsType)
results_obj.edit_expectations(data['modifications'])
# Now that the edits have been committed, update results to reflect them.
_SERVER.update_results()
def redirect_to(self, url):
""" Redirect the HTTP client to a different url.
@ -488,8 +445,7 @@ def main():
parser.add_argument('--reload', type=int,
help=('How often (a period in seconds) to update the '
'results. If specified, both expected and actual '
'results will be updated by running "gclient sync" '
'on your Skia checkout as a whole. '
'results will be updated. '
'By default, we do not reload at all, and you '
'must restart the server to pick up new data.'),
default=0)
@ -500,6 +456,5 @@ def main():
reload_seconds=args.reload)
_SERVER.run()
if __name__ == '__main__':
main()

View File

@ -4,30 +4,9 @@
'conditions': [
[ 'skia_angle', {
'target_defaults': {
'include_dirs': [
'$(DXSDK_DIR)/Include',
],
'msvs_settings': {
'VCLinkerTool': {
'conditions': [
[ 'skia_arch_width == 32 ', {
'AdditionalLibraryDirectories': [
'$(DXSDK_DIR)/Lib/x86',
],
},{
'AdditionalLibraryDirectories': [
'$(DXSDK_DIR)/Lib/x64',
],
}],
],
},
},
'defines': [
'NOMINMAX',
],
'defines/': [
['exclude', 'ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES'],
],
},
'variables': {
'component': 'static_library',

View File

@ -13,89 +13,14 @@
'../src/effects',
'../src/utils',
],
'includes': [
'bench.gypi'
],
'dependencies': [
'skia_lib.gyp:skia_lib',
'bench_timer',
'flags.gyp:flags',
],
'sources': [
'../bench/AAClipBench.cpp',
'../bench/BicubicBench.cpp',
'../bench/BitmapBench.cpp',
'../bench/BitmapRectBench.cpp',
'../bench/BitmapScaleBench.cpp',
'../bench/BlurBench.cpp',
'../bench/BlurImageFilterBench.cpp',
'../bench/BlurRectBench.cpp',
'../bench/BlurRoundRectBench.cpp',
'../bench/ChartBench.cpp',
'../bench/ChecksumBench.cpp',
'../bench/ChromeBench.cpp',
'../bench/CmapBench.cpp',
'../bench/ColorFilterBench.cpp',
'../bench/CoverageBench.cpp',
'../bench/DashBench.cpp',
'../bench/DecodeBench.cpp',
'../bench/DeferredCanvasBench.cpp',
'../bench/DeferredSurfaceCopyBench.cpp',
'../bench/DisplacementBench.cpp',
'../bench/FSRectBench.cpp',
'../bench/FontCacheBench.cpp',
'../bench/FontScalerBench.cpp',
'../bench/GameBench.cpp',
'../bench/GrMemoryPoolBench.cpp',
'../bench/GrResourceCacheBench.cpp',
'../bench/GradientBench.cpp',
'../bench/HairlinePathBench.cpp',
'../bench/ImageCacheBench.cpp',
'../bench/ImageDecodeBench.cpp',
'../bench/InterpBench.cpp',
'../bench/LightingBench.cpp',
'../bench/LineBench.cpp',
'../bench/MagnifierBench.cpp',
'../bench/MathBench.cpp',
'../bench/Matrix44Bench.cpp',
'../bench/MatrixBench.cpp',
'../bench/MatrixConvolutionBench.cpp',
'../bench/MemoryBench.cpp',
'../bench/MemsetBench.cpp',
'../bench/MergeBench.cpp',
'../bench/MorphologyBench.cpp',
'../bench/MutexBench.cpp',
'../bench/PathBench.cpp',
'../bench/PathIterBench.cpp',
'../bench/PathUtilsBench.cpp',
'../bench/PerlinNoiseBench.cpp',
'../bench/PicturePlaybackBench.cpp',
'../bench/PictureRecordBench.cpp',
'../bench/PremulAndUnpremulAlphaOpsBench.cpp',
'../bench/RTreeBench.cpp',
'../bench/ReadPixBench.cpp',
'../bench/RectBench.cpp',
'../bench/RectoriBench.cpp',
'../bench/RefCntBench.cpp',
'../bench/RegionBench.cpp',
'../bench/RegionContainBench.cpp',
'../bench/RepeatTileBench.cpp',
'../bench/ScalarBench.cpp',
'../bench/ShaderMaskBench.cpp',
'../bench/SkipZeroesBench.cpp',
'../bench/SortBench.cpp',
'../bench/StrokeBench.cpp',
'../bench/TableBench.cpp',
'../bench/TextBench.cpp',
'../bench/TileBench.cpp',
'../bench/VertBench.cpp',
'../bench/WritePixelsBench.cpp',
'../bench/WriterBench.cpp',
'../bench/XfermodeBench.cpp',
'../bench/SkBenchLogger.cpp',
'../bench/SkBenchLogger.h',
'../bench/SkBenchmark.cpp',
'../bench/SkBenchmark.h',
'../bench/benchmain.cpp',
],
'conditions': [
['skia_gpu == 1',
{

88
gyp/bench.gypi Normal file
View File

@ -0,0 +1,88 @@
# sources and conditions used in skia's bench.gyp and chromium's skia.gyp
#
{
'sources': [
'../bench/benchmain.cpp',
'../bench/SkBenchmark.h',
'../bench/SkBenchmark.cpp',
'../bench/AAClipBench.cpp',
'../bench/BicubicBench.cpp',
'../bench/BitmapBench.cpp',
'../bench/BitmapRectBench.cpp',
'../bench/BitmapScaleBench.cpp',
'../bench/BlurBench.cpp',
'../bench/BlurImageFilterBench.cpp',
'../bench/BlurRectBench.cpp',
'../bench/BlurRoundRectBench.cpp',
'../bench/ChecksumBench.cpp',
'../bench/ChartBench.cpp',
'../bench/ChromeBench.cpp',
'../bench/CmapBench.cpp',
'../bench/ColorFilterBench.cpp',
'../bench/CoverageBench.cpp',
'../bench/DashBench.cpp',
'../bench/DecodeBench.cpp',
'../bench/DeferredCanvasBench.cpp',
'../bench/DeferredSurfaceCopyBench.cpp',
'../bench/DisplacementBench.cpp',
'../bench/FontCacheBench.cpp',
'../bench/FontScalerBench.cpp',
'../bench/FSRectBench.cpp',
'../bench/GameBench.cpp',
'../bench/GradientBench.cpp',
'../bench/GrMemoryPoolBench.cpp',
'../bench/GrResourceCacheBench.cpp',
'../bench/ImageCacheBench.cpp',
'../bench/ImageDecodeBench.cpp',
'../bench/InterpBench.cpp',
'../bench/HairlinePathBench.cpp',
'../bench/LineBench.cpp',
'../bench/LightingBench.cpp',
'../bench/MagnifierBench.cpp',
'../bench/MathBench.cpp',
'../bench/Matrix44Bench.cpp',
'../bench/MatrixBench.cpp',
'../bench/MatrixConvolutionBench.cpp',
'../bench/MemoryBench.cpp',
'../bench/MemsetBench.cpp',
'../bench/MergeBench.cpp',
'../bench/MorphologyBench.cpp',
'../bench/MutexBench.cpp',
'../bench/PathBench.cpp',
'../bench/PathIterBench.cpp',
'../bench/PathUtilsBench.cpp',
'../bench/PerlinNoiseBench.cpp',
'../bench/PicturePlaybackBench.cpp',
'../bench/PictureRecordBench.cpp',
'../bench/ReadPixBench.cpp',
'../bench/PremulAndUnpremulAlphaOpsBench.cpp',
'../bench/RectBench.cpp',
'../bench/RectoriBench.cpp',
'../bench/RefCntBench.cpp',
'../bench/RegionBench.cpp',
'../bench/RegionContainBench.cpp',
'../bench/RepeatTileBench.cpp',
'../bench/RTreeBench.cpp',
'../bench/ScalarBench.cpp',
'../bench/ShaderMaskBench.cpp',
'../bench/SkipZeroesBench.cpp',
'../bench/SortBench.cpp',
'../bench/StrokeBench.cpp',
'../bench/TableBench.cpp',
'../bench/TextBench.cpp',
'../bench/TileBench.cpp',
'../bench/VertBench.cpp',
'../bench/WriterBench.cpp',
'../bench/XfermodeBench.cpp',
'../bench/WritePixelsBench.cpp',
'../bench/SkBenchLogger.h',
'../bench/SkBenchLogger.cpp',
],
}
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

View File

@ -44,6 +44,7 @@
'<(skia_src_path)/core/SkBlitRow_D32.cpp',
'<(skia_src_path)/core/SkBlitter.h',
'<(skia_src_path)/core/SkBlitter.cpp',
'<(skia_src_path)/core/SkBlitter_A1.cpp',
'<(skia_src_path)/core/SkBlitter_A8.cpp',
'<(skia_src_path)/core/SkBlitter_ARGB32.cpp',
'<(skia_src_path)/core/SkBlitter_RGB16.cpp',

View File

@ -18,7 +18,7 @@
'includes': [ 'gmslides.gypi' ],
'sources': [
'../dm/DM.cpp',
'../dm/DMChecksumTask.cpp',
'../dm/DMComparisonTask.cpp',
'../dm/DMCpuTask.cpp',
'../dm/DMGpuTask.cpp',
'../dm/DMPipeTask.cpp',
@ -27,7 +27,6 @@
'../dm/DMSerializeTask.cpp',
'../dm/DMTask.cpp',
'../dm/DMTaskRunner.cpp',
'../dm/DMTileGridTask.cpp',
'../dm/DMUtil.cpp',
'../dm/DMWriteTask.cpp',
'../gm/gm.cpp',

View File

@ -50,7 +50,6 @@
'../gm/downsamplebitmap.cpp',
'../gm/drawbitmaprect.cpp',
'../gm/drawlooper.cpp',
'../gm/dropshadowimagefilter.cpp',
'../gm/extractbitmap.cpp',
'../gm/emptypath.cpp',
'../gm/fatpathfill.cpp',
@ -105,7 +104,6 @@
'../gm/perlinnoise.cpp',
'../gm/points.cpp',
'../gm/poly2poly.cpp',
'../gm/polygons.cpp',
'../gm/quadpaths.cpp',
'../gm/rects.cpp',
'../gm/rrect.cpp',

View File

@ -126,6 +126,7 @@
'<(skia_src_path)/gpu/GrTextureAccess.cpp',
'<(skia_src_path)/gpu/GrTHashTable.h',
'<(skia_src_path)/gpu/GrVertexBuffer.h',
'<(skia_src_path)/gpu/gr_unittests.cpp',
'<(skia_src_path)/gpu/effects/Gr1DKernelEffect.h',
'<(skia_src_path)/gpu/effects/GrConfigConversionEffect.cpp',

View File

@ -177,7 +177,6 @@
'../src/opts/SkBitmapProcState_matrixProcs_neon.cpp',
'../src/opts/SkBitmapProcState_matrix_clamp_neon.h',
'../src/opts/SkBitmapProcState_matrix_repeat_neon.h',
'../src/opts/SkBlitMask_opts_arm_neon.cpp',
'../src/opts/SkBlitRow_opts_arm_neon.cpp',
'../src/opts/SkMorphology_opts_neon.cpp',
'../src/opts/SkXfermode_opts_arm_neon.cpp',

View File

@ -83,7 +83,6 @@
'../tests/GradientTest.cpp',
'../tests/GrMemoryPoolTest.cpp',
'../tests/GrSurfaceTest.cpp',
'../tests/GrUnitTests.cpp',
'../tests/HashCacheTest.cpp',
'../tests/ImageCacheTest.cpp',
'../tests/ImageDecodingTest.cpp',

View File

@ -42,6 +42,12 @@ public:
enum Config {
kNo_Config, //!< bitmap has not been configured
/**
* 1-bit per pixel, (0 is transparent, 1 is opaque)
* Valid as a destination (target of a canvas), but not valid as a src.
* i.e. you can draw into a 1-bit bitmap, but you cannot draw from one.
*/
kA1_Config,
kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque)
kIndex8_Config, //!< 8-bits per pixel, using SkColorTable to specify the colors
kRGB_565_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
@ -483,6 +489,14 @@ public:
*/
inline uint8_t* getAddr8(int x, int y) const;
/** Returns the address of the byte containing the pixel specified by x,y
* for 1bit pixels.
* In debug build, this asserts that the pixels are allocated and locked,
* and that the config is 1-bit, however none of these checks are performed
* in the release build.
*/
inline uint8_t* getAddr1(int x, int y) const;
/** Returns the color corresponding to the pixel specified by x,y for
* colortable based bitmaps.
* In debug build, this asserts that the pixels are allocated and locked,
@ -804,4 +818,12 @@ inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
}
// returns the address of the byte that contains the x coordinate
inline uint8_t* SkBitmap::getAddr1(int x, int y) const {
SkASSERT(fPixels);
SkASSERT(fConfig == kA1_Config);
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
return (uint8_t*)fPixels + y * fRowBytes + (x >> 3);
}
#endif

View File

@ -186,7 +186,7 @@ public:
src: 32/24, no-alpha -> 4
src: 32/24, yes-alpha -> 5
*/
void setPrefConfigTable(const SkBitmap::Config pref[5]);
void setPrefConfigTable(const SkBitmap::Config pref[6]);
/**
* Optional table describing the caller's preferred config based on

View File

@ -218,14 +218,13 @@ protected:
// V13: add flag to drawBitmapRectToRect
// parameterize blurs by sigma rather than radius
// V14: Add flags word to PathRef serialization
// V15: Remove A1 bitmpa config (and renumber remaining configs)
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V13_AND_ALL_OTHER_INSTANCES_TOO
static const uint32_t PRIOR_PRIOR_PICTURE_VERSION = 12; // TODO: remove when .skps regenerated
#endif
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
static const uint32_t PRIOR_PICTURE_VERSION2 = 13; // TODO: remove when .skps regenerated
#endif
static const uint32_t PICTURE_VERSION = 15;
static const uint32_t PICTURE_VERSION = 14;
// fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
// install their own SkPicturePlayback-derived players,SkPictureRecord-derived

View File

@ -11,7 +11,6 @@
#define SkString_DEFINED
#include "SkScalar.h"
#include "SkTArray.h"
#include <stdarg.h>
@ -245,7 +244,4 @@ template <> inline void SkTSwap(SkString& a, SkString& b) {
a.swap(b);
}
// Split str on any characters in delimiters into out. (Think, strtok with a sane API.)
void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out);
#endif

View File

@ -12,7 +12,6 @@
class SK_API SkDropShadowImageFilter : public SkImageFilter {
public:
SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigma, SkColor, SkImageFilter* input = NULL);
SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor, SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDropShadowImageFilter)
protected:
@ -21,7 +20,7 @@ protected:
virtual bool onFilterImage(Proxy*, const SkBitmap& source, const SkMatrix&, SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
private:
SkScalar fDx, fDy, fSigmaX, fSigmaY;
SkScalar fDx, fDy, fSigma;
SkColor fColor;
typedef SkImageFilter INHERITED;
};

View File

@ -105,6 +105,7 @@ protected:
virtual SkTypeface* onCreateFromStream(SkStream*, int ttcIndex) = 0;
virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) = 0;
// TODO: make this pure-virtual once all ports know about it
virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
unsigned styleBits) = 0;
private:

View File

@ -43,11 +43,6 @@ public class SkiaSampleActivity extends Activity
try {
System.loadLibrary("skia_android");
} catch (UnsatisfiedLinkError e) {
// This might be because skia was linked to SampleApp statically.
}
try {
System.loadLibrary("SampleApp");
LinearLayout holder = (LinearLayout) findViewById(R.id.holder);

View File

@ -28,10 +28,7 @@ then
fi
adb_push_if_needed "${SKIA_OUT}/${configuration}/skia_launcher" /data/local/tmp
if [ -f "${SKIA_OUT}/${configuration}/lib.target/libskia_android.so" ]; then
# Does not exist for builds with static skia.
adb_push_if_needed "${SKIA_OUT}/${configuration}/lib.target/libskia_android.so" /data/local/tmp
fi
adb_push_if_needed "${SKIA_OUT}/${configuration}/lib.target/libskia_android.so" /data/local/tmp
adb_push_if_needed "${SKIA_OUT}/${configuration}/lib.target/lib${runVars[0]}.so" /data/local/tmp
STATUS_FILENAME="/data/local/tmp/.skia_tmp_$(date +%s%N)"

View File

@ -161,9 +161,7 @@ setup_device() {
DEFINES="${DEFINES} host_os=$(uname -s | sed -e 's/Linux/linux/;s/Darwin/mac/')"
DEFINES="${DEFINES} skia_os=android"
DEFINES="${DEFINES} android_base=${SCRIPT_DIR}/.."
if [[ "$GYP_DEFINES" != *skia_shared_lib=* ]]; then
DEFINES="${DEFINES} skia_shared_lib=1"
fi
DEFINES="${DEFINES} skia_shared_lib=1"
# Setup the build variation depending on the target device
TARGET_DEVICE="$1"

View File

@ -30,16 +30,9 @@
# still build.
{
'destination': '<(PRODUCT_DIR)/android/libs/<(android_arch)',
'conditions': [
[ 'skia_shared_lib', {
'files': [
'<(SHARED_LIB_DIR)/libSampleApp.so',
'<(SHARED_LIB_DIR)/libskia_android.so',
]}, {
'files': [
'<(SHARED_LIB_DIR)/libSampleApp.so',
]}
],
'files': [
'<(SHARED_LIB_DIR)/libSampleApp.so',
'<(SHARED_LIB_DIR)/libskia_android.so',
],
},
],

View File

@ -67,16 +67,12 @@ int main(int argc, const char** argv) {
return -1;
}
void* skiaLibrary;
#if defined(SKIA_DLL)
// load the local skia shared library
skiaLibrary = load_library(appLocation, "skia_android");
void* skiaLibrary = load_library(appLocation, "skia_android");
if (NULL == skiaLibrary)
{
return -1;
}
#endif
// load the appropriate library
void* appLibrary = load_library(appLocation, argv[1]);
@ -84,10 +80,6 @@ int main(int argc, const char** argv) {
return -1;
}
#if !defined(SKIA_DLL)
skiaLibrary = appLibrary;
#endif
// find the address of the main function
int (*app_main)(int, const char**);
*(void **) (&app_main) = dlsym(appLibrary, "main");

View File

@ -1537,6 +1537,7 @@ void SampleWindow::afterChild(SkView* child, SkCanvas* canvas) {
static SkBitmap::Config gConfigCycle[] = {
SkBitmap::kNo_Config, // none -> none
SkBitmap::kNo_Config, // a1 -> none
SkBitmap::kNo_Config, // a8 -> none
SkBitmap::kNo_Config, // index8 -> none
SkBitmap::kARGB_4444_Config, // 565 -> 4444
@ -2073,6 +2074,7 @@ void SampleWindow::loadView(SkView* view) {
static const char* gConfigNames[] = {
"unknown config",
"A1",
"A8",
"Index8",
"565",

View File

@ -67,6 +67,7 @@ static SkScalar draw_set(SkCanvas* c, const SkBitmap& bm, SkScalar x, SkPaint* p
static const char* gConfigNames[] = {
"unknown config",
"A1",
"A8",
"Index8",
"565",

View File

@ -75,10 +75,11 @@ void SkDrawBitmap::dump(SkAnimateMaker* maker) {
const char* formatName;
switch (format) {
case 0: formatName = "none"; break;
case 1: formatName = "A8"; break;
case 2: formatName = "Index8"; break;
case 3: formatName = "RGB16"; break;
case 4: formatName = "RGB32"; break;
case 1: formatName = "A1"; break;
case 2: formatName = "A8"; break;
case 3: formatName = "Index8"; break;
case 4: formatName = "RGB16"; break;
case 5: formatName = "RGB32"; break;
}
SkDebugf("format=\"%s\" />\n", formatName);
}

View File

@ -161,6 +161,7 @@ int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) {
int bpp;
switch (config) {
case kNo_Config:
case kA1_Config:
bpp = 0; // not applicable
break;
case kA8_Config:
@ -193,6 +194,11 @@ size_t SkBitmap::ComputeRowBytes(Config c, int width) {
switch (c) {
case kNo_Config:
break;
case kA1_Config:
rowBytes.set(width);
rowBytes.add(7);
rowBytes.shiftRight(3);
break;
case kA8_Config:
case kIndex8_Config:
rowBytes.set(width);
@ -269,6 +275,7 @@ static bool validate_alphaType(SkBitmap::Config config, SkAlphaType alphaType,
case SkBitmap::kNo_Config:
alphaType = kIgnore_SkAlphaType;
break;
case SkBitmap::kA1_Config:
case SkBitmap::kA8_Config:
if (kUnpremul_SkAlphaType == alphaType) {
alphaType = kPremul_SkAlphaType;
@ -284,8 +291,6 @@ static bool validate_alphaType(SkBitmap::Config config, SkAlphaType alphaType,
case SkBitmap::kRGB_565_Config:
alphaType = kOpaque_SkAlphaType;
break;
default:
return false;
}
if (canonical) {
*canonical = alphaType;
@ -601,6 +606,8 @@ void* SkBitmap::getAddr(int x, int y) const {
case SkBitmap::kIndex8_Config:
base += x;
break;
case SkBitmap::kA1_Config:
base += x >> 3;
break;
default:
SkDEBUGFAIL("Can't return addr for config");
@ -616,6 +623,15 @@ SkColor SkBitmap::getColor(int x, int y) const {
SkASSERT((unsigned)y < (unsigned)this->height());
switch (this->config()) {
case SkBitmap::kA1_Config: {
uint8_t* addr = this->getAddr1(x, y);
uint8_t mask = 1 << (7 - (x % 8));
if (addr[0] & mask) {
return SK_ColorBLACK;
} else {
return 0;
}
}
case SkBitmap::kA8_Config: {
uint8_t* addr = this->getAddr8(x, y);
return SkColorSetA(0, addr[0]);
@ -638,7 +654,6 @@ SkColor SkBitmap::getColor(int x, int y) const {
return SkUnPreMultiply::PMColorToColor(addr[0]);
}
case kNo_Config:
default:
SkASSERT(false);
return 0;
}
@ -656,6 +671,9 @@ bool SkBitmap::ComputeIsOpaque(const SkBitmap& bm) {
const int width = bm.width();
switch (bm.config()) {
case SkBitmap::kA1_Config: {
// TODO
} break;
case SkBitmap::kA8_Config: {
unsigned a = 0xFF;
for (int y = 0; y < height; ++y) {
@ -761,6 +779,38 @@ void SkBitmap::internalErase(const SkIRect& area,
}
switch (fConfig) {
case kA1_Config: {
uint8_t* p = this->getAddr1(area.fLeft, area.fTop);
const int left = area.fLeft >> 3;
const int right = area.fRight >> 3;
int middle = right - left - 1;
uint8_t leftMask = 0xFF >> (area.fLeft & 7);
uint8_t rightMask = ~(0xFF >> (area.fRight & 7));
if (left == right) {
leftMask &= rightMask;
rightMask = 0;
}
a = (a >> 7) ? 0xFF : 0;
while (--height >= 0) {
uint8_t* startP = p;
*p = (*p & ~leftMask) | (a & leftMask);
p++;
if (middle > 0) {
memset(p, a, middle);
p += middle;
}
if (rightMask) {
*p = (*p & ~rightMask) | (a & rightMask);
}
p = startP + rowBytes;
}
break;
}
case kA8_Config: {
uint8_t* p = this->getAddr8(area.fLeft, area.fTop);
while (--height >= 0) {
@ -846,6 +896,7 @@ static size_t get_sub_offset(const SkBitmap& bm, int x, int y) {
break;
case SkBitmap::kNo_Config:
case SkBitmap::kA1_Config:
default:
return SUB_OFFSET_FAILURE;
}
@ -888,6 +939,8 @@ bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t r
case SkBitmap::kNo_Config:
// Fall through.
case SkBitmap::kA1_Config:
// Fall through.
default:
return false;
}
@ -968,6 +1021,7 @@ bool SkBitmap::canCopyTo(Config dstConfig) const {
case kRGB_565_Config:
case kARGB_8888_Config:
break;
case kA1_Config:
case kIndex8_Config:
if (!sameConfigs) {
return false;
@ -978,6 +1032,12 @@ bool SkBitmap::canCopyTo(Config dstConfig) const {
default:
return false;
}
// do not copy src if srcConfig == kA1_Config while dstConfig != kA1_Config
if (this->config() == kA1_Config && !sameConfigs) {
return false;
}
return true;
}
@ -1623,7 +1683,7 @@ void SkBitmap::validate() const {
void SkBitmap::toString(SkString* str) const {
static const char* gConfigNames[kConfigCount] = {
"NONE", "A8", "INDEX8", "565", "4444", "8888"
"NONE", "A1", "A8", "INDEX8", "565", "4444", "8888"
};
str->appendf("bitmap: ((%d, %d) %s", this->width(), this->height(),

View File

@ -945,6 +945,11 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
switch (device.config()) {
case SkBitmap::kA1_Config:
SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter,
storage, storageSize, (device, *paint));
break;
case SkBitmap::kA8_Config:
if (drawCoverage) {
SkASSERT(NULL == shader);

50
src/core/SkBlitter_A1.cpp Normal file
View File

@ -0,0 +1,50 @@
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkCoreBlitters.h"
SkA1_Blitter::SkA1_Blitter(const SkBitmap& device, const SkPaint& paint)
: INHERITED(device) {
fSrcA = paint.getAlpha();
}
void SkA1_Blitter::blitH(int x, int y, int width) {
SkASSERT(x >= 0 && y >= 0 &&
(unsigned)(x + width) <= (unsigned)fDevice.width());
if (fSrcA <= 0x7F) {
return;
}
uint8_t* dst = fDevice.getAddr1(x, y);
int right = x + width;
int left_mask = 0xFF >> (x & 7);
int rite_mask = 0xFF << (8 - (right & 7));
int full_runs = (right >> 3) - ((x + 7) >> 3);
// check for empty right mask, so we don't read off the end
// (or go slower than we need to)
if (rite_mask == 0) {
SkASSERT(full_runs >= 0);
full_runs -= 1;
rite_mask = 0xFF;
}
if (left_mask == 0xFF) {
full_runs -= 1;
}
if (full_runs < 0) {
SkASSERT((left_mask & rite_mask) != 0);
*dst |= (left_mask & rite_mask);
} else {
*dst++ |= left_mask;
memset(dst, 0xFF, full_runs);
dst += full_runs;
*dst |= rite_mask;
}
}

View File

@ -162,6 +162,22 @@ private:
///////////////////////////////////////////////////////////////////////////////
class SkA1_Blitter : public SkRasterBlitter {
public:
SkA1_Blitter(const SkBitmap& device, const SkPaint& paint);
virtual void blitH(int x, int y, int width) SK_OVERRIDE;
private:
uint8_t fSrcA;
// illegal
SkA1_Blitter& operator=(const SkA1_Blitter&);
typedef SkRasterBlitter INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
/* These return the correct subclass of blitter for their device config.
Currently, they make the following assumptions about the state of the

View File

@ -87,6 +87,8 @@ SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca
fGlyphArray.setReserve(kMinGlyphCount);
fMetricsCount = 0;
fAdvanceCount = 0;
fAuxProcList = NULL;
}
@ -318,9 +320,11 @@ SkGlyph* SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) {
if (kJustAdvance_MetricsType == mtype) {
fScalerContext->getAdvance(glyph);
fAdvanceCount += 1;
} else {
SkASSERT(kFull_MetricsType == mtype);
fScalerContext->getMetrics(glyph);
fMetricsCount += 1;
}
return glyph;

View File

@ -211,6 +211,8 @@ private:
SkTDArray<SkGlyph*> fGlyphArray;
SkChunkAlloc fGlyphAlloc;
int fMetricsCount, fAdvanceCount;
struct CharGlyphRec {
uint32_t fID; // unichar + subpixel
SkGlyph* fGlyph;

View File

@ -2005,7 +2005,11 @@ enum FlatFlags {
};
// The size of a flat paint's POD fields
static const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) +
// Include an SkScalar for hinting scale factor whether it is
// supported or not so that an SKP is valid whether it was
// created with support or not.
static const uint32_t kPODPaintSize = 6 * sizeof(SkScalar) +
1 * sizeof(SkColor) +
1 * sizeof(uint16_t) +
6 * sizeof(uint8_t);
@ -2042,6 +2046,8 @@ void SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const {
ptr = write_scalar(ptr, this->getTextSize());
ptr = write_scalar(ptr, this->getTextScaleX());
ptr = write_scalar(ptr, this->getTextSkewX());
// Dummy value for obsolete hinting scale factor. TODO: remove with next picture version
ptr = write_scalar(ptr, SK_Scalar1);
ptr = write_scalar(ptr, this->getStrokeWidth());
ptr = write_scalar(ptr, this->getStrokeMiter());
*ptr++ = this->getColor();
@ -2058,6 +2064,8 @@ void SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const {
buffer.writeScalar(fTextSize);
buffer.writeScalar(fTextScaleX);
buffer.writeScalar(fTextSkewX);
// Dummy value for obsolete hinting scale factor. TODO: remove with next picture version
buffer.writeScalar(SK_Scalar1);
buffer.writeScalar(fWidth);
buffer.writeScalar(fMiterLimit);
buffer.writeColor(fColor);
@ -2112,6 +2120,8 @@ void SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
this->setTextSize(read_scalar(pod));
this->setTextScaleX(read_scalar(pod));
this->setTextSkewX(read_scalar(pod));
// Skip the hinting scalar factor, which is not supported.
read_scalar(pod);
this->setStrokeWidth(read_scalar(pod));
this->setStrokeMiter(read_scalar(pod));
this->setColor(*pod++);

View File

@ -266,20 +266,11 @@ void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) {
#include "SkStream.h"
static const char kMagic[] = { 's', 'k', 'i', 'a', 'p', 'i', 'c', 't' };
bool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
if (NULL == stream) {
return false;
}
// Check magic bytes.
char magic[sizeof(kMagic)];
stream->read(magic, sizeof(kMagic));
if (0 != memcmp(magic, kMagic, sizeof(kMagic))) {
return false;
}
SkPictInfo info;
if (!stream->read(&info, sizeof(SkPictInfo))) {
return false;
@ -350,10 +341,6 @@ void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
info.fFlags |= SkPictInfo::kPtrIs64Bit_Flag;
}
// Write 8 magic bytes to ID this file format.
SkASSERT(sizeof(kMagic) == 8);
stream->write(kMagic, sizeof(kMagic));
stream->write(&info, sizeof(info));
if (playback) {
stream->writeBool(true);

View File

@ -49,7 +49,7 @@ static uint32_t compute_hash(const uint32_t data[], int count) {
return hash;
}
struct SkScaledImageCache::Key {
struct Key {
Key(uint32_t genID,
SkScalar scaleX,
SkScalar scaleY,
@ -129,24 +129,22 @@ struct SkScaledImageCache::Rec {
#include "SkTDynamicHash.h"
namespace { // can't use static functions w/ template parameters
const SkScaledImageCache::Key& key_from_rec(const SkScaledImageCache::Rec& rec) {
const Key& key_from_rec(const SkScaledImageCache::Rec& rec) {
return rec.fKey;
}
uint32_t hash_from_key(const SkScaledImageCache::Key& key) {
uint32_t hash_from_key(const Key& key) {
return key.fHash;
}
bool eq_rec_key(const SkScaledImageCache::Rec& rec, const SkScaledImageCache::Key& key) {
bool eq_rec_key(const SkScaledImageCache::Rec& rec, const Key& key) {
return rec.fKey == key;
}
}
class SkScaledImageCache::Hash : public SkTDynamicHash<SkScaledImageCache::Rec,
SkScaledImageCache::Key,
key_from_rec,
hash_from_key,
eq_rec_key> {};
Key, key_from_rec, hash_from_key,
eq_rec_key> {};
///////////////////////////////////////////////////////////////////////////////
@ -189,22 +187,17 @@ SkScaledImageCache::~SkScaledImageCache() {
////////////////////////////////////////////////////////////////////////////////
/**
This private method is the fully general record finder. All other
record finders should call this funtion. */
SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(uint32_t genID,
SkScalar scaleX,
SkScalar scaleY,
const SkIRect& bounds) {
const Key key(genID, scaleX, scaleY, bounds);
return this->findAndLock(key);
}
/**
This private method is the fully general record finder. All other
record finders should call this function or the one above. */
SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkScaledImageCache::Key& key) {
if (key.fBounds.isEmpty()) {
if (bounds.isEmpty()) {
return NULL;
}
Key key(genID, scaleX, scaleY, bounds);
#ifdef USE_HASH
Rec* rec = fHash->find(key);
#else
@ -282,14 +275,8 @@ SkScaledImageCache::ID* SkScaledImageCache::findAndLockMip(const SkBitmap& orig,
/**
This private method is the fully general record adder. All other
record adders should call this funtion. */
SkScaledImageCache::ID* SkScaledImageCache::addAndLock(SkScaledImageCache::Rec* rec) {
void SkScaledImageCache::addAndLock(SkScaledImageCache::Rec* rec) {
SkASSERT(rec);
// See if we already have this key (racy inserts, etc.)
Rec* existing = this->findAndLock(rec->fKey);
if (existing != NULL) {
return rec_to_id(existing);
}
this->addToHead(rec);
SkASSERT(1 == rec->fLockCount);
#ifdef USE_HASH
@ -298,7 +285,6 @@ SkScaledImageCache::ID* SkScaledImageCache::addAndLock(SkScaledImageCache::Rec*
#endif
// We may (now) be overbudget, so see if we need to purge something.
this->purgeAsNeeded();
return rec_to_id(rec);
}
SkScaledImageCache::ID* SkScaledImageCache::addAndLock(uint32_t genID,
@ -307,7 +293,8 @@ SkScaledImageCache::ID* SkScaledImageCache::addAndLock(uint32_t genID,
const SkBitmap& bitmap) {
Key key(genID, SK_Scalar1, SK_Scalar1, SkIRect::MakeWH(width, height));
Rec* rec = SkNEW_ARGS(Rec, (key, bitmap));
return this->addAndLock(rec);
this->addAndLock(rec);
return rec_to_id(rec);
}
SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig,
@ -324,7 +311,8 @@ SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig,
}
Key key(orig.getGenerationID(), scaleX, scaleY, bounds);
Rec* rec = SkNEW_ARGS(Rec, (key, scaled));
return this->addAndLock(rec);
this->addAndLock(rec);
return rec_to_id(rec);
}
SkScaledImageCache::ID* SkScaledImageCache::addAndLockMip(const SkBitmap& orig,
@ -335,7 +323,8 @@ SkScaledImageCache::ID* SkScaledImageCache::addAndLockMip(const SkBitmap& orig,
}
Key key(orig.getGenerationID(), 0, 0, bounds);
Rec* rec = SkNEW_ARGS(Rec, (key, mip));
return this->addAndLock(rec);
this->addAndLock(rec);
return rec_to_id(rec);
}
void SkScaledImageCache::unlock(SkScaledImageCache::ID* id) {

View File

@ -126,7 +126,6 @@ public:
public:
struct Rec;
struct Key;
private:
Rec* fHead;
Rec* fTail;
@ -140,8 +139,7 @@ private:
Rec* findAndLock(uint32_t generationID, SkScalar sx, SkScalar sy,
const SkIRect& bounds);
Rec* findAndLock(const Key& key);
ID* addAndLock(Rec* rec);
void addAndLock(Rec* rec);
void purgeAsNeeded();

View File

@ -352,16 +352,16 @@ void SkScalerContext::getMetrics(SkGlyph* glyph) {
glyph->fHeight = SkToU16(ir.height());
if (glyph->fWidth > 0) {
switch (fRec.fMaskFormat) {
case SkMask::kLCD16_Format:
case SkMask::kLCD32_Format:
glyph->fWidth += 2;
glyph->fLeft -= 1;
break;
default:
break;
}
switch (fRec.fMaskFormat) {
case SkMask::kLCD16_Format:
case SkMask::kLCD32_Format:
glyph->fWidth += 2;
glyph->fLeft -= 1;
break;
default:
break;
}
}
}
}
@ -523,54 +523,10 @@ static void pack4xHToLCD32(const SkBitmap& src, const SkMask& dst,
}
}
static inline int convert_8_to_1(unsigned byte) {
SkASSERT(byte <= 0xFF);
return byte >> 7;
}
static uint8_t pack_8_to_1(const uint8_t alpha[8]) {
unsigned bits = 0;
for (int i = 0; i < 8; ++i) {
bits <<= 1;
bits |= convert_8_to_1(alpha[i]);
}
return SkToU8(bits);
}
static void packA8ToA1(const SkMask& mask, const uint8_t* src, size_t srcRB) {
const int height = mask.fBounds.height();
const int width = mask.fBounds.width();
const int octs = width >> 3;
const int leftOverBits = width & 7;
uint8_t* dst = mask.fImage;
const int dstPad = mask.fRowBytes - SkAlign8(width)/8;
SkASSERT(dstPad >= 0);
const int srcPad = srcRB - width;
SkASSERT(srcPad >= 0);
for (int y = 0; y < height; ++y) {
for (int i = 0; i < octs; ++i) {
*dst++ = pack_8_to_1(src);
src += 8;
}
if (leftOverBits > 0) {
unsigned bits = 0;
int shift = 7;
for (int i = 0; i < leftOverBits; ++i, --shift) {
bits |= convert_8_to_1(*src++ >> 7) << shift;
}
*dst++ = bits;
}
src += srcPad;
dst += dstPad;
}
}
static void generateMask(const SkMask& mask, const SkPath& path,
const SkMaskGamma::PreBlend& maskPreBlend) {
SkPaint paint;
SkBitmap::Config config;
SkPaint paint;
int srcW = mask.fBounds.width();
int srcH = mask.fBounds.height();
@ -582,25 +538,27 @@ static void generateMask(const SkMask& mask, const SkPath& path,
matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
-SkIntToScalar(mask.fBounds.fTop));
SkBitmap::Config config = SkBitmap::kA8_Config;
paint.setAntiAlias(SkMask::kBW_Format != mask.fFormat);
switch (mask.fFormat) {
case SkMask::kBW_Format:
dstRB = 0; // signals we need a copy
break;
case SkMask::kA8_Format:
break;
case SkMask::kLCD16_Format:
case SkMask::kLCD32_Format:
// TODO: trigger off LCD orientation
dstW = 4*dstW - 8;
matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
-SkIntToScalar(mask.fBounds.fTop));
matrix.postScale(SkIntToScalar(4), SK_Scalar1);
dstRB = 0; // signals we need a copy
break;
default:
SkDEBUGFAIL("unexpected mask format");
if (SkMask::kBW_Format == mask.fFormat) {
config = SkBitmap::kA1_Config;
paint.setAntiAlias(false);
} else {
config = SkBitmap::kA8_Config;
paint.setAntiAlias(true);
switch (mask.fFormat) {
case SkMask::kA8_Format:
break;
case SkMask::kLCD16_Format:
case SkMask::kLCD32_Format:
// TODO: trigger off LCD orientation
dstW = 4*dstW - 8;
matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
-SkIntToScalar(mask.fBounds.fTop));
matrix.postScale(SkIntToScalar(4), SK_Scalar1);
dstRB = 0; // signals we need a copy
break;
default:
SkDEBUGFAIL("unexpected mask format");
}
}
SkRasterClip clip;
@ -629,9 +587,6 @@ static void generateMask(const SkMask& mask, const SkPath& path,
draw.drawPath(path, paint);
switch (mask.fFormat) {
case SkMask::kBW_Format:
packA8ToA1(mask, bm.getAddr8(0, 0), bm.rowBytes());
break;
case SkMask::kA8_Format:
if (maskPreBlend.isApplicable()) {
applyLUTToA8Mask(mask, maskPreBlend.fG);

View File

@ -202,57 +202,16 @@ protected:
Rec fRec;
unsigned fBaseGlyphCount;
/** Generates the contents of glyph.fAdvanceX and glyph.fAdvanceY.
* May call getMetrics if that would be just as fast.
*/
virtual void generateAdvance(SkGlyph* glyph) = 0;
/** Generates the contents of glyph.fWidth, fHeight, fTop, fLeft,
* as well as fAdvanceX and fAdvanceY if not already set.
*
* TODO: fMaskFormat is set by getMetrics later; cannot be set here.
*/
virtual void generateMetrics(SkGlyph* glyph) = 0;
/** Generates the contents of glyph.fImage.
* When called, glyph.fImage will be pointing to a pre-allocated,
* uninitialized region of memory of size glyph.computeImageSize().
* This method may change glyph.fMaskFormat if the new image size is
* less than or equal to the old image size.
*
* Because glyph.computeImageSize() will determine the size of fImage,
* generateMetrics will be called before generateImage.
*/
virtual void generateImage(const SkGlyph& glyph) = 0;
/** Sets the passed path to the glyph outline.
* If this cannot be done the path is set to empty;
* this is indistinguishable from a glyph with an empty path.
* This does not set glyph.fPath.
*
* TODO: path is always glyph.fPath, no reason to pass separately.
*/
virtual void generatePath(const SkGlyph& glyph, SkPath* path) = 0;
/** Retrieves font metrics.
* TODO: there is now a vertical bit, no need for two parameters.
*/
virtual unsigned generateGlyphCount() = 0;
virtual uint16_t generateCharToGlyph(SkUnichar) = 0;
virtual void generateAdvance(SkGlyph*) = 0;
virtual void generateMetrics(SkGlyph*) = 0;
virtual void generateImage(const SkGlyph&) = 0;
virtual void generatePath(const SkGlyph&, SkPath*) = 0;
virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
SkPaint::FontMetrics* mY) = 0;
/** Returns the number of glyphs in the font. */
virtual unsigned generateGlyphCount() = 0;
/** Returns the glyph id for the given unichar.
* If there is no 1:1 mapping from the unichar to a glyph id, returns 0.
*/
virtual uint16_t generateCharToGlyph(SkUnichar unichar) = 0;
/** Returns the unichar for the given glyph id.
* If there is no 1:1 mapping from the glyph id to a unichar, returns 0.
* The default implementation always returns 0, indicating failure.
*/
virtual SkUnichar generateGlyphToChar(uint16_t glyphId);
// default impl returns 0, indicating failure.
virtual SkUnichar generateGlyphToChar(uint16_t);
void forceGenerateImageFromPath() { fGenerateImageFromPath = true; }

Some files were not shown because too many files have changed in this diff Show More