From fe206fb8361bf4bb72332c7cd61d2ac5cea602f9 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 8 Nov 2010 12:24:09 -0800 Subject: [PATCH] Wayland: split GL code into separate files For clarity and to prevent merge conflicts etc. in future. --- ...andwindowsurface.cpp => qwaylanddrmsurface.cpp} | 86 --------- .../platforms/wayland/qwaylandglcontext.cpp | 207 +++++++++++++++++++++ .../platforms/wayland/qwaylandintegration.cpp | 202 -------------------- .../platforms/wayland/qwaylandintegration.h | 21 +++ .../platforms/wayland/qwaylandshmsurface.cpp | 142 ++++++++++++++ src/plugins/platforms/wayland/wayland.pro | 6 +- 6 files changed, 374 insertions(+), 290 deletions(-) rename src/plugins/platforms/wayland/{qwaylandwindowsurface.cpp => qwaylanddrmsurface.cpp} (72%) create mode 100644 src/plugins/platforms/wayland/qwaylandglcontext.cpp create mode 100644 src/plugins/platforms/wayland/qwaylandshmsurface.cpp diff --git a/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp b/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp similarity index 72% rename from src/plugins/platforms/wayland/qwaylandwindowsurface.cpp rename to 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 ®ion, const QPoint &offset) -{ - Q_UNUSED(widget); - Q_UNUSED(offset); - QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow(); - QVector 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 +#include + +#include "qfontconfigdatabase.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include "qwaylandintegration.h" +#include "qwaylandwindowsurface.h" + +#include +#include + +extern "C" { +#include +} + +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(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 -#include - #include "qfontconfigdatabase.h" #include @@ -9,16 +5,11 @@ #include #include -#include #include #include #include -#include -#include -#include - #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(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 #include #include +#include +#include #include "qgl.h" +#include + #include #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 +#include + +#include "qwaylandintegration.h" +#include "qwaylandwindowsurface.h" + +#include +#include +#include +#include +#include + +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 ®ion, const QPoint &offset) +{ + Q_UNUSED(widget); + Q_UNUSED(offset); + QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow(); + QVector 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 -- 2.7.4