From 278cd81e6663f541b286d7846aca98f3eca5cb94 Mon Sep 17 00:00:00 2001 From: Michael Schuldt Date: Mon, 27 Jun 2011 16:58:51 +0200 Subject: [PATCH] Bugfix race conditions and compositing startup * Check if composite manager is running improved * race condition in allocate platform surfaces removed --- .../include/WindowSystems/X11WindowSystem.h | 1 + .../Graphic/src/TextureBinders/X11CopyGLX.cpp | 44 +++++++------ .../Graphic/src/WindowSystems/X11WindowSystem.cpp | 75 +++++++++++++--------- 3 files changed, 70 insertions(+), 50 deletions(-) diff --git a/LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/X11WindowSystem.h b/LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/X11WindowSystem.h index 2f06889..c46767a 100644 --- a/LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/X11WindowSystem.h +++ b/LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/X11WindowSystem.h @@ -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_ */ diff --git a/LayerManagerPlugins/Renderers/Graphic/src/TextureBinders/X11CopyGLX.cpp b/LayerManagerPlugins/Renderers/Graphic/src/TextureBinders/X11CopyGLX.cpp index 7e4b5f2..e785f64 100644 --- a/LayerManagerPlugins/Renderers/Graphic/src/TextureBinders/X11CopyGLX.cpp +++ b/LayerManagerPlugins/Renderers/Graphic/src/TextureBinders/X11CopyGLX.cpp @@ -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; } diff --git a/LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/X11WindowSystem.cpp b/LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/X11WindowSystem.cpp index 52d643f..d9928ce 100644 --- a/LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/X11WindowSystem.cpp +++ b/LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/X11WindowSystem.cpp @@ -22,6 +22,9 @@ #include "Layer.h" #include #include +#include +#include +#include #include #include #include @@ -30,9 +33,10 @@ #include #include -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 surfaces = m_pScene->getAllSurfaces(); for(std::map::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 layers = m_pScene->getCurrentRenderOrder(); for(std::list::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* 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; } + -- 2.7.4