summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2010-10-15 01:25:15 (GMT)
committerJørgen Lind <jorgen.lind@nokia.com>2011-01-25 17:54:49 (GMT)
commitf9d0a75c066ecc464907c2021874d9e2c347d9a4 (patch)
tree2f811297d6e0d7b0988980df44d83340746dc9d1 /src
parentd0c99dada04785c95f321495c621cd18eaef8b94 (diff)
downloadQt-f9d0a75c066ecc464907c2021874d9e2c347d9a4.zip
Qt-f9d0a75c066ecc464907c2021874d9e2c347d9a4.tar.gz
Qt-f9d0a75c066ecc464907c2021874d9e2c347d9a4.tar.bz2
Introduce drm wayland buffer
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp33
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.h7
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindowsurface.cpp130
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindowsurface.h21
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 &region, const QPoint &offset)
+void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
{
Q_UNUSED(widget);
Q_UNUSED(offset);
@@ -122,21 +130,9 @@ void QWaylandWindowSurface::flush(QWidget *widget, const QRegion &region, 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 &region, 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 &region, 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 &region, const QPoint &offset);
void resize(const QSize &size);
- void attach(void);
private:
- QWaylandBuffer *mBuffer;
+ QWaylandShmBuffer *mBuffer;
QWaylandDisplay *mDisplay;
};