graphics_plat/guestvideodriver_api/ldd/inc/devicereqhandler.h
branchbug235_bringup_0
changeset 146 4d1fe4a7ce83
child 158 13fc3981f713
equal deleted inserted replaced
145:8f2c3e21aac9 146:4d1fe4a7ce83
       
     1 // Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 #ifndef DEVICEREQHANDLER_H
       
    18 #define DEVICEREQHANDLER_H
       
    19 
       
    20 #include <kernel/kernel.h>
       
    21 #include <kernel/kern_priv.h>
       
    22 #include <e32cmn.h>
       
    23 
       
    24 #include <sgresource/sgcommon.h>//TSgImageMetaData
       
    25 #include "sgextension.h"//For SgExtension
       
    26 
       
    27 #include "guestvideodriverprotocol.h"
       
    28 #include "virtualvideohwinterface.h"
       
    29 #include "remotefunctioncall.h"
       
    30 #include "requestbuffer.h"
       
    31 #include "reqhandlerextension.h"
       
    32 
       
    33 #include <EGL/egltypes.h>//For EGLint
       
    34 
       
    35 class RSgImage;//we only need pointers anyways
       
    36 
       
    37 using namespace GuestVideoDriver;
       
    38 
       
    39 
       
    40 //Container class for the mapping from pbuffers to sgimages
       
    41 class TPbSId
       
    42     {
       
    43     public:
       
    44     TInt iPbuffer;
       
    45     TUint64 iSgId;
       
    46     TPbSId( TInt aP, TUint64 aId ) : iPbuffer( aP ), iSgId( aId ){}
       
    47     };
       
    48 class TVGISId
       
    49     {
       
    50     public:
       
    51     TInt iVGImage;
       
    52     TUint64 iSgId;
       
    53     TVGISId( TInt aI, TUint64 aId ) : iVGImage( aI ), iSgId( aId ){}
       
    54     };
       
    55 
       
    56 /**
       
    57  * Class for handling requests to the Video driver.
       
    58  */
       
    59 class DDeviceReqHandler : public DBase, MReqHandlerCallback , protected MRequestBufferBookKeepingWriter
       
    60     {
       
    61 public:
       
    62     enum TRequestMode
       
    63         {
       
    64         ENormal, //to be issued by the normal route
       
    65         EHandled, //already completed (in the scheduler)
       
    66         EQueued //queued into another outstanding request 
       
    67         };
       
    68     enum TOpChainType
       
    69         {//for performing a series of operations in sequence
       
    70         EOpInit = 1
       
    71         };
       
    72     enum { KMaxFreeRequests = 20 }; 
       
    73     
       
    74     struct SgImageMetaInfo
       
    75     	{
       
    76     	TUint32 iSgImagePointer;
       
    77     	};
       
    78     /*
       
    79      * Stores data belonging to a client thread
       
    80      */
       
    81     struct TPerThreadData
       
    82         {
       
    83         TRequestStatus* iStatus;
       
    84         DThread* iAsyncClient;//asynchronous client
       
    85         TUint32 iProcessId;
       
    86         TUint32 iThreadId;
       
    87         
       
    88         TUint32 iCurrApiUid;//5.2 in "Implementing sgImage on Guest EGL"
       
    89         TUint32 iCurrOpCode;//Not required
       
    90         
       
    91         TBool   iErrUpdatedGLES;
       
    92         TBool   iErrUpdatedVG;
       
    93         TBool   iErrUpdatedEGL;
       
    94         TUint32  iErrorGLES;//The error for the previous GLES call
       
    95         TUint32  iErrorVG;//The error for the previous VG call
       
    96         TUint32  iErrorEGL;//The error for the previous EGL call
       
    97         
       
    98         EGLContext iContext;//The last set context
       
    99 
       
   100         
       
   101         RArray<SgImageMetaInfo> iImageInfo;
       
   102         
       
   103 
       
   104         TBool sameThread( TUint32 aProcId, TUint32 aThreadId )
       
   105             {
       
   106             return ( ( aProcId == iProcessId && aThreadId == iThreadId ) ? ETrue : EFalse );
       
   107             }
       
   108         TPerThreadData( TRequestStatus* aStatus, DThread* aAsyncClient, TUint32 aProcId, TUint32 aThreadId ) :
       
   109             iStatus( aStatus),
       
   110             iAsyncClient(aAsyncClient),
       
   111             iProcessId( aProcId ),
       
   112             iThreadId( aThreadId ),
       
   113             iErrUpdatedGLES(EFalse),
       
   114             iErrUpdatedVG(EFalse),
       
   115             iErrUpdatedEGL(EFalse)
       
   116             {}
       
   117         };
       
   118     
       
   119     struct TTransactionInfo
       
   120         {
       
   121     public:
       
   122         TUint32 iTransactionId;
       
   123         //this must be valid for the whole duration of the transaction, and is now owned here
       
   124         TAny* iTransactionData;
       
   125         TTransactionInfo( TUint32 aTransactionId, TAny* aTransactionData = 0 ) :
       
   126             iTransactionId( aTransactionId ),
       
   127             iTransactionData( aTransactionData )
       
   128             {}
       
   129         };
       
   130     
       
   131     /*
       
   132      * Stores an async request before serialisation
       
   133      */
       
   134     struct TAsyncRequest
       
   135         {
       
   136         enum TRequestType
       
   137             {
       
   138             ERTDriver,
       
   139             ERTRequest,
       
   140             ERTCommandLoad
       
   141             };
       
   142         
       
   143         TAsyncRequest( TRequestStatus* aStatus,
       
   144                         DThread* aAsyncClient,
       
   145                         TAny* aA1,
       
   146                         TAny* aA2,
       
   147                         TRequestType aCommandLoadRequest ):
       
   148         iStatus( aStatus ),
       
   149         iAsyncClient( aAsyncClient ),
       
   150         iA1( aA1 ),
       
   151         iA2( aA2 ),
       
   152         iCommandLoadRequest( aCommandLoadRequest ),
       
   153         iNext( NULL )
       
   154             {    
       
   155             }
       
   156 
       
   157         void Init(TRequestStatus* aStatus,
       
   158                         DThread* aAsyncClient,
       
   159                         TAny* aA1,
       
   160                         TAny* aA2,
       
   161                         TRequestType aCommandLoadRequest )
       
   162             {
       
   163             iStatus = aStatus;
       
   164             iAsyncClient = aAsyncClient;
       
   165             iA1 = aA1;
       
   166             iA2 = aA2;
       
   167             iCommandLoadRequest = aCommandLoadRequest;
       
   168             iNext = NULL;
       
   169             }
       
   170         
       
   171         void AppendToList( TAsyncRequest* iPrev )
       
   172             {
       
   173             if ( iPrev->iNext )
       
   174                 {
       
   175                 this->iNext = iPrev->iNext;
       
   176                 }
       
   177             iPrev->iNext = this;
       
   178             }
       
   179         
       
   180         void RemoveFromList( TAsyncRequest* iPrev )
       
   181             {
       
   182             if ( iPrev->iNext == this )
       
   183                 {
       
   184                 iPrev->iNext = this->iNext;
       
   185                 }
       
   186             this->iNext = NULL;
       
   187             }
       
   188         
       
   189         //Current request status
       
   190         TRequestStatus* iStatus;
       
   191         
       
   192         //Current asynchronous client
       
   193         DThread* iAsyncClient;
       
   194         
       
   195         TAny* iA1;
       
   196         TAny* iA2;
       
   197 
       
   198         TRequestType iCommandLoadRequest;
       
   199         
       
   200         RemoteFunctionCallData iRemoteFunctionCall;
       
   201         
       
   202         //Link for linked list
       
   203         TAsyncRequest* iNext;
       
   204         };
       
   205     
       
   206     struct TAsyncRequestRoot: public TAsyncRequest
       
   207         {
       
   208         TAsyncRequestRoot():
       
   209         TAsyncRequest( NULL, NULL, NULL, NULL, ERTRequest )
       
   210             {
       
   211             }
       
   212         
       
   213         void AppendToLast( TAsyncRequest* aReq )
       
   214             {
       
   215             TAsyncRequest* last( this );
       
   216             TAsyncRequest* next( iNext );            
       
   217             while ( next )
       
   218                 {
       
   219                 last = next;
       
   220                 next = next->iNext;
       
   221                 }
       
   222             aReq->AppendToList( last );
       
   223             }
       
   224 
       
   225         void DeleteAll()
       
   226             {
       
   227             TAsyncRequest* next( iNext );
       
   228             while ( next )
       
   229                 {
       
   230                 TAsyncRequest* nextToDel( next );
       
   231                 next = next->iNext;
       
   232                 delete nextToDel;
       
   233                 }
       
   234             }
       
   235         };
       
   236 
       
   237     /**
       
   238      * Constructor.
       
   239      * 
       
   240      * @param aHwInterface
       
   241      *   Interface to the hardware
       
   242      * @param aQueue
       
   243      *   Deferred function call queue
       
   244      * @param aMdaifSvTable
       
   245      *   MDAIF shared variable table
       
   246      */
       
   247     DDeviceReqHandler(
       
   248             DVirtualVideoHwInterface& aHwInterface,
       
   249             TDfcQue* aQueue );
       
   250 
       
   251     /**
       
   252      * Destructor.
       
   253      */
       
   254     virtual ~DDeviceReqHandler();
       
   255     
       
   256     /**
       
   257      * Handles a command execution
       
   258      * 
       
   259      * @param aUserThread
       
   260      *   Thread making the request
       
   261      * @param aStatus
       
   262      *   Request status to be used in request completion.
       
   263      * @param a1
       
   264      *   Request parameter 1
       
   265      */
       
   266     TInt HandleExecuteAsync(
       
   267             DThread*& aUserThread,
       
   268             TRequestStatus* aStatus,
       
   269             TAny* a1);
       
   270 
       
   271     /**
       
   272      * Handles a command buffering
       
   273      * 
       
   274      * @param aUserThread
       
   275      *   Thread making the request
       
   276      * @param a1
       
   277      *   Request parameter 1
       
   278      */
       
   279     TInt HandleLoadCommands(
       
   280             DThread*& aUserThread,
       
   281             TRequestStatus* aStatus,
       
   282             TAny* a1 );
       
   283     
       
   284     TInt HandleClientShutdown( TUint aProcessId, TUint aThreadId );
       
   285     
       
   286 public: // Called from Dfc context
       
   287     
       
   288     /**
       
   289      * Directs hardware interrupts to appropriate functions.
       
   290      */
       
   291     void ProcessDfc();
       
   292             
       
   293 public: // Inline functions
       
   294 
       
   295     /**
       
   296      * Returns current interrupt ID.
       
   297      * 
       
   298      * @return
       
   299      *   Interrupt ID.
       
   300      */
       
   301     inline TInt InterruptId() { return iInterruptId; }
       
   302         
       
   303     /**
       
   304      * Returns hardware interface.
       
   305      * 
       
   306      * @return
       
   307      *   Hardware interface reference.
       
   308      */
       
   309     inline DVirtualVideoHwInterface& HwInterface() { return iHwInterface; }
       
   310     
       
   311     /**
       
   312      * Returns DFC.
       
   313      * 
       
   314      * @return
       
   315      *   Reference to TDfc object.
       
   316      */
       
   317     inline TDfc& Dfc() { return iDfc; }
       
   318 
       
   319     /**
       
   320      * Returns current interrupt ID.
       
   321      * 
       
   322      * @param aInterrupt
       
   323      *   Interrupt to be reset.
       
   324      * @return
       
   325      *   KErrNone - Successful
       
   326      *   System wide errorcodes in error situations.
       
   327      */
       
   328     inline TInt ResetAndEnableInterrupt(
       
   329             DVirtualVideoHwInterface::TInterrupt aInterrupt )
       
   330         {
       
   331         iHwInterface.ResetInterruptStatus( aInterrupt );
       
   332         Interrupt::Clear( InterruptId() );
       
   333         return Interrupt::Enable( iInterruptId );
       
   334         }
       
   335 
       
   336     /**
       
   337      * Process next request from ring buffer
       
   338      */ 
       
   339     TInt ProcessNextPendingRequest();
       
   340     
       
   341 protected: // Ring buffer book keaping routines
       
   342     void IncrementInputWriteCount( TUint32 aWriteCount )
       
   343         {
       
   344         TUint32 inputBufferWriteCount = GetWriteCount() + aWriteCount;
       
   345         iHwInterface.SetRegisterValue( DVirtualVideoHwInterface::ERegInputBufferWriteCount,
       
   346                 inputBufferWriteCount );
       
   347         }
       
   348     
       
   349     TUint32 GetInputWriteCount()
       
   350         {
       
   351         TUint32 inputBufferWriteCount;
       
   352         iHwInterface.GetRegisterValue( DVirtualVideoHwInterface::ERegInputBufferWriteCount,
       
   353                 inputBufferWriteCount );
       
   354         return inputBufferWriteCount;
       
   355         }
       
   356     
       
   357     TUint32 GetInputReadCount()
       
   358         {
       
   359         TUint32 inputBufferReadCount;
       
   360         iHwInterface.GetRegisterValue( DVirtualVideoHwInterface::ERegInputBufferReadCount,
       
   361                 inputBufferReadCount );
       
   362         return inputBufferReadCount;
       
   363         }
       
   364     
       
   365     TUint32 InputBufferTail()
       
   366         {
       
   367         TUint32 val;
       
   368         iHwInterface.GetRegisterValue( DVirtualVideoHwInterface::ERegInputBufferTail,
       
   369                 val );
       
   370         return val;
       
   371         }
       
   372     
       
   373     TUint32 InputBufferHead()
       
   374         {
       
   375         TUint32 val;
       
   376         iHwInterface.GetRegisterValue( DVirtualVideoHwInterface::ERegInputBufferHead,
       
   377                 val );
       
   378         return val;        
       
   379         }
       
   380     
       
   381     void SetInputBufferTail( TUint32 aIndex )
       
   382         {
       
   383         iHwInterface.SetRegisterValue( DVirtualVideoHwInterface::ERegInputBufferTail,
       
   384                 aIndex );    
       
   385         }
       
   386     
       
   387     void SetInputBufferHead( TUint32 aIndex )
       
   388         {
       
   389         iHwInterface.SetRegisterValue( DVirtualVideoHwInterface::ERegInputBufferHead,
       
   390                 aIndex );
       
   391         }
       
   392 
       
   393 protected: // From MRequestBufferBookKeeping
       
   394     /**
       
   395      * See MRequestBufferBookKeepingWriter
       
   396      */ 
       
   397     void IncrementWriteCount( TUint32 aWriteCount ){ IncrementInputWriteCount( aWriteCount ); }
       
   398 
       
   399     /**
       
   400      * See MRequestBufferBookKeepingWriter
       
   401      */ 
       
   402     TUint32 GetWriteCount(){ return GetInputWriteCount(); }
       
   403     
       
   404     /**
       
   405      * See MRequestBufferBookKeepingWriter
       
   406      */ 
       
   407     TUint32 GetReadCount(){ return GetInputReadCount(); }
       
   408 
       
   409     /**
       
   410      * See MRequestBufferBookKeepingWriter
       
   411      */ 
       
   412     TUint32 BufferTail(){ return InputBufferTail(); }
       
   413 
       
   414     /**
       
   415      * See MRequestBufferBookKeepingWriter
       
   416      */ 
       
   417     TUint32 BufferHead(){ return InputBufferHead(); }
       
   418 
       
   419     /**
       
   420      * See MRequestBufferBookKeepingWriter
       
   421      */ 
       
   422     void SetBufferHead( TUint32 aIndex ){ SetInputBufferHead( aIndex ); }
       
   423 
       
   424     /**
       
   425      * See MRequestBufferBookKeepingWriter
       
   426      */ 
       
   427     TUint32 MaxTailIndex()
       
   428         {
       
   429         TUint32 val;
       
   430         iHwInterface.GetRegisterValue( DVirtualVideoHwInterface::ERegInputBufferMaxTail,
       
   431                 val );
       
   432         return val;        
       
   433         }
       
   434     
       
   435     /**
       
   436      * See MRequestBufferBookKeepingWriter
       
   437      */ 
       
   438     void SetMaxTailIndex( TUint32 aIndex )
       
   439         {
       
   440         iHwInterface.SetRegisterValue( DVirtualVideoHwInterface::ERegInputBufferMaxTail,
       
   441                         aIndex );
       
   442         }
       
   443     
       
   444 protected: //Command Scheduling functions
       
   445     /**
       
   446      * DDeviceReqHandler::InterpretRequest
       
   447      * This function is the focal point of the implementation
       
   448      * of the 1st paragraph of 3.4 in the "Implementing SgImage" design doc.
       
   449      * This function therefore intercepts and interprets SOME EGL,VG (and, in the future GLES)
       
   450      * calls.
       
   451      * 
       
   452      * @param aReq the request
       
   453      * 
       
   454      * @return TBool has the call already been processed? If true, then no further processing
       
   455      * is required for that call (doesn't have to be sent host-side).
       
   456      */
       
   457     DDeviceReqHandler::TRequestMode InterpretRequest( TAsyncRequest* aReq );
       
   458     
       
   459     
       
   460     void ConsumeSchedulerInitiatedRequestResult( TAsyncRequest* aReq );
       
   461     
       
   462     /**
       
   463      * RemoveClientData
       
   464      * @param aProcId
       
   465      * @param aThreadId
       
   466      */
       
   467     void RemoveClientData( const TUint32 aProcId, const TUint32 aThreadId );
       
   468     /**
       
   469      * Initiate a request to the host side from the scheduler (this)
       
   470      * This is needed so that the scheduler can make requests that are not
       
   471      * directly client-originated.
       
   472      */
       
   473     TBool InitiateRequestWithReply( TAsyncRequest* req, TAny* aTransactionData = 0 );
       
   474 
       
   475     /**
       
   476      * Helper function for getting the stored client data for the proc/thread, if present
       
   477      * @return TPerThreadData object, or NULL, if no object was found with the right proc/thread id
       
   478      */
       
   479     TPerThreadData* GetClientData( const TUint32 aProcId, const TUint32 aThreadId );
       
   480     
       
   481     /**
       
   482      * getVGSync
       
   483      * Check if the VGImage is sg image backing, and if it's sync flag is set to dirty.
       
   484      * If both above conditions are met, add the required parameters to the hostside call
       
   485      * so that the hostside can proceed to making the sync.
       
   486      * 
       
   487      */
       
   488     DDeviceReqHandler::TRequestMode DDeviceReqHandler::getVGSync( VGImage aImg, TAsyncRequest* aReq );
       
   489     
       
   490     /**
       
   491      * 
       
   492      * @param aReq the request to add the additional info to
       
   493      * @param aImageIndexInReq the index of the vg image in the rfc call. This will
       
   494      *        be used to determine what the sgImage is, and find the sync bit
       
   495      * @param aSetBufferDirty: set the buffer dirty in any case
       
   496      * @param aAddFalseForOther. All sync operations are prepared to handle two vgimages, thus need to have another
       
   497      *        value to read. Set this to ETrue if you are not going to add another real sync operation.
       
   498      */
       
   499     void getVGSyncInOp( TAsyncRequest* aReq, TInt aSgHandleIndexInReq, TBool aSetBufferDirty = EFalse );
       
   500     
       
   501 public:
       
   502     HBuf8* OpenSgImageMetaData( const TUint64 aId, DSgResource*& aResource );
       
   503 	void CreateSgImagePbuffer( const TSgImageMetaData& aInfo, TRequestStatus* aStatus, DThread* aThread );
       
   504 	void CreateSgImageVGImage( const TSgImageMetaData& aInfo, TRequestStatus* aStatus, DThread* aThread );
       
   505 	TInt DestroySgImage( const TUint64 aId );
       
   506     void ContinueInit( TAsyncRequest* aReq );
       
   507 
       
   508     
       
   509 
       
   510 
       
   511 private: //Request management
       
   512     TInt iOpType; 
       
   513     TInt iOpChainPhase;//just a running nummber
       
   514     TInt iOpReturn;//return value from host side calls
       
   515     TRequestStatus iOpStatus;//dummy request status
       
   516     /*
       
   517      * Allocates a new request data structure
       
   518      */
       
   519     TAsyncRequest* AllocRequest( TRequestStatus* aStatus,
       
   520             DThread* aAsyncClient,
       
   521             TAny* aA1,
       
   522             TAny* aA2,
       
   523             TAsyncRequest::TRequestType aRequestType = TAsyncRequest::ERTRequest );
       
   524     
       
   525     
       
   526 
       
   527     /*
       
   528      * Releases a request data structure
       
   529      */
       
   530     void ReleaseRequest( TAsyncRequest* aReq );
       
   531 
       
   532     /*
       
   533      * Free request data structures
       
   534      */
       
   535     TAsyncRequestRoot iFreeListRoot;
       
   536     
       
   537     /*
       
   538      * Number of free request data structures
       
   539      */
       
   540     TInt iFreeCount;
       
   541     
       
   542 private:
       
   543     
       
   544     TLinearOrder<TPbSId> iPbufferSgMapOrder;
       
   545     TLinearOrder<TVGISId> iVGImageSgMapOrder;
       
   546     //map pbuffer surface handles -> sgImage ID
       
   547     RArray<TPbSId> iPbufferSgMap;
       
   548     RArray<TVGISId> iVGImageSgMap;
       
   549     //The data structs for storing per process&thread information
       
   550     RPointerArray<TPerThreadData>   iClientData;
       
   551     //The current client
       
   552     TPerThreadData* iCurrClientData;
       
   553     RArray<TTransactionInfo> iSchedulerInitiatedTransactionIds;
       
   554     TAny* iSchedulerInitiatedTransactionData;
       
   555     // The process- and thread ids to use in driver rfcs
       
   556     // This is needed as the calling thread may be different, while we still want the same
       
   557     // state to remain on the hostside.
       
   558     TUint32 iDriverRfcProcessId;
       
   559     TUint32 iDriverRfcThreadId;
       
   560     //Is egl initialized or not. If not, then it needs to be done before processing any other command
       
   561     TBool iInitialized;
       
   562     
       
   563     /// Interface to the hardware.
       
   564     DVirtualVideoHwInterface& iHwInterface;
       
   565 
       
   566     /// DFC.
       
   567     TDfc iDfc;
       
   568     
       
   569     /// Current interrupt ID.
       
   570     TInt iInterruptId;
       
   571     
       
   572     /// Kernel address of the shared chunk. 
       
   573     TLinAddr iChunkKernelAddress;
       
   574     
       
   575     /// Size of the chunk.
       
   576     TUint32 iChunkSize;
       
   577     
       
   578     //Request lists
       
   579     TAsyncRequestRoot iSerializedRequestRoot;
       
   580     TAsyncRequestRoot iPendingRequestRoot;
       
   581 
       
   582     /*
       
   583      * Current transaction id 
       
   584      */
       
   585     TUint32 iTransactionId;
       
   586     
       
   587     /*
       
   588      * Ring buffer for requests
       
   589      */    
       
   590     RequestBufferWriter iRequestBuffer;
       
   591     
       
   592     };
       
   593 
       
   594 #endif // DEVICEREQHANDLER_H