guestrendering/guestvideodriver/ldd/src/devicereqhandler.cpp
branchbug235_bringup_0
changeset 51 4f400a6ea71f
parent 49 3b4f7e9d873f
child 52 39e5f73667ba
equal deleted inserted replaced
49:3b4f7e9d873f 51:4f400a6ea71f
     1 // Copyright (c) 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 // Device Request Handler Implementation
       
    15 
       
    16 
       
    17 #include <platform.h>
       
    18 #include <assp.h>
       
    19 #include <kernel/kernel.h>
       
    20 #include <e32cmn.h>
       
    21 
       
    22 #include <graphics/devicereqhandler.h>
       
    23 #include <graphics/virtualvideohwinterface.h>
       
    24 #include <graphics/virtualvideotracing.h>
       
    25 
       
    26 #include "remotefunctioncall.h"
       
    27 #include "serializedfunctioncall.h"
       
    28 #include "driverrfc.h"
       
    29 #include "openvgrfc.h" //For the opcodes
       
    30 #include "eglrfc.h" //For the opcodes
       
    31 #include "opengles11rfc.h" //For the opcodes
       
    32 
       
    33 
       
    34 using namespace GuestVideoDriver;
       
    35 
       
    36 // LOCAL DATA TYPES
       
    37 TInt CmpTPbsIds(const TPbSId& a, const TPbSId& b)
       
    38     {
       
    39     if( a.iPbuffer == b.iPbuffer )
       
    40         return 0;
       
    41     else
       
    42         return b.iPbuffer - a.iPbuffer;
       
    43     }
       
    44 
       
    45 TInt CmpTVGIsIds(const TVGISId& a, const TVGISId& b)
       
    46     {
       
    47     if( a.iVGImage == b.iVGImage )
       
    48         return 0;
       
    49     else
       
    50         return b.iVGImage - a.iVGImage;
       
    51     }
       
    52 /*
       
    53  * Copies data from client space to the request buffer during serialisation
       
    54  */
       
    55 class TDataFromClientSpaceCopier: public MDataCopier
       
    56     {
       
    57 public:
       
    58     TDataFromClientSpaceCopier( DThread* aUserThread ):
       
    59         iUserThread(aUserThread)
       
    60         {
       
    61         }
       
    62     
       
    63     TInt CopyData( TUint8* aDest, const TUint8* aSource, TUint32 aSize )
       
    64         {
       
    65         memcpy( aDest, aSource, aSize );
       
    66         return KErrNone;
       
    67         }
       
    68     
       
    69     TInt CopyVector( TUint8* aDest, const TUint8* aSource, TUint32 aSize )
       
    70         {
       
    71         return Kern::ThreadRawRead( iUserThread, aSource, aDest, aSize );
       
    72         }
       
    73 
       
    74     DThread* iUserThread;
       
    75     };
       
    76 
       
    77 /*
       
    78  * Copies data to client space from the request buffer during deserialisation
       
    79  */
       
    80 class TDataToClientSpaceCopier: public MDataCopier
       
    81     {
       
    82 public:
       
    83     TDataToClientSpaceCopier( DThread* aUserThread ):
       
    84         iUserThread(aUserThread)
       
    85         {
       
    86         }
       
    87     
       
    88     TInt CopyData( TUint8* aDest, const TUint8* aSource, TUint32 aSize )
       
    89         {
       
    90         memcpy( aDest, aSource, aSize );
       
    91         return KErrNone;
       
    92         }
       
    93     
       
    94     TInt CopyVector( TUint8* aDest, const TUint8* aSource, TUint32 aSize )
       
    95         {
       
    96         return Kern::ThreadRawWrite(iUserThread, aDest, aSource, aSize );
       
    97         }
       
    98 
       
    99     DThread* iUserThread;
       
   100     };
       
   101 
       
   102 // LOCAL FUNCTION DEFINITIONS
       
   103 
       
   104 // -----------------------------------------------------------------------------
       
   105 // ListRemoteFunctionCall
       
   106 // -----------------------------------------------------------------------------
       
   107 //
       
   108 inline void ListRemoteFunctionCall(RemoteFunctionCallData& call)
       
   109     {
       
   110 #if _DEBUG
       
   111     VVHW_TRACE("RFC: %u %u %u %u %u %u %u",
       
   112     call.Header().iOpCode,
       
   113     call.Header().iTransactionId,
       
   114     call.Header().iProcessId,
       
   115     call.Header().iThreadId,
       
   116     call.Header().iParameterCount,
       
   117     call.Header().iOpType,
       
   118     call.Header().iReturnValue);
       
   119     
       
   120     for ( TInt i = 0; i < call.Header().iParameterCount; i++)
       
   121         {
       
   122         RemoteFunctionCallData::TParam param = call.Parameters()[i];
       
   123 
       
   124         TUint32 dir = param.iDir;
       
   125         TUint32 type = param.iType;
       
   126 
       
   127         
       
   128         if ( RemoteFunctionCallData::TParam::ESimple == param.iType )
       
   129             {
       
   130             TUint32 datatype = param.iSimpleParam.iDataType; 
       
   131             VVHW_TRACE("RFC Simple Param %d: %u %u %u",i, dir, type, datatype );
       
   132             }
       
   133         else if ( RemoteFunctionCallData::TParam::EVector == param.iType )
       
   134             {
       
   135             TUint32 datatype = param.iVectorParam.iDataType; 
       
   136             TUint32 size = param.iVectorParam.iVectorLength;
       
   137             VVHW_TRACE("RFC Vec Param %d: %u %u %u %u",i, dir, type, datatype, size );
       
   138             }
       
   139         }
       
   140 #endif // _DEBUG
       
   141     }
       
   142 
       
   143 
       
   144 // CONSTANTS
       
   145 const TInt KDfcPriority = 1;
       
   146 
       
   147 // ============================= LOCAL FUNCTIONS ===============================
       
   148 
       
   149 // -----------------------------------------------------------------------------
       
   150 // Isr
       
   151 // Interrupt service routine
       
   152 // -----------------------------------------------------------------------------
       
   153 //
       
   154 void Isr( TAny* aParam )
       
   155     {
       
   156     DDeviceReqHandler* handler = ( DDeviceReqHandler* )aParam;
       
   157     Interrupt::Disable( handler->InterruptId() );
       
   158     handler->Dfc().Add();
       
   159     }
       
   160 
       
   161 // -----------------------------------------------------------------------------
       
   162 // DfcFunc
       
   163 // Function to call when HW has an interrupt
       
   164 // -----------------------------------------------------------------------------
       
   165 //
       
   166 void DfcFunc( TAny* aParam )
       
   167     {
       
   168     DDeviceReqHandler* handler = ( DDeviceReqHandler* )aParam;
       
   169     handler->ProcessDfc();
       
   170     }
       
   171 
       
   172 // ============================ MEMBER FUNCTIONS ===============================
       
   173 
       
   174 
       
   175 // -----------------------------------------------------------------------------
       
   176 // DDeviceReqHandler::DDeviceReqHandler
       
   177 // -----------------------------------------------------------------------------
       
   178 //
       
   179 DDeviceReqHandler::DDeviceReqHandler(
       
   180     DVirtualVideoHwInterface& aHwInterface,
       
   181     TDfcQue* aQueue) :
       
   182     iPbufferSgMapOrder ( &CmpTPbsIds ),
       
   183     iVGImageSgMapOrder ( &CmpTVGIsIds ),
       
   184     iCurrClientData(NULL),
       
   185     iInitialized(EFalse),
       
   186     iHwInterface( aHwInterface ),
       
   187     iDfc( DfcFunc, (TAny*)this, aQueue, KDfcPriority ),
       
   188     iInterruptId( 0 ),
       
   189     iTransactionId( 1 ),
       
   190     iRequestBuffer( *this, VVI_PARAMETERS_INPUT_MEMORY_SIZE )
       
   191     {
       
   192     iDriverRfcProcessId = 0;
       
   193     iDriverRfcThreadId  = 0;
       
   194     iOpType       = 0; 
       
   195     iOpChainPhase = 0;
       
   196     iInterruptId  = VVI_IRQ;
       
   197     VVHW_TRACE( "DDeviceReqHandler constructor" );
       
   198     VVHW_TRACE( "Called in process/thread %0x / %0x", Kern::CurrentProcess().iId, Kern::CurrentThread().iId );
       
   199     TInt err = Interrupt::Bind( iInterruptId, Isr, ( TAny* )this );
       
   200     if ( err != KErrNone )
       
   201         {
       
   202         VVHW_TRACE( "Interrupt::Bind Error: %d", err );
       
   203         }
       
   204     err = Interrupt::Enable( iInterruptId );
       
   205     if ( err != KErrNone )
       
   206         {
       
   207         Interrupt::Unbind( iInterruptId );
       
   208         iInterruptId = 0;
       
   209         VVHW_TRACE( "Interrupt::Enable Error: %d", err );
       
   210         }
       
   211     iRequestBuffer.InitBuffer();
       
   212     //Register this object with the extension
       
   213     VVHW_TRACE( "DDeviceReqHandler calling ReqHandlerExtension" );
       
   214 #ifdef FAISALMEMON_S4_SGIMAGE
       
   215     ReqHandlerExtension::SetReqHandler( this );
       
   216 #endif
       
   217     }
       
   218 
       
   219 // -----------------------------------------------------------------------------
       
   220 // DDeviceReqHandler::~DDeviceReqHandler
       
   221 // -----------------------------------------------------------------------------
       
   222 //
       
   223 DDeviceReqHandler::~DDeviceReqHandler()
       
   224     {
       
   225     for( TInt i=0; i < iClientData.Count(); ++i )
       
   226         {
       
   227         delete iClientData[i];
       
   228         }
       
   229     iClientData.Close();
       
   230     Interrupt::Disable( iInterruptId );
       
   231     Interrupt::Unbind( iInterruptId );
       
   232     iInterruptId = 0;
       
   233     }
       
   234 
       
   235 // -----------------------------------------------------------------------------
       
   236 // DDeviceReqHandler::HandleClientShutdown
       
   237 // -----------------------------------------------------------------------------
       
   238 //
       
   239 TInt DDeviceReqHandler::HandleClientShutdown( TUint aProcessId, TUint aThreadId )
       
   240     {
       
   241     VVHW_TRACE("DDeviceReqHandler::HandleClientShutdown");
       
   242     TInt err( KErrNone );
       
   243     TAsyncRequest* req = AllocRequest( NULL, NULL, NULL, NULL, TAsyncRequest::ERTDriver );
       
   244     
       
   245     if ( req )
       
   246         {
       
   247         DriverRFC drfc( req->iRemoteFunctionCall );
       
   248         drfc.Init( DriverRFC::EDrvClientShutdown, RemoteFunctionCallData::EOpRequest );        
       
   249         req->iRemoteFunctionCall.SetTransactionId( ++iTransactionId );
       
   250         req->iRemoteFunctionCall.SetThreadInformation( aProcessId, aThreadId );        
       
   251         iPendingRequestRoot.AppendToLast( req );
       
   252         TInt ret = ProcessNextPendingRequest();
       
   253         while ( KErrNone == ret )
       
   254             {
       
   255             ret = ProcessNextPendingRequest();
       
   256             }
       
   257         }
       
   258     else
       
   259         {
       
   260         err = KErrNoMemory;
       
   261         }
       
   262     return err;
       
   263     }
       
   264 
       
   265 // -----------------------------------------------------------------------------
       
   266 // DDeviceReqHandler::ProcessNextPendingRequest
       
   267 // -----------------------------------------------------------------------------
       
   268 //
       
   269 TInt DDeviceReqHandler::ProcessNextPendingRequest()
       
   270     {
       
   271     VVHW_TRACE("DDeviceReqHandler::ProcessNextPendingRequest");
       
   272     TInt err( KErrNone );
       
   273     TAsyncRequest* req = iPendingRequestRoot.iNext;
       
   274     if ( !req )
       
   275         {
       
   276         VVHW_TRACE("DDeviceReqHandler::ProcessNextPendingRequest !req");
       
   277         return KErrUnderflow;
       
   278         }
       
   279     //Try to serve the client from here, or do some sgImage specific stuff
       
   280     TInt mode = InterpretRequest( req );
       
   281     switch( mode )
       
   282         {
       
   283         case ENormal:
       
   284             {
       
   285             //Nothing, process as normal
       
   286             break;
       
   287             }
       
   288         case EHandled:
       
   289             {
       
   290             //Already handled, remove and signal complete
       
   291             req->RemoveFromList( &iPendingRequestRoot );
       
   292             Kern::RequestComplete( req->iAsyncClient, req->iStatus, KErrNone );
       
   293             ReleaseRequest( req );
       
   294             return KErrNone;//Change to "err" if you add lines above this that may set it to something else
       
   295             }
       
   296         case EQueued:
       
   297             {
       
   298             //To be removed from the usual queues, but not deleted (released) or completed
       
   299             req->RemoveFromList( &iPendingRequestRoot );
       
   300             return KErrNone;
       
   301             }
       
   302         default:
       
   303             {
       
   304             break;
       
   305             }
       
   306         }
       
   307     
       
   308     if ( TAsyncRequest::ERTCommandLoad == req->iCommandLoadRequest )
       
   309         {
       
   310         VVHW_TRACE("DDeviceReqHandler::HandleLoadCommands");
       
   311         TInt loaderr( KErrNone );
       
   312         TInt len = Kern::ThreadGetDesLength( req->iAsyncClient, req->iA1 );
       
   313 
       
   314         if ( len < 0 )
       
   315             {
       
   316             VVHW_TRACE("DDeviceReqHandler::HandleLoadCommands len < 0");
       
   317             return KErrUnderflow;;
       
   318             }
       
   319 
       
   320         if ( !iRequestBuffer.CheckForSpace( len ) )
       
   321            {
       
   322            //Not enough space
       
   323            VVHW_TRACE("DDeviceReqHandler::HandleLoadCommands No space");
       
   324            return KErrNoMemory;
       
   325            }
       
   326 
       
   327         req->RemoveFromList( &iPendingRequestRoot );
       
   328 
       
   329         const TUint32 base( iRequestBuffer.AllocateBytes( len ) );
       
   330 
       
   331         //Next, serialize the call to the HW memory
       
   332         const TLinAddr paramAddr( iHwInterface.InputParametersAddress() + base );
       
   333 
       
   334         TPtr8 ptr(reinterpret_cast<TUint8*>(paramAddr), 0, len );
       
   335         
       
   336         //Read the RemoveFunctionCall
       
   337         loaderr = Kern::ThreadDesRead( req->iAsyncClient, req->iA1, ptr, 0, 0 );
       
   338         VVHW_TRACE("DDeviceReqHandler::HandleLoadCommands ThreadDesRead %d", loaderr);
       
   339 
       
   340         if ( KErrNone == loaderr )
       
   341             {
       
   342             VVHW_TRACE("DDeviceReqHandler::HandleLoadCommands CommitBytes");
       
   343             iRequestBuffer.CommitBytes( base, len );
       
   344             iHwInterface.IssueCommand( VVI_EXECUTE );
       
   345             }
       
   346         Kern::RequestComplete( req->iAsyncClient, req->iStatus, loaderr );
       
   347         ReleaseRequest( req );
       
   348         }
       
   349     else //ERTRequest or ERTDriver
       
   350         {
       
   351 #if _DEBUG
       
   352         ListRemoteFunctionCall( req->iRemoteFunctionCall );
       
   353 #endif
       
   354        VVHW_TRACE("DDeviceReqHandler::ProcessNextPendingRequest req %u tid %u opcode %u", 
       
   355             req, req->iRemoteFunctionCall.Header().iTransactionId,
       
   356             req->iRemoteFunctionCall.Header().iOpCode );
       
   357         const TUint32 serializedLength( req->iRemoteFunctionCall.SerialisedLength() );
       
   358         if ( !iRequestBuffer.CheckForSpace( serializedLength ) )
       
   359            {
       
   360            //Not enough space
       
   361            VVHW_TRACE("DDeviceReqHandler::ProcessNextPendingRequest No space");
       
   362            return KErrOverflow;
       
   363            }
       
   364     
       
   365         req->RemoveFromList( &iPendingRequestRoot );
       
   366     
       
   367         if ( RemoteFunctionCallData::EOpRequestWithReply == req->iRemoteFunctionCall.Header().iOpType )
       
   368             {
       
   369             VVHW_TRACE("DDeviceReqHandler::ProcessNextPendingRequest 3");
       
   370             iSerializedRequestRoot.AppendToLast( req );
       
   371             }
       
   372         TDataFromClientSpaceCopier datacopier( req->iAsyncClient );
       
   373         SerializedFunctionCall sfc( req->iRemoteFunctionCall );
       
   374         
       
   375         if ( TAsyncRequest::ERTRequest == req->iCommandLoadRequest )
       
   376             {
       
   377             sfc.SetDataCopier( &datacopier );            
       
   378             }
       
   379         
       
   380         const TUint32 base( iRequestBuffer.AllocateBytes( serializedLength ) );
       
   381     
       
   382         //Next, serialize the call to the HW memory
       
   383         const TLinAddr paramAddr( iHwInterface.InputParametersAddress() + base );
       
   384     
       
   385         TInt len = sfc.WriteToBuffer( reinterpret_cast<TUint8*>(paramAddr),
       
   386                 VVI_PARAMETERS_INPUT_MEMORY_SIZE - 1 - base );
       
   387         
       
   388         sfc.SetDataCopier( NULL );
       
   389         VVHW_TRACE("DDeviceReqHandler::ProcessNextPendingRequest Write at index %u with length %u", base, len );
       
   390         iRequestBuffer.CommitBytes( base, serializedLength );
       
   391     
       
   392         iHwInterface.IssueCommand( VVI_EXECUTE );
       
   393         
       
   394         if ( RemoteFunctionCallData::EOpRequest == req->iRemoteFunctionCall.Header().iOpType )
       
   395             {
       
   396             if ( TAsyncRequest::ERTRequest == req->iCommandLoadRequest )
       
   397                 {
       
   398                 VVHW_TRACE("DDeviceReqHandler::ProcessNextPendingRequest RequestComplete");
       
   399                 Kern::RequestComplete( req->iAsyncClient, req->iStatus, KErrNone );
       
   400                 }
       
   401             ReleaseRequest( req );
       
   402             }
       
   403         }
       
   404     VVHW_TRACE("DDeviceReqHandler::ProcessNextPendingRequest DONE");
       
   405     return err;
       
   406     }
       
   407 
       
   408 // -----------------------------------------------------------------------------
       
   409 // DDeviceReqHandler::HandleLoadCommands
       
   410 // -----------------------------------------------------------------------------
       
   411 //
       
   412 TInt DDeviceReqHandler::HandleLoadCommands(
       
   413         DThread*& aUserThread,
       
   414         TRequestStatus* aStatus,
       
   415         TAny* aA1 )
       
   416     {
       
   417     VVHW_TRACE("DDeviceReqHandler::HandleLoadCommands");
       
   418     TInt err( KErrNone );
       
   419     TAsyncRequest* req = AllocRequest( aStatus, aUserThread, aA1, NULL, TAsyncRequest::ERTCommandLoad );
       
   420     
       
   421     if ( req )
       
   422         {
       
   423         TInt len = Kern::ThreadGetDesLength( req->iAsyncClient, req->iA1 );
       
   424     
       
   425         if ( len < 0 )
       
   426             {
       
   427             err = len;//TODO: this sucks
       
   428             ReleaseRequest( req );
       
   429             return err;
       
   430             }
       
   431             
       
   432         iPendingRequestRoot.AppendToLast( req );
       
   433         TInt ret = ProcessNextPendingRequest();
       
   434         while ( KErrNone == ret )
       
   435             {
       
   436             ret = ProcessNextPendingRequest();
       
   437             }
       
   438         }
       
   439     else
       
   440         {
       
   441         err = KErrNoMemory;
       
   442         }
       
   443 
       
   444     return err;
       
   445     }
       
   446 
       
   447 // -----------------------------------------------------------------------------
       
   448 // DDeviceReqHandler::HandleExecuteAsync
       
   449 // -----------------------------------------------------------------------------
       
   450 //
       
   451 TInt DDeviceReqHandler::HandleExecuteAsync(
       
   452         DThread*& aUserThread,
       
   453         TRequestStatus* aStatus,
       
   454         TAny* a1 )
       
   455     {
       
   456     VVHW_TRACE("DDeviceReqHandler::HandleExecuteAsync");
       
   457     TInt err( KErrNone );
       
   458     TAsyncRequest* req = AllocRequest( aStatus, aUserThread, a1, NULL );
       
   459     
       
   460     if ( req )
       
   461         {
       
   462         TInt len = Kern::ThreadGetDesLength( req->iAsyncClient, req->iA1 );
       
   463     
       
   464         if ( len < 0 )
       
   465             {
       
   466             err = len;
       
   467             ReleaseRequest( req );
       
   468             return err;
       
   469             }
       
   470     
       
   471         TPckg<RemoteFunctionCallData> rcallbuf( req->iRemoteFunctionCall );
       
   472         
       
   473         //Read the RemoteFunctionCall
       
   474         err = Kern::ThreadDesRead( req->iAsyncClient, req->iA1, rcallbuf, 0, 0 );
       
   475 
       
   476         if ( KErrNone != err )
       
   477             {
       
   478             ReleaseRequest( req );
       
   479             return err;
       
   480             }
       
   481         
       
   482         req->iRemoteFunctionCall.SetTransactionId( ++iTransactionId );
       
   483 
       
   484         iPendingRequestRoot.AppendToLast( req );
       
   485         TInt ret = ProcessNextPendingRequest();
       
   486         while ( KErrNone == ret )
       
   487             {
       
   488             ret = ProcessNextPendingRequest();
       
   489             }
       
   490         }
       
   491     else
       
   492         {
       
   493         err = KErrNoMemory;
       
   494         }
       
   495     VVHW_TRACE("DDeviceReqHandler::HandleExecuteAsync <-");
       
   496     return err;
       
   497     }
       
   498 
       
   499 // -----------------------------------------------------------------------------
       
   500 // DDeviceReqHandler::ProcessDfc
       
   501 // -----------------------------------------------------------------------------
       
   502 //
       
   503 void DDeviceReqHandler::ProcessDfc()
       
   504     {
       
   505     VVHW_TRACE("DDeviceReqHandler::ProcessDfc");
       
   506     TUint32 error( 0 );
       
   507     iHwInterface.GetRegisterValue( DVirtualVideoHwInterface::ERegError, error );
       
   508 
       
   509     TUint32 transactionId;
       
   510     iHwInterface.GetRegisterValue( DVirtualVideoHwInterface::ERegRequestId, transactionId );
       
   511 
       
   512     TAsyncRequest* req = iSerializedRequestRoot.iNext;
       
   513     VVHW_TRACE( "DDeviceReqHandler::ProcessDfc req %u transactionid %u", req, transactionId );
       
   514     
       
   515 
       
   516     if ( req && transactionId == req->iRemoteFunctionCall.Header().iTransactionId )
       
   517         {
       
   518         req->RemoveFromList( &iSerializedRequestRoot );
       
   519         
       
   520         //Check if the request was scheduler-initiated
       
   521         TBool driverInitiated(EFalse);
       
   522         if( iSchedulerInitiatedTransactionIds.Count() > 0 )
       
   523             {
       
   524             for( int i=0;i<iSchedulerInitiatedTransactionIds.Count();++i )
       
   525                 {
       
   526                 if( iSchedulerInitiatedTransactionIds[i].iTransactionId == req->iRemoteFunctionCall.Header().iTransactionId )
       
   527                     {
       
   528                 driverInitiated = ETrue;
       
   529                     //This will be used in the "consume" function later on in many cases
       
   530                     iSchedulerInitiatedTransactionData = iSchedulerInitiatedTransactionIds[i].iTransactionData; 
       
   531                     iSchedulerInitiatedTransactionIds.Remove( i );
       
   532                     break;
       
   533                     }
       
   534                 }
       
   535             }
       
   536         
       
   537         if( driverInitiated )
       
   538             {
       
   539             //This branch is for the purpose of handling commands that have been initiated from (this) 
       
   540             //Command Scheduler, and not a client thread. So far no cases exists, where this would
       
   541             //imply notifying a (client) DLL, so RequestComplete does not have to be called here (this could change later).
       
   542             //Parse result and write vectors back to client space
       
   543             if ( 0 == error )
       
   544                 {
       
   545                 //Parse result and write vectors back to client space        
       
   546                 TDataToClientSpaceCopier datacopier2( req->iAsyncClient );
       
   547                 RemoteFunctionCallData rfc;
       
   548                 SerializedFunctionCall sfc( rfc );
       
   549                 sfc.SetDataCopier( &datacopier2 );
       
   550                 const TLinAddr paramAddr( iHwInterface.OutputParametersAddress() );
       
   551                 VVHW_TRACE("DDeviceReqHandler::ProcessDfc parse");
       
   552                 sfc.ParseBuffer( reinterpret_cast<TUint8*>( paramAddr ), VVI_PARAMETERS_OUTPUT_MEMORY_SIZE );
       
   553                 TPckg<RemoteFunctionCallData> resultbuf( rfc );
       
   554                 req->iRemoteFunctionCall = resultbuf();//Get the object; its in the same address space 
       
   555                 VVHW_TRACE("DDeviceReqHandler::ProcessDfc ThreadDesWrite err=%d (data len=%d)", error, resultbuf.Length());
       
   556                 sfc.SetDataCopier( NULL );
       
   557                 }
       
   558 
       
   559             error = ResetAndEnableInterrupt( DVirtualVideoHwInterface::EInterruptNewDataAvailable );
       
   560             ConsumeSchedulerInitiatedRequestResult( req );
       
   561             }
       
   562         else
       
   563             {
       
   564 			TInt desWriteError = KErrNone;
       
   565             if ( 0 == error )
       
   566                 {
       
   567                 //Parse result and write vectors back to client space
       
   568 				// TODO for performance only write back result & output vectors, not whole request buffer
       
   569                 TDataToClientSpaceCopier datacopier2( req->iAsyncClient );
       
   570                 RemoteFunctionCallData rfc;
       
   571                 SerializedFunctionCall sfc( rfc );
       
   572                 sfc.SetDataCopier( &datacopier2 );
       
   573                 const TLinAddr paramAddr( iHwInterface.OutputParametersAddress() );
       
   574                 VVHW_TRACE("DDeviceReqHandler::ProcessDfc parse");
       
   575                 sfc.ParseBuffer( reinterpret_cast<TUint8*>( paramAddr ), VVI_PARAMETERS_OUTPUT_MEMORY_SIZE );
       
   576                 TPckg<RemoteFunctionCallData> resultbuf( rfc );
       
   577                 desWriteError = Kern::ThreadDesWrite( req->iAsyncClient, req->iA1, resultbuf, 0, 0 );
       
   578                 VVHW_TRACE("DDeviceReqHandler::ProcessDfc ThreadDesWrite err=%d (data len=%d)",desWriteError, resultbuf.Length());
       
   579                 sfc.SetDataCopier( NULL );
       
   580                 }
       
   581 
       
   582             Kern::RequestComplete( req->iAsyncClient, req->iStatus, desWriteError );
       
   583             ResetAndEnableInterrupt( DVirtualVideoHwInterface::EInterruptNewDataAvailable );
       
   584             ReleaseRequest( req );
       
   585             }
       
   586         }
       
   587     else
       
   588         {
       
   589         ResetAndEnableInterrupt( DVirtualVideoHwInterface::EInterruptNewDataAvailable );
       
   590         }
       
   591     VVHW_TRACE("DDeviceReqHandler::ProcessDfc ProcessNextPendingRequest");
       
   592     
       
   593     TInt ret = ProcessNextPendingRequest();
       
   594     while ( KErrNone == ret )
       
   595         {
       
   596         ret = ProcessNextPendingRequest();
       
   597         }
       
   598     }
       
   599 
       
   600 // -----------------------------------------------------------------------------
       
   601 // DDeviceReqHandler::AllocRequest
       
   602 // -----------------------------------------------------------------------------
       
   603 //
       
   604 DDeviceReqHandler::TAsyncRequest* DDeviceReqHandler::AllocRequest( TRequestStatus* aStatus,
       
   605         DThread* aAsyncClient,
       
   606         TAny* aA1,
       
   607         TAny* aA2,
       
   608         DDeviceReqHandler::TAsyncRequest::TRequestType aRequestType )
       
   609     {
       
   610     TAsyncRequest* req( NULL );
       
   611     if ( iFreeCount )
       
   612         {
       
   613         req = iFreeListRoot.iNext;
       
   614         req->RemoveFromList( &iFreeListRoot );
       
   615         req->Init( aStatus, aAsyncClient, aA1, aA2, aRequestType );
       
   616         iFreeCount--;
       
   617         }
       
   618     else
       
   619         {
       
   620         VVHW_TRACE("DDeviceReqHandler::AllocRequest new");
       
   621         req = new TAsyncRequest( aStatus, aAsyncClient, aA1, aA2, aRequestType );
       
   622         }
       
   623     return req;
       
   624     }
       
   625 
       
   626 // -----------------------------------------------------------------------------
       
   627 // DDeviceReqHandler::ReleaseRequest
       
   628 // -----------------------------------------------------------------------------
       
   629 //
       
   630 void DDeviceReqHandler::ReleaseRequest( DDeviceReqHandler::TAsyncRequest* aReq )
       
   631     {
       
   632     if ( iFreeCount > KMaxFreeRequests )
       
   633         {
       
   634         VVHW_TRACE("DDeviceReqHandler::AllocRequest delete");
       
   635         delete aReq;
       
   636         }
       
   637     else
       
   638         {
       
   639         aReq->AppendToList( &iFreeListRoot );
       
   640         iFreeCount++;
       
   641         }
       
   642     }
       
   643 
       
   644 
       
   645 
       
   646 void DDeviceReqHandler::RemoveClientData( const TUint32 aProcId, const TUint32 aThreadId )
       
   647     {
       
   648     VVHW_TRACE("DDeviceReqHandler::RemoveClientData (%d/%d)", aProcId, aThreadId );
       
   649     TPerThreadData* data( NULL );
       
   650     for( TInt i=0; i < iClientData.Count(); ++i )
       
   651         {
       
   652         if( iClientData[i]->sameThread( aProcId, aThreadId ) )
       
   653             {
       
   654             data = iClientData[i];
       
   655             iClientData.Remove(i);
       
   656             if( data == iCurrClientData )
       
   657                 {
       
   658                 iCurrClientData = 0;
       
   659                 }
       
   660             delete data;
       
   661             break;
       
   662             }
       
   663         }
       
   664     }
       
   665 
       
   666 TBool DDeviceReqHandler::InitiateRequestWithReply( TAsyncRequest* aRec, TAny* aTransactionData )
       
   667     {
       
   668     VVHW_TRACE("DDeviceReqHandler::InitiateRequestWithReply" );
       
   669     if( iDriverRfcThreadId == 0 || iDriverRfcProcessId == 0 )
       
   670         {
       
   671         iDriverRfcProcessId = Kern::CurrentProcess().iId;
       
   672         iDriverRfcThreadId  = Kern::CurrentThread().iId;
       
   673         }
       
   674     //iReqIssueMutex.Wait();
       
   675     const TUint32 serializedLength( aRec->iRemoteFunctionCall.SerialisedLength() );
       
   676     if ( !iRequestBuffer.CheckForSpace( serializedLength ) )
       
   677        {
       
   678        return EFalse;
       
   679        }
       
   680     ++iTransactionId;
       
   681     aRec->iRemoteFunctionCall.SetTransactionId( iTransactionId );
       
   682     aRec->iRemoteFunctionCall.SetOperationType( RemoteFunctionCallData::EOpRequestWithReply );
       
   683     aRec->iAsyncClient = &(Kern::CurrentThread());
       
   684     aRec->iRemoteFunctionCall.SetThreadInformation( iDriverRfcProcessId, iDriverRfcThreadId );
       
   685     
       
   686     iSchedulerInitiatedTransactionIds.Append( TTransactionInfo( iTransactionId, aTransactionData ) );
       
   687     VVHW_TRACE("DDeviceReqHandler::InitiateRequestWithReply ids len=%d transaction id = %u proc/thread = %u / %u api/op = %0x / %0x", iSchedulerInitiatedTransactionIds.Count(), iTransactionId, Kern::CurrentProcess().iId, Kern::CurrentThread().iId, aRec->iRemoteFunctionCall.Header().iApiUid, aRec->iRemoteFunctionCall.Header().iOpCode );
       
   688     if( aRec->iRemoteFunctionCall.Header().iApiUid )
       
   689         {
       
   690         VVHW_TRACE("DDeviceReqHandler::InitiateRequestWithReply request's api is SERIALISED_DRIVER_API_UID" );
       
   691         }
       
   692     
       
   693     iSerializedRequestRoot.AppendToLast( aRec );//we need the result, so add to the dfc handled requests
       
   694     TDataFromClientSpaceCopier datacopier( aRec->iAsyncClient );
       
   695     SerializedFunctionCall sfc( aRec->iRemoteFunctionCall );
       
   696     
       
   697     sfc.SetDataCopier( &datacopier );//We know this is a "request" (precondition)
       
   698     const TUint32 base( iRequestBuffer.AllocateBytes( serializedLength ) );
       
   699     //Next, serialize the call to the HW memory
       
   700     const TLinAddr paramAddr( iHwInterface.InputParametersAddress() + base );
       
   701     TInt len = sfc.WriteToBuffer( reinterpret_cast<TUint8*>(paramAddr), VVI_PARAMETERS_INPUT_MEMORY_SIZE - 1 - base );
       
   702     VVHW_TRACE("DDeviceReqHandler::InitiateRequestWithReply len = %d", len);
       
   703     sfc.SetDataCopier( NULL );
       
   704     iRequestBuffer.CommitBytes( base, serializedLength );
       
   705     iHwInterface.IssueCommand( VVI_EXECUTE );
       
   706     VVHW_TRACE("DDeviceReqHandler::InitiateRequestWithReply issued");
       
   707     return ETrue;
       
   708     }
       
   709 
       
   710 /**
       
   711  * This routine adds extra info about the sgImage's pbuffer handle for syncing,
       
   712  * when that is required. 
       
   713  * 1. checks the sgImage handle, and if it's not NULL, then
       
   714  *  2. Get the sgImage's metadata
       
   715  *  3. Check if the vgImage is "dirty", and if yes,
       
   716  *      then append the pbuffer handle as a parameter to the call   
       
   717  *  4. Set the pbuffer "dirty", if aSetBufferDirty is ETrue
       
   718  */
       
   719 
       
   720 void DDeviceReqHandler::getVGSyncInOp( TAsyncRequest* aReq, TInt aSgHandleIndexInReq, TBool aSetBufferDirty )
       
   721     {    
       
   722     VVHW_TRACE( "DDeviceReqHandler::getVGSyncInOp" );
       
   723     OpenVgRFC call( aReq->iRemoteFunctionCall );
       
   724     TUint64 sgId(NULL);
       
   725     
       
   726     if( call.Data().Header().iParameterCount > aSgHandleIndexInReq )
       
   727         {
       
   728         call.GetTUint64( sgId, aSgHandleIndexInReq );
       
   729         }
       
   730     else
       
   731         {
       
   732         return;//No sgImage handle appended on the client side, just exit
       
   733         }
       
   734     
       
   735 #ifdef FAISALMEMON_S4_SGIMAGE
       
   736     EGLSurface surface( EGL_NO_SURFACE );//The pbuffer surface to sync from, if needed
       
   737     VGboolean syncNeeded = VG_FALSE;
       
   738     if( sgId != NULL )
       
   739         {
       
   740         VVHW_TRACE( "DDeviceReqHandler::getVGSyncInOp SgImage-backing VGImage found" );
       
   741         DSgResource* resource;
       
   742         HBuf8* data = OpenSgImageMetaData( sgId, resource );
       
   743         if( data )
       
   744             {
       
   745             TSgImageMetaData sginfo (((TPckgBuf<TSgImageMetaData>*) data)->operator ()());
       
   746             
       
   747             if( !sginfo.iVGImageClean )
       
   748                 {
       
   749                 //set the sync bit as clean now.
       
   750                 sginfo.iVGImageClean = ETrue;
       
   751                 //Additional info for the host side to use
       
   752                 syncNeeded = VG_TRUE;
       
   753                 surface = sginfo.iPbufferHandle;
       
   754                 }
       
   755             if( aSetBufferDirty )
       
   756                 {
       
   757                 sginfo.iPbufferClean = EFalse;
       
   758                 }
       
   759             resource->SetMetaData( *data );
       
   760             delete data;//delete the copy of the metadata descriptor
       
   761             }
       
   762         }
       
   763     if( syncNeeded )
       
   764         {
       
   765         call.AppendParam ( (int)surface );
       
   766         }
       
   767 #endif
       
   768     }
       
   769 
       
   770 
       
   771 void DDeviceReqHandler::ConsumeSchedulerInitiatedRequestResult( TAsyncRequest* aReq )
       
   772     {
       
   773     const TUint32 proc_id( aReq->iRemoteFunctionCall.Header().iProcessId );
       
   774     const TUint32 thread_id( aReq->iRemoteFunctionCall.Header().iThreadId );
       
   775     const TUint32 apicode( aReq->iRemoteFunctionCall.Header().iApiUid );
       
   776     const TUint32 opcode( aReq->iRemoteFunctionCall.Header().iOpCode );
       
   777     VVHW_TRACE( "DDeviceReqHandler::ConsumeSchedulerInitiatedRequestResult: process/thread id : %d / %d", Kern::CurrentProcess().iId, Kern::CurrentThread().iId );
       
   778     VVHW_TRACE( "DDeviceReqHandler::ConsumeSchedulerInitiatedRequestResult: process/thread id : %d / %d API/opcode = %0x/%0x", proc_id, thread_id, apicode, opcode );
       
   779     TPerThreadData* data(0);
       
   780     for( TInt i=0; i < iClientData.Count(); ++i )
       
   781         {
       
   782         if( iClientData[i]->sameThread( proc_id, thread_id ))
       
   783             {
       
   784             data = iClientData[i];
       
   785             break;
       
   786             }
       
   787         }
       
   788     
       
   789     switch ( apicode )
       
   790         {
       
   791         case SERIALISED_DRIVER_API_UID:
       
   792             {
       
   793             switch( opcode )
       
   794                 {
       
   795                 case DriverRFC::EDrvCreatePbufferSg:
       
   796                     {
       
   797                     VVHW_TRACE( "DDeviceReqHandler::ConsumeSchedulerInitiatedRequestResult : EDrvCreatePbufferSg" );
       
   798 #ifdef FAISALMEMON_S4_SGIMAGE
       
   799                     if( iSchedulerInitiatedTransactionData )
       
   800                         {
       
   801                         ((TSgImageMetaData*)iSchedulerInitiatedTransactionData)->iPbufferHandle = aReq->iRemoteFunctionCall.Header().iReturnValue;
       
   802                         VVHW_TRACE( "DDeviceReqHandler::ConsumeSchedulerInitiatedRequestResult pbuffer=%u", ((TSgImageMetaData*)iSchedulerInitiatedTransactionData)->iPbufferHandle );
       
   803                         }
       
   804                     TPbSId obj ( ((TSgImageMetaData*)iSchedulerInitiatedTransactionData)->iPbufferHandle,
       
   805                                  ((TSgImageMetaData*)iSchedulerInitiatedTransactionData)->iSgId );
       
   806                     iPbufferSgMap.InsertInOrder( obj, iPbufferSgMapOrder );
       
   807                     VVHW_TRACE( "pbuffer creation RequestComplete. Inserted (%u, %u) into sg map. Notify thread %u, request status %u",
       
   808                                                                     ((TSgImageMetaData*)iSchedulerInitiatedTransactionData)->iPbufferHandle,
       
   809                                                                     ((TSgImageMetaData*)iSchedulerInitiatedTransactionData)->iSgId,
       
   810                                                                     aReq->iAsyncClient,
       
   811                                                                     aReq->iStatus );
       
   812                     *(aReq->iStatus) = 0;//REquestComplete doesn't work
       
   813 #endif
       
   814                     VVHW_TRACE( "Pbuffer creation RequestComplete" );
       
   815                     break;
       
   816                     }
       
   817                 case DriverRFC::EDrvCreateVGImageSg:
       
   818                     {
       
   819                     VVHW_TRACE( "DDeviceReqHandler::ConsumeSchedulerInitiatedRequestResult : EDrvCreateVGImageSg" );
       
   820 #ifdef FAISALMEMON_S4_SGIMAGE
       
   821                     if( iSchedulerInitiatedTransactionData )
       
   822                         {
       
   823                         ((TSgImageMetaData*)iSchedulerInitiatedTransactionData)->iVGImageHandle = aReq->iRemoteFunctionCall.Header().iReturnValue;
       
   824                         }
       
   825                     TVGISId obj ( ((TSgImageMetaData*)iSchedulerInitiatedTransactionData)->iVGImageHandle,
       
   826                                  ((TSgImageMetaData*)iSchedulerInitiatedTransactionData)->iSgId );
       
   827                     iVGImageSgMap.InsertInOrder( obj, iVGImageSgMapOrder );
       
   828                     VVHW_TRACE( "pbuffer creation RequestComplete. Inserted (%u, %u) into sg map. Notify thread %u, request status %u",
       
   829                                ((TSgImageMetaData*)iSchedulerInitiatedTransactionData)->iVGImageHandle,
       
   830                                ((TSgImageMetaData*)iSchedulerInitiatedTransactionData)->iSgId,
       
   831                                aReq->iAsyncClient,
       
   832                                aReq->iStatus );
       
   833                     *(aReq->iStatus) = 0;//REquestComplete doesn't work
       
   834 #endif
       
   835                     VVHW_TRACE( "VGImage creation RequestComplete" );
       
   836                     break;
       
   837                     }
       
   838                 case DriverRFC::EDrvDeleteSgImage:
       
   839                     {
       
   840                     *(aReq->iStatus) = 0;
       
   841                     }
       
   842                 case DriverRFC::EDrvSyncVGImageFromPBuffer:
       
   843                     {
       
   844                     ((TAsyncRequest*)iSchedulerInitiatedTransactionData)->AppendToList( (TAsyncRequest*)(&iPendingRequestRoot) );
       
   845                     break;
       
   846                     }
       
   847                 default:
       
   848                     {
       
   849                     break;
       
   850                     }
       
   851                 }
       
   852             }
       
   853         case SERIALISED_OPENVG_API_UID:
       
   854             {
       
   855             switch( opcode )
       
   856                 {
       
   857                 case OpenVgRFC::EvgGetError:
       
   858                     {
       
   859                     VVHW_TRACE("OpenVgRFC::EvgGetError");
       
   860                     data->iErrorVG = aReq->iRemoteFunctionCall.Header().iReturnValue;
       
   861                     data->iErrUpdatedVG = EFalse;//TODO: ETrue
       
   862                     break;
       
   863                     }
       
   864                 default:{break;}
       
   865                 }
       
   866             break;
       
   867             }
       
   868         case SERIALISED_EGL_API_UID:
       
   869             {
       
   870             switch( opcode )
       
   871                 {
       
   872                 case EglRFC::EeglGetError:
       
   873                     {
       
   874                     VVHW_TRACE("EglRFC::EeglGetError");
       
   875                     data->iErrorEGL = aReq->iRemoteFunctionCall.Header().iReturnValue;
       
   876                     data->iErrUpdatedEGL = EFalse;//TODO: ETrue
       
   877                     break;
       
   878                     }
       
   879                 default:
       
   880                     {break;}
       
   881                 }
       
   882             break;
       
   883             }
       
   884         case SERIALISED_OPENGLES_1_1_API_UID:
       
   885             {
       
   886             switch( opcode )
       
   887                 {
       
   888                 case OpenGlES11RFC::EglGetError:
       
   889                     {
       
   890                     VVHW_TRACE("OpenGlES11RFC::EglGetError");
       
   891                     data->iErrorGLES = aReq->iRemoteFunctionCall.Header().iReturnValue;
       
   892                     data->iErrUpdatedGLES = EFalse;//TODO: ETrue
       
   893                     }
       
   894                 default:{break;}
       
   895                 }
       
   896             break;
       
   897             }
       
   898         default:{break;}
       
   899         }
       
   900 
       
   901     VVHW_TRACE( "DDeviceReqHandler::ConsumeSchedulerInitiatedRequestResult return value: %d", aReq->iRemoteFunctionCall.Header().iReturnValue );
       
   902     if( data )
       
   903         {
       
   904         VVHW_TRACE("errors EGL/VG/GLES=%0x/%0x/%0x", data->iErrorEGL, data->iErrorVG, data->iErrorGLES );
       
   905         }
       
   906     //Delete the request object, as it is no longer needed
       
   907     aReq->iStatus = 0;
       
   908     aReq->iAsyncClient = 0;
       
   909     delete aReq;
       
   910     VVHW_TRACE("DDeviceReqHandle::ConsumeSchedulerInitiatedRequestResult done.");
       
   911     }
       
   912 
       
   913 #ifdef FAISALMEMON_S4_SGIMAGE
       
   914 /**
       
   915  * DDeviceReqHandler::CreateSgImagePbuffer
       
   916  * @param aInfo the info 
       
   917  */
       
   918 void DDeviceReqHandler::CreateSgImagePbuffer( const TSgImageMetaData& aInfo, TRequestStatus* aStatus, DThread* aThread )
       
   919     {
       
   920     //eglCreatePbufferSurface
       
   921     //
       
   922     VVHW_TRACE("DDeviceReqHandler::CreateSgImagePbuffer ->");
       
   923     if( !iCurrClientData )
       
   924         {return;}
       
   925     TBool allok = ETrue;
       
   926     TAsyncRequest* req(0);
       
   927     TPckg<TUint32> res( iOpReturn );
       
   928     *aStatus = KRequestPending;
       
   929     VVHW_TRACE("DDeviceReqHandler::CreateSgImagePbuffer request from thread %u, requeststatus %u", aThread, aStatus );
       
   930     req = AllocRequest( aStatus, aThread, NULL, (TAny*)(&res), TAsyncRequest::ERTRequest );
       
   931     if( req )
       
   932         {
       
   933         DriverRFC call( req->iRemoteFunctionCall );
       
   934         call.Init( DriverRFC::EDrvCreatePbufferSg );
       
   935         
       
   936         call.AppendEGLint  ( aInfo.iSizeInPixels.iWidth );
       
   937         call.AppendEGLint  ( aInfo.iSizeInPixels.iHeight );
       
   938         call.AppendEGLint  ( aInfo.iPixelFormat );
       
   939 
       
   940         TPckg<RemoteFunctionCallData> data( req->iRemoteFunctionCall );
       
   941         req->iA1 = (TAny*)( &data );
       
   942         allok = InitiateRequestWithReply( req, (TAny*)(&aInfo) );
       
   943         }
       
   944     if( !allok )
       
   945         {
       
   946         //request not sent, or something else went wrong. Tell the client its over
       
   947         //TODO: somehow dispose of the pbuffer that might have been created
       
   948         }
       
   949     while( *(aStatus) == KRequestPending )
       
   950         {
       
   951         NKern::Sleep( 20 );   
       
   952         }
       
   953     VVHW_TRACE("DDeviceReqHandler::CreateSgImagePBuffer <-");
       
   954     return;
       
   955     }
       
   956 
       
   957 void DDeviceReqHandler::CreateSgImageVGImage( const TSgImageMetaData& aInfo, TRequestStatus* aStatus, DThread* aThread )
       
   958     {
       
   959     //eglCreatePbufferSurface
       
   960     //
       
   961     VVHW_TRACE("DDeviceReqHandler::CreateSgImageVGImage ->");
       
   962     if( !iCurrClientData )
       
   963         {return;}
       
   964     TBool allok = ETrue;
       
   965     TAsyncRequest* req(0);
       
   966     TPckg<TUint32> res( iOpReturn );
       
   967     *aStatus = KRequestPending;
       
   968     //make a request for the vgImage
       
   969     req = AllocRequest( aStatus, aThread, NULL, (TAny*)(&res), TAsyncRequest::ERTRequest );
       
   970     if( req )
       
   971         {
       
   972         DriverRFC call( req->iRemoteFunctionCall );
       
   973         call.Init( DriverRFC::EDrvCreateVGImageSg );
       
   974         
       
   975         call.AppendEGLint  ( aInfo.iSizeInPixels.iWidth );
       
   976         call.AppendEGLint  ( aInfo.iSizeInPixels.iHeight );
       
   977         call.AppendEGLint  ( aInfo.iPixelFormat );
       
   978 
       
   979         TPckg<RemoteFunctionCallData> data( req->iRemoteFunctionCall );
       
   980         req->iA1 = (TAny*)(&data);
       
   981         allok = InitiateRequestWithReply( req, (TAny*)(&aInfo) );
       
   982         }
       
   983     if( !allok )
       
   984         {
       
   985         //request not sent, or something else went wrong. Tell the client its over
       
   986         //TODO: somehow dispose of the image that might have been created
       
   987         //Kern::RequestComplete( aStatus, KErrGeneral );
       
   988         }
       
   989     while( *(aStatus) == KRequestPending )
       
   990         {
       
   991         NKern::Sleep( 20 );
       
   992         }
       
   993     VVHW_TRACE("DDeviceReqHandler::CreateSgImageVGImage <-");
       
   994     return;
       
   995     }
       
   996 #endif
       
   997 
       
   998 TInt DDeviceReqHandler::DestroySgImage( const TUint64 aId )
       
   999     {
       
  1000     VVHW_TRACE("DDeviceReqHandler::DestroySgImage ->");
       
  1001     
       
  1002 #ifdef FAISALMEMON_S4_SGIMAGE
       
  1003     TBool allok = ETrue;
       
  1004     TAsyncRequest* req(0);
       
  1005     TPckg<TUint32> res( iOpReturn );
       
  1006     EGLSurface surface(0);
       
  1007     VGImage    image(0);
       
  1008     DSgResource* resource;
       
  1009     HBuf8* data = OpenSgImageMetaData( aId, resource );
       
  1010     if( data )
       
  1011         {
       
  1012         TSgImageMetaData sginfo (((TPckgBuf<TSgImageMetaData>*) data)->operator ()());
       
  1013         surface = sginfo.iPbufferHandle;
       
  1014         //TODO: are there other cases: e.g. can the vgimage be destroyed without destroying the surface?
       
  1015         if( sginfo.iUsage || ESgUsageBitOpenVgImage )
       
  1016             {
       
  1017             image = sginfo.iVGImageHandle;
       
  1018             }
       
  1019         delete data;
       
  1020         }
       
  1021     TRequestStatus status = KRequestPending;
       
  1022     //make a request for the vgImage
       
  1023     req = AllocRequest( &status, &Kern::CurrentThread(), NULL, (TAny*)(&res), TAsyncRequest::ERTRequest );
       
  1024     allok = (req?EFalse:ETrue);
       
  1025     if( req )
       
  1026         {
       
  1027         DriverRFC call( req->iRemoteFunctionCall );
       
  1028         call.Init( DriverRFC::EDrvDeleteSgImage );
       
  1029         
       
  1030         call.AppendEGLSurface( surface );
       
  1031         call.AppendVGParam ( image );
       
  1032 
       
  1033         TPckg<RemoteFunctionCallData> data( req->iRemoteFunctionCall );
       
  1034         req->iA1 = (TAny*)(&data);
       
  1035         allok = InitiateRequestWithReply( req, 0 );
       
  1036         }
       
  1037     if( !allok )
       
  1038         {
       
  1039         //TODO
       
  1040         }
       
  1041     while( status == KRequestPending )
       
  1042         {
       
  1043         NKern::Sleep( 20 );
       
  1044         }
       
  1045 #endif
       
  1046 
       
  1047     VVHW_TRACE("DDeviceReqHandler::DestroySgImage <-");
       
  1048     return 1;
       
  1049     }
       
  1050 
       
  1051 
       
  1052 DDeviceReqHandler::TRequestMode DDeviceReqHandler::InterpretRequest( TAsyncRequest* aReq )
       
  1053     {
       
  1054     TRequestMode alreadyProcessed( ENormal );//processed here? The return value
       
  1055     const TUint32 proc_id( aReq->iRemoteFunctionCall.Header().iProcessId );
       
  1056     const TUint32 thread_id( aReq->iRemoteFunctionCall.Header().iThreadId );
       
  1057     const TUint32 apicode( aReq->iRemoteFunctionCall.Header().iApiUid );
       
  1058     const TUint32 opcode( aReq->iRemoteFunctionCall.Header().iOpCode );
       
  1059     
       
  1060     VVHW_TRACE( "DDeviceReqHandler::InterpretRequest in the process/thread %0x / %0x", Kern::CurrentProcess().iId, Kern::CurrentThread().iId );
       
  1061     
       
  1062     TBool ErrUpdatedVG = EFalse;//is the error updated during this function call
       
  1063     TBool ErrUpdatedEGL = EFalse;//is the error updated during this function call
       
  1064     TBool ErrUpdatedGLES = EFalse;//is the error updated during this function call
       
  1065     //Get a data object to work with
       
  1066     //(either a previously used client data object, or create a new one)
       
  1067     TPerThreadData* data(NULL);
       
  1068     if( iCurrClientData &&
       
  1069         iCurrClientData->sameThread( proc_id, thread_id ))
       
  1070         {
       
  1071         //the same client as previously
       
  1072         data = iCurrClientData;
       
  1073         }
       
  1074     else
       
  1075         {
       
  1076         //Check if this client is already known
       
  1077         for( TInt i=0; i < iClientData.Count(); ++i )
       
  1078             {
       
  1079             if( iClientData[i]->sameThread( proc_id, thread_id ))
       
  1080                 {
       
  1081                 data = iClientData[i];
       
  1082                 break;
       
  1083                 }
       
  1084             }
       
  1085         if( !data )
       
  1086             {
       
  1087             data = new TPerThreadData( aReq->iStatus, aReq->iAsyncClient, proc_id, thread_id );
       
  1088             iClientData.Append( data );
       
  1089             }
       
  1090         if( iCurrClientData )
       
  1091             {
       
  1092             VVHW_TRACE( "DDeviceReqHandler::InterpretRequest: SWITCHING CONTEXT: %d / %d -> %d / %d",
       
  1093                     iCurrClientData->iProcessId,
       
  1094                     iCurrClientData->iThreadId,
       
  1095                     proc_id,
       
  1096                     thread_id );
       
  1097             //Some other things need to be done here as well, as per 5.2 in the "Implementing SgImage" design doc
       
  1098             //TODO: currently the context switch does not need to be done on this level
       
  1099             }
       
  1100         //Context switched, or no previous client. Current set to new current.
       
  1101         iCurrClientData = data;
       
  1102         }
       
  1103     //Invariant: "data" and "iCurrClient" are the same and not null after this line
       
  1104     VVHW_TRACE("DDeviceReqHandler::InterpretRequest: number of clients = %d", iClientData.Count() );
       
  1105     
       
  1106     
       
  1107     iCurrClientData->iCurrApiUid = apicode;
       
  1108     iCurrClientData->iCurrOpCode = opcode;
       
  1109     VVHW_TRACE( "DDeviceReqHandler::InterpretRequest: process/thread id : %d / %d API/opcode = %d/%0x", proc_id, thread_id, apicode, opcode );
       
  1110     
       
  1111     
       
  1112     switch ( apicode )
       
  1113         {
       
  1114         case SERIALISED_DRIVER_API_UID:
       
  1115             {
       
  1116             VVHW_TRACE("Driver request (must be a shutdown for %d / %d)", proc_id, thread_id  );
       
  1117             if( opcode == DriverRFC::EDrvClientShutdown )
       
  1118                 {
       
  1119                 RemoveClientData( proc_id, thread_id );
       
  1120                 }
       
  1121             break;
       
  1122             }
       
  1123         case SERIALISED_OPENVG_API_UID:
       
  1124             {
       
  1125             VVHW_TRACE("OpenVG request" );
       
  1126             switch( opcode )
       
  1127                 {
       
  1128                 case OpenVgRFC::EvgGetError:
       
  1129                     {
       
  1130                     break;
       
  1131                     }
       
  1132                 //We need to catch all the operations that create or access VGImage buffers
       
  1133                 case OpenVgRFC::EvgChildImage:
       
  1134                     {
       
  1135                     VVHW_TRACE("vgChildImage" );
       
  1136                     break;
       
  1137                     }
       
  1138                 case OpenVgRFC::EvgDestroyImage:
       
  1139                     {
       
  1140                     VVHW_TRACE("vgDestroyImage" );
       
  1141                     break;
       
  1142                     }
       
  1143                 case OpenVgRFC::EvgFinish:
       
  1144                     {
       
  1145                     VVHW_TRACE("vgFinish" );
       
  1146                     //A sync is required if there are any native pixmaps backing surfaces in the current context
       
  1147                     break;
       
  1148                     }
       
  1149                 /* 
       
  1150                 The sgImage ID is a 64-bit value, it has to be serialised as 2 32-bit values, thus occupying
       
  1151                 2 parameter slots each. The sgImage ID position is thus the second last + last parameters in the 
       
  1152                 parameter list
       
  1153                 */ 
       
  1154                 case OpenVgRFC::EvgClearImage:
       
  1155                     {
       
  1156                     VVHW_TRACE("vgClearImage" );
       
  1157                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-2 );
       
  1158                     break;
       
  1159                     }
       
  1160                 case OpenVgRFC::EvgImageSubData:
       
  1161                     {
       
  1162                     VVHW_TRACE("vgImageSubData" );
       
  1163                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-2 );
       
  1164                     break;
       
  1165                     }
       
  1166                 case OpenVgRFC::EvgGetPixels:
       
  1167                     {
       
  1168                     VVHW_TRACE("vgGetPixels" );
       
  1169                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-2 );
       
  1170                     break;
       
  1171                     }
       
  1172                 case OpenVgRFC::EvgSetPixels:
       
  1173                     {
       
  1174                     VVHW_TRACE("vgSetPixels" );
       
  1175                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-2 );
       
  1176                     break;
       
  1177                     }
       
  1178                 case OpenVgRFC::EvgCopyImage:
       
  1179                     {
       
  1180                     VVHW_TRACE("vgCopyImage" );
       
  1181                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-2 );
       
  1182                     break;
       
  1183                     }
       
  1184                 case OpenVgRFC::EvgDrawImage:
       
  1185                     {
       
  1186                     VVHW_TRACE("vgDrawImage" );
       
  1187                     break;
       
  1188                     }
       
  1189                 case OpenVgRFC::EvgColorMatrix:
       
  1190                     {
       
  1191                     VVHW_TRACE("vgColorMatrix" );
       
  1192                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-4 );//dst
       
  1193                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-2 );//src
       
  1194                     break;
       
  1195                     }
       
  1196                 case OpenVgRFC::EvgConvolve:
       
  1197                     {
       
  1198                     VVHW_TRACE("vgConvolve" );
       
  1199                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-4 );//dst
       
  1200                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-2 );//src
       
  1201                     break;
       
  1202                     }
       
  1203                 case OpenVgRFC::EvgSeparableConvolve:
       
  1204                     {
       
  1205                     VVHW_TRACE("vgSeparableConvolve" );
       
  1206                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-4 );//dst
       
  1207                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-2 );//src
       
  1208                     break;
       
  1209                     }
       
  1210                 case OpenVgRFC::EvgGaussianBlur:
       
  1211                     {
       
  1212                     VVHW_TRACE("vgGaussianBlur" );
       
  1213                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-4 );//dst
       
  1214                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-2 );//src
       
  1215                     break;
       
  1216                     }
       
  1217                 case OpenVgRFC::EvgLookup:
       
  1218                     {
       
  1219                     VVHW_TRACE("vgLookup" );
       
  1220                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-4 );//dst
       
  1221                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-2 );//src
       
  1222                     break;
       
  1223                     }
       
  1224                 case OpenVgRFC::EvgLookupSingle:
       
  1225                     {
       
  1226                     VVHW_TRACE("vgLookupSingle" );
       
  1227                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-4 );//dst
       
  1228                     getVGSyncInOp( aReq, aReq->iRemoteFunctionCall.Header().iParameterCount-2 );//src
       
  1229                     break;
       
  1230                     }
       
  1231                 case OpenVgRFC::EvgPathBounds:
       
  1232                     {
       
  1233                     VVHW_TRACE("vgPathBounds" );
       
  1234                     break;
       
  1235                     }
       
  1236                 default:
       
  1237                     {
       
  1238                     break;
       
  1239                     }
       
  1240                 }
       
  1241             break;
       
  1242             }
       
  1243         case SERIALISED_EGL_API_UID:
       
  1244             {
       
  1245             VVHW_TRACE("EGL request" );
       
  1246             switch( opcode )
       
  1247                 {
       
  1248                 case EglRFC::EeglMetaSgGetHandles:
       
  1249                     {
       
  1250                     VVHW_TRACE("EglRFC::EeglMetaSgGetHandles" );
       
  1251                     EglRFC call( aReq->iRemoteFunctionCall );
       
  1252                     TUint64 id(0);
       
  1253                     EGLint* handles;
       
  1254                     EGLint handles_size;
       
  1255                     
       
  1256                     call.GetTUint64( id, 0 );
       
  1257                     call.GetEGLintVectorData( handles, handles_size, 2 );
       
  1258 #ifdef FAISALMEMON_S4_SGIMAGE
       
  1259                     DSgResource* resource;
       
  1260                     VVHW_TRACE("EglRFC::EeglMetaSgGetHandles openSgImageMetaData" );
       
  1261                     HBuf8* data = OpenSgImageMetaData( id, resource );
       
  1262                     if( data && handles_size >= 2 )
       
  1263                         {
       
  1264                         TSgImageMetaData sginfo (((TPckgBuf<TSgImageMetaData>*) data)->operator ()());
       
  1265                         handles[0] = sginfo.iPbufferHandle;
       
  1266                         handles[1] = sginfo.iVGImageHandle;
       
  1267                         call.SetReturnValue( (int)EGL_TRUE );
       
  1268                         }
       
  1269                     else
       
  1270                         {
       
  1271                         call.SetReturnValue( (int)EGL_FALSE );
       
  1272                         }
       
  1273                     alreadyProcessed = EHandled;
       
  1274 #endif
       
  1275 					break;
       
  1276                     }
       
  1277                 case EglRFC::EeglCreateContext:
       
  1278                     {
       
  1279                     //if no share_context specified, pass the sgImage pool context
       
  1280                     VVHW_TRACE("eglCreateContext" );
       
  1281                     break;
       
  1282                     }
       
  1283                 case EglRFC::EeglMakeCurrent:
       
  1284                     {
       
  1285                     EGLDisplay dpy;
       
  1286                     EGLSurface draw;
       
  1287                     EGLSurface read;
       
  1288                     EGLContext ctx;
       
  1289                     EGLint syncRequirement(0);//no sync = 0
       
  1290                     
       
  1291                     EglRFC call( aReq->iRemoteFunctionCall );
       
  1292                     call.GetEGLDisplay( dpy, 0 );
       
  1293                     call.GetEGLSurface( draw, 1 );
       
  1294                     call.GetEGLSurface( read, 2 );
       
  1295                     call.GetEGLContext( ctx, 3 );
       
  1296                     VGImage img = 0;
       
  1297                     
       
  1298                     TPbSId obj ( draw, 0 );
       
  1299 
       
  1300                     TInt sgIdIndex = iPbufferSgMap.FindInOrder( obj, iPbufferSgMapOrder );
       
  1301                     if( sgIdIndex != KErrNotFound )
       
  1302                         {
       
  1303 #ifdef FAISALMEMON_S4_SGIMAGE
       
  1304                         DSgResource* resource;
       
  1305                         HBuf8* data = OpenSgImageMetaData( iPbufferSgMap[sgIdIndex].iSgId, resource );
       
  1306                         if( data )
       
  1307                             {
       
  1308                             TSgImageMetaData sginfo (((TPckgBuf<TSgImageMetaData>*) data)->operator ()());
       
  1309                             
       
  1310                             if( !sginfo.iPbufferClean )
       
  1311                                 {
       
  1312                                 img = sginfo.iVGImageHandle;
       
  1313                                 //sync with the underlying pbuffer surface
       
  1314                                 syncRequirement = syncRequirement | KSyncDrawSurface;
       
  1315                                 call.AppendEGLint( img );
       
  1316                                 }
       
  1317                             delete data;
       
  1318                             }
       
  1319 #endif
       
  1320                         }
       
  1321                     obj.iPbuffer = read;
       
  1322                     obj.iSgId = 0;
       
  1323 
       
  1324                     sgIdIndex = iPbufferSgMap.FindInOrder( obj, iPbufferSgMapOrder );
       
  1325                     if( sgIdIndex != KErrNotFound )
       
  1326                         {
       
  1327 #ifdef FAISALMEMON_S4_SGIMAGE
       
  1328                         DSgResource* resource;
       
  1329                         HBuf8* data = OpenSgImageMetaData( iPbufferSgMap[sgIdIndex].iSgId, resource );
       
  1330                         if( data )
       
  1331                             {
       
  1332                             TSgImageMetaData sginfo (((TPckgBuf<TSgImageMetaData>*) data)->operator ()());
       
  1333                             
       
  1334                             if( !sginfo.iPbufferClean )
       
  1335                                 {
       
  1336                                 img = sginfo.iVGImageHandle;
       
  1337                                 //sync with the underlying pbuffer surface
       
  1338                                 syncRequirement = syncRequirement | KSyncReadSurface;
       
  1339                                 }
       
  1340                             delete data;
       
  1341                             }
       
  1342 #endif
       
  1343                         }
       
  1344                     call.AppendEGLint( syncRequirement );
       
  1345                     call.AppendEGLint( img );
       
  1346                     
       
  1347                     VVHW_TRACE("eglMakeCurrent %u", iCurrClientData->iContext );
       
  1348                     break;
       
  1349                     }
       
  1350                 case EglRFC::EeglMakeCurrentSg:
       
  1351                     {
       
  1352                     VVHW_TRACE("eglMakeCurrentSg" );
       
  1353                     break;
       
  1354                     }
       
  1355                 case EglRFC::EeglCreatePixmapSurfaceSg:
       
  1356                     {
       
  1357                     alreadyProcessed = EHandled;//This will be handled here
       
  1358                     
       
  1359                     TUint64 sgId;
       
  1360                     EglRFC call( aReq->iRemoteFunctionCall );
       
  1361                     call.GetTUint64( sgId, 0 );//get the sgImage id
       
  1362                     
       
  1363 #ifdef FAISALMEMON_S4_SGIMAGE
       
  1364                     DSgResource* resource;
       
  1365                     HBuf8* data = OpenSgImageMetaData( sgId, resource );
       
  1366                     if( data )
       
  1367                         {
       
  1368                             TSgImageMetaData sginfo (((TPckgBuf<TSgImageMetaData>*) data)->operator ()());
       
  1369                             resource->SetMetaData( (*data) );
       
  1370                             aReq->iRemoteFunctionCall.SetReturnValue( sginfo.iPbufferHandle );
       
  1371                             delete data;
       
  1372                         }
       
  1373                     else
       
  1374                         {
       
  1375                         aReq->iRemoteFunctionCall.SetReturnValue( EGL_NO_SURFACE );
       
  1376                         }
       
  1377                     //Find the sgimage's pbuffer surface, then return that
       
  1378 #endif
       
  1379                     VVHW_TRACE( "EeglCreatePixmapSurfaceSg" );
       
  1380                     break;
       
  1381                     }
       
  1382                 case EglRFC::EeglCreatePbufferFromClientBuffer:
       
  1383                     {
       
  1384                     //if a sgImage-backing VGImage handle is passed here, then fail with EGL_BAD_ACCESS
       
  1385                     
       
  1386                     VVHW_TRACE("eglCreatePbufferFromClientBuffer" );
       
  1387                     break;
       
  1388                     }
       
  1389                 case EglRFC::EeglGetError:
       
  1390                     {
       
  1391                     VVHW_TRACE("eglGetError" );
       
  1392                     break;
       
  1393                     }
       
  1394                 default:
       
  1395                     {
       
  1396                     break;
       
  1397                     }
       
  1398                 }//switch opcode (EGL)
       
  1399                 
       
  1400             break;
       
  1401             }
       
  1402         case SERIALISED_OPENGLES_1_1_API_UID:
       
  1403             {
       
  1404             VVHW_TRACE("OpenGLES request" );
       
  1405             switch( opcode )
       
  1406                 {
       
  1407                 case OpenGlES11RFC::EglGetError:
       
  1408                     {
       
  1409                     //Get the GLES error
       
  1410                     }
       
  1411                 default:
       
  1412                     {
       
  1413                     break;
       
  1414                     }
       
  1415                 }
       
  1416             break;
       
  1417             }
       
  1418         default:
       
  1419             {
       
  1420             break;
       
  1421             }
       
  1422         }//switch apicode
       
  1423     //VVHW_TRACE( "DDeviceReqHandler::InterpretRequest: opcode : %d ", data->iCurrOpCode );
       
  1424     if( iCurrClientData )//This could have been removed, in a call to RemoveClientData
       
  1425         {
       
  1426         iCurrClientData->iErrUpdatedVG = ErrUpdatedVG;
       
  1427         iCurrClientData->iErrUpdatedEGL = ErrUpdatedEGL;
       
  1428         iCurrClientData->iErrUpdatedGLES = ErrUpdatedGLES;
       
  1429         }
       
  1430     return alreadyProcessed;
       
  1431     }
       
  1432 
       
  1433 #ifdef FAISALMEMON_S4_SGIMAGE
       
  1434 HBuf8* DDeviceReqHandler::OpenSgImageMetaData( const TUint64 aId, DSgResource*& aResource )
       
  1435     {
       
  1436     VVHW_TRACE("DDeviceReqHandler::OpenSgImageMetaData 0x%lx", aId );
       
  1437     aResource = 0;
       
  1438     HBuf8* data(0);
       
  1439     TInt sgOpenErr( KErrNone );
       
  1440     
       
  1441     sgOpenErr = SgExtension::FindAndOpenResource( aId, aResource );//Open the sgimage resource
       
  1442     VVHW_TRACE(" sgOpenErr %d", sgOpenErr);
       
  1443     if( sgOpenErr == KErrNone )
       
  1444         {
       
  1445         data = HBuf8::New( aResource->GetMetaDataSize() );
       
  1446         if( data )
       
  1447             {
       
  1448             aResource->GetMetaData( (*data) );
       
  1449             }
       
  1450         }
       
  1451     return data;//If there was a problem, this is zero. Ownership belongs to caller
       
  1452     }
       
  1453 #endif