${internal_src_dir}/update/animation/scene-graph-animation.cpp
${internal_src_dir}/update/animation/scene-graph-constraint-base.cpp
+ ${internal_src_dir}/update/common/collected-uniform-map.cpp
${internal_src_dir}/update/common/discard-queue.cpp
${internal_src_dir}/update/common/property-base.cpp
${internal_src_dir}/update/common/property-owner-messages.cpp
${internal_src_dir}/update/common/property-condition-variable-step-functions.cpp
${internal_src_dir}/update/common/property-owner.cpp
${internal_src_dir}/update/common/scene-graph-buffers.cpp
- ${internal_src_dir}/update/common/scene-graph-connection-change-propagator.cpp
${internal_src_dir}/update/common/scene-graph-property-notification.cpp
${internal_src_dir}/update/common/scene-graph-scene.cpp
${internal_src_dir}/update/common/uniform-map.cpp
/**
* An interface to provide data for a Renderer
*/
-class NodeDataProvider : UniformMapDataProvider, public PartialRenderingDataProvider
+class NodeDataProvider : public PartialRenderingDataProvider
{
public:
/**
virtual const Vector4& GetRenderColor(BufferIndex bufferIndex) const = 0;
/**
- * @copydoc Dali::Internal::SceneGraph::UniformMapDataProvider::GetUniformMapChanged()
+ * Get the map of uniforms to property value addresses (for node only)
*/
- bool GetUniformMapChanged(BufferIndex bufferIndex) const override = 0;
-
- /**
- * @copydoc Dali::Internal::SceneGraph::UniformMapDataProvider::GetUniformMap()
- */
- const CollectedUniformMap& GetUniformMap(BufferIndex bufferIndex) const override = 0;
+ virtual const UniformMap& GetNodeUniformMap() const = 0;
protected:
/**
* limitations under the License.
*/
#include <dali/internal/common/buffer-index.h>
-#include <dali/internal/update/common/uniform-map.h>
-#include <dali/public-api/common/dali-vector.h>
+#include <dali/internal/update/common/collected-uniform-map.h>
+#include <dali/public-api/common/vector-wrapper.h>
namespace Dali
{
{
namespace SceneGraph
{
-class UniformMap;
-class UniformPropertyMapping;
-
-using CollectedUniformMap = Dali::Vector<UniformPropertyMapping>;
-
/**
* This class maps uniform names to property value pointers.
*/
UniformMapDataProvider() = default;
/**
- * Return true if the uniform map has been changed this frame
- * Note, this only informs if the uniform mappings have changed,
- * not if any actual property value has changed.
- *
- * @param[in] bufferIndex The buffer index
- * @return true if the uniform map has changed
- */
- [[nodiscard]] virtual bool GetUniformMapChanged(BufferIndex bufferIndex) const = 0;
-
- /**
- * Get the complete map of uniforms to property value addresses
- * (The map is double buffered - it can be retrieved through this interface)
+ * Get the collected map of uniforms to property value addresses
*
- * @param[in] bufferIndex The bufferIndex
* @return the uniform map
*/
- [[nodiscard]] virtual const CollectedUniformMap& GetUniformMap(BufferIndex bufferIndex) const = 0;
+ [[nodiscard]] virtual const CollectedUniformMap& GetCollectedUniformMap() const = 0;
protected:
/**
mRenderDataProvider(dataProvider),
mGeometry(geometry),
mProgramCache(nullptr),
- mUniformIndexMap(),
- mUniformsHash(),
mStencilParameters(stencilParameters),
mBlendingOptions(),
mIndexedDrawFirstElement(0),
BindTextures(commandBuffer, boundTextures);
- BuildUniformIndexMap(bufferIndex, node, size, *program);
+ int nodeIndex = BuildUniformIndexMap(bufferIndex, node, size, *program);
- WriteUniformBuffer(bufferIndex, commandBuffer, program, instruction, node, modelMatrix, modelViewMatrix, viewMatrix, projectionMatrix, size);
+ WriteUniformBuffer(bufferIndex, commandBuffer, program, instruction, node, modelMatrix, modelViewMatrix, viewMatrix, projectionMatrix, size, nodeIndex);
bool drawn = false; // Draw can fail if there are no vertex buffers or they haven't been uploaded yet
// @todo We should detect this case much earlier to prevent unnecessary work
return drawn;
}
-void Renderer::BuildUniformIndexMap(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program)
+int Renderer::BuildUniformIndexMap(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program)
{
// Check if the map has changed
DALI_ASSERT_DEBUG(mRenderDataProvider && "No Uniform map data provider available");
const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMapDataProvider();
+ const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetCollectedUniformMap();
+ const SceneGraph::UniformMap& uniformMapNode = node.GetNodeUniformMap();
- if(uniformMapDataProvider.GetUniformMapChanged(bufferIndex) ||
- node.GetUniformMapChanged(bufferIndex) ||
- mUniformIndexMap.Count() == 0 ||
- mShaderChanged)
+ bool updateMaps;
+
+ // Usual case is to only have 1 node, however we do allow multiple nodes to reuse the same
+ // renderer, so we have to cache uniform map per render item (node / renderer pair).
+
+ const void* nodePtr = static_cast<const void*>(&node);
+ auto iter = std::find_if(mNodeIndexMap.begin(), mNodeIndexMap.end(), [nodePtr](RenderItemLookup& element) { return element.node == nodePtr; });
+
+ int renderItemMapIndex;
+ if(iter == mNodeIndexMap.end())
+ {
+ renderItemMapIndex = mUniformIndexMaps.size();
+ RenderItemLookup renderItemLookup;
+ renderItemLookup.node = &node;
+ renderItemLookup.index = renderItemMapIndex;
+ renderItemLookup.nodeChangeCounter = uniformMapNode.GetChangeCounter();
+ renderItemLookup.renderItemMapChangeCounter = uniformMap.GetChangeCounter();
+ mNodeIndexMap.emplace_back(renderItemLookup);
+
+ updateMaps = true;
+ mUniformIndexMaps.resize(mUniformIndexMaps.size() + 1);
+ }
+ else
+ {
+ renderItemMapIndex = iter->index;
+
+ updateMaps = (uniformMapNode.GetChangeCounter() != iter->nodeChangeCounter) ||
+ (uniformMap.GetChangeCounter() != iter->renderItemMapChangeCounter) ||
+ (mUniformIndexMaps[renderItemMapIndex].size() == 0);
+
+ iter->nodeChangeCounter = uniformMapNode.GetChangeCounter();
+ iter->renderItemMapChangeCounter = uniformMap.GetChangeCounter();
+ }
+
+ if(updateMaps || mShaderChanged)
{
// Reset shader pointer
mShaderChanged = false;
- const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap(bufferIndex);
- const SceneGraph::CollectedUniformMap& uniformMapNode = node.GetUniformMap(bufferIndex);
-
const uint32_t mapCount = uniformMap.Count();
const uint32_t mapNodeCount = uniformMapNode.Count();
- mUniformIndexMap.Clear(); // Clear contents, but keep memory if we don't change size
- mUniformIndexMap.Resize(mapCount + mapNodeCount);
+ mUniformIndexMaps[renderItemMapIndex].clear(); // Clear contents, but keep memory if we don't change size
+ mUniformIndexMaps[renderItemMapIndex].resize(mapCount + mapNodeCount);
// Copy uniform map into mUniformIndexMap
uint32_t mapIndex = 0;
for(; mapIndex < mapCount; ++mapIndex)
{
- mUniformIndexMap[mapIndex].propertyValue = uniformMap[mapIndex].propertyPtr;
- mUniformIndexMap[mapIndex].uniformName = uniformMap[mapIndex].uniformName;
- mUniformIndexMap[mapIndex].uniformNameHash = uniformMap[mapIndex].uniformNameHash;
- mUniformIndexMap[mapIndex].uniformNameHashNoArray = uniformMap[mapIndex].uniformNameHashNoArray;
- mUniformIndexMap[mapIndex].arrayIndex = uniformMap[mapIndex].arrayIndex;
+ mUniformIndexMaps[renderItemMapIndex][mapIndex].propertyValue = uniformMap.mUniformMap[mapIndex].propertyPtr;
+ mUniformIndexMaps[renderItemMapIndex][mapIndex].uniformName = uniformMap.mUniformMap[mapIndex].uniformName;
+ mUniformIndexMaps[renderItemMapIndex][mapIndex].uniformNameHash = uniformMap.mUniformMap[mapIndex].uniformNameHash;
+ mUniformIndexMaps[renderItemMapIndex][mapIndex].uniformNameHashNoArray = uniformMap.mUniformMap[mapIndex].uniformNameHashNoArray;
+ mUniformIndexMaps[renderItemMapIndex][mapIndex].arrayIndex = uniformMap.mUniformMap[mapIndex].arrayIndex;
}
for(uint32_t nodeMapIndex = 0; nodeMapIndex < mapNodeCount; ++nodeMapIndex)
bool found(false);
for(uint32_t i = 0; i < mapCount; ++i)
{
- if(mUniformIndexMap[i].uniformNameHash == hash &&
- mUniformIndexMap[i].uniformName == name)
+ if(mUniformIndexMaps[renderItemMapIndex][i].uniformNameHash == hash &&
+ mUniformIndexMaps[renderItemMapIndex][i].uniformName == name)
{
- mUniformIndexMap[i].propertyValue = uniformMapNode[nodeMapIndex].propertyPtr;
- found = true;
+ mUniformIndexMaps[renderItemMapIndex][i].propertyValue = uniformMapNode[nodeMapIndex].propertyPtr;
+ found = true;
break;
}
}
if(!found)
{
- mUniformIndexMap[mapIndex].propertyValue = uniformMapNode[nodeMapIndex].propertyPtr;
- mUniformIndexMap[mapIndex].uniformName = uniformMapNode[nodeMapIndex].uniformName;
- mUniformIndexMap[mapIndex].uniformNameHash = uniformMapNode[nodeMapIndex].uniformNameHash;
- mUniformIndexMap[mapIndex].uniformNameHashNoArray = uniformMapNode[nodeMapIndex].uniformNameHashNoArray;
- mUniformIndexMap[mapIndex].arrayIndex = uniformMapNode[nodeMapIndex].arrayIndex;
+ mUniformIndexMaps[renderItemMapIndex][mapIndex].propertyValue = uniformMapNode[nodeMapIndex].propertyPtr;
+ mUniformIndexMaps[renderItemMapIndex][mapIndex].uniformName = uniformMapNode[nodeMapIndex].uniformName;
+ mUniformIndexMaps[renderItemMapIndex][mapIndex].uniformNameHash = uniformMapNode[nodeMapIndex].uniformNameHash;
+ mUniformIndexMaps[renderItemMapIndex][mapIndex].uniformNameHashNoArray = uniformMapNode[nodeMapIndex].uniformNameHashNoArray;
+ mUniformIndexMaps[renderItemMapIndex][mapIndex].arrayIndex = uniformMapNode[nodeMapIndex].arrayIndex;
++mapIndex;
}
}
- mUniformIndexMap.Resize(mapIndex);
+ mUniformIndexMaps[renderItemMapIndex].resize(mapIndex);
}
+ return renderItemMapIndex;
}
void Renderer::WriteUniformBuffer(
const Matrix& modelViewMatrix,
const Matrix& viewMatrix,
const Matrix& projectionMatrix,
- const Vector3& size)
+ const Vector3& size,
+ int nodeIndex)
{
// Create the UBO
uint32_t uboOffset{0u};
WriteDefaultUniform(program->GetDefaultUniform(Program::DefaultUniformIndex::ACTOR_COLOR), *uboView, color);
// Write uniforms from the uniform map
- FillUniformBuffer(*program, instruction, *uboView, bindings, uboOffset, bufferIndex);
+ FillUniformBuffer(*program, instruction, *uboView, bindings, uboOffset, bufferIndex, nodeIndex);
// Write uSize in the end, as it shouldn't be overridable by dynamic properties.
WriteDefaultUniform(program->GetDefaultUniform(Program::DefaultUniformIndex::SIZE), *uboView, size);
Render::UniformBufferView& ubo,
std::vector<Graphics::UniformBufferBinding>*& outBindings,
uint32_t& offset,
- BufferIndex updateBufferIndex)
+ BufferIndex updateBufferIndex,
+ int nodeIndex)
{
auto& reflection = mGraphicsController->GetProgramReflection(program.GetGraphicsProgram());
auto uboCount = reflection.GetUniformBlockCount();
dataOffset += GetUniformBufferDataAlignment(mUniformBufferBindings[i].dataSize);
mUniformBufferBindings[i].buffer = ubo.GetBuffer(&mUniformBufferBindings[i].offset);
- for(UniformIndexMappings::Iterator iter = mUniformIndexMap.Begin(),
- end = mUniformIndexMap.End();
+ for(auto iter = mUniformIndexMaps[nodeIndex].begin(),
+ end = mUniformIndexMaps[nodeIndex].end();
iter != end;
++iter)
{
}
}
- uint64_t hash = 0xc70f6907UL;
- const SceneGraph::CollectedUniformMap& uniformMapNode = node->GetUniformMap(bufferIndex);
- for(const auto& uniformProperty : uniformMapNode)
+ // Hash the property values. If the values are different, then rendering is required.
+ uint64_t hash = 0xc70f6907UL;
+ const SceneGraph::UniformMap& uniformMapNode = node->GetNodeUniformMap();
+ for(uint32_t i = 0u, count = uniformMapNode.Count(); i < count; ++i)
{
- hash = uniformProperty.propertyPtr->Hash(bufferIndex, hash);
+ hash = uniformMapNode[i].propertyPtr->Hash(bufferIndex, hash);
}
const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMapDataProvider();
- const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap(bufferIndex);
- for(const auto& uniformProperty : uniformMap)
+ const SceneGraph::CollectedUniformMap& collectedUniformMap = uniformMapDataProvider.GetCollectedUniformMap();
+ for(uint32_t i = 0u, count = collectedUniformMap.Count(); i < count; ++i)
{
- hash = uniformProperty.propertyPtr->Hash(bufferIndex, hash);
+ hash = collectedUniformMap.mUniformMap[i].propertyPtr->Hash(bufferIndex, hash);
}
if(mUniformsHash != hash)
*/
// INTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/math/matrix.h>
#include <dali/public-api/math/vector4.h>
#include <dali/public-api/rendering/texture-set.h>
* @param[in] node The node using the renderer
* @param[in] size The size of the renderer
* @param[in] program The shader program on which to set the uniforms.
+ *
+ * @return the index of the node in change counters store / uniform maps store.
*/
- void BuildUniformIndexMap(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program);
+ int BuildUniformIndexMap(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program);
/**
* Bind the textures and setup the samplers
* @param[in] size Size of the render item
* @param[in] blend If true, blending is enabled
* @param[in] instruction The render instruction
+ * @param[in] The node index
*/
void WriteUniformBuffer(BufferIndex bufferIndex,
Graphics::CommandBuffer& commandBuffer,
const Matrix& modelViewMatrix,
const Matrix& viewMatrix,
const Matrix& projectionMatrix,
- const Vector3& size);
+ const Vector3& size,
+ int nodeIndex);
/**
* @brief Fill uniform buffer at index. Writes uniforms into given memory address
Render::UniformBufferView& ubo,
std::vector<Graphics::UniformBufferBinding>*& outBindings,
uint32_t& offset,
- BufferIndex updateBufferIndex);
+ BufferIndex updateBufferIndex,
+ int nodeIndex);
private:
Graphics::Controller* mGraphicsController;
FuncGetter uniformFunc{0};
};
- using UniformIndexMappings = Dali::Vector<UniformIndexMap>;
-
- UniformIndexMappings mUniformIndexMap;
- uint64_t mUniformsHash;
-
- struct HashedPipeline
- {
- uint64_t mHash{0u};
- Graphics::UniquePtr<Graphics::Pipeline> mGraphicsPipeline{nullptr};
- inline static uint64_t GetHash(const void* node, const void* instruction, bool blend)
- {
- return (reinterpret_cast<uint64_t>(node) << 32) | ((reinterpret_cast<uint64_t>(instruction) & 0xFFFFFFF) << 1) | blend;
- }
- };
-
StencilParameters mStencilParameters; ///< Struct containing all stencil related options
BlendingOptions mBlendingOptions; ///< Blending options including blend color, blend func and blend equation
uint32_t mIndexedDrawFirstElement; ///< Offset of first element to draw
uint32_t mIndexedDrawElementsCount; ///< Number of elements to draw
+ /** Struct to map node to index into mNodeMapCounters and mUniformIndexMaps */
+ struct RenderItemLookup
+ {
+ const SceneGraph::NodeDataProvider* node{nullptr}; ///<Node key
+
+ std::size_t index{0}; ///<Index into mUniformIndexMap
+ std::size_t nodeChangeCounter{0}; ///<The last known change counter for this node's uniform map
+ std::size_t renderItemMapChangeCounter{0u}; ///< Change counter of the renderer & shader collected uniform map for this render item (node/renderer pair)
+ };
+ std::vector<RenderItemLookup> mNodeIndexMap; ///< usually only 1 element.
+ using UniformIndexMappings = std::vector<UniformIndexMap>;
+ std::vector<UniformIndexMappings> mUniformIndexMaps; ///< Cached map per node/renderer/shader.
+
+ uint64_t mUniformsHash{0}; ///< Hash of uniform map property values
+
DepthFunction::Type mDepthFunction : 4; ///< The depth function
FaceCullingMode::Type mFaceCullingMode : 3; ///< The mode of face culling
DepthWriteMode::Type mDepthWriteMode : 3; ///< The depth write mode
namespace SceneGraph
{
Shader::Shader(Dali::Shader::Hint::Value& hints)
-: mHints(hints),
- mConnectionObservers()
+: mHints(hints)
{
- AddUniformMapObserver(*this);
}
Shader::~Shader()
{
- mConnectionObservers.Destroy(*this);
}
void Shader::SetShaderData(ShaderDataPtr shaderData)
DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, "%d\n", shaderData->GetHashValue());
mShaderData = shaderData;
-
- mConnectionObservers.ConnectionsChanged(*this);
}
ShaderDataPtr Shader::GetShaderData() const
return mShaderData;
}
-void Shader::AddConnectionObserver(ConnectionChangePropagator::Observer& observer)
-{
- mConnectionObservers.Add(observer);
-}
-
-void Shader::RemoveConnectionObserver(ConnectionChangePropagator::Observer& observer)
-{
- mConnectionObservers.Remove(observer);
-}
-
-void Shader::UniformMappingsChanged(const UniformMap& mappings)
-{
- // Our uniform map, or that of one of the watched children has changed.
- // Inform connected observers.
- mConnectionObservers.ConnectedUniformMapChanged();
-}
-
} // namespace SceneGraph
} // namespace Internal
#include <dali/internal/common/shader-data.h>
#include <dali/internal/event/common/event-thread-services.h>
#include <dali/internal/update/common/property-owner.h>
-#include <dali/internal/update/common/scene-graph-connection-change-propagator.h>
namespace Dali
{
class SceneController;
/**
- * A holder class for Program; also enables sharing of uniform properties
+ * This PropertyOwner enables registration of properties as uniforms.
+ * It holds a ShaderData, which can be read from Render side.
+ *
+ * Any renderer that uses this shader also registers to it's UniformMap
+ * observer, so that it can be notified when properties are registered
+ * after being linked. (DALi public API allows Renderer to be created
+ * with a shader, or a shader to be set on a renderer _before_ uniform
+ * properties are defined on a shader. This connection ensures that
+ * all the uniforms are loaded into GPU at render time).
+ *
+ * //@todo Move back to scene graph
*/
-class Shader : public PropertyOwner, public UniformMap::Observer
+class Shader : public PropertyOwner
{
public:
/**
*/
[[nodiscard]] ShaderDataPtr GetShaderData() const;
-public:
- /**
- * @copydoc ConnectionChangePropagator::AddObserver
- */
- void AddConnectionObserver(ConnectionChangePropagator::Observer& observer);
-
- /**
- * @copydoc ConnectionChangePropagator::RemoveObserver
- */
- void RemoveConnectionObserver(ConnectionChangePropagator::Observer& observer);
-
-public: // UniformMap::Observer
- /**
- * @copydoc UniformMap::Observer::UniformMappingsChanged
- */
- void UniformMappingsChanged(const UniformMap& mappings) override;
-
private: // Data
Dali::Shader::Hint::Value mHints;
ShaderDataPtr mShaderData;
-
- ConnectionChangePropagator mConnectionObservers;
};
inline void SetShaderDataMessage(EventThreadServices& eventThreadServices, const Shader& shader, ShaderDataPtr shaderData)
--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// CLASS HEADER
+#include <dali/internal/update/common/collected-uniform-map.h>
+
+// INTERNAL HEADERS
+#include <dali/devel-api/common/hash.h>
+#include <dali/internal/render/data-providers/uniform-map-data-provider.h>
+
+// EXTERNAL HEADERS
+#include <algorithm>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace SceneGraph
+{
+void CollectedUniformMap::AddMappings(const UniformMap& uniformMap)
+{
+ // Iterate thru uniformMap.
+ // Any maps that aren't in localMap should be added in a single step
+
+ // keep a static vector to avoid temporary heap allocation.
+ // As this function gets called only from update thread we don't have to
+ // make it thread safe (so no need to keep a thread_local variable).
+ static Dali::Vector<UniformPropertyMapping> newUniformMappings;
+
+ newUniformMappings.Clear();
+
+ for(UniformMap::SizeType i = 0, iCount = uniformMap.Count(); i < iCount; ++i)
+ {
+ bool found = false;
+
+ for(UniformMap::SizeType j = 0, jCount = mUniformMap.Count(); j < jCount; ++j)
+ {
+ if(mUniformMap[j].uniformName == uniformMap[i].uniformName)
+ {
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ {
+ newUniformMappings.PushBack(uniformMap[i]);
+ }
+ }
+
+ if(newUniformMappings.Count() > 0)
+ {
+ mUniformMap.Reserve(mUniformMap.Count() + newUniformMappings.Count());
+
+ for(UniformMap::SizeType i = 0, iCount = newUniformMappings.Count(); i < iCount; ++i)
+ {
+ mUniformMap.PushBack(newUniformMappings[i]);
+ }
+ }
+}
+
+} // namespace SceneGraph
+} // namespace Internal
+} // namespace Dali
--- /dev/null
+#ifndef DALI_INTERNAL_SCENE_GRAPH_COLLECTED_UNIFORM_MAP_H
+#define DALI_INTERNAL_SCENE_GRAPH_COLLECTED_UNIFORM_MAP_H
+
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <dali/internal/common/buffer-index.h>
+#include <dali/internal/update/common/uniform-map.h>
+#include <dali/public-api/common/dali-vector.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace SceneGraph
+{
+class UniformMap;
+class UniformPropertyMapping;
+
+/**
+ * Class to collect uniform mappings together into a new map.
+ * Distinct from UniformMap, as it doesn't need the observation/lifecycle
+ * overhead.
+ *
+ * It has a counter that increments each time it's changed, which
+ * allows a client to know if it's been modified since the last time
+ * the client checked.
+ */
+struct CollectedUniformMap
+{
+ /**
+ * Constructor
+ */
+ CollectedUniformMap() = default;
+
+ /**
+ * Destructor
+ */
+ ~CollectedUniformMap() = default;
+
+ /**
+ * @brief Add mappings from a UniformMap.
+ * @param[in] uniformMap to copy
+ */
+ void AddMappings(const UniformMap& uniformMap);
+
+ /**
+ * Clear the mappings
+ */
+ inline void Clear()
+ {
+ mUniformMap.Clear();
+ UpdateChangeCounter();
+ }
+
+ /**
+ * Reserve space for mappings
+ * @param[in] size The number of mappings to reserve
+ */
+ inline void Reserve(std::size_t size)
+ {
+ mUniformMap.Reserve(size);
+ }
+
+ /**
+ * @return the count of the number of mappings
+ */
+ inline std::size_t Count() const
+ {
+ return mUniformMap.Size();
+ }
+
+ /**
+ * @brief Update the change counter if the map changes.
+ */
+ void UpdateChangeCounter()
+ {
+ ++mChangeCounter;
+ }
+
+ /**
+ * Return the currently calculated hash.
+ */
+ inline std::size_t GetChangeCounter() const
+ {
+ return mChangeCounter;
+ }
+
+ Dali::Vector<UniformPropertyMapping> mUniformMap; ///< The mappings
+ std::size_t mChangeCounter{0u}; ///< The change counter
+};
+
+} // namespace SceneGraph
+} // namespace Internal
+} // namespace Dali
+
+#endif // DALI_INTERNAL_SCENE_GRAPH_COLLECTED_UNIFORM_MAP_H
+++ /dev/null
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "scene-graph-connection-change-propagator.h"
-
-namespace Dali
-{
-namespace Internal
-{
-namespace SceneGraph
-{
-ConnectionChangePropagator::ConnectionChangePropagator() = default;
-
-ConnectionChangePropagator::~ConnectionChangePropagator() = default;
-
-void ConnectionChangePropagator::Add(Observer& observer)
-{
- bool foundObserver = false;
- for(ObserversIterator iter = mObservers.Begin(); iter != mObservers.End(); ++iter)
- {
- if(*iter == &observer)
- {
- foundObserver = true;
- break;
- }
- }
- if(!foundObserver)
- {
- mObservers.PushBack(&observer);
- }
-}
-
-void ConnectionChangePropagator::Remove(Observer& observer)
-{
- for(ObserversIterator iter = mObservers.Begin(); iter != mObservers.End(); ++iter)
- {
- if(*iter == &observer)
- {
- mObservers.Erase(iter);
- return;
- }
- }
-}
-
-void ConnectionChangePropagator::ConnectionsChanged(PropertyOwner& object)
-{
- // Inform observers that the object's children have changed
- for(ObserversIterator iter = mObservers.Begin(); iter != mObservers.End(); ++iter)
- {
- Observer* observer = (*iter);
- observer->ConnectionsChanged(object);
- }
-}
-
-void ConnectionChangePropagator::ConnectedUniformMapChanged()
-{
- // Inform observers that the object's uniform map has changed
- for(ObserversIterator iter = mObservers.Begin(); iter != mObservers.End(); ++iter)
- {
- Observer* observer = (*iter);
- observer->ConnectedUniformMapChanged();
- }
-}
-
-void ConnectionChangePropagator::Destroy(PropertyOwner& object)
-{
- // Inform observers that the object's children have changed
- for(ObserversIterator iter = mObservers.Begin(); iter != mObservers.End(); ++iter)
- {
- Observer* observer = (*iter);
- observer->ObservedObjectDestroyed(object);
- }
-}
-
-} // namespace SceneGraph
-} // namespace Internal
-} // namespace Dali
+++ /dev/null
-#ifndef DALI_INTERNAL_SCENE_GRAPH_CONNECTION_CHANGE_PROPAGATOR_H
-#define DALI_INTERNAL_SCENE_GRAPH_CONNECTION_CHANGE_PROPAGATOR_H
-
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <dali/public-api/common/dali-vector.h>
-
-namespace Dali
-{
-namespace Internal
-{
-namespace SceneGraph
-{
-class PropertyOwner;
-
-/**
- * This class maintains a list of observers that are informed when
- * it's owner changes it's connections.
- */
-class ConnectionChangePropagator
-{
-public:
- class Observer
- {
- public:
- /**
- * Inform the observer of the object that it's connections have changed
- * @param[in] object The connection owner
- */
- virtual void ConnectionsChanged(PropertyOwner& object) = 0;
-
- /**
- * Inform the observer of the object that a connected object has
- * changed it's uniform map in some way.
- */
- virtual void ConnectedUniformMapChanged() = 0;
-
- /**
- * Inform the observer of the object that the object is about to be destroyed
- */
- virtual void ObservedObjectDestroyed(PropertyOwner& object)
- {
- }
-
- protected:
- /**
- * Virtual destructor, no deletion through this interface
- */
- virtual ~Observer() = default;
- };
-
- /**
- * Constructor
- */
- ConnectionChangePropagator();
-
- /**
- * Destructor
- */
- ~ConnectionChangePropagator();
-
- /**
- * Add an observer
- */
- void Add(Observer& observer);
-
- /**
- * Remove an observer
- */
- void Remove(Observer& observer);
-
- /**
- * Inform the observers that the connections to the object have changed
- * @param[in] object The connection owner
- */
- void ConnectionsChanged(PropertyOwner& object);
-
- /**
- * Inform the observers that the uniform map of this or a connected object
- * has changed.
- */
- void ConnectedUniformMapChanged();
-
- /**
- * Inform the observers that the object is about to be destroyed
- * @param[in] object The connection owner
- */
- void Destroy(PropertyOwner& object);
-
-private:
- using Observers = Dali::Vector<Observer*>;
- using ObserversIterator = Observers::Iterator;
-
- Observers mObservers;
-};
-
-} // namespace SceneGraph
-} // namespace Internal
-} // namespace Dali
-
-#endif // DALI_INTERNAL_SCENE_GRAPH_CONNECTION_CHANGE_PROPAGATOR_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
void UniformMap::MappingChanged()
{
+ ++mChangeCounter;
for(ObserversIter iter = mObservers.Begin(); iter != mObservers.End(); ++iter)
{
Observer* observer = (*iter);
#include <string>
// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
#include <dali/devel-api/common/hash.h>
-#include <dali/devel-api/common/owner-container.h>
+
#include <dali/internal/common/const-string.h>
namespace Dali
/**
* The UniformMap class is used to map uniform names to property values. It is available
- * in all of the classes responsible for rendering:
- * Actor, Renderer, Geometry, TextureSet, Shader.
+ * in the following rendering classes: Node, Renderer, Shader.
*
* It can be observed for changes to the mapping table.
*/
*/
const UniformPropertyMapping& operator[](SizeType index) const;
+ /**
+ * Return the change counter
+ */
+ inline std::size_t GetChangeCounter() const
+ {
+ return mChangeCounter;
+ }
+
private:
/**
* Helper to call the observers when the mappings have changed
using Observers = Dali::Vector<Observer*>;
using ObserversIter = Observers::Iterator;
- UniformMapContainer mUniformMaps; // Owner container of uniform maps
-
- Observers mObservers;
+ UniformMapContainer mUniformMaps; ///< container of uniform maps
+ Observers mObservers;
+ std::size_t mChangeCounter{0u}; ///< Counter that is incremented when the map changes
};
} // namespace SceneGraph
item.mRenderer = &renderable.mRenderer->GetRenderer();
item.mTextureSet = renderable.mRenderer->GetTextureSet();
item.mDepthIndex += renderable.mRenderer->GetDepthIndex();
+
+ // Ensure collected map is up to date
+ item.mIsUpdated |= renderable.mRenderer->UpdateUniformMap();
}
else
{
UpdateNodeOpacity(node, nodeDirtyFlags, updateBufferIndex);
- // Collect uniform maps
- node.PrepareRender(updateBufferIndex);
+
// For partial update, mark all children of an animating node as updated.
if(updated) // Only set to updated if parent was updated.
mScissorDepth(0u),
mDepthIndex(0u),
mDirtyFlags(NodePropertyFlags::ALL),
- mRegenerateUniformMap(0),
mDrawMode(DrawMode::NORMAL),
mColorMode(DEFAULT_COLOR_MODE),
mClippingMode(ClippingMode::DISABLED),
mPositionUsesAnchorPoint(true),
mTransparent(false)
{
- mUniformMapChanged[0] = 0u;
- mUniformMapChanged[1] = 0u;
-
#ifdef DEBUG_ENABLED
gNodeCount++;
#endif
mIsRoot = isRoot;
}
-void Node::AddUniformMapping(const UniformPropertyMapping& map)
-{
- PropertyOwner::AddUniformMapping(map);
- mRegenerateUniformMap = 2;
-}
-
-void Node::RemoveUniformMapping(const ConstString& uniformName)
-{
- PropertyOwner::RemoveUniformMapping(uniformName);
- mRegenerateUniformMap = 2;
-}
-
bool Node::IsAnimationPossible() const
{
return mIsConnectedToSceneGraph;
}
-void Node::PrepareRender(BufferIndex bufferIndex)
-{
- if(mRegenerateUniformMap != 0)
- {
- if(mRegenerateUniformMap == 2)
- {
- CollectedUniformMap& localMap = mCollectedUniformMap[bufferIndex];
- localMap.Resize(0);
-
- for(UniformMap::SizeType i = 0, count = mUniformMaps.Count(); i < count; ++i)
- {
- localMap.PushBack(mUniformMaps[i]);
- }
- }
- else if(mRegenerateUniformMap == 1)
- {
- CollectedUniformMap& localMap = mCollectedUniformMap[bufferIndex];
- CollectedUniformMap& oldMap = mCollectedUniformMap[1 - bufferIndex];
-
- localMap.Resize(oldMap.Count());
-
- CollectedUniformMap::SizeType index = 0;
- for(CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End(); iter != end; ++iter, ++index)
- {
- localMap[index] = *iter;
- }
- }
- --mRegenerateUniformMap;
- mUniformMapChanged[bufferIndex] = 1u;
- }
-}
-
void Node::ConnectChild(Node* childNode)
{
DALI_ASSERT_ALWAYS(this != childNode);
public:
/**
- * @copydoc UniformMap::Add
- */
- void AddUniformMapping(const UniformPropertyMapping& map) override;
-
- /**
- * @copydoc UniformMap::Remove
- */
- void RemoveUniformMapping(const ConstString& uniformName) override;
-
- /**
* @copydoc Dali::Internal::SceneGraph::PropertyOwner::IsAnimationPossible
*/
bool IsAnimationPossible() const override;
/**
- * Prepare the node for rendering.
- * This is called by the UpdateManager when an object is due to be rendered in the current frame.
- * @param[in] updateBufferIndex The current update buffer index.
- */
- void PrepareRender(BufferIndex bufferIndex);
-
- /**
* Called by UpdateManager when the node is added.
* Creates a new transform component in the transform manager and initialize all the properties
* related to the transformation
return GetWorldColor(bufferIndex);
}
-public: // From UniformMapDataProvider
- /**
- * @copydoc UniformMapDataProvider::GetUniformMapChanged
- */
- bool GetUniformMapChanged(BufferIndex bufferIndex) const override
- {
- return mUniformMapChanged[bufferIndex];
- }
-
/**
- * @copydoc UniformMapDataProvider::GetUniformMap
+ * @copydoc NodeDataProvider::GetNodeUniformMap
*/
- const CollectedUniformMap& GetUniformMap(BufferIndex bufferIndex) const override
+ const UniformMap& GetNodeUniformMap() const override
{
- return mCollectedUniformMap[bufferIndex];
+ return GetUniformMap();
}
private:
NodeContainer mChildren; ///< Container of children; not owned
- CollectedUniformMap mCollectedUniformMap[2]; ///< Uniform maps of the node
- uint32_t mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame
- uint32_t mClippingDepth; ///< The number of stencil clipping nodes deep this node is
- uint32_t mScissorDepth; ///< The number of scissor clipping nodes deep this node is
+ uint32_t mClippingDepth; ///< The number of stencil clipping nodes deep this node is
+ uint32_t mScissorDepth; ///< The number of scissor clipping nodes deep this node is
uint32_t mDepthIndex; ///< Depth index of the node
// flags, compressed to bitfield
NodePropertyFlags mDirtyFlags; ///< Dirty flags for each of the Node properties
- uint32_t mRegenerateUniformMap : 2; ///< Indicate if the uniform map has to be regenerated this frame
DrawMode::Type mDrawMode : 3; ///< How the Node and its children should be drawn
ColorMode mColorMode : 3; ///< Determines whether mWorldColor is inherited, 2 bits is enough
ClippingMode::Type mClippingMode : 3; ///< The clipping mode of this node
{
namespace // unnamed namespace
{
-const uint32_t UNIFORM_MAP_READY = 0;
-const uint32_t COPY_UNIFORM_MAP = 1;
-const uint32_t REGENERATE_UNIFORM_MAP = 2;
-
//Memory pool used to allocate new renderers. Memory used by this pool will be released when shutting down DALi
MemoryPoolObjectAllocator<Renderer> gRendererMemoryPool;
-void AddMappings(CollectedUniformMap& localMap, const UniformMap& uniformMap)
-{
- // Iterate thru uniformMap.
- // Any maps that aren't in localMap should be added in a single step
-
- // keep a static vector to avoid temporary heap allocation.
- // As this function gets called only from update thread we don't have to
- // make it thread safe (so no need to keep a thread_local variable).
- static CollectedUniformMap newUniformMappings;
-
- newUniformMappings.Clear();
-
- for(UniformMap::SizeType i = 0, count = uniformMap.Count(); i < count; ++i)
- {
- bool found = false;
-
- for(CollectedUniformMap::Iterator iter = localMap.Begin(); iter != localMap.End(); ++iter)
- {
- const UniformPropertyMapping& map = (*iter);
- if(map.uniformName == uniformMap[i].uniformName)
- {
- found = true;
- break;
- }
- }
- if(!found)
- {
- newUniformMappings.PushBack(uniformMap[i]);
- }
- }
-
- if(newUniformMappings.Count() > 0)
- {
- localMap.Reserve(localMap.Count() + newUniformMappings.Count());
-
- for(CollectedUniformMap::Iterator iter = newUniformMappings.Begin(),
- end = newUniformMappings.End();
- iter != end;
- ++iter)
- {
- const UniformPropertyMapping& map = (*iter);
- localMap.PushBack(map);
- }
- }
-}
-
// Flags for re-sending data to renderer.
enum Flags
{
mIndexedDrawFirstElement(0u),
mIndexedDrawElementsCount(0u),
mBlendBitmask(0u),
- mRegenerateUniformMap(0u),
mResendFlag(0u),
mDepthFunction(DepthFunction::LESS),
mFaceCullingMode(FaceCullingMode::NONE),
mDepthWriteMode(DepthWriteMode::AUTO),
mDepthTestMode(DepthTestMode::AUTO),
mRenderingBehavior(DevelRenderer::Rendering::IF_REQUIRED),
+ mUpdateDecay(Renderer::Decay::INITIAL),
+ mRegenerateUniformMap(false),
mPremultipledAlphaEnabled(false),
mOpacity(1.0f),
mDepthIndex(0)
{
- mUniformMapChanged[0] = false;
- mUniformMapChanged[1] = false;
-
- // Observe our own PropertyOwner's uniform map
+ // Observe our own PropertyOwner's uniform map.
AddUniformMapObserver(*this);
}
Renderer::~Renderer()
{
- if(mTextureSet)
- {
- mTextureSet = nullptr;
- }
if(mShader)
{
- mShader->RemoveConnectionObserver(*this);
+ mShader->RemoveUniformMapObserver(*this);
mShader = nullptr;
}
}
bool Renderer::PrepareRender(BufferIndex updateBufferIndex)
{
- if(mRegenerateUniformMap == UNIFORM_MAP_READY)
+ bool rendererUpdated = mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY || mUpdateDecay > 0;
+
+ if(mUniformMapChangeCounter != mUniformMaps.GetChangeCounter())
{
- mUniformMapChanged[updateBufferIndex] = false;
+ // The map has changed since the last time we checked.
+ rendererUpdated = true;
+ mRegenerateUniformMap = true;
+ mUpdateDecay = Renderer::Decay::INITIAL; // Render at least twice if the map has changed/actor has been added
+ mUniformMapChangeCounter = mUniformMaps.GetChangeCounter();
}
- else
+ if(mUpdateDecay > 0)
{
- if(mRegenerateUniformMap == REGENERATE_UNIFORM_MAP)
- {
- CollectedUniformMap& localMap = mCollectedUniformMap[updateBufferIndex];
- localMap.Clear();
-
- const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
-
- auto size = rendererUniformMap.Count();
- if(mShader)
- {
- size += mShader->GetUniformMap().Count();
- }
-
- localMap.Reserve(size);
-
- AddMappings(localMap, rendererUniformMap);
-
- if(mShader)
- {
- AddMappings(localMap, mShader->GetUniformMap());
- }
- }
- else if(mRegenerateUniformMap == COPY_UNIFORM_MAP)
- {
- // Copy old map into current map
- CollectedUniformMap& localMap = mCollectedUniformMap[updateBufferIndex];
- CollectedUniformMap& oldMap = mCollectedUniformMap[1 - updateBufferIndex];
-
- localMap.Resize(oldMap.Count());
-
- uint32_t index = 0;
- for(CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End(); iter != end; ++iter, ++index)
- {
- localMap[index] = *iter;
- }
- }
-
- mUniformMapChanged[updateBufferIndex] = true;
- mRegenerateUniformMap--;
+ mUpdateDecay = static_cast<Renderer::Decay>(static_cast<int>(mUpdateDecay) - 1);
}
- bool rendererUpdated = mUniformMapChanged[updateBufferIndex] || mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY;
-
if(mResendFlag != 0)
{
if(mResendFlag & RESEND_GEOMETRY)
{
DALI_ASSERT_DEBUG(textureSet != NULL && "Texture set pointer is NULL");
- mTextureSet = textureSet;
- mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
+ mTextureSet = textureSet;
}
const Vector<Render::Texture*>* Renderer::GetTextures() const
if(mShader)
{
- mShader->RemoveConnectionObserver(*this);
+ mShader->RemoveUniformMapObserver(*this);
}
mShader = shader;
- mShader->AddConnectionObserver(*this);
- mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
+ mShader->AddUniformMapObserver(*this);
+ mRegenerateUniformMap = true;
mResendFlag |= RESEND_GEOMETRY | RESEND_SHADER;
}
//Called when SceneGraph::Renderer is added to update manager ( that happens when an "event-thread renderer" is created )
void Renderer::ConnectToSceneGraph(SceneController& sceneController, BufferIndex bufferIndex)
{
- mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
+ mRegenerateUniformMap = true;
mSceneController = &sceneController;
mRenderer = Render::Renderer::New(this, mGeometry, mBlendBitmask, GetBlendColor(), static_cast<FaceCullingMode::Type>(mFaceCullingMode), mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters);
return *mRenderer;
}
-const CollectedUniformMap& Renderer::GetUniformMap(BufferIndex bufferIndex) const
-{
- return mCollectedUniformMap[bufferIndex];
-}
-
Renderer::OpacityType Renderer::GetOpacityType(BufferIndex updateBufferIndex, const Node& node) const
{
Renderer::OpacityType opacityType = Renderer::OPAQUE;
return opacityType;
}
-void Renderer::ConnectionsChanged(PropertyOwner& object)
+bool Renderer::UpdateUniformMap()
{
- // One of our child objects has changed it's connections. Ensure the uniform
- // map gets regenerated during PrepareRender
- mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
-}
+ bool updated = false;
-void Renderer::ConnectedUniformMapChanged()
-{
- mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
-}
+ if(mRegenerateUniformMap)
+ {
+ CollectedUniformMap& localMap = mCollectedUniformMap;
+ localMap.Clear();
-void Renderer::UniformMappingsChanged(const UniformMap& mappings)
-{
- // The mappings are either from PropertyOwner base class, or the Actor
- mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
-}
+ const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
-void Renderer::ObservedObjectDestroyed(PropertyOwner& owner)
-{
- if(reinterpret_cast<PropertyOwner*>(mShader) == &owner)
- {
- mShader = nullptr;
+ auto size = rendererUniformMap.Count();
+ if(mShader)
+ {
+ size += mShader->GetUniformMap().Count();
+ }
+
+ localMap.Reserve(size);
+ localMap.AddMappings(rendererUniformMap);
+ if(mShader)
+ {
+ localMap.AddMappings(mShader->GetUniformMap());
+ }
+ localMap.UpdateChangeCounter();
+ mRegenerateUniformMap = false;
+ updated = true;
}
+ return updated;
}
void Renderer::SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size)
mResendFlag |= RESEND_DRAW_COMMANDS;
}
+void Renderer::UniformMappingsChanged(const UniformMap& mappings)
+{
+ // The mappings are either from PropertyOwner base class, or the Shader
+ mRegenerateUniformMap = true; // Should remain true until this renderer is added to a RenderList.
+}
+
+const CollectedUniformMap& Renderer::GetCollectedUniformMap() const
+{
+ return mCollectedUniformMap;
+}
+
} // namespace SceneGraph
} // namespace Internal
} // namespace Dali
#include <dali/internal/render/renderers/render-renderer.h>
#include <dali/internal/update/common/animatable-property.h>
#include <dali/internal/update/common/property-owner.h>
-#include <dali/internal/update/common/scene-graph-connection-change-propagator.h>
#include <dali/internal/update/common/uniform-map.h>
#include <dali/public-api/rendering/geometry.h>
#include <dali/public-api/rendering/renderer.h> // Dali::Renderer
class Renderer : public PropertyOwner,
public UniformMapDataProvider,
public RenderDataProvider,
- public UniformMap::Observer,
- public ConnectionChangePropagator::Observer
+ public UniformMap::Observer
{
public:
enum OpacityType
return mRenderCallback;
}
-public: // Implementation of ConnectionChangePropagator
/**
- * @copydoc ConnectionChangePropagator::AddObserver
+ * Merge shader uniform map into renderer uniform map if any of the
+ * maps have changed. Only update uniform map if added to render
+ * instructions.
+ *
+ * @return true if map has been updated, false otherwise
*/
- void AddConnectionObserver(ConnectionChangePropagator::Observer& observer){};
+ bool UpdateUniformMap();
/**
- * @copydoc ConnectionChangePropagator::RemoveObserver
+ * Set the given external draw commands on this renderer.
*/
- void RemoveConnectionObserver(ConnectionChangePropagator::Observer& observer){};
+ void SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size);
public: // UniformMap::Observer
/**
*/
void UniformMappingsChanged(const UniformMap& mappings) override;
-public: // ConnectionChangePropagator::Observer
- /**
- * @copydoc ConnectionChangePropagator::ConnectionsChanged
- */
- void ConnectionsChanged(PropertyOwner& owner) override;
-
- /**
- * @copydoc ConnectionChangePropagator::ConnectedUniformMapChanged
- */
- void ConnectedUniformMapChanged() override;
-
- /**
- * @copydoc ConnectionChangePropagator::ConnectedUniformMapChanged
- */
- void ObservedObjectDestroyed(PropertyOwner& owner) override;
-
public: // PropertyOwner implementation
/**
* @copydoc Dali::Internal::SceneGraph::PropertyOwner::ResetDefaultProperties()
public: // From UniformMapDataProvider
/**
- * @copydoc UniformMapDataProvider::GetUniformMapChanged
+ * @copydoc UniformMapDataProvider::GetCollectedUniformMap
*/
- bool GetUniformMapChanged(BufferIndex bufferIndex) const override
- {
- return mUniformMapChanged[bufferIndex];
- }
-
- /**
- * @copydoc UniformMapDataProvider::GetUniformMap
- */
- const CollectedUniformMap& GetUniformMap(BufferIndex bufferIndex) const override;
-
- void SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size);
+ const CollectedUniformMap& GetCollectedUniformMap() const override;
public: // For VisualProperties
/**
Renderer();
private:
- CollectedUniformMap mCollectedUniformMap[2]; ///< Uniform maps collected by the renderer
+ enum Decay
+ {
+ DONE = 0,
+ LAST = 1,
+ INITIAL = 2
+ };
+
+private:
+ CollectedUniformMap mCollectedUniformMap; ///< Uniform maps collected by the renderer
SceneController* mSceneController; ///< Used for initializing renderers
Render::Renderer* mRenderer; ///< Raw pointer to the renderer (that's owned by RenderManager)
Dali::Internal::Render::Renderer::StencilParameters mStencilParameters; ///< Struct containing all stencil related options
- uint32_t mIndexedDrawFirstElement; ///< first element index to be drawn using indexed draw
- uint32_t mIndexedDrawElementsCount; ///< number of elements to be drawn using indexed draw
- uint32_t mBlendBitmask; ///< The bitmask of blending options
- uint32_t mRegenerateUniformMap; ///< 2 if the map should be regenerated, 1 if it should be copied.
- uint32_t mResendFlag; ///< Indicate whether data should be resent to the renderer
-
- DepthFunction::Type mDepthFunction : 4; ///< Local copy of the depth function
- FaceCullingMode::Type mFaceCullingMode : 3; ///< Local copy of the mode of face culling
- BlendMode::Type mBlendMode : 3; ///< Local copy of the mode of blending
- DepthWriteMode::Type mDepthWriteMode : 3; ///< Local copy of the depth write mode
- DepthTestMode::Type mDepthTestMode : 3; ///< Local copy of the depth test mode
- DevelRenderer::Rendering::Type mRenderingBehavior : 2; ///< The rendering behavior
- bool mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame
- bool mPremultipledAlphaEnabled : 1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
-
+ uint32_t mIndexedDrawFirstElement; ///< first element index to be drawn using indexed draw
+ uint32_t mIndexedDrawElementsCount; ///< number of elements to be drawn using indexed draw
+ uint32_t mBlendBitmask; ///< The bitmask of blending options
+ uint32_t mResendFlag; ///< Indicate whether data should be resent to the renderer
+ uint32_t mUniformMapChangeCounter{0u}; ///< Value to check if uniform data should be updated
+
+ DepthFunction::Type mDepthFunction : 4; ///< Local copy of the depth function
+ FaceCullingMode::Type mFaceCullingMode : 3; ///< Local copy of the mode of face culling
+ BlendMode::Type mBlendMode : 3; ///< Local copy of the mode of blending
+ DepthWriteMode::Type mDepthWriteMode : 3; ///< Local copy of the depth write mode
+ DepthTestMode::Type mDepthTestMode : 3; ///< Local copy of the depth test mode
+ DevelRenderer::Rendering::Type mRenderingBehavior : 2; ///< The rendering behavior
+ Decay mUpdateDecay : 2; ///< Update decay (aging)
+
+ bool mRegenerateUniformMap : 1; ///< true if the map should be regenerated
+ bool mPremultipledAlphaEnabled : 1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
std::vector<Dali::DevelRenderer::DrawCommand> mDrawCommands;
Dali::RenderCallback* mRenderCallback{nullptr};