Flutter Engine
The Flutter Engine
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) {
34 if (sAAssetManager) {
35 if (AAsset* asset = AAssetManager_open(sAAssetManager, path, AASSET_MODE_STREAMING)) {
36 if (size_t size = SkToSizeT(AAsset_getLength(asset))) {
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);
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
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
Definition: SkMD5.cpp:120
std::string shaderText
Definition: skqp.h:48
std::string name
Definition: skqp.h:47
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63