blob: c9a381eb122eed0b66974c4a2024e3b9f54e2336 [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;
bsalomonf2f1c172016-04-05 12:59:06 -070025#endif
bsalomon@google.coma8e686e2011-08-16 15:45:58 +000026
reed@android.comed673312009-02-27 16:24:51 +000027namespace skiatest {
reed@android.com80e39a72009-04-02 16:59:40 +000028
halcanary87f3ba42015-01-20 09:30:20 -080029SkString GetTmpDir();
reed@android.comed673312009-02-27 16:24:51 +000030
halcanary87f3ba42015-01-20 09:30:20 -080031struct Failure {
32 Failure(const char* f, int l, const char* c, const SkString& m)
33 : fileName(f), lineNo(l), condition(c), message(m) {}
34 const char* fileName;
35 int lineNo;
36 const char* condition;
37 SkString message;
38 SkString toString() const;
39};
scroggo0ee26272014-11-07 06:07:32 -080040
halcanary87f3ba42015-01-20 09:30:20 -080041class Reporter : SkNoncopyable {
42public:
43 virtual ~Reporter() {}
44 virtual void bumpTestCount();
45 virtual void reportFailed(const skiatest::Failure&) = 0;
46 virtual bool allowExtendedTest() const;
47 virtual bool verbose() const;
Cary Clarkab87d7a2016-10-04 10:01:04 -040048 virtual void* stats() const { return nullptr; }
Brian Osman287f6512016-12-05 11:35:07 -050049
50 void reportFailedWithContext(const skiatest::Failure& f) {
51 SkString fullMessage = f.message;
52 if (!fContextStack.empty()) {
53 fullMessage.append(" [");
54 for (int i = 0; i < fContextStack.count(); ++i) {
55 if (i > 0) {
56 fullMessage.append(", ");
57 }
58 fullMessage.append(fContextStack[i]);
59 }
60 fullMessage.append("]");
61 }
62 this->reportFailed(skiatest::Failure(f.fileName, f.lineNo, f.condition, fullMessage));
63 }
64 void push(const SkString& message) {
65 fContextStack.push_back(message);
66 }
67 void pop() {
68 fContextStack.pop_back();
69 }
70
71private:
72 SkTArray<SkString> fContextStack;
halcanary87f3ba42015-01-20 09:30:20 -080073};
scroggo0ee26272014-11-07 06:07:32 -080074
halcanary87f3ba42015-01-20 09:30:20 -080075#define REPORT_FAILURE(reporter, cond, message) \
Brian Osman287f6512016-12-05 11:35:07 -050076 reporter->reportFailedWithContext(skiatest::Failure(__FILE__, __LINE__, cond, message))
77
78class ReporterContext : SkNoncopyable {
79public:
80 ReporterContext(Reporter* reporter, const SkString& message) : fReporter(reporter) {
81 fReporter->push(message);
82 }
83 ~ReporterContext() {
84 fReporter->pop();
85 }
86
87private:
88 Reporter* fReporter;
89};
scroggo0ee26272014-11-07 06:07:32 -080090
bsalomon3724e572016-03-30 18:56:19 -070091typedef void (*TestProc)(skiatest::Reporter*, sk_gpu_test::GrContextFactory*);
reed@android.comed673312009-02-27 16:24:51 +000092
halcanary87f3ba42015-01-20 09:30:20 -080093struct Test {
94 Test(const char* n, bool g, TestProc p) : name(n), needsGpu(g), proc(p) {}
95 const char* name;
96 bool needsGpu;
97 TestProc proc;
Mike Kleinb323a5e2017-07-24 15:21:31 -040098
99 void run(skiatest::Reporter* r, sk_gpu_test::GrContextFactory* factory) const {
100 TRACE_EVENT1("test", TRACE_FUNC, "name", this->name/*these are static*/);
101 this->proc(r, factory);
102 }
halcanary87f3ba42015-01-20 09:30:20 -0800103};
reed@android.comed673312009-02-27 16:24:51 +0000104
Mike Reedab273fa2017-01-11 13:58:55 -0500105typedef sk_tools::Registry<Test> TestRegistry;
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000106
107/*
108 Use the following macros to make use of the skiatest classes, e.g.
109
110 #include "Test.h"
111
112 DEF_TEST(TestName, reporter) {
113 ...
114 REPORTER_ASSERT(reporter, x == 15);
115 ...
116 REPORTER_ASSERT_MESSAGE(reporter, x == 15, "x should be 15");
117 ...
118 if (x != 15) {
119 ERRORF(reporter, "x should be 15, but is %d", x);
120 return;
121 }
122 ...
123 }
124*/
bsalomon758586c2016-04-06 14:02:39 -0700125
126#if SK_SUPPORT_GPU
127using GrContextFactoryContextType = sk_gpu_test::GrContextFactory::ContextType;
128#else
129using GrContextFactoryContextType = int;
130#endif
bsalomonf2f1c172016-04-05 12:59:06 -0700131
132typedef void GrContextTestFn(Reporter*, const sk_gpu_test::ContextInfo&);
bsalomon758586c2016-04-06 14:02:39 -0700133typedef bool GrContextTypeFilterFn(GrContextFactoryContextType);
bsalomonf2f1c172016-04-05 12:59:06 -0700134
bsalomon758586c2016-04-06 14:02:39 -0700135extern bool IsGLContextType(GrContextFactoryContextType);
bsalomondc0fcd42016-04-11 14:21:33 -0700136extern bool IsVulkanContextType(GrContextFactoryContextType);
bsalomon758586c2016-04-06 14:02:39 -0700137extern bool IsRenderingGLContextType(GrContextFactoryContextType);
138extern bool IsNullGLContextType(GrContextFactoryContextType);
bsalomon758586c2016-04-06 14:02:39 -0700139void RunWithGPUTestContexts(GrContextTestFn*, GrContextTypeFilterFn*,
140 Reporter*, sk_gpu_test::GrContextFactory*);
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700141
142/** Timer provides wall-clock duration since its creation. */
143class Timer {
144public:
145 /** Starts the timer. */
146 Timer();
147
148 /** Nanoseconds since creation. */
149 double elapsedNs() const;
150
151 /** Milliseconds since creation. */
152 double elapsedMs() const;
153
154 /** Milliseconds since creation as an integer.
155 Behavior is undefined for durations longer than SK_MSecMax.
156 */
157 SkMSec elapsedMsInt() const;
158private:
159 double fStartNanos;
160};
161
halcanary87f3ba42015-01-20 09:30:20 -0800162} // namespace skiatest
reed@android.comed673312009-02-27 16:24:51 +0000163
halcanary87f3ba42015-01-20 09:30:20 -0800164#define REPORTER_ASSERT(r, cond) \
165 do { \
166 if (!(cond)) { \
167 REPORT_FAILURE(r, #cond, SkString()); \
168 } \
169 } while (0)
reed@android.comed673312009-02-27 16:24:51 +0000170
halcanary87f3ba42015-01-20 09:30:20 -0800171#define REPORTER_ASSERT_MESSAGE(r, cond, message) \
172 do { \
173 if (!(cond)) { \
174 REPORT_FAILURE(r, #cond, SkString(message)); \
175 } \
176 } while (0)
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000177
halcanary87f3ba42015-01-20 09:30:20 -0800178#define ERRORF(r, ...) \
179 do { \
180 REPORT_FAILURE(r, "", SkStringPrintf(__VA_ARGS__)); \
181 } while (0)
reed@android.comed673312009-02-27 16:24:51 +0000182
halcanary7d571242016-02-24 17:59:16 -0800183#define INFOF(REPORTER, ...) \
184 do { \
185 if ((REPORTER)->verbose()) { \
186 SkDebugf(__VA_ARGS__); \
187 } \
188 } while (0)
189
bsalomon3724e572016-03-30 18:56:19 -0700190#define DEF_TEST(name, reporter) \
191 static void test_##name(skiatest::Reporter*, sk_gpu_test::GrContextFactory*); \
192 skiatest::TestRegistry name##TestRegistry( \
193 skiatest::Test(#name, false, test_##name)); \
194 void test_##name(skiatest::Reporter* reporter, sk_gpu_test::GrContextFactory*)
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000195
kkinnunen179a8f52015-11-20 13:32:24 -0800196
bsalomonf2f1c172016-04-05 12:59:06 -0700197#define DEF_GPUTEST(name, reporter, factory) \
198 static void test_##name(skiatest::Reporter*, sk_gpu_test::GrContextFactory*); \
199 skiatest::TestRegistry name##TestRegistry( \
200 skiatest::Test(#name, true, test_##name)); \
bsalomon3724e572016-03-30 18:56:19 -0700201 void test_##name(skiatest::Reporter* reporter, sk_gpu_test::GrContextFactory* factory)
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000202
bsalomonfda88072016-04-11 14:40:50 -0700203#define DEF_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info) \
204 static void test_##name(skiatest::Reporter*, \
205 const sk_gpu_test::ContextInfo& context_info); \
206 static void test_gpu_contexts_##name(skiatest::Reporter* reporter, \
207 sk_gpu_test::GrContextFactory* factory) { \
208 skiatest::RunWithGPUTestContexts(test_##name, context_filter, reporter, factory); \
209 } \
210 skiatest::TestRegistry name##TestRegistry( \
211 skiatest::Test(#name, true, test_gpu_contexts_##name)); \
212 void test_##name(skiatest::Reporter* reporter, \
bsalomonf2f1c172016-04-05 12:59:06 -0700213 const sk_gpu_test::ContextInfo& context_info)
kkinnunen179a8f52015-11-20 13:32:24 -0800214
bsalomonfda88072016-04-11 14:40:50 -0700215#define DEF_GPUTEST_FOR_ALL_CONTEXTS(name, reporter, context_info) \
216 DEF_GPUTEST_FOR_CONTEXTS(name, nullptr, reporter, context_info)
bsalomon68d91342016-04-12 09:59:58 -0700217#define DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info) \
218 DEF_GPUTEST_FOR_CONTEXTS(name, sk_gpu_test::GrContextFactory::IsRenderingContext, \
219 reporter, context_info)
bsalomon758586c2016-04-06 14:02:39 -0700220#define DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(name, reporter, context_info) \
221 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsGLContextType, reporter, context_info)
222#define DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(name, reporter, context_info) \
223 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsRenderingGLContextType, reporter, context_info)
224#define DEF_GPUTEST_FOR_NULLGL_CONTEXT(name, reporter, context_info) \
225 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsNullGLContextType, reporter, context_info)
bsalomondc0fcd42016-04-11 14:21:33 -0700226#define DEF_GPUTEST_FOR_VULKAN_CONTEXT(name, reporter, context_info) \
227 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsVulkanContextType, reporter, context_info)
kkinnunen179a8f52015-11-20 13:32:24 -0800228
halcanary4b656662016-04-27 07:45:18 -0700229#define REQUIRE_PDF_DOCUMENT(TEST_NAME, REPORTER) \
230 do { \
231 SkDynamicMemoryWStream testStream; \
232 sk_sp<SkDocument> testDoc(SkDocument::MakePDF(&testStream)); \
233 if (!testDoc) { \
234 INFOF(REPORTER, "PDF disabled; %s test skipped.", #TEST_NAME); \
235 return; \
236 } \
halcanary2ccdb632015-08-11 13:35:12 -0700237 } while (false)
238
reed@android.comed673312009-02-27 16:24:51 +0000239#endif