1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program Platform Utilites 3 * ---------------------------------------------- 4 * 5 * Copyright 2015 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Android platform capability query JNI component 22 *//*--------------------------------------------------------------------*/ 23 24 #include "tcuDefs.hpp" 25 26 #include "tcuCommandLine.hpp" 27 #include "gluRenderConfig.hpp" 28 #include "gluRenderContext.hpp" 29 #include "eglwLibrary.hpp" 30 #include "eglwEnums.hpp" 31 #include "egluUtil.hpp" 32 #include "egluGLUtil.hpp" 33 34 #include <jni.h> 35 36 namespace 37 { 38 namespace opt 39 { 40 41 DE_DECLARE_COMMAND_LINE_OPT(GLMajorVersion, int); 42 DE_DECLARE_COMMAND_LINE_OPT(GLMinorVersion, int); 43 44 } // opt 45 46 class GLConfigParser : public tcu::CommandLine 47 { 48 public: 49 GLConfigParser (const std::string& argString); 50 51 bool hasGLMajorVersion (void) const; 52 bool hasGLMinorVersion (void) const; 53 int getGLMajorVersion (void) const; 54 int getGLMinorVersion (void) const; 55 56 private: 57 virtual void registerExtendedOptions (de::cmdline::Parser& parser); 58 }; 59 60 GLConfigParser::GLConfigParser (const std::string& argString) 61 { 62 const std::string execString = "fakebinaryname " + argString; // convert argument list to full command line 63 64 if (!parse(execString)) 65 { 66 tcu::print("failed to parse command line"); 67 TCU_THROW(Exception, "failed to parse command line"); 68 } 69 } 70 71 bool GLConfigParser::hasGLMajorVersion (void) const 72 { 73 return getCommandLine().hasOption<opt::GLMajorVersion>(); 74 } 75 76 bool GLConfigParser::hasGLMinorVersion (void) const 77 { 78 return getCommandLine().hasOption<opt::GLMinorVersion>(); 79 } 80 81 int GLConfigParser::getGLMajorVersion (void) const 82 { 83 DE_ASSERT(hasGLMajorVersion()); 84 return getCommandLine().getOption<opt::GLMajorVersion>(); 85 } 86 87 int GLConfigParser::getGLMinorVersion (void) const 88 { 89 DE_ASSERT(hasGLMinorVersion()); 90 return getCommandLine().getOption<opt::GLMinorVersion>(); 91 } 92 93 void GLConfigParser::registerExtendedOptions (de::cmdline::Parser& parser) 94 { 95 using de::cmdline::Option; 96 97 parser 98 << Option<opt::GLMajorVersion> (DE_NULL, "deqp-gl-major-version", "OpenGL ES Major version") 99 << Option<opt::GLMinorVersion> (DE_NULL, "deqp-gl-minor-version", "OpenGL ES Minor version"); 100 } 101 102 glu::RenderConfig parseRenderConfig (const std::string& argsStr) 103 { 104 const GLConfigParser parsedCommandLine (argsStr); 105 106 if (!parsedCommandLine.hasGLMajorVersion() || 107 !parsedCommandLine.hasGLMinorVersion()) 108 { 109 tcu::print("minor and major version must be supplied"); 110 TCU_THROW(Exception, "minor and major version must be supplied"); 111 } 112 else 113 { 114 const glu::ContextType testContextType (glu::ApiType::es(parsedCommandLine.getGLMajorVersion(), parsedCommandLine.getGLMinorVersion())); 115 glu::RenderConfig renderConfig (testContextType); 116 117 glu::parseRenderConfig(&renderConfig, parsedCommandLine); 118 119 return renderConfig; 120 } 121 } 122 123 bool isRenderConfigSupported (const std::string& cmdLineStr) 124 { 125 const glu::RenderConfig renderConfig = parseRenderConfig(cmdLineStr); 126 const eglw::DefaultLibrary egl; 127 const eglw::EGLDisplay display = egl.getDisplay(EGL_DEFAULT_DISPLAY); 128 eglw::EGLint eglMajor = -1; 129 eglw::EGLint eglMinor = -1; 130 131 if (display == EGL_NO_DISPLAY) 132 { 133 tcu::print("could not get default display"); 134 TCU_THROW(Exception, "could not get default display"); 135 } 136 137 if (egl.initialize(display, &eglMajor, &eglMinor) != EGL_TRUE) 138 { 139 tcu::print("failed to initialize egl"); 140 TCU_THROW(Exception, "failed to initialize egl"); 141 } 142 tcu::print("EGL initialized, major=%d, minor=%d", eglMajor, eglMinor); 143 144 try 145 { 146 // ignoring return value 147 (void)eglu::chooseConfig(egl, display, renderConfig); 148 } 149 catch (const tcu::NotSupportedError&) 150 { 151 tcu::print("No matching config"); 152 egl.terminate(display); 153 return false; 154 } 155 catch (...) 156 { 157 egl.terminate(display); 158 throw; 159 } 160 egl.terminate(display); 161 162 return true; 163 } 164 165 } // anonymous 166 167 168 DE_BEGIN_EXTERN_C 169 170 JNIEXPORT jint JNICALL Java_com_drawelements_deqp_platformutil_DeqpPlatformCapabilityQueryInstrumentation_nativeRenderConfigSupportedQuery (JNIEnv* env, jclass, jstring jCmdLine) 171 { 172 enum 173 { 174 CONFIGQUERYRESULT_SUPPORTED = 0, 175 CONFIGQUERYRESULT_NOT_SUPPORTED = 1, 176 CONFIGQUERYRESULT_GENERIC_ERROR = -1, 177 }; 178 179 std::string cmdLine; 180 const char* const cmdLineBytes = env->GetStringUTFChars(jCmdLine, DE_NULL); 181 182 if (cmdLineBytes == DE_NULL) 183 { 184 // no command line is not executable 185 tcu::print("no command line supplied"); 186 return CONFIGQUERYRESULT_GENERIC_ERROR; 187 } 188 189 try 190 { 191 // try to copy to local buffer 192 cmdLine = std::string(cmdLineBytes); 193 } 194 catch (const std::bad_alloc&) 195 { 196 env->ReleaseStringUTFChars(jCmdLine, cmdLineBytes); 197 tcu::print("failed to copy cmdLine"); 198 return CONFIGQUERYRESULT_GENERIC_ERROR; 199 } 200 env->ReleaseStringUTFChars(jCmdLine, cmdLineBytes); 201 202 try 203 { 204 const bool isSupported = isRenderConfigSupported(cmdLine); 205 206 return (isSupported) ? (CONFIGQUERYRESULT_SUPPORTED) 207 : (CONFIGQUERYRESULT_NOT_SUPPORTED); 208 } 209 catch (const std::exception& ex) 210 { 211 // don't bother forwarding the exception to the caller. They cannot do anything with the exception anyway. 212 tcu::print("Error: %s", ex.what()); 213 return CONFIGQUERYRESULT_GENERIC_ERROR; 214 } 215 } 216 217 DE_END_EXTERN_C 218