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 36namespace 37{ 38namespace opt 39{ 40 41DE_DECLARE_COMMAND_LINE_OPT(GLMajorVersion, int); 42DE_DECLARE_COMMAND_LINE_OPT(GLMinorVersion, int); 43 44} // opt 45 46class GLConfigParser : public tcu::CommandLine 47{ 48public: 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 56private: 57 virtual void registerExtendedOptions (de::cmdline::Parser& parser); 58}; 59 60GLConfigParser::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 71bool GLConfigParser::hasGLMajorVersion (void) const 72{ 73 return getCommandLine().hasOption<opt::GLMajorVersion>(); 74} 75 76bool GLConfigParser::hasGLMinorVersion (void) const 77{ 78 return getCommandLine().hasOption<opt::GLMinorVersion>(); 79} 80 81int GLConfigParser::getGLMajorVersion (void) const 82{ 83 DE_ASSERT(hasGLMajorVersion()); 84 return getCommandLine().getOption<opt::GLMajorVersion>(); 85} 86 87int GLConfigParser::getGLMinorVersion (void) const 88{ 89 DE_ASSERT(hasGLMinorVersion()); 90 return getCommandLine().getOption<opt::GLMinorVersion>(); 91} 92 93void 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 102glu::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 123bool 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 168DE_BEGIN_EXTERN_C 169 170JNIEXPORT 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 217DE_END_EXTERN_C 218