Support for direct rendering (non-composited mode)
authorPaul Olav Tvete <paul.tvete@nokia.com>
Thu, 28 Apr 2011 13:11:29 +0000 (15:11 +0200)
committerPaul Olav Tvete <paul.tvete@nokia.com>
Thu, 28 Apr 2011 13:24:08 +0000 (15:24 +0200)
Experimental.

src/qt-compositor/compositor_api/waylandcompositor.cpp
src/qt-compositor/compositor_api/waylandcompositor.h
src/qt-compositor/hardware_integration/graphicshardwareintegration.h
src/qt-compositor/wayland_wrapper/wlcompositor.cpp
src/qt-compositor/wayland_wrapper/wlcompositor.h
src/qt-compositor/wayland_wrapper/wlsurface.cpp

index b9c9355..cc70809 100644 (file)
@@ -80,14 +80,15 @@ void WaylandCompositor::destroyClientForSurface(WaylandSurface *surface)
     m_compositor->destroyClientForSurface(surface->handle());
 }
 
-void WaylandCompositor::setDirectRenderWinId(uint winId)
+void WaylandCompositor::setDirectRenderSurface(WaylandSurface *surface)
 {
-    Q_UNUSED(winId);
+    m_compositor->setDirectRenderSurface(surface ? surface->handle() : 0);
 }
 
-uint WaylandCompositor::directRenderWinId() const
+WaylandSurface *WaylandCompositor::directRenderSurface() const
 {
-    return 0;
+    Wayland::Surface *surf = m_compositor->directRenderSurface();
+    return surf ? surf->handle() : 0;
 }
 
 QWidget * WaylandCompositor::topLevelWidget() const
index 20b136f..805bb33 100644 (file)
@@ -68,8 +68,8 @@ public:
     void setInputFocus(WaylandSurface *surface);
     void destroyClientForSurface(WaylandSurface *surface);
 
-    void setDirectRenderWinId(uint winId);
-    uint directRenderWinId() const;
+    void setDirectRenderSurface(WaylandSurface *surface);
+    WaylandSurface *directRenderSurface() const;
 
     QWidget *topLevelWidget()const;
 
index d74ea55..5824cd1 100644 (file)
@@ -59,6 +59,9 @@ public:
      **/
     virtual GLuint createTextureFromBuffer(struct wl_buffer *buffer) = 0;
 
+    virtual bool setDirectRenderSurface(WaylandSurface *surface) {return false;}
+    virtual bool postBuffer(struct wl_buffer *) {return false;}
+
     static GraphicsHardwareIntegration *createGraphicsHardwareIntegration(WaylandCompositor *compositor);
 
 protected:
index 9fb9ce7..15869d5 100644 (file)
@@ -171,6 +171,7 @@ Compositor::Compositor(WaylandCompositor *qt_compositor)
     , m_qt_compositor(qt_compositor)
     , m_pointerFocusSurface(0)
     , m_keyFocusSurface(0)
+    , m_directRenderSurface(0)
 {
 #if defined (QT_COMPOSITOR_WAYLAND_GL)
     m_graphics_hw_integration = GraphicsHardwareIntegration::createGraphicsHardwareIntegration(qt_compositor);
@@ -346,6 +347,17 @@ void Compositor::initializeHardwareIntegration()
 #endif
 }
 
+bool Compositor::setDirectRenderSurface(Surface *surface)
+{
+#ifdef QT_COMPOSITOR_WAYLAND_GL
+    if (m_graphics_hw_integration->setDirectRenderSurface(surface ? surface->handle() : 0)) {
+        m_directRenderSurface = surface;
+        return true;
+    }
+#endif
+    return false;
+}
+
 
 }
 
index b2bf6ac..ac107d9 100644 (file)
@@ -89,8 +89,11 @@ public:
 
     GraphicsHardwareIntegration *graphicsHWIntegration() const;
     void initializeHardwareIntegration();
+    bool setDirectRenderSurface(Surface *surface);
+    Surface *directRenderSurface() const {return m_directRenderSurface;}
 
     wl_input_device *defaultInputDevice();
+    WaylandCompositor *qtCompositor() const { return m_qt_compositor; }
 private slots:
     void processWaylandEvents();
 
@@ -120,6 +123,7 @@ private:
 
     Surface *m_pointerFocusSurface;
     Surface *m_keyFocusSurface;
+    Surface *m_directRenderSurface;
 
 #ifdef QT_COMPOSITOR_WAYLAND_GL
     GraphicsHardwareIntegration *m_graphics_hw_integration;
index 689a78d..cd83b76 100644 (file)
@@ -65,6 +65,7 @@ public:
         : client(client)
         , compositor(compositor)
         , needsMap(false)
+        , directRenderBuffer(0)
     {
         type = WaylandSurface::Invalid;
 #ifdef QT_COMPOSITOR_WAYLAND_GL
@@ -83,6 +84,7 @@ public:
     GLuint texture_id;
 #endif
     bool needsMap;
+    wl_buffer *directRenderBuffer;
 };
 
 
@@ -174,6 +176,11 @@ WaylandSurface::Type Surface::type() const
 void Surface::damage(const QRect &rect)
 {
     Q_D(Surface);
+    if (d->directRenderBuffer) {
+        //qDebug() << "DIRECT RENDER";
+        if (d->compositor->graphicsHWIntegration()->postBuffer(d->directRenderBuffer))
+                return;
+    }
     d->compositor->markSurfaceAsDirty(this);
     emit d->qtSurface->damaged(rect);
 }
@@ -192,6 +199,18 @@ QImage Surface::image() const
 void Surface::attachHWBuffer(struct wl_buffer *buffer)
 {
     Q_D(Surface);
+
+    if (d->compositor->qtCompositor()->directRenderSurface() == handle()) {
+        d->directRenderBuffer = buffer;
+        if (d->texture_id) {
+            glDeleteTextures(1,&d->texture_id);
+            d->texture_id = 0;
+        }
+        //qDebug() << "        not creating texture";
+        return;
+    }
+    //qDebug() << "creating texture" << handle() << "direct" << d->compositor->qtCompositor()->directRenderSurface();
+    d->directRenderBuffer = 0;
     d->type = WaylandSurface::Texture;
 
     //make current for the topLevel. We could have used the eglContext,