summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWieland Hagen <wieland.hagen@kdab.com>2016-01-22 17:29:29 +0100
committerWieland Hagen <wieland.hagen@kdab.com>2016-02-05 16:08:50 +0000
commit5757b17a7535ca2a97f78463e4798242a5dcb508 (patch)
tree9d8e498554eb12c239e5beff31bac14987ef31d9
parentdb69d8e51172d9150d57aca1331a904a290bcc76 (diff)
Added QBackendNodes for QRenderStates.
RenderStateNode is the backend node for QRenderStates. The actual state-dependent behavior is implemented in subclasses of RenderStateImpl. Backend nodes for QRenderPass and QStateSet now hold IDs of the RenderState-nodes that they contain, instead of pointers. This means that every frame the RenderView has to get the actual backend nodes while building the RenderStateSets. This needs to be fixed. Change-Id: I908ce9763fdb9f4e851df8dbcecf5dc6ce5a4f49 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/render/backend/handle_types_p.h2
-rw-r--r--src/render/backend/managers_p.h11
-rw-r--r--src/render/backend/nodemanagers.cpp7
-rw-r--r--src/render/backend/nodemanagers_p.h7
-rw-r--r--src/render/backend/renderer.cpp6
-rw-r--r--src/render/backend/renderview.cpp4
-rw-r--r--src/render/framegraph/statesetnode.cpp15
-rw-r--r--src/render/framegraph/statesetnode_p.h6
-rw-r--r--src/render/frontend/qrenderaspect.cpp1
-rw-r--r--src/render/jobs/renderviewjobutils.cpp19
-rw-r--r--src/render/jobs/renderviewjobutils_p.h7
-rw-r--r--src/render/materialsystem/renderpass.cpp17
-rw-r--r--src/render/materialsystem/renderpass_p.h6
-rw-r--r--src/render/renderstates/genericstate_p.h176
-rw-r--r--src/render/renderstates/renderstates.cpp217
-rw-r--r--src/render/renderstates/renderstates_p.h177
-rw-r--r--src/render/renderstates/renderstateset.cpp70
-rw-r--r--src/render/renderstates/renderstateset_p.h8
18 files changed, 332 insertions, 424 deletions
diff --git a/src/render/backend/handle_types_p.h b/src/render/backend/handle_types_p.h
index 02fba699e..ab572416b 100644
--- a/src/render/backend/handle_types_p.h
+++ b/src/render/backend/handle_types_p.h
@@ -92,6 +92,7 @@ class OpenGLVertexArrayObject;
class Light;
class ComputeJob;
class GLBuffer;
+class RenderStateNode;
typedef Qt3DCore::QHandle<RenderAttachment, 16> HAttachment;
typedef Qt3DCore::QHandle<CameraLens, 8> HCamera;
@@ -123,6 +124,7 @@ typedef Qt3DCore::QHandle<BoundingVolumeDebug, 16> HBoundingVolumeDebug;
typedef Qt3DCore::QHandle<Light, 16> HLight;
typedef Qt3DCore::QHandle<ComputeJob, 16> HComputeJob;
typedef Qt3DCore::QHandle<GLBuffer, 16> HGLBuffer;
+typedef Qt3DCore::QHandle<RenderStateNode, 16> HRenderState;
} // namespace Render
diff --git a/src/render/backend/managers_p.h b/src/render/backend/managers_p.h
index 5d32e26a6..90487099e 100644
--- a/src/render/backend/managers_p.h
+++ b/src/render/backend/managers_p.h
@@ -66,6 +66,7 @@
#include <Qt3DRender/private/transform_p.h>
#include <Qt3DRender/private/rendertarget_p.h>
#include <Qt3DRender/private/renderpass_p.h>
+#include <Qt3DRender/private/genericstate_p.h>
#include <Qt3DRender/private/parameter_p.h>
#include <Qt3DRender/private/shaderdata_p.h>
#include <Qt3DRender/private/handle_types_p.h>
@@ -367,6 +368,16 @@ public:
ComputeJobManager() {}
};
+class RenderStateManager : public Qt3DCore::QResourceManager<
+ RenderStateNode,
+ Qt3DCore::QNodeId,
+ 16,
+ Qt3DCore::ArrayAllocatingPolicy,
+ Qt3DCore::ObjectLevelLockingPolicy>
+{
+};
+
+
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/backend/nodemanagers.cpp b/src/render/backend/nodemanagers.cpp
index 88791ee8f..0c60351c0 100644
--- a/src/render/backend/nodemanagers.cpp
+++ b/src/render/backend/nodemanagers.cpp
@@ -85,6 +85,7 @@ NodeManagers::NodeManagers()
, m_boundingVolumeDebugManager(new BoundingVolumeDebugManager())
, m_lightManager(new LightManager())
, m_computeJobManager(new ComputeJobManager())
+ , m_renderStateManager(new RenderStateManager())
{
}
@@ -274,6 +275,12 @@ ComputeJobManager *NodeManagers::manager<ComputeJob>() const Q_DECL_NOEXCEPT
return m_computeJobManager;
}
+template<>
+RenderStateManager *NodeManagers::manager<RenderStateNode>() const Q_DECL_NOEXCEPT
+{
+ return m_renderStateManager;
+}
+
} // Render
} // Qt3DRender
diff --git a/src/render/backend/nodemanagers_p.h b/src/render/backend/nodemanagers_p.h
index 45afdbefa..305ef975f 100644
--- a/src/render/backend/nodemanagers_p.h
+++ b/src/render/backend/nodemanagers_p.h
@@ -96,6 +96,7 @@ class TextureDataManager;
class LayerManager;
class LightManager;
class ComputeJobManager;
+class RenderStateManager;
class FrameGraphNode;
class Annotation;
@@ -127,6 +128,7 @@ class ObjectPicker;
class BoundingVolumeDebug;
class Light;
class ComputeJob;
+class RenderStateNode;
class QT3DRENDERSHARED_PRIVATE_EXPORT NodeManagers
{
@@ -198,6 +200,7 @@ public:
inline BoundingVolumeDebugManager *boundingVolumeDebugManager() const Q_DECL_NOEXCEPT { return m_boundingVolumeDebugManager; }
inline LightManager *lightManager() const Q_DECL_NOEXCEPT { return m_lightManager; }
inline ComputeJobManager *computeJobManager() const Q_DECL_NOEXCEPT { return m_computeJobManager; }
+ inline RenderStateManager *renderStateManager() const Q_DECL_NOEXCEPT { return m_renderStateManager; }
private:
CameraManager *m_cameraManager;
@@ -231,6 +234,7 @@ private:
BoundingVolumeDebugManager *m_boundingVolumeDebugManager;
LightManager *m_lightManager;
ComputeJobManager *m_computeJobManager;
+ RenderStateManager *m_renderStateManager;
};
// Specializations
@@ -328,6 +332,9 @@ LightManager *NodeManagers::manager<Light>() const Q_DECL_NOEXCEPT;
template<>
QT3DRENDERSHARED_PRIVATE_EXPORT ComputeJobManager *NodeManagers::manager<ComputeJob>() const Q_DECL_NOEXCEPT;
+template<>
+QT3DRENDERSHARED_PRIVATE_EXPORT RenderStateManager *NodeManagers::manager<RenderStateNode>() const Q_DECL_NOEXCEPT;
+
} // Render
} // Qt3DRender
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index f4fbd56d6..dbb4715b2 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -209,9 +209,9 @@ void Renderer::buildDefaultTechnique()
basicPass->setShaderProgram(defaultShader);
m_defaultRenderStateSet = new RenderStateSet;
- m_defaultRenderStateSet->addState(DepthTest::getOrCreate(GL_LESS));
- m_defaultRenderStateSet->addState(CullFace::getOrCreate(GL_BACK));
- m_defaultRenderStateSet->addState(ColorMask::getOrCreate(true, true, true, true));
+ m_defaultRenderStateSet->addState(createRenderStateImpl<DepthTest>()->set(GL_LESS));
+ m_defaultRenderStateSet->addState(createRenderStateImpl<CullFace>()->set(GL_BACK));
+ m_defaultRenderStateSet->addState(createRenderStateImpl<ColorMask>()->set(true, true, true, true));
//basicPass->setStateSet(m_defaultRenderStateSet);
m_defaultTechnique->addPass(basicPass);
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index 6cc49c9da..660ac68ea 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -526,7 +526,9 @@ void RenderView::buildDrawRenderCommands(Entity *node, const Plane *planes)
// RenderPass { renderStates: [] } will use the states defined by
// StateSet in the FrameGraph
if (!pass->renderStates().isEmpty()) {
- command->m_stateSet = buildRenderStateSet(pass->renderStates(), m_allocator);
+ command->m_stateSet = m_allocator->allocate<RenderStateSet>();
+ addToRenderStateSet(command->m_stateSet, pass->renderStates(), m_manager->renderStateManager());
+
// Merge per pass stateset with global stateset
// so that the local stateset only overrides
if (m_stateSet != Q_NULLPTR)
diff --git a/src/render/framegraph/statesetnode.cpp b/src/render/framegraph/statesetnode.cpp
index 55c8a47a8..e65d48843 100644
--- a/src/render/framegraph/statesetnode.cpp
+++ b/src/render/framegraph/statesetnode.cpp
@@ -66,12 +66,12 @@ void StateSetNode::updateFromPeer(Qt3DCore::QNode *peer)
setEnabled(stateSet->isEnabled());
Q_FOREACH (QRenderState *renderState, stateSet->renderStates())
- appendRenderState(renderState->id(), RenderState::getOrCreateBackendState(renderState));
+ appendRenderState(renderState->id());
}
-QList<RenderState *> StateSetNode::renderStates() const
+QList<Qt3DCore::QNodeId> StateSetNode::renderStates() const
{
- return m_renderStates.values();
+ return m_renderStates;
}
void StateSetNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
@@ -81,8 +81,7 @@ void StateSetNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
case NodeAdded: {
if (propertyChange->propertyName() == QByteArrayLiteral("renderState")) {
QNodePtr nodePtr = propertyChange->value().value<QNodePtr>();
- QRenderState *renderState = static_cast<QRenderState *>(nodePtr.data());
- appendRenderState(renderState->id(), RenderState::getOrCreateBackendState(renderState));
+ appendRenderState(nodePtr->id());
}
}
break;
@@ -98,15 +97,15 @@ void StateSetNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
}
}
-void StateSetNode::appendRenderState(const Qt3DCore::QNodeId &id, RenderState *renderState)
+void StateSetNode::appendRenderState(const Qt3DCore::QNodeId &id)
{
if (!m_renderStates.contains(id))
- m_renderStates[id] = renderState;
+ m_renderStates.append(id);
}
void StateSetNode::removeRenderState(const Qt3DCore::QNodeId &renderStateId)
{
- m_renderStates.remove(renderStateId);
+ m_renderStates.removeAll(renderStateId);
}
} // namespace Render
diff --git a/src/render/framegraph/statesetnode_p.h b/src/render/framegraph/statesetnode_p.h
index 755ea4fbe..aa402e430 100644
--- a/src/render/framegraph/statesetnode_p.h
+++ b/src/render/framegraph/statesetnode_p.h
@@ -67,15 +67,15 @@ public:
void updateFromPeer(Qt3DCore::QNode *peer) Q_DECL_OVERRIDE;
- QList<RenderState *> renderStates() const;
+ QList<Qt3DCore::QNodeId> renderStates() const;
protected:
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE;
- void appendRenderState(const Qt3DCore::QNodeId &id, RenderState *renderState);
+ void appendRenderState(const Qt3DCore::QNodeId &id);
void removeRenderState(const Qt3DCore::QNodeId &renderStateId);
- QHash<Qt3DCore::QNodeId, RenderState *> m_renderStates;
+ QList<Qt3DCore::QNodeId> m_renderStates;
};
} // namespace Render
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index 184c3b433..af30918ee 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -290,6 +290,7 @@ void QRenderAspect::registerBackendTypes()
registerBackendType<QDispatchCompute>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::DispatchCompute, QDispatchCompute>(d->m_nodeManagers->frameGraphManager())));
registerBackendType<QComputeJob>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::ComputeJob, Render::ComputeJobManager>(d->m_nodeManagers->computeJobManager())));
registerBackendType<QRendererSettings>(QBackendNodeFunctorPtr(new Render::RendererSettingsFunctor(d->m_renderer)));
+ registerBackendType<QRenderState>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::RenderStateNode, Render::RenderStateManager>(d->m_nodeManagers->renderStateManager())));
}
void QRenderAspect::renderInitialize(QOpenGLContext *context)
diff --git a/src/render/jobs/renderviewjobutils.cpp b/src/render/jobs/renderviewjobutils.cpp
index 1995bc9c0..23c4ed57b 100644
--- a/src/render/jobs/renderviewjobutils.cpp
+++ b/src/render/jobs/renderviewjobutils.cpp
@@ -194,11 +194,7 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN
rv->setStateSet(stateSet);
}
- // Add renderstates to stateset
- const QList<RenderState *> &states = rStateSet->renderStates();
- Q_FOREACH (RenderState *renderState, states)
- stateSet->addState(renderState);
-
+ addToRenderStateSet(stateSet, rStateSet->renderStates(), manager->renderStateManager());
break;
}
@@ -397,15 +393,14 @@ void parametersFromMaterialEffectTechnique(ParameterInfoList *infoList,
parametersFromParametersProvider(infoList, manager, effect);
}
-RenderStateSet *buildRenderStateSet(const QList<RenderState*> &states, QFrameAllocator *allocator)
+void addToRenderStateSet(RenderStateSet *stateSet,
+ const QList<Qt3DCore::QNodeId> &nodeIds,
+ RenderStateManager *manager)
{
- RenderStateSet *stateSet = allocator->allocate<RenderStateSet>();
-
- Q_FOREACH (RenderState *renderState, states) {
- stateSet->addState(renderState);
+ Q_FOREACH (Qt3DCore::QNodeId renderStateId, nodeIds) {
+ RenderStateNode *rstate = manager->lookupResource(renderStateId);
+ stateSet->addState(rstate->impl());
}
-
- return stateSet;
}
namespace {
diff --git a/src/render/jobs/renderviewjobutils_p.h b/src/render/jobs/renderviewjobutils_p.h
index 66eb3ad5b..ec52ae7cc 100644
--- a/src/render/jobs/renderviewjobutils_p.h
+++ b/src/render/jobs/renderviewjobutils_p.h
@@ -79,7 +79,7 @@ class NodeManagers;
class ShaderDataManager;
struct ShaderUniform;
class ShaderData;
-class RenderState;
+class RenderStateManager;
Q_AUTOTEST_EXPORT void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv,
const FrameGraphNode *fgLeaf);
@@ -132,8 +132,9 @@ void parametersFromParametersProvider(ParameterInfoList *infoList,
Q_AUTOTEST_EXPORT ParameterInfoList::iterator findParamInfo(ParameterInfoList *infoList,
const QString &name);
-Q_AUTOTEST_EXPORT RenderStateSet *buildRenderStateSet(const QList<RenderState*> &states,
- Qt3DCore::QFrameAllocator *allocator);
+Q_AUTOTEST_EXPORT void addToRenderStateSet(RenderStateSet *stateSet,
+ const QList<Qt3DCore::QNodeId> &nodeIds,
+ RenderStateManager *manager);
struct Q_AUTOTEST_EXPORT UniformBlockValueBuilder
diff --git a/src/render/materialsystem/renderpass.cpp b/src/render/materialsystem/renderpass.cpp
index 6492a11e3..1afb1c214 100644
--- a/src/render/materialsystem/renderpass.cpp
+++ b/src/render/materialsystem/renderpass.cpp
@@ -86,7 +86,7 @@ void RenderPass::updateFromPeer(Qt3DCore::QNode *peer)
Q_FOREACH (QAnnotation *c, pass->annotations())
appendAnnotation(c->id());
Q_FOREACH (QRenderState *renderState, pass->renderStates())
- appendRenderState(renderState->id(), RenderState::getOrCreateBackendState(renderState));
+ appendRenderState(renderState->id());
Q_FOREACH (QParameter *p, pass->parameters())
m_parameterPack.appendParameter(p->id());
}
@@ -105,8 +105,7 @@ void RenderPass::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
appendBinding(ParameterMapping(propertyChange->value().value<QParameterMapping *>()));
} else if (propertyChange->propertyName() == QByteArrayLiteral("renderState")) {
QNodePtr nodePtr = propertyChange->value().value<QNodePtr>();
- QRenderState *renderState = static_cast<QRenderState *>(nodePtr.data());
- appendRenderState(renderState->id(), RenderState::getOrCreateBackendState(renderState));
+ appendRenderState(nodePtr->id());
} else if (propertyChange->propertyName() == QByteArrayLiteral("parameter")) {
m_parameterPack.appendParameter(propertyChange->value().value<QNodeId>());
}
@@ -148,9 +147,9 @@ QList<Qt3DCore::QNodeId> RenderPass::annotations() const
return m_annotationList;
}
-QList<RenderState *> RenderPass::renderStates() const
+QList<Qt3DCore::QNodeId> RenderPass::renderStates() const
{
- return m_renderStates.values();
+ return m_renderStates;
}
QList<Qt3DCore::QNodeId> RenderPass::parameters() const
@@ -180,15 +179,15 @@ void RenderPass::removeBinding(const Qt3DCore::QNodeId &bindingId)
m_bindings.remove(bindingId);
}
-void RenderPass::appendRenderState(const Qt3DCore::QNodeId &id, RenderState *renderState)
+void RenderPass::appendRenderState(const Qt3DCore::QNodeId &renderStateId)
{
- if (!m_renderStates.contains(id))
- m_renderStates[id] = renderState;
+ if (!m_renderStates.contains(renderStateId))
+ m_renderStates.append(renderStateId);
}
void RenderPass::removeRenderState(const Qt3DCore::QNodeId &renderStateId)
{
- m_renderStates.remove(renderStateId);
+ m_renderStates.removeAll(renderStateId);
}
} // namespace Render
diff --git a/src/render/materialsystem/renderpass_p.h b/src/render/materialsystem/renderpass_p.h
index 7732f26c1..b55cba35a 100644
--- a/src/render/materialsystem/renderpass_p.h
+++ b/src/render/materialsystem/renderpass_p.h
@@ -88,7 +88,7 @@ public:
Qt3DCore::QNodeId shaderProgram() const;
QList<ParameterMapping> bindings() const;
QList<Qt3DCore::QNodeId> annotations() const;
- QList<RenderState *> renderStates() const;
+ QList<Qt3DCore::QNodeId> renderStates() const;
QList<Qt3DCore::QNodeId> parameters() const;
private:
@@ -98,12 +98,12 @@ private:
void appendBinding(const ParameterMapping &binding);
void removeBinding(const Qt3DCore::QNodeId &bindingId);
- void appendRenderState(const Qt3DCore::QNodeId &id, RenderState *renderState);
+ void appendRenderState(const Qt3DCore::QNodeId &renderStateId);
void removeRenderState(const Qt3DCore::QNodeId &renderStateId);
Qt3DCore::QNodeId m_shaderUuid;
QHash<Qt3DCore::QNodeId, ParameterMapping> m_bindings;
- QHash<Qt3DCore::QNodeId, RenderState *> m_renderStates;
+ QList<Qt3DCore::QNodeId> m_renderStates;
QList<Qt3DCore::QNodeId> m_annotationList;
ParameterPack m_parameterPack;
};
diff --git a/src/render/renderstates/genericstate_p.h b/src/render/renderstates/genericstate_p.h
index 33dfc61fc..5bf69ad8b 100644
--- a/src/render/renderstates/genericstate_p.h
+++ b/src/render/renderstates/genericstate_p.h
@@ -53,6 +53,7 @@
//
#include <QList>
+#include <Qt3DCore/qbackendnode.h>
QT_BEGIN_NAMESPACE
@@ -86,108 +87,175 @@ enum StateMask
typedef quint64 StateMaskSet;
-class Q_AUTOTEST_EXPORT RenderState
+class RenderStateImpl
{
public:
- virtual ~RenderState() {}
+ virtual ~RenderStateImpl() {}
+
virtual void apply(GraphicsContext* gc) const = 0;
virtual StateMaskSet mask() const = 0;
+ virtual bool equalTo(const RenderStateImpl &renderState) const = 0;
- static RenderState *getOrCreateBackendState(QRenderState *renderState);
+ static RenderStateImpl* setOrCreateState(QRenderState *renderState, RenderStateImpl *target);
+ virtual void updateProperty(const char *name, const QVariant &value);
};
-template <typename Derived, typename T>
-class GenericState1 : public RenderState
+/**
+ * @brief Backend Render State Node
+ */
+class Q_AUTOTEST_EXPORT RenderStateNode : public Qt3DCore::QBackendNode
{
public:
+ RenderStateNode();
+ virtual ~RenderStateNode() {}
- bool isEqual(const Derived& i) const
- { return (m_1 == i.m_1); }
+ virtual void updateFromPeer(Qt3DCore::QNode *peer) Q_DECL_OVERRIDE;
+ virtual void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE;
+ void apply(GraphicsContext* gc) const { m_impl->apply(gc); }
+ StateMaskSet mask() const { return m_impl->mask(); }
-protected:
- GenericState1(T t) :
- m_1(t)
- {}
+ RenderStateImpl *impl() const { return m_impl; }
- T m_1;
+protected:
+ RenderStateImpl *m_impl;
+};
+template <StateMaskSet Mask>
+class MaskedRenderState : public RenderStateImpl
+{
+public:
+ StateMaskSet mask() const Q_DECL_OVERRIDE
+ {
+ return Mask;
+ }
};
-template <typename Derived, typename T, typename S>
-class GenericState2 : public RenderState
+template <StateMaskSet Mask, typename T>
+class GenericState1 : public MaskedRenderState<Mask>
{
public:
- bool isEqual(const Derived& i) const
- { return (m_1 == i.m_1) && (m_2 == i.m_2); }
+ GenericState1 *set(const T& v1)
+ {
+ m_1 = v1;
+ return this;
+ }
+ virtual bool equalTo(const RenderStateImpl &renderState) const
+ {
+ const GenericState1 *other = dynamic_cast<const GenericState1*>(&renderState);
+ return (other != NULL
+ && other->m_1 == m_1);
+ }
+
protected:
- GenericState2(T t, S s) :
- m_1(t),
- m_2(s)
- {}
+ T m_1;
+};
+template <StateMaskSet Mask, typename T, typename S>
+class GenericState2 : public MaskedRenderState<Mask>
+{
+public:
+ GenericState2 *set(const T& v1, const S& v2)
+ {
+ m_1 = v1;
+ m_2 = v2;
+ return this;
+ }
+ virtual bool equalTo(const RenderStateImpl &renderState) const
+ {
+ const GenericState2 *other = dynamic_cast<const GenericState2*>(&renderState);
+ return (other != NULL
+ && other->m_1 == m_1
+ && other->m_2 == m_2);
+ }
+protected:
T m_1;
S m_2;
};
-template <typename Derived, typename T, typename S, typename U>
-class GenericState3 : public RenderState
+template <StateMaskSet Mask, typename T, typename S, typename U>
+class GenericState3 : public MaskedRenderState<Mask>
{
public:
- bool isEqual(const Derived& i) const
- { return (m_1 == i.m_1) && (m_2 == i.m_2) && (m_3 == i.m_3); }
+ GenericState3 *set(const T& v1, const S& v2, const U& v3)
+ {
+ m_1 = v1;
+ m_2 = v2;
+ m_3 = v3;
+ return this;
+ }
+ virtual bool equalTo(const RenderStateImpl &renderState) const
+ {
+ const GenericState3 *other = dynamic_cast<const GenericState3*>(&renderState);
+ return (other != NULL
+ && other->m_1 == m_1
+ && other->m_2 == m_2
+ && other->m_3 == m_3);
+ }
protected:
- GenericState3(T t, S s, U u) :
- m_1(t),
- m_2(s),
- m_3(u)
- {}
-
T m_1;
S m_2;
U m_3;
};
-template <typename Derived, typename T, typename S, typename U, typename Z>
-class GenericState4 : public RenderState
+template <StateMaskSet Mask, typename T, typename S, typename U, typename Z>
+class GenericState4 : public MaskedRenderState<Mask>
{
public:
- bool isEqual(const Derived& i) const
- { return (m_1 == i.m_1) && (m_2 == i.m_2) && (m_3 == i.m_3) && (m_4 == i.m_4); }
+ GenericState4 *set(const T& v1, const S& v2, const U& v3, const Z& v4)
+ {
+ m_1 = v1;
+ m_2 = v2;
+ m_3 = v3;
+ m_4 = v4;
+ return this;
+ }
+ virtual bool equalTo(const RenderStateImpl &renderState) const
+ {
+ const GenericState4 *other = dynamic_cast<const GenericState4*>(&renderState);
+ return (other != NULL
+ && other->m_1 == m_1
+ && other->m_2 == m_2
+ && other->m_3 == m_3
+ && other->m_4 == m_4);
+ }
protected:
- GenericState4(T t, S s, U u, Z z) :
- m_1(t),
- m_2(s),
- m_3(u),
- m_4(z)
- {}
-
T m_1;
S m_2;
U m_3;
Z m_4;
};
-template <typename Derived, typename T, typename S, typename U, typename V, typename W, typename Z>
-class GenericState6 : public RenderState
+template <StateMaskSet Mask, typename T, typename S, typename U, typename V, typename W, typename Z>
+class GenericState6 : public MaskedRenderState<Mask>
{
public:
- bool isEqual(const Derived& i) const
- { return (m_1 == i.m_1) && (m_2 == i.m_2) && (m_3 == i.m_3) && (m_4 == i.m_4) && (m_5 == i.m_5) && (m_6 == i.m_6); }
+ GenericState6 *set(const T& v1, const S& v2, const U& v3, const V& v4, const W& v5, const Z& v6)
+ {
+ m_1 = v1;
+ m_2 = v2;
+ m_3 = v3;
+ m_4 = v4;
+ m_5 = v5;
+ m_6 = v6;
+ return this;
+ }
+ virtual bool equalTo(const RenderStateImpl &renderState) const
+ {
+ const GenericState6 *other = dynamic_cast<const GenericState6*>(&renderState);
+ return (other != NULL
+ && other->m_1 == m_1
+ && other->m_2 == m_2
+ && other->m_3 == m_3
+ && other->m_4 == m_4
+ && other->m_5 == m_5
+ && other->m_6 == m_6);
+ }
protected:
- GenericState6(T t, S s, U u, V v, W w, Z z)
- : m_1(t)
- , m_2(s)
- , m_3(u)
- , m_4(v)
- , m_5(w)
- , m_6(z)
- {}
-
T m_1;
S m_2;
U m_3;
diff --git a/src/render/renderstates/renderstates.cpp b/src/render/renderstates/renderstates.cpp
index db0eda0c8..8bf3d2e4b 100644
--- a/src/render/renderstates/renderstates.cpp
+++ b/src/render/renderstates/renderstates.cpp
@@ -40,6 +40,9 @@
#include "renderstates_p.h"
+#include <Qt3DCore/qscenepropertychange.h>
+#include <Qt3DRender/qrenderstate.h>
+
#include <Qt3DRender/private/graphicscontext_p.h>
QT_BEGIN_NAMESPACE
@@ -47,18 +50,32 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
namespace Render {
-template <class State>
-State* getOrCreateImpl(const State& data)
+void RenderStateImpl::updateProperty(const char *name, const QVariant &value)
{
- static QList<State*> static_instances;
- foreach (State* ext, static_instances) {
- if (ext->isEqual(data))
- return ext;
- }
+ Q_UNUSED(name);
+ Q_UNUSED(value);
+}
+
+RenderStateNode::RenderStateNode()
+ : QBackendNode()
+ , m_impl(NULL)
+{
+}
+
+void RenderStateNode::updateFromPeer(Qt3DCore::QNode *peer)
+{
+ QRenderState *renderState = static_cast<QRenderState *>(peer);
+
+ // TODO: allocate m_impl
+ m_impl = RenderStateImpl::setOrCreateState(renderState, Q_NULLPTR);
+}
- State* result = new State(data);
- static_instances.append(result);
- return result;
+void RenderStateNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+{
+ if (e->type() == Qt3DCore::NodeUpdated) {
+ Qt3DCore::QScenePropertyChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QScenePropertyChange>(e);
+ m_impl->updateProperty(propertyChange->propertyName(), propertyChange->value());
+ }
}
void BlendState::apply(GraphicsContext* gc) const
@@ -89,17 +106,14 @@ void BlendState::apply(GraphicsContext* gc) const
}
}
-BlendState *BlendState::getOrCreate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha, bool enabled, int buf)
-{
- BlendState bs(srcRGB, dstRGB, srcAlpha, dstAlpha, enabled, buf);
- return getOrCreateImpl(bs);
-}
-
-BlendState::BlendState(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha, bool enabled, int buf) :
- GenericState6<BlendState, GLenum, GLenum, GLenum, GLenum, bool, int>(
- srcRGB, dstRGB, srcAlpha, dstAlpha, enabled, buf
- )
+void BlendState::updateProperty(const char *name, const QVariant &value)
{
+ if (name == QByteArrayLiteral("srcRGB")) m_1 = value.toInt();
+ else if (name == QByteArrayLiteral("dstRGB")) m_2 = value.toInt();
+ else if (name == QByteArrayLiteral("srcAlpha")) m_3 = value.toInt();
+ else if (name == QByteArrayLiteral("dstAlphaB")) m_4 = value.toInt();
+ else if (name == QByteArrayLiteral("enabled")) m_5 = value.toBool();
+ else if (name == QByteArrayLiteral("bufferIndex")) m_6 = value.toInt();
}
void BlendEquation::apply(GraphicsContext *gc) const
@@ -107,47 +121,24 @@ void BlendEquation::apply(GraphicsContext *gc) const
gc->blendEquation(m_1);
}
-BlendEquation *BlendEquation::getOrCreate(GLenum func)
+void BlendEquation::updateProperty(const char *name, const QVariant &value)
{
- return getOrCreateImpl(BlendEquation(func));
+ if (name == QByteArrayLiteral("mode")) m_1 = value.toInt();
}
-BlendEquation::BlendEquation(GLenum func) :
- GenericState1<BlendEquation, GLenum>(func)
-{
-}
-
-
void AlphaFunc::apply(GraphicsContext* gc) const
{
gc->alphaTest(m_1, m_2);
}
-AlphaFunc *AlphaFunc::getOrCreate(GLenum func, GLclampf value)
-{
- AlphaFunc af(func, value);
- return getOrCreateImpl(af);
-}
-
-AlphaFunc::AlphaFunc(GLenum func, GLclampf value) :
- GenericState2<AlphaFunc, GLenum, GLclampf>(func, value)
-{
-}
-
void DepthTest::apply(GraphicsContext *gc) const
{
gc->depthTest(m_1);
}
-DepthTest *DepthTest::getOrCreate(GLenum func)
-{
- DepthTest dt(func);
- return getOrCreateImpl(dt);
-}
-
-DepthTest::DepthTest(GLenum func) :
- GenericState1<DepthTest, GLenum>(func)
+void DepthTest::updateProperty(const char *name, const QVariant &value)
{
+ if (name == QByteArrayLiteral("func")) m_1 = value.toInt();
}
void CullFace::apply(GraphicsContext *gc) const
@@ -155,14 +146,9 @@ void CullFace::apply(GraphicsContext *gc) const
gc->cullFace(m_1);
}
-CullFace *CullFace::getOrCreate(GLenum func)
-{
- return getOrCreateImpl(CullFace(func));
-}
-
-CullFace::CullFace(GLenum func) :
- GenericState1<CullFace, GLenum>(func)
+void CullFace::updateProperty(const char *name, const QVariant &value)
{
+ if (name == QByteArrayLiteral("mode")) m_1 = value.toInt();
}
void FrontFace::apply(GraphicsContext *gc) const
@@ -170,14 +156,9 @@ void FrontFace::apply(GraphicsContext *gc) const
gc->frontFace(m_1);
}
-FrontFace *FrontFace::getOrCreate(GLenum func)
-{
- return getOrCreateImpl(FrontFace(func));
-}
-
-FrontFace::FrontFace(GLenum func) :
- GenericState1<FrontFace, GLenum>(func)
+void FrontFace::updateProperty(const char *name, const QVariant &value)
{
+ if (name == QByteArrayLiteral("direction")) m_1 = value.toInt();
}
void DepthMask::apply(GraphicsContext *gc) const
@@ -185,19 +166,9 @@ void DepthMask::apply(GraphicsContext *gc) const
gc->depthMask(m_1);
}
-DepthMask *DepthMask::getOrCreate(GLboolean flag)
-{
- return getOrCreateImpl(DepthMask(flag));
-}
-
-DepthMask::DepthMask(GLboolean flag) :
- GenericState1<DepthMask, GLboolean>(flag)
-{
-}
-
-Dithering::Dithering()
- : RenderState()
+void DepthMask::updateProperty(const char *name, const QVariant &value)
{
+ if (name == QByteArrayLiteral("mask")) m_1 = value.toBool();
}
void Dithering::apply(GraphicsContext *gc) const
@@ -205,37 +176,18 @@ void Dithering::apply(GraphicsContext *gc) const
gc->openGLContext()->functions()->glEnable(GL_DITHER);
}
-Dithering *Dithering::getOrCreate()
-{
- return getOrCreateImpl(Dithering());
-}
-
-ScissorTest::ScissorTest(int left, int bottom, int width, int height)
- : GenericState4<ScissorTest, int, int, int, int>(left, bottom, width, height)
-{
-}
-
void ScissorTest::apply(GraphicsContext *gc) const
{
gc->openGLContext()->functions()->glEnable(GL_SCISSOR_TEST);
gc->openGLContext()->functions()->glScissor(m_1, m_2, m_3, m_4);
}
-ScissorTest *ScissorTest::getOrCreate(int left, int bottom, int width, int height)
-{
- return getOrCreateImpl(ScissorTest(left, bottom, width, height));
-}
-
-StencilTest *StencilTest::getOrCreate(GLenum frontFunc, int frontRef, uint frontMask, GLenum backFunc, int backRef, uint backMask)
-{
- return getOrCreateImpl(StencilTest(frontFunc, frontRef, frontMask,
- backFunc, backRef, backMask));
-}
-
-StencilTest::StencilTest(GLenum frontFunc, int frontRef, uint frontMask, GLenum backFunc, int backRef, uint backMask)
- : GenericState6<StencilTest, GLenum, int, uint, GLenum, int, uint>(frontFunc, frontRef, frontMask,
- backFunc, backRef, backMask)
+void ScissorTest::updateProperty(const char *name, const QVariant &value)
{
+ if (name == QByteArrayLiteral("left")) m_1 = value.toInt();
+ else if (name == QByteArrayLiteral("bottom")) m_2 = value.toInt();
+ else if (name == QByteArrayLiteral("width")) m_3 = value.toInt();
+ else if (name == QByteArrayLiteral("height")) m_4 = value.toInt();
}
void StencilTest::apply(GraphicsContext *gc) const
@@ -245,34 +197,20 @@ void StencilTest::apply(GraphicsContext *gc) const
gc->openGLContext()->functions()->glStencilFuncSeparate(GL_BACK, m_4, m_5, m_6);
}
-AlphaCoverage::AlphaCoverage()
- : RenderState()
-{
-}
-
void AlphaCoverage::apply(GraphicsContext *gc) const
{
gc->enableAlphaCoverage();
}
-AlphaCoverage *AlphaCoverage::getOrCreate()
-{
- return getOrCreateImpl(AlphaCoverage());
-}
-
void PointSize::apply(GraphicsContext *gc) const
{
gc->pointSize(m_1, m_2);
}
-PointSize *PointSize::getOrCreate(bool programmable, GLfloat value)
-{
- return getOrCreateImpl(PointSize(programmable, value));
-}
-
-PointSize::PointSize(bool programmable, GLfloat value)
- : GenericState2<PointSize, bool, GLfloat>(programmable, value)
+void PointSize::updateProperty(const char *name, const QVariant &value)
{
+ if (name == QByteArrayLiteral("specification")) m_1 = value.toBool();
+ else if (name == QByteArrayLiteral("value")) m_2 = value.toFloat();
}
void PolygonOffset::apply(GraphicsContext *gc) const
@@ -281,14 +219,10 @@ void PolygonOffset::apply(GraphicsContext *gc) const
gc->openGLContext()->functions()->glPolygonOffset(m_1, m_2);
}
-PolygonOffset *PolygonOffset::getOrCreate(GLfloat factor, GLfloat units)
-{
- return getOrCreateImpl(PolygonOffset(factor, units));
-}
-
-PolygonOffset::PolygonOffset(GLfloat factor, GLfloat units)
- : GenericState2<PolygonOffset, GLfloat, GLfloat>(factor, units)
+void PolygonOffset::updateProperty(const char *name, const QVariant &value)
{
+ if (name == QByteArrayLiteral("factor")) m_1 = value.toFloat();
+ else if (name == QByteArrayLiteral("units")) m_2 = value.toFloat();
}
void ColorMask::apply(GraphicsContext *gc) const
@@ -296,14 +230,12 @@ void ColorMask::apply(GraphicsContext *gc) const
gc->openGLContext()->functions()->glColorMask(m_1, m_2, m_3, m_4);
}
-ColorMask::ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
- : GenericState4<ColorMask, GLboolean, GLboolean, GLboolean, GLboolean>(red, green, blue, alpha)
-{
-}
-
-ColorMask *ColorMask::getOrCreate(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+void ColorMask::updateProperty(const char *name, const QVariant &value)
{
- return getOrCreateImpl(ColorMask(red, green, blue, alpha));
+ if (name == QByteArrayLiteral("red")) m_1 = value.toBool();
+ else if (name == QByteArrayLiteral("green")) m_2 = value.toBool();
+ else if (name == QByteArrayLiteral("blue")) m_3 = value.toBool();
+ else if (name == QByteArrayLiteral("alpha")) m_4 = value.toBool();
}
void ClipPlane::apply(GraphicsContext *gc) const
@@ -311,14 +243,9 @@ void ClipPlane::apply(GraphicsContext *gc) const
gc->enableClipPlane(m_1);
}
-ClipPlane::ClipPlane(int plane)
- : GenericState1<ClipPlane, int>(plane)
-{
-}
-
-ClipPlane *ClipPlane::getOrCreate(int plane)
+void ClipPlane::updateProperty(const char *name, const QVariant &value)
{
- return getOrCreateImpl(ClipPlane(plane));
+ if (name == QByteArrayLiteral("plane")) m_1 = value.toInt();
}
void StencilOp::apply(GraphicsContext *gc) const
@@ -327,30 +254,16 @@ void StencilOp::apply(GraphicsContext *gc) const
gc->openGLContext()->functions()->glStencilOpSeparate(GL_BACK, m_4, m_5, m_6);
}
-StencilOp *StencilOp::getOrCreate(GLenum fsfail, GLenum fdfail, GLenum fdspass, GLenum bsfail, GLenum bdfail, GLenum bdspass)
-{
- return getOrCreateImpl(StencilOp(fsfail, fdfail, fdspass, bsfail, bdfail, bdspass));
-}
-
-StencilOp::StencilOp(GLenum fsfail, GLenum fdfail, GLenum fdspass, GLenum bsfail, GLenum bdfail, GLenum bdspass)
- : GenericState6<StencilOp, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum>(fsfail, fdfail, fdspass, bsfail, bdfail, bdspass)
-{
-}
-
void StencilMask::apply(GraphicsContext *gc) const
{
gc->openGLContext()->functions()->glStencilMaskSeparate(GL_FRONT, m_1);
gc->openGLContext()->functions()->glStencilMaskSeparate(GL_BACK, m_2);
}
-StencilMask *StencilMask::getOrCreate(uint frontMask, uint backMask)
-{
- return getOrCreateImpl(StencilMask(frontMask, backMask));
-}
-
-StencilMask::StencilMask(uint frontMask, uint backMask)
- : GenericState2<StencilMask, uint, uint>(frontMask, backMask)
+void StencilMask::updateProperty(const char *name, const QVariant &value)
{
+ if (name == QByteArrayLiteral("frontMask")) m_1 = value.toInt();
+ else if (name == QByteArrayLiteral("backMask")) m_2 = value.toInt();
}
} // namespace Render
diff --git a/src/render/renderstates/renderstates_p.h b/src/render/renderstates/renderstates_p.h
index 1b2503897..74a2fa82a 100644
--- a/src/render/renderstates/renderstates_p.h
+++ b/src/render/renderstates/renderstates_p.h
@@ -61,232 +61,125 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
namespace Render {
-class Q_AUTOTEST_EXPORT BlendState : public GenericState6<BlendState, GLenum, GLenum, GLenum, GLenum, bool, int>
+template <class State>
+State* createRenderStateImpl()
+{
+ return new State();
+}
+
+class Q_AUTOTEST_EXPORT BlendState : public GenericState6<BlendStateMask, GLenum, GLenum, GLenum, GLenum, bool, int>
{
public:
virtual void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
- virtual StateMaskSet mask() const Q_DECL_OVERRIDE
- { return BlendStateMask; }
-
- static BlendState *getOrCreate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha, bool enabled, int buf);
-private:
- BlendState(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha, bool enabled, int buf);
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
-class Q_AUTOTEST_EXPORT BlendEquation : public GenericState1<BlendEquation, GLenum>
+class Q_AUTOTEST_EXPORT BlendEquation : public GenericState1<BlendStateMask, GLenum>
{
public:
virtual void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
-
- virtual StateMaskSet mask() const Q_DECL_OVERRIDE
- { return BlendStateMask; }
-
- static BlendEquation *getOrCreate(GLenum func);
-
-private:
- BlendEquation(GLenum func);
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
-class Q_AUTOTEST_EXPORT AlphaFunc : public GenericState2<AlphaFunc, GLenum, GLclampf>
+class Q_AUTOTEST_EXPORT AlphaFunc : public GenericState2<AlphaTestMask, GLenum, GLclampf>
{
public:
virtual void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
-
- virtual StateMaskSet mask() const Q_DECL_OVERRIDE
- { return AlphaTestMask; }
-
- static AlphaFunc *getOrCreate(GLenum func, GLclampf value);
-private:
- AlphaFunc(GLenum func, GLclampf value);
};
-class Q_AUTOTEST_EXPORT DepthTest : public GenericState1<DepthTest, GLenum>
+class Q_AUTOTEST_EXPORT DepthTest : public GenericState1<DepthTestStateMask, GLenum>
{
public:
virtual void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
-
- virtual StateMaskSet mask() const Q_DECL_OVERRIDE
- { return DepthTestStateMask; }
-
- static DepthTest *getOrCreate(GLenum func);
-
-private:
- DepthTest(GLenum func);
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
-class Q_AUTOTEST_EXPORT DepthMask : public GenericState1<DepthMask, GLboolean>
+class Q_AUTOTEST_EXPORT DepthMask : public GenericState1<DepthWriteStateMask, GLboolean>
{
public:
virtual void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
-
- virtual StateMaskSet mask() const Q_DECL_OVERRIDE
- { return DepthWriteStateMask; }
-
- static DepthMask *getOrCreate(GLboolean func);
-
-private:
- DepthMask(GLboolean func);
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
-class Q_AUTOTEST_EXPORT CullFace : public GenericState1<CullFace, GLenum>
+class Q_AUTOTEST_EXPORT CullFace : public GenericState1<CullFaceStateMask, GLenum>
{
public:
virtual void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
-
- virtual StateMaskSet mask() const Q_DECL_OVERRIDE
- { return CullFaceStateMask; }
-
- static CullFace *getOrCreate(GLenum func);
-
-private:
- CullFace(GLenum func);
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
-class Q_AUTOTEST_EXPORT FrontFace : public GenericState1<FrontFace, GLenum>
+class Q_AUTOTEST_EXPORT FrontFace : public GenericState1<FrontFaceStateMask, GLenum>
{
public:
virtual void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
-
- virtual StateMaskSet mask() const Q_DECL_OVERRIDE
- { return FrontFaceStateMask; }
- static FrontFace *getOrCreate(GLenum func);
-
-private:
- FrontFace(GLenum func);
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
-class Q_AUTOTEST_EXPORT Dithering : public RenderState
+class Q_AUTOTEST_EXPORT Dithering : public MaskedRenderState<DitheringStateMask>
{
public:
virtual void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
- virtual StateMaskSet mask() const Q_DECL_OVERRIDE
- { return DitheringStateMask; }
-
- bool isEqual(const Dithering &) { return true; }
-
- static Dithering *getOrCreate();
-private:
- Dithering();
};
-class Q_AUTOTEST_EXPORT ScissorTest : public GenericState4<ScissorTest, int, int, int, int>
+class Q_AUTOTEST_EXPORT ScissorTest : public GenericState4<ScissorStateMask, int, int, int, int>
{
public:
virtual void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
- virtual StateMaskSet mask() const Q_DECL_OVERRIDE
- { return ScissorStateMask; }
-
- static ScissorTest *getOrCreate(int left, int bottom, int width, int height);
-
-private:
- ScissorTest(int left, int bottom, int width, int height);
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
-class Q_AUTOTEST_EXPORT StencilTest : public GenericState6<StencilTest, GLenum, int, uint, GLenum, int, uint>
+class Q_AUTOTEST_EXPORT StencilTest : public GenericState6<StencilTestStateMask, GLenum, int, uint, GLenum, int, uint>
{
public:
virtual void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
- virtual StateMaskSet mask() const Q_DECL_OVERRIDE
- { return StencilTestStateMask; }
- static StencilTest *getOrCreate(GLenum frontFunc, int frontRef, uint frontMask, GLenum backFunc, int backRef, uint backMask);
-
-private:
- StencilTest(GLenum frontFunc, int frontRef, uint frontMask, GLenum backFunc, int backRef, uint backMask);
};
-class Q_AUTOTEST_EXPORT AlphaCoverage : public RenderState
+class Q_AUTOTEST_EXPORT AlphaCoverage : public MaskedRenderState<AlphaCoverageStateMask>
{
public:
void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
- StateMaskSet mask() const Q_DECL_OVERRIDE
- { return AlphaCoverageStateMask; }
-
- bool isEqual(const AlphaCoverage &) { return true; }
-
- static AlphaCoverage *getOrCreate();
-
-private:
- AlphaCoverage();
};
-class Q_AUTOTEST_EXPORT PointSize : public GenericState2<PointSize, bool, GLfloat>
+class Q_AUTOTEST_EXPORT PointSize : public GenericState2<PointSizeMask, bool, GLfloat>
{
public:
void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
- StateMaskSet mask() const Q_DECL_OVERRIDE
- { return PointSizeMask; }
-
- static PointSize *getOrCreate(bool programmable, GLfloat value);
-
-private:
- PointSize(bool programmable, GLfloat value);
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
-class Q_AUTOTEST_EXPORT PolygonOffset : public GenericState2<PolygonOffset, GLfloat, GLfloat>
+class Q_AUTOTEST_EXPORT PolygonOffset : public GenericState2<PolygonOffsetStateMask, GLfloat, GLfloat>
{
public:
void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
- StateMaskSet mask() const Q_DECL_OVERRIDE
- { return PolygonOffsetStateMask; }
-
- static PolygonOffset *getOrCreate(GLfloat factor, GLfloat units);
-
-private:
- PolygonOffset(GLfloat factor, GLfloat units);
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
-class Q_AUTOTEST_EXPORT ColorMask : public GenericState4<ColorMask, GLboolean, GLboolean, GLboolean, GLboolean>
+class Q_AUTOTEST_EXPORT ColorMask : public GenericState4<ColorStateMask, GLboolean, GLboolean, GLboolean, GLboolean>
{
public:
void apply(GraphicsContext *gc) const Q_DECL_FINAL;
- StateMaskSet mask() const Q_DECL_FINAL { return ColorStateMask; }
-
- static ColorMask *getOrCreate(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
-
-private:
- ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
-class Q_AUTOTEST_EXPORT ClipPlane : public GenericState1<ClipPlane, int>
+class Q_AUTOTEST_EXPORT ClipPlane : public GenericState1<ClipPlaneMask, int>
{
public:
void apply(GraphicsContext *gc) const Q_DECL_FINAL;
-
- StateMaskSet mask() const Q_DECL_FINAL
- { return ClipPlaneMask; }
- static ClipPlane *getOrCreate(int plane);
-
-private:
- ClipPlane(int plane);
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
-class Q_AUTOTEST_EXPORT StencilOp : public GenericState6<StencilOp, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum>
+class Q_AUTOTEST_EXPORT StencilOp : public GenericState6<StencilOpMask, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum>
{
public:
void apply(GraphicsContext *gc) const Q_DECL_FINAL;
-
- StateMaskSet mask() const Q_DECL_FINAL
- { return StencilOpMask; }
- static StencilOp *getOrCreate(GLenum fsfail, GLenum fdfail, GLenum fdspass,
- GLenum bsfail, GLenum bdfail, GLenum bdspass);
-
-private:
- StencilOp(GLenum fsfail, GLenum fdfail, GLenum fdspass,
- GLenum bsfail, GLenum bdfail, GLenum bdspass);
};
-class Q_AUTOTEST_EXPORT StencilMask : public GenericState2<StencilMask, uint, uint>
+class Q_AUTOTEST_EXPORT StencilMask : public GenericState2<StencilWriteStateMask, uint, uint>
{
public:
void apply(GraphicsContext *gc) const Q_DECL_FINAL;
-
- StateMaskSet mask() const Q_DECL_FINAL
- { return StencilWriteStateMask; }
- static StencilMask *getOrCreate(uint frontMask, uint backMask);
-
-private:
- StencilMask(uint frontMask, uint backMask);
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
} // namespace Render
diff --git a/src/render/renderstates/renderstateset.cpp b/src/render/renderstates/renderstateset.cpp
index 03b921ee8..1ae4f564f 100644
--- a/src/render/renderstates/renderstateset.cpp
+++ b/src/render/renderstates/renderstateset.cpp
@@ -83,7 +83,7 @@ RenderStateSet::~RenderStateSet()
{
}
-void RenderStateSet::addState(RenderState *ds)
+void RenderStateSet::addState(RenderStateImpl *ds)
{
Q_ASSERT(ds);
m_states.append(ds);
@@ -105,7 +105,7 @@ int RenderStateSet::changeCost(RenderStateSet *previousState)
cost += int(bs.count());
// now, find out how many states we're changing
- Q_FOREACH (RenderState* ds, m_states) {
+ Q_FOREACH (RenderStateImpl *ds, m_states) {
// if the other state contains matching, then doesn't
// contribute to cost at all
if (previousState->contains(ds)) {
@@ -139,7 +139,7 @@ void RenderStateSet::apply(GraphicsContext *gc)
if (m_cachedPrevious && previousStates == m_cachedPrevious) {
// state-change cache hit
- foreach (RenderState* ds, m_cachedDeltaStates) {
+ Q_FOREACH (RenderStateImpl *ds, m_cachedDeltaStates) {
ds->apply(gc);
}
} else {
@@ -147,7 +147,7 @@ void RenderStateSet::apply(GraphicsContext *gc)
m_cachedDeltaStates.clear();
m_cachedPrevious = previousStates;
- Q_FOREACH (RenderState* ds, m_states) {
+ Q_FOREACH (RenderStateImpl *ds, m_states) {
if (previousStates && previousStates->contains(ds)) {
continue;
}
@@ -237,110 +237,120 @@ void RenderStateSet::resetMasked(StateMaskSet maskOfStatesToReset, GraphicsConte
}
}
-bool RenderStateSet::contains(RenderState *ds) const
+bool RenderStateSet::contains(RenderStateImpl *ds) const
{
// trivial reject using the state mask bits
if (!(ds->mask() & stateMask()))
return false;
- return m_states.contains(ds);
+ Q_FOREACH (RenderStateImpl* rs, m_states) {
+ if (ds->equalTo(*rs))
+ return true;
+ }
+
+ return false;
}
-RenderState *RenderState::getOrCreateBackendState(QRenderState *renderState)
+template <class State>
+State* createIfNeeded(RenderStateImpl *state)
+{
+ if (state != Q_NULLPTR)
+ return static_cast<State*>(state);
+ return createRenderStateImpl<State>();
+}
+
+
+RenderStateImpl* RenderStateImpl::setOrCreateState(QRenderState *renderState, RenderStateImpl *target)
{
switch (renderState->type()) {
case QRenderState::AlphaTest: {
QAlphaTest *alphaTest = static_cast<QAlphaTest *>(renderState);
- return AlphaFunc::getOrCreate(alphaTest->func(), alphaTest->clamp());
+ return createIfNeeded<AlphaFunc>(target)->set(alphaTest->func(), alphaTest->clamp());
}
case QRenderState::BlendEquation: {
QBlendEquation *blendEquation = static_cast<QBlendEquation *>(renderState);
- return BlendEquation::getOrCreate(blendEquation->mode());
+ return createIfNeeded<BlendEquation>(target)->set(blendEquation->mode());
}
case QRenderState::BlendState: {
QBlendState *blendState = static_cast<QBlendState *>(renderState);
// just use the same values for RGB and Alpha
- return BlendState::getOrCreate(blendState->srcRGB(), blendState->dstRGB(),
+ return createIfNeeded<BlendState>(target)->set(blendState->srcRGB(), blendState->dstRGB(),
blendState->srcRGB(), blendState->dstRGB(),
blendState->enabled(),
blendState->bufferIndex());
}
case QRenderState::BlendStateSeparate: {
QBlendState *blendState = static_cast<QBlendState *>(renderState);
- return BlendState::getOrCreate(blendState->srcRGB(), blendState->dstRGB(),
+ return createIfNeeded<BlendState>(target)->set(blendState->srcRGB(), blendState->dstRGB(),
blendState->srcAlpha(), blendState->dstAlpha(),
blendState->enabled(),
blendState->bufferIndex());
}
case QRenderState::CullFace: {
QCullFace *cullFace = static_cast<QCullFace *>(renderState);
- return CullFace::getOrCreate(cullFace->mode());
+ return createIfNeeded<CullFace>(target)->set(cullFace->mode());
}
case QRenderState::DepthMask: {
QDepthMask *depthMask = static_cast<QDepthMask *>(renderState);
- return DepthMask::getOrCreate(depthMask->mask());
+ return createIfNeeded<DepthMask>(target)->set(depthMask->mask());
}
case QRenderState::DepthTest: {
QDepthTest *depthTest = static_cast<QDepthTest *>(renderState);
- return DepthTest::getOrCreate(depthTest->func());
- }
- case QRenderState::Dithering: {
- return Dithering::getOrCreate();
+ return createIfNeeded<DepthTest>(target)->set(depthTest->func());
}
+ case QRenderState::AlphaCoverage:
+ case QRenderState::Dithering:
case QRenderState::FrontFace: {
QFrontFace *frontFace = static_cast<QFrontFace *>(renderState);
- return FrontFace::getOrCreate(frontFace->direction());
+ return createIfNeeded<FrontFace>(target)->set(frontFace->direction());
}
case QRenderState::ScissorTest: {
QScissorTest *scissorTest = static_cast<QScissorTest *>(renderState);
- return ScissorTest::getOrCreate(scissorTest->left(),
+ return createIfNeeded<ScissorTest>(target)->set(scissorTest->left(),
scissorTest->bottom(),
scissorTest->width(),
scissorTest->height());
}
case QRenderState::StencilTest: {
QStencilTest *stencilTest = static_cast<QStencilTest *>(renderState);
- return StencilTest::getOrCreate(stencilTest->front()->func(),
+ return createIfNeeded<StencilTest>(target)->set(stencilTest->front()->func(),
stencilTest->front()->ref(),
stencilTest->front()->mask(),
stencilTest->back()->func(),
stencilTest->back()->ref(),
stencilTest->back()->mask());
}
- case QRenderState::AlphaCoverage: {
- return AlphaCoverage::getOrCreate();
- }
case QRenderState::PointSize: {
QPointSize *pointSize = static_cast<QPointSize *>(renderState);
- return PointSize::getOrCreate(pointSize->isProgrammable(), pointSize->value());
+ return createIfNeeded<PointSize>(target)->set(pointSize->isProgrammable(), pointSize->value());
}
case QRenderState::PolygonOffset: {
QPolygonOffset *polygonOffset = static_cast<QPolygonOffset *>(renderState);
- return PolygonOffset::getOrCreate(polygonOffset->factor(),
+ return createIfNeeded<PolygonOffset>(target)->set(polygonOffset->factor(),
polygonOffset->units());
}
case QRenderState::ColorMask: {
QColorMask *colorMask = static_cast<QColorMask *>(renderState);
- return ColorMask::getOrCreate(colorMask->isRed(),
+ return createIfNeeded<ColorMask>(target)->set(colorMask->isRed(),
colorMask->isGreen(),
colorMask->isBlue(),
colorMask->isAlpha());
}
case QRenderState::ClipPlane: {
QClipPlane *clipPlane = static_cast<QClipPlane *>(renderState);
- return ClipPlane::getOrCreate(clipPlane->plane());
+ return createIfNeeded<ClipPlane>(target)->set(clipPlane->plane());
}
case QRenderState::StencilOp: {
QStencilOp *stencilOp = static_cast<QStencilOp *>(renderState);
const QStencilOpSeparate *front = stencilOp->front();
const QStencilOpSeparate *back = stencilOp->back();
- return StencilOp::getOrCreate(front->stencilFail(), front->depthFail(), front->stencilDepthPass(),
+ return createIfNeeded<StencilOp>(target)->set(front->stencilFail(), front->depthFail(), front->stencilDepthPass(),
back->stencilFail(), back->depthFail(), back->stencilDepthPass());
}
case QRenderState::StencilMask: {
QStencilMask *stencilMask = static_cast<QStencilMask *>(renderState);
- return StencilMask::getOrCreate(stencilMask->frontMask(), stencilMask->backMask());
- }
+ return createIfNeeded<StencilMask>(target)->set(stencilMask->frontMask(), stencilMask->backMask());
+ }
default:
Q_UNREACHABLE();
diff --git a/src/render/renderstates/renderstateset_p.h b/src/render/renderstates/renderstateset_p.h
index 9f2f1440f..a82cb20f0 100644
--- a/src/render/renderstates/renderstateset_p.h
+++ b/src/render/renderstates/renderstateset_p.h
@@ -72,7 +72,7 @@ public:
RenderStateSet();
~RenderStateSet();
- void addState(RenderState* ds);
+ void addState(RenderStateImpl* ds);
/**
* @brief changeCost - metric of cost to change to this state-set from
@@ -94,14 +94,14 @@ private:
* @param ds
* @return
*/
- bool contains(RenderState* ds) const;
+ bool contains(RenderStateImpl* ds) const;
- QVector<RenderState*> m_states;
+ QVector<RenderStateImpl*> m_states;
StateMaskSet m_stateMask;
RenderStateSet* m_cachedPrevious;
- QVector<RenderState*> m_cachedDeltaStates;
+ QVector<RenderStateImpl*> m_cachedDeltaStates;
};
} // namespace Render