2 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <dali/internal/graphics/gles/egl-implementation.h>
24 #include <dali/integration-api/debug.h>
25 #include <dali/public-api/common/dali-vector.h>
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>
32 // EGL constants use C style casts
33 #pragma GCC diagnostic push
34 #pragma GCC diagnostic ignored "-Wold-style-cast"
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";
53 #define TEST_EGL_ERROR(lastCommand) \
55 EGLint err = eglGetError(); \
56 if (err != EGL_SUCCESS) \
58 DALI_LOG_ERROR("EGL error after %s\n", lastCommand); \
59 Egl::PrintError(err); \
60 DALI_ASSERT_ALWAYS(0 && "EGL error"); \
64 EglImplementation::EglImplementation( int multiSamplingLevel,
65 Integration::DepthBufferAvailable depthBufferRequired,
66 Integration::StencilBufferAvailable stencilBufferRequired ,
67 Integration::PartialUpdateAvailable partialUpdateRequired )
69 mEglNativeDisplay( 0 ),
70 mEglNativeWindow( 0 ),
71 mCurrentEglNativePixmap( 0 ),
75 mCurrentEglSurface( 0 ),
76 mCurrentEglContext( EGL_NO_CONTEXT ),
77 mMultiSamplingLevel( multiSamplingLevel ),
79 mColorDepth( COLOR_DEPTH_24 ),
80 mGlesInitialized( false ),
81 mIsOwnSurface( 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 ),
92 mFullSwapNextFrame( true )
96 EglImplementation::~EglImplementation()
101 bool EglImplementation::InitializeGles( EGLNativeDisplayType display, bool isOwnSurface )
103 if ( !mGlesInitialized )
105 mEglNativeDisplay = display;
107 //@todo see if we can just EGL_DEFAULT_DISPLAY instead
108 mEglDisplay = eglGetDisplay(mEglNativeDisplay);
109 EGLint error = eglGetError();
111 if( mEglDisplay == NULL && error != EGL_SUCCESS )
113 throw Dali::DaliException( "", "OpenGL ES is not supported");
116 EGLint majorVersion = 0;
117 EGLint minorVersion = 0;
118 if ( !eglInitialize( mEglDisplay, &majorVersion, &minorVersion ) )
122 eglBindAPI(EGL_OPENGL_ES_API);
124 mIsOwnSurface = isOwnSurface;
127 // Query EGL extensions to check whether surfaceless context is supported
128 const char* const extensionStr = eglQueryString( mEglDisplay, EGL_EXTENSIONS );
129 std::istringstream stream( extensionStr );
130 std::string currentExtension;
131 uint32_t extensionCheckCount = 0;
132 while( std::getline( stream, currentExtension, ' ' ) && extensionCheckCount < CHECK_EXTENSION_NUMBER )
134 if( currentExtension == EGL_KHR_SURFACELESS_CONTEXT )
136 mIsSurfacelessContextSupported = true;
137 extensionCheckCount++;
139 if( currentExtension == EGL_KHR_CREATE_CONTEXT )
141 mIsKhrCreateContextSupported = true;
142 extensionCheckCount++;
146 mGlesInitialized = true;
148 // We want to display this information all the time, so use the LogMessage directly
149 Integration::Log::LogMessage(Integration::Log::DebugInfo, "EGL Information\n"
154 eglQueryString( mEglDisplay, EGL_VENDOR ),
155 eglQueryString( mEglDisplay, EGL_VERSION ),
156 eglQueryString( mEglDisplay, EGL_CLIENT_APIS ),
159 return mGlesInitialized;
162 bool EglImplementation::CreateContext()
164 // make sure a context isn't created twice
165 DALI_ASSERT_ALWAYS( (mEglContext == 0) && "EGL context recreated" );
167 mEglContext = eglCreateContext(mEglDisplay, mEglConfig, NULL, &(mContextAttribs[0]));
168 TEST_EGL_ERROR("eglCreateContext render thread");
170 DALI_ASSERT_ALWAYS( EGL_NO_CONTEXT != mEglContext && "EGL context not created" );
172 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VENDOR : %s ***\n", glGetString(GL_VENDOR));
173 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_RENDERER : %s ***\n", glGetString(GL_RENDERER));
174 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VERSION : %s ***\n", glGetString(GL_VERSION));
175 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_SHADING_LANGUAGE_VERSION : %s***\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
176 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** Supported Extensions ***\n%s\n\n", glGetString(GL_EXTENSIONS));
178 mEglSetDamageRegionKHR = reinterpret_cast<PFNEGLSETDAMAGEREGIONKHRPROC>(eglGetProcAddress("eglSetDamageRegionKHR"));
179 if (!mEglSetDamageRegionKHR)
181 DALI_LOG_ERROR("Coudn't find eglSetDamageRegionKHR!\n");
182 mPartialUpdateRequired = false;
184 mEglSwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC>(eglGetProcAddress("eglSwapBuffersWithDamageKHR"));
185 if (!mEglSwapBuffersWithDamageKHR)
187 DALI_LOG_ERROR("Coudn't find eglSwapBuffersWithDamageKHR!\n");
188 mPartialUpdateRequired = false;
193 bool EglImplementation::CreateWindowContext( EGLContext& eglContext )
195 // make sure a context isn't created twice
196 DALI_ASSERT_ALWAYS( (eglContext == 0) && "EGL context recreated" );
198 eglContext = eglCreateContext(mEglDisplay, mEglConfig, mEglContext, &(mContextAttribs[0]));
199 TEST_EGL_ERROR("eglCreateContext render thread");
201 DALI_ASSERT_ALWAYS( EGL_NO_CONTEXT != eglContext && "EGL context not created" );
203 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VENDOR : %s ***\n", glGetString(GL_VENDOR));
204 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_RENDERER : %s ***\n", glGetString(GL_RENDERER));
205 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VERSION : %s ***\n", glGetString(GL_VERSION));
206 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_SHADING_LANGUAGE_VERSION : %s***\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
207 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** Supported Extensions ***\n%s\n\n", glGetString(GL_EXTENSIONS));
209 mEglWindowContexts.push_back( eglContext );
211 mEglSetDamageRegionKHR = reinterpret_cast<PFNEGLSETDAMAGEREGIONKHRPROC>(eglGetProcAddress("eglSetDamageRegionKHR"));
212 if (!mEglSetDamageRegionKHR)
214 DALI_LOG_ERROR("Coudn't find eglSetDamageRegionKHR!\n");
215 mPartialUpdateRequired = false;
217 mEglSwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC>(eglGetProcAddress("eglSwapBuffersWithDamageKHR"));
218 if (!mEglSwapBuffersWithDamageKHR)
220 DALI_LOG_ERROR("Coudn't find eglSwapBuffersWithDamageKHR!\n");
221 mPartialUpdateRequired = false;
226 void EglImplementation::DestroyContext( EGLContext& eglContext )
230 eglDestroyContext( mEglDisplay, eglContext );
235 void EglImplementation::DestroySurface( EGLSurface& eglSurface )
237 if(mIsOwnSurface && eglSurface)
239 // Make context null to prevent crash in driver side
241 eglDestroySurface( mEglDisplay, eglSurface );
246 void EglImplementation::MakeContextCurrent( EGLSurface eglSurface, EGLContext eglContext )
248 if (mCurrentEglContext == eglContext)
253 mCurrentEglSurface = eglSurface;
257 eglMakeCurrent( mEglDisplay, eglSurface, eglSurface, eglContext );
259 mCurrentEglContext = eglContext;
262 EGLint error = eglGetError();
264 if ( error != EGL_SUCCESS )
266 Egl::PrintError(error);
268 DALI_ASSERT_ALWAYS(false && "MakeContextCurrent failed!");
272 void EglImplementation::MakeCurrent( EGLNativePixmapType pixmap, EGLSurface eglSurface )
274 if (mCurrentEglContext == mEglContext)
279 mCurrentEglNativePixmap = pixmap;
280 mCurrentEglSurface = eglSurface;
284 eglMakeCurrent( mEglDisplay, eglSurface, eglSurface, mEglContext );
286 mCurrentEglContext = mEglContext;
289 EGLint error = eglGetError();
291 if ( error != EGL_SUCCESS )
293 Egl::PrintError(error);
295 DALI_ASSERT_ALWAYS(false && "MakeCurrent failed!");
299 void EglImplementation::MakeContextNull()
301 // clear the current context
302 eglMakeCurrent( mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
303 mCurrentEglContext = EGL_NO_CONTEXT;
306 void EglImplementation::TerminateGles()
308 if ( mGlesInitialized )
310 // Make context null to prevent crash in driver side
313 for ( auto eglSurface : mEglWindowSurfaces )
315 if(mIsOwnSurface && eglSurface)
317 eglDestroySurface(mEglDisplay, eglSurface);
320 eglDestroyContext(mEglDisplay, mEglContext);
321 for ( auto eglContext : mEglWindowContexts )
323 eglDestroyContext(mEglDisplay, eglContext);
326 eglTerminate(mEglDisplay);
331 mCurrentEglSurface = NULL;
332 mCurrentEglContext = EGL_NO_CONTEXT;
334 mGlesInitialized = false;
338 bool EglImplementation::IsGlesInitialized() const
340 return mGlesInitialized;
343 void EglImplementation::SwapBuffers( EGLSurface& eglSurface )
345 if ( eglSurface != EGL_NO_SURFACE ) // skip if using surfaceless context
347 #ifndef DALI_PROFILE_UBUNTU
348 if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT )
350 DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers started.\n" );
352 #endif //DALI_PROFILE_UBUNTU
354 // DALI_LOG_ERROR("EglImplementation::SwapBuffers()\n");
355 eglSwapBuffers( mEglDisplay, eglSurface );
356 mFullSwapNextFrame = false;
358 #ifndef DALI_PROFILE_UBUNTU
359 if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT )
361 DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers finished.\n" );
362 mSwapBufferCountAfterResume++;
364 #endif //DALI_PROFILE_UBUNTU
368 EGLint EglImplementation::GetBufferAge(EGLSurface& eglSurface) const
371 eglQuerySurface(mEglDisplay, eglSurface, EGL_BUFFER_AGE_EXT, &age);
374 DALI_LOG_ERROR("eglQuerySurface(%d)\n", eglGetError());
378 // 0 - invalid buffer
382 DALI_LOG_ERROR("EglImplementation::GetBufferAge() buffer age %d > 3\n", age);
383 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 bool EglImplementation::DamageAreasSet() const
391 return (mDamagedAreas.size() ? true : false);
394 void EglImplementation::SetDamageAreas( std::vector<Dali::Rect<int>>& damagedAreas )
396 mFullSwapNextFrame = true;
397 mDamagedAreas = damagedAreas;
400 void EglImplementation::SetFullSwapNextFrame()
402 mFullSwapNextFrame = true;
405 void mergeRects(Rect<int>& mergingRect, const std::vector<Rect<int>>& rects)
408 if (mergingRect.IsEmpty())
410 for (;i < rects.size(); i++)
412 if (!rects[i].IsEmpty())
414 mergingRect = rects[i];
420 for (;i < rects.size(); i++)
422 mergingRect.Merge(rects[i]);
426 void insertRects(std::list<std::vector<Rect<int>>>& damagedRectsList, const std::vector<Rect<int>>& damagedRects)
428 damagedRectsList.push_front(damagedRects);
429 if (damagedRectsList.size() > 4) // past triple buffers + current
431 damagedRectsList.pop_back();
435 void EglImplementation::SetDamage( EGLSurface& eglSurface, const std::vector<Rect<int>>& damagedRects, Rect<int>& clippingRect )
437 if (!mPartialUpdateRequired)
442 if (eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
446 eglQuerySurface(mEglDisplay, eglSurface, EGL_WIDTH, &width);
447 eglQuerySurface(mEglDisplay, eglSurface, EGL_HEIGHT, &height);
448 Rect<int> surfaceRect(0, 0, width, height);
450 mSurfaceRect = surfaceRect;
452 if (mFullSwapNextFrame)
455 insertRects(mBufferDamagedRects, std::vector<Rect<int>>(1, surfaceRect));
456 clippingRect = Rect<int>();
460 EGLint bufferAge = GetBufferAge(eglSurface);
461 if (mDamagedAreas.size())
463 mBufferAge = bufferAge;
466 // Buffer age is reset
467 clippingRect = Rect<int>();
471 mergeRects(clippingRect, mDamagedAreas);
475 // Buffer age 0 means the back buffer in invalid and requires full swap
476 if (!damagedRects.size() || bufferAge != mBufferAge || bufferAge == 0)
478 // No damage or buffer is out of order or buffer age is reset
479 mBufferAge = bufferAge;
480 insertRects(mBufferDamagedRects, std::vector<Rect<int>>(1, surfaceRect));
481 clippingRect = Rect<int>();
485 // We push current frame damaged rects here, zero index for current frame
486 mBufferAge = bufferAge;
487 insertRects(mBufferDamagedRects, damagedRects);
489 // Merge damaged rects into clipping rect
490 auto bufferDamagedRects = mBufferDamagedRects.begin();
491 while (bufferAge-- >= 0 && bufferDamagedRects != mBufferDamagedRects.end())
493 const std::vector<Rect<int>>& rects = *bufferDamagedRects++;
494 mergeRects(clippingRect, rects);
498 if (!clippingRect.Intersect(surfaceRect) || clippingRect.Area() > surfaceRect.Area() * 0.8)
500 // clipping area too big or doesn't intersect surface rect
501 clippingRect = Rect<int>();
505 // DALI_LOG_ERROR("eglSetDamageRegionKHR(%d, %d, %d, %d)\n", clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height);
506 EGLBoolean result = mEglSetDamageRegionKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(&clippingRect), 1);
507 if (result == EGL_FALSE)
509 DALI_LOG_ERROR("eglSetDamageRegionKHR(%d)\n", eglGetError());
514 void EglImplementation::SwapBuffers(EGLSurface& eglSurface, const std::vector<Rect<int>>& damagedRects)
516 if (eglSurface != EGL_NO_SURFACE ) // skip if using surfaceless context
518 if (!mPartialUpdateRequired || mFullSwapNextFrame || mBufferAge == 0 || !damagedRects.size())
520 SwapBuffers(eglSurface);
524 #ifndef DALI_PROFILE_UBUNTU
525 if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT )
527 DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers started.\n" );
529 #endif //DALI_PROFILE_UBUNTU
531 if (mDamagedAreas.size())
533 // DALI_LOG_ERROR("EglImplementation::SwapBuffers(%d)\n", mDamagedAreas.size());
534 EGLBoolean result = mEglSwapBuffersWithDamageKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(mDamagedAreas.data()), mDamagedAreas.size());
535 if (result == EGL_FALSE)
537 DALI_LOG_ERROR("eglSwapBuffersWithDamageKHR(%d)\n", eglGetError());
540 #ifndef DALI_PROFILE_UBUNTU
541 if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT )
543 DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers finished.\n" );
544 mSwapBufferCountAfterResume++;
546 #endif //DALI_PROFILE_UBUNTU
550 // current frame damaged rects were pushed by EglImplementation::SetDamage() to 0 index.
551 EGLint bufferAge = mBufferAge;
552 mCombinedDamagedRects.clear();
554 // Combine damaged rects from previous frames (beginning from bufferAge index) with the current frame (0 index)
555 auto bufferDamagedRects = mBufferDamagedRects.begin();
556 while (bufferAge-- >= 0 && bufferDamagedRects != mBufferDamagedRects.end())
558 const std::vector<Rect<int>>& rects = *bufferDamagedRects++;
559 mCombinedDamagedRects.insert(mCombinedDamagedRects.end(), rects.begin(), rects.end());
562 // Merge intersecting rects, form an array of non intersecting rects to help driver a bit
563 // Could be optional and can be removed, needs to be checked with and without on platform
564 const int n = mCombinedDamagedRects.size();
565 for (int i = 0; i < n-1; i++)
567 if (mCombinedDamagedRects[i].IsEmpty())
572 for (int j = i+1; j < n; j++)
574 if (mCombinedDamagedRects[j].IsEmpty())
579 if (mCombinedDamagedRects[i].Intersects(mCombinedDamagedRects[j]))
581 mCombinedDamagedRects[i].Merge(mCombinedDamagedRects[j]);
582 mCombinedDamagedRects[j].width = 0;
583 mCombinedDamagedRects[j].height = 0;
589 for (int i = 0; i < n; i++)
591 if (!mCombinedDamagedRects[i].IsEmpty())
593 mCombinedDamagedRects[j++] = mCombinedDamagedRects[i];
599 mCombinedDamagedRects.resize(j);
602 if (!mCombinedDamagedRects.size() || (mCombinedDamagedRects[0].Area() > mSurfaceRect.Area() * 0.8))
604 SwapBuffers(eglSurface);
608 // DALI_LOG_ERROR("EglImplementation::SwapBuffers(%d)\n", mCombinedDamagedRects.size());
609 EGLBoolean result = mEglSwapBuffersWithDamageKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(mCombinedDamagedRects.data()), mCombinedDamagedRects.size());
610 if (result == EGL_FALSE)
612 DALI_LOG_ERROR("eglSwapBuffersWithDamageKHR(%d)\n", eglGetError());
615 #ifndef DALI_PROFILE_UBUNTU
616 if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT )
618 DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers finished.\n" );
619 mSwapBufferCountAfterResume++;
621 #endif //DALI_PROFILE_UBUNTU
625 void EglImplementation::CopyBuffers( EGLSurface& eglSurface )
627 eglCopyBuffers( mEglDisplay, eglSurface, mCurrentEglNativePixmap );
630 void EglImplementation::WaitGL()
635 bool EglImplementation::ChooseConfig( bool isWindowType, ColorDepth depth )
637 if(mEglConfig && isWindowType == mIsWindow && mColorDepth == depth)
643 mIsWindow = isWindowType;
646 Vector<EGLint> configAttribs;
647 configAttribs.Reserve(31);
651 configAttribs.PushBack( EGL_SURFACE_TYPE );
652 configAttribs.PushBack( EGL_WINDOW_BIT );
656 configAttribs.PushBack( EGL_SURFACE_TYPE );
657 configAttribs.PushBack( EGL_PIXMAP_BIT );
660 configAttribs.PushBack( EGL_RENDERABLE_TYPE );
662 if( mGlesVersion >= 30 )
664 configAttribs.PushBack( EGL_OPENGL_ES3_BIT_KHR );
668 configAttribs.PushBack( EGL_OPENGL_ES2_BIT );
671 // TODO: enable this flag when it becomes supported
672 // configAttribs.PushBack( EGL_CONTEXT_FLAGS_KHR );
673 // configAttribs.PushBack( EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR );
675 configAttribs.PushBack( EGL_RED_SIZE );
676 configAttribs.PushBack( 8 );
677 configAttribs.PushBack( EGL_GREEN_SIZE );
678 configAttribs.PushBack( 8 );
679 configAttribs.PushBack( EGL_BLUE_SIZE );
680 configAttribs.PushBack( 8 );
682 // For underlay video playback, we also need to set the alpha value of the 24/32bit window.
683 configAttribs.PushBack( EGL_ALPHA_SIZE );
684 configAttribs.PushBack( 8 );
686 configAttribs.PushBack( EGL_DEPTH_SIZE );
687 configAttribs.PushBack( mDepthBufferRequired ? 24 : 0 );
688 configAttribs.PushBack( EGL_STENCIL_SIZE );
689 configAttribs.PushBack( mStencilBufferRequired ? 8 : 0 );
691 #ifndef DALI_PROFILE_UBUNTU
692 if( mMultiSamplingLevel != EGL_DONT_CARE )
694 configAttribs.PushBack( EGL_SAMPLES );
695 configAttribs.PushBack( mMultiSamplingLevel );
696 configAttribs.PushBack( EGL_SAMPLE_BUFFERS );
697 configAttribs.PushBack( 1 );
699 #endif // DALI_PROFILE_UBUNTU
700 configAttribs.PushBack( EGL_NONE );
702 // Ensure number of configs is set to 1 as on some drivers,
703 // eglChooseConfig succeeds but does not actually create a proper configuration.
704 if ( ( eglChooseConfig( mEglDisplay, &(configAttribs[0]), &mEglConfig, 1, &numConfigs ) != EGL_TRUE ) ||
705 ( numConfigs != 1 ) )
707 if( mGlesVersion >= 30 )
710 DALI_LOG_ERROR("Fail to use OpenGL es 3.0. Retrying to use OpenGL es 2.0.");
714 if ( numConfigs != 1 )
716 DALI_LOG_ERROR("No configurations found.\n");
718 TEST_EGL_ERROR("eglChooseConfig");
721 EGLint error = eglGetError();
724 case EGL_BAD_DISPLAY:
726 DALI_LOG_ERROR("Display is not an EGL display connection\n");
729 case EGL_BAD_ATTRIBUTE:
731 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");
734 case EGL_NOT_INITIALIZED:
736 DALI_LOG_ERROR("Display has not been initialized\n");
739 case EGL_BAD_PARAMETER:
741 DALI_LOG_ERROR("The parameter numConfig is NULL\n");
746 DALI_LOG_ERROR("Unknown error.\n");
749 DALI_ASSERT_ALWAYS(false && "eglChooseConfig failed!");
752 Integration::Log::LogMessage(Integration::Log::DebugInfo, "Using OpenGL es %d.%d.\n", mGlesVersion / 10, mGlesVersion % 10 );
754 mContextAttribs.Clear();
755 if( mIsKhrCreateContextSupported )
757 mContextAttribs.Reserve(5);
758 mContextAttribs.PushBack( EGL_CONTEXT_MAJOR_VERSION_KHR );
759 mContextAttribs.PushBack( mGlesVersion / 10 );
760 mContextAttribs.PushBack( EGL_CONTEXT_MINOR_VERSION_KHR );
761 mContextAttribs.PushBack( mGlesVersion % 10 );
765 mContextAttribs.Reserve(3);
766 mContextAttribs.PushBack( EGL_CONTEXT_CLIENT_VERSION );
767 mContextAttribs.PushBack( mGlesVersion / 10 );
769 mContextAttribs.PushBack( EGL_NONE );
774 EGLSurface EglImplementation::CreateSurfaceWindow( EGLNativeWindowType window, ColorDepth depth )
776 mEglNativeWindow = window;
781 ChooseConfig(mIsWindow, mColorDepth);
783 mCurrentEglSurface = eglCreateWindowSurface( mEglDisplay, mEglConfig, mEglNativeWindow, NULL );
784 TEST_EGL_ERROR("eglCreateWindowSurface");
786 DALI_ASSERT_ALWAYS( mCurrentEglSurface && "Create window surface failed" );
788 return mCurrentEglSurface;
791 EGLSurface EglImplementation::CreateSurfacePixmap( EGLNativePixmapType pixmap, ColorDepth depth )
793 mCurrentEglNativePixmap = pixmap;
798 ChooseConfig(mIsWindow, mColorDepth);
800 mCurrentEglSurface = eglCreatePixmapSurface( mEglDisplay, mEglConfig, mCurrentEglNativePixmap, NULL );
801 TEST_EGL_ERROR("eglCreatePixmapSurface");
803 DALI_ASSERT_ALWAYS( mCurrentEglSurface && "Create pixmap surface failed" );
805 return mCurrentEglSurface;
808 bool EglImplementation::ReplaceSurfaceWindow( EGLNativeWindowType window, EGLSurface& eglSurface, EGLContext& eglContext )
810 bool contextLost = false;
812 // display connection has not changed, then we can just create a new surface
813 // the surface is bound to the context, so set the context to null
818 // destroy the surface
819 DestroySurface( eglSurface );
822 // create the EGL surface
823 EGLSurface newEglSurface = CreateSurfaceWindow( window, mColorDepth );
825 // set the context to be current with the new surface
826 MakeContextCurrent( newEglSurface, eglContext );
831 bool EglImplementation::ReplaceSurfacePixmap( EGLNativePixmapType pixmap, EGLSurface& eglSurface )
833 bool contextLost = false;
835 // display connection has not changed, then we can just create a new surface
836 // create the EGL surface
837 eglSurface = CreateSurfacePixmap( pixmap, mColorDepth );
839 // set the eglSurface to be current
840 MakeCurrent( pixmap, eglSurface );
845 void EglImplementation::SetGlesVersion( const int32_t glesVersion )
847 mGlesVersion = glesVersion;
850 void EglImplementation::SetFirstFrameAfterResume()
852 mSwapBufferCountAfterResume = 0;
855 EGLDisplay EglImplementation::GetDisplay() const
860 EGLContext EglImplementation::GetContext() const
865 int32_t EglImplementation::GetGlesVersion() const
870 bool EglImplementation::IsSurfacelessContextSupported() const
872 return mIsSurfacelessContextSupported;
875 void EglImplementation::WaitClient()
877 // Wait for EGL to finish executing all rendering calls for the current context
878 if ( eglWaitClient() != EGL_TRUE )
880 TEST_EGL_ERROR("eglWaitClient");
884 } // namespace Adaptor
886 } // namespace Internal
890 #pragma GCC diagnostic pop