--- /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;
+ }