15e17f1935abdfa8c5cd8d9fddd5fe33d229fd33
[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/internal/system/common/configuration-manager.h>
24 #include <dali/internal/system/common/environment-options.h>
25 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
26
27 namespace Dali
28 {
29 namespace Internal
30 {
31 namespace Adaptor
32 {
33 EglGraphics::EglGraphics(EnvironmentOptions& environmentOptions)
34 : mMultiSamplingLevel(0)
35 {
36   mDepthBufferRequired   = static_cast<Integration::DepthBufferAvailable>(environmentOptions.DepthBufferRequired());
37   mStencilBufferRequired = static_cast<Integration::StencilBufferAvailable>(environmentOptions.StencilBufferRequired());
38   mPartialUpdateRequired = static_cast<Integration::PartialUpdateAvailable>(environmentOptions.PartialUpdateRequired());
39   mMultiSamplingLevel    = environmentOptions.GetMultiSamplingLevel();
40
41   if(environmentOptions.GetGlesCallTime() > 0)
42   {
43     mGLES = Utils::MakeUnique<GlProxyImplementation>(environmentOptions);
44   }
45   else
46   {
47     mGLES.reset(new GlImplementation());
48   }
49
50   mGraphicsController.InitializeGLES(*mGLES.get());
51 }
52
53 EglGraphics::~EglGraphics()
54 {
55 }
56
57 void EglGraphics::SetGlesVersion(const int32_t glesVersion)
58 {
59   if(mEglImplementation)
60   {
61     mEglImplementation->SetGlesVersion(glesVersion);
62   }
63
64   mGLES->SetGlesVersion(glesVersion);
65
66   mGraphicsController.SetGLESVersion(static_cast<Graphics::GLES::GLESVersion>(glesVersion));
67 }
68
69 void EglGraphics::SetIsSurfacelessContextSupported(const bool isSupported)
70 {
71   mGLES->SetIsSurfacelessContextSupported(isSupported);
72 }
73
74 void EglGraphics::ActivateResourceContext()
75 {
76   if(mEglImplementation && mEglImplementation->IsSurfacelessContextSupported())
77   {
78     // Make the shared surfaceless context as current before rendering
79     mEglImplementation->MakeContextCurrent(EGL_NO_SURFACE, mEglImplementation->GetContext());
80   }
81
82   mGraphicsController.ActivateResourceContext();
83 }
84
85 void EglGraphics::ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface)
86 {
87   if(surface)
88   {
89     surface->InitializeGraphics();
90     surface->MakeContextCurrent();
91   }
92
93   mGraphicsController.ActivateSurfaceContext(surface);
94 }
95
96 void EglGraphics::PostRender()
97 {
98   ActivateResourceContext();
99
100   if(mGraphicsController.GetCurrentContext())
101   {
102     mGraphicsController.GetCurrentContext()->InvalidateDepthStencilBuffers();
103   }
104
105   mGraphicsController.PostRender();
106 }
107
108 void EglGraphics::SetFirstFrameAfterResume()
109 {
110   if(mEglImplementation)
111   {
112     mEglImplementation->SetFirstFrameAfterResume();
113   }
114 }
115
116 void EglGraphics::Initialize()
117 {
118   EglInitialize();
119
120   // Sync and context helper require EGL to be initialized first (can't execute in the constructor)
121   mGraphicsController.Initialize(*mEglSync.get(), *mEglContextHelper.get(), *this);
122 }
123
124 void EglGraphics::Initialize(bool depth, bool stencil, bool partialRendering, int msaa)
125 {
126   mDepthBufferRequired   = static_cast<Integration::DepthBufferAvailable>(depth);
127   mStencilBufferRequired = static_cast<Integration::StencilBufferAvailable>(stencil);
128   mPartialUpdateRequired = static_cast<Integration::PartialUpdateAvailable>(partialRendering);
129   mMultiSamplingLevel    = msaa;
130
131   EglInitialize();
132 }
133
134 void EglGraphics::EglInitialize()
135 {
136   mEglSync            = Utils::MakeUnique<EglSyncImplementation>();
137   mEglContextHelper   = Utils::MakeUnique<EglContextHelperImplementation>();
138   mEglImplementation  = Utils::MakeUnique<EglImplementation>(mMultiSamplingLevel, mDepthBufferRequired, mStencilBufferRequired, mPartialUpdateRequired);
139   mEglImageExtensions = Utils::MakeUnique<EglImageExtensions>(mEglImplementation.get());
140
141   mEglSync->Initialize(mEglImplementation.get());          // The sync impl needs the EglDisplay
142   mEglContextHelper->Initialize(mEglImplementation.get()); // The context helper impl needs the EglContext
143 }
144
145 void EglGraphics::ConfigureSurface(Dali::RenderSurfaceInterface* surface)
146 {
147   DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
148
149   // Try to use OpenGL es 3.0
150   // ChooseConfig returns false here when the device only support gles 2.0.
151   // Because eglChooseConfig with gles 3.0 setting fails when the device only support gles 2.0 and Our default setting is gles 3.0.
152   if(!mEglImplementation->ChooseConfig(true, COLOR_DEPTH_32))
153   {
154     // Retry to use OpenGL es 2.0
155     SetGlesVersion(20);
156     mEglImplementation->ChooseConfig(true, COLOR_DEPTH_32);
157   }
158
159   // Check whether surfaceless context is supported
160   bool isSurfacelessContextSupported = mEglImplementation->IsSurfacelessContextSupported();
161   SetIsSurfacelessContextSupported(isSurfacelessContextSupported);
162
163   RenderSurfaceInterface* currentSurface = nullptr;
164   if(isSurfacelessContextSupported)
165   {
166     // Create a surfaceless OpenGL context for shared resources
167     mEglImplementation->CreateContext();
168     ActivateResourceContext();
169   }
170   else
171   {
172     currentSurface = surface;
173     if(currentSurface)
174     {
175       ActivateSurfaceContext(currentSurface);
176     }
177   }
178
179   mGLES->ContextCreated();
180   SetGlesVersion(mGLES->GetGlesVersion());
181 }
182
183 void EglGraphics::Shutdown()
184 {
185   if(mEglImplementation)
186   {
187     // Shutdown controller
188     mGraphicsController.Shutdown();
189
190     // Terminate GLES
191     mEglImplementation->TerminateGles();
192   }
193 }
194
195 void EglGraphics::Destroy()
196 {
197   mGraphicsController.Destroy();
198 }
199
200 GlImplementation& EglGraphics::GetGlesInterface()
201 {
202   return *mGLES;
203 }
204
205 Integration::GlAbstraction& EglGraphics::GetGlAbstraction() const
206 {
207   DALI_ASSERT_DEBUG(mGLES && "GLImplementation not created");
208   return *mGLES;
209 }
210
211 EglImplementation& EglGraphics::GetEglImplementation() const
212 {
213   DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
214   return *mEglImplementation;
215 }
216
217 EglInterface& EglGraphics::GetEglInterface() const
218 {
219   DALI_ASSERT_ALWAYS(mEglImplementation && "EGLImplementation not created");
220   EglInterface* eglInterface = mEglImplementation.get();
221   return *eglInterface;
222 }
223
224 EglSyncImplementation& EglGraphics::GetSyncImplementation()
225 {
226   DALI_ASSERT_DEBUG(mEglSync && "EglSyncImplementation not created");
227   return *mEglSync;
228 }
229
230 EglContextHelperImplementation& EglGraphics::GetContextHelperImplementation()
231 {
232   DALI_ASSERT_DEBUG(mEglContextHelper && "EglContextHelperImplementation not created");
233   return *mEglContextHelper;
234 }
235
236 EglImageExtensions* EglGraphics::GetImageExtensions()
237 {
238   DALI_ASSERT_DEBUG(mEglImageExtensions && "EglImageExtensions not created");
239   return mEglImageExtensions.get();
240 }
241
242 Graphics::Controller& EglGraphics::GetController()
243 {
244   return mGraphicsController;
245 }
246
247 void EglGraphics::CacheConfigurations(ConfigurationManager& configurationManager)
248 {
249   mGLES->SetIsAdvancedBlendEquationSupported(configurationManager.IsAdvancedBlendEquationSupported());
250   mGLES->SetIsMultisampledRenderToTextureSupported(configurationManager.IsMultisampledRenderToTextureSupported());
251   mGLES->SetShadingLanguageVersion(configurationManager.GetShadingLanguageVersion());
252 }
253
254 } // namespace Adaptor
255 } // namespace Internal
256 } // namespace Dali