diff options
Diffstat (limited to 'src/quick/items/qquickshadereffectsource.cpp')
-rw-r--r-- | src/quick/items/qquickshadereffectsource.cpp | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index e86550d731..e076a342df 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -45,6 +45,7 @@ #include "qquickwindow_p.h" #include <private/qsgadaptationlayer_p.h> #include <QtQuick/private/qsgrenderer_p.h> +#include <qsgsimplerectnode.h> #include "qopenglframebufferobject.h" #include "qmath.h" @@ -140,10 +141,11 @@ QQuickShaderEffectTexture::QQuickShaderEffectTexture(QQuickItem *shaderSource) , m_renderer(0) , m_fbo(0) , m_secondaryFbo(0) + , m_transparentTexture(0) #ifdef QSG_DEBUG_FBO_OVERLAY , m_debugOverlay(0) #endif - , m_context(QQuickItemPrivate::get(shaderSource)->sceneGraphContext()) + , m_context(QQuickItemPrivate::get(shaderSource)->sceneGraphRenderContext()) , m_mipmap(false) , m_live(true) , m_recursive(false) @@ -164,6 +166,8 @@ QQuickShaderEffectTexture::~QQuickShaderEffectTexture() #ifdef QSG_DEBUG_FBO_OVERLAY delete m_debugOverlay; #endif + if (m_transparentTexture) + glDeleteTextures(1, &m_transparentTexture); } int QQuickShaderEffectTexture::textureId() const @@ -188,8 +192,20 @@ void QQuickShaderEffectTexture::bind() if (!m_recursive && m_fbo && ((m_multisampling && m_secondaryFbo->isBound()) || m_fbo->isBound())) qWarning("ShaderEffectSource: \'recursive\' must be set to true when rendering recursively."); #endif - glBindTexture(GL_TEXTURE_2D, m_fbo ? m_fbo->texture() : 0); - updateBindOptions(); + + if (!m_fbo && m_format == GL_RGBA) { + if (m_transparentTexture == 0) { + glGenTextures(1, &m_transparentTexture); + glBindTexture(GL_TEXTURE_2D, m_transparentTexture); + const uint zero = 0; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &zero); + } else { + glBindTexture(GL_TEXTURE_2D, m_transparentTexture); + } + } else { + glBindTexture(GL_TEXTURE_2D, m_fbo ? m_fbo->texture() : 0); + updateBindOptions(); + } } bool QQuickShaderEffectTexture::updateTexture() @@ -326,7 +342,7 @@ void QQuickShaderEffectTexture::grab() || (!m_fbo->format().mipmap() && m_mipmap)) { if (!m_multisamplingChecked) { - if (m_context->glContext()->format().samples() <= 1) { + if (m_context->openglContext()->format().samples() <= 1) { m_multisampling = false; } else { QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' '); @@ -342,7 +358,7 @@ void QQuickShaderEffectTexture::grab() QOpenGLFramebufferObjectFormat format; format.setInternalTextureFormat(m_format); - format.setSamples(m_context->glContext()->format().samples()); + format.setSamples(m_context->openglContext()->format().samples()); m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format); m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_secondaryFbo); } else { @@ -385,20 +401,16 @@ void QQuickShaderEffectTexture::grab() #ifdef QSG_DEBUG_FBO_OVERLAY if (qmlFboOverlay()) { if (!m_debugOverlay) - m_debugOverlay = m_context->createRectangleNode(); + m_debugOverlay = new QSGSimpleRectNode(); m_debugOverlay->setRect(QRectF(0, 0, m_size.width(), m_size.height())); m_debugOverlay->setColor(QColor(0xff, 0x00, 0x80, 0x40)); - m_debugOverlay->setPenColor(QColor()); - m_debugOverlay->setPenWidth(0); - m_debugOverlay->setRadius(0); - m_debugOverlay->update(); root->appendChildNode(m_debugOverlay); } #endif m_dirtyTexture = false; - QOpenGLContext *ctx = m_context->glContext(); + QOpenGLContext *ctx = m_context->openglContext(); m_renderer->setDeviceRect(m_size); m_renderer->setViewportRect(m_size); QRectF mirrored(m_rect.left(), m_rect.bottom(), m_rect.width(), -m_rect.height()); @@ -591,8 +603,8 @@ void QQuickShaderEffectSource::ensureTexture() return; Q_ASSERT_X(QQuickItemPrivate::get(this)->window - && QQuickItemPrivate::get(this)->sceneGraphContext() - && QThread::currentThread() == QQuickItemPrivate::get(this)->sceneGraphContext()->thread(), + && QQuickItemPrivate::get(this)->sceneGraphRenderContext() + && QThread::currentThread() == QQuickItemPrivate::get(this)->sceneGraphRenderContext()->thread(), "QQuickShaderEffectSource::ensureTexture", "Cannot be used outside the rendering thread"); @@ -603,13 +615,13 @@ void QQuickShaderEffectSource::ensureTexture() QSGTextureProvider *QQuickShaderEffectSource::textureProvider() const { + const QQuickItemPrivate *d = QQuickItemPrivate::get(this); + if (!d->window || !d->sceneGraphRenderContext() || QThread::currentThread() != d->sceneGraphRenderContext()->thread()) { + qWarning("QQuickShaderEffectSource::textureProvider: can only be queried on the rendering thread of an exposed window"); + return 0; + } + if (!m_provider) { - // Make sure it gets thread affinity on the rendering thread so deletion works properly.. - Q_ASSERT_X(QQuickItemPrivate::get(this)->window - && QQuickItemPrivate::get(this)->sceneGraphContext() - && QThread::currentThread() == QQuickItemPrivate::get(this)->sceneGraphContext()->thread(), - "QQuickShaderEffectSource::textureProvider", - "Cannot be used outside the rendering thread"); const_cast<QQuickShaderEffectSource *>(this)->m_provider = new QQuickShaderEffectSourceTextureProvider(); const_cast<QQuickShaderEffectSource *>(this)->ensureTexture(); connect(m_texture, SIGNAL(updateRequested()), m_provider, SIGNAL(textureChanged())); |