aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Stiles <johnstiles@google.com>2022-03-17 21:51:20 -0400
committerDerek Sollenberger <djsollen@google.com>2022-03-22 17:56:43 +0000
commit66c5dfe67aee6b45993abb389502b3852b0b9c4e (patch)
tree425cdd3688a6fe0a0900edffdad3ae5565dd9471
parent83d303394bfcbd19563b0efd72b3be3c0b0e9dac (diff)
downloadskia-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.cpp45
-rw-r--r--tools/skqp/src/skqp.cpp50
-rw-r--r--tools/skqp/src/skqp.h2
-rw-r--r--tools/skqp/src/skqp_main.cpp25
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);