blob: faf5521072a36fa181faf19ee711ca3504d22e19 [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"
Hal Canary23564b92018-09-07 14:33:14 -040011#include "GrContextFactory.h"
Mike Reedebfce6d2016-12-12 10:02:12 -050012#include "SkClipOpPriv.h"
Mike Kleinb323a5e2017-07-24 15:21:31 -040013#include "SkString.h"
14#include "SkTraceEvent.h"
15#include "SkTypes.h"
bsalomon@google.coma8e686e2011-08-16 15:45:58 +000016
reed@android.comed673312009-02-27 16:24:51 +000017namespace skiatest {
reed@android.com80e39a72009-04-02 16:59:40 +000018
halcanary87f3ba42015-01-20 09:30:20 -080019SkString GetTmpDir();
reed@android.comed673312009-02-27 16:24:51 +000020
halcanary87f3ba42015-01-20 09:30:20 -080021struct Failure {
22 Failure(const char* f, int l, const char* c, const SkString& m)
23 : fileName(f), lineNo(l), condition(c), message(m) {}
24 const char* fileName;
25 int lineNo;
26 const char* condition;
27 SkString message;
28 SkString toString() const;
29};
scroggo0ee26272014-11-07 06:07:32 -080030
halcanary87f3ba42015-01-20 09:30:20 -080031class Reporter : SkNoncopyable {
32public:
33 virtual ~Reporter() {}
34 virtual void bumpTestCount();
35 virtual void reportFailed(const skiatest::Failure&) = 0;
36 virtual bool allowExtendedTest() const;
37 virtual bool verbose() const;
Cary Clarkab87d7a2016-10-04 10:01:04 -040038 virtual void* stats() const { return nullptr; }
Brian Osman287f6512016-12-05 11:35:07 -050039
40 void reportFailedWithContext(const skiatest::Failure& f) {
41 SkString fullMessage = f.message;
42 if (!fContextStack.empty()) {
43 fullMessage.append(" [");
44 for (int i = 0; i < fContextStack.count(); ++i) {
45 if (i > 0) {
46 fullMessage.append(", ");
47 }
48 fullMessage.append(fContextStack[i]);
49 }
50 fullMessage.append("]");
51 }
52 this->reportFailed(skiatest::Failure(f.fileName, f.lineNo, f.condition, fullMessage));
53 }
54 void push(const SkString& message) {
55 fContextStack.push_back(message);
56 }
57 void pop() {
58 fContextStack.pop_back();
59 }
60
61private:
62 SkTArray<SkString> fContextStack;
halcanary87f3ba42015-01-20 09:30:20 -080063};
scroggo0ee26272014-11-07 06:07:32 -080064
halcanary87f3ba42015-01-20 09:30:20 -080065#define REPORT_FAILURE(reporter, cond, message) \
Brian Osman287f6512016-12-05 11:35:07 -050066 reporter->reportFailedWithContext(skiatest::Failure(__FILE__, __LINE__, cond, message))
67
68class ReporterContext : SkNoncopyable {
69public:
70 ReporterContext(Reporter* reporter, const SkString& message) : fReporter(reporter) {
71 fReporter->push(message);
72 }
73 ~ReporterContext() {
74 fReporter->pop();
75 }
76
77private:
78 Reporter* fReporter;
79};
scroggo0ee26272014-11-07 06:07:32 -080080
Brian Salomondcfca432017-11-15 15:48:03 -050081typedef void (*TestProc)(skiatest::Reporter*, const GrContextOptions&);
Robert Phillipsec325342017-10-30 18:02:48 +000082typedef void (*ContextOptionsProc)(GrContextOptions*);
reed@android.comed673312009-02-27 16:24:51 +000083
halcanary87f3ba42015-01-20 09:30:20 -080084struct Test {
Robert Phillipsec325342017-10-30 18:02:48 +000085 Test(const char* n, bool g, TestProc p, ContextOptionsProc optionsProc = nullptr)
86 : name(n), needsGpu(g), proc(p), fContextOptionsProc(optionsProc) {}
halcanary87f3ba42015-01-20 09:30:20 -080087 const char* name;
88 bool needsGpu;
89 TestProc proc;
Robert Phillipsec325342017-10-30 18:02:48 +000090 ContextOptionsProc fContextOptionsProc;
91
92 void modifyGrContextOptions(GrContextOptions* options) {
93 if (fContextOptionsProc) {
94 (*fContextOptionsProc)(options);
95 }
96 }
Mike Kleinb323a5e2017-07-24 15:21:31 -040097
Brian Salomondcfca432017-11-15 15:48:03 -050098 void run(skiatest::Reporter* r, const GrContextOptions& options) const {
Mike Kleinb323a5e2017-07-24 15:21:31 -040099 TRACE_EVENT1("test", TRACE_FUNC, "name", this->name/*these are static*/);
Brian Salomondcfca432017-11-15 15:48:03 -0500100 this->proc(r, options);
Mike Kleinb323a5e2017-07-24 15:21:31 -0400101 }
halcanary87f3ba42015-01-20 09:30:20 -0800102};
reed@android.comed673312009-02-27 16:24:51 +0000103
Mike Reedab273fa2017-01-11 13:58:55 -0500104typedef sk_tools::Registry<Test> TestRegistry;
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000105
106/*
107 Use the following macros to make use of the skiatest classes, e.g.
108
109 #include "Test.h"
110
111 DEF_TEST(TestName, reporter) {
112 ...
113 REPORTER_ASSERT(reporter, x == 15);
114 ...
Brian Salomon1c80e992018-01-29 09:50:47 -0500115 REPORTER_ASSERT(reporter, x == 15, "x should be 15");
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000116 ...
117 if (x != 15) {
118 ERRORF(reporter, "x should be 15, but is %d", x);
119 return;
120 }
121 ...
122 }
123*/
bsalomon758586c2016-04-06 14:02:39 -0700124
bsalomon758586c2016-04-06 14:02:39 -0700125using GrContextFactoryContextType = sk_gpu_test::GrContextFactory::ContextType;
bsalomonf2f1c172016-04-05 12:59:06 -0700126
127typedef void GrContextTestFn(Reporter*, const sk_gpu_test::ContextInfo&);
bsalomon758586c2016-04-06 14:02:39 -0700128typedef bool GrContextTypeFilterFn(GrContextFactoryContextType);
bsalomonf2f1c172016-04-05 12:59:06 -0700129
bsalomon758586c2016-04-06 14:02:39 -0700130extern bool IsGLContextType(GrContextFactoryContextType);
bsalomondc0fcd42016-04-11 14:21:33 -0700131extern bool IsVulkanContextType(GrContextFactoryContextType);
Timothy Liang760dbc42018-07-17 13:28:20 -0400132extern bool IsMetalContextType(GrContextFactoryContextType);
bsalomon758586c2016-04-06 14:02:39 -0700133extern bool IsRenderingGLContextType(GrContextFactoryContextType);
134extern bool IsNullGLContextType(GrContextFactoryContextType);
Brian Salomondcfca432017-11-15 15:48:03 -0500135void RunWithGPUTestContexts(GrContextTestFn*, GrContextTypeFilterFn*, Reporter*,
136 const GrContextOptions&);
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700137
138/** Timer provides wall-clock duration since its creation. */
139class Timer {
140public:
141 /** Starts the timer. */
142 Timer();
143
144 /** Nanoseconds since creation. */
145 double elapsedNs() const;
146
147 /** Milliseconds since creation. */
148 double elapsedMs() const;
149
150 /** Milliseconds since creation as an integer.
151 Behavior is undefined for durations longer than SK_MSecMax.
152 */
153 SkMSec elapsedMsInt() const;
154private:
155 double fStartNanos;
156};
157
halcanary87f3ba42015-01-20 09:30:20 -0800158} // namespace skiatest
reed@android.comed673312009-02-27 16:24:51 +0000159
Brian Salomon1c80e992018-01-29 09:50:47 -0500160#define REPORTER_ASSERT(r, cond, ...) \
161 do { \
162 if (!(cond)) { \
163 REPORT_FAILURE(r, #cond, SkStringPrintf(__VA_ARGS__)); \
164 } \
halcanary87f3ba42015-01-20 09:30:20 -0800165 } while (0)
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000166
halcanary87f3ba42015-01-20 09:30:20 -0800167#define ERRORF(r, ...) \
168 do { \
169 REPORT_FAILURE(r, "", SkStringPrintf(__VA_ARGS__)); \
170 } while (0)
reed@android.comed673312009-02-27 16:24:51 +0000171
halcanary7d571242016-02-24 17:59:16 -0800172#define INFOF(REPORTER, ...) \
173 do { \
174 if ((REPORTER)->verbose()) { \
175 SkDebugf(__VA_ARGS__); \
176 } \
177 } while (0)
178
Brian Salomondcfca432017-11-15 15:48:03 -0500179#define DEF_TEST(name, reporter) \
180 static void test_##name(skiatest::Reporter*, const GrContextOptions&); \
181 skiatest::TestRegistry name##TestRegistry(skiatest::Test(#name, false, test_##name)); \
182 void test_##name(skiatest::Reporter* reporter, const GrContextOptions&)
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000183
Brian Salomondcfca432017-11-15 15:48:03 -0500184#define DEF_GPUTEST(name, reporter, options) \
185 static void test_##name(skiatest::Reporter*, const GrContextOptions&); \
186 skiatest::TestRegistry name##TestRegistry(skiatest::Test(#name, true, test_##name)); \
187 void test_##name(skiatest::Reporter* reporter, const GrContextOptions& options)
commit-bot@chromium.orge2eac8b2014-01-14 21:04:37 +0000188
Robert Phillipsec325342017-10-30 18:02:48 +0000189#define DEF_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info, options_filter) \
Brian Salomondcfca432017-11-15 15:48:03 -0500190 static void test_##name(skiatest::Reporter*, const sk_gpu_test::ContextInfo& context_info); \
Robert Phillipsec325342017-10-30 18:02:48 +0000191 static void test_gpu_contexts_##name(skiatest::Reporter* reporter, \
Brian Salomondcfca432017-11-15 15:48:03 -0500192 const GrContextOptions& options) { \
193 skiatest::RunWithGPUTestContexts(test_##name, context_filter, reporter, options); \
Robert Phillipsec325342017-10-30 18:02:48 +0000194 } \
195 skiatest::TestRegistry name##TestRegistry( \
196 skiatest::Test(#name, true, test_gpu_contexts_##name, options_filter)); \
Brian Salomondcfca432017-11-15 15:48:03 -0500197 void test_##name(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& context_info)
kkinnunen179a8f52015-11-20 13:32:24 -0800198
bsalomonfda88072016-04-11 14:40:50 -0700199#define DEF_GPUTEST_FOR_ALL_CONTEXTS(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000200 DEF_GPUTEST_FOR_CONTEXTS(name, nullptr, reporter, context_info, nullptr)
201
bsalomon68d91342016-04-12 09:59:58 -0700202#define DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info) \
203 DEF_GPUTEST_FOR_CONTEXTS(name, sk_gpu_test::GrContextFactory::IsRenderingContext, \
Robert Phillipsec325342017-10-30 18:02:48 +0000204 reporter, context_info, nullptr)
bsalomon758586c2016-04-06 14:02:39 -0700205#define DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000206 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsGLContextType, \
207 reporter, context_info, nullptr)
bsalomon758586c2016-04-06 14:02:39 -0700208#define DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000209 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsRenderingGLContextType, \
210 reporter, context_info, nullptr)
bsalomon758586c2016-04-06 14:02:39 -0700211#define DEF_GPUTEST_FOR_NULLGL_CONTEXT(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000212 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsNullGLContextType, \
213 reporter, context_info, nullptr)
bsalomondc0fcd42016-04-11 14:21:33 -0700214#define DEF_GPUTEST_FOR_VULKAN_CONTEXT(name, reporter, context_info) \
Robert Phillipsec325342017-10-30 18:02:48 +0000215 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsVulkanContextType, \
216 reporter, context_info, nullptr)
Timothy Liang760dbc42018-07-17 13:28:20 -0400217#define DEF_GPUTEST_FOR_METAL_CONTEXT(name, reporter, context_info) \
218 DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsMetalContextType, \
219 reporter, context_info, nullptr)
kkinnunen179a8f52015-11-20 13:32:24 -0800220
halcanary4b656662016-04-27 07:45:18 -0700221#define REQUIRE_PDF_DOCUMENT(TEST_NAME, REPORTER) \
222 do { \
223 SkDynamicMemoryWStream testStream; \
Hal Canary23564b92018-09-07 14:33:14 -0400224 sk_sp<SkDocument> testDoc(SkPDF::MakeDocument(&testStream)); \
halcanary4b656662016-04-27 07:45:18 -0700225 if (!testDoc) { \
226 INFOF(REPORTER, "PDF disabled; %s test skipped.", #TEST_NAME); \
227 return; \
228 } \
halcanary2ccdb632015-08-11 13:35:12 -0700229 } while (false)
230
reed@android.comed673312009-02-27 16:24:51 +0000231#endif