diff options
author | David Boddie <dboddie@trolltech.com> | 2010-05-19 09:33:21 (GMT) |
---|---|---|
committer | David Boddie <dboddie@trolltech.com> | 2010-05-19 09:33:21 (GMT) |
commit | ebe28bdd77ca615c47ebf6b41e34aee0c154fcf9 (patch) | |
tree | a1aa1578f798bae0cc23c32656134628bf5af788 /src/opengl | |
parent | 109024630cbf577d6f6bcb10ea3ac6272113b79e (diff) | |
parent | 28b894f65c5aba01d5ee80c20f617478faaee7e7 (diff) | |
download | Qt-ebe28bdd77ca615c47ebf6b41e34aee0c154fcf9.zip Qt-ebe28bdd77ca615c47ebf6b41e34aee0c154fcf9.tar.gz Qt-ebe28bdd77ca615c47ebf6b41e34aee0c154fcf9.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h | 4 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 1 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 90 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h | 3 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtriangulatingstroker.cpp | 5 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtriangulatingstroker_p.h | 1 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtriangulator.cpp | 12 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 79 | ||||
-rw-r--r-- | src/opengl/qgl.h | 1 | ||||
-rw-r--r-- | src/opengl/qgl_egl.cpp | 20 | ||||
-rw-r--r-- | src/opengl/qgl_p.h | 8 | ||||
-rw-r--r-- | src/opengl/qglpaintdevice.cpp | 5 | ||||
-rw-r--r-- | src/opengl/qpaintengine_opengl.cpp | 5 |
13 files changed, 162 insertions, 72 deletions
diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h index adc69ee..46029b9 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h @@ -100,8 +100,10 @@ class QGL2PEXVertexArray { public: QGL2PEXVertexArray() : + vertexArray(0), vertexArrayStops(0), maxX(-2e10), maxY(-2e10), minX(2e10), minY(2e10), - boundingRectDirty(true) {} + boundingRectDirty(true) + { } inline void addRect(const QRectF &rect) { diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 6ba0c42..0a046dc 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -177,6 +177,7 @@ public: ctx(0), useSystemClip(true), elementIndicesVBOId(0), + opacityArray(0), snapToPixelGrid(false), addOffset(false), nativePaintingActive(false), diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 994c1c9..410cf21 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -42,6 +42,10 @@ #include "qtextureglyphcache_gl_p.h" #include "qpaintengineex_opengl2_p.h" +#if defined QT_OPENGL_ES_2 && !defined(QT_NO_EGL) +#include "private/qeglcontext_p.h" +#endif + QT_BEGIN_NAMESPACE #ifdef Q_WS_WIN @@ -49,12 +53,19 @@ extern Q_GUI_EXPORT bool qt_cleartype_enabled; #endif QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix) - : QTextureGlyphCache(type, matrix) + : QImageTextureGlyphCache(type, matrix) , ctx(context) , m_width(0) , m_height(0) { - glGenFramebuffers(1, &m_fbo); + // broken FBO readback is a bug in the SGX 1.3 and 1.4 drivers for the N900 where + // copying between FBO's is broken if the texture is either GL_ALPHA or POT. The + // workaround is to use a system-memory copy of the glyph cache for this device. + // Switching to NPOT and GL_RGBA would both cost a lot more graphics memory and + // be slower, so that is not desireable. + if (!ctx->d_ptr->workaround_brokenFBOReadBack) + glGenFramebuffers(1, &m_fbo); + connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)), SLOT(contextDestroyed(const QGLContext*))); } @@ -63,7 +74,9 @@ QGLTextureGlyphCache::~QGLTextureGlyphCache() { if (ctx) { QGLShareContextScope scope(ctx); - glDeleteFramebuffers(1, &m_fbo); + + if (!ctx->d_ptr->workaround_brokenFBOReadBack) + glDeleteFramebuffers(1, &m_fbo); if (m_width || m_height) glDeleteTextures(1, &m_texture); @@ -72,6 +85,18 @@ QGLTextureGlyphCache::~QGLTextureGlyphCache() void QGLTextureGlyphCache::createTextureData(int width, int height) { + // create in QImageTextureGlyphCache baseclass is meant to be called + // only to create the initial image and does not preserve the content, + // so we don't call when this function is called from resize. + if (ctx->d_ptr->workaround_brokenFBOReadBack && image().isNull()) + QImageTextureGlyphCache::createTextureData(width, height); + + // Make the lower glyph texture size 16 x 16. + if (width < 16) + width = 16; + if (height < 16) + height = 16; + glGenTextures(1, &m_texture); glBindTexture(GL_TEXTURE_2D, m_texture); @@ -93,14 +118,28 @@ void QGLTextureGlyphCache::createTextureData(int width, int height) void QGLTextureGlyphCache::resizeTextureData(int width, int height) { - // ### the QTextureGlyphCache API needs to be reworked to allow - // ### resizeTextureData to fail - int oldWidth = m_width; int oldHeight = m_height; + // Make the lower glyph texture size 16 x 16. + if (width < 16) + width = 16; + if (height < 16) + height = 16; + GLuint oldTexture = m_texture; createTextureData(width, height); + + if (ctx->d_ptr->workaround_brokenFBOReadBack) { + QImageTextureGlyphCache::resizeTextureData(width, height); + Q_ASSERT(image().depth() == 8); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); + glDeleteTextures(1, &oldTexture); + return; + } + + // ### the QTextureGlyphCache API needs to be reworked to allow + // ### resizeTextureData to fail glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo); @@ -159,20 +198,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) glBindTexture(GL_TEXTURE_2D, m_texture); -#ifdef QT_OPENGL_ES_2 - QDataBuffer<uchar> buffer(4*oldWidth*oldHeight); - buffer.resize(4*oldWidth*oldHeight); - glReadPixels(0, 0, oldWidth, oldHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); - - // do an in-place conversion from GL_RGBA to GL_ALPHA - for (int i=0; i<oldWidth*oldHeight; ++i) - buffer.data()[i] = buffer.at(4*i + 3); - - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, - GL_ALPHA, GL_UNSIGNED_BYTE, buffer.data()); -#else glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight); -#endif glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, 0); @@ -187,6 +213,21 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) { + if (ctx->d_ptr->workaround_brokenFBOReadBack) { + QImageTextureGlyphCache::fillTexture(c, glyph); + + glBindTexture(GL_TEXTURE_2D, m_texture); + const QImage &texture = image(); + const uchar *bits = texture.constBits(); + bits += c.y * texture.bytesPerLine() + c.x; + for (int i=0; i<c.h; ++i) { + glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits); + bits += texture.bytesPerLine(); + } + + return; + } + QImage mask = textureMapForGlyph(glyph); const int maskWidth = mask.width(); const int maskHeight = mask.height(); @@ -235,17 +276,6 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) } } -int QGLTextureGlyphCache::glyphMargin() const -{ -#if defined(Q_WS_MAC) - return 2; -#elif defined (Q_WS_X11) - return 0; -#else - return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0; -#endif -} - int QGLTextureGlyphCache::glyphPadding() const { return 1; diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h index 75c2bb1..6bcd655 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE class QGL2PaintEngineExPrivate; -class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QObject, public QTextureGlyphCache +class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QObject, public QImageTextureGlyphCache { Q_OBJECT public: @@ -72,7 +72,6 @@ public: virtual void createTextureData(int width, int height); virtual void resizeTextureData(int width, int height); virtual void fillTexture(const Coord &c, glyph_t glyph); - virtual int glyphMargin() const; virtual int glyphPadding() const; inline GLuint texture() const { return m_texture; } diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp index f677ce1..9bc099d 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp @@ -481,7 +481,8 @@ static void qdashprocessor_cubicTo(qreal, qreal, qreal, qreal, qreal, qreal, voi } QDashedStrokeProcessor::QDashedStrokeProcessor() - : m_dash_stroker(0), m_inv_scale(1) + : m_points(0), m_types(0), + m_dash_stroker(0), m_inv_scale(1) { m_dash_stroker.setMoveToHook(qdashprocessor_moveTo); m_dash_stroker.setLineToHook(qdashprocessor_lineTo); @@ -499,6 +500,8 @@ void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, c m_points.reset(); m_types.reset(); + m_points.reserve(path.elementCount()); + m_types.reserve(path.elementCount()); qreal width = qpen_widthf(pen); if (width == 0) diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h index 956d7cc..ab27ed6 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h @@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE class QTriangulatingStroker { public: + QTriangulatingStroker() : m_vertices(0) {} void process(const QVectorPath &path, const QPen &pen, const QRectF &clip); inline int vertexCount() const { return m_vertices.size(); } diff --git a/src/opengl/gl2paintengineex/qtriangulator.cpp b/src/opengl/gl2paintengineex/qtriangulator.cpp index ce917ff..df7cbc2 100644 --- a/src/opengl/gl2paintengineex/qtriangulator.cpp +++ b/src/opengl/gl2paintengineex/qtriangulator.cpp @@ -510,6 +510,7 @@ template <class T> class QMaxHeap { public: + QMaxHeap() : m_data(0) {} inline int size() const {return m_data.size();} inline bool empty() const {return m_data.isEmpty();} inline bool isEmpty() const {return m_data.isEmpty();} @@ -1299,7 +1300,8 @@ public: class ComplexToSimple { public: - inline ComplexToSimple(QTriangulator *parent) : m_parent(parent) { } + inline ComplexToSimple(QTriangulator *parent) : m_parent(parent), + m_edges(0), m_events(0), m_splits(0) { } void decompose(); private: struct Edge @@ -1412,7 +1414,7 @@ public: class SimpleToMonotone { public: - inline SimpleToMonotone(QTriangulator *parent) : m_parent(parent) { } + inline SimpleToMonotone(QTriangulator *parent) : m_parent(parent), m_edges(0), m_upperVertex(0) { } void decompose(); private: enum VertexType {MergeVertex, EndVertex, RegularVertex, StartVertex, SplitVertex}; @@ -1486,7 +1488,7 @@ public: int m_length; }; - inline QTriangulator() { } + inline QTriangulator() : m_vertices(0) { } // Call this only once. void initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix); @@ -2709,7 +2711,7 @@ void QTriangulator::SimpleToMonotone::monotoneDecomposition() return; Q_ASSERT(!m_edgeList.root); - QDataBuffer<QPair<int, int> > diagonals; + QDataBuffer<QPair<int, int> > diagonals(m_upperVertex.size()); int i = 0; for (int index = 1; index < m_edges.size(); ++index) { @@ -2853,7 +2855,7 @@ bool QTriangulator::SimpleToMonotone::CompareVertices::operator () (int i, int j void QTriangulator::MonotoneToTriangles::decompose() { QVector<quint32> result; - QDataBuffer<int> stack; + QDataBuffer<int> stack(m_parent->m_indices.size()); m_first = 0; // Require at least three more indices. while (m_first + 3 <= m_parent->m_indices.size()) { diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index cfacf26..922a96c 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1612,6 +1612,9 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) current_fbo = 0; default_fbo = 0; active_engine = 0; + workaround_needsFullClearOnEveryFrame = false; + workaround_brokenFBOReadBack = false; + workaroundsCached = false; for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) vertexAttributeArraysEnabledState[i] = false; } @@ -1723,7 +1726,6 @@ QGLTextureCache::QGLTextureCache() QGLTextureCache::~QGLTextureCache() { - Q_ASSERT(size() == 0); QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData); QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction); QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey); @@ -2773,23 +2775,27 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex /*! \since 4.4 - Draws the given texture, \a textureId, to the given target rectangle, - \a target, in OpenGL model space. The \a textureTarget should be a 2D - texture target. + This function supports the following use cases: + + \list + \i On OpenGL and OpenGL ES 1.x it draws the given texture, \a textureId, + to the given target rectangle, \a target, in OpenGL model space. The + \a textureTarget should be a 2D texture target. + \i On OpenGL and OpenGL ES 2.x, if a painter is active, not inside a + beginNativePainting / endNativePainting block, and uses the + engine with type QPaintEngine::OpenGL2, the function will draw the given + texture, \a textureId, to the given target rectangle, \a target, + respecting the current painter state. This will let you draw a texture + with the clip, transform, render hints, and composition mode set by the + painter. Note that the texture target needs to be GL_TEXTURE_2D for this + use case, and that this is the only supported use case under OpenGL ES 2.x. + \endlist - \note This function is not supported under OpenGL/ES 2.0. */ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) { -#ifndef QT_OPENGL_ES_2 -#ifdef QT_OPENGL_ES - if (textureTarget != GL_TEXTURE_2D) { - qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES"); - return; - } -#else - - if (d_ptr->active_engine && +#if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) + if (d_ptr->active_engine && d_ptr->active_engine->type() == QPaintEngine::OpenGL2) { QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine); if (!eng->isNativePaintingActive()) { @@ -2799,7 +2805,15 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text return; } } +#endif +#ifndef QT_OPENGL_ES_2 +#ifdef QT_OPENGL_ES + if (textureTarget != GL_TEXTURE_2D) { + qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES"); + return; + } +#else const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); GLint oldTexture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); @@ -2821,7 +2835,7 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text Q_UNUSED(target); Q_UNUSED(textureId); Q_UNUSED(textureTarget); - qWarning("drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES/2.0"); + qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine"); #endif } @@ -2836,14 +2850,26 @@ void QGLContext::drawTexture(const QRectF &target, QMacCompatGLuint textureId, Q /*! \since 4.4 - Draws the given texture at the given \a point in OpenGL model - space. The \a textureTarget should be a 2D texture target. + This function supports the following use cases: + + \list + \i By default it draws the given texture, \a textureId, + at the given \a point in OpenGL model space. The + \a textureTarget should be a 2D texture target. + \i If a painter is active, not inside a + beginNativePainting / endNativePainting block, and uses the + engine with type QPaintEngine::OpenGL2, the function will draw the given + texture, \a textureId, at the given \a point, + respecting the current painter state. This will let you draw a texture + with the clip, transform, render hints, and composition mode set by the + painter. Note that the texture target needs to be GL_TEXTURE_2D for this + use case. + \endlist - \note This function is not supported under OpenGL/ES. + \note This function is not supported under any version of OpenGL ES. */ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) { - // this would be ok on OpenGL ES 2.0, but currently we don't have a define for that #ifdef QT_OPENGL_ES Q_UNUSED(point); Q_UNUSED(textureId); @@ -2864,7 +2890,7 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); - if (d_ptr->active_engine && + if (d_ptr->active_engine && d_ptr->active_engine->type() == QPaintEngine::OpenGL2) { QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine); if (!eng->isNativePaintingActive()) { @@ -4911,11 +4937,8 @@ void QGLWidget::deleteTexture(QMacCompatGLuint id) /*! \since 4.4 - Draws the given texture, \a textureId to the given target rectangle, - \a target, in OpenGL model space. The \a textureTarget should be a 2D - texture target. - - Equivalent to the corresponding QGLContext::drawTexture(). + Calls the corresponding QGLContext::drawTexture() on + this widget's context. */ void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) { @@ -4935,10 +4958,8 @@ void QGLWidget::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QM /*! \since 4.4 - Draws the given texture, \a textureId, at the given \a point in OpenGL - model space. The \a textureTarget should be a 2D texture target. - - Equivalent to the corresponding QGLContext::drawTexture(). + Calls the corresponding QGLContext::drawTexture() on + this widget's context. */ void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) { diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 92a064f..f297009 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -431,6 +431,7 @@ private: friend class QGLFramebufferObjectPrivate; friend class QGLFBOGLPaintDevice; friend class QGLPaintDevice; + friend class QGLWidgetGLPaintDevice; friend class QX11GLPixmapData; friend class QX11GLSharedContexts; private: diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 0fbbbf9..44e8ae9 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -185,8 +185,26 @@ void QGLContext::makeCurrent() return; } - if (d->eglContext->makeCurrent(d->eglSurfaceForDevice())) + if (d->eglContext->makeCurrent(d->eglSurfaceForDevice())) { QGLContextPrivate::setCurrentContext(this); + if (!d->workaroundsCached) { + d->workaroundsCached = true; + const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); + if (strstr(renderer, "SGX") || strstr(renderer, "MBX")) { + // PowerVR MBX/SGX chips needs to clear all buffers when starting to render + // a new frame, otherwise there will be a performance penalty to pay for + // each frame. + d->workaround_needsFullClearOnEveryFrame = true; + + // Older PowerVR SGX drivers (like the one in the N900) have a + // bug which prevents glCopyTexSubImage2D() to work with a POT + // or GL_ALPHA texture bound to an FBO. The only way to + // identify that driver is to check the EGL version number for it. + if (strstr(eglQueryString(d->eglContext->display(), EGL_VERSION), "1.3")) + d->workaround_brokenFBOReadBack = true; + } + } + } } void QGLContext::doneCurrent() diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index f19e394..d92f963 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -345,7 +345,7 @@ public: HDC hbitmap_hdc; #endif #ifndef QT_NO_EGL - bool ownsEglContext; + uint ownsEglContext : 1; QEglContext *eglContext; EGLSurface eglSurface; void destroyEglSurfaceForDevice(); @@ -382,6 +382,12 @@ public: 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; + uint workaround_brokenFBOReadBack : 1; + uint workaroundsCached : 1; + QPaintDevice *paintDevice; QColor transpColor; QGLContext *q_ptr; diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp index e874e85..e1dcbfd 100644 --- a/src/opengl/qglpaintdevice.cpp +++ b/src/opengl/qglpaintdevice.cpp @@ -175,7 +175,10 @@ void QGLWidgetGLPaintDevice::beginPaint() float alpha = c.alphaF(); glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha); } - glClear(GL_COLOR_BUFFER_BIT); + if (context()->d_func()->workaround_needsFullClearOnEveryFrame) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + else + glClear(GL_COLOR_BUFFER_BIT); } } diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 306fd8b..08a50cb 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -668,6 +668,7 @@ public: , last_created_state(0) , shader_ctx(0) , grad_palette(0) + , tess_points(0) , drawable_texture(0) , ref_cleaner(this) {} @@ -1950,6 +1951,8 @@ void QOpenGLPaintEnginePrivate::pathToVertexArrays(const QPainterPath &path) void QOpenGLPaintEnginePrivate::drawVertexArrays() { + if (tess_points_stops.count() == 0) + return; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_DOUBLE, 0, tess_points.data()); int previous_stop = 0; @@ -3947,7 +3950,7 @@ void QOpenGLPaintEnginePrivate::strokeLines(const QPainterPath &path) enableClipping(); } -extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp +Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp void QOpenGLPaintEnginePrivate::strokePath(const QPainterPath &path, bool use_cache) { |