[dali_2.3.23] Merge branch 'devel/master'
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles / egl-graphics.cpp
1 /*
2  * Copyright (c) 2024 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/graphics/gles/egl-graphics.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/integration-api/adaptor-framework/render-surface-interface.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/internal/system/common/configuration-manager.h>
25 #include <dali/internal/system/common/environment-options.h>
26 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
27
28 namespace Dali
29 {
30 namespace Internal
31 {
32 namespace Adaptor
33 {
34 EglGraphics::EglGraphics(EnvironmentOptions& environmentOptions)
35 : mMultiSamplingLevel(0)
36 {
37   mDepthBufferRequired   = static_cast<Integration::DepthBufferAvailable>(environmentOptions.DepthBufferRequired());
38   mStencilBufferRequired = static_cast<Integration::StencilBufferAvailable>(environmentOptions.StencilBufferRequired());
39   mPartialUpdateRequired = static_cast<Integration::PartialUpdateAvailable>(environmentOptions.PartialUpdateRequired());
40   mMultiSamplingLevel    = environmentOptions.GetMultiSamplingLevel();
41
42   if(environmentOptions.GetGlesCallTime() > 0)
43   {
44     mGLES = Utils::MakeUnique<GlProxyImplementation>(environmentOptions);
45   }
46   else
47   {
48     mGLES.reset(new GlImplementation());
49   }
50
51   mGraphicsController.InitializeGLES(*mGLES.get());
52 }
53
54 EglGraphics::~EglGraphics()
55 {
56 }
57
58 void EglGraphics::SetIsSurfacelessContextSupported(const bool isSupported)
59 {
60   mGLES->SetIsSurfacelessContextSupported(isSupported);
61 }
62
63 void EglGraphics::ActivateResourceContext()
64 {
65   if(mEglImplementation && mEglImplementation->IsSurfacelessContextSupported())
66   {
67     // Make the shared surfaceless context as current before rendering
68     mEglImplementation->MakeContextCurrent(EGL_NO_SURFACE, mEglImplementation->GetContext());
69   }
70
71   mGraphicsController.ActivateResourceContext();
72 }
73
74 void EglGraphics::ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface)
75 {
76   if(surface)
77   {
78     surface->InitializeGraphics();
79     surface->MakeContextCurrent();
80   }
81
82   mGraphicsController.ActivateSurfaceContext(surface);
83 }
84
85 void EglGraphics::PostRender()
86 {
87   ActivateResourceContext();
88
89   if(mGraphicsController.GetCurrentContext())
90   {
91     mGraphicsController.GetCurrentContext()->InvalidateDepthStencilBuffers();
92   }
93
94   mGraphicsController.PostRender();
95 }
96
97 void EglGraphics::SetFirstFrameAfterResume()
98 {
99   if(mEglImplementation)
100   {
101     mEglImplementation->SetFirstFrameAfterResume();
102   }
103 }
104
105 void EglGraphics::Initialize()
106 {
107   EglInitialize();
108
109   // Sync and context helper require EGL to be initialized first (can't execute in the constructor)
110   mGraphicsController.Initialize(*mEglSync.get(), *this);
111 }
112
113 void EglGraphics::Initialize(bool depth, bool stencil, bool partialRendering, int msaa)
114 {
115   mDepthBufferRequired   = static_cast<Integration::DepthBufferAvailable>(depth);
116   mStencilBufferRequired = static_cast<Integration::StencilBufferAvailable>(stencil);
117   mPartialUpdateRequired = static_cast<Integration::PartialUpdateAvailable>(partialRendering);
118   mMultiSamplingLevel    = msaa;
119
120   EglInitialize();
121 }
122
123 void EglGraphics::EglInitialize()
124 {
125   mEglSync            = Utils::MakeUnique<EglSyncImplementation>();
126   mEglImplementation  = Utils::MakeUnique<EglImplementation>(mMultiSamplingLevel, mDepthBufferRequired, mStencilBufferRequired, mPartialUpdateRequired);
127   mEglImageExtensions = Utils::MakeUnique<EglImageExtensions>(mEglImplementation.get());
128
129   mEglSync->Initialize(mEglImplementation.get()); // The sync impl needs the EglDisplay
130 }
131
132 void EglGraphics::ConfigureSurface(Dali::RenderSurfaceInterface* surface)
133 {
134   DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
135
136   // Try to use OpenGL es 3.0
137   // ChooseConfig returns false here when the device only support gles 2.0.
138   // Because eglChooseConfig with gles 3.0 setting fails when the device only support gles 2.0 and Our default setting is gles 3.0.
139   if(!mEglImplementation->ChooseConfig(true, COLOR_DEPTH_32))
140   {
141     // Retry to use OpenGL es 2.0
142     mEglImplementation->SetGlesVersion(20);
143
144     // Mark gles that we will use gles 2.0 version.
145     // After this call, we will not change mGLES version anymore.
146     mGLES->SetGlesVersion(20);
147
148     mEglImplementation->ChooseConfig(true, COLOR_DEPTH_32);
149   }
150
151   // Check whether surfaceless context is supported
152   bool isSurfacelessContextSupported = mEglImplementation->IsSurfacelessContextSupported();
153   SetIsSurfacelessContextSupported(isSurfacelessContextSupported);
154
155   RenderSurfaceInterface* currentSurface = nullptr;
156   if(isSurfacelessContextSupported)
157   {
158     // Create a surfaceless OpenGL context for shared resources
159     mEglImplementation->CreateContext();
160     ActivateResourceContext();
161   }
162   else
163   {
164     currentSurface = surface;
165     if(currentSurface)
166     {
167       ActivateSurfaceContext(currentSurface);
168     }
169   }
170
171   mGLES->ContextCreated(); // After this call, we can know exact gles version.
172   auto glesVersion = mGLES->GetGlesVersion();
173
174   // Set more detail GLES version to egl and graphics controller.
175   // Note. usually we don't need EGL client's minor version. So don't need to choose config one more time.
176   mEglImplementation->SetGlesVersion(glesVersion);
177   mGraphicsController.SetGLESVersion(static_cast<Graphics::GLES::GLESVersion>(glesVersion));
178 }
179
180 void EglGraphics::Shutdown()
181 {
182   if(mEglImplementation)
183   {
184     // Shutdown controller
185     mGraphicsController.Shutdown();
186
187     // Terminate GLES
188     mEglImplementation->TerminateGles();
189   }
190 }
191
192 void EglGraphics::Destroy()
193 {
194   mGraphicsController.Destroy();
195 }
196
197 GlImplementation& EglGraphics::GetGlesInterface()
198 {
199   return *mGLES;
200 }
201
202 Integration::GlAbstraction& EglGraphics::GetGlAbstraction() const
203 {
204   DALI_ASSERT_DEBUG(mGLES && "GLImplementation not created");
205   return *mGLES;
206 }
207
208 EglImplementation& EglGraphics::GetEglImplementation() const
209 {
210   DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
211   return *mEglImplementation;
212 }
213
214 EglInterface& EglGraphics::GetEglInterface() const
215 {
216   DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
217   EglInterface* eglInterface = mEglImplementation.get();
218   return *eglInterface;
219 }
220
221 EglSyncImplementation& EglGraphics::GetSyncImplementation()
222 {
223   DALI_ASSERT_DEBUG(mEglSync && "EglSyncImplementation not created");
224   return *mEglSync;
225 }
226
227 EglImageExtensions* EglGraphics::GetImageExtensions()
228 {
229   DALI_ASSERT_DEBUG(mEglImageExtensions && "EglImageExtensions not created");
230   return mEglImageExtensions.get();
231 }
232
233 Graphics::Controller& EglGraphics::GetController()
234 {
235   return mGraphicsController;
236 }
237
238 void EglGraphics::CacheConfigurations(ConfigurationManager& configurationManager)
239 {
240   mGLES->SetIsAdvancedBlendEquationSupported(configurationManager.IsAdvancedBlendEquationSupported());
241   mGLES->SetIsMultisampledRenderToTextureSupported(configurationManager.IsMultisampledRenderToTextureSupported());
242   mGLES->SetShadingLanguageVersion(configurationManager.GetShadingLanguageVersion());
243 }
244
245 void EglGraphics::FrameStart()
246 {
247   mGraphicsController.FrameStart();
248 }
249
250 void EglGraphics::LogMemoryPools()
251 {
252   std::size_t graphicsCapacity = mGraphicsController.GetCapacity();
253   DALI_LOG_RELEASE_INFO(
254     "EglGraphics:\n"
255     "  GraphicsController Capacity: %lu\n",
256     graphicsCapacity);
257 }
258
259 } // namespace Adaptor
260 } // namespace Internal
261 } // namespace Dali