X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Frender%2Frenderers%2Frender-renderer.cpp;h=45aa582d4e2da75fbcc8a71ecd0faea97c0e7872;hb=a513234144a775134eff3a24144983a5e374d1d5;hp=dd6c2078cc7a86b6dbbedfedc095e8c323db5f7b;hpb=6f13915a87f9539b40b0fcff191ba2968f87f0a9;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index dd6c207..45aa582 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 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. @@ -22,6 +22,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -143,22 +146,57 @@ inline uint32_t GetUniformBufferDataAlignment(uint32_t dataSize) return ((dataSize / 256u) + ((dataSize % 256u) ? 1u : 0u)) * 256u; } +/** + * @brief Store latest binded RenderGeometry, and help that we can skip duplicated vertex attributes bind. + * + * @param[in] geometry Current geometry to be used, or nullptr if render finished + * @return True if we can reuse latest binded vertex attributes. False otherwise. + */ +inline bool ReuseLatestBindedVertexAttributes(const Render::Geometry* geometry) +{ + static const Render::Geometry* gLatestVertexBindedGeometry = nullptr; + if(gLatestVertexBindedGeometry == geometry) + { + return true; + } + gLatestVertexBindedGeometry = geometry; + return false; +} + } // namespace namespace Render { -Renderer* Renderer::New(SceneGraph::RenderDataProvider* dataProvider, - Render::Geometry* geometry, - uint32_t blendingBitmask, - const Vector4& blendColor, - FaceCullingMode::Type faceCullingMode, - bool preMultipliedAlphaEnabled, - DepthWriteMode::Type depthWriteMode, - DepthTestMode::Type depthTestMode, - DepthFunction::Type depthFunction, - StencilParameters& stencilParameters) +namespace +{ +MemoryPoolObjectAllocator gRenderRendererMemoryPool; +} + +void Renderer::PrepareCommandBuffer() +{ + // Reset latest geometry informations, So we can bind the first of geometry. + ReuseLatestBindedVertexAttributes(nullptr); + + // todo : Fill here as many caches as we can store for reduce the number of command buffers +} + +RendererKey Renderer::NewKey(SceneGraph::RenderDataProvider* dataProvider, + Render::Geometry* geometry, + uint32_t blendingBitmask, + const Vector4& blendColor, + FaceCullingMode::Type faceCullingMode, + bool preMultipliedAlphaEnabled, + DepthWriteMode::Type depthWriteMode, + DepthTestMode::Type depthTestMode, + DepthFunction::Type depthFunction, + StencilParameters& stencilParameters) { - return new Renderer(dataProvider, geometry, blendingBitmask, blendColor, faceCullingMode, preMultipliedAlphaEnabled, depthWriteMode, depthTestMode, depthFunction, stencilParameters); + void* ptr = gRenderRendererMemoryPool.AllocateRawThreadSafe(); + auto key = gRenderRendererMemoryPool.GetKeyFromPtr(static_cast(ptr)); + + // Use placement new to construct renderer. + new(ptr) Renderer(dataProvider, geometry, blendingBitmask, blendColor, faceCullingMode, preMultipliedAlphaEnabled, depthWriteMode, depthTestMode, depthFunction, stencilParameters); + return RendererKey(key); } Renderer::Renderer(SceneGraph::RenderDataProvider* dataProvider, @@ -184,8 +222,7 @@ Renderer::Renderer(SceneGraph::RenderDataProvider* dataProvider, mDepthWriteMode(depthWriteMode), mDepthTestMode(depthTestMode), mPremultipliedAlphaEnabled(preMultipliedAlphaEnabled), - mShaderChanged(false), - mUpdated(true) + mShaderChanged(false) { if(blendingBitmask != 0u) { @@ -206,11 +243,21 @@ void Renderer::Initialize(Graphics::Controller& graphicsController, ProgramCache Renderer::~Renderer() = default; +void Renderer::operator delete(void* ptr) +{ + gRenderRendererMemoryPool.FreeThreadSafe(static_cast(ptr)); +} + +Renderer* Renderer::Get(RendererKey::KeyType rendererKey) +{ + return gRenderRendererMemoryPool.GetPtrFromKey(rendererKey); +} + void Renderer::SetGeometry(Render::Geometry* geometry) { mGeometry = geometry; - mUpdated = true; } + void Renderer::SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size) { mDrawCommands.clear(); @@ -221,8 +268,8 @@ void Renderer::BindTextures(Graphics::CommandBuffer& commandBuffer, Vector* textures(mRenderDataProvider->GetTextures()); - const Dali::Vector* samplers(mRenderDataProvider->GetSamplers()); + auto textures(mRenderDataProvider->GetTextures()); + auto samplers(mRenderDataProvider->GetSamplers()); std::vector textureBindings; @@ -262,49 +309,41 @@ void Renderer::BindTextures(Graphics::CommandBuffer& commandBuffer, Vector(new RenderCallbackInput); + } + Graphics::DrawNativeInfo info{}; info.api = Graphics::DrawNativeAPI::GLES; info.callback = &static_cast(*mRenderCallback); - info.userData = &mRenderCallbackInput; - info.reserved = nullptr; + info.userData = mRenderCallbackInput.get(); + + // Set storage for the context to be used + info.glesNativeInfo.eglSharedContextStoragePointer = &mRenderCallbackInput->eglContext; + info.reserved = nullptr; + + auto& textureResources = mRenderCallback->GetTextureResources(); + + if(!textureResources.empty()) + { + mRenderCallbackTextureBindings.clear(); + mRenderCallbackInput->textureBindings.resize(textureResources.size()); + auto i = 0u; + for(auto& texture : textureResources) + { + auto& textureImpl = GetImplementation(texture); + auto graphicsTexture = textureImpl.GetRenderTextureKey()->GetGraphicsObject(); + + auto properties = mGraphicsController->GetTextureProperties(*graphicsTexture); + + mRenderCallbackTextureBindings.emplace_back(graphicsTexture); + mRenderCallbackInput->textureBindings[i++] = properties.nativeHandle; + } + info.textureCount = mRenderCallbackTextureBindings.size(); + info.textureList = mRenderCallbackTextureBindings.data(); + } // pass render callback input - mRenderCallbackInput.size = size; - mRenderCallbackInput.projection = projectionMatrix; - Matrix::Multiply(mRenderCallbackInput.mvp, modelViewMatrix, projectionMatrix); + mRenderCallbackInput->size = size; + mRenderCallbackInput->projection = projectionMatrix; + + MatrixUtils::MultiplyProjectionMatrix(mRenderCallbackInput->mvp, modelViewMatrix, projectionMatrix); // submit draw commandBuffer.DrawNative(&info); @@ -529,30 +589,38 @@ bool Renderer::Render(Graphics::CommandBuffer& comma BindTextures(commandBuffer, boundTextures); - int nodeIndex = BuildUniformIndexMap(bufferIndex, node, size, *program); + std::size_t nodeIndex = BuildUniformIndexMap(bufferIndex, node, size, *program); 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 - if(mDrawCommands.empty()) + // Reuse latest binded vertex attributes location, or Bind buffers to attribute locations. + if(ReuseLatestBindedVertexAttributes(mGeometry) || mGeometry->BindVertexAttributes(commandBuffer)) { - drawn = mGeometry->Draw(*mGraphicsController, commandBuffer, mIndexedDrawFirstElement, mIndexedDrawElementsCount); + if(mDrawCommands.empty()) + { + drawn = mGeometry->Draw(*mGraphicsController, commandBuffer, mIndexedDrawFirstElement, mIndexedDrawElementsCount); + } + else + { + for(auto& cmd : commands) + { + drawn |= mGeometry->Draw(*mGraphicsController, commandBuffer, cmd->firstIndex, cmd->elementCount); + } + } } else { - for(auto& cmd : commands) - { - mGeometry->Draw(*mGraphicsController, commandBuffer, cmd->firstIndex, cmd->elementCount); - } + // BindVertexAttributes failed. Reset cached geometry. + ReuseLatestBindedVertexAttributes(nullptr); } - mUpdated = false; return drawn; } -int Renderer::BuildUniformIndexMap(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program) +std::size_t 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"); @@ -566,18 +634,24 @@ int Renderer::BuildUniformIndexMap(BufferIndex bufferIndex, const SceneGraph::No // 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(&node); - auto iter = std::find_if(mNodeIndexMap.begin(), mNodeIndexMap.end(), [nodePtr](RenderItemLookup& element) { return element.node == nodePtr; }); + // 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 nodeChangeCounter = nodePtr ? uniformMapNode.GetChangeCounter() : 0; + const auto renderItemMapChangeCounter = uniformMap.GetChangeCounter(); + + auto iter = std::find_if(mNodeIndexMap.begin(), mNodeIndexMap.end(), [nodePtr](RenderItemLookup& element) { return element.node == nodePtr; }); - int renderItemMapIndex; + std::size_t renderItemMapIndex; if(iter == mNodeIndexMap.end()) { renderItemMapIndex = mUniformIndexMaps.size(); RenderItemLookup renderItemLookup; - renderItemLookup.node = &node; + renderItemLookup.node = nodePtr; renderItemLookup.index = renderItemMapIndex; - renderItemLookup.nodeChangeCounter = uniformMapNode.GetChangeCounter(); - renderItemLookup.renderItemMapChangeCounter = uniformMap.GetChangeCounter(); + renderItemLookup.nodeChangeCounter = nodeChangeCounter; + renderItemLookup.renderItemMapChangeCounter = renderItemMapChangeCounter; mNodeIndexMap.emplace_back(renderItemLookup); updateMaps = true; @@ -587,12 +661,12 @@ int Renderer::BuildUniformIndexMap(BufferIndex bufferIndex, const SceneGraph::No { renderItemMapIndex = iter->index; - updateMaps = (uniformMapNode.GetChangeCounter() != iter->nodeChangeCounter) || - (uniformMap.GetChangeCounter() != iter->renderItemMapChangeCounter) || + updateMaps = (nodeChangeCounter != iter->nodeChangeCounter) || + (renderItemMapChangeCounter != iter->renderItemMapChangeCounter) || (mUniformIndexMaps[renderItemMapIndex].size() == 0); - iter->nodeChangeCounter = uniformMapNode.GetChangeCounter(); - iter->renderItemMapChangeCounter = uniformMap.GetChangeCounter(); + iter->nodeChangeCounter = nodeChangeCounter; + iter->renderItemMapChangeCounter = renderItemMapChangeCounter; } if(updateMaps || mShaderChanged) @@ -660,7 +734,7 @@ void Renderer::WriteUniformBuffer( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Vector3& size, - int nodeIndex) + std::size_t nodeIndex) { // Create the UBO uint32_t uboOffset{0u}; @@ -699,7 +773,7 @@ void Renderer::WriteUniformBuffer( if(mvpUniformInfo && !mvpUniformInfo->name.empty()) { Matrix modelViewProjectionMatrix(false); - Matrix::Multiply(modelViewProjectionMatrix, modelViewMatrix, projectionMatrix); + MatrixUtils::MultiplyProjectionMatrix(modelViewProjectionMatrix, modelViewMatrix, projectionMatrix); WriteDefaultUniform(mvpUniformInfo, *uboView, modelViewProjectionMatrix); } @@ -764,7 +838,7 @@ void Renderer::FillUniformBuffer(Program& p std::vector*& outBindings, uint32_t& offset, BufferIndex updateBufferIndex, - int nodeIndex) + std::size_t nodeIndex) { auto& reflection = mGraphicsController->GetProgramReflection(program.GetGraphicsProgram()); auto uboCount = reflection.GetUniformBlockCount(); @@ -844,15 +918,9 @@ void Renderer::SetShaderChanged(bool value) mShaderChanged = value; } -bool Renderer::Updated(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider* node) +bool Renderer::Updated(BufferIndex bufferIndex) { - if(mUpdated) - { - mUpdated = false; - return true; - } - - if(mRenderCallback || mShaderChanged || mGeometry->AttributesChanged()) + if(mRenderCallback || mShaderChanged || mGeometry->AttributesChanged() || mRenderDataProvider->IsUpdated()) { return true; } @@ -863,48 +931,26 @@ bool Renderer::Updated(BufferIndex bufferIndex, const SceneGraph::NodeDataProvid for(auto iter = textures->Begin(), end = textures->End(); iter < end; ++iter) { auto texture = *iter; - if(texture && texture->IsNativeImage()) + if(texture && texture->Updated()) { return true; } } } - - // 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 = uniformMapNode[i].propertyPtr->Hash(bufferIndex, hash); - } - - const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMapDataProvider(); - const SceneGraph::CollectedUniformMap& collectedUniformMap = uniformMapDataProvider.GetCollectedUniformMap(); - for(uint32_t i = 0u, count = collectedUniformMap.Count(); i < count; ++i) - { - hash = collectedUniformMap.mUniformMap[i].propertyPtr->Hash(bufferIndex, hash); - } - - if(mUniformsHash != hash) - { - mUniformsHash = hash; - return true; - } - return false; } +Vector4 Renderer::GetVisualTransformedUpdateArea(BufferIndex bufferIndex, const Vector4& originalUpdateArea) const noexcept +{ + return mRenderDataProvider->GetVisualTransformedUpdateArea(bufferIndex, originalUpdateArea); +} + Graphics::Pipeline& Renderer::PrepareGraphicsPipeline( Program& program, const Dali::Internal::SceneGraph::RenderInstruction& instruction, const SceneGraph::NodeDataProvider& node, bool blend) { - if(mGeometry->AttributesChanged()) - { - mUpdated = true; - } - // Prepare query info PipelineCacheQueryInfo queryInfo{}; queryInfo.program = &program;