10#include <QtCore/QLoggingCategory>
11#include <QtGui/private/qguiapplication_p.h>
13#include <drm_fourcc.h>
20#include <mediactl/mediactl.h>
21#include <mediactl/v4l2subdev.h>
30 Q_ASSERT(DRM_FORMAT_XRGB8888 == GBM_FORMAT_XRGB8888);
36 Q_ASSERT(DRM_FORMAT_XRGB8888 == GBM_FORMAT_XRGB8888);
40void QEglFSKmsVsp2Screen::dmaBufferDestroyedHandler(gbm_bo *gbmBo,
void *
data)
43 auto dmabuf =
static_cast<DmaBuffer *
>(
data);
48QEglFSKmsVsp2Screen::DmaBuffer *QEglFSKmsVsp2Screen::dmaBufferForGbmBuffer(gbm_bo *gbmBo)
50 auto existingBuffer =
static_cast<DmaBuffer *
>(gbm_bo_get_user_data(gbmBo));
52 return existingBuffer;
54 uint32_t
handle = gbm_bo_get_handle(gbmBo).u32;
58 qWarning(
"Failed to create dmabuf file descriptor for buffer with drmPrimeHandleToFd");
62 gbm_bo_set_user_data(gbmBo, fb.data(), dmaBufferDestroyedHandler);
68 , m_blender(new Blender(
this))
76 qCDebug(qLcEglfsKmsDebug,
"Creating gbm_surface for screen %s with format 0x%x",
qPrintable(
name()), gbmFormat);
82 GBM_BO_USE_RENDERING);
88 if (m_frameBuffers[m_backFb].dmabufFd == -1)
96 m_gbmSurface =
nullptr;
101 for (
auto &fb : m_frameBuffers)
102 initDumbFrameBuffer(fb);
107 qCDebug(qLcEglfsKmsDebug,
"Initializing Vsp2 hardware");
120 const uint32_t fallbackFormat = DRM_FORMAT_ARGB8888;
123 formatSet = m_blendDevice->
enableInput(m_qtLayer,
QRect(
QPoint(), screenSize), fallbackFormat, bytesPerLine);
125 qFatal(
"Failed to set vsp2 blending format");
135 qCDebug(qLcEglfsKmsDebug) <<
"Enabled extra layer for vsp input" <<
index;
138 qWarning() <<
"Failed to add layer";
146 if (!m_blendScheduled) {
147 m_blendScheduled =
true;
173 m_blendFinishedCallbacks.
append(callback);
179 qWarning(
"Cannot sync before platform init!");
183 if (!m_blendScheduled && !m_nextGbmBo) {
184 m_nextGbmBo = gbm_surface_lock_front_buffer(m_gbmSurface);
187 qWarning(
"Could not lock GBM surface front buffer!");
191 m_blendScheduled =
true;
196void QEglFSKmsVsp2Screen::ensureModeSet()
201 int ret = drmModeSetCrtc(driFd,
203 m_frameBuffers[m_backFb].drmBufferId,
217void QEglFSKmsVsp2Screen::doDrmFlip()
222 int ret = drmModePageFlip(driFd,
224 m_frameBuffers[m_backFb].drmBufferId,
231 m_backFb = (m_backFb + 1) % 2;
236 m_blendScheduled =
false;
237 if (!m_nextGbmBo && !m_blendDevice->
isDirty())
240 FrameBuffer &backBuffer = m_frameBuffers[m_backFb];
241 if (backBuffer.dmabufFd == -1)
245 Q_ASSERT(m_nextGbmBo != m_currentGbmBo);
246 int compositorBackBufferDmaFd = dmaBufferForGbmBuffer(m_nextGbmBo)->dmabufFd;
247 m_blendDevice->
setInputBuffer(m_qtLayer, compositorBackBufferDmaFd);
250 gbm_surface_release_buffer(m_gbmSurface, m_currentGbmBo);
251 m_currentGbmBo = m_nextGbmBo;
252 m_nextGbmBo =
nullptr;
265 vBlank.request.type =
static_cast<drmVBlankSeqType
>(DRM_VBLANK_RELATIVE | DRM_VBLANK_SECONDARY);
266 vBlank.request.sequence = 1;
267 vBlank.request.signal = 0;
268 drmWaitVBlank(driFd, &vBlank);
270 if (!m_blendDevice->
blend(backBuffer.dmabufFd)) {
271 qWarning() <<
"Vsp2: Blending failed";
278 for (
auto cb : m_blendFinishedCallbacks)
284void QEglFSKmsVsp2Screen::initDumbFrameBuffer(FrameBuffer &fb)
287 const uint32_t
width = op.modes[op.mode].hdisplay;
288 const uint32_t
height = op.modes[op.mode].vdisplay;
291 const uint32_t dumbBufferFlags = 0;
292 const uint32_t bpp = 32;
294 drm_mode_create_dumb creq = {
303 if (drmIoctl(driFd, DRM_IOCTL_MODE_CREATE_DUMB, &creq) == -1)
304 qFatal(
"Failed to create dumb buffer: %s", strerror(errno));
312 uint32_t gbmBoHandles[4] = { creq.handle, 0, 0, 0 };
313 uint32_t
strides[4] = { creq.pitch, 0, 0, 0 };
315 uint32_t pixelFormat = DRM_FORMAT_ARGB8888;
316 uint32_t drmFlags = 0;
323 qFatal(
"drmModeAddFB2 failed: %s", strerror(errno));
325 drmPrimeHandleToFD(driFd, gbmBoHandles[0], DRM_CLOEXEC, &fb.dmabufFd);
328bool QEglFSKmsVsp2Screen::Blender::event(
QEvent *
event)
330 switch (
event->type()) {
332 m_screen->blendAndFlipDrm();
IOBluetoothDevice * device
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
QString name() const override
QEglFSKmsDevice * device() const
void setPowerState(QPlatformScreen::PowerState state) override
Sets the power state for this screen.
QRect rawGeometry() const override
bool removeLayer(int id) override
void setLayerPosition(int id, const QPoint &position) override
gbm_surface * createSurface()
void setLayerBuffer(int id, int dmabufFd) override
void addBlendListener(void(*callback)()) override
int addLayer(int dmabufFd, const QSize &size, const QPoint &position, uint drmPixelFormat, uint bytesPerLine) override
void setLayerAlpha(int id, qreal alpha) override
void initDumbFrameBuffers()
QEglFSKmsVsp2Screen(QEglFSKmsDevice *device, const QKmsOutput &output)
void append(parameter_type t)
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
constexpr QSize size() const noexcept
Returns the size of the rectangle.
T * data() const noexcept
Returns the value of the pointer referenced by this object.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
constexpr int width() const noexcept
Returns the width.
bool blend(int outputDmabufFd)
bool setInputBuffer(int index, int dmabufFd)
bool enableInput(int i, const QRect &bufferGeometry, uint drmFormat, uint bytesPerLine)
bool setInputPosition(int index, const QPoint &position)
bool setInputAlpha(int index, qreal alpha)
void qErrnoWarning(const char *msg,...)
Combined button and popup list for selecting options.
static uint32_t drmFormatToGbmFormat(uint32_t drmFormat)
QT_BEGIN_NAMESPACE QString q_fourccToString(uint code)
static QT_BEGIN_NAMESPACE uint32_t drmFormatToGbmFormat(uint32_t drmFormat)
static uint32_t gbmFormatToDrmFormat(uint32_t gbmFormat)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLuint64 GLenum void * handle
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint GLsizei const GLuint const GLintptr * offsets
GLsizei const GLuint const GLintptr const GLsizei * strides
GLfloat GLfloat GLfloat alpha
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define qPrintable(string)
QT_BEGIN_NAMESPACE typedef uchar * output