# comment out the following CONFIG lines to disable DRM
CONFIG += wayland_gl
CONFIG += mesa_egl
+#CONFIG += dri2_xcb
# comment out the following to not use pkg-config in the pri files
CONFIG += use_pkgconfig
--- /dev/null
+This backend requires that you compile the xcb lighthouse plugin with the
+defined: XCB_USE_DRI2. Please see in the xcb.pro file for an easy way to
+enable it.
--- /dev/null
+INCLUDEPATH += $$PWD/../private
+LIBS += -lxcb -lxcb-dri2 -lEGL
+
+SOURCES += \
+ $$PWD/dri2xcbhwintegration.cpp \
+ $$PWD/dri2xcbbuffer.cpp \
+ $$PWD/../../3rdparty/wayland/wayland-drm-protocol.c \
+
+HEADERS += \
+ $$PWD/dri2xcbhwintegration.h \
+ $$PWD/dri2xcbbuffer.h \
+ $$PWD/../../3rdparty/wayland/wayland-drm-server-protocol.h \
--- /dev/null
+#include "dri2xcbbuffer.h"
+
+#include "wlobject.h"
+
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+Dri2XcbBuffer::Dri2XcbBuffer(uint32_t id, uint32_t name, const QSize &size, uint32_t stride, wl_visual *visual, EGLDisplay eglDisplay, Wayland::Compositor *compositor)
+ :m_egl_display(eglDisplay)
+{
+ base()->compositor = compositor->base();
+ base()->visual = visual;
+ base()->height = size.height();
+ base()->width = size.width();
+ base()->attach = 0;
+ base()->damage = 0;
+
+ EGLint attribs[] = {
+ EGL_WIDTH, size.width(),
+ EGL_HEIGHT, size.height(),
+ EGL_DRM_BUFFER_STRIDE_MESA, stride /4,
+ EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
+ EGL_NONE
+ };
+
+ m_image = eglCreateImageKHR(m_egl_display,
+ EGL_NO_CONTEXT,
+ EGL_DRM_BUFFER_MESA,
+ (EGLClientBuffer) name, attribs);
+}
+
+Dri2XcbBuffer::~Dri2XcbBuffer()
+{
+ eglDestroyImageKHR (m_egl_display, m_image);
+}
+
+void dri2XcbBufferDestroy(struct wl_client *client, struct wl_buffer *buffer)
+{
+ delete Wayland::wayland_cast<Dri2XcbBuffer *>(buffer);
+}
+
+EGLImageKHR Dri2XcbBuffer::image() const
+{
+ return m_image;
+}
--- /dev/null
+#ifndef DRI2XCBBUFFER_H
+#define DRI2XCBBUFFER_H
+
+#include "wlobject.h"
+#include "wlcompositor.h"
+
+#include <wayland-server.h>
+
+#include <QtCore/QSize>
+#include <QtCore/QTextStream>
+#include <QtGui/private/qapplication_p.h>
+#include <QtGui/QPlatformNativeInterface>
+
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+class Dri2XcbBuffer : public Wayland::Object<struct wl_buffer>
+{
+public:
+ Dri2XcbBuffer(uint32_t id, uint32_t name, const QSize &size, uint32_t stride,
+ wl_visual *visual, EGLDisplay eglDisplay, Wayland::Compositor *compositor);
+ ~Dri2XcbBuffer();
+
+ EGLImageKHR image() const;
+
+private:
+ EGLImageKHR m_image;
+ EGLDisplay m_egl_display;
+};
+
+void dri2XcbBufferDestroy(struct wl_client *client, struct wl_buffer *buffer);
+
+const static struct wl_buffer_interface dri2_xcb_buffer_interface = {
+ dri2XcbBufferDestroy
+};
+
+#endif // DRI2XCBBUFFER_H
--- /dev/null
+#include "dri2xcbhwintegration.h"
+
+#include "dri2xcbbuffer.h"
+
+#include "wlobject.h"
+#include "wldisplay.h"
+#include "wlcompositor.h"
+
+#include "wayland-server.h"
+#include "wayland-drm-server-protocol.h"
+
+#include <QtCore/QDebug>
+
+#include <xcb/xcb.h>
+#include <xcb/dri2.h>
+
+class DrmObject : public Wayland::Object<struct wl_object>
+{
+public:
+ DrmObject(Wayland::Compositor *compositor, QWidget *topLevelWidget)
+ :m_compositor(compositor)
+ {
+ QPlatformNativeInterface *nativeInterface = QApplicationPrivate::platformIntegration()->nativeInterface();
+ char *deviceName = static_cast<char *>(nativeInterface->nativeResourceForWidget("GraphicsDevice",topLevelWidget));
+ m_device_name = QByteArray(deviceName);
+
+ m_connection = static_cast<xcb_connection_t *>(nativeInterface->nativeResourceForWidget("Connection",topLevelWidget));
+ m_egl_display = static_cast<EGLDisplay>(nativeInterface->nativeResourceForWidget("EglDisplay",topLevelWidget));
+ }
+ QByteArray deviceName()
+ {
+ return m_device_name;
+ }
+
+ void authenticate(struct wl_client *client, uint32_t id)
+ {
+
+ xcb_screen_iterator_t screenIterator = xcb_setup_roots_iterator(xcb_get_setup(m_connection));
+ xcb_dri2_authenticate_cookie_t authenticateCoockie = xcb_dri2_authenticate_unchecked(m_connection,screenIterator.data->root,id);
+ xcb_dri2_authenticate_reply_t *authenticate = xcb_dri2_authenticate_reply(m_connection,authenticateCoockie,NULL);
+
+ if (authenticate && authenticate->authenticated) {
+ wl_client_post_event(client, base(), WL_DRM_AUTHENTICATED);
+ } else {
+ qDebug() << "Failed to authenticate drm :(";
+ }
+
+ delete authenticate;
+ }
+
+ void createBuffer(wl_client *client, uint32_t id, uint32_t name, const QSize &size, uint32_t stride, wl_visual *visual)
+ {
+ Dri2XcbBuffer *buffer = new Dri2XcbBuffer(id,name,size,stride,visual,m_egl_display, m_compositor);
+ Wayland::addClientResource(client,&buffer->base()->resource,id,&wl_buffer_interface,&dri2_xcb_buffer_interface,0);
+ }
+
+private:
+ QByteArray m_device_name;
+ xcb_connection_t *m_connection;
+ xcb_screen_t *m_screen;
+ EGLDisplay m_egl_display;
+ Wayland::Compositor *m_compositor;
+};
+
+void authenticate(struct wl_client *client,
+ struct wl_drm *drm,
+ uint32_t id)
+{
+ reinterpret_cast<DrmObject *>(drm)->authenticate(client,id);
+}
+
+void create_buffer(struct wl_client *client,
+ struct wl_drm *drm,
+ uint32_t id,
+ uint32_t name,
+ int width,
+ int height,
+ uint32_t stride,
+ struct wl_visual *visual)
+{
+ DrmObject *drmObject = reinterpret_cast<DrmObject *>(drm);
+ drmObject->createBuffer(client,id,name,QSize(width,height),stride,visual);
+}
+
+const static struct wl_drm_interface drm_interface = {
+ authenticate,
+ create_buffer
+};
+
+void post_drm_device(struct wl_client *client, struct wl_object *global)
+{
+ DrmObject *drmObject = Wayland::wayland_cast<DrmObject *>(global);
+ qDebug() << drmObject->deviceName().constData();
+ wl_client_post_event(client, global, WL_DRM_DEVICE, drmObject->deviceName().constData());
+}
+
+Dri2XcbHWIntegration::Dri2XcbHWIntegration(WaylandCompositor *compositor)
+ : GraphicsHardwareIntegration(compositor)
+ , m_drm_object(0)
+{
+}
+
+void Dri2XcbHWIntegration::initializeHardware(Wayland::Display *waylandDisplay)
+{
+ //we need a winId now.
+ m_compositor->topLevelWidget()->winId();
+
+
+ m_drm_object = new DrmObject(m_compositor->handle(),m_compositor->topLevelWidget());
+
+ waylandDisplay->addGlobalObject(m_drm_object->base(),&wl_drm_interface,&drm_interface,post_drm_device);
+}
+
+void Dri2XcbHWIntegration::bindBufferToTexture(wl_buffer *buffer, GLuint textureId)
+{
+ Dri2XcbBuffer *dri2Buffer = Wayland::wayland_cast<Dri2XcbBuffer *>(buffer);
+
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, dri2Buffer->image());
+}
--- /dev/null
+#ifndef DRI2XCBHWINTEGRATION_H
+#define DRI2XCBHWINTEGRATION_H
+
+#include "../graphicshardwareintegration.h"
+
+class DrmObject;
+
+class Dri2XcbHWIntegration : public GraphicsHardwareIntegration
+{
+public:
+ Dri2XcbHWIntegration(WaylandCompositor *compositor);
+
+ void initializeHardware(Wayland::Display *waylandDisplay);
+
+ void bindBufferToTexture(wl_buffer *buffer, GLuint textureId);
+
+private:
+ DrmObject *m_drm_object;
+};
+
+#endif // DRI2XCBHWINTEGRATION_H
#include "../mesa_egl/mesaeglintegration.h"
#endif
+#ifdef QT_COMPOSITOR_DRI2_XCB
+#include "../dri2_xcb/dri2xcbhwintegration.h"
+#endif
+
namespace Wayland {
void input_device_attach(struct wl_client *client,
#ifdef QT_COMPOSITOR_MESA_EGL
m_graphics_hw_integration = new MesaEglIntegration(qt_compositor);
#endif
+#ifdef QT_COMPOSITOR_DRI2_XCB
+ m_graphics_hw_integration = new Dri2XcbHWIntegration(qt_compositor);
+#endif
if (wl_compositor_init(base(), &compositor_interface, m_display->handle())) {
fprintf(stderr, "Fatal: Error initializing compositor\n");
DEFINES += QT_COMPOSITOR_MESA_EGL
}
+dri2_xcb {
+include (dri2_xcb/dri2_xcb.pri)
+DEFINES += QT_COMPOSITOR_DRI2_XCB
+}
+
use_pkgconfig {
QMAKE_CXXFLAGS += $$system(pkg-config --cflags glesv2)
#for some reason this is not included in the cflags line