blob: f02b751c94d2894eb22a2073af4f41d5849a861b [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 Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkString.h"
11#include "include/core/SkTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "src/core/SkTraceEvent.h"
13#include "tools/Registry.h"
14#include "tools/gpu/GrContextFactory.h"
bsalomon@google.coma8e686e2011-08-16 15:45:58 +000015
reed@android.comed673312009-02-27 16:24:51 +000016namespace skiatest {
reed@android.com80e39a72009-04-02 16:59:40 +000017
halcanary87f3ba42015-01-20 09:30:20 -080018SkString GetTmpDir();
reed@android.comed673312009-02-27 16:24:51 +000019
halcanary87f3ba42015-01-20 09:30:20 -080020struct Failure {
21 Failure(const char* f, int l, const char* c, const SkString& m)
22 : fileName(f), lineNo(l), condition(c), message(m) {}
23 const char* fileName;
24 int lineNo;
25 const char* condition;
26 SkString message;
27 SkString toString() const;
28};
scroggo0ee26272014-11-07 06:07:32 -080029
halcanary87f3ba42015-01-20 09:30:20 -080030class Reporter : SkNoncopyable {
31public:
32 virtual ~Reporter() {}
33 virtual void bumpTestCount();
34 virtual void reportFailed(const skiatest::Failure&) = 0;
35 virtual bool allowExtendedTest() const;
36 virtual bool verbose() const;
Cary Clarkab87d7a2016-10-04 10:01:04 -040037 virtual void* stats() const { return nullptr; }
Brian Osman287f6512016-12-05 11:35:07 -050038
Mike Klein4d907da2019-02-07 09:54:30 -050039 void reportFailedWithContext(const skiatest::Failure&);
40
Brian Osman287f6512016-12-05 11:35:07 -050041 void push(const SkString& message) {
42 fContextStack.push_back(message);
43 }
44 void pop() {
45 fContextStack.pop_back();
46 }
47
48private:
49 SkTArray<SkString> fContextStack;
halcanary87f3ba42015-01-20 09:30:20 -080050};
scroggo0ee26272014-11-07 06:07:32 -080051
halcanary87f3ba42015-01-20 09:30:20 -080052#define REPORT_FAILURE(reporter, cond, message) \
Brian Osman287f6512016-12-05 11:35:07 -050053 reporter->reportFailedWithContext(skiatest::Failure(__FILE__, __LINE__, cond, message))
54
55class ReporterContext : SkNoncopyable {
56public:
57 ReporterContext(Reporter* reporter, const SkString& message) : fReporter(reporter) {
58 fReporter->push(message);
59 }
60 ~ReporterContext() {
61 fReporter->pop();
62 }
63
64private:
65 Reporter* fReporter;
66};
scroggo0ee26272014-11-07 06:07:32 -080067
Brian Salomondcfca432017-11-15 15:48:03 -050068typedef void (*TestProc)(skiatest::Reporter*, const GrContextOptions&);
Robert Phillipsec325342017-10-30 18:02:48 +000069typedef void (*ContextOptionsProc)(GrContextOptions*);
reed@android.comed673312009-02-27 16:24:51 +000070
halcanary87f3ba42015-01-20 09:30:20 -080071struct Test {
Robert Phillipsec325342017-10-30 18:02:48 +000072 Test(const char* n, bool g, TestProc p, ContextOptionsProc optionsProc = nullptr)
73 : name(n), needsGpu(g), proc(p), fContextOptionsProc(optionsProc) {}
halcanary87f3ba42015-01-20 09:30:20 -080074 const char* name;
75 bool needsGpu;
76 TestProc proc;
Robert Phillipsec325342017-10-30 18:02:48 +000077 ContextOptionsProc fContextOptionsProc;
78
79 void modifyGrContextOptions(GrContextOptions* options) {
80 if (fContextOptionsProc) {
81 (*fContextOptionsProc)(options);
82 }
83 }
Mike Kleinb323a5e2017-07-24 15:21:31 -040084
Brian Salomondcfca432017-11-15 15:48:03 -050085 void run(skiatest::Reporter* r, const GrContextOptions& options) const {
Mike Kleinb323a5e2017-07-24 15:21:31 -040086 TRACE_EVENT1("test", TRACE_FUNC, "name", this->name/*these are static*/);
Brian Salomondcfca432017-11-15 15:48:03 -050087 this->proc(r, options);
Mike Kleinb323a5e2017-07-24 15:21:31 -040088 }
halcanary87f3ba42015-01-20 09:30:20 -080089};
reed@android.comed673312009-02-27 16:24:51 +000090
Mike Reedab273fa2017-01-11 13:58:55 -050091typedef sk_tools::Registry<Test> TestRegistry;
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +000092
93/*
94 Use the following macros to make use of the skiatest classes, e.g.
95
Mike Kleinc0bd9f92019-04-23 12:05:21 -050096 #include "tests/Test.h"
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +000097
98 DEF_TEST(TestName, reporter) {
99 ...
100 REPORTER_ASSERT(reporter, x == 15);
101 ...
Brian Salomon1c80e992018-01-29 09:50:47 -0500102 REPORTER_ASSERT(reporter, x == 15, "x should be 15");
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000103 ...
104 if (x != 15) {
105 ERRORF(reporter, "x should be 15, but is %d", x);
106 return;
107 }
108 ...
109 }
110*/
bsalomon758586c2016-04-06 14:02:39 -0700111
bsalomon758586c2016-04-06 14:02:39 -0700112using GrContextFactoryContextType = sk_gpu_test::GrContextFactory::ContextType;
bsalomonf2f1c172016-04-05 12:59:06 -0700113
114typedef void GrContextTestFn(Reporter*, const sk_gpu_test::ContextInfo&);
bsalomon758586c2016-04-06 14:02:39 -0700115typedef bool GrContextTypeFilterFn(GrContextFactoryContextType);
bsalomonf2f1c172016-04-05 12:59:06 -0700116
bsalomon758586c2016-04-06 14:02:39 -0700117extern bool IsGLContextType(GrContextFactoryContextType);
bsalomondc0fcd42016-04-11 14:21:33 -0700118extern bool IsVulkanContextType(GrContextFactoryContextType);
Timothy Liang760dbc42018-07-17 13:28:20 -0400119extern bool IsMetalContextType(GrContextFactoryContextType);
Greg Daniela58db7f2020-07-15 09:17:59 -0400120extern bool IsDawnContextType(GrContextFactoryContextType);
Greg Danield4928d02020-06-19 11:13:26 -0400121extern bool IsDirect3DContextType(GrContextFactoryContextType);
bsalomon758586c2016-04-06 14:02:39 -0700122extern bool IsRenderingGLContextType(GrContextFactoryContextType);
Brian Osman7c597742019-03-26 11:10:11 -0400123extern bool IsMockContextType(GrContextFactoryContextType);
Brian Salomondcfca432017-11-15 15:48:03 -0500124void RunWithGPUTestContexts(GrContextTestFn*, GrContextTypeFilterFn*, Reporter*,
125 const GrContextOptions&);
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700126
127/** Timer provides wall-clock duration since its creation. */
128class Timer {
129public:
130 /** Starts the timer. */
131 Timer();
132
133 /** Nanoseconds since creation. */
134 double elapsedNs() const;
135
136 /** Milliseconds since creation. */
137 double elapsedMs() const;
138
139 /** Milliseconds since creation as an integer.
140 Behavior is undefined for durations longer than SK_MSecMax.
141 */
142 SkMSec elapsedMsInt() const;
143private:
144 double fStartNanos;
145};
146
halcanary87f3ba42015-01-20 09:30:20 -0800147} // namespace skiatest
reed@android.comed673312009-02-27 16:24:51 +0000148
Adlai Holler684838f2020-05-12 10:41:04 -0400149static inline SkString reporter_string() { return {}; }
150/// Prevent security warnings when using a non-literal string i.e. not a format string.
151static inline SkString reporter_string(const char* s) { return SkString(s); }
152template<typename... Args>
153static inline SkString reporter_string(const char* fmt, Args... args) {
154 return SkStringPrintf(fmt, std::forward<Args>(args)...);
155}
156
157#define REPORTER_ASSERT(r, cond, ...) \
158 do { \
159 if (!(cond)) { \
160 REPORT_FAILURE(r, #cond, reporter_string(__VA_ARGS__)); \
161 } \
halcanary87f3ba42015-01-20 09:30:20 -0800162 } while (0)
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000163
Adlai Holler684838f2020-05-12 10:41:04 -0400164#define ERRORF(r, ...) \
165 do { \
166 REPORT_FAILURE(r, "", reporter_string(__VA_ARGS__)); \
halcanary87f3ba42015-01-20 09:30:20 -0800167 } while (0)
reed@android.comed673312009-02-27 16:24:51 +0000168
halcanary7d571242016-02-24 17:59:16 -0800169#define INFOF(REPORTER, ...) \
170 do { \
171 if ((REPORTER)->verbose()) { \
172 SkDebugf(__VA_ARGS__); \
173 } \
174 } while (0)
175
Brian Salomondcfca432017-11-15 15:48:03 -0500176#define DEF_TEST(name, reporter) \
177 static void test_##name(skiatest::Reporter*, const GrContextOptions&); \
178 skiatest::TestRegistry name##TestRegistry(skiatest::Test(#name, false, test_##name)); \
179 void test_##name(skiatest::Reporter* reporter, const GrContextOptions&)
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000180
Brian Salomondcfca432017-11-15 15:48:03 -0500181#define DEF_GPUTEST(name, reporter, options) \
182 static void test_##name(skiatest::Reporter*, const GrContextOptions&); \
183 skiatest::TestRegistry name##TestRegistry(skiatest::Test(#name, true, test_##name)); \
184 void test_##name(skiatest::Reporter* reporter, const GrContextOptions& options)
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000185
Robert Phillipsec325342017-10-30 18:02:48 +0000186#define DEF_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info, options_filter) \
Brian Salomondcfca432017-11-15 15:48:03 -0500187 static void test_##name(skiatest::Reporter*, const sk_gpu_test::ContextInfo& context_info); \
Robert Phillipsec325342017-10-30 18:02:48 +0000188 static void test_gpu_contexts_##name(skiatest::Reporter* reporter, \
Brian Salomondcfca432017-11-15 15:48:03 -0500189 const GrContextOptions& options) { \
190 skiatest::RunWithGPUTestContexts(test_##name, context_filter, reporter, options); \
Robert Phillipsec325342017-10-30 18:02:48 +0000191 } \
192 skiatest::TestRegistry name##TestRegistry( \
193 skiatest::Test(#name, true, test_gpu_contexts_##name, options_filter)); \
Brian Salomondcfca432017-11-15 15:48:03 -0500194 void test_##name(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& context_info)
kkinnunen179a8f52015-11-20 13:32:24 -0800195
bsalomonfda88072016-04-11 14:40:50 -0700196#define DEF_GPUTEST_FOR_ALL_CONTEXTS(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000197 DEF_GPUTEST_FOR_CONTEXTS(name, nullptr, reporter, context_info, nullptr)
198
bsalomon68d91342016-04-12 09:59:58 -0700199#define DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info) \
200 DEF_GPUTEST_FOR_CONTEXTS(name, sk_gpu_test::GrContextFactory::IsRenderingContext, \
Robert Phillipsec325342017-10-30 18:02:48 +0000201 reporter, context_info, nullptr)
bsalomon758586c2016-04-06 14:02:39 -0700202#define DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000203 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsGLContextType, \
204 reporter, context_info, nullptr)
bsalomon758586c2016-04-06 14:02:39 -0700205#define DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000206 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsRenderingGLContextType, \
207 reporter, context_info, nullptr)
Brian Osman7c597742019-03-26 11:10:11 -0400208#define DEF_GPUTEST_FOR_MOCK_CONTEXT(name, reporter, context_info) \
209 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsMockContextType, \
210 reporter, context_info, nullptr)
bsalomondc0fcd42016-04-11 14:21:33 -0700211#define DEF_GPUTEST_FOR_VULKAN_CONTEXT(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000212 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsVulkanContextType, \
213 reporter, context_info, nullptr)
Timothy Liang760dbc42018-07-17 13:28:20 -0400214#define DEF_GPUTEST_FOR_METAL_CONTEXT(name, reporter, context_info) \
215 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsMetalContextType, \
216 reporter, context_info, nullptr)
Greg Danield4928d02020-06-19 11:13:26 -0400217#define DEF_GPUTEST_FOR_D3D_CONTEXT(name, reporter, context_info) \
218 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsDirect3DContextType, \
219 reporter, context_info, nullptr)
Greg Daniela58db7f2020-07-15 09:17:59 -0400220#define DEF_GPUTEST_FOR_DAWN_CONTEXT(name, reporter, context_info) \
221 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsDawnContextType, \
222 reporter, context_info, nullptr)
kkinnunen179a8f52015-11-20 13:32:24 -0800223
halcanary4b656662016-04-27 07:45:18 -0700224#define REQUIRE_PDF_DOCUMENT(TEST_NAME, REPORTER) \
225 do { \
Hal Canary3026d4b2019-01-07 10:00:48 -0500226 SkNullWStream testStream; \
227 auto testDoc = SkPDF::MakeDocument(&testStream); \
halcanary4b656662016-04-27 07:45:18 -0700228 if (!testDoc) { \
229 INFOF(REPORTER, "PDF disabled; %s test skipped.", #TEST_NAME); \
230 return; \
231 } \
halcanary2ccdb632015-08-11 13:35:12 -0700232 } while (false)
233
reed@android.comed673312009-02-27 16:24:51 +0000234#endif