Home | History | Annotate | Download | only in jni
      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 <EGL/egl.h>
     21 #include <GLES3/gl3.h>
     22 #include <android/log.h>
     23 #include <android/native_window.h>
     24 #include <jni.h>
     25 #include <vulkan/vulkan.h>
     26 #include <string>
     27 
     28 #define ALOGI(msg, ...) \
     29     __android_log_print(ANDROID_LOG_INFO, LOG_TAG, (msg), __VA_ARGS__)
     30 #define ALOGE(msg, ...) \
     31     __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, (msg), __VA_ARGS__)
     32 #define ALOGD(msg, ...) \
     33     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, (msg), __VA_ARGS__)
     34 
     35 namespace {
     36 
     37 typedef __eglMustCastToProperFunctionPointerType EGLFuncPointer;
     38 
     39 std::string initVulkan() {
     40     std::string result = "";
     41 
     42     const VkApplicationInfo app_info = {
     43         VK_STRUCTURE_TYPE_APPLICATION_INFO,
     44         nullptr,             // pNext
     45         "RootlessGpuDebug",  // app name
     46         0,                   // app version
     47         nullptr,             // engine name
     48         0,                   // engine version
     49         VK_API_VERSION_1_0,
     50     };
     51     const VkInstanceCreateInfo instance_info = {
     52         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
     53         nullptr,  // pNext
     54         0,        // flags
     55         &app_info,
     56         0,        // layer count
     57         nullptr,  // layers
     58         0,        // extension count
     59         nullptr,  // extensions
     60     };
     61     VkInstance instance;
     62     VkResult vkResult = vkCreateInstance(&instance_info, nullptr, &instance);
     63     if (vkResult == VK_ERROR_INITIALIZATION_FAILED) {
     64         result = "vkCreateInstance failed, meaning layers could not be chained.";
     65     } else {
     66         result = "vkCreateInstance succeeded.";
     67     }
     68 
     69     return result;
     70 }
     71 
     72 std::string initGLES() {
     73     std::string result = "";
     74 
     75     const EGLint attribs[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
     76                               EGL_BLUE_SIZE,    8,
     77                               EGL_GREEN_SIZE,   8,
     78                               EGL_RED_SIZE,     8,
     79                               EGL_NONE};
     80 
     81     // Create an EGL context
     82     EGLDisplay display;
     83     EGLConfig config;
     84     EGLint numConfigs;
     85     EGLint format;
     86 
     87     // Check for the EGL_ANDROID_GLES_layers
     88     std::string display_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
     89     if (display_extensions.find("EGL_ANDROID_GLES_layers") == std::string::npos)
     90     {
     91         result = "Did not find EGL_ANDROID_GLES_layers extension";
     92         return result;
     93     }
     94 
     95     if ((display = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY) {
     96         result = "eglGetDisplay() returned error " + std::to_string(eglGetError());
     97         return result;
     98     }
     99 
    100     if (!eglInitialize(display, 0, 0)) {
    101         result = "eglInitialize() returned error " + std::to_string(eglGetError());
    102         return result;
    103     }
    104 
    105     if (!eglChooseConfig(display, attribs, &config, 1, &numConfigs)) {
    106         result =
    107             "eglChooseConfig() returned error " + std::to_string(eglGetError());
    108         return result;
    109     }
    110 
    111     if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format)) {
    112         result =
    113             "eglGetConfigAttrib() returned error " + std::to_string(eglGetError());
    114         return result;
    115     }
    116 
    117     eglTerminate(display);
    118 
    119     return result;
    120 }
    121 
    122 jstring android_gputools_cts_RootlessGpuDebug_nativeInitVulkan(
    123         JNIEnv* env, jclass /*clazz*/) {
    124     std::string result;
    125 
    126     result = initVulkan();
    127 
    128     return env->NewStringUTF(result.c_str());
    129 }
    130 
    131 jstring android_gputools_cts_RootlessGpuDebug_nativeInitGLES(JNIEnv* env,
    132                                                              jclass /*clazz*/) {
    133     std::string result;
    134 
    135     result = initGLES();
    136 
    137     return env->NewStringUTF(result.c_str());
    138 }
    139 
    140 static JNINativeMethod gMethods[] = {
    141     {"nativeInitVulkan", "()Ljava/lang/String;",
    142      (void*)android_gputools_cts_RootlessGpuDebug_nativeInitVulkan},
    143     {"nativeInitGLES", "()Ljava/lang/String;",
    144      (void*)android_gputools_cts_RootlessGpuDebug_nativeInitGLES}};
    145 }  // anonymous namespace
    146 
    147 int register_android_gputools_cts_RootlessGpuDebug(JNIEnv* env) {
    148     jclass clazz = env->FindClass(
    149         "android/rootlessgpudebug/app/RootlessGpuDebugDeviceActivity");
    150     return env->RegisterNatives(clazz, gMethods,
    151                                 sizeof(gMethods) / sizeof(JNINativeMethod));
    152 }
    153