Lock uniform buffer only 1 times per each render + minor fixup of uniforms
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / uniform-buffer-manager.cpp
index 5b6a1ec..5e04f82 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
  *
  */
 
-#include "uniform-buffer-manager.h"
+// CLASS HEADER
+#include <dali/internal/render/renderers/uniform-buffer-manager.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/render/renderers/uniform-buffer-view-pool.h>
+#include <dali/internal/render/renderers/uniform-buffer-view.h>
+#include <dali/internal/render/renderers/uniform-buffer.h>
+
 #include <dali/graphics-api/graphics-buffer-create-info.h>
 #include <dali/graphics-api/graphics-buffer.h>
 
 #include <cstring>
 #include <memory>
 
-namespace Dali
-{
-namespace Internal
-{
-namespace Render
+namespace Dali::Internal::Render
 {
-UniformBuffer::UniformBuffer(Dali::Graphics::Controller* controller,
-                             uint32_t                    sizeInBytes,
-                             uint32_t                    alignment,
-                             bool                        persistentMappedEnabled,
-                             Graphics::BufferUsageFlags  usageFlags)
-: mController(controller),
-  mSize(0u),
-  mPersistentMappedEnabled(persistentMappedEnabled),
-  mUsageFlags(usageFlags)
-{
-  if(sizeInBytes)
-  {
-    Reserve(sizeInBytes);
-  }
-}
-
-UniformBuffer::~UniformBuffer()
-{
-  if(mBuffer && mMemory)
-  {
-    mController->UnmapMemory(std::move(mMemory));
-  }
-}
-
-void UniformBuffer::Flush()
+UniformBufferManager::UniformBufferManager(Dali::Graphics::Controller* controller)
+: mController(controller)
 {
-  if(mBuffer && mMemory)
-  {
-    mMemory->Flush();
-  }
 }
 
-void UniformBuffer::Reserve(uint32_t size)
-{
-  if(mBuffer && mMemory)
-  {
-    Unmap();
-    mMemory = nullptr;
-  }
-
-  mSize = size;
-
-  Graphics::BufferCreateInfo createInfo;
-  createInfo.SetSize(mSize);
-  createInfo.SetUsage(mUsageFlags);
-  mBuffer = std::move(mController->CreateBuffer(createInfo, std::move(mBuffer)));
-
-  mMapBufferInfo.buffer = mBuffer.get();
-  mMapBufferInfo.usage  = 0 | Graphics::MemoryUsageFlagBits::WRITE;
-  mMapBufferInfo.offset = 0;
-  mMapBufferInfo.size   = size;
-
-  if(mPersistentMappedEnabled)
-  {
-    Map();
-  }
-}
+UniformBufferManager::~UniformBufferManager() = default;
 
-void UniformBuffer::Fill(char data, uint32_t offset, uint32_t size)
+Graphics::UniquePtr<UniformBuffer> UniformBufferManager::AllocateUniformBuffer(uint32_t size, uint32_t alignment)
 {
-  bool locallyMapped = (mMemory == nullptr);
-  if(locallyMapped)
-  {
-    Map();
-  }
-
-  if(mMemory)
-  {
-    void* ptr = mMemory->LockRegion(0, mSize);
-
-    auto begin = (reinterpret_cast<char*>(ptr) + offset);
-    if(size == 0)
-    {
-      size = mSize - offset - 1;
-    }
-    auto end = begin + size;
-    std::fill(begin, end, data);
-
-    mMemory->Unlock(true);
-  }
-
-  if(locallyMapped)
-  {
-    Unmap();
-  }
+  // TODO : Current code only assume CPU_ALLOCATED uniform buffer now
+  return Graphics::UniquePtr<UniformBuffer>(
+    new UniformBuffer(mController,
+                      size,
+                      alignment,
+                      Dali::Graphics::BufferUsageFlags{0u} | Dali::Graphics::BufferUsage::TRANSFER_DST | Dali::Graphics::BufferUsage::UNIFORM_BUFFER,
+                      Dali::Graphics::BufferPropertiesFlags{0u} | Dali::Graphics::BufferPropertiesFlagBit::CPU_ALLOCATED));
 }
 
-void UniformBuffer::Write(const void* data, uint32_t size, uint32_t dstOffset)
+Graphics::UniquePtr<UniformBufferView> UniformBufferManager::CreateUniformBufferView(UniformBuffer* uniformBuffer, uint32_t offset, uint32_t size)
 {
-  bool locallyMapped = (mMemory == nullptr);
-  if(locallyMapped)
-  {
-    Map();
-  }
-
-  if(mMemory)
-  {
-    void* ptr = mMemory->LockRegion(0, size);
-    if(dstOffset + size < mSize)
-    {
-      memcpy(reinterpret_cast<char*>(ptr) + dstOffset, data, size);
-    }
-    mMemory->Unlock(true);
-  }
-
-  if(locallyMapped)
-  {
-    Unmap();
-  }
+  // Allocate offset of given UBO (allocation strategy may reuse memory)
+  return Graphics::UniquePtr<UniformBufferView>(new UniformBufferView(*uniformBuffer, offset, size));
 }
 
-void UniformBuffer::Map()
+Graphics::UniquePtr<UniformBufferViewPool> UniformBufferManager::CreateUniformBufferViewPool()
 {
-  if(!mMemory)
-  {
-    mMemory = mController->MapBufferRange(mMapBufferInfo);
-  }
+  return Graphics::UniquePtr<UniformBufferViewPool>(
+    new UniformBufferViewPool(*this, 1));
 }
 
-void UniformBuffer::Unmap()
+[[nodiscard]] UniformBufferViewPool* UniformBufferManager::GetUniformBufferViewPool(uint32_t bufferIndex)
 {
-  if(mMemory)
+  if(!mUniformBufferPoolStorage[bufferIndex])
   {
-    mController->UnmapMemory(std::move(mMemory));
+    // create new uniform buffer view pool with default (initial) capacity
+    mUniformBufferPoolStorage[bufferIndex] = CreateUniformBufferViewPool();
   }
+  return mUniformBufferPoolStorage[bufferIndex].get();
 }
 
-UniformBufferManager::UniformBufferManager(Dali::Graphics::Controller* controller)
-: mController(controller)
+void UniformBufferManager::ReadyToLockUniformBuffer(uint32_t bufferIndex)
 {
+  GetUniformBufferViewPool(bufferIndex)->ReadyToLockUniformBuffer();
 }
 
-UniformBufferManager::~UniformBufferManager() = default;
-
-Graphics::UniquePtr<UniformBuffer> UniformBufferManager::AllocateUniformBuffer(uint32_t size)
+void UniformBufferManager::UnlockUniformBuffer(uint32_t bufferIndex)
 {
-  return Graphics::UniquePtr<UniformBuffer>(
-    new UniformBuffer(mController, size, 256u, true, Dali::Graphics::BufferUsageFlags{0u} | Dali::Graphics::BufferUsage::TRANSFER_DST | Dali::Graphics::BufferUsage::UNIFORM_BUFFER));
+  GetUniformBufferViewPool(bufferIndex)->UnlockUniformBuffer();
 }
 
-} // namespace Render
-
-} // namespace Internal
-
-} // namespace Dali
+} // namespace Dali::Internal::Render