summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2010-11-08 20:24:09 (GMT)
committerJørgen Lind <jorgen.lind@nokia.com>2011-01-25 18:03:50 (GMT)
commitf3bb98a1fa89a505ae3015977840ddbe2219ab5a (patch)
tree0eeb61519272459c2142768ab9513dcb4b545254 /src
parent513f396c7a888473a32cf212f1ce969fe38fdf2e (diff)
downloadQt-f3bb98a1fa89a505ae3015977840ddbe2219ab5a.zip
Qt-f3bb98a1fa89a505ae3015977840ddbe2219ab5a.tar.gz
Qt-f3bb98a1fa89a505ae3015977840ddbe2219ab5a.tar.bz2
Wayland: split GL code into separate files
For clarity and to prevent merge conflicts etc. in future.
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/wayland/qwaylanddrmsurface.cpp (renamed from src/plugins/platforms/wayland/qwaylandwindowsurface.cpp)86
-rw-r--r--src/plugins/platforms/wayland/qwaylandglcontext.cpp207
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp202
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.h21
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmsurface.cpp142
-rw-r--r--src/plugins/platforms/wayland/wayland.pro6
6 files changed, 374 insertions, 290 deletions
diff --git a/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp b/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp
index 2374eac..c9fb187 100644
--- a/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp
@@ -60,92 +60,6 @@
QT_BEGIN_NAMESPACE
-QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
- const QSize &size, QImage::Format format)
-{
- int stride = size.width() * 4;
- int alloc = stride * size.height();
- char filename[] = "/tmp/wayland-shm-XXXXXX";
- int fd = mkstemp(filename);
- if (fd < 0)
- qWarning("open %s failed: %s", filename, strerror(errno));
- if (ftruncate(fd, alloc) < 0) {
- qWarning("ftruncate failed: %s", strerror(errno));
- close(fd);
- return;
- }
- uchar *data = (uchar *)
- mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- unlink(filename);
-
- if (data == (uchar *) MAP_FAILED) {
- qWarning("mmap /dev/zero failed: %s", strerror(errno));
- close(fd);
- return;
- }
-
- mImage = QImage(data, size.width(), size.height(), stride, format);
- mBuffer = display->createShmBuffer(fd, size.width(), size.height(),
- stride, display->argbVisual());
- close(fd);
-}
-
-QWaylandShmBuffer::~QWaylandShmBuffer(void)
-{
- munmap((void *) mImage.constBits(), mImage.byteCount());
- wl_buffer_destroy(mBuffer);
-}
-
-QWaylandShmWindowSurface::QWaylandShmWindowSurface(QWidget *window,
- QWaylandDisplay *display)
- : QWindowSurface(window)
- , mBuffer(0)
- , mDisplay(display)
-{
-}
-
-QWaylandShmWindowSurface::~QWaylandShmWindowSurface()
-{
-}
-
-QPaintDevice *QWaylandShmWindowSurface::paintDevice()
-{
- return &mBuffer->mImage;
-}
-
-void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(widget);
- Q_UNUSED(offset);
- QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow();
- QVector<QRect> rects = region.rects();
- const QRect *r;
- int i;
-
- for (i = 0; i < rects.size(); i++) {
- r = &rects.at(i);
- wl_surface_damage(ww->surface(),
- r->x(), r->y(), r->width(), r->height());
- }
-}
-
-void QWaylandShmWindowSurface::resize(const QSize &size)
-{
- QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow();
- QWindowSurface::resize(size);
- QImage::Format format = QApplicationPrivate::platformIntegration()->screens().first()->format();
-
- if (mBuffer != NULL && mBuffer->mImage.size() == size)
- return;
-
- if (mBuffer != NULL)
- delete mBuffer;
-
- mBuffer = new QWaylandShmBuffer(mDisplay, size, format);
-
- ww->attach(mBuffer);
-}
-
class QWaylandPaintDevice : public QGLPaintDevice
{
public:
diff --git a/src/plugins/platforms/wayland/qwaylandglcontext.cpp b/src/plugins/platforms/wayland/qwaylandglcontext.cpp
new file mode 100644
index 0000000..264da2e
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandglcontext.cpp
@@ -0,0 +1,207 @@
+#define GL_GLEXT_PROTOTYPES
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include "qfontconfigdatabase.h"
+
+#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 <private/qpaintengineex_opengl2_p.h>
+
+#include "qwaylandintegration.h"
+#include "qwaylandwindowsurface.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+
+extern "C" {
+#include <xf86drm.h>
+}
+
+QWaylandGLContext::QWaylandGLContext(QWaylandDisplay *wd, QWaylandWindow *window, const QPlatformWindowFormat &format)
+ : QPlatformGLContext()
+ , mFormat(format)
+ , mDisplay(wd)
+ , mWindow(window)
+ , parentFbo(0)
+ , parentRbo(0)
+{
+}
+
+QWaylandGLContext::~QWaylandGLContext()
+{
+ glDeleteRenderbuffers(1, &parentRbo);
+ glDeleteFramebuffers(1, &parentFbo);
+}
+
+void QWaylandGLContext::makeCurrent()
+{
+ QWaylandDrmBuffer *mBuffer = (QWaylandDrmBuffer *)mWindow->getBuffer();
+ QRect geometry = mWindow->geometry();
+
+ if (!mBuffer)
+ return;
+
+ eglMakeCurrent(mDisplay->eglDisplay(), 0, 0, mBuffer->mContext);
+
+ glViewport(0, 0, geometry.width(), geometry.height());
+ glBindFramebuffer(GL_FRAMEBUFFER, mBuffer->mFbo);
+ glBindTexture(GL_TEXTURE_2D, mBuffer->mTexture);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mBuffer->mImage);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, mBuffer->mTexture, 0);
+}
+
+void QWaylandGLContext::doneCurrent()
+{
+}
+
+/* drawTexture - Draw from a texture into a the current framebuffer
+ * @rect: GL normalized coords for drawing (between -1.0f and 1.0f)
+ * @tex_id: texture source
+ * @texSize: size of source rectangle in Qt coords
+ * @br: bounding rect for drawing
+ */
+static void drawTexture(const QRectF &rect, GLuint tex_id,
+ const QSize &texSize, const QRectF &br)
+{
+ QRectF src = br.isEmpty()
+ ? QRectF(QPointF(), texSize)
+ : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size());
+ qreal width = texSize.width();
+ qreal height = texSize.height();
+
+ src.setLeft(src.left() / width);
+ src.setRight(src.right() / width);
+ src.setTop(src.top() / height);
+ src.setBottom(src.bottom() / height);
+
+ const GLfloat tx1 = src.left();
+ const GLfloat tx2 = src.right();
+ const GLfloat ty1 = src.top();
+ const GLfloat ty2 = src.bottom();
+
+ GLfloat texCoordArray[4*2] = {
+ tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1
+ };
+
+ GLfloat vertexArray[4*2];
+ extern void qt_add_rect_to_array(const QRectF &r, GLfloat *array);
+ qt_add_rect_to_array(rect, vertexArray);
+
+ glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexArray);
+ glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray);
+
+ glBindTexture(GL_TEXTURE_2D, tex_id);
+
+ 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_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
+ glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
+ glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void QWaylandGLContext::swapBuffers()
+{
+ QWaylandWindow *mParentWindow = mWindow->getParentWindow();
+ QWaylandDrmBuffer *mBuffer, *mParentBuffer;
+ QRect geometry = mWindow->geometry(), parentGeometry;
+ QGLShaderProgram *blitProgram;
+ QRectF r;
+ qreal w;
+ qreal h;
+
+ if (!mParentWindow) {
+ qDebug("swap without parent widget?\n");
+ return;
+ }
+
+ if (!mParentWindow->surface()) {
+ qDebug("parent has no surface??\n");
+ return;
+ }
+
+ parentGeometry = mParentWindow->geometry();
+ mBuffer = (QWaylandDrmBuffer *)mWindow->getBuffer();
+ mParentBuffer = (QWaylandDrmBuffer *)mParentWindow->getBuffer();
+
+ glDisable(GL_DEPTH_TEST);
+
+ /* These need to be generated against the src context */
+ if (!parentFbo)
+ glGenFramebuffers(1, &parentFbo);
+ if (!parentRbo)
+ glGenRenderbuffers(1, &parentRbo);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, parentFbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, parentRbo);
+ glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
+ mParentBuffer->mImage);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER, parentRbo);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mBuffer->mImage);
+ glViewport(0, 0, parentGeometry.width(), parentGeometry.height());
+
+ blitProgram = QGLEngineSharedShaders::shadersForContext(QGLContext::currentContext())->blitProgram();
+ blitProgram->bind();
+ blitProgram->setUniformValue("imageTexture", 0);
+
+ /* Transform the target rect to the appropriate coords on the parent */
+ w = parentGeometry.width();
+ h = parentGeometry.height();
+
+ r.setLeft((geometry.left() / w) * 2.0f - 1.0f);
+ if (geometry.right() == (parentGeometry.width() - 1))
+ r.setRight(1.0f);
+ else
+ r.setRight((geometry.right() / w) * 2.0f - 1.0f);
+
+ r.setTop((geometry.top() / h) * 2.0f - 1.0f);
+ if (geometry.bottom() == (parentGeometry.height() - 1))
+ r.setBottom(-1.0f);
+ else
+ r.setBottom((geometry.bottom() / h) * 2.0f - 1.0f);
+
+ drawTexture(r, mBuffer->mTexture, mParentWindow->widget()->size(), parentGeometry);
+
+ wl_surface_damage(mParentWindow->surface(), geometry.left(), geometry.top(),
+ geometry.right(), geometry.bottom());
+ /* restore things to the last valid GL state */
+ makeCurrent();
+ /* hack: avoid tight swapBuffers loops */
+ usleep(20000);
+}
+
+void *QWaylandGLContext::getProcAddress(const QString &string)
+{
+ return (void *) eglGetProcAddress(string.toLatin1().data());
+}
+
+QPlatformGLContext *QWaylandWindow::glContext() const
+{
+ if (!mGLContext) {
+ QWaylandWindow *that = const_cast<QWaylandWindow *>(this);
+ that->mGLContext = new QWaylandGLContext(mDisplay, that, widget()->platformWindowFormat());
+ }
+
+ return mGLContext;
+}
+
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
index b8b7c2f..0109678 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.cpp
+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp
@@ -1,7 +1,3 @@
-#define GL_GLEXT_PROTOTYPES
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
#include "qfontconfigdatabase.h"
#include <QImageReader>
@@ -9,16 +5,11 @@
#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 <private/qpaintengineex_opengl2_p.h>
-
#include "qwaylandintegration.h"
#include "qwaylandwindowsurface.h"
@@ -499,199 +490,6 @@ void QWaylandWindow::configure(uint32_t time, uint32_t edges,
QWindowSystemInterface::handleGeometryChange(widget(), geometry);
}
-class QWaylandGLContext : public QPlatformGLContext {
-public:
- QWaylandGLContext(QWaylandDisplay *wd, QWaylandWindow *window, const QPlatformWindowFormat &format);
- ~QWaylandGLContext();
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString&);
- QPlatformWindowFormat platformWindowFormat() const { return mFormat; }
-
-private:
- QPlatformWindowFormat mFormat;
- QWaylandDisplay *mDisplay;
- QWaylandWindow *mWindow;
- GLuint parentFbo, parentRbo;
-};
-
-QWaylandGLContext::QWaylandGLContext(QWaylandDisplay *wd, QWaylandWindow *window, const QPlatformWindowFormat &format)
- : QPlatformGLContext()
- , mFormat(format)
- , mDisplay(wd)
- , mWindow(window)
- , parentFbo(0)
- , parentRbo(0)
-{
-}
-
-QWaylandGLContext::~QWaylandGLContext()
-{
- glDeleteRenderbuffers(1, &parentRbo);
- glDeleteFramebuffers(1, &parentFbo);
-}
-
-void QWaylandGLContext::makeCurrent()
-{
- QWaylandDrmBuffer *mBuffer = (QWaylandDrmBuffer *)mWindow->getBuffer();
- QRect geometry = mWindow->geometry();
-
- if (!mBuffer)
- return;
-
- eglMakeCurrent(mDisplay->eglDisplay(), 0, 0, mBuffer->mContext);
-
- glViewport(0, 0, geometry.width(), geometry.height());
- glBindFramebuffer(GL_FRAMEBUFFER, mBuffer->mFbo);
- glBindTexture(GL_TEXTURE_2D, mBuffer->mTexture);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mBuffer->mImage);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, mBuffer->mTexture, 0);
-}
-
-void QWaylandGLContext::doneCurrent()
-{
-}
-
-/* drawTexture - Draw from a texture into a the current framebuffer
- * @rect: GL normalized coords for drawing (between -1.0f and 1.0f)
- * @tex_id: texture source
- * @texSize: size of source rectangle in Qt coords
- * @br: bounding rect for drawing
- */
-static void drawTexture(const QRectF &rect, GLuint tex_id,
- const QSize &texSize, const QRectF &br)
-{
- QRectF src = br.isEmpty()
- ? QRectF(QPointF(), texSize)
- : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size());
- qreal width = texSize.width();
- qreal height = texSize.height();
-
- src.setLeft(src.left() / width);
- src.setRight(src.right() / width);
- src.setTop(src.top() / height);
- src.setBottom(src.bottom() / height);
-
- const GLfloat tx1 = src.left();
- const GLfloat tx2 = src.right();
- const GLfloat ty1 = src.top();
- const GLfloat ty2 = src.bottom();
-
- GLfloat texCoordArray[4*2] = {
- tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1
- };
-
- GLfloat vertexArray[4*2];
- extern void qt_add_rect_to_array(const QRectF &r, GLfloat *array);
- qt_add_rect_to_array(rect, vertexArray);
-
- glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexArray);
- glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray);
-
- glBindTexture(GL_TEXTURE_2D, tex_id);
-
- 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_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
-
- glBindTexture(GL_TEXTURE_2D, 0);
-}
-
-void QWaylandGLContext::swapBuffers()
-{
- QWaylandWindow *mParentWindow = mWindow->getParentWindow();
- QWaylandDrmBuffer *mBuffer, *mParentBuffer;
- QRect geometry = mWindow->geometry(), parentGeometry;
- QGLShaderProgram *blitProgram;
- QRectF r;
- qreal w;
- qreal h;
-
- if (!mParentWindow) {
- qDebug("swap without parent widget?\n");
- return;
- }
-
- if (!mParentWindow->surface()) {
- qDebug("parent has no surface??\n");
- return;
- }
-
- parentGeometry = mParentWindow->geometry();
- mBuffer = (QWaylandDrmBuffer *)mWindow->getBuffer();
- mParentBuffer = (QWaylandDrmBuffer *)mParentWindow->getBuffer();
-
- glDisable(GL_DEPTH_TEST);
-
- /* These need to be generated against the src context */
- if (!parentFbo)
- glGenFramebuffers(1, &parentFbo);
- if (!parentRbo)
- glGenRenderbuffers(1, &parentRbo);
-
- glBindFramebuffer(GL_FRAMEBUFFER, parentFbo);
- glBindRenderbuffer(GL_RENDERBUFFER, parentRbo);
- glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
- mParentBuffer->mImage);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_RENDERBUFFER, parentRbo);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mBuffer->mImage);
- glViewport(0, 0, parentGeometry.width(), parentGeometry.height());
-
- blitProgram = QGLEngineSharedShaders::shadersForContext(QGLContext::currentContext())->blitProgram();
- blitProgram->bind();
- blitProgram->setUniformValue("imageTexture", 0);
-
- /* Transform the target rect to the appropriate coords on the parent */
- w = parentGeometry.width();
- h = parentGeometry.height();
-
- r.setLeft((geometry.left() / w) * 2.0f - 1.0f);
- if (geometry.right() == (parentGeometry.width() - 1))
- r.setRight(1.0f);
- else
- r.setRight((geometry.right() / w) * 2.0f - 1.0f);
-
- r.setTop((geometry.top() / h) * 2.0f - 1.0f);
- if (geometry.bottom() == (parentGeometry.height() - 1))
- r.setBottom(-1.0f);
- else
- r.setBottom((geometry.bottom() / h) * 2.0f - 1.0f);
-
- drawTexture(r, mBuffer->mTexture, mParentWindow->widget()->size(), parentGeometry);
-
- wl_surface_damage(mParentWindow->surface(), geometry.left(), geometry.top(),
- geometry.right(), geometry.bottom());
- /* restore things to the last valid GL state */
- makeCurrent();
- /* hack: avoid tight swapBuffers loops */
- usleep(20000);
-}
-
-void *QWaylandGLContext::getProcAddress(const QString &string)
-{
- return (void *) eglGetProcAddress(string.toLatin1().data());
-}
-
-QPlatformGLContext *QWaylandWindow::glContext() const
-{
- if (!mGLContext) {
- QWaylandWindow *that = const_cast<QWaylandWindow *>(this);
- that->mGLContext = new QWaylandGLContext(mDisplay, that, widget()->platformWindowFormat());
- }
-
- return mGLContext;
-}
-
QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWidget *widget, WId winId) const
{
Q_UNUSED(winId);
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h
index e65c141..1c5f834 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.h
+++ b/src/plugins/platforms/wayland/qwaylandintegration.h
@@ -46,8 +46,12 @@
#include <QObject>
#include <QtGui/QPlatformIntegration>
#include <QtGui/QPlatformScreen>
+#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformWindowFormat>
#include "qgl.h"
+#include <private/qpixmapdata_gl_p.h>
+
#include <wayland-client.h>
#include "qwaylandinputdevice.h"
@@ -189,6 +193,23 @@ private:
bool mUseOpenGL;
};
+class QWaylandGLContext : public QPlatformGLContext {
+public:
+ QWaylandGLContext(QWaylandDisplay *wd, QWaylandWindow *window, const QPlatformWindowFormat &format);
+ ~QWaylandGLContext();
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString&);
+ QPlatformWindowFormat platformWindowFormat() const { return mFormat; }
+
+private:
+ QPlatformWindowFormat mFormat;
+ QWaylandDisplay *mDisplay;
+ QWaylandWindow *mWindow;
+ GLuint parentFbo, parentRbo;
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
new file mode 100644
index 0000000..004b93a
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtOpenVG module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qdebug.h>
+#include <QtGui/private/qapplication_p.h>
+
+#include "qwaylandintegration.h"
+#include "qwaylandwindowsurface.h"
+
+#include <wayland-client.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+QT_BEGIN_NAMESPACE
+
+QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
+ const QSize &size, QImage::Format format)
+{
+ int stride = size.width() * 4;
+ int alloc = stride * size.height();
+ char filename[] = "/tmp/wayland-shm-XXXXXX";
+ int fd = mkstemp(filename);
+ if (fd < 0)
+ qWarning("open %s failed: %s", filename, strerror(errno));
+ if (ftruncate(fd, alloc) < 0) {
+ qWarning("ftruncate failed: %s", strerror(errno));
+ close(fd);
+ return;
+ }
+ uchar *data = (uchar *)
+ mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ unlink(filename);
+
+ if (data == (uchar *) MAP_FAILED) {
+ qWarning("mmap /dev/zero failed: %s", strerror(errno));
+ close(fd);
+ return;
+ }
+
+ mImage = QImage(data, size.width(), size.height(), stride, format);
+ mBuffer = display->createShmBuffer(fd, size.width(), size.height(),
+ stride, display->argbVisual());
+ close(fd);
+}
+
+QWaylandShmBuffer::~QWaylandShmBuffer(void)
+{
+ munmap((void *) mImage.constBits(), mImage.byteCount());
+ wl_buffer_destroy(mBuffer);
+}
+
+QWaylandShmWindowSurface::QWaylandShmWindowSurface(QWidget *window,
+ QWaylandDisplay *display)
+ : QWindowSurface(window)
+ , mBuffer(0)
+ , mDisplay(display)
+{
+}
+
+QWaylandShmWindowSurface::~QWaylandShmWindowSurface()
+{
+}
+
+QPaintDevice *QWaylandShmWindowSurface::paintDevice()
+{
+ return &mBuffer->mImage;
+}
+
+void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(offset);
+ QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow();
+ QVector<QRect> rects = region.rects();
+ const QRect *r;
+ int i;
+
+ for (i = 0; i < rects.size(); i++) {
+ r = &rects.at(i);
+ wl_surface_damage(ww->surface(),
+ r->x(), r->y(), r->width(), r->height());
+ }
+}
+
+void QWaylandShmWindowSurface::resize(const QSize &size)
+{
+ QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow();
+ QWindowSurface::resize(size);
+ QImage::Format format = QApplicationPrivate::platformIntegration()->screens().first()->format();
+
+ if (mBuffer != NULL && mBuffer->mImage.size() == size)
+ return;
+
+ if (mBuffer != NULL)
+ delete mBuffer;
+
+ mBuffer = new QWaylandShmBuffer(mDisplay, size, format);
+
+ ww->attach(mBuffer);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro
index ec3f9d3..b0cb98b 100644
--- a/src/plugins/platforms/wayland/wayland.pro
+++ b/src/plugins/platforms/wayland/wayland.pro
@@ -5,8 +5,10 @@ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
SOURCES = main.cpp \
qwaylandintegration.cpp \
- qwaylandwindowsurface.cpp \
- qwaylandinputdevice.cpp
+ qwaylandshmsurface.cpp \
+ qwaylanddrmsurface.cpp \
+ qwaylandinputdevice.cpp \
+ qwaylandglcontext.cpp
HEADERS = qwaylandintegration.h \
qwaylandwindowsurface.h