diff options
Diffstat (limited to 'src/opengl/qpaintengine_opengl.cpp')
-rw-r--r-- | src/opengl/qpaintengine_opengl.cpp | 46 |
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)); } |