From: Eunki Hong Date: Sun, 5 Mar 2023 14:42:00 +0000 (+0900) Subject: Skip duplicated vertex binding X-Git-Tag: dali_2.2.17~2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=a513234144a775134eff3a24144983a5e374d1d5 Skip duplicated vertex binding Let we skip some useless commands for vertex attributes binding. If latest rendered geometry is same as previous, we don't need to re-bind vertex attributes. For hueristic way, Most of Visuals, like image and text, are used simplest QUAD geometry. So for real world app are use only 1 geometry. We can reduce for this case's rendering time. Change-Id: I3643bdb728964365f42284dec3ff0ab77819f42b Signed-off-by: Eunki Hong --- diff --git a/dali/internal/render/common/render-algorithms.cpp b/dali/internal/render/common/render-algorithms.cpp index 152798d..13dfcc4 100644 --- a/dali/internal/render/common/render-algorithms.cpp +++ b/dali/internal/render/common/render-algorithms.cpp @@ -643,6 +643,9 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& mHasLayerScissor = true; } + // Prepare Render::Renderer Render for this secondary command buffer. + Renderer::PrepareCommandBuffer(); + // Loop through all RenderItems in the RenderList, set up any prerequisites to render them, then perform the render. for(uint32_t index = 0u; index < count; ++index) { diff --git a/dali/internal/render/renderers/render-geometry.cpp b/dali/internal/render/renderers/render-geometry.cpp index feb6244..b407b6f 100644 --- a/dali/internal/render/renderers/render-geometry.cpp +++ b/dali/internal/render/renderers/render-geometry.cpp @@ -149,11 +149,7 @@ void Geometry::Upload(Graphics::Controller& graphicsController) } } -bool Geometry::Draw( - Graphics::Controller& graphicsController, - Graphics::CommandBuffer& commandBuffer, - uint32_t elementBufferOffset, - uint32_t elementBufferCount) +bool Geometry::BindVertexAttributes(Graphics::CommandBuffer& commandBuffer) { //Bind buffers to attribute locations const auto vertexBufferCount = static_cast(mVertexBuffers.Count()); @@ -183,6 +179,15 @@ bool Geometry::Draw( commandBuffer.BindVertexBuffers(0, buffers, offsets); + return true; +} + +bool Geometry::Draw( + Graphics::Controller& graphicsController, + Graphics::CommandBuffer& commandBuffer, + uint32_t elementBufferOffset, + uint32_t elementBufferCount) +{ uint32_t numIndices(0u); intptr_t firstIndexOffset(0u); if(mIndexBuffer) @@ -220,7 +225,8 @@ bool Geometry::Draw( { // Un-indexed draw call uint32_t numVertices(0u); - if(vertexBufferCount > 0) + + if(mVertexBuffers.Count() > 0) { // truncated, no value loss happening in practice numVertices = static_cast(mVertexBuffers[0]->GetElementCount()); diff --git a/dali/internal/render/renderers/render-geometry.h b/dali/internal/render/renderers/render-geometry.h index a23c7a0..2f04c97 100644 --- a/dali/internal/render/renderers/render-geometry.h +++ b/dali/internal/render/renderers/render-geometry.h @@ -125,7 +125,7 @@ public: * Set up the attributes and perform the Draw call corresponding to the geometry type. * * @param[in] graphicsController The graphics controller - * @param[in] bufferIndex The current buffer index + * @param[in,out] commandBuffer The current command buffer queue * @param[in] elementBufferOffset The index of first element to draw if index buffer bound * @param[in] elementBufferCount Number of elements to draw if index buffer bound, uses whole buffer when 0 * @return true if the draw command was issued, false otherwise @@ -135,6 +135,14 @@ public: uint32_t elementBufferOffset, uint32_t elementBufferCount); + /** + * @brief Set up the attributes bind commaneds + * + * @param[in,out] commandBuffer The current command buffer queue + * @return true if the bind command was issued, false otherwise + */ + bool BindVertexAttributes(Graphics::CommandBuffer& commandBuffer); + private: // VertexBuffers Vector mVertexBuffers; diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 9b8c2c9..45aa582 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -146,6 +146,23 @@ 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 @@ -155,6 +172,14 @@ 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, @@ -571,16 +596,25 @@ bool Renderer::Render(Graphics::CommandBuffer& comma 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); } return drawn; diff --git a/dali/internal/render/renderers/render-renderer.h b/dali/internal/render/renderers/render-renderer.h index 9f25651..38b0493 100644 --- a/dali/internal/render/renderers/render-renderer.h +++ b/dali/internal/render/renderers/render-renderer.h @@ -115,6 +115,11 @@ public: }; /** + * @brief Global static initialize for Render::Renderer before new CommandBuffer's Render fill start. + */ + static void PrepareCommandBuffer(); + + /** * Create a new renderer instance * @param[in] dataProviders The data providers for the renderer * @param[in] geometry The geometry for the renderer