diff --git a/src/canvas3d.cpp b/src/canvas3d.cpp index 91fbe5b4d79e731a199ec053d93af781da3f66c3..43d182943a095ce509126ad393e7607e880e1054 100644 --- a/src/canvas3d.cpp +++ b/src/canvas3d.cpp @@ -275,6 +275,7 @@ CanvasContext *Canvas::getContext(const QString &type, const QVariantMap &option << ")"; if (!m_isContextAttribsSet) { + // Accept passed attributes only from first call and ignore for subsequent calls m_isContextAttribsSet = true; m_contextAttribs.setFrom(options); if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ @@ -284,6 +285,11 @@ CanvasContext *Canvas::getContext(const QString &type, const QVariantMap &option if (m_maxSamples == 0 || m_isSoftwareRendered) m_contextAttribs.setAntialias(false); + // Reflect the fact that creation of stencil attachment + // causes the creation of depth attachment as well + if (m_contextAttribs.stencil()) + m_contextAttribs.setDepth(true); + // Ensure ignored attributes are left to their default state m_contextAttribs.setAlpha(false); m_contextAttribs.setPremultipliedAlpha(false); @@ -293,6 +299,7 @@ CanvasContext *Canvas::getContext(const QString &type, const QVariantMap &option } if (!m_context3D) { + // Create the context using current context attributes updateWindowParameters(); QOpenGLFramebufferObjectFormat format; @@ -311,12 +318,14 @@ CanvasContext *Canvas::getContext(const QString &type, const QVariantMap &option if (m_contextAttribs.antialias()) { antialiasFboFormat.setSamples(m_maxSamples); + if (antialiasFboFormat.samples() != m_maxSamples) { + qDebug() << "Failed to use " << m_maxSamples << " will use " << antialiasFboFormat.samples(); + } + if (m_contextAttribs.depth() && m_contextAttribs.stencil()) antialiasFboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); else if (m_contextAttribs.depth()) antialiasFboFormat.setAttachment(QOpenGLFramebufferObject::Depth); - else if (m_contextAttribs.stencil()) - antialiasFboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); else antialiasFboFormat.setAttachment(QOpenGLFramebufferObject::NoAttachment); } @@ -338,12 +347,14 @@ CanvasContext *Canvas::getContext(const QString &type, const QVariantMap &option if (m_contextAttribs.depth()) surfaceFormat.setDepthBufferSize(24); - // Ensure if (m_contextAttribs.stencil()) surfaceFormat.setStencilBufferSize(8); else surfaceFormat.setStencilBufferSize(-1); + if (m_contextAttribs.antialias()) + surfaceFormat.setSamples(antialiasFboFormat.samples()); + if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " Creating QOpenGLContext with surfaceFormat :" << surfaceFormat; @@ -414,20 +425,6 @@ CanvasContext *Canvas::getContext(const QString &type, const QVariantMap &option return m_context3D; } -/*! - * \internal - */ -GLuint Canvas::drawFBOHandle() -{ - GLuint fbo = 0; - if (m_renderFbo) - fbo = m_renderFbo->handle(); - - if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << "():" << fbo; - - return fbo; -} - /*! * \internal */ @@ -591,6 +588,32 @@ QSGNode *Canvas::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) return node; } + +/*! + * \internal + */ +void Canvas::bindCurrentRenderTarget() +{ + if (m_context3D->currentFramebuffer() == 0) { + if (m_contextAttribs.antialias()) { + if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ + << " Binding current FBO to antialias FBO of " + << m_antialiasFbo->handle(); + m_antialiasFbo->bind(); + } else { + if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ + << " Binding current FBO to render FBO of " + << m_renderFbo->handle(); + m_renderFbo->bind(); + } + } else { + if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ + << " Binding current FBO to current context FBO of " + << m_context3D->currentFramebuffer(); + glBindFramebuffer(GL_FRAMEBUFFER, m_context3D->currentFramebuffer()); + } +} + /*! * \internal */ @@ -630,14 +653,7 @@ void Canvas::renderNext() m_glContext->makeCurrent(m_offscreenSurface); // Bind the correct render target FBO - if (m_context3D->currentFramebuffer() == 0) { - if (m_contextAttribs.antialias()) - m_antialiasFbo->bind(); - else - m_renderFbo->bind(); - } else { - glBindFramebuffer(GL_FRAMEBUFFER, m_context3D->currentFramebuffer()); - } + bindCurrentRenderTarget(); // Ensure we have correct clip rect set in the context QRect viewport = m_context3D->glViewportRect(); diff --git a/src/canvas3d_p.h b/src/canvas3d_p.h index 8956db7e0349d6ddd15ae9d68ca9808125420d9f..3f57dcdefa2f77c4921fa05f165bdb299fa733b7 100644 --- a/src/canvas3d_p.h +++ b/src/canvas3d_p.h @@ -74,13 +74,13 @@ public: void handleWindowChanged(QQuickWindow *win); float devicePixelRatio(); + void bindCurrentRenderTarget(); + void setLogAllCalls(bool logCalls); bool logAllCalls() const; void setLogAllErrors(bool logErrors); bool logAllErrors() const; - GLuint drawFBOHandle(); - Q_INVOKABLE CanvasContext *getContext(const QString &name); Q_INVOKABLE CanvasContext *getContext(const QString &name, const QVariantMap &options); CanvasContext *context(); diff --git a/src/context3d.cpp b/src/context3d.cpp index d135d6235882c2452f7a35e7763f9fa977e30210..a621becc1d50555d1bb62e856ba60d0fe0d48fd7 100644 --- a/src/context3d.cpp +++ b/src/context3d.cpp @@ -1384,13 +1384,12 @@ void CanvasContext::bindFramebuffer(glEnums target, CanvasFrameBuffer* framebuff return; } - if (framebuffer) { + if (framebuffer) m_currentFramebuffer = framebuffer; - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer->id()); - } else { + else m_currentFramebuffer = 0; - glBindFramebuffer(GL_FRAMEBUFFER, m_canvas->drawFBOHandle()); - } + + m_canvas->bindCurrentRenderTarget(); } /*!