/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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 <dali/internal/graphics/gles-impl/egl-graphics-controller.h>
// EXTERNAL INCLUDES
+#include <dali/integration-api/trace.h>
#include <dali/public-api/common/dali-common.h>
// INTERNAL INCLUDES
// Maximum size of texture upload buffer.
const uint32_t TEXTURE_UPLOAD_MAX_BUFER_SIZE_MB = 1;
+DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_EGL, false);
} // namespace
EglGraphicsController::EglGraphicsController()
{
DALI_LOG_RELEASE_INFO("Initializing Graphics Controller Phase 1\n");
mGlAbstraction = &glAbstraction;
- mContext = std::make_unique<GLES::Context>(*this);
+ mContext = std::make_unique<GLES::Context>(*this, mGlAbstraction);
mCurrentContext = mContext.get();
}
Graphics::UniquePtr<Program> EglGraphicsController::CreateProgram(
const ProgramCreateInfo& programCreateInfo, UniquePtr<Program>&& oldProgram)
{
- // Create program cache if needed
+ // Create pipeline cache if needed
if(!mPipelineCache)
{
mPipelineCache = std::make_unique<GLES::PipelineCache>(*this);
Graphics::UniquePtr<Shader> EglGraphicsController::CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Shader>&& oldShader)
{
- return NewObject<GLES::Shader>(shaderCreateInfo, *this, std::move(oldShader));
+ // Create pipeline cache if needed
+ if(!mPipelineCache)
+ {
+ mPipelineCache = std::make_unique<GLES::PipelineCache>(*this);
+ }
+ return mPipelineCache->GetShader(shaderCreateInfo, std::move(oldShader));
}
Graphics::UniquePtr<Sampler> EglGraphicsController::CreateSampler(const SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Sampler>&& oldSampler)
}
}
+MemoryRequirements EglGraphicsController::GetBufferMemoryRequirements(Buffer& buffer) const
+{
+ MemoryRequirements requirements{};
+
+ auto gl = GetGL();
+ if(gl)
+ {
+ GLint align;
+ gl->GetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &align);
+ requirements.alignment = align;
+ }
+ return requirements;
+}
+
TextureProperties EglGraphicsController::GetTextureProperties(const Texture& texture)
{
const GLES::Texture* glesTexture = static_cast<const GLES::Texture*>(&texture);
- auto createInfo = glesTexture->GetCreateInfo();
+ const auto& createInfo = glesTexture->GetCreateInfo();
TextureProperties properties{};
properties.format = createInfo.format;
void EglGraphicsController::CreateSurfaceContext(Dali::RenderSurfaceInterface* surface)
{
- std::unique_ptr<GLES::Context> context = std::make_unique<GLES::Context>(*this);
+ std::unique_ptr<GLES::Context> context = std::make_unique<GLES::Context>(*this, mGlAbstraction);
mSurfaceContexts.push_back(std::move(std::make_pair(surface, std::move(context))));
}
void EglGraphicsController::ProcessDiscardQueues()
{
+ DALI_TRACE_SCOPE(gTraceFilter, "DALI_EGL_CONTROLLER_DISCARD_QUEUE");
+
// Process textures
ProcessDiscardQueue<GLES::Texture>(mDiscardTextureQueue);
ProcessDiscardQueue<GLES::RenderTarget>(mDiscardRenderTargetQueue);
// Process pipelines
+ if(mPipelineCache && !mDiscardPipelineQueue.empty())
+ {
+ mPipelineCache->MarkPipelineCacheFlushRequired();
+ }
ProcessDiscardQueue(mDiscardPipelineQueue);
// Process programs
+ if(mPipelineCache && !mDiscardProgramQueue.empty())
+ {
+ mPipelineCache->MarkProgramCacheFlushRequired();
+ }
ProcessDiscardQueue<GLES::Program>(mDiscardProgramQueue);
// Process shaders
void EglGraphicsController::ProcessCreateQueues()
{
+ DALI_TRACE_SCOPE(gTraceFilter, "DALI_EGL_CONTROLLER_CREATE_QUEUE");
// Process textures
ProcessCreateQueue(mCreateTextureQueue);
{
auto count = 0u;
const auto commands = commandBuffer.GetCommands(count);
+
+ DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_EGL_CONTROLLER_PROCESS", [&](std::ostringstream& oss) {
+ oss << "[commandCount:" << count << "]";
+ });
+
for(auto i = 0u; i < count; ++i)
{
auto& cmd = commands[i];
}
}
}
+ DALI_TRACE_END(gTraceFilter, "DALI_EGL_CONTROLLER_PROCESS");
}
void EglGraphicsController::ProcessCommandQueues()
void EglGraphicsController::ProcessTextureUpdateQueue()
{
+ if(mTextureUpdateRequests.empty())
+ {
+ return;
+ }
+ DALI_TRACE_SCOPE(gTraceFilter, "DALI_EGL_CONTROLLER_TEXTURE_UPDATE");
while(!mTextureUpdateRequests.empty())
{
TextureUpdateRequest& request = mTextureUpdateRequests.front();
info.srcExtent2D.width != (createInfo.size.width / (1 << info.level)) ||
info.srcExtent2D.height != (createInfo.size.height / (1 << info.level)));
- uint8_t* sourceBuffer;
+ uint8_t* sourceBuffer = nullptr;
+ bool sourceBufferReleaseRequired = false;
if(source.sourceType == Graphics::TextureUpdateSourceInfo::Type::MEMORY)
{
- sourceBuffer = reinterpret_cast<uint8_t*>(source.memorySource.memory);
+ sourceBuffer = reinterpret_cast<uint8_t*>(source.memorySource.memory);
+ sourceBufferReleaseRequired = true;
}
else
{
- // Get buffer of PixelData
Dali::Integration::PixelDataBuffer pixelBufferData = Dali::Integration::GetPixelDataBuffer(source.pixelDataSource.pixelData);
- sourceBuffer = pixelBufferData.buffer + info.srcOffset;
+ sourceBuffer = pixelBufferData.buffer + info.srcOffset;
+ sourceBufferReleaseRequired = Dali::Integration::IsPixelDataReleaseAfterUpload(source.pixelDataSource.pixelData) && info.srcOffset == 0u;
}
auto sourceStride = info.srcStride;
}
}
- if(source.sourceType == Graphics::TextureUpdateSourceInfo::Type::MEMORY)
+ if(sourceBufferReleaseRequired && sourceBuffer != nullptr)
{
- // free staging memory
- free(source.memorySource.memory);
+ if(source.sourceType == Graphics::TextureUpdateSourceInfo::Type::MEMORY)
+ {
+ free(reinterpret_cast<void*>(sourceBuffer));
+ }
+ else
+ {
+ Dali::Integration::ReleasePixelDataBuffer(source.pixelDataSource.pixelData);
+ }
}
break;
}
void EglGraphicsController::ProcessTextureMipmapGenerationQueue()
{
+ if(mTextureMipmapGenerationRequests.empty())
+ {
+ return;
+ }
+ DALI_TRACE_SCOPE(gTraceFilter, "DALI_EGL_CONTROLLER_TEXTURE_MIPMAP");
while(!mTextureMipmapGenerationRequests.empty())
{
auto* texture = mTextureMipmapGenerationRequests.front();
Graphics::UniquePtr<Memory> EglGraphicsController::MapBufferRange(const MapBufferInfo& mapInfo)
{
- mGraphics->ActivateResourceContext();
-
// Mapping buffer requires the object to be created NOW
// Workaround - flush now, otherwise there will be given a staging buffer
// in case when the buffer is not there yet
- ProcessCreateQueues();
+ if(!mCreateBufferQueue.empty())
+ {
+ mGraphics->ActivateResourceContext();
+ ProcessCreateQueues();
+ }
if(GetGLESVersion() < GLES::GLESVersion::GLES_30)
{
return *mPipelineCache;
}
+Graphics::Texture* EglGraphicsController::CreateTextureByResourceId(uint32_t resourceId, const Graphics::TextureCreateInfo& createInfo)
+{
+ Graphics::Texture* ret = nullptr;
+ Graphics::UniquePtr<Graphics::Texture> texture;
+
+ auto iter = mExternalTextureResources.find(resourceId);
+ DALI_ASSERT_ALWAYS(iter == mExternalTextureResources.end());
+
+ texture = CreateTexture(createInfo, std::move(texture));
+
+ ret = texture.get();
+
+ mExternalTextureResources.insert(std::make_pair(resourceId, std::move(texture)));
+
+ return ret;
+}
+
+void EglGraphicsController::DiscardTextureFromResourceId(uint32_t resourceId)
+{
+ auto iter = mExternalTextureResources.find(resourceId);
+ if(iter != mExternalTextureResources.end())
+ {
+ mExternalTextureResources.erase(iter);
+ }
+}
+
+Graphics::Texture* EglGraphicsController::GetTextureFromResourceId(uint32_t resourceId)
+{
+ Graphics::Texture* ret = nullptr;
+
+ auto iter = mExternalTextureResources.find(resourceId);
+ if(iter != mExternalTextureResources.end())
+ {
+ ret = iter->second.get();
+ }
+
+ return ret;
+}
+
+Graphics::UniquePtr<Graphics::Texture> EglGraphicsController::ReleaseTextureFromResourceId(uint32_t resourceId)
+{
+ Graphics::UniquePtr<Graphics::Texture> texture;
+
+ auto iter = mExternalTextureResources.find(resourceId);
+ if(iter != mExternalTextureResources.end())
+ {
+ texture = std::move(iter->second);
+ mExternalTextureResources.erase(iter);
+ }
+
+ return texture;
+}
+
} // namespace Dali::Graphics