vghwinterface/vghwdriver/api/src/guestvideodriver.cpp
branchbug235_bringup_0
changeset 51 4f400a6ea71f
parent 32 b23067389fdf
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 // Guest Video Driver Implementation
       
    15 
       
    16 #include <e32cmn.h>
       
    17 #include <e32des8.h> 
       
    18 #include <e32std.h> 
       
    19 #include <e32debug.h> 
       
    20 
       
    21 #include <graphics/guestvideodriver.h>
       
    22 #include <graphics/guestvideodriverprotocol.h>
       
    23 #include <graphics/guestvideodriverinterfaceconstants.h>
       
    24 
       
    25 #include "remotefunctioncall.h"
       
    26 #include "serializedfunctioncall.h"
       
    27 
       
    28 // tracing
       
    29 #ifdef _DEBUG
       
    30 #include <e32debug.h>
       
    31     #define UTIL_TRACE(fmt, args...) RDebug::Printf(fmt, ##args)
       
    32 	#define DRVRPANIC_ASSERT(condition, panic) if (!(condition)) { DriverPanic(panic, #condition, __LINE__); }
       
    33 	#define DRVRPANIC_ASSERT_DEBUG(condition, panic) if (!(condition)) { DriverPanic(panic, #condition, __LINE__); }
       
    34 #else
       
    35     #define UTIL_TRACE(fmt, args...)
       
    36 	#define DRVRPANIC_ASSERT(condition, panic) if (!(condition)) { DriverPanic(panic, NULL, __LINE__); }
       
    37 	#define DRVRPANIC_ASSERT_DEBUG(condition, panic)
       
    38 #endif
       
    39 
       
    40 //Max supported request size
       
    41 const TUint32 KMaxRequestSize( VVI_PARAMETERS_INPUT_MEMORY_SIZE );
       
    42 
       
    43 typedef enum
       
    44 	{
       
    45 	EDriverPanicSendBufferFailed=1,
       
    46 	EDriverPanicInvalidOperationType,
       
    47 	EDriverPanicOperationDataTooBig,
       
    48 	EDriverPanicDriverAlreadyOpen,
       
    49 	EDriverPanicCreateDriverChannelFailed,
       
    50 	EDriverPanicCreateThreadLockFailed,
       
    51 	EDriverPanicSendBufferFnDoesNotHaveThreadLock,
       
    52 	EDriverPanicBufferCommandFnDoesNotHaveThreadLock,
       
    53 	EDriverPanicDriverNotOpenForExecuteCommandFn,
       
    54 	EDriverPanicRequestStatusErrorInExecuteCommandFn, // 10
       
    55 	EDriverPanicBufferWriteFailed,
       
    56 	} TDriverPanic;
       
    57 
       
    58 _LIT(KDriverPanicCategory, "Guest VidDrv");
       
    59 
       
    60 void DriverPanic(TDriverPanic aPanicCode, char* aCondition, TInt aLine)
       
    61 	{
       
    62 	UTIL_TRACE("Guest Video Driver Panic %d for failed Assert (%s), at guestvideodriver.cpp:%d", aPanicCode, aCondition, aLine);
       
    63 		
       
    64 	User::Panic(KDriverPanicCategory, aPanicCode);
       
    65 	}
       
    66 
       
    67 
       
    68 // ============================ MEMBER FUNCTIONS ===============================
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // RGuestVideoDriver::RGuestVideoDriver
       
    72 // -----------------------------------------------------------------------------
       
    73 //
       
    74 EXPORT_C RGuestVideoDriver::RGuestVideoDriver() : iIsOpen(EFalse), iProcessId(0)
       
    75     {
       
    76     }
       
    77 
       
    78 // -----------------------------------------------------------------------------
       
    79 // RGuestVideoDriver::Open
       
    80 // -----------------------------------------------------------------------------
       
    81 //
       
    82 EXPORT_C TInt RGuestVideoDriver::Open()
       
    83     {
       
    84 	UTIL_TRACE("RGuestVideoDriver::Open start iProcessId=0x%x, iIsOpen=%d", iProcessId, iIsOpen);
       
    85 	DRVRPANIC_ASSERT(iIsOpen == EFalse, EDriverPanicDriverAlreadyOpen);
       
    86 	iProcessId = RProcess().Id();
       
    87 	TInt error = iThreadLock.CreateLocal(EOwnerProcess);
       
    88 	DRVRPANIC_ASSERT_DEBUG( error == KErrNone, EDriverPanicCreateThreadLockFailed);
       
    89 	if (!error)
       
    90 		{
       
    91 		error = DoCreate(
       
    92 			GuestVideoDriver::KDeviceName,
       
    93 			TVersion( GuestVideoDriver::KMajorVer,
       
    94 					  GuestVideoDriver::KMinorVer,
       
    95 					  GuestVideoDriver::KBuildVer ),
       
    96 			KNullUnit,
       
    97 			NULL,
       
    98 			NULL);
       
    99 		DRVRPANIC_ASSERT_DEBUG( error == KErrNone, EDriverPanicCreateDriverChannelFailed);
       
   100 		if (!error)
       
   101 			{
       
   102 			iIsOpen = ETrue;
       
   103 			}
       
   104 		}
       
   105 	UTIL_TRACE("RGuestVideoDriver::Open end iProcessId=0x%x, error=%d", iProcessId, error);
       
   106 	return error;
       
   107 	}
       
   108 
       
   109 // -----------------------------------------------------------------------------
       
   110 // RGuestVideoDriver::~RGuestVideoDriver
       
   111 // -----------------------------------------------------------------------------
       
   112 //
       
   113 EXPORT_C RGuestVideoDriver::~RGuestVideoDriver()
       
   114     {
       
   115 	UTIL_TRACE("RGuestVideoDriver::~RGuestVideoDriver iProcessId=0x%x", iProcessId);
       
   116 	iThreadLock.Close();
       
   117     }
       
   118 
       
   119 // -----------------------------------------------------------------------------
       
   120 // RGuestVideoDriver::ExecuteCommand
       
   121 // Syncrhonous version with local buffering
       
   122 // -----------------------------------------------------------------------------
       
   123 //
       
   124 EXPORT_C void RGuestVideoDriver::ExecuteCommand(RemoteFunctionCallData& aRequestData)
       
   125 	{
       
   126 	DRVRPANIC_ASSERT(iIsOpen, EDriverPanicDriverNotOpenForExecuteCommandFn);
       
   127 	DRVRPANIC_ASSERT( (RemoteFunctionCallData::EOpRequestWithReply == aRequestData.Header().iOpType) ||
       
   128 			(RemoteFunctionCallData::EOpRequest == aRequestData.Header().iOpType),
       
   129 			EDriverPanicInvalidOperationType);
       
   130 
       
   131 	//Set thread and process id
       
   132 	aRequestData.SetThreadInformation(iProcessId, RThread().Id());
       
   133 	TBool sendNow = (RemoteFunctionCallData::EOpRequest != aRequestData.Header().iOpType); 
       
   134 	if (!sendNow)
       
   135 		{
       
   136 		iThreadLock.Wait();
       
   137 		while (!BufferCommand(aRequestData))
       
   138 			{
       
   139 			// Flush any queued commands & retry
       
   140 			if (iBuffer.Length())
       
   141 				{
       
   142 				SendBuffer();
       
   143 				}
       
   144 			else
       
   145 				{ // Too big for buffer
       
   146 				sendNow = ETrue;
       
   147 				break;
       
   148 				}
       
   149 			}
       
   150 		iThreadLock.Signal();
       
   151 		}
       
   152 
       
   153 	if (sendNow)
       
   154 		{
       
   155 		// Maintain order of operations by flushing queue
       
   156 		iThreadLock.Wait();
       
   157 		if (iBuffer.Length())
       
   158 			{
       
   159 			SendBuffer();
       
   160 			}
       
   161 		iThreadLock.Signal();
       
   162 
       
   163 		TRequestStatus status;
       
   164 		TPckg<RemoteFunctionCallData> data(aRequestData);
       
   165 		DRVRPANIC_ASSERT(data().SerialisedLength() <= KMaxRequestSize, EDriverPanicOperationDataTooBig);
       
   166 		UTIL_TRACE("RGuestVideoDriver::ExecuteCommand direct send, req length=%d", data().SerialisedLength());
       
   167 		DoRequest(GuestVideoDriver::ERequestExecuteCommand, status, (TAny*)&data);
       
   168 		User::WaitForRequest(status);
       
   169 		// status <> 0 if write of reply data failed
       
   170 		DRVRPANIC_ASSERT_DEBUG(status.Int() == KErrNone, EDriverPanicRequestStatusErrorInExecuteCommandFn);
       
   171 		}
       
   172 	}
       
   173 
       
   174 // Flush video Command buffer
       
   175 EXPORT_C void RGuestVideoDriver::Flush()
       
   176 	{
       
   177 	iThreadLock.Wait();
       
   178 	if (iIsOpen && iBuffer.Length())
       
   179 		{
       
   180 		SendBuffer();
       
   181 		}
       
   182 	iThreadLock.Signal();
       
   183 	}
       
   184 
       
   185 
       
   186 // -----------------------------------------------------------------------------
       
   187 // RGuestVideoDriver::BufferCommand
       
   188 // -----------------------------------------------------------------------------
       
   189 //
       
   190 TBool RGuestVideoDriver::BufferCommand( RemoteFunctionCallData& aRequestData )
       
   191 	{
       
   192 	DRVRPANIC_ASSERT_DEBUG(iThreadLock.IsHeld(), EDriverPanicBufferCommandFnDoesNotHaveThreadLock);
       
   193 	TBool result = EFalse;
       
   194 	SerializedFunctionCall data( aRequestData );
       
   195 
       
   196 	const TUint32 len = aRequestData.SerialisedLength();
       
   197 	const TInt alignmentAdjIndex( RemoteFunctionCallData::AlignIndex( iBuffer.Length(), 4 ) );
       
   198 
       
   199 	if ( (alignmentAdjIndex + len) < iBuffer.MaxLength() )
       
   200 		{
       
   201 		//There is enough space left on local buffer
       
   202 		iBuffer.SetLength( alignmentAdjIndex + len );
       
   203 		TPtrC8 serialisedDataPtr = iBuffer.Right( len );
       
   204 		TInt wlen = data.WriteToBuffer( const_cast<TUint8*>(serialisedDataPtr.Ptr()), len, 0 );
       
   205 		DRVRPANIC_ASSERT(wlen == len, EDriverPanicBufferWriteFailed);
       
   206 		result = ETrue;
       
   207 		}
       
   208 
       
   209 	UTIL_TRACE("RGuestVideoDriver::BufferCommand length=%d, Req len=%d, result=%d",
       
   210 			iBuffer.Length(), len, result);
       
   211 	return result;
       
   212 	}
       
   213 
       
   214 // -----------------------------------------------------------------------------
       
   215 // RGuestVideoDriver::MapToHWAddress
       
   216 // -----------------------------------------------------------------------------
       
   217 //
       
   218 EXPORT_C TInt RGuestVideoDriver::MapToHWAddress( const TInt aChunkHandle, TUint32& aHWAddress )
       
   219     {
       
   220     TPckgBuf<TInt> handle( aChunkHandle );
       
   221     TPckg<TUint32> address( aHWAddress );
       
   222     return DoControl( GuestVideoDriver::ERequestMapAddress, (TAny*)&handle, (TAny*)&address );
       
   223     }
       
   224 
       
   225 // -----------------------------------------------------------------------------
       
   226 // RGuestVideDriver::GetSurfaceBufferBaseAddress
       
   227 // -----------------------------------------------------------------------------
       
   228 //
       
   229 EXPORT_C TInt RGuestVideoDriver::GetSurfaceBufferBaseAddress( TUint32& aSurfaceBufferBaseAddress )
       
   230     {
       
   231     TPckg<TUint32> address( aSurfaceBufferBaseAddress );
       
   232     return DoControl( GuestVideoDriver::ERequestSurfaceBufferBaseAddress, (TAny*)&address );
       
   233     }
       
   234 
       
   235 // -----------------------------------------------------------------------------
       
   236 // RGuestVideoDriver::EglGetSgHandles
       
   237 // -----------------------------------------------------------------------------
       
   238 //
       
   239 EXPORT_C TInt RGuestVideoDriver::EglGetSgHandles( const TUint64 aId, TUint64 *aSgHandles )
       
   240     {
       
   241     TPckg<TUint64> sgId( aId );
       
   242     TPckg<TUint64> sgHandles( *aSgHandles );
       
   243     return DoControl( GuestVideoDriver::ERequestSgHandles, (TAny*)&sgId, (TAny*)&sgHandles );
       
   244     }
       
   245 
       
   246 // -----------------------------------------------------------------------------
       
   247 // RGuestVideoDriver::SendBuffer
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 void RGuestVideoDriver::SendBuffer()
       
   251     {
       
   252 	UTIL_TRACE("RGuestVideoDriver::SendBuffer length=%d", iBuffer.Length());
       
   253 	DRVRPANIC_ASSERT_DEBUG(iThreadLock.IsHeld(), EDriverPanicSendBufferFnDoesNotHaveThreadLock);
       
   254     TRequestStatus status;
       
   255 
       
   256     DoRequest(GuestVideoDriver::ERequestLoadCommands, status, (TAny*)&iBuffer);
       
   257 
       
   258     User::WaitForRequest( status );
       
   259 
       
   260     iBuffer.Zero();
       
   261 	UTIL_TRACE("RGuestVideoDriver::SendBuffer status=%d", status.Int());
       
   262 	// Commands expecting a reply should never come through here, so status should always be KErrNone
       
   263 	DRVRPANIC_ASSERT(status.Int() == KErrNone, EDriverPanicSendBufferFailed);
       
   264     }