summaryrefslogtreecommitdiff
path: root/src/protocols/ToplevelExport.hpp
blob: 44704d844f0da9c61a1cf183f66e1e4f8a48ed41 (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
#pragma once

#include "../defines.hpp"
#include "hyprland-toplevel-export-v1.hpp"
#include "WaylandProtocol.hpp"
#include "Screencopy.hpp"
#include "../helpers/time/Time.hpp"

#include <vector>

class CMonitor;

class CToplevelExportClient {
  public:
    CToplevelExportClient(SP<CHyprlandToplevelExportManagerV1> resource_);

    bool                      good();

    WP<CToplevelExportClient> m_self;
    eClientOwners             m_clientOwner = CLIENT_TOPLEVEL_EXPORT;

    CTimer                    m_lastFrame;
    int                       m_frameCounter = 0;

  private:
    SP<CHyprlandToplevelExportManagerV1> m_resource;

    int                                  m_framesInLastHalfSecond = 0;
    CTimer                               m_lastMeasure;
    bool                                 m_sentScreencast = false;

    SP<HOOK_CALLBACK_FN>                 m_tickCallback;
    void                                 onTick();

    void                                 captureToplevel(CHyprlandToplevelExportManagerV1* pMgr, uint32_t frame, int32_t overlayCursor, PHLWINDOW handle);

    friend class CToplevelExportProtocol;
};

class CToplevelExportFrame {
  public:
    CToplevelExportFrame(SP<CHyprlandToplevelExportFrameV1> resource_, int32_t overlayCursor, PHLWINDOW pWindow);

    bool                      good();

    WP<CToplevelExportFrame>  m_self;
    WP<CToplevelExportClient> m_client;

  private:
    SP<CHyprlandToplevelExportFrameV1> m_resource;

    PHLWINDOW                          m_window;
    bool                               m_cursorOverlayRequested = false;
    bool                               m_ignoreDamage           = false;

    CHLBufferReference                 m_buffer;
    bool                               m_bufferDMA    = false;
    uint32_t                           m_shmFormat    = 0;
    uint32_t                           m_dmabufFormat = 0;
    int                                m_shmStride    = 0;
    CBox                               m_box          = {};

    void                               copy(CHyprlandToplevelExportFrameV1* pFrame, wl_resource* buffer, int32_t ignoreDamage);
    bool                               copyDmabuf(const Time::steady_tp& now);
    bool                               copyShm(const Time::steady_tp& now);
    void                               share();
    bool                               shouldOverlayCursor() const;

    friend class CToplevelExportProtocol;
};

class CToplevelExportProtocol : IWaylandProtocol {
  public:
    CToplevelExportProtocol(const wl_interface* iface, const int& ver, const std::string& name);

    void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
    void destroyResource(CToplevelExportClient* client);
    void destroyResource(CToplevelExportFrame* frame);

    void onOutputCommit(PHLMONITOR pMonitor);

  private:
    std::vector<SP<CToplevelExportClient>> m_clients;
    std::vector<SP<CToplevelExportFrame>>  m_frames;
    std::vector<WP<CToplevelExportFrame>>  m_framesAwaitingWrite;

    void                                   onWindowUnmap(PHLWINDOW pWindow);

    void                                   shareFrame(CToplevelExportFrame* frame);
    bool                                   copyFrameDmabuf(CToplevelExportFrame* frame, const Time::steady_tp& now);
    bool                                   copyFrameShm(CToplevelExportFrame* frame, const Time::steady_tp& now);
    void                                   sendDamage(CToplevelExportFrame* frame);

    friend class CToplevelExportClient;
    friend class CToplevelExportFrame;
};

namespace PROTO {
    inline UP<CToplevelExportProtocol> toplevelExport;
};