summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2010-10-14 19:36:59 (GMT)
committerJørgen Lind <jorgen.lind@nokia.com>2011-01-25 17:54:39 (GMT)
commitd0c99dada04785c95f321495c621cd18eaef8b94 (patch)
treed4be319060c6666bd34422e4d91e8c6154104348
parenta052aafacb81482f694c4c41d166439c30d12eb7 (diff)
downloadQt-d0c99dada04785c95f321495c621cd18eaef8b94.zip
Qt-d0c99dada04785c95f321495c621cd18eaef8b94.tar.gz
Qt-d0c99dada04785c95f321495c621cd18eaef8b94.tar.bz2
Initialize EGL
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp161
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.h10
-rw-r--r--src/plugins/platforms/wayland/wayland.pro2
3 files changed, 142 insertions, 31 deletions
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
index a728f78..5882ad4 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.cpp
+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp
@@ -1,13 +1,18 @@
+#include "qfontconfigdatabase.h"
+
#include <QImageReader>
#include <QWindowSystemInterface>
#include <QPlatformCursor>
-#include "qwaylandintegration.h"
-#include "qwaylandwindowsurface.h"
-#include "qfontconfigdatabase.h"
+
+#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformWindowFormat>
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/QPlatformWindow>
+#include "qwaylandintegration.h"
+#include "qwaylandwindowsurface.h"
+
#include <unistd.h>
#include <fcntl.h>
@@ -182,16 +187,50 @@ void QWaylandDisplay::drmHandleDevice(void *data,
{
Q_UNUSED(drm);
QWaylandDisplay *qwd = (QWaylandDisplay *) data;
+ drm_magic_t magic;
qwd->mDeviceName = strdup(device);
+
+ qwd->mFd = open(qwd->mDeviceName, O_RDWR);
+ if (qwd->mFd < 0) {
+ qWarning("drm open failed: %m");
+ return;
+ }
+
+ if (drmGetMagic(qwd->mFd, &magic)) {
+ qWarning("DRI2: failed to get drm magic");
+ return;
+ }
+
+ wl_drm_authenticate(qwd->mDrm, magic);
}
void QWaylandDisplay::drmHandleAuthenticated(void *data, struct wl_drm *drm)
{
Q_UNUSED(drm);
QWaylandDisplay *qwd = (QWaylandDisplay *) data;
+ EGLint major, minor;
+ const char *extensions;
+
+ qwd->mEglDisplay = eglGetDRMDisplayMESA(qwd->mFd);
+ if (qwd->mEglDisplay == NULL) {
+ qWarning("failed to create display");
+ return;
+ }
+
+ if (!eglInitialize(qwd->mEglDisplay, &major, &minor)) {
+ qWarning("failed to initialize display");
+ qwd->mEglDisplay = NULL;
+ return;
+ }
- qwd->mAuthenticated = true;
+ extensions = eglQueryString(qwd->mEglDisplay, EGL_EXTENSIONS);
+ if (!strstr(extensions, "EGL_KHR_surfaceless_gles2")) {
+ qWarning("EGL_KHR_surfaceless_opengles2 not available");
+ eglTerminate(qwd->mEglDisplay);
+ qwd->mEglDisplay = NULL;
+ return;
+ }
}
const struct wl_drm_listener QWaylandDisplay::drmListener = {
@@ -265,13 +304,24 @@ void QWaylandDisplay::displayHandleGlobal(struct wl_display *display,
}
}
-static void initial_roundtrip(void *data)
+static void roundtripCallback(void *data)
{
bool *done = (bool *) data;
*done = true;
}
+static void forceRoundtrip(struct wl_display *display)
+{
+ bool done;
+
+ wl_display_sync_callback(display, roundtripCallback, &done);
+ wl_display_iterate(display, WL_DISPLAY_WRITABLE);
+ done = false;
+ while (!done)
+ wl_display_iterate(display, WL_DISPLAY_READABLE);
+}
+
static const char socket_name[] = "\0wayland";
void QWaylandDisplay::eventDispatcher(void)
@@ -304,9 +354,6 @@ void QWaylandDisplay::flushRequests(void)
QWaylandDisplay::QWaylandDisplay(void)
: mWriteNotifier(0)
{
- drm_magic_t magic;
- bool done;
-
mDisplay = wl_display_create(socket_name, sizeof socket_name);
if (mDisplay == NULL) {
fprintf(stderr, "failed to create display: %m\n");
@@ -317,28 +364,17 @@ QWaylandDisplay::QWaylandDisplay(void)
QWaylandDisplay::displayHandleGlobal, this);
/* Process connection events. */
- wl_display_sync_callback(mDisplay, initial_roundtrip, &done);
- wl_display_iterate(mDisplay, WL_DISPLAY_WRITABLE);
- done = false;
- while (!done)
- wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
-
- mFd = open(mDeviceName, O_RDWR);
- if (mFd < 0) {
- qWarning("drm open failed: %m\n");
- return;
- }
-
- if (drmGetMagic(mFd, &magic)) {
- qWarning("DRI2: failed to get drm magic");
- return;
- }
+ wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
+ if (!mShm || !mDeviceName)
+ forceRoundtrip(mDisplay);
- /* Wait for authenticated event */
- wl_drm_authenticate(mDrm, magic);
- wl_display_iterate(mDisplay, WL_DISPLAY_WRITABLE);
- while (!mAuthenticated)
- wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
+ /* Force a roundtrip to finish the drm authentication so we
+ * initialize EGL before proceeding */
+ forceRoundtrip(mDisplay);
+ if (mEglDisplay == NULL)
+ qWarning("EGL not available");
+ else
+ qWarning("EGL initialized");
int fd = wl_display_get_fd(mDisplay, sourceUpdate, this);
mReadNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
@@ -417,6 +453,73 @@ void QWaylandWindow::configure(uint32_t time, uint32_t edges,
QWindowSystemInterface::handleGeometryChange(widget(), geometry);
}
+class QWaylandGLContext : public QPlatformGLContext {
+public:
+ QWaylandGLContext(QWaylandDisplay *wd, const QPlatformWindowFormat &format);
+ ~QWaylandGLContext();
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString&);
+ QPlatformWindowFormat platformWindowFormat() const { return mFormat; }
+
+private:
+ EGLContext mContext;
+ QPlatformWindowFormat mFormat;
+ QWaylandDisplay *mDisplay;
+};
+
+QWaylandGLContext::QWaylandGLContext(QWaylandDisplay *wd, const QPlatformWindowFormat &format)
+ : QPlatformGLContext()
+ , mContext(0)
+ , mFormat(format)
+ , mDisplay(wd)
+{
+ EGLDisplay eglDisplay;
+ static const EGLint contextAttribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+ eglDisplay = mDisplay->eglDisplay();
+ mContext = eglCreateContext(eglDisplay, NULL,
+ EGL_NO_CONTEXT, contextAttribs);
+}
+
+QWaylandGLContext::~QWaylandGLContext()
+{
+ if (mContext)
+ eglDestroyContext(mDisplay->eglDisplay(), mContext);
+}
+
+void QWaylandGLContext::makeCurrent()
+{
+}
+
+void QWaylandGLContext::doneCurrent()
+{
+}
+
+void QWaylandGLContext::swapBuffers()
+{
+}
+
+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, 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 9f0b371..81819be 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.h
+++ b/src/plugins/platforms/wayland/qwaylandintegration.h
@@ -50,6 +50,11 @@
#include <wayland-client.h>
#include "qwaylandinputdevice.h"
+#define MESA_EGL_NO_X11_HEADERS
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
QT_BEGIN_NAMESPACE
class QWaylandBuffer;
@@ -67,6 +72,7 @@ public:
uint32_t stride,
struct wl_visual *visual);
struct wl_visual *argbVisual();
+ EGLDisplay eglDisplay() { return mEglDisplay; }
void setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y);
@@ -82,11 +88,11 @@ private:
struct wl_shell *mShell;
char *mDeviceName;
int mFd;
- bool mAuthenticated;
QList<QPlatformScreen *> mScreens;
QList<QWaylandInputDevice *> mInputDevices;
QSocketNotifier *mReadNotifier;
QSocketNotifier *mWriteNotifier;
+ EGLDisplay mEglDisplay;
static void displayHandleGlobal(struct wl_display *display,
uint32_t id,
@@ -143,10 +149,12 @@ public:
void configure(uint32_t time, uint32_t edges,
int32_t x, int32_t y, int32_t width, int32_t height);
WId winId() const;
+ QPlatformGLContext *glContext() const;
private:
struct wl_surface *mSurface;
QWaylandDisplay *mDisplay;
+ QPlatformGLContext *mGLContext;
WId mWindowId;
};
diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro
index f5751e2..7a3d0b9 100644
--- a/src/plugins/platforms/wayland/wayland.pro
+++ b/src/plugins/platforms/wayland/wayland.pro
@@ -12,7 +12,7 @@ HEADERS = qwaylandintegration.h \
qwaylandwindowsurface.h
INCLUDEPATH += /usr/include/libdrm
-LIBS += -lwayland-client -ldrm -lxkbcommon
+LIBS += -lwayland-client -ldrm -lxkbcommon -lEGL -lGLESv2
include (../fontdatabases/fontconfig/fontconfig.pri)