Only use drmModeAddFB2WithModifiers if supported
This commit is contained in:
parent
c1635c1179
commit
eb7703cd64
11 changed files with 47 additions and 33 deletions
|
@ -9,6 +9,7 @@
|
|||
#include "drm_buffer.h"
|
||||
|
||||
#include "logging.h"
|
||||
#include "drm_gpu.h"
|
||||
|
||||
// system
|
||||
#include <sys/mman.h>
|
||||
|
@ -21,14 +22,14 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
DrmBuffer:: DrmBuffer(int fd)
|
||||
: m_fd(fd)
|
||||
DrmBuffer:: DrmBuffer(DrmGpu *gpu)
|
||||
: m_gpu(gpu)
|
||||
{
|
||||
}
|
||||
|
||||
// DrmDumbBuffer
|
||||
DrmDumbBuffer::DrmDumbBuffer(int fd, const QSize &size)
|
||||
: DrmBuffer(fd)
|
||||
DrmDumbBuffer::DrmDumbBuffer(DrmGpu *gpu, const QSize &size)
|
||||
: DrmBuffer(gpu)
|
||||
{
|
||||
m_size = size;
|
||||
drm_mode_create_dumb createArgs;
|
||||
|
@ -36,14 +37,14 @@ DrmDumbBuffer::DrmDumbBuffer(int fd, const QSize &size)
|
|||
createArgs.bpp = 32;
|
||||
createArgs.width = size.width();
|
||||
createArgs.height = size.height();
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &createArgs) != 0) {
|
||||
if (drmIoctl(m_gpu->fd(), DRM_IOCTL_MODE_CREATE_DUMB, &createArgs) != 0) {
|
||||
qCWarning(KWIN_DRM) << "DRM_IOCTL_MODE_CREATE_DUMB failed";
|
||||
return;
|
||||
}
|
||||
m_handle = createArgs.handle;
|
||||
m_bufferSize = createArgs.size;
|
||||
m_stride = createArgs.pitch;
|
||||
if (drmModeAddFB(fd, size.width(), size.height(), 24, 32,
|
||||
if (drmModeAddFB(m_gpu->fd(), size.width(), size.height(), 24, 32,
|
||||
m_stride, createArgs.handle, &m_bufferId) != 0) {
|
||||
qCWarning(KWIN_DRM) << "drmModeAddFB failed with errno" << errno;
|
||||
}
|
||||
|
@ -52,7 +53,7 @@ DrmDumbBuffer::DrmDumbBuffer(int fd, const QSize &size)
|
|||
DrmDumbBuffer::~DrmDumbBuffer()
|
||||
{
|
||||
if (m_bufferId) {
|
||||
drmModeRmFB(fd(), m_bufferId);
|
||||
drmModeRmFB(m_gpu->fd(), m_bufferId);
|
||||
}
|
||||
|
||||
delete m_image;
|
||||
|
@ -62,7 +63,7 @@ DrmDumbBuffer::~DrmDumbBuffer()
|
|||
if (m_handle) {
|
||||
drm_mode_destroy_dumb destroyArgs;
|
||||
destroyArgs.handle = m_handle;
|
||||
drmIoctl(fd(), DRM_IOCTL_MODE_DESTROY_DUMB, &destroyArgs);
|
||||
drmIoctl(m_gpu->fd(), DRM_IOCTL_MODE_DESTROY_DUMB, &destroyArgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,10 +83,10 @@ bool DrmDumbBuffer::map(QImage::Format format)
|
|||
drm_mode_map_dumb mapArgs;
|
||||
memset(&mapArgs, 0, sizeof mapArgs);
|
||||
mapArgs.handle = m_handle;
|
||||
if (drmIoctl(fd(), DRM_IOCTL_MODE_MAP_DUMB, &mapArgs) != 0) {
|
||||
if (drmIoctl(m_gpu->fd(), DRM_IOCTL_MODE_MAP_DUMB, &mapArgs) != 0) {
|
||||
return false;
|
||||
}
|
||||
void *address = mmap(nullptr, m_bufferSize, PROT_WRITE, MAP_SHARED, fd(), mapArgs.offset);
|
||||
void *address = mmap(nullptr, m_bufferSize, PROT_WRITE, MAP_SHARED, m_gpu->fd(), mapArgs.offset);
|
||||
if (address == MAP_FAILED) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -15,11 +15,13 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
class DrmGpu;
|
||||
|
||||
class DrmBuffer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DrmBuffer(int fd);
|
||||
DrmBuffer(DrmGpu *gpu);
|
||||
virtual ~DrmBuffer() = default;
|
||||
|
||||
virtual bool needsModeChange(DrmBuffer *b) const {Q_UNUSED(b) return false;}
|
||||
|
@ -34,20 +36,20 @@ public:
|
|||
|
||||
virtual void releaseGbm() {}
|
||||
|
||||
int fd() const {
|
||||
return m_fd;
|
||||
DrmGpu *gpu() const {
|
||||
return m_gpu;
|
||||
}
|
||||
|
||||
protected:
|
||||
quint32 m_bufferId = 0;
|
||||
QSize m_size;
|
||||
int m_fd;
|
||||
DrmGpu *m_gpu;
|
||||
};
|
||||
|
||||
class DrmDumbBuffer : public DrmBuffer
|
||||
{
|
||||
public:
|
||||
DrmDumbBuffer(int fd, const QSize &size);
|
||||
DrmDumbBuffer(DrmGpu *gpu, const QSize &size);
|
||||
~DrmDumbBuffer() override;
|
||||
|
||||
bool needsModeChange(DrmBuffer *b) const override;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "gbm_surface.h"
|
||||
|
||||
#include "logging.h"
|
||||
#include "drm_gpu.h"
|
||||
|
||||
// system
|
||||
#include <sys/mman.h>
|
||||
|
@ -28,8 +29,8 @@ namespace KWin
|
|||
{
|
||||
|
||||
// DrmSurfaceBuffer
|
||||
DrmSurfaceBuffer::DrmSurfaceBuffer(int fd, const QSharedPointer<GbmSurface> &surface)
|
||||
: DrmBuffer(fd)
|
||||
DrmSurfaceBuffer::DrmSurfaceBuffer(DrmGpu *gpu, const QSharedPointer<GbmSurface> &surface)
|
||||
: DrmBuffer(gpu)
|
||||
, m_surface(surface)
|
||||
{
|
||||
m_bo = m_surface->lockFrontBuffer();
|
||||
|
@ -40,8 +41,8 @@ DrmSurfaceBuffer::DrmSurfaceBuffer(int fd, const QSharedPointer<GbmSurface> &sur
|
|||
initialize();
|
||||
}
|
||||
|
||||
DrmSurfaceBuffer::DrmSurfaceBuffer(int fd, gbm_bo *buffer, KWaylandServer::BufferInterface *bufferInterface)
|
||||
: DrmBuffer(fd)
|
||||
DrmSurfaceBuffer::DrmSurfaceBuffer(DrmGpu *gpu, gbm_bo *buffer, KWaylandServer::BufferInterface *bufferInterface)
|
||||
: DrmBuffer(gpu)
|
||||
, m_bo(buffer)
|
||||
, m_bufferInterface(bufferInterface)
|
||||
{
|
||||
|
@ -55,7 +56,7 @@ DrmSurfaceBuffer::DrmSurfaceBuffer(int fd, gbm_bo *buffer, KWaylandServer::Buffe
|
|||
DrmSurfaceBuffer::~DrmSurfaceBuffer()
|
||||
{
|
||||
if (m_bufferId) {
|
||||
drmModeRmFB(fd(), m_bufferId);
|
||||
drmModeRmFB(m_gpu->fd(), m_bufferId);
|
||||
}
|
||||
releaseGbm();
|
||||
if (m_bufferInterface) {
|
||||
|
@ -99,14 +100,14 @@ void DrmSurfaceBuffer::initialize()
|
|||
modifiers[0] = DRM_FORMAT_MOD_INVALID;
|
||||
}
|
||||
|
||||
if (modifiers[0] != DRM_FORMAT_MOD_INVALID) {
|
||||
if (drmModeAddFB2WithModifiers(m_fd, m_size.width(), m_size.height(), gbm_bo_get_format(m_bo), handles, strides, offsets, modifiers, &m_bufferId, DRM_MODE_FB_MODIFIERS)) {
|
||||
if (modifiers[0] != DRM_FORMAT_MOD_INVALID && m_gpu->addFB2ModifiersSupported()) {
|
||||
if (drmModeAddFB2WithModifiers(m_gpu->fd(), m_size.width(), m_size.height(), gbm_bo_get_format(m_bo), handles, strides, offsets, modifiers, &m_bufferId, DRM_MODE_FB_MODIFIERS)) {
|
||||
qCWarning(KWIN_DRM) << "drmModeAddFB2WithModifiers failed!" << strerror(errno);
|
||||
}
|
||||
} else {
|
||||
if (drmModeAddFB2(m_fd, m_size.width(), m_size.height(), gbm_bo_get_format(m_bo), handles, strides, offsets, &m_bufferId, 0)) {
|
||||
if (drmModeAddFB2(m_gpu->fd(), m_size.width(), m_size.height(), gbm_bo_get_format(m_bo), handles, strides, offsets, &m_bufferId, 0)) {
|
||||
// fallback
|
||||
if (drmModeAddFB(m_fd, m_size.width(), m_size.height(), 24, 32, strides[0], handles[0], &m_bufferId) != 0) {
|
||||
if (drmModeAddFB(m_gpu->fd(), m_size.width(), m_size.height(), 24, 32, strides[0], handles[0], &m_bufferId) != 0) {
|
||||
qCWarning(KWIN_DRM) << "drmModeAddFB2 and drmModeAddFB both failed!" << strerror(errno);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ class GbmSurface;
|
|||
class DrmSurfaceBuffer : public DrmBuffer
|
||||
{
|
||||
public:
|
||||
DrmSurfaceBuffer(int fd, const QSharedPointer<GbmSurface> &surface);
|
||||
DrmSurfaceBuffer(int fd, gbm_bo *buffer, KWaylandServer::BufferInterface *bufferInterface);
|
||||
DrmSurfaceBuffer(DrmGpu *gpu, const QSharedPointer<GbmSurface> &surface);
|
||||
DrmSurfaceBuffer(DrmGpu *gpu, gbm_bo *buffer, KWaylandServer::BufferInterface *bufferInterface);
|
||||
~DrmSurfaceBuffer() override;
|
||||
|
||||
bool needsModeChange(DrmBuffer *b) const override {
|
||||
|
|
|
@ -58,6 +58,11 @@ DrmGpu::DrmGpu(DrmBackend *backend, QByteArray devNode, int fd, int drmId) : m_b
|
|||
m_presentationClock = CLOCK_REALTIME;
|
||||
}
|
||||
|
||||
if (!qEnvironmentVariableIsSet("KWIN_DRM_NO_MODIFIERS")) {
|
||||
m_addFB2ModifiersSupported = drmGetCap(fd, DRM_CAP_ADDFB2_MODIFIERS, &capability) && capability == 1;
|
||||
qCDebug(KWIN_DRM) << "drmModeAddFB2WithModifiers is" << (m_addFB2ModifiersSupported ? "supported" : "not supported");
|
||||
}
|
||||
|
||||
// find out if this GPU is using the NVidia proprietary driver
|
||||
DrmScopedPointer<drmVersion> version(drmGetVersion(fd));
|
||||
m_useEglStreams = strstr(version->name, "nvidia-drm");
|
||||
|
|
|
@ -92,6 +92,10 @@ public:
|
|||
*/
|
||||
clockid_t presentationClock() const;
|
||||
|
||||
bool addFB2ModifiersSupported() const {
|
||||
return m_addFB2ModifiersSupported;
|
||||
}
|
||||
|
||||
void waitIdle();
|
||||
|
||||
Q_SIGNALS:
|
||||
|
@ -124,6 +128,7 @@ private:
|
|||
EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
|
||||
clockid_t m_presentationClock;
|
||||
QSocketNotifier *m_socketNotifier = nullptr;
|
||||
bool m_addFB2ModifiersSupported = false;
|
||||
|
||||
// all planes: primarys, cursors and overlays
|
||||
QVector<DrmPlane*> m_planes;
|
||||
|
|
|
@ -81,7 +81,7 @@ bool DrmCrtc::blank(DrmOutput *output)
|
|||
}
|
||||
|
||||
if (!m_blackBuffer) {
|
||||
DrmDumbBuffer *blackBuffer = new DrmDumbBuffer(m_gpu->fd(), output->pixelSize());
|
||||
DrmDumbBuffer *blackBuffer = new DrmDumbBuffer(m_gpu, output->pixelSize());
|
||||
if (!blackBuffer->map()) {
|
||||
delete blackBuffer;
|
||||
return false;
|
||||
|
|
|
@ -359,7 +359,7 @@ void DrmOutput::initEdid(drmModeConnector *connector)
|
|||
bool DrmOutput::initCursor(const QSize &cursorSize)
|
||||
{
|
||||
auto createCursor = [this, cursorSize] (int index) {
|
||||
m_cursor[index].reset(new DrmDumbBuffer(m_gpu->fd(), cursorSize));
|
||||
m_cursor[index].reset(new DrmDumbBuffer(m_gpu, cursorSize));
|
||||
if (!m_cursor[index]->map(QImage::Format_ARGB32_Premultiplied)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -580,7 +580,7 @@ void EglGbmBackend::aboutToStartPainting(int screenId, const QRegion &damagedReg
|
|||
bool EglGbmBackend::presentOnOutput(Output &output, const QRegion &damagedRegion)
|
||||
{
|
||||
if (output.directScanoutBuffer) {
|
||||
output.buffer = QSharedPointer<DrmSurfaceBuffer>::create(m_gpu->fd(), output.directScanoutBuffer, output.bufferInterface);
|
||||
output.buffer = QSharedPointer<DrmSurfaceBuffer>::create(m_gpu, output.directScanoutBuffer, output.bufferInterface);
|
||||
} else if (isPrimary()) {
|
||||
if (supportsSwapBuffersWithDamage()) {
|
||||
QVector<EGLint> rects = regionToRects(output.damageHistory.constFirst(), output.output);
|
||||
|
@ -595,7 +595,7 @@ bool EglGbmBackend::presentOnOutput(Output &output, const QRegion &damagedRegion
|
|||
return false;
|
||||
}
|
||||
}
|
||||
output.buffer = QSharedPointer<DrmSurfaceBuffer>::create(m_gpu->fd(), output.gbmSurface);
|
||||
output.buffer = QSharedPointer<DrmSurfaceBuffer>::create(m_gpu, output.gbmSurface);
|
||||
} else {
|
||||
qCDebug(KWIN_DRM) << "imported gbm_bo does not exist!";
|
||||
return false;
|
||||
|
|
|
@ -281,7 +281,7 @@ bool EglStreamBackend::resetOutput(Output &o, DrmOutput *drmOutput)
|
|||
{
|
||||
o.output = drmOutput;
|
||||
// dumb buffer used for modesetting
|
||||
o.buffer = QSharedPointer<DrmDumbBuffer>::create(m_gpu->fd(), drmOutput->pixelSize());
|
||||
o.buffer = QSharedPointer<DrmDumbBuffer>::create(m_gpu, drmOutput->pixelSize());
|
||||
|
||||
EGLAttrib streamAttribs[] = {
|
||||
EGL_STREAM_FIFO_LENGTH_KHR, 0, // mailbox mode
|
||||
|
|
|
@ -45,7 +45,7 @@ void DrmQPainterBackend::initOutput(DrmOutput *output)
|
|||
{
|
||||
Output o;
|
||||
auto initBuffer = [&o, output, this] (int index) {
|
||||
o.buffer[index] = QSharedPointer<DrmDumbBuffer>::create(m_gpu->fd(), output->pixelSize());
|
||||
o.buffer[index] = QSharedPointer<DrmDumbBuffer>::create(m_gpu, output->pixelSize());
|
||||
if (o.buffer[index]->map()) {
|
||||
o.buffer[index]->image()->fill(Qt::black);
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ void DrmQPainterBackend::initOutput(DrmOutput *output)
|
|||
return;
|
||||
}
|
||||
auto initBuffer = [it, output, this] (int index) {
|
||||
it->buffer[index] = QSharedPointer<DrmDumbBuffer>::create(m_gpu->fd(), output->pixelSize());
|
||||
it->buffer[index] = QSharedPointer<DrmDumbBuffer>::create(m_gpu, output->pixelSize());
|
||||
if (it->buffer[index]->map()) {
|
||||
it->buffer[index]->image()->fill(Qt::black);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue