2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/render/renderers/render-renderer.h>
22 #include <dali/graphics-api/graphics-types.h>
23 #include <dali/internal/common/image-sampler.h>
24 #include <dali/internal/render/common/render-instruction.h>
25 #include <dali/internal/render/data-providers/node-data-provider.h>
26 #include <dali/internal/render/data-providers/uniform-map-data-provider.h>
27 #include <dali/internal/render/gl-resources/context.h>
28 #include <dali/internal/render/renderers/render-sampler.h>
29 #include <dali/internal/render/renderers/render-texture.h>
30 #include <dali/internal/render/renderers/render-vertex-buffer.h>
31 #include <dali/internal/render/shaders/program.h>
32 #include <dali/internal/render/shaders/scene-graph-shader.h>
41 * Helper to set view and projection matrices once per program
42 * @param program to set the matrices to
43 * @param modelMatrix to set
44 * @param viewMatrix to set
45 * @param projectionMatrix to set
46 * @param modelViewMatrix to set
47 * @param modelViewProjectionMatrix to set
49 inline void SetMatrices(Program& program,
50 const Matrix& modelMatrix,
51 const Matrix& viewMatrix,
52 const Matrix& projectionMatrix,
53 const Matrix& modelViewMatrix)
55 GLint loc = program.GetUniformLocation(Program::UNIFORM_MODEL_MATRIX);
56 if(Program::UNIFORM_UNKNOWN != loc)
58 program.SetUniformMatrix4fv(loc, 1, modelMatrix.AsFloat());
60 loc = program.GetUniformLocation(Program::UNIFORM_VIEW_MATRIX);
61 if(Program::UNIFORM_UNKNOWN != loc)
63 if(program.GetViewMatrix() != &viewMatrix)
65 program.SetViewMatrix(&viewMatrix);
66 program.SetUniformMatrix4fv(loc, 1, viewMatrix.AsFloat());
69 // set projection matrix if program has not yet received it this frame or if it is dirty
70 loc = program.GetUniformLocation(Program::UNIFORM_PROJECTION_MATRIX);
71 if(Program::UNIFORM_UNKNOWN != loc)
73 if(program.GetProjectionMatrix() != &projectionMatrix)
75 program.SetProjectionMatrix(&projectionMatrix);
76 program.SetUniformMatrix4fv(loc, 1, projectionMatrix.AsFloat());
79 loc = program.GetUniformLocation(Program::UNIFORM_MODELVIEW_MATRIX);
80 if(Program::UNIFORM_UNKNOWN != loc)
82 program.SetUniformMatrix4fv(loc, 1, modelViewMatrix.AsFloat());
85 loc = program.GetUniformLocation(Program::UNIFORM_MVP_MATRIX);
86 if(Program::UNIFORM_UNKNOWN != loc)
88 Matrix modelViewProjectionMatrix(false);
89 Matrix::Multiply(modelViewProjectionMatrix, modelViewMatrix, projectionMatrix);
90 program.SetUniformMatrix4fv(loc, 1, modelViewProjectionMatrix.AsFloat());
93 loc = program.GetUniformLocation(Program::UNIFORM_NORMAL_MATRIX);
94 if(Program::UNIFORM_UNKNOWN != loc)
97 normalMatrix = modelViewMatrix;
98 normalMatrix.Invert();
99 normalMatrix.Transpose();
100 program.SetUniformMatrix3fv(loc, 1, normalMatrix.AsFloat());
104 // Helper to get the vertex input format
105 Dali::Graphics::VertexInputFormat GetPropertyVertexFormat(Property::Type propertyType)
107 Dali::Graphics::VertexInputFormat type{};
112 case Property::STRING:
113 case Property::ARRAY:
115 case Property::EXTENTS: // i4?
116 case Property::RECTANGLE: // i4/f4?
117 case Property::ROTATION:
119 type = Dali::Graphics::VertexInputFormat::UNDEFINED;
122 case Property::BOOLEAN:
124 type = Dali::Graphics::VertexInputFormat::UNDEFINED; // type = GL_BYTE; @todo new type for this?
127 case Property::INTEGER:
129 type = Dali::Graphics::VertexInputFormat::INTEGER; // (short)
132 case Property::FLOAT:
134 type = Dali::Graphics::VertexInputFormat::FLOAT;
137 case Property::VECTOR2:
139 type = Dali::Graphics::VertexInputFormat::FVECTOR2;
142 case Property::VECTOR3:
144 type = Dali::Graphics::VertexInputFormat::FVECTOR3;
147 case Property::VECTOR4:
149 type = Dali::Graphics::VertexInputFormat::FVECTOR4;
152 case Property::MATRIX3:
154 type = Dali::Graphics::VertexInputFormat::FLOAT;
157 case Property::MATRIX:
159 type = Dali::Graphics::VertexInputFormat::FLOAT;
167 constexpr Graphics::CullMode ConvertCullFace(Dali::FaceCullingMode::Type mode)
171 case Dali::FaceCullingMode::NONE:
173 return Graphics::CullMode::NONE;
175 case Dali::FaceCullingMode::FRONT:
177 return Graphics::CullMode::FRONT;
179 case Dali::FaceCullingMode::BACK:
181 return Graphics::CullMode::BACK;
183 case Dali::FaceCullingMode::FRONT_AND_BACK:
185 return Graphics::CullMode::FRONT_AND_BACK;
188 return Graphics::CullMode::NONE;
191 constexpr Graphics::BlendFactor ConvertBlendFactor(BlendFactor::Type blendFactor)
195 case BlendFactor::ZERO:
196 return Graphics::BlendFactor::ZERO;
197 case BlendFactor::ONE:
198 return Graphics::BlendFactor::ONE;
199 case BlendFactor::SRC_COLOR:
200 return Graphics::BlendFactor::SRC_COLOR;
201 case BlendFactor::ONE_MINUS_SRC_COLOR:
202 return Graphics::BlendFactor::ONE_MINUS_SRC_COLOR;
203 case BlendFactor::SRC_ALPHA:
204 return Graphics::BlendFactor::SRC_ALPHA;
205 case BlendFactor::ONE_MINUS_SRC_ALPHA:
206 return Graphics::BlendFactor::ONE_MINUS_SRC_ALPHA;
207 case BlendFactor::DST_ALPHA:
208 return Graphics::BlendFactor::DST_ALPHA;
209 case BlendFactor::ONE_MINUS_DST_ALPHA:
210 return Graphics::BlendFactor::ONE_MINUS_DST_ALPHA;
211 case BlendFactor::DST_COLOR:
212 return Graphics::BlendFactor::DST_COLOR;
213 case BlendFactor::ONE_MINUS_DST_COLOR:
214 return Graphics::BlendFactor::ONE_MINUS_DST_COLOR;
215 case BlendFactor::SRC_ALPHA_SATURATE:
216 return Graphics::BlendFactor::SRC_ALPHA_SATURATE;
217 case BlendFactor::CONSTANT_COLOR:
218 return Graphics::BlendFactor::CONSTANT_COLOR;
219 case BlendFactor::ONE_MINUS_CONSTANT_COLOR:
220 return Graphics::BlendFactor::ONE_MINUS_CONSTANT_COLOR;
221 case BlendFactor::CONSTANT_ALPHA:
222 return Graphics::BlendFactor::CONSTANT_ALPHA;
223 case BlendFactor::ONE_MINUS_CONSTANT_ALPHA:
224 return Graphics::BlendFactor::ONE_MINUS_CONSTANT_ALPHA;
226 return Graphics::BlendFactor{};
229 constexpr Graphics::BlendOp ConvertBlendEquation(DevelBlendEquation::Type blendEquation)
231 switch(blendEquation)
233 case DevelBlendEquation::ADD:
234 return Graphics::BlendOp::ADD;
235 case DevelBlendEquation::SUBTRACT:
236 return Graphics::BlendOp::SUBTRACT;
237 case DevelBlendEquation::REVERSE_SUBTRACT:
238 return Graphics::BlendOp::REVERSE_SUBTRACT;
239 case DevelBlendEquation::COLOR:
240 case DevelBlendEquation::COLOR_BURN:
241 case DevelBlendEquation::COLOR_DODGE:
242 case DevelBlendEquation::DARKEN:
243 case DevelBlendEquation::DIFFERENCE:
244 case DevelBlendEquation::EXCLUSION:
245 case DevelBlendEquation::HARD_LIGHT:
246 case DevelBlendEquation::HUE:
247 case DevelBlendEquation::LIGHTEN:
248 case DevelBlendEquation::LUMINOSITY:
249 case DevelBlendEquation::MAX:
250 case DevelBlendEquation::MIN:
251 case DevelBlendEquation::MULTIPLY:
252 case DevelBlendEquation::OVERLAY:
253 case DevelBlendEquation::SATURATION:
254 case DevelBlendEquation::SCREEN:
255 case DevelBlendEquation::SOFT_LIGHT:
256 return Graphics::BlendOp{};
258 return Graphics::BlendOp{};
265 Renderer* Renderer::New(SceneGraph::RenderDataProvider* dataProvider,
266 Render::Geometry* geometry,
267 uint32_t blendingBitmask,
268 const Vector4& blendColor,
269 FaceCullingMode::Type faceCullingMode,
270 bool preMultipliedAlphaEnabled,
271 DepthWriteMode::Type depthWriteMode,
272 DepthTestMode::Type depthTestMode,
273 DepthFunction::Type depthFunction,
274 StencilParameters& stencilParameters)
276 return new Renderer(dataProvider, geometry, blendingBitmask, blendColor, faceCullingMode, preMultipliedAlphaEnabled, depthWriteMode, depthTestMode, depthFunction, stencilParameters);
279 Renderer::Renderer(SceneGraph::RenderDataProvider* dataProvider,
280 Render::Geometry* geometry,
281 uint32_t blendingBitmask,
282 const Vector4& blendColor,
283 FaceCullingMode::Type faceCullingMode,
284 bool preMultipliedAlphaEnabled,
285 DepthWriteMode::Type depthWriteMode,
286 DepthTestMode::Type depthTestMode,
287 DepthFunction::Type depthFunction,
288 StencilParameters& stencilParameters)
289 : mRenderDataProvider(dataProvider),
292 mProgramCache(nullptr),
294 mAttributeLocations(),
296 mStencilParameters(stencilParameters),
298 mIndexedDrawFirstElement(0),
299 mIndexedDrawElementsCount(0),
300 mDepthFunction(depthFunction),
301 mFaceCullingMode(faceCullingMode),
302 mDepthWriteMode(depthWriteMode),
303 mDepthTestMode(depthTestMode),
304 mUpdateAttributeLocations(true),
305 mPremultipledAlphaEnabled(preMultipliedAlphaEnabled),
306 mShaderChanged(false),
309 if(blendingBitmask != 0u)
311 mBlendingOptions.SetBitmask(blendingBitmask);
314 mBlendingOptions.SetBlendColor(blendColor);
317 void Renderer::Initialize(Context& context, Graphics::Controller& graphicsController, ProgramCache& programCache)
320 mGraphicsController = &graphicsController;
321 mProgramCache = &programCache;
324 Renderer::~Renderer() = default;
326 void Renderer::SetGeometry(Render::Geometry* geometry)
328 mGeometry = geometry;
329 mUpdateAttributeLocations = true;
331 void Renderer::SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size)
333 mDrawCommands.clear();
334 mDrawCommands.insert(mDrawCommands.end(), pDrawCommands, pDrawCommands + size);
337 void Renderer::GlContextDestroyed()
339 mGeometry->GlContextDestroyed();
342 void Renderer::GlCleanup()
346 void Renderer::SetUniforms(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program)
348 // Check if the map has changed
349 DALI_ASSERT_DEBUG(mRenderDataProvider && "No Uniform map data provider available");
351 const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap();
353 if(uniformMapDataProvider.GetUniformMapChanged(bufferIndex) ||
354 node.GetUniformMapChanged(bufferIndex) ||
355 mUniformIndexMap.Count() == 0 ||
358 // Reset shader pointer
359 mShaderChanged = false;
361 const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap(bufferIndex);
362 const SceneGraph::CollectedUniformMap& uniformMapNode = node.GetUniformMap(bufferIndex);
364 uint32_t maxMaps = static_cast<uint32_t>(uniformMap.Count() + uniformMapNode.Count()); // 4,294,967,295 maps should be enough
365 mUniformIndexMap.Clear(); // Clear contents, but keep memory if we don't change size
366 mUniformIndexMap.Resize(maxMaps);
368 uint32_t mapIndex = 0;
369 for(; mapIndex < uniformMap.Count(); ++mapIndex)
371 mUniformIndexMap[mapIndex].propertyValue = uniformMap[mapIndex].propertyPtr;
372 mUniformIndexMap[mapIndex].uniformIndex = program.RegisterUniform(uniformMap[mapIndex].uniformName);
375 for(uint32_t nodeMapIndex = 0; nodeMapIndex < uniformMapNode.Count(); ++nodeMapIndex)
377 uint32_t uniformIndex = program.RegisterUniform(uniformMapNode[nodeMapIndex].uniformName);
379 for(uint32_t i = 0; i < uniformMap.Count(); ++i)
381 if(mUniformIndexMap[i].uniformIndex == uniformIndex)
383 mUniformIndexMap[i].propertyValue = uniformMapNode[nodeMapIndex].propertyPtr;
391 mUniformIndexMap[mapIndex].propertyValue = uniformMapNode[nodeMapIndex].propertyPtr;
392 mUniformIndexMap[mapIndex].uniformIndex = uniformIndex;
397 mUniformIndexMap.Resize(mapIndex);
400 // Set uniforms in local map
401 for(UniformIndexMappings::Iterator iter = mUniformIndexMap.Begin(),
402 end = mUniformIndexMap.End();
406 SetUniformFromProperty(bufferIndex, program, *iter);
409 GLint sizeLoc = program.GetUniformLocation(Program::UNIFORM_SIZE);
412 program.SetSizeUniform3f(sizeLoc, size.x, size.y, size.z);
416 void Renderer::SetUniformFromProperty(BufferIndex bufferIndex, Program& program, UniformIndexMap& map)
418 GLint location = program.GetUniformLocation(map.uniformIndex);
419 if(Program::UNIFORM_UNKNOWN != location)
421 // switch based on property type to use correct GL uniform setter
422 switch(map.propertyValue->GetType())
424 case Property::INTEGER:
426 program.SetUniform1i(location, map.propertyValue->GetInteger(bufferIndex));
429 case Property::FLOAT:
431 program.SetUniform1f(location, map.propertyValue->GetFloat(bufferIndex));
434 case Property::VECTOR2:
436 Vector2 value(map.propertyValue->GetVector2(bufferIndex));
437 program.SetUniform2f(location, value.x, value.y);
441 case Property::VECTOR3:
443 Vector3 value(map.propertyValue->GetVector3(bufferIndex));
444 program.SetUniform3f(location, value.x, value.y, value.z);
448 case Property::VECTOR4:
450 Vector4 value(map.propertyValue->GetVector4(bufferIndex));
451 program.SetUniform4f(location, value.x, value.y, value.z, value.w);
455 case Property::ROTATION:
457 Quaternion value(map.propertyValue->GetQuaternion(bufferIndex));
458 program.SetUniform4f(location, value.mVector.x, value.mVector.y, value.mVector.z, value.mVector.w);
462 case Property::MATRIX:
464 const Matrix& value = map.propertyValue->GetMatrix(bufferIndex);
465 program.SetUniformMatrix4fv(location, 1, value.AsFloat());
469 case Property::MATRIX3:
471 const Matrix3& value = map.propertyValue->GetMatrix3(bufferIndex);
472 program.SetUniformMatrix3fv(location, 1, value.AsFloat());
478 // Other property types are ignored
485 bool Renderer::BindTextures(Program& program, Graphics::CommandBuffer& commandBuffer, Vector<Graphics::Texture*>& boundTextures)
487 uint32_t textureUnit = 0;
490 GLint uniformLocation(-1);
491 std::vector<Render::Sampler*>& samplers(mRenderDataProvider->GetSamplers());
492 std::vector<Render::Texture*>& textures(mRenderDataProvider->GetTextures());
494 std::vector<Graphics::TextureBinding> textureBindings;
495 for(uint32_t i = 0; i < static_cast<uint32_t>(textures.size()) && result; ++i) // not expecting more than uint32_t of textures
499 if(program.GetSamplerUniformLocation(i, uniformLocation))
501 // if the sampler exists,
502 // if it's default, delete the graphics object
503 // otherwise re-initialize it if dirty
505 const Graphics::Sampler* graphicsSampler = (samplers[i] ? samplers[i]->GetGraphicsObject()
508 boundTextures.PushBack(textures[i]->GetGraphicsObject());
509 const Graphics::TextureBinding textureBinding{textures[i]->GetGraphicsObject(), graphicsSampler, textureUnit};
510 textureBindings.push_back(textureBinding);
512 program.SetUniform1i(uniformLocation, textureUnit); // Get through shader reflection
518 if(textureBindings.size() > 0)
520 commandBuffer.BindTextures(textureBindings);
526 void Renderer::SetFaceCullingMode(FaceCullingMode::Type mode)
528 mFaceCullingMode = mode;
532 void Renderer::SetBlendingBitMask(uint32_t bitmask)
534 mBlendingOptions.SetBitmask(bitmask);
538 void Renderer::SetBlendColor(const Vector4& color)
540 mBlendingOptions.SetBlendColor(color);
544 void Renderer::SetIndexedDrawFirstElement(uint32_t firstElement)
546 mIndexedDrawFirstElement = firstElement;
550 void Renderer::SetIndexedDrawElementsCount(uint32_t elementsCount)
552 mIndexedDrawElementsCount = elementsCount;
556 void Renderer::EnablePreMultipliedAlpha(bool enable)
558 mPremultipledAlphaEnabled = enable;
562 void Renderer::SetDepthWriteMode(DepthWriteMode::Type depthWriteMode)
564 mDepthWriteMode = depthWriteMode;
568 void Renderer::SetDepthTestMode(DepthTestMode::Type depthTestMode)
570 mDepthTestMode = depthTestMode;
574 DepthWriteMode::Type Renderer::GetDepthWriteMode() const
576 return mDepthWriteMode;
579 DepthTestMode::Type Renderer::GetDepthTestMode() const
581 return mDepthTestMode;
584 void Renderer::SetDepthFunction(DepthFunction::Type depthFunction)
586 mDepthFunction = depthFunction;
590 DepthFunction::Type Renderer::GetDepthFunction() const
592 return mDepthFunction;
595 void Renderer::SetRenderMode(RenderMode::Type renderMode)
597 mStencilParameters.renderMode = renderMode;
601 RenderMode::Type Renderer::GetRenderMode() const
603 return mStencilParameters.renderMode;
606 void Renderer::SetStencilFunction(StencilFunction::Type stencilFunction)
608 mStencilParameters.stencilFunction = stencilFunction;
612 StencilFunction::Type Renderer::GetStencilFunction() const
614 return mStencilParameters.stencilFunction;
617 void Renderer::SetStencilFunctionMask(int stencilFunctionMask)
619 mStencilParameters.stencilFunctionMask = stencilFunctionMask;
623 int Renderer::GetStencilFunctionMask() const
625 return mStencilParameters.stencilFunctionMask;
628 void Renderer::SetStencilFunctionReference(int stencilFunctionReference)
630 mStencilParameters.stencilFunctionReference = stencilFunctionReference;
634 int Renderer::GetStencilFunctionReference() const
636 return mStencilParameters.stencilFunctionReference;
639 void Renderer::SetStencilMask(int stencilMask)
641 mStencilParameters.stencilMask = stencilMask;
645 int Renderer::GetStencilMask() const
647 return mStencilParameters.stencilMask;
650 void Renderer::SetStencilOperationOnFail(StencilOperation::Type stencilOperationOnFail)
652 mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
656 StencilOperation::Type Renderer::GetStencilOperationOnFail() const
658 return mStencilParameters.stencilOperationOnFail;
661 void Renderer::SetStencilOperationOnZFail(StencilOperation::Type stencilOperationOnZFail)
663 mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
667 StencilOperation::Type Renderer::GetStencilOperationOnZFail() const
669 return mStencilParameters.stencilOperationOnZFail;
672 void Renderer::SetStencilOperationOnZPass(StencilOperation::Type stencilOperationOnZPass)
674 mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
678 StencilOperation::Type Renderer::GetStencilOperationOnZPass() const
680 return mStencilParameters.stencilOperationOnZPass;
683 void Renderer::Upload()
685 mGeometry->Upload(*mGraphicsController);
688 void Renderer::Render(Context& context,
689 BufferIndex bufferIndex,
690 const SceneGraph::NodeDataProvider& node,
691 const Matrix& modelMatrix,
692 const Matrix& modelViewMatrix,
693 const Matrix& viewMatrix,
694 const Matrix& projectionMatrix,
697 Vector<Graphics::Texture*>& boundTextures,
698 const Dali::Internal::SceneGraph::RenderInstruction& instruction,
701 // Before doing anything test if the call happens in the right queue
702 if(mDrawCommands.empty() && queueIndex > 0)
708 std::vector<DevelRenderer::DrawCommand*> commands;
709 for(auto& cmd : mDrawCommands)
711 if(cmd.queue == queueIndex)
713 commands.emplace_back(&cmd);
717 // Have commands but nothing to be drawn - abort
718 if(!mDrawCommands.empty() && commands.empty())
723 // Get the program to use
724 // The program cache owns the Program object so we don't need to worry about this raw allocation here.
725 ShaderDataPtr shaderData = mRenderDataProvider->GetShader().GetShaderData();
726 Program* program = Program::New(*mProgramCache, shaderData, (shaderData->GetHints() & Dali::Shader::Hint::MODIFIES_GEOMETRY) != 0x0);
730 DALI_LOG_ERROR("Failed to get program for shader at address %p.\n", reinterpret_cast<void*>(&mRenderDataProvider->GetShader()));
734 Graphics::UniquePtr<Graphics::CommandBuffer> commandBuffer = mGraphicsController->CreateCommandBuffer(
735 Graphics::CommandBufferCreateInfo()
736 .SetLevel(Graphics::CommandBufferLevel::SECONDARY),
740 if(!mDrawCommands.empty())
742 blend = (commands[0]->queue == DevelRenderer::RENDER_QUEUE_OPAQUE ? false : blend);
745 // Temporarily create a pipeline here - this will be used for transporting
746 // topology, vertex format, attrs, rasterization state
747 Graphics::UniquePtr<Graphics::Pipeline> pipeline = PrepareGraphicsPipeline(*program, instruction, blend);
748 commandBuffer->BindPipeline(*pipeline.get());
750 if(DALI_LIKELY(BindTextures(*program, *commandBuffer.get(), boundTextures)))
752 // Only set up and draw if we have textures and they are all valid
754 // set projection and view matrix if program has not yet received them yet this frame
755 SetMatrices(*program, modelMatrix, viewMatrix, projectionMatrix, modelViewMatrix);
758 GLint loc = program->GetUniformLocation(Program::UNIFORM_COLOR);
759 if(Program::UNIFORM_UNKNOWN != loc)
761 const Vector4& color = node.GetRenderColor(bufferIndex);
762 if(mPremultipledAlphaEnabled)
764 float alpha = color.a * mRenderDataProvider->GetOpacity(bufferIndex);
765 program->SetUniform4f(loc, color.r * alpha, color.g * alpha, color.b * alpha, alpha);
769 program->SetUniform4f(loc, color.r, color.g, color.b, color.a * mRenderDataProvider->GetOpacity(bufferIndex));
773 SetUniforms(bufferIndex, node, size, *program);
775 bool drawn = false; // Draw can fail if there are no vertex buffers or they haven't been uploaded yet
776 // @todo We should detect this case much earlier to prevent unnecessary work
778 //@todo manage mDrawCommands in the same way as above command buffer?!
779 if(mDrawCommands.empty())
781 drawn = mGeometry->Draw(*mGraphicsController, *commandBuffer.get(), mIndexedDrawFirstElement, mIndexedDrawElementsCount);
785 for(auto& cmd : commands)
787 // @todo This should generate a command buffer per cmd
788 // Tests WILL fail. (Temporarily commented out)
789 mGeometry->Draw(*mGraphicsController, *commandBuffer.get(), cmd->firstIndex, cmd->elementCount);
793 // Command buffer contains Texture bindings, vertex bindings, index buffer binding, pipeline(vertex format)
794 // @todo We should return the command buffer(s) and let the calling method submit
795 // If not drawn, then don't add command buffer to submit info, and if empty, don't
799 Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH};
800 submitInfo.cmdBuffer.push_back(commandBuffer.get());
801 mGraphicsController->SubmitCommandBuffers(submitInfo);
808 void Renderer::SetSortAttributes(BufferIndex bufferIndex,
809 SceneGraph::RenderInstructionProcessor::SortAttributes& sortAttributes) const
811 sortAttributes.shader = &(mRenderDataProvider->GetShader());
812 sortAttributes.geometry = mGeometry;
815 void Renderer::SetShaderChanged(bool value)
817 mShaderChanged = value;
820 bool Renderer::Updated(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider* node)
828 if(mShaderChanged || mUpdateAttributeLocations || mGeometry->AttributesChanged())
833 for(const auto& texture : mRenderDataProvider->GetTextures())
835 if(texture && texture->IsNativeImage())
841 uint64_t hash = 0xc70f6907UL;
842 const SceneGraph::CollectedUniformMap& uniformMapNode = node->GetUniformMap(bufferIndex);
843 for(const auto& uniformProperty : uniformMapNode)
845 hash = uniformProperty.propertyPtr->Hash(bufferIndex, hash);
848 const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap();
849 const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap(bufferIndex);
850 for(const auto& uniformProperty : uniformMap)
852 hash = uniformProperty.propertyPtr->Hash(bufferIndex, hash);
855 if(mUniformsHash != hash)
857 mUniformsHash = hash;
864 Graphics::UniquePtr<Graphics::Pipeline> Renderer::PrepareGraphicsPipeline(
866 const Dali::Internal::SceneGraph::RenderInstruction& instruction,
869 Graphics::InputAssemblyState inputAssemblyState{};
870 Graphics::VertexInputState vertexInputState{};
871 uint32_t bindingIndex{0u};
873 if(mUpdateAttributeLocations || mGeometry->AttributesChanged())
875 mAttributeLocations.Clear();
876 mUpdateAttributeLocations = true;
883 for(auto&& vertexBuffer : mGeometry->GetVertexBuffers())
885 const VertexBuffer::Format& vertexFormat = *vertexBuffer->GetFormat();
887 vertexInputState.bufferBindings.emplace_back(vertexFormat.size, // stride
888 Graphics::VertexInputRate::PER_VERTEX);
890 const uint32_t attributeCount = vertexBuffer->GetAttributeCount();
891 for(uint32_t i = 0; i < attributeCount; ++i)
893 if(mUpdateAttributeLocations)
895 auto attributeName = vertexBuffer->GetAttributeName(i);
896 uint32_t index = program.RegisterCustomAttribute(attributeName);
897 int32_t pLocation = program.GetCustomAttributeLocation(index);
900 DALI_LOG_WARNING("Attribute not found in the shader: %s\n", attributeName.GetCString());
902 mAttributeLocations.PushBack(pLocation);
905 uint32_t location = static_cast<uint32_t>(mAttributeLocations[base + i]);
907 vertexInputState.attributes.emplace_back(location,
909 vertexFormat.components[i].offset,
910 GetPropertyVertexFormat(vertexFormat.components[i].type));
912 base += attributeCount;
915 mUpdateAttributeLocations = false;
918 inputAssemblyState.SetTopology(mGeometry->GetTopology());
920 Graphics::RasterizationState rasterizationState{};
923 const Dali::Internal::SceneGraph::Camera* cam = instruction.GetCamera();
924 if(cam->GetReflectionUsed())
926 auto adjFaceCullingMode = mFaceCullingMode;
927 switch(mFaceCullingMode)
929 case FaceCullingMode::Type::FRONT:
931 adjFaceCullingMode = FaceCullingMode::Type::BACK;
934 case FaceCullingMode::Type::BACK:
936 adjFaceCullingMode = FaceCullingMode::Type::FRONT;
941 // nothing to do, leave culling as it is
944 rasterizationState.SetCullMode(ConvertCullFace(adjFaceCullingMode));
948 rasterizationState.SetCullMode(ConvertCullFace(mFaceCullingMode));
951 rasterizationState.SetFrontFace(Graphics::FrontFace::COUNTER_CLOCKWISE);
956 switch(mGeometry->GetTopology())
958 case Graphics::PrimitiveTopology::TRIANGLE_LIST:
959 case Graphics::PrimitiveTopology::TRIANGLE_STRIP:
960 case Graphics::PrimitiveTopology::TRIANGLE_FAN:
961 rasterizationState.SetPolygonMode(Graphics::PolygonMode::FILL);
963 case Graphics::PrimitiveTopology::LINE_LIST:
964 case Graphics::PrimitiveTopology::LINE_LOOP:
965 case Graphics::PrimitiveTopology::LINE_STRIP:
966 rasterizationState.SetPolygonMode(Graphics::PolygonMode::LINE);
968 case Graphics::PrimitiveTopology::POINT_LIST:
969 rasterizationState.SetPolygonMode(Graphics::PolygonMode::POINT);
973 // @todo How to signal a blend barrier is needed?
974 //if(mBlendingOptions.IsAdvancedBlendEquationApplied() && mPremultipledAlphaEnabled)
976 // context.BlendBarrier();
979 Graphics::ColorBlendState colorBlendState{};
980 colorBlendState.SetBlendEnable(false);
984 colorBlendState.SetBlendEnable(true);
986 Graphics::BlendOp rgbOp = ConvertBlendEquation(mBlendingOptions.GetBlendEquationRgb());
987 Graphics::BlendOp alphaOp = ConvertBlendEquation(mBlendingOptions.GetBlendEquationRgb());
988 if(mBlendingOptions.IsAdvancedBlendEquationApplied() && mPremultipledAlphaEnabled)
992 DALI_LOG_ERROR("Advanced Blend Equation MUST be applied by using BlendEquation.\n");
998 .SetSrcColorBlendFactor(ConvertBlendFactor(mBlendingOptions.GetBlendSrcFactorRgb()))
999 .SetSrcAlphaBlendFactor(ConvertBlendFactor(mBlendingOptions.GetBlendSrcFactorAlpha()))
1000 .SetDstColorBlendFactor(ConvertBlendFactor(mBlendingOptions.GetBlendDestFactorRgb()))
1001 .SetDstAlphaBlendFactor(ConvertBlendFactor(mBlendingOptions.GetBlendDestFactorAlpha()))
1002 .SetColorBlendOp(rgbOp)
1003 .SetAlphaBlendOp(alphaOp);
1005 // Blend color is optional and rarely used
1006 Vector4* blendColor = const_cast<Vector4*>(mBlendingOptions.GetBlendColor());
1009 colorBlendState.SetBlendConstants(blendColor->AsFloat());
1013 // Take the program into use so we can send uniforms to it
1014 // @todo Remove this call entirely!
1019 // Create a new pipeline
1020 return mGraphicsController->CreatePipeline(
1021 Graphics::PipelineCreateInfo()
1022 .SetInputAssemblyState(&inputAssemblyState) // Passed as pointers - shallow copy will break. TOO C LIKE
1023 .SetVertexInputState(&vertexInputState)
1024 .SetRasterizationState(&rasterizationState)
1025 .SetColorBlendState(&colorBlendState),
1029 } // namespace Render
1031 } // namespace Internal