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 <eunkiki.hong@samsung.com>
mHasLayerScissor = true;
}
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)
{
// 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)
{
-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<uint32_t>(mVertexBuffers.Count());
{
//Bind buffers to attribute locations
const auto vertexBufferCount = static_cast<uint32_t>(mVertexBuffers.Count());
commandBuffer.BindVertexBuffers(0, buffers, offsets);
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)
uint32_t numIndices(0u);
intptr_t firstIndexOffset(0u);
if(mIndexBuffer)
{
// Un-indexed draw call
uint32_t numVertices(0u);
{
// 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<uint32_t>(mVertexBuffers[0]->GetElementCount());
{
// truncated, no value loss happening in practice
numVertices = static_cast<uint32_t>(mVertexBuffers[0]->GetElementCount());
* Set up the attributes and perform the Draw call corresponding to the geometry type.
*
* @param[in] graphicsController The graphics controller
* 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
* @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
uint32_t elementBufferOffset,
uint32_t elementBufferCount);
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<Render::VertexBuffer*> mVertexBuffers;
private:
// VertexBuffers
Vector<Render::VertexBuffer*> mVertexBuffers;
return ((dataSize / 256u) + ((dataSize % 256u) ? 1u : 0u)) * 256u;
}
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
} // namespace
namespace Render
MemoryPoolObjectAllocator<Renderer> gRenderRendererMemoryPool;
}
MemoryPoolObjectAllocator<Renderer> 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,
RendererKey Renderer::NewKey(SceneGraph::RenderDataProvider* dataProvider,
Render::Geometry* geometry,
uint32_t blendingBitmask,
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
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);
+ }
+ }
- for(auto& cmd : commands)
- {
- mGeometry->Draw(*mGraphicsController, commandBuffer, cmd->firstIndex, cmd->elementCount);
- }
+ // BindVertexAttributes failed. Reset cached geometry.
+ ReuseLatestBindedVertexAttributes(nullptr);
+ * @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
* Create a new renderer instance
* @param[in] dataProviders The data providers for the renderer
* @param[in] geometry The geometry for the renderer