Bugfix race conditions and compositing startup
authorMichael Schuldt <michael.schuldt@bmw-carit.de>
Mon, 27 Jun 2011 14:58:51 +0000 (16:58 +0200)
committerMichael Schuldt <michael.schuldt@bmw-carit.de>
Mon, 27 Jun 2011 14:58:51 +0000 (16:58 +0200)
* Check if composite manager is running improved
* race condition in allocate platform surfaces removed

LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/X11WindowSystem.h
LayerManagerPlugins/Renderers/Graphic/src/TextureBinders/X11CopyGLX.cpp
LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/X11WindowSystem.cpp

index 2f06889..c46767a 100644 (file)
@@ -115,6 +115,7 @@ private:
     static void* EventLoop(void * ptr);
     static int error(Display *dpy, XErrorEvent *ev);
        bool redrawEvent;
+    static bool m_xerror;
 };
 
 #endif /* _X11WINDOWSYSTEM_H_ */
index 7e4b5f2..e785f64 100644 (file)
@@ -30,29 +30,35 @@ bool X11CopyGLX::bindSurfaceTexture(Surface* surface)
     Pixmap pixmap = 0;
     GLenum targetType = GL_BGRA;
     GLenum sourceType = GL_RGBA;
-
-    pixmap = XCompositeNameWindowPixmap (dpy, surface->nativeHandle);
-    if (!pixmap)
+    if (surface != NULL ) 
     {
-        LOG_ERROR("X11CopyGLX", "didnt create pixmap!");
-        return false;
-    }
-
-    nativeSurface->pixmap = pixmap;
-    XImage * xim = XGetImage(dpy, nativeSurface->pixmap, 0, 0, surface->OriginalSourceWidth, surface->OriginalSourceHeight, AllPlanes, ZPixmap);
-    if (xim)
+        nativeSurface = (XPlatformSurface*)surface->platform;
+    } 
+    if( nativeSurface != NULL && surface->nativeHandle != 0 ) 
     {
-        glBindTexture(GL_TEXTURE_2D, nativeSurface->texture);
-        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-        if (xim->depth == 24)
+        pixmap = XCompositeNameWindowPixmap (dpy, surface->nativeHandle);
+        if (!pixmap)
+        {
+            LOG_ERROR("X11CopyGLX", "didnt create pixmap!");
+            return false;
+        }
+
+        nativeSurface->pixmap = pixmap;
+        XImage * xim = XGetImage(dpy, nativeSurface->pixmap, 0, 0, surface->OriginalSourceWidth, surface->OriginalSourceHeight, AllPlanes, ZPixmap);
+        if (xim)
         {
-            targetType = GL_BGR;
-            sourceType = GL_RGB;
+            glBindTexture(GL_TEXTURE_2D, nativeSurface->texture);
+            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+            if (xim->depth == 24)
+            {
+                targetType = GL_BGR;
+                sourceType = GL_RGB;
+            }
+            glTexImage2D(GL_TEXTURE_2D, 0, sourceType, surface->OriginalSourceWidth, surface->OriginalSourceHeight, 0, targetType, GL_UNSIGNED_BYTE, xim->data);
+            XDestroyImage(xim);
+            return true;
         }
-        glTexImage2D(GL_TEXTURE_2D, 0, sourceType, surface->OriginalSourceWidth, surface->OriginalSourceHeight, 0, targetType, GL_UNSIGNED_BYTE, xim->data);
-        XDestroyImage(xim);
-        return true;
     }
     return false;
 }
index 52d643f..d9928ce 100644 (file)
@@ -22,6 +22,9 @@
 #include "Layer.h"
 #include <time.h>
 #include <sys/time.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
 #include <X11/extensions/Xcomposite.h>
 #include <X11/extensions/Xdamage.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <iomanip>
 
-int        X11WindowSystem::composite_opcode;
+int     X11WindowSystem::composite_opcode;
 int            X11WindowSystem::damage_opcode;
 const char X11WindowSystem::CompositorWindowTitle[] = "LayerManager";
+bool    X11WindowSystem::m_xerror = false;
 
 X11WindowSystem::X11WindowSystem(const char* displayname, int width, int height, Scene* pScene,GetVisualInfoFunction func)
 : BaseWindowSystem(pScene)
@@ -189,12 +193,14 @@ Surface* X11WindowSystem::getSurfaceForWindow(Window w)
 
 void X11WindowSystem::checkForNewSurface()
 {
+    m_pScene->lockScene();
        const std::map<unsigned int,Surface*> surfaces = m_pScene->getAllSurfaces();
        for(std::map<unsigned int, Surface*>::const_iterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++)
        {
                Surface* currentSurface = (*currentS).second;
                allocatePlatformSurface(currentSurface);
        }
+    m_pScene->unlockScene();
 }
 
 void X11WindowSystem::configureSurfaceWindow(Window window)
@@ -420,23 +426,8 @@ bool X11WindowSystem::CreatePixmapsForAllWindows()
     bool result = true;
     LOG_DEBUG("X11WindowSystem", "redirecting all windows");
     Window root = RootWindow(x11Display, 0);
-//    XGrabServer (x11Display);
-//    unsigned int numberOfWindows = 0;
-//    Window *children = getListOfAllTopLevelWindows(x11Display,&numberOfWindows);
-
-//    LOG_DEBUG("X11WindowSystem", "Found " << numberOfWindows << " windows");
     XCompositeRedirectSubwindows(x11Display,root,CompositeRedirectManual);
-
-/*    for (unsigned int i=0;i< (numberOfWindows-1);i++)
-    {
-        Window w = (Window) children[i];
-        NewWindow(w);
-        MapWindow(w);
-    } */
-//    XFree(children);
-//    XUngrabServer (x11Display);
-//    XSync(x11Display, 0);
-
+    XSync(x11Display,0);
     return result;
 }
 
@@ -444,7 +435,7 @@ bool X11WindowSystem::CreateCompositorWindow()
 {
     LOG_DEBUG("X11WindowSystem", "Get root window");
     bool result = true;
-    Window root = XDefaultRootWindow(x11Display);
+    Window root = RootWindow(x11Display,0);
 
     LOG_DEBUG("X11WindowSystem", "Get default screen");
     // draw a black background the full size of the resolution
@@ -462,9 +453,15 @@ bool X11WindowSystem::CreateCompositorWindow()
     attr.border_pixel = 0;
     windowVis = getVisualFunc(x11Display);
     attr.colormap = XCreateColormap(x11Display, root, windowVis->visual, AllocNone);
-
     attr.override_redirect = True;
 
+    Window compManager = XGetSelectionOwner(x11Display,XInternAtom(x11Display,"_NET_WM_CM_S0",0));
+    if ( 0 != compManager )
+    {
+        LOG_ERROR("X11WindowSystem", "Could not create compositor window, annother compisite manager is already running");
+        return false;
+    }
+
 //    Window overlaywindow = XCompositeGetOverlayWindow(x11Display,root);
 
     CompositorWindow = XCreateWindow(x11Display, root, 0, 0, windowWidth, windowHeight,
@@ -532,8 +529,6 @@ void CalculateFPS()
 void
 X11WindowSystem::RedrawAllLayers()
 {
-       m_damaged = false;
-
        std::list<Layer*> layers = m_pScene->getCurrentRenderOrder();
        for(std::list<Layer*>::const_iterator current = layers.begin(); current != layers.end(); current++)
        {
@@ -553,6 +548,8 @@ X11WindowSystem::RedrawAllLayers()
                        graphicSystem->endLayer();
                }
        }
+    /* Reset the damage flag, all is up to date */
+       m_damaged = false;
 }
 
 void X11WindowSystem::Redraw()
@@ -626,7 +623,7 @@ X11WindowSystem::error (Display *dpy, XErrorEvent *ev)
     const char* name = NULL;
     static char buffer[256];
 
-    if (ev->request_code == composite_opcode && ev->minor_code == X_CompositeRedirectWindow)
+    if (ev->request_code == composite_opcode && ev->minor_code == X_CompositeRedirectSubwindows)
     {
         LOG_ERROR("X11WindowSystem", "Maybe another composite manager is already running");
     }
@@ -639,6 +636,7 @@ X11WindowSystem::error (Display *dpy, XErrorEvent *ev)
     }
     name = (strlen (name) > 0) ? name : "unknown";
     LOG_ERROR("X11WindowSystem", "X Error: " << (int)ev->error_code << " " << name << " request : " << (int)ev->request_code << " minor: " <<  (int)ev->minor_code << " serial: " << (int)ev->serial);
+    m_xerror = true;
     return 0;
 }
 
@@ -656,14 +654,19 @@ bool X11WindowSystem::initXServer()
 
     LOG_DEBUG("X11WindowSystem", "Compositor Window ID: " << CompositorWindow);
 
-    CreatePixmapsForAllWindows();
-    //unredirect our window
+    if ( CreatePixmapsForAllWindows() )
+    {
+            //unredirect our window
 #ifdef FULLSCREEN
-    XCompositeUnredirectWindow(x11Display, background, CompositeRedirectManual);
+        XCompositeUnredirectWindow(x11Display, background, CompositeRedirectManual);
 #endif
-    XCompositeUnredirectWindow(x11Display, CompositorWindow, CompositeRedirectManual);
+        XCompositeUnredirectWindow(x11Display, CompositorWindow, CompositeRedirectManual);
+        LOG_DEBUG("X11WindowSystem", "Initialised XServer connection complete");
+    } else {
+        LOG_ERROR("X11WindowSystem", "Initialised XServer connection failed");
+        result = false;        
+    }
 
-    LOG_DEBUG("X11WindowSystem", "Initialised XServer connection");
     return result;
 }
 
@@ -809,7 +812,7 @@ void* X11WindowSystem::EventLoop(void * ptr)
                        }
                        else
                        {
-                               windowsys->checkForNewSurface();
+                windowsys->checkForNewSurface();
                                checkRedraw = true;
                        }
 
@@ -839,6 +842,7 @@ void X11WindowSystem::signalRedrawEvent()
 {
        // set flag that redraw is needed
        redrawEvent = true;
+    m_damaged = true;
 #ifdef USE_XTHREADS
        // send dummy expose event, to wake up blocking x11 event loop (XNextEvent)
        LOG_DEBUG("X11WindowSystem", "Sending dummy event to wake up renderer thread");
@@ -894,11 +898,19 @@ bool X11WindowSystem::init(BaseGraphicSystem<Display*,Window>* base)
 
 bool X11WindowSystem::start()
 {
+    bool result = true;
     LOG_INFO("X11WindowSystem", "Starting / Creating thread");
     // let thread actually run
-    this->m_running = true;
-    pthread_mutex_unlock(&run_lock);
-    return true;
+    if ( m_xerror == false ) 
+    {
+        this->m_running = true;
+        pthread_mutex_unlock(&run_lock);
+    } else {
+        this->m_running = false;
+        pthread_mutex_unlock(&run_lock);
+        result = false;
+    }
+    return result;
 }
 
 void X11WindowSystem::stop()
@@ -941,3 +953,4 @@ void X11WindowSystem::doScreenShotOfSurface(std::string fileName, const uint id)
     screenShotFile = fileName;
     screenShotID = id;
 }
+