blob: f74b98aa9c336037e2f886d000cc5b0bf2c6fc6a [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
reed@android.comed673312009-02-27 16:24:51 +00007#ifndef skiatest_Test_DEFINED
8#define skiatest_Test_DEFINED
9
Mike Reedab273fa2017-01-11 13:58:55 -050010#include "../tools/Registry.h"
Mike Reedebfce6d2016-12-12 10:02:12 -050011#include "SkClipOpPriv.h"
Mike Kleinb323a5e2017-07-24 15:21:31 -040012#include "SkString.h"
13#include "SkTraceEvent.h"
14#include "SkTypes.h"
reed@android.comed673312009-02-27 16:24:51 +000015
bsalomonf2f1c172016-04-05 12:59:06 -070016#if SK_SUPPORT_GPU
17#include "GrContextFactory.h"
18#else
bsalomon3724e572016-03-30 18:56:19 -070019namespace sk_gpu_test {
bsalomon@google.com67b915d2013-02-04 16:13:32 +000020class GrContextFactory;
bsalomonf2f1c172016-04-05 12:59:06 -070021class ContextInfo;
bsalomon273c0f52016-03-31 10:59:06 -070022class GLTestContext;
bsalomon3724e572016-03-30 18:56:19 -070023} // namespace sk_gpu_test
kkinnunen179a8f52015-11-20 13:32:24 -080024class GrContext;
Robert Phillips0b6a3e42017-10-30 18:05:00 +000025struct GrContextOptions;
bsalomonf2f1c172016-04-05 12:59:06 -070026#endif
bsalomon@google.coma8e686e2011-08-16 15:45:58 +000027
reed@android.comed673312009-02-27 16:24:51 +000028namespace skiatest {
reed@android.com80e39a72009-04-02 16:59:40 +000029
halcanary87f3ba42015-01-20 09:30:20 -080030SkString GetTmpDir();
reed@android.comed673312009-02-27 16:24:51 +000031
halcanary87f3ba42015-01-20 09:30:20 -080032struct Failure {
33 Failure(const char* f, int l, const char* c, const SkString& m)
34 : fileName(f), lineNo(l), condition(c), message(m) {}
35 const char* fileName;
36 int lineNo;
37 const char* condition;
38 SkString message;
39 SkString toString() const;
40};
scroggo0ee26272014-11-07 06:07:32 -080041
halcanary87f3ba42015-01-20 09:30:20 -080042class Reporter : SkNoncopyable {
43public:
44 virtual ~Reporter() {}
45 virtual void bumpTestCount();
46 virtual void reportFailed(const skiatest::Failure&) = 0;
47 virtual bool allowExtendedTest() const;
48 virtual bool verbose() const;
Cary Clarkab87d7a2016-10-04 10:01:04 -040049 virtual void* stats() const { return nullptr; }
Brian Osman287f6512016-12-05 11:35:07 -050050
51 void reportFailedWithContext(const skiatest::Failure& f) {
52 SkString fullMessage = f.message;
53 if (!fContextStack.empty()) {
54 fullMessage.append(" [");
55 for (int i = 0; i < fContextStack.count(); ++i) {
56 if (i > 0) {
57 fullMessage.append(", ");
58 }
59 fullMessage.append(fContextStack[i]);
60 }
61 fullMessage.append("]");
62 }
63 this->reportFailed(skiatest::Failure(f.fileName, f.lineNo, f.condition, fullMessage));
64 }
65 void push(const SkString& message) {
66 fContextStack.push_back(message);
67 }
68 void pop() {
69 fContextStack.pop_back();
70 }
71
72private:
73 SkTArray<SkString> fContextStack;
halcanary87f3ba42015-01-20 09:30:20 -080074};
scroggo0ee26272014-11-07 06:07:32 -080075
halcanary87f3ba42015-01-20 09:30:20 -080076#define REPORT_FAILURE(reporter, cond, message) \
Brian Osman287f6512016-12-05 11:35:07 -050077 reporter->reportFailedWithContext(skiatest::Failure(__FILE__, __LINE__, cond, message))
78
79class ReporterContext : SkNoncopyable {
80public:
81 ReporterContext(Reporter* reporter, const SkString& message) : fReporter(reporter) {
82 fReporter->push(message);
83 }
84 ~ReporterContext() {
85 fReporter->pop();
86 }
87
88private:
89 Reporter* fReporter;
90};
scroggo0ee26272014-11-07 06:07:32 -080091
Brian Salomondcfca432017-11-15 15:48:03 -050092typedef void (*TestProc)(skiatest::Reporter*, const GrContextOptions&);
Robert Phillipsec325342017-10-30 18:02:48 +000093typedef void (*ContextOptionsProc)(GrContextOptions*);
reed@android.comed673312009-02-27 16:24:51 +000094
halcanary87f3ba42015-01-20 09:30:20 -080095struct Test {
Robert Phillipsec325342017-10-30 18:02:48 +000096 Test(const char* n, bool g, TestProc p, ContextOptionsProc optionsProc = nullptr)
97 : name(n), needsGpu(g), proc(p), fContextOptionsProc(optionsProc) {}
halcanary87f3ba42015-01-20 09:30:20 -080098 const char* name;
99 bool needsGpu;
100 TestProc proc;
Robert Phillipsec325342017-10-30 18:02:48 +0000101 ContextOptionsProc fContextOptionsProc;
102
103 void modifyGrContextOptions(GrContextOptions* options) {
104 if (fContextOptionsProc) {
105 (*fContextOptionsProc)(options);
106 }
107 }
Mike Kleinb323a5e2017-07-24 15:21:31 -0400108
Brian Salomondcfca432017-11-15 15:48:03 -0500109 void run(skiatest::Reporter* r, const GrContextOptions& options) const {
Mike Kleinb323a5e2017-07-24 15:21:31 -0400110 TRACE_EVENT1("test", TRACE_FUNC, "name", this->name/*these are static*/);
Brian Salomondcfca432017-11-15 15:48:03 -0500111 this->proc(r, options);
Mike Kleinb323a5e2017-07-24 15:21:31 -0400112 }
halcanary87f3ba42015-01-20 09:30:20 -0800113};
reed@android.comed673312009-02-27 16:24:51 +0000114
Mike Reedab273fa2017-01-11 13:58:55 -0500115typedef sk_tools::Registry<Test> TestRegistry;
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000116
117/*
118 Use the following macros to make use of the skiatest classes, e.g.
119
120 #include "Test.h"
121
122 DEF_TEST(TestName, reporter) {
123 ...
124 REPORTER_ASSERT(reporter, x == 15);
125 ...
Brian Salomon1c80e992018-01-29 09:50:47 -0500126 REPORTER_ASSERT(reporter, x == 15, "x should be 15");
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000127 ...
128 if (x != 15) {
129 ERRORF(reporter, "x should be 15, but is %d", x);
130 return;
131 }
132 ...
133 }
134*/
bsalomon758586c2016-04-06 14:02:39 -0700135
136#if SK_SUPPORT_GPU
137using GrContextFactoryContextType = sk_gpu_test::GrContextFactory::ContextType;
138#else
139using GrContextFactoryContextType = int;
140#endif
bsalomonf2f1c172016-04-05 12:59:06 -0700141
142typedef void GrContextTestFn(Reporter*, const sk_gpu_test::ContextInfo&);
bsalomon758586c2016-04-06 14:02:39 -0700143typedef bool GrContextTypeFilterFn(GrContextFactoryContextType);
bsalomonf2f1c172016-04-05 12:59:06 -0700144
bsalomon758586c2016-04-06 14:02:39 -0700145extern bool IsGLContextType(GrContextFactoryContextType);
bsalomondc0fcd42016-04-11 14:21:33 -0700146extern bool IsVulkanContextType(GrContextFactoryContextType);
bsalomon758586c2016-04-06 14:02:39 -0700147extern bool IsRenderingGLContextType(GrContextFactoryContextType);
148extern bool IsNullGLContextType(GrContextFactoryContextType);
Brian Salomondcfca432017-11-15 15:48:03 -0500149void RunWithGPUTestContexts(GrContextTestFn*, GrContextTypeFilterFn*, Reporter*,
150 const GrContextOptions&);
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700151
152/** Timer provides wall-clock duration since its creation. */
153class Timer {
154public:
155 /** Starts the timer. */
156 Timer();
157
158 /** Nanoseconds since creation. */
159 double elapsedNs() const;
160
161 /** Milliseconds since creation. */
162 double elapsedMs() const;
163
164 /** Milliseconds since creation as an integer.
165 Behavior is undefined for durations longer than SK_MSecMax.
166 */
167 SkMSec elapsedMsInt() const;
168private:
169 double fStartNanos;
170};
171
halcanary87f3ba42015-01-20 09:30:20 -0800172} // namespace skiatest
reed@android.comed673312009-02-27 16:24:51 +0000173
Brian Salomon1c80e992018-01-29 09:50:47 -0500174#define REPORTER_ASSERT(r, cond, ...) \
175 do { \
176 if (!(cond)) { \
177 REPORT_FAILURE(r, #cond, SkStringPrintf(__VA_ARGS__)); \
178 } \
halcanary87f3ba42015-01-20 09:30:20 -0800179 } while (0)
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000180
halcanary87f3ba42015-01-20 09:30:20 -0800181#define ERRORF(r, ...) \
182 do { \
183 REPORT_FAILURE(r, "", SkStringPrintf(__VA_ARGS__)); \
184 } while (0)
reed@android.comed673312009-02-27 16:24:51 +0000185
halcanary7d571242016-02-24 17:59:16 -0800186#define INFOF(REPORTER, ...) \
187 do { \
188 if ((REPORTER)->verbose()) { \
189 SkDebugf(__VA_ARGS__); \
190 } \
191 } while (0)
192
Brian Salomondcfca432017-11-15 15:48:03 -0500193#define DEF_TEST(name, reporter) \
194 static void test_##name(skiatest::Reporter*, const GrContextOptions&); \
195 skiatest::TestRegistry name##TestRegistry(skiatest::Test(#name, false, test_##name)); \
196 void test_##name(skiatest::Reporter* reporter, const GrContextOptions&)
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000197
Brian Salomondcfca432017-11-15 15:48:03 -0500198#define DEF_GPUTEST(name, reporter, options) \
199 static void test_##name(skiatest::Reporter*, const GrContextOptions&); \
200 skiatest::TestRegistry name##TestRegistry(skiatest::Test(#name, true, test_##name)); \
201 void test_##name(skiatest::Reporter* reporter, const GrContextOptions& options)
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000202
Robert Phillipsec325342017-10-30 18:02:48 +0000203#define DEF_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info, options_filter) \
Brian Salomondcfca432017-11-15 15:48:03 -0500204 static void test_##name(skiatest::Reporter*, const sk_gpu_test::ContextInfo& context_info); \
Robert Phillipsec325342017-10-30 18:02:48 +0000205 static void test_gpu_contexts_##name(skiatest::Reporter* reporter, \
Brian Salomondcfca432017-11-15 15:48:03 -0500206 const GrContextOptions& options) { \
207 skiatest::RunWithGPUTestContexts(test_##name, context_filter, reporter, options); \
Robert Phillipsec325342017-10-30 18:02:48 +0000208 } \
209 skiatest::TestRegistry name##TestRegistry( \
210 skiatest::Test(#name, true, test_gpu_contexts_##name, options_filter)); \
Brian Salomondcfca432017-11-15 15:48:03 -0500211 void test_##name(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& context_info)
kkinnunen179a8f52015-11-20 13:32:24 -0800212
bsalomonfda88072016-04-11 14:40:50 -0700213#define DEF_GPUTEST_FOR_ALL_CONTEXTS(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000214 DEF_GPUTEST_FOR_CONTEXTS(name, nullptr, reporter, context_info, nullptr)
215
bsalomon68d91342016-04-12 09:59:58 -0700216#define DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info) \
217 DEF_GPUTEST_FOR_CONTEXTS(name, sk_gpu_test::GrContextFactory::IsRenderingContext, \
Robert Phillipsec325342017-10-30 18:02:48 +0000218 reporter, context_info, nullptr)
bsalomon758586c2016-04-06 14:02:39 -0700219#define DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000220 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsGLContextType, \
221 reporter, context_info, nullptr)
bsalomon758586c2016-04-06 14:02:39 -0700222#define DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000223 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsRenderingGLContextType, \
224 reporter, context_info, nullptr)
bsalomon758586c2016-04-06 14:02:39 -0700225#define DEF_GPUTEST_FOR_NULLGL_CONTEXT(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000226 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsNullGLContextType, \
227 reporter, context_info, nullptr)
bsalomondc0fcd42016-04-11 14:21:33 -0700228#define DEF_GPUTEST_FOR_VULKAN_CONTEXT(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000229 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsVulkanContextType, \
230 reporter, context_info, nullptr)
kkinnunen179a8f52015-11-20 13:32:24 -0800231
halcanary4b656662016-04-27 07:45:18 -0700232#define REQUIRE_PDF_DOCUMENT(TEST_NAME, REPORTER) \
233 do { \
234 SkDynamicMemoryWStream testStream; \
235 sk_sp<SkDocument> testDoc(SkDocument::MakePDF(&testStream)); \
236 if (!testDoc) { \
237 INFOF(REPORTER, "PDF disabled; %s test skipped.", #TEST_NAME); \
238 return; \
239 } \
halcanary2ccdb632015-08-11 13:35:12 -0700240 } while (false)
241
reed@android.comed673312009-02-27 16:24:51 +0000242#endif