A few fixes to prevent compositor crashes
[profile/ivi/qtwayland.git] / src / compositor / compositor_api / waylandsurfacenode.cpp
1 #include "waylandsurfacenode.h"
2 #include "waylandsurfaceitem.h"
3
4 #include <QtCore/QMutexLocker>
5 #include <QtQuick/QSGTexture>
6 #include <QtQuick/QSGSimpleTextureNode>
7 #include <QtQuick/QSGFlatColorMaterial>
8
9 WaylandSurfaceNode::WaylandSurfaceNode(WaylandSurfaceItem *item)
10     : m_item(item)
11     , m_textureUpdated(false)
12     , m_useTextureAlpha(false)
13     , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
14 {
15     m_textureMaterial = WaylandSurfaceTextureMaterial::createMaterial();
16     m_opaqueTextureMaterial = WaylandSurfaceTextureOpaqueMaterial::createMaterial();
17
18     m_currentMaterial = m_opaqueTextureMaterial;
19
20     setGeometry(&m_geometry);
21     setMaterial(m_currentMaterial);
22
23     if (m_item)
24         m_item->m_node = this;
25     setFlag(UsePreprocess,true);
26 }
27
28
29 WaylandSurfaceNode::~WaylandSurfaceNode()
30 {
31     QMutexLocker locker(WaylandSurfaceItem::mutex);
32     if (m_item)
33         m_item->m_node = 0;
34     delete m_textureMaterial;
35     delete m_opaqueTextureMaterial;
36 }
37
38 void WaylandSurfaceNode::preprocess()
39 {
40     QMutexLocker locker(WaylandSurfaceItem::mutex);
41
42     if (m_item && m_item->surface()) {
43         //Update if the item is dirty and we haven't done an updateTexture for this frame
44         if (m_item->m_damaged && !m_textureUpdated) {
45             m_item->updateTexture();
46             updateTexture();
47         }
48     }
49     //Reset value for next frame: we have not done updatePaintNode yet
50     m_textureUpdated = false;
51 }
52
53 void WaylandSurfaceNode::updateTexture()
54 {
55     Q_ASSERT(m_item && m_item->textureProvider());
56
57     //If m_item->useTextureAlpha has changed to true use m_texureMaterial
58     //otherwise use m_opaqueTextureMaterial.
59     if (m_item->useTextureAlpha() != m_useTextureAlpha) {
60         m_useTextureAlpha = m_item->useTextureAlpha();
61         if (m_useTextureAlpha) {
62             m_currentMaterial = m_textureMaterial;
63         } else {
64             m_currentMaterial = m_opaqueTextureMaterial;
65         }
66         setMaterial(m_currentMaterial);
67     }
68
69     QSGTexture *texture = m_item->textureProvider()->texture();
70     setTexture(texture);
71 }
72
73 void WaylandSurfaceNode::setRect(const QRectF &rect)
74 {
75     if (m_rect == rect)
76         return;
77     m_rect = rect;
78
79     if (texture()) {
80         QSize ts = texture()->textureSize();
81         QRectF sourceRect(0, 0, ts.width(), ts.height());
82         QSGGeometry::updateTexturedRectGeometry(&m_geometry, m_rect, texture()->convertToNormalizedSourceRect(sourceRect));
83     }
84 }
85
86 void WaylandSurfaceNode::setTexture(QSGTexture *texture)
87 {
88     if (m_currentMaterial->state()->texture() == texture)
89         return;
90     m_currentMaterial->state()->setTexture(texture);
91
92     QSize ts = texture->textureSize();
93     QRectF sourceRect(0, 0, ts.width(), ts.height());
94     QSGGeometry::updateTexturedRectGeometry(&m_geometry, m_rect, texture->convertToNormalizedSourceRect(sourceRect));
95     markDirty(DirtyMaterial);
96 }
97
98 QSGTexture *WaylandSurfaceNode::texture() const
99 {
100     return m_currentMaterial->state()->texture();
101 }
102
103 void WaylandSurfaceNode::setItem(WaylandSurfaceItem *item)
104 {
105     m_item = item;
106 }