kernel/eka/include/drivers/display.h
author Tom Cosgrove <tom.cosgrove@nokia.com>
Fri, 28 May 2010 16:29:07 +0100
changeset 30 8aab599e3476
parent 4 56f325a607ea
permissions -rw-r--r--
Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h) Have multiple extension sections in the bld.inf, one for each version of the compiler. The RVCT version building the tools will build the runtime libraries for its version, but make sure we extract all the other versions from zip archives. Also add the archive for RVCT4.

// 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 <videodriver.h>
#include <dispchannel.h>
#include <platform.h>
#include <pixelformats.h>



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__