/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
*
*/
-
// CLASS HEADER
#include <dali/internal/graphics/gles/egl-graphics.h>
// INTERNAL INCLUDES
+#include <dali/integration-api/adaptor-framework/render-surface-interface.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
namespace Dali
{
namespace Adaptor
{
-
-EglGraphics::EglGraphics( )
-: mMultiSamplingLevel( 0 )
+EglGraphics::EglGraphics(EnvironmentOptions& environmentOptions)
+: mMultiSamplingLevel(0)
{
+ 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);
+ }
+ else
+ {
+ mGLES.reset(new GlImplementation());
+ }
+
+ mGraphicsController.InitializeGLES(*mGLES.get());
}
EglGraphics::~EglGraphics()
{
}
-void EglGraphics::SetGlesVersion( const int32_t glesVersion )
+void EglGraphics::SetIsSurfacelessContextSupported(const bool isSupported)
{
- mEglImplementation->SetGlesVersion( glesVersion );
- mGLES->SetGlesVersion( glesVersion );
+ mGLES->SetIsSurfacelessContextSupported(isSupported);
}
-void EglGraphics::SetIsSurfacelessContextSupported( const bool isSupported )
+void EglGraphics::ActivateResourceContext()
{
- mGLES->SetIsSurfacelessContextSupported( isSupported );
+ if(mEglImplementation && mEglImplementation->IsSurfacelessContextSupported())
+ {
+ // Make the shared surfaceless context as current before rendering
+ mEglImplementation->MakeContextCurrent(EGL_NO_SURFACE, mEglImplementation->GetContext());
+ }
+
+ mGraphicsController.ActivateResourceContext();
}
-void EglGraphics::Initialize( EnvironmentOptions* environmentOptions )
+void EglGraphics::ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface)
{
- if( environmentOptions->GetGlesCallTime() > 0 )
+ if(surface)
{
- mGLES = Utils::MakeUnique< GlProxyImplementation >( *environmentOptions );
+ surface->InitializeGraphics();
+ surface->MakeContextCurrent();
}
- else
+
+ mGraphicsController.ActivateSurfaceContext(surface);
+}
+
+void EglGraphics::PostRender()
+{
+ ActivateResourceContext();
+
+ if(mGraphicsController.GetCurrentContext())
{
- mGLES.reset ( new GlImplementation() );
+ mGraphicsController.GetCurrentContext()->InvalidateDepthStencilBuffers();
}
- mDepthBufferRequired = static_cast< Integration::DepthBufferAvailable >( environmentOptions->DepthBufferRequired() );
- mStencilBufferRequired = static_cast< Integration::StencilBufferAvailable >( environmentOptions->StencilBufferRequired() );
- mPartialUpdateAvailable = static_cast< Integration::PartialUpdateAvailable >( environmentOptions->PartialUpdateAvailable() );
+ mGraphicsController.PostRender();
+}
- mMultiSamplingLevel = environmentOptions->GetMultiSamplingLevel();
+void EglGraphics::SetFirstFrameAfterResume()
+{
+ if(mEglImplementation)
+ {
+ mEglImplementation->SetFirstFrameAfterResume();
+ }
+}
- mEglSync = Utils::MakeUnique< EglSyncImplementation >();
+void EglGraphics::Initialize()
+{
+ EglInitialize();
- mEglContextHelper = Utils::MakeUnique< EglContextHelperImplementation >();
+ // Sync and context helper require EGL to be initialized first (can't execute in the constructor)
+ mGraphicsController.Initialize(*mEglSync.get(), *mEglContextHelper.get(), *this);
}
-EglInterface* EglGraphics::Create()
+void EglGraphics::Initialize(bool depth, bool stencil, bool partialRendering, int msaa)
{
- mEglImplementation = Utils::MakeUnique< EglImplementation >( mMultiSamplingLevel, mDepthBufferRequired, mStencilBufferRequired, mPartialUpdateAvailable );
- mEglImageExtensions = Utils::MakeUnique< EglImageExtensions >( mEglImplementation.get() );
+ mDepthBufferRequired = static_cast<Integration::DepthBufferAvailable>(depth);
+ mStencilBufferRequired = static_cast<Integration::StencilBufferAvailable>(stencil);
+ mPartialUpdateRequired = static_cast<Integration::PartialUpdateAvailable>(partialRendering);
+ mMultiSamplingLevel = msaa;
- mEglSync->Initialize( mEglImplementation.get() ); // The sync impl needs the EglDisplay
+ EglInitialize();
+}
- mEglContextHelper->Initialize( mEglImplementation.get() ); // The context helper impl needs the EglContext
+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());
- return mEglImplementation.get();
+ mEglSync->Initialize(mEglImplementation.get()); // The sync impl needs the EglDisplay
+ mEglContextHelper->Initialize(mEglImplementation.get()); // The context helper impl needs the EglContext
+}
+
+void EglGraphics::ConfigureSurface(Dali::RenderSurfaceInterface* surface)
+{
+ DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
+
+ // Try to use OpenGL es 3.0
+ // ChooseConfig returns false here when the device only support gles 2.0.
+ // Because eglChooseConfig with gles 3.0 setting fails when the device only support gles 2.0 and Our default setting is gles 3.0.
+ if(!mEglImplementation->ChooseConfig(true, COLOR_DEPTH_32))
+ {
+ // Retry to use OpenGL es 2.0
+ 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);
+ }
+
+ // Check whether surfaceless context is supported
+ bool isSurfacelessContextSupported = mEglImplementation->IsSurfacelessContextSupported();
+ SetIsSurfacelessContextSupported(isSurfacelessContextSupported);
+
+ RenderSurfaceInterface* currentSurface = nullptr;
+ if(isSurfacelessContextSupported)
+ {
+ // Create a surfaceless OpenGL context for shared resources
+ mEglImplementation->CreateContext();
+ ActivateResourceContext();
+ }
+ else
+ {
+ currentSurface = surface;
+ if(currentSurface)
+ {
+ ActivateSurfaceContext(currentSurface);
+ }
+ }
+
+ 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()
+{
+ if(mEglImplementation)
+ {
+ // Shutdown controller
+ mGraphicsController.Shutdown();
+
+ // Terminate GLES
+ mEglImplementation->TerminateGles();
+ }
}
void EglGraphics::Destroy()
{
+ mGraphicsController.Destroy();
}
GlImplementation& EglGraphics::GetGlesInterface()
Integration::GlAbstraction& EglGraphics::GetGlAbstraction() const
{
- DALI_ASSERT_DEBUG( mGLES && "GLImplementation not created" );
+ DALI_ASSERT_DEBUG(mGLES && "GLImplementation not created");
return *mGLES;
}
EglImplementation& EglGraphics::GetEglImplementation() const
{
- DALI_ASSERT_DEBUG( mEglImplementation && "EGLImplementation not created" );
+ DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
return *mEglImplementation;
}
EglInterface& EglGraphics::GetEglInterface() const
{
- DALI_ASSERT_DEBUG( mEglImplementation && "EGLImplementation not created" );
+ DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
EglInterface* eglInterface = mEglImplementation.get();
return *eglInterface;
}
EglSyncImplementation& EglGraphics::GetSyncImplementation()
{
- DALI_ASSERT_DEBUG( mEglSync && "EglSyncImplementation not created" );
+ DALI_ASSERT_DEBUG(mEglSync && "EglSyncImplementation not created");
return *mEglSync;
}
EglContextHelperImplementation& EglGraphics::GetContextHelperImplementation()
{
- DALI_ASSERT_DEBUG( mEglContextHelper && "EglContextHelperImplementation not created" );
+ DALI_ASSERT_DEBUG(mEglContextHelper && "EglContextHelperImplementation not created");
return *mEglContextHelper;
}
EglImageExtensions* EglGraphics::GetImageExtensions()
{
- DALI_ASSERT_DEBUG( mEglImageExtensions && "EglImageExtensions not created" );
+ DALI_ASSERT_DEBUG(mEglImageExtensions && "EglImageExtensions not created");
return mEglImageExtensions.get();
}
-} // Adaptor
-} // Internal
-} // Dali
+Graphics::Controller& EglGraphics::GetController()
+{
+ return mGraphicsController;
+}
+
+void EglGraphics::CacheConfigurations(ConfigurationManager& configurationManager)
+{
+ mGLES->SetIsAdvancedBlendEquationSupported(configurationManager.IsAdvancedBlendEquationSupported());
+ mGLES->SetIsMultisampledRenderToTextureSupported(configurationManager.IsMultisampledRenderToTextureSupported());
+ mGLES->SetShadingLanguageVersion(configurationManager.GetShadingLanguageVersion());
+}
+
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali