summaryrefslogtreecommitdiffstats
path: root/src/compositor/hardware_integration/xcomposite_egl
diff options
context:
space:
mode:
Diffstat (limited to 'src/compositor/hardware_integration/xcomposite_egl')
-rw-r--r--src/compositor/hardware_integration/xcomposite_egl/xcomposite_egl.pri9
-rw-r--r--src/compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.cpp110
-rw-r--r--src/compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.h26
3 files changed, 145 insertions, 0 deletions
diff --git a/src/compositor/hardware_integration/xcomposite_egl/xcomposite_egl.pri b/src/compositor/hardware_integration/xcomposite_egl/xcomposite_egl.pri
new file mode 100644
index 000000000..f4be9a259
--- /dev/null
+++ b/src/compositor/hardware_integration/xcomposite_egl/xcomposite_egl.pri
@@ -0,0 +1,9 @@
+include (../xcomposite_share/xcomposite_share.pri)
+
+LIBS += -lXcomposite -lX11 -lEGL
+
+HEADERS += \
+ $$PWD/xcompositeeglintegration.h
+
+SOURCES += \
+ $$PWD/xcompositeeglintegration.cpp
diff --git a/src/compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.cpp b/src/compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.cpp
new file mode 100644
index 000000000..dad0c0298
--- /dev/null
+++ b/src/compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.cpp
@@ -0,0 +1,110 @@
+#include "xcompositeeglintegration.h"
+
+#include "waylandobject.h"
+#include "wayland_wrapper/wlcompositor.h"
+#include "wayland-xcomposite-server-protocol.h"
+
+#include <QtWidgets/QApplication>
+#include <QtGui/QPlatformNativeInterface>
+#include <QtGui/QPlatformOpenGLContext>
+
+#include "xcompositebuffer.h"
+#include "xcompositehandler.h"
+#include <X11/extensions/Xcomposite.h>
+
+#include <QtCore/QDebug>
+
+QVector<EGLint> eglbuildSpec()
+{
+ QVector<EGLint> spec;
+
+ spec.append(EGL_SURFACE_TYPE); spec.append(EGL_WINDOW_BIT | EGL_PIXMAP_BIT);
+ spec.append(EGL_RENDERABLE_TYPE); spec.append(EGL_OPENGL_ES2_BIT);
+ spec.append(EGL_BIND_TO_TEXTURE_RGBA); spec.append(EGL_TRUE);
+ spec.append(EGL_ALPHA_SIZE); spec.append(8);
+ spec.append(EGL_NONE);
+ return spec;
+}
+
+
+struct wl_xcomposite_interface XCompositeHandler::xcomposite_interface = {
+ XCompositeHandler::create_buffer
+};
+
+GraphicsHardwareIntegration *GraphicsHardwareIntegration::createGraphicsHardwareIntegration(WaylandCompositor *compositor)
+{
+ return new XCompositeEglIntegration(compositor);
+}
+
+XCompositeEglIntegration::XCompositeEglIntegration(WaylandCompositor *compositor)
+ : GraphicsHardwareIntegration(compositor)
+ , mDisplay(0)
+{
+ QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface();
+ if (nativeInterface) {
+ mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForWindow("Display",m_compositor->window()));
+ if (!mDisplay)
+ qFatal("could not retireve Display from platform integration");
+ mEglDisplay = static_cast<EGLDisplay>(nativeInterface->nativeResourceForWindow("EGLDisplay",m_compositor->window()));
+ if (!mEglDisplay)
+ qFatal("could not retrieve EGLDisplay from plaform integration");
+ } else {
+ qFatal("Platform integration doesn't have native interface");
+ }
+ mScreen = XDefaultScreen(mDisplay);
+}
+
+void XCompositeEglIntegration::initializeHardware(Wayland::Display *waylandDisplay)
+{
+ XCompositeHandler *handler = new XCompositeHandler(m_compositor->handle(),mDisplay,m_compositor->window());
+ wl_display_add_global(waylandDisplay->handle(),&wl_xcomposite_interface,handler,XCompositeHandler::xcomposite_bind_func);
+}
+
+GLuint XCompositeEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *)
+{
+ XCompositeBuffer *compositorBuffer = Wayland::wayland_cast<XCompositeBuffer *>(buffer);
+ Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window());
+
+ QVector<EGLint> eglConfigSpec = eglbuildSpec();
+
+ EGLint matching = 0;
+ EGLConfig config;
+ bool matched = eglChooseConfig(mEglDisplay,eglConfigSpec.constData(),&config,1,&matching);
+ if (!matched || !matching) {
+ qWarning("Could not retrieve a suitable EGL config");
+ return 0;
+ }
+
+ QVector<EGLint> attribList;
+
+ attribList.append(EGL_TEXTURE_FORMAT);
+ attribList.append(EGL_TEXTURE_RGBA);
+ attribList.append(EGL_TEXTURE_TARGET);
+ attribList.append(EGL_TEXTURE_2D);
+ attribList.append(EGL_NONE);
+
+ EGLSurface surface = eglCreatePixmapSurface(mEglDisplay,config,pixmap,attribList.constData());
+ if (surface == EGL_NO_SURFACE) {
+ qDebug() << "Failed to create eglsurface" << pixmap << compositorBuffer->window();
+ }
+
+ compositorBuffer->setInvertedY(false);
+
+ GLuint textureId;
+ glGenTextures(1,&textureId);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ if (!eglBindTexImage(mEglDisplay,surface,EGL_BACK_BUFFER)) {
+ qDebug() << "Failed to bind";
+ }
+
+ // eglDestroySurface(mEglDisplay,surface);
+
+ return textureId;
+}
+
+bool XCompositeEglIntegration::isYInverted(wl_buffer *buffer) const
+{
+ XCompositeBuffer *compositorBuffer = Wayland::wayland_cast<XCompositeBuffer *>(buffer);
+ return compositorBuffer->isYInverted();
+}
diff --git a/src/compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.h b/src/compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.h
new file mode 100644
index 000000000..9e3b16f33
--- /dev/null
+++ b/src/compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.h
@@ -0,0 +1,26 @@
+#ifndef XCOMPOSITEEGLINTEGRATION_H
+#define XCOMPOSITEEGLINTEGRATION_H
+
+#include "hardware_integration/graphicshardwareintegration.h"
+
+#include "xlibinclude.h"
+
+#include <EGL/egl.h>
+
+class XCompositeEglIntegration : public GraphicsHardwareIntegration
+{
+public:
+ XCompositeEglIntegration(WaylandCompositor *compositor);
+
+ void initializeHardware(Wayland::Display *waylandDisplay);
+
+ GLuint createTextureFromBuffer(struct wl_buffer *buffer, QOpenGLContext *context);
+ bool isYInverted(wl_buffer *) const;
+
+private:
+ Display *mDisplay;
+ EGLDisplay mEglDisplay;
+ int mScreen;
+};
+
+#endif // XCOMPOSITEEGLINTEGRATION_H