X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fgraphics%2Fgles-impl%2Fegl-graphics-controller.cpp;h=2206b12ca0e2e0785369eac7b9e9b519aa4ea316;hb=738af85a1b87813312227305117798edf85af875;hp=eec74afd8fff7544ab93184715c24be9fc024187;hpb=08384ee586769b0546b874fe8c8dc4fda815879c;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp b/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp index eec74af..2206b12 100644 --- a/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp +++ b/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 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. @@ -17,12 +17,17 @@ // CLASS HEADER #include +// EXTERNAL INCLUDES +#include +#include + // INTERNAL INCLUDES #include #include #include #include #include +#include #include #include #include @@ -35,7 +40,10 @@ #include #include #include -#include + +#include + +#include // Uncomment the following define to turn on frame dumping //#define ENABLE_COMMAND_BUFFER_FRAME_DUMP 1 @@ -90,6 +98,24 @@ auto NewObject(const GfxCreateInfo& info, EglGraphicsController& controller, T&& } else // Use standard allocator { + // We are given all object for recycling + if(oldObject) + { + auto reusedObject = oldObject.release(); + // If succeeded, attach the object to the unique_ptr and return it back + if(static_cast(reusedObject)->TryRecycle(info, controller)) + { + return UPtr(reusedObject, GLESDeleter()); + } + else + { + // can't reuse so kill object by giving it back to original + // unique pointer. + oldObject.reset(reusedObject); + } + } + + // Create brand new object return UPtr(new GLESType(info, controller), GLESDeleter()); } } @@ -103,15 +129,30 @@ T0* CastObject(T1* apiObject) // 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() = default; +EglGraphicsController::EglGraphicsController() +: mTextureDependencyChecker(*this), + mSyncPool(*this) +{ +} + +EglGraphicsController::~EglGraphicsController() +{ + while(!mPresentationCommandBuffers.empty()) + { + auto presentCommandBuffer = const_cast(mPresentationCommandBuffers.front()); + delete presentCommandBuffer; + mPresentationCommandBuffers.pop(); + } +} void EglGraphicsController::InitializeGLES(Integration::GlAbstraction& glAbstraction) { - DALI_LOG_RELEASE_INFO("Initializing New Graphics Controller #1\n"); + DALI_LOG_RELEASE_INFO("Initializing Graphics Controller Phase 1\n"); mGlAbstraction = &glAbstraction; - mContext = std::make_unique(*this); + mContext = std::make_unique(*this, mGlAbstraction); mCurrentContext = mContext.get(); } @@ -119,7 +160,7 @@ void EglGraphicsController::Initialize(Integration::GraphicsSyncAbstraction& Integration::GlContextHelperAbstraction& glContextHelperAbstraction, Internal::Adaptor::GraphicsInterface& graphicsInterface) { - DALI_LOG_RELEASE_INFO("Initializing New Graphics Controller #2\n"); + DALI_LOG_RELEASE_INFO("Initializing Graphics Controller Phase 2\n"); auto* syncImplPtr = static_cast(&syncImplementation); mEglSyncImplementation = syncImplPtr; @@ -127,12 +168,19 @@ void EglGraphicsController::Initialize(Integration::GraphicsSyncAbstraction& mGraphics = &graphicsInterface; } +void EglGraphicsController::FrameStart() +{ + mCapacity = 0; // Reset the command buffer capacity at the start of the frame. +} + void EglGraphicsController::SubmitCommandBuffers(const SubmitInfo& submitInfo) { for(auto& cmdbuf : submitInfo.cmdBuffer) { // Push command buffers - mCommandQueue.push(static_cast(cmdbuf)); + auto* commandBuffer = static_cast(cmdbuf); + mCapacity += commandBuffer->GetCapacity(); + mCommandQueue.push(commandBuffer); } // If flush bit set, flush all pending tasks @@ -142,6 +190,11 @@ void EglGraphicsController::SubmitCommandBuffers(const SubmitInfo& submitInfo) } } +void EglGraphicsController::WaitIdle() +{ + Flush(); +} + void EglGraphicsController::PresentRenderTarget(RenderTarget* renderTarget) { GLES::CommandBuffer* presentCommandBuffer{nullptr}; @@ -178,6 +231,12 @@ void EglGraphicsController::ResolvePresentRenderTarget(GLES::RenderTarget* rende } } +void EglGraphicsController::PostRender() +{ + mTextureDependencyChecker.Reset(); + mSyncPool.AgeSyncObjects(); +} + Integration::GlAbstraction& EglGraphicsController::GetGlAbstraction() { DALI_ASSERT_DEBUG(mGlAbstraction && "Graphics controller not initialized"); @@ -241,7 +300,7 @@ Graphics::UniquePtr EglGraphicsController::CreatePipeline( Graphics::UniquePtr EglGraphicsController::CreateProgram( const ProgramCreateInfo& programCreateInfo, UniquePtr&& oldProgram) { - // Create program cache if needed + // Create pipeline cache if needed if(!mPipelineCache) { mPipelineCache = std::make_unique(*this); @@ -252,7 +311,12 @@ Graphics::UniquePtr EglGraphicsController::CreateProgram( Graphics::UniquePtr EglGraphicsController::CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr&& oldShader) { - return NewObject(shaderCreateInfo, *this, std::move(oldShader)); + // Create pipeline cache if needed + if(!mPipelineCache) + { + mPipelineCache = std::make_unique(*this); + } + return mPipelineCache->GetShader(shaderCreateInfo, std::move(oldShader)); } Graphics::UniquePtr EglGraphicsController::CreateSampler(const SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr&& oldSampler) @@ -278,6 +342,35 @@ Graphics::UniquePtr EglGraphicsController::CreateSyncObject(const Sy } } +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(&texture); + const auto& createInfo = glesTexture->GetCreateInfo(); + + TextureProperties properties{}; + properties.format = createInfo.format; + properties.compressed = glesTexture->IsCompressed(); + properties.extent2D = createInfo.size; + properties.nativeHandle = glesTexture->GetGLTexture(); + // TODO: Skip format1, emulated, packed, directWriteAccessEnabled of TextureProperties for now + + return properties; +} + const Graphics::Reflection& EglGraphicsController::GetProgramReflection(const Graphics::Program& program) { return static_cast(&program)->GetReflection(); @@ -285,7 +378,7 @@ const Graphics::Reflection& EglGraphicsController::GetProgramReflection(const Gr void EglGraphicsController::CreateSurfaceContext(Dali::RenderSurfaceInterface* surface) { - std::unique_ptr context = std::make_unique(*this); + std::unique_ptr context = std::make_unique(*this, mGlAbstraction); mSurfaceContexts.push_back(std::move(std::make_pair(surface, std::move(context)))); } @@ -300,15 +393,21 @@ void EglGraphicsController::ActivateResourceContext() { mCurrentContext = mContext.get(); mCurrentContext->GlContextCreated(); + if(!mSharedContext) + { + auto eglGraphics = dynamic_cast(mGraphics); + if(eglGraphics) + { + mSharedContext = eglGraphics->GetEglImplementation().GetContext(); + } + } } void EglGraphicsController::ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface) { if(surface && mGraphics->IsResourceContextSupported()) { - auto iter = std::find_if(mSurfaceContexts.begin(), mSurfaceContexts.end(), [surface](SurfaceContextPair& iter) { - return (iter.first == surface); - }); + auto iter = std::find_if(mSurfaceContexts.begin(), mSurfaceContexts.end(), [surface](SurfaceContextPair& iter) { return (iter.first == surface); }); if(iter != mSurfaceContexts.end()) { @@ -338,6 +437,8 @@ void EglGraphicsController::AddFramebuffer(GLES::Framebuffer& framebuffer) void EglGraphicsController::ProcessDiscardQueues() { + DALI_TRACE_SCOPE(gTraceFilter, "DALI_EGL_CONTROLLER_DISCARD_QUEUE"); + // Process textures ProcessDiscardQueue(mDiscardTextureQueue); @@ -347,10 +448,24 @@ void EglGraphicsController::ProcessDiscardQueues() // Process Framebuffers ProcessDiscardQueue(mDiscardFramebufferQueue); + // Process RenderPass + ProcessDiscardQueue(mDiscardRenderPassQueue); + + // Process RenderTarget + ProcessDiscardQueue(mDiscardRenderTargetQueue); + // Process pipelines + if(mPipelineCache && !mDiscardPipelineQueue.empty()) + { + mPipelineCache->MarkPipelineCacheFlushRequired(); + } ProcessDiscardQueue(mDiscardPipelineQueue); // Process programs + if(mPipelineCache && !mDiscardProgramQueue.empty()) + { + mPipelineCache->MarkProgramCacheFlushRequired(); + } ProcessDiscardQueue(mDiscardProgramQueue); // Process shaders @@ -365,6 +480,7 @@ void EglGraphicsController::ProcessDiscardQueues() void EglGraphicsController::ProcessCreateQueues() { + DALI_TRACE_SCOPE(gTraceFilter, "DALI_EGL_CONTROLLER_CREATE_QUEUE"); // Process textures ProcessCreateQueue(mCreateTextureQueue); @@ -379,6 +495,11 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm { 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]; @@ -424,17 +545,17 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm } case GLES::CommandType::DRAW: { - mCurrentContext->Flush(false, cmd.draw); + mCurrentContext->Flush(false, cmd.draw, mTextureDependencyChecker); break; } case GLES::CommandType::DRAW_INDEXED: { - mCurrentContext->Flush(false, cmd.draw); + mCurrentContext->Flush(false, cmd.draw, mTextureDependencyChecker); break; } case GLES::CommandType::DRAW_INDEXED_INDIRECT: { - mCurrentContext->Flush(false, cmd.draw); + mCurrentContext->Flush(false, cmd.draw, mTextureDependencyChecker); break; } case GLES::CommandType::SET_SCISSOR: // @todo Consider correcting for orientation here? @@ -530,12 +651,15 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm } mCurrentContext->BeginRenderPass(cmd.beginRenderPass); + break; } case GLES::CommandType::END_RENDERPASS: { - mCurrentContext->EndRenderPass(); + mCurrentContext->EndRenderPass(mTextureDependencyChecker); + // This sync object is to enable cpu to wait for rendering to complete, not gpu. + // It's only needed for reading the framebuffer texture in the client. auto syncObject = const_cast(static_cast(cmd.endRenderPass.syncObject)); if(syncObject) { @@ -569,8 +693,26 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm } break; } + case GLES::CommandType::DRAW_NATIVE: + { + auto* info = &cmd.drawNative.drawNativeInfo; + + mCurrentContext->PrepareForNativeRendering(); + + if(info->glesNativeInfo.eglSharedContextStoragePointer) + { + auto* anyContext = reinterpret_cast(info->glesNativeInfo.eglSharedContextStoragePointer); + *anyContext = mSharedContext; + } + + CallbackBase::ExecuteReturn(*info->callback, info->userData); + + mCurrentContext->RestoreFromNativeRendering(); + break; + } } } + DALI_TRACE_END(gTraceFilter, "DALI_EGL_CONTROLLER_PROCESS"); } void EglGraphicsController::ProcessCommandQueues() @@ -590,6 +732,11 @@ 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(); @@ -597,108 +744,145 @@ void EglGraphicsController::ProcessTextureUpdateQueue() auto& info = request.first; auto& source = request.second; - if(source.sourceType == Graphics::TextureUpdateSourceInfo::Type::MEMORY) + switch(source.sourceType) { - // GPU memory must be already allocated. + case Graphics::TextureUpdateSourceInfo::Type::MEMORY: + case Graphics::TextureUpdateSourceInfo::Type::PIXEL_DATA: + { + // GPU memory must be already allocated. + + // Check if it needs conversion + auto* texture = static_cast(info.dstTexture); + const auto& createInfo = texture->GetCreateInfo(); + auto srcFormat = GLES::GLTextureFormatType(info.srcFormat).format; + auto srcType = GLES::GLTextureFormatType(info.srcFormat).type; + auto destInternalFormat = GLES::GLTextureFormatType(createInfo.format).internalFormat; + auto destFormat = GLES::GLTextureFormatType(createInfo.format).format; + + // From render-texture.cpp + const bool isSubImage(info.dstOffset2D.x != 0 || info.dstOffset2D.y != 0 || + info.srcExtent2D.width != (createInfo.size.width / (1 << info.level)) || + info.srcExtent2D.height != (createInfo.size.height / (1 << info.level))); + + uint8_t* sourceBuffer = nullptr; + bool sourceBufferReleaseRequired = false; + if(source.sourceType == Graphics::TextureUpdateSourceInfo::Type::MEMORY) + { + sourceBuffer = reinterpret_cast(source.memorySource.memory); + sourceBufferReleaseRequired = true; + } + else + { + Dali::Integration::PixelDataBuffer pixelBufferData = Dali::Integration::GetPixelDataBuffer(source.pixelDataSource.pixelData); - // Check if it needs conversion - auto* texture = static_cast(info.dstTexture); - const auto& createInfo = texture->GetCreateInfo(); - auto srcFormat = GLES::GLTextureFormatType(info.srcFormat).format; - auto srcType = GLES::GLTextureFormatType(info.srcFormat).type; - auto destInternalFormat = GLES::GLTextureFormatType(createInfo.format).internalFormat; - auto destFormat = GLES::GLTextureFormatType(createInfo.format).format; + sourceBuffer = pixelBufferData.buffer + info.srcOffset; + sourceBufferReleaseRequired = Dali::Integration::IsPixelDataReleaseAfterUpload(source.pixelDataSource.pixelData) && info.srcOffset == 0u; + } - // From render-texture.cpp - const bool isSubImage(info.dstOffset2D.x != 0 || info.dstOffset2D.y != 0 || - info.srcExtent2D.width != (createInfo.size.width / (1 << info.level)) || - info.srcExtent2D.height != (createInfo.size.height / (1 << info.level))); + auto sourceStride = info.srcStride; + std::vector tempBuffer; - auto* sourceBuffer = reinterpret_cast(source.memorySource.memory); - std::vector tempBuffer; - if(mGlAbstraction->TextureRequiresConverting(srcFormat, destFormat, isSubImage)) - { - // Convert RGB to RGBA if necessary. - texture->TryConvertPixelData(source.memorySource.memory, info.srcFormat, createInfo.format, info.srcSize, info.srcExtent2D.width, info.srcExtent2D.height, tempBuffer); - sourceBuffer = &tempBuffer[0]; - srcFormat = destFormat; - srcType = GLES::GLTextureFormatType(createInfo.format).type; - } + if(mGlAbstraction->TextureRequiresConverting(srcFormat, destFormat, isSubImage)) + { + // Convert RGB to RGBA if necessary. + if(texture->TryConvertPixelData(sourceBuffer, info.srcFormat, createInfo.format, info.srcSize, info.srcStride, info.srcExtent2D.width, info.srcExtent2D.height, tempBuffer)) + { + sourceBuffer = &tempBuffer[0]; + sourceStride = 0u; // Converted buffer compacted. make stride as 0. + srcFormat = destFormat; + srcType = GLES::GLTextureFormatType(createInfo.format).type; + } + } - // Calculate the maximum mipmap level for the texture - texture->SetMaxMipMapLevel(std::max(texture->GetMaxMipMapLevel(), info.level)); + // Calculate the maximum mipmap level for the texture + texture->SetMaxMipMapLevel(std::max(texture->GetMaxMipMapLevel(), info.level)); - GLenum bindTarget{GL_TEXTURE_2D}; - GLenum target{GL_TEXTURE_2D}; + GLenum bindTarget{GL_TEXTURE_2D}; + GLenum target{GL_TEXTURE_2D}; - if(createInfo.textureType == Graphics::TextureType::TEXTURE_CUBEMAP) - { - bindTarget = GL_TEXTURE_CUBE_MAP; - target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + info.layer; - } + if(createInfo.textureType == Graphics::TextureType::TEXTURE_CUBEMAP) + { + bindTarget = GL_TEXTURE_CUBE_MAP; + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + info.layer; + } - mGlAbstraction->PixelStorei(GL_UNPACK_ALIGNMENT, 1); - mCurrentContext->BindTexture(bindTarget, texture->GetTextureTypeId(), texture->GetGLTexture()); + mGlAbstraction->PixelStorei(GL_UNPACK_ALIGNMENT, 1); + mGlAbstraction->PixelStorei(GL_UNPACK_ROW_LENGTH, sourceStride); - if(!isSubImage) - { - if(!texture->IsCompressed()) + mCurrentContext->BindTexture(bindTarget, texture->GetTextureTypeId(), texture->GetGLTexture()); + + if(!isSubImage) { - mGlAbstraction->TexImage2D(target, - info.level, - destInternalFormat, - info.srcExtent2D.width, - info.srcExtent2D.height, - 0, - srcFormat, - srcType, - sourceBuffer); + if(!texture->IsCompressed()) + { + mGlAbstraction->TexImage2D(target, + info.level, + destInternalFormat, + info.srcExtent2D.width, + info.srcExtent2D.height, + 0, + srcFormat, + srcType, + sourceBuffer); + } + else + { + mGlAbstraction->CompressedTexImage2D(target, + info.level, + destInternalFormat, + info.srcExtent2D.width, + info.srcExtent2D.height, + 0, + info.srcSize, + sourceBuffer); + } } else { - mGlAbstraction->CompressedTexImage2D(target, - info.level, - destInternalFormat, - info.srcExtent2D.width, - info.srcExtent2D.height, - 0, - info.srcSize, - sourceBuffer); + if(!texture->IsCompressed()) + { + mGlAbstraction->TexSubImage2D(target, + info.level, + info.dstOffset2D.x, + info.dstOffset2D.y, + info.srcExtent2D.width, + info.srcExtent2D.height, + srcFormat, + srcType, + sourceBuffer); + } + else + { + mGlAbstraction->CompressedTexSubImage2D(target, + info.level, + info.dstOffset2D.x, + info.dstOffset2D.y, + info.srcExtent2D.width, + info.srcExtent2D.height, + srcFormat, + info.srcSize, + sourceBuffer); + } } - } - else - { - if(!texture->IsCompressed()) - { - mGlAbstraction->TexSubImage2D(target, - info.level, - info.dstOffset2D.x, - info.dstOffset2D.y, - info.srcExtent2D.width, - info.srcExtent2D.height, - srcFormat, - srcType, - sourceBuffer); - } - else + + if(sourceBufferReleaseRequired && sourceBuffer != nullptr) { - mGlAbstraction->CompressedTexSubImage2D(target, - info.level, - info.dstOffset2D.x, - info.dstOffset2D.y, - info.srcExtent2D.width, - info.srcExtent2D.height, - srcFormat, - info.srcSize, - sourceBuffer); + if(source.sourceType == Graphics::TextureUpdateSourceInfo::Type::MEMORY) + { + free(reinterpret_cast(sourceBuffer)); + } + else + { + Dali::Integration::ReleasePixelDataBuffer(source.pixelDataSource.pixelData); + } } + break; + } + default: + { + // TODO: other sources + break; } - // free staging memory - free(source.memorySource.memory); - } - else - { - // TODO: other sources } mTextureUpdateRequests.pop(); @@ -724,10 +908,11 @@ void EglGraphicsController::UpdateTextures(const std::vector& // TODO: using PBO with GLES3, this is just naive // oldschool way - char* stagingBuffer = reinterpret_cast(malloc(info.srcSize)); - std::copy(&reinterpret_cast(source.memorySource.memory)[info.srcOffset], - reinterpret_cast(source.memorySource.memory) + info.srcSize, - stagingBuffer); + uint8_t* stagingBuffer = reinterpret_cast(malloc(info.srcSize)); + + uint8_t* srcMemory = &reinterpret_cast(source.memorySource.memory)[info.srcOffset]; + + std::copy(srcMemory, srcMemory + info.srcSize, stagingBuffer); mTextureUploadTotalCPUMemoryUsed += info.srcSize; @@ -735,6 +920,12 @@ void EglGraphicsController::UpdateTextures(const std::vector& source.memorySource.memory = stagingBuffer; break; } + case Graphics::TextureUpdateSourceInfo::Type::PIXEL_DATA: + { + // Increase CPU memory usage since ownership of PixelData is now on mTextureUpdateRequests. + mTextureUploadTotalCPUMemoryUsed += info.srcSize; + break; + } case Graphics::TextureUpdateSourceInfo::Type::BUFFER: { // TODO, with PBO support @@ -749,7 +940,7 @@ void EglGraphicsController::UpdateTextures(const std::vector& } // If upload buffer exceeds maximum size, flush. - if(mTextureUploadTotalCPUMemoryUsed > TEXTURE_UPLOAD_MAX_BUFER_SIZE_MB * 1024) + if(mTextureUploadTotalCPUMemoryUsed > TEXTURE_UPLOAD_MAX_BUFER_SIZE_MB * 1024 * 1024) { Flush(); mTextureUploadTotalCPUMemoryUsed = 0; @@ -758,6 +949,11 @@ void EglGraphicsController::UpdateTextures(const std::vector& void EglGraphicsController::ProcessTextureMipmapGenerationQueue() { + if(mTextureMipmapGenerationRequests.empty()) + { + return; + } + DALI_TRACE_SCOPE(gTraceFilter, "DALI_EGL_CONTROLLER_TEXTURE_MIPMAP"); while(!mTextureMipmapGenerationRequests.empty()) { auto* texture = mTextureMipmapGenerationRequests.front(); @@ -776,12 +972,14 @@ void EglGraphicsController::GenerateTextureMipmaps(const Graphics::Texture& text Graphics::UniquePtr 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) { @@ -803,4 +1001,57 @@ GLES::PipelineCache& EglGraphicsController::GetPipelineCache() const return *mPipelineCache; } +Graphics::Texture* EglGraphicsController::CreateTextureByResourceId(uint32_t resourceId, const Graphics::TextureCreateInfo& createInfo) +{ + Graphics::Texture* ret = nullptr; + Graphics::UniquePtr 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 EglGraphicsController::ReleaseTextureFromResourceId(uint32_t resourceId) +{ + Graphics::UniquePtr texture; + + auto iter = mExternalTextureResources.find(resourceId); + if(iter != mExternalTextureResources.end()) + { + texture = std::move(iter->second); + mExternalTextureResources.erase(iter); + } + + return texture; +} + } // namespace Dali::Graphics