From 2868281c3b36c0a314a66f56ee7f0c627fda08ba Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=B8rgen=20Lind?= Date: Mon, 7 Mar 2011 17:17:30 +0100 Subject: [PATCH] Initial glsupport in qtcomp. It can now draw simple_client "cant move it around though :D" This is just to get something on screen. Now we have to start doing this "proper". Trying to abstract some things out etc :) --- examples/qwidget-compositor/main.cpp | 35 +++++- examples/qwidget-compositor/qt-compositor.pro | 9 +- src/qt-compositor/qt-compositor.pri | 11 +- src/qt-compositor/qtcompositor.cpp | 26 +++- src/qt-compositor/qtcompositor.h | 20 ++- src/qt-compositor/wlbuffer.cpp | 73 ----------- src/qt-compositor/wlbuffer.h | 73 ----------- src/qt-compositor/wlcompositor.cpp | 32 ++++- src/qt-compositor/wlcompositor.h | 15 ++- src/qt-compositor/wldrmbuffer.cpp | 170 -------------------------- src/qt-compositor/wldrmbuffer.h | 117 ------------------ src/qt-compositor/wlshmbuffer.cpp | 12 +- src/qt-compositor/wlshmbuffer.h | 13 +- src/qt-compositor/wlsurface.cpp | 159 +++++++++++++++++++++--- src/qt-compositor/wlsurface.h | 43 +++++-- 15 files changed, 310 insertions(+), 498 deletions(-) delete mode 100644 src/qt-compositor/wlbuffer.cpp delete mode 100644 src/qt-compositor/wlbuffer.h delete mode 100644 src/qt-compositor/wldrmbuffer.cpp delete mode 100644 src/qt-compositor/wldrmbuffer.h diff --git a/examples/qwidget-compositor/main.cpp b/examples/qwidget-compositor/main.cpp index 854e32d..ca374cc 100644 --- a/examples/qwidget-compositor/main.cpp +++ b/examples/qwidget-compositor/main.cpp @@ -39,18 +39,29 @@ ****************************************************************************/ #include "qtcompositor.h" + #include #include #include #include #include +#ifdef QT_COMPOSITOR_WAYLAND_EGL +#include +#include +#include +#endif + #include +#ifdef QT_COMPOSITOR_WAYLAND_EGL +class QWidgetCompositor : public QGLWidget, public WaylandCompositor +#else class QWidgetCompositor : public QWidget, public WaylandCompositor +#endif { public: - QWidgetCompositor() : WaylandCompositor(), m_dragging(false) { + QWidgetCompositor() : WaylandCompositor(this), m_dragging(false) { setMouseTracking(true); m_background = QImage(QLatin1String("background.jpg")); //make sure we get the window id and create the glcontext @@ -108,11 +119,29 @@ protected: p.drawPixmap(rect(), m_backgroundScaled); for (int i = 0; i < m_surfaces.size(); ++i) { - QImage img = image(m_surfaces.at(i).first); - p.drawImage(m_surfaces.at(i).second.topLeft(), img); + if (hasImage(m_surfaces.at(i).first)) { + QImage img = image(m_surfaces.at(i).first); + p.drawImage(m_surfaces.at(i).second.topLeft(), img); + } +#ifdef QT_COMPOSITOR_WAYLAND_EGL + else { + QPlatformGLContext *glcontext = platformWindow()->glContext(); + if (glcontext) { + QGLContext *context = QGLContext::fromPlatformGLContext(glcontext); + context->makeCurrent(); + context->drawTexture(m_surfaces.at(i).second,textureId(m_surfaces.at(i).first)); + } + } +#endif //QT_COMPOSITOR_WAYLAND_EGL } frameFinished(); + +#ifdef QT_COMPOSITOR_WAYLAND_EGL + //jl:FIX FIX FIX:) + update(); + glFinish(); +#endif } void resizeEvent(QResizeEvent *) diff --git a/examples/qwidget-compositor/qt-compositor.pro b/examples/qwidget-compositor/qt-compositor.pro index 0d32e75..b4bb57c 100644 --- a/examples/qwidget-compositor/qt-compositor.pro +++ b/examples/qwidget-compositor/qt-compositor.pro @@ -5,7 +5,11 @@ INCLUDEPATH += . INCLUDEPATH += ../../src/qt-compositor/ # comment out the following line to disable DRM -CONFIG += wayland_drm +CONFIG += wayland_egl + +wayland_egl { + QT += opengl +} DESTDIR=$$PWD/../../bin/ @@ -13,6 +17,9 @@ LIBS += -L ../../lib include (../../src/qt-compositor/qt-compositor.pri) +LIBS += -L/home/jlind/install/lib +INCLUDEPATH += /home/jlind/install/include + # Input SOURCES += main.cpp diff --git a/src/qt-compositor/qt-compositor.pri b/src/qt-compositor/qt-compositor.pri index facddda..41209e8 100644 --- a/src/qt-compositor/qt-compositor.pri +++ b/src/qt-compositor/qt-compositor.pri @@ -9,24 +9,19 @@ SOURCES += $$PWD/qtcompositor.cpp \ $$PWD/wlsurface.cpp \ $$PWD/wloutput.cpp \ $$PWD/wldisplay.cpp \ - $$PWD/wlbuffer.cpp \ $$PWD/wlshmbuffer.cpp HEADERS += $$PWD/qtcompositor.h \ $$PWD/wlcompositor.h \ $$PWD/wlsurface.h \ $$PWD/wloutput.h \ - $$PWD/wlbuffer.h \ $$PWD/wlshmbuffer.h \ $$PWD/wldisplay.h \ $$PWD/wlobject.h INCLUDEPATH += $$PWD/../3rdparty/wayland -wayland_drm { - SOURCES += $$PWD/wldrmbuffer.cpp - HEADERS += $$PWD/wldrmbuffer.h - - DEFINES += QT_WAYLAND_DRM - LIBS += -lxcb-dri2 -lEGL +wayland_egl { + LIBS += -lEGL -lGLESv2 + DEFINES += QT_COMPOSITOR_WAYLAND_EGL } diff --git a/src/qt-compositor/qtcompositor.cpp b/src/qt-compositor/qtcompositor.cpp index 647d8e5..e804e8a 100644 --- a/src/qt-compositor/qtcompositor.cpp +++ b/src/qt-compositor/qtcompositor.cpp @@ -41,9 +41,11 @@ #include "qtcompositor.h" #include "wlcompositor.h" +#include "wlsurface.h" -WaylandCompositor::WaylandCompositor() +WaylandCompositor::WaylandCompositor(QWidget *topLevelWidget) : m_compositor(new Wayland::Compositor(this)) + , m_toplevel_widget(topLevelWidget) { } @@ -97,8 +99,30 @@ uint WaylandCompositor::directRenderWinId() const return 0; } +bool WaylandCompositor::hasImage(uint winId) const +{ + return m_compositor->getSurfaceFromWinId(winId)->hasImage(); +} + const QImage WaylandCompositor::image(uint winId) const { return m_compositor->image(winId); } +#ifdef QT_COMPOSITOR_WAYLAND_EGL +GLuint WaylandCompositor::textureId(uint winId) const +{ + return m_compositor->getSurfaceFromWinId(winId)->textureId(); +} + +bool WaylandCompositor::hasTexture(uint winId) const +{ + return m_compositor->getSurfaceFromWinId(winId)->hasTexture(); +} +#endif + +QWidget * WaylandCompositor::topLevelWidget() const +{ + return m_toplevel_widget; +} + diff --git a/src/qt-compositor/qtcompositor.h b/src/qt-compositor/qtcompositor.h index 582b315..d69e5a3 100644 --- a/src/qt-compositor/qtcompositor.h +++ b/src/qt-compositor/qtcompositor.h @@ -45,6 +45,14 @@ #include #include +#ifdef QT_COMPOSITOR_WAYLAND_EGL +#define GL_GLEXT_PROTOTYPES +#include +#include +#endif + +class QWidget; + namespace Wayland { class Compositor; @@ -53,7 +61,7 @@ namespace Wayland class WaylandCompositor { public: - WaylandCompositor(); + WaylandCompositor(QWidget *topLevelWidget = 0); virtual ~WaylandCompositor(); void sendMousePressEvent(uint winId, int x, int y, Qt::MouseButton button); @@ -70,8 +78,16 @@ public: void setDirectRenderWinId(uint winId); uint directRenderWinId() const; + QWidget *topLevelWidget()const; + + bool hasImage(uint winId) const; const QImage image(uint winId) const; +#ifdef QT_COMPOSITOR_WAYLAND_EGL + bool hasTexture(uint winId) const; + GLuint textureId(uint winId) const; +#endif + virtual void surfaceCreated(uint winId) = 0; virtual void surfaceDestroyed(uint winId) = 0; virtual void surfaceMapped(uint winId, const QRect &rect) = 0; @@ -79,6 +95,8 @@ public: private: Wayland::Compositor *m_compositor; + QWidget *m_toplevel_widget; + }; #endif // QTCOMP_H diff --git a/src/qt-compositor/wlbuffer.cpp b/src/qt-compositor/wlbuffer.cpp deleted file mode 100644 index 5b60654..0000000 --- a/src/qt-compositor/wlbuffer.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** This file is part of QtCompositor** -** -** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** -** Contact: Nokia Corporation qt-info@nokia.com -** -** You may use this file under the terms of the BSD license as follows: -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** -** Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** -** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the -** names of its contributors may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -****************************************************************************/ - -#include "wlbuffer.h" - -#include "wlcompositor.h" - -namespace Wayland { - -void attachBuffer(struct wl_buffer *buffer, struct wl_surface *surface){ - wayland_cast(buffer)->attach(wayland_cast(surface)); -} - -void damageBuffer(struct wl_buffer *buffer, - struct wl_surface *surface, - int32_t x, int32_t y, int32_t width, int32_t height) -{ - wayland_cast(buffer)->damage(wayland_cast(surface), QRect(x, y, width, height)); -} - -Buffer::Buffer(Compositor *compositor, struct wl_visual *visual, const QSize &size) -{ - base()->visual = visual; - base()->compositor = compositor->base(); - base()->width = size.width(); - base()->height = size.height(); - base()->attach = attachBuffer; - base()->damage = damageBuffer; -} - -QSize Buffer::size() const -{ - return QSize(base()->width,base()->height); -} - -} diff --git a/src/qt-compositor/wlbuffer.h b/src/qt-compositor/wlbuffer.h deleted file mode 100644 index ee2ef33..0000000 --- a/src/qt-compositor/wlbuffer.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** This file is part of QtCompositor** -** -** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** -** Contact: Nokia Corporation qt-info@nokia.com -** -** You may use this file under the terms of the BSD license as follows: -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** -** Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** -** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the -** names of its contributors may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -****************************************************************************/ - -#ifndef WLBUFFER_H -#define WLBUFFER_H - -#include "wlobject.h" -#include - -#include -#include - -namespace Wayland { - -class Compositor; -class Surface; -class Buffer : public Object -{ -public: - enum BufferType { - Shm, - Egl - }; - - Buffer(Compositor *compositor, struct wl_visual *visual, const QSize &size); - - QSize size()const; - virtual BufferType type() const = 0; - - virtual void attach(Surface *surface) =0; - virtual void damage(Surface *surface, const QRect &rect) =0; - -}; - -} -#endif // WLBUFFER_H diff --git a/src/qt-compositor/wlcompositor.cpp b/src/qt-compositor/wlcompositor.cpp index 6de7ea0..2cea1b6 100644 --- a/src/qt-compositor/wlcompositor.cpp +++ b/src/qt-compositor/wlcompositor.cpp @@ -43,6 +43,7 @@ #include "wlobject.h" #include "wldisplay.h" #include "wlshmbuffer.h" +#include "wlsurface.h" #include "qtcompositor.h" #include @@ -66,6 +67,13 @@ #include +#ifdef QT_COMPOSITOR_WAYLAND_EGL +#include +#include +#define EGL_EGLEXT_PROTOTYPES +#include +#include +#endif namespace Wayland { @@ -165,9 +173,6 @@ const static struct wl_shell_interface shell_interface = { Compositor::Compositor(WaylandCompositor *qt_compositor) : m_display(new Display) , m_shm(this) -#ifdef QT_WAYLAND_DRM - , m_drm(this) -#endif , m_current_frame(0) , m_last_queued_buf(-1) , m_qt_compositor(qt_compositor) @@ -182,9 +187,6 @@ Compositor::Compositor(WaylandCompositor *qt_compositor) m_display->addGlobalObject(m_output.base(), &wl_output_interface, 0, output_post_geometry); m_display->addGlobalObject(&m_shell, &wl_shell_interface, &shell_interface, 0); -#ifdef QT_WAYLAND_DRM - m_display->addGlobalObject(m_drm.base(), &wl_drm_interface, &drm_interface, post_drm_device); -#endif m_display->addGlobalObject(m_shm.base(), &wl_shm_interface, &shm_interface, 0); wl_input_device_init(&m_input, base()); @@ -195,6 +197,18 @@ Compositor::Compositor(WaylandCompositor *qt_compositor) exit(EXIT_FAILURE); } +#ifdef QT_COMPOSITOR_WAYLAND_EGL + QPlatformNativeInterface *nativeInterface = QApplicationPrivate::platformIntegration()->nativeInterface(); + if (nativeInterface) { + EGLDisplay m_egl_display = nativeInterface->nativeResourceForWidget("EglDisplay",0); + if (m_egl_display) { + eglBindWaylandDisplayWL(m_egl_display,m_display->handle()); + } else { + fprintf(stderr, "Failed to initialize egl display"); + } + } +#endif //QT_COMPOSITOR_WAYLAND_EGL + m_loop = wl_display_get_event_loop(m_display->handle()); int fd = wl_event_loop_get_fd(m_loop); @@ -367,4 +381,10 @@ void Compositor::sendKeyReleaseEvent(uint winId, uint code) } } +QWidget * Compositor::topLevelWidget() const +{ + return m_qt_compositor->topLevelWidget(); } + +} + diff --git a/src/qt-compositor/wlcompositor.h b/src/qt-compositor/wlcompositor.h index f87137f..dba18c0 100644 --- a/src/qt-compositor/wlcompositor.h +++ b/src/qt-compositor/wlcompositor.h @@ -42,19 +42,18 @@ #define WL_COMPOSITOR_H #include "wloutput.h" -#include "wlsurface.h" #include "wldisplay.h" #include "wlshmbuffer.h" -#ifdef QT_WAYLAND_DRM -# include "wldrmbuffer.h" -#endif #include class WaylandCompositor; +class QWidget; namespace Wayland { +class Surface; + class Compositor : public QObject, public Object { Q_OBJECT @@ -70,6 +69,7 @@ public: struct wl_client *getClientFromWinId(uint winId) const; QImage image(uint winId) const; + const struct wl_input_device *inputDevice() const { return &m_input; } struct wl_input_device *inputDevice() { return &m_input; } @@ -88,6 +88,8 @@ public: uint currentTimeMsecs() const; + QWidget *topLevelWidget() const; + private slots: void processWaylandEvents(); @@ -102,11 +104,8 @@ private: struct wl_object m_shell; - /* shm/drm-Handler */ + /* shm/*/ ShmHandler m_shm; -#ifdef QT_WAYLAND_DRM - DrmHandler m_drm; -#endif QList m_surfaces; /* Render state */ diff --git a/src/qt-compositor/wldrmbuffer.cpp b/src/qt-compositor/wldrmbuffer.cpp deleted file mode 100644 index 9d736d5..0000000 --- a/src/qt-compositor/wldrmbuffer.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/**************************************************************************** -** -** This file is part of QtCompositor** -** -** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** -** Contact: Nokia Corporation qt-info@nokia.com -** -** You may use this file under the terms of the BSD license as follows: -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** -** Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** -** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the -** names of its contributors may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -****************************************************************************/ - -#include "wldrmbuffer.h" - -#include "wlcompositor.h" - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#define GL_GLEXT_PROTOTYPES -#include -#include - -extern "C" { -#include -} - -namespace Wayland { - -DrmBuffer::DrmBuffer(EGLImageKHR image, Compositor *compositor, struct wl_visual *visual, const QSize &size) - : Buffer(compositor,visual,size) - , m_image(image) -{ - -} - -void DrmBuffer::attach(Surface *surface) -{ - Q_UNUSED(surface); - printf("drmBuffer::attach\n"); -} - -void DrmBuffer::damage(Surface *surface, const QRect &rect) -{ - Q_UNUSED(surface); - Q_UNUSED(rect); - printf("drmBuffer::damage\n"); - -} - - -void authenticate(struct wl_client *client, - struct wl_drm *drm, - uint32_t id) -{ - qDebug() << "authenticate"; - Q_UNUSED(client); - wl_object *object = (wl_object*)drm; - DrmHandler *handler = wayland_cast(object); - handler->authenticate(id); - wl_client_post_event(client, object, WL_DRM_AUTHENTICATED); -} - -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) -{ - wl_object *object = (wl_object*)drm; - DrmHandler *handler = wayland_cast(object); - handler->createBuffer(client,id,name,QSize(width,height),stride,visual); -} - -void post_drm_device(struct wl_client *client, struct wl_object *global) -{ - //Lighthouse apis needs to bleed this, think I need to create a native interface abstraction - wl_client_post_event(client, global, WL_DRM_DEVICE,"/dev/dri/card0"); -} - -DrmHandler::DrmHandler(Compositor *compositor) - :m_compositor(compositor) -{ - QPlatformNativeInterface *nativeInterface = QApplicationPrivate::platformIntegration()->nativeInterface(); - m_connection = static_cast(nativeInterface->nativeResourceForWidget("Connection",0)); - xcb_screen_t *screen = static_cast(nativeInterface->nativeResourceForWidget("Screen",0)); - m_root_window = screen->root; - m_egl_display = static_cast(nativeInterface->nativeResourceForWidget("EglDisplay",0)); - - initializeDrm(); -} - -void DrmHandler::initializeDrm() -{ -} - -void DrmHandler::authenticate(uint32_t id) -{ - xcb_dri2_authenticate_cookie_t authenticateCoockie = xcb_dri2_authenticate_unchecked(m_connection,m_root_window,id); - xcb_dri2_authenticate_reply_t *authenticate = xcb_dri2_authenticate_reply(m_connection,authenticateCoockie,NULL); - - if (!authenticate || !authenticate->authenticated) { - fprintf(stderr,"Failed to authenticate drm :(\n"); - } - - free(authenticate); -} - -void DrmHandler::createBuffer(wl_client *client, uint32_t id, uint32_t name, const QSize &size, uint32_t stride, wl_visual *visual) -{ - EGLImageKHR image; - 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 - }; - - image = eglCreateImageKHR(m_egl_display, - EGL_NO_CONTEXT, - EGL_DRM_BUFFER_MESA, - (EGLClientBuffer) name, attribs); - - DrmBuffer *buffer = new DrmBuffer(image,m_compositor,visual,size); - - addClientResource(client,&buffer->base()->resource,id,&wl_buffer_interface,&drm_interface,0); -} - -} diff --git a/src/qt-compositor/wldrmbuffer.h b/src/qt-compositor/wldrmbuffer.h deleted file mode 100644 index ee51d4f..0000000 --- a/src/qt-compositor/wldrmbuffer.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** This file is part of QtCompositor** -** -** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** -** Contact: Nokia Corporation qt-info@nokia.com -** -** You may use this file under the terms of the BSD license as follows: -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** -** Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** -** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the -** names of its contributors may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -****************************************************************************/ - -#ifndef WL_DRMBUFFER_H -#define WL_DRMBUFFER_H - -#include "wlbuffer.h" - -#include - -#include - -#include - -#define MESA_EGL_NO_X11_HEADERS -#define EGL_EGLEXT_PROTOTYPES -#include -#include - -//class Display; - -namespace Wayland { - -class Compositor; -struct Display; -class DrmBuffer : public Buffer -{ -public: - DrmBuffer(EGLImageKHR image, Compositor *compositor, struct wl_visual *visual, const QSize &size); - - Buffer::BufferType type() const {return Buffer::Egl;} - - void attach(Surface *surface); - void damage(Surface *surface, const QRect &rect); - -private: - EGLImageKHR m_image; -}; - -class DrmHandler : public Object -{ -public: - DrmHandler(Compositor *compositor); - void initializeDrm(); - - void authenticate(uint32_t id); - void createBuffer(struct wl_client *client, uint32_t id, uint32_t name, - const QSize &size, uint32_t stride, struct wl_visual *visual); -private: - - xcb_connection_t *m_connection; - xcb_window_t m_root_window; - EGLDisplay m_egl_display; - - Compositor *m_compositor; -}; - -void authenticate(struct wl_client *client, - struct wl_drm *drm, - uint32_t 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); - -void post_drm_device(struct wl_client *client, struct wl_object *global); - -const struct wl_drm_interface drm_interface = { - authenticate, - create_buffer -}; - - -} - -#endif // WL_DRMBUFFER_H diff --git a/src/qt-compositor/wlshmbuffer.cpp b/src/qt-compositor/wlshmbuffer.cpp index 79c99b9..62eb353 100644 --- a/src/qt-compositor/wlshmbuffer.cpp +++ b/src/qt-compositor/wlshmbuffer.cpp @@ -48,15 +48,14 @@ namespace Wayland { void shm_buffer_attach(struct wl_buffer *buffer, struct wl_surface *surface) { - wayland_cast(buffer)->attach(wayland_cast(surface)); + wayland_cast(buffer)->attach(reinterpret_cast(surface)); } void shm_buffer_damage(struct wl_buffer *buffer, struct wl_surface *surface, int x, int y, int width, int height) { - wayland_cast(buffer)->damage(wayland_cast(surface), QRect(x, y, width, height)); + wayland_cast(buffer)->damage(reinterpret_cast(surface), QRect(x, y, width, height)); } - void shm_buffer_destroy(struct wl_resource *resource, struct wl_client *) { delete wayland_cast((wl_buffer *)resource); @@ -95,8 +94,13 @@ ShmBuffer::ShmBuffer(int fd, const QSize &size, uint stride, struct wl_visual *visual) - : Buffer(compositor,visual,size) { + base()->compositor = reinterpret_cast(compositor); + base()->height = size.height(); + base()->width = size.width(); + base()->visual = visual; + base()->attach = shm_buffer_attach; + base()->damage = shm_buffer_damage; m_stride = stride; m_data = mmap(NULL, stride * size.height(), PROT_READ, MAP_SHARED, fd, 0); close(fd); diff --git a/src/qt-compositor/wlshmbuffer.h b/src/qt-compositor/wlshmbuffer.h index 41c3c1f..55a0ec1 100644 --- a/src/qt-compositor/wlshmbuffer.h +++ b/src/qt-compositor/wlshmbuffer.h @@ -41,15 +41,18 @@ #ifndef WL_SHMBUFFER_H #define WL_SHMBUFFER_H -#include "wlbuffer.h" -#include "wlsurface.h" +#include "wlobject.h" #include #include + + namespace Wayland { -struct Surface; -class ShmBuffer : public Buffer +class Surface; +class Compositor; + +class ShmBuffer : public Object { public: ShmBuffer(int fd, @@ -62,8 +65,6 @@ public: void attach(Surface *surface); void damage(Surface *surface, const QRect &rect); - Buffer::BufferType type() const {return Buffer::Shm;} - QImage image() const; QSize size() const; diff --git a/src/qt-compositor/wlsurface.cpp b/src/qt-compositor/wlsurface.cpp index 7ce30dc..c8e1425 100644 --- a/src/qt-compositor/wlsurface.cpp +++ b/src/qt-compositor/wlsurface.cpp @@ -42,10 +42,67 @@ #include "wlcompositor.h" #include "wlshmbuffer.h" + #include +#include + +#ifdef QT_COMPOSITOR_WAYLAND_EGL +#include +#include +#define EGL_EGLEXT_PROTOTYPES +#include +#include +#endif + namespace Wayland { +class SurfacePrivate +{ +public: + SurfacePrivate(struct wl_client *client, Compositor *compositor) + : m_client(client) + , m_compositor(compositor) + { + current.type = State::Invalid; + staged.type = State::Invalid; +#ifdef QT_COMPOSITOR_WAYLAND_EGL + if (QWidget *topLevel = m_compositor->topLevelWidget()) { + if (topLevel->platformWindow() && topLevel->platformWindow()->glContext()) { + topLevel->platformWindow()->glContext()->makeCurrent(); + glGenTextures(1,¤t.texture_id); + staged.texture_id = current.texture_id; + } + } +#endif + } + + struct State { + enum BufferType { + Shm, + Texture, + Invalid + }; + + BufferType type; + + ShmBuffer *shm_buffer; +#ifdef QT_COMPOSITOR_WAYLAND_EGL + GLuint texture_id; +#endif + QRect rect; + + }; + + State current; + State staged; + + struct wl_client *m_client; + Compositor *m_compositor; +}; + + + void surface_destroy(struct wl_client *client, struct wl_surface *surface) { wl_resource_destroy(&surface->resource, client); @@ -58,7 +115,14 @@ void surface_attach(struct wl_client *client, struct wl_surface *surface, Q_UNUSED(x); Q_UNUSED(y); - wayland_cast(surface)->attach(wayland_cast(buffer)); + if (buffer->attach) { + wayland_cast(surface)->attachShm(wayland_cast(buffer)); + } +#ifdef QT_COMPOSITOR_WAYLAND_EGL + else { + wayland_cast(surface)->attachEgl(buffer); + } +#endif //QT_COMPOSITOR_WAYLAND_EGL } void surface_map_toplevel(struct wl_client *client, @@ -102,38 +166,105 @@ void surface_damage(struct wl_client *client, struct wl_surface *surface, } Surface::Surface(struct wl_client *client, Compositor *compositor) - : m_client(client) - , m_compositor(compositor) + : d_ptr(new SurfacePrivate(client,compositor)) { base()->client = client; wl_list_init(&base()->destroy_listener_list); - - current.buffer = 0; - staged.buffer = 0; } Surface::~Surface() { - m_compositor->surfaceDestroyed(this); + Q_D(Surface); + d->m_compositor->surfaceDestroyed(this); } - void Surface::damage(const QRect &rect) { - m_compositor->surfaceDamaged(this, rect); + Q_D(Surface); + d->m_compositor->surfaceDamaged(this, rect); +} + +bool Surface::hasImage() const +{ + Q_D(const Surface); + return d->current.type == SurfacePrivate::State::Shm; } QImage Surface::image() const { - if (current.buffer && current.buffer->type() == Buffer::Shm) { - return static_cast(current.buffer)->image(); + Q_D(const Surface); + if (d->current.type == SurfacePrivate::State::Shm) { + return d->current.shm_buffer->image(); } return QImage(); } -void Surface::attach(Buffer *buffer) +#ifdef QT_COMPOSITOR_WAYLAND_EGL +void Surface::attachEgl(wl_buffer *egl_buffer) +{ + Q_D(Surface); + Q_ASSERT(d->m_compositor->topLevelWidget()); + QPlatformNativeInterface *nativeInterface = QApplicationPrivate::platformIntegration()->nativeInterface(); + Q_ASSERT(nativeInterface); + + //make current for the topLevel. We could have used the eglContext, + //but then we would need to handle eglSurfaces as well. + d->m_compositor->topLevelWidget()->platformWindow()->glContext()->makeCurrent(); + + EGLDisplay eglDisplay = static_cast(nativeInterface->nativeResourceForWidget("EglDisplay",d->m_compositor->topLevelWidget())); + EGLContext eglContext = static_cast(nativeInterface->nativeResourceForWidget("EglContext",d->m_compositor->topLevelWidget())); + Q_ASSERT(eglDisplay); + Q_ASSERT(eglContext); + + EGLImageKHR image = eglCreateImageKHR(eglDisplay, eglContext, + EGL_WAYLAND_BUFFER_WL, + egl_buffer, NULL); + + glBindTexture(GL_TEXTURE_2D, d->staged.texture_id); + + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); + + eglDestroyImageKHR(eglDisplay, image); + + d->staged.type = SurfacePrivate::State::Texture; + d->current.type = d->staged.type; + d->current.texture_id = d->staged.texture_id; + + d->m_compositor->surfaceResized(this,QSize(egl_buffer->width,egl_buffer->height)); +} + +bool Surface::hasTexture() const +{ + Q_D(const Surface); + return (d->current.type == SurfacePrivate::State::Texture); +} + +GLuint Surface::textureId() const +{ + Q_D(const Surface); + return d->current.texture_id; +} +#endif // QT_COMPOSITOR_WAYLAND_EGL + +void Surface::attachShm(Wayland::ShmBuffer *shm_buffer) +{ + Q_D(Surface); + d->current.shm_buffer = d->current.shm_buffer = shm_buffer; + d->current.type = d->staged.type = SurfacePrivate::State::Shm; + d->m_compositor->surfaceResized(this, shm_buffer->size()); +} + + +void Surface::mapTopLevel() +{ + Q_D(Surface); + d->staged.rect = QRect(0, 0, 200, 200); +} + +void Surface::commit() { - current.buffer = staged.buffer = buffer; - m_compositor->surfaceResized(this, buffer->size()); + Q_D(Surface); + d->current = d->staged; + d->m_compositor->surfaceResized(this, buffer->size()); } } diff --git a/src/qt-compositor/wlsurface.h b/src/qt-compositor/wlsurface.h index 91867c8..870dc1e 100644 --- a/src/qt-compositor/wlsurface.h +++ b/src/qt-compositor/wlsurface.h @@ -42,42 +42,59 @@ #define WL_SURFACE_H #include "wlobject.h" +#include "wlshmbuffer.h" #include #include +#include +#include +#include + +#ifdef QT_COMPOSITOR_WAYLAND_EGL +#define GL_GLEXT_PROTOTYPES +#include +#include +#endif + namespace Wayland { class Compositor; class Buffer; + +class SurfacePrivate; + class Surface : public Object { + Q_DECLARE_PRIVATE(Surface) public: Surface(struct wl_client *client, Compositor *compositor); ~Surface(); - struct State { - Buffer *buffer; - QRect rect; - }; - uint id() const { return base()->resource.object.id; } - void attach(Buffer *buffer); +#ifdef QT_COMPOSITOR_WAYLAND_EGL + void attachEgl(wl_buffer *egl_buffer); +#endif + void attachShm(ShmBuffer *shm_buffer); - void mapTopLevel() { staged.rect = QRect(0, 0, 200, 200); } + void mapTopLevel(); - void commit() { current = staged; } + void commit(); void damage(const QRect &rect); QImage image() const; + bool hasImage() const; -private: - State current; - State staged; +#ifdef QT_COMPOSITOR_WAYLAND_EGL + bool hasTexture() const; + GLuint textureId() const; +#endif - struct wl_client *m_client; - Compositor *m_compositor; +protected: + QScopedPointer d_ptr; +private: + Q_DISABLE_COPY(Surface) }; void surface_destroy(struct wl_client *client, struct wl_surface *_surface); -- 2.7.4