diff options
author | John Stiles <johnstiles@google.com> | 2022-03-17 21:51:20 -0400 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2022-03-22 17:56:43 +0000 |
commit | 66c5dfe67aee6b45993abb389502b3852b0b9c4e (patch) | |
tree | 425cdd3688a6fe0a0900edffdad3ae5565dd9471 | |
parent | 83d303394bfcbd19563b0efd72b3be3c0b0e9dac (diff) | |
download | skia-66c5dfe67aee6b45993abb389502b3852b0b9c4e.tar.gz |
Add SkQPAssetManager::iterateDir to find files in a directory.
We can't use SkOSFile::Iter in the Java version of SkQP--it doesn't find
any files. We need to load our assets via the AAssetManager.
Bug: skia:13042
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/521841
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Change-Id: I124020d84a6da69f30f3c0b036e1e47a2bd6ceb1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/523179
Reviewed-by: John Stiles <johnstiles@google.com>
-rw-r--r-- | tools/skqp/src/jni_skqp.cpp | 45 | ||||
-rw-r--r-- | tools/skqp/src/skqp.cpp | 50 | ||||
-rw-r--r-- | tools/skqp/src/skqp.h | 2 | ||||
-rw-r--r-- | tools/skqp/src/skqp_main.cpp | 25 |
4 files changed, 78 insertions, 44 deletions
diff --git a/tools/skqp/src/jni_skqp.cpp b/tools/skqp/src/jni_skqp.cpp index 5f6ce37efc..4e9b92be10 100644 --- a/tools/skqp/src/jni_skqp.cpp +++ b/tools/skqp/src/jni_skqp.cpp @@ -14,6 +14,7 @@ #include "include/core/SkStream.h" #include "include/private/SkTo.h" +#include "src/utils/SkOSPath.h" #include "tools/ResourceFactory.h" #include "tools/skqp/src/skqp.h" @@ -26,12 +27,12 @@ JNIEXPORT void JNICALL Java_org_skia_skqp_SkQP_nMakeReport(JNIEnv*, jobject); } // extern "C" //////////////////////////////////////////////////////////////////////////////// -static AAssetManager* gAAssetManager = nullptr; +static AAssetManager* sAAssetManager = nullptr; static sk_sp<SkData> open_asset_data(const char* path) { sk_sp<SkData> data; - if (gAAssetManager) { - if (AAsset* asset = AAssetManager_open(gAAssetManager, path, AASSET_MODE_STREAMING)) { + if (sAAssetManager) { + if (AAsset* asset = AAssetManager_open(sAAssetManager, path, AASSET_MODE_STREAMING)) { if (size_t size = SkToSizeT(AAsset_getLength(asset))) { data = SkData::MakeUninitialized(size); int ret = AAsset_read(asset, data->writable_data(), size); @@ -47,7 +48,29 @@ static sk_sp<SkData> open_asset_data(const char* path) { namespace { struct AndroidAssetManager : public SkQPAssetManager { - sk_sp<SkData> open(const char* path) override { return open_asset_data(path); } + sk_sp<SkData> open(const char* path) override { + return open_asset_data(path); + } + + std::vector<std::string> iterateDir(const char* directory, const char* extension) override { + std::vector<std::string> paths; + AAssetDir* assetDir = AAssetManager_openDir(sAAssetManager, directory); + + while (const char* filename = AAssetDir_getNextFileName(assetDir)) { + const char* ext = strrchr(filename, '.'); + if (!ext) { + continue; + } + if (0 != strcasecmp(extension, ext)) { + continue; + } + SkString path = SkOSPath::Join(directory, filename); + paths.push_back(path.c_str()); + } + + AAssetDir_close(assetDir); + return paths; + } }; } @@ -109,8 +132,8 @@ void Java_org_skia_skqp_SkQP_nInit(JNIEnv* env, jobject object, jobject assetMan jassert(env, assetManager,); // This global must be set before using AndroidAssetManager - gAAssetManager = AAssetManager_fromJava(env, assetManager); - jassert(env, gAAssetManager,); + sAAssetManager = AAssetManager_fromJava(env, assetManager); + jassert(env, sAAssetManager,); std::lock_guard<std::mutex> lock(gMutex); gSkQP.init(&gAndroidAssetManager, reportDirectory.c_str()); @@ -127,17 +150,15 @@ jobjectArray Java_org_skia_skqp_SkQP_nExecuteUnitTest(JNIEnv* env, jint index) { std::vector<std::string> errors; { - jassert(env, index < (jint)gSkQP.getUnitTests().size(), nullptr); std::lock_guard<std::mutex> lock(gMutex); + jassert(env, index < (jint)gSkQP.getUnitTests().size(), nullptr); errors = gSkQP.executeTest(gSkQP.getUnitTests()[index]); } - if (errors.size() == 0) { + if (errors.empty()) { return nullptr; } - jclass stringClass = env->FindClass("java/lang/String"); - jassert(env, stringClass, nullptr); - jobjectArray array = env->NewObjectArray(errors.size(), stringClass, nullptr); - for (unsigned i = 0; i < errors.size(); ++i) { + jobjectArray array = make_java_string_array(env, errors.size()); + for (size_t i = 0; i < errors.size(); ++i) { set_string_array_element(env, array, errors[i].c_str(), i); } return (jobjectArray)env->NewGlobalRef(array); diff --git a/tools/skqp/src/skqp.cpp b/tools/skqp/src/skqp.cpp index 4cecdc8998..09b7355d53 100644 --- a/tools/skqp/src/skqp.cpp +++ b/tools/skqp/src/skqp.cpp @@ -110,30 +110,24 @@ static std::vector<SkQP::UnitTest> get_unit_tests(const ExclusionList& exclusion } // Returns a list of every SkSL error test to be run. -static std::vector<SkQP::SkSLErrorTest> get_sksl_error_tests(const ExclusionList& exclusionList) { +static std::vector<SkQP::SkSLErrorTest> get_sksl_error_tests(SkQPAssetManager* assetManager, + const ExclusionList& exclusionList) { std::vector<SkQP::SkSLErrorTest> skslErrorTests; - auto iterateFn = [&](const char* directory, const char* extension) { - SkString resourceDirectory = GetResourcePath(directory); - SkOSFile::Iter iter(resourceDirectory.c_str(), extension); - SkString name; - - while (iter.next(&name, /*getDir=*/false)) { - if (exclusionList.isExcluded(name.c_str())) { - continue; - } - SkString path(SkOSPath::Join(directory, name.c_str())); - sk_sp<SkData> shaderText = GetResourceAsData(path.c_str()); - if (!shaderText) { - continue; - } - skslErrorTests.push_back({name.c_str(), static_cast<const char*>(shaderText->data())}); + // Android only supports runtime shaders, not color filters or blenders. + std::vector<std::string> paths = assetManager->iterateDir("sksl/runtime_errors/", ".rts"); + for (const std::string& path : paths) { + SkString name = SkOSPath::Basename(path.c_str()); + if (exclusionList.isExcluded(name.c_str())) { + continue; } + sk_sp<SkData> shaderText = GetResourceAsData(path.c_str()); + if (!shaderText) { + continue; + } + skslErrorTests.push_back({name.c_str(), static_cast<const char*>(shaderText->data())}); }; - // Android only supports runtime shaders, not color filters or blenders. - iterateFn("sksl/runtime_errors/", ".rts"); - auto lt = [](const SkQP::SkSLErrorTest& a, const SkQP::SkSLErrorTest& b) { return a.name < b.name; }; @@ -245,7 +239,7 @@ void SkQP::init(SkQPAssetManager* assetManager, const char* reportDirectory) { } fUnitTests = get_unit_tests(exclusionList); - fSkSLErrorTests = get_sksl_error_tests(exclusionList); + fSkSLErrorTests = get_sksl_error_tests(assetManager, exclusionList); fSupportedBackends = get_backends(); print_backend_info((fReportDirectory + "/grdump.txt").c_str(), fSupportedBackends); @@ -281,19 +275,19 @@ void SkQP::makeReport() { SkDebugf("Report destination does not exist: '%s'\n", fReportDirectory.c_str()); return; } - SkFILEWStream unitOut(SkOSPath::Join(fReportDirectory.c_str(), kUnitTestReportPath).c_str()); - SkASSERT_RELEASE(unitOut.isValid()); + SkFILEWStream report(SkOSPath::Join(fReportDirectory.c_str(), kUnitTestReportPath).c_str()); + SkASSERT_RELEASE(report.isValid()); for (const SkQP::TestResult& result : fTestResults) { - unitOut.writeText(result.name.c_str()); + report.writeText(result.name.c_str()); if (result.errors.empty()) { - unitOut.writeText(" PASSED\n* * *\n"); + report.writeText(" PASSED\n* * *\n"); } else { - write(&unitOut, SkStringPrintf(" FAILED (%zu errors)\n", result.errors.size())); + write(&report, SkStringPrintf(" FAILED (%zu errors)\n", result.errors.size())); for (const std::string& err : result.errors) { - write(&unitOut, err); - unitOut.newline(); + write(&report, err); + report.newline(); } - unitOut.writeText("* * *\n"); + report.writeText("* * *\n"); } } } diff --git a/tools/skqp/src/skqp.h b/tools/skqp/src/skqp.h index 6093e0f1ca..ce6988f030 100644 --- a/tools/skqp/src/skqp.h +++ b/tools/skqp/src/skqp.h @@ -32,6 +32,8 @@ public: SkQPAssetManager() {} virtual ~SkQPAssetManager() {} virtual sk_sp<SkData> open(const char* path) = 0; + virtual std::vector<std::string> iterateDir(const char* directory, const char* extension) = 0; + private: SkQPAssetManager(const SkQPAssetManager&) = delete; SkQPAssetManager& operator=(const SkQPAssetManager&) = delete; diff --git a/tools/skqp/src/skqp_main.cpp b/tools/skqp/src/skqp_main.cpp index 31261e6de3..6ea58df344 100644 --- a/tools/skqp/src/skqp_main.cpp +++ b/tools/skqp/src/skqp_main.cpp @@ -12,6 +12,7 @@ #include "include/core/SkData.h" #include "src/core/SkOSFile.h" +#include "src/utils/SkOSPath.h" #include "tools/Resources.h" //////////////////////////////////////////////////////////////////////////////// @@ -21,12 +22,27 @@ class StdAssetManager : public SkQPAssetManager { public: StdAssetManager(const char* p) : fPrefix(p) { SkASSERT(!fPrefix.empty()); - //TODO(halcanary): does this need to be changed if I run SkQP in Windows? - fPrefix += "/"; } - sk_sp<SkData> open(const char* path) override { - return SkData::MakeFromFileName((fPrefix + path).c_str()); + + sk_sp<SkData> open(const char* subpath) override { + SkString path = SkOSPath::Join(fPrefix.c_str(), subpath); + return SkData::MakeFromFileName(path.c_str()); + } + + std::vector<std::string> iterateDir(const char* directory, const char* extension) override { + std::vector<std::string> paths; + SkString resourceDirectory = GetResourcePath(directory); + SkOSFile::Iter iter(resourceDirectory.c_str(), extension); + SkString name; + + while (iter.next(&name, /*getDir=*/false)) { + SkString path(SkOSPath::Join(directory, name.c_str())); + paths.push_back(path.c_str()); + } + + return paths; } + private: std::string fPrefix; }; @@ -97,6 +113,7 @@ int main(int argc, char *argv[]) { std::cerr << "sk_mkdir(" << args.outputDir << ") failed.\n"; return 2; } + StdAssetManager mgr(args.assetDir); SkQP skqp; skqp.init(&mgr, args.outputDir); |