File indexing completed on 2025-03-23 11:13:58
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2006-2007 Rivo Laks <rivolaks@hot.ee> 0006 SPDX-FileCopyrightText: 2010, 2011 Martin Gräßlin <mgraesslin@kde.org> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "kwinglutils.h" 0012 0013 // need to call GLTexturePrivate::initStatic() 0014 #include "kwingltexture_p.h" 0015 0016 #include "kwineffects.h" 0017 #include "kwinglplatform.h" 0018 #include "logging_p.h" 0019 0020 #include <QFile> 0021 #include <QHash> 0022 #include <QImage> 0023 #include <QMatrix4x4> 0024 #include <QPixmap> 0025 #include <QVarLengthArray> 0026 #include <QVector2D> 0027 #include <QVector3D> 0028 #include <QVector4D> 0029 0030 #include <array> 0031 #include <cmath> 0032 #include <deque> 0033 0034 #define DEBUG_GLFRAMEBUFFER 0 0035 0036 #ifdef __GNUC__ 0037 #define likely(x) __builtin_expect(!!(x), 1) 0038 #define unlikely(x) __builtin_expect(!!(x), 0) 0039 #else 0040 #define likely(x) (x) 0041 #define unlikely(x) (x) 0042 #endif 0043 0044 namespace KWin 0045 { 0046 // Variables 0047 // List of all supported GL extensions 0048 static QList<QByteArray> glExtensions; 0049 0050 // Functions 0051 0052 static void initDebugOutput() 0053 { 0054 static bool enabled = qEnvironmentVariableIntValue("KWIN_GL_DEBUG"); 0055 if (!enabled) { 0056 return; 0057 } 0058 0059 const bool have_KHR_debug = hasGLExtension(QByteArrayLiteral("GL_KHR_debug")); 0060 const bool have_ARB_debug = hasGLExtension(QByteArrayLiteral("GL_ARB_debug_output")); 0061 if (!have_KHR_debug && !have_ARB_debug) { 0062 return; 0063 } 0064 0065 if (!have_ARB_debug) { 0066 // if we don't have ARB debug, but only KHR debug we need to verify whether the context is a debug context 0067 // it should work without as well, but empirical tests show: no it doesn't 0068 if (GLPlatform::instance()->isGLES()) { 0069 if (!hasGLVersion(3, 2)) { 0070 // empirical data shows extension doesn't work 0071 return; 0072 } 0073 } else if (!hasGLVersion(3, 0)) { 0074 return; 0075 } 0076 // can only be queried with either OpenGL >= 3.0 or OpenGL ES of at least 3.1 0077 GLint value = 0; 0078 glGetIntegerv(GL_CONTEXT_FLAGS, &value); 0079 if (!(value & GL_CONTEXT_FLAG_DEBUG_BIT)) { 0080 return; 0081 } 0082 } 0083 0084 // Set the callback function 0085 auto callback = [](GLenum source, GLenum type, GLuint id, 0086 GLenum severity, GLsizei length, 0087 const GLchar *message, 0088 const GLvoid *userParam) { 0089 while (length && std::isspace(message[length - 1])) { 0090 --length; 0091 } 0092 0093 switch (type) { 0094 case GL_DEBUG_TYPE_ERROR: 0095 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: 0096 qCWarning(LIBKWINGLUTILS, "%#x: %.*s", id, length, message); 0097 break; 0098 0099 case GL_DEBUG_TYPE_OTHER: 0100 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: 0101 case GL_DEBUG_TYPE_PORTABILITY: 0102 case GL_DEBUG_TYPE_PERFORMANCE: 0103 default: 0104 qCDebug(LIBKWINGLUTILS, "%#x: %.*s", id, length, message); 0105 break; 0106 } 0107 }; 0108 0109 glDebugMessageCallback(callback, nullptr); 0110 0111 // This state exists only in GL_KHR_debug 0112 if (have_KHR_debug) { 0113 glEnable(GL_DEBUG_OUTPUT); 0114 } 0115 0116 #if !defined(QT_NO_DEBUG) 0117 // Enable all debug messages 0118 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); 0119 #else 0120 // Enable error messages 0121 glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, nullptr, GL_TRUE); 0122 glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, GL_DONT_CARE, 0, nullptr, GL_TRUE); 0123 #endif 0124 0125 // Insert a test message 0126 const QByteArray message = QByteArrayLiteral("OpenGL debug output initialized"); 0127 glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, 0128 GL_DEBUG_SEVERITY_LOW, message.length(), message.constData()); 0129 } 0130 0131 void initGL(const std::function<resolveFuncPtr(const char *)> &resolveFunction) 0132 { 0133 // Get list of supported OpenGL extensions 0134 if (hasGLVersion(3, 0)) { 0135 int count; 0136 glGetIntegerv(GL_NUM_EXTENSIONS, &count); 0137 0138 for (int i = 0; i < count; i++) { 0139 const QByteArray name = (const char *)glGetStringi(GL_EXTENSIONS, i); 0140 glExtensions << name; 0141 } 0142 } else { 0143 glExtensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' '); 0144 } 0145 0146 // handle OpenGL extensions functions 0147 glResolveFunctions(resolveFunction); 0148 0149 initDebugOutput(); 0150 0151 GLTexturePrivate::initStatic(); 0152 GLFramebuffer::initStatic(); 0153 GLVertexBuffer::initStatic(); 0154 } 0155 0156 void cleanupGL() 0157 { 0158 ShaderManager::cleanup(); 0159 GLTexturePrivate::cleanup(); 0160 GLFramebuffer::cleanup(); 0161 GLVertexBuffer::cleanup(); 0162 GLPlatform::cleanup(); 0163 0164 glExtensions.clear(); 0165 } 0166 0167 bool hasGLVersion(int major, int minor, int release) 0168 { 0169 return GLPlatform::instance()->glVersion() >= kVersionNumber(major, minor, release); 0170 } 0171 0172 bool hasGLExtension(const QByteArray &extension) 0173 { 0174 return glExtensions.contains(extension); 0175 } 0176 0177 QList<QByteArray> openGLExtensions() 0178 { 0179 return glExtensions; 0180 } 0181 0182 static QString formatGLError(GLenum err) 0183 { 0184 switch (err) { 0185 case GL_NO_ERROR: 0186 return QStringLiteral("GL_NO_ERROR"); 0187 case GL_INVALID_ENUM: 0188 return QStringLiteral("GL_INVALID_ENUM"); 0189 case GL_INVALID_VALUE: 0190 return QStringLiteral("GL_INVALID_VALUE"); 0191 case GL_INVALID_OPERATION: 0192 return QStringLiteral("GL_INVALID_OPERATION"); 0193 case GL_STACK_OVERFLOW: 0194 return QStringLiteral("GL_STACK_OVERFLOW"); 0195 case GL_STACK_UNDERFLOW: 0196 return QStringLiteral("GL_STACK_UNDERFLOW"); 0197 case GL_OUT_OF_MEMORY: 0198 return QStringLiteral("GL_OUT_OF_MEMORY"); 0199 default: 0200 return QLatin1String("0x") + QString::number(err, 16); 0201 } 0202 } 0203 0204 bool checkGLError(const char *txt) 0205 { 0206 GLenum err = glGetError(); 0207 if (err == GL_CONTEXT_LOST) { 0208 qCWarning(LIBKWINGLUTILS) << "GL error: context lost"; 0209 return true; 0210 } 0211 bool hasError = false; 0212 while (err != GL_NO_ERROR) { 0213 qCWarning(LIBKWINGLUTILS) << "GL error (" << txt << "): " << formatGLError(err); 0214 hasError = true; 0215 err = glGetError(); 0216 if (err == GL_CONTEXT_LOST) { 0217 qCWarning(LIBKWINGLUTILS) << "GL error: context lost"; 0218 break; 0219 } 0220 } 0221 return hasError; 0222 } 0223 0224 //**************************************** 0225 // GLShader 0226 //**************************************** 0227 0228 GLShader::GLShader(unsigned int flags) 0229 : mValid(false) 0230 , mLocationsResolved(false) 0231 , mExplicitLinking(flags & ExplicitLinking) 0232 { 0233 mProgram = glCreateProgram(); 0234 } 0235 0236 GLShader::GLShader(const QString &vertexfile, const QString &fragmentfile, unsigned int flags) 0237 : mValid(false) 0238 , mLocationsResolved(false) 0239 , mExplicitLinking(flags & ExplicitLinking) 0240 { 0241 mProgram = glCreateProgram(); 0242 loadFromFiles(vertexfile, fragmentfile); 0243 } 0244 0245 GLShader::~GLShader() 0246 { 0247 if (mProgram) { 0248 glDeleteProgram(mProgram); 0249 } 0250 } 0251 0252 bool GLShader::loadFromFiles(const QString &vertexFile, const QString &fragmentFile) 0253 { 0254 QFile vf(vertexFile); 0255 if (!vf.open(QIODevice::ReadOnly)) { 0256 qCCritical(LIBKWINGLUTILS) << "Couldn't open" << vertexFile << "for reading!"; 0257 return false; 0258 } 0259 const QByteArray vertexSource = vf.readAll(); 0260 0261 QFile ff(fragmentFile); 0262 if (!ff.open(QIODevice::ReadOnly)) { 0263 qCCritical(LIBKWINGLUTILS) << "Couldn't open" << fragmentFile << "for reading!"; 0264 return false; 0265 } 0266 const QByteArray fragmentSource = ff.readAll(); 0267 0268 return load(vertexSource, fragmentSource); 0269 } 0270 0271 bool GLShader::link() 0272 { 0273 // Be optimistic 0274 mValid = true; 0275 0276 glLinkProgram(mProgram); 0277 0278 // Get the program info log 0279 int maxLength, length; 0280 glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &maxLength); 0281 0282 QByteArray log(maxLength, 0); 0283 glGetProgramInfoLog(mProgram, maxLength, &length, log.data()); 0284 0285 // Make sure the program linked successfully 0286 int status; 0287 glGetProgramiv(mProgram, GL_LINK_STATUS, &status); 0288 0289 if (status == 0) { 0290 qCCritical(LIBKWINGLUTILS) << "Failed to link shader:" 0291 << "\n" 0292 << log; 0293 mValid = false; 0294 } else if (length > 0) { 0295 qCDebug(LIBKWINGLUTILS) << "Shader link log:" << log; 0296 } 0297 0298 return mValid; 0299 } 0300 0301 const QByteArray GLShader::prepareSource(GLenum shaderType, const QByteArray &source) const 0302 { 0303 // Prepare the source code 0304 QByteArray ba; 0305 if (GLPlatform::instance()->isGLES() && GLPlatform::instance()->glslVersion() < kVersionNumber(3, 0)) { 0306 ba.append("precision highp float;\n"); 0307 } 0308 ba.append(source); 0309 if (GLPlatform::instance()->isGLES() && GLPlatform::instance()->glslVersion() >= kVersionNumber(3, 0)) { 0310 ba.replace("#version 140", "#version 300 es\n\nprecision highp float;\n"); 0311 } 0312 0313 return ba; 0314 } 0315 0316 bool GLShader::compile(GLuint program, GLenum shaderType, const QByteArray &source) const 0317 { 0318 GLuint shader = glCreateShader(shaderType); 0319 0320 QByteArray preparedSource = prepareSource(shaderType, source); 0321 const char *src = preparedSource.constData(); 0322 glShaderSource(shader, 1, &src, nullptr); 0323 0324 // Compile the shader 0325 glCompileShader(shader); 0326 0327 // Get the shader info log 0328 int maxLength, length; 0329 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength); 0330 0331 QByteArray log(maxLength, 0); 0332 glGetShaderInfoLog(shader, maxLength, &length, log.data()); 0333 0334 // Check the status 0335 int status; 0336 glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 0337 0338 if (status == 0) { 0339 const char *typeName = (shaderType == GL_VERTEX_SHADER ? "vertex" : "fragment"); 0340 qCCritical(LIBKWINGLUTILS) << "Failed to compile" << typeName << "shader:" 0341 << "\n" 0342 << log; 0343 } else if (length > 0) { 0344 qCDebug(LIBKWINGLUTILS) << "Shader compile log:" << log; 0345 } 0346 0347 if (status != 0) { 0348 glAttachShader(program, shader); 0349 } 0350 0351 glDeleteShader(shader); 0352 return status != 0; 0353 } 0354 0355 bool GLShader::load(const QByteArray &vertexSource, const QByteArray &fragmentSource) 0356 { 0357 // Make sure shaders are actually supported 0358 if (!(GLPlatform::instance()->supports(GLSL) && 0359 // we lack shader branching for Texture2DRectangle everywhere - and it's probably not worth it 0360 GLPlatform::instance()->supports(TextureNPOT))) { 0361 qCCritical(LIBKWINGLUTILS) << "Shaders are not supported"; 0362 return false; 0363 } 0364 0365 mValid = false; 0366 0367 // Compile the vertex shader 0368 if (!vertexSource.isEmpty()) { 0369 bool success = compile(mProgram, GL_VERTEX_SHADER, vertexSource); 0370 0371 if (!success) { 0372 return false; 0373 } 0374 } 0375 0376 // Compile the fragment shader 0377 if (!fragmentSource.isEmpty()) { 0378 bool success = compile(mProgram, GL_FRAGMENT_SHADER, fragmentSource); 0379 0380 if (!success) { 0381 return false; 0382 } 0383 } 0384 0385 if (mExplicitLinking) { 0386 return true; 0387 } 0388 0389 // link() sets mValid 0390 return link(); 0391 } 0392 0393 void GLShader::bindAttributeLocation(const char *name, int index) 0394 { 0395 glBindAttribLocation(mProgram, index, name); 0396 } 0397 0398 void GLShader::bindFragDataLocation(const char *name, int index) 0399 { 0400 if (!GLPlatform::instance()->isGLES() && (hasGLVersion(3, 0) || hasGLExtension(QByteArrayLiteral("GL_EXT_gpu_shader4")))) { 0401 glBindFragDataLocation(mProgram, index, name); 0402 } 0403 } 0404 0405 void GLShader::bind() 0406 { 0407 glUseProgram(mProgram); 0408 } 0409 0410 void GLShader::unbind() 0411 { 0412 glUseProgram(0); 0413 } 0414 0415 void GLShader::resolveLocations() 0416 { 0417 if (mLocationsResolved) { 0418 return; 0419 } 0420 0421 mMatrixLocation[TextureMatrix] = uniformLocation("textureMatrix"); 0422 mMatrixLocation[ProjectionMatrix] = uniformLocation("projection"); 0423 mMatrixLocation[ModelViewMatrix] = uniformLocation("modelview"); 0424 mMatrixLocation[ModelViewProjectionMatrix] = uniformLocation("modelViewProjectionMatrix"); 0425 mMatrixLocation[WindowTransformation] = uniformLocation("windowTransformation"); 0426 mMatrixLocation[ScreenTransformation] = uniformLocation("screenTransformation"); 0427 0428 mVec2Location[Offset] = uniformLocation("offset"); 0429 0430 mVec4Location[ModulationConstant] = uniformLocation("modulation"); 0431 0432 mFloatLocation[Saturation] = uniformLocation("saturation"); 0433 0434 mColorLocation[Color] = uniformLocation("geometryColor"); 0435 0436 mIntLocation[TextureWidth] = uniformLocation("textureWidth"); 0437 mIntLocation[TextureHeight] = uniformLocation("textureHeight"); 0438 0439 mLocationsResolved = true; 0440 } 0441 0442 int GLShader::uniformLocation(const char *name) 0443 { 0444 const int location = glGetUniformLocation(mProgram, name); 0445 return location; 0446 } 0447 0448 bool GLShader::setUniform(GLShader::MatrixUniform uniform, const QMatrix4x4 &matrix) 0449 { 0450 resolveLocations(); 0451 return setUniform(mMatrixLocation[uniform], matrix); 0452 } 0453 0454 bool GLShader::setUniform(GLShader::Vec2Uniform uniform, const QVector2D &value) 0455 { 0456 resolveLocations(); 0457 return setUniform(mVec2Location[uniform], value); 0458 } 0459 0460 bool GLShader::setUniform(GLShader::Vec4Uniform uniform, const QVector4D &value) 0461 { 0462 resolveLocations(); 0463 return setUniform(mVec4Location[uniform], value); 0464 } 0465 0466 bool GLShader::setUniform(GLShader::FloatUniform uniform, float value) 0467 { 0468 resolveLocations(); 0469 return setUniform(mFloatLocation[uniform], value); 0470 } 0471 0472 bool GLShader::setUniform(GLShader::IntUniform uniform, int value) 0473 { 0474 resolveLocations(); 0475 return setUniform(mIntLocation[uniform], value); 0476 } 0477 0478 bool GLShader::setUniform(GLShader::ColorUniform uniform, const QVector4D &value) 0479 { 0480 resolveLocations(); 0481 return setUniform(mColorLocation[uniform], value); 0482 } 0483 0484 bool GLShader::setUniform(GLShader::ColorUniform uniform, const QColor &value) 0485 { 0486 resolveLocations(); 0487 return setUniform(mColorLocation[uniform], value); 0488 } 0489 0490 bool GLShader::setUniform(const char *name, float value) 0491 { 0492 const int location = uniformLocation(name); 0493 return setUniform(location, value); 0494 } 0495 0496 bool GLShader::setUniform(const char *name, int value) 0497 { 0498 const int location = uniformLocation(name); 0499 return setUniform(location, value); 0500 } 0501 0502 bool GLShader::setUniform(const char *name, const QVector2D &value) 0503 { 0504 const int location = uniformLocation(name); 0505 return setUniform(location, value); 0506 } 0507 0508 bool GLShader::setUniform(const char *name, const QVector3D &value) 0509 { 0510 const int location = uniformLocation(name); 0511 return setUniform(location, value); 0512 } 0513 0514 bool GLShader::setUniform(const char *name, const QVector4D &value) 0515 { 0516 const int location = uniformLocation(name); 0517 return setUniform(location, value); 0518 } 0519 0520 bool GLShader::setUniform(const char *name, const QMatrix4x4 &value) 0521 { 0522 const int location = uniformLocation(name); 0523 return setUniform(location, value); 0524 } 0525 0526 bool GLShader::setUniform(const char *name, const QColor &color) 0527 { 0528 const int location = uniformLocation(name); 0529 return setUniform(location, color); 0530 } 0531 0532 bool GLShader::setUniform(int location, float value) 0533 { 0534 if (location >= 0) { 0535 glUniform1f(location, value); 0536 } 0537 return (location >= 0); 0538 } 0539 0540 bool GLShader::setUniform(int location, int value) 0541 { 0542 if (location >= 0) { 0543 glUniform1i(location, value); 0544 } 0545 return (location >= 0); 0546 } 0547 0548 bool GLShader::setUniform(int location, const QVector2D &value) 0549 { 0550 if (location >= 0) { 0551 glUniform2fv(location, 1, (const GLfloat *)&value); 0552 } 0553 return (location >= 0); 0554 } 0555 0556 bool GLShader::setUniform(int location, const QVector3D &value) 0557 { 0558 if (location >= 0) { 0559 glUniform3fv(location, 1, (const GLfloat *)&value); 0560 } 0561 return (location >= 0); 0562 } 0563 0564 bool GLShader::setUniform(int location, const QVector4D &value) 0565 { 0566 if (location >= 0) { 0567 glUniform4fv(location, 1, (const GLfloat *)&value); 0568 } 0569 return (location >= 0); 0570 } 0571 0572 bool GLShader::setUniform(int location, const QMatrix4x4 &value) 0573 { 0574 if (location >= 0) { 0575 glUniformMatrix4fv(location, 1, GL_FALSE, value.constData()); 0576 } 0577 return (location >= 0); 0578 } 0579 0580 bool GLShader::setUniform(int location, const QColor &color) 0581 { 0582 if (location >= 0) { 0583 glUniform4f(location, color.redF(), color.greenF(), color.blueF(), color.alphaF()); 0584 } 0585 return (location >= 0); 0586 } 0587 0588 int GLShader::attributeLocation(const char *name) 0589 { 0590 int location = glGetAttribLocation(mProgram, name); 0591 return location; 0592 } 0593 0594 bool GLShader::setAttribute(const char *name, float value) 0595 { 0596 int location = attributeLocation(name); 0597 if (location >= 0) { 0598 glVertexAttrib1f(location, value); 0599 } 0600 return (location >= 0); 0601 } 0602 0603 QMatrix4x4 GLShader::getUniformMatrix4x4(const char *name) 0604 { 0605 int location = uniformLocation(name); 0606 if (location >= 0) { 0607 GLfloat m[16]; 0608 glGetnUniformfv(mProgram, location, sizeof(m), m); 0609 QMatrix4x4 matrix(m[0], m[4], m[8], m[12], 0610 m[1], m[5], m[9], m[13], 0611 m[2], m[6], m[10], m[14], 0612 m[3], m[7], m[11], m[15]); 0613 matrix.optimize(); 0614 return matrix; 0615 } else { 0616 return QMatrix4x4(); 0617 } 0618 } 0619 0620 //**************************************** 0621 // ShaderManager 0622 //**************************************** 0623 std::unique_ptr<ShaderManager> ShaderManager::s_shaderManager; 0624 0625 ShaderManager *ShaderManager::instance() 0626 { 0627 if (!s_shaderManager) { 0628 s_shaderManager.reset(new ShaderManager()); 0629 } 0630 return s_shaderManager.get(); 0631 } 0632 0633 void ShaderManager::cleanup() 0634 { 0635 s_shaderManager.reset(); 0636 } 0637 0638 ShaderManager::ShaderManager() 0639 { 0640 } 0641 0642 ShaderManager::~ShaderManager() 0643 { 0644 while (!m_boundShaders.isEmpty()) { 0645 popShader(); 0646 } 0647 } 0648 0649 QByteArray ShaderManager::generateVertexSource(ShaderTraits traits) const 0650 { 0651 QByteArray source; 0652 QTextStream stream(&source); 0653 0654 GLPlatform *const gl = GLPlatform::instance(); 0655 QByteArray attribute, varying; 0656 0657 if (!gl->isGLES()) { 0658 const bool glsl_140 = gl->glslVersion() >= kVersionNumber(1, 40); 0659 0660 attribute = glsl_140 ? QByteArrayLiteral("in") : QByteArrayLiteral("attribute"); 0661 varying = glsl_140 ? QByteArrayLiteral("out") : QByteArrayLiteral("varying"); 0662 0663 if (glsl_140) { 0664 stream << "#version 140\n\n"; 0665 } 0666 } else { 0667 const bool glsl_es_300 = gl->glslVersion() >= kVersionNumber(3, 0); 0668 0669 attribute = glsl_es_300 ? QByteArrayLiteral("in") : QByteArrayLiteral("attribute"); 0670 varying = glsl_es_300 ? QByteArrayLiteral("out") : QByteArrayLiteral("varying"); 0671 0672 if (glsl_es_300) { 0673 stream << "#version 300 es\n\n"; 0674 } 0675 } 0676 0677 stream << attribute << " vec4 position;\n"; 0678 if (traits & ShaderTrait::MapTexture) { 0679 stream << attribute << " vec4 texcoord;\n\n"; 0680 stream << varying << " vec2 texcoord0;\n\n"; 0681 } else { 0682 stream << "\n"; 0683 } 0684 0685 stream << "uniform mat4 modelViewProjectionMatrix;\n\n"; 0686 0687 stream << "void main()\n{\n"; 0688 if (traits & ShaderTrait::MapTexture) { 0689 stream << " texcoord0 = texcoord.st;\n"; 0690 } 0691 0692 stream << " gl_Position = modelViewProjectionMatrix * position;\n"; 0693 stream << "}\n"; 0694 0695 stream.flush(); 0696 return source; 0697 } 0698 0699 QByteArray ShaderManager::generateFragmentSource(ShaderTraits traits) const 0700 { 0701 QByteArray source; 0702 QTextStream stream(&source); 0703 0704 GLPlatform *const gl = GLPlatform::instance(); 0705 QByteArray varying, output, textureLookup; 0706 0707 if (!gl->isGLES()) { 0708 const bool glsl_140 = gl->glslVersion() >= kVersionNumber(1, 40); 0709 0710 if (glsl_140) { 0711 stream << "#version 140\n\n"; 0712 } 0713 0714 varying = glsl_140 ? QByteArrayLiteral("in") : QByteArrayLiteral("varying"); 0715 textureLookup = glsl_140 ? QByteArrayLiteral("texture") : QByteArrayLiteral("texture2D"); 0716 output = glsl_140 ? QByteArrayLiteral("fragColor") : QByteArrayLiteral("gl_FragColor"); 0717 } else { 0718 const bool glsl_es_300 = GLPlatform::instance()->glslVersion() >= kVersionNumber(3, 0); 0719 0720 if (glsl_es_300) { 0721 stream << "#version 300 es\n\n"; 0722 } 0723 0724 // From the GLSL ES specification: 0725 // 0726 // "The fragment language has no default precision qualifier for floating point types." 0727 stream << "precision highp float;\n\n"; 0728 0729 varying = glsl_es_300 ? QByteArrayLiteral("in") : QByteArrayLiteral("varying"); 0730 textureLookup = glsl_es_300 ? QByteArrayLiteral("texture") : QByteArrayLiteral("texture2D"); 0731 output = glsl_es_300 ? QByteArrayLiteral("fragColor") : QByteArrayLiteral("gl_FragColor"); 0732 } 0733 0734 if (traits & ShaderTrait::MapTexture) { 0735 stream << "uniform sampler2D sampler;\n"; 0736 0737 if (traits & ShaderTrait::Modulate) { 0738 stream << "uniform vec4 modulation;\n"; 0739 } 0740 if (traits & ShaderTrait::AdjustSaturation) { 0741 stream << "uniform float saturation;\n"; 0742 } 0743 0744 stream << "\n" 0745 << varying << " vec2 texcoord0;\n"; 0746 0747 } else if (traits & ShaderTrait::UniformColor) { 0748 stream << "uniform vec4 geometryColor;\n"; 0749 } 0750 0751 if (output != QByteArrayLiteral("gl_FragColor")) { 0752 stream << "\nout vec4 " << output << ";\n"; 0753 } 0754 0755 stream << "\nvoid main(void)\n{\n"; 0756 if (traits & ShaderTrait::MapTexture) { 0757 stream << "vec2 texcoordC = texcoord0;\n"; 0758 0759 if (traits & (ShaderTrait::Modulate | ShaderTrait::AdjustSaturation)) { 0760 stream << " vec4 texel = " << textureLookup << "(sampler, texcoordC);\n"; 0761 if (traits & ShaderTrait::Modulate) { 0762 stream << " texel *= modulation;\n"; 0763 } 0764 if (traits & ShaderTrait::AdjustSaturation) { 0765 stream << " texel.rgb = mix(vec3(dot(texel.rgb, vec3(0.2126, 0.7152, 0.0722))), texel.rgb, saturation);\n"; 0766 } 0767 0768 stream << " " << output << " = texel;\n"; 0769 } else { 0770 stream << " " << output << " = " << textureLookup << "(sampler, texcoordC);\n"; 0771 } 0772 } else if (traits & ShaderTrait::UniformColor) { 0773 stream << " " << output << " = geometryColor;\n"; 0774 } 0775 0776 stream << "}"; 0777 stream.flush(); 0778 return source; 0779 } 0780 0781 std::unique_ptr<GLShader> ShaderManager::generateShader(ShaderTraits traits) 0782 { 0783 return generateCustomShader(traits); 0784 } 0785 0786 std::unique_ptr<GLShader> ShaderManager::generateCustomShader(ShaderTraits traits, const QByteArray &vertexSource, const QByteArray &fragmentSource) 0787 { 0788 const QByteArray vertex = vertexSource.isEmpty() ? generateVertexSource(traits) : vertexSource; 0789 const QByteArray fragment = fragmentSource.isEmpty() ? generateFragmentSource(traits) : fragmentSource; 0790 0791 #if 0 0792 qCDebug(LIBKWINGLUTILS) << "**************"; 0793 qCDebug(LIBKWINGLUTILS) << vertex; 0794 qCDebug(LIBKWINGLUTILS) << "**************"; 0795 qCDebug(LIBKWINGLUTILS) << fragment; 0796 qCDebug(LIBKWINGLUTILS) << "**************"; 0797 #endif 0798 0799 std::unique_ptr<GLShader> shader{new GLShader(GLShader::ExplicitLinking)}; 0800 shader->load(vertex, fragment); 0801 0802 shader->bindAttributeLocation("position", VA_Position); 0803 shader->bindAttributeLocation("texcoord", VA_TexCoord); 0804 shader->bindFragDataLocation("fragColor", 0); 0805 0806 shader->link(); 0807 return shader; 0808 } 0809 0810 static QString resolveShaderFilePath(const QString &filePath) 0811 { 0812 QString suffix; 0813 QString extension; 0814 0815 const qint64 coreVersionNumber = GLPlatform::instance()->isGLES() ? kVersionNumber(3, 0) : kVersionNumber(1, 40); 0816 if (GLPlatform::instance()->glslVersion() >= coreVersionNumber) { 0817 suffix = QStringLiteral("_core"); 0818 } 0819 0820 if (filePath.endsWith(QStringLiteral(".frag"))) { 0821 extension = QStringLiteral(".frag"); 0822 } else if (filePath.endsWith(QStringLiteral(".vert"))) { 0823 extension = QStringLiteral(".vert"); 0824 } else { 0825 qCWarning(LIBKWINGLUTILS) << filePath << "must end either with .vert or .frag"; 0826 return QString(); 0827 } 0828 0829 const QString prefix = filePath.chopped(extension.size()); 0830 return prefix + suffix + extension; 0831 } 0832 0833 std::unique_ptr<GLShader> ShaderManager::generateShaderFromFile(ShaderTraits traits, const QString &vertexFile, const QString &fragmentFile) 0834 { 0835 auto loadShaderFile = [](const QString &filePath) { 0836 QFile file(filePath); 0837 if (file.open(QIODevice::ReadOnly)) { 0838 return file.readAll(); 0839 } 0840 qCCritical(LIBKWINGLUTILS) << "Failed to read shader " << filePath; 0841 return QByteArray(); 0842 }; 0843 QByteArray vertexSource; 0844 QByteArray fragmentSource; 0845 if (!vertexFile.isEmpty()) { 0846 vertexSource = loadShaderFile(resolveShaderFilePath(vertexFile)); 0847 if (vertexSource.isEmpty()) { 0848 return std::unique_ptr<GLShader>(new GLShader()); 0849 } 0850 } 0851 if (!fragmentFile.isEmpty()) { 0852 fragmentSource = loadShaderFile(resolveShaderFilePath(fragmentFile)); 0853 if (fragmentSource.isEmpty()) { 0854 return std::unique_ptr<GLShader>(new GLShader()); 0855 } 0856 } 0857 return generateCustomShader(traits, vertexSource, fragmentSource); 0858 } 0859 0860 GLShader *ShaderManager::shader(ShaderTraits traits) 0861 { 0862 std::unique_ptr<GLShader> &shader = m_shaderHash[traits]; 0863 if (!shader) { 0864 shader = generateShader(traits); 0865 } 0866 return shader.get(); 0867 } 0868 0869 GLShader *ShaderManager::getBoundShader() const 0870 { 0871 if (m_boundShaders.isEmpty()) { 0872 return nullptr; 0873 } else { 0874 return m_boundShaders.top(); 0875 } 0876 } 0877 0878 bool ShaderManager::isShaderBound() const 0879 { 0880 return !m_boundShaders.isEmpty(); 0881 } 0882 0883 GLShader *ShaderManager::pushShader(ShaderTraits traits) 0884 { 0885 GLShader *shader = this->shader(traits); 0886 pushShader(shader); 0887 return shader; 0888 } 0889 0890 void ShaderManager::pushShader(GLShader *shader) 0891 { 0892 // only bind shader if it is not already bound 0893 if (shader != getBoundShader()) { 0894 shader->bind(); 0895 } 0896 m_boundShaders.push(shader); 0897 } 0898 0899 void ShaderManager::popShader() 0900 { 0901 if (m_boundShaders.isEmpty()) { 0902 return; 0903 } 0904 GLShader *shader = m_boundShaders.pop(); 0905 if (m_boundShaders.isEmpty()) { 0906 // no more shader bound - unbind 0907 shader->unbind(); 0908 } else if (shader != m_boundShaders.top()) { 0909 // only rebind if a different shader is on top of stack 0910 m_boundShaders.top()->bind(); 0911 } 0912 } 0913 0914 void ShaderManager::bindFragDataLocations(GLShader *shader) 0915 { 0916 shader->bindFragDataLocation("fragColor", 0); 0917 } 0918 0919 void ShaderManager::bindAttributeLocations(GLShader *shader) const 0920 { 0921 shader->bindAttributeLocation("vertex", VA_Position); 0922 shader->bindAttributeLocation("texCoord", VA_TexCoord); 0923 } 0924 0925 std::unique_ptr<GLShader> ShaderManager::loadShaderFromCode(const QByteArray &vertexSource, const QByteArray &fragmentSource) 0926 { 0927 std::unique_ptr<GLShader> shader{new GLShader(GLShader::ExplicitLinking)}; 0928 shader->load(vertexSource, fragmentSource); 0929 bindAttributeLocations(shader.get()); 0930 bindFragDataLocations(shader.get()); 0931 shader->link(); 0932 return shader; 0933 } 0934 0935 /*** GLFramebuffer ***/ 0936 bool GLFramebuffer::sSupported = false; 0937 bool GLFramebuffer::s_blitSupported = false; 0938 QStack<GLFramebuffer *> GLFramebuffer::s_fbos = QStack<GLFramebuffer *>(); 0939 0940 void GLFramebuffer::initStatic() 0941 { 0942 if (GLPlatform::instance()->isGLES()) { 0943 sSupported = true; 0944 s_blitSupported = hasGLVersion(3, 0); 0945 } else { 0946 sSupported = hasGLVersion(3, 0) || hasGLExtension(QByteArrayLiteral("GL_ARB_framebuffer_object")) || hasGLExtension(QByteArrayLiteral("GL_EXT_framebuffer_object")); 0947 0948 s_blitSupported = hasGLVersion(3, 0) || hasGLExtension(QByteArrayLiteral("GL_ARB_framebuffer_object")) || hasGLExtension(QByteArrayLiteral("GL_EXT_framebuffer_blit")); 0949 } 0950 } 0951 0952 void GLFramebuffer::cleanup() 0953 { 0954 Q_ASSERT(s_fbos.isEmpty()); 0955 sSupported = false; 0956 s_blitSupported = false; 0957 } 0958 0959 bool GLFramebuffer::blitSupported() 0960 { 0961 return s_blitSupported; 0962 } 0963 0964 GLFramebuffer *GLFramebuffer::currentFramebuffer() 0965 { 0966 return s_fbos.isEmpty() ? nullptr : s_fbos.top(); 0967 } 0968 0969 void GLFramebuffer::pushFramebuffer(GLFramebuffer *fbo) 0970 { 0971 fbo->bind(); 0972 s_fbos.push(fbo); 0973 } 0974 0975 void GLFramebuffer::pushFramebuffers(QStack<GLFramebuffer *> fbos) 0976 { 0977 fbos.top()->bind(); 0978 s_fbos.append(fbos); 0979 } 0980 0981 GLFramebuffer *GLFramebuffer::popFramebuffer() 0982 { 0983 GLFramebuffer *ret = s_fbos.pop(); 0984 if (!s_fbos.isEmpty()) { 0985 s_fbos.top()->bind(); 0986 } else { 0987 glBindFramebuffer(GL_FRAMEBUFFER, 0); 0988 } 0989 0990 return ret; 0991 } 0992 0993 GLFramebuffer::GLFramebuffer() 0994 { 0995 } 0996 0997 GLFramebuffer::GLFramebuffer(GLTexture *colorAttachment) 0998 : mSize(colorAttachment->size()) 0999 { 1000 // Make sure FBO is supported 1001 if (sSupported && !colorAttachment->isNull()) { 1002 initFBO(colorAttachment); 1003 } else { 1004 qCCritical(LIBKWINGLUTILS) << "Framebuffer objects aren't supported!"; 1005 } 1006 } 1007 1008 GLFramebuffer::GLFramebuffer(GLuint handle, const QSize &size) 1009 : mFramebuffer(handle) 1010 , mSize(size) 1011 , mValid(true) 1012 , mForeign(true) 1013 { 1014 } 1015 1016 GLFramebuffer::~GLFramebuffer() 1017 { 1018 if (!mForeign && mValid) { 1019 glDeleteFramebuffers(1, &mFramebuffer); 1020 } 1021 } 1022 1023 bool GLFramebuffer::bind() 1024 { 1025 if (!valid()) { 1026 qCCritical(LIBKWINGLUTILS) << "Can't enable invalid framebuffer object!"; 1027 return false; 1028 } 1029 1030 glBindFramebuffer(GL_FRAMEBUFFER, handle()); 1031 glViewport(0, 0, mSize.width(), mSize.height()); 1032 1033 return true; 1034 } 1035 1036 static QString formatFramebufferStatus(GLenum status) 1037 { 1038 switch (status) { 1039 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 1040 // An attachment is the wrong type / is invalid / has 0 width or height 1041 return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); 1042 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 1043 // There are no images attached to the framebuffer 1044 return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); 1045 case GL_FRAMEBUFFER_UNSUPPORTED: 1046 // A format or the combination of formats of the attachments is unsupported 1047 return QStringLiteral("GL_FRAMEBUFFER_UNSUPPORTED"); 1048 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: 1049 // Not all attached images have the same width and height 1050 return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT"); 1051 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: 1052 // The color attachments don't have the same format 1053 return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT"); 1054 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: 1055 // The attachments don't have the same number of samples 1056 return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"); 1057 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: 1058 // The draw buffer is missing 1059 return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"); 1060 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: 1061 // The read buffer is missing 1062 return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"); 1063 default: 1064 return QStringLiteral("Unknown (0x") + QString::number(status, 16) + QStringLiteral(")"); 1065 } 1066 } 1067 1068 void GLFramebuffer::initFBO(GLTexture *colorAttachment) 1069 { 1070 #if DEBUG_GLFRAMEBUFFER 1071 GLenum err = glGetError(); 1072 if (err != GL_NO_ERROR) 1073 qCCritical(LIBKWINGLUTILS) << "Error status when entering GLFramebuffer::initFBO: " << formatGLError(err); 1074 #endif 1075 1076 GLuint prevFbo = 0; 1077 if (const GLFramebuffer *current = currentFramebuffer()) { 1078 prevFbo = current->handle(); 1079 } 1080 1081 glGenFramebuffers(1, &mFramebuffer); 1082 1083 #if DEBUG_GLFRAMEBUFFER 1084 if ((err = glGetError()) != GL_NO_ERROR) { 1085 qCCritical(LIBKWINGLUTILS) << "glGenFramebuffers failed: " << formatGLError(err); 1086 return; 1087 } 1088 #endif 1089 1090 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); 1091 1092 #if DEBUG_GLFRAMEBUFFER 1093 if ((err = glGetError()) != GL_NO_ERROR) { 1094 qCCritical(LIBKWINGLUTILS) << "glBindFramebuffer failed: " << formatGLError(err); 1095 glDeleteFramebuffers(1, &mFramebuffer); 1096 return; 1097 } 1098 #endif 1099 1100 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 1101 colorAttachment->target(), colorAttachment->texture(), 0); 1102 1103 #if DEBUG_GLFRAMEBUFFER 1104 if ((err = glGetError()) != GL_NO_ERROR) { 1105 qCCritical(LIBKWINGLUTILS) << "glFramebufferTexture2D failed: " << formatGLError(err); 1106 glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); 1107 glDeleteFramebuffers(1, &mFramebuffer); 1108 return; 1109 } 1110 #endif 1111 1112 const GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 1113 1114 glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); 1115 1116 if (status != GL_FRAMEBUFFER_COMPLETE) { 1117 // We have an incomplete framebuffer, consider it invalid 1118 if (status == 0) { 1119 qCCritical(LIBKWINGLUTILS) << "glCheckFramebufferStatus failed: " << formatGLError(glGetError()); 1120 } else { 1121 qCCritical(LIBKWINGLUTILS) << "Invalid framebuffer status: " << formatFramebufferStatus(status); 1122 } 1123 glDeleteFramebuffers(1, &mFramebuffer); 1124 return; 1125 } 1126 1127 mValid = true; 1128 } 1129 1130 void GLFramebuffer::blitFromFramebuffer(const QRect &source, const QRect &destination, GLenum filter) 1131 { 1132 if (!valid()) { 1133 return; 1134 } 1135 1136 const GLFramebuffer *top = currentFramebuffer(); 1137 GLFramebuffer::pushFramebuffer(this); 1138 1139 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, handle()); 1140 glBindFramebuffer(GL_READ_FRAMEBUFFER, top->handle()); 1141 1142 const QRect s = source.isNull() ? QRect(QPoint(0, 0), top->size()) : source; 1143 const QRect d = destination.isNull() ? QRect(QPoint(0, 0), size()) : destination; 1144 1145 const GLuint srcX0 = s.x(); 1146 const GLuint srcY0 = top->size().height() - (s.y() + s.height()); 1147 const GLuint srcX1 = s.x() + s.width(); 1148 const GLuint srcY1 = top->size().height() - s.y(); 1149 1150 const GLuint dstX0 = d.x(); 1151 const GLuint dstY0 = mSize.height() - (d.y() + d.height()); 1152 const GLuint dstX1 = d.x() + d.width(); 1153 const GLuint dstY1 = mSize.height() - d.y(); 1154 1155 glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, GL_COLOR_BUFFER_BIT, filter); 1156 1157 GLFramebuffer::popFramebuffer(); 1158 } 1159 1160 // ------------------------------------------------------------------ 1161 1162 static const uint16_t indices[] = { 1163 1, 0, 3, 3, 2, 1, 5, 4, 7, 7, 6, 5, 9, 8, 11, 11, 10, 9, 1164 13, 12, 15, 15, 14, 13, 17, 16, 19, 19, 18, 17, 21, 20, 23, 23, 22, 21, 1165 25, 24, 27, 27, 26, 25, 29, 28, 31, 31, 30, 29, 33, 32, 35, 35, 34, 33, 1166 37, 36, 39, 39, 38, 37, 41, 40, 43, 43, 42, 41, 45, 44, 47, 47, 46, 45, 1167 49, 48, 51, 51, 50, 49, 53, 52, 55, 55, 54, 53, 57, 56, 59, 59, 58, 57, 1168 61, 60, 63, 63, 62, 61, 65, 64, 67, 67, 66, 65, 69, 68, 71, 71, 70, 69, 1169 73, 72, 75, 75, 74, 73, 77, 76, 79, 79, 78, 77, 81, 80, 83, 83, 82, 81, 1170 85, 84, 87, 87, 86, 85, 89, 88, 91, 91, 90, 89, 93, 92, 95, 95, 94, 93, 1171 97, 96, 99, 99, 98, 97, 101, 100, 103, 103, 102, 101, 105, 104, 107, 107, 106, 105, 1172 109, 108, 111, 111, 110, 109, 113, 112, 115, 115, 114, 113, 117, 116, 119, 119, 118, 117, 1173 121, 120, 123, 123, 122, 121, 125, 124, 127, 127, 126, 125, 129, 128, 131, 131, 130, 129, 1174 133, 132, 135, 135, 134, 133, 137, 136, 139, 139, 138, 137, 141, 140, 143, 143, 142, 141, 1175 145, 144, 147, 147, 146, 145, 149, 148, 151, 151, 150, 149, 153, 152, 155, 155, 154, 153, 1176 157, 156, 159, 159, 158, 157, 161, 160, 163, 163, 162, 161, 165, 164, 167, 167, 166, 165, 1177 169, 168, 171, 171, 170, 169, 173, 172, 175, 175, 174, 173, 177, 176, 179, 179, 178, 177, 1178 181, 180, 183, 183, 182, 181, 185, 184, 187, 187, 186, 185, 189, 188, 191, 191, 190, 189, 1179 193, 192, 195, 195, 194, 193, 197, 196, 199, 199, 198, 197, 201, 200, 203, 203, 202, 201, 1180 205, 204, 207, 207, 206, 205, 209, 208, 211, 211, 210, 209, 213, 212, 215, 215, 214, 213, 1181 217, 216, 219, 219, 218, 217, 221, 220, 223, 223, 222, 221, 225, 224, 227, 227, 226, 225, 1182 229, 228, 231, 231, 230, 229, 233, 232, 235, 235, 234, 233, 237, 236, 239, 239, 238, 237, 1183 241, 240, 243, 243, 242, 241, 245, 244, 247, 247, 246, 245, 249, 248, 251, 251, 250, 249, 1184 253, 252, 255, 255, 254, 253, 257, 256, 259, 259, 258, 257, 261, 260, 263, 263, 262, 261, 1185 265, 264, 267, 267, 266, 265, 269, 268, 271, 271, 270, 269, 273, 272, 275, 275, 274, 273, 1186 277, 276, 279, 279, 278, 277, 281, 280, 283, 283, 282, 281, 285, 284, 287, 287, 286, 285, 1187 289, 288, 291, 291, 290, 289, 293, 292, 295, 295, 294, 293, 297, 296, 299, 299, 298, 297, 1188 301, 300, 303, 303, 302, 301, 305, 304, 307, 307, 306, 305, 309, 308, 311, 311, 310, 309, 1189 313, 312, 315, 315, 314, 313, 317, 316, 319, 319, 318, 317, 321, 320, 323, 323, 322, 321, 1190 325, 324, 327, 327, 326, 325, 329, 328, 331, 331, 330, 329, 333, 332, 335, 335, 334, 333, 1191 337, 336, 339, 339, 338, 337, 341, 340, 343, 343, 342, 341, 345, 344, 347, 347, 346, 345, 1192 349, 348, 351, 351, 350, 349, 353, 352, 355, 355, 354, 353, 357, 356, 359, 359, 358, 357, 1193 361, 360, 363, 363, 362, 361, 365, 364, 367, 367, 366, 365, 369, 368, 371, 371, 370, 369, 1194 373, 372, 375, 375, 374, 373, 377, 376, 379, 379, 378, 377, 381, 380, 383, 383, 382, 381, 1195 385, 384, 387, 387, 386, 385, 389, 388, 391, 391, 390, 389, 393, 392, 395, 395, 394, 393, 1196 397, 396, 399, 399, 398, 397, 401, 400, 403, 403, 402, 401, 405, 404, 407, 407, 406, 405, 1197 409, 408, 411, 411, 410, 409, 413, 412, 415, 415, 414, 413, 417, 416, 419, 419, 418, 417, 1198 421, 420, 423, 423, 422, 421, 425, 424, 427, 427, 426, 425, 429, 428, 431, 431, 430, 429, 1199 433, 432, 435, 435, 434, 433, 437, 436, 439, 439, 438, 437, 441, 440, 443, 443, 442, 441, 1200 445, 444, 447, 447, 446, 445, 449, 448, 451, 451, 450, 449, 453, 452, 455, 455, 454, 453, 1201 457, 456, 459, 459, 458, 457, 461, 460, 463, 463, 462, 461, 465, 464, 467, 467, 466, 465, 1202 469, 468, 471, 471, 470, 469, 473, 472, 475, 475, 474, 473, 477, 476, 479, 479, 478, 477, 1203 481, 480, 483, 483, 482, 481, 485, 484, 487, 487, 486, 485, 489, 488, 491, 491, 490, 489, 1204 493, 492, 495, 495, 494, 493, 497, 496, 499, 499, 498, 497, 501, 500, 503, 503, 502, 501, 1205 505, 504, 507, 507, 506, 505, 509, 508, 511, 511, 510, 509, 513, 512, 515, 515, 514, 513, 1206 517, 516, 519, 519, 518, 517, 521, 520, 523, 523, 522, 521, 525, 524, 527, 527, 526, 525, 1207 529, 528, 531, 531, 530, 529, 533, 532, 535, 535, 534, 533, 537, 536, 539, 539, 538, 537, 1208 541, 540, 543, 543, 542, 541, 545, 544, 547, 547, 546, 545, 549, 548, 551, 551, 550, 549, 1209 553, 552, 555, 555, 554, 553, 557, 556, 559, 559, 558, 557, 561, 560, 563, 563, 562, 561, 1210 565, 564, 567, 567, 566, 565, 569, 568, 571, 571, 570, 569, 573, 572, 575, 575, 574, 573, 1211 577, 576, 579, 579, 578, 577, 581, 580, 583, 583, 582, 581, 585, 584, 587, 587, 586, 585, 1212 589, 588, 591, 591, 590, 589, 593, 592, 595, 595, 594, 593, 597, 596, 599, 599, 598, 597, 1213 601, 600, 603, 603, 602, 601, 605, 604, 607, 607, 606, 605, 609, 608, 611, 611, 610, 609, 1214 613, 612, 615, 615, 614, 613, 617, 616, 619, 619, 618, 617, 621, 620, 623, 623, 622, 621, 1215 625, 624, 627, 627, 626, 625, 629, 628, 631, 631, 630, 629, 633, 632, 635, 635, 634, 633, 1216 637, 636, 639, 639, 638, 637, 641, 640, 643, 643, 642, 641, 645, 644, 647, 647, 646, 645, 1217 649, 648, 651, 651, 650, 649, 653, 652, 655, 655, 654, 653, 657, 656, 659, 659, 658, 657, 1218 661, 660, 663, 663, 662, 661, 665, 664, 667, 667, 666, 665, 669, 668, 671, 671, 670, 669, 1219 673, 672, 675, 675, 674, 673, 677, 676, 679, 679, 678, 677, 681, 680, 683, 683, 682, 681, 1220 685, 684, 687, 687, 686, 685, 689, 688, 691, 691, 690, 689, 693, 692, 695, 695, 694, 693, 1221 697, 696, 699, 699, 698, 697, 701, 700, 703, 703, 702, 701, 705, 704, 707, 707, 706, 705, 1222 709, 708, 711, 711, 710, 709, 713, 712, 715, 715, 714, 713, 717, 716, 719, 719, 718, 717, 1223 721, 720, 723, 723, 722, 721, 725, 724, 727, 727, 726, 725, 729, 728, 731, 731, 730, 729, 1224 733, 732, 735, 735, 734, 733, 737, 736, 739, 739, 738, 737, 741, 740, 743, 743, 742, 741, 1225 745, 744, 747, 747, 746, 745, 749, 748, 751, 751, 750, 749, 753, 752, 755, 755, 754, 753, 1226 757, 756, 759, 759, 758, 757, 761, 760, 763, 763, 762, 761, 765, 764, 767, 767, 766, 765, 1227 769, 768, 771, 771, 770, 769, 773, 772, 775, 775, 774, 773, 777, 776, 779, 779, 778, 777, 1228 781, 780, 783, 783, 782, 781, 785, 784, 787, 787, 786, 785, 789, 788, 791, 791, 790, 789, 1229 793, 792, 795, 795, 794, 793, 797, 796, 799, 799, 798, 797, 801, 800, 803, 803, 802, 801, 1230 805, 804, 807, 807, 806, 805, 809, 808, 811, 811, 810, 809, 813, 812, 815, 815, 814, 813, 1231 817, 816, 819, 819, 818, 817, 821, 820, 823, 823, 822, 821, 825, 824, 827, 827, 826, 825, 1232 829, 828, 831, 831, 830, 829, 833, 832, 835, 835, 834, 833, 837, 836, 839, 839, 838, 837, 1233 841, 840, 843, 843, 842, 841, 845, 844, 847, 847, 846, 845, 849, 848, 851, 851, 850, 849, 1234 853, 852, 855, 855, 854, 853, 857, 856, 859, 859, 858, 857, 861, 860, 863, 863, 862, 861, 1235 865, 864, 867, 867, 866, 865, 869, 868, 871, 871, 870, 869, 873, 872, 875, 875, 874, 873, 1236 877, 876, 879, 879, 878, 877, 881, 880, 883, 883, 882, 881, 885, 884, 887, 887, 886, 885, 1237 889, 888, 891, 891, 890, 889, 893, 892, 895, 895, 894, 893, 897, 896, 899, 899, 898, 897, 1238 901, 900, 903, 903, 902, 901, 905, 904, 907, 907, 906, 905, 909, 908, 911, 911, 910, 909, 1239 913, 912, 915, 915, 914, 913, 917, 916, 919, 919, 918, 917, 921, 920, 923, 923, 922, 921, 1240 925, 924, 927, 927, 926, 925, 929, 928, 931, 931, 930, 929, 933, 932, 935, 935, 934, 933, 1241 937, 936, 939, 939, 938, 937, 941, 940, 943, 943, 942, 941, 945, 944, 947, 947, 946, 945, 1242 949, 948, 951, 951, 950, 949, 953, 952, 955, 955, 954, 953, 957, 956, 959, 959, 958, 957, 1243 961, 960, 963, 963, 962, 961, 965, 964, 967, 967, 966, 965, 969, 968, 971, 971, 970, 969, 1244 973, 972, 975, 975, 974, 973, 977, 976, 979, 979, 978, 977, 981, 980, 983, 983, 982, 981, 1245 985, 984, 987, 987, 986, 985, 989, 988, 991, 991, 990, 989, 993, 992, 995, 995, 994, 993, 1246 997, 996, 999, 999, 998, 997, 1001, 1000, 1003, 1003, 1002, 1001, 1005, 1004, 1007, 1007, 1006, 1005, 1247 1009, 1008, 1011, 1011, 1010, 1009, 1013, 1012, 1015, 1015, 1014, 1013, 1017, 1016, 1019, 1019, 1018, 1017, 1248 1021, 1020, 1023, 1023, 1022, 1021, 1025, 1024, 1027, 1027, 1026, 1025, 1029, 1028, 1031, 1031, 1030, 1029, 1249 1033, 1032, 1035, 1035, 1034, 1033, 1037, 1036, 1039, 1039, 1038, 1037, 1041, 1040, 1043, 1043, 1042, 1041, 1250 1045, 1044, 1047, 1047, 1046, 1045, 1049, 1048, 1051, 1051, 1050, 1049, 1053, 1052, 1055, 1055, 1054, 1053, 1251 1057, 1056, 1059, 1059, 1058, 1057, 1061, 1060, 1063, 1063, 1062, 1061, 1065, 1064, 1067, 1067, 1066, 1065, 1252 1069, 1068, 1071, 1071, 1070, 1069, 1073, 1072, 1075, 1075, 1074, 1073, 1077, 1076, 1079, 1079, 1078, 1077, 1253 1081, 1080, 1083, 1083, 1082, 1081, 1085, 1084, 1087, 1087, 1086, 1085, 1089, 1088, 1091, 1091, 1090, 1089, 1254 1093, 1092, 1095, 1095, 1094, 1093, 1097, 1096, 1099, 1099, 1098, 1097, 1101, 1100, 1103, 1103, 1102, 1101, 1255 1105, 1104, 1107, 1107, 1106, 1105, 1109, 1108, 1111, 1111, 1110, 1109, 1113, 1112, 1115, 1115, 1114, 1113, 1256 1117, 1116, 1119, 1119, 1118, 1117, 1121, 1120, 1123, 1123, 1122, 1121, 1125, 1124, 1127, 1127, 1126, 1125, 1257 1129, 1128, 1131, 1131, 1130, 1129, 1133, 1132, 1135, 1135, 1134, 1133, 1137, 1136, 1139, 1139, 1138, 1137, 1258 1141, 1140, 1143, 1143, 1142, 1141, 1145, 1144, 1147, 1147, 1146, 1145, 1149, 1148, 1151, 1151, 1150, 1149, 1259 1153, 1152, 1155, 1155, 1154, 1153, 1157, 1156, 1159, 1159, 1158, 1157, 1161, 1160, 1163, 1163, 1162, 1161, 1260 1165, 1164, 1167, 1167, 1166, 1165, 1169, 1168, 1171, 1171, 1170, 1169, 1173, 1172, 1175, 1175, 1174, 1173, 1261 1177, 1176, 1179, 1179, 1178, 1177, 1181, 1180, 1183, 1183, 1182, 1181, 1185, 1184, 1187, 1187, 1186, 1185, 1262 1189, 1188, 1191, 1191, 1190, 1189, 1193, 1192, 1195, 1195, 1194, 1193, 1197, 1196, 1199, 1199, 1198, 1197, 1263 1201, 1200, 1203, 1203, 1202, 1201, 1205, 1204, 1207, 1207, 1206, 1205, 1209, 1208, 1211, 1211, 1210, 1209, 1264 1213, 1212, 1215, 1215, 1214, 1213, 1217, 1216, 1219, 1219, 1218, 1217, 1221, 1220, 1223, 1223, 1222, 1221, 1265 1225, 1224, 1227, 1227, 1226, 1225, 1229, 1228, 1231, 1231, 1230, 1229, 1233, 1232, 1235, 1235, 1234, 1233, 1266 1237, 1236, 1239, 1239, 1238, 1237, 1241, 1240, 1243, 1243, 1242, 1241, 1245, 1244, 1247, 1247, 1246, 1245, 1267 1249, 1248, 1251, 1251, 1250, 1249, 1253, 1252, 1255, 1255, 1254, 1253, 1257, 1256, 1259, 1259, 1258, 1257, 1268 1261, 1260, 1263, 1263, 1262, 1261, 1265, 1264, 1267, 1267, 1266, 1265, 1269, 1268, 1271, 1271, 1270, 1269, 1269 1273, 1272, 1275, 1275, 1274, 1273, 1277, 1276, 1279, 1279, 1278, 1277, 1281, 1280, 1283, 1283, 1282, 1281, 1270 1285, 1284, 1287, 1287, 1286, 1285, 1289, 1288, 1291, 1291, 1290, 1289, 1293, 1292, 1295, 1295, 1294, 1293, 1271 1297, 1296, 1299, 1299, 1298, 1297, 1301, 1300, 1303, 1303, 1302, 1301, 1305, 1304, 1307, 1307, 1306, 1305, 1272 1309, 1308, 1311, 1311, 1310, 1309, 1313, 1312, 1315, 1315, 1314, 1313, 1317, 1316, 1319, 1319, 1318, 1317, 1273 1321, 1320, 1323, 1323, 1322, 1321, 1325, 1324, 1327, 1327, 1326, 1325, 1329, 1328, 1331, 1331, 1330, 1329, 1274 1333, 1332, 1335, 1335, 1334, 1333, 1337, 1336, 1339, 1339, 1338, 1337, 1341, 1340, 1343, 1343, 1342, 1341, 1275 1345, 1344, 1347, 1347, 1346, 1345, 1349, 1348, 1351, 1351, 1350, 1349, 1353, 1352, 1355, 1355, 1354, 1353, 1276 1357, 1356, 1359, 1359, 1358, 1357, 1361, 1360, 1363, 1363, 1362, 1361, 1365, 1364, 1367, 1367, 1366, 1365, 1277 1369, 1368, 1371, 1371, 1370, 1369, 1373, 1372, 1375, 1375, 1374, 1373, 1377, 1376, 1379, 1379, 1378, 1377, 1278 1381, 1380, 1383, 1383, 1382, 1381, 1385, 1384, 1387, 1387, 1386, 1385, 1389, 1388, 1391, 1391, 1390, 1389, 1279 1393, 1392, 1395, 1395, 1394, 1393, 1397, 1396, 1399, 1399, 1398, 1397, 1401, 1400, 1403, 1403, 1402, 1401, 1280 1405, 1404, 1407, 1407, 1406, 1405, 1409, 1408, 1411, 1411, 1410, 1409, 1413, 1412, 1415, 1415, 1414, 1413, 1281 1417, 1416, 1419, 1419, 1418, 1417, 1421, 1420, 1423, 1423, 1422, 1421, 1425, 1424, 1427, 1427, 1426, 1425, 1282 1429, 1428, 1431, 1431, 1430, 1429, 1433, 1432, 1435, 1435, 1434, 1433, 1437, 1436, 1439, 1439, 1438, 1437, 1283 1441, 1440, 1443, 1443, 1442, 1441, 1445, 1444, 1447, 1447, 1446, 1445, 1449, 1448, 1451, 1451, 1450, 1449, 1284 1453, 1452, 1455, 1455, 1454, 1453, 1457, 1456, 1459, 1459, 1458, 1457, 1461, 1460, 1463, 1463, 1462, 1461, 1285 1465, 1464, 1467, 1467, 1466, 1465, 1469, 1468, 1471, 1471, 1470, 1469, 1473, 1472, 1475, 1475, 1474, 1473, 1286 1477, 1476, 1479, 1479, 1478, 1477, 1481, 1480, 1483, 1483, 1482, 1481, 1485, 1484, 1487, 1487, 1486, 1485, 1287 1489, 1488, 1491, 1491, 1490, 1489, 1493, 1492, 1495, 1495, 1494, 1493, 1497, 1496, 1499, 1499, 1498, 1497, 1288 1501, 1500, 1503, 1503, 1502, 1501, 1505, 1504, 1507, 1507, 1506, 1505, 1509, 1508, 1511, 1511, 1510, 1509, 1289 1513, 1512, 1515, 1515, 1514, 1513, 1517, 1516, 1519, 1519, 1518, 1517, 1521, 1520, 1523, 1523, 1522, 1521, 1290 1525, 1524, 1527, 1527, 1526, 1525, 1529, 1528, 1531, 1531, 1530, 1529, 1533, 1532, 1535, 1535, 1534, 1533, 1291 1537, 1536, 1539, 1539, 1538, 1537, 1541, 1540, 1543, 1543, 1542, 1541, 1545, 1544, 1547, 1547, 1546, 1545, 1292 1549, 1548, 1551, 1551, 1550, 1549, 1553, 1552, 1555, 1555, 1554, 1553, 1557, 1556, 1559, 1559, 1558, 1557, 1293 1561, 1560, 1563, 1563, 1562, 1561, 1565, 1564, 1567, 1567, 1566, 1565, 1569, 1568, 1571, 1571, 1570, 1569, 1294 1573, 1572, 1575, 1575, 1574, 1573, 1577, 1576, 1579, 1579, 1578, 1577, 1581, 1580, 1583, 1583, 1582, 1581, 1295 1585, 1584, 1587, 1587, 1586, 1585, 1589, 1588, 1591, 1591, 1590, 1589, 1593, 1592, 1595, 1595, 1594, 1593, 1296 1597, 1596, 1599, 1599, 1598, 1597, 1601, 1600, 1603, 1603, 1602, 1601, 1605, 1604, 1607, 1607, 1606, 1605, 1297 1609, 1608, 1611, 1611, 1610, 1609, 1613, 1612, 1615, 1615, 1614, 1613, 1617, 1616, 1619, 1619, 1618, 1617, 1298 1621, 1620, 1623, 1623, 1622, 1621, 1625, 1624, 1627, 1627, 1626, 1625, 1629, 1628, 1631, 1631, 1630, 1629, 1299 1633, 1632, 1635, 1635, 1634, 1633, 1637, 1636, 1639, 1639, 1638, 1637, 1641, 1640, 1643, 1643, 1642, 1641, 1300 1645, 1644, 1647, 1647, 1646, 1645, 1649, 1648, 1651, 1651, 1650, 1649, 1653, 1652, 1655, 1655, 1654, 1653, 1301 1657, 1656, 1659, 1659, 1658, 1657, 1661, 1660, 1663, 1663, 1662, 1661, 1665, 1664, 1667, 1667, 1666, 1665, 1302 1669, 1668, 1671, 1671, 1670, 1669, 1673, 1672, 1675, 1675, 1674, 1673, 1677, 1676, 1679, 1679, 1678, 1677, 1303 1681, 1680, 1683, 1683, 1682, 1681, 1685, 1684, 1687, 1687, 1686, 1685, 1689, 1688, 1691, 1691, 1690, 1689, 1304 1693, 1692, 1695, 1695, 1694, 1693, 1697, 1696, 1699, 1699, 1698, 1697, 1701, 1700, 1703, 1703, 1702, 1701, 1305 1705, 1704, 1707, 1707, 1706, 1705, 1709, 1708, 1711, 1711, 1710, 1709, 1713, 1712, 1715, 1715, 1714, 1713, 1306 1717, 1716, 1719, 1719, 1718, 1717, 1721, 1720, 1723, 1723, 1722, 1721, 1725, 1724, 1727, 1727, 1726, 1725, 1307 1729, 1728, 1731, 1731, 1730, 1729, 1733, 1732, 1735, 1735, 1734, 1733, 1737, 1736, 1739, 1739, 1738, 1737, 1308 1741, 1740, 1743, 1743, 1742, 1741, 1745, 1744, 1747, 1747, 1746, 1745, 1749, 1748, 1751, 1751, 1750, 1749, 1309 1753, 1752, 1755, 1755, 1754, 1753, 1757, 1756, 1759, 1759, 1758, 1757, 1761, 1760, 1763, 1763, 1762, 1761, 1310 1765, 1764, 1767, 1767, 1766, 1765, 1769, 1768, 1771, 1771, 1770, 1769, 1773, 1772, 1775, 1775, 1774, 1773, 1311 1777, 1776, 1779, 1779, 1778, 1777, 1781, 1780, 1783, 1783, 1782, 1781, 1785, 1784, 1787, 1787, 1786, 1785, 1312 1789, 1788, 1791, 1791, 1790, 1789, 1793, 1792, 1795, 1795, 1794, 1793, 1797, 1796, 1799, 1799, 1798, 1797, 1313 1801, 1800, 1803, 1803, 1802, 1801, 1805, 1804, 1807, 1807, 1806, 1805, 1809, 1808, 1811, 1811, 1810, 1809, 1314 1813, 1812, 1815, 1815, 1814, 1813, 1817, 1816, 1819, 1819, 1818, 1817, 1821, 1820, 1823, 1823, 1822, 1821, 1315 1825, 1824, 1827, 1827, 1826, 1825, 1829, 1828, 1831, 1831, 1830, 1829, 1833, 1832, 1835, 1835, 1834, 1833, 1316 1837, 1836, 1839, 1839, 1838, 1837, 1841, 1840, 1843, 1843, 1842, 1841, 1845, 1844, 1847, 1847, 1846, 1845, 1317 1849, 1848, 1851, 1851, 1850, 1849, 1853, 1852, 1855, 1855, 1854, 1853, 1857, 1856, 1859, 1859, 1858, 1857, 1318 1861, 1860, 1863, 1863, 1862, 1861, 1865, 1864, 1867, 1867, 1866, 1865, 1869, 1868, 1871, 1871, 1870, 1869, 1319 1873, 1872, 1875, 1875, 1874, 1873, 1877, 1876, 1879, 1879, 1878, 1877, 1881, 1880, 1883, 1883, 1882, 1881, 1320 1885, 1884, 1887, 1887, 1886, 1885, 1889, 1888, 1891, 1891, 1890, 1889, 1893, 1892, 1895, 1895, 1894, 1893, 1321 1897, 1896, 1899, 1899, 1898, 1897, 1901, 1900, 1903, 1903, 1902, 1901, 1905, 1904, 1907, 1907, 1906, 1905, 1322 1909, 1908, 1911, 1911, 1910, 1909, 1913, 1912, 1915, 1915, 1914, 1913, 1917, 1916, 1919, 1919, 1918, 1917, 1323 1921, 1920, 1923, 1923, 1922, 1921, 1925, 1924, 1927, 1927, 1926, 1925, 1929, 1928, 1931, 1931, 1930, 1929, 1324 1933, 1932, 1935, 1935, 1934, 1933, 1937, 1936, 1939, 1939, 1938, 1937, 1941, 1940, 1943, 1943, 1942, 1941, 1325 1945, 1944, 1947, 1947, 1946, 1945, 1949, 1948, 1951, 1951, 1950, 1949, 1953, 1952, 1955, 1955, 1954, 1953, 1326 1957, 1956, 1959, 1959, 1958, 1957, 1961, 1960, 1963, 1963, 1962, 1961, 1965, 1964, 1967, 1967, 1966, 1965, 1327 1969, 1968, 1971, 1971, 1970, 1969, 1973, 1972, 1975, 1975, 1974, 1973, 1977, 1976, 1979, 1979, 1978, 1977, 1328 1981, 1980, 1983, 1983, 1982, 1981, 1985, 1984, 1987, 1987, 1986, 1985, 1989, 1988, 1991, 1991, 1990, 1989, 1329 1993, 1992, 1995, 1995, 1994, 1993, 1997, 1996, 1999, 1999, 1998, 1997, 2001, 2000, 2003, 2003, 2002, 2001, 1330 2005, 2004, 2007, 2007, 2006, 2005, 2009, 2008, 2011, 2011, 2010, 2009, 2013, 2012, 2015, 2015, 2014, 2013, 1331 2017, 2016, 2019, 2019, 2018, 2017, 2021, 2020, 2023, 2023, 2022, 2021, 2025, 2024, 2027, 2027, 2026, 2025, 1332 2029, 2028, 2031, 2031, 2030, 2029, 2033, 2032, 2035, 2035, 2034, 2033, 2037, 2036, 2039, 2039, 2038, 2037, 1333 2041, 2040, 2043, 2043, 2042, 2041, 2045, 2044, 2047, 2047, 2046, 2045}; 1334 1335 // Certain GPUs, especially mobile, require the data copied to the GPU to be aligned to a 1336 // certain amount of bytes. For example, the Mali GPU requires data to be aligned to 8 bytes. 1337 // This function helps ensure that the data is aligned. 1338 template<typename T> 1339 T align(T value, int bytes) 1340 { 1341 return (value + bytes - 1) & ~T(bytes - 1); 1342 } 1343 1344 class IndexBuffer 1345 { 1346 public: 1347 IndexBuffer(); 1348 ~IndexBuffer(); 1349 1350 void accommodate(int count); 1351 void bind(); 1352 1353 private: 1354 GLuint m_buffer; 1355 size_t m_size; 1356 int m_count; 1357 }; 1358 1359 IndexBuffer::IndexBuffer() 1360 { 1361 // The maximum number of quads we can render with 16 bit indices is 16,384. 1362 // But we start with 512 and grow the buffer as needed. 1363 m_size = sizeof(indices); 1364 m_count = m_size / (6 * sizeof(uint16_t)); 1365 1366 glGenBuffers(1, &m_buffer); 1367 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); 1368 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 1369 } 1370 1371 IndexBuffer::~IndexBuffer() 1372 { 1373 glDeleteBuffers(1, &m_buffer); 1374 } 1375 1376 void IndexBuffer::accommodate(int count) 1377 { 1378 // Check if we need to grow the buffer. 1379 if (count <= m_count) { 1380 return; 1381 } 1382 1383 size_t size = 6 * sizeof(uint16_t) * count; 1384 1385 // Create a new buffer object 1386 GLuint buffer; 1387 glGenBuffers(1, &buffer); 1388 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); 1389 glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, nullptr, GL_STATIC_DRAW); 1390 1391 // Use the GPU to copy the data from the old object to the new object, 1392 glBindBuffer(GL_COPY_READ_BUFFER, m_buffer); 1393 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_ELEMENT_ARRAY_BUFFER, 0, 0, m_size); 1394 glDeleteBuffers(1, &m_buffer); 1395 glFlush(); // Needed to work around what appears to be a CP DMA issue in r600g 1396 1397 // Map the new object and fill in the uninitialized section 1398 const GLbitfield access = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_RANGE_BIT; 1399 uint16_t *map = (uint16_t *)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, m_size, size - m_size, access); 1400 1401 const uint16_t index[] = {1, 0, 3, 3, 2, 1}; 1402 for (int i = m_count; i < count; i++) { 1403 for (int j = 0; j < 6; j++) { 1404 *(map++) = i * 4 + index[j]; 1405 } 1406 } 1407 1408 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); 1409 m_buffer = buffer; 1410 m_count = count; 1411 m_size = size; 1412 } 1413 1414 void IndexBuffer::bind() 1415 { 1416 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); 1417 } 1418 1419 // ------------------------------------------------------------------ 1420 1421 class BitRef 1422 { 1423 public: 1424 BitRef(uint32_t &bitfield, int bit) 1425 : m_bitfield(bitfield) 1426 , m_mask(1 << bit) 1427 { 1428 } 1429 1430 void operator=(bool val) 1431 { 1432 if (val) { 1433 m_bitfield |= m_mask; 1434 } else { 1435 m_bitfield &= ~m_mask; 1436 } 1437 } 1438 1439 operator bool() const 1440 { 1441 return m_bitfield & m_mask; 1442 } 1443 1444 private: 1445 uint32_t &m_bitfield; 1446 int const m_mask; 1447 }; 1448 1449 // ------------------------------------------------------------------ 1450 1451 class Bitfield 1452 { 1453 public: 1454 Bitfield() 1455 : m_bitfield(0) 1456 { 1457 } 1458 Bitfield(uint32_t bits) 1459 : m_bitfield(bits) 1460 { 1461 } 1462 1463 void set(int i) 1464 { 1465 m_bitfield |= (1 << i); 1466 } 1467 void clear(int i) 1468 { 1469 m_bitfield &= ~(1 << i); 1470 } 1471 1472 BitRef operator[](int i) 1473 { 1474 return BitRef(m_bitfield, i); 1475 } 1476 operator uint32_t() const 1477 { 1478 return m_bitfield; 1479 } 1480 1481 private: 1482 uint32_t m_bitfield; 1483 }; 1484 1485 // ------------------------------------------------------------------ 1486 1487 class BitfieldIterator 1488 { 1489 public: 1490 BitfieldIterator(uint32_t bitfield) 1491 : m_bitfield(bitfield) 1492 { 1493 } 1494 1495 bool hasNext() const 1496 { 1497 return m_bitfield != 0; 1498 } 1499 1500 int next() 1501 { 1502 const int bit = ffs(m_bitfield) - 1; 1503 m_bitfield ^= (1 << bit); 1504 return bit; 1505 } 1506 1507 private: 1508 uint32_t m_bitfield; 1509 }; 1510 1511 // ------------------------------------------------------------------ 1512 1513 struct VertexAttrib 1514 { 1515 int size; 1516 GLenum type; 1517 int offset; 1518 }; 1519 1520 // ------------------------------------------------------------------ 1521 1522 struct BufferFence 1523 { 1524 GLsync sync; 1525 intptr_t nextEnd; 1526 1527 bool signaled() const 1528 { 1529 GLint value; 1530 glGetSynciv(sync, GL_SYNC_STATUS, 1, nullptr, &value); 1531 return value == GL_SIGNALED; 1532 } 1533 }; 1534 1535 static void deleteAll(std::deque<BufferFence> &fences) 1536 { 1537 for (const BufferFence &fence : fences) { 1538 glDeleteSync(fence.sync); 1539 } 1540 1541 fences.clear(); 1542 } 1543 1544 // ------------------------------------------------------------------ 1545 1546 template<size_t Count> 1547 struct FrameSizesArray 1548 { 1549 public: 1550 FrameSizesArray() 1551 { 1552 m_array.fill(0); 1553 } 1554 1555 void push(size_t size) 1556 { 1557 m_array[m_index] = size; 1558 m_index = (m_index + 1) % Count; 1559 } 1560 1561 size_t average() const 1562 { 1563 size_t sum = 0; 1564 for (size_t size : m_array) { 1565 sum += size; 1566 } 1567 return sum / Count; 1568 } 1569 1570 private: 1571 std::array<size_t, Count> m_array; 1572 int m_index = 0; 1573 }; 1574 1575 //********************************* 1576 // GLVertexBufferPrivate 1577 //********************************* 1578 class GLVertexBufferPrivate 1579 { 1580 public: 1581 GLVertexBufferPrivate(GLVertexBuffer::UsageHint usageHint) 1582 : vertexCount(0) 1583 , persistent(false) 1584 , useColor(false) 1585 , color(0, 0, 0, 255) 1586 , bufferSize(0) 1587 , bufferEnd(0) 1588 , mappedSize(0) 1589 , frameSize(0) 1590 , nextOffset(0) 1591 , baseAddress(0) 1592 , map(nullptr) 1593 { 1594 glGenBuffers(1, &buffer); 1595 1596 switch (usageHint) { 1597 case GLVertexBuffer::Dynamic: 1598 usage = GL_DYNAMIC_DRAW; 1599 break; 1600 case GLVertexBuffer::Static: 1601 usage = GL_STATIC_DRAW; 1602 break; 1603 default: 1604 usage = GL_STREAM_DRAW; 1605 break; 1606 } 1607 } 1608 1609 ~GLVertexBufferPrivate() 1610 { 1611 deleteAll(fences); 1612 1613 if (buffer != 0) { 1614 glDeleteBuffers(1, &buffer); 1615 map = nullptr; 1616 } 1617 } 1618 1619 void interleaveArrays(float *array, int dim, const float *vertices, const float *texcoords, int count); 1620 void bindArrays(); 1621 void unbindArrays(); 1622 void reallocateBuffer(size_t size); 1623 GLvoid *mapNextFreeRange(size_t size); 1624 void reallocatePersistentBuffer(size_t size); 1625 bool awaitFence(intptr_t offset); 1626 GLvoid *getIdleRange(size_t size); 1627 1628 GLuint buffer; 1629 GLenum usage; 1630 int stride; 1631 int vertexCount; 1632 static std::unique_ptr<GLVertexBuffer> streamingBuffer; 1633 static bool haveBufferStorage; 1634 static bool haveSyncFences; 1635 static bool hasMapBufferRange; 1636 static bool supportsIndexedQuads; 1637 QByteArray dataStore; 1638 bool persistent; 1639 bool useColor; 1640 QVector4D color; 1641 size_t bufferSize; 1642 intptr_t bufferEnd; 1643 size_t mappedSize; 1644 size_t frameSize; 1645 intptr_t nextOffset; 1646 intptr_t baseAddress; 1647 uint8_t *map; 1648 std::deque<BufferFence> fences; 1649 FrameSizesArray<4> frameSizes; 1650 VertexAttrib attrib[VertexAttributeCount]; 1651 Bitfield enabledArrays; 1652 static std::unique_ptr<IndexBuffer> s_indexBuffer; 1653 }; 1654 1655 bool GLVertexBufferPrivate::hasMapBufferRange = false; 1656 bool GLVertexBufferPrivate::supportsIndexedQuads = false; 1657 std::unique_ptr<GLVertexBuffer> GLVertexBufferPrivate::streamingBuffer; 1658 bool GLVertexBufferPrivate::haveBufferStorage = false; 1659 bool GLVertexBufferPrivate::haveSyncFences = false; 1660 std::unique_ptr<IndexBuffer> GLVertexBufferPrivate::s_indexBuffer; 1661 1662 void GLVertexBufferPrivate::interleaveArrays(float *dst, int dim, 1663 const float *vertices, const float *texcoords, 1664 int count) 1665 { 1666 if (!texcoords) { 1667 memcpy((void *)dst, vertices, dim * sizeof(float) * count); 1668 return; 1669 } 1670 1671 switch (dim) { 1672 case 2: 1673 for (int i = 0; i < count; i++) { 1674 *(dst++) = *(vertices++); 1675 *(dst++) = *(vertices++); 1676 *(dst++) = *(texcoords++); 1677 *(dst++) = *(texcoords++); 1678 } 1679 break; 1680 1681 case 3: 1682 for (int i = 0; i < count; i++) { 1683 *(dst++) = *(vertices++); 1684 *(dst++) = *(vertices++); 1685 *(dst++) = *(vertices++); 1686 *(dst++) = *(texcoords++); 1687 *(dst++) = *(texcoords++); 1688 } 1689 break; 1690 1691 default: 1692 for (int i = 0; i < count; i++) { 1693 for (int j = 0; j < dim; j++) { 1694 *(dst++) = *(vertices++); 1695 } 1696 1697 *(dst++) = *(texcoords++); 1698 *(dst++) = *(texcoords++); 1699 } 1700 } 1701 } 1702 1703 void GLVertexBufferPrivate::bindArrays() 1704 { 1705 if (useColor) { 1706 GLShader *shader = ShaderManager::instance()->getBoundShader(); 1707 shader->setUniform(GLShader::Color, color); 1708 } 1709 1710 glBindBuffer(GL_ARRAY_BUFFER, buffer); 1711 1712 BitfieldIterator it(enabledArrays); 1713 while (it.hasNext()) { 1714 const int index = it.next(); 1715 glVertexAttribPointer(index, attrib[index].size, attrib[index].type, GL_FALSE, stride, 1716 (const GLvoid *)(baseAddress + attrib[index].offset)); 1717 glEnableVertexAttribArray(index); 1718 } 1719 } 1720 1721 void GLVertexBufferPrivate::unbindArrays() 1722 { 1723 BitfieldIterator it(enabledArrays); 1724 while (it.hasNext()) { 1725 glDisableVertexAttribArray(it.next()); 1726 } 1727 } 1728 1729 void GLVertexBufferPrivate::reallocatePersistentBuffer(size_t size) 1730 { 1731 if (buffer != 0) { 1732 // This also unmaps and unbinds the buffer 1733 glDeleteBuffers(1, &buffer); 1734 buffer = 0; 1735 1736 deleteAll(fences); 1737 } 1738 1739 if (buffer == 0) { 1740 glGenBuffers(1, &buffer); 1741 } 1742 1743 // Round the size up to 64 kb 1744 size_t minSize = std::max<size_t>(frameSizes.average() * 3, 128 * 1024); 1745 bufferSize = std::max(size, minSize); 1746 1747 const GLbitfield storage = GL_DYNAMIC_STORAGE_BIT; 1748 const GLbitfield access = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT; 1749 1750 glBindBuffer(GL_ARRAY_BUFFER, buffer); 1751 glBufferStorage(GL_ARRAY_BUFFER, bufferSize, nullptr, storage | access); 1752 1753 map = (uint8_t *)glMapBufferRange(GL_ARRAY_BUFFER, 0, bufferSize, access); 1754 1755 nextOffset = 0; 1756 bufferEnd = bufferSize; 1757 } 1758 1759 bool GLVertexBufferPrivate::awaitFence(intptr_t end) 1760 { 1761 // Skip fences until we reach the end offset 1762 while (!fences.empty() && fences.front().nextEnd < end) { 1763 glDeleteSync(fences.front().sync); 1764 fences.pop_front(); 1765 } 1766 1767 Q_ASSERT(!fences.empty()); 1768 1769 // Wait on the next fence 1770 const BufferFence &fence = fences.front(); 1771 1772 if (!fence.signaled()) { 1773 qCDebug(LIBKWINGLUTILS) << "Stalling on VBO fence"; 1774 const GLenum ret = glClientWaitSync(fence.sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000000); 1775 1776 if (ret == GL_TIMEOUT_EXPIRED || ret == GL_WAIT_FAILED) { 1777 qCCritical(LIBKWINGLUTILS) << "Wait failed"; 1778 return false; 1779 } 1780 } 1781 1782 glDeleteSync(fence.sync); 1783 1784 // Update the end pointer 1785 bufferEnd = fence.nextEnd; 1786 fences.pop_front(); 1787 1788 return true; 1789 } 1790 1791 GLvoid *GLVertexBufferPrivate::getIdleRange(size_t size) 1792 { 1793 if (unlikely(size > bufferSize)) { 1794 reallocatePersistentBuffer(size * 2); 1795 } 1796 1797 // Handle wrap-around 1798 if (unlikely(nextOffset + size > bufferSize)) { 1799 nextOffset = 0; 1800 bufferEnd -= bufferSize; 1801 1802 for (BufferFence &fence : fences) { 1803 fence.nextEnd -= bufferSize; 1804 } 1805 1806 // Emit a fence now 1807 if (auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)) { 1808 fences.push_back(BufferFence{ 1809 .sync = sync, 1810 .nextEnd = intptr_t(bufferSize)}); 1811 } 1812 } 1813 1814 if (unlikely(nextOffset + intptr_t(size) > bufferEnd)) { 1815 if (!awaitFence(nextOffset + size)) { 1816 return nullptr; 1817 } 1818 } 1819 1820 return map + nextOffset; 1821 } 1822 1823 void GLVertexBufferPrivate::reallocateBuffer(size_t size) 1824 { 1825 // Round the size up to 4 Kb for streaming/dynamic buffers. 1826 const size_t minSize = 32768; // Minimum size for streaming buffers 1827 const size_t alloc = usage != GL_STATIC_DRAW ? std::max(size, minSize) : size; 1828 1829 glBufferData(GL_ARRAY_BUFFER, alloc, nullptr, usage); 1830 1831 bufferSize = alloc; 1832 } 1833 1834 GLvoid *GLVertexBufferPrivate::mapNextFreeRange(size_t size) 1835 { 1836 GLbitfield access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; 1837 1838 if ((nextOffset + size) > bufferSize) { 1839 // Reallocate the data store if it's too small. 1840 if (size > bufferSize) { 1841 reallocateBuffer(size); 1842 } else { 1843 access |= GL_MAP_INVALIDATE_BUFFER_BIT; 1844 access ^= GL_MAP_UNSYNCHRONIZED_BIT; 1845 } 1846 1847 nextOffset = 0; 1848 } 1849 1850 return glMapBufferRange(GL_ARRAY_BUFFER, nextOffset, size, access); 1851 } 1852 1853 //********************************* 1854 // GLVertexBuffer 1855 //********************************* 1856 1857 const GLVertexAttrib GLVertexBuffer::GLVertex2DLayout[2] = { 1858 {VA_Position, 2, GL_FLOAT, offsetof(GLVertex2D, position)}, 1859 {VA_TexCoord, 2, GL_FLOAT, offsetof(GLVertex2D, texcoord)}, 1860 }; 1861 1862 const GLVertexAttrib GLVertexBuffer::GLVertex3DLayout[2] = { 1863 {VA_Position, 3, GL_FLOAT, offsetof(GLVertex3D, position)}, 1864 {VA_TexCoord, 2, GL_FLOAT, offsetof(GLVertex3D, texcoord)}, 1865 }; 1866 1867 GLVertexBuffer::GLVertexBuffer(UsageHint hint) 1868 : d(std::make_unique<GLVertexBufferPrivate>(hint)) 1869 { 1870 } 1871 1872 GLVertexBuffer::~GLVertexBuffer() = default; 1873 1874 void GLVertexBuffer::setData(const void *data, size_t size) 1875 { 1876 GLvoid *ptr = map(size); 1877 memcpy(ptr, data, size); 1878 unmap(); 1879 } 1880 1881 void GLVertexBuffer::setData(int vertexCount, int dim, const float *vertices, const float *texcoords) 1882 { 1883 const GLVertexAttrib layout[] = { 1884 {VA_Position, dim, GL_FLOAT, 0}, 1885 {VA_TexCoord, 2, GL_FLOAT, int(dim * sizeof(float))}}; 1886 1887 int stride = (texcoords ? dim + 2 : dim) * sizeof(float); 1888 int attribCount = texcoords ? 2 : 1; 1889 1890 setAttribLayout(layout, attribCount, stride); 1891 setVertexCount(vertexCount); 1892 1893 GLvoid *ptr = map(vertexCount * stride); 1894 d->interleaveArrays((float *)ptr, dim, vertices, texcoords, vertexCount); 1895 unmap(); 1896 } 1897 1898 GLvoid *GLVertexBuffer::map(size_t size) 1899 { 1900 d->mappedSize = size; 1901 d->frameSize += size; 1902 1903 if (d->persistent) { 1904 return d->getIdleRange(size); 1905 } 1906 1907 glBindBuffer(GL_ARRAY_BUFFER, d->buffer); 1908 1909 bool preferBufferSubData = GLPlatform::instance()->preferBufferSubData(); 1910 1911 if (GLVertexBufferPrivate::hasMapBufferRange && !preferBufferSubData) { 1912 return (GLvoid *)d->mapNextFreeRange(size); 1913 } 1914 1915 // If we can't map the buffer we allocate local memory to hold the 1916 // buffer data and return a pointer to it. The data will be submitted 1917 // to the actual buffer object when the user calls unmap(). 1918 if (size_t(d->dataStore.size()) < size) { 1919 d->dataStore.resize(size); 1920 } 1921 1922 return (GLvoid *)d->dataStore.data(); 1923 } 1924 1925 void GLVertexBuffer::unmap() 1926 { 1927 if (d->persistent) { 1928 d->baseAddress = d->nextOffset; 1929 d->nextOffset += align(d->mappedSize, 8); 1930 d->mappedSize = 0; 1931 return; 1932 } 1933 1934 bool preferBufferSubData = GLPlatform::instance()->preferBufferSubData(); 1935 1936 if (GLVertexBufferPrivate::hasMapBufferRange && !preferBufferSubData) { 1937 glUnmapBuffer(GL_ARRAY_BUFFER); 1938 1939 d->baseAddress = d->nextOffset; 1940 d->nextOffset += align(d->mappedSize, 8); 1941 } else { 1942 // Upload the data from local memory to the buffer object 1943 if (preferBufferSubData) { 1944 if ((d->nextOffset + d->mappedSize) > d->bufferSize) { 1945 d->reallocateBuffer(d->mappedSize); 1946 d->nextOffset = 0; 1947 } 1948 1949 glBufferSubData(GL_ARRAY_BUFFER, d->nextOffset, d->mappedSize, d->dataStore.constData()); 1950 1951 d->baseAddress = d->nextOffset; 1952 d->nextOffset += align(d->mappedSize, 8); 1953 } else { 1954 glBufferData(GL_ARRAY_BUFFER, d->mappedSize, d->dataStore.data(), d->usage); 1955 d->baseAddress = 0; 1956 } 1957 1958 // Free the local memory buffer if it's unlikely to be used again 1959 if (d->usage == GL_STATIC_DRAW) { 1960 d->dataStore = QByteArray(); 1961 } 1962 } 1963 1964 d->mappedSize = 0; 1965 } 1966 1967 void GLVertexBuffer::setVertexCount(int count) 1968 { 1969 d->vertexCount = count; 1970 } 1971 1972 void GLVertexBuffer::setAttribLayout(const GLVertexAttrib *attribs, int count, int stride) 1973 { 1974 // Start by disabling all arrays 1975 d->enabledArrays = 0; 1976 1977 for (int i = 0; i < count; i++) { 1978 const int index = attribs[i].index; 1979 1980 Q_ASSERT(index >= 0 && index < VertexAttributeCount); 1981 Q_ASSERT(!d->enabledArrays[index]); 1982 1983 d->attrib[index].size = attribs[i].size; 1984 d->attrib[index].type = attribs[i].type; 1985 d->attrib[index].offset = attribs[i].relativeOffset; 1986 1987 d->enabledArrays[index] = true; 1988 } 1989 1990 d->stride = stride; 1991 } 1992 1993 void GLVertexBuffer::render(GLenum primitiveMode) 1994 { 1995 render(infiniteRegion(), primitiveMode, false); 1996 } 1997 1998 void GLVertexBuffer::render(const QRegion ®ion, GLenum primitiveMode, bool hardwareClipping) 1999 { 2000 d->bindArrays(); 2001 draw(region, primitiveMode, 0, d->vertexCount, hardwareClipping); 2002 d->unbindArrays(); 2003 } 2004 2005 void GLVertexBuffer::bindArrays() 2006 { 2007 d->bindArrays(); 2008 } 2009 2010 void GLVertexBuffer::unbindArrays() 2011 { 2012 d->unbindArrays(); 2013 } 2014 2015 void GLVertexBuffer::draw(GLenum primitiveMode, int first, int count) 2016 { 2017 draw(infiniteRegion(), primitiveMode, first, count, false); 2018 } 2019 2020 void GLVertexBuffer::draw(const QRegion ®ion, GLenum primitiveMode, int first, int count, bool hardwareClipping) 2021 { 2022 if (primitiveMode == GL_QUADS) { 2023 if (!GLVertexBufferPrivate::s_indexBuffer) { 2024 GLVertexBufferPrivate::s_indexBuffer = std::make_unique<IndexBuffer>(); 2025 } 2026 2027 GLVertexBufferPrivate::s_indexBuffer->bind(); 2028 GLVertexBufferPrivate::s_indexBuffer->accommodate(count / 4); 2029 2030 count = count * 6 / 4; 2031 2032 if (!hardwareClipping) { 2033 glDrawElementsBaseVertex(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, nullptr, first); 2034 } else { 2035 // Clip using scissoring 2036 const GLFramebuffer *current = GLFramebuffer::currentFramebuffer(); 2037 for (const QRect &r : region) { 2038 glScissor(r.x(), current->size().height() - (r.y() + r.height()), r.width(), r.height()); 2039 glDrawElementsBaseVertex(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, nullptr, first); 2040 } 2041 } 2042 return; 2043 } 2044 2045 if (!hardwareClipping) { 2046 glDrawArrays(primitiveMode, first, count); 2047 } else { 2048 // Clip using scissoring 2049 const GLFramebuffer *current = GLFramebuffer::currentFramebuffer(); 2050 for (const QRect &r : region) { 2051 glScissor(r.x(), current->size().height() - (r.y() + r.height()), r.width(), r.height()); 2052 glDrawArrays(primitiveMode, first, count); 2053 } 2054 } 2055 } 2056 2057 bool GLVertexBuffer::supportsIndexedQuads() 2058 { 2059 return GLVertexBufferPrivate::supportsIndexedQuads; 2060 } 2061 2062 bool GLVertexBuffer::isUseColor() const 2063 { 2064 return d->useColor; 2065 } 2066 2067 void GLVertexBuffer::setUseColor(bool enable) 2068 { 2069 d->useColor = enable; 2070 } 2071 2072 void GLVertexBuffer::setColor(const QColor &color, bool enable) 2073 { 2074 d->useColor = enable; 2075 d->color = QVector4D(color.redF(), color.greenF(), color.blueF(), color.alphaF()); 2076 } 2077 2078 void GLVertexBuffer::reset() 2079 { 2080 d->useColor = false; 2081 d->color = QVector4D(0, 0, 0, 1); 2082 d->vertexCount = 0; 2083 } 2084 2085 void GLVertexBuffer::endOfFrame() 2086 { 2087 if (!d->persistent) { 2088 return; 2089 } 2090 2091 // Emit a fence if we have uploaded data 2092 if (d->frameSize > 0) { 2093 d->frameSizes.push(d->frameSize); 2094 d->frameSize = 0; 2095 2096 // Force the buffer to be reallocated at the beginning of the next frame 2097 // if the average frame size is greater than half the size of the buffer 2098 if (unlikely(d->frameSizes.average() > d->bufferSize / 2)) { 2099 deleteAll(d->fences); 2100 glDeleteBuffers(1, &d->buffer); 2101 2102 d->buffer = 0; 2103 d->bufferSize = 0; 2104 d->nextOffset = 0; 2105 d->map = nullptr; 2106 } else { 2107 if (auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)) { 2108 d->fences.push_back(BufferFence{ 2109 .sync = sync, 2110 .nextEnd = intptr_t(d->nextOffset + d->bufferSize)}); 2111 } 2112 } 2113 } 2114 } 2115 2116 void GLVertexBuffer::beginFrame() 2117 { 2118 if (!d->persistent) { 2119 return; 2120 } 2121 2122 // Remove finished fences from the list and update the bufferEnd offset 2123 while (d->fences.size() > 1 && d->fences.front().signaled()) { 2124 const BufferFence &fence = d->fences.front(); 2125 glDeleteSync(fence.sync); 2126 2127 d->bufferEnd = fence.nextEnd; 2128 d->fences.pop_front(); 2129 } 2130 } 2131 2132 void GLVertexBuffer::initStatic() 2133 { 2134 if (GLPlatform::instance()->isGLES()) { 2135 bool haveBaseVertex = hasGLExtension(QByteArrayLiteral("GL_OES_draw_elements_base_vertex")); 2136 bool haveCopyBuffer = hasGLVersion(3, 0); 2137 bool haveMapBufferRange = hasGLExtension(QByteArrayLiteral("GL_EXT_map_buffer_range")); 2138 2139 GLVertexBufferPrivate::hasMapBufferRange = haveMapBufferRange; 2140 GLVertexBufferPrivate::supportsIndexedQuads = haveBaseVertex && haveCopyBuffer && haveMapBufferRange; 2141 GLVertexBufferPrivate::haveBufferStorage = hasGLExtension("GL_EXT_buffer_storage"); 2142 GLVertexBufferPrivate::haveSyncFences = hasGLVersion(3, 0); 2143 } else { 2144 bool haveBaseVertex = hasGLVersion(3, 2) || hasGLExtension(QByteArrayLiteral("GL_ARB_draw_elements_base_vertex")); 2145 bool haveCopyBuffer = hasGLVersion(3, 1) || hasGLExtension(QByteArrayLiteral("GL_ARB_copy_buffer")); 2146 bool haveMapBufferRange = hasGLVersion(3, 0) || hasGLExtension(QByteArrayLiteral("GL_ARB_map_buffer_range")); 2147 2148 GLVertexBufferPrivate::hasMapBufferRange = haveMapBufferRange; 2149 GLVertexBufferPrivate::supportsIndexedQuads = haveBaseVertex && haveCopyBuffer && haveMapBufferRange; 2150 GLVertexBufferPrivate::haveBufferStorage = hasGLVersion(4, 4) || hasGLExtension("GL_ARB_buffer_storage"); 2151 GLVertexBufferPrivate::haveSyncFences = hasGLVersion(3, 2) || hasGLExtension("GL_ARB_sync"); 2152 } 2153 GLVertexBufferPrivate::s_indexBuffer.reset(); 2154 GLVertexBufferPrivate::streamingBuffer = std::make_unique<GLVertexBuffer>(GLVertexBuffer::Stream); 2155 2156 if (GLVertexBufferPrivate::haveBufferStorage && GLVertexBufferPrivate::haveSyncFences) { 2157 if (qgetenv("KWIN_PERSISTENT_VBO") != QByteArrayLiteral("0")) { 2158 GLVertexBufferPrivate::streamingBuffer->d->persistent = true; 2159 } 2160 } 2161 } 2162 2163 void GLVertexBuffer::cleanup() 2164 { 2165 GLVertexBufferPrivate::s_indexBuffer.reset(); 2166 GLVertexBufferPrivate::hasMapBufferRange = false; 2167 GLVertexBufferPrivate::supportsIndexedQuads = false; 2168 GLVertexBufferPrivate::streamingBuffer.reset(); 2169 } 2170 2171 GLVertexBuffer *GLVertexBuffer::streamingBuffer() 2172 { 2173 return GLVertexBufferPrivate::streamingBuffer.get(); 2174 } 2175 2176 } // namespace