include ($$PWD/wayland_egl/wayland_egl.pri)
}
+xpixmap_egl {
+ include ($$PWD/xpixmap_egl/xpixmap_egl.pri)
+}
+
#define QWAYLANDGLINTEGRATION_H
class QWaylandWindow;
+class QWaylandDisplay;
class QWidget;
class QWaylandGLIntegration
virtual QWaylandWindow *createEglWindow(QWidget *widget) = 0;
- static QWaylandGLIntegration *createEglIntegration(struct wl_display *waylandDisplay);
+ static QWaylandGLIntegration *createEglIntegration(QWaylandDisplay *waylandDisplay);
};
#endif // QWAYLANDGLINTEGRATION_H
QWindowSurface::resize(size);
window()->platformWindow()->glContext()->makeCurrent();
delete mPaintDevice;
- mPaintDevice = new QGLFramebufferObject(size,QGLFramebufferObject::CombinedDepthStencil,GL_TEXTURE_2D,GL_RGBA);
+ mPaintDevice = new QGLFramebufferObject(size);
}
QT_END_NAMESPACE
#include "qwaylandeglintegration.h"
+#include "gl_integration/qwaylandglintegration.h"
+
#include "qwaylandeglwindow.h"
QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay)
return mNativeEglDisplay;
}
-QWaylandGLIntegration *QWaylandGLIntegration::createEglIntegration(wl_display *waylandDisplay)
+QWaylandGLIntegration *QWaylandGLIntegration::createEglIntegration(QWaylandDisplay *waylandDisplay)
{
- return new QWaylandEglIntegration(waylandDisplay);
+ return new QWaylandEglIntegration(waylandDisplay->wl_display());
}
--- /dev/null
+#include "qwaylandxpixmapeglcontext.h"
+
+#include "../../../eglconvenience/qeglconvenience.h"
+
+#include <QtOpenGL/QGLContext>
+
+#include "qwaylandshmsurface.h"
+
+#include <QtCore/QDebug>
+
+QXPixmapReadbackGLContext::QXPixmapReadbackGLContext(QWaylandXPixmapEglIntegration *eglIntegration, QWaylandXPixmapWindow *window)
+ : mEglIntegration(eglIntegration)
+ , mWindow(window)
+ , mBuffer(0)
+ , mPixmap(0)
+ , mConfig(q_configFromQPlatformWindowFormat(eglIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_PIXMAP_BIT))
+ , mPixmapSurface(EGL_NO_SURFACE)
+{
+ QVector<EGLint> eglContextAttrs;
+ eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
+ eglContextAttrs.append(2);
+ eglContextAttrs.append(EGL_NONE);
+
+ mContext = eglCreateContext(eglIntegration->eglDisplay(),mConfig,0,eglContextAttrs.constData());
+
+ geometryChanged();
+}
+
+QXPixmapReadbackGLContext::~QXPixmapReadbackGLContext()
+{
+ eglDestroyContext(mEglIntegration->eglDisplay(),mContext);
+}
+
+void QXPixmapReadbackGLContext::makeCurrent()
+{
+ QPlatformGLContext::makeCurrent();
+
+ while(mWindow->waitingForFrameSync()) {
+ mEglIntegration->waylandDisplay()->iterate();
+ }
+
+ eglMakeCurrent(mEglIntegration->eglDisplay(),mPixmapSurface,mPixmapSurface,mContext);
+}
+
+void QXPixmapReadbackGLContext::doneCurrent()
+{
+ QPlatformGLContext::doneCurrent();
+ eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
+}
+
+void QXPixmapReadbackGLContext::swapBuffers()
+{
+ eglSwapBuffers(mEglIntegration->eglDisplay(),mPixmapSurface);
+
+ if (QPlatformGLContext::currentContext() != this) {
+ makeCurrent();
+ }
+
+ QSize size = mWindow->geometry().size();
+
+ QImage img(size,QImage::Format_ARGB32);
+ const uchar *constBits = img.bits();
+ void *pixels = const_cast<uchar *>(constBits);
+
+ glReadPixels(0,0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels);
+
+ img = img.mirrored();
+ constBits = img.bits();
+
+ const uchar *constDstBits = mBuffer->image()->bits();
+ uchar *dstBits = const_cast<uchar *>(constDstBits);
+ memcpy(dstBits,constBits,(img.width()*4) * img.height());
+
+
+ mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
+}
+
+void * QXPixmapReadbackGLContext::getProcAddress(const QString &procName)
+{
+ return (void *) eglGetProcAddress(procName.toLatin1().data());
+}
+
+QPlatformWindowFormat QXPixmapReadbackGLContext::platformWindowFormat() const
+{
+ return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
+}
+
+void QXPixmapReadbackGLContext::geometryChanged()
+{
+ while (mWindow->waitingForFrameSync())
+ mEglIntegration->waylandDisplay()->iterate();
+
+ QSize size(mWindow->geometry().size());
+ delete mBuffer;
+ if (mPixmap)
+ XFreePixmap(mEglIntegration->xDisplay(),mPixmap);
+ if (mPixmapSurface != EGL_NO_SURFACE)
+ eglDestroySurface(mEglIntegration->eglDisplay(),mPixmapSurface);
+
+ mBuffer = new QWaylandShmBuffer(mEglIntegration->waylandDisplay(),size,QImage::Format_ARGB32);
+ mWindow->attach(mBuffer);
+ mPixmap = XCreatePixmap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),size.width(),size.height(),mEglIntegration->depth());
+ XSync(mEglIntegration->xDisplay(),False);
+
+ mPixmapSurface = eglCreatePixmapSurface(mEglIntegration->eglDisplay(),mConfig,mPixmap,0);
+ if (mPixmapSurface == EGL_NO_SURFACE) {
+ qDebug() << "Could not make egl surface out of pixmap :(";
+ }
+}
--- /dev/null
+#ifndef QXPIXMAPREADBACKGLCONTEXT_H
+#define QXPIXMAPREADBACKGLCONTEXT_H
+
+#include <QPlatformGLContext>
+#include <QtGui/QWidget>
+
+#include "qwaylandxpixmapeglintegration.h"
+#include "qwaylandxpixmapwindow.h"
+
+class QWaylandShmBuffer;
+
+class QXPixmapReadbackGLContext : public QPlatformGLContext
+{
+public:
+ QXPixmapReadbackGLContext(QWaylandXPixmapEglIntegration *eglIntegration, QWaylandXPixmapWindow *window);
+ ~QXPixmapReadbackGLContext();
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString& procName);
+
+ virtual QPlatformWindowFormat platformWindowFormat() const;
+
+ void geometryChanged();
+
+private:
+ QWaylandXPixmapEglIntegration *mEglIntegration;
+ QWaylandXPixmapWindow *mWindow;
+ QWaylandShmBuffer *mBuffer;
+
+ Pixmap mPixmap;
+
+ EGLConfig mConfig;
+ EGLContext mContext;
+ EGLSurface mPixmapSurface;
+};
+
+#endif // QXPIXMAPREADBACKGLCONTEXT_H
--- /dev/null
+#include "qwaylandxpixmapeglintegration.h"
+
+#include <QDebug>
+
+#include "qwaylandxpixmapwindow.h"
+
+QWaylandXPixmapEglIntegration::QWaylandXPixmapEglIntegration(QWaylandDisplay *display)
+ : QWaylandGLIntegration()
+ , mWaylandDisplay(display)
+{
+ char *display_name = getenv("DISPLAY");
+ mDisplay = XOpenDisplay(display_name);
+ mScreen = XDefaultScreen(mDisplay);
+ mRootWindow = XDefaultRootWindow(mDisplay);
+ XSync(mDisplay, False);
+}
+
+QWaylandXPixmapEglIntegration::~QWaylandXPixmapEglIntegration()
+{
+ XCloseDisplay(mDisplay);
+}
+
+
+QWaylandGLIntegration *QWaylandGLIntegration::createEglIntegration(QWaylandDisplay *waylandDisplay)
+{
+ return new QWaylandXPixmapEglIntegration(waylandDisplay);
+}
+
+void QWaylandXPixmapEglIntegration::initialize()
+{
+ eglBindAPI(EGL_OPENGL_ES_API);
+ mEglDisplay = eglGetDisplay(mDisplay);
+ EGLint major, minor;
+ EGLBoolean initialized = eglInitialize(mEglDisplay,&major,&minor);
+ if (initialized) {
+ qDebug() << "EGL initialized successfully" << major << "," << minor;
+ } else {
+ qDebug() << "EGL could not initialized. All EGL and GL operations will fail";
+ }
+}
+
+QWaylandWindow * QWaylandXPixmapEglIntegration::createEglWindow(QWidget *widget)
+{
+ return new QWaylandXPixmapWindow(widget,this);
+}
+
+EGLDisplay QWaylandXPixmapEglIntegration::eglDisplay()
+{
+ return mEglDisplay;
+}
+
+Window QWaylandXPixmapEglIntegration::rootWindow() const
+{
+ return mRootWindow;
+}
+
+int QWaylandXPixmapEglIntegration::depth() const
+{
+ return XDefaultDepth(mDisplay,mScreen);
+}
+
+Display * QWaylandXPixmapEglIntegration::xDisplay() const
+{
+ return mDisplay;
+}
+
+QWaylandDisplay * QWaylandXPixmapEglIntegration::waylandDisplay() const
+{
+ return mWaylandDisplay;
+}
--- /dev/null
+#ifndef QWAYLANDXPIXMAPEGLINTEGRATION_H
+#define QWAYLANDXPIXMAPEGLINTEGRATION_H
+
+#include "gl_integration/qwaylandglintegration.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDataStream>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+#include <QtGui/QWidget>
+
+#include <X11/Xlib.h>
+
+#include <EGL/egl.h>
+//#include <EGL
+
+class QWaylandXPixmapEglIntegration : public QWaylandGLIntegration
+{
+public:
+ QWaylandXPixmapEglIntegration(QWaylandDisplay *display);
+ ~QWaylandXPixmapEglIntegration();
+
+ void initialize();
+ QWaylandWindow *createEglWindow(QWidget *widget);
+
+ QWaylandDisplay *waylandDisplay() const;
+ Display *xDisplay() const;
+ Window rootWindow() const;
+ int depth() const;
+
+ EGLDisplay eglDisplay();
+
+private:
+ QWaylandDisplay *mWaylandDisplay;
+ Display *mDisplay;
+ int mScreen;
+ Window mRootWindow;
+ EGLDisplay mEglDisplay;
+
+};
+
+#endif // QWAYLANDXPIXMAPEGLINTEGRATION_H
--- /dev/null
+#include "qwaylandxpixmapwindow.h"
+
+#include "qwaylandxpixmapeglcontext.h"
+QWaylandXPixmapWindow::QWaylandXPixmapWindow(QWidget *window, QWaylandXPixmapEglIntegration *eglIntegration)
+ : QWaylandShmWindow(window)
+ , mEglIntegration(eglIntegration)
+ , mContext(0)
+{
+}
+
+QWaylandWindow::WindowType QWaylandXPixmapWindow::windowType() const
+{
+ //We'r lying, maybe we should add a type, but for now it will do
+ //since this is primarly used by the windowsurface.
+ return QWaylandWindow::Egl;
+}
+
+QPlatformGLContext *QWaylandXPixmapWindow::glContext() const
+{
+ if (!mContext) {
+ QWaylandXPixmapWindow *that = const_cast<QWaylandXPixmapWindow *>(this);
+ that->mContext = new QXPixmapReadbackGLContext(mEglIntegration,that);
+ }
+ return mContext;
+}
+
+void QWaylandXPixmapWindow::newSurfaceCreated()
+{
+}
+
+void QWaylandXPixmapWindow::setGeometry(const QRect &rect)
+{
+ QPlatformWindow::setGeometry(rect);
+
+ if (mContext)
+ mContext->geometryChanged();
+}
+
--- /dev/null
+#ifndef QWAYLANDXPIXMAPWINDOW_H
+#define QWAYLANDXPIXMAPWINDOW_H
+
+#include "qwaylandshmwindow.h"
+#include "qwaylandxpixmapeglintegration.h"
+
+class QXPixmapReadbackGLContext;
+
+class QWaylandXPixmapWindow : public QWaylandShmWindow
+{
+public:
+ QWaylandXPixmapWindow(QWidget *window, QWaylandXPixmapEglIntegration *eglIntegration);
+
+ WindowType windowType() const;
+
+ QPlatformGLContext *glContext() const;
+
+ void setGeometry(const QRect &rect);
+protected:
+ void newSurfaceCreated();
+
+private:
+ QWaylandXPixmapEglIntegration *mEglIntegration;
+ QXPixmapReadbackGLContext *mContext;
+};
+
+#endif // QWAYLANDXPIXMAPWINDOW_H
--- /dev/null
+
+LIBS += -lX11 -lXext -lEGL
+
+HEADERS += \
+ gl_integration/xpixmap_egl/qwaylandxpixmapeglintegration.h \
+ gl_integration/xpixmap_egl/qwaylandxpixmapwindow.h \
+ gl_integration/xpixmap_egl/qwaylandxpixmapeglcontext.h \
+ $$PWD/../../../eglconvenience/qeglconvenience.h
+
+SOURCES += \
+ gl_integration/xpixmap_egl/qwaylandxpixmapeglintegration.cpp \
+ gl_integration/xpixmap_egl/qwaylandxpixmapwindow.cpp \
+ gl_integration/xpixmap_egl/qwaylandxpixmapeglcontext.cpp \
+ $$PWD/../../../eglconvenience/qeglconvenience.cpp
QWaylandDisplay::displayHandleGlobal, this);
#ifdef QT_WAYLAND_GL_SUPPORT
- mEglIntegration = QWaylandGLIntegration::createEglIntegration(mDisplay);
+ mEglIntegration = QWaylandGLIntegration::createEglIntegration(this);
#endif
readEvents();
void iterate();
+ struct wl_display *wl_display() const { return mDisplay; }
public slots:
void readEvents(void);
void flushRequests(void);
void beginPaint(const QRegion &);
private:
- static void frameCallback(void *data, uint32_t time);\
-
QWaylandShmBuffer *mBuffer;
QWaylandDisplay *mDisplay;
- bool mWaitingForFrameSync;
};
QT_END_NAMESPACE
#include "qwaylandbuffer.h"
+#include <QtCore/QVector>
+
QWaylandShmWindow::QWaylandShmWindow(QWidget *widget)
: QWaylandWindow(widget)
, mBuffer(0)
#define QWAYLANDSHMWINDOW_H
#include "qwaylandwindow.h"
+#include <QtGui/QRegion>
class QWaylandShmWindow : public QWaylandWindow
{
QT += opengl
CONFIG += wayland_egl
+# CONFIG += xpixmap_egl
include ($$PWD/gl_integration/gl_integration.pri)
}