| /*------------------------------------------------------------------------- |
| * drawElements Quality Program Platform Utilites |
| * ---------------------------------------------- |
| * |
| * Copyright 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Android platform capability query JNI component |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "tcuDefs.hpp" |
| |
| #include "tcuCommandLine.hpp" |
| #include "gluRenderConfig.hpp" |
| #include "gluRenderContext.hpp" |
| #include "eglwLibrary.hpp" |
| #include "eglwEnums.hpp" |
| #include "egluUtil.hpp" |
| #include "egluGLUtil.hpp" |
| |
| #include <jni.h> |
| |
| namespace |
| { |
| namespace opt |
| { |
| |
| DE_DECLARE_COMMAND_LINE_OPT(GLMajorVersion, int); |
| DE_DECLARE_COMMAND_LINE_OPT(GLMinorVersion, int); |
| |
| } // opt |
| |
| class GLConfigParser : public tcu::CommandLine |
| { |
| public: |
| GLConfigParser (const std::string& argString); |
| |
| bool hasGLMajorVersion (void) const; |
| bool hasGLMinorVersion (void) const; |
| int getGLMajorVersion (void) const; |
| int getGLMinorVersion (void) const; |
| |
| private: |
| virtual void registerExtendedOptions (de::cmdline::Parser& parser); |
| }; |
| |
| GLConfigParser::GLConfigParser (const std::string& argString) |
| { |
| const std::string execString = "fakebinaryname " + argString; // convert argument list to full command line |
| |
| if (!parse(execString)) |
| { |
| tcu::print("failed to parse command line"); |
| TCU_THROW(Exception, "failed to parse command line"); |
| } |
| } |
| |
| bool GLConfigParser::hasGLMajorVersion (void) const |
| { |
| return getCommandLine().hasOption<opt::GLMajorVersion>(); |
| } |
| |
| bool GLConfigParser::hasGLMinorVersion (void) const |
| { |
| return getCommandLine().hasOption<opt::GLMinorVersion>(); |
| } |
| |
| int GLConfigParser::getGLMajorVersion (void) const |
| { |
| DE_ASSERT(hasGLMajorVersion()); |
| return getCommandLine().getOption<opt::GLMajorVersion>(); |
| } |
| |
| int GLConfigParser::getGLMinorVersion (void) const |
| { |
| DE_ASSERT(hasGLMinorVersion()); |
| return getCommandLine().getOption<opt::GLMinorVersion>(); |
| } |
| |
| void GLConfigParser::registerExtendedOptions (de::cmdline::Parser& parser) |
| { |
| using de::cmdline::Option; |
| |
| parser |
| << Option<opt::GLMajorVersion> (DE_NULL, "deqp-gl-major-version", "OpenGL ES Major version") |
| << Option<opt::GLMinorVersion> (DE_NULL, "deqp-gl-minor-version", "OpenGL ES Minor version"); |
| } |
| |
| glu::RenderConfig parseRenderConfig (const std::string& argsStr) |
| { |
| const GLConfigParser parsedCommandLine (argsStr); |
| |
| if (!parsedCommandLine.hasGLMajorVersion() || |
| !parsedCommandLine.hasGLMinorVersion()) |
| { |
| tcu::print("minor and major version must be supplied"); |
| TCU_THROW(Exception, "minor and major version must be supplied"); |
| } |
| else |
| { |
| const glu::ContextType testContextType (glu::ApiType::es(parsedCommandLine.getGLMajorVersion(), parsedCommandLine.getGLMinorVersion())); |
| glu::RenderConfig renderConfig (testContextType); |
| |
| glu::parseRenderConfig(&renderConfig, parsedCommandLine); |
| |
| return renderConfig; |
| } |
| } |
| |
| bool isRenderConfigSupported (const std::string& cmdLineStr) |
| { |
| const glu::RenderConfig renderConfig = parseRenderConfig(cmdLineStr); |
| const eglw::DefaultLibrary egl; |
| const eglw::EGLDisplay display = egl.getDisplay(EGL_DEFAULT_DISPLAY); |
| eglw::EGLint eglMajor = -1; |
| eglw::EGLint eglMinor = -1; |
| |
| if (display == EGL_NO_DISPLAY) |
| { |
| tcu::print("could not get default display"); |
| TCU_THROW(Exception, "could not get default display"); |
| } |
| |
| if (egl.initialize(display, &eglMajor, &eglMinor) != EGL_TRUE) |
| { |
| tcu::print("failed to initialize egl"); |
| TCU_THROW(Exception, "failed to initialize egl"); |
| } |
| tcu::print("EGL initialized, major=%d, minor=%d", eglMajor, eglMinor); |
| |
| try |
| { |
| // ignoring return value |
| (void)eglu::chooseConfig(egl, display, renderConfig); |
| } |
| catch (const tcu::NotSupportedError&) |
| { |
| tcu::print("No matching config"); |
| egl.terminate(display); |
| return false; |
| } |
| catch (...) |
| { |
| egl.terminate(display); |
| throw; |
| } |
| egl.terminate(display); |
| |
| return true; |
| } |
| |
| } // anonymous |
| |
| |
| DE_BEGIN_EXTERN_C |
| |
| JNIEXPORT jint JNICALL Java_com_drawelements_deqp_platformutil_DeqpPlatformCapabilityQueryInstrumentation_nativeRenderConfigSupportedQuery (JNIEnv* env, jclass, jstring jCmdLine) |
| { |
| enum |
| { |
| CONFIGQUERYRESULT_SUPPORTED = 0, |
| CONFIGQUERYRESULT_NOT_SUPPORTED = 1, |
| CONFIGQUERYRESULT_GENERIC_ERROR = -1, |
| }; |
| |
| std::string cmdLine; |
| const char* const cmdLineBytes = env->GetStringUTFChars(jCmdLine, DE_NULL); |
| |
| if (cmdLineBytes == DE_NULL) |
| { |
| // no command line is not executable |
| tcu::print("no command line supplied"); |
| return CONFIGQUERYRESULT_GENERIC_ERROR; |
| } |
| |
| try |
| { |
| // try to copy to local buffer |
| cmdLine = std::string(cmdLineBytes); |
| } |
| catch (const std::bad_alloc&) |
| { |
| env->ReleaseStringUTFChars(jCmdLine, cmdLineBytes); |
| tcu::print("failed to copy cmdLine"); |
| return CONFIGQUERYRESULT_GENERIC_ERROR; |
| } |
| env->ReleaseStringUTFChars(jCmdLine, cmdLineBytes); |
| |
| try |
| { |
| const bool isSupported = isRenderConfigSupported(cmdLine); |
| |
| return (isSupported) ? (CONFIGQUERYRESULT_SUPPORTED) |
| : (CONFIGQUERYRESULT_NOT_SUPPORTED); |
| } |
| catch (const std::exception& ex) |
| { |
| // don't bother forwarding the exception to the caller. They cannot do anything with the exception anyway. |
| tcu::print("Error: %s", ex.what()); |
| return CONFIGQUERYRESULT_GENERIC_ERROR; |
| } |
| } |
| |
| DE_END_EXTERN_C |