aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@jollamobile.com>2014-01-21 13:28:53 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-22 10:48:18 +0100
commite7ad7739c4886236ea1b8e3149d76dcee8f9d11e (patch)
tree89e1e57f8a34ad7822756f09702fd5d6b95a3960 /src/quick/scenegraph
parent918159a2aae5062935a946e6d64120769802d625 (diff)
Make it possible to render without a depth buffer.
Some GL implementations (especially on embedded) will give us an OpenGL context without a depth buffer. In low memory scenarios, it might also be feasible to request a non-depth buffer context to save the depth buffer memory. The renderer deals with this by treating all nodes as translucent, by not adjusting the shaders and by not creating the extra z-order vertex attribute for merged nodes. Change-Id: I8edc92d530daa3e2628df2ba52901b47d87eaf26 Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp57
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h2
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp21
3 files changed, 53 insertions, 27 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index e9d883f248..a10191ec16 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -757,6 +757,7 @@ Renderer::Renderer(QSGRenderContext *ctx)
, m_nextRenderOrder(0)
, m_partialRebuild(false)
, m_partialRebuildRoot(0)
+ , m_useDepthBuffer(true)
, m_opaqueBatches(16)
, m_alphaBatches(16)
, m_batchPool(16)
@@ -815,6 +816,8 @@ Renderer::Renderer(QSGRenderContext *ctx)
m_vao = new QOpenGLVertexArrayObject(this);
m_vao->create();
}
+
+ m_useDepthBuffer = ctx->openglContext()->format().depthBufferSize() > 0;
}
static void qsg_wipeBuffer(Buffer *buffer, QOpenGLFunctions *funcs)
@@ -1256,7 +1259,7 @@ void Renderer::buildRenderLists(QSGNode *node)
Q_ASSERT(e);
bool opaque = gn->inheritedOpacity() > OPAQUE_LIMIT && !(gn->activeMaterial()->flags() & QSGMaterial::Blending);
- if (opaque)
+ if (opaque && m_useDepthBuffer)
m_opaqueRenderList << e;
else
m_alphaRenderList << e;
@@ -1637,10 +1640,13 @@ void Renderer::uploadMergedElement(Element *e, int vaOffset, char **vertexData,
}
}
- float *vzorder = (float *) *zData;
- float zorder = 1.0f - e->order * m_zRange;
- for (int i=0; i<vCount; ++i)
- vzorder[i] = zorder;
+ if (m_useDepthBuffer) {
+ float *vzorder = (float *) *zData;
+ float zorder = 1.0f - e->order * m_zRange;
+ for (int i=0; i<vCount; ++i)
+ vzorder[i] = zorder;
+ *zData += vCount * sizeof(float);
+ }
int iCount = g->indexCount();
quint16 *indices = (quint16 *) *indexData;
@@ -1664,7 +1670,6 @@ void Renderer::uploadMergedElement(Element *e, int vaOffset, char **vertexData,
}
*vertexData += vCount * vSize;
- *zData += vCount * sizeof(float);
*indexData += iCount * sizeof(quint16);
*iBase += vCount;
*indexCount += iCount;
@@ -1760,8 +1765,9 @@ void Renderer::uploadBatch(Batch *b)
int bufferSize = b->vertexCount * g->sizeOfVertex();
int ibufferSize = 0;
if (b->merged) {
- bufferSize += b->vertexCount * sizeof(float);
ibufferSize = b->indexCount * sizeof(quint16);
+ if (m_useDepthBuffer)
+ bufferSize += b->vertexCount * sizeof(float);
} else {
ibufferSize = unmergedIndexSize;
}
@@ -1783,7 +1789,7 @@ void Renderer::uploadBatch(Batch *b)
#ifdef QSG_SEPARATE_INDEX_BUFFER
char *indexData = b->ibo.data;
#else
- char *indexData = zData + b->vertexCount * sizeof(float);
+ char *indexData = zData + (m_useDepthBuffer ? b->vertexCount * sizeof(float) : 0);
#endif
quint16 iOffset = 0;
@@ -1863,7 +1869,7 @@ void Renderer::uploadBatch(Batch *b)
dump << ") ";
offset += attr.tupleSize * size_of_type(attr.type);
}
- if (b->merged) {
+ if (b->merged && m_useDepthBuffer) {
float zorder = ((float*)(b->vbo.data + b->vertexCount * g->sizeOfVertex()))[i];
dump << " Z:(" << zorder << ")";
}
@@ -2031,7 +2037,7 @@ void Renderer::renderMergedBatch(const Batch *batch)
QSGMaterial *material = gn->activeMaterial();
- ShaderManager::Shader *sms = m_shaderManager->prepareMaterial(material);
+ ShaderManager::Shader *sms = m_useDepthBuffer ? m_shaderManager->prepareMaterial(material) : m_shaderManager->prepareMaterialNoRewrite(material);
QSGMaterialShader *program = sms->program;
if (m_currentShader != sms)
@@ -2060,7 +2066,8 @@ void Renderer::renderMergedBatch(const Batch *batch)
glVertexAttribPointer(a.position, a.tupleSize, a.type, normalize, g->sizeOfVertex(), (void *) (qintptr) (offset + draw.vertices));
offset += a.tupleSize * size_of_type(a.type);
}
- glVertexAttribPointer(sms->pos_order, 1, GL_FLOAT, false, 0, (void *) (qintptr) (draw.zorders));
+ if (m_useDepthBuffer)
+ glVertexAttribPointer(sms->pos_order, 1, GL_FLOAT, false, 0, (void *) (qintptr) (draw.zorders));
glDrawElements(g->drawingMode(), draw.indexCount, GL_UNSIGNED_SHORT, (void *) (qintptr) (indexBase + draw.indices));
}
@@ -2142,8 +2149,10 @@ void Renderer::renderUnmergedBatch(const Batch *batch)
m_current_determinant = m_current_model_view_matrix.determinant();
m_current_projection_matrix = projectionMatrix();
- m_current_projection_matrix(2, 2) = m_zRange;
- m_current_projection_matrix(2, 3) = 1.0f - e->order * m_zRange;
+ if (m_useDepthBuffer) {
+ m_current_projection_matrix(2, 2) = m_zRange;
+ m_current_projection_matrix(2, 3) = 1.0f - e->order * m_zRange;
+ }
program->updateState(state(dirty), material, m_currentMaterial);
@@ -2197,17 +2206,22 @@ void Renderer::renderBatches()
QRect r = viewportRect();
glViewport(r.x(), deviceRect().bottom() - r.bottom(), r.width(), r.height());
glClearColor(clearColor().redF(), clearColor().greenF(), clearColor().blueF(), clearColor().alphaF());
+
+ if (m_useDepthBuffer) {
#if defined(QT_OPENGL_ES)
- glClearDepthf(1);
+ glClearDepthf(1);
#else
- glClearDepth(1);
+ glClearDepth(1);
#endif
-
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ glDepthMask(true);
+ glDisable(GL_BLEND);
+ } else {
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(false);
+ }
glDisable(GL_CULL_FACE);
- glDisable(GL_BLEND);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LESS);
- glDepthMask(true);
glColorMask(true, true, true, true);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_STENCIL_TEST);
@@ -2234,7 +2248,8 @@ void Renderer::renderBatches()
}
glEnable(GL_BLEND);
- glDepthMask(false);
+ if (m_useDepthBuffer)
+ glDepthMask(false);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
if (Q_LIKELY(renderAlpha)) {
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 001c3b21ab..a0fa96f989 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -460,6 +460,8 @@ private:
bool m_partialRebuild;
QSGNode *m_partialRebuildRoot;
+ bool m_useDepthBuffer;
+
QHash<QSGRenderNode *, RenderNodeElement *> m_renderNodeElements;
QDataBuffer<Batch *> m_opaqueBatches;
QDataBuffer<Batch *> m_alphaBatches;
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 90803db9fe..1eeb9441b8 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -210,10 +210,17 @@ void QSGContext::renderContextInitialized(QSGRenderContext *renderContext)
static bool dumped = false;
if (!dumped && qEnvironmentVariableIsSet("QSG_INFO")) {
dumped = true;
- qDebug() << "GL_VENDOR: " << (const char *) glGetString(GL_VENDOR);
- qDebug() << "GL_RENDERER: " << (const char *) glGetString(GL_RENDERER);
- qDebug() << "GL_VERSION: " << (const char *) glGetString(GL_VERSION);
- qDebug() << "GL_EXTENSIONS:\n " << QByteArray((const char *) glGetString(GL_EXTENSIONS)).replace(" ", "\n ").constData();
+ QSurfaceFormat format = renderContext->openglContext()->format();
+ qDebug() << "R/G/B/A Buffers: " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize();
+ qDebug() << "Depth Buffer: " << format.depthBufferSize();
+ qDebug() << "Stencil Buffer: " << format.stencilBufferSize();
+ qDebug() << "Samples: " << format.samples();
+ qDebug() << "GL_VENDOR: " << (const char *) glGetString(GL_VENDOR);
+ qDebug() << "GL_RENDERER: " << (const char *) glGetString(GL_RENDERER);
+ qDebug() << "GL_VERSION: " << (const char *) glGetString(GL_VERSION);
+ QSet<QByteArray> exts = renderContext->openglContext()->extensions();
+ QByteArray all; foreach (const QByteArray &e, exts) all += ' ' + e;
+ qDebug() << "GL_EXTENSIONS: " << all.constData();
}
d->mutex.unlock();
@@ -282,8 +289,10 @@ QSGGlyphNode *QSGContext::createGlyphNode(QSGRenderContext *rc)
QSurfaceFormat QSGContext::defaultSurfaceFormat() const
{
QSurfaceFormat format;
- format.setDepthBufferSize(24);
- format.setStencilBufferSize(8);
+ static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
+ static bool useStencil = qEnvironmentVariableIsEmpty("QSG_NO_STENCIL_BUFFER");
+ format.setDepthBufferSize(useDepth ? 24 : 0);
+ format.setStencilBufferSize(useStencil ? 8 : 0);
if (QQuickWindow::hasDefaultAlphaBuffer())
format.setAlphaBufferSize(8);
format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);