forked from LemonOSProject/LemonOS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Compositor.h
150 lines (115 loc) · 4.53 KB
/
Compositor.h
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
#pragma once
#include <Lemon/Graphics/Surface.h>
#include <Lemon/Graphics/Types.h>
#include <atomic>
#include <ctime>
#include <list>
#include <thread>
template <typename T, class... D> std::list<T> SplitModify(Rect& victim, const Rect& cut, D... extraData) {
std::list<T> clips;
if (cut.left() >= victim.left() && cut.left() <= victim.right()) { // Clip left edge
Rect clip;
clip.top(victim.top());
clip.left(victim.left());
clip.bottom(victim.bottom());
clip.right(cut.left()); // Left of cutting rect's left edge
victim.left(cut.left());
if (clip.width > 0) {
clips.push_back({clip, extraData...});
}
}
if (cut.top() >= victim.top() && cut.top() <= victim.bottom()) { // Clip top edge
Rect clip;
clip.top(victim.top());
clip.left(victim.left());
clip.bottom(cut.top()); // Above cutting rect's top edge
clip.right(victim.right());
victim.top(cut.top());
if (clip.height > 0) {
clips.push_back({clip, extraData...});
}
}
if (cut.right() >= victim.left() && cut.right() <= victim.right()) { // Clip right edge
Rect clip;
clip.top(victim.top());
clip.left(cut.right());
clip.bottom(victim.bottom());
clip.right(victim.right());
victim.right(cut.right());
if (clip.width > 0) {
clips.push_back({clip, extraData...});
}
}
if (cut.bottom() >= victim.top() && cut.bottom() <= victim.bottom()) { // Clip bottom edge
Rect clip;
clip.top(cut.bottom());
clip.left(victim.left());
clip.bottom(victim.bottom());
clip.right(victim.right());
victim.bottom(cut.bottom());
if (clip.height > 0) {
clips.push_back({clip, extraData...});
}
}
return clips;
}
template <typename T, class... D> inline std::list<T> Split(Rect victim, const Rect& cut, D... extraData){
return SplitModify<T, D...>(victim, cut, extraData...);
}
struct WindowClipRect {
Rect rect;
class WMWindow* win;
enum {
TypeWindow,
TypeWindowDecoration,
} type = TypeWindow;
bool invalid = true;
std::list<WindowClipRect> SplitModify(const Rect& cut) { return ::SplitModify<WindowClipRect>(rect, cut, win, type, true); }
std::list<WindowClipRect> Split(const Rect& cut) { return ::Split<WindowClipRect>(rect, cut, win, type, true); }
};
struct BackgroundClipRect {
Rect rect;
bool invalid = true;
std::list<BackgroundClipRect> SplitModify(const Rect& cut) { return ::SplitModify<BackgroundClipRect, bool>(rect, cut, true); }
std::list<BackgroundClipRect> Split(const Rect& cut) { return ::Split<BackgroundClipRect, bool>(rect, cut, true); }
};
class Compositor {
public:
Compositor(const Surface& displaySurface);
void Render();
inline Vector2i GetScreenBounds() const { return {m_renderSurface.width, m_renderSurface.height}; }
void InvalidateAll();
void Invalidate(const Rect& rect);
void InvalidateWindow(class WMWindow* window);
void SetWallpaper(const std::string& path);
void SetShouldDisplayFramerate(bool value) { m_displayFramerate = value; }
inline void SetNormalCursor() { m_cursorCurrent = &m_cursorNormal; }
inline void SetResizeCursor() { m_cursorCurrent = &m_cursorResize; }
private:
void RecalculateWindowClipping();
void RecalculateBackgroundClipping();
void InvalidateBackgroundRect(BackgroundClipRect& bgRect);
void InvalidateWindowRect(WindowClipRect& wRect);
void InvalidateDecorationRect(WindowClipRect& dRect);
bool m_invalidateAll = true;
bool m_displayFramerate = false;
Vector2i m_lastMousePos = {0, 0};
Surface m_cursorNormal; // Normal mouse cursor
Surface m_cursorResize; // Window resize mouse cursor
Surface* m_cursorCurrent = &m_cursorNormal; // Current mouse cursor
// Used for framerate counter
timespec m_lastRender;
int m_avgFrametime = 0;
int m_fCount = 0;
int m_fRate = 0;
Surface m_renderSurface; // Backbuffer to render to
Surface m_displaySurface; // Display mapped surface
Surface m_wallpaper = {}; // Wallpaper surface
std::thread m_wallpaperThread;
std::atomic<int> m_wallpaperStatus = 0;
std::mutex m_renderMutex; // Currently only used for the wallpaper for invalidation
std::mutex m_wallpaperMutex;
std::list<BackgroundClipRect> m_backgroundRects;
std::list<WindowClipRect> m_windowClipRects;
std::list<WindowClipRect> m_windowDecorationClipRects;
};