Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Share depth-stencil buffers between ShaderEffectSources of same size.
Change-Id: If325a38175249c3a3ffe5043d42ba35dbf90ce0c
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
  • Loading branch information
Kim Motoyoshi Kalland authored and Qt by Nokia committed Mar 22, 2012
1 parent 23d56db commit 9d1b013
Show file tree
Hide file tree
Showing 7 changed files with 406 additions and 6 deletions.
45 changes: 40 additions & 5 deletions src/quick/items/qquickshadereffectsource.cpp
Expand Up @@ -54,6 +54,39 @@ QT_BEGIN_NAMESPACE

DEFINE_BOOL_CONFIG_OPTION(qmlFboOverlay, QML_FBO_OVERLAY)

namespace
{
class BindableFbo : public QSGBindable
{
public:
BindableFbo(QOpenGLFramebufferObject *fbo, QSGDepthStencilBuffer *depthStencil);
virtual ~BindableFbo();
virtual void bind() const;
private:
QOpenGLFramebufferObject *m_fbo;
QSGDepthStencilBuffer *m_depthStencil;
};

BindableFbo::BindableFbo(QOpenGLFramebufferObject *fbo, QSGDepthStencilBuffer *depthStencil)
: m_fbo(fbo)
, m_depthStencil(depthStencil)
{
}

BindableFbo::~BindableFbo()
{
if (m_depthStencil)
m_depthStencil->detach();
}

void BindableFbo::bind() const
{
m_fbo->bind();
if (m_depthStencil)
m_depthStencil->attach();
}
}

class QQuickShaderEffectSourceTextureProvider : public QSGTextureProvider
{
Q_OBJECT
Expand Down Expand Up @@ -239,6 +272,7 @@ void QQuickShaderEffectTexture::grab()
delete m_fbo;
delete m_secondaryFbo;
m_fbo = m_secondaryFbo = 0;
m_depthStencilBuffer.clear();
m_dirtyTexture = false;
if (m_grab)
emit scheduledUpdateCompleted();
Expand Down Expand Up @@ -272,13 +306,12 @@ void QQuickShaderEffectTexture::grab()
delete m_secondaryFbo;
QOpenGLFramebufferObjectFormat format;

format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setInternalTextureFormat(m_format);
format.setSamples(8);
m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format);
m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_secondaryFbo);
} else {
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setInternalTextureFormat(m_format);
format.setMipmap(m_mipmap);
if (m_recursive) {
Expand All @@ -287,13 +320,15 @@ void QQuickShaderEffectTexture::grab()
m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format);
glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture());
updateBindOptions(true);
m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_secondaryFbo);
} else {
delete m_fbo;
delete m_secondaryFbo;
m_fbo = new QOpenGLFramebufferObject(m_size, format);
m_secondaryFbo = 0;
glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
updateBindOptions(true);
m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_fbo);
}
}
}
Expand Down Expand Up @@ -336,7 +371,7 @@ void QQuickShaderEffectTexture::grab()
m_renderer->setClearColor(Qt::transparent);

if (m_multisampling) {
m_renderer->renderScene(QSGBindableFbo(m_secondaryFbo));
m_renderer->renderScene(BindableFbo(m_secondaryFbo, m_depthStencilBuffer.data()));

if (deleteFboLater) {
delete m_fbo;
Expand All @@ -354,7 +389,7 @@ void QQuickShaderEffectTexture::grab()
QOpenGLFramebufferObject::blitFramebuffer(m_fbo, r, m_secondaryFbo, r);
} else {
if (m_recursive) {
m_renderer->renderScene(QSGBindableFbo(m_secondaryFbo));
m_renderer->renderScene(BindableFbo(m_secondaryFbo, m_depthStencilBuffer.data()));

if (deleteFboLater) {
delete m_fbo;
Expand All @@ -368,7 +403,7 @@ void QQuickShaderEffectTexture::grab()
}
qSwap(m_fbo, m_secondaryFbo);
} else {
m_renderer->renderScene(QSGBindableFbo(m_fbo));
m_renderer->renderScene(BindableFbo(m_fbo, m_depthStencilBuffer.data()));
}
}

Expand Down
1 change: 1 addition & 0 deletions src/quick/items/qquickshadereffectsource_p.h
Expand Up @@ -136,6 +136,7 @@ public Q_SLOTS:
QSGRenderer *m_renderer;
QOpenGLFramebufferObject *m_fbo;
QOpenGLFramebufferObject *m_secondaryFbo;
QSharedPointer<QSGDepthStencilBuffer> m_depthStencilBuffer;

#ifdef QSG_DEBUG_FBO_OVERLAY
QSGRectangleNode *m_debugOverlay;
Expand Down
42 changes: 41 additions & 1 deletion src/quick/scenegraph/qsgcontext.cpp
Expand Up @@ -54,6 +54,7 @@

#include <QGuiApplication>
#include <QOpenGLContext>
#include <QtGui/qopenglframebufferobject.h>

#include <QQmlImageProvider>
#include <private/qqmlglobal_p.h>
Expand Down Expand Up @@ -96,6 +97,7 @@ class QSGContextPrivate : public QObjectPrivate
public:
QSGContextPrivate()
: gl(0)
, depthStencilBufferManager(0)
, distanceFieldCacheManager(0)
#ifndef QT_OPENGL_ES
, distanceFieldAntialiasing(QSGGlyphNode::HighQualitySubPixelAntialiasing)
Expand All @@ -117,7 +119,7 @@ class QSGContextPrivate : public QObjectPrivate
QHash<QSGMaterialType *, QSGMaterialShader *> materials;
QMutex textureMutex;
QHash<QQuickTextureFactory *, QSGTexture *> textures;

QSGDepthStencilBufferManager *depthStencilBufferManager;
QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager;

QSGDistanceFieldGlyphNode::AntialiasingMode distanceFieldAntialiasing;
Expand Down Expand Up @@ -179,6 +181,8 @@ void QSGContext::invalidate()
d->textureMutex.unlock();
qDeleteAll(d->materials.values());
d->materials.clear();
delete d->depthStencilBufferManager;
d->depthStencilBufferManager = 0;
delete d->distanceFieldCacheManager;
d->distanceFieldCacheManager = 0;

Expand Down Expand Up @@ -411,6 +415,42 @@ QSize QSGContext::minimumFBOSize() const



/*!
Returns a shared pointer to a depth stencil buffer that can be used with \a fbo.
*/
QSharedPointer<QSGDepthStencilBuffer> QSGContext::depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo)
{
Q_D(QSGContext);
if (!d->gl)
return QSharedPointer<QSGDepthStencilBuffer>();
QSGDepthStencilBufferManager *manager = depthStencilBufferManager();
QSGDepthStencilBuffer::Format format;
format.size = fbo->size();
format.samples = fbo->format().samples();
format.attachments = QSGDepthStencilBuffer::DepthAttachment | QSGDepthStencilBuffer::StencilAttachment;
QSharedPointer<QSGDepthStencilBuffer> buffer = manager->bufferForFormat(format);
if (buffer.isNull()) {
buffer = QSharedPointer<QSGDepthStencilBuffer>(new QSGDefaultDepthStencilBuffer(d->gl, format));
manager->insertBuffer(buffer);
}
return buffer;
}

/*!
Returns a pointer to the context's depth/stencil buffer manager. This is useful for custom
implementations of \l depthStencilBufferForFbo().
*/
QSGDepthStencilBufferManager *QSGContext::depthStencilBufferManager()
{
Q_D(QSGContext);
if (!d->gl)
return 0;
if (!d->depthStencilBufferManager)
d->depthStencilBufferManager = new QSGDepthStencilBufferManager(d->gl);
return d->depthStencilBufferManager;
}


/*!
Returns a material shader for the given material.
*/
Expand Down
3 changes: 3 additions & 0 deletions src/quick/scenegraph/qsgcontext_p.h
Expand Up @@ -51,6 +51,7 @@
#include <private/qrawfont_p.h>

#include <QtQuick/qsgnode.h>
#include <QtQuick/private/qsgdepthstencilbuffer_p.h>

QT_BEGIN_HEADER

Expand Down Expand Up @@ -104,6 +105,8 @@ class Q_QUICK_EXPORT QSGContext : public QObject

virtual QSGTexture *createTexture(const QImage &image = QImage()) const;
virtual QSize minimumFBOSize() const;
virtual QSharedPointer<QSGDepthStencilBuffer> depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo);
QSGDepthStencilBufferManager *depthStencilBufferManager();

virtual QSurfaceFormat defaultSurfaceFormat() const;

Expand Down
2 changes: 2 additions & 0 deletions src/quick/scenegraph/scenegraph.pri
Expand Up @@ -23,6 +23,7 @@ SOURCES += \
# Util API
HEADERS += \
$$PWD/util/qsgareaallocator_p.h \
$$PWD/util/qsgdepthstencilbuffer_p.h \
$$PWD/util/qsgengine.h \
$$PWD/util/qsgflatcolormaterial.h \
$$PWD/util/qsgsimplematerial.h \
Expand All @@ -39,6 +40,7 @@ HEADERS += \

SOURCES += \
$$PWD/util/qsgareaallocator.cpp \
$$PWD/util/qsgdepthstencilbuffer.cpp \
$$PWD/util/qsgengine.cpp \
$$PWD/util/qsgflatcolormaterial.cpp \
$$PWD/util/qsgsimplerectnode.cpp \
Expand Down

0 comments on commit 9d1b013

Please sign in to comment.