Remove direct OpenGL calls from QtOpenGL

Task-number: QTBUG-36483
Change-Id: I96dea5649c0a49a11cd2ff31da659cd2067e769d
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
Laszlo Agocs 2014-04-23 09:08:16 +02:00 committed by The Qt Project
parent 8f443ad0b9
commit 33d0a8d753
17 changed files with 373 additions and 312 deletions

View File

@ -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;
}

View File

@ -86,6 +86,10 @@
#include <QDebug>
#ifndef QT_OPENGL_ES_2
# include <qopenglfunctions_1_1.h>
#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<QOpenGLFunctions_1_1>();
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();
}

View File

@ -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

View File

@ -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<uchar> 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<uchar> 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; i<c.h; ++i) {
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits);
funcs->glTexSubImage2D(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<const char*>(glGetString(GL_VENDOR)));
const QByteArray vendorString(reinterpret_cast<const char*>(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());
}
}
}

View File

@ -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()

View File

@ -70,6 +70,10 @@
#include "qlibrary.h"
#include <qmutex.h>
#ifndef QT_OPENGL_ES_2
#include <qopenglfunctions_1_1.h>
#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<QOpenGLFunctions_1_1>();
f->initializeOpenGLFunctions();
return f;
}
#endif
struct QGLThreadContext {
~QGLThreadContext() {
if (context)
@ -1355,7 +1374,7 @@ QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags()
}
}
QString versionString(QLatin1String(reinterpret_cast<const char*>(glGetString(GL_VERSION))));
QString versionString(QLatin1String(reinterpret_cast<const char*>(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();
QOpenGLFunctions *funcs = qgl_functions();
QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions();
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);
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<const GLubyte *>(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.

View File

@ -346,7 +346,7 @@ public:
private:
static void freeTextureFunc(QOpenGLFunctions *, GLuint id) {
glDeleteTextures(1, &id);
QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &id);
}
};

View File

@ -226,7 +226,7 @@ void QGLContext::makeCurrent()
if (d->guiGlContext->makeCurrent(widget->windowHandle())) {
if (!d->workaroundsCached) {
d->workaroundsCached = true;
const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
const char *renderer = reinterpret_cast<const char *>(d->guiGlContext->functions()->glGetString(GL_RENDERER));
if (renderer && strstr(renderer, "Mali")) {
d->workaround_brokenFBOReadBack = true;
}

View File

@ -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);

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -62,7 +62,7 @@ bool tst_QGLFunctions::hasExtension(const char *name)
{
QString extensions =
QString::fromLatin1
(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
(reinterpret_cast<const char *>(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);

View File

@ -48,6 +48,10 @@
#include <QtOpenGL/QtOpenGL>
#include "tst_qglthreads.h"
#ifndef QT_OPENGL_ES_2
#include <QtGui/QOpenGLFunctions_1_0>
#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<QOpenGLFunctions_1_0>();
gl1funcs->initializeOpenGLFunctions();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(0, w, h, 0, 1, 100);
glTranslated(0, 0, -1);
gl1funcs->glViewport(0, 0, w, h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gl1funcs->glMatrixMode(GL_PROJECTION);
gl1funcs->glLoadIdentity();
gl1funcs->glFrustum(0, w, h, 0, 1, 100);
gl1funcs->glTranslated(0, 0, -1);
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();
}