void operator()(T* object)
{
- // GLES object deleter should skip discard queue if controller shutting down
- if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
- {
- // Discard resource (add it to discard queue)
- object->DiscardResource();
- }
- else
- {
- // Destroy and delete object otherwise
- if(DALI_LIKELY(object))
- {
- object->DestroyResource();
- }
- delete object;
- }
+ // Discard resource (add it to discard queue)
+ object->DiscardResource();
}
};
const uint32_t TEXTURE_UPLOAD_MAX_BUFER_SIZE_MB = 1;
DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_EGL, false);
-
-bool gIsShuttingDown = true; ///< Global static flag to ensure that we have single graphics controller instance per each UpdateRender thread loop.
} // namespace
-bool EglGraphicsController::IsShuttingDown()
-{
- return gIsShuttingDown;
-}
-
EglGraphicsController::EglGraphicsController()
: mTextureDependencyChecker(*this),
mSyncPool(*this)
void EglGraphicsController::InitializeGLES(Integration::GlAbstraction& glAbstraction)
{
DALI_LOG_RELEASE_INFO("Initializing Graphics Controller Phase 1\n");
-
mGlAbstraction = &glAbstraction;
mContext = std::make_unique<GLES::Context>(*this, mGlAbstraction);
mCurrentContext = mContext.get();
DALI_LOG_RELEASE_INFO("Initializing Graphics Controller Phase 2\n");
auto* syncImplPtr = static_cast<Internal::Adaptor::EglSyncImplementation*>(&syncImplementation);
- DALI_ASSERT_ALWAYS(gIsShuttingDown && "Don't initialize Phase 2 EglGraphicsController twice");
- gIsShuttingDown = false;
-
mEglSyncImplementation = syncImplPtr;
mGraphics = &graphicsInterface;
}
Flush();
}
-void EglGraphicsController::Shutdown()
-{
- DALI_ASSERT_ALWAYS(!gIsShuttingDown && "Don't call EglGraphicsController::Shutdown twice");
- gIsShuttingDown = true;
-
- // Final flush
- Flush();
-
- if(mContext)
- {
- mContext->GlContextDestroyed();
- }
-
- for(auto&& context : mSurfaceContexts)
- {
- if(context.second)
- {
- context.second->GlContextDestroyed();
- }
- }
-}
-
void EglGraphicsController::PresentRenderTarget(RenderTarget* renderTarget)
{
GLES::CommandBuffer* presentCommandBuffer{nullptr};
class EglGraphicsController : public Graphics::Controller
{
public:
- /**
- * @brief Get whether is graphics controller shutting down or not.
- */
- static bool IsShuttingDown();
-
/**
* @brief Constructor
*/
/**
* @copydoc Dali::Graphics::Shutdown()
*/
- void Shutdown() override;
+ void Shutdown() override
+ {
+ mIsShuttingDown = true;
+
+ // Final flush
+ Flush();
+
+ if(mContext)
+ {
+ mContext->GlContextDestroyed();
+ }
+
+ for(auto&& context : mSurfaceContexts)
+ {
+ if(context.second)
+ {
+ context.second->GlContextDestroyed();
+ }
+ }
+ }
/**
* @copydoc Dali::Graphics::Destroy()
public:
[[nodiscard]] Integration::GlAbstraction* GetGL() const
{
- if(DALI_UNLIKELY(IsShuttingDown()))
+ if(mIsShuttingDown)
{
return nullptr;
}
mGLESVersion = glesVersion;
}
+ bool IsShuttingDown() const
+ {
+ return mIsShuttingDown;
+ }
+
/**
* @brief Reset texture cache in the contexts
*/
GLES::GLESVersion mGLESVersion{GLES::GLESVersion::GLES_20}; ///< Runtime supported GLES version
uint32_t mTextureUploadTotalCPUMemoryUsed{0u};
+ bool mIsShuttingDown{false}; ///< Indicates whether the controller is shutting down
+
std::queue<const GLES::CommandBuffer*> mPresentationCommandBuffers{}; ///< Queue of reusable command buffers used by presentation engine
void* mSharedContext{nullptr}; ///< Shared EGL context
void SyncObject::DestroyResource()
{
- if(DALI_UNLIKELY(EglGraphicsController::IsShuttingDown()))
- {
- return;
- }
- mEglSyncImplementation.DestroySyncObject(mEglSyncObject);
- mEglSyncObject = nullptr;
}
bool SyncObject::InitializeResource()
{
// Called from custom deleter.
// Don't use discard queue, drop immediately.
- DestroyResource();
+ mEglSyncImplementation.DestroySyncObject(mEglSyncObject);
+ mEglSyncObject = nullptr;
}
bool SyncObject::IsSynced()
void Buffer::InitializeGPUBuffer()
{
- if(DALI_UNLIKELY(EglGraphicsController::IsShuttingDown()))
- {
- return;
- }
-
auto context = mController.GetCurrentContext();
auto gl = mController.GetGL();
if(!gl || !context)
// Deestroy GPU allocation
else
{
- if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
+ auto gl = mController.GetGL();
+ if(gl)
{
- auto gl = mController.GetGL();
- if(gl)
- {
- gl->DeleteBuffers(1, &mBufferId);
- }
+ gl->DeleteBuffers(1, &mBufferId);
}
}
}
/*
- * Copyright (c) 2024 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.
void Framebuffer::DestroyResource()
{
- if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
+ auto context = mController.GetCurrentContext();
+ auto gl = mController.GetGL();
+ if(gl && context && mInitialized)
{
- auto context = mController.GetCurrentContext();
- auto gl = mController.GetGL();
- if(gl && context && mInitialized)
+ if(mDepthBufferId)
{
- if(mDepthBufferId)
- {
- gl->DeleteRenderbuffers(1, &mDepthBufferId);
- }
- if(mStencilBufferId)
- {
- gl->DeleteRenderbuffers(1, &mStencilBufferId);
- }
+ gl->DeleteRenderbuffers(1, &mDepthBufferId);
+ }
+ if(mStencilBufferId)
+ {
+ gl->DeleteRenderbuffers(1, &mStencilBufferId);
+ }
- context->DeleteFramebuffers(1, &mFramebufferId);
+ context->DeleteFramebuffers(1, &mFramebufferId);
- mFramebufferId = 0u;
- mInitialized = false;
- }
+ mFramebufferId = 0u;
+ mInitialized = false;
}
}
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
void operator()(T* object)
{
- // Discard resource (add it to discard queue) if controller is not shutting down
- if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
+ // Discard resource (add it to discard queue)
+ object->DiscardResource();
+ }
+};
+
+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
{
- // Destroy and delete object otherwise
- if(DALI_LIKELY(object))
- {
- object->DestroyResource();
- }
+ // delete object otherwise
delete object;
}
}
void PipelineImpl::Bind(const uint32_t glProgram) const
{
- if(DALI_UNLIKELY(EglGraphicsController::IsShuttingDown()))
- {
- return; // Early out if shutting down
- }
-
if(auto gl = GetController().GetGL())
{
gl->UseProgram(glProgram);
bool ProgramImpl::Destroy()
{
- if(DALI_UNLIKELY(EglGraphicsController::IsShuttingDown()))
- {
- return false; // Early out if shutting down
- }
-
if(mImpl->glProgram)
{
auto gl = mImpl->controller.GetGL();
const auto& extraInfos = reflection.GetStandaloneUniformExtraInfo();
- if(DALI_UNLIKELY(EglGraphicsController::IsShuttingDown()))
- {
- return; // Early out if shutting down
- }
-
auto* gl = GetController().GetGL();
if(!gl)
{
ShaderImpl::~ShaderImpl()
{
- if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
+ if(!mImpl->controller.IsShuttingDown())
{
mImpl->Destroy();
}
{
if(!mShader->Release())
{
- if(DALI_UNLIKELY(EglGraphicsController::IsShuttingDown()))
- {
- return; // Early out if shutting down
- }
-
GetImplementation()->GetController().GetPipelineCache().MarkShaderCacheFlushRequired();
}
}
void Shader::DiscardResource()
{
- GetImplementation()->GetController().DiscardResource(this);
+ auto& controller = GetImplementation()->GetController();
+ if(!controller.IsShuttingDown())
+ {
+ controller.DiscardResource(this);
+ }
}
uint32_t Shader::GetGLSLVersion() const
void Texture::DestroyResource()
{
- if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
+ auto gl = mController.GetGL();
+ if(!gl)
{
- auto gl = mController.GetGL();
- if(!gl)
- {
- return;
- }
-
- // This is a proper destructor
- if(mTextureId)
- {
- gl->DeleteTextures(1, &mTextureId);
- }
+ return;
+ }
- // TODO : Shouldn't we call DestroyResource even if shutting down?
- // For now, we use EglExtensions API at DestroyResource. So just block for now.
- if(mCreateInfo.nativeImagePtr)
- {
- mCreateInfo.nativeImagePtr->DestroyResource();
- }
+ // This is a proper destructor
+ if(mTextureId)
+ {
+ gl->DeleteTextures(1, &mTextureId);
+ }
+ if(mCreateInfo.nativeImagePtr)
+ {
+ mCreateInfo.nativeImagePtr->DestroyResource();
}
}
void SyncObject::DestroyResource()
{
- if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
- {
- auto gl = mController.GetGL();
- if(gl)
- {
- gl->DeleteSync(mGlSyncObject);
- }
- mGlSyncObject = 0;
- }
}
bool SyncObject::InitializeResource()
{
// Called from custom deleter.
// Don't use discard queue, drop immediately.
- DestroyResource();
+ auto gl = mController.GetGL();
+ if(gl)
+ {
+ gl->DeleteSync(mGlSyncObject);
+ }
+ mGlSyncObject = 0;
}
bool SyncObject::IsSynced()
AgingSyncObject::~AgingSyncObject()
{
- if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
+ if(!controller.IsShuttingDown())
{
if(egl)
{
void Memory2::Unlock(bool flush)
{
- if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
+ if(auto gl = mController.GetGL())
{
- if(auto gl = mController.GetGL())
+ // for buffer...
+ if(mMapObjectType == MapObjectType::BUFFER && mMappedPointer)
{
- // for buffer...
- if(mMapObjectType == MapObjectType::BUFFER && mMappedPointer)
+ auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
+ if(!buffer->IsCPUAllocated())
{
- auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
- if(!buffer->IsCPUAllocated())
- {
- buffer->Bind(BufferUsage::VERTEX_BUFFER);
- gl->BufferSubData(GL_ARRAY_BUFFER, GLintptr(mMapBufferInfo.offset), GLsizeiptr(mMapBufferInfo.size), mMappedPointer);
- }
+ buffer->Bind(BufferUsage::VERTEX_BUFFER);
+ gl->BufferSubData(GL_ARRAY_BUFFER, GLintptr(mMapBufferInfo.offset), GLsizeiptr(mMapBufferInfo.size), mMappedPointer);
}
+ }
- if(mIsAllocatedLocally)
- {
- free(mMappedPointer);
- mMappedPointer = nullptr;
- }
+ if(mIsAllocatedLocally)
+ {
+ free(mMappedPointer);
+ mMappedPointer = nullptr;
+ }
- if(flush)
- {
- Flush();
- }
+ if(flush)
+ {
+ Flush();
}
}
}
void* Memory3::LockRegion(uint32_t offset, uint32_t size)
{
- if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
+ if(auto gl = mController.GetGL())
{
- if(auto gl = mController.GetGL())
+ if(mMapObjectType == MapObjectType::BUFFER)
{
- if(mMapObjectType == MapObjectType::BUFFER)
- {
- auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
+ auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
- if(buffer->IsCPUAllocated())
- {
- using Ptr = char*;
- mMappedPointer = Ptr(buffer->GetCPUAllocatedAddress()) + offset;
- }
- else
- {
- gl->BindBuffer(GL_COPY_WRITE_BUFFER, buffer->GetGLBuffer());
- void* ptr = nullptr;
- ptr = gl->MapBufferRange(GL_COPY_WRITE_BUFFER, GLintptr(mMapBufferInfo.offset), GLsizeiptr(mMapBufferInfo.size), GL_MAP_WRITE_BIT);
- mMappedPointer = ptr;
- }
- return mMappedPointer;
+ if(buffer->IsCPUAllocated())
+ {
+ using Ptr = char*;
+ mMappedPointer = Ptr(buffer->GetCPUAllocatedAddress()) + offset;
+ }
+ else
+ {
+ gl->BindBuffer(GL_COPY_WRITE_BUFFER, buffer->GetGLBuffer());
+ void* ptr = nullptr;
+ ptr = gl->MapBufferRange(GL_COPY_WRITE_BUFFER, GLintptr(mMapBufferInfo.offset), GLsizeiptr(mMapBufferInfo.size), GL_MAP_WRITE_BIT);
+ mMappedPointer = ptr;
}
+ return mMappedPointer;
}
}
return nullptr;
void Memory3::Unlock(bool flush)
{
- if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
+ if(auto gl = mController.GetGL())
{
- if(auto gl = mController.GetGL())
+ if(mMapObjectType == MapObjectType::BUFFER && mMappedPointer)
{
- if(mMapObjectType == MapObjectType::BUFFER && mMappedPointer)
+ auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
+ if(!buffer->IsCPUAllocated())
{
- auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
- if(!buffer->IsCPUAllocated())
- {
- gl->BindBuffer(GL_COPY_WRITE_BUFFER, buffer->GetGLBuffer());
- gl->UnmapBuffer(GL_COPY_WRITE_BUFFER);
- }
+ gl->BindBuffer(GL_COPY_WRITE_BUFFER, buffer->GetGLBuffer());
+ gl->UnmapBuffer(GL_COPY_WRITE_BUFFER);
}
+ }
- if(flush)
- {
- Flush();
- }
+ if(flush)
+ {
+ Flush();
}
mMappedPointer = nullptr;
EglSyncImplementation::~EglSyncImplementation()
{
- for(auto& syncObject : mSyncObjects)
- {
- delete static_cast<EglSyncObject*>(syncObject);
- }
- mSyncObjects.Clear();
}
void EglSyncImplementation::Initialize(EglImplementation* eglImpl)