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