diff options
author | Gunnar Sletta <gunnar.sletta@digia.com> | 2013-10-30 14:09:18 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-30 15:18:33 +0100 |
commit | 4a7f1326e3d342148a4a9147505a4d8d531b4a06 (patch) | |
tree | 7194f7b696b264e319c3fd3671fc074a7cc25270 /src | |
parent | 388fc07cf28417f6e755ad8a105a71aa55ab13c8 (diff) |
Work around Nouveau driver bugs
Change-Id: I25311a2bd88f41087352e0a43ba505f4e27b7e85
Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/particles/qquickimageparticle.cpp | 6 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 26 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext.cpp | 7 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext_p.h | 5 |
4 files changed, 37 insertions, 7 deletions
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp index fa828d7b63..036dfb901e 100644 --- a/src/particles/qquickimageparticle.cpp +++ b/src/particles/qquickimageparticle.cpp @@ -1385,6 +1385,12 @@ void QQuickImageParticle::finishBuildParticleNodes() } #endif +#ifdef Q_OS_LINUX + // Nouveau drivers can potentially freeze a machine entirely when taking the point-sprite path. + if (perfLevel < Deformable && strstr((char *) glGetString(GL_VENDOR), "nouveau")) + perfLevel = Deformable; +#endif + if (perfLevel >= Colored && !m_color.isValid()) m_color = QColor(Qt::white);//Hidden default, but different from unset diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 8514203f57..7a62dccc0f 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -1889,7 +1889,14 @@ void Renderer::renderMergedBatch(const Batch *batch) updateClip(gn->clipList(), batch); glBindBuffer(GL_ARRAY_BUFFER, batch->vbo.id); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch->vbo.id); + + char *indexBase = 0; + if (m_context->hasBrokenIndexBufferObjects()) { + indexBase = batch->vbo.data; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } else { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch->vbo.id); + } QSGMaterial *material = gn->activeMaterial(); @@ -1924,7 +1931,7 @@ void Renderer::renderMergedBatch(const Batch *batch) } glVertexAttribPointer(sms->pos_order, 1, GL_FLOAT, false, 0, (void *) (qintptr) (draw.zorders)); - glDrawElements(g->drawingMode(), draw.indexCount, GL_UNSIGNED_SHORT, (void *) (qintptr) (draw.indices)); + glDrawElements(g->drawingMode(), draw.indexCount, GL_UNSIGNED_SHORT, (void *) (qintptr) (indexBase + draw.indices)); } } @@ -1957,8 +1964,15 @@ void Renderer::renderUnmergedBatch(const Batch *batch) updateClip(gn->clipList(), batch); glBindBuffer(GL_ARRAY_BUFFER, batch->vbo.id); - if (batch->indexCount) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch->vbo.id); + char *indexBase = 0; + if (batch->indexCount) { + if (m_context->hasBrokenIndexBufferObjects()) { + indexBase = batch->vbo.data; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } else { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch->vbo.id); + } + } // We always have dirty matrix as all batches are at a unique z range. QSGMaterialShader::RenderState::DirtyStates dirty = QSGMaterialShader::RenderState::DirtyMatrix; @@ -1977,7 +1991,7 @@ void Renderer::renderUnmergedBatch(const Batch *batch) } int vOffset = 0; - int iOffset = batch->vertexCount * gn->geometry()->sizeOfVertex(); + char *iOffset = indexBase + batch->vertexCount * gn->geometry()->sizeOfVertex(); QMatrix4x4 rootMatrix = batch->root ? matrixForRoot(batch->root) : QMatrix4x4(); @@ -2008,7 +2022,7 @@ void Renderer::renderUnmergedBatch(const Batch *batch) } if (g->indexCount()) - glDrawElements(g->drawingMode(), g->indexCount(), g->indexType(), (void *) (qintptr) iOffset); + glDrawElements(g->drawingMode(), g->indexCount(), g->indexType(), iOffset); else glDrawArrays(g->drawingMode(), 0, g->vertexCount()); diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 558711ea0e..4fbefb37d8 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -311,6 +311,7 @@ QSGRenderContext::QSGRenderContext(QSGContext *context) , m_atlasManager(0) , m_depthStencilManager(0) , m_distanceFieldCacheManager(0) + , m_brokenIBOs(false) { } @@ -408,6 +409,12 @@ void QSGRenderContext::initialize(QOpenGLContext *context) m_gl->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant::fromValue(this)); m_sg->renderContextInitialized(this); +#ifdef Q_OS_LINUX + const char *vendor = (const char *) glGetString(GL_VENDOR); + if (strstr(vendor, "nouveau")) + m_brokenIBOs = true; +#endif + emit initialized(); } diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index a11a4856c4..08fafb0713 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -109,11 +109,12 @@ public: static QSGRenderContext *from(QOpenGLContext *context); + bool hasBrokenIndexBufferObjects() const { return m_brokenIBOs; } + Q_SIGNALS: void initialized(); void invalidated(); - public Q_SLOTS: void textureFactoryDestroyed(QObject *o); @@ -129,6 +130,8 @@ protected: QSGDistanceFieldGlyphCacheManager *m_distanceFieldCacheManager; QSet<QFontEngine *> m_fontEnginesToClean; + + bool m_brokenIBOs; }; |