Merge "Fix related to eglImage memory" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / egl-graphics-controller.cpp
index 5546800..545c257 100644 (file)
 #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
@@ -96,6 +100,9 @@ T0* CastObject(T1* apiObject)
   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;
@@ -108,12 +115,14 @@ void EglGraphicsController::InitializeGLES(Integration::GlAbstraction& glAbstrac
   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;
 }
@@ -164,18 +173,18 @@ Integration::GlAbstraction& EglGraphicsController::GetGlAbstraction()
   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)
@@ -245,6 +254,19 @@ Graphics::UniquePtr<RenderTarget> EglGraphicsController::CreateRenderTarget(cons
   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();
@@ -266,6 +288,7 @@ void EglGraphicsController::DeleteSurfaceContext(Dali::RenderSurfaceInterface* s
 void EglGraphicsController::ActivateResourceContext()
 {
   mCurrentContext = mContext.get();
+  mCurrentContext->GlContextCreated();
 }
 
 void EglGraphicsController::ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface)
@@ -279,6 +302,7 @@ void EglGraphicsController::ActivateSurfaceContext(Dali::RenderSurfaceInterface*
     if(iter != mSurfaceContexts.end())
     {
       mCurrentContext = iter->second.get();
+      mCurrentContext->GlContextCreated();
     }
   }
 }
@@ -313,7 +337,7 @@ void EglGraphicsController::ProcessDiscardQueues()
   ProcessDiscardQueue<GLES::Framebuffer>(mDiscardFramebufferQueue);
 
   // Process pipelines
-  ProcessDiscardQueue<GLES::Pipeline>(mDiscardPipelineQueue);
+  ProcessDiscardQueue(mDiscardPipelineQueue);
 
   // Process programs
   ProcessDiscardQueue<GLES::Program>(mDiscardProgramQueue);
@@ -406,14 +430,7 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm
       }
       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?
@@ -504,6 +521,12 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm
       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:
@@ -563,11 +586,12 @@ void EglGraphicsController::ProcessTextureUpdateQueue()
       // 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 ||
@@ -581,22 +605,78 @@ void EglGraphicsController::ProcessTextureUpdateQueue()
         // 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);
     }
@@ -633,6 +713,8 @@ void EglGraphicsController::UpdateTextures(const std::vector<TextureUpdateInfo>&
                   reinterpret_cast<char*>(source.memorySource.memory) + info.srcSize,
                   stagingBuffer);
 
+        mTextureUploadTotalCPUMemoryUsed += info.srcSize;
+
         // store staging buffer
         source.memorySource.memory = stagingBuffer;
         break;
@@ -649,6 +731,31 @@ void EglGraphicsController::UpdateTextures(const std::vector<TextureUpdateInfo>&
       }
     }
   }
+
+  // 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)