qml: handle multiple items with different input formats

Issue was that Qt was caching multiple different shadersbased on a static
variable location.  This static variable location was the same no matter
the input video format and so if an item had an input video format of
RGB and another of RGBA, they would eventually end up using the same
GL shader leading to incorrect colours.

Fix by providing different static variable locations for each of the
different shaders that will be produced.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5145>
This commit is contained in:
Matthew Waters 2023-08-04 13:02:21 +10:00 committed by GStreamer Marge Bot
parent 501e53b033
commit 8a7614e814
3 changed files with 35 additions and 4 deletions

View file

@ -173,6 +173,36 @@ GstQSGMaterialShader::fragmentShader() const
return fragment;
}
#define DEFINE_MATERIAL(format) \
class G_PASTE(GstQSGMaterial_,format) : public GstQSGMaterial { \
public: \
G_PASTE(GstQSGMaterial_,format)(); \
~G_PASTE(GstQSGMaterial_,format)(); \
QSGMaterialType *type() const override { static QSGMaterialType type; return &type; }; \
}; \
G_PASTE(GstQSGMaterial_,format)::G_PASTE(GstQSGMaterial_,format)() {} \
G_PASTE(GstQSGMaterial_,format)::~G_PASTE(GstQSGMaterial_,format)() {}
DEFINE_MATERIAL(RGBA);
DEFINE_MATERIAL(RGBA_SWIZZLE);
DEFINE_MATERIAL(YUV_TRIPLANAR);
GstQSGMaterial *
GstQSGMaterial::new_for_format(GstVideoFormat format)
{
switch (format) {
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_RGBA:
return static_cast<GstQSGMaterial *>(new GstQSGMaterial_RGBA());
case GST_VIDEO_FORMAT_BGRA:
return static_cast<GstQSGMaterial *>(new GstQSGMaterial_RGBA_SWIZZLE());
case GST_VIDEO_FORMAT_YV12:
return static_cast<GstQSGMaterial *>(new GstQSGMaterial_YUV_TRIPLANAR());
default:
g_assert_not_reached ();
}
}
GstQSGMaterial::GstQSGMaterial ()
{
static gsize _debug;

View file

@ -35,9 +35,11 @@ class GstQSGMaterialShader;
class GstQSGMaterial : public QSGMaterial
{
protected:
GstQSGMaterial();
~GstQSGMaterial();
public:
GstQSGMaterial ();
~GstQSGMaterial ();
static GstQSGMaterial *new_for_format (GstVideoFormat format);
void setCaps (GstCaps * caps);
gboolean setBuffer (GstBuffer * buffer);
@ -47,7 +49,6 @@ public:
void bind(GstQSGMaterialShader *);
/* QSGMaterial */
QSGMaterialType *type() const override { static QSGMaterialType type; return &type; };
QSGMaterialShader *createShader() const override;
private:

View file

@ -314,7 +314,7 @@ QtGLVideoItem::updatePaintNode(QSGNode * oldNode,
texNode = new QSGGeometryNode();
geometry = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4);
texNode->setGeometry(geometry);
tex = new GstQSGMaterial();
tex = GstQSGMaterial::new_for_format(GST_VIDEO_INFO_FORMAT (&this->priv->v_info));
texNode->setMaterial(tex);
}