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