Renderers: refactor recomposition methods
authorAdam Cheney <acheney@nvidia.com>
Fri, 10 Aug 2012 03:23:29 +0000 (20:23 -0700)
committerMichael Schuldt <michael.schuldt@bmw.de>
Fri, 24 Aug 2012 07:26:28 +0000 (09:26 +0200)
- Adds support in GraphicSystem for accepting a LayerList to
  render, instead of only one Layer.  This enables future
  optimizations that change the rendering order.
      eg. - reverse render order to utilize depth test culling
          - draw multiple layers/surfaces at once (multitexturing)

  also includes a 'clear' flag so the background clear can be
  optimized as well.
      eg. - no need to clear obscurred pixels

- Don't reset any damage flags until after rendering has taken
  place.  Detailed damage information could be useful to the
  GraphicSystem when it is rendering.  Wait until after
  recomposition, then clear all flags. Share the routine to
  clear damage flags in the BaseWindowSystem.

12 files changed:
LayerManagerPlugins/Renderers/Graphic/CMakeLists.txt
LayerManagerPlugins/Renderers/Graphic/include/GraphicSystems/BaseGraphicSystem.h
LayerManagerPlugins/Renderers/Graphic/include/GraphicSystems/GLESGraphicSystem.h
LayerManagerPlugins/Renderers/Graphic/include/GraphicSystems/GLXGraphicsystem.h
LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/BaseWindowSystem.h
LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/WaylandBaseWindowSystem.h
LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/X11WindowSystem.h
LayerManagerPlugins/Renderers/Graphic/src/GraphicSystems/GLESGraphicSystem.cpp
LayerManagerPlugins/Renderers/Graphic/src/GraphicSystems/GLXGraphicSystem.cpp
LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/BaseWindowSystem.cpp [new file with mode: 0644]
LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/WaylandBaseWindowSystem.cpp
LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/X11WindowSystem.cpp

index ba130a6..945e3c1 100644 (file)
@@ -52,6 +52,7 @@ if (WITH_GLESv2_LIB)
     set(SOURCES 
             ../Base/src/BaseRenderer.cpp 
             src/GraphicSystems/GLESGraphicSystem.cpp
+            src/WindowSystems/BaseWindowSystem.cpp
             src/WindowSystems/X11WindowSystem.cpp  
             src/TextureBinders/X11Copy.cpp
             src/TextureBinders/X11CopyGLES.cpp
@@ -157,6 +158,7 @@ if (WITH_GLX_LIB)
     set(SOURCES 
         ../Base/src/BaseRenderer.cpp 
         src/GraphicSystems/GLXGraphicSystem.cpp
+        src/WindowSystems/BaseWindowSystem.cpp
         src/WindowSystems/X11WindowSystem.cpp  
         src/TextureBinders/X11TextureFromPixmap.cpp
         src/TextureBinders/X11CopyGLX.cpp
@@ -256,6 +258,7 @@ if (WITH_WAYLAND)
         set(SOURCES
             ../Base/src/BaseRenderer.cpp
             src/GraphicSystems/GLESGraphicSystem.cpp
+            src/WindowSystems/BaseWindowSystem.cpp
             src/WindowSystems/WaylandBaseWindowSystem.cpp
             src/WindowSystems/WaylandX11WindowSystem.cpp
             src/WindowSystems/WaylandServerinfoProtocol.cpp  
@@ -278,6 +281,7 @@ if (WITH_WAYLAND)
         file(GLOB SOURCES 
             ../Base/src/BaseRenderer.cpp
             src/GraphicSystems/GLESGraphicSystem.cpp
+            src/WindowSystems/BaseWindowSystem.cpp
             src/WindowSystems/WaylandBaseWindowSystem.cpp
             src/WindowSystems/WaylandFbdevWindowSystem.cpp
             src/WindowSystems/WaylandServerinfoProtocol.cpp  
@@ -310,6 +314,7 @@ if (WITH_WAYLAND)
             ../Base/src/BaseRenderer.cpp
             src/GraphicSystems/GLESGraphicSystem.cpp
             src/GraphicSystems/DrmGLESGraphicSystem.cpp
+            src/WindowSystems/BaseWindowSystem.cpp
             src/WindowSystems/WaylandBaseWindowSystem.cpp
             src/WindowSystems/WaylandDrmWindowSystem.cpp
             src/WindowSystems/WaylandServerinfoProtocol.cpp
index 0bdff8b..9f803d2 100644 (file)
@@ -35,10 +35,13 @@ public:
     {
     };
     virtual void beginLayer(Layer* layer) = 0;
-    virtual void checkRenderLayer() = 0;
-    virtual void renderSWLayer() = 0;
     virtual void endLayer() = 0;
 
+    virtual bool needsRedraw(Layer *layer) = 0;
+    virtual bool needsRedraw(LayerList layers) = 0;
+    virtual void renderSWLayer(Layer* layer, bool clear) = 0;
+    virtual void renderSWLayers(LayerList layers, bool clear) = 0;
+
     virtual void setBaseWindowSystem(BaseWindowSystem* windowSystem)
     {
         m_baseWindowSystem = windowSystem;
index 182a50f..0ace94f 100644 (file)
@@ -47,10 +47,13 @@ public:
     virtual void swapBuffers();
 
     virtual void beginLayer(Layer* layer);
-    virtual void checkRenderLayer();
-    virtual void renderSWLayer();
     virtual void endLayer();
 
+    virtual bool needsRedraw(Layer *layer);
+    virtual bool needsRedraw(LayerList layers);
+    virtual void renderSWLayer(Layer* layer, bool clear);
+    virtual void renderSWLayers(LayerList layers, bool clear);
+
     virtual bool initOpenGLES(EGLint displayWidth, EGLint displayHeight);
     virtual void resize(EGLint displayWidth, EGLint displayHeight);
 
index 62b3200..09a0cfc 100644 (file)
@@ -36,10 +36,13 @@ public:
         return m_zerocopy;
     }
     virtual void beginLayer(Layer* layer);
-    virtual void checkRenderLayer();
-    virtual void renderSWLayer();
     virtual void endLayer();
 
+    virtual bool needsRedraw(Layer *layer);
+    virtual bool needsRedraw(LayerList layers);
+    virtual void renderSWLayer(Layer *layer, bool clear);
+    virtual void renderSWLayers(LayerList layers, bool clear);
+
     virtual void clearBackground();
     virtual void swapBuffers();
     virtual void saveScreenShotOfFramebuffer(std::string fileToSave);
index 12d8207..c911c38 100644 (file)
@@ -44,6 +44,7 @@ public:
     virtual void doScreenShotOfSurface(std::string fileName, const uint id, const uint layer_id) = 0;
 
 protected:
+    virtual void ClearDamage();
     Scene* m_pScene;
     InputManager* m_pInputManager;
 
index 149a907..5d286a8 100644 (file)
@@ -81,8 +81,7 @@ protected:
     pthread_t renderThread;
     pthread_mutex_t run_lock;
     BaseGraphicSystem<void*, void*>* graphicSystem;
-    virtual void CheckRedrawAllLayers();
-    virtual void RedrawAllLayers();
+    virtual void RedrawAllLayers(bool clear, bool swap);
     virtual void renderHWLayer(Layer* layer);
     virtual bool initCompositor();
     struct wl_shm* m_wlShm;
index 497a620..25d599c 100644 (file)
@@ -96,10 +96,9 @@ protected:
     pthread_mutex_t init_lock;
     pthread_cond_t init_condition;
     pthread_cond_t run_condition;
-    BaseGraphicSystem<Display*, Window>* graphicSystem;    
-    virtual bool initXServer(); 
-    virtual void CheckRedrawAllLayers();
-    virtual void RedrawAllLayers();
+    BaseGraphicSystem<Display*, Window>* graphicSystem;
+    virtual bool initXServer();
+    virtual void RedrawAllLayers(bool clear, bool swap);
     virtual void renderHWLayer(Layer* layer);
 
 private:
index a382c6b..56d72ae 100644 (file)
@@ -182,66 +182,109 @@ void GLESGraphicsystem::beginLayer(Layer* currentLayer)
     // TODO layer destination / source
 }
 
-void GLESGraphicsystem::checkRenderLayer()
+// Reports whether a single layer is damaged/dirty
+// Can not account for possible occlusion by other layers
+bool GLESGraphicsystem::needsRedraw(Layer *layer)
 {
-    SurfaceList surfaces = m_currentLayer->getAllSurfaces();
-
-    m_currentLayer->damaged = false;
+    if (layer->renderPropertyChanged)
+    {
+        return true;
+    }
 
-    if (!m_baseWindowSystem->m_forceComposition && (!m_baseWindowSystem->m_damaged || m_currentLayer->getLayerType() == Hardware))
+    if (layer->visibility && layer->opacity > 0.0)
     {
-        if (m_currentLayer->renderPropertyChanged)
-        {
-            m_currentLayer->damaged = true;
-        }
-        else if ((m_currentLayer)->visibility && (m_currentLayer)->opacity > 0.0)
+        SurfaceList surfaces = layer->getAllSurfaces();
+        for(SurfaceListConstIterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++)
         {
-            for(std::list<Surface*>::const_iterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++)
+            if ((*currentS)->renderPropertyChanged)
             {
-                if ((*currentS)->renderPropertyChanged)
-                {
-                    m_currentLayer->damaged = true;
-                    break;
-                }
-                else if ((*currentS)->hasNativeContent() && (*currentS)->damaged && (*currentS)->visibility && (*currentS)->opacity>0.0f)
-                {
-                    m_currentLayer->damaged = true;
-                    break;
-                }
+                return true;
             }
-        }
 
-        // Preseve m_currentLayer->damaged for HW layers so that they can be updated independently
-        if (m_currentLayer->damaged && m_currentLayer->getLayerType() != Hardware)
-        {
-            m_baseWindowSystem->m_damaged = true;
-            m_currentLayer->damaged = false;
+            if ((*currentS)->hasNativeContent() && (*currentS)->damaged && (*currentS)->visibility && (*currentS)->opacity>0.0f)
+            {
+                return true;
+            }
         }
     }
 
-    for(std::list<Surface*>::const_iterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++)
+    return false;
+}
+
+// Reports whether the passed in layers have visible damage or are otherwise
+// dirty because render properties changed.
+// Assumes that layers in the list belong to same composition. ie. damage to
+// one layer affects the others.  A warning is logged if the assumption is wrong.
+bool GLESGraphicsystem::needsRedraw(LayerList layers)
+{
+    // TODO: Ignore damage from completely obscured surfaces
+
+    for (LayerListConstIterator layer = layers.begin(); layer != layers.end(); layer++)
     {
-        (*currentS)->damaged = false;
-        (*currentS)->renderPropertyChanged = false;
+        if ((*layer)->getLayerType() == Hardware && layers.size() > 1)
+        {
+            // Damage in a hardware layer should not imply a redraw in other layers
+            LOG_WARNING("GLESGraphicsystem", "needsRedraw() called with layers not in the same composition");
+        }
+
+        if (needsRedraw(*layer))
+        {
+            return true;
+        }
     }
 
-    m_currentLayer->renderPropertyChanged = false;
+    return false;
 }
 
-void GLESGraphicsystem::renderSWLayer()
+void GLESGraphicsystem::renderSWLayer(Layer *layer, bool clear)
 {
-    if ( (m_currentLayer)->visibility && (m_currentLayer)->opacity > 0.0 )
+    beginLayer(layer);
+
+    if ((layer->getLayerType() != Software_2D) &&
+        (layer->getLayerType() != Software_2_5D))
+    {
+        LOG_WARNING("GLESGraphicsystem", "renderSWLayer() called with a non-SW layer");
+    }
+
+    if (clear)
     {
-        SurfaceList surfaces = m_currentLayer->getAllSurfaces();
-        for(std::list<Surface*>::const_iterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++)
+        clearBackground();
+    }
+
+    if ( layer->visibility && layer->opacity > 0.0 )
+    {
+        SurfaceList surfaces = layer->getAllSurfaces();
+        for(SurfaceListConstIterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++)
         {
             if ((*currentS)->hasNativeContent() && (*currentS)->visibility && (*currentS)->opacity>0.0f)
             {
-                Surface* currentSurface = (Surface*)*currentS;
-                renderSurface(currentSurface);
+                renderSurface(*currentS);
             }
         }
     }
+
+    endLayer();
+}
+
+void GLESGraphicsystem::renderSWLayers(LayerList layers, bool clear)
+{
+    // This is a stub.
+    //
+    // TODO: render in a more optimal way
+    //   1. Turn off blending for first surface rendered
+    //   2. Don't clear when it's legal to avoid it
+    //         eg. a fullscreen opaque surface exists
+    //   3. Render multiple surfaces at time via multi-texturing
+    //   4. Remove fully obscured layers/surfaces
+    if (clear)
+    {
+        clearBackground();
+    }
+
+    for (LayerListConstIterator layer = layers.begin(); layer != layers.end(); layer++)
+    {
+        renderSWLayer(*layer, false); // Don't clear
+    }
 }
 
 void GLESGraphicsystem::endLayer()
index 3fb1377..ce53d68 100644 (file)
@@ -248,65 +248,98 @@ void GLXGraphicsystem::beginLayer(Layer* currentLayer)
 /*    glTranslatef(layerDestination.x, layerDestination.y, 0.0); */
 }
 
-void GLXGraphicsystem::checkRenderLayer()
+// Reports whether a single layer is damaged/dirty
+// Can not account for possible occlusion by other layers
+bool GLXGraphicsystem::needsRedraw(Layer *layer)
 {
-    SurfaceList surfaces = m_currentLayer->getAllSurfaces();
-
-    m_currentLayer->damaged = false;
+    if (layer->renderPropertyChanged)
+    {
+        return true;
+    }
 
-    if (!m_baseWindowSystem->m_forceComposition && (!m_baseWindowSystem->m_damaged || m_currentLayer->getLayerType() == Hardware))
+    if (layer->visibility && layer->opacity > 0.0)
     {
-        if (m_currentLayer->renderPropertyChanged)
-        {
-            m_currentLayer->damaged = true;
-        }
-        else if ((m_currentLayer)->visibility && (m_currentLayer)->opacity > 0.0)
+        SurfaceList surfaces = layer->getAllSurfaces();
+        for(SurfaceListConstIterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++)
         {
-            for(std::list<Surface*>::const_iterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++)
+            if ((*currentS)->renderPropertyChanged)
             {
-                if ((*currentS)->renderPropertyChanged)
-                {
-                    m_currentLayer->damaged = true;
-                    break;
-                }
-                else if ((*currentS)->hasNativeContent() && (*currentS)->damaged && (*currentS)->visibility && (*currentS)->opacity>0.0f)
-                {
-                    m_currentLayer->damaged = true;
-                    break;
-                }
+                return true;
             }
-        }
 
-        // Preseve m_currentLayer->damaged for HW layers so that they can be updated independently
-        if (m_currentLayer->damaged && m_currentLayer->getLayerType() != Hardware)
-        {
-            m_baseWindowSystem->m_damaged = true;
-            m_currentLayer->damaged = false;
+            if ((*currentS)->hasNativeContent() && (*currentS)->damaged && (*currentS)->visibility && (*currentS)->opacity>0.0f)
+            {
+                return true;
+            }
         }
     }
+    return false;
+}
+
+// Reports whether the passed in layers have visible damage or are otherwise
+// dirty because render properties changed.
+// Assumes that layers in the list belong to same composition. ie. damage to
+// one layer affects the others.  A warning is logged if the assumption is wrong.
+bool GLXGraphicsystem::needsRedraw(LayerList layers)
+{
+    // TODO: Ignore damage from completely obscured surfaces
 
-    for(std::list<Surface*>::const_iterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++)
+    for (LayerListConstIterator layer = layers.begin(); layer != layers.end(); layer++)
     {
-        (*currentS)->damaged = false;
-        (*currentS)->renderPropertyChanged = false;
-    }
+        if ((*layer)->getLayerType() == Hardware && layers.size() > 1)
+        {
+            // Damage in a hardware layer should not imply a redraw in other layers
+            LOG_WARNING("GLXGraphicsystem", "needsRedraw() called with layers not in the same composition");
+        }
 
-    m_currentLayer->renderPropertyChanged = false;
+        if (needsRedraw(*layer))
+        {
+            return true;
+        }
+    }
+    return false;
 }
 
-void GLXGraphicsystem::renderSWLayer()
+void GLXGraphicsystem::renderSWLayer(Layer *layer, bool clear)
 {
-    if ( (m_currentLayer)->visibility && (m_currentLayer)->opacity > 0.0 )
+    if (clear)
     {
-        SurfaceList surfaces = m_currentLayer->getAllSurfaces();
-        for(std::list<Surface*>::const_iterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++)
+        clearBackground();
+    }
+
+    if ( layer->visibility && layer->opacity > 0.0 )
+    {
+        SurfaceList surfaces = layer->getAllSurfaces();
+        beginLayer(layer);
+        for(SurfaceListConstIterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++)
         {
             if ((*currentS)->hasNativeContent() && (*currentS)->visibility && (*currentS)->opacity>0.0f)
             {
-                Surface* currentSurface = (Surface*)*currentS;
-                renderSurface(currentSurface);
+                renderSurface(*currentS);
             }
         }
+        endLayer();
+    }
+}
+
+void GLXGraphicsystem::renderSWLayers(LayerList layers, bool clear)
+{
+    // This is a stub.
+    //
+    // TODO: render in a more optimal way
+    //   1. Turn off blending for first surface rendered
+    //   2. Don't clear when it's legal to avoid it
+    //         eg. a fullscreen opaque surface exists
+    //   3. Render multiple surfaces at time via multi-texturing
+    //   4. Remove fully obscured layers/surfaces
+    if (clear)
+    {
+        clearBackground();
+    }
+
+    for (LayerListConstIterator layer = layers.begin(); layer != layers.end(); layer++)
+    {
+        renderSWLayer(*layer, false); // Don't clear
     }
 }
 
diff --git a/LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/BaseWindowSystem.cpp b/LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/BaseWindowSystem.cpp
new file mode 100644 (file)
index 0000000..913f854
--- /dev/null
@@ -0,0 +1,40 @@
+/***************************************************************************
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#include "WindowSystems/BaseWindowSystem.h"
+
+void BaseWindowSystem::ClearDamage()
+{
+    LayerList layers = m_pScene->getCurrentRenderOrder();
+    for (LayerListIterator layer = layers.begin(); layer != layers.end(); layer++)
+    {
+        SurfaceList surfaces = (*layer)->getAllSurfaces();
+        for (SurfaceListIterator surface = surfaces.begin(); surface != surfaces.end(); surface++)
+        {
+            // Clear Surface Damage
+            (*surface)->damaged = false;
+            (*surface)->renderPropertyChanged = false;
+        }
+        // Clear Layer Damage
+        (*layer)->damaged = false;
+        (*layer)->renderPropertyChanged = false;
+    }
+    // Clear Window System Damage
+    m_damaged = false;
+}
index e66867e..d53dd97 100644 (file)
@@ -295,48 +295,35 @@ void WaylandBaseWindowSystem::calculateFps()
     // }
 }
 
-void WaylandBaseWindowSystem::CheckRedrawAllLayers()
+void WaylandBaseWindowSystem::RedrawAllLayers(bool clear, bool swap)
 {
-    std::list<Layer*> layers = m_pScene->getCurrentRenderOrder();
-    for(std::list<Layer*>::const_iterator current = layers.begin(); current != layers.end(); current++)
-    {
-        Layer* currentLayer = (Layer*)*current;
-        graphicSystem->beginLayer(currentLayer);
-        graphicSystem->checkRenderLayer();
-        graphicSystem->endLayer();
-    }
-}
-
-void WaylandBaseWindowSystem::RedrawAllLayers()
-{
-    std::list<Layer*> layers = m_pScene->getCurrentRenderOrder();
-    bool bRedraw = m_forceComposition || m_damaged || (m_systemState == REDRAW_STATE);
+    LayerList layers = m_pScene->getCurrentRenderOrder();
+    LayerList swLayers;
+    // TODO: bRedraw is overly conservative if layers includes a hardware layer
+    bool bRedraw = m_forceComposition || needsRedraw(layers) || (m_systemState == REDRAW_STATE);
 
-    // m_damaged represents that SW composition is required
-    // At this point if a layer has damaged = true then it must be a HW layer that needs update.
-    // A SW layer which needs update will make m_damaged = true
     if (bRedraw)
     {
         graphicSystem->activateGraphicContext();
 #ifndef WL_OMIT_CLEAR_GB
-        graphicSystem->clearBackground();
+        if (clear)
+        {
+            graphicSystem->clearBackground();
+        }
 #endif /* WL_OMIT_CLEAR_GB */
     }
     for(std::list<Layer*>::const_iterator current = layers.begin(); current != layers.end(); current++)
     {
         if ((*current)->getLayerType() == Hardware)
         {
-            if (m_forceComposition || (*current)->damaged)
+            if (m_forceComposition || graphicSystem->needsRedraw(*current))
             {
                 renderHWLayer(*current);
-                (*current)->damaged = false;
             }
         }
         else if (bRedraw)
         {
-            graphicSystem->beginLayer(*current);
-            graphicSystem->renderSWLayer();
-            graphicSystem->endLayer();
+            swLayers.push_back(*current);
         }
     }
     if (bRedraw)
@@ -345,15 +332,34 @@ void WaylandBaseWindowSystem::RedrawAllLayers()
         struct timeval tv_s;
         struct timeval tv_e;
         float timeSinceLastCalc = 0.0;
+        //glFinish();
         gettimeofday(&tv_s, NULL);
-        graphicSystem->swapBuffers();
+        graphicSystem->renderSWLayers(swLayers, false); // Already cleared
+        if (swap)
+        {
+            graphicSystem->swapBuffers();
+        }
+        //glFinish();
         gettimeofday(&tv_e, NULL);
         timeSinceLastCalc = (float)(tv_e.tv_sec-tv_s.tv_sec) + 0.000001*((float)(tv_e.tv_usec-tv_s.tv_usec));
         LOG_INFO("WaylandBaseWindowSystem", "swapBuffers" << timeSinceLastCalc);
 #else
-        graphicSystem->swapBuffers();
+        graphicSystem->renderSWLayers(swLayers, false); // Already cleared
+        if (swap)
+        {
+            graphicSystem->swapBuffers();
+        }
 #endif
         graphicSystem->releaseGraphicContext();
+
+        if (m_debugMode)
+        {
+            printDebug();
+        }
+
+        calculateFps();
+
+        m_systemState = IDLE_STATE;
     }
 }
 
@@ -371,27 +377,12 @@ void WaylandBaseWindowSystem::Redraw()
     /*LOG_INFO("WaylandBaseWindowSystem","Locking List");*/
     m_pScene->lockScene();
 
-    CheckRedrawAllLayers();
-    RedrawAllLayers();
+    RedrawAllLayers(true, true); // Clear and Swap
+    ClearDamage();
 
     m_pScene->unlockScene();
 
-    if (m_forceComposition || m_damaged || (m_systemState == REDRAW_STATE))
-    {
-        // TODO: This block won't be executed for HW only changes
-        // Is that acceptable?
-        if (m_debugMode)
-        {
-            printDebug();
-        }
-
-        calculateFps();
-
-        /* Reset the damage flag, all is up to date */
-        m_forceComposition = false;
-        m_damaged = false;
-        m_systemState = IDLE_STATE;
-    }
+    m_forceComposition = false;
 }
 
 void WaylandBaseWindowSystem::Screenshot()
@@ -399,49 +390,38 @@ void WaylandBaseWindowSystem::Screenshot()
     /*LOG_INFO("WaylandBaseWindowSystem","Locking List");*/
     m_pScene->lockScene();
     graphicSystem->activateGraphicContext();
-    graphicSystem->clearBackground();
 
-    if (m_takeScreenshot==ScreenshotOfDisplay)
+    if (m_takeScreenshot == ScreenshotOfDisplay)
     {
         LOG_DEBUG("WaylandBaseWindowSystem", "Taking screenshot");
-        std::list<Layer*> layers = m_pScene->getCurrentRenderOrder();
-
-        for(std::list<Layer*>::const_iterator current = layers.begin(); current != layers.end(); current++)
-        {
-            if ((*current)->getLayerType() != Hardware)
-            {
-                graphicSystem->beginLayer(*current);
-                graphicSystem->renderSWLayer();
-                graphicSystem->endLayer();
-            }
-        }
+        RedrawAllLayers(true, false); // Do clear, Don't swap
     }
-    else if(m_takeScreenshot==ScreenshotOfLayer)
+    else if(m_takeScreenshot == ScreenshotOfLayer)
     {
         LOG_DEBUG("WaylandBaseWindowSystem", "Taking screenshot of layer");
-        Layer* currentLayer = m_pScene->getLayer(m_screenShotLayerID);
+        Layer* layer = m_pScene->getLayer(m_screenShotLayerID);
 
-        if (currentLayer!=NULL){
-            graphicSystem->beginLayer(currentLayer);
-            graphicSystem->renderSWLayer();
-            graphicSystem->endLayer();
+        if (layer != NULL)
+        {
+            graphicSystem->renderSWLayer(layer, true); // Do clear
         }
     }
-    else if(m_takeScreenshot==ScreenshotOfSurface)
+    else if(m_takeScreenshot == ScreenshotOfSurface)
     {
         LOG_DEBUG("WaylandBaseWindowSystem", "Taking screenshot of surface");
-        Layer* currentLayer = m_pScene->getLayer(m_screenShotLayerID);
-        Surface* currentSurface = m_pScene->getSurface(m_screenShotSurfaceID);
+        Layer* layer = m_pScene->getLayer(m_screenShotLayerID);
+        Surface* surface = m_pScene->getSurface(m_screenShotSurfaceID);
 
-        if (currentLayer!=NULL && currentSurface!=NULL){
-            graphicSystem->beginLayer(currentLayer);
-            graphicSystem->renderSurface(currentSurface);
+        graphicSystem->clearBackground();
+        if (layer != NULL && surface != NULL)
+        {
+            graphicSystem->beginLayer(layer);
+            graphicSystem->renderSurface(surface);
             graphicSystem->endLayer();
         }
     }
 
     graphicSystem->saveScreenShotOfFramebuffer(m_screenShotFile);
-//  graphicSystem->swapBuffers();
     m_takeScreenshot = ScreenShotNone;
     LOG_DEBUG("WaylandBaseWindowSystem", "Done taking screenshot");
 
index f62431a..14b5878 100644 (file)
@@ -595,49 +595,43 @@ void X11WindowSystem::calculateFps()
     }
 }
 
-void X11WindowSystem::CheckRedrawAllLayers()
+void X11WindowSystem::RedrawAllLayers(bool clear, bool swap)
 {
-    std::list<Layer*> layers = m_pScene->getCurrentRenderOrder();
-    for(std::list<Layer*>::const_iterator current = layers.begin(); current != layers.end(); current++)
-    {
-        Layer* currentLayer = (Layer*)*current;
-        graphicSystem->beginLayer(currentLayer);
-        graphicSystem->checkRenderLayer();
-        graphicSystem->endLayer();
-    }
-}
-
-void X11WindowSystem::RedrawAllLayers()
-{
-    std::list<Layer*> layers = m_pScene->getCurrentRenderOrder();
+    LayerList layers = m_pScene->getCurrentRenderOrder();
+    LayerList swLayers;
 
-    // m_damaged represents that SW composition is required
-    // At this point if a layer has damaged = true then it must be a HW layer that needs update.
-    // A SW layer which needs update will make m_damaged = true
-    if (m_forceComposition || m_damaged)
-    {
-        graphicSystem->clearBackground();
-    }
-    for(std::list<Layer*>::const_iterator current = layers.begin(); current != layers.end(); current++)
+    // Refresh HW Layers, find SW Layers
+    for(LayerListConstIterator current = layers.begin(); current != layers.end(); current++)
     {
         if ((*current)->getLayerType() == Hardware)
         {
-            if (m_forceComposition || (*current)->damaged)
+            // Redraw HW layers independently of other layers
+            if (m_forceComposition || graphicSystem->needsRedraw(*current))
             {
                 renderHWLayer(*current);
-                (*current)->damaged = false;
             }
         }
-        else if (m_forceComposition || m_damaged)
+        else
         {
-            graphicSystem->beginLayer(*current);
-            graphicSystem->renderSWLayer();
-            graphicSystem->endLayer();
+            swLayers.push_back(*current);
         }
     }
-    if (m_forceComposition || m_damaged)
+
+    if (m_forceComposition || graphicSystem->needsRedraw(swLayers))
     {
-        graphicSystem->swapBuffers();
+        graphicSystem->renderSWLayers(swLayers, clear);
+
+        if (swap)
+        {
+            graphicSystem->swapBuffers();
+        }
+
+        if (debugMode)
+        {
+            printDebug();
+        }
+
+        calculateFps();
     }
 }
 
@@ -649,78 +643,52 @@ void X11WindowSystem::renderHWLayer(Layer *layer)
 void X11WindowSystem::Redraw()
 {
     // draw all the layers
-    //graphicSystem->clearBackground();
     /*LOG_INFO("X11WindowSystem","Locking List");*/
     m_pScene->lockScene();
 
-    CheckRedrawAllLayers();
-    RedrawAllLayers();
+    RedrawAllLayers(true, true);  // Clear and Swap
+    ClearDamage();
 
     m_pScene->unlockScene();
 
-    if (m_forceComposition || m_damaged)
-    {
-        // TODO: This block won't be executed for HW only changes
-        // Is that acceptable?
-       if (debugMode)
-        {
-            printDebug();
-        }
-
-        calculateFps();
-
-        /* Reset the damage flag, all is up to date */
-        m_forceComposition = false;
-        m_damaged = false;
-    }
+    m_forceComposition = false;
 }
 
 void X11WindowSystem::Screenshot()
 {
     /*LOG_INFO("X11WindowSystem","Locking List");*/
     m_pScene->lockScene();
-    graphicSystem->clearBackground();
-    if (takeScreenshot==ScreenshotOfDisplay)
+    if (takeScreenshot == ScreenshotOfDisplay)
     {
         LOG_DEBUG("X11WindowSystem", "Taking screenshot");
-        std::list<Layer*> layers = m_pScene->getCurrentRenderOrder();
-
-        for(std::list<Layer*>::const_iterator current = layers.begin(); current != layers.end(); current++)
-        {
-            if ((*current)->getLayerType() != Hardware)
-            {
-                graphicSystem->beginLayer(*current);
-                graphicSystem->renderSWLayer();
-                graphicSystem->endLayer();
-            }
-        }
+        RedrawAllLayers(true, false);  // Do clear, Don't swap
     }
-    else if(takeScreenshot==ScreenshotOfLayer)
+    else if(takeScreenshot == ScreenshotOfLayer)
     {
         LOG_DEBUG("X11WindowSystem", "Taking screenshot of layer");
-        Layer* currentLayer = m_pScene->getLayer(screenShotLayerID);
+        Layer* layer = m_pScene->getLayer(screenShotLayerID);
 
-        if (currentLayer!=NULL){
-            graphicSystem->beginLayer(currentLayer);
-            graphicSystem->renderSWLayer();
-            graphicSystem->endLayer();
+        if (layer != NULL)
+        {
+            graphicSystem->renderSWLayer(layer, true); // Do clear
         }
     }
-    else if(takeScreenshot==ScreenshotOfSurface)
+    else if(takeScreenshot == ScreenshotOfSurface)
     {
         LOG_DEBUG("X11WindowSystem", "Taking screenshot of surface");
-        Layer* currentLayer = m_pScene->getLayer(screenShotLayerID);
-        Surface* currentSurface = m_pScene->getSurface(screenShotSurfaceID);
+        Layer* layer = m_pScene->getLayer(screenShotLayerID);
+        Surface* surface = m_pScene->getSurface(screenShotSurfaceID);
 
-        if (currentLayer!=NULL && currentSurface!=NULL){
-            graphicSystem->beginLayer(currentLayer);
-            graphicSystem->renderSurface(currentSurface);
+        graphicSystem->clearBackground();
+        if (layer != NULL && surface != NULL)
+        {
+            graphicSystem->beginLayer(layer);
+            graphicSystem->renderSurface(surface);
             graphicSystem->endLayer();
         }
     }
 
     graphicSystem->saveScreenShotOfFramebuffer(screenShotFile);
-//  graphicSystem->swapBuffers();
     takeScreenshot = ScreenShotNone;
     LOG_DEBUG("X11WindowSystem", "Done taking screenshot");
     m_pScene->unlockScene();
@@ -958,7 +926,7 @@ init_complete:
             this->m_systemState = IDLE_STATE;
 
             // check if we are supposed to take screenshot
-            if (this->takeScreenshot!=ScreenShotNone)
+            if (this->takeScreenshot != ScreenShotNone)
             {
                 this->Screenshot();
             }