mCallStack.PushCall("Resume", "");
}
+void TestGraphicsController::Shutdown()
+{
+ mCallStack.PushCall("Shutdown", "");
+}
+
+void TestGraphicsController::Destroy()
+{
+ mCallStack.PushCall("Destroy", "");
+}
+
void TestGraphicsController::UpdateTextures(const std::vector<Graphics::TextureUpdateInfo>& updateInfoList,
const std::vector<Graphics::TextureUpdateSourceInfo>& sourceList)
{
void Resume() override;
/**
+ * @brief Lifecycle shutdown event
+ */
+ void Shutdown() override;
+
+ /**
+ * @brief Lifecycle destroy event
+ */
+ void Destroy() override;
+
+ /**
* @brief Executes batch update of textures
*
* This function may perform full or partial update of many textures.
} // namespace
+EglGraphicsController::~EglGraphicsController() = default;
+
void EglGraphicsController::InitializeGLES(Integration::GlAbstraction& glAbstraction)
{
DALI_LOG_RELEASE_INFO("Initializing New Graphics Controller #1\n");
// Process programs
ProcessDiscardQueue<GLES::Program>(mDiscardProgramQueue);
+
+ // Process shaders
+ ProcessDiscardQueue<GLES::Shader>(mDiscardShaderQueue);
+
+ // Process samplers
+ ProcessDiscardQueue<GLES::Sampler>(mDiscardSamplerQueue);
+
+ // Process command buffers
+ ProcessDiscardQueue<GLES::CommandBuffer>(mDiscardCommandBufferQueue);
}
void EglGraphicsController::ProcessCreateQueues()
// INTERNAL INCLUDES
#include "gles-context.h"
#include "gles-graphics-buffer.h"
+#include "gles-graphics-command-buffer.h"
#include "gles-graphics-pipeline-cache.h"
#include "gles-graphics-pipeline.h"
#include "gles-graphics-reflection.h"
#include "gles-graphics-sampler.h"
+#include "gles-graphics-shader.h"
#include "gles-graphics-texture.h"
#include "gles-graphics-types.h"
#include "gles2-graphics-memory.h"
/**
* @brief Destructor
*/
- ~EglGraphicsController() override = default;
+ ~EglGraphicsController() override;
/**
* Initialize the GLES abstraction. This can be called from the main thread.
}
/**
+ * @copydoc Dali::Graphics::Shutdown()
+ */
+ void Shutdown() override
+ {
+ mIsShuttingDown = true;
+ }
+
+ /**
+ * @copydoc Dali::Graphics::Destroy()
+ */
+ void Destroy() override
+ {
+ // Final flush
+ Flush();
+ }
+
+ /**
* @copydoc Dali::Graphics::UpdateTextures()
*/
void UpdateTextures(const std::vector<TextureUpdateInfo>& updateInfoList,
[[nodiscard]] Integration::GlAbstraction* GetGL() const
{
+ if(mIsShuttingDown)
+ {
+ return nullptr;
+ }
return mGlAbstraction;
}
*
* @param[in] texture Pointer to the texture
*/
- void DiscardResource(GLES::Buffer* texture)
+ void DiscardResource(GLES::Buffer* buffer)
{
- mDiscardBufferQueue.push(texture);
+ mDiscardBufferQueue.push(buffer);
}
/**
}
/**
+ * @brief Pushes Shader to the discard queue
+ *
+ * Function is called from the UniquePtr custom deleter.
+ *
+ * @param[in] program Pointer to the Shader
+ */
+ void DiscardResource(GLES::Shader* shader)
+ {
+ mDiscardShaderQueue.push(shader);
+ }
+
+ /**
+ * @brief Pushes CommandBuffer to the discard queue
+ *
+ * Function is called from the UniquePtr custom deleter.
+ *
+ * @param[in] program Pointer to the CommandBuffer
+ */
+ void DiscardResource(GLES::CommandBuffer* commandBuffer)
+ {
+ mDiscardCommandBufferQueue.push(commandBuffer);
+ }
+
+ /**
+ * @brief Pushes Sampler to the discard queue
+ *
+ * Function is called from the UniquePtr custom deleter.
+ *
+ * @param[in] program Pointer to the Sampler
+ */
+ void DiscardResource(GLES::Sampler* sampler)
+ {
+ mDiscardSamplerQueue.push(sampler);
+ }
+
+ /**
* @brief Pushes Pipeline to the discard queue
*
* Function is called from the UniquePtr custom deleter.
return GLES::GLESVersion::GLES_20;
}
+ bool IsShuttingDown() const
+ {
+ return mIsShuttingDown;
+ }
+
private:
Integration::GlAbstraction* mGlAbstraction{nullptr};
Integration::GlSyncAbstraction* mGlSyncAbstraction{nullptr};
std::queue<GLES::Buffer*> mCreateBufferQueue; ///< Create queue for buffer resource
std::queue<GLES::Buffer*> mDiscardBufferQueue; ///< Discard queue for buffer resource
- std::queue<GLES::Program*> mDiscardProgramQueue; ///< Discard queue for program resource
-
- std::queue<GLES::Pipeline*> mDiscardPipelineQueue; ///< Discard queue of pipelines
+ std::queue<GLES::Program*> mDiscardProgramQueue; ///< Discard queue for program resource
+ std::queue<GLES::Pipeline*> mDiscardPipelineQueue; ///< Discard queue of pipelines
+ std::queue<GLES::Shader*> mDiscardShaderQueue; ///< Discard queue of shaders
+ std::queue<GLES::Sampler*> mDiscardSamplerQueue; ///< Discard queue of samplers
+ std::queue<GLES::CommandBuffer*> mDiscardCommandBufferQueue; ///< Discard queue of command buffers
std::queue<GLES::CommandBuffer*> mCommandQueue; ///< we may have more in the future
std::unique_ptr<GLES::Context> mContext{nullptr}; ///< Context object handling command buffers execution
std::unique_ptr<GLES::PipelineCache> mPipelineCache{nullptr}; ///< Internal pipeline cache
+
+ bool mIsShuttingDown{false}; ///< Indicates whether the controller is shutting down
};
} // namespace Graphics
#include "gles-context.h"
#include <dali/integration-api/gl-abstraction.h>
#include <dali/integration-api/gl-defines.h>
+#include "egl-graphics-controller.h"
#include "gles-graphics-buffer.h"
-#include "gles-graphics-command-buffer.h"
#include "gles-graphics-pipeline.h"
#include "gles-graphics-program.h"
else
{
auto gl = mController.GetGL();
- gl->DeleteBuffers(1, &mBufferId);
+ if(gl)
+ {
+ gl->DeleteBuffers(1, &mBufferId);
+ }
}
}
// CLASS HEADER
#include "gles-graphics-command-buffer.h"
+
+// INTERNAL INCLUDES
+#include "egl-graphics-controller.h"
+#include "gles-graphics-buffer.h"
+#include "gles-graphics-pipeline.h"
+#include "gles-graphics-texture.h"
+
+namespace Dali::Graphics::GLES
+{
+CommandBuffer::CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller)
+: CommandBufferResource(createInfo, controller)
+{
+}
+
+CommandBuffer::~CommandBuffer() = default;
+
+void CommandBuffer::BindVertexBuffers(uint32_t firstBinding,
+ std::vector<const Graphics::Buffer*> buffers,
+ std::vector<uint32_t> offsets)
+{
+ mCommands.emplace_back(CommandType::BIND_VERTEX_BUFFERS);
+ auto& bindings = mCommands.back().bindVertexBuffers.vertexBufferBindings;
+ if(bindings.size() < firstBinding + buffers.size())
+ {
+ bindings.resize(firstBinding + buffers.size());
+ auto index = firstBinding;
+ for(auto& buf : buffers)
+ {
+ bindings[index].buffer = static_cast<const GLES::Buffer*>(buf);
+ bindings[index].offset = offsets[index - firstBinding];
+ index++;
+ }
+ }
+}
+
+void CommandBuffer::BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings)
+{
+ mCommands.emplace_back(CommandType::BIND_UNIFORM_BUFFER);
+ auto& cmd = mCommands.back();
+ auto& bindCmd = cmd.bindUniformBuffers;
+ for(const auto& binding : bindings)
+ {
+ if(binding.buffer)
+ {
+ auto glesBuffer = static_cast<const GLES::Buffer*>(binding.buffer);
+ if(glesBuffer->IsCPUAllocated()) // standalone uniforms
+ {
+ bindCmd.standaloneUniformsBufferBinding.buffer = glesBuffer;
+ bindCmd.standaloneUniformsBufferBinding.offset = binding.offset;
+ bindCmd.standaloneUniformsBufferBinding.binding = binding.binding;
+ bindCmd.standaloneUniformsBufferBinding.emulated = true;
+ }
+ else // Bind regular UBO
+ {
+ // resize binding slots
+ if(binding.binding >= bindCmd.uniformBufferBindings.size())
+ {
+ bindCmd.uniformBufferBindings.resize(binding.binding + 1);
+ }
+ auto& slot = bindCmd.uniformBufferBindings[binding.binding];
+ slot.buffer = glesBuffer;
+ slot.offset = binding.offset;
+ slot.binding = binding.binding;
+ slot.emulated = false;
+ }
+ }
+ }
+}
+
+void CommandBuffer::BindPipeline(const Graphics::Pipeline& pipeline)
+{
+ mCommands.emplace_back(CommandType::BIND_PIPELINE);
+ mCommands.back().bindPipeline.pipeline = static_cast<const GLES::Pipeline*>(&pipeline);
+}
+
+void CommandBuffer::BindTextures(std::vector<TextureBinding>& textureBindings)
+{
+ mCommands.emplace_back(CommandType::BIND_TEXTURES);
+ mCommands.back().bindTextures.textureBindings = std::move(textureBindings);
+}
+
+void CommandBuffer::BindSamplers(std::vector<SamplerBinding>& samplerBindings)
+{
+ mCommands.emplace_back(CommandType::BIND_SAMPLERS);
+ mCommands.back().bindSamplers.samplerBindings = std::move(samplerBindings);
+}
+
+void CommandBuffer::BindPushConstants(void* data,
+ uint32_t size,
+ uint32_t binding)
+{
+}
+
+void CommandBuffer::BindIndexBuffer(const Graphics::Buffer& buffer,
+ uint32_t offset,
+ Format format)
+{
+ mCommands.emplace_back(CommandType::BIND_INDEX_BUFFER);
+ mCommands.back().bindIndexBuffer.buffer = static_cast<const GLES::Buffer*>(&buffer);
+ mCommands.back().bindIndexBuffer.offset = offset;
+ mCommands.back().bindIndexBuffer.format = format;
+}
+
+void CommandBuffer::BeginRenderPass(
+ Graphics::RenderPass& renderPass,
+ Graphics::RenderTarget& renderTarget,
+ Extent2D renderArea,
+ std::vector<ClearValue> clearValues)
+{
+}
+
+/**
+ * @brief Ends current render pass
+ *
+ * This command must be issued in order to finalize the render pass.
+ * It's up to the implementation whether anything has to be done but
+ * the Controller may use end RP marker in order to resolve resource
+ * dependencies (for example, to know when target texture is ready
+ * before passing it to another render pass).
+ */
+void CommandBuffer::EndRenderPass()
+{
+}
+
+void CommandBuffer::Draw(
+ uint32_t vertexCount,
+ uint32_t instanceCount,
+ uint32_t firstVertex,
+ uint32_t firstInstance)
+{
+ mCommands.emplace_back(CommandType::DRAW);
+ auto& cmd = mCommands.back().draw;
+ cmd.type = DrawCallDescriptor::Type::DRAW;
+ cmd.draw.vertexCount = vertexCount;
+ cmd.draw.instanceCount = instanceCount;
+ cmd.draw.firstInstance = firstInstance;
+ cmd.draw.firstVertex = firstVertex;
+}
+
+void CommandBuffer::DrawIndexed(
+ uint32_t indexCount,
+ uint32_t instanceCount,
+ uint32_t firstIndex,
+ int32_t vertexOffset,
+ uint32_t firstInstance)
+{
+ mCommands.emplace_back(CommandType::DRAW_INDEXED);
+ auto& cmd = mCommands.back().draw;
+ cmd.type = DrawCallDescriptor::Type::DRAW_INDEXED;
+ cmd.drawIndexed.firstIndex = firstIndex;
+ cmd.drawIndexed.firstInstance = firstInstance;
+ cmd.drawIndexed.indexCount = indexCount;
+ cmd.drawIndexed.vertexOffset = vertexOffset;
+ cmd.drawIndexed.instanceCount = instanceCount;
+}
+
+void CommandBuffer::DrawIndexedIndirect(
+ Graphics::Buffer& buffer,
+ uint32_t offset,
+ uint32_t drawCount,
+ uint32_t stride)
+{
+ mCommands.emplace_back(CommandType::DRAW_INDEXED_INDIRECT);
+ auto& cmd = mCommands.back().draw;
+ cmd.type = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
+ cmd.drawIndexedIndirect.buffer = static_cast<const GLES::Buffer*>(&buffer);
+ cmd.drawIndexedIndirect.offset = offset;
+ cmd.drawIndexedIndirect.drawCount = drawCount;
+ cmd.drawIndexedIndirect.stride = stride;
+}
+
+void CommandBuffer::Reset()
+{
+ mCommands.clear();
+}
+
+void CommandBuffer::SetScissor(Graphics::Rect2D value)
+{
+ mCommands.emplace_back(CommandType::SET_SCISSOR);
+ mCommands.back().scissor.region = value;
+}
+
+void CommandBuffer::SetScissorTestEnable(bool value)
+{
+ mCommands.emplace_back(CommandType::SET_SCISSOR_TEST);
+ mCommands.back().scissorTest.enable = value;
+}
+
+void CommandBuffer::SetViewport(Viewport value)
+{
+ mCommands.emplace_back(CommandType::SET_VIEWPORT);
+ mCommands.back().viewport.region = value;
+}
+
+void CommandBuffer::SetViewportEnable(bool value)
+{
+ // There is no GL equivalent
+}
+
+[[nodiscard]] const std::vector<Command>& CommandBuffer::GetCommands() const
+{
+ return mCommands;
+}
+
+void CommandBuffer::DestroyResource()
+{
+ // Nothing to do
+}
+
+bool CommandBuffer::InitializeResource()
+{
+ // Nothing to do
+ return true;
+}
+
+void CommandBuffer::DiscardResource()
+{
+ GetController().DiscardResource(this);
+}
+
+} // namespace Dali::Graphics::GLES
\ No newline at end of file
*/
// EXTERNAL INCLUDES
+#include <dali/graphics-api/graphics-command-buffer-create-info.h>
#include <dali/graphics-api/graphics-command-buffer.h>
+#include <dali/graphics-api/graphics-types.h>
// INTERNAL INCLUDES
-#include "egl-graphics-controller.h"
-#include "gles-graphics-buffer.h"
-#include "gles-graphics-pipeline.h"
+#include "gles-graphics-resource.h"
#include "gles-graphics-types.h"
namespace Dali::Graphics::GLES
};
/**
+ * @brief Helper function to invoke destructor on anonymous struct
+ */
+template<class T>
+static void InvokeDestructor(T& object)
+{
+ object.~T();
+}
+
+/**
* Command structure allocates memory to store a single command
*/
struct Command
{
- Command()
+ Command() = delete;
+
+ Command(CommandType commandType)
{
+ type = commandType;
+ switch(type)
+ {
+ case CommandType::BIND_VERTEX_BUFFERS:
+ {
+ new(&bindVertexBuffers) decltype(bindVertexBuffers);
+ break;
+ }
+ case CommandType::BIND_TEXTURES:
+ {
+ new(&bindTextures) decltype(bindTextures);
+ break;
+ }
+ default:
+ {
+ }
+ }
}
~Command()
{
+ switch(type)
+ {
+ case CommandType::BIND_VERTEX_BUFFERS:
+ {
+ InvokeDestructor(bindVertexBuffers);
+ break;
+ }
+ case CommandType::BIND_TEXTURES:
+ {
+ InvokeDestructor(bindTextures);
+ break;
+ }
+ default:
+ {
+ }
+ }
}
/**
{
case CommandType::BIND_VERTEX_BUFFERS:
{
+ new(&bindVertexBuffers) decltype(bindVertexBuffers);
bindVertexBuffers = rhs.bindVertexBuffers;
break;
}
}
case CommandType::BIND_TEXTURES:
{
+ new(&bindTextures) decltype(bindTextures);
bindTextures = rhs.bindTextures;
break;
}
{
case CommandType::BIND_VERTEX_BUFFERS:
{
+ new(&bindVertexBuffers) decltype(bindVertexBuffers);
bindVertexBuffers = std::move(rhs.bindVertexBuffers);
break;
}
}
case CommandType::BIND_TEXTURES:
{
+ new(&bindTextures) decltype(bindTextures);
bindTextures = std::move(rhs.bindTextures);
break;
}
class CommandBuffer : public CommandBufferResource
{
public:
- CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller)
- : CommandBufferResource(createInfo, controller)
- {
- }
+ CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller);
- ~CommandBuffer() override = default;
+ ~CommandBuffer() override;
void BindVertexBuffers(uint32_t firstBinding,
std::vector<const Graphics::Buffer*> buffers,
- std::vector<uint32_t> offsets) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::BIND_VERTEX_BUFFERS;
- auto& bindings = mCommands.back().bindVertexBuffers.vertexBufferBindings;
- if(bindings.size() < firstBinding + buffers.size())
- {
- bindings.resize(firstBinding + buffers.size());
- auto index = firstBinding;
- for(auto& buf : buffers)
- {
- bindings[index].buffer = static_cast<const GLES::Buffer*>(buf);
- bindings[index].offset = offsets[index - firstBinding];
- index++;
- }
- }
- }
+ std::vector<uint32_t> offsets) override;
- void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override
- {
- mCommands.emplace_back();
- auto& cmd = mCommands.back();
- cmd.type = CommandType::BIND_UNIFORM_BUFFER;
- auto& bindCmd = cmd.bindUniformBuffers;
- for(const auto& binding : bindings)
- {
- if(binding.buffer)
- {
- auto glesBuffer = static_cast<const GLES::Buffer*>(binding.buffer);
- if(glesBuffer->IsCPUAllocated()) // standalone uniforms
- {
- bindCmd.standaloneUniformsBufferBinding.buffer = glesBuffer;
- bindCmd.standaloneUniformsBufferBinding.offset = binding.offset;
- bindCmd.standaloneUniformsBufferBinding.binding = binding.binding;
- bindCmd.standaloneUniformsBufferBinding.emulated = true;
- }
- else // Bind regular UBO
- {
- // resize binding slots
- if(binding.binding >= bindCmd.uniformBufferBindings.size())
- {
- bindCmd.uniformBufferBindings.resize(binding.binding + 1);
- }
- auto& slot = bindCmd.uniformBufferBindings[binding.binding];
- slot.buffer = glesBuffer;
- slot.offset = binding.offset;
- slot.binding = binding.binding;
- slot.emulated = false;
- }
- }
- }
- }
+ void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override;
- void BindPipeline(const Graphics::Pipeline& pipeline) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::BIND_PIPELINE;
- mCommands.back().bindPipeline.pipeline = static_cast<const GLES::Pipeline*>(&pipeline);
- }
+ void BindPipeline(const Graphics::Pipeline& pipeline) override;
- void BindTextures(std::vector<TextureBinding>& textureBindings) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::BIND_TEXTURES;
- mCommands.back().bindTextures.textureBindings = std::move(textureBindings);
- }
+ void BindTextures(std::vector<TextureBinding>& textureBindings) override;
- void BindSamplers(std::vector<SamplerBinding>& samplerBindings) override
- {
- mCommands.emplace_back();
- mCommands.back().bindSamplers.samplerBindings = std::move(samplerBindings);
- }
+ void BindSamplers(std::vector<SamplerBinding>& samplerBindings) override;
void BindPushConstants(void* data,
uint32_t size,
- uint32_t binding) override
- {
- }
+ uint32_t binding) override;
void BindIndexBuffer(const Graphics::Buffer& buffer,
uint32_t offset,
- Format format) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::BIND_INDEX_BUFFER;
- mCommands.back().bindIndexBuffer.buffer = static_cast<const GLES::Buffer*>(&buffer);
- mCommands.back().bindIndexBuffer.offset = offset;
- mCommands.back().bindIndexBuffer.format = format;
- }
+ Format format) override;
void BeginRenderPass(
Graphics::RenderPass& renderPass,
Graphics::RenderTarget& renderTarget,
Extent2D renderArea,
- std::vector<ClearValue> clearValues) override
- {
- }
+ std::vector<ClearValue> clearValues) override;
/**
* @brief Ends current render pass
* dependencies (for example, to know when target texture is ready
* before passing it to another render pass).
*/
- void EndRenderPass() override
- {
- }
+ void EndRenderPass() override;
void Draw(
uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex,
- uint32_t firstInstance) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::DRAW;
- auto& cmd = mCommands.back().draw;
- cmd.type = DrawCallDescriptor::Type::DRAW;
- cmd.draw.vertexCount = vertexCount;
- cmd.draw.instanceCount = instanceCount;
- cmd.draw.firstInstance = firstInstance;
- cmd.draw.firstVertex = firstVertex;
- }
+ uint32_t firstInstance) override;
void DrawIndexed(
uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
int32_t vertexOffset,
- uint32_t firstInstance) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::DRAW_INDEXED;
- auto& cmd = mCommands.back().draw;
- cmd.type = DrawCallDescriptor::Type::DRAW_INDEXED;
- cmd.drawIndexed.firstIndex = firstIndex;
- cmd.drawIndexed.firstInstance = firstInstance;
- cmd.drawIndexed.indexCount = indexCount;
- cmd.drawIndexed.vertexOffset = vertexOffset;
- cmd.drawIndexed.instanceCount = instanceCount;
- }
+ uint32_t firstInstance) override;
void DrawIndexedIndirect(
Graphics::Buffer& buffer,
uint32_t offset,
uint32_t drawCount,
- uint32_t stride) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::DRAW_INDEXED_INDIRECT;
- auto& cmd = mCommands.back().draw;
- cmd.type = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
- cmd.drawIndexedIndirect.buffer = static_cast<const GLES::Buffer*>(&buffer);
- cmd.drawIndexedIndirect.offset = offset;
- cmd.drawIndexedIndirect.drawCount = drawCount;
- cmd.drawIndexedIndirect.stride = stride;
- }
+ uint32_t stride) override;
- void Reset() override
- {
- mCommands.clear();
- }
-
- void SetScissor(Graphics::Rect2D value) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::SET_SCISSOR;
- mCommands.back().scissor.region = value;
- }
+ void Reset() override;
- void SetScissorTestEnable(bool value) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::SET_SCISSOR_TEST;
- mCommands.back().scissorTest.enable = value;
- }
+ void SetScissor(Graphics::Rect2D value) override;
- void SetViewport(Viewport value) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::SET_VIEWPORT;
- mCommands.back().viewport.region = value;
- }
+ void SetScissorTestEnable(bool value) override;
- void SetViewportEnable(bool value) override
- {
- // There is no GL equivalent
- }
+ void SetViewport(Viewport value) override;
- [[nodiscard]] const std::vector<Command>& GetCommands() const
- {
- return mCommands;
- }
+ void SetViewportEnable(bool value) override;
- void DestroyResource() override
- {
- // Nothing to do
- }
+ [[nodiscard]] const std::vector<Command>& GetCommands() const;
- bool InitializeResource() override
- {
- // Nothing to do
- return true;
- }
+ void DestroyResource() override;
+ bool InitializeResource() override;
- void DiscardResource() override
- {
- // Nothing to do
- }
+ void DiscardResource() override;
private:
std::vector<Command> mCommands;
#include "gles-graphics-pipeline-cache.h"
#include <algorithm>
+#include "egl-graphics-controller.h"
#include "gles-graphics-pipeline.h"
#include "gles-graphics-program.h"
}
};
+template<>
+struct CachedObjectDeleter<GLES::Program>
+{
+ CachedObjectDeleter() = default;
+
+ void operator()(GLES::Program* object)
+ {
+ // Program deleter should skip discard queue if controller shutting down
+ if(!object->GetController().IsShuttingDown())
+ {
+ object->DiscardResource();
+ }
+ else
+ {
+ // delete object otherwise
+ delete object;
+ }
+ }
+};
+
/**
* @brief The order of states being stored in the cache and mask
*/
struct ProgramCacheEntry
{
// sorted array of shaders
- std::vector<const Shader*> shaders;
- UniquePtr<ProgramImpl> program{nullptr};
+ std::vector<const Graphics::Shader*> shaders;
+ UniquePtr<ProgramImpl> program{nullptr};
};
std::vector<ProgramCacheEntry> programEntries;
}
// assert if no shaders given
- std::vector<const Shader*> shaders;
+ std::vector<const Graphics::Shader*> shaders;
shaders.reserve(info.shaderState->size());
for(auto& state : *info.shaderState)
{
if(mImpl->glProgram)
{
- auto& gl = *mImpl->controller.GetGL();
- gl.DeleteProgram(mImpl->glProgram);
+ auto gl = mImpl->controller.GetGL();
+ if(!gl)
+ {
+ return false;
+ }
+ gl->DeleteProgram(mImpl->glProgram);
return true;
}
return false;
const auto* shader = static_cast<const GLES::Shader*>(state.shader);
// Compile shader first (ignored when compiled)
- shader->Compile();
-
- gl.AttachShader(program, shader->GetGLShader());
+ if(shader->Compile())
+ {
+ gl.AttachShader(program, shader->GetGLShader());
+ }
}
gl.LinkProgram(program);
// CLASS HEADER
#include "gles-graphics-sampler.h"
+
+// INTERNAL INCLUDES
+#include "egl-graphics-controller.h"
+
+namespace Dali::Graphics::GLES
+{
+Sampler::Sampler(const Graphics::SamplerCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
+: SamplerResource(createInfo, controller)
+{
+}
+
+Sampler::~Sampler() = default;
+
+void Sampler::DestroyResource()
+{
+ // For now, no GL resources are initialized so nothing to destroy
+}
+
+bool Sampler::InitializeResource()
+{
+ // For now, there is no support for the modern GL Sampler type (yet)
+ return true;
+}
+
+void Sampler::DiscardResource()
+{
+ GetController().DiscardResource(this);
+}
+} // namespace Dali::Graphics::GLES
* @param[in] createInfo Valid createInfo structure
* @param[in] controller Reference to the controller
*/
- Sampler(const Graphics::SamplerCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
- : SamplerResource(createInfo, controller)
- {
- }
+ Sampler(const Graphics::SamplerCreateInfo& createInfo, Graphics::EglGraphicsController& controller);
/**
* @brief Destructor
*/
- ~Sampler() override = default;
+ ~Sampler() override;
/**
* @brief Called when GL resources are destroyed
*/
- void DestroyResource() override
- {
- // TODO: Implement destroying the resource
- }
+ void DestroyResource();
/**
* @brief Called when initializing the resource
*
* @return True on success
*/
- bool InitializeResource() override
- {
- // TODO: Implement initializing resource
- return {};
- }
+ bool InitializeResource() override;
/**
* @brief Called when UniquePtr<> on client-side dies
*/
- void DiscardResource() override
- {
- // TODO: Implement moving to the discard queue
- }
+ void DiscardResource() override;
};
} // namespace Dali::Graphics::GLES
mCreateInfo.sourceData = mImpl->source.data();
}
+Shader::~Shader() = default;
+
bool Shader::Compile() const
{
auto& gl = *GetController().GetGL();
return mImpl->glShader;
}
+void Shader::DestroyResource()
+{
+ if(mImpl->glShader)
+ {
+ auto gl = GetController().GetGL();
+ if(!gl)
+ {
+ return;
+ }
+ gl->DeleteShader(mImpl->glShader);
+ }
+}
+
+void Shader::DiscardResource()
+{
+ GetController().DiscardResource(this);
+}
+
} // namespace Dali::Graphics::GLES
\ No newline at end of file
/**
* @brief Destructor
*/
- ~Shader() override = default;
+ ~Shader() override;
/**
* @brief Called when GL resources are destroyed
*/
- void DestroyResource() override
- {
- // TODO: Implement destroying the resource
- }
+ void DestroyResource() override;
/**
* @brief Called when initializing the resource
*/
bool InitializeResource() override
{
- // TODO: Implement initializing resource
- return {};
+ // The Shader has instant initialization, hence no need to initialize GL resource
+ // here
+ return true;
}
/**
* @brief Compiles shader
- * @return
+ *
+ * @return True on success
*/
- bool Compile() const;
+ [[nodiscard]] bool Compile() const;
/**
* @brief Called when UniquePtr<> on client-side dies
*/
- void DiscardResource() override
- {
- // TODO: Implement moving to the discard queue
- }
+ void DiscardResource() override;
uint32_t GetGLShader() const;
void Texture::DestroyResource()
{
+ auto gl = mController.GetGL();
+ if(!gl)
+ {
+ return;
+ }
+
// This is a proper destructor
if(mTextureId)
{
- auto gl = mController.GetGL();
gl->DeleteTextures(1, &mTextureId);
}
if(mCreateInfo.nativeImagePtr)
{
if(mEglImplementation)
{
+ // Shutdown controller
+ mGraphicsController.Shutdown();
+
+ // Terminate GLES
mEglImplementation->TerminateGles();
}
}
void EglGraphics::Destroy()
{
+ mGraphicsController.Destroy();
}
GlImplementation& EglGraphics::GetGlesInterface()