void QQuickShapeRadialGradientShader::updateState(const RenderState &state, QSGMaterial *mat, QSGMaterial *) { QQuickShapeRadialGradientMaterial *m = static_cast<QQuickShapeRadialGradientMaterial *>(mat); if (state.isOpacityDirty()) program()->setUniformValue(m_opacityLoc, state.opacity()); if (state.isMatrixDirty()) program()->setUniformValue(m_matrixLoc, state.combinedMatrix()); QQuickShapeGenericStrokeFillNode *node = m->node(); const QPointF centerPoint = node->m_fillGradient.a; const QPointF focalPoint = node->m_fillGradient.b; const QPointF focalToCenter = centerPoint - focalPoint; const GLfloat centerRadius = node->m_fillGradient.v0; const GLfloat focalRadius = node->m_fillGradient.v1; program()->setUniformValue(m_translationPointLoc, focalPoint); program()->setUniformValue(m_centerRadiusLoc, centerRadius); program()->setUniformValue(m_focalRadiusLoc, focalRadius); program()->setUniformValue(m_focalToCenterLoc, focalToCenter); const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread); QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey); tx->bind(); }
void QSGContext::textureFactoryDestroyed(QObject *o) { Q_D(QSGContext); QQuickTextureFactory *f = static_cast<QQuickTextureFactory *>(o); d->textureMutex.lock(); QSGTexture *t = d->textures.take(f); d->textureMutex.unlock(); if (t) { if (t->thread() == thread()) t->deleteLater(); else QCoreApplication::postEvent(this, new QSGTextureCleanupEvent(t)); } }
void QQuickTextNode::addImage(const QRectF &rect, const QImage &image) { QSGRenderContext *sg = QQuickItemPrivate::get(m_ownerElement)->sceneGraphRenderContext(); QSGInternalImageNode *node = sg->sceneGraphContext()->createInternalImageNode(); QSGTexture *texture = sg->createTexture(image); if (m_ownerElement->smooth()) texture->setFiltering(QSGTexture::Linear); m_textures.append(texture); node->setTargetRect(rect); node->setInnerTargetRect(rect); node->setTexture(texture); if (m_ownerElement->smooth()) node->setFiltering(QSGTexture::Linear); appendChildNode(node); node->update(); }
void QQuickShapeLinearGradientShader::updateState(const RenderState &state, QSGMaterial *mat, QSGMaterial *) { QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(mat); if (state.isOpacityDirty()) program()->setUniformValue(m_opacityLoc, state.opacity()); if (state.isMatrixDirty()) program()->setUniformValue(m_matrixLoc, state.combinedMatrix()); QQuickShapeGenericStrokeFillNode *node = m->node(); program()->setUniformValue(m_gradStartLoc, QVector2D(node->m_fillGradient.a)); program()->setUniformValue(m_gradEndLoc, QVector2D(node->m_fillGradient.b)); const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread); QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey); tx->bind(); }
void QQuickShapeConicalGradientShader::updateState(const RenderState &state, QSGMaterial *mat, QSGMaterial *) { QQuickShapeConicalGradientMaterial *m = static_cast<QQuickShapeConicalGradientMaterial *>(mat); if (state.isOpacityDirty()) program()->setUniformValue(m_opacityLoc, state.opacity()); if (state.isMatrixDirty()) program()->setUniformValue(m_matrixLoc, state.combinedMatrix()); QQuickShapeGenericStrokeFillNode *node = m->node(); const QPointF centerPoint = node->m_fillGradient.a; const GLfloat angle = -qDegreesToRadians(node->m_fillGradient.v0); program()->setUniformValue(m_angleLoc, angle); program()->setUniformValue(m_translationPointLoc, centerPoint); const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, QQuickShapeGradient::RepeatSpread); QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey); tx->bind(); }
// ImageLayerNode ImageLayerNode::ImageLayerNode(QQuickWindow *window, const QString file, bool mirroredType) { QImage image(file); // NOTE this is a workaround to get the mirrored effect at the end of the image // ideally, do it using the shader program if (mirroredType) { QImage tempImage(image.width() * 2, image.height(), QImage::Format_ARGB32); QPainter p(&tempImage); p.drawImage(0, 0, image); p.drawImage(image.width(), 0, image.mirrored(true, false)); p.end(); image = tempImage; } QSGTexture *texture = window->createTextureFromImage(image); texture->setHorizontalWrapMode(QSGTexture::Repeat); texture->setVerticalWrapMode(QSGTexture::Repeat); texture->setFiltering(QSGTexture::Linear); m_width = texture->textureSize().width(); m_height = texture->textureSize().height(); QSGSimpleMaterial<ImageLayerState> *m = ImageLayerShader::createMaterial(); m->state()->texture = texture; setMaterial(m); setFlag(OwnsMaterial, true); updateXPos(0); updateYPos(0); QSGGeometry *g = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4); QSGGeometry::updateTexturedRectGeometry(g, QRect(), QRect()); setGeometry(g); setFlag(OwnsGeometry, true); }
QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { Q_D(QQuickImage); QSGTexture *texture = d->sceneGraphRenderContext()->textureForFactory(d->pix.textureFactory(), window()); // Copy over the current texture state into the texture provider... if (d->provider) { d->provider->m_smooth = d->smooth; d->provider->m_mipmap = d->mipmap; d->provider->updateTexture(texture); } if (!texture || width() <= 0 || height() <= 0) { delete oldNode; return 0; } QSGImageNode *node = static_cast<QSGImageNode *>(oldNode); if (!node) { d->pixmapChanged = true; node = d->sceneGraphContext()->createImageNode(); } QRectF targetRect; QRectF sourceRect; QSGTexture::WrapMode hWrap = QSGTexture::ClampToEdge; QSGTexture::WrapMode vWrap = QSGTexture::ClampToEdge; qreal pixWidth = (d->fillMode == PreserveAspectFit) ? d->paintedWidth : d->pix.width() / d->devicePixelRatio; qreal pixHeight = (d->fillMode == PreserveAspectFit) ? d->paintedHeight : d->pix.height() / d->devicePixelRatio; int xOffset = 0; if (d->hAlign == QQuickImage::AlignHCenter) xOffset = qCeil((width() - pixWidth) / 2.); else if (d->hAlign == QQuickImage::AlignRight) xOffset = qCeil(width() - pixWidth); int yOffset = 0; if (d->vAlign == QQuickImage::AlignVCenter) yOffset = qCeil((height() - pixHeight) / 2.); else if (d->vAlign == QQuickImage::AlignBottom) yOffset = qCeil(height() - pixHeight); switch (d->fillMode) { default: case Stretch: targetRect = QRectF(0, 0, width(), height()); sourceRect = d->pix.rect(); break; case PreserveAspectFit: targetRect = QRectF(xOffset, yOffset, d->paintedWidth, d->paintedHeight); sourceRect = d->pix.rect(); break; case PreserveAspectCrop: { targetRect = QRect(0, 0, width(), height()); qreal wscale = width() / qreal(d->pix.width()); qreal hscale = height() / qreal(d->pix.height()); if (wscale > hscale) { int src = (hscale / wscale) * qreal(d->pix.height()); int y = 0; if (d->vAlign == QQuickImage::AlignVCenter) y = qCeil((d->pix.height() - src) / 2.); else if (d->vAlign == QQuickImage::AlignBottom) y = qCeil(d->pix.height() - src); sourceRect = QRectF(0, y, d->pix.width(), src); } else { int src = (wscale / hscale) * qreal(d->pix.width()); int x = 0; if (d->hAlign == QQuickImage::AlignHCenter) x = qCeil((d->pix.width() - src) / 2.); else if (d->hAlign == QQuickImage::AlignRight) x = qCeil(d->pix.width() - src); sourceRect = QRectF(x, 0, src, d->pix.height()); } } break; case Tile: targetRect = QRectF(0, 0, width(), height()); sourceRect = QRectF(-xOffset, -yOffset, width(), height()); hWrap = QSGTexture::Repeat; vWrap = QSGTexture::Repeat; break; case TileHorizontally: targetRect = QRectF(0, 0, width(), height()); sourceRect = QRectF(-xOffset, 0, width(), d->pix.height()); hWrap = QSGTexture::Repeat; break; case TileVertically: targetRect = QRectF(0, 0, width(), height()); sourceRect = QRectF(0, -yOffset, d->pix.width(), height()); vWrap = QSGTexture::Repeat; break; case Pad: qreal w = qMin(qreal(d->pix.width()), width()); qreal h = qMin(qreal(d->pix.height()), height()); qreal x = (d->pix.width() > width()) ? -xOffset : 0; qreal y = (d->pix.height() > height()) ? -yOffset : 0; targetRect = QRectF(x + xOffset, y + yOffset, w, h); sourceRect = QRectF(x, y, w, h); break; }; qreal nsWidth = (hWrap == QSGTexture::Repeat) ? d->pix.width() / d->devicePixelRatio : d->pix.width(); qreal nsHeight = (vWrap == QSGTexture::Repeat) ? d->pix.height() / d->devicePixelRatio : d->pix.height(); QRectF nsrect(sourceRect.x() / nsWidth, sourceRect.y() / nsHeight, sourceRect.width() / nsWidth, sourceRect.height() / nsHeight); if (targetRect.isEmpty() || !qIsFinite(targetRect.width()) || !qIsFinite(targetRect.height()) || nsrect.isEmpty() || !qIsFinite(nsrect.width()) || !qIsFinite(nsrect.height())) { delete node; return 0; } if (d->pixmapChanged) { // force update the texture in the node to trigger reconstruction of // geometry and the likes when a atlas segment has changed. if (texture->isAtlasTexture() && (hWrap == QSGTexture::Repeat || vWrap == QSGTexture::Repeat || d->mipmap)) node->setTexture(texture->removedFromAtlas()); else node->setTexture(texture); d->pixmapChanged = false; } node->setMipmapFiltering(d->mipmap ? QSGTexture::Linear : QSGTexture::None); node->setHorizontalWrapMode(hWrap); node->setVerticalWrapMode(vWrap); node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest); node->setTargetRect(targetRect); node->setInnerTargetRect(targetRect); node->setSubSourceRect(nsrect); node->setMirror(d->mirror); node->setAntialiasing(d->antialiasing); node->update(); return node; }