summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/eglfs
diff options
context:
space:
mode:
authorLouai Al-Khanji <louai.al-khanji@digia.com>2014-09-16 09:57:46 +0300
committerLouai Al-Khanji <louai.al-khanji@digia.com>2014-09-16 15:43:23 +0200
commit4f25bdd21ac5eaadcfaeea89bbfc0bf382cd862b (patch)
tree11361ad14ad39a142824e982fd5b2a3385042f23 /src/plugins/platforms/eglfs
parentfabef06f3326886bad9e6c039ca76e6368ad762c (diff)
EGLFS KMS Hooks: Get rid of flashing
Change-Id: I590572ceb0f64d3e6a1d687874d549e84f20f60a Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
Diffstat (limited to 'src/plugins/platforms/eglfs')
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks_kms.cpp106
1 files changed, 60 insertions, 46 deletions
diff --git a/src/plugins/platforms/eglfs/qeglfshooks_kms.cpp b/src/plugins/platforms/eglfs/qeglfshooks_kms.cpp
index 1e5b50e6ce..e9eec7fdc7 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks_kms.cpp
+++ b/src/plugins/platforms/eglfs/qeglfshooks_kms.cpp
@@ -113,14 +113,22 @@ public:
QPlatformCursor *createCursor(QPlatformScreen *screen) const Q_DECL_OVERRIDE;
void presentBuffer() Q_DECL_OVERRIDE;
+private:
bool setup_kms();
struct FrameBuffer {
FrameBuffer() : fb(0) {}
uint32_t fb;
};
+ static void bufferDestroyedHandler(gbm_bo *bo, void *data);
FrameBuffer *framebufferForBufferObject(gbm_bo *bo);
+ static void pageFlipHandler(int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *user_data);
+
private:
// device bits
QByteArray m_device;
@@ -135,6 +143,10 @@ private:
// Drawing bits
gbm_surface *m_gbm_surface;
+ gbm_bo *m_gbm_bo_current;
+ gbm_bo *m_gbm_bo_next;
+ bool m_flipping;
+ bool m_mode_set;
};
static QEglKmsHooks kms_hooks;
@@ -147,6 +159,10 @@ QEglKmsHooks::QEglKmsHooks()
, m_drm_encoder(Q_NULLPTR)
, m_drm_crtc(0)
, m_gbm_surface(Q_NULLPTR)
+ , m_gbm_bo_current(Q_NULLPTR)
+ , m_gbm_bo_next(Q_NULLPTR)
+ , m_flipping(false)
+ , m_mode_set(false)
{
}
@@ -257,7 +273,6 @@ bool QEglKmsHooks::hasCapability(QPlatformIntegration::Capability cap) const
case QPlatformIntegration::ThreadedPixmaps:
case QPlatformIntegration::OpenGL:
case QPlatformIntegration::ThreadedOpenGL:
- case QPlatformIntegration::BufferQueueingOpenGL:
return true;
default:
return false;
@@ -270,7 +285,7 @@ QPlatformCursor *QEglKmsHooks::createCursor(QPlatformScreen *screen) const
return new QKmsCursor(m_gbm_device, m_dri_fd, m_drm_crtc);
}
-static void gbm_bo_destroyed_callback(gbm_bo *bo, void *data)
+void QEglKmsHooks::bufferDestroyedHandler(gbm_bo *bo, void *data)
{
QEglKmsHooks::FrameBuffer *fb = static_cast<QEglKmsHooks::FrameBuffer *>(data);
@@ -305,23 +320,32 @@ QEglKmsHooks::FrameBuffer *QEglKmsHooks::framebufferForBufferObject(gbm_bo *bo)
return Q_NULLPTR;
}
- gbm_bo_set_user_data(bo, fb.data(), gbm_bo_destroyed_callback);
+ gbm_bo_set_user_data(bo, fb.data(), bufferDestroyedHandler);
return fb.take();
}
-static void page_flip_handler(int fd,
- unsigned int sequence,
- unsigned int tv_sec,
- unsigned int tv_usec,
- void *user_data)
+void QEglKmsHooks::pageFlipHandler(int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *user_data)
{
Q_UNUSED(fd);
Q_UNUSED(sequence);
Q_UNUSED(tv_sec);
Q_UNUSED(tv_usec);
+ QEglKmsHooks *hooks = static_cast<QEglKmsHooks *>(user_data);
+
+ if (hooks->m_gbm_bo_current)
+ gbm_surface_release_buffer(hooks->m_gbm_surface,
+ hooks->m_gbm_bo_current);
+
+ hooks->m_gbm_bo_current = hooks->m_gbm_bo_next;
+ hooks->m_gbm_bo_next = Q_NULLPTR;
+
// We are no longer flipping
- *static_cast<bool *>(user_data) = false;
+ hooks->m_flipping = false;
}
void QEglKmsHooks::presentBuffer()
@@ -331,64 +355,55 @@ void QEglKmsHooks::presentBuffer()
return;
}
- if (!gbm_surface_has_free_buffers(m_gbm_surface)) {
- qWarning("Out of free GBM buffers!");
- return;
- }
-
- gbm_bo *front_buffer = gbm_surface_lock_front_buffer(m_gbm_surface);
- if (!front_buffer) {
+ m_gbm_bo_next = gbm_surface_lock_front_buffer(m_gbm_surface);
+ if (!m_gbm_bo_next) {
qWarning("Could not lock GBM surface front buffer!");
return;
}
- QEglKmsHooks::FrameBuffer *fb = framebufferForBufferObject(front_buffer);
-
- int ret = drmModeSetCrtc(m_dri_fd,
- m_drm_crtc,
- fb->fb,
- 0, 0,
- &m_drm_connector->connector_id, 1,
- &m_drm_mode);
- if (ret) {
- qErrnoWarning("Could not set DRM mode!");
- return;
+ QEglKmsHooks::FrameBuffer *fb = framebufferForBufferObject(m_gbm_bo_next);
+
+ if (!m_mode_set) {
+ int ret = drmModeSetCrtc(m_dri_fd,
+ m_drm_crtc,
+ fb->fb,
+ 0, 0,
+ &m_drm_connector->connector_id, 1,
+ &m_drm_mode);
+ if (ret) {
+ qErrnoWarning("Could not set DRM mode!");
+ } else {
+ m_mode_set = true;
+ }
}
- bool flipping = true;
- ret = drmModePageFlip(m_dri_fd,
- m_drm_encoder->crtc_id,
- fb->fb,
- DRM_MODE_PAGE_FLIP_EVENT,
- &flipping);
+ int ret = drmModePageFlip(m_dri_fd,
+ m_drm_encoder->crtc_id,
+ fb->fb,
+ DRM_MODE_PAGE_FLIP_EVENT,
+ this);
if (ret) {
qErrnoWarning("Could not queue DRM page flip!");
return;
}
+ m_flipping = true;
+
drmEventContext drmEvent = {
DRM_EVENT_CONTEXT_VERSION,
Q_NULLPTR, // vblank handler
- page_flip_handler // page flip handler
+ pageFlipHandler // page flip handler
};
fd_set fds;
FD_ZERO(&fds);
FD_SET(m_dri_fd, &fds);
- time_t start, cur;
- time(&start);
-
- while (flipping && (time(&cur) < start + 1)) {
- timespec v;
- memset(&v, 0, sizeof(v));
- v.tv_sec = start + 1 - cur;
-
- ret = qt_safe_select(m_dri_fd + 1, &fds, Q_NULLPTR, Q_NULLPTR, &v);
+ while (m_flipping) {
+ ret = qt_safe_select(m_dri_fd + 1, &fds, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR);
if (ret == 0) {
// timeout
- break;
} else if (ret == -1) {
qErrnoWarning("Error while selecting on DRM fd");
break;
@@ -396,8 +411,6 @@ void QEglKmsHooks::presentBuffer()
qWarning("Could not handle DRM event!");
}
}
-
- gbm_surface_release_buffer(m_gbm_surface, front_buffer);
}
bool QEglKmsHooks::setup_kms()
@@ -464,6 +477,7 @@ bool QEglKmsHooks::setup_kms()
return true;
}
+
QKmsCursor::QKmsCursor(gbm_device *gbm_device, int dri_fd, uint32_t crtcId)
: m_gbm_device(gbm_device)
, m_dri_fd(dri_fd)