eglfs: add a default framebuffer to NVIDIA eglstreams
Newer versions of NVIDIA's DRM driver are rejecting the previously accepted but non-standard use of framebuffer_id -1 in order to set the output mode but not issue a page flip. This change adds a default framebuffer to the egldevice driver for use with the initial calls to set the CRTC mode and plane. Pick-to: 6.5 Change-Id: I63dbb6b099250fcff7d995eec38fb75c675894cd Reviewed-by: Samuli Piippo <samuli.piippo@qt.io> (cherry picked from commit 17a68dae5e9007d9a8b122b4ede1647d5900d6d4) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
1f0a31d6a6
commit
cf44289e12
@ -13,11 +13,62 @@ Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
|
||||
|
||||
QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsDevice *device, const QKmsOutput &output)
|
||||
: QEglFSKmsScreen(device, output)
|
||||
, m_default_fb_handle(uint32_t(-1))
|
||||
, m_default_fb_id(uint32_t(-1))
|
||||
{
|
||||
const int fd = device->fd();
|
||||
|
||||
struct drm_mode_create_dumb createRequest;
|
||||
createRequest.width = output.size.width();
|
||||
createRequest.height = output.size.height();
|
||||
createRequest.bpp = 32;
|
||||
createRequest.flags = 0;
|
||||
|
||||
qCDebug(qLcEglfsKmsDebug, "Creating dumb fb %dx%d", createRequest.width, createRequest.height);
|
||||
|
||||
int ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &createRequest);
|
||||
if (ret < 0)
|
||||
qFatal("Unable to create dumb buffer.\n");
|
||||
|
||||
m_default_fb_handle = createRequest.handle;
|
||||
|
||||
uint32_t handles[4] = { 0, 0, 0, 0 };
|
||||
uint32_t pitches[4] = { 0, 0, 0, 0 };
|
||||
uint32_t offsets[4] = { 0, 0, 0, 0 };
|
||||
|
||||
handles[0] = createRequest.handle;
|
||||
pitches[0] = createRequest.pitch;
|
||||
offsets[0] = 0;
|
||||
|
||||
ret = drmModeAddFB2(fd, createRequest.width, createRequest.height, DRM_FORMAT_ARGB8888, handles,
|
||||
pitches, offsets, &m_default_fb_id, 0);
|
||||
if (ret)
|
||||
qFatal("Unable to add fb\n");
|
||||
|
||||
qCDebug(qLcEglfsKmsDebug, "Added dumb fb %dx%d handle:%u pitch:%d id:%u", createRequest.width, createRequest.height,
|
||||
createRequest.handle, createRequest.pitch, m_default_fb_id);
|
||||
}
|
||||
|
||||
QEglFSKmsEglDeviceScreen::~QEglFSKmsEglDeviceScreen()
|
||||
{
|
||||
int ret;
|
||||
const int fd = device()->fd();
|
||||
|
||||
if (m_default_fb_id != uint32_t(-1)) {
|
||||
ret = drmModeRmFB(fd, m_default_fb_id);
|
||||
if (ret)
|
||||
qErrnoWarning("drmModeRmFB failed");
|
||||
}
|
||||
|
||||
if (m_default_fb_handle != uint32_t(-1)) {
|
||||
struct drm_mode_destroy_dumb destroyRequest;
|
||||
destroyRequest.handle = m_default_fb_handle;
|
||||
|
||||
ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroyRequest);
|
||||
if (ret)
|
||||
qErrnoWarning("DRM_IOCTL_MODE_DESTROY_DUMB failed");
|
||||
}
|
||||
|
||||
const int remainingScreenCount = qGuiApp->screens().size();
|
||||
qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount);
|
||||
if (!remainingScreenCount && !device()->screenConfig()->separateScreens())
|
||||
@ -53,8 +104,11 @@ void QEglFSKmsEglDeviceScreen::waitForFlip()
|
||||
if (alreadySet) {
|
||||
// Maybe detecting the DPMS mode could help here, but there are no properties
|
||||
// exposed on the connector apparently. So rely on an env var for now.
|
||||
static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE");
|
||||
if (!alwaysDoSet) {
|
||||
// Note that typically, we need to set crtc with the default fb even if the
|
||||
// mode did not change, unless QT_QPA_EGLFS_ALWAYS_SET_MODE is explicitly specified.
|
||||
static bool envVarSet = false;
|
||||
static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE", &envVarSet);
|
||||
if (envVarSet && !alwaysDoSet) {
|
||||
qCDebug(qLcEglfsKmsDebug, "Mode already set");
|
||||
return;
|
||||
}
|
||||
@ -62,7 +116,7 @@ void QEglFSKmsEglDeviceScreen::waitForFlip()
|
||||
|
||||
qCDebug(qLcEglfsKmsDebug, "Setting mode");
|
||||
int ret = drmModeSetCrtc(fd, op.crtc_id,
|
||||
uint32_t(-1), 0, 0,
|
||||
m_default_fb_id, 0, 0,
|
||||
&op.connector_id, 1,
|
||||
&op.modes[op.mode]);
|
||||
if (ret)
|
||||
@ -74,7 +128,7 @@ void QEglFSKmsEglDeviceScreen::waitForFlip()
|
||||
|
||||
if (op.wants_forced_plane) {
|
||||
qCDebug(qLcEglfsKmsDebug, "Setting plane %u", op.forced_plane_id);
|
||||
int ret = drmModeSetPlane(fd, op.forced_plane_id, op.crtc_id, uint32_t(-1), 0,
|
||||
int ret = drmModeSetPlane(fd, op.forced_plane_id, op.crtc_id, m_default_fb_id, 0,
|
||||
0, 0, w, h,
|
||||
0 << 16, 0 << 16, op.size.width() << 16, op.size.height() << 16);
|
||||
if (ret == -1)
|
||||
|
@ -17,6 +17,9 @@ public:
|
||||
QPlatformCursor *cursor() const override;
|
||||
|
||||
void waitForFlip() override;
|
||||
private:
|
||||
uint32_t m_default_fb_handle;
|
||||
uint32_t m_default_fb_id;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
Loading…
x
Reference in New Issue
Block a user