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