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