xref: /third_party/skia/tests/Test.h (revision cb93a386)
1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci#ifndef skiatest_Test_DEFINED
8cb93a386Sopenharmony_ci#define skiatest_Test_DEFINED
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "include/core/SkString.h"
11cb93a386Sopenharmony_ci#include "include/core/SkTypes.h"
12cb93a386Sopenharmony_ci#include "src/core/SkTraceEvent.h"
13cb93a386Sopenharmony_ci#include "tools/Registry.h"
14cb93a386Sopenharmony_ci#include "tools/gpu/GrContextFactory.h"
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_cinamespace skgpu { class Context; }
17cb93a386Sopenharmony_ci
18cb93a386Sopenharmony_cinamespace skiatest {
19cb93a386Sopenharmony_ci
20cb93a386Sopenharmony_ciSkString GetTmpDir();
21cb93a386Sopenharmony_ci
22cb93a386Sopenharmony_cistruct Failure {
23cb93a386Sopenharmony_ci    Failure(const char* f, int l, const char* c, const SkString& m)
24cb93a386Sopenharmony_ci        : fileName(f), lineNo(l), condition(c), message(m) {}
25cb93a386Sopenharmony_ci    const char* fileName;
26cb93a386Sopenharmony_ci    int lineNo;
27cb93a386Sopenharmony_ci    const char* condition;
28cb93a386Sopenharmony_ci    SkString message;
29cb93a386Sopenharmony_ci    SkString toString() const;
30cb93a386Sopenharmony_ci};
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ciclass Reporter : SkNoncopyable {
33cb93a386Sopenharmony_cipublic:
34cb93a386Sopenharmony_ci    virtual ~Reporter() {}
35cb93a386Sopenharmony_ci    virtual void bumpTestCount();
36cb93a386Sopenharmony_ci    virtual void reportFailed(const skiatest::Failure&) = 0;
37cb93a386Sopenharmony_ci    virtual bool allowExtendedTest() const;
38cb93a386Sopenharmony_ci    virtual bool verbose() const;
39cb93a386Sopenharmony_ci    virtual void* stats() const { return nullptr; }
40cb93a386Sopenharmony_ci
41cb93a386Sopenharmony_ci    void reportFailedWithContext(const skiatest::Failure&);
42cb93a386Sopenharmony_ci
43cb93a386Sopenharmony_ci    void push(const SkString& message) {
44cb93a386Sopenharmony_ci        fContextStack.push_back(message);
45cb93a386Sopenharmony_ci    }
46cb93a386Sopenharmony_ci    void pop() {
47cb93a386Sopenharmony_ci        fContextStack.pop_back();
48cb93a386Sopenharmony_ci    }
49cb93a386Sopenharmony_ci
50cb93a386Sopenharmony_ciprivate:
51cb93a386Sopenharmony_ci    SkTArray<SkString> fContextStack;
52cb93a386Sopenharmony_ci};
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_ci#define REPORT_FAILURE(reporter, cond, message) \
55cb93a386Sopenharmony_ci    reporter->reportFailedWithContext(skiatest::Failure(__FILE__, __LINE__, cond, message))
56cb93a386Sopenharmony_ci
57cb93a386Sopenharmony_ciclass ReporterContext : SkNoncopyable {
58cb93a386Sopenharmony_cipublic:
59cb93a386Sopenharmony_ci    ReporterContext(Reporter* reporter, const SkString& message) : fReporter(reporter) {
60cb93a386Sopenharmony_ci        fReporter->push(message);
61cb93a386Sopenharmony_ci    }
62cb93a386Sopenharmony_ci    ~ReporterContext() {
63cb93a386Sopenharmony_ci        fReporter->pop();
64cb93a386Sopenharmony_ci    }
65cb93a386Sopenharmony_ci
66cb93a386Sopenharmony_ciprivate:
67cb93a386Sopenharmony_ci    Reporter* fReporter;
68cb93a386Sopenharmony_ci};
69cb93a386Sopenharmony_ci
70cb93a386Sopenharmony_citypedef void (*TestProc)(skiatest::Reporter*, const GrContextOptions&);
71cb93a386Sopenharmony_citypedef void (*ContextOptionsProc)(GrContextOptions*);
72cb93a386Sopenharmony_ci
73cb93a386Sopenharmony_cistruct Test {
74cb93a386Sopenharmony_ci    Test(const char* name,
75cb93a386Sopenharmony_ci         bool needsGpu,
76cb93a386Sopenharmony_ci         bool needsGraphite,
77cb93a386Sopenharmony_ci         TestProc proc,
78cb93a386Sopenharmony_ci         ContextOptionsProc optionsProc = nullptr)
79cb93a386Sopenharmony_ci            : fName(name)
80cb93a386Sopenharmony_ci            , fNeedsGpu(needsGpu)
81cb93a386Sopenharmony_ci            , fNeedsGraphite(needsGraphite)
82cb93a386Sopenharmony_ci            , fProc(proc)
83cb93a386Sopenharmony_ci            , fContextOptionsProc(optionsProc) {}
84cb93a386Sopenharmony_ci    const char* fName;
85cb93a386Sopenharmony_ci    bool fNeedsGpu;
86cb93a386Sopenharmony_ci    bool fNeedsGraphite;
87cb93a386Sopenharmony_ci    TestProc fProc;
88cb93a386Sopenharmony_ci    ContextOptionsProc fContextOptionsProc;
89cb93a386Sopenharmony_ci
90cb93a386Sopenharmony_ci    void modifyGrContextOptions(GrContextOptions* options) {
91cb93a386Sopenharmony_ci        if (fContextOptionsProc) {
92cb93a386Sopenharmony_ci            (*fContextOptionsProc)(options);
93cb93a386Sopenharmony_ci        }
94cb93a386Sopenharmony_ci    }
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_ci    void run(skiatest::Reporter* r, const GrContextOptions& options) const {
97cb93a386Sopenharmony_ci        TRACE_EVENT1("test", TRACE_FUNC, "name", this->fName/*these are static*/);
98cb93a386Sopenharmony_ci        this->fProc(r, options);
99cb93a386Sopenharmony_ci    }
100cb93a386Sopenharmony_ci};
101cb93a386Sopenharmony_ci
102cb93a386Sopenharmony_citypedef sk_tools::Registry<Test> TestRegistry;
103cb93a386Sopenharmony_ci
104cb93a386Sopenharmony_ci/*
105cb93a386Sopenharmony_ci    Use the following macros to make use of the skiatest classes, e.g.
106cb93a386Sopenharmony_ci
107cb93a386Sopenharmony_ci    #include "tests/Test.h"
108cb93a386Sopenharmony_ci
109cb93a386Sopenharmony_ci    DEF_TEST(TestName, reporter) {
110cb93a386Sopenharmony_ci        ...
111cb93a386Sopenharmony_ci        REPORTER_ASSERT(reporter, x == 15);
112cb93a386Sopenharmony_ci        ...
113cb93a386Sopenharmony_ci        REPORTER_ASSERT(reporter, x == 15, "x should be 15");
114cb93a386Sopenharmony_ci        ...
115cb93a386Sopenharmony_ci        if (x != 15) {
116cb93a386Sopenharmony_ci            ERRORF(reporter, "x should be 15, but is %d", x);
117cb93a386Sopenharmony_ci            return;
118cb93a386Sopenharmony_ci        }
119cb93a386Sopenharmony_ci        ...
120cb93a386Sopenharmony_ci    }
121cb93a386Sopenharmony_ci*/
122cb93a386Sopenharmony_ci
123cb93a386Sopenharmony_ciusing GrContextFactoryContextType = sk_gpu_test::GrContextFactory::ContextType;
124cb93a386Sopenharmony_ci
125cb93a386Sopenharmony_citypedef void GrContextTestFn(Reporter*, const sk_gpu_test::ContextInfo&);
126cb93a386Sopenharmony_citypedef bool GrContextTypeFilterFn(GrContextFactoryContextType);
127cb93a386Sopenharmony_ci
128cb93a386Sopenharmony_ciextern bool IsGLContextType(GrContextFactoryContextType);
129cb93a386Sopenharmony_ciextern bool IsVulkanContextType(GrContextFactoryContextType);
130cb93a386Sopenharmony_ciextern bool IsMetalContextType(GrContextFactoryContextType);
131cb93a386Sopenharmony_ciextern bool IsDawnContextType(GrContextFactoryContextType);
132cb93a386Sopenharmony_ciextern bool IsDirect3DContextType(GrContextFactoryContextType);
133cb93a386Sopenharmony_ciextern bool IsRenderingGLContextType(GrContextFactoryContextType);
134cb93a386Sopenharmony_ciextern bool IsMockContextType(GrContextFactoryContextType);
135cb93a386Sopenharmony_civoid RunWithGPUTestContexts(GrContextTestFn*, GrContextTypeFilterFn*, Reporter*,
136cb93a386Sopenharmony_ci                            const GrContextOptions&);
137cb93a386Sopenharmony_ci
138cb93a386Sopenharmony_cinamespace graphite {
139cb93a386Sopenharmony_ci
140cb93a386Sopenharmony_citypedef void GraphiteTestFn(Reporter*, skgpu::Context*);
141cb93a386Sopenharmony_ci
142cb93a386Sopenharmony_civoid RunWithGraphiteTestContexts(GraphiteTestFn*, Reporter*);
143cb93a386Sopenharmony_ci
144cb93a386Sopenharmony_ci} // namespace graphite
145cb93a386Sopenharmony_ci
146cb93a386Sopenharmony_ci/** Timer provides wall-clock duration since its creation. */
147cb93a386Sopenharmony_ciclass Timer {
148cb93a386Sopenharmony_cipublic:
149cb93a386Sopenharmony_ci    /** Starts the timer. */
150cb93a386Sopenharmony_ci    Timer();
151cb93a386Sopenharmony_ci
152cb93a386Sopenharmony_ci    /** Nanoseconds since creation. */
153cb93a386Sopenharmony_ci    double elapsedNs() const;
154cb93a386Sopenharmony_ci
155cb93a386Sopenharmony_ci    /** Milliseconds since creation. */
156cb93a386Sopenharmony_ci    double elapsedMs() const;
157cb93a386Sopenharmony_ci
158cb93a386Sopenharmony_ci    /** Milliseconds since creation as an integer.
159cb93a386Sopenharmony_ci        Behavior is undefined for durations longer than SK_MSecMax.
160cb93a386Sopenharmony_ci    */
161cb93a386Sopenharmony_ci    SkMSec elapsedMsInt() const;
162cb93a386Sopenharmony_ciprivate:
163cb93a386Sopenharmony_ci    double fStartNanos;
164cb93a386Sopenharmony_ci};
165cb93a386Sopenharmony_ci
166cb93a386Sopenharmony_ci}  // namespace skiatest
167cb93a386Sopenharmony_ci
168cb93a386Sopenharmony_cistatic inline SkString reporter_string() { return {}; }
169cb93a386Sopenharmony_ci/// Prevent security warnings when using a non-literal string i.e. not a format string.
170cb93a386Sopenharmony_cistatic inline SkString reporter_string(const char* s) { return SkString(s); }
171cb93a386Sopenharmony_citemplate<typename... Args>
172cb93a386Sopenharmony_cistatic inline SkString reporter_string(const char* fmt, Args... args)  {
173cb93a386Sopenharmony_ci    return SkStringPrintf(fmt, std::forward<Args>(args)...);
174cb93a386Sopenharmony_ci}
175cb93a386Sopenharmony_ci
176cb93a386Sopenharmony_ci#define REPORTER_ASSERT(r, cond, ...)                               \
177cb93a386Sopenharmony_ci    do {                                                            \
178cb93a386Sopenharmony_ci        if (!(cond)) {                                              \
179cb93a386Sopenharmony_ci            REPORT_FAILURE(r, #cond, reporter_string(__VA_ARGS__)); \
180cb93a386Sopenharmony_ci        }                                                           \
181cb93a386Sopenharmony_ci    } while (0)
182cb93a386Sopenharmony_ci
183cb93a386Sopenharmony_ci#define ERRORF(r, ...)                                       \
184cb93a386Sopenharmony_ci    do {                                                     \
185cb93a386Sopenharmony_ci        REPORT_FAILURE(r, "", reporter_string(__VA_ARGS__)); \
186cb93a386Sopenharmony_ci    } while (0)
187cb93a386Sopenharmony_ci
188cb93a386Sopenharmony_ci#define INFOF(REPORTER, ...)         \
189cb93a386Sopenharmony_ci    do {                             \
190cb93a386Sopenharmony_ci        if ((REPORTER)->verbose()) { \
191cb93a386Sopenharmony_ci            SkDebugf(__VA_ARGS__);   \
192cb93a386Sopenharmony_ci        }                            \
193cb93a386Sopenharmony_ci    } while (0)
194cb93a386Sopenharmony_ci
195cb93a386Sopenharmony_ci#define DEF_TEST(name, reporter)                                                            \
196cb93a386Sopenharmony_ci    static void test_##name(skiatest::Reporter*, const GrContextOptions&);                  \
197cb93a386Sopenharmony_ci    skiatest::TestRegistry name##TestRegistry(                                              \
198cb93a386Sopenharmony_ci            skiatest::Test(#name, /*gpu*/ false, /*graphite*/ false, test_##name));         \
199cb93a386Sopenharmony_ci    void test_##name(skiatest::Reporter* reporter, const GrContextOptions&)
200cb93a386Sopenharmony_ci
201cb93a386Sopenharmony_ci#define DEF_TEST_DISABLED(name, reporter) \
202cb93a386Sopenharmony_ci    static void test_##name(skiatest::Reporter*, const GrContextOptions&);                  \
203cb93a386Sopenharmony_ci    skiatest::TestRegistry name##TestRegistry(                                              \
204cb93a386Sopenharmony_ci            skiatest::Test(#name, /*gpu*/ false, /*graphite*/ false, test_##name));         \
205cb93a386Sopenharmony_ci    void test_##name(skiatest::Reporter* reporter, const GrContextOptions&) {               \
206cb93a386Sopenharmony_ci            /* SkDebugf("Disabled:"#name "\n"); */                                          \
207cb93a386Sopenharmony_ci    }                                                                                       \
208cb93a386Sopenharmony_ci    void disabled_##name(skiatest::Reporter* reporter, const GrContextOptions&)
209cb93a386Sopenharmony_ci
210cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_UNIX
211cb93a386Sopenharmony_ci    #define UNIX_ONLY_TEST DEF_TEST
212cb93a386Sopenharmony_ci#else
213cb93a386Sopenharmony_ci    #define UNIX_ONLY_TEST DEF_TEST_DISABLED
214cb93a386Sopenharmony_ci#endif
215cb93a386Sopenharmony_ci
216cb93a386Sopenharmony_ci#define DEF_GRAPHITE_TEST(name, reporter)                                                   \
217cb93a386Sopenharmony_ci    static void test_##name(skiatest::Reporter*);                                           \
218cb93a386Sopenharmony_ci    static void test_graphite_##name(skiatest::Reporter* reporter,                          \
219cb93a386Sopenharmony_ci                                     const GrContextOptions& /*unused*/) {                  \
220cb93a386Sopenharmony_ci        test_##name(reporter);                                                              \
221cb93a386Sopenharmony_ci    }                                                                                       \
222cb93a386Sopenharmony_ci    skiatest::TestRegistry name##TestRegistry(                                              \
223cb93a386Sopenharmony_ci            skiatest::Test(#name, /*gpu*/ false, /*graphite*/ true, test_graphite_##name)); \
224cb93a386Sopenharmony_ci    void test_##name(skiatest::Reporter* reporter)
225cb93a386Sopenharmony_ci
226cb93a386Sopenharmony_ci#define DEF_GRAPHITE_TEST_FOR_CONTEXTS(name, reporter, graphite_context)                    \
227cb93a386Sopenharmony_ci    static void test_##name(skiatest::Reporter*, skgpu::Context*);                          \
228cb93a386Sopenharmony_ci    static void test_graphite_contexts_##name(skiatest::Reporter* _reporter,                \
229cb93a386Sopenharmony_ci                                              const GrContextOptions& /*unused*/) {         \
230cb93a386Sopenharmony_ci        skiatest::graphite::RunWithGraphiteTestContexts(test_##name, _reporter);            \
231cb93a386Sopenharmony_ci    }                                                                                       \
232cb93a386Sopenharmony_ci    skiatest::TestRegistry name##TestRegistry(                                              \
233cb93a386Sopenharmony_ci            skiatest::Test(#name, /*gpu*/ false, /*graphite*/ true,                         \
234cb93a386Sopenharmony_ci                           test_graphite_contexts_##name));                                 \
235cb93a386Sopenharmony_ci    void test_##name(skiatest::Reporter* reporter, skgpu::Context* graphite_context)
236cb93a386Sopenharmony_ci
237cb93a386Sopenharmony_ci#define DEF_GPUTEST(name, reporter, options)                                             \
238cb93a386Sopenharmony_ci    static void test_##name(skiatest::Reporter*, const GrContextOptions&);               \
239cb93a386Sopenharmony_ci    skiatest::TestRegistry name##TestRegistry(                                           \
240cb93a386Sopenharmony_ci            skiatest::Test(#name, /*gpu*/ true, /*graphite*/ false, test_##name));       \
241cb93a386Sopenharmony_ci    void test_##name(skiatest::Reporter* reporter, const GrContextOptions& options)
242cb93a386Sopenharmony_ci
243cb93a386Sopenharmony_ci#define DEF_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info, options_filter)  \
244cb93a386Sopenharmony_ci    static void test_##name(skiatest::Reporter*, const sk_gpu_test::ContextInfo&);              \
245cb93a386Sopenharmony_ci    static void test_gpu_contexts_##name(skiatest::Reporter* reporter,                          \
246cb93a386Sopenharmony_ci                                         const GrContextOptions& options) {                     \
247cb93a386Sopenharmony_ci        skiatest::RunWithGPUTestContexts(test_##name, context_filter, reporter, options);       \
248cb93a386Sopenharmony_ci    }                                                                                           \
249cb93a386Sopenharmony_ci    skiatest::TestRegistry name##TestRegistry(                                                  \
250cb93a386Sopenharmony_ci            skiatest::Test(#name, /*gpu*/ true, /*graphite*/ false, test_gpu_contexts_##name, options_filter));             \
251cb93a386Sopenharmony_ci    void test_##name(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& context_info)
252cb93a386Sopenharmony_ci
253cb93a386Sopenharmony_ci#define DEF_GPUTEST_FOR_ALL_CONTEXTS(name, reporter, context_info)                          \
254cb93a386Sopenharmony_ci        DEF_GPUTEST_FOR_CONTEXTS(name, nullptr, reporter, context_info, nullptr)
255cb93a386Sopenharmony_ci
256cb93a386Sopenharmony_ci#define DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info)                    \
257cb93a386Sopenharmony_ci        DEF_GPUTEST_FOR_CONTEXTS(name, sk_gpu_test::GrContextFactory::IsRenderingContext,   \
258cb93a386Sopenharmony_ci                                 reporter, context_info, nullptr)
259cb93a386Sopenharmony_ci#define DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(name, reporter, context_info)                       \
260cb93a386Sopenharmony_ci        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsGLContextType,                          \
261cb93a386Sopenharmony_ci                                 reporter, context_info, nullptr)
262cb93a386Sopenharmony_ci#define DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(name, reporter, context_info)                 \
263cb93a386Sopenharmony_ci        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsRenderingGLContextType,                 \
264cb93a386Sopenharmony_ci                                 reporter, context_info, nullptr)
265cb93a386Sopenharmony_ci#define DEF_GPUTEST_FOR_MOCK_CONTEXT(name, reporter, context_info)                          \
266cb93a386Sopenharmony_ci        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsMockContextType,                        \
267cb93a386Sopenharmony_ci                                 reporter, context_info, nullptr)
268cb93a386Sopenharmony_ci#define DEF_GPUTEST_FOR_VULKAN_CONTEXT(name, reporter, context_info)                        \
269cb93a386Sopenharmony_ci        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsVulkanContextType,                      \
270cb93a386Sopenharmony_ci                                 reporter, context_info, nullptr)
271cb93a386Sopenharmony_ci#define DEF_GPUTEST_FOR_METAL_CONTEXT(name, reporter, context_info)                         \
272cb93a386Sopenharmony_ci        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsMetalContextType,                       \
273cb93a386Sopenharmony_ci                                 reporter, context_info, nullptr)
274cb93a386Sopenharmony_ci#define DEF_GPUTEST_FOR_D3D_CONTEXT(name, reporter, context_info)                           \
275cb93a386Sopenharmony_ci    DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsDirect3DContextType,                        \
276cb93a386Sopenharmony_ci                             reporter, context_info, nullptr)
277cb93a386Sopenharmony_ci#define DEF_GPUTEST_FOR_DAWN_CONTEXT(name, reporter, context_info)                          \
278cb93a386Sopenharmony_ci    DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsDawnContextType,                            \
279cb93a386Sopenharmony_ci                             reporter, context_info, nullptr)
280cb93a386Sopenharmony_ci
281cb93a386Sopenharmony_ci#define REQUIRE_PDF_DOCUMENT(TEST_NAME, REPORTER)                          \
282cb93a386Sopenharmony_ci    do {                                                                   \
283cb93a386Sopenharmony_ci        SkNullWStream testStream;                                          \
284cb93a386Sopenharmony_ci        auto testDoc = SkPDF::MakeDocument(&testStream);                   \
285cb93a386Sopenharmony_ci        if (!testDoc) {                                                    \
286cb93a386Sopenharmony_ci            INFOF(REPORTER, "PDF disabled; %s test skipped.", #TEST_NAME); \
287cb93a386Sopenharmony_ci            return;                                                        \
288cb93a386Sopenharmony_ci        }                                                                  \
289cb93a386Sopenharmony_ci    } while (false)
290cb93a386Sopenharmony_ci
291cb93a386Sopenharmony_ci#endif
292