uiacceltk/hitchcock/AlfRenderStage/src/alfrssendbuffer.cpp
changeset 0 15bf7259bb7c
child 3 d8a3531bc6b8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/AlfRenderStage/src/alfrssendbuffer.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,2108 @@
+/*
+* 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:   Handles serializing of data and sending it to alf streamer server.
+*
+*/
+
+
+
+// Maybe...
+// - EAlfCancelClippingRect is many times followed by EAlfSetClippingRect. Could the EAlfCancelClippingRect be ignored?
+// - EAlfSetBrushStyle (etc. other non drawing commands) are followed by AlfReset and no drawing is done. Could the Set
+//   commands be ignored.
+// Can ignoring be done faster than executing useless commands?
+
+#include <barsread.h>
+#include <barsc.h>
+#include <e32std.h>
+#include <alfstreamerconsts.h>
+#include <huiwscanvascommands.h>
+#include <uiacceltk/HuiUtil.h>
+
+#include <alfdecoderserverclient.h>
+#include <alflogger.h>
+#include "alf/alfcompositionclient.h"
+#include "alfrssendbuffer.h"
+#include "alfrenderstage.h"
+#include "alfcommanddebug.h"
+#include <alfnonsupportedwscommands.rsg>
+
+#include <data_caging_path_literals.hrh>
+
+_LIT( KRendererSupportedCommands,"alfnonsupportedwscommands.rsc" );
+
+const TInt KFrameHeaderSizeWhenCacheChunks = 500;
+const TInt KFrameHeaderSize = 5000;
+const TInt KFrameOffsetTemplate = 12345678;
+const TInt KCacheChunkMinSize = 50000;
+const TUint8 KDivisibleByX = 8;
+const TInt KWindowFrameHeader1 = 6; // bytes
+const TInt KWindowFrameHeader2 = 18 + 10; // bytes // TP +10 
+
+const TInt KAllRenderersMask = 63;
+const TInt KPossiblePerformanceProblemInWindow = 64;
+const TInt KPossiblePerformanceProblemInWindowThreshold = 1000;
+
+
+enum TPatternSearchStates
+    {
+    ESeekSetClippingRegion = 0,
+    ESeekBitBlit = 1,
+    ESeekResetClipping = 2,
+    ESeekBrushStyle1 = 3,
+    ESeekBrushStyle2 = 4
+    };
+
+
+#ifdef _OPTIMIZE_WS_COMMANDS_ADVANCED_
+const TInt TSearchPatternBitBlit[2][3] = { 
+                // Search command           // state                // alternative command in this state
+                { EAlfSetClippingRegion,    ESeekSetClippingRegion, KErrNotFound },
+                { EAlfBitBltMasked,         ESeekBitBlit,           EAlfBitBltRect }};
+#else
+const TInt TSearchPatternBitBlit[5][3] = { 
+				// Search command			// state				// alternative command in this state
+        		{ EAlfSetClippingRegion, 	ESeekSetClippingRegion, KErrNotFound },
+        		{ EAlfBitBltMasked, 		ESeekBitBlit, 			EAlfBitBltRect },
+        		{ EAlfResetClippingRegion, 	ESeekResetClipping, 	KErrNotFound },
+        		{ EAlfSetBrushStyle, 		ESeekBrushStyle1, 		KErrNotFound },
+        		{ EAlfSetBrushStyle, 		ESeekBrushStyle2, 		EAlfSetPenStyle} };
+#endif
+                
+
+// ---------------------------------------------------------------------------
+// class CAlfObserver
+// ---------------------------------------------------------------------------
+//
+
+NONSHARABLE_CLASS(CAlfObserver):public CActive
+    {
+    public:
+
+        // ---------------------------------------------------------------------------
+        // SetL
+        // ---------------------------------------------------------------------------
+        //
+        static void SetL(CAlfRsSendBuffer* aHost, TBool aStartServer )
+             {
+             CAlfObserver* me = new (ELeave)  CAlfObserver(aHost, aStartServer);
+             me->SetActive();
+             // breahe one cycle to allow wserv kick its server object alive
+             TRequestStatus* status = &me->iStatus; 
+             User::RequestComplete(status, KErrNone);   
+             }
+  
+        // ---------------------------------------------------------------------------
+        // NewL
+        // ---------------------------------------------------------------------------
+        //
+        CAlfObserver(CAlfRsSendBuffer* aHost, TBool aStartServer):CActive(2*EPriorityHigh),
+            iHost(aHost), iStartServer(aStartServer),  iBreathe(ETrue)
+            {
+            CActiveScheduler::Add(this);
+            iTimer.CreateLocal();
+            }
+        
+        // ---------------------------------------------------------------------------
+        // RunL
+        // ---------------------------------------------------------------------------
+        //
+        void RunL()
+            {
+            if (iBreathe && iStartServer)
+                {
+                iBreathe = EFalse;
+                SetActive();
+                TRAPD(err, AlfServerStarter::StartL(iStatus, EFalse));
+                if (err)
+                    {
+                    // Important, and thus enabled even in release builds. Other option would be letting leave to fall through 
+                    // render stage stack and let window server panic the boot
+                    RDebug::Print(_L("********* Error occurred when starting alf: %d"),err);
+                    }
+                else
+                    {
+                    return;
+                    }
+                }
+            else
+                {
+                if( !iHost->ConnectL() ) // if connecting fails, try again a bit later
+                    {
+                    SetActive();
+                    if( iStartServer )
+                        {
+                        iTimer.After( iStatus, 250000); // primary display is more important
+                        }
+                    else
+                        {
+                        iTimer.After( iStatus, 1000000);
+                        }
+                    }
+                else
+                    {
+                    __ALFLOGSTRING("********************FLUSHING WSERV");    
+					TRAP_IGNORE(iHost->PrepareBufferL());
+					TRAP_IGNORE(iHost->SendL( NULL ));
+                    iTimer.Close();
+                    delete this;
+                    }
+                }
+            }
+
+        // ---------------------------------------------------------------------------
+        // DoCancel
+        // ---------------------------------------------------------------------------
+        //
+        void DoCancel()
+            {
+            // not applicable atm
+            }
+        
+    private: // Data
+        
+        CAlfRsSendBuffer* iHost;
+        TBool iStartServer;
+        TBool iBreathe;
+        RTimer iTimer;
+    };
+        
+// ---------------------------------------------------------------------------
+// doFlushBuffer
+// Local function
+// ---------------------------------------------------------------------------
+//
+TInt doFlushBuffer( TAny* aPtr )
+    {
+    ((CAlfRsSendBuffer*)aPtr)->FlushBuffer();
+    return 0; // must return something
+    }
+
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CAlfRsSendBuffer* CAlfRsSendBuffer::NewL(CAlfRenderStage& aParent, TInt aScreenNumber )
+	{
+	CAlfRsSendBuffer* self = new(ELeave) CAlfRsSendBuffer( aParent, aScreenNumber );
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+	
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CAlfRsSendBuffer::~CAlfRsSendBuffer()
+    {
+    if ( iAlfBridgerClient )
+        {
+        iAlfBridgerClient->Close();
+        delete iAlfBridgerClient;
+        iAlfBridgerClient = NULL;
+        delete iAlfCompositionCntrlClient;
+        }
+#ifdef _OLD_STREAM    
+    if ( iBufStream )
+        {
+        iBufStream->Close();
+        delete iBufStream;
+        iBufStream = NULL;
+        }
+#endif    
+    iChunk.Close();
+    }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::ConstructL()
+    {
+    // If this is not the primary screen (0) do not send any commands to Alf server
+    iDisabled = (iScreenNumber != 0);
+    
+    ReadNonSupportedCommandsL();
+    iChunkInUse = 0;
+    iBooting = ETrue;
+#ifdef _ALF_PRINT_WS_COMMANDS_
+    iLog = 0;
+    iCommandDebugger = CAlfCommandDebug::NewL();
+#endif
+    
+    TBool runInsideWserv = ETrue; // EFalse;
+    if( runInsideWserv )
+        {
+        TBool startServer = ETrue;
+        if (iScreenNumber != 0) // we need one instance only
+            {
+            startServer = EFalse;
+            }
+        CAlfObserver::SetL(this, startServer);
+        }
+    else
+        {
+        CAlfObserver::SetL(this, EFalse);
+        }
+    
+    MAlfCompositionController* compcntrl = (MAlfCompositionController*)iParent.ResolveObjectInterface(KAlfCompositionControllerIfUid);
+    if (compcntrl)
+      {
+      compcntrl->AlfBridgeCallback(MAlfBridge::EAlfBridgeCreated, (MAlfBridge*)this);  
+      }
+    }
+
+// ---------------------------------------------------------------------------
+// ReadNonSupportedCommandsL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::ReadNonSupportedCommandsL()
+    {
+    RFs fs;
+    User::LeaveIfError(fs.Connect());
+    CleanupClosePushL(fs);
+    RResourceFile resFile;    
+    TInt result;
+    // resolve the absolute path
+    // Read unsupported command resource
+    TFileName resourceFileName;
+    TPtrC driveLetter = TParsePtrC( RProcess().FileName() ).Drive();
+    resourceFileName.Copy( driveLetter );  
+    resourceFileName.Append( KDC_ECOM_RESOURCE_DIR );
+    resourceFileName.Append( KRendererSupportedCommands );
+
+    TRAP( result, resFile.OpenL(fs,resourceFileName); );
+    if ( result == KErrNone )
+        {
+        CleanupClosePushL(resFile);
+        resFile.ConfirmSignatureL(0); // offset value.
+
+        TInt resId = R_ALF_NON_SUPPORTED_COMMANDS_ARRAY;
+
+        HBufC8* readData = resFile.AllocReadL(resId);
+        // now first get rid of RResourceFile and RFs as they are not needed any more
+        CleanupStack::PopAndDestroy(); // resFile
+        CleanupStack::PopAndDestroy(); // fs
+        CleanupStack::PushL(readData);
+
+        // now parse it and store the values in cmdTextArray
+        TResourceReader reader;
+        reader.SetBuffer(readData);
+        const TInt count = reader.ReadInt16();
+        TInt8 command;
+
+        TInt8 value;
+        TInt nonSupportedParameterCount = 0;
+        // resource file contains only non supported commands by renderers. Patch them to the iSupportedCommands
+        TInt supportedParameterIndex = 0;
+        for ( TInt i = 0; i < count ; i++ )
+            {
+            command = reader.ReadInt8();
+            value = ConvertToBitsL( 7, &reader );
+
+            nonSupportedParameterCount = reader.ReadInt16();
+            if ( nonSupportedParameterCount > 0 )
+                {
+                iSupportedCommandParameters[command][0] = supportedParameterIndex;
+                for ( TInt l = 0 ; l < nonSupportedParameterCount ; l ++ )
+                    {
+                    TInt8 parameterValue = reader.ReadInt8();
+                    iSupportedParameters[supportedParameterIndex][0] = parameterValue;
+                    TInt8 value2 = ConvertToBitsL( 6, &reader  );
+                    iSupportedParameters[supportedParameterIndex][1] = value2;
+                    supportedParameterIndex++;
+                    }
+                iSupportedCommandParameters[command][1] = supportedParameterIndex;
+                }
+            iNonSupportedCommands[command] = value;
+            }
+        CleanupStack::PopAndDestroy(readData);
+        }
+    else
+        {
+        __ALFLOGSTRING1("CAlfRsSendBuffer::ConstructL - WARNING! Failed to read unsupported commands from resource file: %S! Error code:st %d.", &resourceFileName );
+        CleanupStack::PopAndDestroy(); // fs
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ConvertToBitsL
+// ---------------------------------------------------------------------------
+//
+TUint8 CAlfRsSendBuffer::ConvertToBitsL( TInt aCount, TResourceReader* aReader )
+    {
+#ifdef _DEBUG    
+    if ( aCount > 7 )
+        {
+        __ALFLOGSTRING("CAlfRsSendBuffer::ConvertToBitsL - Can convert only 7 sequantial bytes to one byte");
+        USER_INVARIANT(); //
+        }
+#endif    
+    TInt8 value = 0;
+    TInt8 notSupported[7];
+    aReader->Read( notSupported, aCount );
+    TUint8 mask = 1;
+    for (TInt j = 0; j < aCount ; j ++)
+        {
+        if ( notSupported[j] ){ value |= mask ; }
+        mask = mask << 1;
+        }
+    return value;
+    }
+
+// ---------------------------------------------------------------------------
+// RunL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::RunL()
+    {
+    switch( iState )
+        {
+        case EWaitingAck:
+            {
+            if ( iStatus == EAlfBridgerAsyncronousData || iStatus < 0 )
+                {
+                TInt chunkIndex = 0;
+                // The following is written to the last created chunk.
+                TInt cacheChunkCount = iCacheChunks.Count();
+                
+                if ( cacheChunkCount > 0 )
+                    {
+                    // request destruction of all temporary chunks
+                    while ( chunkIndex < cacheChunkCount )
+                        {
+                        WriteInt8L( EAlfDestroyChunk );
+                        WriteInt8L( 0 ); // screen number, not used.
+                        WriteInt32L( iCacheChunks[chunkIndex].Handle() );
+                        WriteInt8L( EAlfCommandEndMarker );
+                        
+                        chunkIndex++;
+                        }
+                    if ( !iBooting )
+                        {
+                        // This is not necessary in the first boot, because jump 
+                        // request has been already created in PrepareBufferL
+                        
+                        JumpToAnotherChunkL( 0, iPrimaryChunkMaxSize );
+                        OpenPrimaryChunkForWritingL();
+                        SeekL(0); // rewind stream to the beginning
+                        WriteInt8L( EAlfCommandEndMarker );
+                        CommitL();
+                        FlushBuffer();
+                        }
+                    // destroy renderstage side handles to the chunk. alfhierarchy
+                    // has still open handles for a while.
+                    while( iCacheChunks.Count() )    
+                        {
+                        iCacheChunks[ 0 ].Close();
+                        iCacheChunks.Remove( 0 );
+                        }
+                    }
+                iUsedChunkMaxSize = iPrimaryChunkMaxSize - sizeof( TChunkHeader);
+                iChunkInUse = 0;
+                iBooting = EFalse; // alf has acknowledged the first frame
+                iParent.EndCallBack( iQuedStatus );
+                iState = EIdle;
+                }
+            break;
+            }
+        case EWaitingHandle:
+            {
+            break;
+            }
+        case EIdle:
+            {
+            break;
+            }
+        default:;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// DoCancel
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::DoCancel()
+    {
+    // TODO
+    }
+
+// ---------------------------------------------------------------------------
+// WriteFlagsL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::WriteFlagsL( )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    // space has been reserved for us
+    WriteInt8L( EAlfFrameFlags ); 
+    WriteInt32L( iFlags);
+    WriteInt8L( EAlfCommandEndMarker );
+    }
+
+// ---------------------------------------------------------------------------
+// WriteCommandL
+// writes 1 TInt value to the stream
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::WriteCommandL( const TUint8& aCommand, TInt aSize )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    if ( 
+#ifdef _OLD_STREAM
+            iBufStream->Sink() && 
+#endif
+            aCommand == EAlfPacketReady )
+        {
+        iReceivingDrawingCommands = EFalse;
+        // if offscreen content has not been flushed, we'll keep the frame in not completed state.
+        // it will be delivered to CHuiCanvasVisual, but not processed until finished packet arrives.
+        // make sure, that frame flags (iFlags) follow this command.
+        }
+
+    if (! InitCommandL( aCommand, aSize)){ return;}
+#ifdef _ALF_PRINT_WS_COMMANDS_  
+    if ( !iReceivingDrawingCommands )
+        {
+        aSize += sizeof(TUint8);
+        }
+    iCommandDebugger->SetDescriptionAndSize( aCommand, aSize, R_ALF_COMMAND_DESCRIPTION_ARRAY  );
+    iCommandDebugger->Print();
+#endif   
+    if ( !iReceivingDrawingCommands )
+        {
+        WriteInt8L( EAlfCommandEndMarker ); 
+        }
+    if ( aCommand == EAlfPacketReady )
+        {
+        iReceivingDrawingCommands = EFalse;
+        iWrappingFrame = EFalse;
+        
+#ifdef _ALF_PRINT_WS_COMMANDS_    
+        iCommandDebugger->PrintStatistic();
+        iCommandDebugger->EndFrame();
+#endif
+       
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// WriteIntsL
+// writes aCount amount of variables to the stream and updates stream index.
+// ---------------------------------------------------------------------------
+//
+// @todo Reference to Tint parameter was removed, because it did not pass armv5 compiler
+
+void CAlfRsSendBuffer::WriteIntsL( const TUint8& aCommand, TInt aCount, TRefByValue<const TInt> aFirst,... )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    const TInt size = sizeof(TInt32) * aCount;
+    if (! InitCommandL( aCommand, size )){ return;}
+#ifdef _ALF_PRINT_WS_COMMANDS_    
+    iCommandDebugger->SetDescriptionAndSize( aCommand, size, R_ALF_COMMAND_DESCRIPTION_ARRAY  );
+    iCommandDebugger->Print();
+#endif
+    
+	if ( aCount > 0 )
+	    {
+	    aCount--; // first item is serialized separately. It seems to exist at different location as rest of the parameters.
+	    WriteInt32L( aFirst );
+	    WriteL( (TUint8*)&aFirst + sizeof(TInt32), aCount * sizeof(TInt32) );
+	    //TInt size = sizeof(TInt32) * aCount;
+	    //iBufStream->WriteL( (TUint8*)&aFirst + sizeof(TInt32), size ); iOffset += size ; 
+	    }
+	if ( !iReceivingDrawingCommands )
+	    {
+	    WriteInt8L( EAlfCommandEndMarker );
+	    }
+    }
+
+void CAlfRsSendBuffer::WriteIntsL(TUint8 aCommand, TInt aCount, TInt* aArray)
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    const TInt size = sizeof(TInt32) * aCount;
+    if (!InitCommandL( aCommand, size ))
+      { 
+      return;
+      }
+
+#ifdef _ALF_PRINT_WS_COMMANDS_    
+    iCommandDebugger->SetDescriptionAndSize( aCommand, size, R_ALF_COMMAND_DESCRIPTION_ARRAY  );
+    iCommandDebugger->Print();
+#endif
+    
+    for(TInt i = 0; i < aCount; i++)
+        {	    
+        WriteInt32L( aArray[i] );
+        }
+        
+	if ( !iReceivingDrawingCommands )
+	    {
+	    WriteInt8L( EAlfCommandEndMarker );
+	    }
+    }
+
+// ---------------------------------------------------------------------------
+// WriteIntL
+// All possibly non-supported commands that have a parameter are using this version
+// of WriteIntL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::WriteIntL( const TUint8& aCommand, TInt aValue )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    TBool supported = EFalse;
+    if (iNonSupportedCommands[aCommand])
+        {        
+        for( TInt i = iSupportedCommandParameters[aCommand][0]; i < iSupportedCommandParameters[aCommand][1]; i++ )
+            {
+            if ( !supported && aValue == iSupportedParameters[i][0])
+                {
+                supported = ETrue;
+                iNonSupportedCommands[aCommand] = iSupportedParameters[i][1];
+                }
+            }
+        }
+    else
+        {
+        supported = ETrue;
+        }
+    
+     if ( !supported )
+         {
+         iNonSupportedCommands[aCommand] = KAllRenderersMask;
+         }
+    if (! InitCommandL( aCommand, sizeof(TInt32) )){ return;}
+#ifdef _ALF_PRINT_WS_COMMANDS_    
+    iCommandDebugger->SetDescriptionAndSize( aCommand, sizeof(TInt32), R_ALF_COMMAND_DESCRIPTION_ARRAY );
+    iCommandDebugger->Print();
+#endif    
+    // only commands, that may not be supported use this function
+    if ( aCommand == EAlfSetPenStyle )
+        {
+        iPenStyle = aValue; // for patter search
+        }
+    WriteInt32L( aValue);
+    if ( !iReceivingDrawingCommands )
+        {
+        WriteInt8L( EAlfCommandEndMarker );
+        }
+    }
+ 
+// ---------------------------------------------------------------------------
+// WriteRegionL
+// writes aCount amount of variables to the stream and updates stream index.
+// ---------------------------------------------------------------------------
+//
+// @todo Reference to Tint parameter was removed, because it did not pass armv5 compiler
+
+void CAlfRsSendBuffer::WriteRegionL( const TUint8& aCommand, const TRegion& aRegion )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    TInt count = aRegion.Count();
+    const TInt size = sizeof(TInt32) * ( 4 * count + 1);
+
+    if (! InitCommandL( aCommand, size )){ return;}
+#ifdef _ALF_PRINT_WS_COMMANDS_    
+    iCommandDebugger->SetDescriptionAndSize( aCommand, size, R_ALF_COMMAND_DESCRIPTION_ARRAY );
+    iCommandDebugger->SetRegion( aRegion );
+    iCommandDebugger->Print();
+#endif
+    WriteInt32L( count );
+    TInt i = 0;
+    while( i < count )
+        {
+        WriteL( (TUint8*)&aRegion[i].iTl.iX, 4 * sizeof(TInt32 ));
+        if ( aCommand == EAlfSetClippingRegion )
+            {
+            iSearchPatternClipRegion.AddRect(aRegion[i]);
+            }
+        i++;
+        }
+    
+    if ( !iReceivingDrawingCommands )
+        {
+        WriteInt8L( EAlfCommandEndMarker );
+        }
+  
+    }
+
+// ---------------------------------------------------------------------------
+// WriteDescriptorAndIntsL
+// writes aCount amount of variables to the stream and updates stream index.
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::WriteDescriptorAndIntsL(
+        const TUint8& aCommand,
+        const TDesC& aText,
+        const CGraphicsContext::TTextParameters* aTextParameter,
+                TInt aCount,
+        TRefByValue<const TInt> aFirst,... )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    if ( aText.Length() == 0 )
+        {
+        return;
+        }
+   
+   TBool useCachedText( EFalse );
+   if ( iCachedText 
+           && iCachedText->Length() == aText.Length() 
+           && iCachedText->Compare( aText ) == 0 )
+       {
+       useCachedText = ETrue;
+       }
+   else
+       {
+       delete iCachedText;
+       iCachedText = aText.AllocL();
+       }
+   // calculate size for the command
+   TInt  size = sizeof(TInt32) * ( 2 + aCount ) + //  ints
+                + 2 * sizeof(TInt8);  // existances of: text and TextParameters
+               
+   if ( !useCachedText )
+       {
+       size += aText.Size() + sizeof(TInt32); // text + its length  
+       }
+    
+    if ( aTextParameter )
+        {
+        size += ( 2 * sizeof(TInt32) )+ sizeof(TUint16);
+        }
+
+    if (! InitCommandL( aCommand, size )){ return;}
+#ifdef _ALF_PRINT_WS_COMMANDS_    
+    iCommandDebugger->SetDescriptionAndSize( aCommand, size, R_ALF_COMMAND_DESCRIPTION_ARRAY );
+    iCommandDebugger->Print();
+#endif                
+    WriteInt8L( useCachedText );
+    if ( !useCachedText )
+        {
+        WriteInt32L( aText.Size() );
+
+        TInt offset = iOffset + 2 * sizeof(TUint8);
+        TInt startPadding = offset % KDivisibleByX;
+        startPadding = startPadding == 0 ? 0 : KDivisibleByX - startPadding;
+        WriteInt8L( startPadding ); 
+
+        TInt endPadding = (offset + startPadding + aText.Size() ) % KDivisibleByX;
+        endPadding = endPadding == 0 ? 0 : KDivisibleByX - endPadding;
+        WriteInt8L( endPadding );
+        TUint8 padding[KDivisibleByX];
+        WriteL( (TUint8*)padding, startPadding );
+        WriteL( (TUint8*)aText.Ptr(), aText.Size() );
+        WriteL( (TUint8*)padding, endPadding ); 
+        // aTextParameter can be null.
+        }
+    if ( aTextParameter )
+        { 
+        // TODO: Remove commented code, when this is tested.
+        if ( aTextParameter->iStart == 0 
+                && aTextParameter->iEnd == aText.Length()
+                && aTextParameter->iFlags == 0 )
+            {
+			// actually, this never comes so far...
+            WriteInt8L( 2 ); // Use the default values
+            }
+        else
+            {
+            WriteInt8L( 1 ); 
+            TInt size =  2 * sizeof (TInt) + sizeof (TUint16) ;
+            WriteL( (TUint8*)&aTextParameter->iStart, size);
+            }
+        }
+    else
+        {
+        WriteInt8L( 0 );
+        }
+	if ( aCount > 0 )
+	{
+	    aCount--;
+	    WriteInt32L( aFirst );
+	    TInt size = aCount * sizeof(TInt32);
+	    WriteL( (TUint8*)&aFirst + sizeof(TInt32), size );
+    }
+    if ( !iReceivingDrawingCommands )
+        {
+        WriteInt8L( EAlfCommandEndMarker );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// WritePointArrayL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::WritePointArrayL( const TUint8& aCommand, const CArrayFix<TPoint>* aPoWriteIntList )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    TInt count = aPoWriteIntList->Count();
+    const TInt size = sizeof(TInt32) * (2 * count + 1);
+
+    if (! InitCommandL( aCommand, size )){ return;}
+
+    TInt index(0);
+    WriteInt32L( count );
+	while( index < count )
+        {
+        WriteInt32L( aPoWriteIntList->At(index).iX );
+		WriteInt32L( aPoWriteIntList->At(index).iY );
+		index++;
+        }
+    if ( !iReceivingDrawingCommands )
+        {
+        WriteInt8L( EAlfCommandEndMarker );
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// WritePointArrayL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::WritePointArrayL( const TUint8& aCommand, const TPoint* aPoWriteIntList, TInt aNumPoints )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    const TInt size = sizeof(TInt32) * (2 * aNumPoints + 1);
+    if (! InitCommandL( aCommand, size )){ return;}
+
+    TInt index(0);
+    WriteInt32L( aNumPoints );
+	while( index < aNumPoints )
+        {
+        WriteInt32L( aPoWriteIntList[index].iX );
+		WriteInt32L( aPoWriteIntList[index].iY );
+		index++;
+        }
+    if ( !iReceivingDrawingCommands )
+        {
+        WriteInt8L( EAlfCommandEndMarker );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// WritePointArrayL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::WritePointArrayL( const TUint8& aCommand, const TArray<TPoint>* aPoWriteIntList  )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    const TInt size = sizeof(TInt32) * (2 * aPoWriteIntList->Count() + 1);
+    if (! InitCommandL( aCommand, size )){ return;}
+
+    TInt index(0);
+    TInt count = aPoWriteIntList->Count(); 
+    WriteInt32L( count );
+    TArray<TPoint> list = *aPoWriteIntList;
+            
+    while( index < count )
+        {
+        const TPoint& point = list[index]; 
+        WriteInt32L( point.iX );
+		WriteInt32L( point.iY );
+		 index++;
+        }   
+    if ( !iReceivingDrawingCommands )
+        {
+        WriteInt8L( EAlfCommandEndMarker );
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// ConnectL
+// ---------------------------------------------------------------------------
+//
+TBool CAlfRsSendBuffer::ConnectL()
+    {
+/*    if (iDisabled) // return if this send buffer is not in use
+        {
+        return ETrue;
+        }
+  */  
+    if ( iAlfBridgerClient )
+        {
+        return ETrue; // already connected
+        }
+    iAlfBridgerClient = new(ELeave)RAlfBridgerClient();
+    TInt result = iAlfBridgerClient->Connect();
+    if ( result != KErrNone )
+        {
+        // server is not available
+        delete iAlfBridgerClient;
+        iAlfBridgerClient = NULL;
+        return EFalse;
+        }
+    TIpcArgs args(iScreenNumber);
+    User::LeaveIfError(iAlfBridgerClient->SendSynch(KAlfCompositionWServScreenNumber, args));
+
+    MAlfCompositionController* compcntrl = (MAlfCompositionController*)iParent.ResolveObjectInterface(KAlfCompositionControllerIfUid);
+    if (compcntrl)
+      {
+#ifndef USE_UI_LAYER_FOR_ALF
+        TAlfNativeWindowData data;
+        TPckg<TAlfNativeWindowData> pkg(data);
+
+        if( iScreenNumber == 0) // only for primary screen
+            {
+            User::LeaveIfError(iAlfBridgerClient->SendSynch(EAlfGetNativeWindowHandles, TIpcArgs(&pkg)));
+            compcntrl->AlfBridgeCallback(MAlfBridge::EAlfNativeWindowCreated, &data); 
+            }
+        }
+ #endif //#ifdef USE_UI_LAYER_FOR_ALF   
+    iAlfCompositionCntrlClient = CAlfCompositionCntrlClient::NewL(iAlfBridgerClient, compcntrl);
+    return ETrue;
+    }
+
+// ---------------------------------------------------------------------------
+//  WriteWindowIdentifierL
+//  Convenience function
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::WriteWindowIdentifierL( )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+#ifdef _OLD_STREAM
+   if ( !iBufStream->Sink() )
+        {
+        return;
+        }
+#endif    
+    // <HEADER1>
+    // if you change <HEADER1>, you must update its size in the beginning of this file
+    WriteInt8L( EAlfSetWindowId );
+	ResetPatternSearch();
+    
+    WriteInt8L( iScreenNumber );
+    WriteInt32L( iWindowId );
+	// </HEADER1>
+    WriteFollowingFrameOffsetTemplateL();
+     }
+
+// ---------------------------------------------------------------------------
+//  WriteWindowDataL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::WriteWindowDataL(
+		TUint32 aWindowUid,
+		TInt aRegionSize, 
+		TInt aShapeRegionSize )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+	// TODO: TERO: END	
+    iNonSupportedCommandsInWindow = 0;
+    iPerformanceIssueCommandCount = 0;
+    iFlags = 0;
+    delete iCachedText;
+    iCachedText = NULL;
+
+    iPreviousCommand = EAlfCommandNotInitialized;
+	// Note, the size tells the maximum space needed for the command
+    TInt size = sizeof(TUint32) + // windowId
+        sizeof(TUint32) + // next frame offset
+        3 * sizeof(TUint8) + // command + contains unsupported commands + end marker
+        sizeof(TUint8) + // screen number ( in WriteFollowingFrameOffsetTemplate)
+        sizeof(TUint32) * ( 4 * aRegionSize + 1 ) +  // updateregion 
+        sizeof(TUint8) * KDivisibleByX + // possible padding
+        sizeof(TUint32) * ( 4 * aShapeRegionSize + 1) + // possible shape region
+        sizeof(EAlfCommandEndMarker); // endmarker for update region and this command
+    if (! InitCommandL( EAlfSetWindowId, size )){ return;}
+#ifdef _ALF_PRINT_WS_COMMANDS_    
+    iCommandDebugger->StartFrame();
+#endif
+    ResetPatternSearch();
+    iWindowId = aWindowUid;
+    WriteInt32L( aWindowUid );
+	WriteFollowingFrameOffsetTemplateL();
+    iReceivingDrawingCommands = ETrue; // WriteCommand will set to false, when ERedrawComplete is received
+    }
+
+// ---------------------------------------------------------------------------
+//  WriteFollowingFrameOffsetTemplateL
+//  Convenience function
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::WriteFollowingFrameOffsetTemplateL()
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+		
+#ifdef _OLD_STREAM
+    if ( iBufStream->Sink() )
+#endif        
+        {
+        iTemplateOpen++;
+        if ( iTemplateOpen != 1 )
+            {
+            USER_INVARIANT();
+            }
+        iNextFrameOffsetPos = iOffset;
+        
+        // If you add anything to <HEADER2>, you must update its size in the beginning of the file.
+        // <HEADER2>
+        TInt chunkId = 0;
+        if ( iChunkInUse)
+            {
+            chunkId = iCacheChunks[iChunkInUse-1].Handle(); 
+            }
+        WriteInt32L( chunkId );
+		WriteInt32L( KFrameOffsetTemplate ); // we'll come back later on, and write the correct frame size to this location
+        // determine need for padding
+        TInt pos = iOffset; 
+        TInt offset = pos + 2 * sizeof(TUint8) + sizeof(TUint8) + sizeof(TInt32); // padding and endmarker.
+        TInt startPadding = offset % KDivisibleByX;
+        startPadding = startPadding == 0 ? 0 : KDivisibleByX - startPadding;
+        WriteInt8L( EAlfFrameFlags );
+		WriteInt32L( 0 ); 
+		
+        WriteInt8L( startPadding );
+		iFramePadding = startPadding;
+        WriteInt8L( EAlfCommandEndMarker );
+		// actual padding
+        while ( startPadding-- )
+            {
+            WriteInt8L( 0 );
+			}
+        iArrayImplOffset = iOffset;
+        InitMarker(iMarker);
+		WriteInt8L( EAlfFrameContainsUnsupportedCommands );
+        WriteInt8L( 0 );
+        WriteArrayHeaderTemplateL();
+        InitTOffsetElemArray(iOffsetArray);
+        // </HEADER2>
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//  WriteFollowingFrameOffsetL
+// ---------------------------------------------------------------------------
+//
+TBool CAlfRsSendBuffer::WriteFollowingFrameOffsetL(TBool aSendArray)
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return ETrue;
+        }
+    TOffsetElem e;
+    if (aSendArray)
+        {
+        e = WriteIndexArrayL(iOffsetArray);
+        }
+    
+#ifdef _OLD_STREAM    
+    if ( iBufStream->Sink() )
+#endif        
+        {
+        if ( iPerformanceIssueCommandCount > KPossiblePerformanceProblemInWindowThreshold )
+            {
+            if ( iPerformanceIssueCommandCount > iMaxPerformanceIssueCommandCount )
+                {
+                iMaxPerformanceIssueCommandCount = iPerformanceIssueCommandCount;
+                }
+            iNonSupportedCommandsInWindow |= KPossiblePerformanceProblemInWindow; 
+            }
+        
+        iTemplateOpen--;
+        // Empty frames should not be serialized as they cause unnecessary work on Alfserver side. 
+        // WServ sends empty frames from time to time
+        TInt previousPos = iOffset;
+        // Remember to update KWindowFrameHeaderX, if you add stuff to frame header
+        TInt frameSize = previousPos - iNextFrameOffsetPos - KWindowFrameHeader2 - iFramePadding; 
+        if ( !frameSize ) 
+            {
+            SeekL( iNextFrameOffsetPos - KWindowFrameHeader1 );
+            iReceivingDrawingCommands = EFalse;
+            return EFalse;  
+            }
+        SeekL( iNextFrameOffsetPos );
+        // <HEADER2>
+        TInt chunkId = 0;
+        if ( iChunkInUse)
+            {
+            chunkId = iCacheChunks[iChunkInUse-1].Handle(); 
+            }
+        WriteInt32L( chunkId );
+		WriteInt32L( previousPos );
+		WriteInt8L( EAlfFrameFlags );
+		WriteInt32L( iFlags );
+		
+        WriteInt8L( iFramePadding ); 
+		WriteInt8L( EAlfCommandEndMarker ); 
+		// Padding
+        while ( iFramePadding-- )
+            {
+            WriteInt8L( 0xff );
+			}
+        WriteInt8L( EAlfFrameContainsUnsupportedCommands );
+		WriteInt8L( iNonSupportedCommandsInWindow );
+		if (aSendArray) 
+		    {
+		    WriteArrayHeaderL(e);
+		    }
+		/*iWindowHeaderStruct.iWindowEndOffset = previousPos.Offset();
+        iWindowHeaderStruct.iUnsupportedCommandsInWindow = iNonSupportedCommandsInWindow;
+        iBufStream->WriteL( (TUint8*)&iWindowHeaderStruct, sizeof(TWindowHeaderStruct) );*/
+        // <HEADER2>
+        // return to end of frame
+        SeekL( previousPos );
+        
+        if ( iTemplateOpen )
+            {
+            USER_INVARIANT();
+            }
+        }
+    return ETrue; 
+    }
+//
+// ARRAY IMPLEMENTATION
+//
+
+const TInt KArrayOffsetTemplate = 23456789;
+const TInt KArraySizeTemplate = 23456789;
+
+void CAlfRsSendBuffer::WriteArrayHeaderTemplateL()
+{
+    WriteInt8L( EAlfCommandIndexArrayHeader );
+    WriteInt8L( 0 ); // align
+    WriteInt32L( KArrayOffsetTemplate ); // these will be rewritten in WriteArrayHeader2
+    WriteInt32L( KArraySizeTemplate );   // these will be rewritten in WriteArrayHeader2
+}
+
+
+void CAlfRsSendBuffer::InitTOffsetElemArray(RArray<TOffsetElem> &aOffsets)
+{
+    TInt count = aOffsets.Count();
+    for(TInt i=0;i<count;i++)
+        aOffsets.Remove(0);
+}
+
+CAlfRsSendBuffer::TOffsetElem CAlfRsSendBuffer::WriteIndexArrayL(const RArray<TOffsetElem> &aOffsets)
+{
+    TInt marker = iBufStream->Sink()->TellL( MStreamBuf::EWrite ).Offset();
+    if (iPreviousBlockOffset != marker && iLayersEnabled)
+        {
+        TInt size = marker - iPreviousBlockOffset;
+        TOffsetElem e;
+        e.iOffset = iPreviousBlockOffset - iArrayImplOffset; //iFrameBeginOffset + KWindowFrameHeader1 + KWindowFrameHeader2;
+        e.iSize = size;
+        e.iBoundingRectangle = TRect(0,0,0,0);
+        e.iLayerId = iExtraLayerId++;
+        iOffsetArray.AppendL( e ); 
+        }
+    InsertPaddingL();
+
+   // first command to allow wspainter to skip the index array section
+   WriteInt8L(EAlfCommandIndexArray);
+   WriteInt8L(aOffsets.Count());
+   WriteInt8L(0);
+   WriteInt8L(0);
+   TInt offset = iOffset;
+   TInt count = aOffsets.Count();
+
+   // then the actual index array
+   for(TInt i = 0; i<count; i++)
+	{
+	WriteInt32L( aOffsets[i].iOffset );
+	WriteInt32L( aOffsets[i].iSize );	
+	WriteInt32L( aOffsets[i].iLayerId);
+	WriteL( (TUint8*)&aOffsets[i].iBoundingRectangle, sizeof(TRect) );
+	}
+   TOffsetElem e;
+   e.iOffset = offset  - iArrayImplOffset; //iFrameBeginOffset + KWindowFrameHeader1 + KWindowFrameHeader2;
+   e.iSize = aOffsets.Count()*sizeof(TOffsetElem);
+   return e;
+}
+
+void CAlfRsSendBuffer::WriteArrayHeaderL(const TOffsetElem &aIndexArrayOffset)
+{
+   WriteInt8L( EAlfCommandIndexArrayHeader );
+   WriteInt8L( 0 ); // align
+   WriteInt32L( aIndexArrayOffset.iOffset );
+   WriteInt32L( aIndexArrayOffset.iSize );
+}
+
+void CAlfRsSendBuffer::InitMarker(TInt &aMarker)
+{
+   aMarker = -1;
+   iPreviousBlockOffset = iBufStream->Sink()->TellL( MStreamBuf::EWrite ).Offset();
+   iExtraLayerId = 667;
+   iLayersEnabled = EFalse;
+}
+void CAlfRsSendBuffer::StartMarkerL(TInt &aMarker, TRect &aRectangle, TInt &aLayer, TRect aBoundingRectangle, TInt aLayerId)
+{
+   ASSERT(aMarker == -1);
+   aMarker = iBufStream->Sink()->TellL( MStreamBuf::EWrite ).Offset();
+   if (iPreviousBlockOffset != aMarker)
+       {
+       TInt size = aMarker - iPreviousBlockOffset;
+       TOffsetElem e;
+       e.iOffset = iPreviousBlockOffset - iArrayImplOffset; //iFrameBeginOffset + KWindowFrameHeader1 + KWindowFrameHeader2;
+       e.iSize = size;
+       e.iBoundingRectangle = TRect(0,0,0,0);
+       e.iLayerId = iExtraLayerId++;
+       iOffsetArray.AppendL( e ); 
+       }
+   
+   //aMarker = iOffset;
+   aRectangle = aBoundingRectangle;
+   aLayer = aLayerId;
+   iLayersEnabled = ETrue;
+}
+void CAlfRsSendBuffer::EndMarkerL(RArray<TOffsetElem> &aOffset, TInt &aMarker, const TRect &aRectangle, TInt aLayerId)
+{
+   //TODO ASSERT(aMarker != -1);
+   if (aMarker==-1) return; 
+   TInt offset = iBufStream->Sink()->TellL( MStreamBuf::EWrite ).Offset();
+
+   TInt size = offset - aMarker;
+   TOffsetElem e;
+   e.iOffset = aMarker - iArrayImplOffset; //iFrameBeginOffset + KWindowFrameHeader1 + KWindowFrameHeader2;
+   e.iSize = size;
+   e.iBoundingRectangle = aRectangle;
+   e.iLayerId = aLayerId;
+   aOffset.AppendL( e ); 
+   aMarker = -1;
+   iPreviousBlockOffset = offset;
+}
+void CAlfRsSendBuffer::StartMarkerL(TRect aBoundingRectangle, TInt aLayerId)
+    {
+    StartMarkerL(iMarker, iBoundingRectangle, iLayerId, aBoundingRectangle, aLayerId);
+    }
+void CAlfRsSendBuffer::EndMarkerL()
+    {
+    EndMarkerL(iOffsetArray, iMarker, iBoundingRectangle, iLayerId);
+    }
+// ---------------------------------------------------------------------------
+// SendL
+// sends data syncronously in one or more packets to the streamer server
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::SendL( TRequestStatus* aStatus )
+	{
+	// dont send to alf, if chunk is not available or nothing was written
+	if (iDisabled || !iChunk.Handle() )
+        {
+        if ( aStatus )
+            {
+            // AlfRenderStage may complete the request, because we wont do anything with the data
+            iParent.EndCallBack( aStatus );
+            }
+        return;
+        }
+
+    WriteInt8L( EAlfCommitBatch );
+	WriteInt8L( iScreenNumber );
+	WriteInt8L( EAlfCommandEndMarker );
+	
+    iState = EWaitingAck;
+    TInt lastWrittenOffset( iOffset );
+    Commit();
+    
+    TIpcArgs args( lastWrittenOffset );
+    // __ALFLOGSTRING1("CAlfRsSendBuffer::SendL, offset %d ( TRequestStatus)"), lastWrittenOffset );
+    if ( iFlushBufferTimer ) 
+        {
+        iFlushBufferTimer->Cancel();
+        }
+    iAlfBridgerClient->SendAsynchronous( EAlfBridgerAsyncronousData, args, iStatus );
+
+    if ( aStatus )  // aStatus is null, if this was event notification and not drawing
+        {
+        iQuedStatus = aStatus;
+        *aStatus = KRequestPending;
+        }
+
+    if ( !IsActive() )
+        {
+        SetActive();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// FlushBuffer
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::FlushBuffer()
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    TBool connected = (iAlfBridgerClient != NULL);
+    if (!connected)
+        {
+        TRAP_IGNORE(connected = ConnectL());
+        }
+    if (!connected)
+        {
+        // Cannot connect
+        return;
+        }
+    TIpcArgs args( 0 );
+    TInt result = iAlfBridgerClient->SendBlind( EAlfBridgerBlindSend, args  );
+    if ( result != KErrNone && result != KErrServerBusy)
+    	{
+    	__ALFLOGSTRING1("CAlfRsSendBuffer::FlushBuffer, err %d", result );
+    	// This means that AlfDecoderServer has died and is not coming back. 
+    	// There is no point of continuing with non updating UI.
+   		USER_INVARIANT();
+    	}
+    if ( iFlushBufferTimer ) 
+    	{
+    	iFlushBufferTimer->Cancel();
+    	}
+
+	// during boot time, server is known to answer with this. Just try again little later.
+	if ( result == KErrServerBusy)
+		{
+		CommitL();
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// CommitL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::CommitL( )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    if ( iBooting )
+        {
+        return;
+        }
+    Commit();
+    // RDebug::Print(_L("CAlfRsSendBuffer::CommitL - %d %d %d "), iChunkHeader, iChunkHeader->iCommittedWriteOffset, iOffset );
+      if ( !iFlushBufferTimer )
+        {
+        iFlushBufferTimer = CPeriodic::NewL( EPriorityNormal );
+        iFlushBufferTimer->Start( 5000, 10 * 1000000 , TCallBack( doFlushBuffer, this ));
+        }
+    if ( !iFlushBufferTimer->IsActive() )
+        {
+        //__ALFLOGSTRING("CAlfRsSendBuffer::CommitL, activating timer");
+        iFlushBufferTimer->After( 5000 );
+        }
+    else
+    	{
+    	//__ALFLOGSTRING("CAlfRsSendBuffer::CommitL, timer already active ");
+    	}
+    }
+
+// ---------------------------------------------------------------------------
+// SendAsyncCmd
+// Send asynchronous command
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::SendAsyncCmd(TInt aCmd, TDes8& aBuf, TRequestStatus& aStatus)
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+   iAlfBridgerClient->SendAsynchronous(aCmd, TIpcArgs(&aBuf), aStatus);
+    }
+
+// ---------------------------------------------------------------------------
+// OpenPrimaryChunkForWritingL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::OpenPrimaryChunkForWritingL()
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    iChunkHeader = reinterpret_cast<TChunkHeader*>(iChunk.Base());
+    if ( iChunkHeader->iMemWriteStream )
+        {
+#ifdef _OLD_STREAM        
+        iBufStream->Close();
+        delete iBufStream;
+        iBufStream=NULL;
+        iBufStream = new(ELeave)RMemWriteStream;
+        // iBufStream = iChunkHeader->iMemWriteStream;
+        iBufStream->Open( iChunk.Base() + sizeof( TChunkHeader), iPrimaryChunkMaxSize );
+#else
+        delete iStreamPtr;
+        iStreamPtr = new(ELeave)TPtr8( (TUint8*)(iChunk.Base() + sizeof( TChunkHeader)), iPrimaryChunkMaxSize - sizeof( TChunkHeader));
+        iChunkHeader->iMemWriteStream = (RMemWriteStream*)1;
+#endif
+        SeekL( iOffset );
+        iChunkInUse = 0;
+        }
+    else
+        {
+#ifdef _OLD_STREAM
+        iBufStream->Open( iChunk.Base() + sizeof( TChunkHeader), iPrimaryChunkMaxSize );
+        iChunkHeader->iMemWriteStream = iBufStream;
+#else
+        iStreamPtr = new(ELeave)TPtr8( (TUint8*)(iChunk.Base() + sizeof( TChunkHeader)), iPrimaryChunkMaxSize - sizeof( TChunkHeader) );
+        iChunkHeader->iMemWriteStream = (RMemWriteStream*)1;
+#endif        
+        SeekL(0);
+        iChunkHeader->iMemWriteStreamUsers++;
+        }
+    WriteInt8L( EAlfCommandEndMarker );
+    Commit();
+    
+    }
+
+// ---------------------------------------------------------------------------
+// Commit
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::Commit()
+    {
+    iChunkHeader->iCommittedWriteOffset = iOffset;
+    // RDebug::Print(_L("CAlfRsSendBuffer::Commit - %d"), iChunkHeader->iCommittedWriteOffset );
+    }
+
+// ---------------------------------------------------------------------------
+// PrepareBufferL
+// Sets up the stream
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::PrepareBufferL()
+	{
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+	// is alfstreamerserver running?
+	if ( !ConnectL() )
+        {
+        return;
+        }
+	iBeginTime.HomeTime();
+	 
+	// alfstreamerserver is now running, but do we already have chunk for serialization
+	if ( iChunk.Handle() == 0 )
+	    {// Note, ConnectL() == ETrue and iChunk.Handle() == 0  is true ONLY ONCE in runtime.  
+
+	    // write jump to the primary chunk. This chunk jump gets special treatment in RunL. Look for iBooting variable.
+	    JumpToAnotherChunkL( 0, iPrimaryChunkMaxSize ); // 2nd parameter is ignored on alfside, because it knows the primary chunksize
+	    Commit();
+#ifdef _OLD_STREAM	    
+	    iBufStream->Close();
+#endif
+	    // Request chunk from server: handle and lenght of chunk come as response
+	    TPckg<TInt> pkgLength(  iUsedChunkMaxSize );
+	    TIpcArgs args( &pkgLength, iScreenNumber );
+	    TInt handle;
+	    handle = iAlfBridgerClient->SendSynch( EAlfBridgerRequestDataBlock, args);
+	    iPrimaryChunkMaxSize = iUsedChunkMaxSize;
+	    iChunk.SetReturnedHandle( handle );
+
+	    if ( iChunk.Handle() > 0 )
+	        {
+	        OpenPrimaryChunkForWritingL();
+	        }
+	    else
+	        {
+	        // Chunk was not received from server. We cannot continue
+	        USER_INVARIANT();
+	        }
+	    }
+	// The first boot cache chunk is sent here. 
+	if ( iBooting && iCacheChunks.Count() && iChunkInUse )
+	    {
+	    if ( iChunkHeader->iMemWriteStreamUsers > 1 ) 
+            {
+            // make "sure", that there will be space for all the cached data
+            CommitL();
+            }
+
+	    while ( iChunkInUse )
+             {
+             iChunkInUse--;
+             TInt size( KCacheChunkMinSize );
+             TIpcArgs args( size, iCacheChunks[iChunkInUse], iChunkInUse == 0 /* open chunk for reading */);
+             iAlfBridgerClient->SendSynch( EAlfBridgerSendChunk, args);
+             }	    
+        }
+	iFrameBeginOffset = iOffset; // iBufStream->Sink()->TellL( MStreamBuf::EWrite);
+	}
+
+// ---------------------------------------------------------------------------
+// FrameContainsDataL
+// ---------------------------------------------------------------------------
+//
+TBool CAlfRsSendBuffer::FrameContainsDataL()
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return EFalse; // Must return false as no draw commands are allowed 
+        }
+		
+#ifdef _OLD_STREAM    
+    if ( iBufStream->Sink() )
+#endif        
+        {
+#ifdef _OLD_STREAM        
+        iBufStream->CommitL();
+#endif        
+        return ( iFrameBeginOffset != iOffset );
+        }
+#ifdef _OLD_STREAM
+    else
+        {
+        return EFalse;
+        }
+#endif    
+    }
+
+// ---------------------------------------------------------------------------
+// JumpToAnotherChunkL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::JumpToAnotherChunkL( TInt32 aChunkId, TInt aChunkSize )
+    {
+    WriteInt8L( EAlfJumpToAnotherChunk );
+	WriteInt8L( 0 ); // screen number, not used.
+    WriteInt32L( aChunkId );
+	WriteInt32L( aChunkSize );
+	WriteInt8L( EAlfCommandEndMarker );
+	Commit();
+    }
+
+// ---------------------------------------------------------------------------
+// DoCreateTemporaryChunkL
+//
+// If wserv pushes more data in frame that we can handle,  separate one time use 
+// "temporary" chunks are taken into use. 
+//  1. Big enough chunk to contain atleast the command + minimum chunk size is created
+//  2. Jump of from the current chunk to the temporary chunk is created
+//  3. new chunk is taken as the active chunk
+//  4. chunk is rewinded
+//  5. commands can be serialized as before
+//
+//  Same starts from the step 1, if temporary chunk turns out to be not big enough.
+//
+//  Chunks are destroyed in RunL, when asyncronous (frame processed) complete is
+//  received. In RunL, (see RunL for the code)
+//  
+//  The following things are serialized to the active (the last temporary chunk created)
+//  1. destroy command for each existing temporary chunk is created
+//  2. if not in first boot, jump to the primary chunk is created.
+//  3. handles to the temporary chunks on this side are closed 
+//     and chunks removed.
+//
+//  After AlfHierarchy has read the jump command, serialization will be in the normal mode.
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::DoCreateTemporaryChunkL( TInt aMinimumRequiredSize )
+    {
+    __ALFLOGSTRING2("CAlfRsSendBuffer::DoWaitWrapperL iReceivingDrawing commands %d chunk in use: %d", iReceivingDrawingCommands, iChunkInUse );
+    // Optimize bitblits backtracks in a _single chunk_, so changing or wrapping a chunk is 
+    // a very bad idea. Lets skip the optimization, if this rare occation happens.
+    ResetPatternSearch(); 
+            
+    if ( iReceivingDrawingCommands )
+         {
+         // if window drawing is active, the window commands are split. 
+         InsertPaddingL(); // padding is required, that the combined parts on the other side have correct alignment for descriptors
+         WriteFollowingFrameOffsetL(EFalse);
+         WriteInt8L( EAlfPacketNotReady );
+		 WriteInt8L( EAlfCommandEndMarker );
+		 }
+    else
+        {
+        __ALFLOGSTRING("CAlfRsSendBuffer::DoCreateTemporaryChunkL, creating during hierarchy commands");
+        }
+    
+    // rest of this frame will be serilized to cache chunk
+    CommitL();
+    if ( ConnectL() )
+        {
+        FlushBuffer();
+	    }
+    TInt chunkSize = aMinimumRequiredSize;
+    if ( CreateTemporaryChunkL( chunkSize ) == KErrNone )
+        {
+        if ( ConnectL() )
+           {
+           TInt size( chunkSize );
+           TIpcArgs args( size, iCacheChunks[iChunkInUse], EFalse /* open chunk for reading */ );
+           iAlfBridgerClient->SendSynch( EAlfBridgerSendChunk, args); // alf server must open the chunk before it can be read. reading is asyncronous
+           }
+        JumpToAnotherChunkL( iCacheChunks[iChunkInUse].Handle(), chunkSize );
+        OpenRewindChunkL( chunkSize );
+        WriteInt8L( EAlfCommandEndMarker ); // This is must command after jumping to another chunk.
+		CommitL();
+
+        if ( iReceivingDrawingCommands )
+            {
+            WriteWindowIdentifierL();
+            }
+        }
+    else
+        {
+        // TODO: We could not reserve memory. The only option will be to ignore this frame.
+        // 1. rollback to the beginning of the frame
+        // 2. skip all sequential drawing commands to this frame.
+        // problem: what if OOM during hierarchy tree commmands
+        }
+ }
+
+// ---------------------------------------------------------------------------
+// ReserveSpaceL
+//
+// Check, if buffer has enough space for this command.
+// If we encounter the end of buffer, then do a wrap around if possible.
+// If wrap is not possible, create a temporary space for command
+// ---------------------------------------------------------------------------
+//
+TBool CAlfRsSendBuffer::ReserveSpaceL( TInt aCommandSize )
+    {
+    // TInt minumumHeaderSize = iCacheChunks.Count() > 0 ? KFrameHeaderSizeWhenCacheChunks : KFrameHeaderSize;
+    TInt minumumHeaderSize = KFrameHeaderSize;
+    if ( iCacheChunks.Count() > 0 )
+        {
+        // if cache chunks still exists, then wserv is trying to push commands out of redrawstart/end loop and we hope that 
+        minumumHeaderSize = KFrameHeaderSizeWhenCacheChunks; 
+        }
+    TInt writeOffset = iOffset;
+    TInt commandTailOffset = writeOffset + aCommandSize + KFrameHeaderSize;
+    TInt readOffset = iChunkHeader->iReadOffset;
+    TInt bytesFree(0);
+    if ( readOffset > writeOffset)
+        {//                       V
+        // |RRRRRRRRR|W---------RRRRRRRRRRRR | 
+       // ASSERT( iWrappingFrame );
+       bytesFree = readOffset - writeOffset;
+       }
+    if ( readOffset < writeOffset )
+       {
+       //       V              W
+       // | ----RRRRRRRRRRRRRRRW------ |
+       iWrappingFrame = EFalse;
+       bytesFree = iUsedChunkMaxSize - writeOffset; // there might be more free and the beginning of the chunk, but this is not relevant. The entire command needs to fit as one piece
+       }
+    if ( readOffset == writeOffset )
+       {
+       if ( iWrappingFrame )
+           {
+           //                V
+           // | RRRRRRRRRRRRRWRRRRRRRRRRRRR |
+           bytesFree = 0;
+           }
+       else
+           {
+           //  V
+           // | --------------------------- |
+           // the entire chunk is free
+           bytesFree = iUsedChunkMaxSize;
+           }
+       }
+    // are we trying to overwrite unprocessed data
+    if ( bytesFree < aCommandSize + minumumHeaderSize && commandTailOffset <= iUsedChunkMaxSize 
+            || ( bytesFree < aCommandSize + minumumHeaderSize && iWrappingFrame ))
+        {
+        // __ALFLOGSTRING("CAlfRsSendBuffer::CanWriteToBufferL -> DoCreateTemporaryChunkL");
+        DoCreateTemporaryChunkL( aCommandSize );
+        }
+    else if ( commandTailOffset > iUsedChunkMaxSize )
+        {
+        if ( !iChunkInUse )
+            {
+            DoWrapL( aCommandSize,  aCommandSize > readOffset );
+            }
+        else
+            {
+            // we are already using temporary chunks and those cannot be wrapped. The only option is to create 
+            // yet another temporary chunk.
+            DoCreateTemporaryChunkL( aCommandSize );
+            }
+        }
+    return ETrue;
+    }
+
+// ---------------------------------------------------------------------------
+// DoWrapL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::DoWrapL( TInt aCommandSize, TBool aCreateTempororaryChunk )
+    {
+    if ( iCacheChunks.Count() )
+        {
+        DoCreateTemporaryChunkL( aCommandSize );
+        }
+    __ALFLOGSTRING2("CanWriteToBufferL Read/Write %d/%d", iChunkHeader->iReadOffset, iChunkHeader->iWriteOffset);
+
+    if ( aCreateTempororaryChunk )
+        {
+        __ALFLOGSTRING("CAlfRsSendBuffer::DoWrapL -> DoCreateTemporaryChunkL");
+        DoCreateTemporaryChunkL( aCommandSize );
+        return;
+        }
+    else
+        {
+        if ( iReceivingDrawingCommands )
+            {
+            InsertPaddingL();
+            WriteFollowingFrameOffsetL(EFalse);
+            WriteInt8L( EAlfPacketNotReady );
+			WriteInt8L( EAlfCommandEndMarker );
+			}
+        else
+            {
+            __ALFLOGSTRING("CAlfRsSendBuffer::CanWriteToBufferL, non drawing command");
+            }
+        }
+    WriteInt8L( EAlfWrap );
+	WriteInt8L( iScreenNumber );
+	WriteInt8L( EAlfCommandEndMarker );
+	// Optimize bitblits backtracks in a _single chunk_, so changing or wrapping a chunk is 
+    // a very bad idea. Lets skip the optimization, if this rare occation happens.
+    ResetPatternSearch(); 
+
+    iWrappingFrame = ETrue;
+    __ALFLOGSTRING1("CAlfRsSendBuffer::CanWriteToBufferL, Wrap at offset %d", iChunkHeader->iWriteOffset);
+    SeekL(0);
+    WriteInt8L( EAlfCommandEndMarker );
+	
+    if ( iReceivingDrawingCommands )
+        {
+        WriteWindowIdentifierL();
+        }
+    else
+        {
+        __ALFLOGSTRING("CAlfRsSendBuffer::CanWriteToBufferL Wrapping while not receiving drawing commands");
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// SetSupportedCommand
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::SetSupportedCommand( TInt aIndex, TInt8 aSupport )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    iNonSupportedCommands[aIndex] = aSupport;
+    }
+
+// ---------------------------------------------------------------------------
+// InitCommandL
+// Takes care that data fits to the stream
+// ---------------------------------------------------------------------------
+//
+TBool CAlfRsSendBuffer::InitCommandL( const TUint8& aCommand, TInt aCommandSize  )
+    {
+	// THIS IS DIRTY HACK UNTIL WSERV STOPS DOING DRAWING OUTSIDE WINDOW
+	// RE-EVALUATE FOR WK14 RELEASE
+    if ( ( aCommand >= EAlfDrawCommandsStart && aCommand <= EAlfDrawCommandsEnd && !iReceivingDrawingCommands ) && 
+            ( aCommand != EAlfPacketReady && aCommand != EAlfPacketNotReady ))
+        {
+#ifdef _DEBUG
+        RDebug::Print(_L("CAlfRsSendBuffer::InitCommandL - Drawing outside window, Cmd: %d"), aCommand );
+#endif
+        return EFalse;
+		}
+	// END OF DIRTY HACK    
+    if ( iReceivingDrawingCommands )
+        {
+        aCommandSize += sizeof(EAlfCommandEndMarker);
+        }
+    iNonSupportedCommandsInWindow |= iNonSupportedCommands[aCommand] & KAllRenderersMask;
+    if ( iNonSupportedCommands[aCommand] & KPossiblePerformanceProblemInWindow ) // indicates possible performance problem if frame has many of this of commands
+        {
+        iPerformanceIssueCommandCount++;
+        }
+     
+    // Check if chunk has been opened. Must for streaming.
+    if ( 
+#ifdef _OLD_STREAM
+            !iBufStream && 
+#else
+            !iChunkHeader  &&
+#endif            
+            iCacheChunks.Count() == 0 )
+        {
+        TInt chunkSize = aCommandSize;
+        CreateTemporaryChunkL( chunkSize );
+        OpenRewindChunkL( chunkSize );
+        }
+
+
+    // EAlfPacketReady is the last command in the window, and it is guaranteened to fit without checking. Checking would possible slice the command stream unnecessary.
+    if ( aCommand != EAlfPacketReady )
+        {
+        // check for running out of space in the chunk
+        if ( !ReserveSpaceL( aCommandSize + 2*sizeof(TUint8)) )
+            {
+            return EFalse;
+            }
+        }
+    // write command to a chunk. There will be space.
+    // __ALFLOGSTRING3("Command %d, Offset: %d Screen: %d Command: %d",  aCommand, iScreenNumber, aCommand );
+    WriteInt8L( aCommand );
+	iPreviousCommand = aCommand;
+    if ( aCommand < EAlfDrawCommandsStart || aCommand > EAlfDrawCommandsEnd )
+    	{
+    	WriteInt8L( iScreenNumber );
+		}
+    else
+        {
+        // Uncomment following line to do chaff bitblit optimization
+#ifndef __NVG // TODO: Implement the 9-piece drawing for NVG
+        // DoPatternSearch( aCommand, aCommandSize );
+#endif
+        }
+    return ETrue;
+    }
+
+// ---------------------------------------------------------------------------
+// CreateTemporaryChunkL
+// ---------------------------------------------------------------------------
+//
+TBool CAlfRsSendBuffer::CreateTemporaryChunkL( TInt& aSize )
+    {
+    aSize+= KCacheChunkMinSize;
+    iCacheChunks.Append( RChunk() );
+    TInt result = iCacheChunks[iChunkInUse].CreateDisconnectedGlobal( KNullDesC, 0, aSize, aSize );
+    return result;
+    }
+
+// ---------------------------------------------------------------------------
+// OpenRewindChunkL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::OpenRewindChunkL( TInt aSize )
+    {
+#ifdef _OLD_STREAM    
+    if ( iBufStream && iChunkInUse) 
+        {
+        iBufStream->Close();
+        }
+    iBufStream = new(ELeave)RMemWriteStream;
+    iBufStream->Open( iCacheChunks[iChunkInUse].Base() + sizeof( TChunkHeader), aSize );
+#else
+    iStreamPtr = new(ELeave)TPtr8( (TUint8*)(iCacheChunks[iChunkInUse].Base() + sizeof( TChunkHeader)), aSize - sizeof( TChunkHeader));
+    
+#endif
+    iChunkHeader = reinterpret_cast<TChunkHeader*>(iCacheChunks[iChunkInUse].Base());
+    SeekL(0);
+    memset( iChunkHeader, 0, sizeof( TChunkHeader ) );
+    iUsedChunkMaxSize = aSize -  sizeof( TChunkHeader);
+    iChunkInUse++; 
+    }
+
+// ---------------------------------------------------------------------------
+// DoPatternSearch
+//
+// Pattern search seeks for predefined sequence of commands. In TSearchPatternBitBlit case the seqence is 
+// EAlfSetBrushStyle -> EAlfSetBrushStyle -> EAlfSetClippingRegion -> EAlfBitBltMasked -> EAlfResetClippingRegion .
+//
+// When possible pattern is found, the start offset of the pattern is saved. If pattern is
+// noticed 8 or more times in sequence, the pattern is complete. Functions seeks back to the
+// start offset and serializes cached data of the pattern. Some data can be dropped as it has 
+// no significance.
+// ---------------------------------------------------------------------------
+//
+#ifdef _ALF_PRINT_WS_COMMANDS_
+void CAlfRsSendBuffer::DoPatternSearch( const TUint8& aCommand, TInt aSize )
+#else
+void CAlfRsSendBuffer::DoPatternSearch( const TUint8& aCommand, TInt )
+#endif
+    {
+    TInt sizeOfPattern = sizeof(TSearchPatternBitBlit) / (3 * sizeof(TInt32)); // rows = size / width
+    if ( ( TSearchPatternBitBlit[iPatternSearchState][0] == aCommand  
+    		|| ( TSearchPatternBitBlit[iPatternSearchState][2] != KErrNotFound && TSearchPatternBitBlit[iPatternSearchState][2] == aCommand ))
+    		&& TSearchPatternBitBlit[iPatternSearchState][1] == iPatternSearchState )
+    	{
+    	TInt tmp = iPatternSearchState;
+    	iPatternSearchState = TSearchPatternBitBlit[iPatternSearchState+1][1];
+#ifdef _ALF_PRINT_WS_COMMANDS_
+    	TPatternCommand command( aCommand, aSize );
+    	iPatternCommands.Append( command );
+#endif    	
+    	if ( tmp == 0 && iPatterSearchSequentialBlits == 0 )
+    		{
+    		// This is the beginning of the sequence. Save position (offset minus size of the current command) 
+    		// the for later use.
+    		iPatternCacheBeginPosition = iOffset;
+#ifdef _OLD_STREAM    		
+    		iPatternCacheBeginPosition = TStreamPos( iPatternCacheBeginPosition - sizeof(TUint8) ); // the command
+#else
+    		iPatternCacheBeginPosition = iPatternCacheBeginPosition - sizeof(TUint8) ; // the command
+#endif
+    		iSearchPatternClipRegion.Clear();
+#ifdef _ALF_PRINT_WS_COMMANDS_
+    		iPatternCommands.Reset();
+#endif    		
+    		}
+    	else if ( tmp == sizeOfPattern - 1)
+    		{
+    		// Start from the beginning the next sequential pattern
+    		iPatternSearchState = TSearchPatternBitBlit[0][1]; 
+    		iPatterSearchSequentialBlits++;
+    		}
+    	}
+    else
+    	{
+    	TRAP_IGNORE(FinalizePatternL( aCommand ));
+    	}
+    }
+
+// ---------------------------------------------------------------------------
+// FinalizePatternL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::FinalizePatternL( const TUint8& aCommand )
+    {
+    // We are looking 8 or more connected chaff pieces 
+    if ( iPatterSearchSequentialBlits >= 9 )
+        {
+        iSearchPatternClipRegion.Tidy(); // will return only one region, if pieces are connected 
+        iSearchPatternBlitRect.Tidy();
+        
+        
+        if ( iSearchPatternClipRegion.Count() == 1 && iSearchPatternBlitRect.Count() == 1)
+            {
+#ifdef _OLD_STREAM
+            SeekL( iPatternCacheBeginPosition.Offset() );
+#else
+            SeekL( iPatternCacheBeginPosition );
+#endif
+            WriteInt8L( EAlfCombinedBitBlitMasked );
+#ifdef _ALF_PRINT_WS_COMMANDS_
+            TInt size = iPatterSearchSequentialBlits * sizeof(TBlitStruct) + 2 * sizeof(TRect);
+            iCommandDebugger->SetDescriptionAndSize( EAlfCombinedBitBlitMasked, size, R_ALF_COMMAND_DESCRIPTION_ARRAY );
+            iCommandDebugger->Print();
+            while ( iPatternCommands.Count())
+                {
+                iCommandDebugger->AdjustCommand( iPatternCommands[0].iCommand,  (-1) * iPatternCommands[0].iSize );
+                iPatternCommands.Remove(0);
+                }
+#endif
+            // item count
+            WriteInt8L( iPatterSearchSequentialBlits );
+            // Clipping region for all the pieces. 
+            // This contains the clippingregion (set by EAlfSetClippingRegion) and rect for all the pieces 
+            // (from EAlfBitBlit, EAlfBitBltRect, EAlfBitBlitMasked )
+            TRect clipRect = iSearchPatternClipRegion.BoundingRect();
+            TRect clipBlitRect = iSearchPatternBlitRect.BoundingRect();
+
+            WriteL( (TUint8*)&clipRect,     sizeof(TRect));
+            WriteL( (TUint8*)&clipBlitRect, sizeof(TRect));
+                        
+            // Items
+            while( iPatterSearchSequentialBlits-- )
+                {
+                TPoint point = iPatternHandleCache[iPatterSearchSequentialBlits].iTl;
+                WriteL( (TUint8*)&iPatternHandleCache[iPatterSearchSequentialBlits], sizeof(TBlitStruct)  );
+                }
+#ifndef _OPTIMIZE_WS_COMMANDS_ADVANCED_
+            WriteInt8L( EAlfSetPenStyle );
+            WriteInt32L( iPenStyle );
+#endif                        
+            // Write again the current command (after the pattern sequence), because we just overwrote it
+            WriteInt8L( aCommand );
+            }
+        }
+    ResetPatternSearch();
+    }
+
+// ---------------------------------------------------------------------------
+// ResetPatternSearch
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::ResetPatternSearch()
+    {
+    iPatternSearchState = ESeekSetClippingRegion;
+    iPatterSearchSequentialBlits = 0;
+    iSearchPatternClipRegion.Clear();
+    iSearchPatternBlitRect.Clear();
+    iPatternHandleCache.Reset();
+#ifdef _ALF_PRINT_WS_COMMANDS_
+    iPatternCommands.Reset();
+#endif
+    }
+
+// ---------------------------------------------------------------------------
+// AppendPatternSearchCache
+// saves masked bitblits to the cache
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::AppendPatternSearchCache( const CFbsBitmap& aSourceBitmap, const CFbsBitmap* aMaskBitmap, const TRect& aSourceRect, const TPoint& aDestPos, TBool aInvertMask )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    TSize size1 = aSourceRect.Size();
+    TSize size2 = aSourceBitmap.SizeInPixels();
+    if ( aInvertMask == 1 )
+        {
+        TInt handle = aMaskBitmap ?  aMaskBitmap->Handle() : 0;
+        iPatternHandleCache.Append( TBlitStruct( aSourceBitmap.Handle(),handle, aDestPos ) ); 
+        TRect rect( TPoint(0,0), aSourceRect.Size() );
+        rect.Move( aDestPos );
+        iSearchPatternBlitRect.AddRect( rect );
+        }
+    else
+        {
+        ResetPatternSearch();
+        }
+    }    
+
+
+// ---------------------------------------------------------------------------
+// InsertPaddingL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::InsertPaddingL()
+    {
+    // padding is required for the 1st part of the package, because the 2nd package 
+    // is attached straight to it and it MUST start at offset divisible by 4. Otherwise 
+    // possible strings in the second package will not be correctly alligned.
+    TInt offset = iOffset; 
+    TInt padding = offset % KDivisibleByX;
+    if ( padding > 0)
+        {
+        padding = KDivisibleByX - ( offset + sizeof(TUint8) * 2 ) % KDivisibleByX; // 2 = sizeof( EAlfPacketPadding + padding )
+        WriteInt8L( EAlfPacketPadding );
+		WriteInt8L( padding );
+		while( padding--)
+            {
+            WriteInt8L( 0 );
+			}
+        if ( !iReceivingDrawingCommands )
+            {
+            WriteInt8L( EAlfCommandEndMarker );
+			}
+        }
+#ifdef _DEBUG
+    ASSERT( ( offset = iOffset ) % KDivisibleByX == 0);
+#endif    
+    }
+
+// ---------------------------------------------------------------------------
+// SetFlag
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::SetFlag( TAlfSendBufferFrameFlags aFlag )
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    iFlags |= aFlag;
+    }
+
+// ---------------------------------------------------------------------------
+// EndFrameL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::EndFrameL()
+    {
+    if (iDisabled) // return if this send buffer is not in use
+        {
+        return;
+        }
+    
+    TUint8 command(EAlfPacketReady);
+    if ( iFlags & EAlfTransparentContent && !(iFlags & EAlfTransparentContentFlush ) )
+        {
+        InsertPaddingL();
+        }
+
+    if ( WriteFollowingFrameOffsetL() )
+        {
+        WriteCommandL( command );  
+        }
+#ifdef ALF_DEBUG_TRACK_DRAWING
+    TInt trackThisNode = 0;
+    if ( trackThisNode )
+        {
+        WriteIntsL( EAlfDebugTrackNode, 2, (TInt32)&iWindowId, 1 );
+        }
+#endif
+    }
+
+// ---------------------------------------------------------------------------
+// SeekL
+// ---------------------------------------------------------------------------
+//
+void CAlfRsSendBuffer::SeekL( const TInt aOffset )
+    {
+#ifdef _OLD_STREAM    
+    iBufStream->Sink()->SeekL( MStreamBuf::EWrite, TStreamPos(aOffset));
+#endif    
+    iOffset = aOffset;
+    }