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