• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #define LOG_TAG "RootlessGpuDebug"
19 
20 #include <string>
21 #include <vector>
22 
23 #include <EGL/egl.h>
24 #include <GLES3/gl3.h>
25 #include <android/log.h>
26 #include <android/native_window.h>
27 #include <jni.h>
28 #include <vulkan/vulkan.h>
29 
30 #define ALOGI(msg, ...) \
31     __android_log_print(ANDROID_LOG_INFO, LOG_TAG, (msg), __VA_ARGS__)
32 #define ALOGE(msg, ...) \
33     __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, (msg), __VA_ARGS__)
34 #define ALOGD(msg, ...) \
35     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, (msg), __VA_ARGS__)
36 
37 namespace {
38 
39 typedef __eglMustCastToProperFunctionPointerType EGLFuncPointer;
40 
initVulkan()41 std::string initVulkan() {
42     std::string result = "";
43 
44     {
45       uint32_t count = 0;
46       vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
47       if (count > 0) {
48         std::vector<VkExtensionProperties> properties(count);
49         vkEnumerateInstanceExtensionProperties(nullptr, &count,
50                                                properties.data());
51         for (uint32_t i = 0; i < count; ++i) {
52           if (!strcmp("VK_EXT_debug_utils", properties[i].extensionName)) {
53             ALOGI("VK_EXT_debug_utils: %u", properties[i].specVersion);
54             break;
55           }
56         }
57       }
58     }
59 
60     const VkApplicationInfo app_info = {
61         VK_STRUCTURE_TYPE_APPLICATION_INFO,
62         nullptr,             // pNext
63         "RootlessGpuDebug",  // app name
64         0,                   // app version
65         nullptr,             // engine name
66         0,                   // engine version
67         VK_API_VERSION_1_0,
68     };
69     const VkInstanceCreateInfo instance_info = {
70         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
71         nullptr,  // pNext
72         0,        // flags
73         &app_info,
74         0,        // layer count
75         nullptr,  // layers
76         0,        // extension count
77         nullptr,  // extensions
78     };
79     VkInstance instance;
80     VkResult vkResult = vkCreateInstance(&instance_info, nullptr, &instance);
81     if (vkResult == VK_ERROR_INITIALIZATION_FAILED) {
82         result = "vkCreateInstance failed, meaning layers could not be chained.";
83     } else {
84         result = "vkCreateInstance succeeded.";
85     }
86 
87     return result;
88 }
89 
initGLES()90 std::string initGLES() {
91     std::string result = "";
92 
93     const EGLint attribs[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
94                               EGL_BLUE_SIZE,    8,
95                               EGL_GREEN_SIZE,   8,
96                               EGL_RED_SIZE,     8,
97                               EGL_NONE};
98 
99     // Create an EGL context
100     EGLDisplay display;
101     EGLConfig config;
102     EGLint numConfigs;
103     EGLint format;
104 
105     // Check for the EGL_ANDROID_GLES_layers
106     std::string display_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
107     if (display_extensions.find("EGL_ANDROID_GLES_layers") == std::string::npos)
108     {
109         result = "Did not find EGL_ANDROID_GLES_layers extension";
110         return result;
111     }
112 
113     if ((display = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY) {
114         result = "eglGetDisplay() returned error " + std::to_string(eglGetError());
115         return result;
116     }
117 
118     if (!eglInitialize(display, 0, 0)) {
119         result = "eglInitialize() returned error " + std::to_string(eglGetError());
120         return result;
121     }
122 
123     if (!eglChooseConfig(display, attribs, &config, 1, &numConfigs)) {
124         result =
125             "eglChooseConfig() returned error " + std::to_string(eglGetError());
126         return result;
127     }
128 
129     if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format)) {
130         result =
131             "eglGetConfigAttrib() returned error " + std::to_string(eglGetError());
132         return result;
133     }
134 
135     eglTerminate(display);
136 
137     return result;
138 }
139 
android_gputools_cts_RootlessGpuDebug_nativeInitVulkan(JNIEnv * env,jclass)140 jstring android_gputools_cts_RootlessGpuDebug_nativeInitVulkan(
141         JNIEnv* env, jclass /*clazz*/) {
142     std::string result;
143 
144     result = initVulkan();
145 
146     return env->NewStringUTF(result.c_str());
147 }
148 
android_gputools_cts_RootlessGpuDebug_nativeInitGLES(JNIEnv * env,jclass)149 jstring android_gputools_cts_RootlessGpuDebug_nativeInitGLES(JNIEnv* env,
150                                                              jclass /*clazz*/) {
151     std::string result;
152 
153     result = initGLES();
154 
155     return env->NewStringUTF(result.c_str());
156 }
157 
158 static JNINativeMethod gMethods[] = {
159     {"nativeInitVulkan", "()Ljava/lang/String;",
160      (void*)android_gputools_cts_RootlessGpuDebug_nativeInitVulkan},
161     {"nativeInitGLES", "()Ljava/lang/String;",
162      (void*)android_gputools_cts_RootlessGpuDebug_nativeInitGLES}};
163 }  // anonymous namespace
164 
register_android_gputools_cts_RootlessGpuDebug(JNIEnv * env)165 int register_android_gputools_cts_RootlessGpuDebug(JNIEnv* env) {
166     jclass clazz = env->FindClass(
167         "android/rootlessgpudebug/app/RootlessGpuDebugDeviceActivity");
168     return env->RegisterNatives(clazz, gMethods,
169                                 sizeof(gMethods) / sizeof(JNINativeMethod));
170 }
171