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