Remove duplicated code for handling OpenGL extensions in QtOpenGL

We now re-use QOpenGLExtensions/Functions from QtGui in the same way
as QtGui uses these classes. There is still some duplicated logic
in qglfunctions.cpp, but this code now at least uses the shared
QOpenGLExtensionMatcher class.

Change-Id: Ie04008c43d430ae805e6ec1c45e7e363deeb3b8f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
This commit is contained in:
Tor Arne Vestbø 2013-02-06 22:36:27 +01:00 committed by The Qt Project
parent 3250ec0c8f
commit 159f42222d
17 changed files with 371 additions and 1607 deletions

View File

@ -48,7 +48,7 @@
QT_BEGIN_NAMESPACE
class QOpenGLExtensionMatcher
class Q_GUI_EXPORT QOpenGLExtensionMatcher
{
public:
QOpenGLExtensionMatcher();

View File

@ -112,7 +112,7 @@ QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate()
}
if (elementIndicesVBOId != 0) {
glDeleteBuffers(1, &elementIndicesVBOId);
funcs.glDeleteBuffers(1, &elementIndicesVBOId);
elementIndicesVBOId = 0;
}
}
@ -199,7 +199,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
// Get the image data for the pattern
QImage texImage = qt_imageForBrush(style, false);
glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
funcs.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);
}
@ -212,7 +212,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
// for opacity to the cache.
GLuint texId = QGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0);
glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
glBindTexture(GL_TEXTURE_2D, texId);
if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient)
@ -229,7 +229,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);
glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
QGLTexture *tex = ctx->d_func()->bindTexture(currentBrushPixmap, GL_TEXTURE_2D, GL_RGBA,
QGLContext::InternalBindOption |
QGLContext::CanFlipNativePixmapBindOption);
@ -426,9 +426,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.
glVertexAttrib3fv(QT_PMV_MATRIX_1_ATTR, pmvMatrix[0]);
glVertexAttrib3fv(QT_PMV_MATRIX_2_ATTR, pmvMatrix[1]);
glVertexAttrib3fv(QT_PMV_MATRIX_3_ATTR, pmvMatrix[2]);
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]);
dasher.setInvScale(inverseScale);
stroker.setInvScale(inverseScale);
@ -538,12 +538,11 @@ void QGL2PaintEngineEx::beginNativePainting()
d->nativePaintingActive = true;
QGLContext *ctx = d->ctx;
glUseProgram(0);
d->funcs.glUseProgram(0);
// Disable all the vertex attribute arrays:
for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
glDisableVertexAttribArray(i);
d->funcs.glDisableVertexAttribArray(i);
#ifndef QT_OPENGL_ES_2
const QGLFormat &fmt = d->device->format();
@ -572,8 +571,6 @@ void QGL2PaintEngineEx::beginNativePainting()
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&mv_matrix[0][0]);
}
#else
Q_UNUSED(ctx);
#endif
d->lastTextureUsed = GLuint(-1);
@ -588,13 +585,13 @@ void QGL2PaintEngineEx::beginNativePainting()
void QGL2PaintEngineExPrivate::resetGLState()
{
glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
funcs.glActiveTexture(GL_TEXTURE0);
glDisable(GL_STENCIL_TEST);
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
glDepthMask(true);
glDepthFunc(GL_LESS);
glClearDepth(1);
funcs.glClearDepthf(1);
glStencilMask(0xff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_ALWAYS, 0, 0xff);
@ -604,7 +601,7 @@ void QGL2PaintEngineExPrivate::resetGLState()
#ifndef QT_OPENGL_ES_2
// gl_Color, corresponding to vertex attribute 3, may have been changed
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glVertexAttrib4fv(3, color);
funcs.glVertexAttrib4fv(3, color);
#endif
}
@ -733,7 +730,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
glDeleteBuffers(1, &cache->vbo);
funcs.glDeleteBuffers(1, &cache->vbo);
cache->vbo = 0;
Q_ASSERT(cache->ibo == 0);
#else
@ -760,9 +757,9 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
cache->primitiveType = GL_TRIANGLE_FAN;
cache->iscale = inverseScale;
#ifdef QT_OPENGL_CACHE_AS_VBOS
glGenBuffers(1, &cache->vbo);
glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW);
funcs.glGenBuffers(1, &cache->vbo);
funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
funcs.glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW);
cache->ibo = 0;
#else
cache->vertices = (float *) malloc(floatSizeInBytes);
@ -773,7 +770,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
prepareForDraw(currentBrush.isOpaque());
#ifdef QT_OPENGL_CACHE_AS_VBOS
glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0);
#else
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices);
@ -999,9 +996,9 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data,
}
// Inc. for front-facing triangle
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP);
funcs.glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP);
// Dec. for back-facing "holes"
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP);
funcs.glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP);
glStencilMask(~GL_STENCIL_HIGH_BIT);
drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN);
@ -1389,7 +1386,7 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c
bindOptions |= QGLContext::TemporarilyCachedBindOption;
#endif
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
QGLTexture *texture =
ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, bindOptions);
@ -1431,7 +1428,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const
ensureActive();
d->transferMode(ImageDrawingMode);
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
QGLContext::BindOptions bindOptions = QGLContext::InternalBindOption;
#ifdef QGL_USE_TEXTURE_POOL
@ -1491,10 +1488,7 @@ bool QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const
ensureActive();
d->transferMode(ImageDrawingMode);
#ifndef QT_OPENGL_ES_2
QGLContext *ctx = d->ctx;
#endif
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
glBindTexture(GL_TEXTURE_2D, textureId);
QGLRect srcRect(src.left(), src.bottom(), src.right(), src.top());
@ -1778,7 +1772,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
glEnable(GL_BLEND);
glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR);
glBlendColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
funcs.glBlendColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
} else {
// Other brush styles need two passes.
@ -1795,7 +1789,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
glEnable(GL_BLEND);
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
glBindTexture(GL_TEXTURE_2D, cache->texture());
updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
@ -1830,7 +1824,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
QGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QGLTextureGlyphCache::Linear:QGLTextureGlyphCache::Nearest;
if (lastMaskTextureUsed != cache->texture() || cache->filterMode() != filterMode) {
glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
if (lastMaskTextureUsed != cache->texture()) {
glBindTexture(GL_TEXTURE_2D, cache->texture());
lastMaskTextureUsed = cache->texture();
@ -1937,7 +1931,7 @@ void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragmen
allOpaque &= (opacity >= 0.99f);
}
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
QGLTexture *texture = ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA,
QGLContext::InternalBindOption
| QGLContext::CanFlipNativePixmapBindOption);
@ -2010,14 +2004,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
// go after beginPaint:
d->device->beginPaint();
#if !defined(QT_OPENGL_ES_2)
bool success = qt_resolve_version_2_0_functions(d->ctx)
&& qt_resolve_buffer_extensions(d->ctx)
&& (!QGLFramebufferObject::hasOpenGLFramebufferObjects()
|| qt_resolve_framebufferobject_extensions(d->ctx));
Q_ASSERT(success);
Q_UNUSED(success);
#endif
d->funcs.initializeOpenGLFunctions();
d->shaderManager = new QGLEngineShaderManager(d->ctx);
@ -2051,7 +2038,7 @@ bool QGL2PaintEngineEx::end()
Q_D(QGL2PaintEngineEx);
QGLContext *ctx = d->ctx;
glUseProgram(0);
d->funcs.glUseProgram(0);
d->transferMode(BrushDrawingMode);
d->device->endPaint();

View File

@ -62,6 +62,7 @@
#include <private/qfontengine_p.h>
#include <private/qdatabuffer_p.h>
#include <private/qtriangulatingstroker_p.h>
#include <private/qopenglextensions_p.h>
enum EngineMode {
ImageDrawingMode,
@ -256,6 +257,8 @@ public:
EngineMode mode;
QFontEngineGlyphCache::Type glyphCacheType;
QOpenGLExtensions funcs;
// Dirty flags
bool matrixDirty; // Implies matrix uniforms are also dirty
bool compositionModeDirty;
@ -317,9 +320,9 @@ void QGL2PaintEngineExPrivate::setVertexAttributePointer(unsigned int arrayIndex
vertexAttribPointers[arrayIndex] = pointer;
if (arrayIndex == QT_OPACITY_ATTR)
glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, pointer);
funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, pointer);
else
glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, pointer);
funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, pointer);
}
QT_END_NAMESPACE

View File

@ -41,6 +41,7 @@
#include "qtextureglyphcache_gl_p.h"
#include "qpaintengineex_opengl2_p.h"
#include "qglfunctions.h"
#include "private/qglengineshadersource_p.h"
QT_BEGIN_NAMESPACE
@ -167,10 +168,12 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
return;
}
QOpenGLFunctions *funcs = ctx->contextHandle()->functions();
// ### the QTextureGlyphCache API needs to be reworked to allow
// ### resizeTextureData to fail
glBindFramebuffer(GL_FRAMEBUFFER, m_textureResource->m_fbo);
funcs->glBindFramebuffer(GL_FRAMEBUFFER, m_textureResource->m_fbo);
GLuint tmp_texture;
glGenTextures(1, &tmp_texture);
@ -183,10 +186,10 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
m_filterMode = Nearest;
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, tmp_texture, 0);
funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, tmp_texture, 0);
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
funcs->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
glBindTexture(GL_TEXTURE_2D, oldTexture);
if (pex != 0)
@ -232,8 +235,8 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
m_blitProgram->link();
}
glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_vertexCoordinateArray);
glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_textureCoordinateArray);
funcs->glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_vertexCoordinateArray);
funcs->glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_textureCoordinateArray);
m_blitProgram->bind();
m_blitProgram->enableAttributeArray(int(QT_VERTEX_COORDS_ATTR));
@ -258,12 +261,12 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, 0);
funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, 0);
glDeleteTextures(1, &tmp_texture);
glDeleteTextures(1, &oldTexture);
glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo);
funcs->glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo);
if (pex != 0) {
glViewport(0, 0, pex->width, pex->height);

View File

@ -57,6 +57,7 @@
#include <private/qgl_p.h>
#include <qglshaderprogram.h>
#include <qglframebufferobject.h>
#include <qopenglfunctions.h>
// #define QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
@ -73,7 +74,7 @@ struct QGLGlyphTexture : public QOpenGLSharedResource
, m_height(0)
{
if (ctx && QGLFramebufferObject::hasOpenGLFramebufferObjects() && !ctx->d_ptr->workaround_brokenFBOReadBack)
glGenFramebuffers(1, &m_fbo);
ctx->contextHandle()->functions()->glGenFramebuffers(1, &m_fbo);
#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
qDebug(" -> QGLGlyphTexture() %p for context %p.", this, ctx);
@ -88,8 +89,8 @@ struct QGLGlyphTexture : public QOpenGLSharedResource
#else
Q_UNUSED(ctx);
#endif
if (m_fbo)
glDeleteFramebuffers(1, &m_fbo);
if (ctx && m_fbo)
ctx->contextHandle()->functions()->glDeleteFramebuffers(1, &m_fbo);
if (m_width || m_height)
glDeleteTextures(1, &m_texture);
}

View File

@ -23,7 +23,6 @@ HEADERS += qgl.h \
qglpixelbuffer_p.h \
qglframebufferobject.h \
qglframebufferobject_p.h \
qglextensions_p.h \
qglpaintdevice_p.h \
qglbuffer.h \
qtopenglglobal.h
@ -33,7 +32,6 @@ SOURCES += qgl.cpp \
qglfunctions.cpp \
qglpixelbuffer.cpp \
qglframebufferobject.cpp \
qglextensions.cpp \
qglpaintdevice.cpp \
qglbuffer.cpp \

View File

@ -59,6 +59,7 @@
#include <qglpixelbuffer.h>
#include <qglframebufferobject.h>
#include <private/qopenglextensions_p.h>
#include <private/qimage_p.h>
#include <qpa/qplatformpixmap.h>
@ -73,7 +74,52 @@
QT_BEGIN_NAMESPACE
QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs;
class QGLDefaultExtensions
{
public:
QGLDefaultExtensions() : extensions(0) {
QGLTemporaryContext tempContext;
Q_ASSERT(QOpenGLContext::currentContext());
QOpenGLExtensions *ext = qgl_extensions();
Q_ASSERT(ext);
extensions = ext->openGLExtensions();
features = ext->openGLFeatures();
}
QOpenGLFunctions::OpenGLFeatures features;
QOpenGLExtensions::OpenGLExtensions extensions;
};
Q_GLOBAL_STATIC(QGLDefaultExtensions, qtDefaultExtensions)
bool qgl_hasFeature(QOpenGLFunctions::OpenGLFeature feature)
{
if (QOpenGLContext::currentContext())
return QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(feature);
return qtDefaultExtensions()->features & feature;
}
bool qgl_hasExtension(QOpenGLExtensions::OpenGLExtension extension)
{
if (QOpenGLContext::currentContext())
return qgl_extensions()->hasOpenGLExtension(extension);
return qtDefaultExtensions()->extensions & 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
for that context will be returned instead.
*/
QOpenGLExtensions* qgl_extensions()
{
if (QOpenGLContext *context = QOpenGLContext::currentContext())
return static_cast<QOpenGLExtensions *>(context->functions());
Q_ASSERT(false);
return 0;
}
struct QGLThreadContext {
~QGLThreadContext() {
@ -1567,8 +1613,6 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
max_texture_size = -1;
version_flags_cached = false;
version_flags = QGLFormat::OpenGL_Version_None;
extension_flags_cached = false;
extension_flags = 0;
current_fbo = 0;
default_fbo = 0;
active_engine = 0;
@ -1956,30 +2000,32 @@ void QGLContextPrivate::cleanup()
#define ctx q_ptr
void QGLContextPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled)
{
Q_Q(QGLContext);
Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT);
#ifdef glEnableVertexAttribArray
Q_ASSERT(glEnableVertexAttribArray);
#endif
if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled)
glDisableVertexAttribArray(arrayIndex);
q->functions()->glDisableVertexAttribArray(arrayIndex);
if (!vertexAttributeArraysEnabledState[arrayIndex] && enabled)
glEnableVertexAttribArray(arrayIndex);
q->functions()->glEnableVertexAttribArray(arrayIndex);
vertexAttributeArraysEnabledState[arrayIndex] = enabled;
}
void QGLContextPrivate::syncGlState()
{
Q_Q(QGLContext);
#ifdef glEnableVertexAttribArray
Q_ASSERT(glEnableVertexAttribArray);
#endif
for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) {
if (vertexAttributeArraysEnabledState[i])
glEnableVertexAttribArray(i);
q->functions()->glEnableVertexAttribArray(i);
else
glDisableVertexAttribArray(i);
q->functions()->glDisableVertexAttribArray(i);
}
}
@ -2129,11 +2175,6 @@ static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum textu
}
}
QGLExtensionFuncs& QGLContextPrivate::extensionFuncs(const QGLContext *)
{
return qt_extensionFuncs;
}
/*! \internal */
QGLTexture *QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format,
QGLContext::BindOptions options)
@ -2221,7 +2262,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
QImage img = image;
if (!(QGLExtensions::glExtensions() & QGLExtensions::NPOTTextures)
if (!qgl_extensions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures)
&& !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0)
&& (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height())))
{
@ -2243,7 +2284,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
bool genMipmap = false;
#endif
if (glFormat.directRendering()
&& (QGLExtensions::glExtensions() & QGLExtensions::GenerateMipmap)
&& (qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::GenerateMipmap))
&& target == GL_TEXTURE_2D
&& (options & QGLContext::MipmapBindOption))
{
@ -2267,7 +2308,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
bool premul = options & QGLContext::PremultipliedAlphaBindOption;
GLenum externalFormat;
GLuint pixel_type;
if (QGLExtensions::glExtensions() & QGLExtensions::BGRATextureFormat) {
if (qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat)) {
externalFormat = GL_BGRA;
if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2)
pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV;
@ -4651,192 +4692,6 @@ QPaintEngine *QGLWidget::paintEngine() const
return qt_qgl_paint_engine();
}
typedef const GLubyte * (QGLF_APIENTRYP qt_glGetStringi)(GLenum, GLuint);
#ifndef GL_NUM_EXTENSIONS
#define GL_NUM_EXTENSIONS 0x821D
#endif
QGLExtensionMatcher::QGLExtensionMatcher(const char *str)
{
init(str);
}
QGLExtensionMatcher::QGLExtensionMatcher()
{
const char *extensionStr = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
if (extensionStr) {
init(extensionStr);
} else {
// clear error state
while (glGetError()) {}
const QGLContext *ctx = QGLContext::currentContext();
if (ctx) {
qt_glGetStringi glGetStringi = (qt_glGetStringi)ctx->getProcAddress(QLatin1String("glGetStringi"));
GLint numExtensions;
glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
for (int i = 0; i < numExtensions; ++i) {
const char *str = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i));
m_offsets << m_extensions.size();
while (*str != 0)
m_extensions.append(*str++);
m_extensions.append(' ');
}
}
}
}
void QGLExtensionMatcher::init(const char *str)
{
m_extensions = str;
// make sure extension string ends with a space
if (!m_extensions.endsWith(' '))
m_extensions.append(' ');
int index = 0;
int next = 0;
while ((next = m_extensions.indexOf(' ', index)) >= 0) {
m_offsets << index;
index = next + 1;
}
}
// ####TODO Properly #ifdef this class to use #define symbols actually defined
// by OpenGL/ES includes
#ifndef GL_FRAMEBUFFER_SRGB_CAPABLE_EXT
#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
#endif
/*
Returns the GL extensions for the current context.
*/
QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
{
QGLExtensionMatcher extensions;
Extensions glExtensions;
if (extensions.match("GL_ARB_texture_rectangle"))
glExtensions |= TextureRectangle;
if (extensions.match("GL_ARB_multisample"))
glExtensions |= SampleBuffers;
if (extensions.match("GL_SGIS_generate_mipmap"))
glExtensions |= GenerateMipmap;
if (extensions.match("GL_ARB_texture_compression"))
glExtensions |= TextureCompression;
if (extensions.match("GL_EXT_texture_compression_s3tc"))
glExtensions |= DDSTextureCompression;
if (extensions.match("GL_OES_compressed_ETC1_RGB8_texture"))
glExtensions |= ETC1TextureCompression;
if (extensions.match("GL_IMG_texture_compression_pvrtc"))
glExtensions |= PVRTCTextureCompression;
if (extensions.match("GL_ARB_fragment_program"))
glExtensions |= FragmentProgram;
if (extensions.match("GL_ARB_fragment_shader"))
glExtensions |= FragmentShader;
if (extensions.match("GL_ARB_shader_objects"))
glExtensions |= FragmentShader;
if (extensions.match("GL_ARB_texture_mirrored_repeat"))
glExtensions |= MirroredRepeat;
if (extensions.match("GL_EXT_framebuffer_object"))
glExtensions |= FramebufferObject;
if (extensions.match("GL_EXT_stencil_two_side"))
glExtensions |= StencilTwoSide;
if (extensions.match("GL_EXT_stencil_wrap"))
glExtensions |= StencilWrap;
if (extensions.match("GL_EXT_packed_depth_stencil"))
glExtensions |= PackedDepthStencil;
if (extensions.match("GL_NV_float_buffer"))
glExtensions |= NVFloatBuffer;
if (extensions.match("GL_ARB_pixel_buffer_object"))
glExtensions |= PixelBufferObject;
if (extensions.match("GL_IMG_texture_format_BGRA8888"))
glExtensions |= BGRATextureFormat;
#if defined(QT_OPENGL_ES_2)
glExtensions |= FramebufferObject;
glExtensions |= GenerateMipmap;
glExtensions |= FragmentShader;
#endif
#if defined(QT_OPENGL_ES)
if (extensions.match("GL_OES_packed_depth_stencil"))
glExtensions |= PackedDepthStencil;
if (extensions.match("GL_OES_element_index_uint"))
glExtensions |= ElementIndexUint;
if (extensions.match("GL_OES_depth24"))
glExtensions |= Depth24;
#else
glExtensions |= ElementIndexUint;
#endif
if (extensions.match("GL_ARB_framebuffer_object")) {
// ARB_framebuffer_object also includes EXT_framebuffer_blit.
glExtensions |= FramebufferObject;
glExtensions |= FramebufferBlit;
}
if (extensions.match("GL_EXT_framebuffer_blit"))
glExtensions |= FramebufferBlit;
if (extensions.match("GL_ARB_texture_non_power_of_two"))
glExtensions |= NPOTTextures;
if (extensions.match("GL_EXT_bgra"))
glExtensions |= BGRATextureFormat;
#if !defined(QT_OPENGL_ES)
{
GLboolean srgbCapableFramebuffers = false;
glGetBooleanv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgbCapableFramebuffers);
if (srgbCapableFramebuffers)
glExtensions |= SRGBFrameBuffer;
}
#endif
return glExtensions;
}
class QGLDefaultExtensions
{
public:
QGLDefaultExtensions() {
QGLTemporaryContext tempContext;
extensions = QGLExtensions::currentContextExtensions();
}
QGLExtensions::Extensions extensions;
};
Q_GLOBAL_STATIC(QGLDefaultExtensions, qtDefaultExtensions)
/*
Returns the GL extensions for the current QGLContext. If there is no
current QGLContext, a default context will be created and the extensions
for that context will be returned instead.
*/
QGLExtensions::Extensions QGLExtensions::glExtensions()
{
Extensions extensionFlags = 0;
QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext());
if (currentCtx && currentCtx->d_func()->extension_flags_cached)
return currentCtx->d_func()->extension_flags;
if (!currentCtx) {
extensionFlags = qtDefaultExtensions()->extensions;
} else {
extensionFlags = currentContextExtensions();
currentCtx->d_func()->extension_flags_cached = true;
currentCtx->d_func()->extension_flags = extensionFlags;
}
return extensionFlags;
}
/*
This is the shared initialization for all platforms. Called from QGLWidgetPrivate::init()
*/
@ -5023,21 +4878,6 @@ QSize QGLTexture::bindCompressedTexture
// systems such as x86 and ARM at the moment.
return QSize();
}
#if !defined(QT_OPENGL_ES)
if (!glCompressedTexImage2D) {
if (!(QGLExtensions::glExtensions() & QGLExtensions::TextureCompression)) {
qWarning("QGLContext::bindTexture(): The GL implementation does "
"not support texture compression extensions.");
return QSize();
}
glCompressedTexImage2D = (_glCompressedTexImage2DARB) ctx->getProcAddress(QLatin1String("glCompressedTexImage2DARB"));
if (!glCompressedTexImage2D) {
qWarning("QGLContext::bindTexture(): could not resolve "
"glCompressedTexImage2DARB.");
return QSize();
}
}
#endif
if (!format) {
// Auto-detect the format from the header.
if (len >= 4 && !qstrncmp(buf, "DDS ", 4))
@ -5064,7 +4904,7 @@ QSize QGLTexture::bindCompressedTextureDDS(const char *buf, int len)
return QSize();
// Bail out if the necessary extension is not present.
if (!(QGLExtensions::glExtensions() & QGLExtensions::DDSTextureCompression)) {
if (!qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::DDSTextureCompression)) {
qWarning("QGLContext::bindTexture(): DDS texture compression is not supported.");
return QSize();
}
@ -5116,7 +4956,7 @@ QSize QGLTexture::bindCompressedTextureDDS(const char *buf, int len)
size = ((w+3)/4) * ((h+3)/4) * blockSize;
if (size > available)
break;
glCompressedTexImage2D(GL_TEXTURE_2D, i, format, w, h, 0,
qgl_extensions()->glCompressedTexImage2D(GL_TEXTURE_2D, i, format, w, h, 0,
size, pixels + offset);
offset += size;
available -= size;
@ -5174,14 +5014,12 @@ QSize QGLTexture::bindCompressedTexturePVR(const char *buf, int len)
// Bail out if the necessary extension is not present.
if (textureFormat == GL_ETC1_RGB8_OES) {
if (!(QGLExtensions::glExtensions() &
QGLExtensions::ETC1TextureCompression)) {
if (!qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::ETC1TextureCompression)) {
qWarning("QGLContext::bindTexture(): ETC1 texture compression is not supported.");
return QSize();
}
} else {
if (!(QGLExtensions::glExtensions() &
QGLExtensions::PVRTCTextureCompression)) {
if (!qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::PVRTCTextureCompression)) {
qWarning("QGLContext::bindTexture(): PVRTC texture compression is not supported.");
return QSize();
}
@ -5227,7 +5065,7 @@ QSize QGLTexture::bindCompressedTexturePVR(const char *buf, int len)
pvrHeader->bitsPerPixel) / 8;
if (size > bufferSize)
break;
glCompressedTexImage2D(GL_TEXTURE_2D, GLint(level), textureFormat,
qgl_extensions()->glCompressedTexImage2D(GL_TEXTURE_2D, GLint(level), textureFormat,
GLsizei(width), GLsizei(height), 0,
GLsizei(size), buffer);
width /= 2;

View File

@ -368,7 +368,6 @@ private:
friend struct QGLGlyphTexture;
friend class QGLContextGroup;
friend class QGLPixmapBlurFilter;
friend class QGLExtensions;
friend class QGLTexture;
friend QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags();
friend class QGLFramebufferObject;

View File

@ -62,17 +62,18 @@
#include "QtCore/qatomic.h"
#include "QtWidgets/private/qwidget_p.h"
#include "QtGui/private/qopenglcontext_p.h"
#include "QtGui/private/qopenglextensions_p.h"
#include "qcache.h"
#include "qglpaintdevice_p.h"
#include <QtGui/QOpenGLContext>
#include <QtOpenGL/private/qglextensions_p.h>
QT_BEGIN_NAMESPACE
class QGLContext;
class QGLOverlayWidget;
class QPixmap;
class QOpenGLExtensions;
class QGLFormatPrivate
{
@ -162,7 +163,6 @@ class QGLContextGroup
public:
~QGLContextGroup();
QGLExtensionFuncs &extensionFuncs() {return m_extensionFuncs;}
const QGLContext *context() const {return m_context;}
bool isSharing() const { return m_shares.size() >= 2; }
QList<const QGLContext *> shares() const { return m_shares; }
@ -173,7 +173,6 @@ public:
private:
QGLContextGroup(const QGLContext *context);
QGLExtensionFuncs m_extensionFuncs;
const QGLContext *m_context; // context group's representative
QList<const QGLContext *> m_shares;
QAtomicInt m_refs;
@ -187,39 +186,6 @@ private:
// "ctx" is destroyed. Returns null if nothing is sharing with ctx.
const QGLContext *qt_gl_transfer_context(const QGLContext *);
// GL extension definitions
class QGLExtensions {
public:
enum Extension {
TextureRectangle = 0x00000001,
SampleBuffers = 0x00000002,
GenerateMipmap = 0x00000004,
TextureCompression = 0x00000008,
FragmentProgram = 0x00000010,
MirroredRepeat = 0x00000020,
FramebufferObject = 0x00000040,
StencilTwoSide = 0x00000080,
StencilWrap = 0x00000100,
PackedDepthStencil = 0x00000200,
NVFloatBuffer = 0x00000400,
PixelBufferObject = 0x00000800,
FramebufferBlit = 0x00001000,
NPOTTextures = 0x00002000,
BGRATextureFormat = 0x00004000,
DDSTextureCompression = 0x00008000,
ETC1TextureCompression = 0x00010000,
PVRTCTextureCompression = 0x00020000,
FragmentShader = 0x00040000,
ElementIndexUint = 0x00080000,
Depth24 = 0x00100000,
SRGBFrameBuffer = 0x00200000
};
Q_DECLARE_FLAGS(Extensions, Extension)
static Extensions glExtensions();
static Extensions currentContextExtensions();
};
/*
QGLTemporaryContext - the main objective of this class is to have a way of
creating a GL context and making it current, without going via QGLWidget
@ -288,7 +254,6 @@ public:
uint crWin : 1;
uint internal_context : 1;
uint version_flags_cached : 1;
uint extension_flags_cached : 1;
// workarounds for driver/hw bugs on different platforms
uint workaround_needsFullClearOnEveryFrame : 1;
@ -306,7 +271,6 @@ public:
QColor transpColor;
QGLContext *q_ptr;
QGLFormat::OpenGLVersionFlags version_flags;
QGLExtensions::Extensions extension_flags;
QGLContextGroup *group;
GLint max_texture_size;
@ -322,14 +286,9 @@ public:
static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; }
static Q_OPENGL_EXPORT QGLExtensionFuncs qt_extensionFuncs;
static Q_OPENGL_EXPORT QGLExtensionFuncs& extensionFuncs(const QGLContext *);
static void setCurrentContext(QGLContext *context);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QGLExtensions::Extensions)
// Temporarily make a context current if not already current or
// shared with the current contex. The previous context is made
// current when the object goes out of scope.
@ -510,6 +469,10 @@ QGLTexture* QGLTextureCache::getTexture(QGLContext *ctx, qint64 key)
Q_OPENGL_EXPORT extern QPaintEngine* qt_qgl_paint_engine();
QOpenGLExtensions* qgl_extensions();
bool qgl_hasFeature(QOpenGLFunctions::OpenGLFeature feature);
bool qgl_hasExtension(QOpenGLExtensions::OpenGLExtension extension);
// Put a guard around a GL object identifier and its context.
// When the context goes away, a shared context will be used
// in its place. If there are no more shared contexts, then
@ -574,35 +537,6 @@ QGLSharedResourceGuardBase *createSharedResourceGuard(QGLContext *context, GLuin
return new QGLSharedResourceGuard<Func>(context, id, cleanupFunc);
}
class QGLExtensionMatcher
{
public:
QGLExtensionMatcher(const char *str);
QGLExtensionMatcher();
bool match(const char *str) const {
int str_length = qstrlen(str);
Q_ASSERT(str);
Q_ASSERT(str_length > 0);
Q_ASSERT(str[str_length-1] != ' ');
for (int i = 0; i < m_offsets.size(); ++i) {
const char *extension = m_extensions.constData() + m_offsets.at(i);
if (qstrncmp(extension, str, str_length) == 0 && extension[str_length] == ' ')
return true;
}
return false;
}
private:
void init(const char *str);
QByteArray m_extensions;
QVector<int> m_offsets;
};
// this is a class that wraps a QThreadStorage object for storing
// thread local instances of the GL 1 and GL 2 paint engines

View File

@ -41,7 +41,7 @@
#include <QtOpenGL/qgl.h>
#include <QtOpenGL/private/qgl_p.h>
#include <QtOpenGL/private/qglextensions_p.h>
#include <private/qopenglextensions_p.h>
#include <QtCore/qatomic.h>
#include "qglbuffer.h"
@ -139,7 +139,8 @@ public:
type(t),
guard(0),
usagePattern(QGLBuffer::StaticDraw),
actualUsagePattern(QGLBuffer::StaticDraw)
actualUsagePattern(QGLBuffer::StaticDraw),
funcs(0)
{
}
@ -148,6 +149,7 @@ public:
QGLSharedResourceGuardBase *guard;
QGLBuffer::UsagePattern usagePattern;
QGLBuffer::UsagePattern actualUsagePattern;
QOpenGLExtensions *funcs;
};
/*!
@ -259,8 +261,8 @@ void QGLBuffer::setUsagePattern(QGLBuffer::UsagePattern value)
namespace {
void freeBufferFunc(QGLContext *ctx, GLuint id)
{
Q_UNUSED(ctx);
glDeleteBuffers(1, &id);
Q_ASSERT(ctx);
ctx->contextHandle()->functions()->glDeleteBuffers(1, &id);
}
}
@ -284,10 +286,13 @@ bool QGLBuffer::create()
return true;
QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx) {
if (!qt_resolve_buffer_extensions(ctx))
delete d->funcs;
d->funcs = new QOpenGLExtensions(ctx->contextHandle());
if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers))
return false;
GLuint bufferId = 0;
glGenBuffers(1, &bufferId);
d->funcs->glGenBuffers(1, &bufferId);
if (bufferId) {
if (d->guard)
d->guard->free();
@ -340,10 +345,10 @@ bool QGLBuffer::read(int offset, void *data, int count)
{
#if !defined(QT_OPENGL_ES)
Q_D(QGLBuffer);
if (!glGetBufferSubData || !d->guard->id())
if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
return false;
while (glGetError() != GL_NO_ERROR) ; // Clear error state.
glGetBufferSubData(d->type, offset, count, data);
d->funcs->glGetBufferSubData(d->type, offset, count, data);
return glGetError() == GL_NO_ERROR;
#else
Q_UNUSED(offset);
@ -371,7 +376,7 @@ void QGLBuffer::write(int offset, const void *data, int count)
#endif
Q_D(QGLBuffer);
if (d->guard && d->guard->id())
glBufferSubData(d->type, offset, count, data);
d->funcs->glBufferSubData(d->type, offset, count, data);
}
/*!
@ -391,7 +396,7 @@ void QGLBuffer::allocate(const void *data, int count)
#endif
Q_D(QGLBuffer);
if (d->guard && d->guard->id())
glBufferData(d->type, count, data, d->actualUsagePattern);
d->funcs->glBufferData(d->type, count, data, d->actualUsagePattern);
}
/*!
@ -433,7 +438,7 @@ bool QGLBuffer::bind()
#endif
return false;
}
glBindBuffer(d->type, bufferId);
d->funcs->glBindBuffer(d->type, bufferId);
return true;
} else {
return false;
@ -457,7 +462,7 @@ void QGLBuffer::release()
#endif
Q_D(const QGLBuffer);
if (d->guard && d->guard->id())
glBindBuffer(d->type, 0);
d->funcs->glBindBuffer(d->type, 0);
}
#undef ctx
@ -477,9 +482,8 @@ void QGLBuffer::release()
*/
void QGLBuffer::release(QGLBuffer::Type type)
{
const QGLContext *ctx = QGLContext::currentContext();
if (ctx && qt_resolve_buffer_extensions(const_cast<QGLContext *>(ctx)))
glBindBuffer(GLenum(type), 0);
if (QOpenGLContext *ctx = QOpenGLContext::currentContext())
ctx->functions()->glBindBuffer(GLenum(type), 0);
}
#define ctx QGLContext::currentContext()
@ -515,7 +519,7 @@ int QGLBuffer::size() const
if (!d->guard || !d->guard->id())
return -1;
GLint value = -1;
glGetBufferParameteriv(d->type, GL_BUFFER_SIZE, &value);
d->funcs->glGetBufferParameteriv(d->type, GL_BUFFER_SIZE, &value);
return value;
}
@ -542,9 +546,7 @@ void *QGLBuffer::map(QGLBuffer::Access access)
#endif
if (!d->guard || !d->guard->id())
return 0;
if (!glMapBufferARB)
return 0;
return glMapBufferARB(d->type, access);
return d->funcs->glMapBuffer(d->type, access);
}
/*!
@ -569,9 +571,7 @@ bool QGLBuffer::unmap()
#endif
if (!d->guard || !d->guard->id())
return false;
if (!glUnmapBufferARB)
return false;
return glUnmapBufferARB(d->type) == GL_TRUE;
return d->funcs->glUnmapBuffer(d->type) == GL_TRUE;
}
QT_END_NAMESPACE

View File

@ -1,414 +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 "qgl_p.h"
#include <qglframebufferobject.h>
QT_BEGIN_NAMESPACE
static QFunctionPointer qt_gl_getProcAddress_search
(QGLContext *ctx, const char *name1, const char *name2,
const char *name3, const char *name4)
{
QFunctionPointer addr = ctx->getProcAddress(QLatin1String(name1));
if (addr)
return addr;
addr = ctx->getProcAddress(QLatin1String(name2));
if (addr)
return addr;
addr = ctx->getProcAddress(QLatin1String(name3));
if (addr)
return addr;
if (name4)
return ctx->getProcAddress(QLatin1String(name4));
return 0;
}
// Search for an extension function starting with the most likely
// function suffix first, and then trying the other variations.
#if defined(QT_OPENGL_ES)
#define qt_gl_getProcAddress(ctx,name) \
qt_gl_getProcAddress_search((ctx), name, name "OES", name "EXT", name "ARB")
#define qt_gl_getProcAddressEXT(ctx,name) \
qt_gl_getProcAddress_search((ctx), name "OES", name, name "EXT", name "ARB")
#define qt_gl_getProcAddressARB(ctx,name) \
qt_gl_getProcAddress_search((ctx), name "OES", name, name "ARB", name "EXT")
#define qt_gl_getProcAddressOES(ctx,name) \
qt_gl_getProcAddress_search((ctx), name "OES", name, name "EXT", name "ARB")
#else
#define qt_gl_getProcAddress(ctx,name) \
qt_gl_getProcAddress_search((ctx), name, name "ARB", name "EXT", 0)
#define qt_gl_getProcAddressEXT(ctx,name) \
qt_gl_getProcAddress_search((ctx), name "EXT", name, name "ARB", 0)
#define qt_gl_getProcAddressARB(ctx,name) \
qt_gl_getProcAddress_search((ctx), name "ARB", name, name "EXT", 0)
#define qt_gl_getProcAddressOES(ctx,name) \
qt_gl_getProcAddress_search((ctx), name "OES", name, name "EXT", name "ARB")
#endif
bool qt_resolve_framebufferobject_extensions(QGLContext *ctx)
{
#if defined(QT_OPENGL_ES_2)
static bool have_resolved = false;
if (have_resolved)
return true;
have_resolved = true;
#else
if (glIsRenderbuffer != 0)
return true;
#endif
if (ctx == 0) {
qWarning("QGLFramebufferObject: Unable to resolve framebuffer object extensions -"
" make sure there is a current context when creating the framebuffer object.");
return false;
}
glBlitFramebufferEXT = (_glBlitFramebufferEXT) qt_gl_getProcAddressEXT(ctx, "glBlitFramebuffer");
glRenderbufferStorageMultisampleEXT =
(_glRenderbufferStorageMultisampleEXT) qt_gl_getProcAddressEXT(ctx, "glRenderbufferStorageMultisample");
#if !defined(QT_OPENGL_ES_2)
glIsRenderbuffer = (_glIsRenderbuffer) qt_gl_getProcAddressEXT(ctx, "glIsRenderbuffer");
if (!glIsRenderbuffer)
return false; // Not much point searching for anything else.
glBindRenderbuffer = (_glBindRenderbuffer) qt_gl_getProcAddressEXT(ctx, "glBindRenderbuffer");
glDeleteRenderbuffers = (_glDeleteRenderbuffers) qt_gl_getProcAddressEXT(ctx, "glDeleteRenderbuffers");
glGenRenderbuffers = (_glGenRenderbuffers) qt_gl_getProcAddressEXT(ctx, "glGenRenderbuffers");
glRenderbufferStorage = (_glRenderbufferStorage) qt_gl_getProcAddressEXT(ctx, "glRenderbufferStorage");
glGetRenderbufferParameteriv =
(_glGetRenderbufferParameteriv) qt_gl_getProcAddressEXT(ctx, "glGetRenderbufferParameteriv");
glIsFramebuffer = (_glIsFramebuffer) qt_gl_getProcAddressEXT(ctx, "glIsFramebuffer");
glBindFramebuffer = (_glBindFramebuffer) qt_gl_getProcAddressEXT(ctx, "glBindFramebuffer");
glDeleteFramebuffers = (_glDeleteFramebuffers) qt_gl_getProcAddressEXT(ctx, "glDeleteFramebuffers");
glGenFramebuffers = (_glGenFramebuffers) qt_gl_getProcAddressEXT(ctx, "glGenFramebuffers");
glCheckFramebufferStatus = (_glCheckFramebufferStatus) qt_gl_getProcAddressEXT(ctx, "glCheckFramebufferStatus");
glFramebufferTexture2D = (_glFramebufferTexture2D) qt_gl_getProcAddressEXT(ctx, "glFramebufferTexture2D");
glFramebufferRenderbuffer = (_glFramebufferRenderbuffer) qt_gl_getProcAddressEXT(ctx, "glFramebufferRenderbuffer");
glGetFramebufferAttachmentParameteriv =
(_glGetFramebufferAttachmentParameteriv) qt_gl_getProcAddressEXT(ctx, "glGetFramebufferAttachmentParameteriv");
glGenerateMipmap = (_glGenerateMipmap) qt_gl_getProcAddressEXT(ctx, "glGenerateMipmap");
return glIsRenderbuffer != 0;
#else
return true;
#endif
}
#if !defined(QT_OPENGL_ES_2)
bool qt_resolve_version_1_3_functions(QGLContext *ctx)
{
if (glMultiTexCoord4f != 0)
return true;
QGLContext cx(QGLFormat::defaultFormat());
glMultiTexCoord4f = (_glMultiTexCoord4f) ctx->getProcAddress(QLatin1String("glMultiTexCoord4f"));
glActiveTexture = (_glActiveTexture) ctx->getProcAddress(QLatin1String("glActiveTexture"));
return glMultiTexCoord4f && glActiveTexture;
}
#endif
#if !defined(QT_OPENGL_ES_2)
bool qt_resolve_stencil_face_extension(QGLContext *ctx)
{
if (glActiveStencilFaceEXT != 0)
return true;
QGLContext cx(QGLFormat::defaultFormat());
glActiveStencilFaceEXT = (_glActiveStencilFaceEXT) ctx->getProcAddress(QLatin1String("glActiveStencilFaceEXT"));
return glActiveStencilFaceEXT;
}
#endif
#if !defined(QT_OPENGL_ES_2)
bool qt_resolve_frag_program_extensions(QGLContext *ctx)
{
if (glProgramStringARB != 0)
return true;
// ARB_fragment_program
glProgramStringARB = (_glProgramStringARB) ctx->getProcAddress(QLatin1String("glProgramStringARB"));
glBindProgramARB = (_glBindProgramARB) ctx->getProcAddress(QLatin1String("glBindProgramARB"));
glDeleteProgramsARB = (_glDeleteProgramsARB) ctx->getProcAddress(QLatin1String("glDeleteProgramsARB"));
glGenProgramsARB = (_glGenProgramsARB) ctx->getProcAddress(QLatin1String("glGenProgramsARB"));
glProgramLocalParameter4fvARB = (_glProgramLocalParameter4fvARB) ctx->getProcAddress(QLatin1String("glProgramLocalParameter4fvARB"));
return glProgramStringARB
&& glBindProgramARB
&& glDeleteProgramsARB
&& glGenProgramsARB
&& glProgramLocalParameter4fvARB;
}
#endif
bool qt_resolve_buffer_extensions(QGLContext *ctx)
{
#if defined(QGL_RESOLVE_BUFFER_FUNCS)
if (glBindBuffer && glDeleteBuffers && glGenBuffers && glBufferData
&& glBufferSubData && glGetBufferParameteriv)
return true;
#endif
#if defined(QGL_RESOLVE_BUFFER_FUNCS)
glBindBuffer = (_glBindBuffer) qt_gl_getProcAddressARB(ctx, "glBindBuffer");
glDeleteBuffers = (_glDeleteBuffers) qt_gl_getProcAddressARB(ctx, "glDeleteBuffers");
glGenBuffers = (_glGenBuffers) qt_gl_getProcAddressARB(ctx, "glGenBuffers");
glBufferData = (_glBufferData) qt_gl_getProcAddressARB(ctx, "glBufferData");
glBufferSubData = (_glBufferSubData) qt_gl_getProcAddressARB(ctx, "glBufferSubData");
glGetBufferSubData = (_glGetBufferSubData) qt_gl_getProcAddressARB(ctx, "glGetBufferSubData");
glGetBufferParameteriv = (_glGetBufferParameteriv) qt_gl_getProcAddressARB(ctx, "glGetBufferParameteriv");
#endif
glMapBufferARB = (_glMapBufferARB) qt_gl_getProcAddressARB(ctx, "glMapBuffer");
glUnmapBufferARB = (_glUnmapBufferARB) qt_gl_getProcAddressARB(ctx, "glUnmapBuffer");
#if defined(QGL_RESOLVE_BUFFER_FUNCS)
return glBindBuffer
&& glDeleteBuffers
&& glGenBuffers
&& glBufferData
&& glBufferSubData
&& glGetBufferParameteriv;
// glGetBufferSubData() is optional
#else
return true;
#endif
}
bool qt_resolve_glsl_extensions(QGLContext *ctx)
{
#if defined(QT_OPENGL_ES_2)
// The GLSL shader functions are always present in OpenGL/ES 2.0.
// The only exceptions are glGetProgramBinaryOES and glProgramBinaryOES.
if (!QGLContextPrivate::extensionFuncs(ctx).qt_glslResolved) {
glGetProgramBinaryOES = (_glGetProgramBinaryOES) ctx->getProcAddress(QLatin1String("glGetProgramBinaryOES"));
glProgramBinaryOES = (_glProgramBinaryOES) ctx->getProcAddress(QLatin1String("glProgramBinaryOES"));
QGLContextPrivate::extensionFuncs(ctx).qt_glslResolved = true;
}
return true;
#else
if (glCreateShader)
return true;
// Geometry shaders are optional...
glProgramParameteriEXT = (_glProgramParameteriEXT) ctx->getProcAddress(QLatin1String("glProgramParameteriEXT"));
glFramebufferTextureEXT = (_glFramebufferTextureEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureEXT"));
glFramebufferTextureLayerEXT = (_glFramebufferTextureLayerEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureLayerEXT"));
glFramebufferTextureFaceEXT = (_glFramebufferTextureFaceEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureFaceEXT"));
// Must at least have the FragmentShader extension to continue.
if (!(QGLExtensions::glExtensions() & QGLExtensions::FragmentShader))
return false;
glCreateShader = (_glCreateShader) ctx->getProcAddress(QLatin1String("glCreateShader"));
if (glCreateShader) {
glShaderSource = (_glShaderSource) ctx->getProcAddress(QLatin1String("glShaderSource"));
glShaderBinary = (_glShaderBinary) ctx->getProcAddress(QLatin1String("glShaderBinary"));
glCompileShader = (_glCompileShader) ctx->getProcAddress(QLatin1String("glCompileShader"));
glDeleteShader = (_glDeleteShader) ctx->getProcAddress(QLatin1String("glDeleteShader"));
glIsShader = (_glIsShader) ctx->getProcAddress(QLatin1String("glIsShader"));
glCreateProgram = (_glCreateProgram) ctx->getProcAddress(QLatin1String("glCreateProgram"));
glAttachShader = (_glAttachShader) ctx->getProcAddress(QLatin1String("glAttachShader"));
glDetachShader = (_glDetachShader) ctx->getProcAddress(QLatin1String("glDetachShader"));
glLinkProgram = (_glLinkProgram) ctx->getProcAddress(QLatin1String("glLinkProgram"));
glUseProgram = (_glUseProgram) ctx->getProcAddress(QLatin1String("glUseProgram"));
glDeleteProgram = (_glDeleteProgram) ctx->getProcAddress(QLatin1String("glDeleteProgram"));
glIsProgram = (_glIsProgram) ctx->getProcAddress(QLatin1String("glIsProgram"));
glGetShaderInfoLog = (_glGetShaderInfoLog) ctx->getProcAddress(QLatin1String("glGetShaderInfoLog"));
glGetShaderiv = (_glGetShaderiv) ctx->getProcAddress(QLatin1String("glGetShaderiv"));
glGetShaderSource = (_glGetShaderSource) ctx->getProcAddress(QLatin1String("glGetShaderSource"));
glGetProgramiv = (_glGetProgramiv) ctx->getProcAddress(QLatin1String("glGetProgramiv"));
glGetProgramInfoLog = (_glGetProgramInfoLog) ctx->getProcAddress(QLatin1String("glGetProgramInfoLog"));
glGetUniformLocation = (_glGetUniformLocation) ctx->getProcAddress(QLatin1String("glGetUniformLocation"));
glUniform4fv = (_glUniform4fv) ctx->getProcAddress(QLatin1String("glUniform4fv"));
glUniform3fv = (_glUniform3fv) ctx->getProcAddress(QLatin1String("glUniform3fv"));
glUniform2fv = (_glUniform2fv) ctx->getProcAddress(QLatin1String("glUniform2fv"));
glUniform1fv = (_glUniform1fv) ctx->getProcAddress(QLatin1String("glUniform1fv"));
glUniform1i = (_glUniform1i) ctx->getProcAddress(QLatin1String("glUniform1i"));
glUniform1iv = (_glUniform1iv) ctx->getProcAddress(QLatin1String("glUniform1iv"));
glUniformMatrix2fv = (_glUniformMatrix2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2fv"));
glUniformMatrix3fv = (_glUniformMatrix3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3fv"));
glUniformMatrix4fv = (_glUniformMatrix4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4fv"));
glUniformMatrix2x3fv = (_glUniformMatrix2x3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2x3fv"));
glUniformMatrix2x4fv = (_glUniformMatrix2x4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2x4fv"));
glUniformMatrix3x2fv = (_glUniformMatrix3x2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3x2fv"));
glUniformMatrix3x4fv = (_glUniformMatrix3x4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3x4fv"));
glUniformMatrix4x2fv = (_glUniformMatrix4x2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4x2fv"));
glUniformMatrix4x3fv = (_glUniformMatrix4x3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4x3fv"));
glBindAttribLocation = (_glBindAttribLocation) ctx->getProcAddress(QLatin1String("glBindAttribLocation"));
glGetAttribLocation = (_glGetAttribLocation) ctx->getProcAddress(QLatin1String("glGetAttribLocation"));
glVertexAttrib1fv = (_glVertexAttrib1fv) ctx->getProcAddress(QLatin1String("glVertexAttrib1fv"));
glVertexAttrib2fv = (_glVertexAttrib2fv) ctx->getProcAddress(QLatin1String("glVertexAttrib2fv"));
glVertexAttrib3fv = (_glVertexAttrib3fv) ctx->getProcAddress(QLatin1String("glVertexAttrib3fv"));
glVertexAttrib4fv = (_glVertexAttrib4fv) ctx->getProcAddress(QLatin1String("glVertexAttrib4fv"));
glVertexAttribPointer = (_glVertexAttribPointer) ctx->getProcAddress(QLatin1String("glVertexAttribPointer"));
glDisableVertexAttribArray = (_glDisableVertexAttribArray) ctx->getProcAddress(QLatin1String("glDisableVertexAttribArray"));
glEnableVertexAttribArray = (_glEnableVertexAttribArray) ctx->getProcAddress(QLatin1String("glEnableVertexAttribArray"));
} else {
// We may not have the standard shader functions, but we might
// have the older ARB functions instead.
glCreateShader = (_glCreateShader) ctx->getProcAddress(QLatin1String("glCreateShaderObjectARB"));
glShaderSource = (_glShaderSource) ctx->getProcAddress(QLatin1String("glShaderSourceARB"));
glShaderBinary = (_glShaderBinary) ctx->getProcAddress(QLatin1String("glShaderBinaryARB"));
glCompileShader = (_glCompileShader) ctx->getProcAddress(QLatin1String("glCompileShaderARB"));
glDeleteShader = (_glDeleteShader) ctx->getProcAddress(QLatin1String("glDeleteObjectARB"));
glIsShader = 0;
glCreateProgram = (_glCreateProgram) ctx->getProcAddress(QLatin1String("glCreateProgramObjectARB"));
glAttachShader = (_glAttachShader) ctx->getProcAddress(QLatin1String("glAttachObjectARB"));
glDetachShader = (_glDetachShader) ctx->getProcAddress(QLatin1String("glDetachObjectARB"));
glLinkProgram = (_glLinkProgram) ctx->getProcAddress(QLatin1String("glLinkProgramARB"));
glUseProgram = (_glUseProgram) ctx->getProcAddress(QLatin1String("glUseProgramObjectARB"));
glDeleteProgram = (_glDeleteProgram) ctx->getProcAddress(QLatin1String("glDeleteObjectARB"));
glIsProgram = 0;
glGetShaderInfoLog = (_glGetShaderInfoLog) ctx->getProcAddress(QLatin1String("glGetInfoLogARB"));
glGetShaderiv = (_glGetShaderiv) ctx->getProcAddress(QLatin1String("glGetObjectParameterivARB"));
glGetShaderSource = (_glGetShaderSource) ctx->getProcAddress(QLatin1String("glGetShaderSourceARB"));
glGetProgramiv = (_glGetProgramiv) ctx->getProcAddress(QLatin1String("glGetObjectParameterivARB"));
glGetProgramInfoLog = (_glGetProgramInfoLog) ctx->getProcAddress(QLatin1String("glGetInfoLogARB"));
glGetUniformLocation = (_glGetUniformLocation) ctx->getProcAddress(QLatin1String("glGetUniformLocationARB"));
glUniform4fv = (_glUniform4fv) ctx->getProcAddress(QLatin1String("glUniform4fvARB"));
glUniform3fv = (_glUniform3fv) ctx->getProcAddress(QLatin1String("glUniform3fvARB"));
glUniform2fv = (_glUniform2fv) ctx->getProcAddress(QLatin1String("glUniform2fvARB"));
glUniform1fv = (_glUniform1fv) ctx->getProcAddress(QLatin1String("glUniform1fvARB"));
glUniform1i = (_glUniform1i) ctx->getProcAddress(QLatin1String("glUniform1iARB"));
glUniform1iv = (_glUniform1iv) ctx->getProcAddress(QLatin1String("glUniform1ivARB"));
glUniformMatrix2fv = (_glUniformMatrix2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2fvARB"));
glUniformMatrix3fv = (_glUniformMatrix3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3fvARB"));
glUniformMatrix4fv = (_glUniformMatrix4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4fvARB"));
glUniformMatrix2x3fv = (_glUniformMatrix2x3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2x3fvARB"));
glUniformMatrix2x4fv = (_glUniformMatrix2x4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2x4fvARB"));
glUniformMatrix3x2fv = (_glUniformMatrix3x2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3x2fvARB"));
glUniformMatrix3x4fv = (_glUniformMatrix3x4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3x4fvARB"));
glUniformMatrix4x2fv = (_glUniformMatrix4x2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4x2fvARB"));
glUniformMatrix4x3fv = (_glUniformMatrix4x3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4x3fvARB"));
glBindAttribLocation = (_glBindAttribLocation) ctx->getProcAddress(QLatin1String("glBindAttribLocationARB"));
glGetAttribLocation = (_glGetAttribLocation) ctx->getProcAddress(QLatin1String("glGetAttribLocationARB"));
glVertexAttrib1fv = (_glVertexAttrib1fv) ctx->getProcAddress(QLatin1String("glVertexAttrib1fvARB"));
glVertexAttrib2fv = (_glVertexAttrib2fv) ctx->getProcAddress(QLatin1String("glVertexAttrib2fvARB"));
glVertexAttrib3fv = (_glVertexAttrib3fv) ctx->getProcAddress(QLatin1String("glVertexAttrib3fvARB"));
glVertexAttrib4fv = (_glVertexAttrib4fv) ctx->getProcAddress(QLatin1String("glVertexAttrib4fvARB"));
glVertexAttribPointer = (_glVertexAttribPointer) ctx->getProcAddress(QLatin1String("glVertexAttribPointerARB"));
glDisableVertexAttribArray = (_glDisableVertexAttribArray) ctx->getProcAddress(QLatin1String("glDisableVertexAttribArrayARB"));
glEnableVertexAttribArray = (_glEnableVertexAttribArray) ctx->getProcAddress(QLatin1String("glEnableVertexAttribArrayARB"));
}
// Note: glShaderBinary(), glIsShader(), glIsProgram(), and
// glUniformMatrixNxMfv() are optional, but all other functions
// are required.
return glCreateShader &&
glShaderSource &&
glCompileShader &&
glDeleteProgram &&
glCreateProgram &&
glAttachShader &&
glDetachShader &&
glLinkProgram &&
glUseProgram &&
glGetShaderInfoLog &&
glGetShaderiv &&
glGetShaderSource &&
glGetProgramiv &&
glGetProgramInfoLog &&
glGetUniformLocation &&
glUniform1fv &&
glUniform2fv &&
glUniform3fv &&
glUniform4fv &&
glUniform1i &&
glUniform1iv &&
glUniformMatrix2fv &&
glUniformMatrix3fv &&
glUniformMatrix4fv &&
glBindAttribLocation &&
glGetAttribLocation &&
glVertexAttrib1fv &&
glVertexAttrib2fv &&
glVertexAttrib3fv &&
glVertexAttrib4fv &&
glVertexAttribPointer &&
glDisableVertexAttribArray &&
glEnableVertexAttribArray;
#endif
}
#if !defined(QT_OPENGL_ES_2)
bool qt_resolve_version_2_0_functions(QGLContext *ctx)
{
bool gl2supported = true;
if (!qt_resolve_glsl_extensions(ctx))
gl2supported = false;
if (!qt_resolve_version_1_3_functions(ctx))
gl2supported = false;
if (glStencilOpSeparate)
return gl2supported;
glBlendColor = (_glBlendColor) ctx->getProcAddress(QLatin1String("glBlendColor"));
glStencilOpSeparate = (_glStencilOpSeparate) ctx->getProcAddress(QLatin1String("glStencilOpSeparate"));
if (!glBlendColor || !glStencilOpSeparate)
gl2supported = false;
return gl2supported;
}
#endif
QT_END_NAMESPACE

View File

@ -1,587 +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$
**
****************************************************************************/
#ifndef QGL_EXTENSIONS_P_H
#define QGL_EXTENSIONS_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of the Qt OpenGL classes. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
// extension prototypes
# ifndef APIENTRYP
# ifdef APIENTRY
# define APIENTRYP APIENTRY *
# else
# define APIENTRY
# define APIENTRYP *
# endif
# endif
#include <QtCore/qglobal.h>
#ifndef GL_ARB_vertex_buffer_object
typedef ptrdiff_t GLintptrARB;
typedef ptrdiff_t GLsizeiptrARB;
#endif
#ifndef GL_VERSION_2_0
typedef char GLchar;
#endif
// ARB_vertex_buffer_object
typedef void (APIENTRY *_glBindBuffer) (GLenum, GLuint);
typedef void (APIENTRY *_glDeleteBuffers) (GLsizei, const GLuint *);
typedef void (APIENTRY *_glGenBuffers) (GLsizei, GLuint *);
typedef void (APIENTRY *_glBufferData) (GLenum, GLsizeiptrARB, const GLvoid *, GLenum);
typedef void (APIENTRY *_glBufferSubData) (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *);
typedef void (APIENTRY *_glGetBufferSubData) (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *);
typedef void (APIENTRY *_glGetBufferParameteriv) (GLenum, GLenum, GLint *);
typedef GLvoid* (APIENTRY *_glMapBufferARB) (GLenum, GLenum);
typedef GLboolean (APIENTRY *_glUnmapBufferARB) (GLenum);
// We can call the buffer functions directly in OpenGL/ES 1.1 or higher,
// but all other platforms need to resolve the extensions.
#if defined(QT_OPENGL_ES)
#if defined(GL_OES_VERSION_1_0) && !defined(GL_OES_VERSION_1_1)
#define QGL_RESOLVE_BUFFER_FUNCS 1
#endif
#else
#define QGL_RESOLVE_BUFFER_FUNCS 1
#endif
// ARB_fragment_program
typedef void (APIENTRY *_glProgramStringARB) (GLenum, GLenum, GLsizei, const GLvoid *);
typedef void (APIENTRY *_glBindProgramARB) (GLenum, GLuint);
typedef void (APIENTRY *_glDeleteProgramsARB) (GLsizei, const GLuint *);
typedef void (APIENTRY *_glGenProgramsARB) (GLsizei, GLuint *);
typedef void (APIENTRY *_glProgramLocalParameter4fvARB) (GLenum, GLuint, const GLfloat *);
// GLSL
typedef GLuint (APIENTRY *_glCreateShader) (GLenum);
typedef void (APIENTRY *_glShaderSource) (GLuint, GLsizei, const char **, const GLint *);
typedef void (APIENTRY *_glShaderBinary) (GLint, const GLuint*, GLenum, const void*, GLint);
typedef void (APIENTRY *_glCompileShader) (GLuint);
typedef void (APIENTRY *_glDeleteShader) (GLuint);
typedef GLboolean (APIENTRY *_glIsShader) (GLuint);
typedef GLuint (APIENTRY *_glCreateProgram) ();
typedef void (APIENTRY *_glAttachShader) (GLuint, GLuint);
typedef void (APIENTRY *_glDetachShader) (GLuint, GLuint);
typedef void (APIENTRY *_glLinkProgram) (GLuint);
typedef void (APIENTRY *_glUseProgram) (GLuint);
typedef void (APIENTRY *_glDeleteProgram) (GLuint);
typedef GLboolean (APIENTRY *_glIsProgram) (GLuint);
typedef void (APIENTRY *_glGetShaderInfoLog) (GLuint, GLsizei, GLsizei *, char *);
typedef void (APIENTRY *_glGetShaderiv) (GLuint, GLenum, GLint *);
typedef void (APIENTRY *_glGetShaderSource) (GLuint, GLsizei, GLsizei *, char *);
typedef void (APIENTRY *_glGetProgramiv) (GLuint, GLenum, GLint *);
typedef void (APIENTRY *_glGetProgramInfoLog) (GLuint, GLsizei, GLsizei *, char *);
typedef GLuint (APIENTRY *_glGetUniformLocation) (GLuint, const char*);
typedef void (APIENTRY *_glUniform4fv) (GLint, GLsizei, const GLfloat *);
typedef void (APIENTRY *_glUniform3fv) (GLint, GLsizei, const GLfloat *);
typedef void (APIENTRY *_glUniform2fv) (GLint, GLsizei, const GLfloat *);
typedef void (APIENTRY *_glUniform1fv) (GLint, GLsizei, const GLfloat *);
typedef void (APIENTRY *_glUniform1i) (GLint, GLint);
typedef void (APIENTRY *_glUniform1iv) (GLint, GLsizei, const GLint *);
typedef void (APIENTRY *_glUniformMatrix2fv) (GLint, GLsizei, GLboolean, const GLfloat *);
typedef void (APIENTRY *_glUniformMatrix3fv) (GLint, GLsizei, GLboolean, const GLfloat *);
typedef void (APIENTRY *_glUniformMatrix4fv) (GLint, GLsizei, GLboolean, const GLfloat *);
typedef void (APIENTRY *_glUniformMatrix2x3fv) (GLint, GLsizei, GLboolean, const GLfloat *);
typedef void (APIENTRY *_glUniformMatrix2x4fv) (GLint, GLsizei, GLboolean, const GLfloat *);
typedef void (APIENTRY *_glUniformMatrix3x2fv) (GLint, GLsizei, GLboolean, const GLfloat *);
typedef void (APIENTRY *_glUniformMatrix3x4fv) (GLint, GLsizei, GLboolean, const GLfloat *);
typedef void (APIENTRY *_glUniformMatrix4x2fv) (GLint, GLsizei, GLboolean, const GLfloat *);
typedef void (APIENTRY *_glUniformMatrix4x3fv) (GLint, GLsizei, GLboolean, const GLfloat *);
typedef void (APIENTRY *_glBindAttribLocation) (GLuint, GLuint, const char *);
typedef GLint (APIENTRY *_glGetAttribLocation) (GLuint, const char *);
typedef void (APIENTRY *_glVertexAttrib1fv) (GLuint, const GLfloat *);
typedef void (APIENTRY *_glVertexAttrib2fv) (GLuint, const GLfloat *);
typedef void (APIENTRY *_glVertexAttrib3fv) (GLuint, const GLfloat *);
typedef void (APIENTRY *_glVertexAttrib4fv) (GLuint, const GLfloat *);
typedef void (APIENTRY *_glVertexAttribPointer) (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *);
typedef void (APIENTRY *_glDisableVertexAttribArray) (GLuint);
typedef void (APIENTRY *_glEnableVertexAttribArray) (GLuint);
typedef void (APIENTRY *_glGetProgramBinaryOES) (GLuint, GLsizei, GLsizei *, GLenum *, void *);
typedef void (APIENTRY *_glProgramBinaryOES) (GLuint, GLenum, const void *, GLint);
typedef void (APIENTRY *_glMultiTexCoord4f) (GLenum, GLfloat, GLfloat, GLfloat, GLfloat);
typedef void (APIENTRY *_glActiveStencilFaceEXT) (GLenum );
// Needed for GL2 engine:
typedef void (APIENTRY *_glStencilOpSeparate) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
typedef void (APIENTRY *_glActiveTexture) (GLenum);
typedef void (APIENTRY *_glBlendColor) (GLclampf, GLclampf, GLclampf, GLclampf);
// EXT_GL_framebuffer_object
typedef GLboolean (APIENTRY *_glIsRenderbuffer) (GLuint renderbuffer);
typedef void (APIENTRY *_glBindRenderbuffer) (GLenum target, GLuint renderbuffer);
typedef void (APIENTRY *_glDeleteRenderbuffers) (GLsizei n, const GLuint *renderbuffers);
typedef void (APIENTRY *_glGenRenderbuffers) (GLsizei n, GLuint *renderbuffers);
typedef void (APIENTRY *_glRenderbufferStorage) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (APIENTRY *_glGetRenderbufferParameteriv) (GLenum target, GLenum pname, GLint *params);
typedef GLboolean (APIENTRY *_glIsFramebuffer) (GLuint framebuffer);
typedef void (APIENTRY *_glBindFramebuffer) (GLenum target, GLuint framebuffer);
typedef void (APIENTRY *_glDeleteFramebuffers) (GLsizei n, const GLuint *framebuffers);
typedef void (APIENTRY *_glGenFramebuffers) (GLsizei n, GLuint *framebuffers);
typedef GLenum (APIENTRY *_glCheckFramebufferStatus) (GLenum target);
typedef void (APIENTRY *_glFramebufferTexture2D) (GLenum target, GLenum attachment, GLenum textarget,
GLuint texture, GLint level);
typedef void (APIENTRY *_glFramebufferRenderbuffer) (GLenum target, GLenum attachment, GLenum renderbuffertarget,
GLuint renderbuffer);
typedef void (APIENTRY *_glGetFramebufferAttachmentParameteriv) (GLenum target, GLenum attachment, GLenum pname,
GLint *params);
typedef void (APIENTRY *_glGenerateMipmap) (GLenum target);
// EXT_GL_framebuffer_blit
typedef void (APIENTRY *_glBlitFramebufferEXT) (int srcX0, int srcY0, int srcX1, int srcY1,
int dstX0, int dstY0, int dstX1, int dstY1,
GLbitfield mask, GLenum filter);
// EXT_GL_framebuffer_multisample
typedef void (APIENTRY *_glRenderbufferStorageMultisampleEXT) (GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height);
// GL_EXT_geometry_shader4
typedef void (APIENTRY *_glProgramParameteriEXT)(GLuint program, GLenum pname, GLint value);
typedef void (APIENTRY *_glFramebufferTextureEXT)(GLenum target, GLenum attachment,
GLuint texture, GLint level);
typedef void (APIENTRY *_glFramebufferTextureLayerEXT)(GLenum target, GLenum attachment,
GLuint texture, GLint level, GLint layer);
typedef void (APIENTRY *_glFramebufferTextureFaceEXT)(GLenum target, GLenum attachment,
GLuint texture, GLint level, GLenum face);
// ARB_texture_compression
typedef void (APIENTRY *_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei,
GLsizei, GLint, GLsizei, const GLvoid *);
QT_BEGIN_NAMESPACE
struct QGLExtensionFuncs
{
QGLExtensionFuncs() {
#if !defined(QT_OPENGL_ES_2)
qt_glProgramStringARB = 0;
qt_glBindProgramARB = 0;
qt_glDeleteProgramsARB = 0;
qt_glGenProgramsARB = 0;
qt_glProgramLocalParameter4fvARB = 0;
// GLSL
qt_glCreateShader = 0;
qt_glShaderSource = 0;
qt_glShaderBinary = 0;
qt_glCompileShader = 0;
qt_glDeleteShader = 0;
qt_glIsShader = 0;
qt_glCreateProgram = 0;
qt_glAttachShader = 0;
qt_glDetachShader = 0;
qt_glLinkProgram = 0;
qt_glUseProgram = 0;
qt_glDeleteProgram = 0;
qt_glIsProgram = 0;
qt_glGetShaderInfoLog = 0;
qt_glGetShaderiv = 0;
qt_glGetShaderSource = 0;
qt_glGetProgramiv = 0;
qt_glGetProgramInfoLog = 0;
qt_glGetUniformLocation = 0;
qt_glUniform4fv = 0;
qt_glUniform3fv = 0;
qt_glUniform2fv = 0;
qt_glUniform1fv = 0;
qt_glUniform1i = 0;
qt_glUniform1iv = 0;
qt_glUniformMatrix2fv = 0;
qt_glUniformMatrix3fv = 0;
qt_glUniformMatrix4fv = 0;
qt_glUniformMatrix2x3fv = 0;
qt_glUniformMatrix2x4fv = 0;
qt_glUniformMatrix3x2fv = 0;
qt_glUniformMatrix3x4fv = 0;
qt_glUniformMatrix4x2fv = 0;
qt_glUniformMatrix4x3fv = 0;
qt_glBindAttribLocation = 0;
qt_glGetAttribLocation = 0;
qt_glVertexAttrib1fv = 0;
qt_glVertexAttrib2fv = 0;
qt_glVertexAttrib3fv = 0;
qt_glVertexAttrib4fv = 0;
qt_glVertexAttribPointer = 0;
qt_glDisableVertexAttribArray = 0;
qt_glEnableVertexAttribArray = 0;
// Extras for GL2 engine:
qt_glActiveTexture = 0;
qt_glStencilOpSeparate = 0;
qt_glBlendColor = 0;
qt_glActiveStencilFaceEXT = 0;
qt_glMultiTexCoord4f = 0;
#else
qt_glslResolved = false;
qt_glGetProgramBinaryOES = 0;
qt_glProgramBinaryOES = 0;
#endif
// FBOs
#if !defined(QT_OPENGL_ES_2)
qt_glIsRenderbuffer = 0;
qt_glBindRenderbuffer = 0;
qt_glDeleteRenderbuffers = 0;
qt_glGenRenderbuffers = 0;
qt_glRenderbufferStorage = 0;
qt_glGetRenderbufferParameteriv = 0;
qt_glIsFramebuffer = 0;
qt_glBindFramebuffer = 0;
qt_glDeleteFramebuffers = 0;
qt_glGenFramebuffers = 0;
qt_glCheckFramebufferStatus = 0;
qt_glFramebufferTexture2D = 0;
qt_glFramebufferRenderbuffer = 0;
qt_glGetFramebufferAttachmentParameteriv = 0;
qt_glGenerateMipmap = 0;
#endif
qt_glBlitFramebufferEXT = 0;
qt_glRenderbufferStorageMultisampleEXT = 0;
// Buffer objects:
#if defined(QGL_RESOLVE_BUFFER_FUNCS)
qt_glBindBuffer = 0;
qt_glDeleteBuffers = 0;
qt_glGenBuffers = 0;
qt_glBufferData = 0;
qt_glBufferSubData = 0;
qt_glGetBufferSubData = 0;
qt_glGetBufferParameteriv = 0;
#endif
qt_glMapBufferARB = 0;
qt_glUnmapBufferARB = 0;
qt_glProgramParameteriEXT = 0;
qt_glFramebufferTextureEXT = 0;
qt_glFramebufferTextureLayerEXT = 0;
qt_glFramebufferTextureFaceEXT = 0;
#if !defined(QT_OPENGL_ES)
// Texture compression
qt_glCompressedTexImage2DARB = 0;
#endif
}
#if !defined(QT_OPENGL_ES_2)
_glProgramStringARB qt_glProgramStringARB;
_glBindProgramARB qt_glBindProgramARB;
_glDeleteProgramsARB qt_glDeleteProgramsARB;
_glGenProgramsARB qt_glGenProgramsARB;
_glProgramLocalParameter4fvARB qt_glProgramLocalParameter4fvARB;
// GLSL definitions
_glCreateShader qt_glCreateShader;
_glShaderSource qt_glShaderSource;
_glShaderBinary qt_glShaderBinary;
_glCompileShader qt_glCompileShader;
_glDeleteShader qt_glDeleteShader;
_glIsShader qt_glIsShader;
_glCreateProgram qt_glCreateProgram;
_glAttachShader qt_glAttachShader;
_glDetachShader qt_glDetachShader;
_glLinkProgram qt_glLinkProgram;
_glUseProgram qt_glUseProgram;
_glDeleteProgram qt_glDeleteProgram;
_glIsProgram qt_glIsProgram;
_glGetShaderInfoLog qt_glGetShaderInfoLog;
_glGetShaderiv qt_glGetShaderiv;
_glGetShaderSource qt_glGetShaderSource;
_glGetProgramiv qt_glGetProgramiv;
_glGetProgramInfoLog qt_glGetProgramInfoLog;
_glGetUniformLocation qt_glGetUniformLocation;
_glUniform4fv qt_glUniform4fv;
_glUniform3fv qt_glUniform3fv;
_glUniform2fv qt_glUniform2fv;
_glUniform1fv qt_glUniform1fv;
_glUniform1i qt_glUniform1i;
_glUniform1iv qt_glUniform1iv;
_glUniformMatrix2fv qt_glUniformMatrix2fv;
_glUniformMatrix3fv qt_glUniformMatrix3fv;
_glUniformMatrix4fv qt_glUniformMatrix4fv;
_glUniformMatrix2x3fv qt_glUniformMatrix2x3fv;
_glUniformMatrix2x4fv qt_glUniformMatrix2x4fv;
_glUniformMatrix3x2fv qt_glUniformMatrix3x2fv;
_glUniformMatrix3x4fv qt_glUniformMatrix3x4fv;
_glUniformMatrix4x2fv qt_glUniformMatrix4x2fv;
_glUniformMatrix4x3fv qt_glUniformMatrix4x3fv;
_glBindAttribLocation qt_glBindAttribLocation;
_glGetAttribLocation qt_glGetAttribLocation;
_glVertexAttrib1fv qt_glVertexAttrib1fv;
_glVertexAttrib2fv qt_glVertexAttrib2fv;
_glVertexAttrib3fv qt_glVertexAttrib3fv;
_glVertexAttrib4fv qt_glVertexAttrib4fv;
_glVertexAttribPointer qt_glVertexAttribPointer;
_glDisableVertexAttribArray qt_glDisableVertexAttribArray;
_glEnableVertexAttribArray qt_glEnableVertexAttribArray;
#else
bool qt_glslResolved;
_glGetProgramBinaryOES qt_glGetProgramBinaryOES;
_glProgramBinaryOES qt_glProgramBinaryOES;
#endif
_glActiveStencilFaceEXT qt_glActiveStencilFaceEXT;
_glMultiTexCoord4f qt_glMultiTexCoord4f;
#if !defined(QT_OPENGL_ES_2)
// Extras needed for GL2 engine:
_glActiveTexture qt_glActiveTexture;
_glStencilOpSeparate qt_glStencilOpSeparate;
_glBlendColor qt_glBlendColor;
#endif
// FBOs
#if !defined(QT_OPENGL_ES_2)
_glIsRenderbuffer qt_glIsRenderbuffer;
_glBindRenderbuffer qt_glBindRenderbuffer;
_glDeleteRenderbuffers qt_glDeleteRenderbuffers;
_glGenRenderbuffers qt_glGenRenderbuffers;
_glRenderbufferStorage qt_glRenderbufferStorage;
_glGetRenderbufferParameteriv qt_glGetRenderbufferParameteriv;
_glIsFramebuffer qt_glIsFramebuffer;
_glBindFramebuffer qt_glBindFramebuffer;
_glDeleteFramebuffers qt_glDeleteFramebuffers;
_glGenFramebuffers qt_glGenFramebuffers;
_glCheckFramebufferStatus qt_glCheckFramebufferStatus;
_glFramebufferTexture2D qt_glFramebufferTexture2D;
_glFramebufferRenderbuffer qt_glFramebufferRenderbuffer;
_glGetFramebufferAttachmentParameteriv qt_glGetFramebufferAttachmentParameteriv;
_glGenerateMipmap qt_glGenerateMipmap;
#endif
_glBlitFramebufferEXT qt_glBlitFramebufferEXT;
_glRenderbufferStorageMultisampleEXT qt_glRenderbufferStorageMultisampleEXT;
// Buffer objects
#if defined(QGL_RESOLVE_BUFFER_FUNCS)
_glBindBuffer qt_glBindBuffer;
_glDeleteBuffers qt_glDeleteBuffers;
_glGenBuffers qt_glGenBuffers;
_glBufferData qt_glBufferData;
_glBufferSubData qt_glBufferSubData;
_glGetBufferSubData qt_glGetBufferSubData;
_glGetBufferParameteriv qt_glGetBufferParameteriv;
#endif
_glMapBufferARB qt_glMapBufferARB;
_glUnmapBufferARB qt_glUnmapBufferARB;
// Geometry shaders...
_glProgramParameteriEXT qt_glProgramParameteriEXT;
_glFramebufferTextureEXT qt_glFramebufferTextureEXT;
_glFramebufferTextureLayerEXT qt_glFramebufferTextureLayerEXT;
_glFramebufferTextureFaceEXT qt_glFramebufferTextureFaceEXT;
#if !defined(QT_OPENGL_ES)
// Texture compression
_glCompressedTexImage2DARB qt_glCompressedTexImage2DARB;
#endif
};
#if !defined(QT_OPENGL_ES_2)
#define glProgramStringARB QGLContextPrivate::extensionFuncs(ctx).qt_glProgramStringARB
#define glBindProgramARB QGLContextPrivate::extensionFuncs(ctx).qt_glBindProgramARB
#define glDeleteProgramsARB QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteProgramsARB
#define glGenProgramsARB QGLContextPrivate::extensionFuncs(ctx).qt_glGenProgramsARB
#define glProgramLocalParameter4fvARB QGLContextPrivate::extensionFuncs(ctx).qt_glProgramLocalParameter4fvARB
#define glActiveStencilFaceEXT QGLContextPrivate::extensionFuncs(ctx).qt_glActiveStencilFaceEXT
#define glMultiTexCoord4f QGLContextPrivate::extensionFuncs(ctx).qt_glMultiTexCoord4f
#define glActiveTexture QGLContextPrivate::extensionFuncs(ctx).qt_glActiveTexture
#endif // !defined(QT_OPENGL_ES_2)
// FBOs
#if !defined(QT_OPENGL_ES_2)
#define glIsRenderbuffer QGLContextPrivate::extensionFuncs(ctx).qt_glIsRenderbuffer
#define glBindRenderbuffer QGLContextPrivate::extensionFuncs(ctx).qt_glBindRenderbuffer
#define glDeleteRenderbuffers QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteRenderbuffers
#define glGenRenderbuffers QGLContextPrivate::extensionFuncs(ctx).qt_glGenRenderbuffers
#define glRenderbufferStorage QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorage
#define glGetRenderbufferParameteriv QGLContextPrivate::extensionFuncs(ctx).qt_glGetRenderbufferParameteriv
#define glIsFramebuffer QGLContextPrivate::extensionFuncs(ctx).qt_glIsFramebuffer
#define glBindFramebuffer QGLContextPrivate::extensionFuncs(ctx).qt_glBindFramebuffer
#define glDeleteFramebuffers QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteFramebuffers
#define glGenFramebuffers QGLContextPrivate::extensionFuncs(ctx).qt_glGenFramebuffers
#define glCheckFramebufferStatus QGLContextPrivate::extensionFuncs(ctx).qt_glCheckFramebufferStatus
#define glFramebufferTexture2D QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTexture2D
#define glFramebufferRenderbuffer QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferRenderbuffer
#define glGetFramebufferAttachmentParameteriv QGLContextPrivate::extensionFuncs(ctx).qt_glGetFramebufferAttachmentParameteriv
#define glGenerateMipmap QGLContextPrivate::extensionFuncs(ctx).qt_glGenerateMipmap
#endif // QT_OPENGL_ES_2
#define glBlitFramebufferEXT QGLContextPrivate::extensionFuncs(ctx).qt_glBlitFramebufferEXT
#define glRenderbufferStorageMultisampleEXT QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorageMultisampleEXT
// Buffer objects
#if defined(QGL_RESOLVE_BUFFER_FUNCS)
#define glBindBuffer QGLContextPrivate::extensionFuncs(ctx).qt_glBindBuffer
#define glDeleteBuffers QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteBuffers
#define glGenBuffers QGLContextPrivate::extensionFuncs(ctx).qt_glGenBuffers
#define glBufferData QGLContextPrivate::extensionFuncs(ctx).qt_glBufferData
#define glBufferSubData QGLContextPrivate::extensionFuncs(ctx).qt_glBufferSubData
#define glGetBufferSubData QGLContextPrivate::extensionFuncs(ctx).qt_glGetBufferSubData
#define glGetBufferParameteriv QGLContextPrivate::extensionFuncs(ctx).qt_glGetBufferParameteriv
#endif
#define glMapBufferARB QGLContextPrivate::extensionFuncs(ctx).qt_glMapBufferARB
#define glUnmapBufferARB QGLContextPrivate::extensionFuncs(ctx).qt_glUnmapBufferARB
// GLSL
#if !defined(QT_OPENGL_ES_2)
#define glCreateShader QGLContextPrivate::extensionFuncs(ctx).qt_glCreateShader
#define glShaderSource QGLContextPrivate::extensionFuncs(ctx).qt_glShaderSource
#define glShaderBinary QGLContextPrivate::extensionFuncs(ctx).qt_glShaderBinary
#define glCompileShader QGLContextPrivate::extensionFuncs(ctx).qt_glCompileShader
#define glDeleteShader QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteShader
#define glIsShader QGLContextPrivate::extensionFuncs(ctx).qt_glIsShader
#define glCreateProgram QGLContextPrivate::extensionFuncs(ctx).qt_glCreateProgram
#define glAttachShader QGLContextPrivate::extensionFuncs(ctx).qt_glAttachShader
#define glDetachShader QGLContextPrivate::extensionFuncs(ctx).qt_glDetachShader
#define glLinkProgram QGLContextPrivate::extensionFuncs(ctx).qt_glLinkProgram
#define glUseProgram QGLContextPrivate::extensionFuncs(ctx).qt_glUseProgram
#define glDeleteProgram QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteProgram
#define glIsProgram QGLContextPrivate::extensionFuncs(ctx).qt_glIsProgram
#define glGetShaderInfoLog QGLContextPrivate::extensionFuncs(ctx).qt_glGetShaderInfoLog
#define glGetShaderiv QGLContextPrivate::extensionFuncs(ctx).qt_glGetShaderiv
#define glGetShaderSource QGLContextPrivate::extensionFuncs(ctx).qt_glGetShaderSource
#define glGetProgramiv QGLContextPrivate::extensionFuncs(ctx).qt_glGetProgramiv
#define glGetProgramInfoLog QGLContextPrivate::extensionFuncs(ctx).qt_glGetProgramInfoLog
#define glGetUniformLocation QGLContextPrivate::extensionFuncs(ctx).qt_glGetUniformLocation
#define glUniform4fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniform4fv
#define glUniform3fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniform3fv
#define glUniform2fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniform2fv
#define glUniform1fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniform1fv
#define glUniform1i QGLContextPrivate::extensionFuncs(ctx).qt_glUniform1i
#define glUniform1iv QGLContextPrivate::extensionFuncs(ctx).qt_glUniform1iv
#define glUniformMatrix2fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniformMatrix2fv
#define glUniformMatrix3fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniformMatrix3fv
#define glUniformMatrix4fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniformMatrix4fv
#define glUniformMatrix2x3fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniformMatrix2x3fv
#define glUniformMatrix2x4fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniformMatrix2x4fv
#define glUniformMatrix3x2fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniformMatrix3x2fv
#define glUniformMatrix3x4fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniformMatrix3x4fv
#define glUniformMatrix4x2fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniformMatrix4x2fv
#define glUniformMatrix4x3fv QGLContextPrivate::extensionFuncs(ctx).qt_glUniformMatrix4x3fv
#define glBindAttribLocation QGLContextPrivate::extensionFuncs(ctx).qt_glBindAttribLocation
#define glGetAttribLocation QGLContextPrivate::extensionFuncs(ctx).qt_glGetAttribLocation
#define glVertexAttrib1fv QGLContextPrivate::extensionFuncs(ctx).qt_glVertexAttrib1fv
#define glVertexAttrib2fv QGLContextPrivate::extensionFuncs(ctx).qt_glVertexAttrib2fv
#define glVertexAttrib3fv QGLContextPrivate::extensionFuncs(ctx).qt_glVertexAttrib3fv
#define glVertexAttrib4fv QGLContextPrivate::extensionFuncs(ctx).qt_glVertexAttrib4fv
#define glVertexAttribPointer QGLContextPrivate::extensionFuncs(ctx).qt_glVertexAttribPointer
#define glDisableVertexAttribArray QGLContextPrivate::extensionFuncs(ctx).qt_glDisableVertexAttribArray
#define glEnableVertexAttribArray QGLContextPrivate::extensionFuncs(ctx).qt_glEnableVertexAttribArray
#else // QT_OPENGL_ES_2
#define glGetProgramBinaryOES QGLContextPrivate::extensionFuncs(ctx).qt_glGetProgramBinaryOES
#define glProgramBinaryOES QGLContextPrivate::extensionFuncs(ctx).qt_glProgramBinaryOES
#endif // QT_OPENGL_ES_2
#if !defined(QT_OPENGL_ES_2)
#define glStencilOpSeparate QGLContextPrivate::extensionFuncs(ctx).qt_glStencilOpSeparate
#define glBlendColor QGLContextPrivate::extensionFuncs(ctx).qt_glBlendColor
#endif
#if defined(QT_OPENGL_ES_2)
#define glClearDepth glClearDepthf
#endif
#define glProgramParameteriEXT QGLContextPrivate::extensionFuncs(ctx).qt_glProgramParameteriEXT
#define glFramebufferTextureEXT QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTextureEXT
#define glFramebufferTextureLayerEXT QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTextureLayerEXT
#define glFramebufferTextureFaceEXT QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTextureFaceEXT
#if !defined(QT_OPENGL_ES)
#define glCompressedTexImage2D QGLContextPrivate::extensionFuncs(ctx).qt_glCompressedTexImage2DARB
#endif
extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx);
bool qt_resolve_buffer_extensions(QGLContext *ctx);
bool qt_resolve_version_1_3_functions(QGLContext *ctx);
bool qt_resolve_version_2_0_functions(QGLContext *ctx);
bool qt_resolve_stencil_face_extension(QGLContext *ctx);
bool qt_resolve_frag_program_extensions(QGLContext *ctx);
bool qt_resolve_glsl_extensions(QGLContext *ctx);
QT_END_NAMESPACE
#endif // QGL_EXTENSIONS_P_H

View File

@ -389,7 +389,7 @@ bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
QGL_FUNCP_CONTEXT;
if (!ctx)
return false; // Context no longer exists.
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
GLenum status = ctx->contextHandle()->functions()->glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status) {
case GL_NO_ERROR:
case GL_FRAMEBUFFER_COMPLETE:
@ -444,14 +444,14 @@ namespace
{
void freeFramebufferFunc(QGLContext *ctx, GLuint id)
{
Q_UNUSED(ctx);
glDeleteFramebuffers(1, &id);
Q_ASSERT(ctx);
ctx->contextHandle()->functions()->glDeleteFramebuffers(1, &id);
}
void freeRenderbufferFunc(QGLContext *ctx, GLuint id)
{
Q_UNUSED(ctx);
glDeleteRenderbuffers(1, &id);
Q_ASSERT(ctx);
ctx->contextHandle()->functions()->glDeleteRenderbuffers(1, &id);
}
void freeTextureFunc(QGLContext *ctx, GLuint id)
@ -468,8 +468,9 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
{
QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
funcs.initializeOpenGLFunctions();
if (!funcs.hasOpenGLFeature(QOpenGLFunctions::Framebuffers))
return;
size = sz;
@ -478,8 +479,8 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
QT_RESET_GLERROR(); // reset error state
GLuint fbo = 0;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
funcs.glGenFramebuffers(1, &fbo);
funcs.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
GLuint texture = 0;
GLuint color_buffer = 0;
@ -509,7 +510,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
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);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
target, texture, 0);
QT_CHECK_GLERROR();
@ -524,25 +525,25 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
samples = qBound(0, int(samples), int(maxSamples));
glGenRenderbuffers(1, &color_buffer);
glBindRenderbuffer(GL_RENDERBUFFER, color_buffer);
if (glRenderbufferStorageMultisampleEXT && samples > 0) {
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
funcs.glGenRenderbuffers(1, &color_buffer);
funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer);
if (funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample) && samples > 0) {
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
internal_format, size.width(), size.height());
} else {
samples = 0;
glRenderbufferStorage(GL_RENDERBUFFER, internal_format,
funcs.glRenderbufferStorage(GL_RENDERBUFFER, internal_format,
size.width(), size.height());
}
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, color_buffer);
QT_CHECK_GLERROR();
valid = checkFramebufferStatus();
if (valid)
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
}
// In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a
@ -550,28 +551,28 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
// might not be supported while separate buffers are, according to QTBUG-12861.
if (attachment == QGLFramebufferObject::CombinedDepthStencil
&& (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) {
&& funcs.hasOpenGLExtension(QOpenGLExtensions::PackedDepthStencil)) {
// depth and stencil buffer needs another extension
glGenRenderbuffers(1, &depth_buffer);
Q_ASSERT(!glIsRenderbuffer(depth_buffer));
glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
Q_ASSERT(glIsRenderbuffer(depth_buffer));
if (samples != 0 && glRenderbufferStorageMultisampleEXT)
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
funcs.glGenRenderbuffers(1, &depth_buffer);
Q_ASSERT(!funcs.glIsRenderbuffer(depth_buffer));
funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH24_STENCIL8, size.width(), size.height());
else
glRenderbufferStorage(GL_RENDERBUFFER,
funcs.glRenderbufferStorage(GL_RENDERBUFFER,
GL_DEPTH24_STENCIL8, size.width(), size.height());
stencil_buffer = depth_buffer;
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_buffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, stencil_buffer);
valid = checkFramebufferStatus();
if (!valid) {
glDeleteRenderbuffers(1, &depth_buffer);
funcs.glDeleteRenderbuffers(1, &depth_buffer);
stencil_buffer = depth_buffer = 0;
}
}
@ -579,72 +580,72 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil
|| (attachment == QGLFramebufferObject::Depth)))
{
glGenRenderbuffers(1, &depth_buffer);
Q_ASSERT(!glIsRenderbuffer(depth_buffer));
glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
Q_ASSERT(glIsRenderbuffer(depth_buffer));
if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
funcs.glGenRenderbuffers(1, &depth_buffer);
Q_ASSERT(!funcs.glIsRenderbuffer(depth_buffer));
funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
#ifdef QT_OPENGL_ES
if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) {
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH_COMPONENT24_OES, size.width(), size.height());
} else {
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH_COMPONENT16, size.width(), size.height());
}
#else
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
} else {
#ifdef QT_OPENGL_ES
if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) {
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES,
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES,
size.width(), size.height());
} else {
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
size.width(), size.height());
}
#else
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
}
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_buffer);
valid = checkFramebufferStatus();
if (!valid) {
glDeleteRenderbuffers(1, &depth_buffer);
funcs.glDeleteRenderbuffers(1, &depth_buffer);
depth_buffer = 0;
}
}
if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) {
glGenRenderbuffers(1, &stencil_buffer);
Q_ASSERT(!glIsRenderbuffer(stencil_buffer));
glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
Q_ASSERT(glIsRenderbuffer(stencil_buffer));
if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
funcs.glGenRenderbuffers(1, &stencil_buffer);
Q_ASSERT(!funcs.glIsRenderbuffer(stencil_buffer));
funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer));
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
#ifdef QT_OPENGL_ES
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_STENCIL_INDEX8, size.width(), size.height());
#else
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_STENCIL_INDEX, size.width(), size.height());
#endif
} else {
#ifdef QT_OPENGL_ES
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
size.width(), size.height());
#else
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX,
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX,
size.width(), size.height());
#endif
}
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, stencil_buffer);
valid = checkFramebufferStatus();
if (!valid) {
glDeleteRenderbuffers(1, &stencil_buffer);
funcs.glDeleteRenderbuffers(1, &stencil_buffer);
stencil_buffer = 0;
}
}
@ -660,7 +661,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
fbo_attachment = QGLFramebufferObject::NoAttachment;
}
glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo);
funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo);
if (valid) {
fbo_guard = createSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
if (color_buffer)
@ -677,14 +678,14 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
}
} else {
if (color_buffer)
glDeleteRenderbuffers(1, &color_buffer);
funcs.glDeleteRenderbuffers(1, &color_buffer);
else
glDeleteTextures(1, &texture);
if (depth_buffer)
glDeleteRenderbuffers(1, &depth_buffer);
funcs.glDeleteRenderbuffers(1, &depth_buffer);
if (stencil_buffer && depth_buffer != stencil_buffer)
glDeleteRenderbuffers(1, &stencil_buffer);
glDeleteFramebuffers(1, &fbo);
funcs.glDeleteRenderbuffers(1, &stencil_buffer);
funcs.glDeleteFramebuffers(1, &fbo);
}
QT_CHECK_GLERROR();
@ -991,7 +992,7 @@ bool QGLFramebufferObject::bind()
qWarning("QGLFramebufferObject::bind() called from incompatible context");
}
#endif
glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
d->valid = d->checkFramebufferStatus();
if (d->valid && current)
current->d_ptr->current_fbo = d->fbo();
@ -1011,6 +1012,7 @@ bool QGLFramebufferObject::release()
{
if (!isValid())
return false;
Q_D(QGLFramebufferObject);
QGL_FUNC_CONTEXT;
if (!ctx)
return false; // Context no longer exists.
@ -1027,7 +1029,7 @@ bool QGLFramebufferObject::release()
if (current) {
current->d_ptr->current_fbo = current->d_ptr->default_fbo;
glBindFramebuffer(GL_FRAMEBUFFER, current->d_ptr->default_fbo);
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->d_ptr->default_fbo);
}
return true;
@ -1133,12 +1135,12 @@ bool QGLFramebufferObject::bindDefault()
QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx) {
bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
QOpenGLFunctions functions(ctx->contextHandle());
if (!functions.hasOpenGLFeature(QOpenGLFunctions::Framebuffers))
return false;
ctx->d_ptr->current_fbo = ctx->d_ptr->default_fbo;
glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->default_fbo);
functions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->default_fbo);
#ifdef QT_DEBUG
} else {
qWarning("QGLFramebufferObject::bindDefault() called without current context.");
@ -1156,7 +1158,7 @@ bool QGLFramebufferObject::bindDefault()
*/
bool QGLFramebufferObject::hasOpenGLFramebufferObjects()
{
return (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
return qgl_hasFeature(QOpenGLFunctions::Framebuffers);
}
/*!
@ -1296,7 +1298,7 @@ bool QGLFramebufferObject::isBound() const
*/
bool QGLFramebufferObject::hasOpenGLFramebufferBlit()
{
return (QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit);
return QOpenGLExtensions(QOpenGLContext::currentContext()).hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit);
}
/*!
@ -1336,13 +1338,14 @@ void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const Q
GLbitfield buffers,
GLenum filter)
{
if (!(QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit))
return;
const QGLContext *ctx = QGLContext::currentContext();
if (!ctx || !ctx->contextHandle())
return;
QOpenGLExtensions functions(ctx->contextHandle());
if (!functions.hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit))
return;
QSurface *surface = ctx->contextHandle()->surface();
const int height = static_cast<QWindow *>(surface)->height();
@ -1360,14 +1363,14 @@ void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const Q
const int ty0 = th - (targetRect.top() + targetRect.height());
const int ty1 = th - targetRect.top();
glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : 0);
functions.glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : 0);
functions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : 0);
glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
functions.glBlitFramebuffer(sx0, sy0, sx1, sy1,
tx0, ty0, tx1, ty1,
buffers, filter);
glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo);
functions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo);
}
QT_END_NAMESPACE

View File

@ -56,6 +56,7 @@
#include <qglframebufferobject.h>
#include <private/qglpaintdevice_p.h>
#include <private/qgl_p.h>
#include <private/qopenglextensions_p.h>
QT_BEGIN_NAMESPACE
@ -148,6 +149,7 @@ public:
QGLFramebufferObject::Attachment fbo_attachment;
mutable QPaintEngine *engine;
QGLFBOGLPaintDevice glDevice;
QOpenGLExtensions funcs;
inline GLuint fbo() const { return fbo_guard ? fbo_guard->id() : 0; }
};

View File

@ -42,6 +42,7 @@
#include "qglfunctions.h"
#include "qgl_p.h"
#include "QtGui/private/qopenglcontext_p.h"
#include <private/qopengl_p.h>
QT_BEGIN_NAMESPACE
@ -225,7 +226,7 @@ static int qt_gl_resolve_features()
QGLFunctions::CompressedTextures |
QGLFunctions::Multisample |
QGLFunctions::StencilSeparate;
QGLExtensionMatcher extensions;
QOpenGLExtensionMatcher extensions;
if (extensions.match("GL_OES_texture_npot"))
features |= QGLFunctions::NPOTTextures;
if (extensions.match("GL_IMG_texture_npot"))
@ -236,7 +237,7 @@ static int qt_gl_resolve_features()
QGLFunctions::Buffers |
QGLFunctions::CompressedTextures |
QGLFunctions::Multisample;
QGLExtensionMatcher extensions;
QOpenGLExtensionMatcher extensions;
if (extensions.match("GL_OES_framebuffer_object"))
features |= QGLFunctions::Framebuffers;
if (extensions.match("GL_OES_blend_equation_separate"))
@ -253,7 +254,7 @@ static int qt_gl_resolve_features()
#else
int features = 0;
QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
QGLExtensionMatcher extensions;
QOpenGLExtensionMatcher extensions;
// Recognize features by extension name.
if (extensions.match("GL_ARB_multitexture"))

View File

@ -40,7 +40,7 @@
****************************************************************************/
#include "qglshaderprogram.h"
#include "qglextensions_p.h"
#include <private/qopenglextensions_p.h>
#include "qgl_p.h"
#include <QtCore/private/qobject_p.h>
#include <QtCore/qdebug.h>
@ -197,10 +197,11 @@ class QGLShaderPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QGLShader)
public:
QGLShaderPrivate(const QGLContext *, QGLShader::ShaderType type)
QGLShaderPrivate(const QGLContext *ctx, QGLShader::ShaderType type)
: shaderGuard(0)
, shaderType(type)
, compiled(false)
, glfuncs(new QOpenGLFunctions(ctx->contextHandle()))
{
}
~QGLShaderPrivate();
@ -210,6 +211,8 @@ public:
bool compiled;
QString log;
QOpenGLFunctions *glfuncs;
bool create();
bool compile(QGLShader *q);
void deleteShader();
@ -218,8 +221,8 @@ public:
namespace {
void freeShaderFunc(QGLContext *ctx, GLuint id)
{
Q_UNUSED(ctx);
glDeleteShader(id);
Q_ASSERT(ctx);
ctx->contextHandle()->functions()->glDeleteShader(id);
}
}
@ -227,6 +230,7 @@ namespace {
QGLShaderPrivate::~QGLShaderPrivate()
{
delete glfuncs;
if (shaderGuard)
shaderGuard->free();
}
@ -236,16 +240,17 @@ bool QGLShaderPrivate::create()
QGLContext *context = const_cast<QGLContext *>(QGLContext::currentContext());
if (!context)
return false;
if (qt_resolve_glsl_extensions(context)) {
if (glfuncs->hasOpenGLFeature(QOpenGLFunctions::Shaders)) {
GLuint shader;
if (shaderType == QGLShader::Vertex)
shader = glCreateShader(GL_VERTEX_SHADER);
shader = glfuncs->glCreateShader(GL_VERTEX_SHADER);
#if !defined(QT_OPENGL_ES_2)
else if (shaderType == QGLShader::Geometry)
shader = glCreateShader(GL_GEOMETRY_SHADER_EXT);
shader = glfuncs->glCreateShader(GL_GEOMETRY_SHADER_EXT);
#endif
else
shader = glCreateShader(GL_FRAGMENT_SHADER);
shader = glfuncs->glCreateShader(GL_FRAGMENT_SHADER);
if (!shader) {
qWarning("%s: Could not create shader of type %d.",
Q_FUNC_INFO, int(shaderType));
@ -263,16 +268,16 @@ bool QGLShaderPrivate::compile(QGLShader *q)
GLuint shader = shaderGuard ? shaderGuard->id() : 0;
if (!shader)
return false;
glCompileShader(shader);
glfuncs->glCompileShader(shader);
GLint value = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &value);
glfuncs->glGetShaderiv(shader, GL_COMPILE_STATUS, &value);
compiled = (value != 0);
value = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &value);
glfuncs->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &value);
if (!compiled && value > 1) {
char *logbuf = new char [value];
GLint len;
glGetShaderInfoLog(shader, value, &len, logbuf);
glfuncs->glGetShaderInfoLog(shader, value, &len, logbuf);
log = QString::fromLatin1(logbuf);
QString name = q->objectName();
@ -434,7 +439,7 @@ bool QGLShader::compileSourceCode(const char *source)
#endif
src.append(source + headerLen);
srclen.append(GLint(qstrlen(source + headerLen)));
glShaderSource(d->shaderGuard->id(), src.size(), src.data(), srclen.data());
d->glfuncs->glShaderSource(d->shaderGuard->id(), src.size(), src.data(), srclen.data());
return d->compile(this);
} else {
return false;
@ -498,12 +503,12 @@ QByteArray QGLShader::sourceCode() const
if (!shader)
return QByteArray();
GLint size = 0;
glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &size);
d->glfuncs->glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &size);
if (size <= 0)
return QByteArray();
GLint len = 0;
char *source = new char [size];
glGetShaderSource(shader, size, &len, source);
d->glfuncs->glGetShaderSource(shader, size, &len, source);
QByteArray src(source);
delete [] source;
return src;
@ -544,6 +549,32 @@ GLuint QGLShader::shaderId() const
#undef ctx
class ShaderProgramOpenGLFunctions : public QOpenGLFunctions
{
public:
ShaderProgramOpenGLFunctions()
: QOpenGLFunctions()
, glProgramParameteri(0)
{
}
typedef void (QOPENGLF_APIENTRYP type_glProgramParameteri)(GLuint program, GLenum pname, GLint value);
void initializeGeometryShaderFunctions()
{
QOpenGLContext *context = QOpenGLContext::currentContext();
glProgramParameteri = (type_glProgramParameteri)
context->getProcAddress("glProgramParameteri");
if (!glProgramParameteri) {
glProgramParameteri = (type_glProgramParameteri)
context->getProcAddress("glProgramParameteriEXT");
}
}
type_glProgramParameteri glProgramParameteri;
};
class QGLShaderProgramPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QGLShaderProgram)
@ -556,6 +587,7 @@ public:
, geometryVertexCount(64)
, geometryInputType(0)
, geometryOutputType(0)
, glfuncs(new ShaderProgramOpenGLFunctions)
{
}
~QGLShaderProgramPrivate();
@ -573,20 +605,23 @@ public:
QList<QGLShader *> shaders;
QList<QGLShader *> anonShaders;
ShaderProgramOpenGLFunctions *glfuncs;
bool hasShader(QGLShader::ShaderType type) const;
};
namespace {
void freeProgramFunc(QGLContext *ctx, GLuint id)
{
Q_UNUSED(ctx);
glDeleteProgram(id);
Q_ASSERT(ctx);
ctx->contextHandle()->functions()->glDeleteProgram(id);
}
}
QGLShaderProgramPrivate::~QGLShaderProgramPrivate()
{
delete glfuncs;
if (programGuard)
programGuard->free();
}
@ -644,8 +679,10 @@ bool QGLShaderProgram::init()
QGLContext *context = const_cast<QGLContext *>(QGLContext::currentContext());
if (!context)
return false;
if (qt_resolve_glsl_extensions(context)) {
GLuint program = glCreateProgram();
d->glfuncs->initializeOpenGLFunctions();
d->glfuncs->initializeGeometryShaderFunctions();
if (d->glfuncs->hasOpenGLFeature(QOpenGLFunctions::Shaders)) {
GLuint program = d->glfuncs->glCreateProgram();
if (!program) {
qWarning() << "QGLShaderProgram: could not create shader program";
return false;
@ -686,7 +723,7 @@ bool QGLShaderProgram::addShader(QGLShader *shader)
qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context.");
return false;
}
glAttachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
d->glfuncs->glAttachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
d->linked = false; // Program needs to be relinked.
d->shaders.append(shader);
connect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed()));
@ -805,7 +842,7 @@ void QGLShaderProgram::removeShader(QGLShader *shader)
if (d->programGuard && d->programGuard->id()
&& shader && shader->d_func()->shaderGuard)
{
glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
d->glfuncs->glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
}
d->linked = false; // Program needs to be relinked.
if (shader) {
@ -843,7 +880,7 @@ void QGLShaderProgram::removeAllShaders()
if (d->programGuard && d->programGuard->id()
&& shader && shader->d_func()->shaderGuard)
{
glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
d->glfuncs->glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
}
}
foreach (QGLShader *shader, d->anonShaders) {
@ -884,7 +921,7 @@ bool QGLShaderProgram::link()
// or otherwise populated the shaders itself. Check to see if the
// program is already linked and bail out if so.
value = 0;
glGetProgramiv(program, GL_LINK_STATUS, &value);
d->glfuncs->glGetProgramiv(program, GL_LINK_STATUS, &value);
d->linked = (value != 0);
if (d->linked)
return true;
@ -892,14 +929,14 @@ bool QGLShaderProgram::link()
#if !defined(QT_OPENGL_ES_2)
// Set up the geometry shader parameters
if (glProgramParameteriEXT) {
if (d->glfuncs->glProgramParameteri) {
foreach (QGLShader *shader, d->shaders) {
if (shader->shaderType() & QGLShader::Geometry) {
glProgramParameteriEXT(program, GL_GEOMETRY_INPUT_TYPE_EXT,
d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_INPUT_TYPE_EXT,
d->geometryInputType);
glProgramParameteriEXT(program, GL_GEOMETRY_OUTPUT_TYPE_EXT,
d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_OUTPUT_TYPE_EXT,
d->geometryOutputType);
glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT,
d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_VERTICES_OUT_EXT,
d->geometryVertexCount);
break;
}
@ -907,17 +944,17 @@ bool QGLShaderProgram::link()
}
#endif
glLinkProgram(program);
d->glfuncs->glLinkProgram(program);
value = 0;
glGetProgramiv(program, GL_LINK_STATUS, &value);
d->glfuncs->glGetProgramiv(program, GL_LINK_STATUS, &value);
d->linked = (value != 0);
value = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value);
d->glfuncs->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value);
d->log = QString();
if (value > 1) {
char *logbuf = new char [value];
GLint len;
glGetProgramInfoLog(program, value, &len, logbuf);
d->glfuncs->glGetProgramInfoLog(program, value, &len, logbuf);
d->log = QString::fromLatin1(logbuf);
QString name = objectName();
if (name.isEmpty())
@ -976,7 +1013,7 @@ bool QGLShaderProgram::bind()
return false;
}
#endif
glUseProgram(program);
d->glfuncs->glUseProgram(program);
return true;
}
@ -991,17 +1028,12 @@ bool QGLShaderProgram::bind()
*/
void QGLShaderProgram::release()
{
#ifndef QT_NO_DEBUG
Q_D(QGLShaderProgram);
#ifndef QT_NO_DEBUG
if (d->programGuard && d->programGuard->group() != QOpenGLContextGroup::currentContextGroup())
qWarning("QGLShaderProgram::release: program is not valid in the current context.");
#endif
#if defined(QT_OPENGL_ES_2)
glUseProgram(0);
#else
if (glUseProgram)
glUseProgram(0);
#endif
d->glfuncs->glUseProgram(0);
}
/*!
@ -1040,7 +1072,7 @@ void QGLShaderProgram::bindAttributeLocation(const char *name, int location)
Q_D(QGLShaderProgram);
if (!init() || !d->programGuard || !d->programGuard->id())
return;
glBindAttribLocation(d->programGuard->id(), location, name);
d->glfuncs->glBindAttribLocation(d->programGuard->id(), location, name);
d->linked = false; // Program needs to be relinked.
}
@ -1091,7 +1123,7 @@ int QGLShaderProgram::attributeLocation(const char *name) const
{
Q_D(const QGLShaderProgram);
if (d->linked && d->programGuard && d->programGuard->id()) {
return glGetAttribLocation(d->programGuard->id(), name);
return d->glfuncs->glGetAttribLocation(d->programGuard->id(), name);
} else {
qWarning() << "QGLShaderProgram::attributeLocation(" << name
<< "): shader program is not linked";
@ -1137,7 +1169,7 @@ void QGLShaderProgram::setAttributeValue(int location, GLfloat value)
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glVertexAttrib1fv(location, &value);
d->glfuncs->glVertexAttrib1fv(location, &value);
}
/*!
@ -1164,7 +1196,7 @@ void QGLShaderProgram::setAttributeValue(int location, GLfloat x, GLfloat y)
Q_UNUSED(d);
if (location != -1) {
GLfloat values[2] = {x, y};
glVertexAttrib2fv(location, values);
d->glfuncs->glVertexAttrib2fv(location, values);
}
}
@ -1194,7 +1226,7 @@ void QGLShaderProgram::setAttributeValue
Q_UNUSED(d);
if (location != -1) {
GLfloat values[3] = {x, y, z};
glVertexAttrib3fv(location, values);
d->glfuncs->glVertexAttrib3fv(location, values);
}
}
@ -1225,7 +1257,7 @@ void QGLShaderProgram::setAttributeValue
Q_UNUSED(d);
if (location != -1) {
GLfloat values[4] = {x, y, z, w};
glVertexAttrib4fv(location, values);
d->glfuncs->glVertexAttrib4fv(location, values);
}
}
@ -1253,7 +1285,7 @@ void QGLShaderProgram::setAttributeValue(int location, const QVector2D& value)
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glVertexAttrib2fv(location, reinterpret_cast<const GLfloat *>(&value));
d->glfuncs->glVertexAttrib2fv(location, reinterpret_cast<const GLfloat *>(&value));
}
/*!
@ -1278,7 +1310,7 @@ void QGLShaderProgram::setAttributeValue(int location, const QVector3D& value)
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glVertexAttrib3fv(location, reinterpret_cast<const GLfloat *>(&value));
d->glfuncs->glVertexAttrib3fv(location, reinterpret_cast<const GLfloat *>(&value));
}
/*!
@ -1303,7 +1335,7 @@ void QGLShaderProgram::setAttributeValue(int location, const QVector4D& value)
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glVertexAttrib4fv(location, reinterpret_cast<const GLfloat *>(&value));
d->glfuncs->glVertexAttrib4fv(location, reinterpret_cast<const GLfloat *>(&value));
}
/*!
@ -1330,7 +1362,7 @@ void QGLShaderProgram::setAttributeValue(int location, const QColor& value)
if (location != -1) {
GLfloat values[4] = {GLfloat(value.redF()), GLfloat(value.greenF()),
GLfloat(value.blueF()), GLfloat(value.alphaF())};
glVertexAttrib4fv(location, values);
d->glfuncs->glVertexAttrib4fv(location, values);
}
}
@ -1367,13 +1399,13 @@ void QGLShaderProgram::setAttributeValue
if (location != -1) {
while (columns-- > 0) {
if (rows == 1)
glVertexAttrib1fv(location, values);
d->glfuncs->glVertexAttrib1fv(location, values);
else if (rows == 2)
glVertexAttrib2fv(location, values);
d->glfuncs->glVertexAttrib2fv(location, values);
else if (rows == 3)
glVertexAttrib3fv(location, values);
d->glfuncs->glVertexAttrib3fv(location, values);
else
glVertexAttrib4fv(location, values);
d->glfuncs->glVertexAttrib4fv(location, values);
values += rows;
++location;
}
@ -1417,7 +1449,7 @@ void QGLShaderProgram::setAttributeArray
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1) {
glVertexAttribPointer(location, tupleSize, GL_FLOAT, GL_FALSE,
d->glfuncs->glVertexAttribPointer(location, tupleSize, GL_FLOAT, GL_FALSE,
stride, values);
}
}
@ -1441,7 +1473,7 @@ void QGLShaderProgram::setAttributeArray
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1) {
glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE,
d->glfuncs->glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE,
stride, values);
}
}
@ -1465,7 +1497,7 @@ void QGLShaderProgram::setAttributeArray
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1) {
glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE,
d->glfuncs->glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE,
stride, values);
}
}
@ -1489,7 +1521,7 @@ void QGLShaderProgram::setAttributeArray
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1) {
glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE,
d->glfuncs->glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE,
stride, values);
}
}
@ -1521,7 +1553,7 @@ void QGLShaderProgram::setAttributeArray
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1) {
glVertexAttribPointer(location, tupleSize, type, GL_TRUE,
d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE,
stride, values);
}
}
@ -1665,7 +1697,7 @@ void QGLShaderProgram::setAttributeBuffer
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1) {
glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride,
d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride,
reinterpret_cast<const void *>(offset));
}
}
@ -1710,7 +1742,7 @@ void QGLShaderProgram::enableAttributeArray(int location)
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glEnableVertexAttribArray(location);
d->glfuncs->glEnableVertexAttribArray(location);
}
/*!
@ -1740,7 +1772,7 @@ void QGLShaderProgram::disableAttributeArray(int location)
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glDisableVertexAttribArray(location);
d->glfuncs->glDisableVertexAttribArray(location);
}
/*!
@ -1769,7 +1801,7 @@ int QGLShaderProgram::uniformLocation(const char *name) const
Q_D(const QGLShaderProgram);
Q_UNUSED(d);
if (d->linked && d->programGuard && d->programGuard->id()) {
return glGetUniformLocation(d->programGuard->id(), name);
return d->glfuncs->glGetUniformLocation(d->programGuard->id(), name);
} else {
qWarning() << "QGLShaderProgram::uniformLocation(" << name
<< "): shader program is not linked";
@ -1815,7 +1847,7 @@ void QGLShaderProgram::setUniformValue(int location, GLfloat value)
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniform1fv(location, 1, &value);
d->glfuncs->glUniform1fv(location, 1, &value);
}
/*!
@ -1841,7 +1873,7 @@ void QGLShaderProgram::setUniformValue(int location, GLint value)
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniform1i(location, value);
d->glfuncs->glUniform1i(location, value);
}
/*!
@ -1868,7 +1900,7 @@ void QGLShaderProgram::setUniformValue(int location, GLuint value)
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniform1i(location, value);
d->glfuncs->glUniform1i(location, value);
}
/*!
@ -1896,7 +1928,7 @@ void QGLShaderProgram::setUniformValue(int location, GLfloat x, GLfloat y)
Q_UNUSED(d);
if (location != -1) {
GLfloat values[2] = {x, y};
glUniform2fv(location, 1, values);
d->glfuncs->glUniform2fv(location, 1, values);
}
}
@ -1926,7 +1958,7 @@ void QGLShaderProgram::setUniformValue
Q_UNUSED(d);
if (location != -1) {
GLfloat values[3] = {x, y, z};
glUniform3fv(location, 1, values);
d->glfuncs->glUniform3fv(location, 1, values);
}
}
@ -1957,7 +1989,7 @@ void QGLShaderProgram::setUniformValue
Q_UNUSED(d);
if (location != -1) {
GLfloat values[4] = {x, y, z, w};
glUniform4fv(location, 1, values);
d->glfuncs->glUniform4fv(location, 1, values);
}
}
@ -1985,7 +2017,7 @@ void QGLShaderProgram::setUniformValue(int location, const QVector2D& value)
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniform2fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
d->glfuncs->glUniform2fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
}
/*!
@ -2011,7 +2043,7 @@ void QGLShaderProgram::setUniformValue(int location, const QVector3D& value)
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniform3fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
d->glfuncs->glUniform3fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
}
/*!
@ -2037,7 +2069,7 @@ void QGLShaderProgram::setUniformValue(int location, const QVector4D& value)
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniform4fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
d->glfuncs->glUniform4fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
}
/*!
@ -2066,7 +2098,7 @@ void QGLShaderProgram::setUniformValue(int location, const QColor& color)
if (location != -1) {
GLfloat values[4] = {GLfloat(color.redF()), GLfloat(color.greenF()),
GLfloat(color.blueF()), GLfloat(color.alphaF())};
glUniform4fv(location, 1, values);
d->glfuncs->glUniform4fv(location, 1, values);
}
}
@ -2095,7 +2127,7 @@ void QGLShaderProgram::setUniformValue(int location, const QPoint& point)
Q_UNUSED(d);
if (location != -1) {
GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())};
glUniform2fv(location, 1, values);
d->glfuncs->glUniform2fv(location, 1, values);
}
}
@ -2124,7 +2156,7 @@ void QGLShaderProgram::setUniformValue(int location, const QPointF& point)
Q_UNUSED(d);
if (location != -1) {
GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())};
glUniform2fv(location, 1, values);
d->glfuncs->glUniform2fv(location, 1, values);
}
}
@ -2153,7 +2185,7 @@ void QGLShaderProgram::setUniformValue(int location, const QSize& size)
Q_UNUSED(d);
if (location != -1) {
GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())};
glUniform2fv(location, 1, values);
d->glfuncs->glUniform2fv(location, 1, values);
}
}
@ -2182,7 +2214,7 @@ void QGLShaderProgram::setUniformValue(int location, const QSizeF& size)
Q_UNUSED(d);
if (location != -1) {
GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())};
glUniform2fv(location, 1, values);
d->glfuncs->glUniform2fv(location, 1, values);
}
}
@ -2208,8 +2240,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QSizeF& size)
void QGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
glUniformMatrix2fv(location, 1, GL_FALSE, value.constData());
d->glfuncs->glUniformMatrix2fv(location, 1, GL_FALSE, value.constData());
}
/*!
@ -2234,8 +2265,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x2& value
void QGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
glUniform3fv(location, 2, value.constData());
d->glfuncs->glUniform3fv(location, 2, value.constData());
}
/*!
@ -2260,8 +2290,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& value
void QGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
glUniform4fv(location, 2, value.constData());
d->glfuncs->glUniform4fv(location, 2, value.constData());
}
/*!
@ -2286,8 +2315,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& value
void QGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
glUniform2fv(location, 3, value.constData());
d->glfuncs->glUniform2fv(location, 3, value.constData());
}
/*!
@ -2312,8 +2340,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x2& value
void QGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
glUniformMatrix3fv(location, 1, GL_FALSE, value.constData());
d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, value.constData());
}
/*!
@ -2338,8 +2365,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x3& value
void QGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
glUniform4fv(location, 3, value.constData());
d->glfuncs->glUniform4fv(location, 3, value.constData());
}
/*!
@ -2364,8 +2390,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& value
void QGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
glUniform2fv(location, 4, value.constData());
d->glfuncs->glUniform2fv(location, 4, value.constData());
}
/*!
@ -2390,8 +2415,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& value
void QGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
glUniform3fv(location, 4, value.constData());
d->glfuncs->glUniform3fv(location, 4, value.constData());
}
/*!
@ -2416,8 +2440,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x3& value
void QGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
glUniformMatrix4fv(location, 1, GL_FALSE, value.constData());
d->glfuncs->glUniformMatrix4fv(location, 1, GL_FALSE, value.constData());
}
/*!
@ -2446,9 +2469,8 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x4& value
void QGLShaderProgram::setUniformValue(int location, const GLfloat value[2][2])
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniformMatrix2fv(location, 1, GL_FALSE, value[0]);
d->glfuncs->glUniformMatrix2fv(location, 1, GL_FALSE, value[0]);
}
/*!
@ -2464,9 +2486,8 @@ void QGLShaderProgram::setUniformValue(int location, const GLfloat value[2][2])
void QGLShaderProgram::setUniformValue(int location, const GLfloat value[3][3])
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniformMatrix3fv(location, 1, GL_FALSE, value[0]);
d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, value[0]);
}
/*!
@ -2481,9 +2502,8 @@ void QGLShaderProgram::setUniformValue(int location, const GLfloat value[3][3])
void QGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4])
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniformMatrix4fv(location, 1, GL_FALSE, value[0]);
d->glfuncs->glUniformMatrix4fv(location, 1, GL_FALSE, value[0]);
}
@ -2541,14 +2561,13 @@ void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[4][
void QGLShaderProgram::setUniformValue(int location, const QTransform& value)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1) {
GLfloat mat[3][3] = {
{GLfloat(value.m11()), GLfloat(value.m12()), GLfloat(value.m13())},
{GLfloat(value.m21()), GLfloat(value.m22()), GLfloat(value.m23())},
{GLfloat(value.m31()), GLfloat(value.m32()), GLfloat(value.m33())}
};
glUniformMatrix3fv(location, 1, GL_FALSE, mat[0]);
d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, mat[0]);
}
}
@ -2576,9 +2595,8 @@ void QGLShaderProgram::setUniformValue
void QGLShaderProgram::setUniformValueArray(int location, const GLint *values, int count)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniform1iv(location, count, values);
d->glfuncs->glUniform1iv(location, count, values);
}
/*!
@ -2605,9 +2623,8 @@ void QGLShaderProgram::setUniformValueArray
void QGLShaderProgram::setUniformValueArray(int location, const GLuint *values, int count)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniform1iv(location, count, reinterpret_cast<const GLint *>(values));
d->glfuncs->glUniform1iv(location, count, reinterpret_cast<const GLint *>(values));
}
/*!
@ -2635,16 +2652,15 @@ void QGLShaderProgram::setUniformValueArray
void QGLShaderProgram::setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1) {
if (tupleSize == 1)
glUniform1fv(location, count, values);
d->glfuncs->glUniform1fv(location, count, values);
else if (tupleSize == 2)
glUniform2fv(location, count, values);
d->glfuncs->glUniform2fv(location, count, values);
else if (tupleSize == 3)
glUniform3fv(location, count, values);
d->glfuncs->glUniform3fv(location, count, values);
else if (tupleSize == 4)
glUniform4fv(location, count, values);
d->glfuncs->glUniform4fv(location, count, values);
else
qWarning() << "QGLShaderProgram::setUniformValue: size" << tupleSize << "not supported";
}
@ -2674,9 +2690,8 @@ void QGLShaderProgram::setUniformValueArray
void QGLShaderProgram::setUniformValueArray(int location, const QVector2D *values, int count)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniform2fv(location, count, reinterpret_cast<const GLfloat *>(values));
d->glfuncs->glUniform2fv(location, count, reinterpret_cast<const GLfloat *>(values));
}
/*!
@ -2701,9 +2716,8 @@ void QGLShaderProgram::setUniformValueArray(const char *name, const QVector2D *v
void QGLShaderProgram::setUniformValueArray(int location, const QVector3D *values, int count)
{
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniform3fv(location, count, reinterpret_cast<const GLfloat *>(values));
d->glfuncs->glUniform3fv(location, count, reinterpret_cast<const GLfloat *>(values));
}
/*!
@ -2730,7 +2744,7 @@ void QGLShaderProgram::setUniformValueArray(int location, const QVector4D *value
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1)
glUniform4fv(location, count, reinterpret_cast<const GLfloat *>(values));
d->glfuncs->glUniform4fv(location, count, reinterpret_cast<const GLfloat *>(values));
}
/*!
@ -2763,32 +2777,7 @@ void QGLShaderProgram::setUniformValueArray(const char *name, const QVector4D *v
} \
func(location, count, GL_FALSE, temp.constData()); \
}
#if !defined(QT_OPENGL_ES_2)
#define setUniformGenericMatrixArray(func,colfunc,location,values,count,type,cols,rows) \
if (location == -1 || count <= 0) \
return; \
if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
const GLfloat *data = reinterpret_cast<const GLfloat *> \
(values[0].constData()); \
if (func) \
func(location, count, GL_FALSE, data); \
else \
colfunc(location, count * cols, data); \
} else { \
QVarLengthArray<GLfloat> temp(cols * rows * count); \
for (int index = 0; index < count; ++index) { \
for (int index2 = 0; index2 < (cols * rows); ++index2) { \
temp.data()[cols * rows * index + index2] = \
values[index].constData()[index2]; \
} \
} \
if (func) \
func(location, count, GL_FALSE, temp.constData()); \
else \
colfunc(location, count * cols, temp.constData()); \
}
#else
#define setUniformGenericMatrixArray(func,colfunc,location,values,count,type,cols,rows) \
#define setUniformGenericMatrixArray(colfunc,location,values,count,type,cols,rows) \
if (location == -1 || count <= 0) \
return; \
if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
@ -2805,7 +2794,6 @@ void QGLShaderProgram::setUniformValueArray(const char *name, const QVector4D *v
} \
colfunc(location, count * cols, temp.constData()); \
}
#endif
/*!
Sets the uniform variable array at \a location in the current
@ -2818,7 +2806,7 @@ void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x2 *valu
Q_D(QGLShaderProgram);
Q_UNUSED(d);
setUniformMatrixArray
(glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2);
(d->glfuncs->glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2);
}
/*!
@ -2845,7 +2833,7 @@ void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x3 *valu
Q_D(QGLShaderProgram);
Q_UNUSED(d);
setUniformGenericMatrixArray
(glUniformMatrix2x3fv, glUniform3fv, location, values, count,
(d->glfuncs->glUniform3fv, location, values, count,
QMatrix2x3, 2, 3);
}
@ -2873,7 +2861,7 @@ void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x4 *valu
Q_D(QGLShaderProgram);
Q_UNUSED(d);
setUniformGenericMatrixArray
(glUniformMatrix2x4fv, glUniform4fv, location, values, count,
(d->glfuncs->glUniform4fv, location, values, count,
QMatrix2x4, 2, 4);
}
@ -2901,7 +2889,7 @@ void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x2 *valu
Q_D(QGLShaderProgram);
Q_UNUSED(d);
setUniformGenericMatrixArray
(glUniformMatrix3x2fv, glUniform2fv, location, values, count,
(d->glfuncs->glUniform2fv, location, values, count,
QMatrix3x2, 3, 2);
}
@ -2929,7 +2917,7 @@ void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x3 *valu
Q_D(QGLShaderProgram);
Q_UNUSED(d);
setUniformMatrixArray
(glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3);
(d->glfuncs->glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3);
}
/*!
@ -2956,7 +2944,7 @@ void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x4 *valu
Q_D(QGLShaderProgram);
Q_UNUSED(d);
setUniformGenericMatrixArray
(glUniformMatrix3x4fv, glUniform4fv, location, values, count,
(d->glfuncs->glUniform4fv, location, values, count,
QMatrix3x4, 3, 4);
}
@ -2984,7 +2972,7 @@ void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x2 *valu
Q_D(QGLShaderProgram);
Q_UNUSED(d);
setUniformGenericMatrixArray
(glUniformMatrix4x2fv, glUniform2fv, location, values, count,
(d->glfuncs->glUniform2fv, location, values, count,
QMatrix4x2, 4, 2);
}
@ -3012,7 +3000,7 @@ void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x3 *valu
Q_D(QGLShaderProgram);
Q_UNUSED(d);
setUniformGenericMatrixArray
(glUniformMatrix4x3fv, glUniform3fv, location, values, count,
(d->glfuncs->glUniform3fv, location, values, count,
QMatrix4x3, 4, 3);
}
@ -3040,7 +3028,7 @@ void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x4 *valu
Q_D(QGLShaderProgram);
Q_UNUSED(d);
setUniformMatrixArray
(glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4);
(d->glfuncs->glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4);
}
/*!
@ -3176,7 +3164,9 @@ bool QGLShaderProgram::hasOpenGLShaderPrograms(const QGLContext *context)
context = QGLContext::currentContext();
if (!context)
return false;
return qt_resolve_glsl_extensions(const_cast<QGLContext *>(context));
QOpenGLFunctions functions(context->contextHandle());
return functions.hasOpenGLFeature(QOpenGLFunctions::Shaders);
#else
Q_UNUSED(context);
return true;
@ -3217,7 +3207,8 @@ bool QGLShader::hasOpenGLShaders(ShaderType type, const QGLContext *context)
if ((type & ~(Geometry | Vertex | Fragment)) || type == 0)
return false;
bool resolved = qt_resolve_glsl_extensions(const_cast<QGLContext *>(context));
QOpenGLFunctions functions(context->contextHandle());
bool resolved = functions.hasOpenGLFeature(QOpenGLFunctions::Shaders);
if (!resolved)
return false;

View File

@ -202,6 +202,11 @@ void tst_QGLBuffer::testBuffer(QGLBuffer::Type type)
void tst_QGLBuffer::bufferSharing()
{
#if defined(Q_OS_WIN)
// Needs investigation on Windows: https://bugreports.qt-project.org/browse/QTBUG-29692
QSKIP("Unreproducible timeout on Windows (MSVC/MinGW) CI bots");
#endif
QGLWidget *w1 = new QGLWidget();
w1->makeCurrent();