summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2010-10-22 17:31:03 (GMT)
committerJørgen Lind <jorgen.lind@nokia.com>2011-01-25 17:56:26 (GMT)
commit506e3535c85de2b41e0d31bbcd3b726ce8adbeca (patch)
tree7845a55d113fdfcc2e8607d070ef92a783ef2721 /src/plugins/platforms
parent229d9d36c3ba3f4149d050a6942886b181a90db7 (diff)
downloadQt-506e3535c85de2b41e0d31bbcd3b726ce8adbeca.zip
Qt-506e3535c85de2b41e0d31bbcd3b726ce8adbeca.tar.gz
Qt-506e3535c85de2b41e0d31bbcd3b726ce8adbeca.tar.bz2
Wayland: add GL drawing support
Works with analogclock, draws upside down, fails to resize, and doesn't show GL widget with hello_es2.
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp17
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.h5
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindowsurface.cpp140
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindowsurface.h37
4 files changed, 167 insertions, 32 deletions
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
index 248158d..c433983 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.cpp
+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp
@@ -3,6 +3,7 @@
#include <QImageReader>
#include <QWindowSystemInterface>
#include <QPlatformCursor>
+#include <QPaintEngine>
#include <QtGui/QPlatformGLContext>
#include <QtGui/QPlatformWindowFormat>
@@ -10,6 +11,9 @@
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/QPlatformWindow>
+#include <private/qwindowsurface_gl_p.h>
+#include <private/qpixmapdata_gl_p.h>
+
#include "qwaylandintegration.h"
#include "qwaylandwindowsurface.h"
@@ -405,9 +409,10 @@ QWaylandDisplay::~QWaylandDisplay(void)
wl_display_destroy(mDisplay);
}
-QWaylandIntegration::QWaylandIntegration()
+QWaylandIntegration::QWaylandIntegration(bool useOpenGL)
: mFontDb(new QFontconfigDatabase())
, mDisplay(new QWaylandDisplay())
+ , mUseOpenGL(useOpenGL)
{
}
@@ -419,6 +424,8 @@ QWaylandIntegration::screens() const
QPixmapData *QWaylandIntegration::createPixmapData(QPixmapData::PixelType type) const
{
+ if (mUseOpenGL)
+ return new QGLPixmapData(type);
return new QRasterPixmapData(type);
}
@@ -426,6 +433,7 @@ QWaylandWindow::QWaylandWindow(QWidget *window, QWaylandDisplay *display)
: QPlatformWindow(window)
, mSurface(0)
, mDisplay(display)
+ , mGLContext(0)
{
static WId id = 1;
@@ -434,6 +442,8 @@ QWaylandWindow::QWaylandWindow(QWidget *window, QWaylandDisplay *display)
QWaylandWindow::~QWaylandWindow()
{
+ if (mGLContext)
+ delete mGLContext;
}
WId QWaylandWindow::winId() const
@@ -508,6 +518,7 @@ QWaylandGLContext::QWaylandGLContext(QWaylandDisplay *wd, const QPlatformWindowF
eglDisplay = mDisplay->eglDisplay();
mContext = eglCreateContext(eglDisplay, NULL,
EGL_NO_CONTEXT, contextAttribs);
+ eglMakeCurrent(eglDisplay, NULL, NULL, mContext);
}
QWaylandGLContext::~QWaylandGLContext()
@@ -518,10 +529,12 @@ QWaylandGLContext::~QWaylandGLContext()
void QWaylandGLContext::makeCurrent()
{
+ eglMakeCurrent(mDisplay->eglDisplay(), 0, 0, mContext);
}
void QWaylandGLContext::doneCurrent()
{
+ eglMakeCurrent(mDisplay->eglDisplay(), 0, 0, mContext);
}
void QWaylandGLContext::swapBuffers()
@@ -554,6 +567,8 @@ QWindowSurface *QWaylandIntegration::createWindowSurface(QWidget *widget, WId wi
Q_UNUSED(winId);
Q_UNUSED(winId);
+ if (mUseOpenGL)
+ return new QWaylandDrmWindowSurface(widget, mDisplay);
return new QWaylandShmWindowSurface(widget, mDisplay);
}
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h
index 6267e9b..70fb538 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.h
+++ b/src/plugins/platforms/wayland/qwaylandintegration.h
@@ -46,6 +46,7 @@
#include <QObject>
#include <QtGui/QPlatformIntegration>
#include <QtGui/QPlatformScreen>
+#include "qgl.h"
#include <wayland-client.h>
#include "qwaylandinputdevice.h"
@@ -155,6 +156,7 @@ public:
WId winId() const;
QPlatformGLContext *glContext() const;
void attach(QWaylandBuffer *buffer);
+ QWaylandBuffer *getBuffer(void) { return mBuffer; }
private:
struct wl_surface *mSurface;
@@ -168,7 +170,7 @@ private:
class QWaylandIntegration : public QPlatformIntegration
{
public:
- QWaylandIntegration();
+ QWaylandIntegration(bool useOpenGL = false);
QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
@@ -181,6 +183,7 @@ public:
private:
QPlatformFontDatabase *mFontDb;
QWaylandDisplay *mDisplay;
+ bool mUseOpenGL;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp b/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp
index 0954bc5..78900ba 100644
--- a/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp
@@ -39,10 +39,18 @@
**
****************************************************************************/
-#include "qwaylandintegration.h"
-#include "qwaylandwindowsurface.h"
+#define GL_GLEXT_PROTOTYPES
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <QGLFramebufferObject>
#include <QtCore/qdebug.h>
#include <QtGui/private/qapplication_p.h>
+#include <QtOpenGL/private/qgl_p.h>
+#include <QtOpenGL/private/qglpaintdevice_p.h>
+
+#include "qwaylandintegration.h"
+#include "qwaylandwindowsurface.h"
#include <wayland-client.h>
#include <unistd.h>
@@ -50,15 +58,6 @@
#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
QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
@@ -147,35 +146,77 @@ void QWaylandShmWindowSurface::resize(const QSize &size)
ww->attach(mBuffer);
}
-
-class QWaylandDrmBuffer : public QWaylandBuffer {
+class QWaylandPaintDevice : public QGLPaintDevice
+{
public:
- QWaylandDrmBuffer(QWaylandDisplay *display,
- const QSize &size, QImage::Format format);
- ~QWaylandDrmBuffer();
- EGLImageKHR mImage;
- GLuint mTexture;
+ QWaylandPaintDevice(QWaylandDisplay *display, QWidget *widget)
+ : QGLPaintDevice(), mDisplay(display), mWidget(widget)
+ {
+ QGLFormat format;
+ mContext = new QGLContext(format, widget);
+ mContext->create();
+ glGenFramebuffers(1, &mFbo);
+ glGenRenderbuffers(1, &mRbo);
+ }
+ ~QWaylandPaintDevice()
+ {
+ glDeleteFramebuffers(1, &mFbo);
+ glDeleteRenderbuffers(1, &mRbo);
+ }
+
+ QSize size() const { return mWidget->size(); }
+ QGLContext *context() const { return mContext; }
+ QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); }
+
+ void beginPaint();
+ void endPaint();
+private:
QWaylandDisplay *mDisplay;
+ QWidget *mWidget;
+ QGLContext *mContext;
+ GLuint mFbo, mRbo;
};
-class QWaylandDrmWindowSurface : public QWindowSurface
+void QWaylandPaintDevice::beginPaint(void)
{
-public:
- QWaylandDrmWindowSurface(QWidget *window, QWaylandDisplay *display);
- ~QWaylandDrmWindowSurface();
+ QWaylandWindow *mWindow = (QWaylandWindow *)mWidget->platformWindow();
+ QWaylandDrmBuffer *mBuffer = (QWaylandDrmBuffer *)mWindow->getBuffer();
+ QPlatformGLContext *ctx = mWindow->glContext();
+ QRect geometry = mWidget->geometry();
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize(const QSize &size);
+ QGLPaintDevice::beginPaint();
-private:
- QWaylandDrmBuffer *mBuffer;
- QWaylandDisplay *mDisplay;
-};
+ ctx->makeCurrent();
+ glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, mRbo);
+ glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mBuffer->mImage);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER, mRbo);
+}
+
+void QWaylandPaintDevice::endPaint(void)
+{
+ QWaylandWindow *mWindow = (QWaylandWindow *)mWidget->platformWindow();
+ QPlatformGLContext *ctx = mWindow->glContext();
+ QRect geometry = mWidget->geometry();
+
+ wl_surface_damage(mWindow->surface(), 0, 0,
+ geometry.width(), geometry.height());
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ ctx->doneCurrent();
+
+ QGLPaintDevice::endPaint();
+}
+
+/*
+ * Shared DRM surface for GL based drawing
+ */
QWaylandDrmBuffer::QWaylandDrmBuffer(QWaylandDisplay *display,
const QSize &size, QImage::Format format)
: mDisplay(display)
+ , mSize(size)
{
Q_UNUSED(format);
@@ -216,23 +257,62 @@ QWaylandDrmWindowSurface::QWaylandDrmWindowSurface(QWidget *window,
, mBuffer(0)
, mDisplay(display)
{
+ mPaintDevice = new QWaylandPaintDevice(display, window);
}
QWaylandDrmWindowSurface::~QWaylandDrmWindowSurface()
{
+ delete mPaintDevice;
}
QPaintDevice *QWaylandDrmWindowSurface::paintDevice()
{
- return NULL;
+ return mPaintDevice;
}
void QWaylandDrmWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
{
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+ Q_UNUSED(widget);
+#if 0
+ GLuint surf_rbo, surf_fbo;
+ QWaylandWindow *mWindow = (QWaylandWindow *)widget->platformWindow();
+ QPlatformGLContext *ctx = mWindow->glContext();
+ QRect geometry = widget->geometry();
+
+ ctx->makeCurrent();
+
+ glGenFramebuffers(1, &surf_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, surf_fbo);
+ glGenRenderbuffers(1, &surf_rbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, surf_rbo);
+ glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mBuffer->mImage);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER, surf_rbo);
+
+ wl_surface_damage(mWindow->surface(), 0, 0,
+ geometry.width(), geometry.height());
+
+ ctx->doneCurrent();
+#endif
}
void QWaylandDrmWindowSurface::resize(const QSize &size)
{
+ QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow();
+ QWindowSurface::resize(size);
+ QImage::Format format = QApplicationPrivate::platformIntegration()->screens().first()->format();
+
+ if (mBuffer != NULL && mBuffer->mSize == size)
+ return;
+
+ if (mBuffer != NULL)
+ delete mBuffer;
+
+ mBuffer = new QWaylandDrmBuffer(mDisplay, size, format);
+
+ ww->attach(mBuffer);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandwindowsurface.h b/src/plugins/platforms/wayland/qwaylandwindowsurface.h
index 2246db6..a033531 100644
--- a/src/plugins/platforms/wayland/qwaylandwindowsurface.h
+++ b/src/plugins/platforms/wayland/qwaylandwindowsurface.h
@@ -42,10 +42,18 @@
#ifndef QWINDOWSURFACE_WAYLAND_H
#define QWINDOWSURFACE_WAYLAND_H
+#include <QGLFramebufferObject>
#include <QtGui/private/qwindowsurface_p.h>
#include <QtGui/QPlatformWindow>
+#define MESA_EGL_NO_X11_HEADERS
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <QtOpenGL/qgl.h>
+
QT_BEGIN_NAMESPACE
class QWaylandDisplay;
@@ -80,6 +88,35 @@ private:
QWaylandDisplay *mDisplay;
};
+class QWaylandDrmBuffer : public QWaylandBuffer {
+public:
+ QWaylandDrmBuffer(QWaylandDisplay *display,
+ const QSize &size, QImage::Format format);
+ ~QWaylandDrmBuffer();
+ EGLImageKHR mImage;
+ GLuint mTexture;
+ QWaylandDisplay *mDisplay;
+ QGLFramebufferObject *pdev;
+ QSize mSize;
+};
+
+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;
+ QPaintDevice *mPaintDevice;
+};
+
+
QT_END_NAMESPACE
#endif