aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/render/OpenGL.hpp
blob: fa19305747b9f98db62fd9b38e1a9b3bf6d066a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#pragma once

#include "../defines.hpp"
#include "../helpers/Monitor.hpp"
#include "../helpers/Color.hpp"
#include <list>
#include <unordered_map>

#include "Shaders.hpp"
#include "Shader.hpp"
#include "Texture.hpp"
#include "Framebuffer.hpp"

inline const float matrixFlip180[] = {
	1.0f, 0.0f, 0.0f,
	0.0f, -1.0f, 0.0f,
	0.0f, 0.0f, 1.0f,
};
inline const float fullVerts[] = {
    1, 0,  // top right
    0, 0,  // top left
    1, 1,  // bottom right
    0, 1,  // bottom left
};
inline const float fanVertsFull[] = {
    -1.0f, -1.0f,
    1.0f, -1.0f,
    1.0f, 1.0f,
    -1.0f, 1.0f
};

struct SCurrentRenderData {
    SMonitor*   pMonitor = nullptr;
    float       projection[9];

    pixman_region32_t* pDamage = nullptr;
};

struct SMonitorRenderData {
    CFramebuffer primaryFB;
    CFramebuffer mirrorFB;
    CFramebuffer mirrorSwapFB;

    CTexture     stencilTex;
};

class CHyprOpenGLImpl {
public:

    CHyprOpenGLImpl();

    void    begin(SMonitor*, pixman_region32_t*, bool fake = false);
    void    end();

    void    renderRect(wlr_box*, const CColor&, int round = 0);
    void    renderTexture(wlr_texture*, wlr_box*, float a, int round = 0);
    void    renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool border = false);
    void    renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool border = false);

    void    makeWindowSnapshot(CWindow*);
    void    makeLayerSnapshot(SLayerSurface*);
    void    renderSnapshot(CWindow**);
    void    renderSnapshot(SLayerSurface**);

    void    clear(const CColor&);
    void    clearWithTex();
    void    scissor(const wlr_box*);
    void    scissor(const pixman_box32*);
    void    scissor(const int x, const int y, const int w, const int h);

    void    destroyMonitorResources(SMonitor*);

    SCurrentRenderData m_RenderData;

    GLint  m_iCurrentOutputFb = 0;
    GLint  m_iWLROutputFb = 0;

    CWindow* m_pCurrentWindow = nullptr; // hack to get the current rendered window

    pixman_region32_t m_rOriginalDamageRegion; // used for storing the pre-expanded region

    std::unordered_map<CWindow*, CFramebuffer> m_mWindowFramebuffers;
    std::unordered_map<SLayerSurface*, CFramebuffer> m_mLayerFramebuffers;
    std::unordered_map<SMonitor*, SMonitorRenderData> m_mMonitorRenderResources;
    std::unordered_map<SMonitor*, CTexture> m_mMonitorBGTextures;

private:
    std::list<GLuint>       m_lBuffers;
    std::list<GLuint>       m_lTextures;

    int                     m_iDRMFD;
    std::string             m_szExtensions;

    bool                    m_bFakeFrame = false;

    // Shaders
    SQuad                   m_shQUAD;
    CShader                 m_shRGBA;
    CShader                 m_shRGBX;
    CShader                 m_shEXT;
    CShader                 m_shBLUR1;
    CShader                 m_shBLUR2;
    //

    GLuint                  createProgram(const std::string&, const std::string&);
    GLuint                  compileShader(const GLuint&, std::string);
    void                    createBGTextureForMonitor(SMonitor*);

    // returns the out FB, can be either Mirror or MirrorSwap
    CFramebuffer*           blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);

    void                    renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool border = false);
    void                    renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0);
};

inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL;