BatchCompatibility Batch::isMaterialCompatible(Element *e) const
{
- // If material has changed between opaque and translucent, it is not compatible
- QSGMaterial *m = e->node->activeMaterial();
- if (isOpaque != ((m->flags() & QSGMaterial::Blending) == 0))
- return BatchBreaksOnBlending;
-
Element *n = first;
// Skip to the first node other than e which has not been removed
while (n && (n == e || n->removed))
if (!n)
return BatchIsCompatible;
+ QSGMaterial *m = e->node->activeMaterial();
QSGMaterial *nm = n->node->activeMaterial();
return (nm->type() == m->type() && nm->compare(m) == 0)
? BatchIsCompatible
if (state & QSGNode::DirtyMaterial && node->type() == QSGNode::GeometryNodeType) {
Element *e = shadowNode->element();
if (e) {
- if (e->batch) {
- BatchCompatibility compat = e->batch->isMaterialCompatible(e);
- if (compat == BatchBreaksOnBlending)
- m_rebuild |= Renderer::FullRebuild;
- else if (compat == BatchBreaksOnCompare)
+ bool blended = hasMaterialWithBlending(static_cast<QSGGeometryNode *>(node));
+ if (e->isMaterialBlended != blended) {
+ m_rebuild |= Renderer::FullRebuild;
+ e->isMaterialBlended = blended;
+ } else if (e->batch) {
+ if (e->batch->isMaterialCompatible(e) == BatchBreaksOnCompare)
invalidateBatchAndOverlappingRenderOrders(e->batch);
} else {
m_rebuild |= Renderer::BuildBatches;
class Renderer;
class ShaderManager;
+inline bool hasMaterialWithBlending(QSGGeometryNode *n)
+{
+ return (n->opaqueMaterial() ? n->opaqueMaterial()->flags() & QSGMaterial::Blending
+ : n->material()->flags() & QSGMaterial::Blending);
+}
+
struct Pt {
float x, y;
, removed(false)
, orphaned(false)
, isRenderNode(false)
+ , isMaterialBlended(n ? hasMaterialWithBlending(n) : false)
{
}
uint removed : 1;
uint orphaned : 1;
uint isRenderNode : 1;
+ uint isMaterialBlended : 1;
};
struct RenderNodeElement : public Element {
enum BatchCompatibility
{
- BatchBreaksOnBlending,
BatchBreaksOnCompare,
BatchIsCompatible
};