diff options
Diffstat (limited to 'src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp')
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 197 |
1 files changed, 91 insertions, 106 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 700ec051ff..1a9669f9ab 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -599,11 +599,6 @@ void Element::computeBounds() boundsOutsideFloatRange = bounds.isOutsideFloatRange(); } -RenderNodeElement::~RenderNodeElement() -{ - delete fbo; -} - bool Batch::isMaterialCompatible(Element *e) const { // If material has changed between opaque and translucent, it is not compatible @@ -751,6 +746,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) @@ -761,6 +757,8 @@ Renderer::Renderer(QSGRenderContext *ctx) , m_zRange(0) , m_currentMaterial(0) , m_currentShader(0) + , m_currentClip(0) + , m_currentClipType(NoClip) , m_vao(0) { setNodeUpdater(new Updater(this)); @@ -809,6 +807,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) @@ -1005,6 +1005,8 @@ void Renderer::nodeWasAdded(QSGNode *node, Node *shadowParent) snode->data = e; Q_ASSERT(!m_renderNodeElements.contains(static_cast<QSGRenderNode *>(node))); m_renderNodeElements.insert(e->renderNode, e); + m_useDepthBuffer = false; + m_rebuild |= FullRebuild; } QSGNODE_TRAVERSE(node) @@ -1250,7 +1252,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; @@ -1631,10 +1633,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; @@ -1658,7 +1663,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; @@ -1754,8 +1758,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; } @@ -1777,7 +1782,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; @@ -1857,7 +1862,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 << ")"; } @@ -1907,10 +1912,10 @@ void Renderer::updateClip(const QSGClipNode *clipList, const Batch *batch) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); if (batch->isOpaque) glDisable(GL_DEPTH_TEST); - ClipType type = updateStencilClip(m_currentClip); + m_currentClipType = updateStencilClip(m_currentClip); if (batch->isOpaque) { glEnable(GL_DEPTH_TEST); - if (type & StencilClip) + if (m_currentClipType & StencilClip) glDepthMask(true); } } @@ -2025,7 +2030,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) @@ -2054,7 +2059,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)); } @@ -2136,8 +2142,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); @@ -2187,25 +2195,25 @@ void Renderer::renderBatches() << " -> Alpha: " << qsg_countNodesInBatches(m_alphaBatches) << " nodes in " << m_alphaBatches.size() << " batches..."; } - for (QHash<QSGRenderNode *, RenderNodeElement *>::const_iterator it = m_renderNodeElements.constBegin(); - it != m_renderNodeElements.constEnd(); ++it) { - prepareRenderNode(it.value()); - } - 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); @@ -2232,7 +2240,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)) { @@ -2252,7 +2261,6 @@ void Renderer::renderBatches() updateStencilClip(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } void Renderer::deleteRemovedElements() @@ -2404,33 +2412,15 @@ void Renderer::render() m_vao->release(); } -void Renderer::prepareRenderNode(RenderNodeElement *e) +void Renderer::renderRenderNode(Batch *batch) { - if (e->fbo && e->fbo->size() != deviceRect().size()) { - delete e->fbo; - e->fbo = 0; - } + if (Q_UNLIKELY(debug_render)) + qDebug() << " -" << batch << "rendernode"; - if (!e->fbo) - e->fbo = new QOpenGLFramebufferObject(deviceRect().size(), QOpenGLFramebufferObject::CombinedDepthStencil); - e->fbo->bind(); + Q_ASSERT(batch->first->isRenderNode); + RenderNodeElement *e = (RenderNodeElement *) batch->first; - glDisable(GL_STENCIL_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - - QSGRenderNode::RenderState state; - QMatrix4x4 pm = projectionMatrix(); - state.projectionMatrix = ± - state.scissorEnabled = false; - state.stencilEnabled = false; + setActiveShader(0, 0); QSGNode *clip = e->renderNode->parent(); e->renderNode->m_clip_list = 0; @@ -2442,6 +2432,16 @@ void Renderer::prepareRenderNode(RenderNodeElement *e) clip = clip->parent(); } + updateClip(e->renderNode->m_clip_list, batch); + + QSGRenderNode::RenderState state; + QMatrix4x4 pm = projectionMatrix(); + state.projectionMatrix = ± + state.scissorEnabled = m_currentClipType & ScissorClip; + state.stencilEnabled = m_currentClipType & StencilClip; + state.scissorRect = m_current_scissor_rect; + state.stencilValue = m_current_stencil_value; + QSGNode *xform = e->renderNode->parent(); QMatrix4x4 matrix; while (xform != rootNode()) { @@ -2463,66 +2463,51 @@ void Renderer::prepareRenderNode(RenderNodeElement *e) opacity = opacity->parent(); } + glDisable(GL_STENCIL_TEST); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_DEPTH_TEST); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + e->renderNode->render(state); e->renderNode->m_matrix = 0; + e->renderNode->m_clip_list = 0; - bindable()->bind(); -} - -void Renderer::renderRenderNode(Batch *batch) -{ - updateStencilClip(0); - m_currentClip = 0; - - setActiveShader(0, 0); - - if (!m_shaderManager->blitProgram) { - m_shaderManager->blitProgram = new QOpenGLShaderProgram(); - - QSGShaderSourceBuilder::initializeProgramFromFiles( - m_shaderManager->blitProgram, - QStringLiteral(":/scenegraph/shaders/rendernode.vert"), - QStringLiteral(":/scenegraph/shaders/rendernode.frag")); - m_shaderManager->blitProgram->bindAttributeLocation("av", 0); - m_shaderManager->blitProgram->bindAttributeLocation("at", 1); - m_shaderManager->blitProgram->link(); - - Q_ASSERT(m_shaderManager->blitProgram->isLinked()); + QSGRenderNode::StateFlags changes = e->renderNode->changedStates(); + if (changes & QSGRenderNode::ViewportState) { + QRect r = viewportRect(); + glViewport(r.x(), deviceRect().bottom() - r.bottom(), r.width(), r.height()); } - RenderNodeElement *e = static_cast<RenderNodeElement *>(batch->first); - glBindTexture(GL_TEXTURE_2D, e->fbo->texture()); - - m_shaderManager->blitProgram->bind(); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + if (changes & QSGRenderNode::StencilState) { + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilMask(0xff); + glDisable(GL_STENCIL_TEST); + } - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); + if (changes & (QSGRenderNode::StencilState | QSGRenderNode::ScissorState)) { + glDisable(GL_SCISSOR_TEST); + m_currentClip = 0; + m_currentClipType = NoClip; + } - float z = 1.0f - e->order * m_zRange; + if (changes & QSGRenderNode::DepthState) + glDisable(GL_DEPTH_TEST); - float av[] = { -1, -1, z, - 1, -1, z, - -1, 1, z, - 1, 1, z }; - float at[] = { 0, 0, - 1, 0, - 0, 1, - 1, 1 }; + if (changes & QSGRenderNode::ColorState) + bindable()->reactivate(); - glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, av); - glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, at); + if (changes & QSGRenderNode::BlendState) { + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + if (changes & QSGRenderNode::CullState) { + glFrontFace(isMirrored() ? GL_CW : GL_CCW); + glDisable(GL_CULL_FACE); + } - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - glBindTexture(GL_TEXTURE_2D, 0); } QT_END_NAMESPACE |