1 | // Copyright (C) 2016 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qopenglcustomshaderstage_p.h" |
5 | #include "qopenglengineshadermanager_p.h" |
6 | #include "qopenglpaintengine_p.h" |
7 | #include <private/qpainter_p.h> |
8 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | class QOpenGLCustomShaderStagePrivate |
12 | { |
13 | public: |
14 | QOpenGLCustomShaderStagePrivate() : |
15 | m_manager(nullptr) {} |
16 | |
17 | QPointer<QOpenGLEngineShaderManager> m_manager; |
18 | QByteArray m_source; |
19 | }; |
20 | |
21 | |
22 | |
23 | |
24 | QOpenGLCustomShaderStage::QOpenGLCustomShaderStage() |
25 | : d_ptr(new QOpenGLCustomShaderStagePrivate) |
26 | { |
27 | } |
28 | |
29 | QOpenGLCustomShaderStage::~QOpenGLCustomShaderStage() |
30 | { |
31 | Q_D(QOpenGLCustomShaderStage); |
32 | if (d->m_manager) { |
33 | d->m_manager->removeCustomStage(); |
34 | d->m_manager->sharedShaders->cleanupCustomStage(stage: this); |
35 | } |
36 | delete d_ptr; |
37 | } |
38 | |
39 | void QOpenGLCustomShaderStage::setUniformsDirty() |
40 | { |
41 | Q_D(QOpenGLCustomShaderStage); |
42 | if (d->m_manager) |
43 | d->m_manager->setDirty(); // ### Probably a bit overkill! |
44 | } |
45 | |
46 | bool QOpenGLCustomShaderStage::setOnPainter(QPainter* p) |
47 | { |
48 | Q_D(QOpenGLCustomShaderStage); |
49 | if (p->paintEngine()->type() != QPaintEngine::OpenGL2) { |
50 | qWarning(msg: "QOpenGLCustomShaderStage::setOnPainter() - paint engine not OpenGL2"); |
51 | return false; |
52 | } |
53 | if (d->m_manager) |
54 | qWarning(msg: "Custom shader is already set on a painter"); |
55 | |
56 | QOpenGL2PaintEngineEx *engine = static_cast<QOpenGL2PaintEngineEx*>(p->paintEngine()); |
57 | d->m_manager = QOpenGL2PaintEngineExPrivate::shaderManagerForEngine(engine); |
58 | Q_ASSERT(d->m_manager); |
59 | |
60 | d->m_manager->setCustomStage(this); |
61 | return true; |
62 | } |
63 | |
64 | void QOpenGLCustomShaderStage::removeFromPainter(QPainter* p) |
65 | { |
66 | Q_D(QOpenGLCustomShaderStage); |
67 | if (p->paintEngine()->type() != QPaintEngine::OpenGL2) |
68 | return; |
69 | |
70 | QOpenGL2PaintEngineEx *engine = static_cast<QOpenGL2PaintEngineEx*>(p->paintEngine()); |
71 | d->m_manager = QOpenGL2PaintEngineExPrivate::shaderManagerForEngine(engine); |
72 | Q_ASSERT(d->m_manager); |
73 | |
74 | // Just set the stage to null, don't call removeCustomStage(). |
75 | // This should leave the program in a compiled/linked state |
76 | // if the next custom shader stage is this one again. |
77 | d->m_manager->setCustomStage(nullptr); |
78 | d->m_manager = nullptr; |
79 | } |
80 | |
81 | QByteArray QOpenGLCustomShaderStage::source() const |
82 | { |
83 | Q_D(const QOpenGLCustomShaderStage); |
84 | return d->m_source; |
85 | } |
86 | |
87 | // Called by the shader manager if another custom shader is attached or |
88 | // the manager is deleted |
89 | void QOpenGLCustomShaderStage::setInactive() |
90 | { |
91 | Q_D(QOpenGLCustomShaderStage); |
92 | d->m_manager = nullptr; |
93 | } |
94 | |
95 | void QOpenGLCustomShaderStage::setSource(const QByteArray& s) |
96 | { |
97 | Q_D(QOpenGLCustomShaderStage); |
98 | d->m_source = s; |
99 | } |
100 | |
101 | QT_END_NAMESPACE |
102 |