blob: 83e047d4141f9e4dda60322056fdd468281273f0 [file] [log] [blame]
/*-------------------------------------------------------------------------
* 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