Flutter Engine
The Flutter Engine
skqp.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2018 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 */
7
9
10#include "gm/gm.h"
16#include "src/core/SkOSFile.h"
17#include "src/utils/SkOSPath.h"
18#include "tests/Test.h"
19#include "tests/TestHarness.h"
20#include "tools/Resources.h"
22#ifdef SK_GL
24#endif
25#ifdef SK_VULKAN
27#endif
28
29#ifdef SK_GRAPHITE
31#endif
32
33#ifdef SK_BUILD_FOR_ANDROID
34#include <sys/system_properties.h>
35#endif
36
37#include <algorithm>
38#include <regex>
39
40static constexpr char kUnitTestReportPath[] = "unit_tests.txt";
41
42// Returns a list of every unit test to be run.
43static std::vector<SkQP::UnitTest> get_unit_tests(int enforcedAndroidAPILevel) {
44 std::vector<SkQP::UnitTest> unitTests;
46 const auto ctsMode = test.fCTSEnforcement.eval(enforcedAndroidAPILevel);
47 if (ctsMode != CtsEnforcement::RunMode::kSkip) {
49 "Non-GPU test was included in SkQP: %s\n", test.fName);
50 unitTests.push_back(&test);
51 }
52 }
53 auto lt = [](SkQP::UnitTest u, SkQP::UnitTest v) { return strcmp(u->fName, v->fName) < 0; };
54 std::sort(unitTests.begin(), unitTests.end(), lt);
55 return unitTests;
56}
57
58/**
59 * SkSL error tests are used by CTS to verify that Android's RuntimeShader API fails when certain
60 * shader programs are compiled. Unlike unit tests these error tests are defined in resource files
61 * not source code. As such, we are unable to mark each test with a CtsEnforcement value. This
62 * list of exclusion rules excludes tests based on their file name so that we can have some form of
63 * control for which Android version an SkSL error test is expected to run.
64 */
65static const std::pair<std::regex, CtsEnforcement> sExclusionRulesForSkSLTests[] = {
66 // disable all ES3 tests until AGSL supports it.
68
69// Returns a list of every SkSL error test to be run.
70static std::vector<SkQP::SkSLErrorTest> get_sksl_error_tests(SkQPAssetManager* assetManager,
71 int enforcedAndroidAPILevel) {
72 std::vector<SkQP::SkSLErrorTest> skslErrorTests;
73 auto iterateFn = [&](const char* directory, const char* extension) {
74 std::vector<std::string> paths = assetManager->iterateDir(directory, extension);
75 for (const std::string& path : paths) {
77 for (auto& exclusionEntry : sExclusionRulesForSkSLTests) {
78 if (std::regex_match(name.c_str(), exclusionEntry.first) &&
79 exclusionEntry.second.eval(enforcedAndroidAPILevel) ==
81 continue;
82 }
83 }
84 sk_sp<SkData> shaderText = GetResourceAsData(path.c_str());
85 if (!shaderText) {
86 continue;
87 }
88 skslErrorTests.push_back({
89 name.c_str(),
90 std::string(static_cast<const char*>(shaderText->data()), shaderText->size())
91 });
92 }
93 };
94
95 // Android only supports runtime shaders, not fragment shaders, color filters or blenders.
96 iterateFn("sksl/errors/", ".rts");
97 iterateFn("sksl/runtime_errors/", ".rts");
98
99 auto lt = [](const SkQP::SkSLErrorTest& a, const SkQP::SkSLErrorTest& b) {
100 return a.name < b.name;
101 };
102 std::sort(skslErrorTests.begin(), skslErrorTests.end(), lt);
103 return skslErrorTests;
104}
105
106////////////////////////////////////////////////////////////////////////////////
107
109 return TestHarness::kSkQP;
110}
111
112////////////////////////////////////////////////////////////////////////////////
113
114const char* SkQP::GetUnitTestName(SkQP::UnitTest t) { return t->fName; }
115
117
119
120void SkQP::init(SkQPAssetManager* assetManager, const char* reportDirectory) {
121 SkASSERT_RELEASE(assetManager);
122 fReportDirectory = reportDirectory;
123
126
127#ifdef SK_BUILD_FOR_ANDROID
128 // ro.vendor.api_level contains the minAPI level based on the order defined in
129 // docs.partner.android.com/gms/building/integrating/extending-os-upgrade-support-windows
130 // 1. board's current api level (for boards that have been upgraded by the SoC vendor)
131 // 2. board's first api level (for devices that initially shipped with an older version)
132 // 3. product's first api level
133 // 4. product's current api level
134 char minAPIVersionStr[PROP_VALUE_MAX];
135 int strLength = __system_property_get("ro.vendor.api_level", minAPIVersionStr);
136 if (strLength != 0) {
137 fEnforcedAndroidAPILevel = atoi(minAPIVersionStr);
138 }
139#endif
140
141 fUnitTests = get_unit_tests(fEnforcedAndroidAPILevel);
142 fSkSLErrorTests = get_sksl_error_tests(assetManager, fEnforcedAndroidAPILevel);
143
144 printBackendInfo((fReportDirectory + "/grdump.txt").c_str());
145}
146
147std::vector<std::string> SkQP::executeTest(SkQP::UnitTest test) {
148 struct : public skiatest::Reporter {
149 std::vector<std::string> fErrors;
150 void reportFailed(const skiatest::Failure& failure) override {
151 SkString desc = failure.toString();
152 fErrors.push_back(std::string(desc.c_str(), desc.size()));
153 }
154 } r;
155
156 if (test->fTestType == skiatest::TestType::kGanesh) {
158 if (test->fCTSEnforcement.eval(fEnforcedAndroidAPILevel) ==
160 options.fDisableDriverCorrectnessWorkarounds = true;
161 }
162 if (test->fGaneshContextOptionsProc) {
163 test->fGaneshContextOptionsProc(&options);
164 }
165 test->ganesh(&r, options);
166 }
167#ifdef SK_GRAPHITE
168 else if (test->fTestType == skiatest::TestType::kGraphite) {
170 if (test->fCTSEnforcement.eval(fEnforcedAndroidAPILevel) ==
172 options.fContextOptions.fDisableDriverCorrectnessWorkarounds = true;
173 }
174 if (test->fGraphiteContextOptionsProc) {
175 test->fGraphiteContextOptionsProc(&options.fContextOptions);
176 }
177 test->graphite(&r, options);
178 }
179#endif
180
181 fTestResults.push_back(TestResult{test->fName, r.fErrors});
182 return r.fErrors;
183}
184
185////////////////////////////////////////////////////////////////////////////////
186
187template <typename T>
188inline void write(SkWStream* wStream, const T& text) {
189 wStream->write(text.c_str(), text.size());
190}
191
193 if (!sk_isdir(fReportDirectory.c_str())) {
194 SkDebugf("Report destination does not exist: '%s'\n", fReportDirectory.c_str());
195 return;
196 }
197 SkFILEWStream report(SkOSPath::Join(fReportDirectory.c_str(), kUnitTestReportPath).c_str());
198 SkASSERT_RELEASE(report.isValid());
199 for (const SkQP::TestResult& result : fTestResults) {
200 report.writeText(result.name.c_str());
201 if (result.errors.empty()) {
202 report.writeText(" PASSED\n* * *\n");
203 } else {
204 write(&report, SkStringPrintf(" FAILED (%zu errors)\n", result.errors.size()));
205 for (const std::string& err : result.errors) {
206 write(&report, err);
207 report.newline();
208 }
209 report.writeText("* * *\n");
210 }
211 }
212}
const char * options
sk_sp< SkData > GetResourceAsData(const char *resource)
Definition: Resources.cpp:42
#define SkASSERT_RELEASE(cond)
Definition: SkAssert.h:100
#define SkASSERTF(cond, fmt,...)
Definition: SkAssert.h:117
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
bool sk_isdir(const char *path)
static std::vector< SkPDFIndirectReference > sort(const THashSet< SkPDFIndirectReference > &src)
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
TestHarness
Definition: TestHarness.h:14
const void * data() const
Definition: SkData.h:37
size_t size() const
Definition: SkData.h:30
bool isValid() const
Definition: SkStream.h:442
static void Init()
Definition: SkGraphics.cpp:22
static SkString Join(const char *rootPath, const char *relativePath)
Definition: SkOSPath.cpp:14
static SkString Basename(const char *fullPath)
Definition: SkOSPath.cpp:23
virtual std::vector< std::string > iterateDir(const char *directory, const char *extension)=0
void makeReport()
Definition: skqp.cpp:192
SkQP()
Definition: skqp.cpp:116
~SkQP()
Definition: skqp.cpp:118
std::vector< std::string > executeTest(UnitTest)
Definition: skqp.cpp:147
void init(SkQPAssetManager *assetManager, const char *reportDirectory)
Definition: skqp.cpp:120
static const char * GetUnitTestName(UnitTest)
Definition: skqp.cpp:114
const char * c_str() const
Definition: SkString.h:133
virtual bool write(const void *buffer, size_t size)=0
bool writeText(const char text[])
Definition: SkStream.h:247
bool newline()
Definition: SkStream.h:252
static bool b
struct MyStruct a[10]
GAsyncResult * result
std::u16string text
void UsePortableFontMgr()
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
#define T
Definition: precompiler.cc:65
void write(SkWStream *wStream, const T &text)
Definition: skqp.cpp:188
static const std::pair< std::regex, CtsEnforcement > sExclusionRulesForSkSLTests[]
Definition: skqp.cpp:65
static std::vector< SkQP::UnitTest > get_unit_tests(int enforcedAndroidAPILevel)
Definition: skqp.cpp:43
static constexpr char kUnitTestReportPath[]
Definition: skqp.cpp:40
TestHarness CurrentTestHarness()
Definition: skqp.cpp:108
static std::vector< SkQP::SkSLErrorTest > get_sksl_error_tests(SkQPAssetManager *assetManager, int enforcedAndroidAPILevel)
Definition: skqp.cpp:70
SkString toString() const
Definition: Test.cpp:41
const char * fName
Definition: Test.h:146