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 
GLConfigParser(const std::string & argString)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 
hasGLMajorVersion(void) const71 bool GLConfigParser::hasGLMajorVersion (void) const
72 {
73 	return getCommandLine().hasOption<opt::GLMajorVersion>();
74 }
75 
hasGLMinorVersion(void) const76 bool GLConfigParser::hasGLMinorVersion (void) const
77 {
78 	return getCommandLine().hasOption<opt::GLMinorVersion>();
79 }
80 
getGLMajorVersion(void) const81 int GLConfigParser::getGLMajorVersion (void) const
82 {
83 	DE_ASSERT(hasGLMajorVersion());
84 	return getCommandLine().getOption<opt::GLMajorVersion>();
85 }
86 
getGLMinorVersion(void) const87 int GLConfigParser::getGLMinorVersion (void) const
88 {
89 	DE_ASSERT(hasGLMinorVersion());
90 	return getCommandLine().getOption<opt::GLMinorVersion>();
91 }
92 
registerExtendedOptions(de::cmdline::Parser & parser)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 
parseRenderConfig(const std::string & argsStr)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 
isRenderConfigSupported(const std::string & cmdLineStr)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 
Java_com_drawelements_deqp_platformutil_DeqpPlatformCapabilityQueryInstrumentation_nativeRenderConfigSupportedQuery(JNIEnv * env,jclass,jstring jCmdLine)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