summaryrefslogtreecommitdiffstats
path: root/src/opengl/qpaintengine_opengl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/qpaintengine_opengl.cpp')
-rw-r--r--src/opengl/qpaintengine_opengl.cpp46
1 files changed, 33 insertions, 13 deletions
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index c823187..57918d0 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -108,6 +108,10 @@ static bool DEBUG_TEMP_FLAG;
#define DEBUG_ONCE_STR(str) DEBUG_ONCE qDebug() << (str);
#endif
+#ifdef Q_WS_X11
+static bool qt_nvidiaFboNeedsFinish = false;
+#endif
+
static inline void qt_glColor4ubv(unsigned char *col)
{
glColor4f(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, col[3]/255.0f);
@@ -423,7 +427,7 @@ inline void QGLOffscreen::release()
#ifdef Q_WS_X11
// workaround for bug in nvidia driver versions 9x.xx
- if (QGLExtensions::nvidiaFboNeedsFinish)
+ if (qt_nvidiaFboNeedsFinish)
glFinish();
#endif
@@ -477,7 +481,7 @@ inline QGLContext *QGLOffscreen::context() const
bool QGLOffscreen::isSupported()
{
- return (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject); // for fbo
+ return (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject); // for fbo
}
struct QDrawQueueItem
@@ -1266,7 +1270,7 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
for (int j = 0; j < 4; ++j)
d->mv_matrix[i][j] = (i == j ? qreal(1) : qreal(0));
- bool has_frag_program = (QGLExtensions::glExtensions & QGLExtensions::FragmentProgram)
+ bool has_frag_program = (QGLExtensions::glExtensions() & QGLExtensions::FragmentProgram)
&& (pdev->devType() != QInternal::Pixmap);
QGLContext *ctx = const_cast<QGLContext *>(d->device->context());
@@ -1279,11 +1283,27 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
has_frag_program = qt_resolve_frag_program_extensions(ctx) && qt_resolve_version_1_3_functions(ctx);
d->use_stencil_method = d->device->format().stencil()
- && (QGLExtensions::glExtensions & QGLExtensions::StencilWrap);
+ && (QGLExtensions::glExtensions() & QGLExtensions::StencilWrap);
if (d->device->format().directRendering()
- && (d->use_stencil_method && QGLExtensions::glExtensions & QGLExtensions::StencilTwoSide))
+ && (d->use_stencil_method && QGLExtensions::glExtensions() & QGLExtensions::StencilTwoSide))
d->has_stencil_face_ext = qt_resolve_stencil_face_extension(ctx);
+#ifdef Q_WS_X11
+ static bool nvidia_workaround_needs_init = true;
+ if (nvidia_workaround_needs_init) {
+ // nvidia 9x.xx unix drivers contain a bug which requires us to
+ // call glFinish before releasing an fbo to avoid painting
+ // artifacts
+ const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION)));
+ const int pos = versionString.indexOf("NVIDIA");
+ if (pos >= 0) {
+ const float nvidiaDriverVersion = versionString.mid(pos + strlen("NVIDIA")).toFloat();
+ qt_nvidiaFboNeedsFinish = nvidiaDriverVersion >= 90.0 && nvidiaDriverVersion < 100.0;
+ }
+ nvidia_workaround_needs_init = false;
+ }
+#endif
+
#ifndef QT_OPENGL_ES
if (!ctx->d_ptr->internal_context) {
glGetDoublev(GL_PROJECTION_MATRIX, &d->projection_matrix[0][0]);
@@ -1333,10 +1353,10 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
- if (QGLExtensions::glExtensions & QGLExtensions::SampleBuffers)
+ if (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers)
glDisable(GL_MULTISAMPLE);
glDisable(GL_TEXTURE_2D);
- if (QGLExtensions::glExtensions & QGLExtensions::TextureRectangle)
+ if (QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
glDisable(GL_TEXTURE_RECTANGLE_NV);
glDisable(GL_STENCIL_TEST);
glDisable(GL_CULL_FACE);
@@ -1534,7 +1554,7 @@ void QOpenGLPaintEnginePrivate::updateGradient(const QBrush &brush, const QRectF
#ifdef QT_OPENGL_ES
Q_UNUSED(brush);
#else
- bool has_mirrored_repeat = QGLExtensions::glExtensions & QGLExtensions::MirroredRepeat;
+ bool has_mirrored_repeat = QGLExtensions::glExtensions() & QGLExtensions::MirroredRepeat;
Qt::BrushStyle style = brush.style();
QTransform m = brush.transform();
@@ -2098,7 +2118,7 @@ static inline bool needsEmulation(Qt::BrushStyle style)
{
return !(style == Qt::SolidPattern
|| (style == Qt::LinearGradientPattern
- && (QGLExtensions::glExtensions & QGLExtensions::MirroredRepeat)));
+ && (QGLExtensions::glExtensions() & QGLExtensions::MirroredRepeat)));
}
void QOpenGLPaintEnginePrivate::updateUseEmulation()
@@ -2420,12 +2440,12 @@ void QOpenGLPaintEngine::updateRenderHints(QPainter::RenderHints hints)
d->high_quality_antialiasing = true;
} else {
d->high_quality_antialiasing = false;
- if (QGLExtensions::glExtensions & QGLExtensions::SampleBuffers)
+ if (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers)
glEnable(GL_MULTISAMPLE);
}
} else {
d->high_quality_antialiasing = false;
- if (QGLExtensions::glExtensions & QGLExtensions::SampleBuffers)
+ if (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers)
glDisable(GL_MULTISAMPLE);
}
@@ -2435,14 +2455,14 @@ void QOpenGLPaintEngine::updateRenderHints(QPainter::RenderHints hints)
if (!d->offscreen.isValid()) {
DEBUG_ONCE_STR("Unable to initialize offscreen, disabling high quality antialiasing");
d->high_quality_antialiasing = false;
- if (QGLExtensions::glExtensions & QGLExtensions::SampleBuffers)
+ if (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers)
glEnable(GL_MULTISAMPLE);
}
}
d->has_antialiasing = d->high_quality_antialiasing
|| ((hints & QPainter::Antialiasing)
- && (QGLExtensions::glExtensions & QGLExtensions::SampleBuffers));
+ && (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers));
}