- Add Instrumentation for querying if the described render target is supported.
- Move chooseConfig() from egluGLContextFactory to egluGLUtil
Change-Id: I5f55d0d7c2c1f6c70de9333e42298deb32f19953
framework/platform/android/tcuAndroidMain.cpp \
framework/platform/android/tcuAndroidNativeActivity.cpp \
framework/platform/android/tcuAndroidPlatform.cpp \
+ framework/platform/android/tcuAndroidPlatformCapabilityQueryJNI.cpp \
framework/platform/android/tcuAndroidRenderActivity.cpp \
framework/platform/android/tcuAndroidTestActivity.cpp \
framework/platform/android/tcuAndroidUtil.cpp \
if (DE_OS_IS_ANDROID)
include_directories(executor)
- add_library(deqp SHARED framework/platform/android/tcuAndroidMain.cpp framework/platform/android/tcuAndroidJNI.cpp framework/platform/android/tcuTestLogParserJNI.cpp ${DEQP_MODULE_ENTRY_POINTS})
+ add_library(deqp SHARED framework/platform/android/tcuAndroidMain.cpp framework/platform/android/tcuAndroidJNI.cpp framework/platform/android/tcuAndroidPlatformCapabilityQueryJNI.cpp framework/platform/android/tcuTestLogParserJNI.cpp ${DEQP_MODULE_ENTRY_POINTS})
target_link_libraries(deqp tcutil-platform xecore ${DEQP_MODULE_LIBRARIES})
elseif (DE_OS_IS_IOS)
<instrumentation android:label="dEQP-Instrumentation"
android:name="com.drawelements.deqp.testercore.DeqpInstrumentation"
android:targetPackage="com.drawelements.deqp" />
+ <instrumentation android:label="dEQP-PlatformCapabilityQueryInstrumentation"
+ android:name="com.drawelements.deqp.platformutil.DeqpPlatformCapabilityQueryInstrumentation"
+ android:targetPackage="com.drawelements.deqp" />
</manifest>
--- /dev/null
+/*-------------------------------------------------------------------------
+ * 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 dEQP platform capability query instrumentation
+ *//*--------------------------------------------------------------------*/
+
+package com.drawelements.deqp.platformutil;
+
+import android.app.Instrumentation;
+
+import android.os.Bundle;
+
+public class DeqpPlatformCapabilityQueryInstrumentation extends Instrumentation
+{
+ static
+ {
+ System.loadLibrary("deqp");
+ }
+
+ private static final String LOG_TAG = "dEQP/PlatformCapabilityQueryInstrumentation";
+ private static final int CONFIGQUERYRESULT_SUPPORTED = 0;
+ private static final int CONFIGQUERYRESULT_NOT_SUPPORTED = 1;
+ private static final int CONFIGQUERYRESULT_GENERIC_ERROR = -1;
+
+ private String m_cmdLine;
+ private String m_queryType;
+
+ @Override
+ public void onCreate (Bundle arguments) {
+ super.onCreate(arguments);
+ start();
+
+ m_queryType = arguments.getString("deqpQueryType");
+ m_cmdLine = arguments.getString("deqpCmdLine");
+ }
+
+ @Override
+ public void onStart () {
+ super.onStart();
+
+ Bundle resultInfo;
+ int resultCode = 0;
+
+ try
+ {
+ if ("renderConfigSupported".equals(m_queryType))
+ resultInfo = doRenderConfigSupportedQuery();
+ else
+ {
+ resultInfo = new Bundle();
+ resultInfo.putString("Error", "unknown query");
+ resultCode = 2;
+ }
+ }
+ catch (Exception e)
+ {
+ resultInfo = new Bundle();
+ resultInfo.putString("Error", e.getMessage());
+ resultCode = 1;
+ }
+
+ finish(resultCode, resultInfo);
+ }
+
+ private Bundle doRenderConfigSupportedQuery ()
+ {
+ if (m_cmdLine == null)
+ throw new RuntimeException("missing command line");
+
+ final int result = nativeRenderConfigSupportedQuery(m_cmdLine);
+
+ if (result == CONFIGQUERYRESULT_SUPPORTED)
+ {
+ final Bundle resultInfo = new Bundle();
+ resultInfo.putString("Supported", "Yes");
+ return resultInfo;
+ }
+ else if (result == CONFIGQUERYRESULT_NOT_SUPPORTED)
+ {
+ final Bundle resultInfo = new Bundle();
+ resultInfo.putString("Supported", "No");
+ return resultInfo;
+ }
+ else if (result == CONFIGQUERYRESULT_GENERIC_ERROR)
+ throw new RuntimeException("platform query reported failure");
+ else
+ throw new RuntimeException("platform query returned out-of-range result");
+ }
+
+ private static native int nativeRenderConfigSupportedQuery (String cmdLine);
+}
m_caseTree = DE_NULL;
}
+const de::cmdline::CommandLine& CommandLine::getCommandLine (void) const
+{
+ return m_cmdLine;
+}
+
+void CommandLine::registerExtendedOptions (de::cmdline::Parser& parser)
+{
+ DE_UNREF(parser);
+}
+
/*--------------------------------------------------------------------*//*!
* \brief Parse command line from standard argc, argv pair.
* \note parse() must be called exactly once.
opt::registerOptions(parser);
opt::registerLegacyOptions(parser);
+ registerExtendedOptions(parser);
clear();
//! Check if test case is in supplied test case list.
bool checkTestCaseName (const char* caseName) const;
+protected:
+ const de::cmdline::CommandLine& getCommandLine (void) const;
+
private:
CommandLine (const CommandLine&); // not allowed!
CommandLine& operator= (const CommandLine&); // not allowed!
void clear (void);
+ virtual void registerExtendedOptions (de::cmdline::Parser& parser);
+
de::cmdline::CommandLine m_cmdLine;
deUint32 m_logFlags;
CaseTreeNode* m_caseTree;
delete m_dynamicGLLibrary;
}
-bool configMatches (const Library& egl, EGLDisplay display, EGLConfig eglConfig, const glu::RenderConfig& renderConfig)
-{
- // \todo [2014-03-12 pyry] Check other attributes like double-buffer bit.
-
- {
- EGLint renderableType = 0;
- EGLint requiredRenderable = apiRenderableType(renderConfig.type.getAPI());
-
- EGLU_CHECK_CALL(egl, getConfigAttrib(display, eglConfig, EGL_RENDERABLE_TYPE, &renderableType));
-
- if ((renderableType & requiredRenderable) == 0)
- return false;
- }
-
- if (renderConfig.surfaceType != (glu::RenderConfig::SurfaceType)glu::RenderConfig::DONT_CARE)
- {
- EGLint surfaceType = 0;
- EGLint requiredSurface = 0;
-
- switch (renderConfig.surfaceType)
- {
- case glu::RenderConfig::SURFACETYPE_WINDOW: requiredSurface = EGL_WINDOW_BIT; break;
- case glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE: requiredSurface = EGL_PIXMAP_BIT; break;
- case glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC: requiredSurface = EGL_PBUFFER_BIT; break;
- default:
- DE_ASSERT(false);
- }
-
- EGLU_CHECK_CALL(egl, getConfigAttrib(display, eglConfig, EGL_SURFACE_TYPE, &surfaceType));
-
- if ((surfaceType & requiredSurface) == 0)
- return false;
- }
-
- {
- static const struct
- {
- int glu::RenderConfig::*field;
- EGLint attrib;
- } s_attribs[] =
- {
- { &glu::RenderConfig::id, EGL_CONFIG_ID },
- { &glu::RenderConfig::redBits, EGL_RED_SIZE },
- { &glu::RenderConfig::greenBits, EGL_GREEN_SIZE },
- { &glu::RenderConfig::blueBits, EGL_BLUE_SIZE },
- { &glu::RenderConfig::alphaBits, EGL_ALPHA_SIZE },
- { &glu::RenderConfig::depthBits, EGL_DEPTH_SIZE },
- { &glu::RenderConfig::stencilBits, EGL_STENCIL_SIZE },
- { &glu::RenderConfig::numSamples, EGL_SAMPLES },
- };
-
- for (int attribNdx = 0; attribNdx < DE_LENGTH_OF_ARRAY(s_attribs); attribNdx++)
- {
- if (renderConfig.*s_attribs[attribNdx].field != glu::RenderConfig::DONT_CARE)
- {
- EGLint value = 0;
- EGLU_CHECK_CALL(egl, getConfigAttrib(display, eglConfig, s_attribs[attribNdx].attrib, &value));
- if (value != renderConfig.*s_attribs[attribNdx].field)
- return false;
- }
- }
- }
-
- return true;
-}
-
-EGLConfig chooseConfig (const Library& egl, EGLDisplay display, const glu::RenderConfig& config)
-{
- const std::vector<EGLConfig> configs = eglu::getConfigs(egl, display);
-
- for (vector<EGLConfig>::const_iterator iter = configs.begin(); iter != configs.end(); ++iter)
- {
- if (configMatches(egl, display, *iter, config))
- return *iter;
- }
-
- throw tcu::NotSupportedError("Matching EGL config not found", DE_NULL, __FILE__, __LINE__);
-}
-
static WindowParams::Visibility getNativeWindowVisibility (glu::RenderConfig::Visibility visibility)
{
using glu::RenderConfig;
return context;
}
+static bool configMatches (const eglw::Library& egl, eglw::EGLDisplay display, eglw::EGLConfig eglConfig, const glu::RenderConfig& renderConfig)
+{
+ // \todo [2014-03-12 pyry] Check other attributes like double-buffer bit.
+
+ {
+ EGLint renderableType = 0;
+ EGLint requiredRenderable = apiRenderableType(renderConfig.type.getAPI());
+
+ EGLU_CHECK_CALL(egl, getConfigAttrib(display, eglConfig, EGL_RENDERABLE_TYPE, &renderableType));
+
+ if ((renderableType & requiredRenderable) == 0)
+ return false;
+ }
+
+ if (renderConfig.surfaceType != (glu::RenderConfig::SurfaceType)glu::RenderConfig::DONT_CARE)
+ {
+ EGLint surfaceType = 0;
+ EGLint requiredSurface = 0;
+
+ switch (renderConfig.surfaceType)
+ {
+ case glu::RenderConfig::SURFACETYPE_WINDOW: requiredSurface = EGL_WINDOW_BIT; break;
+ case glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE: requiredSurface = EGL_PIXMAP_BIT; break;
+ case glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC: requiredSurface = EGL_PBUFFER_BIT; break;
+ default:
+ DE_ASSERT(false);
+ }
+
+ EGLU_CHECK_CALL(egl, getConfigAttrib(display, eglConfig, EGL_SURFACE_TYPE, &surfaceType));
+
+ if ((surfaceType & requiredSurface) == 0)
+ return false;
+ }
+
+ {
+ static const struct
+ {
+ int glu::RenderConfig::*field;
+ EGLint attrib;
+ } s_attribs[] =
+ {
+ { &glu::RenderConfig::id, EGL_CONFIG_ID },
+ { &glu::RenderConfig::redBits, EGL_RED_SIZE },
+ { &glu::RenderConfig::greenBits, EGL_GREEN_SIZE },
+ { &glu::RenderConfig::blueBits, EGL_BLUE_SIZE },
+ { &glu::RenderConfig::alphaBits, EGL_ALPHA_SIZE },
+ { &glu::RenderConfig::depthBits, EGL_DEPTH_SIZE },
+ { &glu::RenderConfig::stencilBits, EGL_STENCIL_SIZE },
+ { &glu::RenderConfig::numSamples, EGL_SAMPLES },
+ };
+
+ for (int attribNdx = 0; attribNdx < DE_LENGTH_OF_ARRAY(s_attribs); attribNdx++)
+ {
+ if (renderConfig.*s_attribs[attribNdx].field != glu::RenderConfig::DONT_CARE)
+ {
+ EGLint value = 0;
+ EGLU_CHECK_CALL(egl, getConfigAttrib(display, eglConfig, s_attribs[attribNdx].attrib, &value));
+ if (value != renderConfig.*s_attribs[attribNdx].field)
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+EGLConfig chooseConfig (const Library& egl, EGLDisplay display, const glu::RenderConfig& config)
+{
+ const std::vector<EGLConfig> configs = eglu::getConfigs(egl, display);
+
+ for (vector<EGLConfig>::const_iterator iter = configs.begin(); iter != configs.end(); ++iter)
+ {
+ if (configMatches(egl, display, *iter, config))
+ return *iter;
+ }
+
+ throw tcu::NotSupportedError("Matching EGL config not found", DE_NULL, __FILE__, __LINE__);
+}
+
}
glw::GLenum getImageGLTarget (eglw::EGLenum source);
eglw::EGLint apiRenderableType (glu::ApiType apiType);
eglw::EGLContext createGLContext (const eglw::Library& egl, eglw::EGLDisplay display, eglw::EGLConfig config, const glu::ContextType& contextType);
+eglw::EGLConfig chooseConfig (const eglw::Library& egl, eglw::EGLDisplay display, const glu::RenderConfig& config);
}
--- /dev/null
+/*-------------------------------------------------------------------------
+ * 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