uiacceltk/hitchcock/coretoolkit/src/HuiCanvasVisual.cpp
branchRCL_3
changeset 3 d8a3531bc6b8
parent 0 15bf7259bb7c
child 7 433cbbb6a04b
--- a/uiacceltk/hitchcock/coretoolkit/src/HuiCanvasVisual.cpp	Tue Feb 02 07:56:43 2010 +0200
+++ b/uiacceltk/hitchcock/coretoolkit/src/HuiCanvasVisual.cpp	Mon Feb 22 17:57:49 2010 +0200
@@ -46,6 +46,9 @@
 
 #include "HuiFxEffect.h"
 #include "HuiCmdBufferBrush.h"
+#include "huiextension.h"
+
+#include "huiwscanvascommands.h"
 
 /** Flag to convienintly disable/enable canvas render buffer usage if needed */
 /* Turned to EFalse as DFS77 was having booting problems in wk26 */
@@ -93,7 +96,9 @@
 void CHuiCanvasVisual::ConstructL()
     {
     CHuiLayout::ConstructL();
-        
+
+    SetFlags(EHuiVisualFlagWserv);
+    
     iCanvasVisualData = new (ELeave) THuiCanvasVisualData;
     iCanvasVisualData->iCommandSetType = ECommandBufferWs;
     iCanvasVisualData->iCanvasFlags = 0;   
@@ -101,13 +106,13 @@
     iCanvasVisualData->iParentCanvas = NULL;
     iCanvasVisualData->iBackground = NULL;
     iCanvasVisualData->iCanvasPainter = NULL;
+    iCanvasVisualData->iStoredRenderBuffer = 0;
     
     iCanvasVisualData->iBackground = CHuiCanvasBackground::NewL();
     iCanvasVisualData->iBackground->SetVisual(this);
     
     iCanvasVisualData->iCanvasPainter = CHuiCanvasWsPainter::NewL();
     iCanvasVisualData->iCanvasPainter->SetVisual(this);
-    iCanvasVisualData->iStoredRenderBuffer = 0;
     
     TBool useCanvasRenderBuffer = CHuiStatic::Renderer().Allows(EHuiRenderPluginAllowVisualPBufferSurfaces);    
     iCanvasVisualData->iCanvasPainter->EnableRenderBuffer(useCanvasRenderBuffer); 
@@ -116,26 +121,34 @@
     iCanvasVisualData->iLayerExtent = TRect();
     
     // subwindow effects
-    EnableBrushesL(ETrue);
+    //EnableBrushesL(ETrue);
     }
 
 
 CHuiCanvasVisual::~CHuiCanvasVisual()
     {
-    FreeRenderBuffer();
-    if(iCanvasVisualData->iExternalContentVisual)
-    	{
-    	// Allow the external content visual to be drawn normally
-    	iCanvasVisualData->iExternalContentVisual->ClearFlag(EHuiVisualFlagDrawOnlyAsExternalContent);
-    	}
-    	
+   
+    FreeRenderBuffer();	
     if (iCanvasVisualData)
         {
+        if(iCanvasVisualData->iExternalContentVisual)
+            {
+            // Allow the external content visual to be drawn normally
+            iCanvasVisualData->iExternalContentVisual->ClearFlag(EHuiVisualFlagDrawOnlyAsExternalContent);
+            }
         ClearCommandSet();
-        delete iCanvasVisualData->iBackground;
-        iCanvasVisualData->iBackground = NULL;
-        delete iCanvasVisualData->iCanvasPainter;
-    	iCanvasVisualData->iCanvasPainter = NULL;
+        if ( iCanvasVisualData->iBackground )
+            {
+            delete iCanvasVisualData->iBackground;
+            iCanvasVisualData->iBackground = NULL;
+            }
+        if ( iCanvasVisualData->iCanvasPainter )
+            {
+            delete iCanvasVisualData->iCanvasPainter;
+            iCanvasVisualData->iCanvasPainter = NULL;
+            }
+        
+    	
     	iCanvasVisualData->iExternalContentVisual = NULL;
     	
     	// Tell parent that we are destructed
@@ -332,14 +345,17 @@
 
     if ((IsDelayedEffectSource() || Freezed()))
         {
+        // Select right draw mode
+        THuiCanvasDrawMode drawMode = (Flags() & EHuiVisualFlagOpaqueHint) ? EHuiCanvasDrawModeNormal : EHuiCanvasDrawModeBlend;
+
         if (StoredRenderBuffer())
             {
-            DrawStoredFullScreenRenderBuffer(aGc);
+            DrawStoredFullScreenRenderBuffer(drawMode, aGc);
             return;
             }
         else if (iCanvasVisualData->iStoredRenderBuffer)
             {
-            DrawStoredVisualRenderBuffer();
+            DrawStoredVisualRenderBuffer(drawMode);
             return;
 			}
         }  
@@ -492,14 +508,17 @@
 
     if ((IsDelayedEffectSource() || Freezed()))
         {
+        // Select right draw mode
+        THuiCanvasDrawMode drawMode = (Flags() & EHuiVisualFlagOpaqueHint) ? EHuiCanvasDrawModeNormal : EHuiCanvasDrawModeBlend;
+        
         if (StoredRenderBuffer())
             {
-            DrawStoredFullScreenRenderBuffer(aGc);
+            DrawStoredFullScreenRenderBuffer(drawMode, aGc);
 			return;
             }
         else if (iCanvasVisualData->iStoredRenderBuffer)
             {
-            DrawStoredVisualRenderBuffer();
+            DrawStoredVisualRenderBuffer(drawMode);
             return;
             }
         }    
@@ -590,20 +609,26 @@
     const TInt count = Count();
     for(TInt i = 0; i < count; ++i)
         {
-        // This cast is not really safe, but dynamic cast is slow
-        CHuiCanvasVisual* visual = (CHuiCanvasVisual*) iHuiLayoutPrivateData->iChildren[i];
+        CHuiVisual* visual = iHuiLayoutPrivateData->iChildren[i];
+        
         //Ignore inactive child visuals
         if ((visual->Flags()& EHuiVisualFlagInactive))
             {
             continue;
             }
         
-        if (aIncludeCanvasFlags && !(visual->CanvasFlags()& aIncludeCanvasFlags))
+        TInt canvasFlags = 0;
+        if (aIncludeCanvasFlags || aExcludeCanvasFlags)
+            {
+            canvasFlags = visual->QueryCanvasFlags();
+            }
+        
+        if (aIncludeCanvasFlags && !(canvasFlags & aIncludeCanvasFlags))
             {
             continue;
             }
 
-        if (aExcludeCanvasFlags && (visual->CanvasFlags()& aExcludeCanvasFlags))
+        if (aExcludeCanvasFlags && (canvasFlags & aExcludeCanvasFlags))
             {
             continue;
             }
@@ -649,34 +674,50 @@
    	return hasChanged;
     }
 
-TBool CHuiCanvasVisual::ChildTreeChanged(TInt aExcludeCanvasFlags) const
+// Goes through visual hierarchy and checks if any visual has changed.
+// This method does not modify any visuals. Parameter is not const 
+// because of CanvasVisual method.
+TBool CHuiCanvasVisual::RecursiveChildTreeChanged(CHuiVisual* aVisual, TInt aExcludeCanvasFlags)
     {
-    // CHuiLayout::Changed() does not check children.  
-    // This utility method checks whole child tree below this visual.
     TBool changed = EFalse;
 
     // Check wheter we should include this visual or igonre it.
     if (aExcludeCanvasFlags)
         {
-        if (!(iCanvasVisualData->iCanvasFlags & aExcludeCanvasFlags))
+        if ( !(aVisual->Flags() & EHuiVisualFlagInactive) )
             {
-            changed |= Changed();
+            TInt canvasFlags = aVisual->QueryCanvasFlags();
+                
+            if ( !(canvasFlags & aExcludeCanvasFlags) )
+                {
+                changed |= aVisual->Changed();
+                }
             }        
         }
     
-    const TInt count = Count();
-    for(TInt i = 0; i < count; ++i)
+    if ( !changed )
         {
-        CHuiCanvasVisual* visual = (CHuiCanvasVisual*) iHuiLayoutPrivateData->iChildren[i];
-        changed |= visual->ChildTreeChanged(aExcludeCanvasFlags);        
-        if (changed)
+        const TInt count = aVisual->Count();
+        for(TInt i = 0; i < count; ++i)
             {
-            break;
+            CHuiVisual* visual = &aVisual->Visual(i);
+            changed |= RecursiveChildTreeChanged( visual, aExcludeCanvasFlags );
+            if ( changed )
+                {
+                break;
+                }
             }
         }
-    return changed;
+    return changed;    
     }
 
+TBool CHuiCanvasVisual::ChildTreeChanged(TInt aExcludeCanvasFlags) const
+    {
+    // CHuiLayout::Changed() does not check children.  
+    // This utility method checks whole child tree below this visual.
+    return RecursiveChildTreeChanged(
+        const_cast<CHuiCanvasVisual*>(this), aExcludeCanvasFlags);
+    }
 
 EXPORT_C void CHuiCanvasVisual::ClearChanged()
     {
@@ -747,8 +788,11 @@
 
 EXPORT_C void CHuiCanvasVisual::ClearCommandSet()
     {
-    iCanvasVisualData->iCanvasPainter->ClearCommandSet();
-    SetChanged();
+    if ( iCanvasVisualData->iCanvasPainter )
+        {
+        iCanvasVisualData->iCanvasPainter->ClearCommandSet();
+        SetChanged();
+        }
     }
 
 #ifdef HUI_DEBUG_TRACK_DRAWING  
@@ -815,6 +859,7 @@
     
    	if (aCommandType == ECommandBufferAlf)
    	   	{
+   	   	ClearFlags(EHuiVisualFlagWserv);
    	   	delete iCanvasVisualData->iCanvasPainter;
    	   	iCanvasVisualData->iCanvasPainter = NULL;
         iCanvasVisualData->iCommandSetType = ECommandBufferAlf;    
@@ -823,6 +868,7 @@
    		}	     
     else if (aCommandType == ECommandBufferWs)
     	{
+    	SetFlags(EHuiVisualFlagWserv);
     	delete iCanvasVisualData->iCanvasPainter;
    	   	iCanvasVisualData->iCanvasPainter = NULL;
         iCanvasVisualData->iCommandSetType = ECommandBufferWs;    
@@ -983,6 +1029,31 @@
     return drawContent;       
     }
 
+// Goes through visual hierarchy and checks if any visual has external content drawing enabled.
+TBool CHuiCanvasVisual::RecursiveIsExternalContentDrawingEnabled(CHuiVisual* aVisual)
+    {
+    TBool drawExternalContent = EFalse;
+    
+    const TInt count = aVisual->Count();
+    for(TInt i = 0; i < count; ++i)
+        {
+        CHuiVisual* visual = &aVisual->Visual(i);
+        drawExternalContent |= visual->QueryExternalContentDrawingEnabled();
+        if ( drawExternalContent )
+            {
+            break;
+            }
+        
+        drawExternalContent |= RecursiveIsExternalContentDrawingEnabled( visual );
+        if ( drawExternalContent )
+            {
+            break;
+            }
+        }
+    
+    return drawExternalContent;    
+    }
+
 TBool CHuiCanvasVisual::IsExternalContentDrawingEnabled(TBool aIncludeChildren) const
     {
     TBool drawExternalContent = EFalse;
@@ -990,13 +1061,10 @@
         {
         drawExternalContent = ETrue;    
         }
-    if (aIncludeChildren)
+    if (aIncludeChildren && !drawExternalContent)
         {
-        for (TInt i=0; !drawExternalContent && i<Count(); i++)
-             {
-             CHuiCanvasVisual* canvasVisual = (CHuiCanvasVisual*) &Visual(i);
-             drawExternalContent |= canvasVisual->IsExternalContentDrawingEnabled(ETrue);
-             }
+        drawExternalContent |= RecursiveIsExternalContentDrawingEnabled(
+            const_cast<CHuiCanvasVisual*>(this));        
         }
     return drawExternalContent;       
     }
@@ -1055,6 +1123,11 @@
 
 EXPORT_C void CHuiCanvasVisual::SetLayerUsesAlphaFlag(TBool aEnabled)
     {
+    if (aEnabled == KWindowIsDSAHost)
+        {
+        iCanvasVisualData->iCanvasFlags |= EHuiCanvasFlagDisableCanvasContent;        
+        return;    
+        }    
     iCanvasVisualData->iLayerUsesAlphaFlag = aEnabled;
     }
 
@@ -1118,7 +1191,8 @@
         }
     else // background surface was removed
         {
-        EnableTransformationL(EFalse);
+        iCanvasVisualData->iCanvasFlags &= (~EHuiCanvasFlagDisableCanvasContent);    
+        //EnableTransformationL(EFalse);
         }
     }
 
@@ -1154,17 +1228,39 @@
         }
     }
 
-void CHuiCanvasVisual::DrawStoredVisualRenderBuffer() const
+void CHuiCanvasVisual::DrawStoredVisualRenderBuffer(TInt aCanvasDrawMode) const
     {
     CHuiCanvasGc& gc = CanvasGc();
+    CHuiCanvasVisual* visual = NULL; 
+    TBool transparent = EffectiveOpacity() < 1.0f;
+    gc.SetDrawMode((THuiCanvasDrawMode)aCanvasDrawMode);
+    if (transparent)
+        {
+        gc.EnableEffectiveOpacity(ETrue);  
+        visual = gc.Visual();
+        gc.SetVisual(*this);
+        gc.SetDrawMode(EHuiCanvasDrawModeBlend);
+        }
     THuiRealPoint dest_point = DisplayRect().iTl;
     CHuiCanvasRenderBuffer *stored = iCanvasVisualData->iStoredRenderBuffer;
+
     gc.DrawImage(*stored, dest_point);
+    if (transparent)
+        {
+        gc.SetVisual(*visual);
+        gc.EnableEffectiveOpacity(EFalse);
+        }
     }
 
-void CHuiCanvasVisual::DrawStoredFullScreenRenderBuffer(CHuiGc& aGc) const
+void CHuiCanvasVisual::DrawStoredFullScreenRenderBuffer(TInt aCanvasDrawMode, CHuiGc& aGc) const
     {
     if (!Display()) return;
+    if (!iHuiLayoutPrivateData->iGc)
+        {
+        CHuiRenderPlugin& renderplugin = CHuiStatic::Renderer();
+		// deleted in CHuiLayout destructor or CHuiCanvasVisual::FreeRenderBuffer when not needed anymore
+        iHuiLayoutPrivateData->iGc = renderplugin.CreateCanvasGcL();
+        }
     CHuiCanvasGc& gc = *iHuiLayoutPrivateData->iGc;
     gc.SetGc(aGc);
     gc.SetDefaults();
@@ -1182,8 +1278,23 @@
     
     THuiRealPoint dest_point = DisplayRect().iTl;
     CHuiCanvasRenderBuffer *stored = StoredRenderBuffer();
-    gc.DrawImage(*stored, dest_point); 
-
+    TBool transparent = EffectiveOpacity() < 1.0f;
+    CHuiCanvasVisual* visual = NULL; 
+	gc.SetDrawMode((THuiCanvasDrawMode)aCanvasDrawMode);
+    if (transparent)
+        {
+        
+        gc.EnableEffectiveOpacity(ETrue);  
+        visual = gc.Visual();
+        gc.SetVisual(*this);
+        gc.SetDrawMode(EHuiCanvasDrawModeBlend);
+        }
+    gc.DrawImage(*stored, dest_point);
+    if (transparent)
+        {
+        gc.SetVisual(*visual);
+        gc.EnableEffectiveOpacity(EFalse);
+        }
     gc.PopTransformationMatrix();
     }
 
@@ -1195,24 +1306,47 @@
             {
             delete iCanvasVisualData->iStoredRenderBuffer;
             iCanvasVisualData->iStoredRenderBuffer = NULL;
+            delete iHuiLayoutPrivateData->iGc;
+            iHuiLayoutPrivateData->iGc = NULL;
             }
         }
     }
 
+// Goes through visual hierarchy and checks if any visual has command buffers
+// or other drawable content.
+TBool CHuiCanvasVisual::RecursiveHasCommandBuffers(CHuiVisual* aVisual)
+    {
+    TBool hasCommandBuffers = EFalse;
+    
+    const TInt count = aVisual->Count();
+    for(TInt i = 0; i < count; ++i)
+        {
+        CHuiVisual* visual = &aVisual->Visual(i);
+        // If visual is a canvas one, then QueryHasDrawableContent returns 
+        // HasCommandBuffers(EFalse)
+        hasCommandBuffers |= visual->QueryHasDrawableContent();
+        if ( hasCommandBuffers )
+            {
+            break;
+            }
+        
+        hasCommandBuffers |= RecursiveHasCommandBuffers( visual );
+        if ( hasCommandBuffers )
+            {
+            break;
+            }
+        }
+    
+    return hasCommandBuffers;    
+    }
+
 EXPORT_C TBool CHuiCanvasVisual::HasCommandBuffers(TBool aIncludeChildren) const
     {
     TBool hasCommandBuffers = iCanvasVisualData->iCanvasPainter->HasCommandBuffers();
-    if (aIncludeChildren)
+    if (aIncludeChildren && !hasCommandBuffers)
         {
-        for (TInt i=0; i<Count(); i++)
-            {
-            CHuiCanvasVisual* canvasVisual = (CHuiCanvasVisual*) &Visual(i); // Dynamic cast is too slow for us ;)
-            hasCommandBuffers |= canvasVisual->HasCommandBuffers(aIncludeChildren);
-            if (hasCommandBuffers)
-                {
-                break;
-                }
-            }
+        // Include children branch - just check if there is something to draw.
+        hasCommandBuffers |= RecursiveHasCommandBuffers(const_cast<CHuiCanvasVisual*>(this));
         }
     return hasCommandBuffers;
     }
@@ -1267,4 +1401,31 @@
     return THuiLayoutChildRectLayoutUpdateNeeded;
     }
 
-
+void CHuiCanvasVisual::VisualExtension(const TUid& aExtensionUid, TAny** aExtensionParams)
+    {
+    if (aExtensionUid == KHuiVisualQueryUid && aExtensionParams && *aExtensionParams)
+        {
+        THuiVisualQueryParams* params = static_cast<THuiVisualQueryParams*>(*aExtensionParams);
+        switch (params->iQueryType)
+            {
+        case THuiVisualQueryParams::EQueryCanvasFlags:
+            params->iValue = CanvasFlags();
+            params->iResult = KErrNone;
+            break;
+        case THuiVisualQueryParams::EQueryExternalContentDrawingEnabled:
+            params->iValue = IsExternalContentDrawingEnabled(EFalse);
+            params->iResult = KErrNone;
+            break;
+        case THuiVisualQueryParams::EQueryHasDrawableContent:
+            params->iValue = HasCommandBuffers(EFalse);
+            params->iResult = KErrNone;
+            break;
+        default:
+            break;
+            }
+        }
+    else
+	    {
+		CHuiVisual::VisualExtension(aExtensionUid, aExtensionParams);
+		}
+    }