uiacceltk/hitchcock/coretoolkit/src/HuiCmdBufferBrush.cpp
changeset 0 15bf7259bb7c
child 3 d8a3531bc6b8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/src/HuiCmdBufferBrush.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,368 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:   
+*
+*/
+
+#include "HuiCmdBufferBrush.h"
+#include "HuiFxEffect.h"
+#include <uiacceltk/HuiBrushArray.h>
+#include "huicanvasgc.h"
+#include "huicanvaswsgc.h"
+#include "huicanvaswshwgc.h"
+#include "huicanvaspainter.h"
+#include "huicanvaswspainter.h"
+CHuiCmdBufferBrush *CHuiCmdBufferBrush::NewL(TInt aLayerId, CHuiCanvasGc &aGc, CHuiCanvasWsGc &aWsGc, CHuiCanvasVisual &aVisual, CHuiCanvasPainter &aPainter)
+    {
+    CHuiCmdBufferBrush *brush = new (ELeave) CHuiCmdBufferBrush(aGc, aWsGc);
+    CleanupStack::PushL(brush);
+    brush->ConstructL(aLayerId, aVisual, aPainter);
+    CleanupStack::Pop(brush);
+    return brush;
+    }
+CHuiCmdBufferBrush::CHuiCmdBufferBrush( CHuiCanvasGc &aGc, CHuiCanvasWsGc &aWsGc )
+    : iCanvasGc(aGc), iCanvasWsGc(aWsGc)
+    {
+    }
+
+
+void CHuiCmdBufferBrush::ConstructL(TInt aLayerId, CHuiCanvasVisual &aVisual, CHuiCanvasPainter &aPainter)
+    {
+    iLayerId = aLayerId;
+    iVisual = &aVisual;
+    iCanvasPainter = &aPainter;
+    }
+CHuiCmdBufferBrush::~CHuiCmdBufferBrush()
+    {
+    TInt count = iBuffers.Count();
+    for(int i=0;i<count;i++)
+        {
+        CHuiCanvasCommandBuffer *buf = iBuffers[i].iCommandBuffer;
+        buf->RemoveDestroyObserver(this);
+        }
+    }
+TInt CHuiCmdBufferBrush::Type2() const { return ECmdBufferBrush; }
+
+void CHuiCmdBufferBrush::AddBufferL(TLayeredBuffer aBuffer)
+    {
+    iBuffers.AppendL(aBuffer);
+    }
+
+
+void CHuiCmdBufferBrush::Draw(CHuiGc& aGc, const MHuiBrushGuide& aGuide) const
+    {
+    THuiRealRect brushRect = aGuide.BrushRect();
+    DrawSelf(aGc, brushRect);
+    }
+void CHuiCmdBufferBrush::DrawSelf(CHuiGc &aGc, THuiRealRect brushRect) const
+{    
+    iCanvasGc.SetVisual(*iVisual);
+    iCanvasGc.SetGc(aGc);
+    iCanvasGc.SetDefaults();   
+    //iCanvasPainter->EnableRenderBuffer(ETrue);
+    //static_cast<CHuiCanvasWsPainter*>(iCanvasPainter)->EnableRenderBufferIfNeeded(ETrue);
+
+    TRect displayRect = brushRect.Round();
+    
+    RRegion reg;
+    TInt size = iBuffers.Count();
+    for(int i=0;i<size;i++)
+        {
+        TRect rect = iBuffers[i].iBoundingRectangle;
+
+        RDebug::Print(_L("TP: ClearBackground %d"), iLayerId);
+        ClearBackground(aGc, rect);
+
+        rect.iTl.iX += brushRect.iTl.iX;
+        rect.iTl.iY += brushRect.iTl.iY;
+        rect.iBr.iX += brushRect.iTl.iX;
+        rect.iBr.iY += brushRect.iTl.iY;
+        reg.AddRect(rect);
+        }
+    iCanvasWsGc.BeginActionL(EDrawBuffer,reg.BoundingRect() /*displayRect*/,*iVisual,EFalse,reg);                   
+
+    for(int i2=0;i2<size;i2++)
+        {
+        TRect rect = iBuffers[i2].iBoundingRectangle;
+
+        rect.iTl.iX += brushRect.iTl.iX;
+        rect.iTl.iY += brushRect.iTl.iY;
+        rect.iBr.iX += brushRect.iTl.iX;
+        rect.iBr.iY += brushRect.iTl.iY;
+
+        RRegion region;
+        region.AddRect(rect);
+        for(int ii2 = i2+1;ii2<size; ii2++)
+            {
+            TRect rect2 = iBuffers[ii2].iBoundingRectangle;
+
+            rect2.iTl.iX += brushRect.iTl.iX;
+            rect2.iTl.iY += brushRect.iTl.iY;
+            rect2.iBr.iX += brushRect.iTl.iX;
+            rect2.iBr.iY += brushRect.iTl.iY;
+            if (iBuffers[i2].iCommandBuffer != iBuffers[ii2].iCommandBuffer)
+                {
+                region.SubRect(rect2);
+                }
+            }
+        region.Intersect(iBuffers[i2].iCommandBuffer->iUpdateRegion);
+            
+        if (!region.IsEmpty())
+            {
+            
+            //iCanvasWsGc.BeginActionL(EScanBuffer,rect /*displayRect*/,*iVisual,EFalse,region);                   
+            //DrawDrawingCommands(EScanBuffer, aGc, rect, iBuffers[i2].iBufferPart, iBuffers[i2].iCommandBuffer, region);
+            //iCanvasWsGc.EndActionL(region);                 
+
+            DrawDrawingCommands(EDrawBuffer, aGc, rect, iBuffers[i2].iBufferPart, iBuffers[i2].iCommandBuffer, region);
+            }
+        region.Close();
+        }
+    {
+    TInt flags = iVisual->Flags();
+    iVisual->ClearFlag(EHuiVisualFlagOpaqueHint);
+    iCanvasWsGc.EndActionL(reg, ETrue);                     
+    iVisual->SetFlags(flags);
+    }
+
+    reg.Close();
+    
+#if 0
+    for(int i3=0;i3<size;i3++)
+        {
+        TRect rect = iBuffers[i3].iBoundingRectangle;
+        rect.iTl.iX += brushRect.iTl.iX;
+        rect.iTl.iY += brushRect.iTl.iY;
+        rect.iBr.iX += brushRect.iTl.iX;
+        rect.iBr.iY += brushRect.iTl.iY;
+        CopyBuffer(aGc, rect);
+        }
+#endif
+
+    }
+
+void CHuiCmdBufferBrush::ClearBackground(CHuiGc &aGc, TRect aRectangle) const
+    {
+    //void DrawRects(RArray<THuiRealRect>& aRects);
+#if 0
+    THuiRealPoint tl(aRectangle.iTl.iX, aRectangle.iTl.iY);
+    THuiRealPoint br(aRectangle.iBr.iX, aRectangle.iBr.iY);
+    THuiRealRect rect(tl, br);
+    TReal32 opacity = iCanvasGc.Opacity();
+    iCanvasGc.SetOpacity(0.0f);
+    iCanvasGc.Clear(rect);
+    iCanvasGc.SetOpacity(opacity);
+#endif
+
+    CHuiCanvasRenderBuffer* renderbuffer = NULL;
+    renderbuffer = iVisual->Env().CanvasTextureCache().FindCachedRenderBuffer(*iVisual);
+    iCanvasGc.ClearRenderBuffer(*renderbuffer, aRectangle /*TRect(0,0,iVisual->DisplayRect().Size().iWidth, iVisual->DisplayRect().Size().iHeight)*/);
+    }
+void CHuiCmdBufferBrush::DrawDrawingCommands(TInt aAction, CHuiGc &aGc, TRect aClippingRectangle, 
+                                             TPtrC8 aCommands, CHuiCanvasCommandBuffer *buf, const TRegion &reg) const
+    {
+    TRect rect = aClippingRectangle;
+    RDebug::Print(_L("TP: DrawDrawingCommands (%d,%d)-(%d,%d)"), rect.iTl.iX, rect.iTl.iY, rect.iBr.iX, rect.iBr.iY);    
+
+    //iCanvasWsGc.EnableUpdateRegion(reg /*buf->iUpdateRegion*/, EFalse /*aClearBeforeHandlingBuffers*/);
+
+    TRAP_IGNORE(iCanvasPainter->HandleBufferL(rect, aAction, *iVisual, &aGc, TPoint(0,0), aCommands, buf));  
+    //iCanvasWsGc.DisableUpdateRegion();
+
+    }
+void CHuiCmdBufferBrush::CopyBuffer(CHuiGc &aGc, TRect aRectangle) const
+    {
+    RDebug::Print(_L("TP: CopyBuffer"));    
+    }
+
+void CHuiCmdBufferBrush::Flush() const
+    {
+    
+    }
+
+void CHuiCmdBufferBrush::EffectSetEffect(CHuiFxEffect* aEffect)
+    {
+    if (iEffect)
+        {
+        iEffect->SetEffectEndObserver( NULL, 0 );
+        }
+    delete iEffect;
+    iEffect = aEffect;
+    }
+
+TReal32 CHuiCmdBufferBrush::EffectOpacityTarget() const
+    {
+    return 1.0;
+    }
+void CHuiCmdBufferBrush::EffectSetOpacity(TReal32 aOpacity)
+    {
+    // empty
+    }
+void CHuiCmdBufferBrush::EffectDrawSelf( CHuiGc &aGc, const TRect & aDisplayRect) const
+    {
+    DrawSelf(aGc, aDisplayRect);
+    }
+
+THuiRealRect CHuiCmdBufferBrush::EffectDisplayRect() const __SOFTFP
+    {
+    RRegion reg;
+    TInt size = iBuffers.Count();
+    for(int i=0;i<size;i++)
+        {
+        TRect rect = iBuffers[i].iBoundingRectangle;
+        reg.AddRect(rect);
+        }
+    
+    THuiRealRect r(reg.BoundingRect());
+    reg.Close();
+    return r;
+    }
+
+void CHuiCmdBufferBrush::SetLoadingEffect(TBool /*aLoading*/)
+    {
+    // TODO
+    }
+void CHuiCmdBufferBrush::EffectSetSource( TBool /*aIsInput1*/ )
+    {
+    }
+TBool CHuiCmdBufferBrush::EffectGetSource() const
+    {
+    return EFalse;
+    }
+
+void CHuiCmdBufferBrush::DestroyBuffer(CHuiCanvasCommandBuffer *aBuffer)
+    {
+    TInt count = iBuffers.Count();
+    for(int i=count-1;i>=0;i--)
+        {
+        CHuiCanvasCommandBuffer *buf = iBuffers[i].iCommandBuffer;
+        if (buf == aBuffer)
+            {
+            iBuffers.Remove(i);
+            }
+        }
+    }
+
+struct TIndexTableElement
+    {
+    TInt32 iOffset;
+    TInt32 iSize;
+    TInt32 iLayerId;
+    //TRect iBoundingRect;
+    TInt iTliX;
+    TInt iTliY;
+    TInt iBriX;
+    TInt iBriY;
+    //TInt32 iBufferId;
+    };
+
+void ReplaceBufferL(RArray<CHuiCmdBufferBrush::TLayeredBuffer> &aBuffers, const CHuiCmdBufferBrush::TLayeredBuffer &buf);
+TInt FindBuffer(CHuiBrushArray &aBrushes, TInt aLayerId);
+
+
+void ParseCmdBufferL(CHuiBrushArray &aBrushes, TPtrC8 aBuffer, TPtrC8 aIndexTable, CHuiCanvasGc &aGc, CHuiCanvasWsGc &aWsGc, CHuiCanvasVisual &aVisual, CHuiCanvasPainter &aPainter)
+    {
+    TInt32 numIndexes = aIndexTable.Length() / sizeof(TIndexTableElement);
+    for(TInt i=0;i<numIndexes;i++)
+        {
+        TInt32 offset = i * sizeof(TIndexTableElement);
+        TInt32 size = sizeof(TIndexTableElement);
+        TPtrC8 ptr;
+        ptr.Set(aIndexTable.Mid(offset, size));
+        TIndexTableElement *elem = (TIndexTableElement*)ptr.Ptr();
+        //RDebug::Print(_L("Layer: %d: ID: %d, offset=%d, size = %d"), i, elem->iLayerId, elem->iOffset, elem->iSize);
+        //RDebug::Print(_L("aBuffer.Length()=%d"), aBuffer.Length());
+        TPtrC8 ptr2(aBuffer.Ptr()+elem->iOffset, elem->iSize) ; // aBuffer.Mid(elem->iOffset, elem->iSize));
+        //ptr2.Set();
+	
+        TInt index = FindBuffer(aBrushes, elem->iLayerId);
+        if (index == -1)
+            {
+            CHuiCmdBufferBrush *brush2 = CHuiCmdBufferBrush::NewL(elem->iLayerId, aGc, aWsGc, aVisual, aPainter);
+            CleanupStack::PushL(brush2);
+            aBrushes.AppendL(brush2, EHuiHasOwnership);
+            CleanupStack::Pop();
+            brush2->SetLayer(EHuiBrushLayerForeground);
+            index = aBrushes.Count() - 1;
+            }
+        CHuiCmdBufferBrush &brush = (CHuiCmdBufferBrush&)aBrushes[index];
+        CHuiCmdBufferBrush::TLayeredBuffer buf;
+        //buf.iBufferId = elem->iBufferId;
+        //TODO buf.iUpdateRegion = ...
+        TInt count = aPainter.NumBuffers();
+        CHuiCanvasCommandBuffer *buffer = count ? aPainter.At(count-1) : NULL;
+        if (buffer)
+            {
+            buffer->AddDestroyObserver(&brush);
+            }
+        buf.iBoundingRectangle.SetRect(elem->iTliX, elem->iTliY, elem->iBriX, elem->iBriY);
+        if (buf.iBoundingRectangle == TRect(0,0,0,0))
+            {
+            buf.iBoundingRectangle = TRect(0,0,aVisual.BrushRect().Size().iWidth, aVisual.BrushRect().Size().iHeight);
+            }
+        buf.iBufferPart.Set(ptr2);
+        buf.iCommandBuffer = buffer;
+        ReplaceBufferL(brush.iBuffers, buf);
+        }
+    }
+
+void ReplaceBufferL(RArray<CHuiCmdBufferBrush::TLayeredBuffer> &aBuffers, const CHuiCmdBufferBrush::TLayeredBuffer &aBuf)
+    {
+    aBuffers.AppendL(aBuf);
+#if 0
+    // TODO: Dunno if iBufferId can be used or whether we need to use regions to
+    // identify buffers.
+    TInt size = aBuffers.Count();
+    TInt index = -1;
+    for(int i=0;i<size;i++)
+        { // this loop might be able to optimize away if it becomes performance problem.
+          // but would need to notice that ParseCmdBuffer always goes layers in order.
+          // current code has no such assumption.
+        CHuiCmdBufferBrush::TLayeredBuffer &buffer= aBuffers[i];
+        if (buffer.iBufferId == buf.iBufferId)
+            {
+            index = i;
+            break;
+            }
+        }
+    if (index != -1)
+        {
+        aBuffers[index] = buf;
+        }
+    else
+        {
+        aBuffers.AppendL(buf);
+        }
+#endif
+    }
+
+TInt FindBuffer(CHuiBrushArray &aBrushes, TInt aLayerId)
+    {
+    TInt size = aBrushes.Count();
+    for(int i=0;i<size;i++)
+        {
+        CHuiCmdBufferBrush *brush = dynamic_cast<CHuiCmdBufferBrush*>(&aBrushes[i]);
+        if (brush && brush->LayerId() == aLayerId)
+            {
+            return i;
+            }
+        }
+    return -1;
+    }
+
+// wspainter needs to be able to skip the index table command
+void SkipCommand()
+    {
+    
+    }