18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include "egl_state.h" 198bf80f4bSopenharmony_ci 208bf80f4bSopenharmony_ci#include <EGL/egl.h> 218bf80f4bSopenharmony_ci#include <EGL/eglext.h> 228bf80f4bSopenharmony_ci 238bf80f4bSopenharmony_ci#ifndef EGL_VERSION_1_5 248bf80f4bSopenharmony_ci// If egl 1.5 headers not available, just define the values here. 258bf80f4bSopenharmony_ci// (copied from khronos specifications) 268bf80f4bSopenharmony_ci#define EGL_CONTEXT_MAJOR_VERSION 0x3098 278bf80f4bSopenharmony_ci#define EGL_CONTEXT_MINOR_VERSION 0x30FB 288bf80f4bSopenharmony_ci#define EGL_OPENGL_ES3_BIT 0x00000040 298bf80f4bSopenharmony_ci#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0 308bf80f4bSopenharmony_ci#define EGL_GL_COLORSPACE 0x309D 318bf80f4bSopenharmony_ci#define EGL_GL_COLORSPACE_SRGB 0x3089 328bf80f4bSopenharmony_ci#define EGL_GL_COLORSPACE_LINEAR 0x308A 338bf80f4bSopenharmony_citypedef intptr_t EGLAttrib; 348bf80f4bSopenharmony_ci#endif 358bf80f4bSopenharmony_ci 368bf80f4bSopenharmony_ci#ifndef EGL_KHR_create_context 378bf80f4bSopenharmony_ci// If EGL_KHR_create_context extension not defined in headers, so just define the values here. 388bf80f4bSopenharmony_ci// (copied from khronos specifications) 398bf80f4bSopenharmony_ci#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 408bf80f4bSopenharmony_ci#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB 418bf80f4bSopenharmony_ci#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 428bf80f4bSopenharmony_ci#define EGL_CONTEXT_FLAGS_KHR 0x30FC 438bf80f4bSopenharmony_ci#define EGL_OPENGL_ES3_BIT_KHR 0x00000040 448bf80f4bSopenharmony_ci#endif 458bf80f4bSopenharmony_ci 468bf80f4bSopenharmony_ci#ifndef EGL_KHR_gl_colorspace 478bf80f4bSopenharmony_ci// If EGL_KHR_gl_colorspace extension not defined in headers, so just define the values here. 488bf80f4bSopenharmony_ci// (copied from khronos specifications) 498bf80f4bSopenharmony_ci#define EGL_GL_COLORSPACE_KHR 0x309D 508bf80f4bSopenharmony_ci#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089 518bf80f4bSopenharmony_ci#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A 528bf80f4bSopenharmony_ci#endif /* EGL_KHR_gl_colorspace */ 538bf80f4bSopenharmony_ci 548bf80f4bSopenharmony_ci#ifndef EGL_KHR_no_config_context 558bf80f4bSopenharmony_ci// If #ifndef EGL_KHR_no_config_context extension not defined in headers, so just define the values here. 568bf80f4bSopenharmony_ci// (copied from khronos specifications) 578bf80f4bSopenharmony_ci#define EGL_NO_CONFIG_KHR ((EGLConfig)0) 588bf80f4bSopenharmony_ci#endif 598bf80f4bSopenharmony_ci 608bf80f4bSopenharmony_ci#include <securec.h> 618bf80f4bSopenharmony_ci 628bf80f4bSopenharmony_ci#include <render/namespace.h> 638bf80f4bSopenharmony_ci 648bf80f4bSopenharmony_ci#include "gles/gl_functions.h" 658bf80f4bSopenharmony_ci#include "util/log.h" 668bf80f4bSopenharmony_ci#define declare(a, b) a b = nullptr; 678bf80f4bSopenharmony_ci#include "gles/gl_functions.h" 688bf80f4bSopenharmony_ci#define declare(a, b) a b = nullptr; 698bf80f4bSopenharmony_ci#include "gles/egl_functions.h" 708bf80f4bSopenharmony_ci#include "gles/surface_information.h" 718bf80f4bSopenharmony_ci#include "gles/swapchain_gles.h" 728bf80f4bSopenharmony_ci 738bf80f4bSopenharmony_ci#if RENDER_GL_DEBUG 748bf80f4bSopenharmony_ci#define CHECK_EGL_ERROR() EGLHelpers::CheckEGLError(PLUGIN_FILE_INFO) 758bf80f4bSopenharmony_ci#define CHECK_EGL_ERROR2() EGLHelpers::CheckEGLError2(PLUGIN_FILE_INFO) 768bf80f4bSopenharmony_ci#else 778bf80f4bSopenharmony_ci#define CHECK_EGL_ERROR() 788bf80f4bSopenharmony_ci#define CHECK_EGL_ERROR2() EGLHelpers::CheckEGLError2(PLUGIN_FILE_INFO) 798bf80f4bSopenharmony_ci#endif 808bf80f4bSopenharmony_ci 818bf80f4bSopenharmony_ciRENDER_BEGIN_NAMESPACE() 828bf80f4bSopenharmony_ciusing BASE_NS::string; 838bf80f4bSopenharmony_ciusing BASE_NS::string_view; 848bf80f4bSopenharmony_ciusing BASE_NS::vector; 858bf80f4bSopenharmony_ci 868bf80f4bSopenharmony_cinamespace EGLHelpers { 878bf80f4bSopenharmony_cinamespace { 888bf80f4bSopenharmony_cistatic bool FilterError( 898bf80f4bSopenharmony_ci GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei, const string_view, const void*) noexcept 908bf80f4bSopenharmony_ci{ 918bf80f4bSopenharmony_ci if (source == GL_DEBUG_SOURCE_OTHER) { 928bf80f4bSopenharmony_ci if (type == GL_DEBUG_TYPE_PERFORMANCE) { 938bf80f4bSopenharmony_ci if ((id == 2147483647) && (severity == GL_DEBUG_SEVERITY_HIGH)) { // 2147483647:big data 948bf80f4bSopenharmony_ci /* Ignore the following warning that Adreno drivers seem to spam. 958bf80f4bSopenharmony_ci source: GL_DEBUG_SOURCE_OTHER 968bf80f4bSopenharmony_ci type: GL_DEBUG_TYPE_PERFORMANCE 978bf80f4bSopenharmony_ci id: 2147483647 988bf80f4bSopenharmony_ci severity: GL_DEBUG_SEVERITY_HIGH 998bf80f4bSopenharmony_ci message: FreeAllocationOnTimestamp - WaitForTimestamp 1008bf80f4bSopenharmony_ci */ 1018bf80f4bSopenharmony_ci return true; 1028bf80f4bSopenharmony_ci } 1038bf80f4bSopenharmony_ci } 1048bf80f4bSopenharmony_ci } 1058bf80f4bSopenharmony_ci return false; 1068bf80f4bSopenharmony_ci} 1078bf80f4bSopenharmony_ci 1088bf80f4bSopenharmony_ciconst char* EglErrorStr(EGLint aError) 1098bf80f4bSopenharmony_ci{ 1108bf80f4bSopenharmony_ci switch (aError) { 1118bf80f4bSopenharmony_ci case EGL_SUCCESS: 1128bf80f4bSopenharmony_ci return "The last function succeeded without error."; 1138bf80f4bSopenharmony_ci case EGL_NOT_INITIALIZED: 1148bf80f4bSopenharmony_ci return "EGL is not initialized, or could not be initialized, for the specified EGL display connection."; 1158bf80f4bSopenharmony_ci case EGL_BAD_ACCESS: 1168bf80f4bSopenharmony_ci return "EGL cannot access a requested resource(for example a context is bound in another thread)."; 1178bf80f4bSopenharmony_ci case EGL_BAD_ALLOC: 1188bf80f4bSopenharmony_ci return "EGL failed to allocate resources for the requested operation."; 1198bf80f4bSopenharmony_ci case EGL_BAD_ATTRIBUTE: 1208bf80f4bSopenharmony_ci return "An unrecognized attribute or attribute value was passed in the attribute list."; 1218bf80f4bSopenharmony_ci case EGL_BAD_CONTEXT: 1228bf80f4bSopenharmony_ci return "An EGLContext argument does not name a valid EGL rendering context."; 1238bf80f4bSopenharmony_ci case EGL_BAD_CONFIG: 1248bf80f4bSopenharmony_ci return "An EGLConfig argument does not name a valid EGL frame buffer configuration."; 1258bf80f4bSopenharmony_ci case EGL_BAD_CURRENT_SURFACE: 1268bf80f4bSopenharmony_ci return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer " 1278bf80f4bSopenharmony_ci "valid."; 1288bf80f4bSopenharmony_ci case EGL_BAD_DISPLAY: 1298bf80f4bSopenharmony_ci return "An EGLDisplay argument does not name a valid EGL display connection."; 1308bf80f4bSopenharmony_ci case EGL_BAD_SURFACE: 1318bf80f4bSopenharmony_ci return "An EGLSurface argument does not name a valid surface(window, pixel buffer or pixmap) configured " 1328bf80f4bSopenharmony_ci "for GL rendering."; 1338bf80f4bSopenharmony_ci case EGL_BAD_MATCH: 1348bf80f4bSopenharmony_ci return "Arguments are inconsistent (for example, a valid context requires buffers not supplied by a valid " 1358bf80f4bSopenharmony_ci "surface)."; 1368bf80f4bSopenharmony_ci case EGL_BAD_PARAMETER: 1378bf80f4bSopenharmony_ci return "One or more argument values are invalid."; 1388bf80f4bSopenharmony_ci case EGL_BAD_NATIVE_PIXMAP: 1398bf80f4bSopenharmony_ci return "A NativePixmapType argument does not refer to a valid native pixmap."; 1408bf80f4bSopenharmony_ci case EGL_BAD_NATIVE_WINDOW: 1418bf80f4bSopenharmony_ci return "A NativeWindowType argument does not refer to a valid native window."; 1428bf80f4bSopenharmony_ci case EGL_CONTEXT_LOST: 1438bf80f4bSopenharmony_ci return "A power management event has occurred.The application must destroy all contexts and reinitialise " 1448bf80f4bSopenharmony_ci "OpenGL ES state and objects to continue rendering."; 1458bf80f4bSopenharmony_ci default: 1468bf80f4bSopenharmony_ci break; 1478bf80f4bSopenharmony_ci } 1488bf80f4bSopenharmony_ci 1498bf80f4bSopenharmony_ci static char error[64]; 1508bf80f4bSopenharmony_ci if (sprintf_s(error, sizeof(error), "Unknown error %x", aError) < 0) { 1518bf80f4bSopenharmony_ci PLUGIN_LOG_E("EglErrorStr: sprintf_s failed"); 1528bf80f4bSopenharmony_ci } 1538bf80f4bSopenharmony_ci return error; 1548bf80f4bSopenharmony_ci} 1558bf80f4bSopenharmony_ci 1568bf80f4bSopenharmony_civoid CheckEGLError(const char* const file, int line) 1578bf80f4bSopenharmony_ci{ 1588bf80f4bSopenharmony_ci EGLint error = eglGetError(); 1598bf80f4bSopenharmony_ci if (error != EGL_SUCCESS) { 1608bf80f4bSopenharmony_ci PLUGIN_LOG_E("eglGetError failed : %s (%s %d)", EglErrorStr(error), file, line); 1618bf80f4bSopenharmony_ci PLUGIN_ASSERT(false); 1628bf80f4bSopenharmony_ci } 1638bf80f4bSopenharmony_ci} 1648bf80f4bSopenharmony_ci 1658bf80f4bSopenharmony_civoid CheckEGLError2(const char* const file, int line) 1668bf80f4bSopenharmony_ci{ 1678bf80f4bSopenharmony_ci EGLint error = eglGetError(); 1688bf80f4bSopenharmony_ci if (error != EGL_SUCCESS) { 1698bf80f4bSopenharmony_ci PLUGIN_LOG_E("eglGetError failed : %s (%s %d)", EglErrorStr(error), file, line); 1708bf80f4bSopenharmony_ci } 1718bf80f4bSopenharmony_ci} 1728bf80f4bSopenharmony_ci 1738bf80f4bSopenharmony_ci#define ATTRIBUTE(_attr) \ 1748bf80f4bSopenharmony_ci { \ 1758bf80f4bSopenharmony_ci _attr, #_attr \ 1768bf80f4bSopenharmony_ci } 1778bf80f4bSopenharmony_ci 1788bf80f4bSopenharmony_cistruct Attribute { 1798bf80f4bSopenharmony_ci EGLint attribute; 1808bf80f4bSopenharmony_ci char const* const Name; 1818bf80f4bSopenharmony_ci}; 1828bf80f4bSopenharmony_ci 1838bf80f4bSopenharmony_civoid DumpEGLStrings(EGLDisplay dpy) 1848bf80f4bSopenharmony_ci{ 1858bf80f4bSopenharmony_ci // extensions dumped later. 1868bf80f4bSopenharmony_ci static constexpr Attribute strings[] = { ATTRIBUTE(EGL_CLIENT_APIS), ATTRIBUTE(EGL_VENDOR), 1878bf80f4bSopenharmony_ci ATTRIBUTE(EGL_VERSION) }; 1888bf80f4bSopenharmony_ci for (size_t attr = 0; attr < sizeof(strings) / sizeof(Attribute); attr++) { 1898bf80f4bSopenharmony_ci const char* const value = eglQueryString(dpy, strings[attr].attribute); 1908bf80f4bSopenharmony_ci if (value) { 1918bf80f4bSopenharmony_ci PLUGIN_LOG_D("\t%-32s: %s", strings[attr].Name, value); 1928bf80f4bSopenharmony_ci } else { 1938bf80f4bSopenharmony_ci PLUGIN_LOG_D("\t%-32s:", strings[attr].Name); 1948bf80f4bSopenharmony_ci } 1958bf80f4bSopenharmony_ci } 1968bf80f4bSopenharmony_ci} 1978bf80f4bSopenharmony_ci 1988bf80f4bSopenharmony_ci#ifdef PLUGIN_UNUSED_EGL_HELPERS 1998bf80f4bSopenharmony_civoid DumpEGLConfigs(EGLDisplay dpy) 2008bf80f4bSopenharmony_ci{ 2018bf80f4bSopenharmony_ci EGLConfig* configs = nullptr; 2028bf80f4bSopenharmony_ci EGLint n = 0; 2038bf80f4bSopenharmony_ci 2048bf80f4bSopenharmony_ci eglGetConfigs(dpy, NULL, 0, &n); 2058bf80f4bSopenharmony_ci configs = new EGLConfig[(size_t)n]; 2068bf80f4bSopenharmony_ci eglGetConfigs(dpy, configs, n, &n); 2078bf80f4bSopenharmony_ci for (EGLint i = 0; i < n; i++) { 2088bf80f4bSopenharmony_ci PLUGIN_LOG_V("EGLConfig[%d]", i); 2098bf80f4bSopenharmony_ci DumpEGLConfig(dpy, configs[i]); 2108bf80f4bSopenharmony_ci } 2118bf80f4bSopenharmony_ci delete[] configs; 2128bf80f4bSopenharmony_ci} 2138bf80f4bSopenharmony_ci#endif 2148bf80f4bSopenharmony_ci 2158bf80f4bSopenharmony_cibool stringToUInt(string_view string, EGLint& value) 2168bf80f4bSopenharmony_ci{ 2178bf80f4bSopenharmony_ci value = 0; 2188bf80f4bSopenharmony_ci for (auto digit : string) { 2198bf80f4bSopenharmony_ci value *= 10; 2208bf80f4bSopenharmony_ci if ((digit >= '0') && (digit <= '9')) { 2218bf80f4bSopenharmony_ci value += digit - '0'; 2228bf80f4bSopenharmony_ci } else { 2238bf80f4bSopenharmony_ci return false; 2248bf80f4bSopenharmony_ci } 2258bf80f4bSopenharmony_ci } 2268bf80f4bSopenharmony_ci return true; 2278bf80f4bSopenharmony_ci} 2288bf80f4bSopenharmony_ci 2298bf80f4bSopenharmony_civoid DumpEGLSurface(EGLDisplay dpy, EGLSurface surf) 2308bf80f4bSopenharmony_ci{ 2318bf80f4bSopenharmony_ci static constexpr Attribute attribs[] = { 2328bf80f4bSopenharmony_ci // Returns the ID of the EGL frame buffer configuration with respect to which the surface was created. 2338bf80f4bSopenharmony_ci ATTRIBUTE(EGL_CONFIG_ID), 2348bf80f4bSopenharmony_ci // Returns the color space used by OpenGL and OpenGL ES when rendering to the surface, either 2358bf80f4bSopenharmony_ci // EGL_GL_COLORSPACE_SRGB or EGL_GL_COLORSPACE_LINEAR. 2368bf80f4bSopenharmony_ci ATTRIBUTE(EGL_GL_COLORSPACE), 2378bf80f4bSopenharmony_ci // Returns the height of the surface in pixels 2388bf80f4bSopenharmony_ci ATTRIBUTE(EGL_HEIGHT), 2398bf80f4bSopenharmony_ci // Returns the horizontal dot pitch of the display on which a window surface is visible.The value returned is 2408bf80f4bSopenharmony_ci // equal to the actual dot pitch, in pixels meter, multiplied by the constant value EGL_DISPLAY_SCALING. 2418bf80f4bSopenharmony_ci ATTRIBUTE(EGL_HORIZONTAL_RESOLUTION), 2428bf80f4bSopenharmony_ci // Returns the same attribute value specified when the surface was created with eglCreatePbufferSurface.For a 2438bf80f4bSopenharmony_ci // window or pixmap surface, value is not modified. 2448bf80f4bSopenharmony_ci ATTRIBUTE(EGL_LARGEST_PBUFFER), 2458bf80f4bSopenharmony_ci ATTRIBUTE(EGL_MIPMAP_LEVEL), // Returns which level of the mipmap to render to, if texture has mipmaps. 2468bf80f4bSopenharmony_ci ATTRIBUTE(EGL_MIPMAP_TEXTURE), // Returns EGL_TRUE if texture has mipmaps, EGL_FALSE otherwise. 2478bf80f4bSopenharmony_ci // Returns the filter used when resolving the multisample buffer.The filter may be either 2488bf80f4bSopenharmony_ci // EGL_MULTISAMPLE_RESOLVE_DEFAULT or EGL_MULTISAMPLE_RESOLVE_BOX, as described for eglSurfaceAttrib. 2498bf80f4bSopenharmony_ci ATTRIBUTE(EGL_MULTISAMPLE_RESOLVE), 2508bf80f4bSopenharmony_ci // Returns the aspect ratio of an individual pixel(the ratio of a pixel's width to its height). The value 2518bf80f4bSopenharmony_ci // returned is equal to the actual aspect ratio multiplied by the constant value EGL_DISPLAY_SCALING. 2528bf80f4bSopenharmony_ci ATTRIBUTE(EGL_PIXEL_ASPECT_RATIO), 2538bf80f4bSopenharmony_ci // Returns the buffer which client API rendering is requested to use.For a window surface, this is the same 2548bf80f4bSopenharmony_ci // attribute value specified when the surface was created.For a pbuffer surface, it is always 2558bf80f4bSopenharmony_ci // EGL_BACK_BUFFER.For a pixmap surface, it is always EGL_SINGLE_BUFFER.To determine the actual buffer being 2568bf80f4bSopenharmony_ci // rendered to by a context, call eglQueryContext. 2578bf80f4bSopenharmony_ci ATTRIBUTE(EGL_RENDER_BUFFER), 2588bf80f4bSopenharmony_ci // Returns the effect on the color buffer when posting a surface with eglSwapBuffers.Swap behavior may be either 2598bf80f4bSopenharmony_ci // EGL_BUFFER_PRESERVED or EGL_BUFFER_DESTROYED, as described for eglSurfaceAttrib. 2608bf80f4bSopenharmony_ci ATTRIBUTE(EGL_SWAP_BEHAVIOR), 2618bf80f4bSopenharmony_ci // Returns format of texture.Possible values are EGL_NO_TEXTURE, EGL_TEXTURE_RGB, and EGL_TEXTURE_RGBA. 2628bf80f4bSopenharmony_ci ATTRIBUTE(EGL_TEXTURE_FORMAT), 2638bf80f4bSopenharmony_ci ATTRIBUTE(EGL_TEXTURE_TARGET), // Returns type of texture.Possible values are EGL_NO_TEXTURE, or EGL_TEXTURE_2D. 2648bf80f4bSopenharmony_ci // Returns the vertical dot pitch of the display on which a window surface is visible.The value returned is 2658bf80f4bSopenharmony_ci // equal to the actual dot pitch, in pixels / meter, multiplied by the constant value EGL_DISPLAY_SCALING. 2668bf80f4bSopenharmony_ci ATTRIBUTE(EGL_VERTICAL_RESOLUTION), 2678bf80f4bSopenharmony_ci // Returns the interpretation of alpha values used by OpenVG when rendering to the surface, either 2688bf80f4bSopenharmony_ci // EGL_VG_ALPHA_FORMAT_NONPRE or EGL_VG_ALPHA_FORMAT_PRE. 2698bf80f4bSopenharmony_ci ATTRIBUTE(EGL_VG_ALPHA_FORMAT), 2708bf80f4bSopenharmony_ci // Returns the color space used by OpenVG when rendering to the surface, either EGL_VG_COLORSPACE_sRGB or 2718bf80f4bSopenharmony_ci // EGL_VG_COLORSPACE_LINEAR. 2728bf80f4bSopenharmony_ci ATTRIBUTE(EGL_VG_COLORSPACE), 2738bf80f4bSopenharmony_ci ATTRIBUTE(EGL_WIDTH), // Returns the width of the surface in pixels. 2748bf80f4bSopenharmony_ci }; 2758bf80f4bSopenharmony_ci for (size_t attr = 0; attr < sizeof(attribs) / sizeof(Attribute); attr++) { 2768bf80f4bSopenharmony_ci EGLint value; 2778bf80f4bSopenharmony_ci if (EGL_TRUE == eglQuerySurface(dpy, surf, attribs[attr].attribute, &value)) { 2788bf80f4bSopenharmony_ci PLUGIN_LOG_V("\t%-32s: %10d (0x%08x)", attribs[attr].Name, value, value); 2798bf80f4bSopenharmony_ci } 2808bf80f4bSopenharmony_ci } 2818bf80f4bSopenharmony_ci} 2828bf80f4bSopenharmony_ci 2838bf80f4bSopenharmony_civoid DumpEGLConfig(EGLDisplay dpy, const EGLConfig& config) 2848bf80f4bSopenharmony_ci{ 2858bf80f4bSopenharmony_ci static constexpr Attribute attributes[] = { 2868bf80f4bSopenharmony_ci ATTRIBUTE(EGL_ALPHA_SIZE), // Returns the number of bits of alpha stored in the color buffer. 2878bf80f4bSopenharmony_ci ATTRIBUTE(EGL_ALPHA_MASK_SIZE), // Returns the number of bits in the alpha mask buffer. 2888bf80f4bSopenharmony_ci // Returns EGL_TRUE if color buffers can be bound to an RGB texture, EGL_FALSE otherwise. 2898bf80f4bSopenharmony_ci ATTRIBUTE(EGL_BIND_TO_TEXTURE_RGB), 2908bf80f4bSopenharmony_ci // Returns EGL_TRUE if color buffers can be bound to an RGBA texture, EGL_FALSE otherwise. 2918bf80f4bSopenharmony_ci ATTRIBUTE(EGL_BIND_TO_TEXTURE_RGBA), 2928bf80f4bSopenharmony_ci ATTRIBUTE(EGL_BLUE_SIZE), // Returns the number of bits of blue stored in the color buffer. 2938bf80f4bSopenharmony_ci // Returns the depth of the color buffer.It is the sum of EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE, and 2948bf80f4bSopenharmony_ci // EGL_ALPHA_SIZE. 2958bf80f4bSopenharmony_ci ATTRIBUTE(EGL_BUFFER_SIZE), 2968bf80f4bSopenharmony_ci // Returns the color buffer type.Possible types are EGL_RGB_BUFFER and EGL_LUMINANCE_BUFFER. 2978bf80f4bSopenharmony_ci ATTRIBUTE(EGL_COLOR_BUFFER_TYPE), 2988bf80f4bSopenharmony_ci // Returns the caveats for the frame buffer configuration.Possible caveat values are EGL_NONE, EGL_SLOW_CONFIG, 2998bf80f4bSopenharmony_ci // and EGL_NON_CONFORMANT. 3008bf80f4bSopenharmony_ci ATTRIBUTE(EGL_CONFIG_CAVEAT), 3018bf80f4bSopenharmony_ci ATTRIBUTE(EGL_CONFIG_ID), // Returns the ID of the frame buffer configuration. 3028bf80f4bSopenharmony_ci // Returns a bitmask indicating which client API contexts created with respect to this 3038bf80f4bSopenharmony_ci // config are conformant. 3048bf80f4bSopenharmony_ci ATTRIBUTE(EGL_CONFORMANT), 3058bf80f4bSopenharmony_ci ATTRIBUTE(EGL_DEPTH_SIZE), // Returns the number of bits in the depth buffer. 3068bf80f4bSopenharmony_ci ATTRIBUTE(EGL_GREEN_SIZE), // Returns the number of bits of green stored in the color buffer. 3078bf80f4bSopenharmony_ci // Returns the frame buffer level.Level zero is the default frame buffer.Positive levels correspond to frame 3088bf80f4bSopenharmony_ci // buffers that overlay the default buffer and negative levels correspond to frame buffers that underlay the 3098bf80f4bSopenharmony_ci // default buffer. 3108bf80f4bSopenharmony_ci ATTRIBUTE(EGL_LEVEL), 3118bf80f4bSopenharmony_ci ATTRIBUTE(EGL_LUMINANCE_SIZE), // Returns the number of bits of luminance stored in the luminance buffer. 3128bf80f4bSopenharmony_ci ATTRIBUTE(EGL_MAX_PBUFFER_WIDTH), // Returns the maximum width of a pixel buffer surface in pixels. 3138bf80f4bSopenharmony_ci ATTRIBUTE(EGL_MAX_PBUFFER_HEIGHT), // Returns the maximum height of a pixel buffer surface in pixels. 3148bf80f4bSopenharmony_ci ATTRIBUTE(EGL_MAX_PBUFFER_PIXELS), // Returns the maximum size of a pixel buffer surface in pixels. 3158bf80f4bSopenharmony_ci ATTRIBUTE(EGL_MAX_SWAP_INTERVAL), // Returns the maximum value that can be passed to eglSwapInterval. 3168bf80f4bSopenharmony_ci ATTRIBUTE(EGL_MIN_SWAP_INTERVAL), // Returns the minimum value that can be passed to eglSwapInterval. 3178bf80f4bSopenharmony_ci // Returns EGL_TRUE if native rendering APIs can render into the surface, EGL_FALSE otherwise. 3188bf80f4bSopenharmony_ci ATTRIBUTE(EGL_NATIVE_RENDERABLE), 3198bf80f4bSopenharmony_ci ATTRIBUTE(EGL_NATIVE_VISUAL_ID), // Returns the ID of the associated native visual. 3208bf80f4bSopenharmony_ci ATTRIBUTE(EGL_NATIVE_VISUAL_TYPE), // Returns the type of the associated native visual. 3218bf80f4bSopenharmony_ci ATTRIBUTE(EGL_RED_SIZE), // Returns the number of bits of red stored in the color buffer. 3228bf80f4bSopenharmony_ci ATTRIBUTE(EGL_RENDERABLE_TYPE), // Returns a bitmask indicating the types of supported client API contexts. 3238bf80f4bSopenharmony_ci ATTRIBUTE(EGL_SAMPLE_BUFFERS), // Returns the number of multisample buffers. 3248bf80f4bSopenharmony_ci ATTRIBUTE(EGL_SAMPLES), // Returns the number of samples per pixel. 3258bf80f4bSopenharmony_ci ATTRIBUTE(EGL_STENCIL_SIZE), // Returns the number of bits in the stencil buffer. 3268bf80f4bSopenharmony_ci ATTRIBUTE(EGL_SURFACE_TYPE), // Returns a bitmask indicating the types of supported EGL surfaces. 3278bf80f4bSopenharmony_ci // Returns the type of supported transparency.Possible transparency values are EGL_NONE, and 3288bf80f4bSopenharmony_ci // EGL_TRANSPARENT_RGB. 3298bf80f4bSopenharmony_ci ATTRIBUTE(EGL_TRANSPARENT_TYPE), 3308bf80f4bSopenharmony_ci ATTRIBUTE(EGL_TRANSPARENT_RED_VALUE), // Returns the transparent red value. 3318bf80f4bSopenharmony_ci ATTRIBUTE(EGL_TRANSPARENT_GREEN_VALUE), // Returns the transparent green value. 3328bf80f4bSopenharmony_ci ATTRIBUTE(EGL_TRANSPARENT_BLUE_VALUE), // Returns the transparent blue value. 3338bf80f4bSopenharmony_ci // ATTRIBUTE(EGL_MATCH_NATIVE_PIXMAP), While EGL_MATCH_NATIVE_PIXMAP can be specified in the attribute list 3348bf80f4bSopenharmony_ci // passed to eglChooseConfig, it is not an attribute of the resulting config and cannot be queried using 3358bf80f4bSopenharmony_ci // eglGetConfigAttrib. 3368bf80f4bSopenharmony_ci }; 3378bf80f4bSopenharmony_ci for (size_t attr = 0; attr < sizeof(attributes) / sizeof(Attribute); attr++) { 3388bf80f4bSopenharmony_ci EGLint value; 3398bf80f4bSopenharmony_ci if (EGL_TRUE == eglGetConfigAttrib(dpy, config, attributes[attr].attribute, &value)) { 3408bf80f4bSopenharmony_ci PLUGIN_LOG_V("\t%-32s: %10d (0x%08x)", attributes[attr].Name, value, value); 3418bf80f4bSopenharmony_ci } 3428bf80f4bSopenharmony_ci } 3438bf80f4bSopenharmony_ci} 3448bf80f4bSopenharmony_ci 3458bf80f4bSopenharmony_civoid ParseExtensions(const string& extensions, vector<string_view>& extensionList) 3468bf80f4bSopenharmony_ci{ 3478bf80f4bSopenharmony_ci size_t start = 0; 3488bf80f4bSopenharmony_ci for (auto end = extensions.find(' '); end != string::npos; end = extensions.find(' ', start)) { 3498bf80f4bSopenharmony_ci extensionList.emplace_back(extensions.data() + start, end - start); 3508bf80f4bSopenharmony_ci start = end + 1; 3518bf80f4bSopenharmony_ci } 3528bf80f4bSopenharmony_ci if (start < extensions.size()) { 3538bf80f4bSopenharmony_ci extensionList.emplace_back(extensions.data() + start); 3548bf80f4bSopenharmony_ci } 3558bf80f4bSopenharmony_ci} 3568bf80f4bSopenharmony_ci 3578bf80f4bSopenharmony_civoid FillProperties(DevicePropertiesGLES& properties) 3588bf80f4bSopenharmony_ci{ 3598bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &properties.maxCombinedTextureImageUnits); 3608bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &properties.maxCubeMapTextureSize); 3618bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &properties.maxFragmentUniformVectors); 3628bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &properties.maxRenderbufferSize); 3638bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &properties.maxTextureImageUnits); 3648bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_TEXTURE_SIZE, &properties.maxTextureSize); 3658bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VARYING_VECTORS, &properties.maxVaryingVectors); 3668bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &properties.maxVertexAttribs); 3678bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &properties.maxVertexTextureImageUnits); 3688bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &properties.maxVertexUniformVectors); 3698bf80f4bSopenharmony_ci glGetFloatv(GL_MAX_VIEWPORT_DIMS, properties.maxViewportDims); 3708bf80f4bSopenharmony_ci glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &properties.numCompressedTextureFormats); 3718bf80f4bSopenharmony_ci glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &properties.numShaderBinaryFormats); 3728bf80f4bSopenharmony_ci glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &properties.numProgramBinaryFormats); 3738bf80f4bSopenharmony_ci 3748bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &properties.max3DTextureSize); 3758bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &properties.maxArrayTextureLayers); 3768bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &properties.maxColorAttachments); 3778bf80f4bSopenharmony_ci glGetInteger64v(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, &properties.maxCombinedFragmentUniformComponents); 3788bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, &properties.maxCombinedUniformBlocks); 3798bf80f4bSopenharmony_ci glGetInteger64v(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, &properties.maxCombinedVertexUniformComponents); 3808bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_DRAW_BUFFERS, &properties.maxDrawBuffers); 3818bf80f4bSopenharmony_ci glGetInteger64v(GL_MAX_ELEMENT_INDEX, &properties.maxElementIndex); 3828bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &properties.maxElementsIndices); 3838bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &properties.maxElementsVertices); 3848bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, &properties.maxFragmentInputComponents); 3858bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &properties.maxFragmentUniformBlocks); 3868bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &properties.maxFragmentUniformComponents); 3878bf80f4bSopenharmony_ci glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &properties.minProgramTexelOffset); 3888bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &properties.maxProgramTexelOffset); 3898bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_SAMPLES, &properties.maxSamples); 3908bf80f4bSopenharmony_ci glGetInteger64v(GL_MAX_SERVER_WAIT_TIMEOUT, &properties.maxServerWaitTimeout); 3918bf80f4bSopenharmony_ci glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &properties.maxTextureLodBias); 3928bf80f4bSopenharmony_ci glGetIntegerv( 3938bf80f4bSopenharmony_ci GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &properties.maxTransformFeedbackInterleavedComponents); 3948bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &properties.maxTransformFeedbackSeparateAttribs); 3958bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &properties.maxTransformFeedbackSeparateComponents); 3968bf80f4bSopenharmony_ci glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &properties.maxUniformBlockSize); 3978bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &properties.maxUniformBufferBindings); 3988bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &properties.maxVaryingComponents); 3998bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, &properties.maxVertexOutputComponents); 4008bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &properties.maxVertexUniformBlocks); 4018bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &properties.maxVertexUniformComponents); 4028bf80f4bSopenharmony_ci 4038bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &properties.maxAtomicCounterBufferBindings); 4048bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE, &properties.maxAtomicCounterBufferSize); 4058bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &properties.maxColorTextureSamples); 4068bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTERS, &properties.maxCombinedAtomicCounters); 4078bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS, &properties.maxCombinedAtomicCounterBuffers); 4088bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS, &properties.maxCombinedComputeUniformComponents); 4098bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMBINED_IMAGE_UNIFORMS, &properties.maxCombinedImageUniforms); 4108bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, &properties.maxCombinedShaderOutputResources); 4118bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &properties.maxCombinedShaderStorageBlocks); 4128bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTERS, &properties.maxComputeAtomicCounters); 4138bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &properties.maxComputeAtomicCounterBuffers); 4148bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMPUTE_IMAGE_UNIFORMS, &properties.maxComputeImageUniforms); 4158bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &properties.maxComputeShaderStorageBlocks); 4168bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, &properties.maxComputeSharedMemorySize); 4178bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &properties.maxComputeTextureImageUnits); 4188bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_BLOCKS, &properties.maxComputeUniformBlocks); 4198bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_COMPONENTS, &properties.maxComputeUniformComponents); 4208bf80f4bSopenharmony_ci glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, properties.maxComputeWorkGroupCount); 4218bf80f4bSopenharmony_ci glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, properties.maxComputeWorkGroupCount + 1); 4228bf80f4bSopenharmony_ci glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, properties.maxComputeWorkGroupCount + 2); // 2 : param 4238bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &properties.maxComputeWorkGroupInvocations); 4248bf80f4bSopenharmony_ci glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, properties.maxComputeWorkGroupSize); 4258bf80f4bSopenharmony_ci glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, properties.maxComputeWorkGroupSize + 1); 4268bf80f4bSopenharmony_ci glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, properties.maxComputeWorkGroupSize + 2); // 2 : param 4278bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &properties.maxDepthTextureSamples); 4288bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, &properties.maxFragmentAtomicCounters); 4298bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &properties.maxFragmentAtomicCounterBuffers); 4308bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &properties.maxFragmentImageUniforms); 4318bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &properties.maxFragmentShaderStorageBlocks); 4328bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_FRAMEBUFFER_HEIGHT, &properties.maxFramebufferHeight); 4338bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_FRAMEBUFFER_SAMPLES, &properties.maxFramebufferSamples); 4348bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_FRAMEBUFFER_WIDTH, &properties.maxFramebufferWidth); 4358bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_IMAGE_UNITS, &properties.maxImageUnits); 4368bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &properties.maxIntegerSamples); 4378bf80f4bSopenharmony_ci glGetIntegerv(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET, &properties.minProgramTextureGatherOffset); 4388bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET, &properties.maxProgramTextureGatherOffset); 4398bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &properties.maxSampleMaskWords); 4408bf80f4bSopenharmony_ci glGetInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &properties.maxShaderStorageBlockSize); 4418bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &properties.maxShaderStorageBufferBindings); 4428bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, &properties.maxUniformLocations); 4438bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, &properties.maxVertexAtomicCounters); 4448bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS, &properties.maxVertexAtomicCounterBuffers); 4458bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &properties.maxVertexAttribBindings); 4468bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &properties.maxVertexAttribRelativeOffset); 4478bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &properties.maxVertexAttribStride); 4488bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &properties.maxVertexImageUniforms); 4498bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &properties.maxVertexShaderStorageBlocks); 4508bf80f4bSopenharmony_ci glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &properties.uniformBufferOffsetAlignment); 4518bf80f4bSopenharmony_ci glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &properties.shaderStorageBufferOffsetAlignment); 4528bf80f4bSopenharmony_ci 4538bf80f4bSopenharmony_ci glGetIntegerv(GL_MIN_SAMPLE_SHADING_VALUE, &properties.minSampleShadingValue); 4548bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_DEBUG_GROUP_STACK_DEPTH, &properties.maxDebugGroupStackDepth); 4558bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_DEBUG_LOGGED_MESSAGES, &properties.maxDebugLoggedMessages); 4568bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, &properties.maxDebugMessageLength); 4578bf80f4bSopenharmony_ci glGetFloatv(GL_MIN_FRAGMENT_INTERPOLATION_OFFSET, &properties.minFragmentInterpolationOffset); 4588bf80f4bSopenharmony_ci glGetFloatv(GL_MAX_FRAGMENT_INTERPOLATION_OFFSET, &properties.maxFragmentInterpolationOffset); 4598bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_FRAMEBUFFER_LAYERS, &properties.maxFramebufferLayers); 4608bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_LABEL_LENGTH, &properties.maxLabelLength); 4618bf80f4bSopenharmony_ci glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &properties.maxTextureBufferSize); 4628bf80f4bSopenharmony_ci} 4638bf80f4bSopenharmony_ci 4648bf80f4bSopenharmony_cibool IsSrgbSurfaceSupported(const DevicePlatformDataGLES& plat) 4658bf80f4bSopenharmony_ci{ 4668bf80f4bSopenharmony_ci // Check if EGL supports sRGB color space (either EGL is > 1.5 or EGL_KHR_gl_colorspace extension is supported). 4678bf80f4bSopenharmony_ci if (plat.majorVersion > 1u || (plat.majorVersion == 1u && plat.minorVersion >= 5u)) { 4688bf80f4bSopenharmony_ci // EGL 1.5 or newer -> no need to check the extension. 4698bf80f4bSopenharmony_ci return true; 4708bf80f4bSopenharmony_ci } 4718bf80f4bSopenharmony_ci // Check if the sRGB color space extension is supported. 4728bf80f4bSopenharmony_ci return plat.hasColorSpaceExt; 4738bf80f4bSopenharmony_ci} 4748bf80f4bSopenharmony_ci 4758bf80f4bSopenharmony_ci} // namespace 4768bf80f4bSopenharmony_ci 4778bf80f4bSopenharmony_ci#undef ATTRIBUTE 4788bf80f4bSopenharmony_civoid EGLState::HandleExtensions() 4798bf80f4bSopenharmony_ci{ 4808bf80f4bSopenharmony_ci if (plat_.minorVersion > 4) { 4818bf80f4bSopenharmony_ci cextensions_ = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); 4828bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 4838bf80f4bSopenharmony_ci PLUGIN_LOG_D("\t%-32s: %s", "EGL_EXTENSIONS (CLIENT)", cextensions_.c_str()); 4848bf80f4bSopenharmony_ci ParseExtensions(cextensions_, cextensionList_); 4858bf80f4bSopenharmony_ci } 4868bf80f4bSopenharmony_ci 4878bf80f4bSopenharmony_ci dextensions_ = eglQueryString(plat_.display, EGL_EXTENSIONS); 4888bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 4898bf80f4bSopenharmony_ci ParseExtensions(dextensions_, dextensionList_); 4908bf80f4bSopenharmony_ci PLUGIN_LOG_D("\t%-32s: %s", "EGL_EXTENSIONS (DISPLAY)", dextensions_.c_str()); 4918bf80f4bSopenharmony_ci} 4928bf80f4bSopenharmony_ci 4938bf80f4bSopenharmony_ciuint32_t EGLState::MajorVersion() const 4948bf80f4bSopenharmony_ci{ 4958bf80f4bSopenharmony_ci return plat_.majorVersion; 4968bf80f4bSopenharmony_ci} 4978bf80f4bSopenharmony_ci 4988bf80f4bSopenharmony_ciuint32_t EGLState::MinorVersion() const 4998bf80f4bSopenharmony_ci{ 5008bf80f4bSopenharmony_ci return plat_.minorVersion; 5018bf80f4bSopenharmony_ci} 5028bf80f4bSopenharmony_ci 5038bf80f4bSopenharmony_civoid EGLState::ChooseConfiguration(const BackendExtraGLES* backendConfig) 5048bf80f4bSopenharmony_ci{ 5058bf80f4bSopenharmony_ci EGLint num_configs; 5068bf80f4bSopenharmony_ci // construct attribute list dynamically 5078bf80f4bSopenharmony_ci vector<EGLint> attributes; 5088bf80f4bSopenharmony_ci const size_t ATTRIBUTE_RESERVE = 16; // reserve 16 attributes 5098bf80f4bSopenharmony_ci attributes.reserve(ATTRIBUTE_RESERVE * 2); // 2 EGLints per attribute 5108bf80f4bSopenharmony_ci auto addAttribute = [&attributes](EGLint a, EGLint b) { 5118bf80f4bSopenharmony_ci attributes.push_back(a); 5128bf80f4bSopenharmony_ci attributes.push_back(b); 5138bf80f4bSopenharmony_ci }; 5148bf80f4bSopenharmony_ci // Request OpenGL ES 3.x configs 5158bf80f4bSopenharmony_ci if (IsVersionGreaterOrEqual(1, 5)) { 5168bf80f4bSopenharmony_ci // EGL 1.5+ 5178bf80f4bSopenharmony_ci addAttribute(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT); 5188bf80f4bSopenharmony_ci addAttribute(EGL_CONFORMANT, EGL_OPENGL_ES3_BIT); 5198bf80f4bSopenharmony_ci } else if (HasExtension("EGL_KHR_create_context")) { 5208bf80f4bSopenharmony_ci // "EGL_KHR_create_context" 5218bf80f4bSopenharmony_ci addAttribute(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR); 5228bf80f4bSopenharmony_ci addAttribute(EGL_CONFORMANT, EGL_OPENGL_ES3_BIT_KHR); 5238bf80f4bSopenharmony_ci } else { 5248bf80f4bSopenharmony_ci // We might be in trouble now. 5258bf80f4bSopenharmony_ci addAttribute(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT); 5268bf80f4bSopenharmony_ci addAttribute(EGL_CONFORMANT, EGL_OPENGL_ES2_BIT); 5278bf80f4bSopenharmony_ci } 5288bf80f4bSopenharmony_ci addAttribute(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT); 5298bf80f4bSopenharmony_ci addAttribute(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER); 5308bf80f4bSopenharmony_ci addAttribute(EGL_RED_SIZE, 8); 5318bf80f4bSopenharmony_ci addAttribute(EGL_GREEN_SIZE, 8); 5328bf80f4bSopenharmony_ci addAttribute(EGL_BLUE_SIZE, 8); 5338bf80f4bSopenharmony_ci addAttribute(EGL_CONFIG_CAVEAT, EGL_NONE); 5348bf80f4bSopenharmony_ci if (backendConfig) { 5358bf80f4bSopenharmony_ci if (backendConfig->MSAASamples > 1) { 5368bf80f4bSopenharmony_ci addAttribute(EGL_SAMPLES, (EGLint)backendConfig->MSAASamples); 5378bf80f4bSopenharmony_ci addAttribute(EGL_SAMPLE_BUFFERS, 1); 5388bf80f4bSopenharmony_ci } 5398bf80f4bSopenharmony_ci addAttribute(EGL_ALPHA_SIZE, (EGLint)backendConfig->alphaBits); 5408bf80f4bSopenharmony_ci addAttribute(EGL_DEPTH_SIZE, (EGLint)backendConfig->depthBits); 5418bf80f4bSopenharmony_ci addAttribute(EGL_STENCIL_SIZE, (EGLint)backendConfig->stencilBits); 5428bf80f4bSopenharmony_ci PLUGIN_LOG_I("Samples:%d Alpha:%d Depth:%d Stencil:%d", backendConfig->MSAASamples, backendConfig->alphaBits, 5438bf80f4bSopenharmony_ci backendConfig->depthBits, backendConfig->stencilBits); 5448bf80f4bSopenharmony_ci } 5458bf80f4bSopenharmony_ci addAttribute(EGL_NONE, EGL_NONE); // terminate list 5468bf80f4bSopenharmony_ci eglChooseConfig(plat_.display, attributes.data(), &plat_.config, 1, &num_configs); 5478bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 5488bf80f4bSopenharmony_ci#if RENDER_GL_DEBUG 5498bf80f4bSopenharmony_ci PLUGIN_LOG_I("eglChooseConfig returned:"); 5508bf80f4bSopenharmony_ci DumpEGLConfig(plat_.display, plat_.config); 5518bf80f4bSopenharmony_ci#endif 5528bf80f4bSopenharmony_ci} 5538bf80f4bSopenharmony_ci 5548bf80f4bSopenharmony_civoid EGLState::CreateContext(const BackendExtraGLES* backendConfig) 5558bf80f4bSopenharmony_ci{ 5568bf80f4bSopenharmony_ci vector<EGLint> context_attributes; 5578bf80f4bSopenharmony_ci const size_t ATTRIBUTE_RESERVE = 16; // reserve 16 attributes 5588bf80f4bSopenharmony_ci context_attributes.reserve(ATTRIBUTE_RESERVE * 2); // 2 EGLints per attribute 5598bf80f4bSopenharmony_ci auto addAttribute = [&context_attributes](EGLint a, EGLint b) { 5608bf80f4bSopenharmony_ci context_attributes.push_back(a); 5618bf80f4bSopenharmony_ci context_attributes.push_back(b); 5628bf80f4bSopenharmony_ci }; 5638bf80f4bSopenharmony_ci if (IsVersionGreaterOrEqual(1, 5)) { 5648bf80f4bSopenharmony_ci // egl 1.5 or greater. 5658bf80f4bSopenharmony_ci addAttribute(EGL_CONTEXT_MAJOR_VERSION, 3); // Select an OpenGL ES 3.x context 5668bf80f4bSopenharmony_ci addAttribute(EGL_CONTEXT_MINOR_VERSION, 2); // Select an OpenGL ES x.2 context 5678bf80f4bSopenharmony_ci#if RENDER_GL_DEBUG 5688bf80f4bSopenharmony_ci // should use EGL_CONTEXT_OPENGL_DEBUG , but at least PowerVR simulator fails with this 5698bf80f4bSopenharmony_ci if (HasExtension("EGL_KHR_create_context")) { 5708bf80f4bSopenharmony_ci // Setting up debug context with the extension seems to work. 5718bf80f4bSopenharmony_ci addAttribute(EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR); 5728bf80f4bSopenharmony_ci } 5738bf80f4bSopenharmony_ci#endif 5748bf80f4bSopenharmony_ci } else if (HasExtension("EGL_KHR_create_context")) { 5758bf80f4bSopenharmony_ci // egl 1.4 with EGL_KHR_create_context 5768bf80f4bSopenharmony_ci addAttribute(EGL_CONTEXT_MAJOR_VERSION_KHR, 3); // Select an OpenGL ES 3.x context 5778bf80f4bSopenharmony_ci addAttribute(EGL_CONTEXT_MINOR_VERSION_KHR, 2); // Select an OpenGL ES x.2 context 5788bf80f4bSopenharmony_ci#if RENDER_GL_DEBUG 5798bf80f4bSopenharmony_ci addAttribute(EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR); 5808bf80f4bSopenharmony_ci#endif 5818bf80f4bSopenharmony_ci } else { 5828bf80f4bSopenharmony_ci // fallback to non-extended or pre 1.5 EGL, we expect 3.2 OpenGL context, this is now checked later. 5838bf80f4bSopenharmony_ci addAttribute(EGL_CONTEXT_CLIENT_VERSION, 3); // Select an OpenGL ES 3.x context 5848bf80f4bSopenharmony_ci } 5858bf80f4bSopenharmony_ci addAttribute(EGL_NONE, EGL_NONE); 5868bf80f4bSopenharmony_ci 5878bf80f4bSopenharmony_ci EGLContext sharedContext = EGL_NO_CONTEXT; 5888bf80f4bSopenharmony_ci if (backendConfig) { 5898bf80f4bSopenharmony_ci sharedContext = backendConfig->sharedContext; 5908bf80f4bSopenharmony_ci } 5918bf80f4bSopenharmony_ci plat_.context = eglCreateContext(plat_.display, plat_.config, sharedContext, context_attributes.data()); 5928bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 5938bf80f4bSopenharmony_ci 5948bf80f4bSopenharmony_ci if (plat_.context == EGL_NO_CONTEXT) { 5958bf80f4bSopenharmony_ci PLUGIN_LOG_E("eglCreateContext failed : %s", EglErrorStr(eglGetError())); 5968bf80f4bSopenharmony_ci PLUGIN_ASSERT(false); 5978bf80f4bSopenharmony_ci return; 5988bf80f4bSopenharmony_ci } 5998bf80f4bSopenharmony_ci} 6008bf80f4bSopenharmony_ci 6018bf80f4bSopenharmony_cibool EGLState::IsVersionGreaterOrEqual(uint32_t major, uint32_t minor) const 6028bf80f4bSopenharmony_ci{ 6038bf80f4bSopenharmony_ci if (plat_.majorVersion < major) { 6048bf80f4bSopenharmony_ci return false; 6058bf80f4bSopenharmony_ci } 6068bf80f4bSopenharmony_ci if (plat_.majorVersion > major) { 6078bf80f4bSopenharmony_ci return true; 6088bf80f4bSopenharmony_ci } 6098bf80f4bSopenharmony_ci if (plat_.minorVersion >= minor) { 6108bf80f4bSopenharmony_ci return true; 6118bf80f4bSopenharmony_ci } 6128bf80f4bSopenharmony_ci return false; 6138bf80f4bSopenharmony_ci} 6148bf80f4bSopenharmony_ci 6158bf80f4bSopenharmony_cibool EGLState::VerifyVersion() 6168bf80f4bSopenharmony_ci{ 6178bf80f4bSopenharmony_ci // Verify that we have at least 3.2 context. 6188bf80f4bSopenharmony_ci EGLint glMajor = 0; 6198bf80f4bSopenharmony_ci EGLint glMinor = 0; 6208bf80f4bSopenharmony_ci SaveContext(); 6218bf80f4bSopenharmony_ci SetContext(nullptr); // activate the context with the dummy PBuffer. 6228bf80f4bSopenharmony_ci string_view string((char*)glGetString(GL_VERSION)); 6238bf80f4bSopenharmony_ci // the format according to spec pdf is "OpenGL ES N.M vendor-specific information" 6248bf80f4bSopenharmony_ci bool fail = false; 6258bf80f4bSopenharmony_ci if (string.starts_with("OpenGL ES ")) { 6268bf80f4bSopenharmony_ci // Must be OpenGL ES FULL. Trust this information. (even if it might mismatch with the eglQueryContext results) 6278bf80f4bSopenharmony_ci string_view version = string.substr(10); 6288bf80f4bSopenharmony_ci version = version.substr(0, version.find_first_of(' ')); 6298bf80f4bSopenharmony_ci auto dot = version.find_first_of('.'); 6308bf80f4bSopenharmony_ci auto majorS = version.substr(0, dot); 6318bf80f4bSopenharmony_ci if (dot != string_view::npos) { 6328bf80f4bSopenharmony_ci auto minorS = version.substr(dot + 1); 6338bf80f4bSopenharmony_ci fail = (stringToUInt(minorS, glMinor)) ? fail : false; 6348bf80f4bSopenharmony_ci } 6358bf80f4bSopenharmony_ci fail = (stringToUInt(majorS, glMajor)) ? fail : false; 6368bf80f4bSopenharmony_ci } 6378bf80f4bSopenharmony_ci if (fail) { 6388bf80f4bSopenharmony_ci // Try these then, if parsing the GL_VERSION string failed 6398bf80f4bSopenharmony_ci glMajor = glMinor = 0; 6408bf80f4bSopenharmony_ci eglQueryContext(plat_.display, plat_.context, EGL_CONTEXT_MAJOR_VERSION, &glMajor); 6418bf80f4bSopenharmony_ci eglQueryContext(plat_.display, plat_.context, EGL_CONTEXT_MINOR_VERSION_KHR, &glMinor); 6428bf80f4bSopenharmony_ci } 6438bf80f4bSopenharmony_ci 6448bf80f4bSopenharmony_ci if (glMajor < 3) { 6458bf80f4bSopenharmony_ci fail = true; 6468bf80f4bSopenharmony_ci } else if (glMajor == 3) { 6478bf80f4bSopenharmony_ci if (glMinor < 2) { 6488bf80f4bSopenharmony_ci // We do NOT support 3.0 or 3.1 6498bf80f4bSopenharmony_ci fail = true; 6508bf80f4bSopenharmony_ci } 6518bf80f4bSopenharmony_ci } 6528bf80f4bSopenharmony_ci 6538bf80f4bSopenharmony_ci if (fail) { 6548bf80f4bSopenharmony_ci // restore contexts and cleanup. 6558bf80f4bSopenharmony_ci PLUGIN_LOG_E( 6568bf80f4bSopenharmony_ci "Could not to Initialize required OpenGL ES version [%d.%d] [%s]", glMajor, glMinor, string.data()); 6578bf80f4bSopenharmony_ci RestoreContext(); 6588bf80f4bSopenharmony_ci // destroy the dummy surface also. 6598bf80f4bSopenharmony_ci eglDestroySurface(plat_.display, dummySurface_); 6608bf80f4bSopenharmony_ci dummyContext_.context = EGL_NO_CONTEXT; 6618bf80f4bSopenharmony_ci dummyContext_.drawSurface = dummyContext_.readSurface = EGL_NO_SURFACE; 6628bf80f4bSopenharmony_ci dummyContext_.display = EGL_NO_DISPLAY; 6638bf80f4bSopenharmony_ci } 6648bf80f4bSopenharmony_ci return !fail; 6658bf80f4bSopenharmony_ci} 6668bf80f4bSopenharmony_ci 6678bf80f4bSopenharmony_cibool EGLState::CreateContext(DeviceCreateInfo const& createInfo) 6688bf80f4bSopenharmony_ci{ 6698bf80f4bSopenharmony_ci auto backendConfig = static_cast<const BackendExtraGLES*>(createInfo.backendConfiguration); 6708bf80f4bSopenharmony_ci EGLint major, minor; 6718bf80f4bSopenharmony_ci 6728bf80f4bSopenharmony_ci plat_.display = eglGetDisplay(backendConfig ? backendConfig->display : EGL_DEFAULT_DISPLAY); 6738bf80f4bSopenharmony_ci const EGLContext appContext = backendConfig ? backendConfig->applicationContext : EGL_NO_CONTEXT; 6748bf80f4bSopenharmony_ci const EGLContext sharedContext = backendConfig ? backendConfig->sharedContext : EGL_NO_CONTEXT; 6758bf80f4bSopenharmony_ci if (appContext == EGL_NO_CONTEXT && sharedContext == EGL_NO_CONTEXT) { 6768bf80f4bSopenharmony_ci if (!eglInitialize(plat_.display, &major, &minor)) { 6778bf80f4bSopenharmony_ci PLUGIN_LOG_E("EGL initialization failed"); 6788bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 6798bf80f4bSopenharmony_ci PLUGIN_ASSERT(false); 6808bf80f4bSopenharmony_ci return false; 6818bf80f4bSopenharmony_ci } 6828bf80f4bSopenharmony_ci plat_.eglInitialized = true; 6838bf80f4bSopenharmony_ci } else { 6848bf80f4bSopenharmony_ci major = 0; 6858bf80f4bSopenharmony_ci minor = 0; 6868bf80f4bSopenharmony_ci 6878bf80f4bSopenharmony_ci // Check version from display as we don't call eglInitialize ourselves 6888bf80f4bSopenharmony_ci const string_view version = eglQueryString(plat_.display, EGL_VERSION); 6898bf80f4bSopenharmony_ci if (!version.empty()) { 6908bf80f4bSopenharmony_ci const auto dot = version.find_first_of('.'); 6918bf80f4bSopenharmony_ci if (dot != string_view::npos) { 6928bf80f4bSopenharmony_ci const auto majorS = version.substr(0, dot); 6938bf80f4bSopenharmony_ci if (!stringToUInt(majorS, major)) { 6948bf80f4bSopenharmony_ci major = 0; 6958bf80f4bSopenharmony_ci } 6968bf80f4bSopenharmony_ci const auto space = version.find_first_of(' ', dot + 1); 6978bf80f4bSopenharmony_ci if (space != string_view::npos) { 6988bf80f4bSopenharmony_ci auto minorS = version.substr(dot + 1, space - (dot + 1)); 6998bf80f4bSopenharmony_ci if (!stringToUInt(minorS, minor)) { 7008bf80f4bSopenharmony_ci minor = 0; 7018bf80f4bSopenharmony_ci } 7028bf80f4bSopenharmony_ci } 7038bf80f4bSopenharmony_ci } 7048bf80f4bSopenharmony_ci } else { 7058bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 7068bf80f4bSopenharmony_ci } 7078bf80f4bSopenharmony_ci } 7088bf80f4bSopenharmony_ci plat_.majorVersion = static_cast<uint32_t>(major); 7098bf80f4bSopenharmony_ci plat_.minorVersion = static_cast<uint32_t>(minor); 7108bf80f4bSopenharmony_ci PLUGIN_LOG_I("EGL %d.%d Initialized", major, minor); 7118bf80f4bSopenharmony_ci 7128bf80f4bSopenharmony_ci if (!IsVersionGreaterOrEqual(1, 4)) { 7138bf80f4bSopenharmony_ci // we need atleast egl 1.4 7148bf80f4bSopenharmony_ci PLUGIN_LOG_F("EGL version too old. 1.4 or later requried."); 7158bf80f4bSopenharmony_ci if (plat_.eglInitialized) { 7168bf80f4bSopenharmony_ci eglTerminate(plat_.display); 7178bf80f4bSopenharmony_ci } 7188bf80f4bSopenharmony_ci return false; 7198bf80f4bSopenharmony_ci } 7208bf80f4bSopenharmony_ci 7218bf80f4bSopenharmony_ci eglBindAPI(EGL_OPENGL_ES_API); 7228bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 7238bf80f4bSopenharmony_ci 7248bf80f4bSopenharmony_ci DumpEGLStrings(plat_.display); 7258bf80f4bSopenharmony_ci 7268bf80f4bSopenharmony_ci HandleExtensions(); 7278bf80f4bSopenharmony_ci 7288bf80f4bSopenharmony_ci plat_.hasColorSpaceExt = hasColorSpaceExt_ = HasExtension("EGL_KHR_gl_colorspace"); 7298bf80f4bSopenharmony_ci // NOTE: "EGL_KHR_no_config_context" and "EGL_KHR_surfaceless_context" is technically working, but disabled for now. 7308bf80f4bSopenharmony_ci hasConfiglessExt_ = false; 7318bf80f4bSopenharmony_ci hasSurfacelessExt_ = false; 7328bf80f4bSopenharmony_ci plat_.config = EGL_NO_CONFIG_KHR; 7338bf80f4bSopenharmony_ci if (!hasConfiglessExt_) { 7348bf80f4bSopenharmony_ci // we need a config for the context.. 7358bf80f4bSopenharmony_ci ChooseConfiguration(backendConfig); 7368bf80f4bSopenharmony_ci } 7378bf80f4bSopenharmony_ci 7388bf80f4bSopenharmony_ci if (appContext) { 7398bf80f4bSopenharmony_ci // use applications context 7408bf80f4bSopenharmony_ci PLUGIN_LOG_I("Using application context in DeviceGLES"); 7418bf80f4bSopenharmony_ci plat_.context = appContext; 7428bf80f4bSopenharmony_ci } else { 7438bf80f4bSopenharmony_ci // Create a new context 7448bf80f4bSopenharmony_ci CreateContext(backendConfig); 7458bf80f4bSopenharmony_ci plat_.contextCreated = true; 7468bf80f4bSopenharmony_ci } 7478bf80f4bSopenharmony_ci if (plat_.context == EGL_NO_CONTEXT) { 7488bf80f4bSopenharmony_ci // we have failed then. 7498bf80f4bSopenharmony_ci if (plat_.eglInitialized) { 7508bf80f4bSopenharmony_ci eglTerminate(plat_.display); 7518bf80f4bSopenharmony_ci } 7528bf80f4bSopenharmony_ci return false; 7538bf80f4bSopenharmony_ci } 7548bf80f4bSopenharmony_ci 7558bf80f4bSopenharmony_ci if (!hasSurfacelessExt_) { 7568bf80f4bSopenharmony_ci // Create a placeholder pbuffer, since we do NOT have a surface yet. 7578bf80f4bSopenharmony_ci if (plat_.config == EGL_NO_CONFIG_KHR) { 7588bf80f4bSopenharmony_ci // we need to choose a config for the surface.. 7598bf80f4bSopenharmony_ci ChooseConfiguration(backendConfig); 7608bf80f4bSopenharmony_ci } 7618bf80f4bSopenharmony_ci GLint surface_attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; 7628bf80f4bSopenharmony_ci dummySurface_ = eglCreatePbufferSurface(plat_.display, plat_.config, surface_attribs); 7638bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 7648bf80f4bSopenharmony_ci#if RENDER_GL_DEBUG 7658bf80f4bSopenharmony_ci DumpEGLSurface(plat_.display, dummySurface_); 7668bf80f4bSopenharmony_ci#endif 7678bf80f4bSopenharmony_ci } 7688bf80f4bSopenharmony_ci 7698bf80f4bSopenharmony_ci dummyContext_.context = plat_.context; 7708bf80f4bSopenharmony_ci dummyContext_.drawSurface = dummyContext_.readSurface = dummySurface_; 7718bf80f4bSopenharmony_ci dummyContext_.display = plat_.display; 7728bf80f4bSopenharmony_ci 7738bf80f4bSopenharmony_ci if (!VerifyVersion()) { 7748bf80f4bSopenharmony_ci if (plat_.contextCreated) { 7758bf80f4bSopenharmony_ci eglDestroyContext(plat_.display, plat_.context); 7768bf80f4bSopenharmony_ci plat_.context = EGL_NO_CONTEXT; 7778bf80f4bSopenharmony_ci } 7788bf80f4bSopenharmony_ci if (plat_.eglInitialized) { 7798bf80f4bSopenharmony_ci eglTerminate(plat_.display); 7808bf80f4bSopenharmony_ci } 7818bf80f4bSopenharmony_ci return false; 7828bf80f4bSopenharmony_ci } 7838bf80f4bSopenharmony_ci return true; 7848bf80f4bSopenharmony_ci} 7858bf80f4bSopenharmony_ci 7868bf80f4bSopenharmony_civoid EGLState::GlInitialize() 7878bf80f4bSopenharmony_ci{ 7888bf80f4bSopenharmony_ci#define declare(a, b) \ 7898bf80f4bSopenharmony_ci if (b == nullptr) { \ 7908bf80f4bSopenharmony_ci *(reinterpret_cast<void**>(&b)) = reinterpret_cast<void*>(eglGetProcAddress(#b)); \ 7918bf80f4bSopenharmony_ci } \ 7928bf80f4bSopenharmony_ci if (b == nullptr) { \ 7938bf80f4bSopenharmony_ci PLUGIN_LOG_E("Missing %s\n", #b); \ 7948bf80f4bSopenharmony_ci } 7958bf80f4bSopenharmony_ci#include "gles/gl_functions.h" 7968bf80f4bSopenharmony_ci 7978bf80f4bSopenharmony_ci#define declare(a, b) \ 7988bf80f4bSopenharmony_ci if (b == nullptr) { \ 7998bf80f4bSopenharmony_ci *(reinterpret_cast<void**>(&b)) = reinterpret_cast<void*>(eglGetProcAddress(#b)); \ 8008bf80f4bSopenharmony_ci } \ 8018bf80f4bSopenharmony_ci if (b == nullptr) { \ 8028bf80f4bSopenharmony_ci PLUGIN_LOG_E("Missing %s\n", #b); \ 8038bf80f4bSopenharmony_ci } 8048bf80f4bSopenharmony_ci#include "gles/egl_functions.h" 8058bf80f4bSopenharmony_ci if (!HasExtension("EGL_ANDROID_get_native_client_buffer")) { 8068bf80f4bSopenharmony_ci eglGetNativeClientBufferANDROID = nullptr; 8078bf80f4bSopenharmony_ci } 8088bf80f4bSopenharmony_ci if (!HasExtension("EGL_KHR_image_base")) { 8098bf80f4bSopenharmony_ci eglCreateImageKHR = nullptr; 8108bf80f4bSopenharmony_ci eglDestroyImageKHR = nullptr; 8118bf80f4bSopenharmony_ci } 8128bf80f4bSopenharmony_ci 8138bf80f4bSopenharmony_ci plat_.deviceName = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); 8148bf80f4bSopenharmony_ci plat_.driverVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION)); 8158bf80f4bSopenharmony_ci BASE_NS::ClearToValue( 8168bf80f4bSopenharmony_ci &plat_.deviceProperties, sizeof(plat_.deviceProperties), 0x00, sizeof(plat_.deviceProperties)); 8178bf80f4bSopenharmony_ci FillProperties(plat_.deviceProperties); 8188bf80f4bSopenharmony_ci 8198bf80f4bSopenharmony_ci SetSwapInterval(1); // default to vsync enabled. 8208bf80f4bSopenharmony_ci} 8218bf80f4bSopenharmony_ci 8228bf80f4bSopenharmony_cibool EGLState::IsValid() 8238bf80f4bSopenharmony_ci{ 8248bf80f4bSopenharmony_ci return (plat_.context != EGL_NO_CONTEXT); 8258bf80f4bSopenharmony_ci} 8268bf80f4bSopenharmony_ci 8278bf80f4bSopenharmony_civoid EGLState::SaveContext() 8288bf80f4bSopenharmony_ci{ 8298bf80f4bSopenharmony_ci PLUGIN_ASSERT(!oldIsSet_); 8308bf80f4bSopenharmony_ci oldIsSet_ = true; 8318bf80f4bSopenharmony_ci GetContext(oldContext_); 8328bf80f4bSopenharmony_ci} 8338bf80f4bSopenharmony_ci 8348bf80f4bSopenharmony_civoid EGLState::SetContext(const SwapchainGLES* swapchain) 8358bf80f4bSopenharmony_ci{ 8368bf80f4bSopenharmony_ci if (swapchain == nullptr) { 8378bf80f4bSopenharmony_ci SetContext(dummyContext_, true); 8388bf80f4bSopenharmony_ci } else { 8398bf80f4bSopenharmony_ci ContextState newContext; 8408bf80f4bSopenharmony_ci const auto& plat = swapchain->GetPlatformData(); 8418bf80f4bSopenharmony_ci newContext.display = plat_.display; 8428bf80f4bSopenharmony_ci newContext.context = plat_.context; 8438bf80f4bSopenharmony_ci newContext.drawSurface = (EGLSurface)plat.surface; 8448bf80f4bSopenharmony_ci newContext.readSurface = (EGLSurface)plat.surface; 8458bf80f4bSopenharmony_ci SetContext(newContext, false); 8468bf80f4bSopenharmony_ci 8478bf80f4bSopenharmony_ci if (vSync_ != plat.vsync) { 8488bf80f4bSopenharmony_ci vSync_ = plat.vsync; 8498bf80f4bSopenharmony_ci SetSwapInterval(plat.vsync ? 1u : 0u); 8508bf80f4bSopenharmony_ci } 8518bf80f4bSopenharmony_ci } 8528bf80f4bSopenharmony_ci} 8538bf80f4bSopenharmony_ci 8548bf80f4bSopenharmony_civoid EGLState::RestoreContext() 8558bf80f4bSopenharmony_ci{ 8568bf80f4bSopenharmony_ci PLUGIN_ASSERT(oldIsSet_); 8578bf80f4bSopenharmony_ci SetContext(oldContext_, true); 8588bf80f4bSopenharmony_ci oldIsSet_ = false; 8598bf80f4bSopenharmony_ci} 8608bf80f4bSopenharmony_ci 8618bf80f4bSopenharmony_civoid EGLState::GetContext(ContextState& state) 8628bf80f4bSopenharmony_ci{ 8638bf80f4bSopenharmony_ci state.display = eglGetCurrentDisplay(); 8648bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 8658bf80f4bSopenharmony_ci if (state.display != EGL_NO_DISPLAY) { 8668bf80f4bSopenharmony_ci state.context = eglGetCurrentContext(); 8678bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 8688bf80f4bSopenharmony_ci state.readSurface = eglGetCurrentSurface(EGL_READ); 8698bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 8708bf80f4bSopenharmony_ci state.drawSurface = eglGetCurrentSurface(EGL_DRAW); 8718bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 8728bf80f4bSopenharmony_ci } else { 8738bf80f4bSopenharmony_ci state.context = EGL_NO_CONTEXT; 8748bf80f4bSopenharmony_ci state.readSurface = EGL_NO_SURFACE; 8758bf80f4bSopenharmony_ci state.drawSurface = EGL_NO_SURFACE; 8768bf80f4bSopenharmony_ci } 8778bf80f4bSopenharmony_ci} 8788bf80f4bSopenharmony_ci 8798bf80f4bSopenharmony_civoid EGLState::SetContext(const ContextState& state, bool force) 8808bf80f4bSopenharmony_ci{ 8818bf80f4bSopenharmony_ci PLUGIN_ASSERT(oldIsSet_); 8828bf80f4bSopenharmony_ci if (state.display != EGL_NO_DISPLAY) { 8838bf80f4bSopenharmony_ci if ((force) || (oldContext_.display != state.display) || (oldContext_.drawSurface != state.drawSurface) || 8848bf80f4bSopenharmony_ci (oldContext_.readSurface != state.readSurface) || (oldContext_.context != state.context)) { 8858bf80f4bSopenharmony_ci if (eglMakeCurrent(state.display, state.drawSurface, state.readSurface, state.context) == EGL_FALSE) { 8868bf80f4bSopenharmony_ci CHECK_EGL_ERROR2(); 8878bf80f4bSopenharmony_ci if (eglMakeCurrent(state.display, dummySurface_, dummySurface_, state.context) == EGL_FALSE) { 8888bf80f4bSopenharmony_ci CHECK_EGL_ERROR2(); 8898bf80f4bSopenharmony_ci } 8908bf80f4bSopenharmony_ci } 8918bf80f4bSopenharmony_ci } 8928bf80f4bSopenharmony_ci } else { 8938bf80f4bSopenharmony_ci // Okay, do nothing. 8948bf80f4bSopenharmony_ci // no display was active, so there can be no surface and no context. 8958bf80f4bSopenharmony_ci // We need a display to deactivate context. (EGL_NO_DISPLAY is not a valid argument to eglMakeCurrent) 8968bf80f4bSopenharmony_ci // so what to do, leak context? 8978bf80f4bSopenharmony_ci // Or just disconnect context/surface from plat_.display (which currently is EGL_DEFAULT_DISPLAY...) 8988bf80f4bSopenharmony_ci if (eglMakeCurrent(plat_.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_FALSE) { 8998bf80f4bSopenharmony_ci CHECK_EGL_ERROR2(); 9008bf80f4bSopenharmony_ci } 9018bf80f4bSopenharmony_ci } 9028bf80f4bSopenharmony_ci} 9038bf80f4bSopenharmony_ci 9048bf80f4bSopenharmony_civoid EGLState::DestroyContext() 9058bf80f4bSopenharmony_ci{ 9068bf80f4bSopenharmony_ci if (plat_.display != EGL_NO_DISPLAY) { 9078bf80f4bSopenharmony_ci eglMakeCurrent(plat_.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 9088bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 9098bf80f4bSopenharmony_ci if (dummySurface_ != EGL_NO_SURFACE) { 9108bf80f4bSopenharmony_ci eglDestroySurface(plat_.display, dummySurface_); 9118bf80f4bSopenharmony_ci } 9128bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 9138bf80f4bSopenharmony_ci if (plat_.contextCreated) { 9148bf80f4bSopenharmony_ci if (plat_.context != EGL_NO_CONTEXT) { 9158bf80f4bSopenharmony_ci eglDestroyContext(plat_.display, plat_.context); 9168bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 9178bf80f4bSopenharmony_ci } 9188bf80f4bSopenharmony_ci } 9198bf80f4bSopenharmony_ci if (plat_.eglInitialized) { 9208bf80f4bSopenharmony_ci eglTerminate(plat_.display); 9218bf80f4bSopenharmony_ci CHECK_EGL_ERROR(); 9228bf80f4bSopenharmony_ci } 9238bf80f4bSopenharmony_ci } 9248bf80f4bSopenharmony_ci} 9258bf80f4bSopenharmony_ci 9268bf80f4bSopenharmony_cibool EGLState::HasExtension(const string_view extension) const 9278bf80f4bSopenharmony_ci{ 9288bf80f4bSopenharmony_ci for (const auto& e : dextensionList_) { 9298bf80f4bSopenharmony_ci if (extension == e) 9308bf80f4bSopenharmony_ci return true; 9318bf80f4bSopenharmony_ci } 9328bf80f4bSopenharmony_ci for (const auto& e : cextensionList_) { 9338bf80f4bSopenharmony_ci if (extension == e) 9348bf80f4bSopenharmony_ci return true; 9358bf80f4bSopenharmony_ci } 9368bf80f4bSopenharmony_ci return false; 9378bf80f4bSopenharmony_ci} 9388bf80f4bSopenharmony_ci 9398bf80f4bSopenharmony_civoid EGLState::SetSwapInterval(uint32_t interval) 9408bf80f4bSopenharmony_ci{ 9418bf80f4bSopenharmony_ci eglSwapInterval(plat_.display, (EGLint)interval); 9428bf80f4bSopenharmony_ci} 9438bf80f4bSopenharmony_ci 9448bf80f4bSopenharmony_ciconst DevicePlatformData& EGLState::GetPlatformData() const 9458bf80f4bSopenharmony_ci{ 9468bf80f4bSopenharmony_ci return plat_; 9478bf80f4bSopenharmony_ci} 9488bf80f4bSopenharmony_ci 9498bf80f4bSopenharmony_civoid* EGLState::ErrorFilter() const 9508bf80f4bSopenharmony_ci{ 9518bf80f4bSopenharmony_ci return reinterpret_cast<void*>(FilterError); 9528bf80f4bSopenharmony_ci} 9538bf80f4bSopenharmony_ci 9548bf80f4bSopenharmony_ciuintptr_t EGLState::CreateSurface(uintptr_t window, uintptr_t instance) const noexcept 9558bf80f4bSopenharmony_ci{ 9568bf80f4bSopenharmony_ci // Check if sRGB colorspace is supported by EGL. 9578bf80f4bSopenharmony_ci const bool isSrgbSurfaceSupported = IsSrgbSurfaceSupported(plat_); 9588bf80f4bSopenharmony_ci 9598bf80f4bSopenharmony_ci EGLint attribsSrgb[] = { EGL_NONE, EGL_NONE, EGL_NONE }; 9608bf80f4bSopenharmony_ci if (isSrgbSurfaceSupported) { 9618bf80f4bSopenharmony_ci if (IsVersionGreaterOrEqual(1, 5)) { // 5 : param 9628bf80f4bSopenharmony_ci attribsSrgb[0] = EGL_GL_COLORSPACE; 9638bf80f4bSopenharmony_ci attribsSrgb[1] = EGL_GL_COLORSPACE_SRGB; 9648bf80f4bSopenharmony_ci } else if (hasColorSpaceExt_) { 9658bf80f4bSopenharmony_ci attribsSrgb[0] = EGL_GL_COLORSPACE_KHR; 9668bf80f4bSopenharmony_ci attribsSrgb[1] = EGL_GL_COLORSPACE_SRGB_KHR; 9678bf80f4bSopenharmony_ci } 9688bf80f4bSopenharmony_ci } 9698bf80f4bSopenharmony_ci EGLSurface eglSurface = eglCreateWindowSurface(plat_.display, plat_.config, 9708bf80f4bSopenharmony_ci reinterpret_cast<EGLNativeWindowType>(window), isSrgbSurfaceSupported ? attribsSrgb : nullptr); 9718bf80f4bSopenharmony_ci if (eglSurface == EGL_NO_SURFACE) { 9728bf80f4bSopenharmony_ci EGLint error = eglGetError(); 9738bf80f4bSopenharmony_ci PLUGIN_LOG_E("eglCreateWindowSurface failed (with null attributes): %d", error); 9748bf80f4bSopenharmony_ci } 9758bf80f4bSopenharmony_ci return reinterpret_cast<uintptr_t>(eglSurface); 9768bf80f4bSopenharmony_ci} 9778bf80f4bSopenharmony_ci 9788bf80f4bSopenharmony_civoid EGLState::DestroySurface(uintptr_t surface) const noexcept 9798bf80f4bSopenharmony_ci{ 9808bf80f4bSopenharmony_ci if (reinterpret_cast<EGLSurface>(surface) != EGL_NO_SURFACE) { 9818bf80f4bSopenharmony_ci eglDestroySurface(plat_.display, reinterpret_cast<EGLSurface>(surface)); 9828bf80f4bSopenharmony_ci } 9838bf80f4bSopenharmony_ci} 9848bf80f4bSopenharmony_ci 9858bf80f4bSopenharmony_cibool EGLState::GetSurfaceInformation( 9868bf80f4bSopenharmony_ci const DevicePlatformDataGLES& plat, EGLSurface surface, GlesImplementation::SurfaceInfo& res) const 9878bf80f4bSopenharmony_ci{ 9888bf80f4bSopenharmony_ci EGLDisplay display = plat.display; 9898bf80f4bSopenharmony_ci 9908bf80f4bSopenharmony_ci#ifndef NDEBUG 9918bf80f4bSopenharmony_ci PLUGIN_LOG_V("EGLState::GetSurfaceInformation: input surface information:"); 9928bf80f4bSopenharmony_ci DumpEGLSurface(display, surface); 9938bf80f4bSopenharmony_ci#endif 9948bf80f4bSopenharmony_ci EGLint configId; 9958bf80f4bSopenharmony_ci // Get configId from surface 9968bf80f4bSopenharmony_ci if (eglQuerySurface(display, surface, EGL_CONFIG_ID, &configId) == false) { 9978bf80f4bSopenharmony_ci PLUGIN_LOG_E("EGLState::GetSurfaceInformation: Could not fetch surface config_id."); 9988bf80f4bSopenharmony_ci return false; 9998bf80f4bSopenharmony_ci } 10008bf80f4bSopenharmony_ci 10018bf80f4bSopenharmony_ci EGLConfig config = EGL_NO_CONFIG_KHR; 10028bf80f4bSopenharmony_ci EGLint numconfigs = 0; 10038bf80f4bSopenharmony_ci EGLint attrs[] = { EGL_CONFIG_ID, configId, EGL_NONE }; 10048bf80f4bSopenharmony_ci if (eglChooseConfig(display, attrs, &config, 1, &numconfigs) == false) { 10058bf80f4bSopenharmony_ci PLUGIN_LOG_E("EGLState::GetSurfaceInformation: Could not fetch surface config."); 10068bf80f4bSopenharmony_ci return false; 10078bf80f4bSopenharmony_ci } 10088bf80f4bSopenharmony_ci 10098bf80f4bSopenharmony_ci PLUGIN_LOG_V("EGLState::GetSurfaceInformation: input surface configuration:"); 10108bf80f4bSopenharmony_ci DumpEGLConfig(display, config); 10118bf80f4bSopenharmony_ci 10128bf80f4bSopenharmony_ci#ifndef NDEBUG 10138bf80f4bSopenharmony_ci if (!hasConfiglessExt_) { 10148bf80f4bSopenharmony_ci // Check that it matches the config id from "system config" 10158bf80f4bSopenharmony_ci EGLConfig plat_config = plat.config; 10168bf80f4bSopenharmony_ci if ((plat_config != EGL_NO_CONFIG_KHR) && (plat_config != config)) { 10178bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(plat_config == config, "display config and surface config should match!"); 10188bf80f4bSopenharmony_ci PLUGIN_LOG_V("EGLState::GetSurfaceInformation: plat surface configuration:"); 10198bf80f4bSopenharmony_ci EGLHelpers::DumpEGLConfig(display, plat_config); 10208bf80f4bSopenharmony_ci } 10218bf80f4bSopenharmony_ci } 10228bf80f4bSopenharmony_ci#endif 10238bf80f4bSopenharmony_ci 10248bf80f4bSopenharmony_ci // Fetch surface parameters 10258bf80f4bSopenharmony_ci EGLint width = 0; 10268bf80f4bSopenharmony_ci EGLint height = 0; 10278bf80f4bSopenharmony_ci EGLint red_size = 0; 10288bf80f4bSopenharmony_ci EGLint green_size = 0; 10298bf80f4bSopenharmony_ci EGLint blue_size = 0; 10308bf80f4bSopenharmony_ci EGLint alpha_size = 0; 10318bf80f4bSopenharmony_ci EGLint samples = 0; 10328bf80f4bSopenharmony_ci EGLint depth_size = 0; 10338bf80f4bSopenharmony_ci EGLint stencil_size = 0; 10348bf80f4bSopenharmony_ci eglQuerySurface(display, surface, EGL_WIDTH, &width); 10358bf80f4bSopenharmony_ci eglQuerySurface(display, surface, EGL_HEIGHT, &height); 10368bf80f4bSopenharmony_ci eglGetConfigAttrib(display, config, EGL_RED_SIZE, &red_size); 10378bf80f4bSopenharmony_ci eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &green_size); 10388bf80f4bSopenharmony_ci eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blue_size); 10398bf80f4bSopenharmony_ci eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alpha_size); 10408bf80f4bSopenharmony_ci eglGetConfigAttrib(display, config, EGL_SAMPLES, &samples); 10418bf80f4bSopenharmony_ci eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depth_size); 10428bf80f4bSopenharmony_ci eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencil_size); 10438bf80f4bSopenharmony_ci 10448bf80f4bSopenharmony_ci res.configId = (uint32_t)configId; 10458bf80f4bSopenharmony_ci res.alpha_size = (uint32_t)alpha_size; 10468bf80f4bSopenharmony_ci res.blue_size = (uint32_t)blue_size; 10478bf80f4bSopenharmony_ci res.depth_size = (uint32_t)depth_size; 10488bf80f4bSopenharmony_ci res.green_size = (uint32_t)green_size; 10498bf80f4bSopenharmony_ci res.height = (uint32_t)height; 10508bf80f4bSopenharmony_ci res.red_size = (uint32_t)red_size; 10518bf80f4bSopenharmony_ci res.samples = (uint32_t)samples; 10528bf80f4bSopenharmony_ci res.stencil_size = (uint32_t)stencil_size; 10538bf80f4bSopenharmony_ci res.width = (uint32_t)width; 10548bf80f4bSopenharmony_ci 10558bf80f4bSopenharmony_ci EGLint colorspace = 0; 10568bf80f4bSopenharmony_ci EGLint COLOR_SPACE = 0; 10578bf80f4bSopenharmony_ci EGLint COLOR_SPACE_SRGB = 0; 10588bf80f4bSopenharmony_ci if (IsVersionGreaterOrEqual(1, 5)) { 10598bf80f4bSopenharmony_ci COLOR_SPACE = EGL_GL_COLORSPACE; 10608bf80f4bSopenharmony_ci COLOR_SPACE_SRGB = EGL_GL_COLORSPACE_SRGB; 10618bf80f4bSopenharmony_ci } else if (hasColorSpaceExt_) { 10628bf80f4bSopenharmony_ci COLOR_SPACE = EGL_GL_COLORSPACE_KHR; 10638bf80f4bSopenharmony_ci COLOR_SPACE_SRGB = EGL_GL_COLORSPACE_SRGB_KHR; 10648bf80f4bSopenharmony_ci } 10658bf80f4bSopenharmony_ci 10668bf80f4bSopenharmony_ci if (COLOR_SPACE > 0) { 10678bf80f4bSopenharmony_ci if (eglQuerySurface(display, surface, COLOR_SPACE, &colorspace)) { 10688bf80f4bSopenharmony_ci // EGL_GL_COLORSPACE_SRGB or EGL_GL_COLORSPACE_LINEAR. 10698bf80f4bSopenharmony_ci res.srgb = (colorspace == COLOR_SPACE_SRGB); 10708bf80f4bSopenharmony_ci } 10718bf80f4bSopenharmony_ci } 10728bf80f4bSopenharmony_ci 10738bf80f4bSopenharmony_ci if (colorspace == 0) { 10748bf80f4bSopenharmony_ci // surface is linear (no conversion made during read/write) 10758bf80f4bSopenharmony_ci // data should be srgb though. 10768bf80f4bSopenharmony_ci PLUGIN_LOG_E("EGL_GL_COLORSPACE query failed (or not available). Defaulting to linear buffer with srgb data"); 10778bf80f4bSopenharmony_ci res.srgb = false; 10788bf80f4bSopenharmony_ci } 10798bf80f4bSopenharmony_ci 10808bf80f4bSopenharmony_ci return true; 10818bf80f4bSopenharmony_ci} 10828bf80f4bSopenharmony_ci 10838bf80f4bSopenharmony_civoid EGLState::SwapBuffers(const SwapchainGLES& swapchain) 10848bf80f4bSopenharmony_ci{ 10858bf80f4bSopenharmony_ci SetContext(&swapchain); 10868bf80f4bSopenharmony_ci const auto& platSwapchain = static_cast<const SwapchainPlatformDataGL&>(swapchain.GetPlatformData()); 10878bf80f4bSopenharmony_ci eglSwapBuffers(plat_.display, (EGLSurface)platSwapchain.surface); 10888bf80f4bSopenharmony_ci} 10898bf80f4bSopenharmony_ci} // namespace EGLHelpers 10908bf80f4bSopenharmony_ciRENDER_END_NAMESPACE() 10918bf80f4bSopenharmony_ci#endif 1092