Optimierung mit glLists

Im Würfel Effekt werden einige Zeichenoperationen wiederholt ausgeführt, daher ist es naheliegend diese in glLists zu bündeln und nur einmalig zu berechnen. Durch die Spiegelung wird der Würfel zweimal gezeichnet, dazu wird auf Grund des fehlenden z-Buffer Face Culling verwendet, was noch einmal die Anzahl der Zeichenvorgänge verdoppelt. Leider kann auf Grund der Effekt-Architektur nicht der komplette Würfel in eine glList gespeichert werden. Die Effekte sind verkettet, d.h. ein Effekt ruft die Zeichenfunktion des nächsten Effekt auf. Möchte man nun den Zeichenvorgang mit glLists optimieren, so würden die Animationen der nachfolgenden Effekte nicht mehr ausgeführt. Daher ist es nicht möglich den kompletten Würfel in eine glLists zu kompilieren.

Um dennoch den Vorteil der glLists nutzen zu können, ist es möglich die Bereiche, welche nicht von anderen Effekten beeinflust werden in glLists zu speichern. So können die Cube Caps (Bilder auf Ober- und Unterseite) in eine Liste gespeichert werden, sowie die manuelle Rotation mit der Maus. Zusätzlich kann man in jedem Frame einmalig den Würfel in eine glList speichern und beim eigentlichen Zeichnen verwenden. Damit werden drei Würfelzeichnungen eingespart.

Dieses Vorgehen führt leider erneut zu einem Problem. Um dieses zu verstehen muss man einen Blick auf die Technik werfen. Wenn ein Composition Manager verwendet wird, wird der Zeichenvorgang der einzelnen Fenster nicht direkt in den Framebuffer geschrieben, sondern in einen off-screen Speicher (Pixmap) umgeleitet. Für die Anwendung ist dies komplett transparent und sie merkt davon nichts. Der Composition Manager kann nun aus der Pixmap über eine GLX Erweiterung (GLX_EXT_texture_from_pixmap) eine GL Textur erstellen und diese wie üblich auf den Framebuffer zeichnen.

Das auftretende Problem mit glLists und "texture from pixmap" betrifft Fenster, welche lange nicht angezeigt wurden und sich auf einem anderen virtuellen Desktop befinden. Die Pixmap des Fensters wird vom Grafikkartentreiber verworfen, um Arbeitsspeicher zu sparen. Wenn nun der Würfel gestartet wird, dann muss zuerst die Pixmap erstellt werden. Geschieht dieses während der Erstellung einer glList, so scheitert das folgende "texture from pixmap" und das Fenster erscheint schwarz. Dieser Zustand bleibt auch nach dem Beenden des Effekts bestehen und tritt auch auf für neu erstellte Fenster.

Für dieses Problem konnte auch eine Lösung gefunden werden: es muss sichergestellt sein, dass ein Fenster mindestens einmal ohne glList gezeichnet wird und somit die Pixmap wieder erstellt ist. So wird beim Starten des Würfels einmal ohne glLists gezeichnet und jedes nachfolgende Frame verwendet glLists, außer wenn ein neues Fenster geöffnet wird. Dieses löst einen einmaligen Zeichenvorgang ohne glList aus:

void CubeEffect::windowAdded( EffectWindow* )
    {
    // when there is a new window we have to paint it once without using GL List
    // to prevent that the window is black
    if( activated )
        useList = false;
    }

Und in der Zeichenroutine (paintScreen):

// compile List for cube
if( useList )
    {
    glNewList( glList + 1, GL_COMPILE );
    glPushMatrix();
    paintCube( mask, region, data );
    glPopMatrix();
    glEndList();
    }

sowie mehrmalige Überprüfung an den entsprechenden Stellen:

if( useList )
    glCallList( glList + 1 );
else
    {
    glPushMatrix();
    paintCube( mask, region, data );
    glPopMatrix();
    }