44 #include <QtCore/QJsonDocument>
45 #include <QtCore/QJsonObject>
46 #include <QtCore/QJsonArray>
47 #include <QtCore/QFile>
48 #include <QtCore/QLoggingCategory>
52 #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
71 for (
int i = 0;
i < connector->count_encoders;
i++) {
72 drmModeEncoderPtr encoder = drmModeGetEncoder(
m_dri_fd, connector->encoders[
i]);
78 quint32 encoderId = encoder->encoder_id;
79 quint32 crtcId = encoder->crtc_id;
80 quint32 possibleCrtcs = encoder->possible_crtcs;
81 drmModeFreeEncoder(encoder);
83 for (
int j = 0;
j < resources->count_crtcs;
j++) {
84 bool isPossible = possibleCrtcs & (1 <<
j);
89 bool isBestChoice = (!connector->encoder_id ||
90 (connector->encoder_id == encoderId &&
91 resources->crtcs[
j] == crtcId));
93 if (isPossible && isAvailable && isBestChoice) {
95 }
else if (isPossible && isAvailable) {
104 static const char *
const connector_type_names[] = {
124 static QByteArray nameForConnector(
const drmModeConnectorPtr connector)
128 if (connector->connector_type <
ARRAY_LENGTH(connector_type_names))
129 connectorName = connector_type_names[connector->connector_type];
133 return connectorName;
142 mode->type = DRM_MODE_TYPE_USERDEF;
148 if (sscanf(
text.
constData(),
"%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s",
157 &
mode->vtotal, hsync, vsync) != 11)
160 mode->clock = fclock * 1000;
162 if (
strcmp(hsync,
"+hsync") == 0)
163 mode->flags |= DRM_MODE_FLAG_PHSYNC;
164 else if (
strcmp(hsync,
"-hsync") == 0)
165 mode->flags |= DRM_MODE_FLAG_NHSYNC;
169 if (
strcmp(vsync,
"+vsync") == 0)
170 mode->flags |= DRM_MODE_FLAG_PVSYNC;
171 else if (
strcmp(vsync,
"-vsync") == 0)
172 mode->flags |= DRM_MODE_FLAG_NVSYNC;
189 drmModeConnectorPtr connector,
193 const QByteArray connectorName = nameForConnector(connector);
197 qWarning() <<
"No usable crtc/encoder pair for connector" << connectorName;
202 QSize configurationSize;
203 int configurationRefresh = 0;
204 drmModeModeInfo configurationModeline;
213 }
else if (
mode ==
"preferred") {
215 }
else if (
mode ==
"current") {
217 }
else if (
mode ==
"skip") {
219 }
else if (sscanf(
mode.constData(),
"%dx%d@%d", &configurationSize.
rwidth(), &configurationSize.
rheight(),
220 &configurationRefresh) == 3)
223 }
else if (sscanf(
mode.constData(),
"%dx%d", &configurationSize.
rwidth(), &configurationSize.
rheight()) == 2) {
225 }
else if (parseModeline(
mode, &configurationModeline)) {
237 if (vposComp.count() == 2)
243 const uint32_t crtc_id = resources->crtcs[crtc];
246 qCDebug(qLcKmsDebug) <<
"Turning off output" << connectorName;
247 drmModeSetCrtc(
m_dri_fd, crtc_id, 0, 0, 0, 0, 0,
nullptr);
253 qCDebug(qLcKmsDebug) <<
"Skipping disconnected output" << connectorName;
258 qCDebug(qLcKmsDebug) <<
"Skipping output" << connectorName;
263 drmModeModeInfo crtc_mode;
264 memset(&crtc_mode, 0,
sizeof crtc_mode);
265 if (drmModeEncoderPtr encoder = drmModeGetEncoder(
m_dri_fd, connector->encoder_id)) {
266 drmModeCrtcPtr crtc = drmModeGetCrtc(
m_dri_fd, encoder->crtc_id);
267 drmModeFreeEncoder(encoder);
272 if (crtc->mode_valid)
273 crtc_mode = crtc->mode;
275 drmModeFreeCrtc(crtc);
279 modes.
reserve(connector->count_modes);
280 qCDebug(qLcKmsDebug) << connectorName <<
"mode count:" << connector->count_modes
281 <<
"crtc index:" << crtc <<
"crtc id:" << crtc_id;
282 for (
int i = 0;
i < connector->count_modes;
i++) {
283 const drmModeModeInfo &
mode = connector->modes[
i];
284 qCDebug(qLcKmsDebug) <<
"mode" <<
i <<
mode.hdisplay <<
"x" <<
mode.vdisplay
285 <<
'@' <<
mode.vrefresh <<
"hz";
286 modes << connector->modes[
i];
294 for (
int i = modes.
size() - 1;
i >= 0;
i--) {
295 const drmModeModeInfo &
m = modes.
at(
i);
298 &&
m.hdisplay == configurationSize.
width()
299 &&
m.vdisplay == configurationSize.
height()
300 && (!configurationRefresh ||
m.vrefresh == uint32_t(configurationRefresh)))
305 if (!memcmp(&crtc_mode, &
m,
sizeof m))
308 if (
m.type & DRM_MODE_TYPE_PREFERRED)
315 modes << configurationModeline;
316 configured = modes.
size() - 1;
319 if (current < 0 && crtc_mode.clock != 0) {
325 configured = current;
327 int selected_mode = -1;
330 selected_mode = configured;
331 else if (preferred >= 0)
332 selected_mode = preferred;
333 else if (current >= 0)
334 selected_mode = current;
336 selected_mode = best;
338 if (selected_mode < 0) {
339 qWarning() <<
"No modes available for output" << connectorName;
342 int width = modes[selected_mode].hdisplay;
343 int height = modes[selected_mode].vdisplay;
344 int refresh = modes[selected_mode].vrefresh;
345 qCDebug(qLcKmsDebug) <<
"Selected mode" << selected_mode <<
":" <<
width <<
"x" <<
height
346 <<
'@' << refresh <<
"hz for output" << connectorName;
350 int pwidth = qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_PHYSICAL_WIDTH");
352 pwidth = qEnvironmentVariableIntValue(
"QT_QPA_PHYSICAL_WIDTH");
353 int pheight = qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_PHYSICAL_HEIGHT");
355 pheight = qEnvironmentVariableIntValue(
"QT_QPA_PHYSICAL_HEIGHT");
356 QSizeF physSize(pwidth, pheight);
361 physSize.
setWidth(connector->mmWidth);
365 qCDebug(qLcKmsDebug) <<
"Physical size is" << physSize <<
"mm" <<
"for output" << connectorName;
370 bool drmFormatExplicit =
true;
372 drmFormat = DRM_FORMAT_XRGB8888;
373 drmFormatExplicit =
false;
374 }
else if (formatStr ==
"xrgb8888") {
375 drmFormat = DRM_FORMAT_XRGB8888;
376 }
else if (formatStr ==
"xbgr8888") {
377 drmFormat = DRM_FORMAT_XBGR8888;
378 }
else if (formatStr ==
"argb8888") {
379 drmFormat = DRM_FORMAT_ARGB8888;
380 }
else if (formatStr ==
"abgr8888") {
381 drmFormat = DRM_FORMAT_ABGR8888;
382 }
else if (formatStr ==
"rgb565") {
383 drmFormat = DRM_FORMAT_RGB565;
384 }
else if (formatStr ==
"bgr565") {
385 drmFormat = DRM_FORMAT_BGR565;
386 }
else if (formatStr ==
"xrgb2101010") {
387 drmFormat = DRM_FORMAT_XRGB2101010;
388 }
else if (formatStr ==
"xbgr2101010") {
389 drmFormat = DRM_FORMAT_XBGR2101010;
390 }
else if (formatStr ==
"argb2101010") {
391 drmFormat = DRM_FORMAT_ARGB2101010;
392 }
else if (formatStr ==
"abgr2101010") {
393 drmFormat = DRM_FORMAT_ABGR2101010;
396 drmFormat = DRM_FORMAT_XRGB8888;
397 drmFormatExplicit =
false;
399 qCDebug(qLcKmsDebug) <<
"Format is" <<
Qt::hex << drmFormat <<
Qt::dec <<
"requested_by_user =" << drmFormatExplicit
400 <<
"for output" << connectorName;
404 qCDebug(qLcKmsDebug) <<
"Output" << connectorName <<
" clones output " << cloneSource;
406 QSize framebufferSize;
407 bool framebufferSizeSet =
false;
411 #if QT_CONFIG(drm_atomic)
413 framebufferSizeSet =
true;
415 if (!framebufferSizeSet)
416 qWarning(
"Setting framebuffer size is only available with DRM atomic API");
421 if (!framebufferSizeSet) {
422 framebufferSize.
setWidth(modes[selected_mode].hdisplay);
423 framebufferSize.
setHeight(modes[selected_mode].vdisplay);
426 qCDebug(qLcKmsDebug) <<
"Output" << connectorName <<
"framebuffer size is " << framebufferSize;
434 output.
preferred_mode = preferred >= 0 ? preferred : selected_mode;
435 output.
mode = selected_mode;
438 output.
modes = modes;
439 output.
subpixel = connector->subpixel;
448 output.
size = framebufferSize;
450 #if QT_CONFIG(drm_atomic)
451 if (drmModeCreatePropertyBlob(
m_dri_fd, &modes[selected_mode],
sizeof(drmModeModeInfo),
453 qCDebug(qLcKmsDebug) <<
"Failed to create mode blob for mode" << selected_mode;
470 assignPlane(&output, &plane);
473 qCDebug(qLcKmsDebug,
"Output %s can use %d planes: %s",
480 int idx = qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_KMS_PLANE_INDEX", &
ok);
482 drmModePlaneRes *planeResources = drmModeGetPlaneResources(
m_dri_fd);
483 if (planeResources) {
484 if (
idx >= 0 &&
idx <
int(planeResources->count_planes)) {
485 drmModePlane *plane = drmModeGetPlane(
m_dri_fd, planeResources->planes[
idx]);
489 qCDebug(qLcKmsDebug,
"Forcing plane index %d, plane id %u (belongs to crtc id %u)",
490 idx, plane->plane_id, plane->crtc_id);
494 assignPlane(&output, &kmsplane);
499 drmModeFreePlane(plane);
502 qWarning(
"Invalid plane index %d, must be between 0 and %u",
idx, planeResources->count_planes - 1);
509 if (qEnvironmentVariableIsSet(
"QT_QPA_EGLFS_KMS_PLANES_FOR_CRTCS")) {
511 qCDebug(qLcKmsDebug,
"crtc_id:plane_id override list: %s", qPrintable(
val));
513 for (
const QString &crtcPlanePair : crtcPlanePairs) {
518 if (kmsplane.id == planeId) {
519 assignPlane(&output, &kmsplane);
528 qCDebug(qLcKmsDebug,
"Chose plane %u for output %s (crtc id %u) (may not be applicable)",
532 #if QT_CONFIG(drm_atomic)
534 qCDebug(qLcKmsDebug,
"No plane associated with output %s (crtc id %u) and atomic modesetting is enabled. This is bad.",
548 drmModePropertyPtr prop;
550 for (
int i = 0;
i < connector->count_props;
i++) {
551 prop = drmModeGetProperty(
m_dri_fd, connector->props[
i]);
554 if (
strcmp(prop->name,
name.constData()) == 0)
556 drmModeFreeProperty(prop);
564 drmModePropertyPtr prop;
565 drmModePropertyBlobPtr blob =
nullptr;
567 for (
int i = 0;
i < connector->count_props && !blob;
i++) {
568 prop = drmModeGetProperty(
m_dri_fd, connector->props[
i]);
571 if ((prop->flags & DRM_MODE_PROP_BLOB) && (
strcmp(prop->name,
name.constData()) == 0))
572 blob = drmModeGetPropertyBlob(
m_dri_fd, connector->prop_values[
i]);
573 drmModeFreeProperty(prop);
580 : m_screenConfig(screenConfig)
583 , m_has_atomic_support(
false)
584 , m_crtc_allocator(0)
588 qCDebug(qLcKmsDebug,
"Using DRM device %s specified in config file", qPrintable(
m_path));
590 qFatal(
"No DRM device given");
592 qCDebug(qLcKmsDebug,
"Using backend-provided DRM device %s", qPrintable(
m_path));
598 #if QT_CONFIG(drm_atomic)
599 threadLocalAtomicReset();
615 dbg.
nospace() <<
"OrderedScreen(QPlatformScreen=" <<
s.screen <<
" (" <<
s.screen->name() <<
") : "
616 <<
s.vinfo.virtualIndex
617 <<
" / " <<
s.vinfo.virtualPos
618 <<
" / primary: " <<
s.vinfo.isPrimary
625 return a.vinfo.virtualIndex <
b.vinfo.virtualIndex;
635 qCDebug(qLcKmsDebug,
"Headless mode enabled");
639 qWarning(
"QKmsDevice: Requested headless mode without support in the backend. Request is ignored.");
645 #if QT_CONFIG(drm_atomic)
649 qCDebug(qLcKmsDebug,
"Atomic reported as supported");
650 if (qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_KMS_ATOMIC")) {
651 qCDebug(qLcKmsDebug,
"Atomic enabled");
653 qCDebug(qLcKmsDebug,
"Atomic disabled");
659 drmModeResPtr resources = drmModeGetResources(
m_dri_fd);
669 int wantedConnectorIndex = -1;
671 int idx = qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_KMS_CONNECTOR_INDEX", &
ok);
673 if (
idx >= 0 && idx < resources->count_connectors)
674 wantedConnectorIndex =
idx;
676 qWarning(
"Invalid connector index %d, must be between 0 and %u",
idx, resources->count_connectors - 1);
679 for (
int i = 0;
i < resources->count_connectors;
i++) {
680 if (wantedConnectorIndex >= 0 &&
i != wantedConnectorIndex)
683 drmModeConnectorPtr connector = drmModeGetConnector(
m_dri_fd, resources->connectors[
i]);
692 drmModeFreeConnector(connector);
695 drmModeFreeResources(resources);
699 std::stable_sort(screens.
begin(), screens.
end(), orderedScreenLessThan);
700 qCDebug(qLcKmsDebug) <<
"Sorted screen list:" << screens;
707 if (
s.vinfo.output.clone_source == orderedScreen.vinfo.output.name)
708 screensCloningThisScreen.
append(
s.screen);
711 if (!orderedScreen.vinfo.output.clone_source.isEmpty()) {
713 if (
s.vinfo.output.name == orderedScreen.vinfo.output.clone_source) {
714 screenThisScreenClones =
s.
screen;
719 if (screenThisScreenClones)
720 qCDebug(qLcKmsDebug) << orderedScreen.screen->name() <<
"clones" << screenThisScreenClones;
721 if (!screensCloningThisScreen.
isEmpty())
722 qCDebug(qLcKmsDebug) << orderedScreen.screen->name() <<
"is cloned by" << screensCloningThisScreen;
731 int primarySiblingIdx = -1;
737 if (orderedScreen.vinfo.virtualPos.isNull()) {
740 pos.ry() +=
s->geometry().height();
742 pos.rx() +=
s->geometry().width();
744 virtualPos = orderedScreen.vinfo.virtualPos;
746 qCDebug(qLcKmsDebug) <<
"Adding QPlatformScreen" <<
s <<
"(" <<
s->name() <<
")"
747 <<
"to QPA with geometry" <<
s->geometry()
748 <<
"and isPrimary=" << orderedScreen.vinfo.isPrimary;
754 virtualPositions.
append(virtualPos);
755 if (orderedScreen.vinfo.isPrimary)
756 primarySiblingIdx = siblings.
count() - 1;
764 for (
int i = 0;
i < siblings.
count(); ++
i)
765 registerScreen(siblings[
i],
i == primarySiblingIdx, virtualPositions[
i], siblings);
786 static inline bool propTypeIs(drmModePropertyPtr prop, uint32_t
type)
790 return prop->flags &
type;
795 for (uint32_t propIdx = 0; propIdx < objProps->count_props; ++propIdx) {
796 drmModePropertyPtr prop = drmModeGetProperty(
m_dri_fd, objProps->props[propIdx]);
801 qCDebug(qLcKmsDebug,
" property %d: id = %u name = '%s'", propIdx, prop->prop_id, prop->name);
804 qCDebug(qLcKmsDebug,
" type is SIGNED_RANGE, value is %lld, possible values are:",
qint64(
value));
805 for (
int i = 0;
i < prop->count_values; ++
i)
807 }
else if (propTypeIs(prop, DRM_MODE_PROP_RANGE)) {
808 qCDebug(qLcKmsDebug,
" type is RANGE, value is %llu, possible values are:",
value);
809 for (
int i = 0;
i < prop->count_values; ++
i)
811 }
else if (propTypeIs(prop, DRM_MODE_PROP_ENUM)) {
812 qCDebug(qLcKmsDebug,
" type is ENUM, value is %llu, possible values are:",
value);
813 for (
int i = 0;
i < prop->count_enums; ++
i)
814 qCDebug(qLcKmsDebug,
" enum %d: %s - %llu",
i, prop->enums[
i].name,
quint64(prop->enums[
i].value));
815 }
else if (propTypeIs(prop, DRM_MODE_PROP_BITMASK)) {
816 qCDebug(qLcKmsDebug,
" type is BITMASK, value is %llu, possible bits are:",
value);
817 for (
int i = 0;
i < prop->count_enums; ++
i)
818 qCDebug(qLcKmsDebug,
" bitmask %d: %s - %u",
i, prop->enums[
i].name, 1 << prop->enums[
i].value);
819 }
else if (propTypeIs(prop, DRM_MODE_PROP_BLOB)) {
820 qCDebug(qLcKmsDebug,
" type is BLOB");
822 qCDebug(qLcKmsDebug,
" type is OBJECT");
825 callback(prop,
value);
827 drmModeFreeProperty(prop);
835 drmModePlaneResPtr planeResources = drmModeGetPlaneResources(
m_dri_fd);
839 const int countPlanes = planeResources->count_planes;
840 qCDebug(qLcKmsDebug,
"Found %d planes", countPlanes);
841 for (
int planeIdx = 0; planeIdx < countPlanes; ++planeIdx) {
842 drmModePlanePtr drmplane = drmModeGetPlane(
m_dri_fd, planeResources->planes[planeIdx]);
844 qCDebug(qLcKmsDebug,
"Failed to query plane %d, ignoring", planeIdx);
849 plane.
id = drmplane->plane_id;
852 const int countFormats = drmplane->count_formats;
854 for (
int i = 0;
i < countFormats; ++
i) {
855 uint32_t
f = drmplane->formats[
i];
860 qCDebug(qLcKmsDebug,
"plane %d: id = %u countFormats = %d possibleCrtcs = 0x%x supported formats = %s",
861 planeIdx, plane.
id, countFormats, plane.
possibleCrtcs, qPrintable(formatStr));
863 drmModeFreePlane(drmplane);
865 drmModeObjectPropertiesPtr objProps = drmModeObjectGetProperties(
m_dri_fd, plane.
id, DRM_MODE_OBJECT_PLANE);
867 qCDebug(qLcKmsDebug,
"Failed to query plane %d object properties, ignoring", planeIdx);
872 if (!
strcmp(prop->name,
"type")) {
873 plane.type = QKmsPlane::Type(value);
874 }
else if (!
strcmp(prop->name,
"rotation")) {
875 plane.initialRotation = QKmsPlane::Rotations(int(value));
876 plane.availableRotations = { };
877 if (propTypeIs(prop, DRM_MODE_PROP_BITMASK)) {
878 for (
int i = 0;
i < prop->count_enums; ++
i)
882 }
else if (!strcasecmp(prop->name,
"crtc_id")) {
883 plane.crtcPropertyId = prop->prop_id;
884 }
else if (!strcasecmp(prop->name,
"fb_id")) {
885 plane.framebufferPropertyId = prop->prop_id;
886 }
else if (!strcasecmp(prop->name,
"src_w")) {
887 plane.srcwidthPropertyId = prop->prop_id;
888 }
else if (!strcasecmp(prop->name,
"src_h")) {
889 plane.srcheightPropertyId = prop->prop_id;
890 }
else if (!strcasecmp(prop->name,
"crtc_w")) {
891 plane.crtcwidthPropertyId = prop->prop_id;
892 }
else if (!strcasecmp(prop->name,
"crtc_h")) {
893 plane.crtcheightPropertyId = prop->prop_id;
894 }
else if (!strcasecmp(prop->name,
"src_x")) {
895 plane.srcXPropertyId = prop->prop_id;
896 }
else if (!strcasecmp(prop->name,
"src_y")) {
897 plane.srcYPropertyId = prop->prop_id;
898 }
else if (!strcasecmp(prop->name,
"crtc_x")) {
899 plane.crtcXPropertyId = prop->prop_id;
900 }
else if (!strcasecmp(prop->name,
"crtc_y")) {
901 plane.crtcYPropertyId = prop->prop_id;
902 }
else if (!strcasecmp(prop->name,
"zpos")) {
903 plane.zposPropertyId = prop->prop_id;
904 }
else if (!strcasecmp(prop->name,
"blend_op")) {
905 plane.blendOpPropertyId = prop->prop_id;
911 drmModeFreeObjectProperties(objProps);
914 drmModeFreePlaneResources(planeResources);
938 #if QT_CONFIG(drm_atomic)
939 drmModeAtomicReq *QKmsDevice::threadLocalAtomicRequest()
944 AtomicReqs &
a(m_atomicReqs.localData());
946 a.request = drmModeAtomicAlloc();
951 bool QKmsDevice::threadLocalAtomicCommit(
void *
user_data)
956 AtomicReqs &
a(m_atomicReqs.localData());
961 DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_ALLOW_MODESET,
965 qWarning(
"Failed to commit atomic request (code=%d)",
ret);
969 a.previous_request =
a.request;
975 void QKmsDevice::threadLocalAtomicReset()
980 AtomicReqs &
a(m_atomicReqs.localData());
981 if (
a.previous_request) {
982 drmModeAtomicFree(
a.previous_request);
983 a.previous_request =
nullptr;
990 drmModeObjectPropertiesPtr objProps = drmModeObjectGetProperties(
m_dri_fd, connectorId, DRM_MODE_OBJECT_CONNECTOR);
992 qCDebug(qLcKmsDebug,
"Failed to query connector %d object properties", connectorId);
998 if (!strcasecmp(prop->name,
"crtc_id"))
1002 drmModeFreeObjectProperties(objProps);
1007 drmModeObjectPropertiesPtr objProps = drmModeObjectGetProperties(
m_dri_fd, crtcId, DRM_MODE_OBJECT_CRTC);
1009 qCDebug(qLcKmsDebug,
"Failed to query crtc %d object properties", crtcId);
1015 if (!strcasecmp(prop->name,
"mode_id"))
1017 else if (!strcasecmp(prop->name,
"active"))
1021 drmModeFreeObjectProperties(objProps);
1032 , m_separateScreens(
false)
1034 , m_virtualDesktopLayout(VirtualDesktopLayoutHorizontal)
1040 QByteArray json = qgetenv(
"QT_QPA_EGLFS_KMS_CONFIG");
1042 json = qgetenv(
"QT_QPA_KMS_CONFIG");
1047 qCDebug(qLcKmsDebug) <<
"Loading KMS setup from" << json;
1051 qCWarning(qLcKmsDebug) <<
"Could not open config file"
1052 << json <<
"for reading";
1058 qCWarning(qLcKmsDebug) <<
"Invalid config file" << json
1059 <<
"- no top-level JSON object";
1087 qCWarning(qLcKmsDebug) <<
"Unknown virtualDesktopOrientation value" << vdOriString;
1091 for (
int i = 0;
i < outputs.
size();
i++) {
1098 qCDebug(qLcKmsDebug) <<
"Output" <<
name <<
"configured multiple times!";
1105 qCDebug(qLcKmsDebug) <<
"Requested configuration (some settings may be ignored):\n"
1117 drmModeSetCrtc(
device->fd(),
1151 case DRM_MODE_SUBPIXEL_UNKNOWN:
1152 case DRM_MODE_SUBPIXEL_NONE:
1154 case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
1156 case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
1158 case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
1160 case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
small capitals from c petite p scientific i
[1]
The QByteArray class provides an array of bytes.
const char * constData() const noexcept
QList< QByteArray > split(char sep) const
bool isEmpty() const noexcept
static QByteArray number(int, int base=10)
QByteArray toLower() const &
The QByteArrayList class provides a list of byte arrays.
operator<<(QDataStream &ds, qfloat16 f)
The QDebug class provides an output stream for debugging information.
Convenience class for custom QDebug operators.
The QFile class provides an interface for reading from and writing to files.
bool open(OpenMode flags) override
The QJsonArray class encapsulates a JSON array.
QJsonValue at(qsizetype i) const
The QJsonDocument class provides a way to read and write JSON documents.
QJsonObject object() const
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error=nullptr)
The QJsonObject class encapsulates a JSON object.
QVariantMap toVariantMap() const
QJsonObject toObject() const
void enumerateProperties(drmModeObjectPropertiesPtr objProps, PropCallback callback)
QList< QKmsPlane > m_planes
drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name)
virtual QPlatformScreen * createScreen(const QKmsOutput &output)=0
void parseCrtcProperties(uint32_t crtcId, QKmsOutput *output)
QKmsScreenConfig * screenConfig() const
virtual QPlatformScreen * createHeadlessScreen()
QKmsScreenConfig * m_screenConfig
int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector)
std::function< void(drmModePropertyPtr, quint64)> PropCallback
void parseConnectorProperties(uint32_t connectorId, QKmsOutput *output)
QKmsDevice(QKmsScreenConfig *screenConfig, const QString &path=QString())
QString devicePath() const
QPlatformScreen * createScreenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, ScreenInfo *vinfo)
virtual void registerScreen(QPlatformScreen *screen, bool isPrimary, const QPoint &virtualPos, const QList< QPlatformScreen * > &virtualSiblings)=0
bool m_has_atomic_support
drmModePropertyBlobPtr connectorPropertyBlob(drmModeConnectorPtr connector, const QByteArray &name)
virtual void registerScreenCloning(QPlatformScreen *screen, QPlatformScreen *screenThisScreenClones, const QList< QPlatformScreen * > &screensCloningThisScreen)
QSize headlessSize() const
QMap< QString, QVariantMap > m_outputSettings
bool separateScreens() const
VirtualDesktopLayout virtualDesktopLayout() const
virtual void loadConfig()
@ VirtualDesktopLayoutVertical
@ VirtualDesktopLayoutHorizontal
QMap< QString, QVariantMap > outputSettings() const
VirtualDesktopLayout m_virtualDesktopLayout
QString devicePath() const
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
qsizetype size() const noexcept
bool isEmpty() const noexcept
const_reference at(qsizetype i) const noexcept
qsizetype count() const noexcept
void reserve(qsizetype size)
void append(parameter_type t)
T value(const Key &key, const T &defaultValue=T()) const
bool contains(const Key &key) const
The QPoint class defines a point in the plane using integer precision.
The QSizeF class defines the size of a two-dimensional object using floating point precision.
constexpr void setHeight(qreal h) noexcept
constexpr void setWidth(qreal w) noexcept
constexpr bool isEmpty() const noexcept
The QSize class defines the size of a two-dimensional object using integer point precision.
constexpr int height() const noexcept
constexpr int width() const noexcept
constexpr int & rheight() noexcept
constexpr void setWidth(int w) noexcept
constexpr int & rwidth() noexcept
constexpr void setHeight(int h) noexcept
The QString class provides a Unicode character string.
const QChar * constData() const
static QString fromUtf8(QByteArrayView utf8)
static QString number(int, int base=10)
QString & append(QChar c)
QByteArray toUtf8() const &
static QString static QString asprintf(const char *format,...) Q_ATTRIBUTE_FORMAT_PRINTF(1
The QStringList class provides a list of strings.
int toInt(bool *ok=nullptr) const
QByteArray toByteArray() const
QTextStream & hex(QTextStream &stream)
QTextStream & dec(QTextStream &stream)
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QByteArrayView trimmed(QByteArrayView s) noexcept
int PRIV() strcmp(PCRE2_SPTR str1, PCRE2_SPTR str2)
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
[3]
#define QByteArrayLiteral(str)
EGLOutputLayerEXT EGLint EGLAttrib value
QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
unsigned long long quint64
#define DRM_CLIENT_CAP_UNIVERSAL_PLANES
#define DRM_CLIENT_CAP_ATOMIC
#define DRM_MODE_PROP_SIGNED_RANGE
#define DRM_MODE_PROP_EXTENDED_TYPE
#define DRM_MODE_PROP_OBJECT
Q_CORE_EXPORT Q_DECL_COLD_FUNCTION void qErrnoWarning(int code, const char *msg,...)
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLenum GLsizei GLsizei GLint * values
[16]
GLboolean GLboolean GLboolean b
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLsizei const GLchar *const * path
#define QStringLiteral(str)
HB_EXTERN hb_font_get_glyph_func_t void * user_data
QKmsDevice::ScreenInfo vinfo
OrderedScreen(QPlatformScreen *screen, const QKmsDevice::ScreenInfo &vinfo)
void restoreMode(QKmsDevice *device)
uint32_t modeIdPropertyId
struct QKmsPlane * eglfs_plane
drmModePropertyPtr dpms_prop
void setPowerState(QKmsDevice *device, QPlatformScreen::PowerState state)
QList< QKmsPlane > available_planes
drmModeCrtcPtr saved_crtc
QList< drmModeModeInfo > modes
drmModePropertyBlobPtr edid_blob
QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const
void cleanup(QKmsDevice *device)
uint32_t activePropertyId
bool drm_format_requested_by_user
uint32_t crtcIdPropertyId
uint32_t rotationPropertyId
QList< uint32_t > supportedFormats
Rotations availableRotations
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.