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 Context Info Class. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp" 25e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp" 26e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 27e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 28e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 29e5c31af7Sopenharmony_ci 30e5c31af7Sopenharmony_ci#include <iterator> 31e5c31af7Sopenharmony_ci#include <algorithm> 32e5c31af7Sopenharmony_ci 33e5c31af7Sopenharmony_ciusing std::vector; 34e5c31af7Sopenharmony_ciusing std::string; 35e5c31af7Sopenharmony_ciusing std::set; 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_cinamespace glu 38e5c31af7Sopenharmony_ci{ 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ciclass TryCompileProgram 41e5c31af7Sopenharmony_ci{ 42e5c31af7Sopenharmony_cipublic: 43e5c31af7Sopenharmony_ci // \note Assumes that shader pointer can be stored as is (eg. it is static data) 44e5c31af7Sopenharmony_ci TryCompileProgram (const char* vertexSource, const char* fragmentSource) 45e5c31af7Sopenharmony_ci : m_vertexSource (vertexSource) 46e5c31af7Sopenharmony_ci , m_fragmentSource (fragmentSource) 47e5c31af7Sopenharmony_ci { 48e5c31af7Sopenharmony_ci } 49e5c31af7Sopenharmony_ci 50e5c31af7Sopenharmony_ci bool operator() (const RenderContext& context) const 51e5c31af7Sopenharmony_ci { 52e5c31af7Sopenharmony_ci ShaderProgram program(context, 53e5c31af7Sopenharmony_ci ProgramSources() << VertexSource(m_vertexSource) 54e5c31af7Sopenharmony_ci << FragmentSource(m_fragmentSource)); 55e5c31af7Sopenharmony_ci return program.isOk(); 56e5c31af7Sopenharmony_ci } 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_ciprivate: 59e5c31af7Sopenharmony_ci const char* m_vertexSource; 60e5c31af7Sopenharmony_ci const char* m_fragmentSource; 61e5c31af7Sopenharmony_ci}; 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_citypedef CachedValue<bool, TryCompileProgram> IsProgramSupported; 64e5c31af7Sopenharmony_ci 65e5c31af7Sopenharmony_cibool IsES3Compatible(const glw::Functions& gl) 66e5c31af7Sopenharmony_ci{ 67e5c31af7Sopenharmony_ci // Detect compatible GLES context by querying GL_MAJOR_VERSION. 68e5c31af7Sopenharmony_ci // This query does not exist on GLES2 so succeeding query implies GLES3+ context. 69e5c31af7Sopenharmony_ci glw::GLint majorVersion = 0; 70e5c31af7Sopenharmony_ci gl.getError(); 71e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAJOR_VERSION, &majorVersion); 72e5c31af7Sopenharmony_ci 73e5c31af7Sopenharmony_ci return (gl.getError() == GL_NO_ERROR); 74e5c31af7Sopenharmony_ci} 75e5c31af7Sopenharmony_ci 76e5c31af7Sopenharmony_ci// ES2-specific context info 77e5c31af7Sopenharmony_ciclass ES2ContextInfo : public ContextInfo 78e5c31af7Sopenharmony_ci{ 79e5c31af7Sopenharmony_cipublic: 80e5c31af7Sopenharmony_ci ES2ContextInfo (const RenderContext& context); 81e5c31af7Sopenharmony_ci ~ES2ContextInfo (void) {} 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_ci bool isVertexUniformLoopSupported (void) const { return m_vertexUniformLoopsSupported.getValue(m_context); } 84e5c31af7Sopenharmony_ci bool isVertexDynamicLoopSupported (void) const { return m_vertexDynamicLoopsSupported.getValue(m_context); } 85e5c31af7Sopenharmony_ci bool isFragmentHighPrecisionSupported (void) const { return m_fragmentHighPrecisionSupported.getValue(m_context); } 86e5c31af7Sopenharmony_ci bool isFragmentUniformLoopSupported (void) const { return m_fragmentUniformLoopsSupported.getValue(m_context); } 87e5c31af7Sopenharmony_ci bool isFragmentDynamicLoopSupported (void) const { return m_fragmentDynamicLoopsSupported.getValue(m_context); } 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_ciprivate: 90e5c31af7Sopenharmony_ci IsProgramSupported m_vertexUniformLoopsSupported; 91e5c31af7Sopenharmony_ci IsProgramSupported m_vertexDynamicLoopsSupported; 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_ci IsProgramSupported m_fragmentHighPrecisionSupported; 94e5c31af7Sopenharmony_ci IsProgramSupported m_fragmentUniformLoopsSupported; 95e5c31af7Sopenharmony_ci IsProgramSupported m_fragmentDynamicLoopsSupported; 96e5c31af7Sopenharmony_ci}; 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_cistatic const char* s_defaultVertexShader = 99e5c31af7Sopenharmony_ci "attribute highp vec4 a_position;\n" 100e5c31af7Sopenharmony_ci "void main (void) {\n" 101e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 102e5c31af7Sopenharmony_ci "}\n"; 103e5c31af7Sopenharmony_cistatic const char* s_defaultFragmentShader = 104e5c31af7Sopenharmony_ci "void main (void) {\n" 105e5c31af7Sopenharmony_ci " gl_FragColor = vec4(1.0);\n" 106e5c31af7Sopenharmony_ci "}\n"; 107e5c31af7Sopenharmony_ci 108e5c31af7Sopenharmony_cistatic const char* s_vertexUniformLoopsSupported = 109e5c31af7Sopenharmony_ci "attribute highp vec4 a_position;\n" 110e5c31af7Sopenharmony_ci "uniform int u_numIters;\n" 111e5c31af7Sopenharmony_ci "void main (void) {\n" 112e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 113e5c31af7Sopenharmony_ci " for (int i = 0; i < u_numIters; i++)\n" 114e5c31af7Sopenharmony_ci " gl_Position += vec4(0.1);\n" 115e5c31af7Sopenharmony_ci "}\n"; 116e5c31af7Sopenharmony_cistatic const char* s_vertexDynamicLoopsSupported = 117e5c31af7Sopenharmony_ci "attribute highp vec4 a_position;\n" 118e5c31af7Sopenharmony_ci "uniform mediump float a, b;\n" 119e5c31af7Sopenharmony_ci "void main (void) {\n" 120e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 121e5c31af7Sopenharmony_ci " int numIters = a < b ? int(3.0*b) : int(a_position.x);\n" 122e5c31af7Sopenharmony_ci " for (int i = 0; i < numIters; i++)\n" 123e5c31af7Sopenharmony_ci " gl_Position += vec4(0.1);\n" 124e5c31af7Sopenharmony_ci "}\n"; 125e5c31af7Sopenharmony_ci 126e5c31af7Sopenharmony_cistatic const char* s_fragmentHighPrecisionSupported = 127e5c31af7Sopenharmony_ci "varying highp vec4 v_color;\n" 128e5c31af7Sopenharmony_ci "void main (void) {\n" 129e5c31af7Sopenharmony_ci " highp float tmp = v_color.r;\n" 130e5c31af7Sopenharmony_ci " gl_FragColor = v_color;\n" 131e5c31af7Sopenharmony_ci "}\n"; 132e5c31af7Sopenharmony_cistatic const char* s_fragmentUniformLoopsSupported = 133e5c31af7Sopenharmony_ci "varying mediump vec4 v_color;\n" 134e5c31af7Sopenharmony_ci "uniform int u_numIters;\n" 135e5c31af7Sopenharmony_ci "void main (void) {\n" 136e5c31af7Sopenharmony_ci " gl_FragColor = v_color;\n" 137e5c31af7Sopenharmony_ci " for (int i = 0; i < u_numIters; i++)\n" 138e5c31af7Sopenharmony_ci " gl_FragColor += vec4(0.1);\n" 139e5c31af7Sopenharmony_ci "}\n"; 140e5c31af7Sopenharmony_cistatic const char* s_fragmentDynamicLoopsSupported = 141e5c31af7Sopenharmony_ci "varying mediump vec4 v_color;\n" 142e5c31af7Sopenharmony_ci "uniform mediump float a, b;\n" 143e5c31af7Sopenharmony_ci "void main (void) {\n" 144e5c31af7Sopenharmony_ci " gl_FragColor = v_color;\n" 145e5c31af7Sopenharmony_ci " int numIters = a < b ? int(3.0*b) : int(v_color.x);\n" 146e5c31af7Sopenharmony_ci " for (int i = 0; i < numIters; i++)\n" 147e5c31af7Sopenharmony_ci " gl_FragColor += vec4(0.1);\n" 148e5c31af7Sopenharmony_ci "}\n"; 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_ciES2ContextInfo::ES2ContextInfo (const RenderContext& context) 151e5c31af7Sopenharmony_ci : glu::ContextInfo (context) 152e5c31af7Sopenharmony_ci , m_vertexUniformLoopsSupported (TryCompileProgram(s_vertexUniformLoopsSupported, s_defaultFragmentShader)) 153e5c31af7Sopenharmony_ci , m_vertexDynamicLoopsSupported (TryCompileProgram(s_vertexDynamicLoopsSupported, s_defaultFragmentShader)) 154e5c31af7Sopenharmony_ci , m_fragmentHighPrecisionSupported (TryCompileProgram(s_defaultVertexShader, s_fragmentHighPrecisionSupported)) 155e5c31af7Sopenharmony_ci , m_fragmentUniformLoopsSupported (TryCompileProgram(s_defaultVertexShader, s_fragmentUniformLoopsSupported)) 156e5c31af7Sopenharmony_ci , m_fragmentDynamicLoopsSupported (TryCompileProgram(s_defaultVertexShader, s_fragmentDynamicLoopsSupported)) 157e5c31af7Sopenharmony_ci{ 158e5c31af7Sopenharmony_ci} 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_cistatic void split (vector<string>& dst, const string& src) 161e5c31af7Sopenharmony_ci{ 162e5c31af7Sopenharmony_ci size_t start = 0; 163e5c31af7Sopenharmony_ci size_t end = string::npos; 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci while ((end = src.find(' ', start)) != string::npos) 166e5c31af7Sopenharmony_ci { 167e5c31af7Sopenharmony_ci dst.push_back(src.substr(start, end-start)); 168e5c31af7Sopenharmony_ci start = end+1; 169e5c31af7Sopenharmony_ci } 170e5c31af7Sopenharmony_ci 171e5c31af7Sopenharmony_ci if (start < end) 172e5c31af7Sopenharmony_ci dst.push_back(src.substr(start, end-start)); 173e5c31af7Sopenharmony_ci} 174e5c31af7Sopenharmony_ci 175e5c31af7Sopenharmony_ciset<int> GetCompressedTextureFormats::operator() (const RenderContext& context) const 176e5c31af7Sopenharmony_ci{ 177e5c31af7Sopenharmony_ci const glw::Functions& gl = context.getFunctions(); 178e5c31af7Sopenharmony_ci 179e5c31af7Sopenharmony_ci int numFormats = 0; 180e5c31af7Sopenharmony_ci gl.getIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats); 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ci vector<int> formats(numFormats); 183e5c31af7Sopenharmony_ci if (numFormats > 0) 184e5c31af7Sopenharmony_ci gl.getIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, &formats[0]); 185e5c31af7Sopenharmony_ci 186e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS) failed"); 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ci set<int> formatSet; 189e5c31af7Sopenharmony_ci std::copy(formats.begin(), formats.end(), std::inserter(formatSet, formatSet.begin())); 190e5c31af7Sopenharmony_ci 191e5c31af7Sopenharmony_ci return formatSet; 192e5c31af7Sopenharmony_ci} 193e5c31af7Sopenharmony_ci 194e5c31af7Sopenharmony_ci// ContextInfo 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ciContextInfo::ContextInfo (const RenderContext& context) 197e5c31af7Sopenharmony_ci : m_context(context) 198e5c31af7Sopenharmony_ci{ 199e5c31af7Sopenharmony_ci const glw::Functions& gl = context.getFunctions(); 200e5c31af7Sopenharmony_ci 201e5c31af7Sopenharmony_ci if (context.getType().getAPI() == ApiType::es(2,0)) 202e5c31af7Sopenharmony_ci { 203e5c31af7Sopenharmony_ci const char* result = (const char*)gl.getString(GL_EXTENSIONS); 204e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetString(GL_EXTENSIONS) failed"); 205e5c31af7Sopenharmony_ci 206e5c31af7Sopenharmony_ci split(m_extensions, string(result)); 207e5c31af7Sopenharmony_ci } 208e5c31af7Sopenharmony_ci else 209e5c31af7Sopenharmony_ci { 210e5c31af7Sopenharmony_ci int numExtensions = 0; 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_ci gl.getIntegerv(GL_NUM_EXTENSIONS, &numExtensions); 213e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_NUM_EXTENSIONS) failed"); 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_ci m_extensions.resize(numExtensions); 216e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numExtensions; ndx++) 217e5c31af7Sopenharmony_ci m_extensions[ndx] = (const char*)gl.getStringi(GL_EXTENSIONS, ndx); 218e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetStringi(GL_EXTENSIONS, ndx) failed"); 219e5c31af7Sopenharmony_ci } 220e5c31af7Sopenharmony_ci} 221e5c31af7Sopenharmony_ci 222e5c31af7Sopenharmony_ciContextInfo::~ContextInfo (void) 223e5c31af7Sopenharmony_ci{ 224e5c31af7Sopenharmony_ci} 225e5c31af7Sopenharmony_ci 226e5c31af7Sopenharmony_ciint ContextInfo::getInt (int param) const 227e5c31af7Sopenharmony_ci{ 228e5c31af7Sopenharmony_ci int val = -1; 229e5c31af7Sopenharmony_ci m_context.getFunctions().getIntegerv(param, &val); 230e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_context.getFunctions().getError(), "glGetIntegerv() failed"); 231e5c31af7Sopenharmony_ci return val; 232e5c31af7Sopenharmony_ci} 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_cibool ContextInfo::getBool (int param) const 235e5c31af7Sopenharmony_ci{ 236e5c31af7Sopenharmony_ci glw::GLboolean val = GL_FALSE; 237e5c31af7Sopenharmony_ci m_context.getFunctions().getBooleanv(param, &val); 238e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_context.getFunctions().getError(), "glGetBooleanv() failed"); 239e5c31af7Sopenharmony_ci return val != GL_FALSE; 240e5c31af7Sopenharmony_ci} 241e5c31af7Sopenharmony_ci 242e5c31af7Sopenharmony_ciconst char* ContextInfo::getString (int param) const 243e5c31af7Sopenharmony_ci{ 244e5c31af7Sopenharmony_ci const char* str = (const char*)m_context.getFunctions().getString(param); 245e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_context.getFunctions().getError(), "glGetString() failed"); 246e5c31af7Sopenharmony_ci return str; 247e5c31af7Sopenharmony_ci} 248e5c31af7Sopenharmony_ci 249e5c31af7Sopenharmony_cibool ContextInfo::isCompressedTextureFormatSupported (int format) const 250e5c31af7Sopenharmony_ci{ 251e5c31af7Sopenharmony_ci const set<int>& formats = m_compressedTextureFormats.getValue(m_context); 252e5c31af7Sopenharmony_ci return formats.find(format) != formats.end(); 253e5c31af7Sopenharmony_ci} 254e5c31af7Sopenharmony_ci 255e5c31af7Sopenharmony_cibool ContextInfo::isExtensionSupported (const char* name) const 256e5c31af7Sopenharmony_ci{ 257e5c31af7Sopenharmony_ci const std::vector<std::string>& extensions = getExtensions(); 258e5c31af7Sopenharmony_ci return std::find(extensions.begin(), extensions.end(), name) != extensions.end(); 259e5c31af7Sopenharmony_ci} 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_cibool ContextInfo::isES3Compatible() const 262e5c31af7Sopenharmony_ci{ 263e5c31af7Sopenharmony_ci return IsES3Compatible(m_context.getFunctions()); 264e5c31af7Sopenharmony_ci} 265e5c31af7Sopenharmony_ci 266e5c31af7Sopenharmony_ciContextInfo* ContextInfo::create (const RenderContext& context) 267e5c31af7Sopenharmony_ci{ 268e5c31af7Sopenharmony_ci // ES2 uses special variant that checks support for various shader features 269e5c31af7Sopenharmony_ci // by trying to compile shader programs. 270e5c31af7Sopenharmony_ci if (context.getType().getAPI() == ApiType::es(2,0)) 271e5c31af7Sopenharmony_ci return new ES2ContextInfo(context); 272e5c31af7Sopenharmony_ci 273e5c31af7Sopenharmony_ci return new ContextInfo(context); 274e5c31af7Sopenharmony_ci} 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_ci} // glu 277