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 } // namespace 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 << Option<opt::GLMajorVersion>(DE_NULL, "deqp-gl-major-version", "OpenGL ES Major version")
98 << Option<opt::GLMinorVersion>(DE_NULL, "deqp-gl-minor-version", "OpenGL ES Minor version");
99 }
100
parseRenderConfig(const std::string & argsStr)101 glu::RenderConfig parseRenderConfig(const std::string &argsStr)
102 {
103 const GLConfigParser parsedCommandLine(argsStr);
104
105 if (!parsedCommandLine.hasGLMajorVersion() || !parsedCommandLine.hasGLMinorVersion())
106 {
107 tcu::print("minor and major version must be supplied");
108 TCU_THROW(Exception, "minor and major version must be supplied");
109 }
110 else
111 {
112 const glu::ContextType testContextType(
113 glu::ApiType::es(parsedCommandLine.getGLMajorVersion(), parsedCommandLine.getGLMinorVersion()));
114 glu::RenderConfig renderConfig(testContextType);
115
116 glu::parseRenderConfig(&renderConfig, parsedCommandLine);
117
118 return renderConfig;
119 }
120 }
121
isRenderConfigSupported(const std::string & cmdLineStr)122 bool isRenderConfigSupported(const std::string &cmdLineStr)
123 {
124 const glu::RenderConfig renderConfig = parseRenderConfig(cmdLineStr);
125 const eglw::DefaultLibrary egl;
126 const eglw::EGLDisplay display = egl.getDisplay(EGL_DEFAULT_DISPLAY);
127 eglw::EGLint eglMajor = -1;
128 eglw::EGLint eglMinor = -1;
129
130 if (display == EGL_NO_DISPLAY)
131 {
132 tcu::print("could not get default display");
133 TCU_THROW(Exception, "could not get default display");
134 }
135
136 if (egl.initialize(display, &eglMajor, &eglMinor) != EGL_TRUE)
137 {
138 tcu::print("failed to initialize egl");
139 TCU_THROW(Exception, "failed to initialize egl");
140 }
141 tcu::print("EGL initialized, major=%d, minor=%d", eglMajor, eglMinor);
142
143 try
144 {
145 // ignoring return value
146 (void)eglu::chooseConfig(egl, display, renderConfig);
147 }
148 catch (const tcu::NotSupportedError &)
149 {
150 tcu::print("No matching config");
151 egl.terminate(display);
152 return false;
153 }
154 catch (...)
155 {
156 egl.terminate(display);
157 throw;
158 }
159 egl.terminate(display);
160
161 return true;
162 }
163
164 } // namespace
165
166 DE_BEGIN_EXTERN_C
167
168 JNIEXPORT jint JNICALL
Java_com_drawelements_deqp_platformutil_DeqpPlatformCapabilityQueryInstrumentation_nativeRenderConfigSupportedQuery(JNIEnv * env,jclass,jstring jCmdLine)169 Java_com_drawelements_deqp_platformutil_DeqpPlatformCapabilityQueryInstrumentation_nativeRenderConfigSupportedQuery(
170 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) : (CONFIGQUERYRESULT_NOT_SUPPORTED);
207 }
208 catch (const std::exception &ex)
209 {
210 // don't bother forwarding the exception to the caller. They cannot do anything with the exception anyway.
211 tcu::print("Error: %s", ex.what());
212 return CONFIGQUERYRESULT_GENERIC_ERROR;
213 }
214 }
215
216 DE_END_EXTERN_C
217