/*
- * 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