aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@digia.com>2013-10-30 14:09:18 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-30 15:18:33 +0100
commit4a7f1326e3d342148a4a9147505a4d8d531b4a06 (patch)
tree7194f7b696b264e319c3fd3671fc074a7cc25270 /src
parent388fc07cf28417f6e755ad8a105a71aa55ab13c8 (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.cpp6
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp26
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp7
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h5
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;
};