diff options
Diffstat (limited to 'src/quick/items/qquickpainteditem.cpp')
-rw-r--r-- | src/quick/items/qquickpainteditem.cpp | 126 |
1 files changed, 94 insertions, 32 deletions
diff --git a/src/quick/items/qquickpainteditem.cpp b/src/quick/items/qquickpainteditem.cpp index 8d93c577ab..ad8d94d240 100644 --- a/src/quick/items/qquickpainteditem.cpp +++ b/src/quick/items/qquickpainteditem.cpp @@ -67,15 +67,11 @@ public: To enable QPainter to do anti-aliased rendering, use setAntialiasing(). - To write your own painted item, you first create a subclass of QQuickPaintedItem, and then - start by implementing its only pure virtual public function: paint(), which implements - the actual painting. To get the size of the area painted by the item, use - contentsBoundingRect(). - - Starting Qt 5.4, the QQuickPaintedItem is a - \l{QSGTextureProvider}{texture provider} - and can be used directly in \l {ShaderEffect}{ShaderEffects} and other - classes that consume texture providers. + To write your own painted item, you first create a subclass of + QQuickPaintedItem, and then start by implementing its only pure virtual + public function: paint(), which implements the actual painting. The + painting will be inside the rectangle spanning from 0,0 to + width(),height(). */ /*! @@ -109,11 +105,12 @@ public: This enum describes flags that you can enable to improve rendering performance in QQuickPaintedItem. By default, none of these flags are set. - \value FastFBOResizing If your item gets resized often and you are using the - QQuickPaintedItem::FramebufferObject render target, set this flag to true to reduce the - item resizing time at the cost of using more graphics memory. Resizing a Framebuffer object - is a costly operation, by enabling this property the Framebuffer Object will use a texture - larger than the actual size of the item to avoid as much as possible resizing it. + \value FastFBOResizing Resizing an FBO can be a costly operation on a few + OpenGL driver implementations. To work around this, one can set this flag + to let the QQuickPaintedItem allocate one large framebuffer object and + instead draw into a subregion of it. This saves the resize at the cost of + using more memory. Please note that this is not a common problem. + */ /*! @@ -332,16 +329,47 @@ void QQuickPaintedItem::setPerformanceHints(QQuickPaintedItem::PerformanceHints update(); } +QSize QQuickPaintedItem::textureSize() const +{ + Q_D(const QQuickPaintedItem); + return d->textureSize; +} + /*! - This function returns the outer bounds of the item as a rectangle; all painting must be - restricted to inside an item's bounding rect. + \property QQuickPaintedItem::textureSize + + \brief Defines the size of the texture. + + Changing the texture's size does not affect the coordinate system used in + paint(). A scale factor is instead applied so painting should still happen + inside 0,0 to width(),height(). + + By default, the texture size will have the same size as this item. + + \note If the item is on a window with a device pixel ratio different from + 1, this scale factor will be implicitly applied to the texture size. + + */ +void QQuickPaintedItem::setTextureSize(const QSize &size) +{ + Q_D(QQuickPaintedItem); + if (d->textureSize == size) + return; + d->textureSize = size; + emit textureSizeChanged(); +} + +#if QT_VERSION >= 0x060000 +#warning "Remove: QQuickPaintedItem::contentsBoundingRect, contentsScale, contentsSize. Also remove them from qsgadaptationlayer_p.h and qsgdefaultpainternode.h/cpp." +#endif - If the contents size has not been set it reflects the size of the item; otherwise - it reflects the contents size scaled by the contents scale. +/*! + \obsolete - Use this function to know the area painted by the item. + This function is provided for compatibility, use size in combination + with textureSize to decide the size of what you are drawing. - \sa QQuickItem::width(), QQuickItem::height(), contentsSize(), contentsScale() + \sa width(), height(), textureSize() */ QRectF QQuickPaintedItem::contentsBoundingRect() const { @@ -360,11 +388,13 @@ QRectF QQuickPaintedItem::contentsBoundingRect() const /*! \property QQuickPaintedItem::contentsSize - \brief The size of the contents + \brief Obsolete method for setting the contents size. + \obsolete - The contents size is the size of the item in regards to how it is painted - using the paint() function. This is distinct from the size of the - item in regards to height() and width(). + This function is provided for compatibility, use size in combination + with textureSize to decide the size of what you are drawing. + + \sa width(), height(), textureSize() */ QSize QQuickPaintedItem::contentsSize() const { @@ -386,6 +416,7 @@ void QQuickPaintedItem::setContentsSize(const QSize &size) } /*! + \obsolete This convenience function is equivalent to calling setContentsSize(QSize()). */ void QQuickPaintedItem::resetContentsSize() @@ -395,12 +426,13 @@ void QQuickPaintedItem::resetContentsSize() /*! \property QQuickPaintedItem::contentsScale - \brief The scale of the contents + \brief Obsolete method for scaling the contents. + \obsolete - All painting happening in paint() is scaled by the contents scale. This is distinct - from the scale of the item in regards to scale(). + This function is provided for compatibility, use size() in combination + with textureSize() to decide the size of what you are drawing. - The default value is 1. + \sa width(), height(), textureSize() */ qreal QQuickPaintedItem::contentsScale() const { @@ -451,7 +483,7 @@ void QQuickPaintedItem::setFillColor(const QColor &c) \brief The item's render target. This property defines which render target the QPainter renders into, it can be either - QSGPaintedItem::Image, QSGPaintedItem::FramebufferObject or QSGPaintedItem::InvertedYFramebufferObject. + QQuickPaintedItem::Image, QQuickPaintedItem::FramebufferObject or QQuickPaintedItem::InvertedYFramebufferObject. Each has certain benefits, typically performance versus quality. Using a framebuffer object avoids a costly upload of the image contents to the texture in graphics memory, @@ -487,6 +519,9 @@ void QQuickPaintedItem::setRenderTarget(RenderTarget target) This function, which is usually called by the QML Scene Graph, paints the contents of an item in local coordinates. + The underlying texture will have a size defined by textureSize when set, + or the item's size, multiplied by the window's device pixel ratio. + The function is called after the item has been filled with the fillColor. Reimplement this function in a QQuickPaintedItem subclass to provide the @@ -500,6 +535,8 @@ void QQuickPaintedItem::setRenderTarget(RenderTarget target) \warning Extreme caution must be used when creating QObjects, emitting signals, starting timers and similar inside this function as these will have affinity to the rendering thread. + + \sa width(), height(), textureSize */ /*! @@ -525,17 +562,35 @@ QSGNode *QQuickPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat d->node = node; } - QRectF br = contentsBoundingRect(); + bool hasTextureSize = d->textureSize.width() > 0 && d->textureSize.height() > 0; + + // Use the compat mode if any of the compat things are set and + // textureSize is 0x0. + if (!hasTextureSize + && (d->contentsScale != 1 + || (d->contentsSize.width() > 0 && d->contentsSize.height() > 0))) { + QRectF br = contentsBoundingRect(); + node->setContentsScale(d->contentsScale); + QSize size = QSize(qRound(br.width()), qRound(br.height())); + node->setSize(size); + node->setTextureSize(size); + } else { + // The default, use textureSize or item's size * device pixel ratio + node->setContentsScale(1); + QSize itemSize(qRound(width()), qRound(height())); + node->setSize(itemSize); + QSize textureSize = (hasTextureSize ? d->textureSize : itemSize) + * window()->effectiveDevicePixelRatio(); + node->setTextureSize(textureSize); + } node->setPreferredRenderTarget(d->renderTarget); node->setFastFBOResizing(d->performanceHints & FastFBOResizing); - node->setSize(QSize(qRound(br.width()), qRound(br.height()))); node->setSmoothPainting(d->antialiasing); node->setLinearFiltering(d->smooth); node->setMipmapping(d->mipmap); node->setOpaquePainting(d->opaquePainting); node->setFillColor(d->fillColor); - node->setContentsScale(d->contentsScale); node->setDirty(d->dirtyRect); node->update(); @@ -583,6 +638,13 @@ bool QQuickPaintedItem::isTextureProvider() const */ QSGTextureProvider *QQuickPaintedItem::textureProvider() const { + // When Item::layer::enabled == true, QQuickItem will be a texture + // provider. In this case we should prefer to return the layer rather + // than the image itself. The layer will include any children and any + // the image's wrap and fill mode. + if (QQuickItem::isTextureProvider()) + return QQuickItem::textureProvider(); + Q_D(const QQuickPaintedItem); QQuickWindow *w = window(); if (!w || !w->openglContext() || QThread::currentThread() != w->openglContext()->thread()) { |