summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache.cpp14
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp95
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp81
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h2
-rw-r--r--src/opengl/opengl.pro3
-rw-r--r--src/opengl/qgl.cpp701
-rw-r--r--src/opengl/qgl_p.h2
-rw-r--r--src/opengl/qgl_qpa.cpp464
-rw-r--r--src/opengl/qglbuffer.cpp4
-rw-r--r--src/opengl/qglframebufferobject.cpp36
-rw-r--r--src/opengl/qglpaintdevice.cpp9
-rw-r--r--src/opengl/qglpixelbuffer.cpp33
-rw-r--r--src/opengl/qglshaderprogram.cpp5
14 files changed, 703 insertions, 754 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 5d4ca42dc2..5045d4a2ae 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -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)
@@ -231,7 +235,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
wrapMode = GL_CLAMP_TO_EDGE;
}
- 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);
@@ -428,9 +432,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);
@@ -540,11 +544,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()->isOpenGLES()) {
@@ -569,12 +573,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
@@ -591,13 +598,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);
@@ -608,7 +615,7 @@ void QGL2PaintEngineExPrivate::resetGLState()
if (!ctx->contextHandle()->isOpenGLES()) {
// 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
}
@@ -758,7 +765,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
@@ -785,9 +792,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);
@@ -798,7 +805,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);
@@ -1024,9 +1031,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);
@@ -1375,9 +1382,9 @@ void QGL2PaintEngineEx::renderHintsChanged()
if (!d->ctx->contextHandle()->isOpenGLES()) {
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
@@ -1423,7 +1430,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);
@@ -1465,7 +1472,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
@@ -1526,8 +1533,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());
@@ -1812,7 +1819,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.
@@ -1829,7 +1836,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);
@@ -1864,7 +1871,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();
@@ -1965,7 +1972,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);
@@ -2039,17 +2046,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()->isOpenGLES())
- glDisable(GL_MULTISAMPLE);
+ d->glDisable(GL_MULTISAMPLE);
#endif
d->glyphCacheFormat = QFontEngine::Format_A8;
@@ -2075,7 +2082,7 @@ bool QGL2PaintEngineEx::end()
Q_D(QGL2PaintEngineEx);
QGLContext *ctx = d->ctx;
- d->funcs.glUseProgram(0);
+ d->glUseProgram(0);
d->transferMode(BrushDrawingMode);
d->device->endPaint();
@@ -2089,11 +2096,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
@@ -2115,7 +2122,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();
@@ -2436,7 +2443,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 f1da50a6b9..aa1d7decdb 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<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()->isOpenGLES())
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());
}
}
}
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/opengl.pro b/src/opengl/opengl.pro
index 5cd553a5e8..9c62d41d3e 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -12,7 +12,6 @@ load(qt_module)
contains(QT_CONFIG, opengl):CONFIG += opengl
contains(QT_CONFIG, opengles2):CONFIG += opengles2
-contains(QT_CONFIG, egl):CONFIG += egl
HEADERS += qgl.h \
qgl_p.h \
@@ -54,5 +53,3 @@ SOURCES += qglshaderprogram.cpp \
gl2paintengineex/qpaintengineex_opengl2.cpp \
gl2paintengineex/qglcustomshaderstage.cpp \
gl2paintengineex/qtextureglyphcache_gl.cpp
-
-SOURCES += qgl_qpa.cpp
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 02ea6e45e3..d1417cfde5 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -70,6 +70,15 @@
#include "qlibrary.h"
#include <qmutex.h>
+#include "qsurfaceformat.h"
+#include <private/qapplication_p.h>
+#include <qpa/qplatformopenglcontext.h>
+#include <qpa/qplatformwindow.h>
+
+#ifndef QT_OPENGL_ES_2
+#include <qopenglfunctions_1_1.h>
+#endif
+
// #define QT_GL_CONTEXT_RESOURCE_DEBUG
QT_BEGIN_NAMESPACE
@@ -107,6 +116,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 +131,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)
@@ -420,6 +444,80 @@ QGLFormat::~QGLFormat()
}
/*!
+ Returns an OpenGL format for the window format specified by \a format.
+*/
+QGLFormat QGLFormat::fromSurfaceFormat(const QSurfaceFormat &format)
+{
+ QGLFormat retFormat;
+ if (format.alphaBufferSize() >= 0)
+ retFormat.setAlphaBufferSize(format.alphaBufferSize());
+ if (format.blueBufferSize() >= 0)
+ retFormat.setBlueBufferSize(format.blueBufferSize());
+ if (format.greenBufferSize() >= 0)
+ retFormat.setGreenBufferSize(format.greenBufferSize());
+ if (format.redBufferSize() >= 0)
+ retFormat.setRedBufferSize(format.redBufferSize());
+ if (format.depthBufferSize() >= 0)
+ retFormat.setDepthBufferSize(format.depthBufferSize());
+ if (format.samples() > 1) {
+ retFormat.setSampleBuffers(true);
+ retFormat.setSamples(format.samples());
+ }
+ if (format.stencilBufferSize() > 0) {
+ retFormat.setStencil(true);
+ retFormat.setStencilBufferSize(format.stencilBufferSize());
+ }
+ retFormat.setDoubleBuffer(format.swapBehavior() != QSurfaceFormat::SingleBuffer);
+ retFormat.setStereo(format.stereo());
+ retFormat.setVersion(format.majorVersion(), format.minorVersion());
+ retFormat.setProfile(static_cast<QGLFormat::OpenGLContextProfile>(format.profile()));
+ return retFormat;
+}
+
+/*!
+ Returns a window format for the OpenGL format specified by \a format.
+*/
+QSurfaceFormat QGLFormat::toSurfaceFormat(const QGLFormat &format)
+{
+ QSurfaceFormat retFormat;
+ if (format.alpha())
+ retFormat.setAlphaBufferSize(format.alphaBufferSize() == -1 ? 1 : format.alphaBufferSize());
+ if (format.blueBufferSize() >= 0)
+ retFormat.setBlueBufferSize(format.blueBufferSize());
+ if (format.greenBufferSize() >= 0)
+ retFormat.setGreenBufferSize(format.greenBufferSize());
+ if (format.redBufferSize() >= 0)
+ retFormat.setRedBufferSize(format.redBufferSize());
+ if (format.depth())
+ retFormat.setDepthBufferSize(format.depthBufferSize() == -1 ? 1 : format.depthBufferSize());
+ retFormat.setSwapBehavior(format.doubleBuffer() ? QSurfaceFormat::DoubleBuffer : QSurfaceFormat::SingleBuffer);
+ if (format.sampleBuffers())
+ retFormat.setSamples(format.samples() == -1 ? 4 : format.samples());
+ if (format.stencil())
+ retFormat.setStencilBufferSize(format.stencilBufferSize() == -1 ? 1 : format.stencilBufferSize());
+ retFormat.setStereo(format.stereo());
+ retFormat.setMajorVersion(format.majorVersion());
+ retFormat.setMinorVersion(format.minorVersion());
+ retFormat.setProfile(static_cast<QSurfaceFormat::OpenGLContextProfile>(format.profile()));
+ // QGLFormat has no way to set DeprecatedFunctions, that is, to tell that forward
+ // compatibility should not be requested. Some drivers fail to ignore the fwdcompat
+ // bit with compatibility profiles so make sure it is not set.
+ if (format.profile() == QGLFormat::CompatibilityProfile)
+ retFormat.setOption(QSurfaceFormat::DeprecatedFunctions);
+ return retFormat;
+}
+
+void QGLContextPrivate::setupSharing() {
+ Q_Q(QGLContext);
+ QOpenGLContext *sharedContext = guiGlContext->shareContext();
+ if (sharedContext) {
+ QGLContext *actualSharedContext = QGLContext::fromOpenGLContext(sharedContext);
+ sharing = true;
+ QGLContextGroup::addShare(q, actualSharedContext);
+ }
+}
+
+/*!
\fn bool QGLFormat::doubleBuffer() const
Returns \c true if double buffering is enabled; otherwise returns
@@ -1113,8 +1211,11 @@ QGLFormat::OpenGLContextProfile QGLFormat::profile() const
\warning This function must not be called until the QApplication
object has been created.
*/
-
-
+bool QGLFormat::hasOpenGL()
+{
+ return QApplicationPrivate::platformIntegration()
+ ->hasCapability(QPlatformIntegration::OpenGL);
+}
/*!
\fn bool QGLFormat::hasOpenGLOverlays()
@@ -1125,6 +1226,10 @@ QGLFormat::OpenGLContextProfile QGLFormat::profile() const
\warning This function must not be called until the QApplication
object has been created.
*/
+bool QGLFormat::hasOpenGLOverlays()
+{
+ return false;
+}
QGLFormat::OpenGLVersionFlags Q_AUTOTEST_EXPORT qOpenGLVersionFlagsFromString(const QString &versionString)
{
@@ -1355,7 +1460,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;
@@ -1631,6 +1736,60 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
QGLContext* QGLContext::currentCtx = 0;
/*
+ QGLTemporaryContext implementation
+*/
+class QGLTemporaryContextPrivate
+{
+public:
+ QWindow *window;
+ QOpenGLContext *context;
+
+ QGLContext *oldContext;
+};
+
+QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
+ : d(new QGLTemporaryContextPrivate)
+{
+ d->oldContext = const_cast<QGLContext *>(QGLContext::currentContext());
+
+ d->window = new QWindow;
+ d->window->setSurfaceType(QWindow::OpenGLSurface);
+ d->window->setGeometry(QRect(0, 0, 3, 3));
+ d->window->create();
+
+ d->context = new QOpenGLContext;
+#if !defined(QT_OPENGL_ES)
+ if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
+ // On desktop, request latest released version
+ QSurfaceFormat format;
+#if defined(Q_OS_MAC)
+ // OS X is limited to OpenGL 3.2 Core Profile at present
+ // so set that here. If we use compatibility profile it
+ // only reports 2.x contexts.
+ format.setMajorVersion(3);
+ format.setMinorVersion(2);
+ format.setProfile(QSurfaceFormat::CoreProfile);
+#else
+ format.setMajorVersion(4);
+ format.setMinorVersion(3);
+#endif
+ d->context->setFormat(format);
+ }
+#endif // QT_OPENGL_ES
+ d->context->create();
+ d->context->makeCurrent(d->window);
+}
+
+QGLTemporaryContext::~QGLTemporaryContext()
+{
+ if (d->oldContext)
+ d->oldContext->makeCurrent();
+
+ delete d->context;
+ delete d->window;
+}
+
+/*
Read back the contents of the currently bound framebuffer, used in
QGLWidget::grabFrameBuffer(), QGLPixelbuffer::toImage() and
QGLFramebufferObject::toImage()
@@ -1687,7 +1846,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,28 +1860,14 @@ 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()->isOpenGLES()) {
- //### 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);
return img;
}
-// returns the highest number closest to v, which is a power of 2
-// NB! assumes 32 bit ints
-int qt_next_power_of_two(int v)
-{
- v--;
- v |= v >> 1;
- v |= v >> 2;
- v |= v >> 4;
- v |= v >> 8;
- v |= v >> 16;
- ++v;
- return v;
-}
-
Q_GLOBAL_STATIC(QGLTextureCache, qt_gl_texture_cache)
QGLTextureCache::QGLTextureCache()
@@ -1981,6 +2126,47 @@ QGLContext::QGLContext(const QGLFormat &format)
d->init(0, format);
}
+void qDeleteQGLContext(void *handle)
+{
+ QGLContext *context = static_cast<QGLContext *>(handle);
+ delete context;
+}
+
+QGLContext::QGLContext(QOpenGLContext *context)
+ : d_ptr(new QGLContextPrivate(this))
+{
+ Q_D(QGLContext);
+ d->init(0, QGLFormat::fromSurfaceFormat(context->format()));
+ d->guiGlContext = context;
+ d->guiGlContext->setQGLContextHandle(this, qDeleteQGLContext);
+ d->ownContext = false;
+ d->valid = context->isValid();
+ d->setupSharing();
+}
+
+QOpenGLContext *QGLContext::contextHandle() const
+{
+ Q_D(const QGLContext);
+ return d->guiGlContext;
+}
+
+/*!
+ Returns a OpenGL context for the window context specified by the \a context
+ parameter.
+*/
+QGLContext *QGLContext::fromOpenGLContext(QOpenGLContext *context)
+{
+ if (!context)
+ return 0;
+ if (context->qGLContextHandle()) {
+ return reinterpret_cast<QGLContext *>(context->qGLContextHandle());
+ }
+ QGLContext *glContext = new QGLContext(context);
+ //Don't call create on context. This can cause the platformFormat to be set on the widget, which
+ //will cause the platformWindow to be recreated.
+ return glContext;
+}
+
/*!
Destroys the OpenGL context and frees its resources.
*/
@@ -2193,7 +2379,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 +2431,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,14 +2442,14 @@ 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
// dimensions 2^n+2(border) x 2^m+2(border), unless we're using GL
// 2.0 or use the GL_TEXTURE_RECTANGLE texture target
- int tx_w = qt_next_power_of_two(image.width());
- int tx_h = qt_next_power_of_two(image.height());
+ int tx_w = qNextPowerOfTwo(image.width() - 1);
+ int tx_h = qNextPowerOfTwo(image.height() - 1);
QImage img = image;
@@ -2280,9 +2467,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->isOpenGLES();
@@ -2293,23 +2480,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 +2625,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->isOpenGLES())
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 +2678,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;
}
}
@@ -2532,7 +2719,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);
@@ -2541,8 +2729,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;
}
@@ -2552,8 +2741,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;
@@ -2670,7 +2859,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)
@@ -2706,6 +2895,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;
@@ -2716,8 +2906,9 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex
#else
if (textureTarget != GL_TEXTURE_2D && !QOpenGLContext::currentContext()->isOpenGLES()) {
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);
@@ -2732,15 +2923,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
@@ -2781,6 +2973,7 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
#endif
#ifndef QT_OPENGL_ES_2
+ QOpenGLFunctions *funcs = qgl_functions();
if (!contextHandle()->isOpenGLES()) {
#ifdef QT_OPENGL_ES
if (textureTarget != GL_TEXTURE_2D) {
@@ -2788,22 +2981,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;
}
@@ -2844,18 +3037,20 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text
Q_UNUSED(textureTarget);
#else
if (!contextHandle()->isOpenGLES()) {
- 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) {
@@ -2872,8 +3067,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
@@ -3031,7 +3226,10 @@ bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *contex
Returns a colormap index for the color c, in ColorIndex mode. Used
by qglColor() and qglClearColor().
*/
-
+uint QGLContext::colorIndex(const QColor&) const
+{
+ return 0;
+}
/*!
\fn bool QGLContext::initialized() const
@@ -3079,7 +3277,10 @@ bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *contex
also be used to draw transparent graphics with a QPainter. See the
examples/opengl/overlay_x11 example for details.
*/
-
+QColor QGLContext::overlayTransparentColor() const
+{
+ return QColor(); // Invalid color
+}
/*!
Creates the GL context. Returns \c true if it was successful in
@@ -3239,6 +3440,51 @@ void QGLContext::moveToThread(QThread *thread)
the virtual function chooseVisual() which finds an appropriate X
visual. On other platforms it may work differently.
*/
+bool QGLContext::chooseContext(const QGLContext* shareContext)
+{
+ Q_D(QGLContext);
+ if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) {
+ // Unlike in Qt 4, the only possible target is a widget backed by an OpenGL-based
+ // QWindow. Pixmaps in particular are not supported anymore as paint devices since
+ // starting from Qt 5 QPixmap is raster-backed on almost all platforms.
+ d->valid = false;
+ }else {
+ QWidget *widget = static_cast<QWidget *>(d->paintDevice);
+ QGLFormat glformat = format();
+ QSurfaceFormat winFormat = QGLFormat::toSurfaceFormat(glformat);
+ if (widget->testAttribute(Qt::WA_TranslucentBackground))
+ winFormat.setAlphaBufferSize(qMax(winFormat.alphaBufferSize(), 8));
+
+ QWindow *window = widget->windowHandle();
+ if (!window->handle()
+ || window->surfaceType() != QWindow::OpenGLSurface
+ || window->requestedFormat() != winFormat)
+ {
+ window->setSurfaceType(QWindow::OpenGLSurface);
+ window->setFormat(winFormat);
+ window->destroy();
+ window->create();
+ }
+
+ if (d->ownContext)
+ delete d->guiGlContext;
+ d->ownContext = true;
+ QOpenGLContext *shareGlContext = shareContext ? shareContext->d_func()->guiGlContext : 0;
+ d->guiGlContext = new QOpenGLContext;
+ d->guiGlContext->setFormat(winFormat);
+ d->guiGlContext->setShareContext(shareGlContext);
+ d->valid = d->guiGlContext->create();
+
+ if (d->valid)
+ d->guiGlContext->setQGLContextHandle(this, qDeleteQGLContext);
+
+ d->glFormat = QGLFormat::fromSurfaceFormat(d->guiGlContext->format());
+ d->setupSharing();
+ }
+
+
+ return d->valid;
+}
/*!
\fn void QGLContext::reset()
@@ -3247,7 +3493,33 @@ void QGLContext::moveToThread(QThread *thread)
\sa create(), isValid()
*/
-
+void QGLContext::reset()
+{
+ Q_D(QGLContext);
+ if (!d->valid)
+ return;
+ d->cleanup();
+
+ d->crWin = false;
+ d->sharing = false;
+ d->valid = false;
+ d->transpColor = QColor();
+ d->initDone = false;
+ QGLContextGroup::removeShare(this);
+ if (d->guiGlContext) {
+ if (QOpenGLContext::currentContext() == d->guiGlContext)
+ doneCurrent();
+ if (d->ownContext) {
+ if (d->guiGlContext->thread() == QThread::currentThread())
+ delete d->guiGlContext;
+ else
+ d->guiGlContext->deleteLater();
+ } else
+ d->guiGlContext->setQGLContextHandle(0,0);
+ d->guiGlContext = 0;
+ }
+ d->ownContext = false;
+}
/*!
\fn void QGLContext::makeCurrent()
@@ -3263,7 +3535,26 @@ void QGLContext::moveToThread(QThread *thread)
make sure you've first pushed the context to the relevant thread
from the UI thread using moveToThread().
*/
+void QGLContext::makeCurrent()
+{
+ Q_D(QGLContext);
+ if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget)
+ return;
+ QWidget *widget = static_cast<QWidget *>(d->paintDevice);
+ if (!widget->windowHandle())
+ return;
+
+ if (d->guiGlContext->makeCurrent(widget->windowHandle())) {
+ if (!d->workaroundsCached) {
+ d->workaroundsCached = true;
+ const char *renderer = reinterpret_cast<const char *>(d->guiGlContext->functions()->glGetString(GL_RENDERER));
+ if (renderer && strstr(renderer, "Mali")) {
+ d->workaround_brokenFBOReadBack = true;
+ }
+ }
+ }
+}
/*!
\fn void QGLContext::swapBuffers() const
@@ -3271,7 +3562,18 @@ void QGLContext::moveToThread(QThread *thread)
Call this to finish a frame of OpenGL rendering, and make sure to
call makeCurrent() again before you begin a new frame.
*/
+void QGLContext::swapBuffers() const
+{
+ Q_D(const QGLContext);
+ if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget)
+ return;
+ QWidget *widget = static_cast<QWidget *>(d->paintDevice);
+ if (!widget->windowHandle())
+ return;
+
+ d->guiGlContext->swapBuffers(widget->windowHandle());
+}
/*!
\fn void QGLContext::doneCurrent()
@@ -3279,7 +3581,11 @@ void QGLContext::moveToThread(QThread *thread)
Makes no GL context the current context. Normally, you do not need
to call this function; QGLContext calls it as necessary.
*/
-
+void QGLContext::doneCurrent()
+{
+ Q_D(QGLContext);
+ d->guiGlContext->doneCurrent();
+}
/*!
\fn QPaintDevice* QGLContext::device() const
@@ -3289,7 +3595,6 @@ void QGLContext::moveToThread(QThread *thread)
\sa QGLContext::QGLContext()
*/
-
/*****************************************************************************
QGLWidget implementation
*****************************************************************************/
@@ -3688,6 +3993,11 @@ QGLWidget::~QGLWidget()
\a proc. 0 is returned if a pointer to the function could not be
obtained.
*/
+QFunctionPointer QGLContext::getProcAddress(const QString &procName) const
+{
+ Q_D(const QGLContext);
+ return d->guiGlContext->getProcAddress(procName.toLatin1());
+}
/*!
\fn bool QGLWidget::isValid() const
@@ -3775,8 +4085,10 @@ void QGLWidget::swapBuffers()
\sa context()
*/
-
-
+const QGLContext* QGLWidget::overlayContext() const
+{
+ return 0;
+}
/*!
\fn void QGLWidget::makeOverlayCurrent()
@@ -3789,7 +4101,9 @@ void QGLWidget::swapBuffers()
\sa makeCurrent()
*/
-
+void QGLWidget::makeOverlayCurrent()
+{
+}
/*!
\obsolete
@@ -3865,8 +4179,28 @@ void QGLWidget::setFormat(const QGLFormat &format)
\sa context(), isSharing()
*/
+void QGLWidget::setContext(QGLContext *context,
+ const QGLContext* shareContext,
+ bool deleteOldContext)
+{
+ Q_D(QGLWidget);
+ if (context == 0) {
+ qWarning("QGLWidget::setContext: Cannot set null context");
+ return;
+ }
+
+ if (context->device() == 0) // a context may refere to more than 1 window.
+ context->setDevice(this); //but its better to point to 1 of them than none of them.
+
+ QGLContext* oldcx = d->glcx;
+ d->glcx = context;
+ if (!d->glcx->isValid())
+ d->glcx->create(shareContext ? shareContext : oldcx);
+ if (deleteOldContext)
+ delete oldcx;
+}
/*!
\fn void QGLWidget::updateGL()
@@ -3892,7 +4226,9 @@ void QGLWidget::updateGL()
The widget's rendering context will become the current context and
initializeGL() will be called if it hasn't already been called.
*/
-
+void QGLWidget::updateOverlayGL()
+{
+}
/*!
This virtual function is called once before the first call to
@@ -3921,7 +4257,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);
}
@@ -3994,6 +4330,20 @@ void QGLWidget::resizeOverlayGL(int, int)
{
}
+bool QGLWidget::event(QEvent *e)
+{
+ Q_D(QGLWidget);
+
+ // A re-parent will destroy the window and re-create it. We should not reset the context while it happens.
+ if (e->type() == QEvent::ParentAboutToChange)
+ d->parent_changing = true;
+
+ if (e->type() == QEvent::ParentChange)
+ d->parent_changing = false;
+
+ return QWidget::event(e);
+}
+
/*!
\fn void QGLWidget::paintEvent(QPaintEvent *event)
@@ -4019,7 +4369,21 @@ void QGLWidget::paintEvent(QPaintEvent *)
Handles resize events that are passed in the \a event parameter.
Calls the virtual function resizeGL().
*/
+void QGLWidget::resizeEvent(QResizeEvent *e)
+{
+ Q_D(QGLWidget);
+
+ QWidget::resizeEvent(e);
+ if (!isValid())
+ return;
+ makeCurrent();
+ if (!d->glcx->initialized())
+ glInit();
+ const qreal scaleFactor = (window() && window()->windowHandle()) ?
+ window()->windowHandle()->devicePixelRatio() : 1.0;
+ resizeGL(width() * scaleFactor, height() * scaleFactor);
+}
/*!
Renders the current scene on a pixmap and returns the pixmap.
@@ -4148,7 +4512,7 @@ void QGLWidget::glDraw()
makeCurrent();
#ifndef QT_OPENGL_ES
if (d->glcx->deviceIsPixmap() && !d->glcx->contextHandle()->isOpenGLES())
- glDrawBuffer(GL_FRONT);
+ qgl1_functions()->glDrawBuffer(GL_FRONT);
#endif
QSize readback_target_size = d->glcx->d_ptr->readback_target_size;
if (!d->glcx->initialized()) {
@@ -4170,7 +4534,7 @@ void QGLWidget::glDraw()
if (d->autoSwap)
swapBuffers();
} else {
- glFlush();
+ qgl_functions()->glFlush();
}
}
@@ -4188,20 +4552,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()->isOpenGLES()) {
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
@@ -4220,23 +4584,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()->isOpenGLES()) {
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
}
@@ -4305,6 +4669,11 @@ QImage QGLWidget::convertToGLFormat(const QImage& img)
\sa setColormap(), QGLColormap::isEmpty()
*/
+const QGLColormap & QGLWidget::colormap() const
+{
+ Q_D(const QGLWidget);
+ return d->cmap;
+}
/*!
\fn void QGLWidget::setColormap(const QGLColormap & cmap)
@@ -4314,47 +4683,56 @@ QImage QGLWidget::convertToGLFormat(const QImage& img)
\sa colormap()
*/
+void QGLWidget::setColormap(const QGLColormap & c)
+{
+ Q_UNUSED(c);
+}
#ifndef QT_OPENGL_ES
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]);
@@ -4404,10 +4782,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();
@@ -4422,8 +4801,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()
@@ -4435,11 +4814,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);
@@ -4494,15 +4873,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);
@@ -4512,8 +4893,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();
@@ -4529,16 +4910,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
@@ -4731,6 +5112,11 @@ QPaintEngine *QGLWidget::paintEngine() const
return qt_qgl_paint_engine();
}
+void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget)
+{
+ initContext(context, shareWidget);
+}
+
/*
This is the shared initialization for all platforms. Called from QGLWidgetPrivate::init()
*/
@@ -4751,6 +5137,19 @@ void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWi
glcx = new QGLContext(QGLFormat::defaultFormat(), q);
}
+bool QGLWidgetPrivate::renderCxPm(QPixmap*)
+{
+ return false;
+}
+
+/*! \internal
+ Free up any allocated colormaps. This fn is only called for
+ top-level widgets.
+*/
+void QGLWidgetPrivate::cleanupColormaps()
+{
+}
+
Q_GLOBAL_STATIC(QString, qt_gl_lib_name)
void qt_set_gl_library_name(const QString& name)
@@ -4976,10 +5375,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;
@@ -5072,23 +5472,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.
@@ -5114,7 +5515,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
deleted file mode 100644
index 61d295f173..0000000000
--- a/src/opengl/qgl_qpa.cpp
+++ /dev/null
@@ -1,464 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QApplication>
-#include <private/qapplication_p.h>
-#include <QPixmap>
-#include <QDebug>
-
-#include <qpa/qplatformopenglcontext.h>
-#include <qpa/qplatformwindow.h>
-#include <QtGui/QSurfaceFormat>
-
-#include "qgl.h"
-#include "qgl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- Returns an OpenGL format for the window format specified by \a format.
-*/
-QGLFormat QGLFormat::fromSurfaceFormat(const QSurfaceFormat &format)
-{
- QGLFormat retFormat;
- if (format.alphaBufferSize() >= 0)
- retFormat.setAlphaBufferSize(format.alphaBufferSize());
- if (format.blueBufferSize() >= 0)
- retFormat.setBlueBufferSize(format.blueBufferSize());
- if (format.greenBufferSize() >= 0)
- retFormat.setGreenBufferSize(format.greenBufferSize());
- if (format.redBufferSize() >= 0)
- retFormat.setRedBufferSize(format.redBufferSize());
- if (format.depthBufferSize() >= 0)
- retFormat.setDepthBufferSize(format.depthBufferSize());
- if (format.samples() > 1) {
- retFormat.setSampleBuffers(true);
- retFormat.setSamples(format.samples());
- }
- if (format.stencilBufferSize() > 0) {
- retFormat.setStencil(true);
- retFormat.setStencilBufferSize(format.stencilBufferSize());
- }
- retFormat.setDoubleBuffer(format.swapBehavior() != QSurfaceFormat::SingleBuffer);
- retFormat.setStereo(format.stereo());
- retFormat.setVersion(format.majorVersion(), format.minorVersion());
- retFormat.setProfile(static_cast<QGLFormat::OpenGLContextProfile>(format.profile()));
- return retFormat;
-}
-
-/*!
- Returns a window format for the OpenGL format specified by \a format.
-*/
-QSurfaceFormat QGLFormat::toSurfaceFormat(const QGLFormat &format)
-{
- QSurfaceFormat retFormat;
- if (format.alpha())
- retFormat.setAlphaBufferSize(format.alphaBufferSize() == -1 ? 1 : format.alphaBufferSize());
- if (format.blueBufferSize() >= 0)
- retFormat.setBlueBufferSize(format.blueBufferSize());
- if (format.greenBufferSize() >= 0)
- retFormat.setGreenBufferSize(format.greenBufferSize());
- if (format.redBufferSize() >= 0)
- retFormat.setRedBufferSize(format.redBufferSize());
- if (format.depth())
- retFormat.setDepthBufferSize(format.depthBufferSize() == -1 ? 1 : format.depthBufferSize());
- retFormat.setSwapBehavior(format.doubleBuffer() ? QSurfaceFormat::DoubleBuffer : QSurfaceFormat::SingleBuffer);
- if (format.sampleBuffers())
- retFormat.setSamples(format.samples() == -1 ? 4 : format.samples());
- if (format.stencil())
- retFormat.setStencilBufferSize(format.stencilBufferSize() == -1 ? 1 : format.stencilBufferSize());
- retFormat.setStereo(format.stereo());
- retFormat.setMajorVersion(format.majorVersion());
- retFormat.setMinorVersion(format.minorVersion());
- retFormat.setProfile(static_cast<QSurfaceFormat::OpenGLContextProfile>(format.profile()));
- // QGLFormat has no way to set DeprecatedFunctions, that is, to tell that forward
- // compatibility should not be requested. Some drivers fail to ignore the fwdcompat
- // bit with compatibility profiles so make sure it is not set.
- if (format.profile() == QGLFormat::CompatibilityProfile)
- retFormat.setOption(QSurfaceFormat::DeprecatedFunctions);
- return retFormat;
-}
-
-void QGLContextPrivate::setupSharing() {
- Q_Q(QGLContext);
- QOpenGLContext *sharedContext = guiGlContext->shareContext();
- if (sharedContext) {
- QGLContext *actualSharedContext = QGLContext::fromOpenGLContext(sharedContext);
- sharing = true;
- QGLContextGroup::addShare(q, actualSharedContext);
- }
-}
-
-bool QGLFormat::hasOpenGL()
-{
- return QApplicationPrivate::platformIntegration()
- ->hasCapability(QPlatformIntegration::OpenGL);
-}
-
-void qDeleteQGLContext(void *handle)
-{
- QGLContext *context = static_cast<QGLContext *>(handle);
- delete context;
-}
-
-bool QGLContext::chooseContext(const QGLContext* shareContext)
-{
- Q_D(QGLContext);
- if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) {
- // Unlike in Qt 4, the only possible target is a widget backed by an OpenGL-based
- // QWindow. Pixmaps in particular are not supported anymore as paint devices since
- // starting from Qt 5 QPixmap is raster-backed on almost all platforms.
- d->valid = false;
- }else {
- QWidget *widget = static_cast<QWidget *>(d->paintDevice);
- QGLFormat glformat = format();
- QSurfaceFormat winFormat = QGLFormat::toSurfaceFormat(glformat);
- if (widget->testAttribute(Qt::WA_TranslucentBackground))
- winFormat.setAlphaBufferSize(qMax(winFormat.alphaBufferSize(), 8));
-
- QWindow *window = widget->windowHandle();
- if (!window->handle()
- || window->surfaceType() != QWindow::OpenGLSurface
- || window->requestedFormat() != winFormat)
- {
- window->setSurfaceType(QWindow::OpenGLSurface);
- window->setFormat(winFormat);
- window->destroy();
- window->create();
- }
-
- if (d->ownContext)
- delete d->guiGlContext;
- d->ownContext = true;
- QOpenGLContext *shareGlContext = shareContext ? shareContext->d_func()->guiGlContext : 0;
- d->guiGlContext = new QOpenGLContext;
- d->guiGlContext->setFormat(winFormat);
- d->guiGlContext->setShareContext(shareGlContext);
- d->valid = d->guiGlContext->create();
-
- if (d->valid)
- d->guiGlContext->setQGLContextHandle(this,qDeleteQGLContext);
-
- d->glFormat = QGLFormat::fromSurfaceFormat(d->guiGlContext->format());
- d->setupSharing();
- }
-
-
- return d->valid;
-}
-
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- if (!d->valid)
- return;
- d->cleanup();
-
- d->crWin = false;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- d->initDone = false;
- QGLContextGroup::removeShare(this);
- if (d->guiGlContext) {
- if (QOpenGLContext::currentContext() == d->guiGlContext)
- doneCurrent();
- if (d->ownContext) {
- if (d->guiGlContext->thread() == QThread::currentThread())
- delete d->guiGlContext;
- else
- d->guiGlContext->deleteLater();
- } else
- d->guiGlContext->setQGLContextHandle(0,0);
- d->guiGlContext = 0;
- }
- d->ownContext = false;
-}
-
-void QGLContext::makeCurrent()
-{
- Q_D(QGLContext);
- if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget)
- return;
-
- QWidget *widget = static_cast<QWidget *>(d->paintDevice);
- if (!widget->windowHandle())
- return;
-
- if (d->guiGlContext->makeCurrent(widget->windowHandle())) {
- if (!d->workaroundsCached) {
- d->workaroundsCached = true;
- const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
- if (renderer && strstr(renderer, "Mali")) {
- d->workaround_brokenFBOReadBack = true;
- }
- }
- }
-}
-
-void QGLContext::doneCurrent()
-{
- Q_D(QGLContext);
- d->guiGlContext->doneCurrent();
-}
-
-void QGLContext::swapBuffers() const
-{
- Q_D(const QGLContext);
- if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget)
- return;
-
- QWidget *widget = static_cast<QWidget *>(d->paintDevice);
- if (!widget->windowHandle())
- return;
-
- d->guiGlContext->swapBuffers(widget->windowHandle());
-}
-
-QFunctionPointer QGLContext::getProcAddress(const QString &procName) const
-{
- Q_D(const QGLContext);
- return d->guiGlContext->getProcAddress(procName.toLatin1());
-}
-
-void QGLWidget::setContext(QGLContext *context,
- const QGLContext* shareContext,
- bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
-
- if (context->device() == 0) // a context may refere to more than 1 window.
- context->setDevice(this); //but its better to point to 1 of them than none of them.
-
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- if (!d->glcx->isValid())
- d->glcx->create(shareContext ? shareContext : oldcx);
-
- if (deleteOldContext)
- delete oldcx;
-}
-
-void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget)
-{
- initContext(context, shareWidget);
-}
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- return false;
-}
-
-QColor QGLContext::overlayTransparentColor() const
-{
- return QColor(); // Invalid color
-}
-
-uint QGLContext::colorIndex(const QColor&) const
-{
- return 0;
-}
-
-/*
- QGLTemporaryContext implementation
-*/
-class QGLTemporaryContextPrivate
-{
-public:
- QWindow *window;
- QOpenGLContext *context;
-
- QGLContext *oldContext;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->oldContext = const_cast<QGLContext *>(QGLContext::currentContext());
-
- d->window = new QWindow;
- d->window->setSurfaceType(QWindow::OpenGLSurface);
- d->window->setGeometry(QRect(0, 0, 3, 3));
- d->window->create();
-
- d->context = new QOpenGLContext;
-#if !defined(QT_OPENGL_ES)
- if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
- // On desktop, request latest released version
- QSurfaceFormat format;
-#if defined(Q_OS_MAC)
- // OS X is limited to OpenGL 3.2 Core Profile at present
- // so set that here. If we use compatibility profile it
- // only reports 2.x contexts.
- format.setMajorVersion(3);
- format.setMinorVersion(2);
- format.setProfile(QSurfaceFormat::CoreProfile);
-#else
- format.setMajorVersion(4);
- format.setMinorVersion(3);
-#endif
- d->context->setFormat(format);
- }
-#endif // QT_OPENGL_ES
- d->context->create();
- d->context->makeCurrent(d->window);
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- if (d->oldContext)
- d->oldContext->makeCurrent();
-
- delete d->context;
- delete d->window;
-}
-
-
-bool QGLWidgetPrivate::renderCxPm(QPixmap*)
-{
- return false;
-}
-
-/*! \internal
- Free up any allocated colormaps. This fn is only called for
- top-level widgets.
-*/
-void QGLWidgetPrivate::cleanupColormaps()
-{
-}
-
-bool QGLWidget::event(QEvent *e)
-{
- Q_D(QGLWidget);
-
- // A re-parent will destroy the window and re-create it. We should not reset the context while it happens.
- if (e->type() == QEvent::ParentAboutToChange)
- d->parent_changing = true;
-
- if (e->type() == QEvent::ParentChange)
- d->parent_changing = false;
-
- return QWidget::event(e);
-}
-
-void QGLWidget::resizeEvent(QResizeEvent *e)
-{
- Q_D(QGLWidget);
-
- QWidget::resizeEvent(e);
- if (!isValid())
- return;
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- const qreal scaleFactor = (window() && window()->windowHandle()) ?
- window()->windowHandle()->devicePixelRatio() : 1.0;
-
- resizeGL(width() * scaleFactor, height() * scaleFactor);
-}
-
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return 0;
-}
-
-void QGLWidget::makeOverlayCurrent()
-{
-}
-
-
-void QGLWidget::updateOverlayGL()
-{
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- Q_D(const QGLWidget);
- return d->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap & c)
-{
- Q_UNUSED(c);
-}
-
-QGLContext::QGLContext(QOpenGLContext *context)
- : d_ptr(new QGLContextPrivate(this))
-{
- Q_D(QGLContext);
- d->init(0, QGLFormat::fromSurfaceFormat(context->format()));
- d->guiGlContext = context;
- d->guiGlContext->setQGLContextHandle(this,qDeleteQGLContext);
- d->ownContext = false;
- d->valid = context->isValid();
- d->setupSharing();
-}
-
-QOpenGLContext *QGLContext::contextHandle() const
-{
- Q_D(const QGLContext);
- return d->guiGlContext;
-}
-
-/*!
- Returns a OpenGL context for the window context specified by the \a context
- parameter.
-*/
-QGLContext *QGLContext::fromOpenGLContext(QOpenGLContext *context)
-{
- if (!context)
- return 0;
- if (context->qGLContextHandle()) {
- return reinterpret_cast<QGLContext *>(context->qGLContextHandle());
- }
- QGLContext *glContext = new QGLContext(context);
- //Don't call create on context. This can cause the platformFormat to be set on the widget, which
- //will cause the platformWindow to be recreated.
- return glContext;
-}
-
-QT_END_NAMESPACE
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 419055f1a3..57498f8929 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); \
@@ -94,6 +94,10 @@ extern QImage qt_gl_read_frame_buffer(const QSize&, bool, bool);
#define GL_DEPTH_COMPONENT24 0x81A6
#endif
+#ifndef GL_DEPTH_COMPONENT24_OES
+#define GL_DEPTH_COMPONENT24_OES 0x81A6
+#endif
+
#ifndef GL_READ_FRAMEBUFFER
#define GL_READ_FRAMEBUFFER 0x8CA8
#endif
@@ -460,7 +464,7 @@ namespace
void freeTextureFunc(QGLContext *ctx, GLuint id)
{
Q_UNUSED(ctx);
- glDeleteTextures(1, &id);
+ ctx->contextHandle()->functions()->glDeleteTextures(1, &id);
}
}
@@ -493,10 +497,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 +509,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 +698,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 12b26e5381..4205761472 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;
}
@@ -338,7 +338,7 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
if (d->invalid || !d->fbo)
return;
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ const QGLContext *ctx = QGLContext::currentContext();
if (!ctx)
return;
@@ -352,19 +352,19 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
#define GL_DRAW_FRAMEBUFFER 0x8CA9
#endif
- QOpenGLExtensions extensions(ctx);
+ QOpenGLExtensions extensions(ctx->contextHandle());
if (d->blit_fbo) {
QOpenGLFramebufferObject::blitFramebuffer(d->blit_fbo, d->fbo);
extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, d->blit_fbo->handle());
}
- glBindTexture(GL_TEXTURE_2D, texture_id);
+ extensions.glBindTexture(GL_TEXTURE_2D, texture_id);
#ifndef QT_OPENGL_ES
- GLenum format = ctx->isOpenGLES() ? GL_RGBA : GL_RGBA8;
- glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0);
+ GLenum format = ctx->contextHandle()->isOpenGLES() ? GL_RGBA : GL_RGBA8;
+ extensions.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);
+ extensions.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 6173ad1288..9cd6ada058 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()->isOpenGLES())
- 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;