-
-
Notifications
You must be signed in to change notification settings - Fork 116
Expand file tree
/
Copy pathLegacy.cpp
More file actions
172 lines (137 loc) · 7.38 KB
/
Copy pathLegacy.cpp
File metadata and controls
172 lines (137 loc) · 7.38 KB
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
#include "aquamarine/output/Output.hpp"
#include <aquamarine/backend/drm/Legacy.hpp>
#include <cstring>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <sys/mman.h>
using namespace Aquamarine;
using namespace Hyprutils::Memory;
using namespace Hyprutils::Math;
#define SP CSharedPointer
Aquamarine::CDRMLegacyImpl::CDRMLegacyImpl(Hyprutils::Memory::CSharedPointer<CDRMBackend> backend_) : backend(backend_) {
;
}
bool Aquamarine::CDRMLegacyImpl::moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, bool skipSchedule) {
if (!connector->output->cursorVisible || !connector->output->state->state().enabled || !connector->crtc || !connector->crtc->cursor)
return true;
if (!skipSchedule)
connector->output->scheduleFrame(IOutput::AQ_SCHEDULE_CURSOR_MOVE);
return true;
}
bool Aquamarine::CDRMLegacyImpl::commitInternal(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data) {
const auto& STATE = connector->output->state->state();
SP<CDRMFB> mainFB;
bool enable = STATE.enabled;
if (enable) {
if (!data.mainFB)
connector->backend->backend->log(AQ_LOG_WARNING, "legacy drm: No buffer, will fall back to only modeset (if present)");
else
mainFB = data.mainFB;
}
if (data.modeset) {
connector->backend->backend->log(AQ_LOG_DEBUG, std::format("legacy drm: Modesetting CRTC {}", connector->crtc->id));
uint32_t dpms = enable ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF;
if (drmModeConnectorSetProperty(connector->backend->gpu->fd, connector->id, connector->props.values.dpms, dpms)) {
connector->backend->backend->log(AQ_LOG_ERROR, "legacy drm: Failed to set dpms");
return false;
}
std::vector<uint32_t> connectors;
drmModeModeInfo* mode = nullptr;
if (enable) {
connectors.push_back(connector->id);
mode = &data.modeInfo;
}
if (mode) {
connector->backend->backend->log(
AQ_LOG_DEBUG,
std::format("legacy drm: Modesetting CRTC, mode: clock {} hdisplay {} vdisplay {} vrefresh {}", mode->clock, mode->hdisplay, mode->vdisplay, mode->vrefresh));
} else
connector->backend->backend->log(AQ_LOG_DEBUG, "legacy drm: Modesetting CRTC, mode null");
if (auto ret = drmModeSetCrtc(connector->backend->gpu->fd, connector->crtc->id, mainFB ? mainFB->id : -1, 0, 0, connectors.data(), connectors.size(), mode); ret) {
connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: drmModeSetCrtc failed: {}", strerror(-ret)));
return false;
}
}
if (STATE.committed & COutputState::eOutputStateProperties::AQ_OUTPUT_STATE_ADAPTIVE_SYNC) {
if (STATE.adaptiveSync && !connector->canDoVrr) {
connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: connector {} can't do vrr", connector->id));
return false;
}
if (connector->crtc->props.values.vrr_enabled) {
if (auto ret =
drmModeObjectSetProperty(backend->gpu->fd, connector->crtc->id, DRM_MODE_OBJECT_CRTC, connector->crtc->props.values.vrr_enabled, (uint64_t)STATE.adaptiveSync);
ret) {
connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: drmModeObjectSetProperty: vrr -> {} failed: {}", STATE.adaptiveSync, strerror(-ret)));
return false;
}
}
connector->output->vrrActive = STATE.adaptiveSync;
connector->backend->backend->log(AQ_LOG_DEBUG, std::format("legacy drm: connector {} vrr -> {}", connector->id, STATE.adaptiveSync));
}
// TODO: gamma
if (data.cursorFB && connector->crtc->cursor && connector->output->cursorVisible && enable &&
(STATE.committed & COutputState::AQ_OUTPUT_STATE_CURSOR_SHAPE || STATE.committed & COutputState::AQ_OUTPUT_STATE_CURSOR_POS)) {
uint32_t boHandle = 0;
auto attrs = data.cursorFB->buffer->dmabuf();
if (int ret = drmPrimeFDToHandle(connector->backend->gpu->fd, attrs.fds.at(0), &boHandle); ret) {
connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: drmPrimeFDToHandle failed: {}", strerror(-ret)));
return false;
}
connector->backend->backend->log(AQ_LOG_DEBUG,
std::format("legacy drm: cursor fb: {} with bo handle {} from fd {}, size {}", connector->backend->gpu->fd, boHandle,
data.cursorFB->buffer->dmabuf().fds.at(0), data.cursorFB->buffer->size));
Vector2D cursorPos = connector->output->cursorPos;
struct drm_mode_cursor2 request = {
.flags = DRM_MODE_CURSOR_BO | DRM_MODE_CURSOR_MOVE,
.crtc_id = connector->crtc->id,
.x = (int32_t)cursorPos.x,
.y = (int32_t)cursorPos.y,
.width = (uint32_t)data.cursorFB->buffer->size.x,
.height = (uint32_t)data.cursorFB->buffer->size.y,
.handle = boHandle,
.hot_x = (int32_t)connector->output->cursorHotspot.x,
.hot_y = (int32_t)connector->output->cursorHotspot.y,
};
int ret = drmIoctl(connector->backend->gpu->fd, DRM_IOCTL_MODE_CURSOR2, &request);
if (boHandle && drmCloseBufferHandle(connector->backend->gpu->fd, boHandle))
connector->backend->backend->log(AQ_LOG_ERROR, "legacy drm: drmCloseBufferHandle in cursor failed");
if (ret) {
connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: cursor drmIoctl failed: {}", strerror(errno)));
return false;
}
} else if (drmModeSetCursor(connector->backend->gpu->fd, connector->crtc->id, 0, 0, 0))
connector->backend->backend->log(AQ_LOG_ERROR, "legacy drm: cursor null failed");
if (!enable)
return true;
if (!(data.flags & DRM_MODE_PAGE_FLIP_EVENT))
return true;
if (int ret = drmModePageFlip(connector->backend->gpu->fd, connector->crtc->id, mainFB ? mainFB->id : -1, data.flags, &connector->pendingPageFlip); ret) {
connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: drmModePageFlip failed: {}", strerror(-ret)));
return false;
}
connector->isPageFlipPending = true;
struct timespec ts;
clock_gettime(CLOCK_BOOTTIME, &ts);
connector->pageFlipPendingAtMs = ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000ULL;
return true;
}
bool Aquamarine::CDRMLegacyImpl::testInternal(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data) {
return true; // TODO: lol
}
bool Aquamarine::CDRMLegacyImpl::commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data) {
if (!testInternal(connector, data))
return false;
return commitInternal(connector, data);
}
bool Aquamarine::CDRMLegacyImpl::reset() {
bool ok = true;
for (auto const& connector : backend->connectors) {
if (!connector->crtc)
continue;
if (int ret = drmModeSetCrtc(backend->gpu->fd, connector->crtc->id, 0, 0, 0, nullptr, 0, nullptr); ret) {
connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: reset failed: {}", strerror(-ret)));
ok = false;
}
}
return ok;
}