--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/AlfRenderStage/inc/alfrssendbuffer.h Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,795 @@
+/*
+* 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.
+*
+*/
+
+#ifndef CALFSENDBUFFER_H_
+#define CALFSENDBUFFER_H_
+
+#include <e32cmn.h>
+#include <e32std.h>
+#include <s32mem.h>
+#include <gdi.h>
+#include <alfwindowstructs.h>
+#include <huiwscanvascommands.h>
+#include "alfrenderstageutils.h"
+
+#define _OLD_STREAM
+
+const TInt KAlfWsCommandCount = 90;
+const TInt KAlfWsMaxParameterCount = 15;
+const TInt KAlfRsSearchRectMaxCount = 9;
+
+class RAlfBridgerClient;
+class CAlfCommandDebug;
+class TRgb;
+class CAlfRenderStage;
+class TResourceReader;
+class CAlfCompositionCntrlClient;
+/**
+ * The class handles data serialization and syncronous sending to server. Multiple renderstages will share the same chunk.
+ *
+ * @code
+ * iAlfSendBuffer = CAlfRsSendBuffer::NewL();
+ * @endcode
+ *
+ * @lib alfrenderstage.lib
+ * @since S60 v5.2
+ */
+NONSHARABLE_CLASS(CAlfRsSendBuffer) : public CActive, public MAlfBridge
+ {
+ public: // New methods
+
+ /**
+ * NewL
+ *
+ * Constructor
+ *
+ * @param aParent
+ * @param aScreenNumber
+ * @return New instance of the class
+ */
+ static CAlfRsSendBuffer* NewL( CAlfRenderStage& aParent, TInt aScreenNumber );
+
+ /**
+ * C++ destructor.
+ */
+ virtual ~CAlfRsSendBuffer();
+
+ /**
+ * ConnectL
+ *
+ * Establish connection to AlfStreamerServer.
+ *
+ * @return ETrue, if connection was made or connection was already established. Otherwise returns EFalse
+ */
+ TBool ConnectL();
+
+ /**
+ * Connected
+ *
+ * Check connection state
+ *
+ * @return Connection state
+ */
+ TBool Connected(){ return iChunk.Handle(); }
+
+ /**
+ * WriteIntsL
+ *
+ * Convenience function for writing TInt values to the stream
+ *
+ * @param aCommand CommandId
+ * @param aCount Amount of TInt values to be streamed
+ * @param aFirst The first value
+ * @param ... variable aCount-1 amount of TInt values
+ */
+ void WriteIntsL( const TUint8& aCommand, TInt aCount, TRefByValue<const TInt> aFirst, ...);
+
+ /**
+ * WriteIntL
+ *
+ * Convenience function for writing possible unsupported command (depending on its parameters) to the stream
+ *
+ * @param aCommand CommandId
+ * @param aValue parameters value
+ */
+ void WriteIntL( const TUint8& aCommand, TInt aValue );
+
+ /**
+ * WriteRegionL
+ *
+ * Convenience function for writing region to the stream
+ *
+ * @param aCommand CommandId
+ * @param aRegion Region
+ */
+ void WriteRegionL( const TUint8& aCommand, const TRegion& aRegion );
+
+ /**
+ * WriteDescriptorAndIntsL
+ *
+ * Convenience function for writing TDesC reference and TInt values to the stream.
+ * Inserts padding to ensure that text starts on divisible by 4 offset.
+ *
+ * @param aCommand CommandId
+ * @param aText Descriptor to be streamed
+ * @param aCount Amount of TInt values to be streamed
+ * @param aFirst The first value
+ * @param ... variable aCount-1 amount of TInt values
+ */
+ void WriteDescriptorAndIntsL( const TUint8& aCommand, const TDesC& aText, TInt aCount, TRefByValue<const TInt> aFirst,... );
+
+ /**
+ * WriteDescriptorL
+ *
+ * Convenience function for writing TDesC reference to the stream.
+ * Inserts padding to ensure that text starts on divisible by 4 offset.
+ *
+ * @param aCommand CommandId
+ * @param aText Descriptor to be streamed
+ * @param aTextParameter Text parameters
+ * @param aCount Amount of Ints to be streamed
+ * @param aFirst The first value
+ * @param ... variable aCount-1 amount of TInt values
+ */
+ void WriteDescriptorAndIntsL(const TUint8& aCommand, const TDesC& aText, const CGraphicsContext::TTextParameters* aTextParameter, TInt aCount, TRefByValue<const TInt> aFirst, ... );
+
+ /**
+ * WriteCommandL
+ *
+ * Convenience function for writing 1 value to the stream
+ *
+ * @param aCommand Command
+ * @param aSize Size
+ */
+ void WriteCommandL( const TUint8& aCommand, TInt aSize = 0);
+
+ /**
+ * WritePointArrayL
+ *
+ * Convenience function for writing pointer array to the stream
+ *
+ * @param aCommand CommandId
+ * @param aPoWriteIntList Point array to be streamed
+ */
+ void WritePointArrayL( const TUint8& aCommand, const CArrayFix<TPoint>* aPoWriteIntList );
+
+ /**
+ * WritePointArrayL
+ *
+ * Convenience function for writing pointer array to the stream
+ *
+ * @param aCommand CommandId
+ * @param aPoWriteIntList Point array to be streamed
+ * @param aNumPoints Point array to be streamed
+ */
+ void WritePointArrayL( const TUint8& aCommand, const TPoint* aPoWriteIntList, TInt aNumPoints );
+
+ /**
+ * WritePointArrayL
+ *
+ * Convenience function for writing pointer array to the stream
+ *
+ * @param aCommand CommandId
+ * @param aPoWriteIntList Point array to be streamed
+ */
+ void WritePointArrayL( const TUint8& aCommand, const TArray<TPoint>* aPoWriteIntList );
+
+ /**
+ * WriteFlagsL
+ *
+ * Write flags to the stream
+ */
+ void WriteFlagsL();
+
+ //
+ // ARRAY IMPLEMENTATION
+ //
+ struct TOffsetElem
+ {
+ TInt32 iOffset; // offset from beginning of buffer
+ TInt32 iSize; // size of the data.
+ TInt32 iLayerId;
+ TRect iBoundingRectangle;
+ };
+
+
+ void WriteArrayHeaderTemplateL();
+ void InitTOffsetElemArray(RArray<TOffsetElem> &aOffset);
+ void WriteArrayHeaderL(const TOffsetElem &aIndexArrayOffset);
+ TOffsetElem WriteIndexArrayL(const RArray<TOffsetElem> &aOffset);
+ void InitMarker(TInt &aMarker);
+ void StartMarkerL(TInt &aMarker, TRect &aRectangle, TInt &aLayer, TRect aBoundingRectangle, TInt aLayerId);
+ void EndMarkerL(RArray<TOffsetElem> &aOffset, TInt &aMarker, const TRect &aRectangle, TInt aLayerId);
+ void StartMarkerL(TRect aBoundingRectangle, TInt aLayerId);
+ void EndMarkerL();
+
+ /**
+ * SendL
+ *
+ * Sends commands to via AlfBridger to AlfStreamerServer. Flushes the buffer.
+ * iBufStream is ready for writing after this call.
+ *
+ * @param aStatus Request status
+ */
+ void SendL( TRequestStatus* aStatus );
+
+ /**
+ * Commit
+ *
+ * Report the last written offset. Reader side may read until
+ * offset.
+ *
+ */
+ void Commit();
+
+ /**
+ * CommitL
+ *
+ * Starts the timer for FlushBuffer call. The idea is to deliver bigger
+ * patch of commands to alf in one go and avoid unnecessary IPC calls.
+ *
+ */
+ void CommitL( );
+
+ /**
+ * SetFlag
+ *
+ * Set flags
+ *
+ * @param aFlag Flags
+ */
+ void SetFlag( TAlfSendBufferFrameFlags aFlag );
+
+ /**
+ * EndFrameL
+ *
+ * Prepares frame for sending
+ */
+ void EndFrameL();
+
+ /**
+ * FrameContainsDataL
+ *
+ * @return ETrue, if data has been serialized to the frame after previous call to PrepareBufferL. this is used for filtering out empty
+ * frames. Wserv might be fixed in the future and this could become obsolete.
+ */
+ TBool FrameContainsDataL();
+
+ /**
+ * SendAsyncCmd
+ *
+ * Called by CRsAlfNativeWindowListener::RequestEvent. Used when requesting native window handle from
+ * Alf.
+ *
+ * @param aFlag aCmd
+ * @param aFlag aBuf
+ * @param aFlag aStatus
+ */
+ void SendAsyncCmd(TInt aCmd, TDes8& aBuf, TRequestStatus& aStatus);
+
+ /**
+ * OpenPrimaryChunkForWritingL
+ *
+ * Open the stream
+ */
+ void OpenPrimaryChunkForWritingL();
+
+ /**
+ * PrepareBufferL
+ *
+ * Resets buffer. Must be called before Write*L and SendSyncL.
+ */
+ void PrepareBufferL();
+
+ /**
+ * WriteWindowDataL
+ *
+ * Writes data to the stream
+ *
+ * @param aWindowUid
+ * @param aRegionSize
+ * @param aShapeRegionSize
+ */
+ void WriteWindowDataL(TUint32 aWindowUid, TInt aRegionSize, TInt aShapeRegionSize );
+
+ /**
+ * WriteFrameSizeTemplateL
+ *
+ * Writes a temporary value to the beginning of a frame. This value is later updated with WriteNextFrameBeginL.
+ */
+ void WriteFollowingFrameOffsetTemplateL();
+
+ /**
+ * WriteFollowingFrameOffsetL
+ *
+ * Goes back to header of the drawing commands and updates the offset to the following frame.
+ * This is called, when drawing into a single window in a frame is complete.
+ *
+ * @return ETrue, If this frame contains any commands. Otherwise EFalse.
+ */
+ TBool WriteFollowingFrameOffsetL(TBool aWriteArray= ETrue);
+
+ /**
+ * WriteWindowIdentifierL
+ *
+ * Convience function for writing window id and group id to the stream
+ */
+ void WriteWindowIdentifierL();
+
+ /**
+ * FlushBuffer
+ *
+ * Commands are not passed immediately after they are serialized. There
+ * is a timer, which regularly flushes the buffer. See doFlushBuffer.
+ *
+ * Buffer is also flushed (or in fact the flushtimer is canceled, and buffer
+ * is flushed) when SendL is called from CAlfRsRenderStage
+ *
+ */
+ void FlushBuffer();
+
+ /**
+ * SetSupportedCommand
+ *
+ * Sets this command as supported
+ *
+ * @param aIndex
+ * @param aSupport
+ */
+ void SetSupportedCommand( TInt aIndex, TInt8 aSupport );
+
+ /**
+ * AppendPatternSearchCache
+ *
+ * Caches data for the pattern search. This is call from CAlfRsGc. Cache is released by
+ * ResetPatternSearch.
+ *
+ * @param aSourceBitmap
+ * @param aMaskBitmap
+ * @param aSourceRect
+ * @param aDestPos
+ * @param aInvertMask
+ */
+ void AppendPatternSearchCache( const CFbsBitmap& aSourceBitmap, const CFbsBitmap* aMaskBitmap,const TRect& aSourceRect, const TPoint& aDestPos, TBool aInvertMask );
+
+ /**
+ * PreviousCommand
+ *
+ * This is used for filtering out sequential reset commands in window command stream
+ *
+ * @return Previous command
+ */
+ inline TInt PreviousCommand(){ return iPreviousCommand; }
+
+ public: // From CActive
+
+ void RunL();
+ void DoCancel();
+
+ private:
+
+ /**
+ * CAlfRsSendBuffer
+ *
+ * C++ constructor
+ *
+ * @param aParent
+ * @param aScreenNumber
+ */
+ CAlfRsSendBuffer( CAlfRenderStage& aParent, TInt aScreenNumber ) : iParent( aParent), iScreenNumber( aScreenNumber) , CActive( EPriorityStandard ){CActiveScheduler::Add( this ); };
+
+ /**
+ * ConstructL
+ *
+ * Constructor
+ */
+ void ConstructL();
+
+ /**
+ * ReadNonSupportedCommandsL
+ *
+ * It is known that some commands are not/cannot be supported by certain
+ * renderers. Each frame is inspected in case of such command and frame
+ * is marked if it has unsupported commands for certain renderer. This
+ * information can be in the future used for selecting suitable renderer
+ * during runtime.
+ *
+ * @todo This table could be shared with multiple renderstages.
+ * Currently each sendbuffer has own table.
+ */
+ void ReadNonSupportedCommandsL();
+
+ // only in debug mode
+#ifdef _ALF_PRINT_WS_COMMANDS_
+ void ReadCommandDescriptionsL();
+#endif
+
+ /**
+ * SeekL
+ *
+ */
+ void SeekL( const TInt aOffset );
+
+ /**
+ * ConvertToBitsL
+ *
+ * Converts aCount bytes of data into one byte.
+ *
+ * @param aCount Must be under 7.
+ * @param aReader
+ * @return Converted result
+ */
+ TUint8 ConvertToBitsL( TInt aCount, TResourceReader* aReader );
+
+ /**
+ * JumpToAnotherChunkL
+ */
+ void JumpToAnotherChunkL( TInt32 aChunkId, TInt aChunkSize );
+
+ /**
+ * WriteInt8L
+ */
+ inline void WriteInt8L( const TInt8& aValue )
+ {
+#ifdef _OLD_STREAM
+ iBufStream->WriteInt8L( aValue );
+#else
+ //memcpy( ( TUint8*)(iStreamPtr->Ptr()+iOffset), (const TUint8*)&aValue, sizeof(TInt8));
+ *(( TUint8*)(iStreamPtr->Ptr()+iOffset)) = aValue;
+#endif
+ iOffset += sizeof(TInt8);
+ }
+
+ /**
+ * WriteInt32L
+ */
+ inline void WriteInt32L( const TInt32& aValue )
+ {
+#ifdef _OLD_STREAM
+ iBufStream->WriteInt32L( aValue );
+#else
+ memcpy( ( TUint8*)(iStreamPtr->Ptr()+iOffset), (const TUint8*)&aValue, sizeof(TInt32));
+#endif
+ iOffset += sizeof(TInt32);
+ }
+
+ /**
+ * WriteL
+ */
+ inline void WriteL( const TUint8* aPtr, TInt aSize )
+ {
+#ifdef _OLD_STREAM
+ iBufStream->WriteL( aPtr, aSize );
+#else
+ memcpy( ( TUint8*)(iStreamPtr->Ptr()+iOffset), (const TUint8*)aPtr, aSize);
+#endif
+ iOffset += aSize;
+ }
+
+ /**
+ * DoCreateTemporaryChunkL
+ */
+ void DoCreateTemporaryChunkL( TInt aMinimumRequiredSize );
+
+ /**
+ * DoWrapL
+ *
+ * Wraps the writing in the chunk. This happens when write head has reached the maximum size of the chunk.
+ * After wrapping, writing continues from the beginning of the chunk. If wrap happens during a frame, then
+ * the frame is split into two parts. The first part is padded (@see InsertPaddingL)
+ *
+ */
+ void DoWrapL( TInt aCommandSize, TBool aCreateTempororaryChunk );
+
+ /**
+ * ReserveSpaceL
+ *
+ * Checks if there is enough space to stream the command. Calls DoWrap
+ * or DoWait, if there is not enough space for serializing the command.
+ *
+ * @param aCommandSize
+ */
+ TBool ReserveSpaceL( TInt aCommandSize );
+
+ /**
+ * InitCommandL
+ */
+ TBool InitCommandL( const TUint8& aCommand, TInt aSize );
+
+ /**
+ * CreateTemporaryChunkL
+ */
+ TBool CreateTemporaryChunkL( TInt& aSize );
+
+ /**
+ * OpenRewindChunkL
+ */
+ void OpenRewindChunkL( TInt aSize );
+
+ /**
+ * DoPatternSearch
+ *
+ * Searches for certain bitblit pattern.
+ *
+ * This functions is most likely to change in the future.
+ *
+ */
+ void DoPatternSearch( const TUint8& aCommand, TInt aSize );
+
+ /**
+ * ResetPatternSearch
+ *
+ * Called when searched pattern was not found and search needs to start
+ * from beginning.
+ */
+ void ResetPatternSearch();
+
+ /**
+ * FinalizePatternL
+ *
+ * Full pattern was found. Replace the bitblits with EAlfCombinedBitBlit
+ * that joins the clipping regions, drawrects and partial images into single
+ * command.
+ */
+ void FinalizePatternL(const TUint8& aCommand);
+
+ /**
+ * InsertPaddingL
+ *
+ * Each frame payload need to start on address divisible by 4.
+ * Otherwise operations on the streamed data will fail due to alignment
+ * issues. This function adds padding if necessary.
+ */
+ void InsertPaddingL();
+
+ public:
+ RAlfBridgerClient* Client()
+ {
+ return iAlfBridgerClient;
+ }
+ void WriteIntsL(TUint8 aCommand, TInt aCount, TInt* aArray);
+
+ private: // data
+
+ /**
+ * If this is true this class acts as a stub, the does not really do anything.
+ * That is used when we handle tv-out drawing commands as they should not go to anywhere.
+ */
+ TBool iDisabled;
+
+ /**
+ * Window Uid is cached for the use of FlushBuffer
+ */
+ TUint32 iWindowId;
+
+ TInt iWindowGroupIdentifier;
+
+ /**
+ * Stream access for chunk received from server side
+ */
+#ifdef _OLD_STREAM
+ RMemWriteStream* iBufStream;
+#else
+ TPtr8* iStreamPtr;
+#endif
+
+ TInt iNextFrameOffsetPos;
+
+ TBool iIsSprite;
+
+ /**
+ * Bridge to Alf stream server
+ *
+ * Own.
+ */
+ RAlfBridgerClient* iAlfBridgerClient;
+
+ /**
+ * Our handle to server chunk. InitBufferL must be called before this is valid.
+ */
+ RChunk iChunk;
+
+ /**
+ * Cache chunks are needed for 2 purposes. See DoCreateTemporaryChunkL for more information.
+ * 1. During booting, the primary chunk (owned by alf) is not available and data must be serialized into something
+ * 2. App (and sequentially Wserv) pushes more data than the primary chunk can chew (write head reachs read head).
+ */
+ RArray<RChunk> iCacheChunks;
+
+ /**
+ * Non drawing window updates have no relevance to the drawing. If frame update contains only such
+ * commands, it can be discarded altogether.
+ *
+ * Use Mark() to mark the place of frame start. Use RollBack() to set the buffer to the original place,
+ * if only non-drawing commands were issued. See CAlfGraphicsContext::iDrawCommandCount for more details.
+ */
+#ifdef _OLD_STREAM
+ TStreamPos iFrameBeginOffset;
+#else
+ TInt iFrameBeginOffset;
+#endif
+ /**
+ * Data transfer is normally asynchronous operation. iParent is used for the callback.
+ * Not own.
+ */
+ CAlfRenderStage& iParent;
+
+ /**
+ * The maximum size of the iChunk and iBufStream
+ */
+ TInt iUsedChunkMaxSize;
+
+ TInt iPrimaryChunkMaxSize;
+
+ TTime iBeginTime;
+
+ TInt iOffset;
+
+ /**
+ * iState values
+ */
+ enum
+ {
+ EIdle,
+ EWaitingAck,
+ EWaitingHandle
+ };
+
+ TInt iState;
+
+ TInt iTemplateOpen;
+
+ TRequestStatus* iQuedStatus;
+
+ TChunkHeader* iChunkHeader;
+
+ TBool iReceivingDrawingCommands;
+
+ /**
+ * Debug variable for tracking the delivered chunk sizes. Can be used for optimizing the junk size.
+ */
+ //TInt iMaxSentBatchSize;
+
+ TBool iWrappingFrame;
+
+ /**
+ * Screen connected to this CAlfRsSendBuffer
+ */
+ TInt iScreenNumber;
+
+ CPeriodic* iFlushBufferTimer;
+
+ TUint8 iNonSupportedCommandsInWindow;
+
+ /**
+ * See ReadNonSupportedCommandsL for more information
+ */
+ TUint8 iNonSupportedCommands[KAlfWsCommandCount];
+
+ TUint8 iSupportedCommandParameters[KAlfWsCommandCount][2]; // [index of first parameter in iSupportedParameters][index of last parameter in iSupportedParameters]
+ TInt8 iSupportedParameters[KAlfWsMaxParameterCount][2]; // [parameter value][render support], note the limited count
+
+ TInt iPerformanceIssueCommandCount;
+
+ TInt iMaxPerformanceIssueCommandCount;
+
+ struct TWindowHeaderStruct
+ {
+ TInt32 iWindowEndOffset;
+ TUint8 iCommandEndMarker;
+ TUint8 iContainsUnsupportedCommandsCommand;
+ TUint8 iUnsupportedCommandsInWindow;
+ };
+
+ TWindowHeaderStruct iWindowHeaderStruct;
+
+ TUint8 iFramePadding;
+
+ TInt32 iFlags;
+
+ TUint8 iPreviousCommand;
+
+ /**
+ * AlfRsSendBuffers searches certain bitblit pattern in the serialized
+ * commands. It tries to combine joined bitblits into one command, which
+ * can be handled more efficiently on HW.
+ *
+ * See DoPatternSearch, AppendPatternSearchCache, ResetPatternSearch and FinalizePatternL for more
+ * information.
+ *
+ */
+ TInt iPatternSearchState;
+
+ TInt iPatterSearchSequentialBlits;
+
+ TInt iPenStyle;
+
+ /**
+ * Under normal circumtances, a single chunk is used for passing the
+ * commands to alf. However, if Wserv pushes large frames that fill the
+ * whole chunk, alfsendbuffer takes a growing cache chunk into use.
+ *
+ * The cache chunk is destroyed, when it is no longer needed.
+ */
+
+ TUint8 iChunkInUse;
+
+ /**
+ * Joined clipping region is usually different than the following joined blit region (iSearchPatternBlitRect)
+ */
+ RRegionBuf<KAlfRsSearchRectMaxCount> iSearchPatternClipRegion;
+
+ RRegionBuf<KAlfRsSearchRectMaxCount> iSearchPatternBlitRect;
+
+ class TBlitStruct
+ {
+
+ public:
+
+ TBlitStruct( TInt aHandle, TInt aMaskHandle, TPoint aTl ) : iHandle( aHandle ), iMaskHandle( aMaskHandle ), iTl( aTl ){};
+ TInt iHandle;
+ TInt iMaskHandle;
+ TPoint iTl;
+ };
+
+ RArray<TBlitStruct> iPatternHandleCache;
+#ifdef _OLD_STREAM
+ TStreamPos iPatternCacheBeginPosition;
+#else
+ TInt iPatternCacheBeginPosition;
+#endif
+ TBool iBooting;
+
+#ifdef _ALF_PRINT_WS_COMMANDS_
+
+ /**
+ * debug for printing the serializaed commands in human understandable format
+ */
+ TBool iLog;
+
+ CAlfCommandDebug* iCommandDebugger;
+
+ class TPatternCommand
+ {
+ public:
+
+ TPatternCommand( TUint8 aCommand, TInt aSize ): iCommand( aCommand ), iSize(aSize){};
+
+ TUint8 iCommand;
+
+ TInt iSize;
+ };
+
+ RArray<TPatternCommand> iPatternCommands;
+
+#endif
+
+ // caches text. If same text is used 2nd time inside buffer
+ HBufC16* iCachedText;
+ CAlfCompositionCntrlClient* iAlfCompositionCntrlClient;
+
+ // array implementation
+ RArray<TOffsetElem> iOffsetArray;
+ TInt iMarker;
+ TRect iBoundingRectangle;
+ TInt iLayerId;
+ TInt iArrayImplOffset;
+ TInt iPreviousBlockOffset;
+ TInt iExtraLayerId;
+ TBool iLayersEnabled;
+ };
+#endif /*CALFSENDBUFFER_H_*/