diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/AlfRenderStage/inc/alfrssendbuffer.h --- /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 +#include +#include +#include +#include +#include +#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 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 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 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* 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* 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 &aOffset); + void WriteArrayHeaderL(const TOffsetElem &aIndexArrayOffset); + TOffsetElem WriteIndexArrayL(const RArray &aOffset); + void InitMarker(TInt &aMarker); + void StartMarkerL(TInt &aMarker, TRect &aRectangle, TInt &aLayer, TRect aBoundingRectangle, TInt aLayerId); + void EndMarkerL(RArray &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 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 iSearchPatternClipRegion; + + RRegionBuf iSearchPatternBlitRect; + + class TBlitStruct + { + + public: + + TBlitStruct( TInt aHandle, TInt aMaskHandle, TPoint aTl ) : iHandle( aHandle ), iMaskHandle( aMaskHandle ), iTl( aTl ){}; + TInt iHandle; + TInt iMaskHandle; + TPoint iTl; + }; + + RArray 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 iPatternCommands; + +#endif + + // caches text. If same text is used 2nd time inside buffer + HBufC16* iCachedText; + CAlfCompositionCntrlClient* iAlfCompositionCntrlClient; + + // array implementation + RArray iOffsetArray; + TInt iMarker; + TRect iBoundingRectangle; + TInt iLayerId; + TInt iArrayImplOffset; + TInt iPreviousBlockOffset; + TInt iExtraLayerId; + TBool iLayersEnabled; + }; +#endif /*CALFSENDBUFFER_H_*/