| /* | |
| * Copyright 2023 Rive | |
| */ | |
| #include "rive/renderer/gl/gles3.hpp" | |
| #include <EGL/egl.h> | |
| #include <assert.h> | |
| PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC | |
| glDrawArraysInstancedBaseInstanceEXT = nullptr; | |
| PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC | |
| glDrawElementsInstancedBaseInstanceEXT = nullptr; | |
| PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC | |
| glDrawElementsInstancedBaseVertexBaseInstanceEXT = nullptr; | |
| PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC glFramebufferFetchBarrierQCOM = nullptr; | |
| PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC | |
| glFramebufferTexture2DMultisampleEXT = nullptr; | |
| PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT = | |
| nullptr; | |
| PFNGLBLENDBARRIERKHRPROC glBlendBarrierKHR = nullptr; | |
| PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC | |
| glFramebufferPixelLocalStorageSizeEXT = nullptr; | |
| PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC glClearPixelLocalStorageuiEXT = nullptr; | |
| PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glMaxShaderCompilerThreadsKHR = nullptr; | |
| void LoadAndValidateGLESExtensions(GLCapabilities* extensions) | |
| { | |
| assert(extensions != nullptr); | |
| static GLCapabilities loadedExtensions{}; | |
| if (extensions->EXT_base_instance && !loadedExtensions.EXT_base_instance) | |
| { | |
| glDrawArraysInstancedBaseInstanceEXT = | |
| (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC)eglGetProcAddress( | |
| "glDrawArraysInstancedBaseInstanceEXT"); | |
| glDrawElementsInstancedBaseInstanceEXT = | |
| (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC)eglGetProcAddress( | |
| "glDrawElementsInstancedBaseInstanceEXT"); | |
| glDrawElementsInstancedBaseVertexBaseInstanceEXT = | |
| (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC) | |
| eglGetProcAddress( | |
| "glDrawElementsInstancedBaseVertexBaseInstanceEXT"); | |
| if (glDrawArraysInstancedBaseInstanceEXT != nullptr && | |
| glDrawElementsInstancedBaseInstanceEXT != nullptr && | |
| glDrawElementsInstancedBaseVertexBaseInstanceEXT != nullptr) | |
| { | |
| loadedExtensions.EXT_base_instance = true; | |
| } | |
| else | |
| { | |
| extensions->EXT_base_instance = false; | |
| } | |
| } | |
| if (extensions->QCOM_shader_framebuffer_fetch_noncoherent && | |
| !loadedExtensions.QCOM_shader_framebuffer_fetch_noncoherent) | |
| { | |
| glFramebufferFetchBarrierQCOM = | |
| (PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC)eglGetProcAddress( | |
| "glFramebufferFetchBarrierQCOM"); | |
| if (glFramebufferFetchBarrierQCOM != nullptr) | |
| { | |
| loadedExtensions.QCOM_shader_framebuffer_fetch_noncoherent = true; | |
| } | |
| else | |
| { | |
| extensions->QCOM_shader_framebuffer_fetch_noncoherent = false; | |
| } | |
| } | |
| if (extensions->EXT_multisampled_render_to_texture && | |
| !loadedExtensions.EXT_multisampled_render_to_texture) | |
| { | |
| glFramebufferTexture2DMultisampleEXT = | |
| (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)eglGetProcAddress( | |
| "glFramebufferTexture2DMultisampleEXT"); | |
| glRenderbufferStorageMultisampleEXT = | |
| (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)eglGetProcAddress( | |
| "glRenderbufferStorageMultisampleEXT"); | |
| if (glFramebufferTexture2DMultisampleEXT != nullptr && | |
| glRenderbufferStorageMultisampleEXT != nullptr) | |
| { | |
| loadedExtensions.EXT_multisampled_render_to_texture = true; | |
| } | |
| else | |
| { | |
| extensions->EXT_multisampled_render_to_texture = false; | |
| } | |
| } | |
| if (extensions->KHR_blend_equation_advanced && | |
| !loadedExtensions.KHR_blend_equation_advanced) | |
| { | |
| glBlendBarrierKHR = | |
| (PFNGLBLENDBARRIERKHRPROC)eglGetProcAddress("glBlendBarrierKHR"); | |
| if (glBlendBarrierKHR != nullptr) | |
| { | |
| loadedExtensions.KHR_blend_equation_advanced = true; | |
| } | |
| else | |
| { | |
| extensions->KHR_blend_equation_advanced = false; | |
| } | |
| } | |
| if (extensions->EXT_shader_pixel_local_storage2 && | |
| !loadedExtensions.EXT_shader_pixel_local_storage2) | |
| { | |
| glFramebufferPixelLocalStorageSizeEXT = | |
| (PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC)eglGetProcAddress( | |
| "glFramebufferPixelLocalStorageSizeEXT"); | |
| glClearPixelLocalStorageuiEXT = | |
| (PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC)eglGetProcAddress( | |
| "glClearPixelLocalStorageuiEXT"); | |
| if (glFramebufferPixelLocalStorageSizeEXT != nullptr && | |
| glClearPixelLocalStorageuiEXT != nullptr) | |
| { | |
| loadedExtensions.EXT_shader_pixel_local_storage2 = true; | |
| } | |
| else | |
| { | |
| extensions->EXT_shader_pixel_local_storage2 = false; | |
| } | |
| } | |
| if (extensions->KHR_parallel_shader_compile && | |
| !loadedExtensions.KHR_parallel_shader_compile) | |
| { | |
| glMaxShaderCompilerThreadsKHR = | |
| (PFNGLMAXSHADERCOMPILERTHREADSKHRPROC)eglGetProcAddress( | |
| "glMaxShaderCompilerThreadsKHR"); | |
| if (glMaxShaderCompilerThreadsKHR != nullptr) | |
| { | |
| loadedExtensions.KHR_parallel_shader_compile = true; | |
| } | |
| else | |
| { | |
| extensions->KHR_parallel_shader_compile = false; | |
| } | |
| } | |
| } |