/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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 GetShaderData(const Property::Map& shaderMap, std::string& vertexShader, std::string& fragmentShader, uint32_t& renderPassTag, Dali::Shader::Hint::Value& hints)
{
- hints = Dali::Shader::Hint::NONE;
- renderPassTag = 0u;
+ hints = Dali::Shader::Hint::NONE;
+ renderPassTag = DEFAULT_RENDER_PASS_TAG;
if(Property::Value* value = shaderMap.Find("vertex"))
{
if(mShaderDataList.size() == 1u)
{
Dali::Property::Map map;
- map["vertex"] = Property::Value(mShaderDataList.front()->GetVertexShader());
- map["fragment"] = Property::Value(mShaderDataList.front()->GetFragmentShader());
+ map["vertex"] = Property::Value(mShaderDataList.front()->GetVertexShader());
+ map["fragment"] = Property::Value(mShaderDataList.front()->GetFragmentShader());
map["renderPassTag"] = Property::Value(static_cast<int32_t>(mShaderDataList.front()->GetRenderPassTag()));
- map["hints"] = HintString(mShaderDataList.front()->GetHints());
- value = map;
+ map["hints"] = HintString(mShaderDataList.front()->GetHints());
+ value = map;
}
else
{
if(shaderData)
{
Dali::Property::Map map;
- map["vertex"] = Property::Value(shaderData->GetVertexShader());
- map["fragment"] = Property::Value(shaderData->GetFragmentShader());
+ map["vertex"] = Property::Value(shaderData->GetVertexShader());
+ map["fragment"] = Property::Value(shaderData->GetFragmentShader());
map["renderPassTag"] = Property::Value(static_cast<int32_t>(shaderData->GetRenderPassTag()));
- map["hints"] = HintString(shaderData->GetHints());
+ map["hints"] = HintString(shaderData->GetHints());
array.PushBack(map);
}
}
size_t shaderHash;
Internal::ShaderDataPtr shaderData = shaderFactory.Load(vertexSource, fragmentSource, hints, renderPassTag, shaderHash);
- std::vector<Internal::ShaderDataPtr>::iterator shaderDataIterator = std::find_if(mShaderDataList.begin(), mShaderDataList.end(), [&shaderData](const Internal::ShaderDataPtr& shaderDataItem)
- { return shaderDataItem->GetRenderPassTag() == shaderData->GetRenderPassTag(); });
+ std::vector<Internal::ShaderDataPtr>::iterator shaderDataIterator = std::find_if(mShaderDataList.begin(), mShaderDataList.end(), [&shaderData](const Internal::ShaderDataPtr& shaderDataItem) { return shaderDataItem->GetRenderPassTag() == shaderData->GetRenderPassTag(); });
if(shaderDataIterator != mShaderDataList.end())
{
*shaderDataIterator = shaderData;
{
std::string vertex;
std::string fragment;
- uint32_t renderPassTag{0u};
+ uint32_t renderPassTag{DEFAULT_RENDER_PASS_TAG};
Dali::Shader::Hint::Value hints(Dali::Shader::Hint::NONE);
GetShaderData(*map, vertex, fragment, renderPassTag, hints);
{
std::string vertex;
std::string fragment;
- uint32_t renderPassTag{0u};
+ uint32_t renderPassTag{DEFAULT_RENDER_PASS_TAG};
Dali::Shader::Hint::Value hints(Dali::Shader::Hint::NONE);
GetShaderData(*map, vertex, fragment, renderPassTag, hints);
// Create Program
const SceneGraph::Shader& shader = mRenderDataProvider->GetShader();
- ShaderDataPtr shaderData = shader.GetShaderData(instruction.mRenderPassTag);
+ const ShaderDataPtr& shaderData = shader.GetShaderData(instruction.mRenderPassTag);
if(!shaderData)
{
DALI_LOG_ERROR("Failed to get shader data.\n");
// Specially, if node don't have uniformMap, we mark nodePtr as nullptr.
// So, all nodes without uniformMap will share same UniformIndexMap, contains only render data providers.
- const auto nodePtr = uniformMapNode.Count() ? &node : nullptr;
+ const auto nodePtr = uniformMapNode.Count() ? &node : nullptr;
const auto programPtr = &program;
const auto nodeChangeCounter = nodePtr ? uniformMapNode.GetChangeCounter() : 0;
// IMPLEMENTATION
-Program* Program::New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController)
+Program* Program::New(ProgramCache& cache, const Internal::ShaderDataPtr& shaderData, Graphics::Controller& gfxController)
{
size_t shaderHash = shaderData->GetHashValue();
mViewMatrix(nullptr),
mGfxProgram(nullptr),
mGfxController(controller),
- mProgramData(shaderData)
+ mProgramData(std::move(shaderData))
{
}
* @param[in] gfxController Reference to valid graphics Controller object
* @return pointer to the program
*/
- static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController);
+ static Program* New(ProgramCache& cache, const Internal::ShaderDataPtr& shaderData, Graphics::Controller& gfxController);
/**
* Set the projection matrix that has currently been sent
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
{
namespace SceneGraph
{
-
namespace
{
static constexpr uint32_t DEFAULT_RENDER_PASS_TAG = 0u;
void Shader::UpdateShaderData(ShaderDataPtr shaderData)
{
+ if(shaderData->GetRenderPassTag() == DEFAULT_RENDER_PASS_TAG)
+ {
+ mDefaultShaderData = std::move(shaderData);
+ return;
+ }
+
DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, "%d\n", shaderData->GetHashValue());
- std::vector<Internal::ShaderDataPtr>::iterator shaderDataIterator = std::find_if(mShaderDataList.begin(), mShaderDataList.end(), [&shaderData](const Internal::ShaderDataPtr& shaderDataItem)
- { return shaderDataItem->GetRenderPassTag() == shaderData->GetRenderPassTag(); });
+ std::vector<Internal::ShaderDataPtr>::iterator shaderDataIterator = std::find_if(mShaderDataList.begin(), mShaderDataList.end(), [&shaderData](const Internal::ShaderDataPtr& shaderDataItem) { return shaderDataItem->GetRenderPassTag() == shaderData->GetRenderPassTag(); });
if(shaderDataIterator != mShaderDataList.end())
{
- *shaderDataIterator = shaderData;
+ *shaderDataIterator = std::move(shaderData);
}
else
{
- mShaderDataList.push_back(shaderData);
+ mShaderDataList.push_back(std::move(shaderData));
}
}
ShaderDataPtr Shader::GetShaderData(uint32_t renderPassTag) const
{
- if(mShaderDataList.empty())
- {
- return nullptr;
- }
-
- Internal::ShaderDataPtr returnShaderData = nullptr;
- for(auto && shaderData : mShaderDataList)
+ if(renderPassTag != DEFAULT_RENDER_PASS_TAG)
{
- if(shaderData->GetRenderPassTag() == renderPassTag)
- {
- return shaderData;
- }
- if(shaderData->GetRenderPassTag() == DEFAULT_RENDER_PASS_TAG)
+ for(auto&& shaderData : mShaderDataList)
{
- returnShaderData = shaderData;
+ if(shaderData->GetRenderPassTag() == renderPassTag)
+ {
+ return shaderData;
+ }
}
}
- if(returnShaderData)
- {
- return returnShaderData;
- }
-
- return mShaderDataList.front();
+ return mDefaultShaderData;
}
} // namespace SceneGraph
[[nodiscard]] ShaderDataPtr GetShaderData(uint32_t renderPassTag) const;
private: // Data
- std::vector<ShaderDataPtr> mShaderDataList;
+ ShaderDataPtr mDefaultShaderData{nullptr};
+ std::vector<ShaderDataPtr> mShaderDataList{};
};
inline void UpdateShaderDataMessage(EventThreadServices& eventThreadServices, const Shader& shader, ShaderDataPtr shaderData)
Matrix nodeModelViewMatrix(false);
bool nodeModelViewMatrixSet(false);
+ const bool rendererExist(renderable.mRenderer);
+
// Don't cull items which have render callback
- bool hasRenderCallback = (renderable.mRenderer && renderable.mRenderer->GetRenderCallback());
+ bool hasRenderCallback = (rendererExist && renderable.mRenderer->GetRenderCallback());
+
+ auto requiredInsideCheck = [&]() {
+ if(cull &&
+ !hasRenderCallback &&
+ node->GetClippingMode() == ClippingMode::DISABLED &&
+ rendererExist)
+ {
+ const auto& shaderData = renderable.mRenderer->GetShader().GetShaderData(renderPass);
+ return (shaderData && !shaderData->HintEnabled(Dali::Shader::Hint::MODIFIES_GEOMETRY));
+ }
+ return false;
+ };
- if(cull && renderable.mRenderer && !hasRenderCallback && renderable.mRenderer->GetShader().GetShaderData(renderPass) && !renderable.mRenderer->GetShader().GetShaderData(renderPass)->HintEnabled(Dali::Shader::Hint::MODIFIES_GEOMETRY) && node->GetClippingMode() == ClippingMode::DISABLED)
+ if(requiredInsideCheck())
{
const Vector4& boundingSphere = node->GetBoundingSphere();
inside = (boundingSphere.w > Math::MACHINE_EPSILON_1000) &&
bool isOpaque = true;
if(!hasRenderCallback)
{
- Renderer::OpacityType opacityType = renderable.mRenderer ? renderable.mRenderer->GetOpacityType(updateBufferIndex, renderPass, *node) : Renderer::OPAQUE;
+ Renderer::OpacityType opacityType = rendererExist ? renderable.mRenderer->GetOpacityType(updateBufferIndex, renderPass, *node) : Renderer::OPAQUE;
// We can skip render when node is not clipping and transparent
skipRender = (opacityType == Renderer::TRANSPARENT && node->GetClippingMode() == ClippingMode::DISABLED);
item.mIsOpaque = isOpaque;
item.mDepthIndex = isLayer3d ? 0 : node->GetDepthIndex();
- if(DALI_LIKELY(renderable.mRenderer))
+ if(DALI_LIKELY(rendererExist))
{
item.mRenderer = renderable.mRenderer->GetRenderer();
item.mTextureSet = renderable.mRenderer->GetTextureSet();
* @param[in] clippingDepth The current stencil clipping depth
* @param[in] clippingDepth The current scissor clipping depth
* @param[out] clippingUsed Gets set to true if any clipping nodes have been found
- * @return true if rendering should be kept, false otherwise.
+ * @param[out] keepRendering Gets set to true if rendering should be kept.
*/
-bool AddRenderablesForTask(BufferIndex updateBufferIndex,
+void AddRenderablesForTask(BufferIndex updateBufferIndex,
Node& node,
Layer& currentLayer,
RenderTask& renderTask,
uint32_t& currentClippingId,
uint32_t clippingDepth,
uint32_t scissorDepth,
- bool& clippingUsed)
+ bool& clippingUsed,
+ bool& keepRendering)
{
- bool keepRendering = false;
-
// Short-circuit for invisible nodes
if(!node.IsVisible(updateBufferIndex))
{
node.GetPartialRenderingData().mVisible = false;
- return keepRendering;
+ return;
}
// If the node was not previously visible
// Check whether node is exclusive to a different render-task
if(node.GetExclusiveRenderTaskCount() && !node.IsExclusiveRenderTask(&renderTask))
{
- return keepRendering;
+ return;
}
// Assume all children go to this layer (if this node is a layer).
for(NodeIter iter = children.Begin(); iter != endIter; ++iter)
{
Node& child = **iter;
- keepRendering |= AddRenderablesForTask(updateBufferIndex, child, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth, scissorDepth, clippingUsed);
+ AddRenderablesForTask(updateBufferIndex, child, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth, scissorDepth, clippingUsed, keepRendering);
}
-
- return keepRendering;
}
/**
* @param[in] sortedLayers The layers containing lists of opaque / transparent renderables.
* @param[out] instructions The instructions for rendering the next frame.
* @param[in] renderInstructionProcessor An instance of the RenderInstructionProcessor used to sort and handle the renderers for each layer.
+ * @param[out] keepRendering Gets set to true if rendering should be kept.
* @param[in] renderToFboEnabled Whether rendering into the Frame Buffer Object is enabled (used to measure FPS above 60)
* @param[in] isRenderingToFbo Whether this frame is being rendered into the Frame Buffer Object (used to measure FPS above 60)
* @param[in] processOffscreen Whether the offscreen render tasks are the ones processed. Otherwise it processes the onscreen tasks.
- * @return true if rendering should be kept, false otherwise.
*/
-bool ProcessTasks(BufferIndex updateBufferIndex,
+void ProcessTasks(BufferIndex updateBufferIndex,
RenderTaskList::RenderTaskContainer& taskContainer,
Layer& rootNode,
SortedLayerPointers& sortedLayers,
RenderInstructionContainer& instructions,
RenderInstructionProcessor& renderInstructionProcessor,
+ bool& keepRendering,
bool renderToFboEnabled,
bool isRenderingToFbo,
bool processOffscreen)
bool hasClippingNodes = false;
bool isFirstRenderTask = true;
- bool keepRendering = false;
// Retrieve size of Scene and default camera position to update viewport of each RenderTask if the RenderTask uses ViewportGuideNode.
RenderTaskList::RenderTaskContainer::Iterator iter = taskContainer.Begin();
sortedLayer->ClearRenderables();
}
- keepRendering |= AddRenderablesForTask(updateBufferIndex,
- *sourceNode,
- *layer,
- renderTask,
- sourceNode->GetDrawMode(),
- clippingId,
- 0u,
- 0u,
- hasClippingNodes);
+ AddRenderablesForTask(updateBufferIndex,
+ *sourceNode,
+ *layer,
+ renderTask,
+ sourceNode->GetDrawMode(),
+ clippingId,
+ 0u,
+ 0u,
+ hasClippingNodes,
+ keepRendering);
renderInstructionProcessor.Prepare(updateBufferIndex,
sortedLayers,
}
}
}
-
- return keepRendering;
}
} // Anonymous namespace.
// First process off screen render tasks - we may need the results of these for the on screen renders
- keepRendering = ProcessTasks(updateBufferIndex,
- taskContainer,
- rootNode,
- sortedLayers,
- instructions,
- mRenderInstructionProcessor,
- renderToFboEnabled,
- isRenderingToFbo,
- true);
+ ProcessTasks(updateBufferIndex,
+ taskContainer,
+ rootNode,
+ sortedLayers,
+ instructions,
+ mRenderInstructionProcessor,
+ keepRendering,
+ renderToFboEnabled,
+ isRenderingToFbo,
+ true);
DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "RenderTaskProcessor::Process() Onscreen\n");
// Now that the off screen renders are done we can process on screen render tasks.
// Reset the clipping Id for the OnScreen render tasks.
- keepRendering |= ProcessTasks(updateBufferIndex,
- taskContainer,
- rootNode,
- sortedLayers,
- instructions,
- mRenderInstructionProcessor,
- renderToFboEnabled,
- isRenderingToFbo,
- false);
+ ProcessTasks(updateBufferIndex,
+ taskContainer,
+ rootNode,
+ sortedLayers,
+ instructions,
+ mRenderInstructionProcessor,
+ keepRendering,
+ renderToFboEnabled,
+ isRenderingToFbo,
+ false);
return keepRendering;
}
break;
}
- if(mShader->GetShaderData(renderPass))
+ if(mTextureSet && mTextureSet->HasAlpha())
{
- bool shaderRequiresBlending(mShader->GetShaderData(renderPass)->HintEnabled(Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT));
- if(shaderRequiresBlending || (mTextureSet && mTextureSet->HasAlpha()))
+ opacityType = Renderer::TRANSLUCENT;
+ }
+ else
+ {
+ const auto& shaderData = mShader->GetShaderData(renderPass);
+ if(shaderData && shaderData->HintEnabled(Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT))
{
opacityType = Renderer::TRANSLUCENT;
}