DALi Version 2.1.15
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles / egl-implementation.cpp
1 /*
2  * Copyright (c) 2021 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-implementation.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <dali/public-api/common/dali-vector.h>
24 #include <sstream>
25
26 // INTERNAL INCLUDES
27 #include <dali/internal/graphics/gles/egl-debug.h>
28 #include <dali/internal/graphics/gles/gl-implementation.h>
29 #include <dali/public-api/dali-adaptor-common.h>
30
31 // EGL constants use C style casts
32 #pragma GCC diagnostic push
33 #pragma GCC diagnostic ignored "-Wold-style-cast"
34
35 namespace
36 {
37 const uint32_t    THRESHOLD_SWAPBUFFER_COUNT              = 5;
38 const uint32_t    CHECK_EXTENSION_NUMBER                  = 4;
39 const uint32_t    EGL_VERSION_SUPPORT_SURFACELESS_CONTEXT = 15;
40 const std::string EGL_KHR_SURFACELESS_CONTEXT             = "EGL_KHR_surfaceless_context";
41 const std::string EGL_KHR_CREATE_CONTEXT                  = "EGL_KHR_create_context";
42 const std::string EGL_KHR_PARTIAL_UPDATE                  = "EGL_KHR_partial_update";
43 const std::string EGL_KHR_SWAP_BUFFERS_WITH_DAMAGE        = "EGL_KHR_swap_buffers_with_damage";
44
45 } // namespace
46
47 namespace Dali
48 {
49 namespace Internal
50 {
51 namespace Adaptor
52 {
53 #define TEST_EGL_ERROR(lastCommand)                        \
54   {                                                        \
55     EGLint err = eglGetError();                            \
56     if(err != EGL_SUCCESS)                                 \
57     {                                                      \
58       DALI_LOG_ERROR("EGL error after %s\n", lastCommand); \
59       Egl::PrintError(err);                                \
60       DALI_ASSERT_ALWAYS(0 && "EGL error");                \
61     }                                                      \
62   }
63
64 EglImplementation::EglImplementation(int                                 multiSamplingLevel,
65                                      Integration::DepthBufferAvailable   depthBufferRequired,
66                                      Integration::StencilBufferAvailable stencilBufferRequired,
67                                      Integration::PartialUpdateAvailable partialUpdateRequired)
68 : mContextAttribs(),
69   mEglNativeDisplay(0),
70   mEglNativeWindow(0),
71   mCurrentEglNativePixmap(0),
72   mEglDisplay(0),
73   mEglConfig(0),
74   mEglContext(0),
75   mCurrentEglSurface(0),
76   mCurrentEglContext(EGL_NO_CONTEXT),
77   mMultiSamplingLevel(multiSamplingLevel),
78   mGlesVersion(30),
79   mColorDepth(COLOR_DEPTH_24),
80   mGlesInitialized(false),
81   mIsOwnSurface(true),
82   mIsWindow(true),
83   mDepthBufferRequired(depthBufferRequired == Integration::DepthBufferAvailable::TRUE),
84   mStencilBufferRequired(stencilBufferRequired == Integration::StencilBufferAvailable::TRUE),
85   mPartialUpdateRequired(partialUpdateRequired == Integration::PartialUpdateAvailable::TRUE),
86   mIsSurfacelessContextSupported(false),
87   mIsKhrCreateContextSupported(false),
88   mSwapBufferCountAfterResume(0),
89   mEglSetDamageRegionKHR(0),
90   mEglSwapBuffersWithDamageKHR(0)
91 {
92 }
93
94 EglImplementation::~EglImplementation()
95 {
96   TerminateGles();
97 }
98
99 bool EglImplementation::InitializeGles(EGLNativeDisplayType display, bool isOwnSurface)
100 {
101   if(!mGlesInitialized)
102   {
103     mEglNativeDisplay = display;
104
105     // Try to get the display connection for the native display first
106     mEglDisplay = eglGetDisplay(mEglNativeDisplay);
107
108     if(mEglDisplay == EGL_NO_DISPLAY)
109     {
110       // If failed, try to get the default display connection
111       mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
112     }
113
114     if(mEglDisplay == EGL_NO_DISPLAY)
115     {
116       // Still failed to get a display connection
117       throw Dali::DaliException("", "OpenGL ES is not supported");
118     }
119
120     EGLint majorVersion = 0;
121     EGLint minorVersion = 0;
122     if(!eglInitialize(mEglDisplay, &majorVersion, &minorVersion))
123     {
124       return false;
125     }
126     eglBindAPI(EGL_OPENGL_ES_API);
127
128     mIsOwnSurface = isOwnSurface;
129   }
130
131   const char* const versionStr   = eglQueryString(mEglDisplay, EGL_VERSION);
132   const char* const extensionStr = eglQueryString(mEglDisplay, EGL_EXTENSIONS);
133
134   // Query EGL extensions to check whether required extensions are supported
135   std::istringstream versionStream(versionStr);
136   std::string        majorVersion, minorVersion;
137   std::getline(versionStream, majorVersion, '.');
138   std::getline(versionStream, minorVersion);
139   uint32_t extensionCheckCount = 0;
140   if(stoul(majorVersion) * 10 + stoul(minorVersion) >= EGL_VERSION_SUPPORT_SURFACELESS_CONTEXT)
141   {
142     mIsSurfacelessContextSupported = true;
143     mIsKhrCreateContextSupported   = true;
144     extensionCheckCount += 2;
145   }
146
147   std::istringstream stream(extensionStr);
148   std::string        currentExtension;
149   bool               isKhrPartialUpdateSupported         = false;
150   bool               isKhrSwapBuffersWithDamageSupported = false;
151   while(std::getline(stream, currentExtension, ' ') && extensionCheckCount < CHECK_EXTENSION_NUMBER)
152   {
153     if(currentExtension == EGL_KHR_SURFACELESS_CONTEXT && !mIsSurfacelessContextSupported)
154     {
155       mIsSurfacelessContextSupported = true;
156       extensionCheckCount++;
157     }
158     if(currentExtension == EGL_KHR_CREATE_CONTEXT && !mIsKhrCreateContextSupported)
159     {
160       mIsKhrCreateContextSupported = true;
161       extensionCheckCount++;
162     }
163     if(currentExtension == EGL_KHR_PARTIAL_UPDATE)
164     {
165       isKhrPartialUpdateSupported = true;
166       extensionCheckCount++;
167     }
168     if(currentExtension == EGL_KHR_SWAP_BUFFERS_WITH_DAMAGE)
169     {
170       isKhrSwapBuffersWithDamageSupported = true;
171       extensionCheckCount++;
172     }
173   }
174
175   if(!isKhrPartialUpdateSupported || !isKhrSwapBuffersWithDamageSupported)
176   {
177     mPartialUpdateRequired = false;
178   }
179
180   mGlesInitialized = true;
181
182   // We want to display this information all the time, so use the LogMessage directly
183   Integration::Log::LogMessage(Integration::Log::DebugInfo,
184                                "EGL Information\n"
185                                "            PartialUpdate  %d\n"
186                                "            Vendor:        %s\n"
187                                "            Version:       %s\n"
188                                "            Client APIs:   %s\n"
189                                "            Extensions:    %s\n",
190                                mPartialUpdateRequired,
191                                eglQueryString(mEglDisplay, EGL_VENDOR),
192                                versionStr,
193                                eglQueryString(mEglDisplay, EGL_CLIENT_APIS),
194                                extensionStr);
195
196   return mGlesInitialized;
197 }
198
199 bool EglImplementation::CreateContext()
200 {
201   // make sure a context isn't created twice
202   DALI_ASSERT_ALWAYS((mEglContext == 0) && "EGL context recreated");
203
204   mEglContext = eglCreateContext(mEglDisplay, mEglConfig, NULL, &(mContextAttribs[0]));
205   TEST_EGL_ERROR("eglCreateContext render thread");
206
207   DALI_ASSERT_ALWAYS(EGL_NO_CONTEXT != mEglContext && "EGL context not created");
208
209   DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VENDOR : %s ***\n", glGetString(GL_VENDOR));
210   DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_RENDERER : %s ***\n", glGetString(GL_RENDERER));
211   DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VERSION : %s ***\n", glGetString(GL_VERSION));
212   DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_SHADING_LANGUAGE_VERSION : %s***\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
213   DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** Supported Extensions ***\n%s\n\n", glGetString(GL_EXTENSIONS));
214
215   mEglSetDamageRegionKHR = reinterpret_cast<PFNEGLSETDAMAGEREGIONKHRPROC>(eglGetProcAddress("eglSetDamageRegionKHR"));
216   if(!mEglSetDamageRegionKHR)
217   {
218     DALI_LOG_ERROR("Coudn't find eglSetDamageRegionKHR!\n");
219     mPartialUpdateRequired = false;
220   }
221   mEglSwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC>(eglGetProcAddress("eglSwapBuffersWithDamageKHR"));
222   if(!mEglSwapBuffersWithDamageKHR)
223   {
224     DALI_LOG_ERROR("Coudn't find eglSwapBuffersWithDamageKHR!\n");
225     mPartialUpdateRequired = false;
226   }
227   return true;
228 }
229
230 bool EglImplementation::CreateWindowContext(EGLContext& eglContext)
231 {
232   // make sure a context isn't created twice
233   DALI_ASSERT_ALWAYS((eglContext == 0) && "EGL context recreated");
234
235   eglContext = eglCreateContext(mEglDisplay, mEglConfig, mEglContext, &(mContextAttribs[0]));
236   TEST_EGL_ERROR("eglCreateContext render thread");
237
238   DALI_ASSERT_ALWAYS(EGL_NO_CONTEXT != eglContext && "EGL context not created");
239
240   DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VENDOR : %s ***\n", glGetString(GL_VENDOR));
241   DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_RENDERER : %s ***\n", glGetString(GL_RENDERER));
242   DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VERSION : %s ***\n", glGetString(GL_VERSION));
243   DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_SHADING_LANGUAGE_VERSION : %s***\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
244   DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** Supported Extensions ***\n%s\n\n", glGetString(GL_EXTENSIONS));
245
246   mEglWindowContexts.push_back(eglContext);
247
248   mEglSetDamageRegionKHR = reinterpret_cast<PFNEGLSETDAMAGEREGIONKHRPROC>(eglGetProcAddress("eglSetDamageRegionKHR"));
249   if(!mEglSetDamageRegionKHR)
250   {
251     DALI_LOG_ERROR("Coudn't find eglSetDamageRegionKHR!\n");
252     mPartialUpdateRequired = false;
253   }
254   mEglSwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC>(eglGetProcAddress("eglSwapBuffersWithDamageKHR"));
255   if(!mEglSwapBuffersWithDamageKHR)
256   {
257     DALI_LOG_ERROR("Coudn't find eglSwapBuffersWithDamageKHR!\n");
258     mPartialUpdateRequired = false;
259   }
260   return true;
261 }
262
263 void EglImplementation::DestroyContext(EGLContext& eglContext)
264 {
265   if(eglContext)
266   {
267     eglDestroyContext(mEglDisplay, eglContext);
268     eglContext = 0;
269   }
270 }
271
272 void EglImplementation::DestroySurface(EGLSurface& eglSurface)
273 {
274   if(mIsOwnSurface && eglSurface)
275   {
276     // Make context null to prevent crash in driver side
277     MakeContextNull();
278     eglDestroySurface(mEglDisplay, eglSurface);
279     eglSurface = 0;
280   }
281 }
282
283 void EglImplementation::MakeContextCurrent(EGLSurface eglSurface, EGLContext eglContext)
284 {
285   if(mCurrentEglContext == eglContext)
286   {
287     return;
288   }
289
290   mCurrentEglSurface = eglSurface;
291
292   if(mIsOwnSurface)
293   {
294     eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, eglContext);
295
296     mCurrentEglContext = eglContext;
297   }
298
299   EGLint error = eglGetError();
300
301   if(error != EGL_SUCCESS)
302   {
303     Egl::PrintError(error);
304
305     DALI_ASSERT_ALWAYS(false && "MakeContextCurrent failed!");
306   }
307 }
308
309 void EglImplementation::MakeCurrent(EGLNativePixmapType pixmap, EGLSurface eglSurface)
310 {
311   if(mCurrentEglContext == mEglContext)
312   {
313     return;
314   }
315
316   mCurrentEglNativePixmap = pixmap;
317   mCurrentEglSurface      = eglSurface;
318
319   if(mIsOwnSurface)
320   {
321     eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext);
322
323     mCurrentEglContext = mEglContext;
324   }
325
326   EGLint error = eglGetError();
327
328   if(error != EGL_SUCCESS)
329   {
330     Egl::PrintError(error);
331
332     DALI_ASSERT_ALWAYS(false && "MakeCurrent failed!");
333   }
334 }
335
336 void EglImplementation::MakeContextNull()
337 {
338   // clear the current context
339   eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
340   mCurrentEglContext = EGL_NO_CONTEXT;
341 }
342
343 void EglImplementation::TerminateGles()
344 {
345   if(mGlesInitialized)
346   {
347     // Make context null to prevent crash in driver side
348     MakeContextNull();
349
350     for(auto eglSurface : mEglWindowSurfaces)
351     {
352       if(mIsOwnSurface && eglSurface)
353       {
354         eglDestroySurface(mEglDisplay, eglSurface);
355       }
356     }
357     eglDestroyContext(mEglDisplay, mEglContext);
358     for(auto eglContext : mEglWindowContexts)
359     {
360       eglDestroyContext(mEglDisplay, eglContext);
361     }
362
363     eglTerminate(mEglDisplay);
364
365     mEglDisplay        = NULL;
366     mEglConfig         = NULL;
367     mEglContext        = NULL;
368     mCurrentEglSurface = NULL;
369     mCurrentEglContext = EGL_NO_CONTEXT;
370
371     mGlesInitialized = false;
372   }
373 }
374
375 bool EglImplementation::IsGlesInitialized() const
376 {
377   return mGlesInitialized;
378 }
379
380 void EglImplementation::SwapBuffers(EGLSurface& eglSurface)
381 {
382   if(eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
383   {
384 #ifndef DALI_PROFILE_UBUNTU
385     if(mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT)
386     {
387       DALI_LOG_RELEASE_INFO("EglImplementation::eglSwapBuffers started. eglSurface(%p)\n", eglSurface);
388     }
389 #endif //DALI_PROFILE_UBUNTU
390
391     // DALI_LOG_ERROR("EglImplementation::SwapBuffers()\n");
392     eglSwapBuffers(mEglDisplay, eglSurface);
393
394 #ifndef DALI_PROFILE_UBUNTU
395     if(mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT)
396     {
397       DALI_LOG_RELEASE_INFO("EglImplementation::eglSwapBuffers finished.\n");
398       mSwapBufferCountAfterResume++;
399     }
400 #endif //DALI_PROFILE_UBUNTU
401   }
402 }
403
404 EGLint EglImplementation::GetBufferAge(EGLSurface& eglSurface) const
405 {
406   EGLint age = 0;
407   eglQuerySurface(mEglDisplay, eglSurface, EGL_BUFFER_AGE_EXT, &age);
408   if(age < 0)
409   {
410     DALI_LOG_ERROR("eglQuerySurface(%d)\n", eglGetError());
411     age = 0;
412   }
413
414   // 0 - invalid buffer
415   // 1, 2, 3
416   if(age > 3)
417   {
418     DALI_LOG_ERROR("EglImplementation::GetBufferAge() buffer age %d > 3\n", age);
419     age = 0; // shoudn't be more than 3 back buffers, if there is just reset, I don't want to add extra history level
420   }
421
422   return age;
423 }
424
425 void EglImplementation::SetDamageRegion(EGLSurface& eglSurface, std::vector<Rect<int>>& damagedRects)
426 {
427   if(!mPartialUpdateRequired)
428   {
429     return;
430   }
431
432   if(eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
433   {
434     EGLBoolean result = mEglSetDamageRegionKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(damagedRects.data()), 1);
435     if(result == EGL_FALSE)
436     {
437       DALI_LOG_ERROR("eglSetDamageRegionKHR(%d)\n", eglGetError());
438     }
439   }
440 }
441
442 void EglImplementation::SwapBuffers(EGLSurface& eglSurface, const std::vector<Rect<int>>& damagedRects)
443 {
444   if(eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
445   {
446     if(!mPartialUpdateRequired)
447     {
448       SwapBuffers(eglSurface);
449       return;
450     }
451
452 #ifndef DALI_PROFILE_UBUNTU
453     if(mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT)
454     {
455       DALI_LOG_RELEASE_INFO("EglImplementation::eglSwapBuffersWithDamageKHR started. eglSurface(%p)\n", eglSurface);
456     }
457 #endif //DALI_PROFILE_UBUNTU
458
459     EGLBoolean result = mEglSwapBuffersWithDamageKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(const_cast<std::vector<Rect<int>>&>(damagedRects).data()), damagedRects.size());
460     if(result == EGL_FALSE)
461     {
462       DALI_LOG_ERROR("eglSwapBuffersWithDamageKHR(%d)\n", eglGetError());
463     }
464
465 #ifndef DALI_PROFILE_UBUNTU
466     if(mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT)
467     {
468       DALI_LOG_RELEASE_INFO("EglImplementation::eglSwapBuffersWithDamageKHR finished.\n");
469       mSwapBufferCountAfterResume++;
470     }
471 #endif //DALI_PROFILE_UBUNTU
472   }
473 }
474
475 void EglImplementation::CopyBuffers(EGLSurface& eglSurface)
476 {
477   eglCopyBuffers(mEglDisplay, eglSurface, mCurrentEglNativePixmap);
478 }
479
480 void EglImplementation::WaitGL()
481 {
482   eglWaitGL();
483 }
484
485 bool EglImplementation::ChooseConfig(bool isWindowType, ColorDepth depth)
486 {
487   if(mEglConfig && isWindowType == mIsWindow && mColorDepth == depth)
488   {
489     return true;
490   }
491
492   mColorDepth = depth;
493   mIsWindow   = isWindowType;
494
495   EGLint         numConfigs;
496   Vector<EGLint> configAttribs;
497   configAttribs.Reserve(31);
498
499   if(isWindowType)
500   {
501     configAttribs.PushBack(EGL_SURFACE_TYPE);
502     configAttribs.PushBack(EGL_WINDOW_BIT);
503   }
504   else
505   {
506     configAttribs.PushBack(EGL_SURFACE_TYPE);
507     configAttribs.PushBack(EGL_PIXMAP_BIT);
508   }
509
510   configAttribs.PushBack(EGL_RENDERABLE_TYPE);
511
512   if(mGlesVersion >= 30)
513   {
514     configAttribs.PushBack(EGL_OPENGL_ES3_BIT_KHR);
515   }
516   else
517   {
518     configAttribs.PushBack(EGL_OPENGL_ES2_BIT);
519   }
520
521   // TODO: enable this flag when it becomes supported
522   //  configAttribs.PushBack( EGL_CONTEXT_FLAGS_KHR );
523   //  configAttribs.PushBack( EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR );
524
525   configAttribs.PushBack(EGL_RED_SIZE);
526   configAttribs.PushBack(8);
527   configAttribs.PushBack(EGL_GREEN_SIZE);
528   configAttribs.PushBack(8);
529   configAttribs.PushBack(EGL_BLUE_SIZE);
530   configAttribs.PushBack(8);
531
532   //  For underlay video playback, we also need to set the alpha value of the 24/32bit window.
533   // TODO: When the tbm queue of GlView is 24bit, do we have to set the alpha size??
534   configAttribs.PushBack(EGL_ALPHA_SIZE);
535   configAttribs.PushBack(8);
536
537   configAttribs.PushBack(EGL_DEPTH_SIZE);
538   configAttribs.PushBack(mDepthBufferRequired ? 24 : 0);
539   configAttribs.PushBack(EGL_STENCIL_SIZE);
540   configAttribs.PushBack(mStencilBufferRequired ? 8 : 0);
541
542 #ifndef DALI_PROFILE_UBUNTU
543   if(mMultiSamplingLevel != EGL_DONT_CARE)
544   {
545     configAttribs.PushBack(EGL_SAMPLES);
546     configAttribs.PushBack(mMultiSamplingLevel);
547     configAttribs.PushBack(EGL_SAMPLE_BUFFERS);
548     configAttribs.PushBack(1);
549   }
550 #endif // DALI_PROFILE_UBUNTU
551   configAttribs.PushBack(EGL_NONE);
552
553   // Ensure number of configs is set to 1 as on some drivers,
554   // eglChooseConfig succeeds but does not actually create a proper configuration.
555   if((eglChooseConfig(mEglDisplay, &(configAttribs[0]), &mEglConfig, 1, &numConfigs) != EGL_TRUE) ||
556      (numConfigs != 1))
557   {
558     if(mGlesVersion >= 30)
559     {
560       mEglConfig = NULL;
561       DALI_LOG_ERROR("Fail to use OpenGL es 3.0. Retrying to use OpenGL es 2.0.");
562       return false;
563     }
564
565     if(numConfigs != 1)
566     {
567       DALI_LOG_ERROR("No configurations found.\n");
568
569       TEST_EGL_ERROR("eglChooseConfig");
570     }
571
572     EGLint error = eglGetError();
573     switch(error)
574     {
575       case EGL_BAD_DISPLAY:
576       {
577         DALI_LOG_ERROR("Display is not an EGL display connection\n");
578         break;
579       }
580       case EGL_BAD_ATTRIBUTE:
581       {
582         DALI_LOG_ERROR("The parameter configAttribs contains an invalid frame buffer configuration attribute or an attribute value that is unrecognized or out of range\n");
583         break;
584       }
585       case EGL_NOT_INITIALIZED:
586       {
587         DALI_LOG_ERROR("Display has not been initialized\n");
588         break;
589       }
590       case EGL_BAD_PARAMETER:
591       {
592         DALI_LOG_ERROR("The parameter numConfig is NULL\n");
593         break;
594       }
595       default:
596       {
597         DALI_LOG_ERROR("Unknown error.\n");
598       }
599     }
600     DALI_ASSERT_ALWAYS(false && "eglChooseConfig failed!");
601     return false;
602   }
603   Integration::Log::LogMessage(Integration::Log::DebugInfo, "Using OpenGL es %d.%d.\n", mGlesVersion / 10, mGlesVersion % 10);
604
605   mContextAttribs.Clear();
606   if(mIsKhrCreateContextSupported)
607   {
608     mContextAttribs.Reserve(5);
609     mContextAttribs.PushBack(EGL_CONTEXT_MAJOR_VERSION_KHR);
610     mContextAttribs.PushBack(mGlesVersion / 10);
611     mContextAttribs.PushBack(EGL_CONTEXT_MINOR_VERSION_KHR);
612     mContextAttribs.PushBack(mGlesVersion % 10);
613   }
614   else
615   {
616     mContextAttribs.Reserve(3);
617     mContextAttribs.PushBack(EGL_CONTEXT_CLIENT_VERSION);
618     mContextAttribs.PushBack(mGlesVersion / 10);
619   }
620   mContextAttribs.PushBack(EGL_NONE);
621
622   return true;
623 }
624
625 EGLSurface EglImplementation::CreateSurfaceWindow(EGLNativeWindowType window, ColorDepth depth)
626 {
627   mEglNativeWindow = window;
628   mColorDepth      = depth;
629   mIsWindow        = true;
630
631   // egl choose config
632   ChooseConfig(mIsWindow, mColorDepth);
633
634   mCurrentEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, mEglNativeWindow, NULL);
635   TEST_EGL_ERROR("eglCreateWindowSurface");
636
637   DALI_ASSERT_ALWAYS(mCurrentEglSurface && "Create window surface failed");
638
639   return mCurrentEglSurface;
640 }
641
642 EGLSurface EglImplementation::CreateSurfacePixmap(EGLNativePixmapType pixmap, ColorDepth depth)
643 {
644   mCurrentEglNativePixmap = pixmap;
645   mColorDepth             = depth;
646   mIsWindow               = false;
647
648   // egl choose config
649   ChooseConfig(mIsWindow, mColorDepth);
650
651   mCurrentEglSurface = eglCreatePixmapSurface(mEglDisplay, mEglConfig, mCurrentEglNativePixmap, NULL);
652   TEST_EGL_ERROR("eglCreatePixmapSurface");
653
654   DALI_ASSERT_ALWAYS(mCurrentEglSurface && "Create pixmap surface failed");
655
656   return mCurrentEglSurface;
657 }
658
659 bool EglImplementation::ReplaceSurfaceWindow(EGLNativeWindowType window, EGLSurface& eglSurface, EGLContext& eglContext)
660 {
661   bool contextLost = false;
662
663   // display connection has not changed, then we can just create a new surface
664   //  the surface is bound to the context, so set the context to null
665   MakeContextNull();
666
667   if(eglSurface)
668   {
669     // destroy the surface
670     DestroySurface(eglSurface);
671   }
672
673   // create the EGL surface
674   EGLSurface newEglSurface = CreateSurfaceWindow(window, mColorDepth);
675
676   // set the context to be current with the new surface
677   MakeContextCurrent(newEglSurface, eglContext);
678
679   return contextLost;
680 }
681
682 bool EglImplementation::ReplaceSurfacePixmap(EGLNativePixmapType pixmap, EGLSurface& eglSurface)
683 {
684   bool contextLost = false;
685
686   // display connection has not changed, then we can just create a new surface
687   // create the EGL surface
688   eglSurface = CreateSurfacePixmap(pixmap, mColorDepth);
689
690   // set the eglSurface to be current
691   MakeCurrent(pixmap, eglSurface);
692
693   return contextLost;
694 }
695
696 void EglImplementation::SetGlesVersion(const int32_t glesVersion)
697 {
698   mGlesVersion = glesVersion;
699 }
700
701 void EglImplementation::SetFirstFrameAfterResume()
702 {
703   mSwapBufferCountAfterResume = 0;
704 }
705
706 EGLDisplay EglImplementation::GetDisplay() const
707 {
708   return mEglDisplay;
709 }
710
711 EGLContext EglImplementation::GetContext() const
712 {
713   return mEglContext;
714 }
715
716 int32_t EglImplementation::GetGlesVersion() const
717 {
718   return mGlesVersion;
719 }
720
721 bool EglImplementation::IsSurfacelessContextSupported() const
722 {
723   return mIsSurfacelessContextSupported;
724 }
725
726 void EglImplementation::WaitClient()
727 {
728   // Wait for EGL to finish executing all rendering calls for the current context
729   if(eglWaitClient() != EGL_TRUE)
730   {
731     TEST_EGL_ERROR("eglWaitClient");
732   }
733 }
734
735 bool EglImplementation::IsPartialUpdateRequired() const
736 {
737   return mPartialUpdateRequired;
738 }
739
740 } // namespace Adaptor
741
742 } // namespace Internal
743
744 } // namespace Dali
745
746 #pragma GCC diagnostic pop