Fixing vertex buffer upload issues. 12/253512/1 graphics-backend-pre-release-1
authorDavid Steele <david.steele@samsung.com>
Fri, 12 Feb 2021 14:50:26 +0000 (14:50 +0000)
committerDavid Steele <david.steele@samsung.com>
Fri, 12 Feb 2021 14:54:26 +0000 (14:54 +0000)
At present, we get into the rendering calls even if a vertex buffer
hasn't yet been uploaded. Fixed null pointer traversal, and
prevented draw call if not ready.

Ensured that if the vertex buffer upload exceeds the allocated
capacity that the buffer is reallocated first.

Change-Id: Iad6271dc510e09be9afbb1f89a1c4767bb1ae5de
Signed-off-by: David Steele <david.steele@samsung.com>
dali/internal/render/gl-resources/gpu-buffer.cpp
dali/internal/render/gl-resources/gpu-buffer.h
dali/internal/render/renderers/render-geometry.cpp
dali/internal/render/renderers/render-geometry.h
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-vertex-buffer.h

index b13d2a1..3b7791c 100644 (file)
@@ -46,11 +46,11 @@ void GpuBuffer::UpdateDataBuffer(Graphics::Controller& graphicsController, uint3
   DALI_ASSERT_DEBUG(size > 0);
   mSize = size;
 
-  if(!mGraphicsObject)
+  if(!mGraphicsObject || size > mCapacity)
   {
     Graphics::BufferCreateInfo createInfo{};
     createInfo.SetUsage(mUsage).SetSize(size);
-    mGraphicsObject = graphicsController.CreateBuffer(createInfo, nullptr);
+    mGraphicsObject = graphicsController.CreateBuffer(createInfo, std::move(mGraphicsObject));
     mCapacity       = size;
   }
 
index 7734643..d5e5281 100644 (file)
@@ -74,7 +74,7 @@ public:
     return mSize;
   }
 
-  inline Graphics::Buffer* GetGraphicsObject()
+  inline const Graphics::Buffer* GetGraphicsObject() const
   {
     return mGraphicsObject.get();
   }
index 2c28b72..5c3d6fe 100644 (file)
@@ -126,7 +126,7 @@ void Geometry::Upload(Graphics::Controller& graphicsController)
   }
 }
 
-void Geometry::Draw(
+bool Geometry::Draw(
   Graphics::Controller&    graphicsController,
   Graphics::CommandBuffer& commandBuffer,
   uint32_t                 elementBufferOffset,
@@ -140,14 +140,24 @@ void Geometry::Draw(
 
   for(uint32_t i = 0; i < vertexBufferCount; ++i)
   {
-    Graphics::Buffer* buffer = mVertexBuffers[i]->GetGpuBuffer().GetGraphicsObject();
-
-    if(buffer)
+    const GpuBuffer* gpuBuffer = mVertexBuffers[i]->GetGpuBuffer();
+    if(gpuBuffer)
     {
-      buffers.push_back(buffer);
-      offsets.push_back(0u);
+      const Graphics::Buffer* buffer = gpuBuffer->GetGraphicsObject();
+
+      if(buffer)
+      {
+        buffers.push_back(buffer);
+        offsets.push_back(0u);
+      }
     }
+    //@todo Figure out why this is being drawn without geometry having been uploaded
   }
+  if(buffers.size() == 0)
+  {
+    return false;
+  }
+
   commandBuffer.BindVertexBuffers(0, buffers, offsets);
 
   uint32_t numIndices(0u);
@@ -173,7 +183,7 @@ void Geometry::Draw(
   if(mIndexBuffer && mGeometryType != Dali::Geometry::POINTS)
   {
     //Indexed draw call
-    Graphics::Buffer* ibo = mIndexBuffer->GetGraphicsObject();
+    const Graphics::Buffer* ibo = mIndexBuffer->GetGraphicsObject();
     if(ibo)
     {
       commandBuffer.BindIndexBuffer(*ibo, 0, Graphics::Format::R16_UINT);
@@ -193,6 +203,7 @@ void Geometry::Draw(
 
     commandBuffer.Draw(numVertices, 1, 0, 0);
   }
+  return true;
 }
 
 Graphics::PrimitiveTopology Geometry::GetTopology() const
index 6a8f3e4..927cf73 100644 (file)
@@ -124,15 +124,17 @@ public:
   void Upload(Graphics::Controller& graphicsController);
 
   /**
-   * Set up the attributes and perform the Draw call corresponding to the geometry type
+   * Set up the attributes and perform the Draw call corresponding to the geometry type.
+   *
    * @param[in] context The GL context @todo remove
    * @param[in] graphicsController The graphics controller
    * @param[in] bufferIndex The current buffer index
    * @param[in] attributeLocation The location for the attributes in the shader
    * @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
    */
-  void Draw(Graphics::Controller&    graphicsController,
+  bool Draw(Graphics::Controller&    graphicsController,
             Graphics::CommandBuffer& commandBuffer,
             uint32_t                 elementBufferOffset,
             uint32_t                 elementBufferCount);
index 69f6b20..823af04 100644 (file)
@@ -746,12 +746,15 @@ void Renderer::Render(Context&                                             conte
       context.BlendBarrier();
     }
 
+    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
+
     //@todo manage mDrawCommands in the same way as above command buffer?!
     if(mDrawCommands.empty())
     {
       SetBlending(context, blend);
 
-      mGeometry->Draw(*mGraphicsController, *commandBuffer.get(), mIndexedDrawFirstElement, mIndexedDrawElementsCount);
+      drawn = mGeometry->Draw(*mGraphicsController, *commandBuffer.get(), mIndexedDrawFirstElement, mIndexedDrawElementsCount);
     }
     else
     {
@@ -770,9 +773,15 @@ void Renderer::Render(Context&                                             conte
     }
 
     // Command buffer contains Texture bindings, vertex bindings, index buffer binding, pipeline(vertex format)
-    Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH};
-    submitInfo.cmdBuffer.push_back(commandBuffer.get());
-    mGraphicsController->SubmitCommandBuffers(submitInfo);
+    // @todo We should return the command buffer(s) and let the calling method submit
+    // If not drawn, then don't add command buffer to submit info, and if empty, don't
+    // submit.
+    if(drawn)
+    {
+      Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH};
+      submitInfo.cmdBuffer.push_back(commandBuffer.get());
+      mGraphicsController->SubmitCommandBuffers(submitInfo);
+    }
 
     mUpdated = false;
   }
index c02c002..a02c493 100644 (file)
@@ -170,9 +170,9 @@ public:
     return mFormat.Get();
   }
 
-  inline GpuBuffer& GetGpuBuffer()
+  inline const GpuBuffer* GetGpuBuffer() const
   {
-    return *(const_cast<GpuBuffer*>(mGpuBuffer.Get())); // @todo change to unique_ptr to avoid const cast?
+    return mGpuBuffer.Get();
   }
 
 private: