summaryrefslogtreecommitdiff
path: root/src/render/OpenGL.hpp
blob: 33ebb96489b39209d2307f6ef54d3520bcfb890e (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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#pragma once

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

#include <cairo/cairo.h>

#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 SMonitorRenderData {
    CFramebuffer primaryFB;
    CFramebuffer mirrorFB;     // these are used for some effects,
    CFramebuffer mirrorSwapFB; // etc

    CFramebuffer monitorMirrorFB; // used for mirroring outputs

    CTexture     stencilTex;

    CFramebuffer blurFB;
    bool         blurFBDirty = true;

    wlr_box      backgroundTexBox;

    // Shaders
    bool                    m_bShadersInitialized = false;
    CShader                 m_shQUAD;
    CShader                 m_shRGBA;
    CShader                 m_shRGBX;
    CShader                 m_shEXT;
    CShader                 m_shBLUR1;
    CShader                 m_shBLUR2;
    CShader                 m_shSHADOW;
    CShader                 m_shBORDER1;
    //
};

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

    SMonitorRenderData* pCurrentMonData = nullptr;

    pixman_region32_t* pDamage = nullptr;

    Vector2D    primarySurfaceUVTopLeft = Vector2D(-1, -1);
    Vector2D    primarySurfaceUVBottomRight = Vector2D(-1, -1);

    wlr_box     clipBox = {};
};

class CHyprOpenGLImpl {
public:

    CHyprOpenGLImpl();

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

    void    renderRect(wlr_box*, const CColor&, int round = 0);
    void    renderRectWithDamage(wlr_box*, const CColor&, pixman_region32_t* damage, int round = 0);
    void    renderTexture(wlr_texture*, wlr_box*, float a, int round = 0, bool allowCustomUV = false);
    void    renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool allowCustomUV = false);
    void    renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0);
    void    renderRoundedShadow(wlr_box*, int round, int range, float a = 1.0);
    void    renderBorder(wlr_box*, const CColor&, int round);

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

    void    clear(const CColor&);
    void    clearWithTex();
    void    scissor(const wlr_box*, 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(CMonitor*);

    void    markBlurDirtyForMonitor(CMonitor*);

    void    preWindowPass();
    void    preRender(CMonitor*);

    void    saveBufferForMirror();
    void    renderMirrored();

    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<CMonitor*, SMonitorRenderData> m_mMonitorRenderResources;
    std::unordered_map<CMonitor*, 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;
    bool                    m_bEndFrame = false;

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

    // 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 noAA = false, bool allowCustomUV = false, bool allowDim = false);
    void                    renderSplash(cairo_t *const, cairo_surface_t *const, double);

    void                    preBlurForCurrentMonitor();
};

inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL;