#include <dali/integration-api/debug.h>
#include <dali/integration-api/gl-abstraction.h>
#include <dali/integration-api/gl-defines.h>
+#include <dali/integration-api/graphics-sync-abstraction.h>
+#include <dali/internal/graphics/gles-impl/egl-sync-object.h>
#include <dali/internal/graphics/gles-impl/gles-graphics-command-buffer.h>
#include <dali/internal/graphics/gles-impl/gles-graphics-pipeline.h>
+#include <dali/internal/graphics/gles-impl/gles-graphics-program.h>
#include <dali/internal/graphics/gles-impl/gles-graphics-render-pass.h>
#include <dali/internal/graphics/gles-impl/gles-graphics-render-target.h>
#include <dali/internal/graphics/gles-impl/gles-graphics-shader.h>
#include <dali/internal/graphics/gles-impl/gles-graphics-texture.h>
#include <dali/internal/graphics/gles-impl/gles-graphics-types.h>
+#include <dali/internal/graphics/gles-impl/gles-sync-object.h>
#include <dali/internal/graphics/gles-impl/gles3-graphics-memory.h>
+#include <dali/internal/graphics/gles/egl-sync-implementation.h>
#include <dali/public-api/common/dali-common.h>
-#include "gles-graphics-program.h"
// Uncomment the following define to turn on frame dumping
//#define ENABLE_COMMAND_BUFFER_FRAME_DUMP 1
return static_cast<T0*>(apiObject);
}
+// Maximum size of texture upload buffer.
+const uint32_t TEXTURE_UPLOAD_MAX_BUFER_SIZE_MB = 1;
+
} // namespace
EglGraphicsController::~EglGraphicsController() = default;
mCurrentContext = mContext.get();
}
-void EglGraphicsController::Initialize(Integration::GlSyncAbstraction& glSyncAbstraction,
+void EglGraphicsController::Initialize(Integration::GraphicsSyncAbstraction& syncImplementation,
Integration::GlContextHelperAbstraction& glContextHelperAbstraction,
Internal::Adaptor::GraphicsInterface& graphicsInterface)
{
DALI_LOG_RELEASE_INFO("Initializing New Graphics Controller #2\n");
- mGlSyncAbstraction = &glSyncAbstraction;
+ auto* syncImplPtr = static_cast<Internal::Adaptor::EglSyncImplementation*>(&syncImplementation);
+
+ mEglSyncImplementation = syncImplPtr;
mGlContextHelperAbstraction = &glContextHelperAbstraction;
mGraphics = &graphicsInterface;
}
return *mGlAbstraction;
}
-Integration::GlSyncAbstraction& EglGraphicsController::GetGlSyncAbstraction()
-{
- DALI_ASSERT_DEBUG(mGlSyncAbstraction && "Graphics controller not initialized");
- return *mGlSyncAbstraction;
-}
-
Integration::GlContextHelperAbstraction& EglGraphicsController::GetGlContextHelperAbstraction()
{
DALI_ASSERT_DEBUG(mGlContextHelperAbstraction && "Graphics controller not initialized");
return *mGlContextHelperAbstraction;
}
+Internal::Adaptor::EglSyncImplementation& EglGraphicsController::GetEglSyncImplementation()
+{
+ DALI_ASSERT_DEBUG(mEglSyncImplementation && "Sync implementation not initialized");
+ return *mEglSyncImplementation;
+}
+
Graphics::UniquePtr<CommandBuffer> EglGraphicsController::CreateCommandBuffer(
const CommandBufferCreateInfo& commandBufferCreateInfo,
Graphics::UniquePtr<CommandBuffer>&& oldCommandBuffer)
return NewObject<GLES::RenderTarget>(renderTargetCreateInfo, *this, std::move(oldRenderTarget));
}
+Graphics::UniquePtr<SyncObject> EglGraphicsController::CreateSyncObject(const SyncObjectCreateInfo& syncObjectCreateInfo,
+ UniquePtr<SyncObject>&& oldSyncObject)
+{
+ if(GetGLESVersion() < GLES::GLESVersion::GLES_30)
+ {
+ return NewObject<EGL::SyncObject>(syncObjectCreateInfo, *this, std::move(oldSyncObject));
+ }
+ else
+ {
+ return NewObject<GLES::SyncObject>(syncObjectCreateInfo, *this, std::move(oldSyncObject));
+ }
+}
+
const Graphics::Reflection& EglGraphicsController::GetProgramReflection(const Graphics::Program& program)
{
return static_cast<const Graphics::GLES::Program*>(&program)->GetReflection();
void EglGraphicsController::ActivateResourceContext()
{
mCurrentContext = mContext.get();
+ mCurrentContext->GlContextCreated();
}
void EglGraphicsController::ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface)
if(iter != mSurfaceContexts.end())
{
mCurrentContext = iter->second.get();
+ mCurrentContext->GlContextCreated();
}
}
}
ProcessDiscardQueue<GLES::Framebuffer>(mDiscardFramebufferQueue);
// Process pipelines
- ProcessDiscardQueue<GLES::Pipeline>(mDiscardPipelineQueue);
+ ProcessDiscardQueue(mDiscardPipelineQueue);
// Process programs
ProcessDiscardQueue<GLES::Program>(mDiscardProgramQueue);
}
case GLES::CommandType::SET_SCISSOR_TEST:
{
- if(cmd.scissorTest.enable)
- {
- mGlAbstraction->Enable(GL_SCISSOR_TEST);
- }
- else
- {
- mGlAbstraction->Disable(GL_SCISSOR_TEST);
- }
+ mCurrentContext->SetScissorTestEnabled(cmd.scissorTest.enable);
break;
}
case GLES::CommandType::SET_VIEWPORT: // @todo Consider correcting for orientation here?
case GLES::CommandType::END_RENDERPASS:
{
mCurrentContext->EndRenderPass();
+
+ auto syncObject = const_cast<GLES::SyncObject*>(static_cast<const GLES::SyncObject*>(cmd.endRenderPass.syncObject));
+ if(syncObject)
+ {
+ syncObject->InitializeResource();
+ }
break;
}
case GLES::CommandType::PRESENT_RENDER_TARGET:
// GPU memory must be already allocated.
// Check if it needs conversion
- auto* texture = static_cast<GLES::Texture*>(info.dstTexture);
- const auto& createInfo = texture->GetCreateInfo();
- auto srcFormat = GLES::GLTextureFormatType(info.srcFormat).format;
- auto destFormat = GLES::GLTextureFormatType(createInfo.format).format;
- auto destType = GLES::GLTextureFormatType(createInfo.format).type;
+ auto* texture = static_cast<GLES::Texture*>(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 ||
// 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;
}
- mGlAbstraction->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ // Calculate the maximum mipmap level for the texture
+ texture->SetMaxMipMapLevel(std::max(texture->GetMaxMipMapLevel(), info.level));
- mGlAbstraction->BindTexture(GL_TEXTURE_2D, texture->GetGLTexture());
+ GLenum bindTarget{GL_TEXTURE_2D};
+ GLenum target{GL_TEXTURE_2D};
- mGlAbstraction->TexSubImage2D(GL_TEXTURE_2D,
- info.level,
- info.dstOffset2D.x,
- info.dstOffset2D.y,
- info.srcExtent2D.width,
- info.srcExtent2D.height,
- destFormat,
- destType,
- sourceBuffer);
+ 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());
+ if(!isSubImage)
+ {
+ 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
+ {
+ 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);
+ }
+ }
// free staging memory
free(source.memorySource.memory);
}
reinterpret_cast<char*>(source.memorySource.memory) + info.srcSize,
stagingBuffer);
+ mTextureUploadTotalCPUMemoryUsed += info.srcSize;
+
// store staging buffer
source.memorySource.memory = stagingBuffer;
break;
}
}
}
+
+ // If upload buffer exceeds maximum size, flush.
+ if(mTextureUploadTotalCPUMemoryUsed > TEXTURE_UPLOAD_MAX_BUFER_SIZE_MB * 1024)
+ {
+ Flush();
+ mTextureUploadTotalCPUMemoryUsed = 0;
+ }
+}
+
+void EglGraphicsController::ProcessTextureMipmapGenerationQueue()
+{
+ while(!mTextureMipmapGenerationRequests.empty())
+ {
+ auto* texture = mTextureMipmapGenerationRequests.front();
+
+ mCurrentContext->BindTexture(texture->GetGlTarget(), texture->GetTextureTypeId(), texture->GetGLTexture());
+ mCurrentContext->GenerateMipmap(texture->GetGlTarget());
+
+ mTextureMipmapGenerationRequests.pop();
+ }
+}
+
+void EglGraphicsController::GenerateTextureMipmaps(const Graphics::Texture& texture)
+{
+ mTextureMipmapGenerationRequests.push(static_cast<const GLES::Texture*>(&texture));
}
Graphics::UniquePtr<Memory> EglGraphicsController::MapBufferRange(const MapBufferInfo& mapInfo)