diff -r d8d95053303a -r e8ccf068ac7f guestrendering/guestvideodriver/api/src/guestvideodriver.cpp --- a/guestrendering/guestvideodriver/api/src/guestvideodriver.cpp Fri Aug 20 18:02:40 2010 +0100 +++ b/guestrendering/guestvideodriver/api/src/guestvideodriver.cpp Wed Aug 25 17:57:53 2010 +0100 @@ -1,254 +1,254 @@ -// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -// All rights reserved. -// This component and the accompanying materials are made available -// under the terms of "Eclipse Public License v1.0" -// which accompanies this distribution, and is available -// at the URL "http://www.eclipse.org/legal/epl-v10.html". -// -// Initial Contributors: -// Nokia Corporation - initial contribution. -// -// Contributors: -// -// Description: -// Guest Video Driver Implementation - -#include -#include -#include -#include - -#include -#include -#include - -#include "remotefunctioncall.h" -#include "serializedfunctioncall.h" - -// tracing -#ifdef _DEBUG -#include - #define UTIL_TRACE(fmt, args...) RDebug::Printf(fmt, ##args) - #define DRVRPANIC_ASSERT(condition, panic) if (!(condition)) { DriverPanic(panic, #condition, __LINE__); } - #define DRVRPANIC_ASSERT_DEBUG(condition, panic) if (!(condition)) { DriverPanic(panic, #condition, __LINE__); } -#else - #define UTIL_TRACE(fmt, args...) - #define DRVRPANIC_ASSERT(condition, panic) if (!(condition)) { DriverPanic(panic, NULL, __LINE__); } - #define DRVRPANIC_ASSERT_DEBUG(condition, panic) -#endif - -//Max supported request size -const TUint32 KMaxRequestSize( VVI_PARAMETERS_INPUT_MEMORY_SIZE ); - -typedef enum - { - EDriverPanicSendBufferFailed=1, - EDriverPanicInvalidOperationType, - EDriverPanicOperationDataTooBig, - EDriverPanicDriverAlreadyOpen, - EDriverPanicCreateDriverChannelFailed, - EDriverPanicCreateThreadLockFailed, - EDriverPanicSendBufferFnDoesNotHaveThreadLock, - EDriverPanicBufferCommandFnDoesNotHaveThreadLock, - EDriverPanicDriverNotOpenForExecuteCommandFn, - EDriverPanicRequestStatusErrorInExecuteCommandFn, // 10 - EDriverPanicBufferWriteFailed, - } TDriverPanic; - -_LIT(KDriverPanicCategory, "Guest VidDrv"); - -void DriverPanic(TDriverPanic aPanicCode, char* aCondition, TInt aLine) - { - UTIL_TRACE("Guest Video Driver Panic %d for failed Assert (%s), at guestvideodriver.cpp:%d", aPanicCode, aCondition, aLine); - - User::Panic(KDriverPanicCategory, aPanicCode); - } - - -// ============================ MEMBER FUNCTIONS =============================== - -// ----------------------------------------------------------------------------- -// RGuestVideoDriver::RGuestVideoDriver -// ----------------------------------------------------------------------------- -// -EXPORT_C RGuestVideoDriver::RGuestVideoDriver() : iIsOpen(EFalse), iProcessId(0) - { - } - -// ----------------------------------------------------------------------------- -// RGuestVideoDriver::Open -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt RGuestVideoDriver::Open() - { - UTIL_TRACE("RGuestVideoDriver::Open start iProcessId=0x%x, iIsOpen=%d", iProcessId, iIsOpen); - DRVRPANIC_ASSERT(iIsOpen == EFalse, EDriverPanicDriverAlreadyOpen); - iProcessId = RProcess().Id(); - TInt error = iThreadLock.CreateLocal(EOwnerProcess); - DRVRPANIC_ASSERT_DEBUG( error == KErrNone, EDriverPanicCreateThreadLockFailed); - if (!error) - { - error = DoCreate( - GuestVideoDriver::KDeviceName, - TVersion( GuestVideoDriver::KMajorVer, - GuestVideoDriver::KMinorVer, - GuestVideoDriver::KBuildVer ), - KNullUnit, - NULL, - NULL); - DRVRPANIC_ASSERT_DEBUG( error == KErrNone, EDriverPanicCreateDriverChannelFailed); - if (!error) - { - iIsOpen = ETrue; - } - } - UTIL_TRACE("RGuestVideoDriver::Open end iProcessId=0x%x, error=%d", iProcessId, error); - return error; - } - -// ----------------------------------------------------------------------------- -// RGuestVideoDriver::~RGuestVideoDriver -// ----------------------------------------------------------------------------- -// -EXPORT_C RGuestVideoDriver::~RGuestVideoDriver() - { - UTIL_TRACE("RGuestVideoDriver::~RGuestVideoDriver iProcessId=0x%x", iProcessId); - iThreadLock.Close(); - } - -// ----------------------------------------------------------------------------- -// RGuestVideoDriver::ExecuteCommand -// Syncrhonous version with local buffering -// ----------------------------------------------------------------------------- -// -EXPORT_C void RGuestVideoDriver::ExecuteCommand(RemoteFunctionCallData& aRequestData) - { - DRVRPANIC_ASSERT(iIsOpen, EDriverPanicDriverNotOpenForExecuteCommandFn); - DRVRPANIC_ASSERT( (RemoteFunctionCallData::EOpRequestWithReply == aRequestData.Header().iOpType) || - (RemoteFunctionCallData::EOpRequest == aRequestData.Header().iOpType), - EDriverPanicInvalidOperationType); - - //Set thread and process id - aRequestData.SetThreadInformation(iProcessId, RThread().Id()); - TBool sendNow = (RemoteFunctionCallData::EOpRequest != aRequestData.Header().iOpType); - if (!sendNow) - { - iThreadLock.Wait(); - while (!BufferCommand(aRequestData)) - { - // Flush any queued commands & retry - if (iBuffer.Length()) - { - SendBuffer(); - } - else - { // Too big for buffer - sendNow = ETrue; - break; - } - } - iThreadLock.Signal(); - } - - if (sendNow) - { - // Maintain order of operations by flushing queue - iThreadLock.Wait(); - if (iBuffer.Length()) - { - SendBuffer(); - } - iThreadLock.Signal(); - - TRequestStatus status; - TPckg data(aRequestData); - DRVRPANIC_ASSERT(data().SerialisedLength() <= KMaxRequestSize, EDriverPanicOperationDataTooBig); - UTIL_TRACE("RGuestVideoDriver::ExecuteCommand direct send, req length=%d", data().SerialisedLength()); - DoRequest(GuestVideoDriver::ERequestExecuteCommand, status, (TAny*)&data); - User::WaitForRequest(status); - // status <> 0 if write of reply data failed - DRVRPANIC_ASSERT_DEBUG(status.Int() == KErrNone, EDriverPanicRequestStatusErrorInExecuteCommandFn); - } - } - -// Flush video Command buffer -EXPORT_C void RGuestVideoDriver::Flush() - { - iThreadLock.Wait(); - if (iIsOpen && iBuffer.Length()) - { - SendBuffer(); - } - iThreadLock.Signal(); - } - - -// ----------------------------------------------------------------------------- -// RGuestVideoDriver::BufferCommand -// ----------------------------------------------------------------------------- -// -TBool RGuestVideoDriver::BufferCommand( RemoteFunctionCallData& aRequestData ) - { - DRVRPANIC_ASSERT_DEBUG(iThreadLock.IsHeld(), EDriverPanicBufferCommandFnDoesNotHaveThreadLock); - TBool result = EFalse; - SerializedFunctionCall data( aRequestData ); - - const TUint32 len = aRequestData.SerialisedLength(); - const TInt alignmentAdjIndex( RemoteFunctionCallData::AlignIndex( iBuffer.Length(), 4 ) ); - - if ( (alignmentAdjIndex + len) < iBuffer.MaxLength() ) - { - //There is enough space left on local buffer - iBuffer.SetLength( alignmentAdjIndex + len ); - TPtrC8 serialisedDataPtr = iBuffer.Right( len ); - TInt wlen = data.WriteToBuffer( const_cast(serialisedDataPtr.Ptr()), len, 0 ); - DRVRPANIC_ASSERT(wlen == len, EDriverPanicBufferWriteFailed); - result = ETrue; - } - - UTIL_TRACE("RGuestVideoDriver::BufferCommand length=%d, Req len=%d, result=%d", - iBuffer.Length(), len, result); - return result; - } - -// ----------------------------------------------------------------------------- -// RGuestVideoDriver::MapToHWAddress -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt RGuestVideoDriver::MapToHWAddress( const TInt aChunkHandle, TUint32& aHWAddress ) - { - TPckgBuf handle( aChunkHandle ); - TPckg address( aHWAddress ); - return DoControl( GuestVideoDriver::ERequestMapAddress, (TAny*)&handle, (TAny*)&address ); - } - -// ----------------------------------------------------------------------------- -// RGuestVideoDriver::EglGetSgHandles -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt RGuestVideoDriver::EglGetSgHandles( const TUint64 aId, TUint64 *aSgHandles ) - { - TPckg sgId( aId ); - TPckg sgHandles( *aSgHandles ); - return DoControl( GuestVideoDriver::ERequestSgHandles, (TAny*)&sgId, (TAny*)&sgHandles ); - } - -// ----------------------------------------------------------------------------- -// RGuestVideoDriver::SendBuffer -// ----------------------------------------------------------------------------- -// -void RGuestVideoDriver::SendBuffer() - { - UTIL_TRACE("RGuestVideoDriver::SendBuffer length=%d", iBuffer.Length()); - DRVRPANIC_ASSERT_DEBUG(iThreadLock.IsHeld(), EDriverPanicSendBufferFnDoesNotHaveThreadLock); - TRequestStatus status; - - DoRequest(GuestVideoDriver::ERequestLoadCommands, status, (TAny*)&iBuffer); - - User::WaitForRequest( status ); - - iBuffer.Zero(); - UTIL_TRACE("RGuestVideoDriver::SendBuffer status=%d", status.Int()); - // Commands expecting a reply should never come through here, so status should always be KErrNone - DRVRPANIC_ASSERT(status.Int() == KErrNone, EDriverPanicSendBufferFailed); - } +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Guest Video Driver Implementation + +#include +#include +#include +#include + +#include +#include +#include + +#include "remotefunctioncall.h" +#include "serializedfunctioncall.h" + +// tracing +#ifdef _DEBUG +#include + #define UTIL_TRACE(fmt, args...) RDebug::Printf(fmt, ##args) + #define DRVRPANIC_ASSERT(condition, panic) if (!(condition)) { DriverPanic(panic, #condition, __LINE__); } + #define DRVRPANIC_ASSERT_DEBUG(condition, panic) if (!(condition)) { DriverPanic(panic, #condition, __LINE__); } +#else + #define UTIL_TRACE(fmt, args...) + #define DRVRPANIC_ASSERT(condition, panic) if (!(condition)) { DriverPanic(panic, NULL, __LINE__); } + #define DRVRPANIC_ASSERT_DEBUG(condition, panic) +#endif + +//Max supported request size +const TUint32 KMaxRequestSize( VVI_PARAMETERS_INPUT_MEMORY_SIZE ); + +typedef enum + { + EDriverPanicSendBufferFailed=1, + EDriverPanicInvalidOperationType, + EDriverPanicOperationDataTooBig, + EDriverPanicDriverAlreadyOpen, + EDriverPanicCreateDriverChannelFailed, + EDriverPanicCreateThreadLockFailed, + EDriverPanicSendBufferFnDoesNotHaveThreadLock, + EDriverPanicBufferCommandFnDoesNotHaveThreadLock, + EDriverPanicDriverNotOpenForExecuteCommandFn, + EDriverPanicRequestStatusErrorInExecuteCommandFn, // 10 + EDriverPanicBufferWriteFailed, + } TDriverPanic; + +_LIT(KDriverPanicCategory, "Guest VidDrv"); + +void DriverPanic(TDriverPanic aPanicCode, char* aCondition, TInt aLine) + { + UTIL_TRACE("Guest Video Driver Panic %d for failed Assert (%s), at guestvideodriver.cpp:%d", aPanicCode, aCondition, aLine); + + User::Panic(KDriverPanicCategory, aPanicCode); + } + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// RGuestVideoDriver::RGuestVideoDriver +// ----------------------------------------------------------------------------- +// +EXPORT_C RGuestVideoDriver::RGuestVideoDriver() : iIsOpen(EFalse), iProcessId(0) + { + } + +// ----------------------------------------------------------------------------- +// RGuestVideoDriver::Open +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RGuestVideoDriver::Open() + { + UTIL_TRACE("RGuestVideoDriver::Open start iProcessId=0x%x, iIsOpen=%d", iProcessId, iIsOpen); + DRVRPANIC_ASSERT(iIsOpen == EFalse, EDriverPanicDriverAlreadyOpen); + iProcessId = RProcess().Id(); + TInt error = iThreadLock.CreateLocal(EOwnerProcess); + DRVRPANIC_ASSERT_DEBUG( error == KErrNone, EDriverPanicCreateThreadLockFailed); + if (!error) + { + error = DoCreate( + GuestVideoDriver::KDeviceName, + TVersion( GuestVideoDriver::KMajorVer, + GuestVideoDriver::KMinorVer, + GuestVideoDriver::KBuildVer ), + KNullUnit, + NULL, + NULL); + DRVRPANIC_ASSERT_DEBUG( error == KErrNone, EDriverPanicCreateDriverChannelFailed); + if (!error) + { + iIsOpen = ETrue; + } + } + UTIL_TRACE("RGuestVideoDriver::Open end iProcessId=0x%x, error=%d", iProcessId, error); + return error; + } + +// ----------------------------------------------------------------------------- +// RGuestVideoDriver::~RGuestVideoDriver +// ----------------------------------------------------------------------------- +// +EXPORT_C RGuestVideoDriver::~RGuestVideoDriver() + { + UTIL_TRACE("RGuestVideoDriver::~RGuestVideoDriver iProcessId=0x%x", iProcessId); + iThreadLock.Close(); + } + +// ----------------------------------------------------------------------------- +// RGuestVideoDriver::ExecuteCommand +// Syncrhonous version with local buffering +// ----------------------------------------------------------------------------- +// +EXPORT_C void RGuestVideoDriver::ExecuteCommand(RemoteFunctionCallData& aRequestData) + { + DRVRPANIC_ASSERT(iIsOpen, EDriverPanicDriverNotOpenForExecuteCommandFn); + DRVRPANIC_ASSERT( (RemoteFunctionCallData::EOpRequestWithReply == aRequestData.Header().iOpType) || + (RemoteFunctionCallData::EOpRequest == aRequestData.Header().iOpType), + EDriverPanicInvalidOperationType); + + //Set thread and process id + aRequestData.SetThreadInformation(iProcessId, RThread().Id()); + TBool sendNow = (RemoteFunctionCallData::EOpRequest != aRequestData.Header().iOpType); + if (!sendNow) + { + iThreadLock.Wait(); + while (!BufferCommand(aRequestData)) + { + // Flush any queued commands & retry + if (iBuffer.Length()) + { + SendBuffer(); + } + else + { // Too big for buffer + sendNow = ETrue; + break; + } + } + iThreadLock.Signal(); + } + + if (sendNow) + { + // Maintain order of operations by flushing queue + iThreadLock.Wait(); + if (iBuffer.Length()) + { + SendBuffer(); + } + iThreadLock.Signal(); + + TRequestStatus status; + TPckg data(aRequestData); + DRVRPANIC_ASSERT(data().SerialisedLength() <= KMaxRequestSize, EDriverPanicOperationDataTooBig); + UTIL_TRACE("RGuestVideoDriver::ExecuteCommand direct send, req length=%d", data().SerialisedLength()); + DoRequest(GuestVideoDriver::ERequestExecuteCommand, status, (TAny*)&data); + User::WaitForRequest(status); + // status <> 0 if write of reply data failed + DRVRPANIC_ASSERT_DEBUG(status.Int() == KErrNone, EDriverPanicRequestStatusErrorInExecuteCommandFn); + } + } + +// Flush video Command buffer +EXPORT_C void RGuestVideoDriver::Flush() + { + iThreadLock.Wait(); + if (iIsOpen && iBuffer.Length()) + { + SendBuffer(); + } + iThreadLock.Signal(); + } + + +// ----------------------------------------------------------------------------- +// RGuestVideoDriver::BufferCommand +// ----------------------------------------------------------------------------- +// +TBool RGuestVideoDriver::BufferCommand( RemoteFunctionCallData& aRequestData ) + { + DRVRPANIC_ASSERT_DEBUG(iThreadLock.IsHeld(), EDriverPanicBufferCommandFnDoesNotHaveThreadLock); + TBool result = EFalse; + SerializedFunctionCall data( aRequestData ); + + const TUint32 len = aRequestData.SerialisedLength(); + const TInt alignmentAdjIndex( RemoteFunctionCallData::AlignIndex( iBuffer.Length(), 4 ) ); + + if ( (alignmentAdjIndex + len) < iBuffer.MaxLength() ) + { + //There is enough space left on local buffer + iBuffer.SetLength( alignmentAdjIndex + len ); + TPtrC8 serialisedDataPtr = iBuffer.Right( len ); + TInt wlen = data.WriteToBuffer( const_cast(serialisedDataPtr.Ptr()), len, 0 ); + DRVRPANIC_ASSERT(wlen == len, EDriverPanicBufferWriteFailed); + result = ETrue; + } + + UTIL_TRACE("RGuestVideoDriver::BufferCommand length=%d, Req len=%d, result=%d", + iBuffer.Length(), len, result); + return result; + } + +// ----------------------------------------------------------------------------- +// RGuestVideoDriver::MapToHWAddress +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RGuestVideoDriver::MapToHWAddress( const TInt aChunkHandle, TUint32& aHWAddress ) + { + TPckgBuf handle( aChunkHandle ); + TPckg address( aHWAddress ); + return DoControl( GuestVideoDriver::ERequestMapAddress, (TAny*)&handle, (TAny*)&address ); + } + +// ----------------------------------------------------------------------------- +// RGuestVideoDriver::EglGetSgHandles +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RGuestVideoDriver::EglGetSgHandles( const TUint64 aId, TUint64 *aSgHandles ) + { + TPckg sgId( aId ); + TPckg sgHandles( *aSgHandles ); + return DoControl( GuestVideoDriver::ERequestSgHandles, (TAny*)&sgId, (TAny*)&sgHandles ); + } + +// ----------------------------------------------------------------------------- +// RGuestVideoDriver::SendBuffer +// ----------------------------------------------------------------------------- +// +void RGuestVideoDriver::SendBuffer() + { + UTIL_TRACE("RGuestVideoDriver::SendBuffer length=%d", iBuffer.Length()); + DRVRPANIC_ASSERT_DEBUG(iThreadLock.IsHeld(), EDriverPanicSendBufferFnDoesNotHaveThreadLock); + TRequestStatus status; + + DoRequest(GuestVideoDriver::ERequestLoadCommands, status, (TAny*)&iBuffer); + + User::WaitForRequest( status ); + + iBuffer.Zero(); + UTIL_TRACE("RGuestVideoDriver::SendBuffer status=%d", status.Int()); + // Commands expecting a reply should never come through here, so status should always be KErrNone + DRVRPANIC_ASSERT(status.Int() == KErrNone, EDriverPanicSendBufferFailed); + }