#include <fcntl.h>
#include <stdio.h>
-extern "C" {
-#include <xf86drm.h>
-}
+#include <wayland-egl.h>
struct wl_surface *QWaylandDisplay::createSurface()
{
return wl_shm_create_buffer(mShm, fd, width, height, stride, visual);
}
-struct wl_buffer *QWaylandDisplay::createDrmBuffer(int name,
- int width, int height,
- uint32_t stride,
- struct wl_visual *visual)
-{
- return wl_drm_create_buffer(mDrm, name, width, height, stride, visual);
-}
-
struct wl_visual *QWaylandDisplay::rgbVisual()
{
return wl_display_get_rgb_visual(mDisplay);
return wl_display_get_premultiplied_argb_visual(mDisplay);
}
-void QWaylandDisplay::drmHandleDevice(void *data,
- struct wl_drm *drm, const char *device)
+struct wl_egl_display *QWaylandDisplay::nativeDisplay()
{
- 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);
+ return mNativeEglDisplay;
}
-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;
- }
-
- 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 = {
- QWaylandDisplay::drmHandleDevice,
- QWaylandDisplay::drmHandleAuthenticated
-};
-
void QWaylandDisplay::shellHandleConfigure(void *data, struct wl_shell *shell,
uint32_t time, uint32_t edges,
struct wl_surface *surface,
if (strcmp(interface, "compositor") == 0) {
qwd->mCompositor = wl_compositor_create(display, id);
- } else if (strcmp(interface, "drm") == 0) {
- qwd->mDrm = wl_drm_create(display, id);
- wl_drm_add_listener(qwd->mDrm, &drmListener, qwd);
} else if (strcmp(interface, "shm") == 0) {
qwd->mShm = wl_shm_create(display, id);
} else if (strcmp(interface, "shell") == 0) {
}
}
-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 = NULL;
-
void QWaylandDisplay::eventDispatcher(void)
{
wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
QWaylandDisplay::QWaylandDisplay(void)
: mWriteNotifier(0)
{
- mDisplay = wl_display_connect(socket_name);
+ EGLint major, minor;
+
+ mDisplay = wl_display_connect(NULL);
if (mDisplay == NULL) {
fprintf(stderr, "failed to create display: %m\n");
return;
wl_display_add_global_listener(mDisplay,
QWaylandDisplay::displayHandleGlobal, this);
- /* Process connection events. */
- wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
- if (!mShm || !mDeviceName)
- forceRoundtrip(mDisplay);
+ mNativeEglDisplay = wl_egl_native_display_create(mDisplay);
- /* Force a roundtrip to finish the drm authentication so we
- * initialize EGL before proceeding */
- forceRoundtrip(mDisplay);
- if (mEglDisplay == NULL)
- qDebug("EGL not available");
- else
- qDebug("EGL initialized");
+ mEglDisplay = eglGetDisplay(mNativeEglDisplay);
+ if (mEglDisplay == NULL) {
+ qWarning("EGL not available");
+ } else {
+ if (!eglInitialize(mEglDisplay, &major, &minor)) {
+ qWarning("failed to initialize EGL display");
+ return;
+ }
+ }
int fd = wl_display_get_fd(mDisplay, sourceUpdate, this);
mReadNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
QWaylandDisplay::~QWaylandDisplay(void)
{
close(mFd);
+ eglTerminate(mEglDisplay);
wl_display_destroy(mDisplay);
}
struct wl_buffer *createShmBuffer(int fd, int width, int height,
uint32_t stride,
struct wl_visual *visual);
- struct wl_buffer *createDrmBuffer(int name, int width, int height,
- uint32_t stride,
- struct wl_visual *visual);
struct wl_visual *rgbVisual();
struct wl_visual *argbVisual();
struct wl_visual *argbPremultipliedVisual();
+ struct wl_egl_display *nativeDisplay();
EGLDisplay eglDisplay() { return mEglDisplay; }
void setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y);
private:
struct wl_display *mDisplay;
struct wl_compositor *mCompositor;
- struct wl_drm *mDrm;
struct wl_shm *mShm;
struct wl_shell *mShell;
char *mDeviceName;
QSocketNotifier *mReadNotifier;
QSocketNotifier *mWriteNotifier;
EGLDisplay mEglDisplay;
+ struct wl_egl_display *mNativeEglDisplay;
static void displayHandleGlobal(struct wl_display *display,
uint32_t id,
const char *interface,
uint32_t version, void *data);
- static void drmHandleDevice(void *data,
- struct wl_drm *drm, const char *device);
- static void drmHandleAuthenticated(void *data, struct wl_drm *drm);
-
static void outputHandleGeometry(void *data,
struct wl_output *output,
int32_t x, int32_t y,
static int sourceUpdate(uint32_t mask, void *data);
- static const struct wl_drm_listener drmListener;
static const struct wl_output_listener outputListener;
static const struct wl_shell_listener shellListener;
};
#include <QtGui/private/qpaintengine_p.h>
#include <wayland-client.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/mman.h>
+#include <wayland-egl.h>
QT_BEGIN_NAMESPACE
, mSize(size)
{
struct wl_visual *visual;
- EGLint name, stride;
- EGLint imageAttribs[] = {
- EGL_WIDTH, size.width(),
- EGL_HEIGHT, size.height(),
- EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
- EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA,
- EGL_NONE
- };
-
- mImage = eglCreateDRMImageMESA(mDisplay->eglDisplay(), imageAttribs);
-
- glGenTextures(1, &mTexture);
- glBindTexture(GL_TEXTURE_2D, mTexture);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
-
- eglExportDRMImageMESA(mDisplay->eglDisplay(),
- mImage, &name, NULL, &stride);
switch (format) {
case QImage::Format_ARGB32:
break;
}
- mBuffer = display->createDrmBuffer(name, size.width(), size.height(),
- stride, visual);
+ mPixmap = wl_egl_native_pixmap_create(display->nativeDisplay(),
+ size.width(), size.height(),
+ visual, 0);
+
+ mImage = eglCreateImageKHR(display->eglDisplay(),
+ NULL, EGL_NATIVE_PIXMAP_KHR,
+ (EGLClientBuffer) mPixmap, NULL);
+
+ glGenTextures(1, &mTexture);
+ qDebug() << "generating mTexture" << mTexture;
+ glBindTexture(GL_TEXTURE_2D, mTexture);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
+
+ mBuffer = wl_egl_native_pixmap_create_buffer(display->nativeDisplay(),
+ mPixmap);
}
QWaylandDrmBuffer::~QWaylandDrmBuffer(void)
{
glDeleteTextures(1, &mTexture);
eglDestroyImageKHR(mDisplay->eglDisplay(), mImage);
+ wl_egl_native_pixmap_destroy(mPixmap);
wl_buffer_destroy(mBuffer);
}