Memory Pool Logging
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles / egl-graphics.cpp
1 /*
2  * Copyright (c) 2022 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::SetGlesVersion(const int32_t glesVersion)
59 {
60   if(mEglImplementation)
61   {
62     mEglImplementation->SetGlesVersion(glesVersion);
63   }
64
65   mGLES->SetGlesVersion(glesVersion);
66
67   mGraphicsController.SetGLESVersion(static_cast<Graphics::GLES::GLESVersion>(glesVersion));
68 }
69
70 void EglGraphics::SetIsSurfacelessContextSupported(const bool isSupported)
71 {
72   mGLES->SetIsSurfacelessContextSupported(isSupported);
73 }
74
75 void EglGraphics::ActivateResourceContext()
76 {
77   if(mEglImplementation && mEglImplementation->IsSurfacelessContextSupported())
78   {
79     // Make the shared surfaceless context as current before rendering
80     mEglImplementation->MakeContextCurrent(EGL_NO_SURFACE, mEglImplementation->GetContext());
81   }
82
83   mGraphicsController.ActivateResourceContext();
84 }
85
86 void EglGraphics::ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface)
87 {
88   if(surface)
89   {
90     surface->InitializeGraphics();
91     surface->MakeContextCurrent();
92   }
93
94   mGraphicsController.ActivateSurfaceContext(surface);
95 }
96
97 void EglGraphics::PostRender()
98 {
99   ActivateResourceContext();
100
101   if(mGraphicsController.GetCurrentContext())
102   {
103     mGraphicsController.GetCurrentContext()->InvalidateDepthStencilBuffers();
104   }
105
106   mGraphicsController.PostRender();
107 }
108
109 void EglGraphics::SetFirstFrameAfterResume()
110 {
111   if(mEglImplementation)
112   {
113     mEglImplementation->SetFirstFrameAfterResume();
114   }
115 }
116
117 void EglGraphics::Initialize()
118 {
119   EglInitialize();
120
121   // Sync and context helper require EGL to be initialized first (can't execute in the constructor)
122   mGraphicsController.Initialize(*mEglSync.get(), *mEglContextHelper.get(), *this);
123 }
124
125 void EglGraphics::Initialize(bool depth, bool stencil, bool partialRendering, int msaa)
126 {
127   mDepthBufferRequired   = static_cast<Integration::DepthBufferAvailable>(depth);
128   mStencilBufferRequired = static_cast<Integration::StencilBufferAvailable>(stencil);
129   mPartialUpdateRequired = static_cast<Integration::PartialUpdateAvailable>(partialRendering);
130   mMultiSamplingLevel    = msaa;
131
132   EglInitialize();
133 }
134
135 void EglGraphics::EglInitialize()
136 {
137   mEglSync            = Utils::MakeUnique<EglSyncImplementation>();
138   mEglContextHelper   = Utils::MakeUnique<EglContextHelperImplementation>();
139   mEglImplementation  = Utils::MakeUnique<EglImplementation>(mMultiSamplingLevel, mDepthBufferRequired, mStencilBufferRequired, mPartialUpdateRequired);
140   mEglImageExtensions = Utils::MakeUnique<EglImageExtensions>(mEglImplementation.get());
141
142   mEglSync->Initialize(mEglImplementation.get());          // The sync impl needs the EglDisplay
143   mEglContextHelper->Initialize(mEglImplementation.get()); // The context helper impl needs the EglContext
144 }
145
146 void EglGraphics::ConfigureSurface(Dali::RenderSurfaceInterface* surface)
147 {
148   DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
149
150   // Try to use OpenGL es 3.0
151   // ChooseConfig returns false here when the device only support gles 2.0.
152   // Because eglChooseConfig with gles 3.0 setting fails when the device only support gles 2.0 and Our default setting is gles 3.0.
153   if(!mEglImplementation->ChooseConfig(true, COLOR_DEPTH_32))
154   {
155     // Retry to use OpenGL es 2.0
156     SetGlesVersion(20);
157     mEglImplementation->ChooseConfig(true, COLOR_DEPTH_32);
158   }
159
160   // Check whether surfaceless context is supported
161   bool isSurfacelessContextSupported = mEglImplementation->IsSurfacelessContextSupported();
162   SetIsSurfacelessContextSupported(isSurfacelessContextSupported);
163
164   RenderSurfaceInterface* currentSurface = nullptr;
165   if(isSurfacelessContextSupported)
166   {
167     // Create a surfaceless OpenGL context for shared resources
168     mEglImplementation->CreateContext();
169     ActivateResourceContext();
170   }
171   else
172   {
173     currentSurface = surface;
174     if(currentSurface)
175     {
176       ActivateSurfaceContext(currentSurface);
177     }
178   }
179
180   mGLES->ContextCreated();
181   SetGlesVersion(mGLES->GetGlesVersion());
182 }
183
184 void EglGraphics::Shutdown()
185 {
186   if(mEglImplementation)
187   {
188     // Shutdown controller
189     mGraphicsController.Shutdown();
190
191     // Terminate GLES
192     mEglImplementation->TerminateGles();
193   }
194 }
195
196 void EglGraphics::Destroy()
197 {
198   mGraphicsController.Destroy();
199 }
200
201 GlImplementation& EglGraphics::GetGlesInterface()
202 {
203   return *mGLES;
204 }
205
206 Integration::GlAbstraction& EglGraphics::GetGlAbstraction() const
207 {
208   DALI_ASSERT_DEBUG(mGLES && "GLImplementation not created");
209   return *mGLES;
210 }
211
212 EglImplementation& EglGraphics::GetEglImplementation() const
213 {
214   DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
215   return *mEglImplementation;
216 }
217
218 EglInterface& EglGraphics::GetEglInterface() const
219 {
220   DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
221   EglInterface* eglInterface = mEglImplementation.get();
222   return *eglInterface;
223 }
224
225 EglSyncImplementation& EglGraphics::GetSyncImplementation()
226 {
227   DALI_ASSERT_DEBUG(mEglSync && "EglSyncImplementation not created");
228   return *mEglSync;
229 }
230
231 EglContextHelperImplementation& EglGraphics::GetContextHelperImplementation()
232 {
233   DALI_ASSERT_DEBUG(mEglContextHelper && "EglContextHelperImplementation not created");
234   return *mEglContextHelper;
235 }
236
237 EglImageExtensions* EglGraphics::GetImageExtensions()
238 {
239   DALI_ASSERT_DEBUG(mEglImageExtensions && "EglImageExtensions not created");
240   return mEglImageExtensions.get();
241 }
242
243 Graphics::Controller& EglGraphics::GetController()
244 {
245   return mGraphicsController;
246 }
247
248 void EglGraphics::CacheConfigurations(ConfigurationManager& configurationManager)
249 {
250   mGLES->SetIsAdvancedBlendEquationSupported(configurationManager.IsAdvancedBlendEquationSupported());
251   mGLES->SetIsMultisampledRenderToTextureSupported(configurationManager.IsMultisampledRenderToTextureSupported());
252   mGLES->SetShadingLanguageVersion(configurationManager.GetShadingLanguageVersion());
253 }
254
255 void EglGraphics::FrameStart()
256 {
257   mGraphicsController.FrameStart();
258 }
259
260 void EglGraphics::LogMemoryPools()
261 {
262   std::size_t graphicsCapacity = mGraphicsController.GetCapacity();
263   DALI_LOG_RELEASE_INFO(
264     "EglGraphics:\n"
265     "  GraphicsController Capacity: %lu\n",
266     graphicsCapacity);
267 }
268
269 } // namespace Adaptor
270 } // namespace Internal
271 } // namespace Dali