summaryrefslogtreecommitdiffstats
path: root/src/graphicsitems/nodes/qxpainternode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphicsitems/nodes/qxpainternode.cpp')
-rw-r--r--src/graphicsitems/nodes/qxpainternode.cpp119
1 files changed, 68 insertions, 51 deletions
diff --git a/src/graphicsitems/nodes/qxpainternode.cpp b/src/graphicsitems/nodes/qxpainternode.cpp
index 2b3edf7..9190587 100644
--- a/src/graphicsitems/nodes/qxpainternode.cpp
+++ b/src/graphicsitems/nodes/qxpainternode.cpp
@@ -51,6 +51,7 @@ QxPainterNode::QxPainterNode(QxPaintItem *item)
, m_multisampledFbo(0)
, m_size(1, 1)
, m_opacity(1.0)
+ , m_opaquePainting(false)
, m_linear_filtering(false)
, m_smoothPainting(false)
, m_extensionsChecked(false)
@@ -58,6 +59,7 @@ QxPainterNode::QxPainterNode(QxPaintItem *item)
{
setFlag(Node::UsePreprocess);
setMaterial(&m_material);
+ updateGeometryDescription(Utilities::getTexturedRectGeometryDescription(), GL_UNSIGNED_SHORT);
}
QxPainterNode::~QxPainterNode()
@@ -71,35 +73,7 @@ void QxPainterNode::preprocess()
if (!m_item || !m_item->isDirty())
return;
- if (!m_fbo) {
- const QGLContext *ctx = QGLContext::currentContext();
- if (!m_extensionsChecked) {
- QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' ');
- m_multisamplingSupported = extensions.contains("GL_EXT_framebuffer_multisample")
- && extensions.contains("GL_EXT_framebuffer_blit");
- m_extensionsChecked = true;
- }
-
- if (m_smoothPainting && ctx->format().sampleBuffers() && m_multisamplingSupported) {
- // If mipmapping was just enabled, m_fbo might be 0 while m_multisampledFbo != 0.
- if (!m_multisampledFbo) {
- QGLFramebufferObjectFormat format;
- format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
- format.setSamples(ctx->format().samples());
- m_multisampledFbo = new QGLFramebufferObject(m_size, format);
- }
- {
- QGLFramebufferObjectFormat format;
- format.setAttachment(QGLFramebufferObject::NoAttachment);
- m_fbo = new QGLFramebufferObject(m_size, format);
- }
- } else {
- QGLFramebufferObjectFormat format;
- format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
- m_fbo = new QGLFramebufferObject(m_size, format);
- }
- updateTexture();
- }
+ Q_ASSERT(m_fbo != 0);
QPainter fbo_painter;
if (m_multisampledFbo)
@@ -123,41 +97,82 @@ void QxPainterNode::preprocess()
m_item->setDirty(false);
}
+void QxPainterNode::update(uint updateFlags)
+{
+ if (updateFlags & UpdateGeometry)
+ updateGeometry();
+ if (updateFlags & (UpdateFBO | UpdateGeometry))
+ updateFBO();
+ if (updateFlags & (UpdateTexture | UpdateFBO))
+ updateTexture();
+}
+
void QxPainterNode::updateTexture()
{
QSGTexture *texture = new QSGTexture;
texture->setTextureId(m_fbo->texture());
texture->setTextureSize(m_fbo->size());
- texture->setAlphaChannel(m_item->opaquePainting());
+ texture->setAlphaChannel(m_opaquePainting);
texture->setOwnsTexture(false);
texture->setStatus(QSGTexture::Ready);
m_texture = QSGTextureRef(texture);
- m_material.setTexture(m_texture, m_item->opaquePainting());
+ m_material.setTexture(m_texture, m_opaquePainting);
m_material.setLinearFiltering(m_linear_filtering);
- m_materialO.setTexture(m_texture, m_item->opaquePainting());
+ m_materialO.setTexture(m_texture, m_opaquePainting);
m_materialO.setLinearFiltering(m_linear_filtering);
m_materialO.setOpacity(m_opacity);
setMaterial(m_opacity == 1 ? &m_material : &m_materialO);
}
-void QxPainterNode::setSize(const QSize &size)
+void QxPainterNode::updateGeometry()
{
- if (size == m_size)
- return;
-
- m_size = size;
+ Utilities::setupRectGeometry(geometry(), QRectF(0, 0, m_size.width(), m_size.height()), QSize(1, 1), QRectF(0,1,1,-1));
+ markDirty(DirtyGeometry);
+}
+void QxPainterNode::updateFBO()
+{
delete m_fbo;
delete m_multisampledFbo;
- m_fbo = 0;
- m_multisampledFbo = 0;
+ m_fbo = m_multisampledFbo = 0;
+
+ const QGLContext *ctx = QGLContext::currentContext();
+ if (!m_extensionsChecked) {
+ QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' ');
+ m_multisamplingSupported = extensions.contains("GL_EXT_framebuffer_multisample")
+ && extensions.contains("GL_EXT_framebuffer_blit");
+ m_extensionsChecked = true;
+ }
- if (geometry()->isNull())
- updateGeometryDescription(Utilities::getTexturedRectGeometryDescription(), GL_UNSIGNED_SHORT);
- Utilities::setupRectGeometry(geometry(), QRectF(0, 0, size.width(), size.height()), QSize(1, 1), QRectF(0,1,1,-1));
+ if (m_smoothPainting && ctx->format().sampleBuffers() && m_multisamplingSupported) {
+ // If mipmapping was just enabled, m_fbo might be 0 while m_multisampledFbo != 0.
+ if (!m_multisampledFbo) {
+ QGLFramebufferObjectFormat format;
+ format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
+ format.setSamples(ctx->format().samples());
+ m_multisampledFbo = new QGLFramebufferObject(m_size, format);
+ }
+ {
+ QGLFramebufferObjectFormat format;
+ format.setAttachment(QGLFramebufferObject::NoAttachment);
+ m_fbo = new QGLFramebufferObject(m_size, format);
+ }
+ } else {
+ QGLFramebufferObjectFormat format;
+ format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
+ m_fbo = new QGLFramebufferObject(m_size, format);
+ }
+}
- markDirty(DirtyGeometry);
+void QxPainterNode::setSize(const QSize &size)
+{
+ if (size == m_size)
+ return;
+
+ m_size = size;
+ setBoundingRect(QRectF(0, 0, size.width(), size.height()));
+ setUpdateFlag(UpdateGeometry);
}
void QxPainterNode::setOpacity(qreal opacity)
@@ -171,6 +186,15 @@ void QxPainterNode::setOpacity(qreal opacity)
setMaterial(opacity == 1 ? &m_material : &m_materialO);
}
+void QxPainterNode::setOpaquePainting(bool opaque)
+{
+ if (opaque == m_opaquePainting)
+ return;
+
+ m_opaquePainting = opaque;
+ setUpdateFlag(UpdateTexture);
+}
+
void QxPainterNode::setLinearFiltering(bool linearFiltering)
{
if (linearFiltering == m_linear_filtering)
@@ -189,12 +213,5 @@ void QxPainterNode::setSmoothPainting(bool s)
return;
m_smoothPainting = s;
-
- if (m_multisamplingSupported) {
- delete m_fbo;
- delete m_multisampledFbo;
- m_fbo = 0;
- m_multisampledFbo = 0;
- markDirty(DirtyMaterial);
- }
+ setUpdateFlag(UpdateFBO);
}