2 * Copyright (c) 2020 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 // Try to get the display connection for the native display first
108 mEglDisplay = eglGetDisplay( mEglNativeDisplay );
110 if( mEglDisplay == EGL_NO_DISPLAY )
112 // If failed, try to get the default display connection
113 mEglDisplay = eglGetDisplay( EGL_DEFAULT_DISPLAY );
116 if( mEglDisplay == EGL_NO_DISPLAY )
118 // Still failed to get a display connection
119 throw Dali::DaliException( "", "OpenGL ES is not supported");
122 EGLint majorVersion = 0;
123 EGLint minorVersion = 0;
124 if ( !eglInitialize( mEglDisplay, &majorVersion, &minorVersion ) )
128 eglBindAPI(EGL_OPENGL_ES_API);
130 mIsOwnSurface = isOwnSurface;
133 // Query EGL extensions to check whether surfaceless context is supported
134 const char* const extensionStr = eglQueryString( mEglDisplay, EGL_EXTENSIONS );
135 std::istringstream stream( extensionStr );
136 std::string currentExtension;
137 uint32_t extensionCheckCount = 0;
138 while( std::getline( stream, currentExtension, ' ' ) && extensionCheckCount < CHECK_EXTENSION_NUMBER )
140 if( currentExtension == EGL_KHR_SURFACELESS_CONTEXT )
142 mIsSurfacelessContextSupported = true;
143 extensionCheckCount++;
145 if( currentExtension == EGL_KHR_CREATE_CONTEXT )
147 mIsKhrCreateContextSupported = true;
148 extensionCheckCount++;
152 mGlesInitialized = true;
154 // We want to display this information all the time, so use the LogMessage directly
155 Integration::Log::LogMessage(Integration::Log::DebugInfo, "EGL Information\n"
156 " PartialUpdate %d\n"
161 mPartialUpdateRequired,
162 eglQueryString( mEglDisplay, EGL_VENDOR ),
163 eglQueryString( mEglDisplay, EGL_VERSION ),
164 eglQueryString( mEglDisplay, EGL_CLIENT_APIS ),
167 return mGlesInitialized;
170 bool EglImplementation::CreateContext()
172 // make sure a context isn't created twice
173 DALI_ASSERT_ALWAYS( (mEglContext == 0) && "EGL context recreated" );
175 mEglContext = eglCreateContext(mEglDisplay, mEglConfig, NULL, &(mContextAttribs[0]));
176 TEST_EGL_ERROR("eglCreateContext render thread");
178 DALI_ASSERT_ALWAYS( EGL_NO_CONTEXT != mEglContext && "EGL context not created" );
180 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VENDOR : %s ***\n", glGetString(GL_VENDOR));
181 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_RENDERER : %s ***\n", glGetString(GL_RENDERER));
182 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VERSION : %s ***\n", glGetString(GL_VERSION));
183 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_SHADING_LANGUAGE_VERSION : %s***\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
184 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** Supported Extensions ***\n%s\n\n", glGetString(GL_EXTENSIONS));
186 mEglSetDamageRegionKHR = reinterpret_cast<PFNEGLSETDAMAGEREGIONKHRPROC>(eglGetProcAddress("eglSetDamageRegionKHR"));
187 if (!mEglSetDamageRegionKHR)
189 DALI_LOG_ERROR("Coudn't find eglSetDamageRegionKHR!\n");
190 mPartialUpdateRequired = false;
192 mEglSwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC>(eglGetProcAddress("eglSwapBuffersWithDamageKHR"));
193 if (!mEglSwapBuffersWithDamageKHR)
195 DALI_LOG_ERROR("Coudn't find eglSwapBuffersWithDamageKHR!\n");
196 mPartialUpdateRequired = false;
201 bool EglImplementation::CreateWindowContext( EGLContext& eglContext )
203 // make sure a context isn't created twice
204 DALI_ASSERT_ALWAYS( (eglContext == 0) && "EGL context recreated" );
206 eglContext = eglCreateContext(mEglDisplay, mEglConfig, mEglContext, &(mContextAttribs[0]));
207 TEST_EGL_ERROR("eglCreateContext render thread");
209 DALI_ASSERT_ALWAYS( EGL_NO_CONTEXT != eglContext && "EGL context not created" );
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));
217 mEglWindowContexts.push_back( eglContext );
219 mEglSetDamageRegionKHR = reinterpret_cast<PFNEGLSETDAMAGEREGIONKHRPROC>(eglGetProcAddress("eglSetDamageRegionKHR"));
220 if (!mEglSetDamageRegionKHR)
222 DALI_LOG_ERROR("Coudn't find eglSetDamageRegionKHR!\n");
223 mPartialUpdateRequired = false;
225 mEglSwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC>(eglGetProcAddress("eglSwapBuffersWithDamageKHR"));
226 if (!mEglSwapBuffersWithDamageKHR)
228 DALI_LOG_ERROR("Coudn't find eglSwapBuffersWithDamageKHR!\n");
229 mPartialUpdateRequired = false;
234 void EglImplementation::DestroyContext( EGLContext& eglContext )
238 eglDestroyContext( mEglDisplay, eglContext );
243 void EglImplementation::DestroySurface( EGLSurface& eglSurface )
245 if(mIsOwnSurface && eglSurface)
247 // Make context null to prevent crash in driver side
249 eglDestroySurface( mEglDisplay, eglSurface );
254 void EglImplementation::MakeContextCurrent( EGLSurface eglSurface, EGLContext eglContext )
256 if (mCurrentEglContext == eglContext)
261 mCurrentEglSurface = eglSurface;
265 eglMakeCurrent( mEglDisplay, eglSurface, eglSurface, eglContext );
267 mCurrentEglContext = eglContext;
270 EGLint error = eglGetError();
272 if ( error != EGL_SUCCESS )
274 Egl::PrintError(error);
276 DALI_ASSERT_ALWAYS(false && "MakeContextCurrent failed!");
280 void EglImplementation::MakeCurrent( EGLNativePixmapType pixmap, EGLSurface eglSurface )
282 if (mCurrentEglContext == mEglContext)
287 mCurrentEglNativePixmap = pixmap;
288 mCurrentEglSurface = eglSurface;
292 eglMakeCurrent( mEglDisplay, eglSurface, eglSurface, mEglContext );
294 mCurrentEglContext = mEglContext;
297 EGLint error = eglGetError();
299 if ( error != EGL_SUCCESS )
301 Egl::PrintError(error);
303 DALI_ASSERT_ALWAYS(false && "MakeCurrent failed!");
307 void EglImplementation::MakeContextNull()
309 // clear the current context
310 eglMakeCurrent( mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
311 mCurrentEglContext = EGL_NO_CONTEXT;
314 void EglImplementation::TerminateGles()
316 if ( mGlesInitialized )
318 // Make context null to prevent crash in driver side
321 for ( auto eglSurface : mEglWindowSurfaces )
323 if(mIsOwnSurface && eglSurface)
325 eglDestroySurface(mEglDisplay, eglSurface);
328 eglDestroyContext(mEglDisplay, mEglContext);
329 for ( auto eglContext : mEglWindowContexts )
331 eglDestroyContext(mEglDisplay, eglContext);
334 eglTerminate(mEglDisplay);
339 mCurrentEglSurface = NULL;
340 mCurrentEglContext = EGL_NO_CONTEXT;
342 mGlesInitialized = false;
346 bool EglImplementation::IsGlesInitialized() const
348 return mGlesInitialized;
351 void EglImplementation::SwapBuffers( EGLSurface& eglSurface )
353 if ( eglSurface != EGL_NO_SURFACE ) // skip if using surfaceless context
355 #ifndef DALI_PROFILE_UBUNTU
356 if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT )
358 DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers started.\n" );
360 #endif //DALI_PROFILE_UBUNTU
362 // DALI_LOG_ERROR("EglImplementation::SwapBuffers()\n");
363 eglSwapBuffers( mEglDisplay, eglSurface );
364 mFullSwapNextFrame = false;
366 #ifndef DALI_PROFILE_UBUNTU
367 if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT )
369 DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers finished.\n" );
370 mSwapBufferCountAfterResume++;
372 #endif //DALI_PROFILE_UBUNTU
376 EGLint EglImplementation::GetBufferAge(EGLSurface& eglSurface) const
379 eglQuerySurface(mEglDisplay, eglSurface, EGL_BUFFER_AGE_EXT, &age);
382 DALI_LOG_ERROR("eglQuerySurface(%d)\n", eglGetError());
386 // 0 - invalid buffer
390 DALI_LOG_ERROR("EglImplementation::GetBufferAge() buffer age %d > 3\n", age);
391 age = 0; // shoudn't be more than 3 back buffers, if there is just reset, I don't want to add extra history level
397 bool EglImplementation::DamageAreasSet() const
399 return (mDamagedAreas.size() ? true : false);
402 void EglImplementation::SetDamageAreas( std::vector<Dali::Rect<int>>& damagedAreas )
404 mFullSwapNextFrame = true;
405 mDamagedAreas = damagedAreas;
408 void EglImplementation::SetFullSwapNextFrame()
410 mFullSwapNextFrame = true;
413 void mergeRects(Rect<int>& mergingRect, const std::vector<Rect<int>>& rects)
416 if (mergingRect.IsEmpty())
418 for (;i < rects.size(); i++)
420 if (!rects[i].IsEmpty())
422 mergingRect = rects[i];
428 for (;i < rects.size(); i++)
430 mergingRect.Merge(rects[i]);
434 void insertRects(std::list<std::vector<Rect<int>>>& damagedRectsList, const std::vector<Rect<int>>& damagedRects)
436 damagedRectsList.push_front(damagedRects);
437 if (damagedRectsList.size() > 4) // past triple buffers + current
439 damagedRectsList.pop_back();
443 void EglImplementation::SetDamage( EGLSurface& eglSurface, const std::vector<Rect<int>>& damagedRects, Rect<int>& clippingRect )
445 if (!mPartialUpdateRequired)
450 if (eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
454 eglQuerySurface(mEglDisplay, eglSurface, EGL_WIDTH, &width);
455 eglQuerySurface(mEglDisplay, eglSurface, EGL_HEIGHT, &height);
456 Rect<int> surfaceRect(0, 0, width, height);
458 mSurfaceRect = surfaceRect;
460 if (mFullSwapNextFrame)
463 insertRects(mBufferDamagedRects, std::vector<Rect<int>>(1, surfaceRect));
464 clippingRect = Rect<int>();
468 EGLint bufferAge = GetBufferAge(eglSurface);
469 if (mDamagedAreas.size())
471 mBufferAge = bufferAge;
474 // Buffer age is reset
475 clippingRect = Rect<int>();
479 mergeRects(clippingRect, mDamagedAreas);
483 // Buffer age 0 means the back buffer in invalid and requires full swap
484 if (!damagedRects.size() || bufferAge != mBufferAge || bufferAge == 0)
486 // No damage or buffer is out of order or buffer age is reset
487 mBufferAge = bufferAge;
488 insertRects(mBufferDamagedRects, std::vector<Rect<int>>(1, surfaceRect));
489 clippingRect = Rect<int>();
493 // We push current frame damaged rects here, zero index for current frame
494 mBufferAge = bufferAge;
495 insertRects(mBufferDamagedRects, damagedRects);
497 // Merge damaged rects into clipping rect
498 auto bufferDamagedRects = mBufferDamagedRects.begin();
499 while (bufferAge-- >= 0 && bufferDamagedRects != mBufferDamagedRects.end())
501 const std::vector<Rect<int>>& rects = *bufferDamagedRects++;
502 mergeRects(clippingRect, rects);
506 if (!clippingRect.Intersect(surfaceRect) || clippingRect.Area() > surfaceRect.Area() * 0.8)
508 // clipping area too big or doesn't intersect surface rect
509 clippingRect = Rect<int>();
513 // DALI_LOG_ERROR("eglSetDamageRegionKHR(%d, %d, %d, %d)\n", clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height);
514 EGLBoolean result = mEglSetDamageRegionKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(&clippingRect), 1);
515 if (result == EGL_FALSE)
517 DALI_LOG_ERROR("eglSetDamageRegionKHR(%d)\n", eglGetError());
522 void EglImplementation::SwapBuffers(EGLSurface& eglSurface, const std::vector<Rect<int>>& damagedRects)
524 if (eglSurface != EGL_NO_SURFACE ) // skip if using surfaceless context
526 if (!mPartialUpdateRequired || mFullSwapNextFrame || mBufferAge == 0 || !damagedRects.size())
528 SwapBuffers(eglSurface);
532 #ifndef DALI_PROFILE_UBUNTU
533 if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT )
535 DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers started.\n" );
537 #endif //DALI_PROFILE_UBUNTU
539 if (mDamagedAreas.size())
541 // DALI_LOG_ERROR("EglImplementation::SwapBuffers(%d)\n", mDamagedAreas.size());
542 EGLBoolean result = mEglSwapBuffersWithDamageKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(mDamagedAreas.data()), mDamagedAreas.size());
543 if (result == EGL_FALSE)
545 DALI_LOG_ERROR("eglSwapBuffersWithDamageKHR(%d)\n", eglGetError());
548 #ifndef DALI_PROFILE_UBUNTU
549 if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT )
551 DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers finished.\n" );
552 mSwapBufferCountAfterResume++;
554 #endif //DALI_PROFILE_UBUNTU
558 // current frame damaged rects were pushed by EglImplementation::SetDamage() to 0 index.
559 EGLint bufferAge = mBufferAge;
560 mCombinedDamagedRects.clear();
562 // Combine damaged rects from previous frames (beginning from bufferAge index) with the current frame (0 index)
563 auto bufferDamagedRects = mBufferDamagedRects.begin();
564 while (bufferAge-- >= 0 && bufferDamagedRects != mBufferDamagedRects.end())
566 const std::vector<Rect<int>>& rects = *bufferDamagedRects++;
567 mCombinedDamagedRects.insert(mCombinedDamagedRects.end(), rects.begin(), rects.end());
570 // Merge intersecting rects, form an array of non intersecting rects to help driver a bit
571 // Could be optional and can be removed, needs to be checked with and without on platform
572 const int n = mCombinedDamagedRects.size();
573 for (int i = 0; i < n-1; i++)
575 if (mCombinedDamagedRects[i].IsEmpty())
580 for (int j = i+1; j < n; j++)
582 if (mCombinedDamagedRects[j].IsEmpty())
587 if (mCombinedDamagedRects[i].Intersects(mCombinedDamagedRects[j]))
589 mCombinedDamagedRects[i].Merge(mCombinedDamagedRects[j]);
590 mCombinedDamagedRects[j].width = 0;
591 mCombinedDamagedRects[j].height = 0;
597 for (int i = 0; i < n; i++)
599 if (!mCombinedDamagedRects[i].IsEmpty())
601 mCombinedDamagedRects[j++] = mCombinedDamagedRects[i];
607 mCombinedDamagedRects.resize(j);
610 if (!mCombinedDamagedRects.size() || (mCombinedDamagedRects[0].Area() > mSurfaceRect.Area() * 0.8))
612 SwapBuffers(eglSurface);
616 // DALI_LOG_ERROR("EglImplementation::SwapBuffers(%d)\n", mCombinedDamagedRects.size());
617 EGLBoolean result = mEglSwapBuffersWithDamageKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(mCombinedDamagedRects.data()), mCombinedDamagedRects.size());
618 if (result == EGL_FALSE)
620 DALI_LOG_ERROR("eglSwapBuffersWithDamageKHR(%d)\n", eglGetError());
623 #ifndef DALI_PROFILE_UBUNTU
624 if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT )
626 DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers finished.\n" );
627 mSwapBufferCountAfterResume++;
629 #endif //DALI_PROFILE_UBUNTU
633 void EglImplementation::CopyBuffers( EGLSurface& eglSurface )
635 eglCopyBuffers( mEglDisplay, eglSurface, mCurrentEglNativePixmap );
638 void EglImplementation::WaitGL()
643 bool EglImplementation::ChooseConfig( bool isWindowType, ColorDepth depth )
645 if(mEglConfig && isWindowType == mIsWindow && mColorDepth == depth)
651 mIsWindow = isWindowType;
654 Vector<EGLint> configAttribs;
655 configAttribs.Reserve(31);
659 configAttribs.PushBack( EGL_SURFACE_TYPE );
660 configAttribs.PushBack( EGL_WINDOW_BIT );
664 configAttribs.PushBack( EGL_SURFACE_TYPE );
665 configAttribs.PushBack( EGL_PIXMAP_BIT );
668 configAttribs.PushBack( EGL_RENDERABLE_TYPE );
670 if( mGlesVersion >= 30 )
672 configAttribs.PushBack( EGL_OPENGL_ES3_BIT_KHR );
676 configAttribs.PushBack( EGL_OPENGL_ES2_BIT );
679 // TODO: enable this flag when it becomes supported
680 // configAttribs.PushBack( EGL_CONTEXT_FLAGS_KHR );
681 // configAttribs.PushBack( EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR );
683 configAttribs.PushBack( EGL_RED_SIZE );
684 configAttribs.PushBack( 8 );
685 configAttribs.PushBack( EGL_GREEN_SIZE );
686 configAttribs.PushBack( 8 );
687 configAttribs.PushBack( EGL_BLUE_SIZE );
688 configAttribs.PushBack( 8 );
690 // For underlay video playback, we also need to set the alpha value of the 24/32bit window.
691 configAttribs.PushBack( EGL_ALPHA_SIZE );
692 configAttribs.PushBack( 8 );
694 configAttribs.PushBack( EGL_DEPTH_SIZE );
695 configAttribs.PushBack( mDepthBufferRequired ? 24 : 0 );
696 configAttribs.PushBack( EGL_STENCIL_SIZE );
697 configAttribs.PushBack( mStencilBufferRequired ? 8 : 0 );
699 #ifndef DALI_PROFILE_UBUNTU
700 if( mMultiSamplingLevel != EGL_DONT_CARE )
702 configAttribs.PushBack( EGL_SAMPLES );
703 configAttribs.PushBack( mMultiSamplingLevel );
704 configAttribs.PushBack( EGL_SAMPLE_BUFFERS );
705 configAttribs.PushBack( 1 );
707 #endif // DALI_PROFILE_UBUNTU
708 configAttribs.PushBack( EGL_NONE );
710 // Ensure number of configs is set to 1 as on some drivers,
711 // eglChooseConfig succeeds but does not actually create a proper configuration.
712 if ( ( eglChooseConfig( mEglDisplay, &(configAttribs[0]), &mEglConfig, 1, &numConfigs ) != EGL_TRUE ) ||
713 ( numConfigs != 1 ) )
715 if( mGlesVersion >= 30 )
718 DALI_LOG_ERROR("Fail to use OpenGL es 3.0. Retrying to use OpenGL es 2.0.");
722 if ( numConfigs != 1 )
724 DALI_LOG_ERROR("No configurations found.\n");
726 TEST_EGL_ERROR("eglChooseConfig");
729 EGLint error = eglGetError();
732 case EGL_BAD_DISPLAY:
734 DALI_LOG_ERROR("Display is not an EGL display connection\n");
737 case EGL_BAD_ATTRIBUTE:
739 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");
742 case EGL_NOT_INITIALIZED:
744 DALI_LOG_ERROR("Display has not been initialized\n");
747 case EGL_BAD_PARAMETER:
749 DALI_LOG_ERROR("The parameter numConfig is NULL\n");
754 DALI_LOG_ERROR("Unknown error.\n");
757 DALI_ASSERT_ALWAYS(false && "eglChooseConfig failed!");
760 Integration::Log::LogMessage(Integration::Log::DebugInfo, "Using OpenGL es %d.%d.\n", mGlesVersion / 10, mGlesVersion % 10 );
762 mContextAttribs.Clear();
763 if( mIsKhrCreateContextSupported )
765 mContextAttribs.Reserve(5);
766 mContextAttribs.PushBack( EGL_CONTEXT_MAJOR_VERSION_KHR );
767 mContextAttribs.PushBack( mGlesVersion / 10 );
768 mContextAttribs.PushBack( EGL_CONTEXT_MINOR_VERSION_KHR );
769 mContextAttribs.PushBack( mGlesVersion % 10 );
773 mContextAttribs.Reserve(3);
774 mContextAttribs.PushBack( EGL_CONTEXT_CLIENT_VERSION );
775 mContextAttribs.PushBack( mGlesVersion / 10 );
777 mContextAttribs.PushBack( EGL_NONE );
782 EGLSurface EglImplementation::CreateSurfaceWindow( EGLNativeWindowType window, ColorDepth depth )
784 mEglNativeWindow = window;
789 ChooseConfig(mIsWindow, mColorDepth);
791 mCurrentEglSurface = eglCreateWindowSurface( mEglDisplay, mEglConfig, mEglNativeWindow, NULL );
792 TEST_EGL_ERROR("eglCreateWindowSurface");
794 DALI_ASSERT_ALWAYS( mCurrentEglSurface && "Create window surface failed" );
796 return mCurrentEglSurface;
799 EGLSurface EglImplementation::CreateSurfacePixmap( EGLNativePixmapType pixmap, ColorDepth depth )
801 mCurrentEglNativePixmap = pixmap;
806 ChooseConfig(mIsWindow, mColorDepth);
808 mCurrentEglSurface = eglCreatePixmapSurface( mEglDisplay, mEglConfig, mCurrentEglNativePixmap, NULL );
809 TEST_EGL_ERROR("eglCreatePixmapSurface");
811 DALI_ASSERT_ALWAYS( mCurrentEglSurface && "Create pixmap surface failed" );
813 return mCurrentEglSurface;
816 bool EglImplementation::ReplaceSurfaceWindow( EGLNativeWindowType window, EGLSurface& eglSurface, EGLContext& eglContext )
818 bool contextLost = false;
820 // display connection has not changed, then we can just create a new surface
821 // the surface is bound to the context, so set the context to null
826 // destroy the surface
827 DestroySurface( eglSurface );
830 // create the EGL surface
831 EGLSurface newEglSurface = CreateSurfaceWindow( window, mColorDepth );
833 // set the context to be current with the new surface
834 MakeContextCurrent( newEglSurface, eglContext );
839 bool EglImplementation::ReplaceSurfacePixmap( EGLNativePixmapType pixmap, EGLSurface& eglSurface )
841 bool contextLost = false;
843 // display connection has not changed, then we can just create a new surface
844 // create the EGL surface
845 eglSurface = CreateSurfacePixmap( pixmap, mColorDepth );
847 // set the eglSurface to be current
848 MakeCurrent( pixmap, eglSurface );
853 void EglImplementation::SetGlesVersion( const int32_t glesVersion )
855 mGlesVersion = glesVersion;
858 void EglImplementation::SetFirstFrameAfterResume()
860 mSwapBufferCountAfterResume = 0;
863 EGLDisplay EglImplementation::GetDisplay() const
868 EGLContext EglImplementation::GetContext() const
873 int32_t EglImplementation::GetGlesVersion() const
878 bool EglImplementation::IsSurfacelessContextSupported() const
880 return mIsSurfacelessContextSupported;
883 void EglImplementation::WaitClient()
885 // Wait for EGL to finish executing all rendering calls for the current context
886 if ( eglWaitClient() != EGL_TRUE )
888 TEST_EGL_ERROR("eglWaitClient");
892 } // namespace Adaptor
894 } // namespace Internal
898 #pragma GCC diagnostic pop