2 * Copyright (c) 2024 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.
19 #include <dali/internal/graphics/gles/egl-implementation.h>
22 #include <dali/integration-api/debug.h>
23 #include <dali/integration-api/trace.h>
24 #include <dali/public-api/common/dali-vector.h>
29 #include <dali/devel-api/adaptor-framework/environment-variable.h>
30 #include <dali/internal/graphics/gles/egl-debug.h>
31 #include <dali/internal/graphics/gles/gl-implementation.h>
32 #include <dali/internal/system/common/environment-variables.h>
33 #include <dali/internal/system/common/time-service.h>
34 #include <dali/public-api/dali-adaptor-common.h>
36 // EGL constants use C style casts
37 #pragma GCC diagnostic push
38 #pragma GCC diagnostic ignored "-Wold-style-cast"
42 #ifndef DALI_PROFILE_UBUNTU
43 const uint32_t THRESHOLD_SWAPBUFFER_COUNT = 20;
45 const uint32_t THRESHOLD_SWAPBUFFER_COUNT = 5;
47 const uint32_t CHECK_EXTENSION_NUMBER = 4;
48 const uint32_t EGL_VERSION_SUPPORT_SURFACELESS_CONTEXT = 15;
49 const char* EGL_KHR_SURFACELESS_CONTEXT = "EGL_KHR_surfaceless_context";
50 const char* EGL_KHR_CREATE_CONTEXT = "EGL_KHR_create_context";
51 const char* EGL_KHR_PARTIAL_UPDATE = "EGL_KHR_partial_update";
52 const char* EGL_KHR_SWAP_BUFFERS_WITH_DAMAGE = "EGL_KHR_swap_buffers_with_damage";
54 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_EGL, true);
56 static uint32_t GetPerformanceLogThresholdTime()
58 auto timeString = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_EGL_PERFORMANCE_LOG_THRESHOLD_TIME);
59 uint32_t time = timeString ? static_cast<uint32_t>(std::atoi(timeString)) : std::numeric_limits<uint32_t>::max();
63 #define START_DURATION_CHECK() \
64 uint64_t startTimeNanoSeconds = 0ull; \
65 uint64_t endTimeNanoSeconds = 0ull; \
68 TimeService::GetNanoseconds(startTimeNanoSeconds); \
71 #define FINISH_DURATION_CHECK(functionName) \
74 TimeService::GetNanoseconds(endTimeNanoSeconds); \
75 if(static_cast<uint32_t>((endTimeNanoSeconds - startTimeNanoSeconds) / 1000000ull) >= mLogThreshold) \
77 DALI_LOG_RELEASE_INFO("%s takes long time! [%.6lf ms]\n", functionName, static_cast<double>(endTimeNanoSeconds - startTimeNanoSeconds) / 1000000.0); \
89 #define TEST_EGL_ERROR(lastCommand) \
91 EGLint err = eglGetError(); \
92 if(err != EGL_SUCCESS) \
94 DALI_LOG_ERROR("EGL error after %s\n", lastCommand); \
95 Egl::PrintError(err); \
96 DALI_ASSERT_ALWAYS(0 && "EGL error"); \
100 EglImplementation::EglImplementation(int multiSamplingLevel,
101 Integration::DepthBufferAvailable depthBufferRequired,
102 Integration::StencilBufferAvailable stencilBufferRequired,
103 Integration::PartialUpdateAvailable partialUpdateRequired)
105 mEglNativeDisplay(0),
107 mCurrentEglNativePixmap(0),
111 mCurrentEglSurface(0),
112 mCurrentEglContext(EGL_NO_CONTEXT),
113 mMultiSamplingLevel(multiSamplingLevel),
115 mColorDepth(COLOR_DEPTH_24),
116 mGlesInitialized(false),
119 mDepthBufferRequired(depthBufferRequired == Integration::DepthBufferAvailable::TRUE),
120 mStencilBufferRequired(stencilBufferRequired == Integration::StencilBufferAvailable::TRUE),
121 mPartialUpdateRequired(partialUpdateRequired == Integration::PartialUpdateAvailable::TRUE),
122 mIsSurfacelessContextSupported(false),
123 mIsKhrCreateContextSupported(false),
124 mSwapBufferCountAfterResume(0),
125 mEglSetDamageRegionKHR(0),
126 mEglSwapBuffersWithDamageKHR(0)
130 EglImplementation::~EglImplementation()
135 bool EglImplementation::InitializeGles(EGLNativeDisplayType display, bool isOwnSurface)
137 mLogThreshold = GetPerformanceLogThresholdTime();
138 mLogEnabled = mLogThreshold < std::numeric_limits<uint32_t>::max() ? true : false;
140 if(!mGlesInitialized)
142 mEglNativeDisplay = display;
145 START_DURATION_CHECK();
146 // Try to get the display connection for the native display first
147 mEglDisplay = eglGetDisplay(mEglNativeDisplay);
148 FINISH_DURATION_CHECK("eglGetDisplay");
151 if(mEglDisplay == EGL_NO_DISPLAY)
153 START_DURATION_CHECK();
154 // If failed, try to get the default display connection
155 mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
156 FINISH_DURATION_CHECK("eglGetDisplay");
159 if(mEglDisplay == EGL_NO_DISPLAY)
161 // Still failed to get a display connection
162 throw Dali::DaliException("", "OpenGL ES is not supported");
165 EGLint majorVersion = 0;
166 EGLint minorVersion = 0;
169 START_DURATION_CHECK();
170 bool ret = eglInitialize(mEglDisplay, &majorVersion, &minorVersion);
171 FINISH_DURATION_CHECK("eglInitialize");
180 START_DURATION_CHECK();
181 eglBindAPI(EGL_OPENGL_ES_API);
182 FINISH_DURATION_CHECK("eglBindAPI");
185 mIsOwnSurface = isOwnSurface;
189 START_DURATION_CHECK();
190 const char* const versionStr = eglQueryString(mEglDisplay, EGL_VERSION);
191 const char* const extensionStr = eglQueryString(mEglDisplay, EGL_EXTENSIONS);
192 const char* const vendorStr = eglQueryString(mEglDisplay, EGL_VENDOR);
193 const char* const clientStr = eglQueryString(mEglDisplay, EGL_CLIENT_APIS);
194 FINISH_DURATION_CHECK("eglQueryString");
196 // Query EGL extensions to check whether required extensions are supported
197 std::istringstream versionStream(versionStr);
198 std::string majorVersion, minorVersion;
199 std::getline(versionStream, majorVersion, '.');
200 std::getline(versionStream, minorVersion);
201 uint32_t extensionCheckCount = 0;
202 if(stoul(majorVersion) * 10 + stoul(minorVersion) >= EGL_VERSION_SUPPORT_SURFACELESS_CONTEXT)
204 mIsSurfacelessContextSupported = true;
205 mIsKhrCreateContextSupported = true;
206 extensionCheckCount += 2;
209 std::istringstream stream(extensionStr);
210 std::string currentExtension;
211 bool isKhrPartialUpdateSupported = false;
212 bool isKhrSwapBuffersWithDamageSupported = false;
213 while(std::getline(stream, currentExtension, ' ') && extensionCheckCount < CHECK_EXTENSION_NUMBER)
215 if(currentExtension == EGL_KHR_SURFACELESS_CONTEXT && !mIsSurfacelessContextSupported)
217 mIsSurfacelessContextSupported = true;
218 extensionCheckCount++;
220 if(currentExtension == EGL_KHR_CREATE_CONTEXT && !mIsKhrCreateContextSupported)
222 mIsKhrCreateContextSupported = true;
223 extensionCheckCount++;
225 if(currentExtension == EGL_KHR_PARTIAL_UPDATE)
227 isKhrPartialUpdateSupported = true;
228 extensionCheckCount++;
230 if(currentExtension == EGL_KHR_SWAP_BUFFERS_WITH_DAMAGE)
232 isKhrSwapBuffersWithDamageSupported = true;
233 extensionCheckCount++;
237 if(!isKhrPartialUpdateSupported || !isKhrSwapBuffersWithDamageSupported)
239 mPartialUpdateRequired = false;
242 mGlesInitialized = true;
244 // We want to display this information all the time, so use the LogMessage directly
245 Integration::Log::LogMessage(Integration::Log::INFO,
247 " PartialUpdate %d\n"
252 mPartialUpdateRequired,
259 return mGlesInitialized;
262 bool EglImplementation::CreateContext()
264 // make sure a context isn't created twice
265 DALI_ASSERT_ALWAYS((mEglContext == 0) && "EGL context recreated");
268 START_DURATION_CHECK();
269 mEglContext = eglCreateContext(mEglDisplay, mEglConfig, NULL, &(mContextAttribs[0]));
270 FINISH_DURATION_CHECK("eglCreateContext");
272 TEST_EGL_ERROR("eglCreateContext render thread");
274 DALI_ASSERT_ALWAYS(EGL_NO_CONTEXT != mEglContext && "EGL context not created");
276 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VENDOR : %s ***\n", glGetString(GL_VENDOR));
277 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_RENDERER : %s ***\n", glGetString(GL_RENDERER));
278 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VERSION : %s ***\n", glGetString(GL_VERSION));
279 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_SHADING_LANGUAGE_VERSION : %s***\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
280 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** Supported Extensions ***\n%s\n\n", glGetString(GL_EXTENSIONS));
283 START_DURATION_CHECK();
284 mEglSetDamageRegionKHR = reinterpret_cast<PFNEGLSETDAMAGEREGIONKHRPROC>(eglGetProcAddress("eglSetDamageRegionKHR"));
285 if(!mEglSetDamageRegionKHR)
287 DALI_LOG_ERROR("Coudn't find eglSetDamageRegionKHR!\n");
288 mPartialUpdateRequired = false;
290 FINISH_DURATION_CHECK("eglGetProcAddress(\"eglSetDamageRegionKHR\")");
293 START_DURATION_CHECK();
294 mEglSwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC>(eglGetProcAddress("eglSwapBuffersWithDamageKHR"));
295 if(!mEglSwapBuffersWithDamageKHR)
297 DALI_LOG_ERROR("Coudn't find eglSwapBuffersWithDamageKHR!\n");
298 mPartialUpdateRequired = false;
300 FINISH_DURATION_CHECK("eglGetProcAddress(\"eglSwapBuffersWithDamageKHR\")");
305 bool EglImplementation::CreateWindowContext(EGLContext& eglContext)
307 // make sure a context isn't created twice
308 DALI_ASSERT_ALWAYS((eglContext == 0) && "EGL context recreated");
311 START_DURATION_CHECK();
312 eglContext = eglCreateContext(mEglDisplay, mEglConfig, mEglContext, &(mContextAttribs[0]));
313 FINISH_DURATION_CHECK("eglCreateContext");
315 TEST_EGL_ERROR("eglCreateContext render thread");
317 DALI_ASSERT_ALWAYS(EGL_NO_CONTEXT != eglContext && "EGL context not created");
319 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VENDOR : %s ***\n", glGetString(GL_VENDOR));
320 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_RENDERER : %s ***\n", glGetString(GL_RENDERER));
321 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VERSION : %s ***\n", glGetString(GL_VERSION));
322 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_SHADING_LANGUAGE_VERSION : %s***\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
323 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** Supported Extensions ***\n%s\n\n", glGetString(GL_EXTENSIONS));
325 mEglWindowContexts.push_back(eglContext);
328 START_DURATION_CHECK();
329 mEglSetDamageRegionKHR = reinterpret_cast<PFNEGLSETDAMAGEREGIONKHRPROC>(eglGetProcAddress("eglSetDamageRegionKHR"));
330 if(!mEglSetDamageRegionKHR)
332 DALI_LOG_ERROR("Coudn't find eglSetDamageRegionKHR!\n");
333 mPartialUpdateRequired = false;
335 FINISH_DURATION_CHECK("eglGetProcAddress(\"eglSetDamageRegionKHR\")");
338 START_DURATION_CHECK();
339 mEglSwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC>(eglGetProcAddress("eglSwapBuffersWithDamageKHR"));
340 if(!mEglSwapBuffersWithDamageKHR)
342 DALI_LOG_ERROR("Coudn't find eglSwapBuffersWithDamageKHR!\n");
343 mPartialUpdateRequired = false;
345 FINISH_DURATION_CHECK("eglGetProcAddress(\"eglSwapBuffersWithDamageKHR\")");
350 void EglImplementation::DestroyContext(EGLContext& eglContext)
354 START_DURATION_CHECK();
355 eglDestroyContext(mEglDisplay, eglContext);
357 FINISH_DURATION_CHECK("eglDestroyContext");
361 void EglImplementation::DestroySurface(EGLSurface& eglSurface)
363 if(mIsOwnSurface && eglSurface)
365 // Make context null to prevent crash in driver side
367 START_DURATION_CHECK();
368 eglDestroySurface(mEglDisplay, eglSurface);
370 FINISH_DURATION_CHECK("eglDestroySurface");
374 void EglImplementation::MakeContextCurrent(EGLSurface eglSurface, EGLContext eglContext)
376 if(mCurrentEglContext == eglContext)
381 mCurrentEglSurface = eglSurface;
385 START_DURATION_CHECK();
386 eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, eglContext);
388 mCurrentEglContext = eglContext;
389 FINISH_DURATION_CHECK("eglMakeCurrent");
392 EGLint error = eglGetError();
394 if(error != EGL_SUCCESS)
396 Egl::PrintError(error);
398 DALI_ASSERT_ALWAYS(false && "MakeContextCurrent failed!");
402 void EglImplementation::MakeCurrent(EGLNativePixmapType pixmap, EGLSurface eglSurface)
404 if(mCurrentEglContext == mEglContext)
409 mCurrentEglNativePixmap = pixmap;
410 mCurrentEglSurface = eglSurface;
414 START_DURATION_CHECK();
415 eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext);
417 mCurrentEglContext = mEglContext;
418 FINISH_DURATION_CHECK("eglMakeCurrent");
421 EGLint error = eglGetError();
423 if(error != EGL_SUCCESS)
425 Egl::PrintError(error);
427 DALI_ASSERT_ALWAYS(false && "MakeCurrent failed!");
431 void EglImplementation::MakeContextNull()
433 // clear the current context
434 START_DURATION_CHECK();
435 eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
436 mCurrentEglContext = EGL_NO_CONTEXT;
437 FINISH_DURATION_CHECK("eglMakeCurrent(null)");
440 void EglImplementation::TerminateGles()
444 // Make context null to prevent crash in driver side
449 for(auto eglSurface : mEglWindowSurfaces)
453 START_DURATION_CHECK();
454 eglDestroySurface(mEglDisplay, eglSurface);
455 FINISH_DURATION_CHECK("eglDestroySurface");
460 START_DURATION_CHECK();
461 eglDestroyContext(mEglDisplay, mEglContext);
462 FINISH_DURATION_CHECK("eglDestroyContext");
464 for(auto eglContext : mEglWindowContexts)
466 START_DURATION_CHECK();
467 eglDestroyContext(mEglDisplay, eglContext);
468 FINISH_DURATION_CHECK("eglDestroyContext");
472 START_DURATION_CHECK();
473 eglTerminate(mEglDisplay);
474 FINISH_DURATION_CHECK("eglTerminate");
480 mCurrentEglSurface = NULL;
481 mCurrentEglContext = EGL_NO_CONTEXT;
483 mGlesInitialized = false;
487 bool EglImplementation::IsGlesInitialized() const
489 return mGlesInitialized;
492 void EglImplementation::SwapBuffers(EGLSurface& eglSurface)
494 if(eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
496 START_DURATION_CHECK();
498 #ifndef DALI_PROFILE_UBUNTU
499 if(mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT)
501 DALI_LOG_RELEASE_INFO("EglImplementation::eglSwapBuffers started. eglSurface(%p)\n", eglSurface);
503 DALI_TRACE_BEGIN(gTraceFilter, "DALI_EGL_SWAP_BUFFERS");
504 #endif //DALI_PROFILE_UBUNTU
506 // DALI_LOG_ERROR("EglImplementation::SwapBuffers()\n");
507 eglSwapBuffers(mEglDisplay, eglSurface);
509 #ifndef DALI_PROFILE_UBUNTU
510 DALI_TRACE_END(gTraceFilter, "DALI_EGL_SWAP_BUFFERS");
511 if(mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT)
513 DALI_LOG_RELEASE_INFO("EglImplementation::eglSwapBuffers finished.\n");
514 mSwapBufferCountAfterResume++;
516 #endif //DALI_PROFILE_UBUNTU
518 FINISH_DURATION_CHECK("eglSwapBuffers");
522 EGLint EglImplementation::GetBufferAge(EGLSurface& eglSurface) const
524 START_DURATION_CHECK();
527 eglQuerySurface(mEglDisplay, eglSurface, EGL_BUFFER_AGE_EXT, &age);
530 DALI_LOG_ERROR("eglQuerySurface(%d)\n", eglGetError());
534 FINISH_DURATION_CHECK("eglQuerySurface");
539 void EglImplementation::SetDamageRegion(EGLSurface& eglSurface, std::vector<Rect<int>>& damagedRects)
541 if(!mPartialUpdateRequired)
546 if(eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
548 START_DURATION_CHECK();
549 EGLBoolean result = mEglSetDamageRegionKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(damagedRects.data()), 1);
550 if(result == EGL_FALSE)
552 DALI_LOG_ERROR("eglSetDamageRegionKHR(0x%x)\n", eglGetError());
554 FINISH_DURATION_CHECK("eglSetDamageRegionKHR");
558 void EglImplementation::SwapBuffers(EGLSurface& eglSurface, const std::vector<Rect<int>>& damagedRects)
560 if(eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
562 if(!mPartialUpdateRequired)
564 SwapBuffers(eglSurface);
568 START_DURATION_CHECK();
570 #ifndef DALI_PROFILE_UBUNTU
571 if(mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT)
573 DALI_LOG_RELEASE_INFO("EglImplementation::eglSwapBuffersWithDamageKHR started. eglSurface(%p)\n", eglSurface);
575 DALI_TRACE_BEGIN(gTraceFilter, "DALI_EGL_SWAP_BUFFERS_KHR");
576 #endif //DALI_PROFILE_UBUNTU
578 EGLBoolean result = mEglSwapBuffersWithDamageKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(const_cast<std::vector<Rect<int>>&>(damagedRects).data()), damagedRects.size());
579 if(result == EGL_FALSE)
581 DALI_LOG_ERROR("eglSwapBuffersWithDamageKHR(%d)\n", eglGetError());
584 #ifndef DALI_PROFILE_UBUNTU
585 DALI_TRACE_END(gTraceFilter, "DALI_EGL_SWAP_BUFFERS_KHR");
586 if(mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT)
588 DALI_LOG_RELEASE_INFO("EglImplementation::eglSwapBuffersWithDamageKHR finished.\n");
589 mSwapBufferCountAfterResume++;
591 #endif //DALI_PROFILE_UBUNTU
593 FINISH_DURATION_CHECK("eglSwapBuffersWithDamageKHR");
597 void EglImplementation::CopyBuffers(EGLSurface& eglSurface)
599 START_DURATION_CHECK();
600 eglCopyBuffers(mEglDisplay, eglSurface, mCurrentEglNativePixmap);
601 FINISH_DURATION_CHECK("eglCopyBuffers");
604 void EglImplementation::WaitGL()
606 START_DURATION_CHECK();
608 FINISH_DURATION_CHECK("eglWaitGL");
611 bool EglImplementation::ChooseConfig(bool isWindowType, ColorDepth depth)
613 if(mEglConfig && isWindowType == mIsWindow && mColorDepth == depth)
619 mIsWindow = isWindowType;
622 Vector<EGLint> configAttribs;
623 configAttribs.Reserve(31);
627 configAttribs.PushBack(EGL_SURFACE_TYPE);
628 configAttribs.PushBack(EGL_WINDOW_BIT);
632 configAttribs.PushBack(EGL_SURFACE_TYPE);
633 configAttribs.PushBack(EGL_PIXMAP_BIT);
636 configAttribs.PushBack(EGL_RENDERABLE_TYPE);
638 if(mGlesVersion >= 30)
640 configAttribs.PushBack(EGL_OPENGL_ES3_BIT_KHR);
644 configAttribs.PushBack(EGL_OPENGL_ES2_BIT);
647 // TODO: enable this flag when it becomes supported
648 // configAttribs.PushBack( EGL_CONTEXT_FLAGS_KHR );
649 // configAttribs.PushBack( EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR );
651 configAttribs.PushBack(EGL_RED_SIZE);
652 configAttribs.PushBack(8);
653 configAttribs.PushBack(EGL_GREEN_SIZE);
654 configAttribs.PushBack(8);
655 configAttribs.PushBack(EGL_BLUE_SIZE);
656 configAttribs.PushBack(8);
658 // For underlay video playback, we also need to set the alpha value of the 24/32bit window.
659 // TODO: When the tbm queue of GlView is 24bit, do we have to set the alpha size??
660 configAttribs.PushBack(EGL_ALPHA_SIZE);
661 configAttribs.PushBack(8);
663 configAttribs.PushBack(EGL_DEPTH_SIZE);
664 configAttribs.PushBack(mDepthBufferRequired ? 24 : 0);
665 configAttribs.PushBack(EGL_STENCIL_SIZE);
666 configAttribs.PushBack(mStencilBufferRequired ? 8 : 0);
668 if(mMultiSamplingLevel != EGL_DONT_CARE)
670 configAttribs.PushBack(EGL_SAMPLES);
671 configAttribs.PushBack(mMultiSamplingLevel);
672 configAttribs.PushBack(EGL_SAMPLE_BUFFERS);
673 configAttribs.PushBack(1);
676 configAttribs.PushBack(EGL_NONE);
678 START_DURATION_CHECK();
679 auto ret = eglChooseConfig(mEglDisplay, &(configAttribs[0]), &mEglConfig, 1, &numConfigs);
680 FINISH_DURATION_CHECK("eglChooseConfig");
682 // Ensure number of configs is set to 1 as on some drivers,
683 // eglChooseConfig succeeds but does not actually create a proper configuration.
684 if((ret != EGL_TRUE) ||
687 if(mGlesVersion >= 30)
690 DALI_LOG_ERROR("Fail to use OpenGL es 3.0. Retrying to use OpenGL es 2.0.");
696 DALI_LOG_ERROR("No configurations found.\n");
698 TEST_EGL_ERROR("eglChooseConfig");
701 EGLint error = eglGetError();
704 case EGL_BAD_DISPLAY:
706 DALI_LOG_ERROR("Display is not an EGL display connection\n");
709 case EGL_BAD_ATTRIBUTE:
711 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");
714 case EGL_NOT_INITIALIZED:
716 DALI_LOG_ERROR("Display has not been initialized\n");
719 case EGL_BAD_PARAMETER:
721 DALI_LOG_ERROR("The parameter numConfig is NULL\n");
726 DALI_LOG_ERROR("Unknown error.\n");
729 DALI_ASSERT_ALWAYS(false && "eglChooseConfig failed!");
732 Integration::Log::LogMessage(Integration::Log::INFO, "Using OpenGL es %d.%d.\n", mGlesVersion / 10, mGlesVersion % 10);
734 mContextAttribs.Clear();
735 if(mIsKhrCreateContextSupported)
737 mContextAttribs.Reserve(5);
738 mContextAttribs.PushBack(EGL_CONTEXT_MAJOR_VERSION_KHR);
739 mContextAttribs.PushBack(mGlesVersion / 10);
740 mContextAttribs.PushBack(EGL_CONTEXT_MINOR_VERSION_KHR);
741 mContextAttribs.PushBack(mGlesVersion % 10);
745 mContextAttribs.Reserve(3);
746 mContextAttribs.PushBack(EGL_CONTEXT_CLIENT_VERSION);
747 mContextAttribs.PushBack(mGlesVersion / 10);
749 mContextAttribs.PushBack(EGL_NONE);
754 EGLSurface EglImplementation::CreateSurfaceWindow(EGLNativeWindowType window, ColorDepth depth)
756 mEglNativeWindow = window;
761 ChooseConfig(mIsWindow, mColorDepth);
763 START_DURATION_CHECK();
764 mCurrentEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, mEglNativeWindow, NULL);
765 FINISH_DURATION_CHECK("eglCreateWindowSurface");
766 TEST_EGL_ERROR("eglCreateWindowSurface");
768 DALI_ASSERT_ALWAYS(mCurrentEglSurface && "Create window surface failed");
770 return mCurrentEglSurface;
773 EGLSurface EglImplementation::CreateSurfacePixmap(EGLNativePixmapType pixmap, ColorDepth depth)
775 mCurrentEglNativePixmap = pixmap;
780 ChooseConfig(mIsWindow, mColorDepth);
782 START_DURATION_CHECK();
783 mCurrentEglSurface = eglCreatePixmapSurface(mEglDisplay, mEglConfig, mCurrentEglNativePixmap, NULL);
784 FINISH_DURATION_CHECK("eglCreatePixmapSurface");
785 TEST_EGL_ERROR("eglCreatePixmapSurface");
787 DALI_ASSERT_ALWAYS(mCurrentEglSurface && "Create pixmap surface failed");
789 return mCurrentEglSurface;
792 bool EglImplementation::ReplaceSurfaceWindow(EGLNativeWindowType window, EGLSurface& eglSurface, EGLContext& eglContext)
794 bool contextLost = false;
796 // display connection has not changed, then we can just create a new surface
797 // the surface is bound to the context, so set the context to null
802 // destroy the surface
803 DestroySurface(eglSurface);
806 // create the EGL surface
807 EGLSurface newEglSurface = CreateSurfaceWindow(window, mColorDepth);
809 // set the context to be current with the new surface
810 MakeContextCurrent(newEglSurface, eglContext);
815 bool EglImplementation::ReplaceSurfacePixmap(EGLNativePixmapType pixmap, EGLSurface& eglSurface)
817 bool contextLost = false;
819 // display connection has not changed, then we can just create a new surface
820 // create the EGL surface
821 eglSurface = CreateSurfacePixmap(pixmap, mColorDepth);
823 // set the eglSurface to be current
824 MakeCurrent(pixmap, eglSurface);
829 void EglImplementation::SetGlesVersion(const int32_t glesVersion)
831 mGlesVersion = glesVersion;
834 void EglImplementation::SetFirstFrameAfterResume()
836 mSwapBufferCountAfterResume = 0;
839 EGLDisplay EglImplementation::GetDisplay() const
844 EGLContext EglImplementation::GetContext() const
849 int32_t EglImplementation::GetGlesVersion() const
854 bool EglImplementation::IsSurfacelessContextSupported() const
856 return mIsSurfacelessContextSupported;
859 void EglImplementation::WaitClient()
861 START_DURATION_CHECK();
862 // Wait for EGL to finish executing all rendering calls for the current context
863 if(eglWaitClient() != EGL_TRUE)
865 TEST_EGL_ERROR("eglWaitClient");
867 FINISH_DURATION_CHECK("eglWaitClient");
870 bool EglImplementation::IsPartialUpdateRequired() const
872 return mPartialUpdateRequired;
875 } // namespace Adaptor
877 } // namespace Internal
881 #pragma GCC diagnostic pop