summaryrefslogtreecommitdiffstats
path: root/src/render/backend/renderview_p.h
blob: 029a11f62aa3c02d9550aa9db31486bef2df6646 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef QT3D_RENDER_RENDERVIEW_H
#define QT3D_RENDER_RENDERVIEW_H

#include <Qt3DRenderer/qparameter.h>
#include <Qt3DRenderer/qclearbuffer.h>
#include <Qt3DRenderer/private/renderer_p.h>
#include <Qt3DRenderer/private/rendercameralens_p.h>
#include <Qt3DRenderer/private/attachmentpack_p.h>
#include <Qt3DRenderer/private/handle_types_p.h>
#include <Qt3DRenderer/qparameter.h>

#include <Qt3DCore/qframeallocator.h>

// TODO: Move out once this is all refactored
#include <Qt3DRenderer/private/renderviewjobutils_p.h>

#include <QVector>
#include <QMutex>
#include <QColor>

QT_BEGIN_NAMESPACE

namespace Qt3D {

class QRenderPass;
class QFrameAllocator;

namespace Render {

class Renderer;
class RenderCommand;
class RenderPassFilter;
class TechniqueFilter;
class ViewportNode;
class RenderEffect;
class RenderRenderPass;

typedef QPair<ShaderUniform, QVariant> ActivePropertyContent;
typedef QPair<QString, ActivePropertyContent > ActiveProperty;

// This class is kind of analogous to RenderBin but I want to avoid trampling
// on that until we get this working

class Q_AUTOTEST_EXPORT RenderView
{
public:
    RenderView();
    ~RenderView();

    static void operator delete(void *ptr);
    static void operator delete(void *ptr, void *);

    // TODO: Add a way to specify a sort predicate for the RenderCommands
    void sort();

    void setRenderer(Renderer *renderer);
    inline void setSurfaceSize(const QSize &size) { m_surfaceSize = size; }
    inline Renderer *renderer() const { return m_renderer; }

    inline void setAllocator(QFrameAllocator *allocator)
    {
        m_allocator = allocator;
        m_data = m_allocator->allocate<InnerData>();
        // If we have a viewMatrix pointer instead of directly a QMatrix4x4 object in RenderView
        // This allows us to keep the size of RenderView smaller and avoid huge block fragmentation
        //
        // TODO: Is this worth it here. We don't have that many RenderViews to iterate over. This
        // level of memory management would be better in RenderEntity's matrices as they will
        // help cache performance during iteration
        m_data->m_viewMatrix = m_allocator->allocate<QMatrix4x4>();
    }
    inline QFrameAllocator *allocator() const { return m_allocator; }

    inline void setRenderCamera(RenderCameraLens *renderCamera) { m_data->m_renderCamera = renderCamera; }
    inline RenderCameraLens *renderCamera() const { return m_data->m_renderCamera; }

    inline void setViewMatrix(const QMatrix4x4 viewMatrix) { *(m_data->m_viewMatrix) = viewMatrix; }
    inline QMatrix4x4 viewmatrix() const { Q_ASSERT(m_data->m_viewMatrix); return *(m_data->m_viewMatrix); }

    inline void setEyePosition(const QVector3D &eyePos) { m_data->m_eyePos = eyePos; }
    inline QVector3D eyePosition() const { return m_data->m_eyePos; }

    inline void appendLayerFilter(const QStringList &layers) { m_data->m_layers << layers; }
    inline QStringList layerFilters() const { return m_data->m_layers; }

    inline void setRenderPassFilter(const RenderPassFilter *rpFilter) { m_data->m_passFilter = rpFilter; }
    inline const RenderPassFilter *renderPassFilter() const { return m_data->m_passFilter; }

    inline void setTechniqueFilter(const TechniqueFilter *filter) { m_data->m_techniqueFilter = filter; }
    inline const TechniqueFilter *techniqueFilter() const { return m_data->m_techniqueFilter; }

    inline RenderStateSet *stateSet() const { return m_stateSet; }
    void setStateSet(RenderStateSet *stateSet) { m_stateSet = stateSet; }

    inline bool noDraw() const { return m_noDraw; }
    void setNoDraw(bool noDraw) { m_noDraw = noDraw; }

    // TODO: Get rid of this overly complex memory management by splitting out the
    // InnerData as a RenderViewConfig struct. This can be created by setRenderViewConfigFromFrameGraphLeafNode
    // and passed along with the RenderView to the functions that populate the renderview
    inline void setViewport(const QRectF &vp)
    {
        if (!m_viewport) {
            Q_ASSERT(m_allocator);
            m_viewport = m_allocator->allocate<QRectF>();
            *m_viewport = QRectF(0.0f, 0.0f, 1.0f, 1.0f);
        }
        *m_viewport = vp;
    }
    inline QRectF viewport() const
    {
        if (!m_viewport) {
            Q_ASSERT(m_allocator);
            m_viewport = m_allocator->allocate<QRectF>();
            *m_viewport = QRectF(0.0f, 0.0f, 1.0f, 1.0f);
        }
        return *m_viewport;
    }

    inline void setClearColor(const QColor &c)
    {
        if (!m_clearColor) {
            Q_ASSERT(m_allocator);
            m_clearColor = m_allocator->allocate<QColor>();
            *m_clearColor = QColor(QColor::Invalid);
        }
        *m_clearColor = c;
    }
    inline QColor clearColor() const
    {
        if (!m_clearColor) {
            Q_ASSERT(m_allocator);
            m_clearColor = m_allocator->allocate<QColor>();
            *m_clearColor = QColor(QColor::Invalid);
        }
        return *m_clearColor;
    }

    inline void setClearBuffer(QClearBuffer::BufferType clearBuffer) { m_clearBuffer = clearBuffer; }
    inline QClearBuffer::BufferType clearBuffer() const { return m_clearBuffer; }

    void buildRenderCommands(RenderEntity *preprocessedTreeRoot);
    QVector<RenderCommand *> commands() const { return m_commands; }


    // This can be removed once we're 100% sure the QFrameAllocator is death proof
    void setFrameIndex(int index) { m_frameIndex = index; }
    int frameIndex() const { return m_frameIndex; }

    void addRenderAttachment(Attachment attachment) { m_attachmentPack.addAttachment(attachment); }
    const AttachmentPack &attachmentPack() const;

    void setRenderTargetHandle(HTarget renderTargetHandle) { m_renderTarget = renderTargetHandle; }
    HTarget renderTargetHandle() const { return m_renderTarget; }

    void addSortCriteria(const QList<QNodeId> &sortMethodUid) { m_data->m_sortingCriteria.append(sortMethodUid); }

    // Helps making the size of RenderView smaller
    // Contains all the data needed for the actual building of the RenderView
    // But that aren't used later by the Renderer
    struct InnerData {
        InnerData()
            : m_renderCamera(Q_NULLPTR)
            , m_techniqueFilter(Q_NULLPTR)
            , m_passFilter(Q_NULLPTR)
            , m_viewMatrix(Q_NULLPTR)
        {
        }
        RenderCameraLens *m_renderCamera;
        const TechniqueFilter *m_techniqueFilter;
        const RenderPassFilter *m_passFilter;
        QMatrix4x4 *m_viewMatrix;
        QStringList m_layers;
        QList<QNodeId> m_sortingCriteria;
        QVector3D m_eyePos;
        UniformBlockValueBuilder m_uniformBlockBuilder;
    };

private:
    void setShaderAndUniforms(RenderCommand *command, RenderRenderPass *pass, ParameterInfoList &parameters, const QMatrix4x4 &worldTransform);

    Renderer *m_renderer;
    QSize m_surfaceSize;
    QFrameAllocator *m_allocator;

    InnerData *m_data;

    mutable QColor *m_clearColor;
    mutable QRectF *m_viewport;
    HTarget m_renderTarget;
    AttachmentPack m_attachmentPack;
    QClearBuffer::BufferType m_clearBuffer;
    RenderStateSet *m_stateSet;
    bool m_noDraw;
    int m_frameIndex;

    // We do not use pointers to RenderNodes or Drawable's here so that the
    // render aspect is free to change the drawables on the next frame whilst
    // the render thread is submitting these commands.
    QVector<RenderCommand *> m_commands;

    typedef QHash<QString, QUniformValue* (RenderView::*)(const QMatrix4x4& model) const> StandardUniformsPFuncsHash;
    static StandardUniformsPFuncsHash ms_standardUniformSetters;
    static StandardUniformsPFuncsHash initializeStandardUniformSetters();
    static QStringList ms_standardAttributesNames;
    static QStringList initializeStandardAttributeNames();

    QUniformValue *modelMatrix(const QMatrix4x4& model) const;
    QUniformValue *viewMatrix(const QMatrix4x4&) const;
    QUniformValue *projectionMatrix(const QMatrix4x4 &) const;
    QUniformValue *modelViewMatrix(const QMatrix4x4 &model) const;
    QUniformValue *modelViewProjectionMatrix(const QMatrix4x4 &model) const;
    QUniformValue *inverseModelMatrix(const QMatrix4x4 &model) const;
    QUniformValue *inverseViewMatrix(const QMatrix4x4 &) const;
    QUniformValue *inverseProjectionMatrix(const QMatrix4x4 &) const;
    QUniformValue *inverseModelViewMatrix(const QMatrix4x4 &model) const;
    QUniformValue *inverseModelViewProjectionMatrix(const QMatrix4x4 &model) const;
    QUniformValue *modelNormalMatrix(const QMatrix4x4 &model) const;
    QUniformValue *modelViewNormalMatrix(const QMatrix4x4 &model) const;
    QUniformValue *viewportMatrix(const QMatrix4x4 &model) const;
    QUniformValue *inverseViewportMatrix(const QMatrix4x4 &model) const;
    QUniformValue *time(const QMatrix4x4 &model) const;

    void setUniformValue(QUniformPack &uniformPack, const QString &name, const QVariant &value);
    void setUniformBlockValue(QUniformPack &uniformPack,
                              RenderShader *shader,
                              const ShaderUniformBlock &block,
                              const QVariant &value);
    void setDefaultUniformBlockShaderDataValue(QUniformPack &uniformPack,
                                               RenderShader *shader,
                                               RenderShaderData *shaderData,
                                               const QString &structName);
    void buildSortingKey(RenderCommand *command);
};

} // namespace Render
} // namespace Qt3D

QT_END_NAMESPACE

#endif // QT3D_RENDER_RENDERVIEW_H