diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2010-10-15 01:25:15 (GMT) |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2011-01-25 17:54:49 (GMT) |
commit | f9d0a75c066ecc464907c2021874d9e2c347d9a4 (patch) | |
tree | 2f811297d6e0d7b0988980df44d83340746dc9d1 /src | |
parent | d0c99dada04785c95f321495c621cd18eaef8b94 (diff) | |
download | Qt-f9d0a75c066ecc464907c2021874d9e2c347d9a4.zip Qt-f9d0a75c066ecc464907c2021874d9e2c347d9a4.tar.gz Qt-f9d0a75c066ecc464907c2021874d9e2c347d9a4.tar.bz2 |
Introduce drm wayland buffer
Diffstat (limited to 'src')
4 files changed, 151 insertions, 40 deletions
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 5882ad4..30e0f6a 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -28,7 +28,7 @@ public: , mDisplay(display) { } void changeCursor(QCursor *cursor, QWidget *widget); - QWaylandBuffer *mBuffer; + QWaylandShmBuffer *mBuffer; QWaylandDisplay *mDisplay; }; @@ -145,8 +145,8 @@ void QWaylandCursor::changeCursor(QCursor *cursor, QWidget *widget) if (mBuffer) delete mBuffer; - mBuffer = new QWaylandBuffer(mDisplay, reader.size(), - QImage::Format_ARGB32); + mBuffer = new QWaylandShmBuffer(mDisplay, reader.size(), + QImage::Format_ARGB32); } reader.read(&mBuffer->mImage); @@ -177,6 +177,14 @@ struct wl_buffer *QWaylandDisplay::createShmBuffer(int fd, return wl_shm_create_buffer(mShm, fd, width, height, stride, visual); } +struct wl_buffer *QWaylandDisplay::createDrmBuffer(int name, + int width, int height, + uint32_t stride, + struct wl_visual *visual) +{ + return wl_drm_create_buffer(mDrm, name, width, height, stride, visual); +} + struct wl_visual *QWaylandDisplay::argbVisual() { return wl_display_get_argb_visual(mDisplay); @@ -431,19 +439,28 @@ WId QWaylandWindow::winId() const void QWaylandWindow::setVisible(bool visible) { - QWaylandWindowSurface *wws = - (QWaylandWindowSurface *) widget()->windowSurface(); - if (visible) { mSurface = mDisplay->createSurface(); wl_surface_set_user_data(mSurface, this); - wws->attach(); + attach(mBuffer); } else { wl_surface_destroy(mSurface); mSurface = NULL; } } +void QWaylandWindow::attach(QWaylandBuffer *buffer) +{ + QRect geometry = widget()->geometry(); + + mBuffer = buffer; + if (mSurface) { + wl_surface_attach(mSurface, mBuffer->mBuffer); + wl_surface_map(mSurface, geometry.x(), geometry.y(), + geometry.width(), geometry.height()); + } +} + void QWaylandWindow::configure(uint32_t time, uint32_t edges, int32_t x, int32_t y, int32_t width, int32_t height) @@ -529,7 +546,7 @@ QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWidget *widget, WId QWindowSurface *QWaylandIntegration::createWindowSurface(QWidget *widget, WId winId) const { Q_UNUSED(winId); - return new QWaylandWindowSurface(widget, mDisplay); + return new QWaylandShmWindowSurface(widget, mDisplay); } QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h index 81819be..6267e9b 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.h +++ b/src/plugins/platforms/wayland/qwaylandintegration.h @@ -71,6 +71,10 @@ public: struct wl_buffer *createShmBuffer(int fd, int width, int height, uint32_t stride, struct wl_visual *visual); + struct wl_buffer *createDrmBuffer(int name, int width, int height, + uint32_t stride, + struct wl_visual *visual); + struct wl_visual *argbVisual(); EGLDisplay eglDisplay() { return mEglDisplay; } @@ -150,12 +154,15 @@ public: int32_t x, int32_t y, int32_t width, int32_t height); WId winId() const; QPlatformGLContext *glContext() const; + void attach(QWaylandBuffer *buffer); private: struct wl_surface *mSurface; QWaylandDisplay *mDisplay; QPlatformGLContext *mGLContext; WId mWindowId; + + QWaylandBuffer *mBuffer; }; class QWaylandIntegration : public QPlatformIntegration diff --git a/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp b/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp index a988d63..0fd519e 100644 --- a/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp @@ -50,10 +50,19 @@ #include <errno.h> #include <sys/mman.h> +#define GL_GLEXT_PROTOTYPES +#define EGL_EGLEXT_PROTOTYPES +#define MESA_EGL_NO_X11_HEADERS + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + QT_BEGIN_NAMESPACE -QWaylandBuffer::QWaylandBuffer(QWaylandDisplay *display, - const QSize &size, QImage::Format format) +QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, + const QSize &size, QImage::Format format) { int stride = size.width() * 4; int alloc = stride * size.height(); @@ -82,31 +91,30 @@ QWaylandBuffer::QWaylandBuffer(QWaylandDisplay *display, close(fd); } -QWaylandBuffer::~QWaylandBuffer(void) +QWaylandShmBuffer::~QWaylandShmBuffer(void) { munmap((void *) mImage.constBits(), mImage.byteCount()); wl_buffer_destroy(mBuffer); } -QWaylandWindowSurface::QWaylandWindowSurface(QWidget *window, - QWaylandDisplay *display) +QWaylandShmWindowSurface::QWaylandShmWindowSurface(QWidget *window, + QWaylandDisplay *display) : QWindowSurface(window) , mBuffer(0) , mDisplay(display) { - //qDebug() << "QWaylandWindowSurface::QWaylandWindowSurface:" << (long)this; } -QWaylandWindowSurface::~QWaylandWindowSurface() +QWaylandShmWindowSurface::~QWaylandShmWindowSurface() { } -QPaintDevice *QWaylandWindowSurface::paintDevice() +QPaintDevice *QWaylandShmWindowSurface::paintDevice() { return &mBuffer->mImage; } -void QWaylandWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) +void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) { Q_UNUSED(widget); Q_UNUSED(offset); @@ -122,21 +130,9 @@ void QWaylandWindowSurface::flush(QWidget *widget, const QRegion ®ion, const } } -void QWaylandWindowSurface::attach(void) +void QWaylandShmWindowSurface::resize(const QSize &size) { QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow(); - QRect geometry = window()->geometry(); - - if (ww->surface() && mBuffer) { - wl_surface_attach(ww->surface(), mBuffer->mBuffer); - wl_surface_map(ww->surface(), geometry.x(), geometry.y(), - mBuffer->mImage.width(), mBuffer->mImage.height()); - } -} - -void QWaylandWindowSurface::resize(const QSize &size) -{ - //qDebug() << "QWaylandWindowSurface::setGeometry:" << (long)this << rect; QWindowSurface::resize(size); QImage::Format format = QApplicationPrivate::platformIntegration()->screens().first()->format(); @@ -146,9 +142,95 @@ void QWaylandWindowSurface::resize(const QSize &size) if (mBuffer != NULL) delete mBuffer; - mBuffer = new QWaylandBuffer(mDisplay, size, format); + mBuffer = new QWaylandShmBuffer(mDisplay, size, format); + + ww->attach(mBuffer); +} + - attach(); +class QWaylandDrmBuffer : public QWaylandBuffer { +public: + QWaylandDrmBuffer(QWaylandDisplay *display, + const QSize &size, QImage::Format format); + ~QWaylandDrmBuffer(); + EGLImageKHR mImage; + GLuint mTexture; + QWaylandDisplay *mDisplay; +}; + +class QWaylandDrmWindowSurface : public QWindowSurface +{ +public: + QWaylandDrmWindowSurface(QWidget *window, QWaylandDisplay *display); + ~QWaylandDrmWindowSurface(); + + QPaintDevice *paintDevice(); + void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); + void resize(const QSize &size); + +private: + QWaylandDrmBuffer *mBuffer; + QWaylandDisplay *mDisplay; +}; + +QWaylandDrmBuffer::QWaylandDrmBuffer(QWaylandDisplay *display, + const QSize &size, QImage::Format format) + : mDisplay(display) +{ + EGLint name, stride; + EGLint imageAttribs[] = { + EGL_WIDTH, 0, + EGL_HEIGHT, 0, + EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, + EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA, + EGL_NONE + }; + + imageAttribs[1] = size.width(); + imageAttribs[3] = size.height(); + mImage = eglCreateDRMImageMESA(mDisplay->eglDisplay(), imageAttribs); + glGenTextures(1, &mTexture); + glBindTexture(GL_TEXTURE_2D, mTexture); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mImage); + + eglExportDRMImageMESA(mDisplay->eglDisplay(), + mImage, &name, NULL, &stride); + + mBuffer = display->createDrmBuffer(name, size.width(), size.height(), + stride, display->argbVisual()); +} + +QWaylandDrmBuffer::~QWaylandDrmBuffer(void) +{ + glDeleteTextures(1, &mTexture); + eglDestroyImageKHR(mDisplay->eglDisplay(), mImage); + wl_buffer_destroy(mBuffer); +} + + +QWaylandDrmWindowSurface::QWaylandDrmWindowSurface(QWidget *window, + QWaylandDisplay *display) + : QWindowSurface(window) + , mBuffer(0) + , mDisplay(display) +{ +} + +QWaylandDrmWindowSurface::~QWaylandDrmWindowSurface() +{ +} + +QPaintDevice *QWaylandDrmWindowSurface::paintDevice() +{ + return NULL; +} + +void QWaylandDrmWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) +{ +} + +void QWaylandDrmWindowSurface::resize(const QSize &size) +{ } QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland/qwaylandwindowsurface.h b/src/plugins/platforms/wayland/qwaylandwindowsurface.h index 711b0c1..2246db6 100644 --- a/src/plugins/platforms/wayland/qwaylandwindowsurface.h +++ b/src/plugins/platforms/wayland/qwaylandwindowsurface.h @@ -52,26 +52,31 @@ class QWaylandDisplay; class QWaylandBuffer { public: - QWaylandBuffer(QWaylandDisplay *display, + QWaylandBuffer() { } + virtual ~QWaylandBuffer() { } + struct wl_buffer *mBuffer; +}; + +class QWaylandShmBuffer : public QWaylandBuffer { +public: + QWaylandShmBuffer(QWaylandDisplay *display, const QSize &size, QImage::Format format); - ~QWaylandBuffer(); + ~QWaylandShmBuffer(); QImage mImage; - struct wl_buffer *mBuffer; }; -class QWaylandWindowSurface : public QWindowSurface +class QWaylandShmWindowSurface : public QWindowSurface { public: - QWaylandWindowSurface(QWidget *window, QWaylandDisplay *display); - ~QWaylandWindowSurface(); + QWaylandShmWindowSurface(QWidget *window, QWaylandDisplay *display); + ~QWaylandShmWindowSurface(); QPaintDevice *paintDevice(); void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); void resize(const QSize &size); - void attach(void); private: - QWaylandBuffer *mBuffer; + QWaylandShmBuffer *mBuffer; QWaylandDisplay *mDisplay; }; |