summaryrefslogtreecommitdiff
path: root/src/render/Renderer.hpp
blob: a832802e52fb119f1c8b720f826fc138085624f7 (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
#pragma once

#include "../defines.hpp"
#include <list>
#include "../helpers/Monitor.hpp"
#include "../helpers/Workspace.hpp"
#include "../Window.hpp"
#include "OpenGL.hpp"
#include "Renderbuffer.hpp"
#include "../helpers/Timer.hpp"
#include "../helpers/Region.hpp"

struct SMonitorRule;

// TODO: add fuller damage tracking for updating only parts of a window
enum DAMAGETRACKINGMODES {
    DAMAGE_TRACKING_INVALID = -1,
    DAMAGE_TRACKING_NONE    = 0,
    DAMAGE_TRACKING_MONITOR,
    DAMAGE_TRACKING_FULL
};

enum eRenderPassMode {
    RENDER_PASS_ALL = 0,
    RENDER_PASS_MAIN,
    RENDER_PASS_POPUP
};

enum eRenderMode {
    RENDER_MODE_NORMAL              = 0,
    RENDER_MODE_FULL_FAKE           = 1,
    RENDER_MODE_TO_BUFFER           = 2,
    RENDER_MODE_TO_BUFFER_READ_ONLY = 3,
};

class CToplevelExportProtocolManager;
class CInputManager;
struct SSessionLockSurface;

class CHyprRenderer {
  public:
    CHyprRenderer();

    void                            renderMonitor(CMonitor* pMonitor);
    void                            outputMgrApplyTest(wlr_output_configuration_v1*, bool);
    void                            arrangeLayersForMonitor(const int&);
    void                            damageSurface(wlr_surface*, double, double, double scale = 1.0);
    void                            damageWindow(CWindow*);
    void                            damageBox(CBox*);
    void                            damageBox(const int& x, const int& y, const int& w, const int& h);
    void                            damageRegion(const CRegion&);
    void                            damageMonitor(CMonitor*);
    void                            damageMirrorsWith(CMonitor*, const CRegion&);
    bool                            applyMonitorRule(CMonitor*, SMonitorRule*, bool force = false);
    bool                            shouldRenderWindow(CWindow*, CMonitor*, CWorkspace*);
    bool                            shouldRenderWindow(CWindow*);
    void                            ensureCursorRenderingMode();
    bool                            shouldRenderCursor();
    void                            calculateUVForSurface(CWindow*, wlr_surface*, bool main = false);
    std::tuple<float, float, float> getRenderTimes(CMonitor* pMonitor); // avg max min
    void                            renderLockscreen(CMonitor* pMonitor, timespec* now);
    void                            setOccludedForBackLayers(CRegion& region, CWorkspace* pWorkspace);
    bool                            canSkipBackBufferClear(CMonitor* pMonitor);
    void                            recheckSolitaryForMonitor(CMonitor* pMonitor);
    void                            setCursorSurface(wlr_surface* surf, int hotspotX, int hotspotY);
    void                            setCursorFromName(const std::string& name);
    void                            renderSoftwareCursors(CMonitor* pMonitor, const CRegion& damage, std::optional<Vector2D> overridePos = {});
    void                            onRenderbufferDestroy(CRenderbuffer* rb);
    CRenderbuffer*                  getCurrentRBO();
    bool                            isNvidia();
    void                            makeEGLCurrent();
    void                            unsetEGL();

    bool      beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode mode = RENDER_MODE_NORMAL, wlr_buffer* buffer = nullptr, CFramebuffer* fb = nullptr);
    void      endRender();

    bool      m_bWindowRequestedCursorHide = false;
    bool      m_bBlockSurfaceFeedback      = false;
    bool      m_bRenderingSnapshot         = false;
    CWindow*  m_pLastScanout               = nullptr;
    CMonitor* m_pMostHzMonitor             = nullptr;
    bool      m_bDirectScanoutBlocked      = false;
    bool      m_bSoftwareCursorsLocked     = false;
    bool      m_bTearingEnvSatisfied       = false;

    DAMAGETRACKINGMODES
    damageTrackingModeFromStr(const std::string&);

    bool                                             attemptDirectScanout(CMonitor*);
    void                                             setWindowScanoutMode(CWindow*);
    void                                             initiateManualCrash();

    bool                                             m_bCrashingInProgress = false;
    float                                            m_fCrashingDistort    = 0.5f;
    wl_event_source*                                 m_pCrashingLoop       = nullptr;

    std::vector<std::unique_ptr<STearingController>> m_vTearingControllers;

    CTimer                                           m_tRenderTimer;

    struct {
        std::optional<wlr_surface*> surf = nullptr;
        std::string                 name;
    } m_sLastCursorData;

  private:
    void           arrangeLayerArray(CMonitor*, const std::vector<std::unique_ptr<SLayerSurface>>&, bool, CBox*);
    void           renderWorkspaceWindowsFullscreen(CMonitor*, CWorkspace*, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special)
    void           renderWorkspaceWindows(CMonitor*, CWorkspace*, timespec*);           // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special)
    void           renderWindow(CWindow*, CMonitor*, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool ignoreAllGeometry = false);
    void           renderLayer(SLayerSurface*, CMonitor*, timespec*);
    void           renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*);
    void           renderDragIcon(CMonitor*, timespec*);
    void           renderIMEPopup(SIMEPopup*, CMonitor*, timespec*);
    void           renderWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const CBox& geometry);
    void           renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f);

    bool           m_bHasARenderedCursor  = true;
    bool           m_bCursorHasSurface    = false;
    CRenderbuffer* m_pCurrentRenderbuffer = nullptr;
    wlr_buffer*    m_pCurrentWlrBuffer    = nullptr;
    eRenderMode    m_eRenderMode          = RENDER_MODE_NORMAL;
    int            m_iLastBufferAge       = 0;

    bool           m_bNvidia = false;

    CRenderbuffer* getOrCreateRenderbuffer(wlr_buffer* buffer, uint32_t fmt);
    std::vector<std::unique_ptr<CRenderbuffer>> m_vRenderbuffers;

    friend class CHyprOpenGLImpl;
    friend class CToplevelExportProtocolManager;
    friend class CInputManager;
};

inline std::unique_ptr<CHyprRenderer> g_pHyprRenderer;