Introduce the FrameSvgItem fastPath alternative, opt out of it on overlays
Fallback to the old code if there's something not (yet?) handled by the new implementation. This way we get to optimize for the the common use-case without breaking former, complex, code-paths. Reviewed by David Edmundson
This commit is contained in:
parent
cbe13ac765
commit
a4e3569bbd
@ -157,7 +157,8 @@ bool FrameSvgItemMargins::isFixed() const
|
|||||||
FrameSvgItem::FrameSvgItem(QQuickItem *parent)
|
FrameSvgItem::FrameSvgItem(QQuickItem *parent)
|
||||||
: QQuickItem(parent),
|
: QQuickItem(parent),
|
||||||
m_textureChanged(false),
|
m_textureChanged(false),
|
||||||
m_sizeChanged(false)
|
m_sizeChanged(false),
|
||||||
|
m_fastPath(true)
|
||||||
{
|
{
|
||||||
m_frameSvg = new Plasma::FrameSvg(this);
|
m_frameSvg = new Plasma::FrameSvg(this);
|
||||||
m_margins = new FrameSvgItemMargins(m_frameSvg, this);
|
m_margins = new FrameSvgItemMargins(m_frameSvg, this);
|
||||||
@ -289,6 +290,8 @@ void FrameSvgItem::doUpdate()
|
|||||||
setImplicitHeight(m_frameSvg->marginSize(Plasma::Types::TopMargin) + m_frameSvg->marginSize(Plasma::Types::BottomMargin));
|
setImplicitHeight(m_frameSvg->marginSize(Plasma::Types::TopMargin) + m_frameSvg->marginSize(Plasma::Types::BottomMargin));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasOverlay = !actualPrefix().startsWith(QLatin1String("mask-")) && m_frameSvg->hasElement(actualPrefix() % "overlay");
|
||||||
|
m_fastPath = !hasOverlay;
|
||||||
m_textureChanged = true;
|
m_textureChanged = true;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
@ -337,40 +340,62 @@ QSGNode *FrameSvgItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaint
|
|||||||
return Q_NULLPTR;
|
return Q_NULLPTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_textureChanged) {
|
if (m_fastPath) {
|
||||||
delete oldNode;
|
if (m_textureChanged) {
|
||||||
oldNode = 0;
|
delete oldNode;
|
||||||
}
|
oldNode = 0;
|
||||||
|
|
||||||
if (!oldNode) {
|
|
||||||
oldNode = new QSGNode;
|
|
||||||
|
|
||||||
new FrameItemNode(this, FrameSvg::NoBorder, oldNode); //needs to be de first, in case of composeOverBorder
|
|
||||||
new FrameItemNode(this, FrameSvg::TopBorder | FrameSvg::LeftBorder, oldNode);
|
|
||||||
new FrameItemNode(this, FrameSvg::TopBorder | FrameSvg::RightBorder, oldNode);
|
|
||||||
new FrameItemNode(this, FrameSvg::TopBorder, oldNode);
|
|
||||||
new FrameItemNode(this, FrameSvg::BottomBorder, oldNode);
|
|
||||||
new FrameItemNode(this, FrameSvg::BottomBorder | FrameSvg::LeftBorder, oldNode);
|
|
||||||
new FrameItemNode(this, FrameSvg::BottomBorder | FrameSvg::RightBorder, oldNode);
|
|
||||||
new FrameItemNode(this, FrameSvg::LeftBorder, oldNode);
|
|
||||||
new FrameItemNode(this, FrameSvg::RightBorder, oldNode);
|
|
||||||
|
|
||||||
m_sizeChanged = true;
|
|
||||||
m_textureChanged = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameData* frame = frameData();
|
|
||||||
if (frame && m_sizeChanged)
|
|
||||||
{
|
|
||||||
QRect geometry = m_frameSvg->d->contentGeometry(frame, QSize(width(), height()));
|
|
||||||
for(int i = 0; i<oldNode->childCount(); ++i) {
|
|
||||||
FrameItemNode* it = static_cast<FrameItemNode*>(oldNode->childAtIndex(i));
|
|
||||||
it->reposition(geometry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sizeChanged = false;
|
if (!oldNode) {
|
||||||
} else if(!frame) {
|
oldNode = new QSGNode;
|
||||||
qWarning() << "no frame for" << imagePath() << prefix();
|
|
||||||
|
new FrameItemNode(this, FrameSvg::NoBorder, oldNode); //needs to be de first, in case of composeOverBorder
|
||||||
|
new FrameItemNode(this, FrameSvg::TopBorder | FrameSvg::LeftBorder, oldNode);
|
||||||
|
new FrameItemNode(this, FrameSvg::TopBorder | FrameSvg::RightBorder, oldNode);
|
||||||
|
new FrameItemNode(this, FrameSvg::TopBorder, oldNode);
|
||||||
|
new FrameItemNode(this, FrameSvg::BottomBorder, oldNode);
|
||||||
|
new FrameItemNode(this, FrameSvg::BottomBorder | FrameSvg::LeftBorder, oldNode);
|
||||||
|
new FrameItemNode(this, FrameSvg::BottomBorder | FrameSvg::RightBorder, oldNode);
|
||||||
|
new FrameItemNode(this, FrameSvg::LeftBorder, oldNode);
|
||||||
|
new FrameItemNode(this, FrameSvg::RightBorder, oldNode);
|
||||||
|
|
||||||
|
m_sizeChanged = true;
|
||||||
|
m_textureChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameData* frame = frameData();
|
||||||
|
if (frame && m_sizeChanged)
|
||||||
|
{
|
||||||
|
QRect geometry = m_frameSvg->d->contentGeometry(frame, QSize(width(), height()));
|
||||||
|
for(int i = 0; i<oldNode->childCount(); ++i) {
|
||||||
|
FrameItemNode* it = static_cast<FrameItemNode*>(oldNode->childAtIndex(i));
|
||||||
|
it->reposition(geometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sizeChanged = false;
|
||||||
|
} else if(!frame) {
|
||||||
|
qWarning() << "no frame for" << imagePath() << prefix();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SVGTextureNode *textureNode = dynamic_cast<SVGTextureNode *>(oldNode);
|
||||||
|
if (!textureNode) {
|
||||||
|
delete oldNode;
|
||||||
|
textureNode = new SVGTextureNode;
|
||||||
|
textureNode->setFiltering(QSGTexture::Nearest);
|
||||||
|
m_textureChanged = true; //force updating the texture on our newly created node
|
||||||
|
oldNode = textureNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_textureChanged || m_sizeChanged) || textureNode->texture()->textureSize() != m_frameSvg->size()) {
|
||||||
|
QImage image = m_frameSvg->framePixmap().toImage();
|
||||||
|
QSGTexture *texture = window()->createTextureFromImage(image);
|
||||||
|
texture->setFiltering(QSGTexture::Nearest);
|
||||||
|
textureNode->setTexture(texture);
|
||||||
|
textureNode->setRect(0, 0, width(), height());
|
||||||
|
|
||||||
|
m_textureChanged = false;
|
||||||
|
m_sizeChanged = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldNode;
|
return oldNode;
|
||||||
|
@ -194,6 +194,7 @@ private:
|
|||||||
Units m_units;
|
Units m_units;
|
||||||
bool m_textureChanged;
|
bool m_textureChanged;
|
||||||
bool m_sizeChanged;
|
bool m_sizeChanged;
|
||||||
|
bool m_fastPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user