diff -r 000000000000 -r 5d03bc08d59c graphicscomposition/openwfsupport/inc/surfacestream.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicscomposition/openwfsupport/inc/surfacestream.h Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,672 @@ +// Copyright (c) 1995-2009 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: +// SurfaceStream.h +// CSurfaceStream declaration + +#ifndef SURFACESTREAM_H +#define SURFACESTREAM_H + +// INCLUDES +#include +#include +#include +#include +#include +#include +#include "symbianstream.h" + +#if defined(ENABLE_NF_LOGGING) +#define NFLOG(X) RDebug::Printf X +#else +#define NFLOG(X) +#endif + +// CLASS DECLARATION + +// Each surface buffer has its corresponding TBufferInfo to hold reference count and memory offset +struct TBufferInfo + { + TInt iRefCount; + TInt iOffset; + }; + +// Notification data +struct TNotificationBase + { + TRequestStatus* iStatus; + TThreadId iThreadId; + TInt iBufferNumber; + TInt iSerialNumber; + TInt iGlobalIndex; + }; + +struct TNotificationDisplayed: public TNotificationBase + { + TUint32* iTimeStamp; + }; + +struct TNotificationDisplayedX: public TNotificationBase + { + TInt iCount; + }; + +struct TNotificationAvailable: public TNotificationBase + { + TRequestStatus* iNewStatus; + TThreadId iNewThreadId; + TInt iNewBufferNumber; + TInt iNewGlobalIndex; + }; + + +class COpenWfcStreamMap; +/** + * CSurfaceStream + * internal + */ +NONSHARABLE_CLASS( CSurfaceStream ) : public CBase + { + struct TNewGlobalNotifications; + + private: + class Guard + { + public: + Guard(RFastLock& aLock); + ~Guard(); + private: + RFastLock& iLock; + RHeap* iHeap; + }; + + struct ContentUpdatedParams + { + ContentUpdatedParams(TInt aBuffer, + TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp, + TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes, + TRequestStatus* aStatusConsumed, const TRegion* aRegion, + TBool aImmediateAvailable, + TInt32 aImmediateVisibility, const TNewGlobalNotifications& aGlobalNotifications); + TInt iBuffer; + TRequestStatus* iStatusDisplayed; + TUint32* iTimeStamp; + TRequestStatus* iStatusDispXTimes; + TInt* iDisplayedXTimes; + TRequestStatus* iStatusConsumed; + const TRegion* iRegion; + TBool iImmediateAvailable; + TInt32 iImmediateVisibility; + const TNewGlobalNotifications& iGlobalNotifications; + }; + +public: + enum CallBackOperations + { + EDefaultOperation, + ECheckVisibleOperation + }; +public: + // Constructors and destructor + + /** + * Destructor. + */ + ~CSurfaceStream(); + + /** + * Two-phased constructor. + */ + static CSurfaceStream* NewL(const TSurfaceId& aId); + + /** + * Two-phased constructor. + */ + static CSurfaceStream* NewLC(const TSurfaceId& aId); + + /** + Helper to resolve handle to stream object + **/ + static CSurfaceStream* FromHandle(SymbianStreamType aNativeStreamHandle); + + /** + * A helper function that returns the bytes per pixel for a given pixel format UID + * @param aPixelFormat Pixel format UID to convert + * @return Positive: bytes per pixel; negative is pixels per byte; 0 is error + */ + + static TInt BytesPerPixel(TUidPixelFormat aPixelFormat); + /** + Helper to resolve handle to stream object + **/ + SymbianStreamType ToHandle(); + +public: + //Internal helpers + /** Returns internal surface ID. + * + * @return surface id asociated with this stream + **/ + const TSurfaceId& SurfaceId()const; + +public: + //OpenWF-C SI/CT/MIG API implementation + + /** + * Increase stream's reference count by one. + * + */ + void + AddReference(); + + /** + * Decrease stream's reference count by one and destroy + * the stream, if the reference count goes to zero. + * + * All acquired read & write buffers must be released + * before calling WFC_Native_Destroy. + * + */ + void + ReleaseReference(); + + /** + * internal + * + * @return flag if reference count is now zero. + * + */ + TBool + RemainingReference(); + + /** + * internal + * + * Sets flipped state. + * + */ + void + SetFlipState(TBool aFlip); + + /** + * Get stream "frame header". Can be used to query + * all or some of the frame properties. + * + * @param width Pointer to location where width parameter should be saved + * @param height Pointer to location where height parameter should be saved + * @param stride Pointer to location where stride (row size in bytes) + * parameter should be saved + * @param pixelSize Pointer to location where pizelSize (pixel size in bytes) + * parameter should be saved + + * Passing a NULL pointer implies that particular + * value is of no interest to caller. E.g. + * GetHeader(stream, &w, &h, NULL, NULL, NULL); + * would only fetch width & height parameters. + */ + void + GetHeader(khronos_int32_t* width, + khronos_int32_t* height, + khronos_int32_t* stride, + SymOwfPixelFormat* format, + khronos_int32_t* pixelSize); + + /** + * Acquires read buffer for stream. For > 1 buffer + * streams this function doesn't block, but simply returns + * WFC_INVALID_HANDLE if no buffer is available for reading. + * For 1 buffer stream the caller is blocked until the buffer + * is ready for reading (the reader has committed the buffer, + * that is.) + * + * + * @return WFC_INVALID_HANDLE if no buffer is available or + * handle to last committed buffer. + * + * An example sequence for 3 buffer stream where + * producer produces frames approx. after every ~5th time unit. + * Consumer consumes buffers at constant rate of 1buf/time unit. + * Pframe is the number/handle of buffer that is being written by + * the producer (let's assume that it takes 2 time units + * for producer to produce a frame/buffer.) Cframe is the number/ + * handle of the buffer the consumer receives from AcquireReadBuffer(). + * "i" stands for WFC_INVALID_HANDLE: + * + * Time: 0 5 10 15 20 25 + * Pframe: 0 1 2 0 1 ... + * Cframe: ii00000111112222200000111... + */ + SymbianStreamBuffer + AcquireReadBuffer(); + + /** + * Releases read buffer. + * + * When read buffer is released, it is marked as clean to + * be written again, unless it is the only committed buffer + * in which case it is recycled so that the same buffer + * can be read again (as long as no new buffers are committed + * by the producer) + * + * @param buf Buffer handle. Must be valid read buffer handle for + * given stream. + * @return KErrNone if succeessful or KErrBadHandle if buf is not a currently + * open write buffer on this stream; + */ + TInt + ReleaseReadBuffer(SymbianStreamBuffer buf); + + /** + * Acquires write buffer for stream. + * + * Returns handle to a buffer that can be used to write + * data into stream. If no clean buffer is available, + * invalid handle is returned. + * + * + * @return Handle to a writable buffer + */ + SymbianStreamBuffer + AcquireWriteBuffer(); + + /** + * Releases write buffer to stream. + * Released buffer is made new front buffer, i.e., producer is expected + * to release buffer is the same order they were acquired. + * + * @param buf Buffer handle. Must be valid write buffer handle + * for given stream. + */ + void + ReleaseWriteBuffer(SymbianStreamBuffer buf); + + /** + * Add event observer for stream. Observers are served in + * first-come-first-serve fashion. That is, newest observer + * is always placed at the end of the chain. If the observer + * is already in the chain, it's popped out and moved to + * the end of the chain. + * + * @param observer Observer (callback function) who should + * be notified when something interesting happens in the stream. + * @param data Additional data to pass to callback function + * + * @return 0 if successful, -1 if stream handle is invalid, -2 if + * OOM situation occurs. + */ + int AddObserver(SymOwfStreamCallback observer, + void* data,MultipleSymbianStreamEventBits aEvents); + + /** + * Remove stream event observer. Observer is removed from + * the stream's event nofitication chain and won't receive + * any events from the stream afterwards. + * + * @param observer Observer (callback function) + * + * @param 0 if successful, -1 otherwise + */ + int RemoveObserver(SymOwfStreamCallback observer, + void* aData,MultipleSymbianStreamEventBits aEvents); + + /** + * Returns pointer to pixel buffer. + * + * @param buffer Handle of buffer + */ + void* + GetBufferPtrL(SymbianStreamBuffer buffer); + + /** + * Undocumented protection flag + * + * @param flag enable disable protection + */ + void + SetProtectionFlag(TBool flag); + + TInt BufferHandleToIndex(SymbianStreamBuffer aBuff); + + /** + * Add event observer for stream. Observers are served in + * first-come-first-serve fashion. That is, newest observer + * is always placed at the end of the chain. + * + * @param observer Observer (callback function) who should + * be notified when something interesting happens in the stream. + * @aEvent The event corresponding to the observer + * @aScreenNumber The context identifier (screen number) + * @param data Additional data to pass to callback function + * + * @return KErrNone if successful + * KErrArgument if un unknown event is registered + * KErrOverflow if the observer was already registered + * An other system wide error if container couldn't be appended + * OOM situation occurs. + */ + int AddObserver(SymbianStreamCallback aObserver, + TInt32 aEvent, + TInt32 aScreenNumber, + void* aData); + + /** + * Remove stream event observer. Observer is removed from + * the stream's event nofitication chain and won't receive + * any events from the stream afterwards. + * + * @param aObserver The callback function + * @param aEvent The event id corresponding to the observer + * @param aScreenNumber The screen number + * @param aData Data must uniquely identify the observer + * + * @param KErrNone if successful, -1 otherwise + * KErrArgument if un unknown event passed as parameter + * KErrNotFount if the event is not found + */ + int RemoveObserver(TInt32 aEvents, void* aData); + + /*! + * Notifies the observers not associated with a context. + * The aim is to support legacy SI behavior. + * + * @param aEvent Observer identifier + * + */ + int NotifyObservers(TInt32 aEvent); + + /** + * Implements surface content notifications. + * + * When the contents of a surface change, this function gets called + * MCompositionSurfaceUpdate implementation. + * + * @param aSurface The surface that has been updated. + * @param aBuffer The buffer of the surface to be used in + * composition. Integer starting from 0. + * @param aRegion The sub-area that has the updates. If NULL, the + * whole surface is considered changed. + * @param aStatusConsumed A request status object or NULL. If not NULL, then the + * request status is completed once the backend + * does not anymore need the contents of the + * surface to render the update. This may happen + * before actually displaying the finished frame. + * @param aStatusDisplayed This is signaled after the composited frame + * is posted the to display for the first time after + * the update. After this the value in + * aTimeStamp is valid, if the value in the + * status object is KErrNone. Can be NULL, if + * no signal is desired. + * @param aTimeStamp Value of the User::FastCounter() right after the + * display refresh that signaled aStatusDisplayed. + * @param aStatusDispXTimes This is signaled when the surface has been on + * the screen for aDisplayedXTimes refreshes, + * including the update that signaled aStatusDisplayed. + * Can be NULL, if no signal is wanted. + * @param aDisplayedXTimes The number of refreshes after which aStatusDispXTimes + * is signaled or NULL. If values is provided, it must be + * >= 1. + * @param aScreenNumber Uniquelly identifies the context (composer) + */ + void SetNewNotifications(TInt aBuffer, + TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp, + TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes, + TRequestStatus* aStatusConsumed, const TRegion* aRegion, + TInt32 aScreenNumber); + + /** + * Implements surface content notifications. + * + * When the contents of a surface change, this function gets called + * MCompositionSurfaceUpdate implementation. + * + * @param aSurface The surface that has been updated. + * @param aBuffer The buffer of the surface to be used in + * composition. Integer starting from 0. + * @param aRegion The sub-area that has the updates. If NULL, the + * whole surface is considered changed. + * @param aStatusConsumed A request status object or NULL. If not NULL, then the + * request status is completed once the backend + * does not anymore need the contents of the + * surface to render the update. This may happen + * before actually displaying the finished frame. + * @param aStatusDisplayed This is signaled after the composited frame + * is posted the to display for the first time after + * the update. After this the value in + * aTimeStamp is valid, if the value in the + * status object is KErrNone. Can be NULL, if + * no signal is desired. + * @param aTimeStamp Value of the User::FastCounter() right after the + * display refresh that signaled aStatusDisplayed. + * @param aStatusDispXTimes This is signaled when the surface has been on + * the screen for aDisplayedXTimes refreshes, + * including the update that signaled aStatusDisplayed. + * Can be NULL, if no signal is wanted. + * @param aDisplayedXTimes The number of refreshes after which aStatusDispXTimes + * is signaled or NULL. If values is provided, it must be + * >= 1. + * @param aScreenNumber Uniquelly identifies the context (composer) + */ + void SetAllNotifications(TInt aBuffer, + TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp, + TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes, + TRequestStatus* aStatusConsumed, const TRegion* aRegion); + + /** + * Process the notifications by accessing the information stored in the observer container. + * + * This method is expected to be called from the observer context every time composer has finished processing + * a stream and the rigger condition is met. + * + * @param aEvent Events map to identify the observer to be processed. + * @param aScreenNumber Screen ID used to identify the target composer that invokes the method + * @param aOperation The Operation expected to be executed + * @param aSerialNumber A number used to identify the composition operation + * @param aReturnMask Parameter to be retrieved by composer, representing the event to be processed + * when composed next time. A new composition is automatically triggered. + * + */ + void ProcessNotifications(TInt32 aEvent, TInt32 aScreenNumber, TInt32 aOperation, TInt32 aSerialNumber, TInt32* aReturnMask); + + /** + * A function that checks the validity of the new buffer provided by SUS + * + * + * When the contents of a surface change, this function gets called by the MCompositionSurfaceUpdate implementation. + * If the buffer is invalid all request statuses will be completed with KErrArgument + * + * @param aBuffer The buffer of the surface to be used in + * composition. Integer starting from 0. + * @param aStatusConsumed A request status object or NULL. + * @param aStatusDisplayed A request status object or NULL. + * @param aStatusDispXTimes A request status object or NULL. + * + * @return KErrNone if successful + * KErrArgument if aBuffer parameter is invalid + * + */ + TInt CheckBufferNumber(TInt aBuffer, + TRequestStatus* aStatusDisplayed, + TRequestStatus* aStatusDispXTimes, + TRequestStatus* aStatusConsumed); + +private: + /** + * Notifies the composer that the content has been updated. + * + * + * @param aScreenNumber Screen ID used to identify the target composer + * @param aOp The Operation expected the callback to execute + * @param aParam Parameter containing aaditional information to push/pop from targetet composer + * + */ + TBool NotifyComposerContext(TInt32 aScreenNumber, TInt aOp, SYMOWF_CONTENT_UPDATED_PARAM* aParam); + + /** + * Notifies the composer that the content is in process to be updated. The composer will have to not access + * observer related information + * + * + * Note that while calling the callback the context update mutex is acquired. + * + * @param aScreenNumber Screen ID used to identify the target composer + * @param aBufferNum The buffer number to be updated + * @param aUpdatedFlags The events that triggers this function call + * @param aRegion The sub-area that has the updates. If NULL, the whole surface is considered changed. + */ + TBool StartUpdateNotifications(TInt aScreenNumber, SYMOWF_CONTENT_UPDATED_PARAM& param); + + /** + * Notifies the composer that process of updating the content has finisshed + * + * The composer releases the content mutex and triggers a new composition + * + * @param aScreenNumber Screen ID used to identify the target composer + * @param aBufferNum The buffer number to be updated + * @param aUpdatedFlags The events that triggers this function call + * @param aRegion The sub-area that has the updates. If NULL, the whole surface is considered changed. + */ + TBool EndUpdateNotifications(TInt aScreenNum, + TInt aBufferNum, + TInt32 aUpdatedFlags, + const TRegion* aRegion); + + /** + * Notifies the composer that content has been updated + * + * It is used to support old SI behaviour. The content update mutex is acuired + * and released while a new composition is triggered + * + * @param aScreenNumber Screen ID used to identify the target composer + * @param aBufferNum The buffer number to be updated + * @param aUpdatedFlags The events that triggers this function call + * @param aRegion The sub-area that has the updates. If NULL, the whole surface is considered changed. + */ + TBool UpdateNotifications(TInt aScreenNum, + TInt aBufferNum, + TInt32 aUpdatedFlags, + const TRegion* aRegion); + + /** + * Processes the available observer + * + * @param aEvent Events map to identify the operation to be executed. + * @param aSerialNumber A number used to identify the composition operation + * @param ContentUpdatedParams Packs the information used when a new request from SUS has to be processed + * @param aCallBackData The observer data stored in the container of observers + * @param aReturnMask Parameter to be retrieved by composer, representing the event to be processed + */ + void Available(TInt32 aEvent, TInt32 aSerialNumber, ContentUpdatedParams* aParams, void* aCallBackData, TInt32* aReturnMask); + /** + * Processes the available observer + * + * @param aEvent Events map to identify the operation to be executed. + * @param aSerialNumber A number used to identify the composition operation + * @param ContentUpdatedParams Packs the information used when a new request from SUS has to be processed + * @param aCallBackData The observer data stored in the container of observers + * @param aReturnMask Parameter to be retrieved by composer, representing the event to be processed + */ + void Displayed(TInt32 aEvent, TInt32 aSerialNumber, ContentUpdatedParams* aParams, void* aCallBackData, TInt32* aReturnMask); + /** + * Processes the available observer + * + * @param aEvent Events map to identify the operation to be executed. + * @param aSerialNumber A number used to identify the composition operation + * @param ContentUpdatedParams Packs the information used when a new request from SUS has to be processed + * @param aCallBackData The observer data stored in the container of observers + * @param aReturnMask Parameter to be retrieved by composer, representing the event to be processed + */ + void DisplayedXTimes(TInt32 aEvent, TInt32 aSerialNumber, ContentUpdatedParams* aParams, void* aCallBackData, TInt32* aReturnMask); + /** + * Function used to reset observer data fields + * + * @param aEvent Event identifier for whis the operation is to be executed. + * @param aCallBackData The observer data stored in the container of observers + */ + void ResetCallBackData(void* aCallBackData, TInt32 aEvent); + /** + * Cancels all active notifications by completeting the associated requests + */ + void CancelNotifications(); + + void SetNotifications(TInt aBuffer, + TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp, + TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes, + TRequestStatus* aStatusConsumed, const TRegion* aRegion, + TInt32 aScreenNumber, const TNewGlobalNotifications& aGlobalNotifications); + + void RequestComplete(TThreadId& aThreadId, TRequestStatus*& aRequestStatus, TInt& aGlobalIndexArray, TInt aStatus); + /** + * Constructor for performing 1st stage construction + */ + CSurfaceStream(); + + /** + * Symbian's default constructor for performing 2nd stage construction + */ + void ConstructL(const TSurfaceId& aId); + + TInt AddNewGlobalNotification(TRequestStatus* aStatusDisplayed, TInt aAssociatedScreens); + void SetReadBufferIndex(TInt aIndex); + TInt GetReadBufferIndex(); + TInt GetWriteBufferIndex(); + TInt Stride(TInt aWidth, TUidPixelFormat aPixelFormat); + static SymbianStreamBuffer IndexToReadHandle(TInt aIndex); + static SymbianStreamBuffer IndexToWriteHandle(TInt aIndex); + + static COpenWfcStreamMap& GetSingletonL(); + + void SurfaceInfoL(const TSurfaceId& aSurface, RSurfaceManager::TInfoBuf& aInfo); +private: + enum FlippedTarget + { + EFlipNotSet, + EFlippedTargetNormal, + EFlippedTargetFlipped + }; + +private: + // Each surface buffer has its corresponding TBufferInfo to hold reference count and memory offset + struct TBufferInfo + { + TInt iRefCount; + TInt iOffset; + }; + +private: + struct TCallBackEntry; + struct TGlobalNotification; + TSurfaceId iSurfaceId; //< Surface ID associated with stream. + TSurfaceId iStreamProxySurfaceId; //< Surface ID generated to represent stream + TInt iRefCount; + RFastLock iRefCountMutex; + TInt iReadBuffer; + RChunk iBufferChunk; + TBufferInfo* iBufferInfo; //< Array of buffer info + RSurfaceManager::TSurfaceInfoV01 iInfo; + static const TInt BUFFER_READ_HANDLE_BASE = 0x100; + static const TInt BUFFER_WRITE_HANDLE_BASE = 0x200; + static const TInt BUFFER_WRITE_UPDATE_OVERWRITE = -1; + TInt iAcquiredWriteBuffer; + TAny* iCallBackHighestPriority; + RArray iCallBacks; + RFastLock iCallBacksMutex; + TBool iProtected; + RArray iGlobalNotifications; + TInt iNumberOfScreenAttachedAvailableNotif; + TInt iNumberOfScreenAttachedDisplayedNotif; + TInt iNumberOfScreenAttachedDisplayedXNotif; + FlippedTarget iFlipState; + FlippedTarget iNewFlip; + }; + +#endif // SURFACESTREAM_H