[dali_2.3.39] Merge branch 'devel/master'
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles / egl-graphics.cpp
index e1dd665..6b0e9d2 100644 (file)
@@ -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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/adaptor-framework/render-surface-interface.h>
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/adaptor-framework/render-surface-interface.h>
+#include <dali/integration-api/debug.h>
+#include <dali/internal/graphics/common/egl-include.h>
 #include <dali/internal/system/common/configuration-manager.h>
 #include <dali/internal/system/common/environment-options.h>
 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
 #include <dali/internal/system/common/configuration-manager.h>
 #include <dali/internal/system/common/environment-options.h>
 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
+#include <dali/internal/window-system/common/window-base.h>
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -30,14 +33,15 @@ namespace Internal
 {
 namespace Adaptor
 {
 {
 namespace Adaptor
 {
-EglGraphics::EglGraphics(EnvironmentOptions& environmentOptions)
-: mMultiSamplingLevel(0)
+EglGraphics::EglGraphics(
+  EnvironmentOptions&                 environmentOptions,
+  const Graphics::GraphicsCreateInfo& info,
+  Integration::DepthBufferAvailable   depthBufferRequired,
+  Integration::StencilBufferAvailable stencilBufferRequired,
+  Integration::PartialUpdateAvailable partialUpdateRequired)
+: GraphicsInterface(info, depthBufferRequired, stencilBufferRequired, partialUpdateRequired),
+  mMultiSamplingLevel(info.multiSamplingLevel)
 {
 {
-  mDepthBufferRequired   = static_cast<Integration::DepthBufferAvailable>(environmentOptions.DepthBufferRequired());
-  mStencilBufferRequired = static_cast<Integration::StencilBufferAvailable>(environmentOptions.StencilBufferRequired());
-  mPartialUpdateRequired = static_cast<Integration::PartialUpdateAvailable>(environmentOptions.PartialUpdateRequired());
-  mMultiSamplingLevel    = environmentOptions.GetMultiSamplingLevel();
-
   if(environmentOptions.GetGlesCallTime() > 0)
   {
     mGLES = Utils::MakeUnique<GlProxyImplementation>(environmentOptions);
   if(environmentOptions.GetGlesCallTime() > 0)
   {
     mGLES = Utils::MakeUnique<GlProxyImplementation>(environmentOptions);
@@ -54,16 +58,6 @@ EglGraphics::~EglGraphics()
 {
 }
 
 {
 }
 
-void EglGraphics::SetGlesVersion(const int32_t glesVersion)
-{
-  if(mEglImplementation)
-  {
-    mEglImplementation->SetGlesVersion(glesVersion);
-  }
-
-  mGLES->SetGlesVersion(glesVersion);
-}
-
 void EglGraphics::SetIsSurfacelessContextSupported(const bool isSupported)
 {
   mGLES->SetIsSurfacelessContextSupported(isSupported);
 void EglGraphics::SetIsSurfacelessContextSupported(const bool isSupported)
 {
   mGLES->SetIsSurfacelessContextSupported(isSupported);
@@ -76,9 +70,51 @@ void EglGraphics::ActivateResourceContext()
     // Make the shared surfaceless context as current before rendering
     mEglImplementation->MakeContextCurrent(EGL_NO_SURFACE, mEglImplementation->GetContext());
   }
     // Make the shared surfaceless context as current before rendering
     mEglImplementation->MakeContextCurrent(EGL_NO_SURFACE, mEglImplementation->GetContext());
   }
+
+  mGraphicsController.ActivateResourceContext();
+}
+
+void EglGraphics::ActivateSurfaceContext(Dali::Integration::RenderSurfaceInterface* surface)
+{
+  if(surface)
+  {
+    surface->InitializeGraphics();
+    surface->MakeContextCurrent();
+  }
+
+  mGraphicsController.ActivateSurfaceContext(surface);
 }
 
 }
 
-void EglGraphics::SetFirstFrameAfterResume()
+void EglGraphics::MakeContextCurrent(Graphics::SurfaceId surfaceId)
+{
+  auto search = mSurfaceMap.find(surfaceId);
+  if(DALI_UNLIKELY(search == mSurfaceMap.end()))
+  {
+    DALI_LOG_ERROR("Invalid surface id [%u] used! Ignore\n", surfaceId);
+    DALI_ASSERT_DEBUG(0 && "Invalid srufaceId");
+    return;
+  }
+
+  mEglImplementation->MakeContextCurrent(search->second.surface, search->second.context);
+}
+
+void EglGraphics::PostRender()
+{
+  ActivateResourceContext();
+
+  if(mGraphicsController.GetCurrentContext())
+  {
+    mGraphicsController.GetCurrentContext()->InvalidateDepthStencilBuffers();
+  }
+
+  mGraphicsController.PostRender();
+}
+
+void EglGraphics::Pause()
+{
+}
+
+void EglGraphics::Resume()
 {
   if(mEglImplementation)
   {
 {
   if(mEglImplementation)
   {
@@ -86,15 +122,68 @@ void EglGraphics::SetFirstFrameAfterResume()
   }
 }
 
   }
 }
 
-void EglGraphics::Initialize()
+int EglGraphics::GetBufferAge(Graphics::SurfaceId surfaceId)
+{
+  auto search = mSurfaceMap.find(surfaceId);
+  if(DALI_UNLIKELY(search == mSurfaceMap.end()))
+  {
+    DALI_LOG_ERROR("Invalid surface id [%u] used! Ignore\n", surfaceId);
+    DALI_ASSERT_DEBUG(0 && "Invalid srufaceId");
+    return 0;
+  }
+
+  return mEglImplementation->GetBufferAge(search->second.surface);
+}
+
+void EglGraphics::SetDamageRegion(Graphics::SurfaceId surfaceId, std::vector<Rect<int>>& damagedRegion)
+{
+  auto search = mSurfaceMap.find(surfaceId);
+  if(DALI_UNLIKELY(search == mSurfaceMap.end()))
+  {
+    DALI_LOG_ERROR("Invalid surface id [%u] used! Ignore\n", surfaceId);
+    DALI_ASSERT_DEBUG(0 && "Invalid srufaceId");
+    return;
+  }
+
+  mEglImplementation->SetDamageRegion(search->second.surface, damagedRegion);
+}
+
+void EglGraphics::SwapBuffers(Graphics::SurfaceId surfaceId)
+{
+  auto search = mSurfaceMap.find(surfaceId);
+  if(DALI_UNLIKELY(search == mSurfaceMap.end()))
+  {
+    DALI_LOG_ERROR("Invalid surface id [%u] used! Ignore\n", surfaceId);
+    DALI_ASSERT_DEBUG(0 && "Invalid srufaceId");
+    return;
+  }
+
+  mEglImplementation->SwapBuffers(search->second.surface);
+}
+
+void EglGraphics::SwapBuffers(Graphics::SurfaceId surfaceId, const std::vector<Rect<int>>& damagedRegion)
+{
+  auto search = mSurfaceMap.find(surfaceId);
+  if(DALI_UNLIKELY(search == mSurfaceMap.end()))
+  {
+    DALI_LOG_ERROR("Invalid surface id [%u] used! Ignore\n", surfaceId);
+    DALI_ASSERT_DEBUG(0 && "Invalid srufaceId");
+    return;
+  }
+
+  mEglImplementation->SwapBuffers(search->second.surface, damagedRegion);
+}
+
+void EglGraphics::Initialize(const Dali::DisplayConnection& displayConnection)
 {
   EglInitialize();
 
   // Sync and context helper require EGL to be initialized first (can't execute in the constructor)
 {
   EglInitialize();
 
   // Sync and context helper require EGL to be initialized first (can't execute in the constructor)
-  mGraphicsController.Initialize(*mEglSync.get(), *mEglContextHelper.get());
+  mGraphicsController.Initialize(*mEglSync.get(), *this);
+  InitializeGraphicsAPI(displayConnection);
 }
 
 }
 
-void EglGraphics::Initialize(bool depth, bool stencil, bool partialRendering, int msaa)
+void EglGraphics::Initialize(const Dali::DisplayConnection& displayConnection, bool depth, bool stencil, bool partialRendering, int msaa)
 {
   mDepthBufferRequired   = static_cast<Integration::DepthBufferAvailable>(depth);
   mStencilBufferRequired = static_cast<Integration::StencilBufferAvailable>(stencil);
 {
   mDepthBufferRequired   = static_cast<Integration::DepthBufferAvailable>(depth);
   mStencilBufferRequired = static_cast<Integration::StencilBufferAvailable>(stencil);
@@ -102,20 +191,88 @@ void EglGraphics::Initialize(bool depth, bool stencil, bool partialRendering, in
   mMultiSamplingLevel    = msaa;
 
   EglInitialize();
   mMultiSamplingLevel    = msaa;
 
   EglInitialize();
+  InitializeGraphicsAPI(displayConnection);
+}
+
+void EglGraphics::InitializeGraphicsAPI(const Dali::DisplayConnection& displayConnection)
+{
+  auto display    = displayConnection.GetNativeGraphicsDisplay();
+  auto eglDisplay = display.Get<EGLNativeDisplayType>();
+  mEglImplementation->InitializeGles(eglDisplay);
+}
+
+Dali::Any EglGraphics::GetDisplay() const
+{
+  return {mEglImplementation->GetDisplay()};
 }
 
 void EglGraphics::EglInitialize()
 {
   mEglSync            = Utils::MakeUnique<EglSyncImplementation>();
 }
 
 void EglGraphics::EglInitialize()
 {
   mEglSync            = Utils::MakeUnique<EglSyncImplementation>();
-  mEglContextHelper   = Utils::MakeUnique<EglContextHelperImplementation>();
   mEglImplementation  = Utils::MakeUnique<EglImplementation>(mMultiSamplingLevel, mDepthBufferRequired, mStencilBufferRequired, mPartialUpdateRequired);
   mEglImageExtensions = Utils::MakeUnique<EglImageExtensions>(mEglImplementation.get());
 
   mEglImplementation  = Utils::MakeUnique<EglImplementation>(mMultiSamplingLevel, mDepthBufferRequired, mStencilBufferRequired, mPartialUpdateRequired);
   mEglImageExtensions = Utils::MakeUnique<EglImageExtensions>(mEglImplementation.get());
 
-  mEglSync->Initialize(mEglImplementation.get());          // The sync impl needs the EglDisplay
-  mEglContextHelper->Initialize(mEglImplementation.get()); // The context helper impl needs the EglContext
+  mEglSync->Initialize(mEglImplementation.get()); // The sync impl needs the EglDisplay
+}
+
+Graphics::SurfaceId EglGraphics::CreateSurface(Graphics::SurfaceFactory* surfaceFactory, WindowBase* windowBase, ColorDepth colorDepth, int width, int height)
+{
+  // Create the OpenGL context for this window
+  mEglImplementation->ChooseConfig(true, colorDepth);
+  EGLContext context = 0;
+  mEglImplementation->CreateWindowContext(context);
+
+  auto window     = windowBase->CreateWindow(width, height);
+  auto eglWindow  = reinterpret_cast<EGLNativeWindowType>(window.Get<void*>());
+  auto eglSurface = mEglImplementation->CreateSurfaceWindow(eglWindow, colorDepth);
+
+  auto surfaceId         = ++mBaseSurfaceId;
+  mSurfaceMap[surfaceId] = EglSurfaceContext{windowBase, eglSurface, context};
+
+  return surfaceId;
 }
 
 }
 
-void EglGraphics::ConfigureSurface(Dali::RenderSurfaceInterface* surface)
+void EglGraphics::DestroySurface(Graphics::SurfaceId surfaceId)
+{
+  auto search = mSurfaceMap.find(surfaceId);
+  if(DALI_UNLIKELY(search == mSurfaceMap.end()))
+  {
+    DALI_LOG_ERROR("Invalid surface id [%u] used! Ignore\n", surfaceId);
+    DALI_ASSERT_DEBUG(0 && "Invalid srufaceId");
+    return;
+  }
+
+  mEglImplementation->DestroySurface(search->second.surface);
+  mEglImplementation->DestroyContext(search->second.context);
+  search->second.windowBase->DestroyWindow();
+  mSurfaceMap.erase(search);
+}
+
+bool EglGraphics::ReplaceSurface(Graphics::SurfaceId surfaceId, int width, int height)
+{
+  auto search = mSurfaceMap.find(surfaceId);
+  if(DALI_UNLIKELY(search == mSurfaceMap.end()))
+  {
+    DALI_LOG_ERROR("Invalid surface id [%u] used! Ignore\n", surfaceId);
+    DALI_ASSERT_DEBUG(0 && "Invalid srufaceId");
+    return false;
+  }
+
+  auto& windowBase = search->second.windowBase;
+
+  // Destroy the old graphics window
+  windowBase->DestroyWindow();
+
+  // Create the EGL window
+  Dali::Any window = windowBase->CreateWindow(width, height);
+
+  EGLNativeWindowType eglWindow = window.Get<EGLNativeWindowType>();
+  auto&               context   = search->second.context;
+  auto&               surface   = search->second.surface;
+  return mEglImplementation->ReplaceSurfaceWindow(eglWindow, surface, context); // Should update the map.
+}
+
+void EglGraphics::ConfigureSurface(Dali::Integration::RenderSurfaceInterface* surface)
 {
   DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
 
 {
   DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
 
@@ -125,7 +282,12 @@ void EglGraphics::ConfigureSurface(Dali::RenderSurfaceInterface* surface)
   if(!mEglImplementation->ChooseConfig(true, COLOR_DEPTH_32))
   {
     // Retry to use OpenGL es 2.0
   if(!mEglImplementation->ChooseConfig(true, COLOR_DEPTH_32))
   {
     // Retry to use OpenGL es 2.0
-    SetGlesVersion(20);
+    mEglImplementation->SetGlesVersion(20);
+
+    // Mark gles that we will use gles 2.0 version.
+    // After this call, we will not change mGLES version anymore.
+    mGLES->SetGlesVersion(20);
+
     mEglImplementation->ChooseConfig(true, COLOR_DEPTH_32);
   }
 
     mEglImplementation->ChooseConfig(true, COLOR_DEPTH_32);
   }
 
@@ -133,25 +295,29 @@ void EglGraphics::ConfigureSurface(Dali::RenderSurfaceInterface* surface)
   bool isSurfacelessContextSupported = mEglImplementation->IsSurfacelessContextSupported();
   SetIsSurfacelessContextSupported(isSurfacelessContextSupported);
 
   bool isSurfacelessContextSupported = mEglImplementation->IsSurfacelessContextSupported();
   SetIsSurfacelessContextSupported(isSurfacelessContextSupported);
 
-  RenderSurfaceInterface* currentSurface = nullptr;
+  Integration::RenderSurfaceInterface* currentSurface = nullptr;
   if(isSurfacelessContextSupported)
   {
     // Create a surfaceless OpenGL context for shared resources
     mEglImplementation->CreateContext();
   if(isSurfacelessContextSupported)
   {
     // Create a surfaceless OpenGL context for shared resources
     mEglImplementation->CreateContext();
-    mEglImplementation->MakeContextCurrent(EGL_NO_SURFACE, mEglImplementation->GetContext());
+    ActivateResourceContext();
   }
   else
   {
     currentSurface = surface;
     if(currentSurface)
     {
   }
   else
   {
     currentSurface = surface;
     if(currentSurface)
     {
-      currentSurface->InitializeGraphics();
-      currentSurface->MakeContextCurrent();
+      ActivateSurfaceContext(currentSurface);
     }
   }
 
     }
   }
 
-  mGLES->ContextCreated();
-  SetGlesVersion(mGLES->GetGlesVersion());
+  mGLES->ContextCreated(); // After this call, we can know exact gles version.
+  auto glesVersion = mGLES->GetGlesVersion();
+
+  // Set more detail GLES version to egl and graphics controller.
+  // Note. usually we don't need EGL client's minor version. So don't need to choose config one more time.
+  mEglImplementation->SetGlesVersion(glesVersion);
+  mGraphicsController.SetGLESVersion(static_cast<Graphics::GLES::GLESVersion>(glesVersion));
 }
 
 void EglGraphics::Shutdown()
 }
 
 void EglGraphics::Shutdown()
@@ -171,11 +337,6 @@ void EglGraphics::Destroy()
   mGraphicsController.Destroy();
 }
 
   mGraphicsController.Destroy();
 }
 
-GlImplementation& EglGraphics::GetGlesInterface()
-{
-  return *mGLES;
-}
-
 Integration::GlAbstraction& EglGraphics::GetGlAbstraction() const
 {
   DALI_ASSERT_DEBUG(mGLES && "GLImplementation not created");
 Integration::GlAbstraction& EglGraphics::GetGlAbstraction() const
 {
   DALI_ASSERT_DEBUG(mGLES && "GLImplementation not created");
@@ -201,12 +362,6 @@ EglSyncImplementation& EglGraphics::GetSyncImplementation()
   return *mEglSync;
 }
 
   return *mEglSync;
 }
 
-EglContextHelperImplementation& EglGraphics::GetContextHelperImplementation()
-{
-  DALI_ASSERT_DEBUG(mEglContextHelper && "EglContextHelperImplementation not created");
-  return *mEglContextHelper;
-}
-
 EglImageExtensions* EglGraphics::GetImageExtensions()
 {
   DALI_ASSERT_DEBUG(mEglImageExtensions && "EglImageExtensions not created");
 EglImageExtensions* EglGraphics::GetImageExtensions()
 {
   DALI_ASSERT_DEBUG(mEglImageExtensions && "EglImageExtensions not created");
@@ -221,9 +376,29 @@ Graphics::Controller& EglGraphics::GetController()
 void EglGraphics::CacheConfigurations(ConfigurationManager& configurationManager)
 {
   mGLES->SetIsAdvancedBlendEquationSupported(configurationManager.IsAdvancedBlendEquationSupported());
 void EglGraphics::CacheConfigurations(ConfigurationManager& configurationManager)
 {
   mGLES->SetIsAdvancedBlendEquationSupported(configurationManager.IsAdvancedBlendEquationSupported());
+  mGLES->SetIsMultisampledRenderToTextureSupported(configurationManager.IsMultisampledRenderToTextureSupported());
   mGLES->SetShadingLanguageVersion(configurationManager.GetShadingLanguageVersion());
 }
 
   mGLES->SetShadingLanguageVersion(configurationManager.GetShadingLanguageVersion());
 }
 
+void EglGraphics::FrameStart()
+{
+  mGraphicsController.FrameStart();
+}
+
+void EglGraphics::PostRenderDebug()
+{
+  mGLES->PostRender();
+}
+
+void EglGraphics::LogMemoryPools()
+{
+  std::size_t graphicsCapacity = mGraphicsController.GetCapacity();
+  DALI_LOG_RELEASE_INFO(
+    "EglGraphics:\n"
+    "  GraphicsController Capacity: %lu\n",
+    graphicsCapacity);
+}
+
 } // namespace Adaptor
 } // namespace Internal
 } // namespace Dali
 } // namespace Adaptor
 } // namespace Internal
 } // namespace Dali