2 * Copyright (c) 2021 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/public-api/common/dali-vector.h>
27 #include <dali/internal/graphics/gles/egl-debug.h>
28 #include <dali/internal/graphics/gles/gl-implementation.h>
29 #include <dali/public-api/dali-adaptor-common.h>
31 // EGL constants use C style casts
32 #pragma GCC diagnostic push
33 #pragma GCC diagnostic ignored "-Wold-style-cast"
37 const uint32_t THRESHOLD_SWAPBUFFER_COUNT = 5;
38 const uint32_t CHECK_EXTENSION_NUMBER = 4;
39 const uint32_t EGL_VERSION_SUPPORT_SURFACELESS_CONTEXT = 15;
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 const std::string EGL_KHR_SWAP_BUFFERS_WITH_DAMAGE = "EGL_KHR_swap_buffers_with_damage";
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)
71 mCurrentEglNativePixmap(0),
75 mCurrentEglSurface(0),
76 mCurrentEglContext(EGL_NO_CONTEXT),
77 mMultiSamplingLevel(multiSamplingLevel),
79 mColorDepth(COLOR_DEPTH_24),
80 mGlesInitialized(false),
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)
94 EglImplementation::~EglImplementation()
99 bool EglImplementation::InitializeGles(EGLNativeDisplayType display, bool isOwnSurface)
101 if(!mGlesInitialized)
103 mEglNativeDisplay = display;
105 // Try to get the display connection for the native display first
106 mEglDisplay = eglGetDisplay(mEglNativeDisplay);
108 if(mEglDisplay == EGL_NO_DISPLAY)
110 // If failed, try to get the default display connection
111 mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
114 if(mEglDisplay == EGL_NO_DISPLAY)
116 // Still failed to get a display connection
117 throw Dali::DaliException("", "OpenGL ES is not supported");
120 EGLint majorVersion = 0;
121 EGLint minorVersion = 0;
122 if(!eglInitialize(mEglDisplay, &majorVersion, &minorVersion))
126 eglBindAPI(EGL_OPENGL_ES_API);
128 mIsOwnSurface = isOwnSurface;
131 const char* const versionStr = eglQueryString(mEglDisplay, EGL_VERSION);
132 const char* const extensionStr = eglQueryString(mEglDisplay, EGL_EXTENSIONS);
134 // Query EGL extensions to check whether required extensions are supported
135 std::istringstream versionStream(versionStr);
136 std::string majorVersion, minorVersion;
137 std::getline(versionStream, majorVersion, '.');
138 std::getline(versionStream, minorVersion);
139 uint32_t extensionCheckCount = 0;
140 if(stoul(majorVersion) * 10 + stoul(minorVersion) >= EGL_VERSION_SUPPORT_SURFACELESS_CONTEXT)
142 mIsSurfacelessContextSupported = true;
143 mIsKhrCreateContextSupported = true;
144 extensionCheckCount += 2;
147 std::istringstream stream(extensionStr);
148 std::string currentExtension;
149 bool isKhrPartialUpdateSupported = false;
150 bool isKhrSwapBuffersWithDamageSupported = false;
151 while(std::getline(stream, currentExtension, ' ') && extensionCheckCount < CHECK_EXTENSION_NUMBER)
153 if(currentExtension == EGL_KHR_SURFACELESS_CONTEXT && !mIsSurfacelessContextSupported)
155 mIsSurfacelessContextSupported = true;
156 extensionCheckCount++;
158 if(currentExtension == EGL_KHR_CREATE_CONTEXT && !mIsKhrCreateContextSupported)
160 mIsKhrCreateContextSupported = true;
161 extensionCheckCount++;
163 if(currentExtension == EGL_KHR_PARTIAL_UPDATE)
165 isKhrPartialUpdateSupported = true;
166 extensionCheckCount++;
168 if(currentExtension == EGL_KHR_SWAP_BUFFERS_WITH_DAMAGE)
170 isKhrSwapBuffersWithDamageSupported = true;
171 extensionCheckCount++;
175 if(!isKhrPartialUpdateSupported || !isKhrSwapBuffersWithDamageSupported)
177 mPartialUpdateRequired = false;
180 mGlesInitialized = true;
182 // We want to display this information all the time, so use the LogMessage directly
183 Integration::Log::LogMessage(Integration::Log::DebugInfo,
185 " PartialUpdate %d\n"
190 mPartialUpdateRequired,
191 eglQueryString(mEglDisplay, EGL_VENDOR),
193 eglQueryString(mEglDisplay, EGL_CLIENT_APIS),
196 return mGlesInitialized;
199 bool EglImplementation::CreateContext()
201 // make sure a context isn't created twice
202 DALI_ASSERT_ALWAYS((mEglContext == 0) && "EGL context recreated");
204 mEglContext = eglCreateContext(mEglDisplay, mEglConfig, NULL, &(mContextAttribs[0]));
205 TEST_EGL_ERROR("eglCreateContext render thread");
207 DALI_ASSERT_ALWAYS(EGL_NO_CONTEXT != mEglContext && "EGL context not created");
209 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VENDOR : %s ***\n", glGetString(GL_VENDOR));
210 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_RENDERER : %s ***\n", glGetString(GL_RENDERER));
211 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VERSION : %s ***\n", glGetString(GL_VERSION));
212 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_SHADING_LANGUAGE_VERSION : %s***\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
213 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** Supported Extensions ***\n%s\n\n", glGetString(GL_EXTENSIONS));
215 mEglSetDamageRegionKHR = reinterpret_cast<PFNEGLSETDAMAGEREGIONKHRPROC>(eglGetProcAddress("eglSetDamageRegionKHR"));
216 if(!mEglSetDamageRegionKHR)
218 DALI_LOG_ERROR("Coudn't find eglSetDamageRegionKHR!\n");
219 mPartialUpdateRequired = false;
221 mEglSwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC>(eglGetProcAddress("eglSwapBuffersWithDamageKHR"));
222 if(!mEglSwapBuffersWithDamageKHR)
224 DALI_LOG_ERROR("Coudn't find eglSwapBuffersWithDamageKHR!\n");
225 mPartialUpdateRequired = false;
230 bool EglImplementation::CreateWindowContext(EGLContext& eglContext)
232 // make sure a context isn't created twice
233 DALI_ASSERT_ALWAYS((eglContext == 0) && "EGL context recreated");
235 eglContext = eglCreateContext(mEglDisplay, mEglConfig, mEglContext, &(mContextAttribs[0]));
236 TEST_EGL_ERROR("eglCreateContext render thread");
238 DALI_ASSERT_ALWAYS(EGL_NO_CONTEXT != eglContext && "EGL context not created");
240 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VENDOR : %s ***\n", glGetString(GL_VENDOR));
241 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_RENDERER : %s ***\n", glGetString(GL_RENDERER));
242 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_VERSION : %s ***\n", glGetString(GL_VERSION));
243 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_SHADING_LANGUAGE_VERSION : %s***\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
244 DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** Supported Extensions ***\n%s\n\n", glGetString(GL_EXTENSIONS));
246 mEglWindowContexts.push_back(eglContext);
248 mEglSetDamageRegionKHR = reinterpret_cast<PFNEGLSETDAMAGEREGIONKHRPROC>(eglGetProcAddress("eglSetDamageRegionKHR"));
249 if(!mEglSetDamageRegionKHR)
251 DALI_LOG_ERROR("Coudn't find eglSetDamageRegionKHR!\n");
252 mPartialUpdateRequired = false;
254 mEglSwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC>(eglGetProcAddress("eglSwapBuffersWithDamageKHR"));
255 if(!mEglSwapBuffersWithDamageKHR)
257 DALI_LOG_ERROR("Coudn't find eglSwapBuffersWithDamageKHR!\n");
258 mPartialUpdateRequired = false;
263 void EglImplementation::DestroyContext(EGLContext& eglContext)
267 eglDestroyContext(mEglDisplay, eglContext);
272 void EglImplementation::DestroySurface(EGLSurface& eglSurface)
274 if(mIsOwnSurface && eglSurface)
276 // Make context null to prevent crash in driver side
278 eglDestroySurface(mEglDisplay, eglSurface);
283 void EglImplementation::MakeContextCurrent(EGLSurface eglSurface, EGLContext eglContext)
285 if(mCurrentEglContext == eglContext)
290 mCurrentEglSurface = eglSurface;
294 eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, eglContext);
296 mCurrentEglContext = eglContext;
299 EGLint error = eglGetError();
301 if(error != EGL_SUCCESS)
303 Egl::PrintError(error);
305 DALI_ASSERT_ALWAYS(false && "MakeContextCurrent failed!");
309 void EglImplementation::MakeCurrent(EGLNativePixmapType pixmap, EGLSurface eglSurface)
311 if(mCurrentEglContext == mEglContext)
316 mCurrentEglNativePixmap = pixmap;
317 mCurrentEglSurface = eglSurface;
321 eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext);
323 mCurrentEglContext = mEglContext;
326 EGLint error = eglGetError();
328 if(error != EGL_SUCCESS)
330 Egl::PrintError(error);
332 DALI_ASSERT_ALWAYS(false && "MakeCurrent failed!");
336 void EglImplementation::MakeContextNull()
338 // clear the current context
339 eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
340 mCurrentEglContext = EGL_NO_CONTEXT;
343 void EglImplementation::TerminateGles()
347 // Make context null to prevent crash in driver side
350 for(auto eglSurface : mEglWindowSurfaces)
352 if(mIsOwnSurface && eglSurface)
354 eglDestroySurface(mEglDisplay, eglSurface);
357 eglDestroyContext(mEglDisplay, mEglContext);
358 for(auto eglContext : mEglWindowContexts)
360 eglDestroyContext(mEglDisplay, eglContext);
363 eglTerminate(mEglDisplay);
368 mCurrentEglSurface = NULL;
369 mCurrentEglContext = EGL_NO_CONTEXT;
371 mGlesInitialized = false;
375 bool EglImplementation::IsGlesInitialized() const
377 return mGlesInitialized;
380 void EglImplementation::SwapBuffers(EGLSurface& eglSurface)
382 if(eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
384 #ifndef DALI_PROFILE_UBUNTU
385 if(mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT)
387 DALI_LOG_RELEASE_INFO("EglImplementation::eglSwapBuffers started. eglSurface(%p)\n", eglSurface);
389 #endif //DALI_PROFILE_UBUNTU
391 // DALI_LOG_ERROR("EglImplementation::SwapBuffers()\n");
392 eglSwapBuffers(mEglDisplay, eglSurface);
394 #ifndef DALI_PROFILE_UBUNTU
395 if(mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT)
397 DALI_LOG_RELEASE_INFO("EglImplementation::eglSwapBuffers finished.\n");
398 mSwapBufferCountAfterResume++;
400 #endif //DALI_PROFILE_UBUNTU
404 EGLint EglImplementation::GetBufferAge(EGLSurface& eglSurface) const
407 eglQuerySurface(mEglDisplay, eglSurface, EGL_BUFFER_AGE_EXT, &age);
410 DALI_LOG_ERROR("eglQuerySurface(%d)\n", eglGetError());
414 // 0 - invalid buffer
418 DALI_LOG_ERROR("EglImplementation::GetBufferAge() buffer age %d > 3\n", age);
419 age = 0; // shoudn't be more than 3 back buffers, if there is just reset, I don't want to add extra history level
425 void EglImplementation::SetDamageRegion(EGLSurface& eglSurface, std::vector<Rect<int>>& damagedRects)
427 if(!mPartialUpdateRequired)
432 if(eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
434 EGLBoolean result = mEglSetDamageRegionKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(damagedRects.data()), 1);
435 if(result == EGL_FALSE)
437 DALI_LOG_ERROR("eglSetDamageRegionKHR(%d)\n", eglGetError());
442 void EglImplementation::SwapBuffers(EGLSurface& eglSurface, const std::vector<Rect<int>>& damagedRects)
444 if(eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
446 if(!mPartialUpdateRequired)
448 SwapBuffers(eglSurface);
452 #ifndef DALI_PROFILE_UBUNTU
453 if(mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT)
455 DALI_LOG_RELEASE_INFO("EglImplementation::eglSwapBuffersWithDamageKHR started. eglSurface(%p)\n", eglSurface);
457 #endif //DALI_PROFILE_UBUNTU
459 EGLBoolean result = mEglSwapBuffersWithDamageKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(const_cast<std::vector<Rect<int>>&>(damagedRects).data()), damagedRects.size());
460 if(result == EGL_FALSE)
462 DALI_LOG_ERROR("eglSwapBuffersWithDamageKHR(%d)\n", eglGetError());
465 #ifndef DALI_PROFILE_UBUNTU
466 if(mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT)
468 DALI_LOG_RELEASE_INFO("EglImplementation::eglSwapBuffersWithDamageKHR finished.\n");
469 mSwapBufferCountAfterResume++;
471 #endif //DALI_PROFILE_UBUNTU
475 void EglImplementation::CopyBuffers(EGLSurface& eglSurface)
477 eglCopyBuffers(mEglDisplay, eglSurface, mCurrentEglNativePixmap);
480 void EglImplementation::WaitGL()
485 bool EglImplementation::ChooseConfig(bool isWindowType, ColorDepth depth)
487 if(mEglConfig && isWindowType == mIsWindow && mColorDepth == depth)
493 mIsWindow = isWindowType;
496 Vector<EGLint> configAttribs;
497 configAttribs.Reserve(31);
501 configAttribs.PushBack(EGL_SURFACE_TYPE);
502 configAttribs.PushBack(EGL_WINDOW_BIT);
506 configAttribs.PushBack(EGL_SURFACE_TYPE);
507 configAttribs.PushBack(EGL_PIXMAP_BIT);
510 configAttribs.PushBack(EGL_RENDERABLE_TYPE);
512 if(mGlesVersion >= 30)
514 configAttribs.PushBack(EGL_OPENGL_ES3_BIT_KHR);
518 configAttribs.PushBack(EGL_OPENGL_ES2_BIT);
521 // TODO: enable this flag when it becomes supported
522 // configAttribs.PushBack( EGL_CONTEXT_FLAGS_KHR );
523 // configAttribs.PushBack( EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR );
525 configAttribs.PushBack(EGL_RED_SIZE);
526 configAttribs.PushBack(8);
527 configAttribs.PushBack(EGL_GREEN_SIZE);
528 configAttribs.PushBack(8);
529 configAttribs.PushBack(EGL_BLUE_SIZE);
530 configAttribs.PushBack(8);
532 // For underlay video playback, we also need to set the alpha value of the 24/32bit window.
533 // TODO: When the tbm queue of GlView is 24bit, do we have to set the alpha size??
534 configAttribs.PushBack(EGL_ALPHA_SIZE);
535 configAttribs.PushBack(8);
537 configAttribs.PushBack(EGL_DEPTH_SIZE);
538 configAttribs.PushBack(mDepthBufferRequired ? 24 : 0);
539 configAttribs.PushBack(EGL_STENCIL_SIZE);
540 configAttribs.PushBack(mStencilBufferRequired ? 8 : 0);
542 #ifndef DALI_PROFILE_UBUNTU
543 if(mMultiSamplingLevel != EGL_DONT_CARE)
545 configAttribs.PushBack(EGL_SAMPLES);
546 configAttribs.PushBack(mMultiSamplingLevel);
547 configAttribs.PushBack(EGL_SAMPLE_BUFFERS);
548 configAttribs.PushBack(1);
550 #endif // DALI_PROFILE_UBUNTU
551 configAttribs.PushBack(EGL_NONE);
553 // Ensure number of configs is set to 1 as on some drivers,
554 // eglChooseConfig succeeds but does not actually create a proper configuration.
555 if((eglChooseConfig(mEglDisplay, &(configAttribs[0]), &mEglConfig, 1, &numConfigs) != EGL_TRUE) ||
558 if(mGlesVersion >= 30)
561 DALI_LOG_ERROR("Fail to use OpenGL es 3.0. Retrying to use OpenGL es 2.0.");
567 DALI_LOG_ERROR("No configurations found.\n");
569 TEST_EGL_ERROR("eglChooseConfig");
572 EGLint error = eglGetError();
575 case EGL_BAD_DISPLAY:
577 DALI_LOG_ERROR("Display is not an EGL display connection\n");
580 case EGL_BAD_ATTRIBUTE:
582 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");
585 case EGL_NOT_INITIALIZED:
587 DALI_LOG_ERROR("Display has not been initialized\n");
590 case EGL_BAD_PARAMETER:
592 DALI_LOG_ERROR("The parameter numConfig is NULL\n");
597 DALI_LOG_ERROR("Unknown error.\n");
600 DALI_ASSERT_ALWAYS(false && "eglChooseConfig failed!");
603 Integration::Log::LogMessage(Integration::Log::DebugInfo, "Using OpenGL es %d.%d.\n", mGlesVersion / 10, mGlesVersion % 10);
605 mContextAttribs.Clear();
606 if(mIsKhrCreateContextSupported)
608 mContextAttribs.Reserve(5);
609 mContextAttribs.PushBack(EGL_CONTEXT_MAJOR_VERSION_KHR);
610 mContextAttribs.PushBack(mGlesVersion / 10);
611 mContextAttribs.PushBack(EGL_CONTEXT_MINOR_VERSION_KHR);
612 mContextAttribs.PushBack(mGlesVersion % 10);
616 mContextAttribs.Reserve(3);
617 mContextAttribs.PushBack(EGL_CONTEXT_CLIENT_VERSION);
618 mContextAttribs.PushBack(mGlesVersion / 10);
620 mContextAttribs.PushBack(EGL_NONE);
625 EGLSurface EglImplementation::CreateSurfaceWindow(EGLNativeWindowType window, ColorDepth depth)
627 mEglNativeWindow = window;
632 ChooseConfig(mIsWindow, mColorDepth);
634 mCurrentEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, mEglNativeWindow, NULL);
635 TEST_EGL_ERROR("eglCreateWindowSurface");
637 DALI_ASSERT_ALWAYS(mCurrentEglSurface && "Create window surface failed");
639 return mCurrentEglSurface;
642 EGLSurface EglImplementation::CreateSurfacePixmap(EGLNativePixmapType pixmap, ColorDepth depth)
644 mCurrentEglNativePixmap = pixmap;
649 ChooseConfig(mIsWindow, mColorDepth);
651 mCurrentEglSurface = eglCreatePixmapSurface(mEglDisplay, mEglConfig, mCurrentEglNativePixmap, NULL);
652 TEST_EGL_ERROR("eglCreatePixmapSurface");
654 DALI_ASSERT_ALWAYS(mCurrentEglSurface && "Create pixmap surface failed");
656 return mCurrentEglSurface;
659 bool EglImplementation::ReplaceSurfaceWindow(EGLNativeWindowType window, EGLSurface& eglSurface, EGLContext& eglContext)
661 bool contextLost = false;
663 // display connection has not changed, then we can just create a new surface
664 // the surface is bound to the context, so set the context to null
669 // destroy the surface
670 DestroySurface(eglSurface);
673 // create the EGL surface
674 EGLSurface newEglSurface = CreateSurfaceWindow(window, mColorDepth);
676 // set the context to be current with the new surface
677 MakeContextCurrent(newEglSurface, eglContext);
682 bool EglImplementation::ReplaceSurfacePixmap(EGLNativePixmapType pixmap, EGLSurface& eglSurface)
684 bool contextLost = false;
686 // display connection has not changed, then we can just create a new surface
687 // create the EGL surface
688 eglSurface = CreateSurfacePixmap(pixmap, mColorDepth);
690 // set the eglSurface to be current
691 MakeCurrent(pixmap, eglSurface);
696 void EglImplementation::SetGlesVersion(const int32_t glesVersion)
698 mGlesVersion = glesVersion;
701 void EglImplementation::SetFirstFrameAfterResume()
703 mSwapBufferCountAfterResume = 0;
706 EGLDisplay EglImplementation::GetDisplay() const
711 EGLContext EglImplementation::GetContext() const
716 int32_t EglImplementation::GetGlesVersion() const
721 bool EglImplementation::IsSurfacelessContextSupported() const
723 return mIsSurfacelessContextSupported;
726 void EglImplementation::WaitClient()
728 // Wait for EGL to finish executing all rendering calls for the current context
729 if(eglWaitClient() != EGL_TRUE)
731 TEST_EGL_ERROR("eglWaitClient");
735 bool EglImplementation::IsPartialUpdateRequired() const
737 return mPartialUpdateRequired;
740 } // namespace Adaptor
742 } // namespace Internal
746 #pragma GCC diagnostic pop