summaryrefslogtreecommitdiffstats
path: root/src/render/renderers/opengl
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2019-02-28 11:54:59 +0100
committerPaul Lemire <paul.lemire@kdab.com>2019-03-06 14:12:15 +0000
commitf875e7156fa4a2772a6622949877db66aebdacca (patch)
treeb837afa3c36de0a1d94db0bbebfd3a4aa654d517 /src/render/renderers/opengl
parenta356d132b2a426ecd7edb7858245266433b3e855 (diff)
QSortPolicy: add sorting by Texture
It can be more efficient to render a scene by sorting drawing commands based on the textures they are requiring. In conjunction with Material sorting, this can reduce the amount of GL calls being sent to the driver. [ChangeLog][Qt3DRender] QSortPolicy can now sort by Texture Change-Id: Ibc013e9d506ea3061b19a56c548e8184f2b981cc Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src/render/renderers/opengl')
-rw-r--r--src/render/renderers/opengl/renderer/renderview.cpp53
-rw-r--r--src/render/renderers/opengl/renderer/shaderparameterpack_p.h12
2 files changed, 65 insertions, 0 deletions
diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp
index 3aa45c836..ff43e74f4 100644
--- a/src/render/renderers/opengl/renderer/renderview.cpp
+++ b/src/render/renderers/opengl/renderer/renderview.cpp
@@ -321,6 +321,27 @@ struct AdjacentSubRangeFinder<QSortPolicy::FrontToBack>
}
};
+template<>
+struct AdjacentSubRangeFinder<QSortPolicy::Texture>
+{
+ static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
+ {
+ // Two renderCommands are adjacent if one contains all the other command's textures
+ QVector<ShaderParameterPack::NamedTexture> texturesA = a->m_parameterPack.textures();
+ QVector<ShaderParameterPack::NamedTexture> texturesB = b->m_parameterPack.textures();
+
+ if (texturesB.size() > texturesA.size())
+ qSwap(texturesA, texturesB);
+
+ // textureB.size() is always <= textureA.size()
+ for (const ShaderParameterPack::NamedTexture &texB : qAsConst(texturesB)) {
+ if (!texturesA.contains(texB))
+ return false;
+ }
+ return true;
+ }
+};
+
template<typename Predicate>
int advanceUntilNonAdjacent(const QVector<RenderCommand *> &commands,
const int beg, const int end, Predicate pred)
@@ -393,6 +414,33 @@ struct SubRangeSorter<QSortPolicy::FrontToBack>
}
};
+template<>
+struct SubRangeSorter<QSortPolicy::Texture>
+{
+ static void sortSubRange(CommandIt begin, const CommandIt end)
+ {
+ std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
+ QVector<ShaderParameterPack::NamedTexture> texturesA = a->m_parameterPack.textures();
+ QVector<ShaderParameterPack::NamedTexture> texturesB = b->m_parameterPack.textures();
+
+ const int originalTextureASize = texturesA.size();
+ const bool isSuperior = originalTextureASize > texturesB.size();
+
+ if (texturesB.size() > texturesA.size())
+ qSwap(texturesA, texturesB);
+
+ int identicalTextureCount = 0;
+
+ for (const ShaderParameterPack::NamedTexture &texB : qAsConst(texturesB)) {
+ if (texturesA.contains(texB))
+ ++identicalTextureCount;
+ }
+
+ return identicalTextureCount < originalTextureASize;
+ });
+ }
+};
+
int findSubRange(const QVector<RenderCommand *> &commands,
const int begin, const int end,
const QSortPolicy::SortType sortType)
@@ -406,6 +454,8 @@ int findSubRange(const QVector<RenderCommand *> &commands,
return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Material>::adjacentSubRange);
case QSortPolicy::FrontToBack:
return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::FrontToBack>::adjacentSubRange);
+ case QSortPolicy::Texture:
+ return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Texture>::adjacentSubRange);
default:
Q_UNREACHABLE();
return end;
@@ -449,6 +499,9 @@ void sortCommandRange(QVector<RenderCommand *> &commands, int begin, const int e
case QSortPolicy::FrontToBack:
SubRangeSorter<QSortPolicy::FrontToBack>::sortSubRange(commands.begin() + begin, commands.begin() + end);
break;
+ case QSortPolicy::Texture:
+ SubRangeSorter<QSortPolicy::Texture>::sortSubRange(commands.begin() + begin, commands.begin() + end);
+ break;
default:
Q_UNREACHABLE();
}
diff --git a/src/render/renderers/opengl/renderer/shaderparameterpack_p.h b/src/render/renderers/opengl/renderer/shaderparameterpack_p.h
index fe9ab3995..d1fbe936f 100644
--- a/src/render/renderers/opengl/renderer/shaderparameterpack_p.h
+++ b/src/render/renderers/opengl/renderer/shaderparameterpack_p.h
@@ -118,6 +118,18 @@ public:
int glslNameId;
Qt3DCore::QNodeId texId;
int uniformArrayIndex;
+
+ bool operator==(const NamedTexture &other) const
+ {
+ return glslNameId == other.glslNameId &&
+ texId == other.texId &&
+ uniformArrayIndex == other.uniformArrayIndex;
+ }
+
+ bool operator!=(const NamedTexture &other) const
+ {
+ return !(*this == other);
+ }
};
inline QVector<NamedTexture> textures() const { return m_textures; }