summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@nokia.com>2010-12-08 16:09:28 +0100
committerYoann Lopes <yoann.lopes@nokia.com>2010-12-08 16:09:28 +0100
commita18130b26501b93c7d799f79ca21e448b7e697eb (patch)
tree33a9d15705470b2d0bdaf09c11f8bfaf906dae12
parentf87a860553c4cdb70fe33154bee6ce96fb407d85 (diff)
Creates QxPaintItem's node on componentComplete.
Also, QxPainterNode now uses update flags.
-rw-r--r--src/graphicsitems/nodes/qxpainternode.cpp119
-rw-r--r--src/graphicsitems/nodes/qxpainternode.h17
-rw-r--r--src/graphicsitems/qxpaintitem.cpp40
-rw-r--r--src/graphicsitems/qxpaintitem_p.h3
4 files changed, 111 insertions, 68 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);
}
diff --git a/src/graphicsitems/nodes/qxpainternode.h b/src/graphicsitems/nodes/qxpainternode.h
index 7d6212c..bf7b71d 100644
--- a/src/graphicsitems/nodes/qxpainternode.h
+++ b/src/graphicsitems/nodes/qxpainternode.h
@@ -64,15 +64,29 @@ public:
void setOpacity(qreal opacity) ;
qreal opacity() const { return m_opacity; }
+ void setOpaquePainting(bool opaque);
+ bool opaquePainting() const { return m_opaquePainting; }
+
void setLinearFiltering(bool linearFiltering);
bool linearFiltering() const { return m_linear_filtering; }
void setSmoothPainting(bool s);
bool smoothPainting() const { return m_smoothPainting; }
- void updateTexture();
+ virtual void update(uint updateFlags);
private:
+ enum UpdateFlag
+ {
+ UpdateTexture = 0x01,
+ UpdateGeometry = 0x02,
+ UpdateFBO = 0x03
+ };
+
+ void updateTexture();
+ void updateGeometry();
+ void updateFBO();
+
QxPaintItem *m_item;
QGLFramebufferObject *m_fbo;
@@ -83,6 +97,7 @@ private:
QSize m_size;
qreal m_opacity;
+ bool m_opaquePainting;
bool m_linear_filtering;
bool m_smoothPainting;
bool m_extensionsChecked;
diff --git a/src/graphicsitems/qxpaintitem.cpp b/src/graphicsitems/qxpaintitem.cpp
index fa6e7d6..3c74455 100644
--- a/src/graphicsitems/qxpaintitem.cpp
+++ b/src/graphicsitems/qxpaintitem.cpp
@@ -56,19 +56,23 @@
QxPaintItemPrivate::QxPaintItemPrivate()
: QxItemPrivate()
+ , m_node(0)
, m_opaque_painting(false)
, m_dirty(false)
{
}
+QxPaintItemPrivate::~QxPaintItemPrivate()
+{
+ delete m_node;
+}
+
/*!
Constructs a QxPaintItem with \a parent.
*/
QxPaintItem::QxPaintItem(QxItem *parent)
: QxItem(*(new QxPaintItemPrivate), parent)
{
- Q_D(QxPaintItem);
- d->m_node.setPaintItem(this);
}
/*!
@@ -77,8 +81,6 @@ QxPaintItem::QxPaintItem(QxItem *parent)
QxPaintItem::QxPaintItem(QxPaintItemPrivate &dd, QxItem *parent)
: QxItem(dd, parent)
{
- Q_D(QxPaintItem);
- d->m_node.setPaintItem(this);
}
/*!
@@ -95,7 +97,8 @@ void QxPaintItem::update()
{
Q_D(QxPaintItem);
d->m_dirty = true;
- d->m_node.markDirty(Node::DirtyMaterial);
+ if (d->m_node)
+ d->m_node->markDirty(Node::DirtyMaterial);
}
/*!
@@ -105,8 +108,14 @@ void QxPaintItem::componentComplete()
{
Q_D(QxPaintItem);
QxItem::componentComplete();
- d->m_node.setSize(size().toSize());
- setPaintNode(&d->m_node);
+ Q_ASSERT(d->m_node == 0);
+ d->m_node = new QxPainterNode(this);
+ d->m_node->setSize(size().toSize());
+ d->m_node->setOpacity(renderOpacity());
+ d->m_node->setSmoothPainting(smooth());
+ d->m_node->setLinearFiltering(smooth());
+ d->m_node->setOpaquePainting(d->m_opaque_painting);
+ setPaintNode(d->m_node);
update();
}
@@ -116,8 +125,8 @@ void QxPaintItem::componentComplete()
void QxPaintItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QxPaintItem);
- if (newGeometry.size() != oldGeometry.size()) {
- d->m_node.setSize(newGeometry.size().toSize());
+ if (d->m_node && newGeometry.size() != oldGeometry.size()) {
+ d->m_node->setSize(newGeometry.size().toSize());
update();
}
QxItem::geometryChanged(newGeometry, oldGeometry);
@@ -129,8 +138,8 @@ void QxPaintItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGe
void QxPaintItem::renderOpacityChanged(qreal newOpacity, qreal oldOpacity)
{
Q_D(QxPaintItem);
- if (newOpacity != oldOpacity)
- d->m_node.setOpacity(newOpacity);
+ if (d->m_node && newOpacity != oldOpacity)
+ d->m_node->setOpacity(newOpacity);
QxItem::renderOpacityChanged(newOpacity, oldOpacity);
}
@@ -140,9 +149,9 @@ void QxPaintItem::renderOpacityChanged(qreal newOpacity, qreal oldOpacity)
void QxPaintItem::smoothChange(bool newSmooth, bool oldSmooth)
{
Q_D(QxPaintItem);
- if (newSmooth != oldSmooth) {
- d->m_node.setSmoothPainting(newSmooth);
- d->m_node.setLinearFiltering(newSmooth);
+ if (d->m_node && newSmooth != oldSmooth) {
+ d->m_node->setSmoothPainting(newSmooth);
+ d->m_node->setLinearFiltering(newSmooth);
update();
}
QxItem::smoothChange(newSmooth, oldSmooth);
@@ -163,7 +172,8 @@ void QxPaintItem::setOpaquePainting(bool opaque)
if (opaque == d->m_opaque_painting)
return;
d->m_opaque_painting = opaque;
- d->m_node.updateTexture();
+ if (d->m_node)
+ d->m_node->setOpaquePainting(d->m_opaque_painting);
}
/*!
diff --git a/src/graphicsitems/qxpaintitem_p.h b/src/graphicsitems/qxpaintitem_p.h
index c40e1cd..37efcc8 100644
--- a/src/graphicsitems/qxpaintitem_p.h
+++ b/src/graphicsitems/qxpaintitem_p.h
@@ -52,8 +52,9 @@ class QxPaintItemPrivate : public QxItemPrivate
public:
QxPaintItemPrivate();
+ ~QxPaintItemPrivate();
- QxPainterNode m_node;
+ QxPainterNode *m_node;
bool m_opaque_painting;
bool m_dirty;