#include <QImageReader>
#include <QWindowSystemInterface>
#include <QPlatformCursor>
+#include <QPaintEngine>
#include <QtGui/QPlatformGLContext>
#include <QtGui/QPlatformWindowFormat>
#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"
wl_display_destroy(mDisplay);
}
-QWaylandIntegration::QWaylandIntegration()
+QWaylandIntegration::QWaylandIntegration(bool useOpenGL)
: mFontDb(new QFontconfigDatabase())
, mDisplay(new QWaylandDisplay())
+ , mUseOpenGL(useOpenGL)
{
}
QPixmapData *QWaylandIntegration::createPixmapData(QPixmapData::PixelType type) const
{
+ if (mUseOpenGL)
+ return new QGLPixmapData(type);
return new QRasterPixmapData(type);
}
: QPlatformWindow(window)
, mSurface(0)
, mDisplay(display)
+ , mGLContext(0)
{
static WId id = 1;
QWaylandWindow::~QWaylandWindow()
{
+ if (mGLContext)
+ delete mGLContext;
}
WId QWaylandWindow::winId() const
eglDisplay = mDisplay->eglDisplay();
mContext = eglCreateContext(eglDisplay, NULL,
EGL_NO_CONTEXT, contextAttribs);
+ eglMakeCurrent(eglDisplay, NULL, NULL, mContext);
}
QWaylandGLContext::~QWaylandGLContext()
void QWaylandGLContext::makeCurrent()
{
+ eglMakeCurrent(mDisplay->eglDisplay(), 0, 0, mContext);
}
void QWaylandGLContext::doneCurrent()
{
+ eglMakeCurrent(mDisplay->eglDisplay(), 0, 0, mContext);
}
void QWaylandGLContext::swapBuffers()
Q_UNUSED(winId);
Q_UNUSED(winId);
+ if (mUseOpenGL)
+ return new QWaylandDrmWindowSurface(widget, mDisplay);
return new QWaylandShmWindowSurface(widget, mDisplay);
}
**
****************************************************************************/
-#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>
#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,
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 ®ion, 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);
, 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 ®ion, 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
#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;
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 ®ion, const QPoint &offset);
+ void resize(const QSize &size);
+
+private:
+ QWaylandDrmBuffer *mBuffer;
+ QWaylandDisplay *mDisplay;
+ QPaintDevice *mPaintDevice;
+};
+
+
QT_END_NAMESPACE
#endif