From 936aceb5f204e6f51b69de5555d7d8337677c9c3 Mon Sep 17 00:00:00 2001 From: anknight Date: Thu, 14 Feb 2013 15:29:10 +0200 Subject: KMS QPA Plugin: use GBM cursor writer GBM provides a way to write directly to a buffer object that gets set as the drmMode cursor. This eliminates the need to create a GL texture and opens this class up to platforms that support GBM but not OpenGL. Change-Id: I7297827387ef9a717a5287b5484f14c9987b4158 Reviewed-by: Andy Nichols --- src/plugins/platforms/kms/qkmscursor.cpp | 65 ++++++++------------------------ src/plugins/platforms/kms/qkmscursor.h | 10 ++--- 2 files changed, 19 insertions(+), 56 deletions(-) diff --git a/src/plugins/platforms/kms/qkmscursor.cpp b/src/plugins/platforms/kms/qkmscursor.cpp index d5a28dbc9a..da5dc9bb06 100644 --- a/src/plugins/platforms/kms/qkmscursor.cpp +++ b/src/plugins/platforms/kms/qkmscursor.cpp @@ -48,22 +48,17 @@ QT_BEGIN_NAMESPACE QKmsCursor::QKmsCursor(QKmsScreen *screen) : m_screen(screen), m_graphicsBufferManager(screen->device()->gbmDevice()), + m_cursorBufferObject(gbm_bo_create(m_graphicsBufferManager, 64, 64, GBM_FORMAT_ARGB8888, + GBM_BO_USE_CURSOR_64X64|GBM_BO_USE_WRITE)), + m_cursorImage(new QPlatformCursorImage(0, 0, 0, 0, 0, 0)), m_moved(false) { - gbm_bo *bo = gbm_bo_create(m_graphicsBufferManager, 64, 64, - GBM_BO_FORMAT_ARGB8888, - GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_RENDERING); - - m_eglImage = eglCreateImageKHR(m_screen->device()->eglDisplay(), 0, EGL_NATIVE_PIXMAP_KHR, - bo, 0); - gbm_bo_destroy(bo); - m_cursorImage = new QPlatformCursorImage(0, 0, 0, 0, 0, 0); } QKmsCursor::~QKmsCursor() { - drmModeSetCursor(m_screen->device()->fd(), m_screen->crtcId(), - 0, 0, 0); + drmModeSetCursor(m_screen->device()->fd(), m_screen->crtcId(), 0, 0, 0); + gbm_bo_destroy(m_cursorBufferObject); } void QKmsCursor::pointerEvent(const QMouseEvent &event) @@ -78,58 +73,30 @@ void QKmsCursor::pointerEvent(const QMouseEvent &event) } } -void QKmsCursor::changeCursor(QCursor *widgetCursor, QWindow *window) +void QKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window) { Q_UNUSED(window) if (!m_moved) drmModeMoveCursor(m_screen->device()->fd(), m_screen->crtcId(), 0, 0); - const Qt::CursorShape newShape = widgetCursor ? widgetCursor->shape() : Qt::ArrowCursor; + const Qt::CursorShape newShape = windowCursor ? windowCursor->shape() : Qt::ArrowCursor; if (newShape != Qt::BitmapCursor) { m_cursorImage->set(newShape); } else { - m_cursorImage->set(widgetCursor->pixmap().toImage(), - widgetCursor->hotSpot().x(), - widgetCursor->hotSpot().y()); - } - - if ((m_cursorImage->image()->width() > 64) || (m_cursorImage->image()->width() > 64)) { - qWarning("failed to set hardware cursor: larger than 64x64."); - return; - } - - QImage cursorImage = m_cursorImage->image()->convertToFormat(QImage::Format_RGB32); - - //Load cursor image into EGLImage - GLuint cursorTexture; - glGenTextures(1, &cursorTexture); - glBindTexture(GL_TEXTURE_2D, cursorTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - - //TODO: Format may be wrong here, need a color icon to test. - if (m_eglImage != EGL_NO_IMAGE_KHR) { - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, cursorImage.width(), - cursorImage.height(), GL_RGBA, - GL_UNSIGNED_BYTE, cursorImage.constBits()); - } else { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cursorImage.width(), - cursorImage.height(), 0, GL_RGBA, - GL_UNSIGNED_BYTE, cursorImage.constBits()); + m_cursorImage->set(windowCursor->pixmap().toImage(), + windowCursor->hotSpot().x(), + windowCursor->hotSpot().y()); } - //EGLImage needs to contain sprite before calling this: - gbm_bo *bufferObject = gbm_bo_import(m_graphicsBufferManager, GBM_BO_IMPORT_EGL_IMAGE, - m_eglImage, GBM_BO_USE_CURSOR_64X64); - quint32 handle = gbm_bo_get_handle(bufferObject).u32; + if ((m_cursorImage->image()->width() > 64) || (m_cursorImage->image()->width() > 64)) + qWarning("Warning: cursor larger than 64x64; only 64x64 pixels will be shown."); - gbm_bo_destroy(bufferObject); + QImage cursorImage = m_cursorImage->image()-> + convertToFormat(QImage::Format_ARGB32).copy(0, 0, 64, 64); + gbm_bo_write(m_cursorBufferObject, cursorImage.constBits(), cursorImage.byteCount()); + quint32 handle = gbm_bo_get_handle(m_cursorBufferObject).u32; int status = drmModeSetCursor(m_screen->device()->fd(), m_screen->crtcId(), handle, 64, 64); diff --git a/src/plugins/platforms/kms/qkmscursor.h b/src/plugins/platforms/kms/qkmscursor.h index fda47ebedc..ee65b01e36 100644 --- a/src/plugins/platforms/kms/qkmscursor.h +++ b/src/plugins/platforms/kms/qkmscursor.h @@ -44,15 +44,11 @@ #include -#define EGL_EGLEXT_PROTOTYPES 1 - -#include -#include - QT_BEGIN_NAMESPACE class QKmsScreen; class gbm_device; +class gbm_bo; class QKmsCursor : public QPlatformCursor { @@ -61,12 +57,12 @@ public: ~QKmsCursor(); void pointerEvent(const QMouseEvent &event); - void changeCursor(QCursor *widgetCursor, QWindow *window); + void changeCursor(QCursor *windowCursor, QWindow *window); private: QKmsScreen *m_screen; gbm_device *m_graphicsBufferManager; - EGLImageKHR m_eglImage; + gbm_bo *m_cursorBufferObject; QPlatformCursorImage *m_cursorImage; bool m_moved; }; -- cgit v1.2.3