summaryrefslogtreecommitdiffstats
path: root/src/gui/opengl/qopenglpaintengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/opengl/qopenglpaintengine.cpp')
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp375
1 files changed, 187 insertions, 188 deletions
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index 7fa80c5343..f160b340e0 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -123,14 +123,14 @@ void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wra
lastTextureUsed = id;
if (smoothPixmapTransform) {
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} else {
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
- glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode);
- glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode);
+ funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode);
+ funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode);
}
@@ -204,7 +204,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
GLuint texId = QOpenGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0);
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
- glBindTexture(GL_TEXTURE_2D, texId);
+ funcs.glBindTexture(GL_TEXTURE_2D, texId);
if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient)
updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
@@ -439,43 +439,43 @@ void QOpenGL2PaintEngineExPrivate::updateCompositionMode()
// qDebug() << "QOpenGL2PaintEngineExPrivate::updateCompositionMode() - Setting GL composition mode for " << q->state()->composition_mode;
switch(q->state()->composition_mode) {
case QPainter::CompositionMode_SourceOver:
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ funcs.glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
break;
case QPainter::CompositionMode_DestinationOver:
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
+ funcs.glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
break;
case QPainter::CompositionMode_Clear:
- glBlendFunc(GL_ZERO, GL_ZERO);
+ funcs.glBlendFunc(GL_ZERO, GL_ZERO);
break;
case QPainter::CompositionMode_Source:
- glBlendFunc(GL_ONE, GL_ZERO);
+ funcs.glBlendFunc(GL_ONE, GL_ZERO);
break;
case QPainter::CompositionMode_Destination:
- glBlendFunc(GL_ZERO, GL_ONE);
+ funcs.glBlendFunc(GL_ZERO, GL_ONE);
break;
case QPainter::CompositionMode_SourceIn:
- glBlendFunc(GL_DST_ALPHA, GL_ZERO);
+ funcs.glBlendFunc(GL_DST_ALPHA, GL_ZERO);
break;
case QPainter::CompositionMode_DestinationIn:
- glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
+ funcs.glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
break;
case QPainter::CompositionMode_SourceOut:
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO);
+ funcs.glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO);
break;
case QPainter::CompositionMode_DestinationOut:
- glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
+ funcs.glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
break;
case QPainter::CompositionMode_SourceAtop:
- glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ funcs.glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
case QPainter::CompositionMode_DestinationAtop:
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA);
+ funcs.glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA);
break;
case QPainter::CompositionMode_Xor:
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ funcs.glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
case QPainter::CompositionMode_Plus:
- glBlendFunc(GL_ONE, GL_ONE);
+ funcs.glBlendFunc(GL_ONE, GL_ONE);
break;
default:
qWarning("Unsupported composition mode");
@@ -524,7 +524,7 @@ void QOpenGL2PaintEngineExPrivate::drawTexture(const QOpenGLRect& dest, const QO
setCoords(staticVertexCoordinateArray, dest);
setCoords(staticTextureCoordinateArray, srcTextureRect);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ funcs.glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
void QOpenGL2PaintEngineEx::beginNativePainting()
@@ -541,37 +541,35 @@ void QOpenGL2PaintEngineEx::beginNativePainting()
for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
d->funcs.glDisableVertexAttribArray(i);
-#ifndef QT_OPENGL_ES_2
- if (!QOpenGLContext::currentContext()->isES()) {
- Q_ASSERT(QOpenGLContext::currentContext());
- const QOpenGLContext *ctx = d->ctx;
- const QSurfaceFormat &fmt = d->device->context()->format();
- if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
- || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
- || fmt.profile() == QSurfaceFormat::CompatibilityProfile)
- {
- // be nice to people who mix OpenGL 1.x code with QPainter commands
- // by setting modelview and projection matrices to mirror the GL 1
- // paint engine
- const QTransform& mtx = state()->matrix;
-
- float mv_matrix[4][4] =
- {
- { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
- { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
- { 0, 0, 1, 0 },
- { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
- };
-
- const QSize sz = d->device->size();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(&mv_matrix[0][0]);
- }
+#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_DYNAMIC)
+ Q_ASSERT(QOpenGLContext::currentContext());
+ const QOpenGLContext *ctx = d->ctx;
+ const QSurfaceFormat &fmt = d->device->context()->format();
+ if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
+ || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
+ || fmt.profile() == QSurfaceFormat::CompatibilityProfile)
+ {
+ // be nice to people who mix OpenGL 1.x code with QPainter commands
+ // by setting modelview and projection matrices to mirror the GL 1
+ // paint engine
+ const QTransform& mtx = state()->matrix;
+
+ float mv_matrix[4][4] =
+ {
+ { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
+ { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
+ { 0, 0, 1, 0 },
+ { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
+ };
+
+ const QSize sz = d->device->size();
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadMatrixf(&mv_matrix[0][0]);
}
#endif // QT_OPENGL_ES_2
@@ -586,17 +584,17 @@ void QOpenGL2PaintEngineEx::beginNativePainting()
void QOpenGL2PaintEngineExPrivate::resetGLState()
{
- glDisable(GL_BLEND);
+ funcs.glDisable(GL_BLEND);
funcs.glActiveTexture(GL_TEXTURE0);
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDepthMask(true);
- glDepthFunc(GL_LESS);
+ funcs.glDisable(GL_STENCIL_TEST);
+ funcs.glDisable(GL_DEPTH_TEST);
+ funcs.glDisable(GL_SCISSOR_TEST);
+ funcs.glDepthMask(true);
+ funcs.glDepthFunc(GL_LESS);
funcs.glClearDepthf(1);
- glStencilMask(0xff);
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- glStencilFunc(GL_ALWAYS, 0, 0xff);
+ funcs.glStencilMask(0xff);
+ funcs.glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ funcs.glStencilFunc(GL_ALWAYS, 0, 0xff);
setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false);
setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false);
setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
@@ -755,9 +753,9 @@ void QOpenGL2PaintEngineExPrivate::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);
@@ -768,12 +766,12 @@ void QOpenGL2PaintEngineExPrivate::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);
#endif
- glDrawArrays(cache->primitiveType, 0, cache->vertexCount);
+ funcs.glDrawArrays(cache->primitiveType, 0, cache->vertexCount);
} else {
// printf(" - Marking path as cachable...\n");
@@ -833,10 +831,10 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path)
cache->iscale = inverseScale;
cache->indexType = polys.indices.type();
#ifdef QT_OPENGL_CACHE_AS_VBOS
- glGenBuffers(1, &cache->vbo);
- glGenBuffers(1, &cache->ibo);
- glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);
+ funcs.glGenBuffers(1, &cache->vbo);
+ funcs.glGenBuffers(1, &cache->ibo);
+ funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
+ funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);
if (polys.indices.type() == QVertexIndexVector::UnsignedInt)
funcs.glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint32) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW);
@@ -863,21 +861,21 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path)
prepareForDraw(currentBrush.isOpaque());
#ifdef QT_OPENGL_CACHE_AS_VBOS
- glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);
+ funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
+ funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0);
if (cache->indexType == QVertexIndexVector::UnsignedInt)
- glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, 0);
+ funcs.glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, 0);
else
- glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ funcs.glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, 0);
+ funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ funcs.glBindBuffer(GL_ARRAY_BUFFER, 0);
#else
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices);
if (cache->indexType == QVertexIndexVector::UnsignedInt)
- glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, (qint32 *)cache->indices);
+ funcs.glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, (qint32 *)cache->indices);
else
- glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, (qint16 *)cache->indices);
+ funcs.glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, (qint16 *)cache->indices);
#endif
} else {
@@ -904,9 +902,9 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path)
prepareForDraw(currentBrush.isOpaque());
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertices.constData());
if (funcs.hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint))
- glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.data());
+ funcs.glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.data());
else
- glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_SHORT, polys.indices.data());
+ funcs.glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_SHORT, polys.indices.data());
} else {
// We can't handle big, concave painter paths with OpenGL without stencil buffer.
qWarning("Painter path exceeds +/-32767 pixels.");
@@ -920,24 +918,24 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path)
fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill());
- glStencilMask(0xff);
- glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+ funcs.glStencilMask(0xff);
+ funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
if (q->state()->clipTestEnabled) {
// Pass when high bit is set, replace stencil value with current clip
- glStencilFunc(GL_NOTEQUAL, q->state()->currentClip, GL_STENCIL_HIGH_BIT);
+ funcs.glStencilFunc(GL_NOTEQUAL, q->state()->currentClip, GL_STENCIL_HIGH_BIT);
} else if (path.hasWindingFill()) {
// Pass when any bit is set, replace stencil value with 0
- glStencilFunc(GL_NOTEQUAL, 0, 0xff);
+ funcs.glStencilFunc(GL_NOTEQUAL, 0, 0xff);
} else {
// Pass when high bit is set, replace stencil value with 0
- glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);
+ funcs.glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);
}
prepareForDraw(currentBrush.isOpaque());
// Stencil the brush onto the dest buffer
composite(vertexCoordinateArray.boundingRect());
- glStencilMask(0);
+ funcs.glStencilMask(0);
updateClipScissorTest();
}
}
@@ -954,16 +952,16 @@ void QOpenGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data,
Q_ASSERT(count || stops);
// qDebug("QOpenGL2PaintEngineExPrivate::fillStencilWithVertexArray()");
- glStencilMask(0xff); // Enable stencil writes
+ funcs.glStencilMask(0xff); // Enable stencil writes
if (dirtyStencilRegion.intersects(currentScissorBounds)) {
QVector<QRect> clearRegion = dirtyStencilRegion.intersected(currentScissorBounds).rects();
- glClearStencil(0); // Clear to zero
+ funcs.glClearStencil(0); // Clear to zero
for (int i = 0; i < clearRegion.size(); ++i) {
#ifndef QT_GL_NO_SCISSOR_TEST
setScissor(clearRegion.at(i));
#endif
- glClear(GL_STENCIL_BUFFER_BIT);
+ funcs.glClear(GL_STENCIL_BUFFER_BIT);
}
dirtyStencilRegion -= currentScissorBounds;
@@ -973,23 +971,23 @@ void QOpenGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data,
#endif
}
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Disable color writes
+ funcs.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Disable color writes
useSimpleShader();
- glEnable(GL_STENCIL_TEST); // For some reason, this has to happen _after_ the simple shader is use()'d
+ funcs.glEnable(GL_STENCIL_TEST); // For some reason, this has to happen _after_ the simple shader is use()'d
if (mode == WindingFillMode) {
Q_ASSERT(stops && !count);
if (q->state()->clipTestEnabled) {
// Flatten clip values higher than current clip, and set high bit to match current clip
- glStencilFunc(GL_LEQUAL, GL_STENCIL_HIGH_BIT | q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
- glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+ funcs.glStencilFunc(GL_LEQUAL, GL_STENCIL_HIGH_BIT | q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
+ funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
composite(bounds);
- glStencilFunc(GL_EQUAL, GL_STENCIL_HIGH_BIT, GL_STENCIL_HIGH_BIT);
+ funcs.glStencilFunc(GL_EQUAL, GL_STENCIL_HIGH_BIT, GL_STENCIL_HIGH_BIT);
} else if (!stencilClean) {
// Clear stencil buffer within bounding rect
- glStencilFunc(GL_ALWAYS, 0, 0xff);
- glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
+ funcs.glStencilFunc(GL_ALWAYS, 0, 0xff);
+ funcs.glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
composite(bounds);
}
@@ -997,44 +995,44 @@ void QOpenGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data,
funcs.glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP);
// Dec. for back-facing "holes"
funcs.glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP);
- glStencilMask(~GL_STENCIL_HIGH_BIT);
+ funcs.glStencilMask(~GL_STENCIL_HIGH_BIT);
drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN);
if (q->state()->clipTestEnabled) {
// Clear high bit of stencil outside of path
- glStencilFunc(GL_EQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
- glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
- glStencilMask(GL_STENCIL_HIGH_BIT);
+ funcs.glStencilFunc(GL_EQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
+ funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+ funcs.glStencilMask(GL_STENCIL_HIGH_BIT);
composite(bounds);
}
} else if (mode == OddEvenFillMode) {
- glStencilMask(GL_STENCIL_HIGH_BIT);
- glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit
+ funcs.glStencilMask(GL_STENCIL_HIGH_BIT);
+ funcs.glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit
drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN);
} else { // TriStripStrokeFillMode
Q_ASSERT(count && !stops); // tristrips generated directly, so no vertexArray or stops
- glStencilMask(GL_STENCIL_HIGH_BIT);
+ funcs.glStencilMask(GL_STENCIL_HIGH_BIT);
#if 0
- glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit
+ funcs.glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, count);
+ funcs.glDrawArrays(GL_TRIANGLE_STRIP, 0, count);
#else
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ funcs.glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
if (q->state()->clipTestEnabled) {
- glStencilFunc(GL_LEQUAL, q->state()->currentClip | GL_STENCIL_HIGH_BIT,
- ~GL_STENCIL_HIGH_BIT);
+ funcs.glStencilFunc(GL_LEQUAL, q->state()->currentClip | GL_STENCIL_HIGH_BIT,
+ ~GL_STENCIL_HIGH_BIT);
} else {
- glStencilFunc(GL_ALWAYS, GL_STENCIL_HIGH_BIT, 0xff);
+ funcs.glStencilFunc(GL_ALWAYS, GL_STENCIL_HIGH_BIT, 0xff);
}
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, count);
+ funcs.glDrawArrays(GL_TRIANGLE_STRIP, 0, count);
#endif
}
// Enable color writes & disable stencil writes
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ funcs.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
/*
@@ -1050,22 +1048,22 @@ void QOpenGL2PaintEngineExPrivate::resetClipIfNeeded()
Q_Q(QOpenGL2PaintEngineEx);
useSimpleShader();
- glEnable(GL_STENCIL_TEST);
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ funcs.glEnable(GL_STENCIL_TEST);
+ funcs.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
QRectF bounds = q->state()->matrix.inverted().mapRect(QRectF(0, 0, width, height));
QOpenGLRect rect(bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
// Set high bit on clip region
- glStencilFunc(GL_LEQUAL, q->state()->currentClip, 0xff);
- glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT);
- glStencilMask(GL_STENCIL_HIGH_BIT);
+ funcs.glStencilFunc(GL_LEQUAL, q->state()->currentClip, 0xff);
+ funcs.glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT);
+ funcs.glStencilMask(GL_STENCIL_HIGH_BIT);
composite(rect);
// Reset clipping to 1 and everything else to zero
- glStencilFunc(GL_NOTEQUAL, 0x01, GL_STENCIL_HIGH_BIT);
- glStencilOp(GL_ZERO, GL_REPLACE, GL_REPLACE);
- glStencilMask(0xff);
+ funcs.glStencilFunc(GL_NOTEQUAL, 0x01, GL_STENCIL_HIGH_BIT);
+ funcs.glStencilOp(GL_ZERO, GL_REPLACE, GL_REPLACE);
+ funcs.glStencilMask(0xff);
composite(rect);
q->state()->currentClip = 1;
@@ -1073,8 +1071,8 @@ void QOpenGL2PaintEngineExPrivate::resetClipIfNeeded()
maxClip = 1;
- glStencilMask(0x0);
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ funcs.glStencilMask(0x0);
+ funcs.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
bool QOpenGL2PaintEngineExPrivate::prepareForCachedGlyphDraw(const QFontEngineGlyphCache &cache)
@@ -1107,9 +1105,9 @@ bool QOpenGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
|| (q->state()->composition_mode == QPainter::CompositionMode_SourceOver
&& srcPixelsAreOpaque && !stateHasOpacity))
{
- glDisable(GL_BLEND);
+ funcs.glDisable(GL_BLEND);
} else {
- glEnable(GL_BLEND);
+ funcs.glEnable(GL_BLEND);
}
QOpenGLEngineShaderManager::OpacityMode opacityMode;
@@ -1159,7 +1157,7 @@ void QOpenGL2PaintEngineExPrivate::composite(const QOpenGLRect& boundingRect)
{
setCoords(staticVertexCoordinateArray, boundingRect);
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, staticVertexCoordinateArray);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ funcs.glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
// Draws the vertex array as a set of <vertexArrayStops.size()> triangle fans.
@@ -1177,7 +1175,7 @@ void QOpenGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stop
for (int i=previousStop; i<stop; ++i)
qDebug(" %02d: [%.2f, %.2f]", i, vertexArray.data()[i].x, vertexArray.data()[i].y);
*/
- glDrawArrays(primitive, previousStop, stop - previousStop);
+ funcs.glDrawArrays(primitive, previousStop, stop - previousStop);
previousStop = stop;
}
}
@@ -1269,7 +1267,7 @@ void QOpenGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &p
if (opaque) {
prepareForDraw(opaque);
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, stroker.vertices());
- glDrawArrays(GL_TRIANGLE_STRIP, 0, stroker.vertexCount() / 2);
+ funcs.glDrawArrays(GL_TRIANGLE_STRIP, 0, stroker.vertexCount() / 2);
// QBrush b(Qt::green);
// d->setBrush(&b);
@@ -1292,16 +1290,16 @@ void QOpenGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &p
fillStencilWithVertexArray(stroker.vertices(), stroker.vertexCount() / 2,
0, 0, bounds, QOpenGL2PaintEngineExPrivate::TriStripStrokeFillMode);
- glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+ funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
// Pass when any bit is set, replace stencil value with 0
- glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);
+ funcs.glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);
prepareForDraw(false);
// Stencil the brush onto the dest buffer
composite(bounds);
- glStencilMask(0);
+ funcs.glStencilMask(0);
updateClipScissorTest();
}
@@ -1336,11 +1334,12 @@ void QOpenGL2PaintEngineEx::renderHintsChanged()
#ifndef QT_OPENGL_ES_2
if (!QOpenGLContext::currentContext()->isES()) {
+ Q_D(QOpenGL2PaintEngineEx);
if ((state()->renderHints & QPainter::Antialiasing)
|| (state()->renderHints & QPainter::HighQualityAntialiasing))
- glEnable(GL_MULTISAMPLE);
+ d->funcs.glEnable(GL_MULTISAMPLE);
else
- glDisable(GL_MULTISAMPLE);
+ d->funcs.glDisable(GL_MULTISAMPLE);
}
#endif // QT_OPENGL_ES_2
@@ -1461,7 +1460,7 @@ bool QOpenGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, co
d->transferMode(ImageDrawingMode);
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
- glBindTexture(GL_TEXTURE_2D, textureId);
+ d->funcs.glBindTexture(GL_TEXTURE_2D, textureId);
QOpenGLRect srcRect(src.left(), src.bottom(), src.right(), src.top());
@@ -1720,15 +1719,15 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
if (elementIndicesVBOId == 0)
- glGenBuffers(1, &elementIndicesVBOId);
+ funcs.glGenBuffers(1, &elementIndicesVBOId);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementIndices.size() * sizeof(GLushort),
- elementIndices.constData(), GL_STATIC_DRAW);
+ funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId);
+ funcs.glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementIndices.size() * sizeof(GLushort),
+ elementIndices.constData(), GL_STATIC_DRAW);
#endif
} else {
#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId);
+ funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId);
#endif
}
@@ -1774,8 +1773,8 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
opacityUniformDirty = true;
}
- glEnable(GL_BLEND);
- glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR);
+ funcs.glEnable(GL_BLEND);
+ funcs.glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR);
funcs.glBlendColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
} else {
// Other brush styles need two passes.
@@ -1790,17 +1789,17 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
compositionModeDirty = false; // I can handle this myself, thank you very much
prepareForCachedGlyphDraw(*cache);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
+ funcs.glEnable(GL_BLEND);
+ funcs.glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
- glBindTexture(GL_TEXTURE_2D, cache->texture());
+ funcs.glBindTexture(GL_TEXTURE_2D, cache->texture());
updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
- glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);
+ funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);
#else
- glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data());
+ funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data());
#endif
shaderManager->setMaskType(QOpenGLEngineShaderManager::SubPixelMaskPass2);
@@ -1814,8 +1813,8 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
compositionModeDirty = false;
prepareForCachedGlyphDraw(*cache);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE);
+ funcs.glEnable(GL_BLEND);
+ funcs.glBlendFunc(GL_ONE, GL_ONE);
}
compositionModeDirty = true;
} else if (glyphFormat == QFontEngine::Format_ARGB) {
@@ -1839,27 +1838,27 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
if (lastMaskTextureUsed != cache->texture()) {
- glBindTexture(GL_TEXTURE_2D, cache->texture());
+ funcs.glBindTexture(GL_TEXTURE_2D, cache->texture());
lastMaskTextureUsed = cache->texture();
}
if (cache->filterMode() != filterMode) {
if (filterMode == QOpenGLTextureGlyphCache::Linear) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ funcs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ funcs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ funcs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ funcs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
cache->setFilterMode(filterMode);
}
}
#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
- glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);
+ funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#else
- glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data());
+ funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data());
#endif
}
@@ -1960,7 +1959,7 @@ void QOpenGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFra
shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::PatternColor), col);
}
- glDrawArrays(GL_TRIANGLES, 0, 6 * fragmentCount);
+ funcs.glDrawArrays(GL_TRIANGLES, 0, 6 * fragmentCount);
}
bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
@@ -2005,15 +2004,15 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->shaderManager = new QOpenGLEngineShaderManager(d->ctx);
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
+ d->funcs.glDisable(GL_STENCIL_TEST);
+ d->funcs.glDisable(GL_DEPTH_TEST);
+ d->funcs.glDisable(GL_SCISSOR_TEST);
d->glyphCacheFormat = QFontEngine::Format_A8;
#ifndef QT_OPENGL_ES_2
if (!QOpenGLContext::currentContext()->isES()) {
- glDisable(GL_MULTISAMPLE);
+ d->funcs.glDisable(GL_MULTISAMPLE);
d->glyphCacheFormat = QFontEngine::Format_A32;
d->multisamplingAlwaysEnabled = false;
} else
@@ -2071,7 +2070,7 @@ void QOpenGL2PaintEngineEx::ensureActive()
d->device->ensureActiveTarget();
d->transferMode(BrushDrawingMode);
- glViewport(0, 0, d->width, d->height);
+ d->funcs.glViewport(0, 0, d->width, d->height);
d->needsSync = false;
d->lastMaskTextureUsed = 0;
d->shaderManager->setDirty();
@@ -2086,11 +2085,11 @@ void QOpenGL2PaintEngineExPrivate::updateClipScissorTest()
{
Q_Q(QOpenGL2PaintEngineEx);
if (q->state()->clipTestEnabled) {
- glEnable(GL_STENCIL_TEST);
- glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
+ funcs.glEnable(GL_STENCIL_TEST);
+ funcs.glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
} else {
- glDisable(GL_STENCIL_TEST);
- glStencilFunc(GL_ALWAYS, 0, 0xff);
+ funcs.glDisable(GL_STENCIL_TEST);
+ funcs.glStencilFunc(GL_ALWAYS, 0, 0xff);
}
#ifdef QT_GL_NO_SCISSOR_TEST
@@ -2112,9 +2111,9 @@ void QOpenGL2PaintEngineExPrivate::updateClipScissorTest()
currentScissorBounds = bounds;
if (bounds == QRect(0, 0, width, height)) {
- glDisable(GL_SCISSOR_TEST);
+ funcs.glDisable(GL_SCISSOR_TEST);
} else {
- glEnable(GL_SCISSOR_TEST);
+ funcs.glEnable(GL_SCISSOR_TEST);
setScissor(bounds);
}
#endif
@@ -2130,7 +2129,7 @@ void QOpenGL2PaintEngineExPrivate::setScissor(const QRect &rect)
}
const int height = rect.height();
- glScissor(left, bottom, width, height);
+ funcs.glScissor(left, bottom, width, height);
}
void QOpenGL2PaintEngineEx::clipEnabledChanged()
@@ -2149,10 +2148,10 @@ void QOpenGL2PaintEngineExPrivate::clearClip(uint value)
{
dirtyStencilRegion -= currentScissorBounds;
- glStencilMask(0xff);
- glClearStencil(value);
- glClear(GL_STENCIL_BUFFER_BIT);
- glStencilMask(0x0);
+ funcs.glStencilMask(0xff);
+ funcs.glClearStencil(value);
+ funcs.glClear(GL_STENCIL_BUFFER_BIT);
+ funcs.glStencilMask(0x0);
q->state()->needsClipBufferClear = false;
}
@@ -2180,15 +2179,15 @@ void QOpenGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, uint value
clearClip(1);
if (path.isEmpty()) {
- glEnable(GL_STENCIL_TEST);
- glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT);
+ funcs.glEnable(GL_STENCIL_TEST);
+ funcs.glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT);
return;
}
if (q->state()->clipTestEnabled)
- glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
+ funcs.glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
else
- glStencilFunc(GL_ALWAYS, 0, 0xff);
+ funcs.glStencilFunc(GL_ALWAYS, 0, 0xff);
vertexCoordinateArray.clear();
vertexCoordinateArray.addPath(path, inverseScale, false);
@@ -2196,39 +2195,39 @@ void QOpenGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, uint value
if (!singlePass)
fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill());
- glColorMask(false, false, false, false);
- glEnable(GL_STENCIL_TEST);
+ funcs.glColorMask(false, false, false, false);
+ funcs.glEnable(GL_STENCIL_TEST);
useSimpleShader();
if (singlePass) {
// Under these conditions we can set the new stencil value in a single
// pass, by using the current value and the "new value" as the toggles
- glStencilFunc(GL_LEQUAL, referenceClipValue, ~GL_STENCIL_HIGH_BIT);
- glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT);
- glStencilMask(value ^ referenceClipValue);
+ funcs.glStencilFunc(GL_LEQUAL, referenceClipValue, ~GL_STENCIL_HIGH_BIT);
+ funcs.glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT);
+ funcs.glStencilMask(value ^ referenceClipValue);
drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN);
} else {
- glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
- glStencilMask(0xff);
+ funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+ funcs.glStencilMask(0xff);
if (!q->state()->clipTestEnabled && path.hasWindingFill()) {
// Pass when any clip bit is set, set high bit
- glStencilFunc(GL_NOTEQUAL, GL_STENCIL_HIGH_BIT, ~GL_STENCIL_HIGH_BIT);
+ funcs.glStencilFunc(GL_NOTEQUAL, GL_STENCIL_HIGH_BIT, ~GL_STENCIL_HIGH_BIT);
composite(vertexCoordinateArray.boundingRect());
}
// Pass when high bit is set, replace stencil value with new clip value
- glStencilFunc(GL_NOTEQUAL, value, GL_STENCIL_HIGH_BIT);
+ funcs.glStencilFunc(GL_NOTEQUAL, value, GL_STENCIL_HIGH_BIT);
composite(vertexCoordinateArray.boundingRect());
}
- glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT);
- glStencilMask(0);
+ funcs.glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT);
+ funcs.glStencilMask(0);
- glColorMask(true, true, true, true);
+ funcs.glColorMask(true, true, true, true);
}
void QOpenGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op)
@@ -2384,7 +2383,7 @@ void QOpenGL2PaintEngineEx::setState(QPainterState *new_state)
if (old_state == s || old_state->clipChanged) {
if (old_state && old_state != s && old_state->canRestoreClip) {
d->updateClipScissorTest();
- glDepthFunc(GL_LEQUAL);
+ d->funcs.glDepthFunc(GL_LEQUAL);
} else {
d->regenerateClip();
}