aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dm/DM.cpp92
-rw-r--r--dm/DMGpuTask.cpp19
-rw-r--r--dm/DMGpuTask.h1
-rw-r--r--dm/DMReporter.cpp16
-rw-r--r--dm/DMReporter.h7
-rw-r--r--dm/DMTask.cpp11
-rw-r--r--dm/DMTask.h2
-rw-r--r--dm/DMTaskRunner.cpp28
-rw-r--r--dm/DMTaskRunner.h12
-rw-r--r--dm/DMTestTask.cpp34
-rw-r--r--dm/DMTestTask.h50
-rw-r--r--gyp/dm.gyp8
-rw-r--r--gyp/tests.gyp178
-rw-r--r--gyp/tests.gypi181
-rw-r--r--tests/Test.cpp27
-rw-r--r--tests/Test.h16
-rw-r--r--tests/skia_test.cpp34
17 files changed, 432 insertions, 284 deletions
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 8a4a38209a..ee53e9d99f 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -7,26 +7,29 @@
#include "SkForceLinking.h"
#include "SkGraphics.h"
#include "SkString.h"
+#include "Test.h"
#include "gm.h"
+#include "DMCpuTask.h"
+#include "DMGpuTask.h"
#include "DMReporter.h"
#include "DMTask.h"
#include "DMTaskRunner.h"
-#include "DMCpuTask.h"
-#include "DMGpuTask.h"
+#include "DMTestTask.h"
#include "DMWriteTask.h"
#include <string.h>
using skiagm::GM;
using skiagm::GMRegistry;
+using skiatest::Test;
+using skiatest::TestRegistry;
-DEFINE_int32(cpuThreads, -1, "Threads for CPU work. Default NUM_CPUS.");
-DEFINE_int32(gpuThreads, 1, "Threads for GPU work.");
+DEFINE_int32(threads, -1, "Threads for CPU work. Default NUM_CPUS.");
DEFINE_string2(expectations, r, "",
"If a directory, compare generated images against images under this path. "
"If a file, compare generated images against JSON expectations at this path.");
-DEFINE_string(resources, "resources", "Path to resources directory.");
+DEFINE_string2(resources, i, "resources", "Path to resources directory.");
DEFINE_string(match, "", "[~][^]substring[$] [...] of GM name to run.\n"
"Multiple matches may be separated by spaces.\n"
"~ causes a matching GM to always be skipped\n"
@@ -37,6 +40,10 @@ DEFINE_string(match, "", "[~][^]substring[$] [...] of GM name to run.\n"
"it is skipped unless some list entry starts with ~");
DEFINE_string(config, "565 8888 gpu",
"Options: 565 8888 gpu msaa4 msaa16 gpunull gpudebug angle mesa"); // TODO(mtklein): pdf
+DEFINE_bool(leaks, false, "Print leaked instance-counted objects at exit?");
+
+DEFINE_bool(gms, true, "Run GMs?");
+DEFINE_bool(tests, true, "Run tests?");
__SK_FORCE_IMAGE_DECODER_LINKING;
@@ -48,11 +55,11 @@ static SkString lowercase(SkString s) {
return s;
}
-static void kick_off_tasks(const SkTDArray<GMRegistry::Factory>& gms,
- const SkTArray<SkString>& configs,
- const DM::Expectations& expectations,
- DM::Reporter* reporter,
- DM::TaskRunner* tasks) {
+static void kick_off_gms(const SkTDArray<GMRegistry::Factory>& gms,
+ const SkTArray<SkString>& configs,
+ const DM::Expectations& expectations,
+ DM::Reporter* reporter,
+ DM::TaskRunner* tasks) {
const SkColorType _565 = kRGB_565_SkColorType;
const SkColorType _8888 = kPMColor_SkColorType;
const GrContextFactory::GLContextType native = GrContextFactory::kNative_GLContextType;
@@ -93,6 +100,14 @@ static void kick_off_tasks(const SkTDArray<GMRegistry::Factory>& gms,
#undef START
}
+static void kick_off_tests(const SkTDArray<TestRegistry::Factory>& tests,
+ DM::Reporter* reporter,
+ DM::TaskRunner* tasks) {
+ for (int i = 0; i < tests.count(); i++) {
+ tasks->add(SkNEW_ARGS(DM::TestTask, (reporter, tasks, tests[i])));
+ }
+}
+
static void report_failures(const DM::Reporter& reporter) {
SkTArray<SkString> failures;
reporter.getFailures(&failures);
@@ -109,40 +124,57 @@ static void report_failures(const DM::Reporter& reporter) {
int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
+#if SK_ENABLE_INST_COUNT
+ gPrintInstCount = FLAGS_leaks;
+#endif
SkGraphics::Init();
-
SkCommandLineFlags::Parse(argc, argv);
GM::SetResourcePath(FLAGS_resources[0]);
- SkTArray<SkString> configs;
- for (int i = 0; i < FLAGS_config.count(); i++) {
- SkStrSplit(FLAGS_config[i], ", ", &configs);
- }
+ Test::SetResourcePath(FLAGS_resources[0]);
+ SkTArray<SkString> configs;
SkTDArray<GMRegistry::Factory> gms;
- for (const GMRegistry* reg = GMRegistry::Head(); reg != NULL; reg = reg->next()) {
- SkAutoTDelete<GM> gmForName(reg->factory()(NULL));
- if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, gmForName->shortName())) {
- *gms.append() = reg->factory();
+ SkAutoTDelete<DM::Expectations> expectations(SkNEW(DM::NoExpectations));
+
+ if (FLAGS_gms) {
+ for (int i = 0; i < FLAGS_config.count(); i++) {
+ SkStrSplit(FLAGS_config[i], ", ", &configs);
+ }
+
+ for (const GMRegistry* reg = GMRegistry::Head(); reg != NULL; reg = reg->next()) {
+ SkAutoTDelete<GM> gmForName(reg->factory()(NULL));
+ if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, gmForName->shortName())) {
+ *gms.append() = reg->factory();
+ }
+ }
+
+ if (FLAGS_expectations.count() > 0) {
+ const char* path = FLAGS_expectations[0];
+ if (sk_isdir(path)) {
+ expectations.reset(SkNEW_ARGS(DM::WriteTask::Expectations, (path)));
+ } else {
+ expectations.reset(SkNEW_ARGS(DM::JsonExpectations, (path)));
+ }
}
}
- SkDebugf("%d GMs x %d configs\n", gms.count(), configs.count());
- SkAutoTDelete<DM::Expectations> expectations(SkNEW(DM::NoExpectations));
- if (FLAGS_expectations.count() > 0) {
- const char* path = FLAGS_expectations[0];
- if (sk_isdir(path)) {
- expectations.reset(SkNEW_ARGS(DM::WriteTask::Expectations, (path)));
- } else {
- expectations.reset(SkNEW_ARGS(DM::JsonExpectations, (path)));
+ SkTDArray<TestRegistry::Factory> tests;
+ if (FLAGS_tests) {
+ for (const TestRegistry* reg = TestRegistry::Head(); reg != NULL; reg = reg->next()) {
+ SkAutoTDelete<Test> testForName(reg->factory()(NULL));
+ if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, testForName->getName())) {
+ *tests.append() = reg->factory();
+ }
}
}
+ SkDebugf("%d GMs x %d configs, %d tests\n", gms.count(), configs.count(), tests.count());
DM::Reporter reporter;
- DM::TaskRunner tasks(FLAGS_cpuThreads, FLAGS_gpuThreads);
- kick_off_tasks(gms, configs, *expectations, &reporter, &tasks);
+ DM::TaskRunner tasks(FLAGS_threads);
+ kick_off_gms(gms, configs, *expectations, &reporter, &tasks);
+ kick_off_tests(tests, &reporter, &tasks);
tasks.wait();
- reporter.updateStatusLine();
SkDebugf("\n");
report_failures(reporter);
diff --git a/dm/DMGpuTask.cpp b/dm/DMGpuTask.cpp
index f787e2544f..3a4708b8db 100644
--- a/dm/DMGpuTask.cpp
+++ b/dm/DMGpuTask.cpp
@@ -18,6 +18,7 @@ GpuTask::GpuTask(const char* name,
GrContextFactory::GLContextType contextType,
int sampleCount)
: Task(reporter, taskRunner)
+ , fTaskRunner(taskRunner)
, fGM(gmFactory(NULL))
, fName(UnderJoin(fGM->shortName(), name))
, fExpectations(expectations)
@@ -26,24 +27,12 @@ GpuTask::GpuTask(const char* name,
, fSampleCount(sampleCount)
{}
-static void* new_gr_context_factory() {
- return SkNEW(GrContextFactory);
-}
-
-static void delete_gr_context_factory(void* factory) {
- SkDELETE((GrContextFactory*) factory);
-}
-
-static GrContextFactory* get_gr_factory() {
- return reinterpret_cast<GrContextFactory*>(SkTLS::Get(&new_gr_context_factory,
- &delete_gr_context_factory));
-}
-
void GpuTask::draw() {
- GrContext* gr = get_gr_factory()->get(fContextType); // Will be owned by device.
SkImageInfo info = SkImageInfo::Make(SkScalarCeilToInt(fGM->width()),
SkScalarCeilToInt(fGM->height()),
- fColorType, kPremul_SkAlphaType);
+ fColorType,
+ kPremul_SkAlphaType);
+ GrContext* gr = fTaskRunner->getGrContextFactory()->get(fContextType); // Owned by surface.
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(gr, info, fSampleCount));
SkCanvas* canvas = surface->getCanvas();
diff --git a/dm/DMGpuTask.h b/dm/DMGpuTask.h
index a3fe52b751..1380e443d4 100644
--- a/dm/DMGpuTask.h
+++ b/dm/DMGpuTask.h
@@ -32,6 +32,7 @@ public:
virtual SkString name() const SK_OVERRIDE { return fName; }
private:
+ TaskRunner* fTaskRunner;
SkAutoTDelete<skiagm::GM> fGM;
const SkString fName;
const Expectations& fExpectations;
diff --git a/dm/DMReporter.cpp b/dm/DMReporter.cpp
index 0fd83e5bb6..1ff64c57cc 100644
--- a/dm/DMReporter.cpp
+++ b/dm/DMReporter.cpp
@@ -3,21 +3,27 @@
#include "SkCommandLineFlags.h"
#include "OverwriteLine.h"
-DEFINE_bool(quiet, false, "If true, don't print status updates.");
+DEFINE_bool2(quiet, q, false, "If true, don't print status updates.");
+DEFINE_bool2(verbose, v, false, "If true, print status updates one-per-line.");
namespace DM {
-void Reporter::updateStatusLine() const {
+void Reporter::finish(SkString name) {
+ sk_atomic_inc(&fFinished);
+
if (FLAGS_quiet) {
return;
}
SkString status;
- status.printf("%s%d tasks left", kSkOverwriteLine, this->started() - this->finished());
+ status.printf("%s%d tasks left",
+ FLAGS_verbose ? "\n" : kSkOverwriteLine,
+ this->started() - this->finished());
const int failed = this->failed();
if (failed > 0) {
status.appendf(", %d failed", failed);
}
+ status.appendf("\t[%s done]", name.c_str());
SkDebugf(status.c_str());
}
@@ -26,9 +32,9 @@ int32_t Reporter::failed() const {
return fFailures.count();
}
-void Reporter::fail(SkString name) {
+void Reporter::fail(SkString msg) {
SkAutoMutexAcquire writer(&fMutex);
- fFailures.push_back(name);
+ fFailures.push_back(msg);
}
void Reporter::getFailures(SkTArray<SkString>* failures) const {
diff --git a/dm/DMReporter.h b/dm/DMReporter.h
index 4f4ad432d5..2bb4702178 100644
--- a/dm/DMReporter.h
+++ b/dm/DMReporter.h
@@ -7,7 +7,6 @@
#include "SkTypes.h"
// Used to report status changes including failures. All public methods are threadsafe.
-
namespace DM {
class Reporter : SkNoncopyable {
@@ -15,15 +14,13 @@ public:
Reporter() : fStarted(0), fFinished(0) {}
void start() { sk_atomic_inc(&fStarted); }
- void finish() { sk_atomic_inc(&fFinished); }
- void fail(SkString name);
+ void finish(SkString name);
+ void fail(SkString msg);
int32_t started() const { return fStarted; }
int32_t finished() const { return fFinished; }
int32_t failed() const;
- void updateStatusLine() const;
-
void getFailures(SkTArray<SkString>*) const;
private:
diff --git a/dm/DMTask.cpp b/dm/DMTask.cpp
index a5c75f0f8a..2f009f0670 100644
--- a/dm/DMTask.cpp
+++ b/dm/DMTask.cpp
@@ -26,8 +26,7 @@ void Task::run() {
if (!this->shouldSkip()) {
this->draw();
}
- fReporter->finish();
- fReporter->updateStatusLine();
+ fReporter->finish(this->name());
delete this;
}
@@ -39,8 +38,12 @@ void Task::spawnChild(Task* task) {
}
}
-void Task::fail() {
- fReporter->fail(this->name());
+void Task::fail(const char* msg) {
+ SkString failure(this->name());
+ if (msg) {
+ failure.appendf(": %s", msg);
+ }
+ fReporter->fail(failure);
}
} // namespace DM
diff --git a/dm/DMTask.h b/dm/DMTask.h
index 0d3ef74cc3..638a939304 100644
--- a/dm/DMTask.h
+++ b/dm/DMTask.h
@@ -34,7 +34,7 @@ public:
protected:
void spawnChild(Task* task);
- void fail();
+ void fail(const char* msg = NULL);
private:
// Both unowned.
diff --git a/dm/DMTaskRunner.cpp b/dm/DMTaskRunner.cpp
index 22269a4d70..bd53ce615a 100644
--- a/dm/DMTaskRunner.cpp
+++ b/dm/DMTaskRunner.cpp
@@ -3,10 +3,21 @@
namespace DM {
-TaskRunner::TaskRunner(int cputhreads, int gpuThreads)
+
+TaskRunner::TaskRunner(int cputhreads)
: fMain(cputhreads)
- , fGpu(gpuThreads)
- {}
+ , fGpu(1) {
+ // Enqueue a task on the GPU thread to create a GrContextFactory.
+ struct Create : public SkRunnable {
+ Create(GrContextFactory** ptr) : fPtr(ptr) {}
+ void run() SK_OVERRIDE {
+ *fPtr = SkNEW(GrContextFactory);
+ delete this;
+ }
+ GrContextFactory** fPtr;
+ };
+ fGpu.add(SkNEW_ARGS(Create, (&fGrContextFactory)));
+}
void TaskRunner::add(Task* task) {
if (task->usesGpu()) {
@@ -17,6 +28,17 @@ void TaskRunner::add(Task* task) {
}
void TaskRunner::wait() {
+ // Enqueue a task on the GPU thread to destroy the GrContextFactory.
+ struct Delete : public SkRunnable {
+ Delete(GrContextFactory* ptr) : fPtr(ptr) {}
+ void run() SK_OVERRIDE {
+ delete fPtr;
+ delete this;
+ }
+ GrContextFactory* fPtr;
+ };
+ fGpu.add(SkNEW_ARGS(Delete, (fGrContextFactory)));
+
// These wait calls block until the threadpool is done. We don't allow
// children to spawn new GPU tasks so we can wait for that first knowing
// we'll never try to add to it later. Same can't be said of fMain: fGpu
diff --git a/dm/DMTaskRunner.h b/dm/DMTaskRunner.h
index 5d7b320d6c..8af1b63719 100644
--- a/dm/DMTaskRunner.h
+++ b/dm/DMTaskRunner.h
@@ -1,12 +1,12 @@
#ifndef DMTaskRunner_DEFINED
#define DMTaskRunner_DEFINED
+#include "GrContextFactory.h"
#include "SkThreadPool.h"
#include "SkTypes.h"
-// TaskRunner runs Tasks on one of two threadpools depending on the Task's usesGpu() method.
-// This lets us drive the GPU with a small number of threads (e.g. 2 or 4 can be faster than 1)
-// while not swamping it with requests from the full fleet of threads that CPU-bound tasks run on.
+// TaskRunner runs Tasks on one of two threadpools depending on the Task's usesGpu() method. This
+// lets us drive the GPU from a single thread while parallelizing CPU-bound work.
namespace DM {
@@ -14,13 +14,17 @@ class Task;
class TaskRunner : SkNoncopyable {
public:
- TaskRunner(int cputhreads, int gpuThreads);
+ explicit TaskRunner(int cputhreads);
void add(Task* task);
void wait();
+ // This can only be safely called from a GPU task's draw() method.
+ GrContextFactory* getGrContextFactory() const { return fGrContextFactory; }
+
private:
SkThreadPool fMain, fGpu;
+ GrContextFactory* fGrContextFactory; // Created and destroyed on fGpu threadpool.
};
} // namespace DM
diff --git a/dm/DMTestTask.cpp b/dm/DMTestTask.cpp
new file mode 100644
index 0000000000..7a5f8cf9f9
--- /dev/null
+++ b/dm/DMTestTask.cpp
@@ -0,0 +1,34 @@
+#include "DMTestTask.h"
+#include "DMUtil.h"
+#include "SkCommandLineFlags.h"
+
+DEFINE_bool2(pathOpsExtended, x, false, "Run extended pathOps tests.");
+DEFINE_bool2(pathOpsSingleThread, z, false, "Disallow pathOps tests from using threads.");
+DEFINE_bool2(pathOpsVerbose, V, false, "Tell pathOps tests to be verbose.");
+
+namespace DM {
+
+TestTask::TestTask(Reporter* reporter,
+ TaskRunner* taskRunner,
+ skiatest::TestRegistry::Factory factory)
+ : Task(reporter, taskRunner)
+ , fTaskRunner(taskRunner)
+ , fTest(factory(NULL))
+ , fName(UnderJoin("test", fTest->getName())) {}
+
+void TestTask::draw() {
+ if (this->usesGpu()) {
+ fTest->setGrContextFactory(fTaskRunner->getGrContextFactory());
+ }
+ fTest->setReporter(&fTestReporter);
+ fTest->run();
+ if (!fTest->passed()) {
+ this->fail(fTestReporter.failure());
+ }
+}
+
+bool TestTask::TestReporter::allowExtendedTest() const { return FLAGS_pathOpsExtended; }
+bool TestTask::TestReporter::allowThreaded() const { return !FLAGS_pathOpsSingleThread; }
+bool TestTask::TestReporter::verbose() const { return FLAGS_pathOpsVerbose; }
+
+} // namespace DM
diff --git a/dm/DMTestTask.h b/dm/DMTestTask.h
new file mode 100644
index 0000000000..a4903ee717
--- /dev/null
+++ b/dm/DMTestTask.h
@@ -0,0 +1,50 @@
+#ifndef DMTestTask_DEFINED
+#define DMTestTask_DEFINED
+
+#include "DMReporter.h"
+#include "DMTask.h"
+#include "DMTaskRunner.h"
+#include "SkString.h"
+#include "SkTemplates.h"
+#include "Test.h"
+
+// Runs a unit test.
+namespace DM {
+
+class TestTask : public Task {
+public:
+ TestTask(Reporter*, TaskRunner*, skiatest::TestRegistry::Factory);
+
+ virtual void draw() SK_OVERRIDE;
+ virtual bool usesGpu() const SK_OVERRIDE { return fTest->isGPUTest(); }
+ virtual bool shouldSkip() const SK_OVERRIDE { return false; }
+ virtual SkString name() const SK_OVERRIDE { return fName; }
+
+private:
+ class TestReporter : public skiatest::Reporter {
+ public:
+ TestReporter() {}
+
+ const char* failure() const { return fFailure.c_str(); }
+
+ private:
+ virtual bool allowExtendedTest() const SK_OVERRIDE;
+ virtual bool allowThreaded() const SK_OVERRIDE;
+ virtual bool verbose() const SK_OVERRIDE;
+
+ virtual void onReportFailed(const SkString& desc) SK_OVERRIDE {
+ fFailure = desc;
+ }
+
+ SkString fFailure;
+ };
+
+ TaskRunner* fTaskRunner;
+ TestReporter fTestReporter;
+ SkAutoTDelete<skiatest::Test> fTest;
+ const SkString fName;
+};
+
+} // namespace DM
+
+#endif // DMTestTask_DEFINED
diff --git a/gyp/dm.gyp b/gyp/dm.gyp
index 3cc51a09ba..55f5f9bd14 100644
--- a/gyp/dm.gyp
+++ b/gyp/dm.gyp
@@ -9,6 +9,7 @@
'include_dirs': [
'../dm',
'../gm',
+ '../tests',
'../src/images',
'../src/lazy',
'../src/core',
@@ -18,7 +19,11 @@
'../src/utils/debugger',
'../tools',
],
- 'includes': [ 'gmslides.gypi' ],
+ 'includes': [
+ 'gmslides.gypi',
+ 'pathops_unittest.gypi',
+ 'tests.gypi',
+ ],
'sources': [
'../dm/DM.cpp',
'../dm/DMCpuTask.cpp',
@@ -30,6 +35,7 @@
'../dm/DMSerializeTask.cpp',
'../dm/DMTask.cpp',
'../dm/DMTaskRunner.cpp',
+ '../dm/DMTestTask.cpp',
'../dm/DMTileGridTask.cpp',
'../dm/DMUtil.cpp',
'../dm/DMWriteTask.cpp',
diff --git a/gyp/tests.gyp b/gyp/tests.gyp
index 44d053e0b0..d0a898c41e 100644
--- a/gyp/tests.gyp
+++ b/gyp/tests.gyp
@@ -7,188 +7,12 @@
{
'target_name': 'tests',
'type': 'executable',
- 'include_dirs' : [
- '../src/core',
- '../src/effects',
- '../src/image',
- '../src/lazy',
- '../src/images',
- '../src/pathops',
- '../src/pdf',
- '../src/pipe/utils',
- '../src/utils',
- '../src/utils/debugger',
- '../tools/',
-
- # Needed for TDStackNesterTest.
- '../experimental/PdfViewer',
- '../experimental/PdfViewer/src',
- ],
'includes': [
'pathops_unittest.gypi',
+ 'tests.gypi',
],
'sources': [
- '../tests/AAClipTest.cpp',
- '../tests/ARGBImageEncoderTest.cpp',
- '../tests/AndroidPaintTest.cpp',
- '../tests/AnnotationTest.cpp',
- '../tests/AtomicTest.cpp',
- '../tests/BBoxHierarchyTest.cpp',
- '../tests/BitSetTest.cpp',
- '../tests/BitmapCopyTest.cpp',
- '../tests/BitmapGetColorTest.cpp',
- '../tests/BitmapHasherTest.cpp',
- '../tests/BitmapHeapTest.cpp',
- '../tests/BitmapTest.cpp',
- '../tests/BlendTest.cpp',
- '../tests/BlitRowTest.cpp',
- '../tests/BlurTest.cpp',
- '../tests/CachedDecodingPixelRefTest.cpp',
- '../tests/CanvasStateTest.cpp',
- '../tests/CanvasTest.cpp',
- '../tests/ChecksumTest.cpp',
- '../tests/ClampRangeTest.cpp',
- '../tests/ClipCacheTest.cpp',
- '../tests/ClipCubicTest.cpp',
- '../tests/ClipStackTest.cpp',
- '../tests/ClipperTest.cpp',
- '../tests/ColorFilterTest.cpp',
- '../tests/ColorPrivTest.cpp',
- '../tests/ColorTest.cpp',
- '../tests/DataRefTest.cpp',
- '../tests/DeferredCanvasTest.cpp',
- '../tests/DequeTest.cpp',
- '../tests/DeviceLooperTest.cpp',
- '../tests/DiscardableMemoryPool.cpp',
- '../tests/DiscardableMemoryTest.cpp',
- '../tests/DocumentTest.cpp',
- '../tests/DrawBitmapRectTest.cpp',
- '../tests/DrawPathTest.cpp',
- '../tests/DrawTextTest.cpp',
- '../tests/DynamicHashTest.cpp',
- '../tests/EmptyPathTest.cpp',
- '../tests/ErrorTest.cpp',
- '../tests/FillPathTest.cpp',
- '../tests/FitsInTest.cpp',
- '../tests/FlatDataTest.cpp',
- '../tests/FlateTest.cpp',
- '../tests/FontHostStreamTest.cpp',
- '../tests/FontHostTest.cpp',
- '../tests/FontMgrTest.cpp',
- '../tests/FontNamesTest.cpp',
- '../tests/FrontBufferedStreamTest.cpp',
- '../tests/GLInterfaceValidation.cpp',
- '../tests/GLProgramsTest.cpp',
- '../tests/GeometryTest.cpp',
- '../tests/GifTest.cpp',
- '../tests/GpuBitmapCopyTest.cpp',
- '../tests/GpuColorFilterTest.cpp',
- '../tests/GpuDrawPathTest.cpp',
- '../tests/GrBinHashKeyTest.cpp',
- '../tests/GrContextFactoryTest.cpp',
- '../tests/GrDrawTargetTest.cpp',
- '../tests/GrMemoryPoolTest.cpp',
- '../tests/GrRedBlackTreeTest.cpp',
- '../tests/GrSurfaceTest.cpp',
- '../tests/GrTBSearchTest.cpp',
- '../tests/GradientTest.cpp',
- '../tests/HashCacheTest.cpp',
- '../tests/ImageCacheTest.cpp',
- '../tests/ImageDecodingTest.cpp',
- '../tests/ImageFilterTest.cpp',
- '../tests/InfRectTest.cpp',
- '../tests/JpegTest.cpp',
- '../tests/LListTest.cpp',
- '../tests/LayerDrawLooperTest.cpp',
- '../tests/MD5Test.cpp',
- '../tests/MallocPixelRefTest.cpp',
- '../tests/MathTest.cpp',
- '../tests/Matrix44Test.cpp',
- '../tests/MatrixClipCollapseTest.cpp',
- '../tests/MatrixTest.cpp',
- '../tests/MemoryTest.cpp',
- '../tests/MemsetTest.cpp',
- '../tests/MessageBusTest.cpp',
- '../tests/MetaDataTest.cpp',
- '../tests/MipMapTest.cpp',
- '../tests/OSPathTest.cpp',
- '../tests/OnceTest.cpp',
- '../tests/PDFPrimitivesTest.cpp',
- '../tests/PackBitsTest.cpp',
- '../tests/PaintTest.cpp',
- '../tests/ParsePathTest.cpp',
- '../tests/PathCoverageTest.cpp',
- '../tests/PathMeasureTest.cpp',
- '../tests/PathTest.cpp',
- '../tests/PathUtilsTest.cpp',
- '../tests/PictureTest.cpp',
- '../tests/PictureUtilsTest.cpp',
- '../tests/PipeTest.cpp',
- '../tests/PixelRefTest.cpp',
- '../tests/PointTest.cpp',
- '../tests/PremulAlphaRoundTripTest.cpp',
- '../tests/QuickRejectTest.cpp',
- '../tests/RTreeTest.cpp',
- '../tests/RandomTest.cpp',
- '../tests/ReadPixelsTest.cpp',
- '../tests/ReadWriteAlphaTest.cpp',
- '../tests/Reader32Test.cpp',
- '../tests/RefCntTest.cpp',
- '../tests/RefDictTest.cpp',
- '../tests/RegionTest.cpp',
- '../tests/ResourceCacheTest.cpp',
- '../tests/RoundRectTest.cpp',
- '../tests/RuntimeConfigTest.cpp',
- '../tests/SHA1Test.cpp',
- '../tests/ScalarTest.cpp',
- '../tests/SerializationTest.cpp',
- '../tests/ShaderImageFilterTest.cpp',
- '../tests/ShaderOpacityTest.cpp',
- '../tests/SkBase64Test.cpp',
- '../tests/SortTest.cpp',
- '../tests/SrcOverTest.cpp',
- '../tests/StreamTest.cpp',
- '../tests/StringTest.cpp',
- '../tests/StrokeTest.cpp',
- '../tests/SurfaceTest.cpp',
- '../tests/TLSTest.cpp',
- '../tests/TSetTest.cpp',
- '../tests/Test.cpp',
- '../tests/Test.h',
- '../tests/TestSize.cpp',
- '../tests/TileGridTest.cpp',
- '../tests/TracingTest.cpp',
- '../tests/ToUnicode.cpp',
- '../tests/Typeface.cpp',
- '../tests/UnicodeTest.cpp',
- '../tests/UnitTestTest.cpp',
- '../tests/UtilsTest.cpp',
- '../tests/WArrayTest.cpp',
- '../tests/WritePixelsTest.cpp',
- '../tests/Writer32Test.cpp',
- '../tests/XfermodeTest.cpp',
'../tests/skia_test.cpp',
-
- '../experimental/PdfViewer/src/SkTDStackNester.h',
- '../tests/TDStackNesterTest.cpp',
-
- # Needed for PipeTest.
- '../src/pipe/utils/SamplePipeControllers.cpp',
-
- # Needed for MatrixClipCollapse test.
- '../src/utils/debugger/SkDrawCommand.h',
- '../src/utils/debugger/SkDrawCommand.cpp',
- '../src/utils/debugger/SkDebugCanvas.h',
- '../src/utils/debugger/SkDebugCanvas.cpp',
- '../src/utils/debugger/SkObjectParser.h',
- '../src/utils/debugger/SkObjectParser.cpp',
- ],
- 'dependencies': [
- 'skia_lib.gyp:skia_lib',
- 'flags.gyp:flags',
- 'experimental.gyp:experimental',
- 'pdf.gyp:pdf',
- 'tools.gyp:picture_utils',
],
'conditions': [
[ 'skia_gpu == 1', {
diff --git a/gyp/tests.gypi b/gyp/tests.gypi
new file mode 100644
index 0000000000..f5143e2028
--- /dev/null
+++ b/gyp/tests.gypi
@@ -0,0 +1,181 @@
+{
+ 'include_dirs': [
+ '../src/core',
+ '../src/effects',
+ '../src/image',
+ '../src/lazy',
+ '../src/images',
+ '../src/pathops',
+ '../src/pdf',
+ '../src/pipe/utils',
+ '../src/utils',
+ '../src/utils/debugger',
+ '../tools/',
+
+ # Needed for TDStackNesterTest.
+ '../experimental/PdfViewer',
+ '../experimental/PdfViewer/src',
+ ],
+ 'dependencies': [
+ 'skia_lib.gyp:skia_lib',
+ 'experimental.gyp:experimental',
+ 'flags.gyp:flags',
+ 'pdf.gyp:pdf',
+ 'tools.gyp:picture_utils',
+ ],
+ 'sources': [
+ '../tests/Test.cpp',
+ '../tests/Test.h',
+
+ '../tests/AAClipTest.cpp',
+ '../tests/ARGBImageEncoderTest.cpp',
+ '../tests/AndroidPaintTest.cpp',
+ '../tests/AnnotationTest.cpp',
+ '../tests/AtomicTest.cpp',
+ '../tests/BBoxHierarchyTest.cpp',
+ '../tests/BitSetTest.cpp',
+ '../tests/BitmapCopyTest.cpp',
+ '../tests/BitmapGetColorTest.cpp',
+ '../tests/BitmapHasherTest.cpp',
+ '../tests/BitmapHeapTest.cpp',
+ '../tests/BitmapTest.cpp',
+ '../tests/BlendTest.cpp',
+ '../tests/BlitRowTest.cpp',
+ '../tests/BlurTest.cpp',
+ '../tests/CachedDecodingPixelRefTest.cpp',
+ '../tests/CanvasStateTest.cpp',
+ '../tests/CanvasTest.cpp',
+ '../tests/ChecksumTest.cpp',
+ '../tests/ClampRangeTest.cpp',
+ '../tests/ClipCacheTest.cpp',
+ '../tests/ClipCubicTest.cpp',
+ '../tests/ClipStackTest.cpp',
+ '../tests/ClipperTest.cpp',
+ '../tests/ColorFilterTest.cpp',
+ '../tests/ColorPrivTest.cpp',
+ '../tests/ColorTest.cpp',
+ '../tests/DataRefTest.cpp',
+ '../tests/DeferredCanvasTest.cpp',
+ '../tests/DequeTest.cpp',
+ '../tests/DeviceLooperTest.cpp',
+ '../tests/DiscardableMemoryPool.cpp',
+ '../tests/DiscardableMemoryTest.cpp',
+ '../tests/DocumentTest.cpp',
+ '../tests/DrawBitmapRectTest.cpp',
+ '../tests/DrawPathTest.cpp',
+ '../tests/DrawTextTest.cpp',
+ '../tests/DynamicHashTest.cpp',
+ '../tests/EmptyPathTest.cpp',
+ '../tests/ErrorTest.cpp',
+ '../tests/FillPathTest.cpp',
+ '../tests/FitsInTest.cpp',
+ '../tests/FlatDataTest.cpp',
+ '../tests/FlateTest.cpp',
+ '../tests/FontHostStreamTest.cpp',
+ '../tests/FontHostTest.cpp',
+ '../tests/FontMgrTest.cpp',
+ '../tests/FontNamesTest.cpp',
+ '../tests/FrontBufferedStreamTest.cpp',
+ '../tests/GLInterfaceValidation.cpp',
+ '../tests/GLProgramsTest.cpp',
+ '../tests/GeometryTest.cpp',
+ '../tests/GifTest.cpp',
+ '../tests/GpuBitmapCopyTest.cpp',
+ '../tests/GpuColorFilterTest.cpp',
+ '../tests/GpuDrawPathTest.cpp',
+ '../tests/GrBinHashKeyTest.cpp',
+ '../tests/GrContextFactoryTest.cpp',
+ '../tests/GrDrawTargetTest.cpp',
+ '../tests/GrMemoryPoolTest.cpp',
+ '../tests/GrRedBlackTreeTest.cpp',
+ '../tests/GrSurfaceTest.cpp',
+ '../tests/GrTBSearchTest.cpp',
+ '../tests/GradientTest.cpp',
+ '../tests/HashCacheTest.cpp',
+ '../tests/ImageCacheTest.cpp',
+ '../tests/ImageDecodingTest.cpp',
+ '../tests/ImageFilterTest.cpp',
+ '../tests/InfRectTest.cpp',
+ '../tests/JpegTest.cpp',
+ '../tests/LListTest.cpp',
+ '../tests/LayerDrawLooperTest.cpp',
+ '../tests/MD5Test.cpp',
+ '../tests/MallocPixelRefTest.cpp',
+ '../tests/MathTest.cpp',
+ '../tests/Matrix44Test.cpp',
+ '../tests/MatrixClipCollapseTest.cpp',
+ '../tests/MatrixTest.cpp',
+ '../tests/MemoryTest.cpp',
+ '../tests/MemsetTest.cpp',
+ '../tests/MessageBusTest.cpp',
+ '../tests/MetaDataTest.cpp',
+ '../tests/MipMapTest.cpp',
+ '../tests/OSPathTest.cpp',
+ '../tests/OnceTest.cpp',
+ '../tests/PDFPrimitivesTest.cpp',
+ '../tests/PackBitsTest.cpp',
+ '../tests/PaintTest.cpp',
+ '../tests/ParsePathTest.cpp',
+ '../tests/PathCoverageTest.cpp',
+ '../tests/PathMeasureTest.cpp',
+ '../tests/PathTest.cpp',
+ '../tests/PathUtilsTest.cpp',
+ '../tests/PictureTest.cpp',
+ '../tests/PictureUtilsTest.cpp',
+ '../tests/PixelRefTest.cpp',
+ '../tests/PointTest.cpp',
+ '../tests/PremulAlphaRoundTripTest.cpp',
+ '../tests/QuickRejectTest.cpp',
+ '../tests/RTreeTest.cpp',
+ '../tests/RandomTest.cpp',
+ '../tests/ReadPixelsTest.cpp',
+ '../tests/ReadWriteAlphaTest.cpp',
+ '../tests/Reader32Test.cpp',
+ '../tests/RefCntTest.cpp',
+ '../tests/RefDictTest.cpp',
+ '../tests/RegionTest.cpp',
+ '../tests/ResourceCacheTest.cpp',
+ '../tests/RoundRectTest.cpp',
+ '../tests/RuntimeConfigTest.cpp',
+ '../tests/SHA1Test.cpp',
+ '../tests/ScalarTest.cpp',
+ '../tests/SerializationTest.cpp',
+ '../tests/ShaderImageFilterTest.cpp',
+ '../tests/ShaderOpacityTest.cpp',
+ '../tests/SkBase64Test.cpp',
+ '../tests/SortTest.cpp',
+ '../tests/SrcOverTest.cpp',
+ '../tests/StreamTest.cpp',
+ '../tests/StringTest.cpp',
+ '../tests/StrokeTest.cpp',
+ '../tests/SurfaceTest.cpp',
+ '../tests/TLSTest.cpp',
+ '../tests/TSetTest.cpp',
+ '../tests/TestSize.cpp',
+ '../tests/TileGridTest.cpp',
+ '../tests/ToUnicode.cpp',
+ '../tests/TracingTest.cpp',
+ '../tests/Typeface.cpp',
+ '../tests/UnicodeTest.cpp',
+ '../tests/UnitTestTest.cpp',
+ '../tests/UtilsTest.cpp',
+ '../tests/WArrayTest.cpp',
+ '../tests/WritePixelsTest.cpp',
+ '../tests/Writer32Test.cpp',
+ '../tests/XfermodeTest.cpp',
+
+ '../tests/MatrixClipCollapseTest.cpp',
+ '../src/utils/debugger/SkDrawCommand.h',
+ '../src/utils/debugger/SkDrawCommand.cpp',
+ '../src/utils/debugger/SkDebugCanvas.h',
+ '../src/utils/debugger/SkDebugCanvas.cpp',
+ '../src/utils/debugger/SkObjectParser.h',
+ '../src/utils/debugger/SkObjectParser.cpp',
+
+ '../tests/PipeTest.cpp',
+ '../src/pipe/utils/SamplePipeControllers.cpp',
+
+ '../tests/TDStackNesterTest.cpp',
+ '../experimental/PdfViewer/src/SkTDStackNester.h',
+ ],
+}
diff --git a/tests/Test.cpp b/tests/Test.cpp
index daa23b132c..95b2f91c0c 100644
--- a/tests/Test.cpp
+++ b/tests/Test.cpp
@@ -7,6 +7,7 @@
*/
#include "Test.h"
+#include "SkCommandLineFlags.h"
#include "SkError.h"
#include "SkString.h"
#include "SkTArray.h"
@@ -19,6 +20,8 @@
class GrContext;
#endif
+DEFINE_string2(tmpDir, t, NULL, "tmp directory for tests to use.");
+
using namespace skiatest;
Reporter::Reporter() : fTestCount(0) {
@@ -114,23 +117,15 @@ void Test::run() {
}
-///////////////////////////////////////////////////////////////////////////////
+SkString Test::GetTmpDir() {
+ const char* tmpDir = FLAGS_tmpDir.isEmpty() ? NULL : FLAGS_tmpDir[0];
+ return SkString(tmpDir);
+}
-#if SK_SUPPORT_GPU
-#include "GrContextFactory.h"
-GrContextFactory gGrContextFactory;
-#endif
+static const char* gResourcePath = NULL;
+void Test::SetResourcePath(const char* resourcePath) { gResourcePath = resourcePath; }
-GrContextFactory* GpuTest::GetGrContextFactory() {
-#if SK_SUPPORT_GPU
- return &gGrContextFactory;
-#else
- return NULL;
-#endif
+SkString Test::GetResourcePath() {
+ return SkString(gResourcePath);
}
-void GpuTest::DestroyContexts() {
-#if SK_SUPPORT_GPU
- gGrContextFactory.destroyContexts();
-#endif
-}
diff --git a/tests/Test.h b/tests/Test.h
index 0a9c306b15..4d2cf2b639 100644
--- a/tests/Test.h
+++ b/tests/Test.h
@@ -62,9 +62,11 @@ namespace skiatest {
static SkString GetTmpDir();
+ static void SetResourcePath(const char*);
static SkString GetResourcePath();
virtual bool isGPUTest() const { return false; }
+ virtual void setGrContextFactory(GrContextFactory* factory) {}
protected:
virtual void onGetName(SkString*) = 0;
@@ -79,11 +81,15 @@ namespace skiatest {
class GpuTest : public Test{
public:
- GpuTest() : Test() {}
- static GrContextFactory* GetGrContextFactory();
- static void DestroyContexts();
+ GpuTest() : Test(), fGrContextFactory(NULL) {}
+
virtual bool isGPUTest() const { return true; }
- private:
+ virtual void setGrContextFactory(GrContextFactory* factory) {
+ fGrContextFactory = factory;
+ }
+
+ protected:
+ GrContextFactory* fGrContextFactory; // Unowned.
};
typedef SkTRegistry<Test*(*)(void*)> TestRegistry;
@@ -162,7 +168,7 @@ namespace skiatest {
name->set(#name); \
} \
virtual void onRun(Reporter* r) SK_OVERRIDE { \
- name(r, GetGrContextFactory()); \
+ name(r, fGrContextFactory); \
} \
}; \
static TestRegistry gReg_##name##Class(name##Class::Factory); \
diff --git a/tests/skia_test.cpp b/tests/skia_test.cpp
index 48d87719d5..3ecb67673e 100644
--- a/tests/skia_test.cpp
+++ b/tests/skia_test.cpp
@@ -17,6 +17,7 @@
#if SK_SUPPORT_GPU
#include "GrContext.h"
+#include "GrContextFactory.h"
#endif
using namespace skiatest;
@@ -29,8 +30,6 @@ DEFINE_string2(match, m, NULL, "[~][^]substring[$] [...] of test name to run.\n"
"^ and $ requires an exact match\n" \
"If a test does not match any list entry,\n" \
"it is skipped unless some list entry starts with ~");
-DEFINE_string2(tmpDir, t, NULL, "tmp directory for tests to use.");
-DEFINE_string2(resourcePath, i, "resources", "directory for test resources.");
DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps.");
DEFINE_bool2(leaks, l, false, "show leaked ref cnt'd objects.");
DEFINE_bool2(single, z, false, "run tests on a single thread internally.");
@@ -40,6 +39,7 @@ DEFINE_bool(cpu, true, "whether or not to run CPU tests.");
DEFINE_bool(gpu, true, "whether or not to run GPU tests.");
DEFINE_int32(threads, SkThreadPool::kThreadPerCore,
"Run threadsafe tests on a threadpool with this many threads.");
+DEFINE_string2(resourcePath, i, "resources", "directory for test resources.");
// need to explicitly declare this, or we get some weird infinite loop llist
template TestRegistry* TestRegistry::gHead;
@@ -98,16 +98,6 @@ private:
const int fTotal;
};
-SkString Test::GetTmpDir() {
- const char* tmpDir = FLAGS_tmpDir.isEmpty() ? NULL : FLAGS_tmpDir[0];
- return SkString(tmpDir);
-}
-
-SkString Test::GetResourcePath() {
- const char* resourcePath = FLAGS_resourcePath.isEmpty() ? NULL : FLAGS_resourcePath[0];
- return SkString(resourcePath);
-}
-
// Deletes self when run.
class SkTestRunnable : public SkRunnable {
public:
@@ -144,6 +134,7 @@ int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
SkCommandLineFlags::SetUsage("");
SkCommandLineFlags::Parse(argc, argv);
+ Test::SetResourcePath(FLAGS_resourcePath[0]);
#if SK_ENABLE_INST_COUNT
if (FLAGS_leaks) {
@@ -199,7 +190,7 @@ int tool_main(int argc, char** argv) {
int skipCount = 0;
SkThreadPool threadpool(FLAGS_threads);
- SkTArray<Test*> unsafeTests; // Always passes ownership to an SkTestRunnable
+ SkTArray<Test*> gpuTests; // Always passes ownership to an SkTestRunnable
DebugfReporter reporter(toRun);
for (int i = 0; i < total; i++) {
@@ -207,15 +198,23 @@ int tool_main(int argc, char** argv) {
if (!should_run(test->getName(), test->isGPUTest())) {
++skipCount;
} else if (test->isGPUTest()) {
- unsafeTests.push_back() = test.detach();
+ gpuTests.push_back() = test.detach();
} else {
threadpool.add(SkNEW_ARGS(SkTestRunnable, (test.detach(), &failCount)));
}
}
- // Run the tests that aren't threadsafe.
- for (int i = 0; i < unsafeTests.count(); i++) {
- SkNEW_ARGS(SkTestRunnable, (unsafeTests[i], &failCount))->run();
+#if SK_SUPPORT_GPU
+ // Give GPU tests a context factory if that makes sense on this machine.
+ GrContextFactory grContextFactory;
+ for (int i = 0; i < gpuTests.count(); i++) {
+ gpuTests[i]->setGrContextFactory(&grContextFactory);
+ }
+#endif
+
+ // Run GPU tests on this thread.
+ for (int i = 0; i < gpuTests.count(); i++) {
+ SkNEW_ARGS(SkTestRunnable, (gpuTests[i], &failCount))->run();
}
// Block until threaded tests finish.
@@ -226,7 +225,6 @@ int tool_main(int argc, char** argv) {
toRun, failCount, skipCount, reporter.countTests());
}
SkGraphics::Term();
- GpuTest::DestroyContexts();
SkDebugf("\n");
return (failCount == 0) ? 0 : 1;