diff options
author | Gunnar Sletta <gunnar.sletta@jollamobile.com> | 2014-01-21 13:28:53 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-22 10:48:18 +0100 |
commit | e7ad7739c4886236ea1b8e3149d76dcee8f9d11e (patch) | |
tree | 89e1e57f8a34ad7822756f09702fd5d6b95a3960 /src | |
parent | 918159a2aae5062935a946e6d64120769802d625 (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')
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 57 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext.cpp | 21 |
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); |