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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
#pragma once
#include "../defines.hpp"
#include "../helpers/Monitor.hpp"
#include "../helpers/Color.hpp"
#include "../helpers/Timer.hpp"
#include "../helpers/Region.hpp"
#include <list>
#include <unordered_map>
#include <cairo/cairo.h>
#include "Shader.hpp"
#include "Texture.hpp"
#include "Framebuffer.hpp"
#include "Transformer.hpp"
#include "../debug/TracyDefines.hpp"
class CHyprRenderer;
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};
enum eDiscardMode
{
DISCARD_OPAQUE = 1,
DISCARD_ALPHA = 1 << 1
};
struct SRenderModifData {
Vector2D translate = {};
float scale = 1.f;
};
struct SMonitorRenderData {
CFramebuffer primaryFB;
CFramebuffer mirrorFB; // these are used for some effects,
CFramebuffer mirrorSwapFB; // etc
CFramebuffer offMainFB;
CFramebuffer monitorMirrorFB; // used for mirroring outputs
CTexture stencilTex;
CFramebuffer blurFB;
bool blurFBDirty = true;
bool blurFBShouldRender = false;
wlr_box backgroundTexBox;
// Shaders
bool m_bShadersInitialized = false;
CShader m_shQUAD;
CShader m_shRGBA;
CShader m_shPASSTHRURGBA;
CShader m_shRGBX;
CShader m_shEXT;
CShader m_shBLUR1;
CShader m_shBLUR2;
CShader m_shBLURFINISH;
CShader m_shSHADOW;
CShader m_shBORDER1;
CShader m_shGLITCH;
//
};
struct SCurrentRenderData {
CMonitor* pMonitor = nullptr;
CWorkspace* pWorkspace = nullptr;
float projection[9];
float savedProjection[9];
SMonitorRenderData* pCurrentMonData = nullptr;
CFramebuffer* currentFB = nullptr;
CRegion damage;
SRenderModifData renderModif;
float mouseZoomFactor = 1.f;
bool mouseZoomUseMouse = true; // true by default
bool useNearestNeighbor = false;
Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
wlr_box clipBox = {};
uint32_t discardMode = DISCARD_OPAQUE;
float discardOpacity = 0.f;
};
class CGradientValueData;
class CHyprOpenGLImpl {
public:
CHyprOpenGLImpl();
void begin(CMonitor*, CRegion*, bool fake = false);
void end();
void bindWlrOutputFb();
void renderRect(wlr_box*, const CColor&, int round = 0);
void renderRectWithBlur(wlr_box*, const CColor&, int round = 0, float blurA = 1.f);
void renderRectWithDamage(wlr_box*, const CColor&, CRegion* 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 discardActive = false, bool allowCustomUV = false);
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f);
void renderRoundedShadow(wlr_box*, int round, int range, float a = 1.0, CFramebuffer* matte = nullptr);
void renderBorder(wlr_box*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */);
void saveMatrix();
void setMatrixScaleTranslate(const Vector2D& translate, const float& scale);
void restoreMatrix();
void blend(bool enabled);
void makeWindowSnapshot(CWindow*);
void makeRawWindowSnapshot(CWindow*, CFramebuffer*);
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();
bool preBlurQueued();
void preRender(CMonitor*);
void saveBufferForMirror();
void renderMirrored();
void applyScreenShader(const std::string& path);
void bindOffMain();
void renderOffToMain(CFramebuffer* off);
void bindBackOnMain();
SCurrentRenderData m_RenderData;
GLint m_iCurrentOutputFb = 0;
GLint m_iWLROutputFb = 0;
bool m_bReloadScreenShader = true; // at launch it can be set
CWindow* m_pCurrentWindow = nullptr; // hack to get the current rendered window
SLayerSurface* m_pCurrentLayer = nullptr; // hack to get the current rendered layer
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;
bool m_bApplyFinalShader = false;
bool m_bBlend = false;
CShader m_sFinalScreenShader;
CTimer m_tGlobalTimer;
GLuint createProgram(const std::string&, const std::string&, bool dynamic = false);
GLuint compileShader(const GLuint&, std::string, bool dynamic = false);
void createBGTextureForMonitor(CMonitor*);
void initShaders();
// returns the out FB, can be either Mirror or MirrorSwap
CFramebuffer* blurMainFramebufferWithDamage(float a, CRegion* damage);
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, CRegion* damage, int round = 0, bool discardOpaque = false, bool noAA = false,
bool allowCustomUV = false, bool allowDim = false);
void renderTexturePrimitive(const CTexture& tex, wlr_box* pBox);
void renderSplash(cairo_t* const, cairo_surface_t* const, double);
void preBlurForCurrentMonitor();
bool shouldUseNewBlurOptimizations(SLayerSurface* pLayer, CWindow* pWindow);
friend class CHyprRenderer;
};
inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL;
|