1 /*
2     SPDX-FileCopyrightText: 2013 Digia Plc and /or its subsidiary(-ies).
3     SPDX-FileCopyrightText: 2013 basysKom GmbH <info@basyskom.com>
4     SPDX-FileCopyrightText: 2013 Collabora Ltd. <info@collabora.com>
5 
6     SPDX-License-Identifier: LGPL-2.1-only
7 */
8 
9 #include "videonode.h"
10 #include "videomaterial.h"
11 
12 #include <QtQuick/QSGFlatColorMaterial>
13 
VideoNode()14 VideoNode::VideoNode()
15   : QSGGeometryNode()
16   , m_validGeometry(false)
17 {
18     setFlags(OwnsGeometry | OwnsMaterial, true);
19     setMaterialTypeSolidBlack();
20 }
21 
changeFormat(const BufferFormat & format)22 void VideoNode::changeFormat(const BufferFormat & format)
23 {
24     setMaterial(VideoMaterial::create(format));
25     m_materialType = MaterialTypeVideo;
26     m_validGeometry = false;
27 }
28 
setMaterialTypeSolidBlack()29 void VideoNode::setMaterialTypeSolidBlack()
30 {
31     QSGFlatColorMaterial *m = new QSGFlatColorMaterial;
32     m->setColor(Qt::black);
33     setMaterial(m);
34     m_materialType = MaterialTypeSolidBlack;
35     m_validGeometry = false;
36 }
37 
setCurrentFrame(GstBuffer * buffer)38 void VideoNode::setCurrentFrame(GstBuffer* buffer)
39 {
40     Q_ASSERT (m_materialType == MaterialTypeVideo);
41     static_cast<VideoMaterial*>(material())->setCurrentFrame(buffer);
42     markDirty(DirtyMaterial);
43 }
44 
updateColors(int brightness,int contrast,int hue,int saturation)45 void VideoNode::updateColors(int brightness, int contrast, int hue, int saturation)
46 {
47     Q_ASSERT (m_materialType == MaterialTypeVideo);
48     static_cast<VideoMaterial*>(material())->updateColors(brightness, contrast, hue, saturation);
49     markDirty(DirtyMaterial);
50 }
51 
52 /* Helpers */
53 template <typename V>
setGeom(V * v,const QPointF & p)54 static inline void setGeom(V *v, const QPointF &p)
55 {
56     v->x = p.x();
57     v->y = p.y();
58 }
59 
setTex(QSGGeometry::TexturedPoint2D * v,const QPointF & p)60 static inline void setTex(QSGGeometry::TexturedPoint2D *v, const QPointF &p)
61 {
62     v->tx = p.x();
63     v->ty = p.y();
64 }
65 
updateGeometry(const PaintAreas & areas)66 void VideoNode::updateGeometry(const PaintAreas & areas)
67 {
68     QSGGeometry *g = geometry();
69 
70     if (m_materialType == MaterialTypeVideo) {
71         if (!m_validGeometry)
72             g = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4);
73 
74         QSGGeometry::TexturedPoint2D *v = g->vertexDataAsTexturedPoint2D();
75 
76         // Set geometry first
77         setGeom(v + 0, areas.videoArea.topLeft());
78         setGeom(v + 1, areas.videoArea.bottomLeft());
79         setGeom(v + 2, areas.videoArea.topRight());
80         setGeom(v + 3, areas.videoArea.bottomRight());
81 
82         // and then texture coordinates
83         setTex(v + 0, areas.sourceRect.topLeft());
84         setTex(v + 1, areas.sourceRect.bottomLeft());
85         setTex(v + 2, areas.sourceRect.topRight());
86         setTex(v + 3, areas.sourceRect.bottomRight());
87     } else {
88         if (!m_validGeometry)
89             g = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
90 
91         QSGGeometry::Point2D *v = g->vertexDataAsPoint2D();
92 
93         setGeom(v + 0, areas.videoArea.topLeft());
94         setGeom(v + 1, areas.videoArea.bottomLeft());
95         setGeom(v + 2, areas.videoArea.topRight());
96         setGeom(v + 3, areas.videoArea.bottomRight());
97     }
98 
99     if (!m_validGeometry) {
100         setGeometry(g);
101         m_validGeometry = true;
102     }
103 
104     markDirty(DirtyGeometry);
105 }
106