1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES Utilities 3e5c31af7Sopenharmony_ci * ------------------------------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 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 OpenGL ES rendering context. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp" 25e5c31af7Sopenharmony_ci#include "gluDefs.hpp" 26e5c31af7Sopenharmony_ci#include "gluRenderConfig.hpp" 27e5c31af7Sopenharmony_ci#include "gluFboRenderContext.hpp" 28e5c31af7Sopenharmony_ci#include "gluPlatform.hpp" 29e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp" 30e5c31af7Sopenharmony_ci#include "glwInitFunctions.hpp" 31e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 32e5c31af7Sopenharmony_ci#include "tcuPlatform.hpp" 33e5c31af7Sopenharmony_ci#include "tcuCommandLine.hpp" 34e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 35e5c31af7Sopenharmony_ci#include "deSTLUtil.hpp" 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_cinamespace glu 38e5c31af7Sopenharmony_ci{ 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ci// RenderContext 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_ciglw::GenericFuncType RenderContext::getProcAddress (const char*) const 43e5c31af7Sopenharmony_ci{ 44e5c31af7Sopenharmony_ci return (glw::GenericFuncType)DE_NULL; 45e5c31af7Sopenharmony_ci} 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_civoid RenderContext::makeCurrent (void) 48e5c31af7Sopenharmony_ci{ 49e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "RenderContext::makeCurrent() is not implemented"); 50e5c31af7Sopenharmony_ci} 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_ci// Utilities 53e5c31af7Sopenharmony_ci 54e5c31af7Sopenharmony_ciinline bool versionGreaterOrEqual (ApiType a, ApiType b) 55e5c31af7Sopenharmony_ci{ 56e5c31af7Sopenharmony_ci return a.getMajorVersion() > b.getMajorVersion() || 57e5c31af7Sopenharmony_ci (a.getMajorVersion() == b.getMajorVersion() && a.getMinorVersion() >= b.getMinorVersion()); 58e5c31af7Sopenharmony_ci} 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_cibool contextSupports (ContextType ctxType, ApiType requiredApiType) 61e5c31af7Sopenharmony_ci{ 62e5c31af7Sopenharmony_ci // \todo [2014-10-06 pyry] Check exact forward-compatible restrictions. 63e5c31af7Sopenharmony_ci const bool forwardCompatible = (ctxType.getFlags() & CONTEXT_FORWARD_COMPATIBLE) != 0; 64e5c31af7Sopenharmony_ci 65e5c31af7Sopenharmony_ci if (isContextTypeES(ctxType)) 66e5c31af7Sopenharmony_ci { 67e5c31af7Sopenharmony_ci DE_ASSERT(!forwardCompatible); 68e5c31af7Sopenharmony_ci return requiredApiType.getProfile() == PROFILE_ES && 69e5c31af7Sopenharmony_ci versionGreaterOrEqual(ctxType.getAPI(), requiredApiType); 70e5c31af7Sopenharmony_ci } 71e5c31af7Sopenharmony_ci else if (isContextTypeGLCore(ctxType)) 72e5c31af7Sopenharmony_ci { 73e5c31af7Sopenharmony_ci if (forwardCompatible) 74e5c31af7Sopenharmony_ci return ctxType.getAPI() == requiredApiType; 75e5c31af7Sopenharmony_ci else 76e5c31af7Sopenharmony_ci return requiredApiType.getProfile() == PROFILE_CORE && 77e5c31af7Sopenharmony_ci versionGreaterOrEqual(ctxType.getAPI(), requiredApiType); 78e5c31af7Sopenharmony_ci } 79e5c31af7Sopenharmony_ci else if (isContextTypeGLCompatibility(ctxType)) 80e5c31af7Sopenharmony_ci { 81e5c31af7Sopenharmony_ci DE_ASSERT(!forwardCompatible); 82e5c31af7Sopenharmony_ci return (requiredApiType.getProfile() == PROFILE_CORE || requiredApiType.getProfile() == PROFILE_COMPATIBILITY) && 83e5c31af7Sopenharmony_ci versionGreaterOrEqual(ctxType.getAPI(), requiredApiType); 84e5c31af7Sopenharmony_ci } 85e5c31af7Sopenharmony_ci else 86e5c31af7Sopenharmony_ci { 87e5c31af7Sopenharmony_ci DE_ASSERT(false); 88e5c31af7Sopenharmony_ci return false; 89e5c31af7Sopenharmony_ci } 90e5c31af7Sopenharmony_ci} 91e5c31af7Sopenharmony_ci 92e5c31af7Sopenharmony_cistatic ContextFlags parseContextFlags (const std::string& flagsStr) 93e5c31af7Sopenharmony_ci{ 94e5c31af7Sopenharmony_ci const std::vector<std::string> flagNames = de::splitString(flagsStr, ','); 95e5c31af7Sopenharmony_ci ContextFlags flags = ContextFlags(0); 96e5c31af7Sopenharmony_ci static const struct 97e5c31af7Sopenharmony_ci { 98e5c31af7Sopenharmony_ci const char* name; 99e5c31af7Sopenharmony_ci ContextFlags flag; 100e5c31af7Sopenharmony_ci } s_flagMap[] = 101e5c31af7Sopenharmony_ci { 102e5c31af7Sopenharmony_ci { "debug", CONTEXT_DEBUG }, 103e5c31af7Sopenharmony_ci { "robust", CONTEXT_ROBUST } 104e5c31af7Sopenharmony_ci }; 105e5c31af7Sopenharmony_ci 106e5c31af7Sopenharmony_ci for (std::vector<std::string>::const_iterator flagIter = flagNames.begin(); flagIter != flagNames.end(); ++flagIter) 107e5c31af7Sopenharmony_ci { 108e5c31af7Sopenharmony_ci int ndx; 109e5c31af7Sopenharmony_ci for (ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_flagMap); ndx++) 110e5c31af7Sopenharmony_ci { 111e5c31af7Sopenharmony_ci if (*flagIter == s_flagMap[ndx].name) 112e5c31af7Sopenharmony_ci { 113e5c31af7Sopenharmony_ci flags = flags | s_flagMap[ndx].flag; 114e5c31af7Sopenharmony_ci break; 115e5c31af7Sopenharmony_ci } 116e5c31af7Sopenharmony_ci } 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_ci if (ndx == DE_LENGTH_OF_ARRAY(s_flagMap)) 119e5c31af7Sopenharmony_ci { 120e5c31af7Sopenharmony_ci tcu::print("ERROR: Unrecognized GL context flag '%s'\n", flagIter->c_str()); 121e5c31af7Sopenharmony_ci tcu::print("Supported GL context flags:\n"); 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_ci for (ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_flagMap); ndx++) 124e5c31af7Sopenharmony_ci tcu::print(" %s\n", s_flagMap[ndx].name); 125e5c31af7Sopenharmony_ci 126e5c31af7Sopenharmony_ci throw tcu::NotSupportedError((std::string("Unknown GL context flag '") + *flagIter + "'").c_str(), DE_NULL, __FILE__, __LINE__); 127e5c31af7Sopenharmony_ci } 128e5c31af7Sopenharmony_ci } 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_ci return flags; 131e5c31af7Sopenharmony_ci} 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_ciRenderContext* createRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, const RenderConfig& config, const RenderContext* sharedContext) 134e5c31af7Sopenharmony_ci{ 135e5c31af7Sopenharmony_ci const ContextFactoryRegistry& registry = platform.getGLPlatform().getContextFactoryRegistry(); 136e5c31af7Sopenharmony_ci const char* factoryName = cmdLine.getGLContextType(); 137e5c31af7Sopenharmony_ci const ContextFactory* factory = DE_NULL; 138e5c31af7Sopenharmony_ci 139e5c31af7Sopenharmony_ci if (registry.empty()) 140e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("OpenGL is not supported", DE_NULL, __FILE__, __LINE__); 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ci if (factoryName) 143e5c31af7Sopenharmony_ci { 144e5c31af7Sopenharmony_ci factory = registry.getFactoryByName(factoryName); 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ci if (!factory) 147e5c31af7Sopenharmony_ci { 148e5c31af7Sopenharmony_ci tcu::print("ERROR: Unknown or unsupported GL context type '%s'\n", factoryName); 149e5c31af7Sopenharmony_ci tcu::print("Supported GL context types:\n"); 150e5c31af7Sopenharmony_ci 151e5c31af7Sopenharmony_ci for (int factoryNdx = 0; factoryNdx < (int)registry.getFactoryCount(); factoryNdx++) 152e5c31af7Sopenharmony_ci { 153e5c31af7Sopenharmony_ci const ContextFactory* curFactory = registry.getFactoryByIndex(factoryNdx); 154e5c31af7Sopenharmony_ci tcu::print(" %s: %s\n", curFactory->getName(), curFactory->getDescription()); 155e5c31af7Sopenharmony_ci } 156e5c31af7Sopenharmony_ci 157e5c31af7Sopenharmony_ci throw tcu::NotSupportedError((std::string("Unknown GL context type '") + factoryName + "'").c_str(), DE_NULL, __FILE__, __LINE__); 158e5c31af7Sopenharmony_ci } 159e5c31af7Sopenharmony_ci } 160e5c31af7Sopenharmony_ci else 161e5c31af7Sopenharmony_ci factory = registry.getDefaultFactory(); 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ci if (cmdLine.getSurfaceType() == tcu::SURFACETYPE_FBO) 164e5c31af7Sopenharmony_ci { 165e5c31af7Sopenharmony_ci if (sharedContext) 166e5c31af7Sopenharmony_ci TCU_FAIL("Shared context not implemented for FBO surface type"); 167e5c31af7Sopenharmony_ci return new FboRenderContext(*factory, config, cmdLine); 168e5c31af7Sopenharmony_ci } 169e5c31af7Sopenharmony_ci else 170e5c31af7Sopenharmony_ci return factory->createContext(config, cmdLine, sharedContext); 171e5c31af7Sopenharmony_ci} 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_ciRenderContext* createDefaultRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, ApiType apiType) 174e5c31af7Sopenharmony_ci{ 175e5c31af7Sopenharmony_ci RenderConfig config; 176e5c31af7Sopenharmony_ci ContextFlags ctxFlags = ContextFlags(0); 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_ci if (cmdLine.getGLContextFlags()) 179e5c31af7Sopenharmony_ci ctxFlags = parseContextFlags(cmdLine.getGLContextFlags()); 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_ci config.type = glu::ContextType(apiType, ctxFlags); 182e5c31af7Sopenharmony_ci parseRenderConfig(&config, cmdLine); 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ci return createRenderContext(platform, cmdLine, config); 185e5c31af7Sopenharmony_ci} 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_cistatic std::vector<std::string> getExtensions (const glw::Functions& gl, ApiType apiType) 188e5c31af7Sopenharmony_ci{ 189e5c31af7Sopenharmony_ci using std::vector; 190e5c31af7Sopenharmony_ci using std::string; 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ci if (apiType.getProfile() == PROFILE_ES && apiType.getMajorVersion() == 2) 193e5c31af7Sopenharmony_ci { 194e5c31af7Sopenharmony_ci TCU_CHECK(gl.getString); 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ci const char* extStr = (const char*)gl.getString(GL_EXTENSIONS); 197e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetString(GL_EXTENSIONS)"); 198e5c31af7Sopenharmony_ci 199e5c31af7Sopenharmony_ci if (extStr) 200e5c31af7Sopenharmony_ci return de::splitString(extStr); 201e5c31af7Sopenharmony_ci else 202e5c31af7Sopenharmony_ci throw tcu::TestError("glGetString(GL_EXTENSIONS) returned null pointer", DE_NULL, __FILE__, __LINE__); 203e5c31af7Sopenharmony_ci } 204e5c31af7Sopenharmony_ci else 205e5c31af7Sopenharmony_ci { 206e5c31af7Sopenharmony_ci int numExtensions = 0; 207e5c31af7Sopenharmony_ci vector<string> extensions; 208e5c31af7Sopenharmony_ci 209e5c31af7Sopenharmony_ci TCU_CHECK(gl.getIntegerv && gl.getStringi); 210e5c31af7Sopenharmony_ci 211e5c31af7Sopenharmony_ci gl.getIntegerv(GL_NUM_EXTENSIONS, &numExtensions); 212e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_NUM_EXTENSIONS)"); 213e5c31af7Sopenharmony_ci 214e5c31af7Sopenharmony_ci if (numExtensions > 0) 215e5c31af7Sopenharmony_ci { 216e5c31af7Sopenharmony_ci extensions.resize(numExtensions); 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numExtensions; ndx++) 219e5c31af7Sopenharmony_ci { 220e5c31af7Sopenharmony_ci const char* const ext = (const char*)gl.getStringi(GL_EXTENSIONS, ndx); 221e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetStringi(GL_EXTENSIONS)"); 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_ci if (ext) 224e5c31af7Sopenharmony_ci extensions[ndx] = ext; 225e5c31af7Sopenharmony_ci else 226e5c31af7Sopenharmony_ci throw tcu::TestError("glGetStringi(GL_EXTENSIONS) returned null pointer", DE_NULL, __FILE__, __LINE__); 227e5c31af7Sopenharmony_ci } 228e5c31af7Sopenharmony_ci 229e5c31af7Sopenharmony_ci } 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_ci return extensions; 232e5c31af7Sopenharmony_ci } 233e5c31af7Sopenharmony_ci} 234e5c31af7Sopenharmony_ci 235e5c31af7Sopenharmony_cibool hasExtension (const glw::Functions& gl, ApiType apiType, const std::string& extension) 236e5c31af7Sopenharmony_ci{ 237e5c31af7Sopenharmony_ci std::vector<std::string> extensions(getExtensions(gl, apiType)); 238e5c31af7Sopenharmony_ci 239e5c31af7Sopenharmony_ci return de::contains(extensions.begin(), extensions.end(), extension); 240e5c31af7Sopenharmony_ci} 241e5c31af7Sopenharmony_ci 242e5c31af7Sopenharmony_civoid initCoreFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType) 243e5c31af7Sopenharmony_ci{ 244e5c31af7Sopenharmony_ci static const struct 245e5c31af7Sopenharmony_ci { 246e5c31af7Sopenharmony_ci ApiType apiType; 247e5c31af7Sopenharmony_ci void (*initFunc) (glw::Functions* gl, const glw::FunctionLoader* loader); 248e5c31af7Sopenharmony_ci } s_initFuncs[] = 249e5c31af7Sopenharmony_ci { 250e5c31af7Sopenharmony_ci { ApiType::es(2,0), glw::initES20 }, 251e5c31af7Sopenharmony_ci { ApiType::es(3,0), glw::initES30 }, 252e5c31af7Sopenharmony_ci { ApiType::es(3,1), glw::initES31 }, 253e5c31af7Sopenharmony_ci { ApiType::es(3,2), glw::initES32 }, 254e5c31af7Sopenharmony_ci { ApiType::core(3,0), glw::initGL30Core }, 255e5c31af7Sopenharmony_ci { ApiType::core(3,1), glw::initGL31Core }, 256e5c31af7Sopenharmony_ci { ApiType::core(3,2), glw::initGL32Core }, 257e5c31af7Sopenharmony_ci { ApiType::core(3,3), glw::initGL33Core }, 258e5c31af7Sopenharmony_ci { ApiType::core(4,0), glw::initGL40Core }, 259e5c31af7Sopenharmony_ci { ApiType::core(4,1), glw::initGL41Core }, 260e5c31af7Sopenharmony_ci { ApiType::core(4,2), glw::initGL42Core }, 261e5c31af7Sopenharmony_ci { ApiType::core(4,3), glw::initGL43Core }, 262e5c31af7Sopenharmony_ci { ApiType::core(4,4), glw::initGL44Core }, 263e5c31af7Sopenharmony_ci { ApiType::core(4,5), glw::initGL45Core }, 264e5c31af7Sopenharmony_ci { ApiType::core(4,6), glw::initGL46Core }, 265e5c31af7Sopenharmony_ci // TODO: initialise actual compat functions rather than using core as a dummy 266e5c31af7Sopenharmony_ci { ApiType::compatibility(3,2), glw::initGL32Core }, 267e5c31af7Sopenharmony_ci { ApiType::compatibility(3,3), glw::initGL33Core }, 268e5c31af7Sopenharmony_ci { ApiType::compatibility(4,0), glw::initGL40Core }, 269e5c31af7Sopenharmony_ci { ApiType::compatibility(4,1), glw::initGL41Core }, 270e5c31af7Sopenharmony_ci { ApiType::compatibility(4,2), glw::initGL42Core }, 271e5c31af7Sopenharmony_ci { ApiType::compatibility(4,3), glw::initGL43Core }, 272e5c31af7Sopenharmony_ci { ApiType::compatibility(4,4), glw::initGL44Core }, 273e5c31af7Sopenharmony_ci { ApiType::compatibility(4,5), glw::initGL45Core }, 274e5c31af7Sopenharmony_ci { ApiType::compatibility(4,6), glw::initGL46Core }, 275e5c31af7Sopenharmony_ci }; 276e5c31af7Sopenharmony_ci 277e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_initFuncs); ndx++) 278e5c31af7Sopenharmony_ci { 279e5c31af7Sopenharmony_ci if (s_initFuncs[ndx].apiType == apiType) 280e5c31af7Sopenharmony_ci { 281e5c31af7Sopenharmony_ci s_initFuncs[ndx].initFunc(dst, loader); 282e5c31af7Sopenharmony_ci return; 283e5c31af7Sopenharmony_ci } 284e5c31af7Sopenharmony_ci } 285e5c31af7Sopenharmony_ci 286e5c31af7Sopenharmony_ci throw tcu::InternalError(std::string("Don't know how to load functions for ") + de::toString(apiType)); 287e5c31af7Sopenharmony_ci} 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_civoid initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType) 290e5c31af7Sopenharmony_ci{ 291e5c31af7Sopenharmony_ci std::vector<std::string> extensions = getExtensions(*dst, apiType); 292e5c31af7Sopenharmony_ci 293e5c31af7Sopenharmony_ci if (!extensions.empty()) 294e5c31af7Sopenharmony_ci { 295e5c31af7Sopenharmony_ci std::vector<const char*> extStr(extensions.size()); 296e5c31af7Sopenharmony_ci 297e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < extensions.size(); ndx++) 298e5c31af7Sopenharmony_ci extStr[ndx] = extensions[ndx].c_str(); 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_ci initExtensionFunctions(dst, loader, apiType, (int)extStr.size(), &extStr[0]); 301e5c31af7Sopenharmony_ci } 302e5c31af7Sopenharmony_ci} 303e5c31af7Sopenharmony_ci 304e5c31af7Sopenharmony_civoid initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType, int numExtensions, const char* const* extensions) 305e5c31af7Sopenharmony_ci{ 306e5c31af7Sopenharmony_ci if (apiType.getProfile() == PROFILE_ES) 307e5c31af7Sopenharmony_ci glw::initExtensionsES(dst, loader, numExtensions, extensions); 308e5c31af7Sopenharmony_ci else 309e5c31af7Sopenharmony_ci glw::initExtensionsGL(dst, loader, numExtensions, extensions); 310e5c31af7Sopenharmony_ci} 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_civoid initFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType) 313e5c31af7Sopenharmony_ci{ 314e5c31af7Sopenharmony_ci initCoreFunctions(dst, loader, apiType); 315e5c31af7Sopenharmony_ci initExtensionFunctions(dst, loader, apiType); 316e5c31af7Sopenharmony_ci} 317e5c31af7Sopenharmony_ci 318e5c31af7Sopenharmony_ciconst char* getApiTypeDescription (ApiType type) 319e5c31af7Sopenharmony_ci{ 320e5c31af7Sopenharmony_ci if (type == glu::ApiType::es(2, 0)) return "OpenGL ES 2"; 321e5c31af7Sopenharmony_ci else if (type == glu::ApiType::es(3, 0)) return "OpenGL ES 3"; 322e5c31af7Sopenharmony_ci else if (type == glu::ApiType::es(3, 1)) return "OpenGL ES 3.1"; 323e5c31af7Sopenharmony_ci else if (type == glu::ApiType::es(3, 2)) return "OpenGL ES 3.2"; 324e5c31af7Sopenharmony_ci else if (type == glu::ApiType::core(3, 0)) return "OpenGL 3.0 core"; 325e5c31af7Sopenharmony_ci else if (type == glu::ApiType::core(3, 1)) return "OpenGL 3.1 core"; 326e5c31af7Sopenharmony_ci else if (type == glu::ApiType::core(3, 2)) return "OpenGL 3.2 core"; 327e5c31af7Sopenharmony_ci else if (type == glu::ApiType::core(3, 3)) return "OpenGL 3.3 core"; 328e5c31af7Sopenharmony_ci else if (type == glu::ApiType::core(4, 0)) return "OpenGL 4.0 core"; 329e5c31af7Sopenharmony_ci else if (type == glu::ApiType::core(4, 1)) return "OpenGL 4.1 core"; 330e5c31af7Sopenharmony_ci else if (type == glu::ApiType::core(4, 2)) return "OpenGL 4.2 core"; 331e5c31af7Sopenharmony_ci else if (type == glu::ApiType::core(4, 3)) return "OpenGL 4.3 core"; 332e5c31af7Sopenharmony_ci else if (type == glu::ApiType::core(4, 4)) return "OpenGL 4.4 core"; 333e5c31af7Sopenharmony_ci else if (type == glu::ApiType::core(4, 5)) return "OpenGL 4.5 core"; 334e5c31af7Sopenharmony_ci else if (type == glu::ApiType::core(4, 6)) return "OpenGL 4.6 core"; 335e5c31af7Sopenharmony_ci else if (type == glu::ApiType::compatibility(3, 2)) return "OpenGL 3.2 compatibility"; 336e5c31af7Sopenharmony_ci else if (type == glu::ApiType::compatibility(3, 3)) return "OpenGL 3.3 compatibility"; 337e5c31af7Sopenharmony_ci else if (type == glu::ApiType::compatibility(4, 0)) return "OpenGL 4.0 compatibility"; 338e5c31af7Sopenharmony_ci else if (type == glu::ApiType::compatibility(4, 1)) return "OpenGL 4.1 compatibility"; 339e5c31af7Sopenharmony_ci else if (type == glu::ApiType::compatibility(4, 2)) return "OpenGL 4.2 compatibility"; 340e5c31af7Sopenharmony_ci else if (type == glu::ApiType::compatibility(4, 3)) return "OpenGL 4.3 compatibility"; 341e5c31af7Sopenharmony_ci else if (type == glu::ApiType::compatibility(4, 4)) return "OpenGL 4.4 compatibility"; 342e5c31af7Sopenharmony_ci else if (type == glu::ApiType::compatibility(4, 5)) return "OpenGL 4.5 compatibility"; 343e5c31af7Sopenharmony_ci else if (type == glu::ApiType::compatibility(4, 6)) return "OpenGL 4.6 compatibility"; 344e5c31af7Sopenharmony_ci else return DE_NULL; 345e5c31af7Sopenharmony_ci} 346e5c31af7Sopenharmony_ci 347e5c31af7Sopenharmony_ci} // glu 348