summaryrefslogtreecommitdiffstats
path: root/src/render/renderers/opengl/graphicshelpers
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2019-03-14 11:19:45 +0000
committerMike Krus <mike.krus@kdab.com>2019-03-18 13:53:37 +0000
commite9868e157b56eea991e34712eace5962d14543e6 (patch)
treee4dfe9476a88bce3fcbfad314d0e04efb45ddca5 /src/render/renderers/opengl/graphicshelpers
parent0cbc08e2a7bf5195af8d0134e190d49d24ecabc9 (diff)
Don't reset texture units at every frame
Resetting texture to unit assignment at every frame seems to trigger constant shader recompilation on macOS. Maybe GL driver is implemented on top of Metal which has more restrictions. Not resetting the assignment means the same texture units are used for consecutive frames and fixes excessive recompilation. Refactored the code to move the texture handling to separate class. Change-Id: I480f76e7e7b0ea669c6acb039cc3d079937ff97f Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/render/renderers/opengl/graphicshelpers')
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri6
-rw-r--r--src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp172
-rw-r--r--src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h35
-rw-r--r--src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext.cpp214
-rw-r--r--src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext_p.h104
5 files changed, 342 insertions, 189 deletions
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri b/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri
index 9b25be0eb..c40f52374 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri
@@ -13,7 +13,8 @@ HEADERS += \
$$PWD/graphicshelpergl3_3_p.h \
$$PWD/graphicshelpergl4_p.h \
$$PWD/graphicshelpergl3_2_p.h \
- $$PWD/submissioncontext_p.h
+ $$PWD/submissioncontext_p.h \
+ $$PWD/texturesubmissioncontext_p.h
SOURCES += \
$$PWD/graphicscontext.cpp \
@@ -25,4 +26,5 @@ SOURCES += \
$$PWD/graphicshelpergl3_3.cpp \
$$PWD/graphicshelpergl4.cpp \
$$PWD/graphicshelpergl3_2.cpp \
- $$PWD/submissioncontext.cpp
+ $$PWD/submissioncontext.cpp \
+ $$PWD/texturesubmissioncontext.cpp
diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
index 60fa9ed83..59c2d4286 100644
--- a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
@@ -49,6 +49,7 @@
#include <Qt3DRender/private/buffer_p.h>
#include <Qt3DRender/private/attribute_p.h>
#include <Qt3DRender/private/rendercommand_p.h>
+#include <Qt3DRender/private/renderstates_p.h>
#include <Qt3DRender/private/renderstateset_p.h>
#include <Qt3DRender/private/rendertarget_p.h>
#include <Qt3DRender/private/graphicshelperinterface_p.h>
@@ -96,40 +97,18 @@ namespace Qt3DRender {
namespace Render {
-class TextureExtRendererLocker
+static QHash<unsigned int, SubmissionContext*> static_contexts;
+
+unsigned int nextFreeContextId()
{
-public:
- static void lock(GLTexture *tex)
- {
- if (!tex->isExternalRenderingEnabled())
- return;
- if (s_lockHash.keys().contains(tex)) {
- ++s_lockHash[tex];
- } else {
- tex->externalRenderingLock()->lock();
- s_lockHash[tex] = 1;
- }
- }
- static void unlock(GLTexture *tex)
- {
- if (!tex->isExternalRenderingEnabled())
- return;
- if (!s_lockHash.keys().contains(tex))
- return;
-
- --s_lockHash[tex];
- if (s_lockHash[tex] == 0) {
- s_lockHash.remove(tex);
- tex->externalRenderingLock()->unlock();
- }
+ for (unsigned int i=0; i < 0xffff; ++i) {
+ if (!static_contexts.contains(i))
+ return i;
}
-private:
- static QHash<GLTexture*, int> s_lockHash;
-};
-QHash<GLTexture*, int> TextureExtRendererLocker::s_lockHash = QHash<GLTexture*, int>();
-
-static QHash<unsigned int, SubmissionContext*> static_contexts;
+ qFatal("Couldn't find free context ID");
+ return 0;
+}
namespace {
@@ -366,16 +345,6 @@ void applyStateHelper<LineWidth>(const LineWidth *state, SubmissionContext *gc)
} // anonymous
-unsigned int nextFreeContextId()
-{
- for (unsigned int i=0; i < 0xffff; ++i) {
- if (!static_contexts.contains(i))
- return i;
- }
-
- qFatal("Couldn't find free context ID");
- return 0;
-}
SubmissionContext::SubmissionContext()
: GraphicsContext()
@@ -409,7 +378,7 @@ SubmissionContext::~SubmissionContext()
void SubmissionContext::initialize()
{
GraphicsContext::initialize();
- m_activeTextures.resize(maxTextureUnitsCount());
+ m_textureContext.initialize(this);
}
void SubmissionContext::resolveRenderTargetFormat()
@@ -482,10 +451,6 @@ bool SubmissionContext::beginDrawing(QSurface *surface)
m_activeShaderDNA = 0;
}
- // reset active textures
- for (int u = 0; u < m_activeTextures.size(); ++u)
- m_activeTextures[u].texture = nullptr;
-
m_boundArrayBuffer = nullptr;
static int callCount = 0;
@@ -503,10 +468,7 @@ void SubmissionContext::endDrawing(bool swapBuffers)
m_gl->swapBuffers(m_surface);
if (m_ownCurrent)
m_gl->doneCurrent();
- decayTextureScores();
- for (int i = 0; i < m_activeTextures.size(); ++i)
- if (m_activeTextures[i].texture)
- TextureExtRendererLocker::unlock(m_activeTextures[i].texture);
+ m_textureContext.endDrawing();
}
void SubmissionContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, GLuint defaultFboId)
@@ -891,114 +853,10 @@ void SubmissionContext::setActiveMaterial(Material *rmat)
if (m_material == rmat)
return;
- deactivateTexturesWithScope(TextureScopeMaterial);
+ m_textureContext.deactivateTexturesWithScope(TextureSubmissionContext::TextureScopeMaterial);
m_material = rmat;
}
-int SubmissionContext::activateTexture(TextureScope scope, GLTexture *tex, int onUnit)
-{
- // Returns the texture unit to use for the texture
- // This always return a valid unit, unless there are more textures than
- // texture unit available for the current material
- onUnit = assignUnitForTexture(tex);
-
- // check we didn't overflow the available units
- if (onUnit == -1)
- return -1;
-
- // actually re-bind if required, the tex->dna on the unit not being the same
- // Note: tex->dna() could be 0 if the texture has not been created yet
- if (m_activeTextures[onUnit].texture != tex) {
- // Texture must have been created and updated at this point
- QOpenGLTexture *glTex = tex->getGLTexture();
- if (glTex == nullptr)
- return -1;
- glTex->bind(onUnit);
- if (m_activeTextures[onUnit].texture)
- TextureExtRendererLocker::unlock(m_activeTextures[onUnit].texture);
- m_activeTextures[onUnit].texture = tex;
- TextureExtRendererLocker::lock(tex);
- }
-
-#if defined(QT3D_RENDER_ASPECT_OPENGL_DEBUG)
- int err = m_gl->functions()->glGetError();
- if (err)
- qCWarning(Backend) << "GL error after activating texture" << QString::number(err, 16)
- << tex->getGLTexture()->textureId() << "on unit" << onUnit;
-#endif
-
- m_activeTextures[onUnit].score = 200;
- m_activeTextures[onUnit].pinned = true;
- m_activeTextures[onUnit].scope = scope;
-
- return onUnit;
-}
-
-void SubmissionContext::deactivateTexturesWithScope(TextureScope ts)
-{
- for (int u=0; u<m_activeTextures.size(); ++u) {
- if (!m_activeTextures[u].pinned)
- continue; // inactive, ignore
-
- if (m_activeTextures[u].scope == ts) {
- m_activeTextures[u].pinned = false;
- m_activeTextures[u].score = qMax(m_activeTextures[u].score, 1) - 1;
- }
- } // of units iteration
-}
-
-void SubmissionContext::deactivateTexture(GLTexture* tex)
-{
- for (int u=0; u<m_activeTextures.size(); ++u) {
- if (m_activeTextures[u].texture == tex) {
- Q_ASSERT(m_activeTextures[u].pinned);
- m_activeTextures[u].pinned = false;
- return;
- }
- } // of units iteration
-
- qCWarning(Backend) << Q_FUNC_INFO << "texture not active:" << tex;
-}
-
-/*!
- \internal
- Returns a texture unit for a texture, -1 if all texture units are assigned.
- Tries to use the texture unit with the texture that hasn't been used for the longest time
- if the texture happens not to be already pinned on a texture unit.
- */
-GLint SubmissionContext::assignUnitForTexture(GLTexture *tex)
-{
- int lowestScoredUnit = -1;
- int lowestScore = 0xfffffff;
-
- for (int u=0; u<m_activeTextures.size(); ++u) {
- if (m_activeTextures[u].texture == tex)
- return u;
-
- // No texture is currently active on the texture unit
- // we save the texture unit with the texture that has been on there
- // the longest time while not being used
- if (!m_activeTextures[u].pinned) {
- int score = m_activeTextures[u].score;
- if (score < lowestScore) {
- lowestScore = score;
- lowestScoredUnit = u;
- }
- }
- } // of units iteration
-
- if (lowestScoredUnit == -1)
- qCWarning(Backend) << Q_FUNC_INFO << "No free texture units!";
-
- return lowestScoredUnit;
-}
-
-void SubmissionContext::decayTextureScores()
-{
- for (int u = 0; u < m_activeTextures.size(); u++)
- m_activeTextures[u].score = qMax(m_activeTextures[u].score - 1, 0);
-}
-
void SubmissionContext::setCurrentStateSet(RenderStateSet *ss)
{
if (ss == m_stateSet)
@@ -1243,7 +1101,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
// to pinable so that we should easily find an available texture unit
NodeManagers *manager = m_renderer->nodeManagers();
- deactivateTexturesWithScope(TextureScopeMaterial);
+ m_textureContext.deactivateTexturesWithScope(TextureSubmissionContext::TextureScopeMaterial);
// Update the uniforms with the correct texture unit id's
PackUniformHash &uniformValues = parameterPack.uniforms();
@@ -1255,7 +1113,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
if (t != nullptr) {
UniformValue &texUniform = uniformValues[namedTex.glslNameId];
if (texUniform.valueType() == UniformValue::TextureValue) {
- const int texUnit = activateTexture(TextureScopeMaterial, t);
+ const int texUnit = m_textureContext.activateTexture(TextureSubmissionContext::TextureScopeMaterial, t);
texUniform.data<int>()[namedTex.uniformArrayIndex] = texUnit;
if (texUnit == -1) {
if (namedTex.glslNameId != irradianceId &&
diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h b/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h
index 52c6034d7..9b9bd7fa8 100644
--- a/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h
@@ -54,6 +54,7 @@
#include <Qt3DRender/private/graphicscontext_p.h>
+#include <Qt3DRender/private/texturesubmissioncontext_p.h>
#include <Qt3DRender/qclearbuffers.h>
#include <Qt3DRender/private/glbuffer_p.h>
#include <Qt3DRender/qattribute.h>
@@ -81,13 +82,6 @@ class Buffer;
class ShaderManager;
struct StateVariant;
-enum TextureScope
-{
- TextureScopeMaterial = 0,
- TextureScopeTechnique
- // per-pass for deferred rendering?
-};
-
typedef QPair<QString, int> NamedUniformLocation;
class Q_AUTOTEST_EXPORT SubmissionContext : public GraphicsContext
@@ -124,11 +118,6 @@ public:
QRenderTargetOutput::AttachmentPoint outputAttachmentPoint,
QBlitFramebuffer::InterpolationMethod interpolationMethod);
-
- // Material
- Material* activeMaterial() const { return m_material; }
- void setActiveMaterial(Material* rmat);
-
// Attributes
void specifyAttribute(const Attribute *attribute,
Buffer *buffer,
@@ -145,10 +134,6 @@ public:
// Parameters
bool setParameters(ShaderParameterPack &parameterPack);
- // Textures
- int activateTexture(TextureScope scope, GLTexture* tex, int onUnit = -1);
- void deactivateTexture(GLTexture *tex);
-
// RenderState
void setCurrentStateSet(RenderStateSet* ss);
RenderStateSet *currentStateSet() const;
@@ -165,10 +150,9 @@ public:
private:
void initialize();
- // Textures
- void decayTextureScores();
- GLint assignUnitForTexture(GLTexture* tex);
- void deactivateTexturesWithScope(TextureScope ts);
+ // Material
+ Material* activeMaterial() const { return m_material; }
+ void setActiveMaterial(Material* rmat);
// FBO
void bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments);
@@ -177,7 +161,6 @@ private:
GLuint createRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments);
GLuint updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, bool isActiveRenderTarget);
-
// Buffers
HGLBuffer createGLBufferFor(Buffer *buffer, GLBuffer::Type type);
void uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool releaseBuffer = false);
@@ -197,15 +180,6 @@ private:
QHash<GLuint, QSize> m_renderTargetsSize;
QAbstractTexture::TextureFormat m_renderTargetFormat;
- // active textures, indexed by texture unit
- struct ActiveTexture {
- GLTexture *texture = nullptr;
- int score = 0;
- TextureScope scope = TextureScopeMaterial;
- bool pinned = false;
- };
- QVector<ActiveTexture> m_activeTextures;
-
// cache some current state, to make sure we don't issue unnecessary GL calls
int m_currClearStencilValue;
float m_currClearDepthValue;
@@ -220,6 +194,7 @@ private:
Renderer *m_renderer;
QByteArray m_uboTempArray;
+ TextureSubmissionContext m_textureContext;
// Attributes
friend class OpenGLVertexArrayObject;
diff --git a/src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext.cpp
new file mode 100644
index 000000000..35fc1dc7c
--- /dev/null
+++ b/src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "texturesubmissioncontext_p.h"
+
+#include <Qt3DRender/private/graphicscontext_p.h>
+#include <Qt3DRender/private/gltexture_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+namespace Render {
+
+class TextureExtRendererLocker
+{
+public:
+ static void lock(GLTexture *tex)
+ {
+ if (!tex->isExternalRenderingEnabled())
+ return;
+ if (s_lockHash.keys().contains(tex)) {
+ ++s_lockHash[tex];
+ } else {
+ tex->externalRenderingLock()->lock();
+ s_lockHash[tex] = 1;
+ }
+ }
+ static void unlock(GLTexture *tex)
+ {
+ if (!tex->isExternalRenderingEnabled())
+ return;
+ if (!s_lockHash.keys().contains(tex))
+ return;
+
+ --s_lockHash[tex];
+ if (s_lockHash[tex] == 0) {
+ s_lockHash.remove(tex);
+ tex->externalRenderingLock()->unlock();
+ }
+ }
+private:
+ static QHash<GLTexture*, int> s_lockHash;
+};
+
+QHash<GLTexture*, int> TextureExtRendererLocker::s_lockHash = QHash<GLTexture*, int>();
+
+
+TextureSubmissionContext::TextureSubmissionContext()
+{
+
+}
+
+TextureSubmissionContext::~TextureSubmissionContext()
+{
+
+}
+
+void TextureSubmissionContext::initialize(GraphicsContext *context)
+{
+ m_activeTextures.resize(context->maxTextureUnitsCount());
+}
+
+void TextureSubmissionContext::endDrawing()
+{
+ decayTextureScores();
+ for (int i = 0; i < m_activeTextures.size(); ++i)
+ if (m_activeTextures[i].texture)
+ TextureExtRendererLocker::unlock(m_activeTextures[i].texture);
+}
+
+int TextureSubmissionContext::activateTexture(TextureSubmissionContext::TextureScope scope, GLTexture *tex)
+{
+ // Returns the texture unit to use for the texture
+ // This always return a valid unit, unless there are more textures than
+ // texture unit available for the current material
+ const int onUnit = assignUnitForTexture(tex);
+
+ // check we didn't overflow the available units
+ if (onUnit == -1)
+ return -1;
+
+ // Texture must have been created and updated at this point
+ QOpenGLTexture *glTex = tex->getGLTexture();
+ if (glTex == nullptr)
+ return -1;
+ glTex->bind(uint(onUnit));
+ if (m_activeTextures[onUnit].texture != tex) {
+ if (m_activeTextures[onUnit].texture)
+ TextureExtRendererLocker::unlock(m_activeTextures[onUnit].texture);
+ m_activeTextures[onUnit].texture = tex;
+ TextureExtRendererLocker::lock(tex);
+ }
+
+#if defined(QT3D_RENDER_ASPECT_OPENGL_DEBUG)
+ int err = m_gl->functions()->glGetError();
+ if (err)
+ qCWarning(Backend) << "GL error after activating texture" << QString::number(err, 16)
+ << tex->getGLTexture()->textureId() << "on unit" << onUnit;
+#endif
+
+ m_activeTextures[onUnit].score = 200;
+ m_activeTextures[onUnit].pinned = true;
+ m_activeTextures[onUnit].scope = scope;
+
+ return onUnit;
+}
+
+void TextureSubmissionContext::deactivateTexturesWithScope(TextureSubmissionContext::TextureScope ts)
+{
+ for (int u=0; u<m_activeTextures.size(); ++u) {
+ if (!m_activeTextures[u].pinned)
+ continue; // inactive, ignore
+
+ if (m_activeTextures[u].scope == ts) {
+ m_activeTextures[u].pinned = false;
+ m_activeTextures[u].score = qMax(m_activeTextures[u].score, 1) - 1;
+ }
+ } // of units iteration
+}
+
+void TextureSubmissionContext::deactivateTexture(GLTexture* tex)
+{
+ for (int u=0; u<m_activeTextures.size(); ++u) {
+ if (m_activeTextures[u].texture == tex) {
+ Q_ASSERT(m_activeTextures[u].pinned);
+ m_activeTextures[u].pinned = false;
+ return;
+ }
+ } // of units iteration
+
+ qCWarning(Backend) << Q_FUNC_INFO << "texture not active:" << tex;
+}
+
+/*!
+ \internal
+ Returns a texture unit for a texture, -1 if all texture units are assigned.
+ Tries to use the texture unit with the texture that hasn't been used for the longest time
+ if the texture happens not to be already pinned on a texture unit.
+ */
+int TextureSubmissionContext::assignUnitForTexture(GLTexture *tex)
+{
+ int lowestScoredUnit = -1;
+ int lowestScore = 0xfffffff;
+
+ for (int u=0; u<m_activeTextures.size(); ++u) {
+ if (m_activeTextures[u].texture == tex)
+ return u;
+ }
+
+ for (int u=0; u<m_activeTextures.size(); ++u) {
+ // No texture is currently active on the texture unit
+ // we save the texture unit with the texture that has been on there
+ // the longest time while not being used
+ if (!m_activeTextures[u].pinned) {
+ int score = m_activeTextures[u].score;
+ if (score < lowestScore) {
+ lowestScore = score;
+ lowestScoredUnit = u;
+ }
+ }
+ } // of units iteration
+
+ if (lowestScoredUnit == -1)
+ qCWarning(Backend) << Q_FUNC_INFO << "No free texture units!";
+
+ return lowestScoredUnit;
+}
+
+void TextureSubmissionContext::decayTextureScores()
+{
+ for (int u = 0; u < m_activeTextures.size(); u++)
+ m_activeTextures[u].score = qMax(m_activeTextures[u].score - 1, 0);
+}
+
+} // namespace Render
+} // namespace Qt3DRender of namespace
+
+QT_END_NAMESPACE
diff --git a/src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext_p.h b/src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext_p.h
new file mode 100644
index 000000000..d0c1565b2
--- /dev/null
+++ b/src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DRENDER_RENDER_TEXTURESUBMISSIONCONTEXT_H
+#define QT3DRENDER_RENDER_TEXTURESUBMISSIONCONTEXT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include <qglobal.h>
+#include <QVector>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+namespace Render {
+
+class GraphicsContext;
+class GLTexture;
+
+class Q_AUTOTEST_EXPORT TextureSubmissionContext
+{
+public:
+ enum TextureScope
+ {
+ TextureScopeMaterial = 0,
+ TextureScopeTechnique
+ // per-pass for deferred rendering?
+ };
+
+ TextureSubmissionContext();
+ ~TextureSubmissionContext();
+
+ void initialize(GraphicsContext *context);
+ void endDrawing();
+ int activateTexture(TextureScope scope, GLTexture* tex);
+ void deactivateTexture(GLTexture *tex);
+ void deactivateTexturesWithScope(TextureScope ts);
+
+private:
+ void decayTextureScores();
+ int assignUnitForTexture(GLTexture* tex);
+
+ // active textures, indexed by texture unit
+ struct ActiveTexture {
+ GLTexture *texture = nullptr;
+ int score = 0;
+ TextureScope scope = TextureScopeMaterial;
+ bool pinned = false;
+ };
+ QVector<ActiveTexture> m_activeTextures;
+};
+
+} // namespace Render
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
+
+#endif // QT3DRENDER_RENDER_TEXTURESUBMISSIONCONTEXT_H