summaryrefslogtreecommitdiff
path: root/src/render/OpenGL.hpp
diff options
context:
space:
mode:
authorUjinT34 <41110182+UjinT34@users.noreply.github.com>2026-03-29 00:41:45 +0300
committerGitHub <noreply@github.com>2026-03-28 21:41:45 +0000
commit38a7f03cf0e5ee116794a78581634ba3dab508fa (patch)
tree969891411b2af4e437a183004018cfc359a3057e /src/render/OpenGL.hpp
parentef2e8dfd5f7e6ee55fa7bc48e44974e64938d14a (diff)
renderer: refactor part 7: api fixes (#13631)
Part 7 of ujin's refactors --------- Co-authored-by: Vaxry <vaxry@vaxry.net>
Diffstat (limited to 'src/render/OpenGL.hpp')
-rw-r--r--src/render/OpenGL.hpp623
1 files changed, 300 insertions, 323 deletions
diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp
index bbca01c0..78518ffe 100644
--- a/src/render/OpenGL.hpp
+++ b/src/render/OpenGL.hpp
@@ -16,6 +16,8 @@
#include <cairo/cairo.h>
+#include "render/SyncFDManager.hpp"
+#include "types.hpp"
#include "Shader.hpp"
#include "Texture.hpp"
#include "Framebuffer.hpp"
@@ -40,343 +42,318 @@
#define GLFB(ifb) dc<CGLFramebuffer*>(ifb.get())
struct gbm_device;
-class IHyprRenderer;
-
+namespace Render {
+ class IHyprRenderer;
+}
namespace Config {
class CGradientValueData;
}
-struct SVertex {
- float x, y; // position
- float u, v; // uv
-};
-
-constexpr std::array<SVertex, 4> fullVerts = {{
- {0.0f, 0.0f, 0.0f, 0.0f}, // top-left
- {0.0f, 1.0f, 0.0f, 1.0f}, // bottom-left
- {1.0f, 0.0f, 1.0f, 0.0f}, // top-right
- {1.0f, 1.0f, 1.0f, 1.0f}, // bottom-right
-}};
-
-inline const float fanVertsFull[] = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f};
-
-struct SRenderModifData {
- enum eRenderModifType : uint8_t {
- RMOD_TYPE_SCALE, /* scale by a float */
- RMOD_TYPE_SCALECENTER, /* scale by a float from the center */
- RMOD_TYPE_TRANSLATE, /* translate by a Vector2D */
- RMOD_TYPE_ROTATE, /* rotate by a float in rad from top left */
- RMOD_TYPE_ROTATECENTER, /* rotate by a float in rad from center */
+namespace Render::GL {
+
+ struct SVertex {
+ float x, y; // position
+ float u, v; // uv
+ };
+
+ constexpr std::array<SVertex, 4> fullVerts = {{
+ {0.0f, 0.0f, 0.0f, 0.0f}, // top-left
+ {0.0f, 1.0f, 0.0f, 1.0f}, // bottom-left
+ {1.0f, 0.0f, 1.0f, 0.0f}, // top-right
+ {1.0f, 1.0f, 1.0f, 1.0f}, // bottom-right
+ }};
+
+ inline const float fanVertsFull[] = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f};
+
+ enum eMonitorRenderFBs : uint8_t {
+ FB_MONITOR_RENDER_MAIN = 0,
+ FB_MONITOR_RENDER_CURRENT = 1,
+ FB_MONITOR_RENDER_OUT = 2,
};
- std::vector<std::pair<eRenderModifType, std::any>> modifs;
-
- void applyToBox(CBox& box);
- void applyToRegion(CRegion& rg);
- float combinedScale();
-
- bool enabled = true;
-};
-
-enum eMonitorRenderFBs : uint8_t {
- FB_MONITOR_RENDER_MAIN = 0,
- FB_MONITOR_RENDER_CURRENT = 1,
- FB_MONITOR_RENDER_OUT = 2,
-};
-
-enum eMonitorExtraRenderFBs : uint8_t {
- FB_MONITOR_RENDER_EXTRA_OFFLOAD = 0,
- FB_MONITOR_RENDER_EXTRA_MIRROR,
- FB_MONITOR_RENDER_EXTRA_MIRROR_SWAP,
- FB_MONITOR_RENDER_EXTRA_OFF_MAIN,
- FB_MONITOR_RENDER_EXTRA_MONITOR_MIRROR,
- FB_MONITOR_RENDER_EXTRA_BLUR,
-};
-
-struct SFragShaderDesc {
- Render::ePreparedFragmentShader id;
- const char* file;
-};
-
-struct SPreparedShaders {
- // SPreparedShaders() {
- // for (auto& f : frag) {
- // f = makeShared<CShader>();
- // }
- // }
-
- std::string TEXVERTSRC;
- std::string TEXVERTSRC320;
- // std::array<SP<CShader>, SH_FRAG_LAST> frag;
- // std::map<uint8_t, SP<CShader>> fragVariants;
- std::array<std::map<Render::ShaderFeatureFlags, SP<CShader>>, Render::SH_FRAG_LAST> fragVariants;
-};
-
-struct SCurrentRenderData {
- PHLMONITORREF pMonitor;
- Mat3x3 projection;
- Mat3x3 savedProjection;
- Mat3x3 monitorProjection;
-
- SP<IFramebuffer> currentFB = nullptr; // current rendering to
- SP<IFramebuffer> mainFB = nullptr; // main to render to
- SP<IFramebuffer> outFB = nullptr; // out to render to (if offloaded, etc)
-
- CRegion damage;
- CRegion finalDamage; // damage used for funal off -> main
-
- SRenderModifData renderModif;
- float mouseZoomFactor = 1.f;
- bool mouseZoomUseMouse = true; // true by default
- bool useNearestNeighbor = false;
- bool blockScreenShader = false;
- bool simplePass = false;
- bool transformDamage = true;
- bool noSimplify = false;
-
- Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
- Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
-
- CBox clipBox = {}; // scaled coordinates
- CRegion clipRegion;
-
- uint32_t discardMode = DISCARD_OPAQUE;
- float discardOpacity = 0.f;
-
- PHLLSREF currentLS;
- PHLWINDOWREF currentWindow;
- WP<CWLSurfaceResource> surface;
-};
-
-class CEGLSync {
- public:
- static UP<CEGLSync> create();
-
- ~CEGLSync();
-
- Hyprutils::OS::CFileDescriptor& fd();
- Hyprutils::OS::CFileDescriptor&& takeFd();
- bool isValid();
-
- private:
- CEGLSync() = default;
-
- Hyprutils::OS::CFileDescriptor m_fd;
- EGLSyncKHR m_sync = EGL_NO_SYNC_KHR;
- bool m_valid = false;
-
- friend class CHyprOpenGLImpl;
-};
-
-class CHyprOpenGLImpl {
- public:
- CHyprOpenGLImpl();
- ~CHyprOpenGLImpl();
-
- struct SRectRenderData {
- const CRegion* damage = nullptr;
- int round = 0;
- float roundingPower = 2.F;
- bool blur = false;
- float blurA = 1.F;
- bool xray = false;
+ enum eMonitorExtraRenderFBs : uint8_t {
+ FB_MONITOR_RENDER_EXTRA_OFFLOAD = 0,
+ FB_MONITOR_RENDER_EXTRA_MIRROR,
+ FB_MONITOR_RENDER_EXTRA_MIRROR_SWAP,
+ FB_MONITOR_RENDER_EXTRA_OFF_MAIN,
+ FB_MONITOR_RENDER_EXTRA_MONITOR_MIRROR,
+ FB_MONITOR_RENDER_EXTRA_BLUR,
};
- struct STextureRenderData {
- bool blur = false;
- float blurA = 1.F, overallA = 1.F;
- bool blockBlurOptimization = false;
- SP<ITexture> blurredBG;
-
- const CRegion* damage = nullptr;
- SP<CWLSurfaceResource> surface = nullptr;
- float a = 1.F;
- int round = 0;
- float roundingPower = 2.F;
- bool discardActive = false;
- bool allowCustomUV = false;
- bool allowDim = true;
- bool noAA = false; // unused
- GLenum wrapX = GL_CLAMP_TO_EDGE, wrapY = GL_CLAMP_TO_EDGE;
- bool cmBackToSRGB = false;
- bool finalMonitorCM = false;
- SP<CMonitor> cmBackToSRGBSource;
-
- uint32_t discardMode = DISCARD_OPAQUE;
- float discardOpacity = 0.f;
-
- CRegion clipRegion;
- PHLLSREF currentLS;
-
- Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
- Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
+ struct SFragShaderDesc {
+ Render::ePreparedFragmentShader id;
+ const char* file;
};
- struct SBorderRenderData {
- int round = 0;
- float roundingPower = 2.F;
- int borderSize = 1;
- float a = 1.0;
- int outerRound = -1; /* use round */
+ struct SPreparedShaders {
+ std::string TEXVERTSRC;
+ std::string TEXVERTSRC320;
+ std::array<std::map<Render::ShaderFeatureFlags, SP<CShader>>, Render::SH_FRAG_LAST> fragVariants;
};
- void makeEGLCurrent();
- void begin(PHLMONITOR, const CRegion& damage, SP<IFramebuffer> fb = nullptr, std::optional<CRegion> finalDamage = {});
- void beginSimple(PHLMONITOR, const CRegion& damage, SP<IRenderbuffer> rb = nullptr, SP<IFramebuffer> fb = nullptr);
- void end();
-
- void renderRect(const CBox&, const CHyprColor&, SRectRenderData data);
- void renderTexture(SP<ITexture>, const CBox&, STextureRenderData data);
- void renderRoundedShadow(const CBox&, int round, float roundingPower, int range, const CHyprColor& color, float a = 1.0);
- void renderInnerGlow(const CBox&, int round, float roundingPower, int range, const CHyprColor& color, int glowPower, float a = 1.0);
- void renderBorder(const CBox&, const Config::CGradientValueData&, SBorderRenderData data);
- void renderBorder(const CBox&, const Config::CGradientValueData&, const Config::CGradientValueData&, float lerp, SBorderRenderData data);
- void renderTextureMatte(SP<ITexture> tex, const CBox& pBox, SP<IFramebuffer> matte);
- void renderTexturePrimitive(SP<ITexture> tex, const CBox& box);
-
- void setViewport(GLint x, GLint y, GLsizei width, GLsizei height);
- void setCapStatus(int cap, bool status);
-
- void blend(bool enabled);
-
- void clear(const CHyprColor&);
- void scissor(const CBox&, bool transform = true);
- void scissor(const pixman_box32*, bool transform = true);
- void scissor(const int x, const int y, const int w, const int h, bool transform = true);
-
- void destroyMonitorResources(PHLMONITORREF);
-
- void preRender(PHLMONITOR);
-
- void saveBufferForMirror(const CBox&);
-
- void applyScreenShader(const std::string& path);
-
- void renderOffToMain(IFramebuffer* off);
-
- std::vector<SDRMFormat> getDRMFormats();
- std::vector<uint64_t> getDRMFormatModifiers(DRMFormat format);
- EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs);
-
- bool initShaders(const std::string& path = "");
-
- WP<CShader> useShader(WP<CShader> prog);
-
- bool explicitSyncSupported();
- WP<CShader> getShaderVariant(Render::ePreparedFragmentShader frag, Render::ShaderFeatureFlags features = 0);
-
- bool m_shadersInitialized = false;
- SP<SPreparedShaders> m_shaders;
-
- Hyprutils::OS::CFileDescriptor m_gbmFD;
- gbm_device* m_gbmDevice = nullptr;
- EGLContext m_eglContext = nullptr;
- EGLDisplay m_eglDisplay = nullptr;
- EGLDeviceEXT m_eglDevice = nullptr;
-
- std::map<PHLMONITORREF, SP<IFramebuffer>> m_monitorBGFBs;
-
- struct {
- PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES = nullptr;
- PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = nullptr;
- PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = nullptr;
- PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = nullptr;
- PFNEGLQUERYDMABUFFORMATSEXTPROC eglQueryDmaBufFormatsEXT = nullptr;
- PFNEGLQUERYDMABUFMODIFIERSEXTPROC eglQueryDmaBufModifiersEXT = nullptr;
- PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = nullptr;
- PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR = nullptr;
- PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT = nullptr;
- PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT = nullptr;
- PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT = nullptr;
- PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR = nullptr;
- PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR = nullptr;
- PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID = nullptr;
- PFNEGLWAITSYNCKHRPROC eglWaitSyncKHR = nullptr;
- } m_proc;
-
- struct {
- bool EXT_read_format_bgra = false;
- bool EXT_image_dma_buf_import = false;
- bool EXT_image_dma_buf_import_modifiers = false;
- bool KHR_context_flush_control = false;
- bool KHR_display_reference = false;
- bool IMG_context_priority = false;
- bool EXT_create_context_robustness = false;
- bool EGL_ANDROID_native_fence_sync_ext = false;
- } m_exts;
-
- enum eEGLContextVersion : uint8_t {
- EGL_CONTEXT_GLES_2_0 = 0,
- EGL_CONTEXT_GLES_3_0,
- EGL_CONTEXT_GLES_3_2,
+ struct SCurrentRenderData {
+ PHLMONITORREF pMonitor;
+ Mat3x3 projection;
+ Mat3x3 savedProjection;
+ Mat3x3 monitorProjection;
+
+ SP<IFramebuffer> currentFB = nullptr; // current rendering to
+ SP<IFramebuffer> mainFB = nullptr; // main to render to
+ SP<IFramebuffer> outFB = nullptr; // out to render to (if offloaded, etc)
+
+ CRegion damage;
+ CRegion finalDamage; // damage used for funal off -> main
+
+ Render::SRenderModifData renderModif;
+ float mouseZoomFactor = 1.f;
+ bool mouseZoomUseMouse = true; // true by default
+ bool useNearestNeighbor = false;
+ bool blockScreenShader = false;
+ bool simplePass = false;
+ bool transformDamage = true;
+ bool noSimplify = false;
+
+ Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
+ Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
+
+ CBox clipBox = {}; // scaled coordinates
+ CRegion clipRegion;
+
+ uint32_t discardMode = DISCARD_OPAQUE;
+ float discardOpacity = 0.f;
+
+ PHLLSREF currentLS;
+ PHLWINDOWREF currentWindow;
+ WP<CWLSurfaceResource> surface;
};
- eEGLContextVersion m_eglContextVersion = EGL_CONTEXT_GLES_3_2;
+ class CEGLSync : public ISyncFDManager {
+ public:
+ static UP<CEGLSync> create();
+ ~CEGLSync() override;
+
+ bool isValid() override;
- enum eCachedCapStatus : uint8_t {
- CAP_STATUS_BLEND = 0,
- CAP_STATUS_SCISSOR_TEST,
- CAP_STATUS_STENCIL_TEST,
- CAP_STATUS_END
+ private:
+ CEGLSync() : ISyncFDManager() {};
+
+ EGLSyncKHR m_sync = EGL_NO_SYNC_KHR;
+
+ friend class CHyprOpenGLImpl;
};
- private:
- struct {
- GLint x = 0;
- GLint y = 0;
- GLsizei width = 0;
- GLsizei height = 0;
- } m_lastViewport;
-
- std::array<bool, CAP_STATUS_END> m_capStatus = {};
-
- std::vector<SDRMFormat> m_drmFormats;
- bool m_hasModifiers = false;
-
- int m_drmFD = -1;
- std::string m_extensions;
-
- bool m_fakeFrame = false;
- bool m_applyFinalShader = false;
- bool m_blend = false;
- bool m_offloadedFramebuffer = false;
- bool m_cmSupported = true;
-
- SP<CShader> m_finalScreenShader;
- GLuint m_currentProgram = 0;
-
- void initDRMFormats();
- void initEGL(bool gbm);
- EGLDeviceEXT eglDeviceFromDRMFD(int drmFD);
-
- // for the final shader
- std::array<CTimer, POINTER_PRESSED_HISTORY_LENGTH> m_pressedHistoryTimers = {};
- std::array<Vector2D, POINTER_PRESSED_HISTORY_LENGTH> m_pressedHistoryPositions = {};
- GLint m_pressedHistoryKilled = 0;
- GLint m_pressedHistoryTouched = 0;
-
- //
- std::optional<std::vector<uint64_t>> getModsForFormat(EGLint format);
-
- // returns the out FB, can be either Mirror or MirrorSwap
- SP<IFramebuffer> blurFramebufferWithDamage(float a, CRegion* damage, CGLFramebuffer& source);
-
- void passCMUniforms(WP<CShader>, const NColorManagement::PImageDescription imageDescription, const NColorManagement::PImageDescription targetImageDescription,
- bool modifySDR = false, float sdrMinLuminance = -1.0f, int sdrMaxLuminance = -1);
- void passCMUniforms(WP<CShader>, const NColorManagement::PImageDescription imageDescription);
- void renderRectInternal(const CBox&, const CHyprColor&, const SRectRenderData& data);
- void renderRectWithBlurInternal(const CBox&, const CHyprColor&, const SRectRenderData& data);
- void renderRectWithDamageInternal(const CBox&, const CHyprColor&, const SRectRenderData& data);
- WP<CShader> renderToOutputInternal();
- WP<CShader> renderToFBInternal(const STextureRenderData& data, eTextureType texType, const CBox& newBox);
- void renderTextureInternal(SP<ITexture>, const CBox&, const STextureRenderData& data);
- void renderTextureWithBlurInternal(SP<ITexture>, const CBox&, const STextureRenderData& data);
-
- friend class IHyprRenderer;
- friend class CHyprGLRenderer;
- friend class CTexPassElement;
- friend class CPreBlurElement;
- friend class CSurfacePassElement;
-};
-
-inline UP<CHyprOpenGLImpl> g_pHyprOpenGL;
+ class CHyprOpenGLImpl {
+ public:
+ CHyprOpenGLImpl();
+ ~CHyprOpenGLImpl();
+
+ struct SRectRenderData {
+ const CRegion* damage = nullptr;
+ int round = 0;
+ float roundingPower = 2.F;
+ bool blur = false;
+ float blurA = 1.F;
+ bool xray = false;
+ };
+
+ struct STextureRenderData {
+ bool blur = false;
+ float blurA = 1.F, overallA = 1.F;
+ bool blockBlurOptimization = false;
+ SP<ITexture> blurredBG;
+
+ const CRegion* damage = nullptr;
+ SP<CWLSurfaceResource> surface = nullptr;
+ float a = 1.F;
+ int round = 0;
+ float roundingPower = 2.F;
+ bool discardActive = false;
+ bool allowCustomUV = false;
+ bool allowDim = true;
+ bool noAA = false; // unused
+ GLenum wrapX = GL_CLAMP_TO_EDGE, wrapY = GL_CLAMP_TO_EDGE;
+ bool cmBackToSRGB = false;
+ bool finalMonitorCM = false;
+ SP<CMonitor> cmBackToSRGBSource;
+
+ uint32_t discardMode = DISCARD_OPAQUE;
+ float discardOpacity = 0.f;
+
+ CRegion clipRegion;
+ PHLLSREF currentLS;
+
+ Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
+ Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
+ };
+
+ struct SBorderRenderData {
+ int round = 0;
+ float roundingPower = 2.F;
+ int borderSize = 1;
+ float a = 1.0;
+ int outerRound = -1; /* use round */
+ };
+
+ void makeEGLCurrent();
+ void begin(PHLMONITOR, const CRegion& damage, SP<IFramebuffer> fb = nullptr, std::optional<CRegion> finalDamage = {});
+ void beginSimple(PHLMONITOR, const CRegion& damage, SP<IRenderbuffer> rb = nullptr, SP<IFramebuffer> fb = nullptr);
+ void end();
+
+ void renderRect(const CBox&, const CHyprColor&, SRectRenderData data);
+ void renderTexture(SP<ITexture>, const CBox&, STextureRenderData data);
+ void renderRoundedShadow(const CBox&, int round, float roundingPower, int range, const CHyprColor& color, float a = 1.0);
+ void renderInnerGlow(const CBox&, int round, float roundingPower, int range, const CHyprColor& color, int glowPower, float a = 1.0);
+ void renderBorder(const CBox&, const Config::CGradientValueData&, SBorderRenderData data);
+ void renderBorder(const CBox&, const Config::CGradientValueData&, const Config::CGradientValueData&, float lerp, SBorderRenderData data);
+ void renderTextureMatte(SP<ITexture> tex, const CBox& pBox, SP<IFramebuffer> matte);
+ void renderTexturePrimitive(SP<ITexture> tex, const CBox& box);
+
+ void setViewport(GLint x, GLint y, GLsizei width, GLsizei height);
+ void setCapStatus(int cap, bool status);
+
+ void blend(bool enabled);
+
+ void scissor(const CBox&, bool transform = true);
+ void scissor(const pixman_box32*, bool transform = true);
+ void scissor(const int x, const int y, const int w, const int h, bool transform = true);
+
+ void destroyMonitorResources(PHLMONITORREF);
+
+ void preRender(PHLMONITOR);
+
+ void saveBufferForMirror(const CBox&);
+
+ void applyScreenShader(const std::string& path);
+
+ void renderOffToMain(SP<IFramebuffer> off);
+
+ std::vector<SDRMFormat> getDRMFormats();
+ std::vector<uint64_t> getDRMFormatModifiers(DRMFormat format);
+ EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs);
+
+ bool initShaders(const std::string& path = "");
+
+ WP<CShader> useShader(WP<CShader> prog);
+
+ bool explicitSyncSupported();
+ WP<CShader> getShaderVariant(Render::ePreparedFragmentShader frag, Render::ShaderFeatureFlags features = 0);
+
+ bool m_shadersInitialized = false;
+ SP<SPreparedShaders> m_shaders;
+
+ Hyprutils::OS::CFileDescriptor m_gbmFD;
+ gbm_device* m_gbmDevice = nullptr;
+ EGLContext m_eglContext = nullptr;
+ EGLDisplay m_eglDisplay = nullptr;
+ EGLDeviceEXT m_eglDevice = nullptr;
+
+ std::map<PHLMONITORREF, SP<IFramebuffer>> m_monitorBGFBs;
+
+ struct {
+ PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES = nullptr;
+ PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = nullptr;
+ PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = nullptr;
+ PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = nullptr;
+ PFNEGLQUERYDMABUFFORMATSEXTPROC eglQueryDmaBufFormatsEXT = nullptr;
+ PFNEGLQUERYDMABUFMODIFIERSEXTPROC eglQueryDmaBufModifiersEXT = nullptr;
+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = nullptr;
+ PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR = nullptr;
+ PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT = nullptr;
+ PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT = nullptr;
+ PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT = nullptr;
+ PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR = nullptr;
+ PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR = nullptr;
+ PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID = nullptr;
+ PFNEGLWAITSYNCKHRPROC eglWaitSyncKHR = nullptr;
+ } m_proc;
+
+ struct {
+ bool EXT_read_format_bgra = false;
+ bool EXT_image_dma_buf_import = false;
+ bool EXT_image_dma_buf_import_modifiers = false;
+ bool KHR_context_flush_control = false;
+ bool KHR_display_reference = false;
+ bool IMG_context_priority = false;
+ bool EXT_create_context_robustness = false;
+ bool EGL_ANDROID_native_fence_sync_ext = false;
+ } m_exts;
+
+ enum eEGLContextVersion : uint8_t {
+ EGL_CONTEXT_GLES_2_0 = 0,
+ EGL_CONTEXT_GLES_3_0,
+ EGL_CONTEXT_GLES_3_2,
+ };
+
+ eEGLContextVersion m_eglContextVersion = EGL_CONTEXT_GLES_3_2;
+
+ enum eCachedCapStatus : uint8_t {
+ CAP_STATUS_BLEND = 0,
+ CAP_STATUS_SCISSOR_TEST,
+ CAP_STATUS_STENCIL_TEST,
+ CAP_STATUS_END
+ };
+
+ private:
+ struct {
+ GLint x = 0;
+ GLint y = 0;
+ GLsizei width = 0;
+ GLsizei height = 0;
+ } m_lastViewport;
+
+ std::array<bool, CAP_STATUS_END> m_capStatus = {};
+
+ std::vector<SDRMFormat> m_drmFormats;
+ bool m_hasModifiers = false;
+
+ int m_drmFD = -1;
+ std::string m_extensions;
+
+ bool m_fakeFrame = false;
+ bool m_applyFinalShader = false;
+ bool m_blend = false;
+ bool m_offloadedFramebuffer = false;
+ bool m_cmSupported = true;
+
+ SP<CShader> m_finalScreenShader;
+ GLuint m_currentProgram;
+
+ void initDRMFormats();
+ void initEGL(bool gbm);
+ EGLDeviceEXT eglDeviceFromDRMFD(int drmFD);
+
+ // for the final shader
+ std::array<CTimer, POINTER_PRESSED_HISTORY_LENGTH> m_pressedHistoryTimers = {};
+ std::array<Vector2D, POINTER_PRESSED_HISTORY_LENGTH> m_pressedHistoryPositions = {};
+ GLint m_pressedHistoryKilled = 0;
+ GLint m_pressedHistoryTouched = 0;
+
+ //
+ std::optional<std::vector<uint64_t>> getModsForFormat(EGLint format);
+
+ // returns the out FB, can be either Mirror or MirrorSwap
+ SP<IFramebuffer> blurFramebufferWithDamage(float a, CRegion* damage, CGLFramebuffer& source);
+
+ void passCMUniforms(WP<CShader>, const NColorManagement::PImageDescription imageDescription, const NColorManagement::PImageDescription targetImageDescription,
+ bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance, const SCMSettings& settings);
+ void passCMUniforms(WP<CShader>, const NColorManagement::PImageDescription imageDescription, const NColorManagement::PImageDescription targetImageDescription,
+ bool modifySDR = false, float sdrMinLuminance = -1.0f, int sdrMaxLuminance = -1);
+ void passCMUniforms(WP<CShader>, const NColorManagement::PImageDescription imageDescription);
+ void renderRectInternal(const CBox&, const CHyprColor&, const SRectRenderData& data);
+ void renderRectWithBlurInternal(const CBox&, const CHyprColor&, const SRectRenderData& data);
+ void renderRectWithDamageInternal(const CBox&, const CHyprColor&, const SRectRenderData& data);
+ WP<CShader> renderToOutputInternal();
+ WP<CShader> renderToFBInternal(SP<ITexture> tex, const STextureRenderData& data, eTextureType texType, const CBox& newBox);
+ void renderTextureInternal(SP<ITexture>, const CBox&, const STextureRenderData& data);
+ void renderTextureWithBlurInternal(SP<ITexture>, const CBox&, const STextureRenderData& data);
+
+ friend class IHyprRenderer;
+ friend class CHyprGLRenderer;
+ friend class CGLElementRenderer;
+ friend class CTexPassElement;
+ friend class CPreBlurElement;
+ friend class CSurfacePassElement;
+ };
+
+ inline UP<CHyprOpenGLImpl> g_pHyprOpenGL;
+}