Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
jni_skqp.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2017 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
8#include <mutex>
9
10#include <android/asset_manager.h>
11#include <android/asset_manager_jni.h>
12#include <jni.h>
13#include <sys/stat.h>
14
17#include "src/utils/SkOSPath.h"
19
20#include "tools/skqp/src/skqp.h"
21
22////////////////////////////////////////////////////////////////////////////////
23extern "C" {
24JNIEXPORT void JNICALL Java_org_skia_skqp_SkQP_nInit(JNIEnv*, jobject, jobject, jstring);
25JNIEXPORT jobjectArray JNICALL Java_org_skia_skqp_SkQP_nExecuteUnitTest(JNIEnv*, jobject, jint);
26JNIEXPORT void JNICALL Java_org_skia_skqp_SkQP_nMakeReport(JNIEnv*, jobject);
27} // extern "C"
28////////////////////////////////////////////////////////////////////////////////
29
30static AAssetManager* sAAssetManager = nullptr;
31
32static sk_sp<SkData> open_asset_data(const char* path) {
33 sk_sp<SkData> data;
34 if (sAAssetManager) {
35 if (AAsset* asset = AAssetManager_open(sAAssetManager, path, AASSET_MODE_STREAMING)) {
36 if (size_t size = SkToSizeT(AAsset_getLength(asset))) {
37 data = SkData::MakeUninitialized(size);
38 int ret = AAsset_read(asset, data->writable_data(), size);
39 if (ret != SkToInt(size)) {
40 SK_ABORT("ERROR: AAsset_read != AAsset_getLength (%s)\n", path);
41 }
42 }
43 AAsset_close(asset);
44 }
45 }
46 return data;
47}
48
49namespace {
50struct AndroidAssetManager : public SkQPAssetManager {
51 sk_sp<SkData> open(const char* path) override {
52 return open_asset_data(path);
53 }
54
55 std::vector<std::string> iterateDir(const char* directory, const char* extension) override {
56 std::vector<std::string> paths;
57 AAssetDir* assetDir = AAssetManager_openDir(sAAssetManager, directory);
58
59 while (const char* filename = AAssetDir_getNextFileName(assetDir)) {
60 const char* ext = strrchr(filename, '.');
61 if (!ext) {
62 continue;
63 }
64 if (0 != strcasecmp(extension, ext)) {
65 continue;
66 }
67 SkString path = SkOSPath::Join(directory, filename);
68 paths.push_back(path.c_str());
69 }
70
71 AAssetDir_close(assetDir);
72 return paths;
73 }
74};
75}
76
77// TODO(halcanary): Should not have global variables; SkQP Java object should
78// own pointers and manage concurency.
79static AndroidAssetManager gAndroidAssetManager;
80static std::mutex gMutex;
81static SkQP gSkQP;
82
83#define jassert(env, cond, ret) do { if (!(cond)) { \
84 (env)->ThrowNew((env)->FindClass("java/lang/Exception"), \
85 __FILE__ ": assert(" #cond ") failed."); \
86 return ret; } } while (0)
87
88////////////////////////////////////////////////////////////////////////////////
89
90static jobjectArray make_java_string_array(JNIEnv* env, jint arraySize) {
91 jclass stringClass = env->FindClass("java/lang/String");
92 jassert(env, stringClass, nullptr);
93 jobjectArray jarray = env->NewObjectArray(arraySize, stringClass, nullptr);
94 jassert(env, jarray != nullptr, nullptr);
95 return jarray;
96}
97
98static void set_string_array_element(JNIEnv* env, jobjectArray a, const char* s, unsigned i) {
99 jstring jstr = env->NewStringUTF(s);
100 jassert(env, jstr != nullptr,);
101 env->SetObjectArrayElement(a, (jsize)i, jstr);
102 env->DeleteLocalRef(jstr);
103}
104
105template <typename T, typename F>
106static jobjectArray to_java_string_array(JNIEnv* env,
107 const std::vector<T>& array,
108 F stringizeFn) {
109 jobjectArray jarray = make_java_string_array(env, (jint)array.size());
110 for (size_t i = 0; i < array.size(); ++i) {
111 set_string_array_element(env, jarray, stringizeFn(array[i]), i);
112 }
113 return jarray;
114}
115
116static std::string to_string(JNIEnv* env, jstring jString) {
117 const char* utf8String = env->GetStringUTFChars(jString, nullptr);
118 jassert(env, utf8String && utf8String[0], "");
119 std::string sString(utf8String);
120 env->ReleaseStringUTFChars(jString, utf8String);
121 return sString;
122}
123
124static const char* get_sksl_error_name(const SkQP::SkSLErrorTest& t) {
125 return t.name.c_str();
126}
127
129 return t.shaderText.c_str();
130}
131
132void Java_org_skia_skqp_SkQP_nInit(JNIEnv* env, jobject object, jobject assetManager,
133 jstring dataDir) {
134 jclass SkQP_class = env->GetObjectClass(object);
135
136 // tools/Resources
138
139 std::string reportDirectory = to_string(env, dataDir);
140
141 jassert(env, assetManager,);
142 // This global must be set before using AndroidAssetManager
143 sAAssetManager = AAssetManager_fromJava(env, assetManager);
145
146 std::lock_guard<std::mutex> lock(gMutex);
147 gSkQP.init(&gAndroidAssetManager, reportDirectory.c_str());
148
149 const std::vector<SkQP::UnitTest>& unitTests = gSkQP.getUnitTests();
150 const std::vector<SkQP::SkSLErrorTest>& skslErrorTests = gSkQP.getSkSLErrorTests();
151
152 constexpr char kStringArrayType[] = "[Ljava/lang/String;";
153 env->SetObjectField(object,
154 env->GetFieldID(SkQP_class, "mUnitTests", kStringArrayType),
156 env->SetObjectField(object,
157 env->GetFieldID(SkQP_class, "mSkSLErrorTestName", kStringArrayType),
159 env->SetObjectField(object,
160 env->GetFieldID(SkQP_class, "mSkSLErrorTestShader", kStringArrayType),
162}
163
165 jobject object,
166 jint index) {
167 std::vector<std::string> errors;
168 {
169 std::lock_guard<std::mutex> lock(gMutex);
170 jassert(env, index < (jint)gSkQP.getUnitTests().size(), nullptr);
171 errors = gSkQP.executeTest(gSkQP.getUnitTests()[index]);
172 }
173 if (errors.empty()) {
174 return nullptr;
175 }
176 jobjectArray array = make_java_string_array(env, errors.size());
177 for (size_t i = 0; i < errors.size(); ++i) {
178 set_string_array_element(env, array, errors[i].c_str(), i);
179 }
180 return (jobjectArray)env->NewGlobalRef(array);
181}
182
184 std::lock_guard<std::mutex> lock(gMutex);
186}
187
188////////////////////////////////////////////////////////////////////////////////
189
sk_sp< SkData >(* gResourceFactory)(const char *)
Definition Resources.cpp:21
#define SK_ABORT(message,...)
Definition SkAssert.h:70
constexpr size_t SkToSizeT(S x)
Definition SkTo.h:31
constexpr int SkToInt(S x)
Definition SkTo.h:29
static sk_sp< SkData > MakeUninitialized(size_t length)
Definition SkData.cpp:116
static SkString Join(const char *rootPath, const char *relativePath)
Definition SkOSPath.cpp:14
virtual sk_sp< SkData > open(const char *path)=0
virtual std::vector< std::string > iterateDir(const char *directory, const char *extension)=0
Definition skqp.h:42
void makeReport()
Definition skqp.cpp:192
const std::vector< UnitTest > & getUnitTests() const
Definition skqp.h:74
const std::vector< SkSLErrorTest > & getSkSLErrorTests() const
Definition skqp.h:77
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
struct MyStruct s
struct MyStruct a[10]
static AndroidAssetManager gAndroidAssetManager
Definition jni_skqp.cpp:79
static std::mutex gMutex
Definition jni_skqp.cpp:80
static jobjectArray make_java_string_array(JNIEnv *env, jint arraySize)
Definition jni_skqp.cpp:90
static std::string to_string(JNIEnv *env, jstring jString)
Definition jni_skqp.cpp:116
JNIEXPORT jobjectArray JNICALL Java_org_skia_skqp_SkQP_nExecuteUnitTest(JNIEnv *, jobject, jint)
Definition jni_skqp.cpp:164
#define jassert(env, cond, ret)
Definition jni_skqp.cpp:83
JNIEXPORT void JNICALL Java_org_skia_skqp_SkQP_nMakeReport(JNIEnv *, jobject)
Definition jni_skqp.cpp:183
static SkQP gSkQP
Definition jni_skqp.cpp:81
static sk_sp< SkData > open_asset_data(const char *path)
Definition jni_skqp.cpp:32
static void set_string_array_element(JNIEnv *env, jobjectArray a, const char *s, unsigned i)
Definition jni_skqp.cpp:98
JNIEXPORT void JNICALL Java_org_skia_skqp_SkQP_nInit(JNIEnv *, jobject, jobject, jstring)
Definition jni_skqp.cpp:132
static const char * get_sksl_error_shader_text(const SkQP::SkSLErrorTest &t)
Definition jni_skqp.cpp:128
static const char * get_sksl_error_name(const SkQP::SkSLErrorTest &t)
Definition jni_skqp.cpp:124
static AAssetManager * sAAssetManager
Definition jni_skqp.cpp:30
static jobjectArray to_java_string_array(JNIEnv *env, const std::vector< T > &array, F stringizeFn)
Definition jni_skqp.cpp:106
Definition __init__.py:1
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
Definition SkMD5.cpp:120
std::string shaderText
Definition skqp.h:48
std::string name
Definition skqp.h:47