diff -r 000000000000 -r 96e5fb8b040d kernel/eka/include/drivers/display.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/include/drivers/display.h Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,363 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "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: +// os\kernelhwsrv\kernel\eka\include\drivers\display.h +// Interface to LDD of the Display GCE driver +// Kernel side definitions for the GCE driver +// + +/** + @file + @internalTechnology + @prototype +*/ + + +#ifndef __DISPLAY_H__ +#define __DISPLAY_H__ + +#include +#include +#include +#include + + + +const TInt KDisplayLBMax = 2; +const TInt KDisplayCBMax = 2; +const TInt KDisplayUBMax = 8; + + +const TInt KPendingReqArraySize = RDisplayChannel::EReqWaitForPost +1; + +const TInt KMaxQueuedRequests = 3; + +class DDisplayChannel; + + +enum TBufferType +{ + EBufferTypeLegacy = 0, + EBufferTypeComposition, + EBufferTypeUser, +}; + + +enum TBufferState +{ + EBufferFree = 0, + EBufferCompose, + EBufferPending, + EBufferActive +}; + + +typedef struct +{ + TInt iType; + TInt iBufferId; + TBool iFree; + TInt iHandle; + TInt iSize; + TUint32 iAddress; + TUint32 iPhysicalAddress; + TInt iOffset ; + DChunk * iChunk ; + TBufferState iState; + TRequestStatus* iPendingRequest; + +} TBufferNode; + + +/** +An object encapsulating a request from the client(iOwningThread) to the GCE driver. +*/ +typedef struct +{ + + /** The TClientRequest object associated with the request - used to signal completion of the request and pass back a + completion code. */ + TClientRequest* iTClientReq; + + /** The thread which issued the request and which supplied the request status. */ + DThread* iOwningThread; + +} TRequestNode; + + + +class DDisplayPdd; + + +/** + Logical Channel factory class for 'Display Channel LDD' +*/ + +class DDisplayLddFactory : public DLogicalDevice + { +public: + static DDisplayLddFactory* CreateInstance(); + ~DDisplayLddFactory(); + // Inherited from DLogicalDevice + virtual TInt Install(); + virtual void GetCaps(TDes8& aDes) const; + virtual TInt Create(DLogicalChannelBase*& aChannel); + TBool IsUnitOpen(TInt aUnit); + TInt SetUnitOpen(TInt aUnit,TBool aIsOpenSetting); +private: + DDisplayLddFactory(); + + +private: + /** Mask to keep track of which units have a channel open on them. */ + TUint iUnitsOpenMask; + /** A mutex to protect access to the unit info mask. */ + NFastMutex iUnitInfoMutex; + }; + + +/** + Logical Channel class for 'Display Channel LDD' +*/ +class DDisplayLdd : public DLogicalChannel + { + +public: + // create one instance of this object + static DDisplayLdd* CreateInstance(); + virtual ~DDisplayLdd(); + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + virtual void HandleMsg(TMessageBase* aMsg); + +private: + DDisplayLdd(); + +private: + // Implementation for the differnt kinds of messages sent through RBusLogicalChannel + TInt DoControl(TInt aFunction, TAny* a1, TAny* a2, DThread* aClient); + TInt DoRequest(TInt aReqNo, TAny* a1, TAny* a2, TInt index, DThread* aClient); + void DoCancel(TUint aMask); + + TInt SendRequest(TMessageBase* aMsg); + TInt SendControl(TMessageBase* aMsg); + TInt SendMsg(TMessageBase* aMsg); + + TBufferNode* FindUserBufferNode(TInt aBufferId); + TInt CheckAndOpenUserBuffer(TBufferNode* aNode, TInt aHandle, TInt aOffset, DThread* aClient); + TInt FreeUserBufferNode(TBufferNode* aNode); + + void CompleteRequest(DThread* aThread, TClientRequest*& aTClientReq, TInt aReason); + + DDisplayPdd * Pdd(); + +public: + virtual TInt RequestComplete(TInt aRequest, TInt ); + + +public: + + // display info + RDisplayChannel::TDisplayInfo iLegacyInfo; + RDisplayChannel::TDisplayInfo iDisplayInfo; + + // post counters + RDisplayChannel::TPostCount iCurrentPostCount; + RDisplayChannel::TPostCount iRequestedPostCount; + + + DThread* iClient; + TInt iUnit; + + // frame buffer nodes + TBufferNode iLegacyBuffer[KDisplayLBMax]; + TBufferNode iCompositionBuffer[KDisplayCBMax]; + TBufferNode iUserBuffer[KDisplayUBMax]; + + //pending queue for asynchronous requests + TRequestNode iPendingReq[KPendingReqArraySize][KMaxQueuedRequests]; + + //Queue of TClientRequest objects, one for each type of asynchronous request. + TClientRequest* iClientRequest[KPendingReqArraySize][KMaxQueuedRequests]; + + //The index in structures iPendingReq and iClientRequest that identifies the active TClientRequest object. + //For each type of asynchronous request, iPendingIndex is the index of the active TClientRequest object + //in iPendingReq + TInt iPendingIndex[KPendingReqArraySize]; + + // Protect access of iClientRequest + DMutex * iClientRequestMutex; + + + // current index + TInt iLegacyBuffIdx; + TInt iCompositionBuffIdx; + TInt iUserBuffIdx; + + + RDisplayChannel::TDisplayRotation iLegacyRotation; + RDisplayChannel::TDisplayRotation iCurrentRotation; + + + TBool iReady; + + /** Used in debug builds to track that all calls to DThread::Open() are balanced with a close before the driver closes. */ + TInt iThreadOpenCount; + + /** Used in debug builds to track the number of asynchronous requests that are queued is equal to the number of + requests that are completed, before the driver closes.*/ + TInt iAsyncReqCount; + + /** Chunk used in UDEB only for testing user buffers. */ + DChunk* iChunk; + }; + + + /** + Display PDD base class with GCE support. + */ + +class DDisplayPdd : public DBase + { + + public: + + /** + Called by the LDD to handle the device specific part of switching to Legacy mode. + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt SetLegacyMode()=0; + + /** + Called by the LDD to handle the device specific part of switching to GCE mode. + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt SetGceMode()=0; + + /** + Called by the LDD to handle the device specific part of setting the rotation. + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt SetRotation(RDisplayChannel::TDisplayRotation aRotation)=0; + + /** + Called by the LDD to handle the device specific part of posting a User Buffer. + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt PostUserBuffer(TBufferNode* aNode)=0; + + /** + Called by the LDD to handle the device specific part of posting a Composition Buffer + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt PostCompositionBuffer(TBufferNode* aNode)=0; + + /** + Called by the LDD to handle the device specific part of posting the Legacy Buffuer + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt PostLegacyBuffer()=0; + + /** + Called by the LDD to handle device specific cleanup operations when a channel is closed. + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt CloseMsg()=0; + + /** + Called by the LDD to handle device specific initialisation tasks when a channel is opened. + + @param aUnit The screen/hardware unit number. + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt CreateChannelSetup(TInt aUnit)=0; + + /** + Called by the LDD in order to detect whether a post operation is pending. This type of + information is specific to the actual physical device. + + @return ETrue if a Post operation is pending otherwise EFalse. + */ + virtual TBool PostPending()=0; + + /** + Called by the LDD to retrieve the DFC Queue created in the PDD. + + @param aUnit The screen/hardware unit number. + @return A pointer to the TDfcQue object created in the PDD. + */ + virtual TDfcQue* DfcQ(TInt aUnit)=0; + + /** + Called by the PDD when an asynchronous request should be completed with a specific reason. + (Just calls the LDD's RequestComplete method) + + @param aRequest Any value from the RDisplayChannel::TRequest enumeration. + @param aReason Any valid error reason. + + @return KErrNone if successful; or one of the other system wide error codes. + */ + inline TInt RequestComplete(TInt aRequest, TInt aReason ); + + +public: + /** + A pointer to the logical device driver's channel that owns this device. + */ + DDisplayLdd *iLdd; + /** + Every post operation sets this flag to true in order to identify when + the previsouly posted buffer is no longer in use by the display hardware. + */ + TBool iPostFlag; + + }; + + +inline DDisplayPdd * DDisplayLdd::Pdd() + { return (DDisplayPdd*) iPdd; } + + +inline TInt DDisplayPdd::RequestComplete(TInt aRequest, TInt aReason) + { return iLdd->RequestComplete(aRequest,aReason); } + + + + +//#define _GCE_DISPLAY_DEBUG + +#ifdef _GCE_DISPLAY_DEBUG + +#define __DEBUG_PRINT(a) Kern::Printf(a) +#define __DEBUG_PRINT2(a,b) Kern::Printf(a,b) +#define __DEBUG_PRINT3(a,b,c) Kern::Printf(a,b,c) +#define __DEBUG_PRINT4(a,b,c,d) Kern::Printf(a,b,c,d) +#define __DEBUG_PRINT5(a,b,c,d,e) Kern::Printf(a,b,c,d,e) + +#else +#define __DEBUG_PRINT(a) +#define __DEBUG_PRINT2(a,b) +#define __DEBUG_PRINT3(a,b,c) +#define __DEBUG_PRINT4(a,b,c,d) +#define __DEBUG_PRINT5(a,b,c,d,e) + +#endif + + +#endif // __DISPLAY_H__