From 33d0a8d753883e6b33ba8610c52f7fee42d6d9f1 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 23 Apr 2014 09:08:16 +0200 Subject: Remove direct OpenGL calls from QtOpenGL Task-number: QTBUG-36483 Change-Id: I96dea5649c0a49a11cd2ff31da659cd2067e769d Reviewed-by: Friedemann Kleint --- src/opengl/gl2paintengineex/qglgradientcache.cpp | 14 +- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 95 +++---- .../gl2paintengineex/qpaintengineex_opengl2_p.h | 8 +- .../gl2paintengineex/qtextureglyphcache_gl.cpp | 81 +++--- .../gl2paintengineex/qtextureglyphcache_gl_p.h | 2 +- src/opengl/qgl.cpp | 284 ++++++++++++--------- src/opengl/qgl_p.h | 2 +- src/opengl/qgl_qpa.cpp | 2 +- src/opengl/qglbuffer.cpp | 4 +- src/opengl/qglframebufferobject.cpp | 32 +-- src/opengl/qglpaintdevice.cpp | 9 +- src/opengl/qglpixelbuffer.cpp | 27 +- src/opengl/qglshaderprogram.cpp | 5 +- tests/auto/gui/qopengl/tst_qopengl.cpp | 14 +- tests/auto/opengl/qgl/tst_qgl.cpp | 35 +-- .../auto/opengl/qglfunctions/tst_qglfunctions.cpp | 20 +- tests/auto/opengl/qglthreads/tst_qglthreads.cpp | 53 ++-- 17 files changed, 374 insertions(+), 313 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp index 6160554472..d2b6842a8a 100644 --- a/src/opengl/gl2paintengineex/qglgradientcache.cpp +++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp @@ -89,11 +89,12 @@ void QGL2GradientCache::freeResource(QOpenGLContext *) void QGL2GradientCache::cleanCache() { + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); QMutexLocker lock(&m_mutex); QGLGradientColorTableHash::const_iterator it = cache.constBegin(); for (; it != cache.constEnd(); ++it) { const CacheInfo &cache_info = it.value(); - glDeleteTextures(1, &cache_info.texId); + funcs->glDeleteTextures(1, &cache_info.texId); } cache.clear(); } @@ -129,6 +130,7 @@ GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity) GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity) { + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); if (cache.size() == maxCacheSize()) { int elem_to_remove = qrand() % maxCacheSize(); quint64 key = cache.keys()[elem_to_remove]; @@ -136,7 +138,7 @@ GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gra // need to call glDeleteTextures on each removed cache entry: QGLGradientColorTableHash::const_iterator it = cache.constFind(key); do { - glDeleteTextures(1, &it.value().texId); + funcs->glDeleteTextures(1, &it.value().texId); } while (++it != cache.constEnd() && it.key() == key); cache.remove(key); // may remove more than 1, but OK } @@ -144,10 +146,10 @@ GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gra CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode()); uint buffer[1024]; generateGradientColorTable(gradient, buffer, paletteSize(), opacity); - glGenTextures(1, &cache_entry.texId); - glBindTexture(GL_TEXTURE_2D, cache_entry.texId); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1, - 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + funcs->glGenTextures(1, &cache_entry.texId); + funcs->glBindTexture(GL_TEXTURE_2D, cache_entry.texId); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1, + 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); return cache.insert(hash_val, cache_entry).value().texId; } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 2b49e4d2d1..162ae9fe79 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -86,6 +86,10 @@ #include +#ifndef QT_OPENGL_ES_2 +# include +#endif + QT_BEGIN_NAMESPACE @@ -106,7 +110,7 @@ QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate() } if (elementIndicesVBOId != 0) { - funcs.glDeleteBuffers(1, &elementIndicesVBOId); + glDeleteBuffers(1, &elementIndicesVBOId); elementIndicesVBOId = 0; } } @@ -193,7 +197,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() // Get the image data for the pattern QImage texImage = qt_imageForBrush(style, false); - funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); + glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); ctx->d_func()->bindTexture(texImage, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); } @@ -206,7 +210,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() // for opacity to the cache. GLuint texId = QGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0); - funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); + glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); glBindTexture(GL_TEXTURE_2D, texId); if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient) @@ -223,7 +227,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size) currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); - funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); + glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); QGLTexture *tex = ctx->d_func()->bindTexture(currentBrushPixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption | QGLContext::CanFlipNativePixmapBindOption); @@ -420,9 +424,9 @@ void QGL2PaintEngineExPrivate::updateMatrix() // Set the PMV matrix attribute. As we use an attributes rather than uniforms, we only // need to do this once for every matrix change and persists across all shader programs. - funcs.glVertexAttrib3fv(QT_PMV_MATRIX_1_ATTR, pmvMatrix[0]); - funcs.glVertexAttrib3fv(QT_PMV_MATRIX_2_ATTR, pmvMatrix[1]); - funcs.glVertexAttrib3fv(QT_PMV_MATRIX_3_ATTR, pmvMatrix[2]); + glVertexAttrib3fv(QT_PMV_MATRIX_1_ATTR, pmvMatrix[0]); + glVertexAttrib3fv(QT_PMV_MATRIX_2_ATTR, pmvMatrix[1]); + glVertexAttrib3fv(QT_PMV_MATRIX_3_ATTR, pmvMatrix[2]); dasher.setInvScale(inverseScale); stroker.setInvScale(inverseScale); @@ -532,11 +536,11 @@ void QGL2PaintEngineEx::beginNativePainting() d->nativePaintingActive = true; - d->funcs.glUseProgram(0); + d->glUseProgram(0); // Disable all the vertex attribute arrays: for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) - d->funcs.glDisableVertexAttribArray(i); + d->glDisableVertexAttribArray(i); #ifndef QT_OPENGL_ES_2 if (!d->ctx->contextHandle()->isES()) { @@ -561,12 +565,15 @@ void QGL2PaintEngineEx::beginNativePainting() const QSize sz = d->device->size(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999); + QOpenGLFunctions_1_1 *gl1funcs = QOpenGLContext::currentContext()->versionFunctions(); + gl1funcs->initializeOpenGLFunctions(); - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(&mv_matrix[0][0]); + gl1funcs->glMatrixMode(GL_PROJECTION); + gl1funcs->glLoadIdentity(); + gl1funcs->glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999); + + gl1funcs->glMatrixMode(GL_MODELVIEW); + gl1funcs->glLoadMatrixf(&mv_matrix[0][0]); } } #endif @@ -583,13 +590,13 @@ void QGL2PaintEngineEx::beginNativePainting() void QGL2PaintEngineExPrivate::resetGLState() { glDisable(GL_BLEND); - funcs.glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE0); glDisable(GL_STENCIL_TEST); glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); glDepthMask(true); glDepthFunc(GL_LESS); - funcs.glClearDepthf(1); + glClearDepthf(1); glStencilMask(0xff); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_ALWAYS, 0, 0xff); @@ -600,7 +607,7 @@ void QGL2PaintEngineExPrivate::resetGLState() if (!ctx->contextHandle()->isES()) { // gl_Color, corresponding to vertex attribute 3, may have been changed float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - funcs.glVertexAttrib4fv(3, color); + glVertexAttrib4fv(3, color); } #endif } @@ -750,7 +757,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) qreal scaleFactor = cache->iscale / inverseScale; if (scaleFactor < 0.5 || scaleFactor > 2.0) { #ifdef QT_OPENGL_CACHE_AS_VBOS - funcs.glDeleteBuffers(1, &cache->vbo); + glDeleteBuffers(1, &cache->vbo); cache->vbo = 0; Q_ASSERT(cache->ibo == 0); #else @@ -777,9 +784,9 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) cache->primitiveType = GL_TRIANGLE_FAN; cache->iscale = inverseScale; #ifdef QT_OPENGL_CACHE_AS_VBOS - funcs.glGenBuffers(1, &cache->vbo); - funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); - funcs.glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW); + glGenBuffers(1, &cache->vbo); + glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); + glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW); cache->ibo = 0; #else cache->vertices = (float *) malloc(floatSizeInBytes); @@ -790,7 +797,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) prepareForDraw(currentBrush.isOpaque()); #ifdef QT_OPENGL_CACHE_AS_VBOS - funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); + glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0); #else setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices); @@ -1016,9 +1023,9 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, } // Inc. for front-facing triangle - funcs.glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP); + glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP); // Dec. for back-facing "holes" - funcs.glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP); + glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP); glStencilMask(~GL_STENCIL_HIGH_BIT); drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN); @@ -1367,9 +1374,9 @@ void QGL2PaintEngineEx::renderHintsChanged() if (!d->ctx->contextHandle()->isES()) { if ((state()->renderHints & QPainter::Antialiasing) || (state()->renderHints & QPainter::HighQualityAntialiasing)) - glEnable(GL_MULTISAMPLE); + d->glEnable(GL_MULTISAMPLE); else - glDisable(GL_MULTISAMPLE); + d->glDisable(GL_MULTISAMPLE); } #endif @@ -1415,7 +1422,7 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c bindOptions |= QGLContext::TemporarilyCachedBindOption; #endif - d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); + d->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); QGLTexture *texture = ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, bindOptions); @@ -1457,7 +1464,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const ensureActive(); d->transferMode(ImageDrawingMode); - d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); + d->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); QGLContext::BindOptions bindOptions = QGLContext::InternalBindOption; #ifdef QGL_USE_TEXTURE_POOL @@ -1518,8 +1525,8 @@ bool QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const ensureActive(); d->transferMode(ImageDrawingMode); - d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - glBindTexture(GL_TEXTURE_2D, textureId); + d->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); + d->glBindTexture(GL_TEXTURE_2D, textureId); QGLRect srcRect(src.left(), src.bottom(), src.right(), src.top()); @@ -1804,7 +1811,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat glyphFo glEnable(GL_BLEND); glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR); - funcs.glBlendColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); + glBlendColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); } else { // Other brush styles need two passes. @@ -1821,7 +1828,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat glyphFo glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); + glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); glBindTexture(GL_TEXTURE_2D, cache->texture()); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); @@ -1856,7 +1863,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat glyphFo QGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QGLTextureGlyphCache::Linear:QGLTextureGlyphCache::Nearest; if (lastMaskTextureUsed != cache->texture() || cache->filterMode() != filterMode) { - funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); + glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); if (lastMaskTextureUsed != cache->texture()) { glBindTexture(GL_TEXTURE_2D, cache->texture()); lastMaskTextureUsed = cache->texture(); @@ -1957,7 +1964,7 @@ void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragmen allOpaque &= (opacity >= 0.99f); } - funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); + glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); QGLTexture *texture = ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption | QGLContext::CanFlipNativePixmapBindOption); @@ -2031,17 +2038,17 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) // go after beginPaint: d->device->beginPaint(); - d->funcs.initializeOpenGLFunctions(); + d->initializeOpenGLFunctions(); d->shaderManager = new QGLEngineShaderManager(d->ctx); - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); + d->glDisable(GL_STENCIL_TEST); + d->glDisable(GL_DEPTH_TEST); + d->glDisable(GL_SCISSOR_TEST); #if !defined(QT_OPENGL_ES_2) if (!d->ctx->contextHandle()->isES()) - glDisable(GL_MULTISAMPLE); + d->glDisable(GL_MULTISAMPLE); #endif d->glyphCacheFormat = QFontEngine::Format_A8; @@ -2067,7 +2074,7 @@ bool QGL2PaintEngineEx::end() Q_D(QGL2PaintEngineEx); QGLContext *ctx = d->ctx; - d->funcs.glUseProgram(0); + d->glUseProgram(0); d->transferMode(BrushDrawingMode); d->device->endPaint(); @@ -2081,11 +2088,11 @@ bool QGL2PaintEngineEx::end() #ifdef QT_OPENGL_CACHE_AS_VBOS if (!d->unusedVBOSToClean.isEmpty()) { - glDeleteBuffers(d->unusedVBOSToClean.size(), d->unusedVBOSToClean.constData()); + d->glDeleteBuffers(d->unusedVBOSToClean.size(), d->unusedVBOSToClean.constData()); d->unusedVBOSToClean.clear(); } if (!d->unusedIBOSToClean.isEmpty()) { - glDeleteBuffers(d->unusedIBOSToClean.size(), d->unusedIBOSToClean.constData()); + d->glDeleteBuffers(d->unusedIBOSToClean.size(), d->unusedIBOSToClean.constData()); d->unusedIBOSToClean.clear(); } #endif @@ -2107,7 +2114,7 @@ void QGL2PaintEngineEx::ensureActive() if (d->needsSync) { d->transferMode(BrushDrawingMode); - glViewport(0, 0, d->width, d->height); + d->glViewport(0, 0, d->width, d->height); d->needsSync = false; d->lastMaskTextureUsed = 0; d->shaderManager->setDirty(); @@ -2428,7 +2435,7 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state) if (old_state == s || old_state->clipChanged) { if (old_state && old_state != s && old_state->canRestoreClip) { d->updateClipScissorTest(); - glDepthFunc(GL_LEQUAL); + d->glDepthFunc(GL_LEQUAL); } else { d->regenerateClip(); } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 15ed5bc57d..e851ccac18 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -165,7 +165,7 @@ private: Q_DISABLE_COPY(QGL2PaintEngineEx) }; -class QGL2PaintEngineExPrivate : public QPaintEngineExPrivate +class QGL2PaintEngineExPrivate : public QPaintEngineExPrivate, protected QOpenGLExtensions { Q_DECLARE_PUBLIC(QGL2PaintEngineEx) public: @@ -261,8 +261,6 @@ public: EngineMode mode; QFontEngine::GlyphFormat glyphCacheFormat; - QOpenGLExtensions funcs; - // Dirty flags bool matrixDirty; // Implies matrix uniforms are also dirty bool compositionModeDirty; @@ -327,9 +325,9 @@ void QGL2PaintEngineExPrivate::setVertexAttributePointer(unsigned int arrayIndex vertexAttribPointers[arrayIndex] = pointer; if (arrayIndex == QT_OPACITY_ATTR) - funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, pointer); + glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, pointer); else - funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, pointer); + glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, pointer); } QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index b1e289254f..01dfb38857 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -96,6 +96,7 @@ void QGLTextureGlyphCache::createTextureData(int width, int height) qWarning("QGLTextureGlyphCache::createTextureData: Called with no context"); return; } + QOpenGLFunctions *funcs = ctx->contextHandle()->functions(); // create in QImageTextureGlyphCache baseclass is meant to be called // only to create the initial image and does not preserve the content, @@ -117,8 +118,8 @@ void QGLTextureGlyphCache::createTextureData(int width, int height) if (!m_textureResource) m_textureResource = new QGLGlyphTexture(ctx); - glGenTextures(1, &m_textureResource->m_texture); - glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); + funcs->glGenTextures(1, &m_textureResource->m_texture); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); m_textureResource->m_width = width; m_textureResource->m_height = height; @@ -127,18 +128,18 @@ void QGLTextureGlyphCache::createTextureData(int width, int height) QVarLengthArray data(width * height * 4); for (int i = 0; i < data.size(); ++i) data[i] = 0; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); } else { QVarLengthArray data(width * height); for (int i = 0; i < data.size(); ++i) data[i] = 0; - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]); } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); m_filterMode = Nearest; } @@ -149,6 +150,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) qWarning("QGLTextureGlyphCache::resizeTextureData: Called with no context"); return; } + QOpenGLFunctions *funcs = ctx->contextHandle()->functions(); int oldWidth = m_textureResource->m_width; int oldHeight = m_textureResource->m_height; @@ -165,44 +167,42 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) if (!QGLFramebufferObject::hasOpenGLFramebufferObjects() || ctx->d_ptr->workaround_brokenFBOReadBack) { QImageTextureGlyphCache::resizeTextureData(width, height); Q_ASSERT(image().depth() == 8); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); - glDeleteTextures(1, &oldTexture); + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); + funcs->glDeleteTextures(1, &oldTexture); return; } - QOpenGLFunctions *funcs = ctx->contextHandle()->functions(); - // ### the QTextureGlyphCache API needs to be reworked to allow // ### resizeTextureData to fail funcs->glBindFramebuffer(GL_FRAMEBUFFER, m_textureResource->m_fbo); GLuint tmp_texture; - glGenTextures(1, &tmp_texture); - glBindTexture(GL_TEXTURE_2D, tmp_texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + funcs->glGenTextures(1, &tmp_texture); + funcs->glBindTexture(GL_TEXTURE_2D, tmp_texture); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); m_filterMode = Nearest; - glBindTexture(GL_TEXTURE_2D, 0); + funcs->glBindTexture(GL_TEXTURE_2D, 0); funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_texture, 0); funcs->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - glBindTexture(GL_TEXTURE_2D, oldTexture); + funcs->glBindTexture(GL_TEXTURE_2D, oldTexture); if (pex != 0) pex->transferMode(BrushDrawingMode); - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); + funcs->glDisable(GL_STENCIL_TEST); + funcs->glDisable(GL_DEPTH_TEST); + funcs->glDisable(GL_SCISSOR_TEST); + funcs->glDisable(GL_BLEND); - glViewport(0, 0, oldWidth, oldHeight); + funcs->glViewport(0, 0, oldWidth, oldHeight); QGLShaderProgram *blitProgram = 0; if (pex == 0) { @@ -257,21 +257,21 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) blitProgram->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + funcs->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight); + funcs->glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight); funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0); - glDeleteTextures(1, &tmp_texture); - glDeleteTextures(1, &oldTexture); + funcs->glDeleteTextures(1, &tmp_texture); + funcs->glDeleteTextures(1, &oldTexture); funcs->glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo); if (pex != 0) { - glViewport(0, 0, pex->width, pex->height); + funcs->glViewport(0, 0, pex->width, pex->height); pex->updateClipScissorTest(); } } @@ -283,16 +283,17 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub qWarning("QGLTextureGlyphCache::fillTexture: Called with no context"); return; } + QOpenGLFunctions *funcs = ctx->contextHandle()->functions(); if (!QGLFramebufferObject::hasOpenGLFramebufferObjects() || ctx->d_ptr->workaround_brokenFBOReadBack) { QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition); - glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); const QImage &texture = image(); const uchar *bits = texture.constBits(); bits += c.y * texture.bytesPerLine() + c.x; for (int i=0; iglTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits); bits += texture.bytesPerLine(); } return; @@ -329,14 +330,14 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub } } - glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); if (mask.format() == QImage::Format_RGB32) { GLenum format = GL_RGBA; #if !defined(QT_OPENGL_ES_2) if (!ctx->contextHandle()->isES()) format = GL_BGRA; #endif - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, format, GL_UNSIGNED_BYTE, mask.bits()); + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, format, GL_UNSIGNED_BYTE, mask.bits()); } else { // glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is // not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista @@ -349,16 +350,16 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub if (!ctx->d_ptr->workaround_brokenAlphaTexSubImage_init) { // don't know which driver versions exhibit this bug, so be conservative for now - const QByteArray vendorString(reinterpret_cast(glGetString(GL_VENDOR))); + const QByteArray vendorString(reinterpret_cast(funcs->glGetString(GL_VENDOR))); ctx->d_ptr->workaround_brokenAlphaTexSubImage = vendorString.indexOf("NVIDIA") >= 0; ctx->d_ptr->workaround_brokenAlphaTexSubImage_init = true; } if (ctx->d_ptr->workaround_brokenAlphaTexSubImage) { for (int i = 0; i < maskHeight; ++i) - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i)); + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i)); } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits()); + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits()); } } } diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h index 5ffbea8708..5c160ffd59 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h @@ -92,7 +92,7 @@ struct QGLGlyphTexture : public QOpenGLSharedResource if (ctx && m_fbo) ctx->contextHandle()->functions()->glDeleteFramebuffers(1, &m_fbo); if (m_width || m_height) - glDeleteTextures(1, &m_texture); + ctx->contextHandle()->functions()->glDeleteTextures(1, &m_texture); } void invalidateResource() diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 3cfdcc549c..f4bf8fd68b 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -70,6 +70,10 @@ #include "qlibrary.h" #include +#ifndef QT_OPENGL_ES_2 +#include +#endif + // #define QT_GL_CONTEXT_RESOURCE_DEBUG QT_BEGIN_NAMESPACE @@ -107,6 +111,7 @@ bool qgl_hasExtension(QOpenGLExtensions::OpenGLExtension extension) } QOpenGLExtensions::OpenGLExtensions extensions; + /* Returns the GL extensions for the current QOpenGLContext. If there is no current QOpenGLContext, a default context will be created and the extensions @@ -121,6 +126,20 @@ QOpenGLExtensions* qgl_extensions() return 0; } +QOpenGLFunctions *qgl_functions() +{ + return qgl_extensions(); // QOpenGLExtensions is just a subclass of QOpenGLFunctions +} + +#ifndef QT_OPENGL_ES_2 +QOpenGLFunctions_1_1 *qgl1_functions() +{ + QOpenGLFunctions_1_1 *f = QOpenGLContext::currentContext()->versionFunctions(); + f->initializeOpenGLFunctions(); + return f; +} +#endif + struct QGLThreadContext { ~QGLThreadContext() { if (context) @@ -1355,7 +1374,7 @@ QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags() } } - QString versionString(QLatin1String(reinterpret_cast(glGetString(GL_VERSION)))); + QString versionString(QLatin1String(reinterpret_cast(qgl_functions()->glGetString(GL_VERSION)))); OpenGLVersionFlags versionFlags = qOpenGLVersionFlagsFromString(versionString); if (currentCtx) { currentCtx->d_func()->version_flags_cached = true; @@ -1687,7 +1706,7 @@ QImage qt_gl_read_frame_buffer(const QSize &size, bool alpha_format, bool includ return QImage(); int w = size.width(); int h = size.height(); - glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); + qgl_functions()->glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); convertFromGLImage(img, w, h, alpha_format, include_alpha); return img; } @@ -1701,8 +1720,8 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp int h = size.height(); #ifndef QT_OPENGL_ES if (!QOpenGLContext::currentContext()->isES()) { - //### glGetTexImage not in GL ES 2.0, need to do something else here! - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); + + qgl1_functions()->glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); } #endif // QT_OPENGL_ES convertFromGLImage(img, w, h, alpha_format, include_alpha); @@ -2193,7 +2212,7 @@ QGLTexture *QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G q->deleteTexture(texture->id); texture = 0; } else { - glBindTexture(target, texture->id); + qgl_functions()->glBindTexture(target, texture->id); return texture; } } @@ -2245,6 +2264,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G const qint64 key, QGLContext::BindOptions options) { Q_Q(QGLContext); + QOpenGLFunctions *funcs = qgl_functions(); #ifdef QGL_BIND_TEXTURE_DEBUG printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x, key=%llx\n", @@ -2255,7 +2275,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G #ifndef QT_NO_DEBUG // Reset the gl error stack...git - while (glGetError() != GL_NO_ERROR) ; + while (funcs->glGetError() != GL_NO_ERROR) ; #endif // Scale the pixmap if needed. GL textures needs to have the @@ -2280,9 +2300,9 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G GLuint filtering = options & QGLContext::LinearFilteringBindOption ? GL_LINEAR : GL_NEAREST; GLuint tx_id; - glGenTextures(1, &tx_id); - glBindTexture(target, tx_id); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filtering); + funcs->glGenTextures(1, &tx_id); + funcs->glBindTexture(target, tx_id); + funcs->glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filtering); QOpenGLContext *ctx = QOpenGLContext::currentContext(); bool genMipmap = !ctx->isES(); @@ -2293,23 +2313,23 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G { #if !defined(QT_OPENGL_ES_2) if (genMipmap) { - glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); - glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); + funcs->glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); + funcs->glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); } else { - glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); + funcs->glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); genMipmap = true; } #else - glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); + funcs->glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); genMipmap = true; #endif - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, options & QGLContext::LinearFilteringBindOption - ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST); + funcs->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, options & QGLContext::LinearFilteringBindOption + ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST); #ifdef QGL_BIND_TEXTURE_DEBUG printf(" - generating mipmaps (%d ms)\n", time.elapsed()); #endif } else { - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filtering); + funcs->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filtering); } QImage::Format target_format = img.format(); @@ -2438,12 +2458,12 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G #endif const QImage &constRef = img; // to avoid detach in bits()... - glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat, - pixel_type, constRef.bits()); + funcs->glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat, + pixel_type, constRef.bits()); if (genMipmap && ctx->isES()) q->functions()->glGenerateMipmap(target); #ifndef QT_NO_DEBUG - GLenum error = glGetError(); + GLenum error = funcs->glGetError(); if (error != GL_NO_ERROR) { qWarning(" - texture upload failed, error code 0x%x, enum: %d (%x)\n", error, target, target); } @@ -2491,7 +2511,7 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, q->deleteTexture(texture->id); texture = 0; } else { - glBindTexture(target, texture->id); + qgl_functions()->glBindTexture(target, texture->id); return texture; } } @@ -2520,7 +2540,8 @@ int QGLContextPrivate::maxTextureSize() if (max_texture_size != -1) return max_texture_size; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); + QOpenGLFunctions *funcs = qgl_functions(); + funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); #ifndef QT_OPENGL_ES Q_Q(QGLContext); @@ -2529,8 +2550,9 @@ int QGLContextPrivate::maxTextureSize() GLint size; GLint next = 64; - glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); + funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); + gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); if (size == 0) { return max_texture_size; } @@ -2540,8 +2562,8 @@ int QGLContextPrivate::maxTextureSize() if (next > max_texture_size) break; - glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); + funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); } while (next > size); max_texture_size = size; @@ -2658,7 +2680,7 @@ void QGLContext::deleteTexture(GLuint id) { if (QGLTextureCache::instance()->remove(this, id)) return; - glDeleteTextures(1, &id); + qgl_functions()->glDeleteTextures(1, &id); } void qt_add_rect_to_array(const QRectF &r, GLfloat *array) @@ -2694,6 +2716,7 @@ void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, GLfloat * static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint textureHeight, GLenum textureTarget) { + QOpenGLFunctions *funcs = qgl_functions(); GLfloat tx = 1.0f; GLfloat ty = 1.0f; @@ -2704,8 +2727,9 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex #else if (textureTarget != GL_TEXTURE_2D && !QOpenGLContext::currentContext()->isES()) { if (textureWidth == -1 || textureHeight == -1) { - glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); - glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); + QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); + gl1funcs->glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); + gl1funcs->glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); } tx = GLfloat(textureWidth); @@ -2720,15 +2744,16 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex GLfloat vertexArray[4*2]; qt_add_rect_to_array(target, vertexArray); - glVertexPointer(2, GL_FLOAT, 0, vertexArray); - glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); + QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); + gl1funcs->glVertexPointer(2, GL_FLOAT, 0, vertexArray); + gl1funcs->glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + gl1funcs->glEnableClientState(GL_VERTEX_ARRAY); + gl1funcs->glEnableClientState(GL_TEXTURE_COORD_ARRAY); + funcs->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + gl1funcs->glDisableClientState(GL_VERTEX_ARRAY); + gl1funcs->glDisableClientState(GL_TEXTURE_COORD_ARRAY); } #endif // !QT_OPENGL_ES_2 @@ -2769,6 +2794,7 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text #endif #ifndef QT_OPENGL_ES_2 + QOpenGLFunctions *funcs = qgl_functions(); if (!contextHandle()->isES()) { #ifdef QT_OPENGL_ES if (textureTarget != GL_TEXTURE_2D) { @@ -2776,22 +2802,22 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text return; } #else - const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); + const bool wasEnabled = funcs->glIsEnabled(GL_TEXTURE_2D); GLint oldTexture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); + funcs->glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); #endif - glEnable(textureTarget); - glBindTexture(textureTarget, textureId); + funcs->glEnable(textureTarget); + funcs->glBindTexture(textureTarget, textureId); qDrawTextureRect(target, -1, -1, textureTarget); #ifdef QT_OPENGL_ES - glDisable(textureTarget); + funcs->glDisable(textureTarget); #else if (!wasEnabled) - glDisable(textureTarget); - glBindTexture(textureTarget, oldTexture); + funcs->glDisable(textureTarget); + funcs->glBindTexture(textureTarget, oldTexture); #endif return; } @@ -2832,18 +2858,20 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text Q_UNUSED(textureTarget); #else if (!contextHandle()->isES()) { - const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); + QOpenGLFunctions *funcs = qgl_functions(); + const bool wasEnabled = funcs->glIsEnabled(GL_TEXTURE_2D); GLint oldTexture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); + funcs->glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); - glEnable(textureTarget); - glBindTexture(textureTarget, textureId); + funcs->glEnable(textureTarget); + funcs->glBindTexture(textureTarget, textureId); GLint textureWidth; GLint textureHeight; - glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); - glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); + QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); + gl1funcs->glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); + gl1funcs->glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); if (d_ptr->active_engine && d_ptr->active_engine->type() == QPaintEngine::OpenGL2) { @@ -2860,8 +2888,8 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget); if (!wasEnabled) - glDisable(textureTarget); - glBindTexture(textureTarget, oldTexture); + funcs->glDisable(textureTarget); + funcs->glBindTexture(textureTarget, oldTexture); return; } #endif @@ -3909,7 +3937,7 @@ void QGLWidget::initializeGL() void QGLWidget::paintGL() { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + qgl_functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -4136,7 +4164,7 @@ void QGLWidget::glDraw() makeCurrent(); #ifndef QT_OPENGL_ES if (d->glcx->deviceIsPixmap() && !d->glcx->contextHandle()->isES()) - glDrawBuffer(GL_FRONT); + qgl1_functions()->glDrawBuffer(GL_FRONT); #endif QSize readback_target_size = d->glcx->d_ptr->readback_target_size; if (!d->glcx->initialized()) { @@ -4158,7 +4186,7 @@ void QGLWidget::glDraw() if (d->autoSwap) swapBuffers(); } else { - glFlush(); + qgl_functions()->glFlush(); } } @@ -4176,20 +4204,20 @@ void QGLWidget::qglColor(const QColor& c) const { #if !defined(QT_OPENGL_ES_2) #ifdef QT_OPENGL_ES - glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF()); + qgl_functions()->glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF()); #else Q_D(const QGLWidget); const QGLContext *ctx = QGLContext::currentContext(); if (ctx && !ctx->contextHandle()->isES()) { if (ctx->format().rgba()) - glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF()); + qgl1_functions()->glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF()); else if (!d->cmap.isEmpty()) { // QGLColormap in use? int i = d->cmap.find(c.rgb()); if (i < 0) i = d->cmap.findNearest(c.rgb()); - glIndexi(i); + qgl1_functions()->glIndexi(i); } else - glIndexi(ctx->colorIndex(c)); + qgl1_functions()->glIndexi(ctx->colorIndex(c)); } #endif //QT_OPENGL_ES #else @@ -4208,23 +4236,23 @@ void QGLWidget::qglColor(const QColor& c) const void QGLWidget::qglClearColor(const QColor& c) const { #ifdef QT_OPENGL_ES - glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); + qgl_functions()->glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); #else Q_D(const QGLWidget); const QGLContext *ctx = QGLContext::currentContext(); if (ctx && !ctx->contextHandle()->isES()) { if (ctx->format().rgba()) - glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); + qgl_functions()->glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); else if (!d->cmap.isEmpty()) { // QGLColormap in use? int i = d->cmap.find(c.rgb()); if (i < 0) i = d->cmap.findNearest(c.rgb()); - glClearIndex(i); + qgl1_functions()->glClearIndex(i); } else { - glClearIndex(ctx->colorIndex(c)); + qgl1_functions()->glClearIndex(ctx->colorIndex(c)); } } else { - glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); + qgl_functions()->glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); } #endif } @@ -4307,42 +4335,47 @@ QImage QGLWidget::convertToGLFormat(const QImage& img) static void qt_save_gl_state() { - glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); - glPushAttrib(GL_ALL_ATTRIB_BITS); - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - glShadeModel(GL_FLAT); - glDisable(GL_CULL_FACE); - glDisable(GL_LIGHTING); - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + QOpenGLFunctions *funcs = qgl_functions(); + QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); + + gl1funcs->glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); + gl1funcs->glPushAttrib(GL_ALL_ATTRIB_BITS); + gl1funcs->glMatrixMode(GL_TEXTURE); + gl1funcs->glPushMatrix(); + gl1funcs->glLoadIdentity(); + gl1funcs->glMatrixMode(GL_PROJECTION); + gl1funcs->glPushMatrix(); + gl1funcs->glMatrixMode(GL_MODELVIEW); + gl1funcs->glPushMatrix(); + + gl1funcs->glShadeModel(GL_FLAT); + funcs->glDisable(GL_CULL_FACE); + funcs->glDisable(GL_LIGHTING); + funcs->glDisable(GL_STENCIL_TEST); + funcs->glDisable(GL_DEPTH_TEST); + funcs->glEnable(GL_BLEND); + funcs->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } static void qt_restore_gl_state() { - glMatrixMode(GL_TEXTURE); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glPopAttrib(); - glPopClientAttrib(); + QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); + + gl1funcs->glMatrixMode(GL_TEXTURE); + gl1funcs->glPopMatrix(); + gl1funcs->glMatrixMode(GL_PROJECTION); + gl1funcs->glPopMatrix(); + gl1funcs->glMatrixMode(GL_MODELVIEW); + gl1funcs->glPopMatrix(); + gl1funcs->glPopAttrib(); + gl1funcs->glPopClientAttrib(); } static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str, const QFont &font) { GLfloat color[4]; - glGetFloatv(GL_CURRENT_COLOR, &color[0]); + qgl_functions()->glGetFloatv(GL_CURRENT_COLOR, &color[0]); QColor col; col.setRgbF(color[0], color[1], color[2],color[3]); @@ -4392,10 +4425,11 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font) if (str.isEmpty() || !isValid()) return; + QOpenGLFunctions *funcs = qgl_functions(); GLint view[4]; - bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST); + bool use_scissor_testing = funcs->glIsEnabled(GL_SCISSOR_TEST); if (!use_scissor_testing) - glGetIntegerv(GL_VIEWPORT, &view[0]); + funcs->glGetIntegerv(GL_VIEWPORT, &view[0]); int width = d->glcx->device()->width(); int height = d->glcx->device()->height(); bool auto_swap = autoBufferSwap(); @@ -4410,8 +4444,8 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font) reuse_painter = true; p = engine->painter(); - glDisable(GL_DEPTH_TEST); - glViewport(0, 0, width, height); + funcs->glDisable(GL_DEPTH_TEST); + funcs->glViewport(0, 0, width, height); } else { setAutoBufferSwap(false); // disable glClear() as a result of QPainter::begin() @@ -4423,11 +4457,11 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font) if (!use_scissor_testing && viewport != rect()) { // if the user hasn't set a scissor box, we set one that // covers the current viewport - glScissor(view[0], view[1], view[2], view[3]); - glEnable(GL_SCISSOR_TEST); + funcs->glScissor(view[0], view[1], view[2], view[3]); + funcs->glEnable(GL_SCISSOR_TEST); } else if (use_scissor_testing) { // use the scissor box set by the user - glEnable(GL_SCISSOR_TEST); + funcs->glEnable(GL_SCISSOR_TEST); } qt_gl_draw_text(p, x, y, str, font); @@ -4482,15 +4516,17 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con if (str.isEmpty() || !isValid()) return; + QOpenGLFunctions *funcs = qgl_functions(); bool auto_swap = autoBufferSwap(); int width = d->glcx->device()->width(); int height = d->glcx->device()->height(); GLdouble model[4 * 4], proj[4 * 4]; GLint view[4]; - glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]); - glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]); - glGetIntegerv(GL_VIEWPORT, &view[0]); + QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); + gl1funcs->glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]); + gl1funcs->glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]); + funcs->glGetIntegerv(GL_VIEWPORT, &view[0]); GLdouble win_x = 0, win_y = 0, win_z = 0; qgluProject(x, y, z, &model[0], &proj[0], &view[0], &win_x, &win_y, &win_z); @@ -4500,8 +4536,8 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con QPainter *p; bool reuse_painter = false; - bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST); - bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST); + bool use_depth_testing = funcs->glIsEnabled(GL_DEPTH_TEST); + bool use_scissor_testing = funcs->glIsEnabled(GL_SCISSOR_TEST); qt_save_gl_state(); @@ -4517,16 +4553,16 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con QRect viewport(view[0], view[1], view[2], view[3]); if (!use_scissor_testing && viewport != rect()) { - glScissor(view[0], view[1], view[2], view[3]); - glEnable(GL_SCISSOR_TEST); + funcs->glScissor(view[0], view[1], view[2], view[3]); + funcs->glEnable(GL_SCISSOR_TEST); } else if (use_scissor_testing) { - glEnable(GL_SCISSOR_TEST); + funcs->glEnable(GL_SCISSOR_TEST); } - glViewport(0, 0, width, height); - glAlphaFunc(GL_GREATER, 0.0); - glEnable(GL_ALPHA_TEST); + funcs->glViewport(0, 0, width, height); + gl1funcs->glAlphaFunc(GL_GREATER, 0.0); + funcs->glEnable(GL_ALPHA_TEST); if (use_depth_testing) - glEnable(GL_DEPTH_TEST); + funcs->glEnable(GL_DEPTH_TEST); // The only option in Qt 5 is the shader-based OpenGL 2 paint engine. // Setting fixed pipeline transformations is futile. Instead, pass the @@ -4964,10 +5000,11 @@ QSize QGLTexture::bindCompressedTextureDDS(const char *buf, int len) const GLubyte *pixels = reinterpret_cast(buf + ddsHeader->dwSize + 4); - glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_2D, id); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + QOpenGLFunctions *funcs = qgl_functions(); + funcs->glGenTextures(1, &id); + funcs->glBindTexture(GL_TEXTURE_2D, id); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); int size; int offset = 0; @@ -5060,23 +5097,24 @@ QSize QGLTexture::bindCompressedTexturePVR(const char *buf, int len) } // Create the texture. - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_2D, id); + QOpenGLFunctions *funcs = qgl_functions(); + funcs->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + funcs->glGenTextures(1, &id); + funcs->glBindTexture(GL_TEXTURE_2D, id); if (pvrHeader->mipMapCount) { if ((options & QGLContext::LinearFilteringBindOption) != 0) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); } } else if ((options & QGLContext::LinearFilteringBindOption) != 0) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } // Load the compressed mipmap levels. @@ -5102,7 +5140,7 @@ QSize QGLTexture::bindCompressedTexturePVR(const char *buf, int len) } // Restore the default pixel alignment for later texture uploads. - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + funcs->glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // Set the invert flag for the texture. The "vertical flip" // flag in PVR is the opposite sense to our sense of inversion. diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 22fc3f4ad0..6dd939c2de 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -346,7 +346,7 @@ public: private: static void freeTextureFunc(QOpenGLFunctions *, GLuint id) { - glDeleteTextures(1, &id); + QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &id); } }; diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 10e6ffde46..fbcc8a5adb 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -226,7 +226,7 @@ void QGLContext::makeCurrent() if (d->guiGlContext->makeCurrent(widget->windowHandle())) { if (!d->workaroundsCached) { d->workaroundsCached = true; - const char *renderer = reinterpret_cast(glGetString(GL_RENDERER)); + const char *renderer = reinterpret_cast(d->guiGlContext->functions()->glGetString(GL_RENDERER)); if (renderer && strstr(renderer, "Mali")) { d->workaround_brokenFBOReadBack = true; } diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp index 1c9545990f..525fc15829 100644 --- a/src/opengl/qglbuffer.cpp +++ b/src/opengl/qglbuffer.cpp @@ -347,9 +347,9 @@ bool QGLBuffer::read(int offset, void *data, int count) Q_D(QGLBuffer); if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id()) return false; - while (glGetError() != GL_NO_ERROR) ; // Clear error state. + while (d->funcs->glGetError() != GL_NO_ERROR) ; // Clear error state. d->funcs->glGetBufferSubData(d->type, offset, count, data); - return glGetError() == GL_NO_ERROR; + return d->funcs->glGetError() == GL_NO_ERROR; #else Q_UNUSED(offset); Q_UNUSED(data); diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index bd8bc2f64a..050e47c372 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -61,11 +61,11 @@ extern QImage qt_gl_read_frame_buffer(const QSize&, bool, bool); #ifndef QT_NO_DEBUG #define QT_RESET_GLERROR() \ { \ - while (glGetError() != GL_NO_ERROR) {} \ + while (QOpenGLContext::currentContext()->functions()->glGetError() != GL_NO_ERROR) {} \ } #define QT_CHECK_GLERROR() \ { \ - GLenum err = glGetError(); \ + GLenum err = QOpenGLContext::currentContext()->functions()->glGetError(); \ if (err != GL_NO_ERROR) { \ qDebug("[%s line %d] GL Error: %d", \ __FILE__, __LINE__, (int)err); \ @@ -460,7 +460,7 @@ namespace void freeTextureFunc(QGLContext *ctx, GLuint id) { Q_UNUSED(ctx); - glDeleteTextures(1, &id); + ctx->contextHandle()->functions()->glDeleteTextures(1, &id); } } @@ -493,10 +493,10 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, QT_CHECK_GLERROR(); // init texture if (samples == 0) { - glGenTextures(1, &texture); - glBindTexture(target, texture); - glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + funcs.glGenTextures(1, &texture); + funcs.glBindTexture(target, texture); + funcs.glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); if (mipmap) { int width = size.width(); int height = size.height(); @@ -505,26 +505,26 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, width = qMax(1, width >> 1); height = qMax(1, height >> 1); ++level; - glTexImage2D(target, level, internal_format, width, height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + funcs.glTexImage2D(target, level, internal_format, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); } } - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, texture, 0); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); - glBindTexture(target, 0); + funcs.glBindTexture(target, 0); color_buffer = 0; } else { mipmap = false; GLint maxSamples; - glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + funcs.glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); samples = qBound(0, int(samples), int(maxSamples)); @@ -694,7 +694,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, if (color_buffer) funcs.glDeleteRenderbuffers(1, &color_buffer); else - glDeleteTextures(1, &texture); + funcs.glDeleteTextures(1, &texture); if (depth_buffer) funcs.glDeleteRenderbuffers(1, &depth_buffer); if (stencil_buffer && depth_buffer != stencil_buffer) diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp index 6a8d5c042e..1af4762e6a 100644 --- a/src/opengl/qglpaintdevice.cpp +++ b/src/opengl/qglpaintdevice.cpp @@ -164,18 +164,19 @@ void QGLWidgetGLPaintDevice::setWidget(QGLWidget* w) void QGLWidgetGLPaintDevice::beginPaint() { QGLPaintDevice::beginPaint(); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); if (!glWidget->d_func()->disable_clear_on_painter_begin && glWidget->autoFillBackground()) { if (glWidget->testAttribute(Qt::WA_TranslucentBackground)) - glClearColor(0.0, 0.0, 0.0, 0.0); + funcs->glClearColor(0.0, 0.0, 0.0, 0.0); else { const QColor &c = glWidget->palette().brush(glWidget->backgroundRole()).color(); float alpha = c.alphaF(); - glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha); + funcs->glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha); } if (context()->d_func()->workaround_needsFullClearOnEveryFrame) - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + funcs->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); else - glClear(GL_COLOR_BUFFER_BIT); + funcs->glClear(GL_COLOR_BUFFER_BIT); } } diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index 32b18bfda4..8623f44ae1 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -124,7 +124,7 @@ void QGLPBufferGLPaintDevice::beginPaint() void QGLPBufferGLPaintDevice::endPaint() { - glFlush(); + QOpenGLContext::currentContext()->functions()->glFlush(); QGLPaintDevice::endPaint(); } @@ -235,7 +235,7 @@ bool QGLPixelBuffer::makeCurrent() d->fbo = new QOpenGLFramebufferObject(d->req_size, format); d->fbo->bind(); d->glDevice.setFbo(d->fbo->handle()); - glViewport(0, 0, d->req_size.width(), d->req_size.height()); + QOpenGLContext::currentContext()->functions()->glViewport(0, 0, d->req_size.width(), d->req_size.height()); } return true; } @@ -359,12 +359,12 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, d->blit_fbo->handle()); } - glBindTexture(GL_TEXTURE_2D, texture_id); + ctx->functions()->glBindTexture(GL_TEXTURE_2D, texture_id); #ifndef QT_OPENGL_ES GLenum format = ctx->isES() ? GL_RGBA : GL_RGBA8; - glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0); + ctx->functions()->glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0); #else - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0); + ctx->functions()->glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0); #endif if (d->blit_fbo) @@ -629,17 +629,18 @@ GLuint QGLPixelBuffer::generateDynamicTexture() const } GLuint texture; + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); + funcs->glGenTextures(1, &texture); + funcs->glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->req_size.width(), d->req_size.height(), 0, - GL_RGBA, GL_UNSIGNED_BYTE, 0); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->req_size.width(), d->req_size.height(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0); return texture; } diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 65f217edf2..5314db173e 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -3074,8 +3074,9 @@ int QGLShaderProgram::maxGeometryOutputVertices() const { GLint n = 0; #if !defined(QT_OPENGL_ES_2) + Q_D(const QGLShaderProgram); if (!QOpenGLContext::currentContext()->isES()) - glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n); + d->glfuncs->glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n); #endif return n; } @@ -3229,7 +3230,7 @@ bool QGLShader::hasOpenGLShaders(ShaderType type, const QGLContext *context) if (!resolved) return false; - if ((type & Geometry) && !QByteArray((const char *) glGetString(GL_EXTENSIONS)).contains("GL_EXT_geometry_shader4")) + if ((type & Geometry) && !QByteArray((const char *) functions.glGetString(GL_EXTENSIONS)).contains("GL_EXT_geometry_shader4")) return false; return true; diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp index 07a07210af..c32edd3f71 100644 --- a/tests/auto/gui/qopengl/tst_qopengl.cpp +++ b/tests/auto/gui/qopengl/tst_qopengl.cpp @@ -459,9 +459,9 @@ void tst_QOpenGL::fboSimpleRendering() QVERIFY(fbo->bind()); - glClearColor(1.0, 0.0, 0.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT); - glFinish(); + ctx.functions()->glClearColor(1.0, 0.0, 0.0, 1.0); + ctx.functions()->glClear(GL_COLOR_BUFFER_BIT); + ctx.functions()->glFinish(); const QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32); QCOMPARE(fb.size(), size); @@ -505,9 +505,9 @@ void tst_QOpenGL::fboTextureOwnership() fbo->bind(); QVERIFY(fbo->texture() != 0 && fbo->texture() != texture); - glClearColor(1.0, 0.0, 0.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT); - glFinish(); + ctx.functions()->glClearColor(1.0, 0.0, 0.0, 1.0); + ctx.functions()->glClear(GL_COLOR_BUFFER_BIT); + ctx.functions()->glFinish(); QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32); QImage reference(fb.size(), QImage::Format_RGB32); @@ -515,7 +515,7 @@ void tst_QOpenGL::fboTextureOwnership() QFUZZY_COMPARE_IMAGES(fb, reference); - glDeleteTextures(1, &texture); + ctx.functions()->glDeleteTextures(1, &texture); delete fbo; } diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp index 5831b33974..02f32adf57 100644 --- a/tests/auto/opengl/qgl/tst_qgl.cpp +++ b/tests/auto/opengl/qgl/tst_qgl.cpp @@ -1090,9 +1090,10 @@ void tst_QGL::glFBOSimpleRendering() fbo->bind(); - glClearColor(1.0, 0.0, 0.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT); - glFinish(); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + funcs->glClearColor(1.0, 0.0, 0.0, 1.0); + funcs->glClear(GL_COLOR_BUFFER_BIT); + funcs->glFinish(); QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32); QImage reference(fb.size(), QImage::Format_RGB32); @@ -1390,11 +1391,11 @@ class RenderPixmapWidget : public QGLWidget protected: void initializeGL() { // Set some gl state: - glClearColor(1.0, 0.0, 0.0, 1.0); + QOpenGLContext::currentContext()->functions()->glClearColor(1.0, 0.0, 0.0, 1.0); } void paintGL() { - glClear(GL_COLOR_BUFFER_BIT); + QOpenGLContext::currentContext()->functions()->glClear(GL_COLOR_BUFFER_BIT); } }; @@ -1683,11 +1684,12 @@ protected: void paintEvent(QPaintEvent*) { // clear the stencil with junk - glStencilMask(0xFFFF); - glClearStencil(0xFFFF); - glDisable(GL_STENCIL_TEST); - glDisable(GL_SCISSOR_TEST); - glClear(GL_STENCIL_BUFFER_BIT); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + funcs->glStencilMask(0xFFFF); + funcs->glClearStencil(0xFFFF); + funcs->glDisable(GL_STENCIL_TEST); + funcs->glDisable(GL_SCISSOR_TEST); + funcs->glClear(GL_STENCIL_BUFFER_BIT); QPainter painter(this); paint(&painter); @@ -2029,26 +2031,27 @@ void tst_QGL::qglContextDefaultBindTexture() QVERIFY(QImagePixmapCleanupHooks::isImageCached(*boundImage)); QVERIFY(QImagePixmapCleanupHooks::isPixmapCached(*boundPixmap)); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); // Make sure the texture IDs returned are valid: - QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_TRUE); - QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_TRUE); + QCOMPARE((bool)funcs->glIsTexture(boundImageTextureId), GL_TRUE); + QCOMPARE((bool)funcs->glIsTexture(boundPixmapTextureId), GL_TRUE); // Make sure the textures are still valid after we delete the image/pixmap: // Also check that although the textures are left intact, the cache entries are removed: delete boundImage; boundImage = 0; - QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_TRUE); + QCOMPARE((bool)funcs->glIsTexture(boundImageTextureId), GL_TRUE); QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); delete boundPixmap; boundPixmap = 0; - QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_TRUE); + QCOMPARE((bool)funcs->glIsTexture(boundPixmapTextureId), GL_TRUE); QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); // Finally, make sure QGLContext::deleteTexture deletes the texture IDs: ctx->deleteTexture(boundImageTextureId); ctx->deleteTexture(boundPixmapTextureId); - QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_FALSE); - QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_FALSE); + QCOMPARE((bool)funcs->glIsTexture(boundImageTextureId), GL_FALSE); + QCOMPARE((bool)funcs->glIsTexture(boundPixmapTextureId), GL_FALSE); } #endif diff --git a/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp b/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp index cdd820cf5b..4e0375171a 100644 --- a/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp +++ b/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp @@ -62,7 +62,7 @@ bool tst_QGLFunctions::hasExtension(const char *name) { QString extensions = QString::fromLatin1 - (reinterpret_cast(glGetString(GL_EXTENSIONS))); + (reinterpret_cast(QOpenGLContext::currentContext()->functions()->glGetString(GL_EXTENSIONS))); return extensions.split(QLatin1Char(' ')).contains (QString::fromLatin1(name)); } @@ -194,46 +194,46 @@ void tst_QGLFunctions::features() // Verify that the multitexture functions appear to resolve and work. void tst_QGLFunctions::multitexture() { - QGLFunctions funcs; + QOpenGLFunctions funcs; QGLWidget glw; if (!glw.isValid()) QSKIP("Could not create a GL context"); glw.makeCurrent(); - funcs.initializeGLFunctions(); + funcs.initializeOpenGLFunctions(); - if (!funcs.hasOpenGLFeature(QGLFunctions::Multitexture)) + if (!funcs.hasOpenGLFeature(QOpenGLFunctions::Multitexture)) QSKIP("Multitexture functions are not supported"); funcs.glActiveTexture(GL_TEXTURE1); GLint active = 0; - glGetIntegerv(GL_ACTIVE_TEXTURE, &active); + funcs.glGetIntegerv(GL_ACTIVE_TEXTURE, &active); QVERIFY(active == GL_TEXTURE1); funcs.glActiveTexture(GL_TEXTURE0); active = 0; - glGetIntegerv(GL_ACTIVE_TEXTURE, &active); + funcs.glGetIntegerv(GL_ACTIVE_TEXTURE, &active); QVERIFY(active == GL_TEXTURE0); } // Verify that the glBlendColor() function appears to resolve and work. void tst_QGLFunctions::blendColor() { - QGLFunctions funcs; + QOpenGLFunctions funcs; QGLWidget glw; if (!glw.isValid()) QSKIP("Could not create a GL context"); glw.makeCurrent(); - funcs.initializeGLFunctions(); + funcs.initializeOpenGLFunctions(); - if (!funcs.hasOpenGLFeature(QGLFunctions::BlendColor)) + if (!funcs.hasOpenGLFeature(QOpenGLFunctions::BlendColor)) QSKIP("glBlendColor() is not supported"); funcs.glBlendColor(0.0f, 1.0f, 0.0f, 1.0f); GLfloat colors[4] = {0.5f, 0.5f, 0.5f, 0.5f}; - glGetFloatv(GL_BLEND_COLOR, colors); + funcs.glGetFloatv(GL_BLEND_COLOR, colors); QCOMPARE(colors[0], 0.0f); QCOMPARE(colors[1], 1.0f); diff --git a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp index 999761e3f0..e190af31e4 100644 --- a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp +++ b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp @@ -48,6 +48,10 @@ #include #include "tst_qglthreads.h" +#ifndef QT_OPENGL_ES_2 +#include +#endif + #define RUNNING_TIME 5000 tst_QGLThreads::tst_QGLThreads(QObject *parent) @@ -339,8 +343,9 @@ static inline float qrandom() { return (rand() % 100) / 100.f; } void renderAScene(int w, int h) { + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + if (QOpenGLContext::currentContext()->isES()) { - QGLFunctions funcs(QGLContext::currentContext()); Q_UNUSED(w); Q_UNUSED(h); QGLShaderProgram program; @@ -349,7 +354,7 @@ void renderAScene(int w, int h) program.bindAttributeLocation("pos", 0); program.bind(); - funcs.glEnableVertexAttribArray(0); + funcs->glEnableVertexAttribArray(0); for (int i=0; i<1000; ++i) { GLfloat pos[] = { @@ -361,30 +366,33 @@ void renderAScene(int w, int h) (rand() % 100) / 100.f }; - funcs.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + funcs->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos); + funcs->glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); } } else { #ifndef QT_OPENGL_ES_2 - glViewport(0, 0, w, h); + QOpenGLFunctions_1_0 *gl1funcs = QOpenGLContext::currentContext()->versionFunctions(); + gl1funcs->initializeOpenGLFunctions(); + + gl1funcs->glViewport(0, 0, w, h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum(0, w, h, 0, 1, 100); - glTranslated(0, 0, -1); + gl1funcs->glMatrixMode(GL_PROJECTION); + gl1funcs->glLoadIdentity(); + gl1funcs->glFrustum(0, w, h, 0, 1, 100); + gl1funcs->glTranslated(0, 0, -1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + gl1funcs->glMatrixMode(GL_MODELVIEW); + gl1funcs->glLoadIdentity(); for (int i=0;i<1000; ++i) { - glBegin(GL_TRIANGLES); - glColor3f(qrandom(), qrandom(), qrandom()); - glVertex2f(qrandom() * w, qrandom() * h); - glColor3f(qrandom(), qrandom(), qrandom()); - glVertex2f(qrandom() * w, qrandom() * h); - glColor3f(qrandom(), qrandom(), qrandom()); - glVertex2f(qrandom() * w, qrandom() * h); - glEnd(); + gl1funcs->glBegin(GL_TRIANGLES); + gl1funcs->glColor3f(qrandom(), qrandom(), qrandom()); + gl1funcs->glVertex2f(qrandom() * w, qrandom() * h); + gl1funcs->glColor3f(qrandom(), qrandom(), qrandom()); + gl1funcs->glVertex2f(qrandom() * w, qrandom() * h); + gl1funcs->glColor3f(qrandom(), qrandom(), qrandom()); + gl1funcs->glVertex2f(qrandom() * w, qrandom() * h); + gl1funcs->glEnd(); } #endif } @@ -434,8 +442,9 @@ public: QSize s = m_widget->newSize; m_widget->mutex.unlock(); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); if (s != m_size) { - glViewport(0, 0, s.width(), s.height()); + funcs->glViewport(0, 0, s.width(), s.height()); } if (QGLContext::currentContext() != m_widget->context()) { @@ -443,7 +452,7 @@ public: break; } - glClear(GL_COLOR_BUFFER_BIT); + funcs->glClear(GL_COLOR_BUFFER_BIT); int w = m_widget->width(); int h = m_widget->height(); @@ -451,7 +460,7 @@ public: renderAScene(w, h); int color; - glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color); + funcs->glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color); m_widget->swapBuffers(); } -- cgit v1.2.3