--- a/guestrendering/guestopenvg/src/vgstate.cpp Thu Sep 16 12:43:44 2010 +0100
+++ b/guestrendering/guestopenvg/src/vgstate.cpp Mon Sep 20 14:29:05 2010 +0100
@@ -1,788 +1,788 @@
-// 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:
-// Client-side state information for Symbian DLL
-
-#include "vgstate.h"
-#include "remotefunctioncall.h"
-#include "openvgrfc.h"
-
-
-
-// VG Client-side state is Writeable Static Data in the DLL, (holds state information for the process)
-// Constructor/Destructor called on process load/unload to perform initialiser/release of static resources
-XOpenVgState OpenVgState;
-
-
-
-_LIT(KVgPanicCategory, "Guest VG");
-
-void VgPanic(TVgPanic aPanicCode, char* aPanicName, char* aCondition, char* aFile, TInt aLine)
- {
- if (aPanicName && aCondition && aFile)
- { // normal for Debug builds
- RDebug::Printf("Guest Open VG DLL Panic %s for failed Assert (%s),\n\tat %s:%d", aPanicName, aCondition, aFile, aLine);
- }
- else if (aPanicName && aFile)
- { // Debug builds Assert Always
- RDebug::Printf("Guest Open VG DLL Panic %s at %s:%d", aPanicName, aFile, aLine);
- }
- else
- { // normal for Release builds
- RDebug::Printf("Guest Open VG DLL Panic %d (line %d)", aPanicCode, aLine);
- }
-
- User::Panic(KVgPanicCategory, aPanicCode);
- }
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-// TCheck - parameter checking utility functions
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-
-/*
- aWidth & aHeight parameters must be >0, also ax, ay, aX + aWidth and aY + aHeight must all
- be within image size, otherwise a VG_ILLEGAL_ARGUMENT_ERROR is flagged.
- */
-TBool TCheck::ChkAreaIsWithinImage(MVgContext& aVgContext, CVgImageBase* aImageInfo, VGint aX, VGint aY, VGint aWidth, VGint aHeight)
- {
- VGPANIC_ASSERT_DEBUG(aImageInfo, EVgPanicTemp);
- if ( (aX >= 0) && (aY >= 0) && (aWidth > 0) && (aHeight > 0) )
- {
- VGint maxX = aWidth + aX;
- VGint maxY = aHeight + aY;
- if ( (maxX > 0) && (maxY > 0) && (aImageInfo->Width() >= maxX) && (aImageInfo->Height() >= maxY) )
- {
- return ETrue;
- }
- }
- OPENVG_TRACE("TCheck::ChkAreaIsWithinImage setting VG_ILLEGAL_ARGUMENT_ERROR");
- aVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR);
- return EFalse;
- }
-
-
-VGint TCheck::ImageFormatByteDepth(VGImageFormat aImageFormat)
- {
- switch (aImageFormat)
- {
- case VG_sRGBX_8888:
- case VG_sRGBA_8888:
- case VG_sRGBA_8888_PRE:
- case VG_lRGBX_8888:
- case VG_lRGBA_8888:
- case VG_lRGBA_8888_PRE:
- case VG_sXRGB_8888:
- case VG_sARGB_8888:
- case VG_sARGB_8888_PRE:
- case VG_lXRGB_8888:
- case VG_lARGB_8888:
- case VG_lARGB_8888_PRE:
- case VG_sBGRX_8888:
- case VG_sBGRA_8888:
- case VG_sBGRA_8888_PRE:
- case VG_lBGRX_8888:
- case VG_lBGRA_8888:
- case VG_lBGRA_8888_PRE:
- case VG_sXBGR_8888:
- case VG_sABGR_8888:
- case VG_sABGR_8888_PRE:
- case VG_lXBGR_8888:
- case VG_lABGR_8888:
- case VG_lABGR_8888_PRE:
- return 4;
- case VG_sRGB_565:
- case VG_sRGBA_5551:
- case VG_sRGBA_4444:
- case VG_sARGB_1555:
- case VG_sARGB_4444:
- case VG_sBGR_565:
- case VG_sBGRA_5551:
- case VG_sBGRA_4444:
- case VG_sABGR_1555:
- case VG_sABGR_4444:
- return 2;
- case VG_sL_8:
- case VG_lL_8:
- case VG_A_8:
- case VG_A_4:
- case VG_A_1:
- case VG_BW_1:
- return 1;
- case VG_IMAGE_FORMAT_INVALID:
- default:
- return 0;
- }
- }
-
-
-// Checks aCount & aValues for SetParameteriv & SetParameterfv
-TBool TCheck::ChkParamCountAndValuesPtr(MVgContext& aVgContext, VGint aCount, const void* aValues)
- {
- VGErrorCode error = VG_NO_ERROR;
- if (aValues == NULL)
- {
- if (aCount != 0)
- {
- error = VG_ILLEGAL_ARGUMENT_ERROR;
- }
- }
- // we should check count for not being too large for serialization, but
- // there is no limit in spec for VG_SCISSOR_RECTS and VG_STROKE_DASH_PATTERN
- else if ( (3ul & (unsigned)aValues) || (aCount < 0) || (aCount > 100000) )
- {
- error = VG_ILLEGAL_ARGUMENT_ERROR;
- }
-
- if (error != VG_NO_ERROR)
- {
- OPENVG_TRACE("TCheck::ChkParamCountAndValuesPtr setting error=0x%x", error);
- aVgContext.SetVgError(error);
- return EFalse;
- }
- return ETrue;
- }
-
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-// XOpenVgState
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-// Singleton object is in WSD memory, so this Constructor is called when the DLL is loaded
-XOpenVgState::XOpenVgState() :
- iEglManagementApi(NULL), iKVgMaxKernelSize(0), iKVgMaxSeparableKernelSize(0)
- {
- OPENVG_TRACE("XOpenVgState::XOpenVgState 1. start Process=0x%lx, Thread=0x%lx", RProcess().Id().Id(), RThread().Id().Id());
-
- TInt createErr1 = iStateLock.CreateLocal(EOwnerProcess);
- OPENVG_TRACE("XOpenVgState::XOpenVgState 2. iStateLock.CreateLocal error=%d, Handle=0x%x", createErr1, iStateLock.Handle());
-
- TInt createErr2 = iMapLock.CreateLocal(EOwnerProcess);
- OPENVG_TRACE("XOpenVgState::XOpenVgState 2. iMapLock.CreateLocal error=%d, Handle=0x%x", createErr2, iMapLock.Handle());
- // cannot continue if there is an error, so Panic
- VGPANIC_ASSERT( (createErr1 == KErrNone) && (createErr2 == KErrNone), EVgPanicTemp);
-
- CVgHandleBase::InitStatics();
-
- // publish MVgApiforEgl vtable
- CVghwUtils::SetVgApiForEgl(this);
- }
-
-
-// Desstructor is called when the DLL is unloaded
-XOpenVgState::~XOpenVgState()
- {
- OPENVG_TRACE("XOpenVgState::~XOpenVgState 1. iStateLock handle=0x%x, iMapLock handle=0x%x, Process=0x%lx, Thread=0x%lx",
- iStateLock.Handle(), iMapLock.Handle(), RProcess().Id().Id(), RThread().Id().Id());
-
- if (iStateLock.Handle())
- {
- iStateLock.Close();
- OPENVG_TRACE("XOpenVgState::~XOpenVgState 2. iStateLock Handle=0x%x", iStateLock.Handle());
- }
- if (iMapLock.Handle())
- {
- iMapLock.Close();
- OPENVG_TRACE("XOpenVgState::~XOpenVgState 3. iMapLock Handle=0x%x", iMapLock.Handle());
- }
-
- // unpublish MVgApiforEgl vtable
- CVghwUtils::SetVgApiForEgl(NULL);
- }
-
-
-TBool XOpenVgState::CheckVGHandle(MVgContext& aVgContext, VGHandle aHandle, CVgHandleBase** aHandleInfo, TVgHandleType aMatchType)
- { // client side VGHandle is an opaque data handle to Host Open VG objects such as VGPath or VGImage
- // only check for logic errors in VG code in Debug builds
- VGPANIC_ASSERT_DEBUG(iStateLock.IsHeld(), EVgPanicStateLockMutexNotHeld);
- VGPANIC_ASSERT_DEBUG(aHandleInfo, EVgPanicFunctionParameterIsNull);
-
- if (aHandle != VG_INVALID_HANDLE)
- {
- iMapLock.Wait();
- CVgHandleBase** pHandleInfo = iHandleHashMap.Find(aHandle);
- if (pHandleInfo)
- {
- CVgHandleBase* handleInfo = *pHandleInfo;
- if (handleInfo && !handleInfo->IsDestroyed() &&
- ( (aMatchType == EVgHandleAny) || (aMatchType == handleInfo->HandleType()) ) )
- {
- // ToDo confirm handle belongs to this context or is shared with this context
- *aHandleInfo = handleInfo;
- OPENVG_TRACE(" XOpenVgState::CheckVGHandle client handle=0x%x, match type=%d; found matching Host VG Handle=0x%x",
- aHandle, aMatchType, handleInfo->HostHandle());
- iMapLock.Signal();
- return ETrue;
- }
- }
- iMapLock.Signal();
- }
- OPENVG_TRACE(" XOpenVgState::CheckVGHandle client handle=0x%x, match type=%d, setting VG_BAD_HANDLE_ERROR", aHandle, aMatchType);
- aVgContext.SetVgError(VG_BAD_HANDLE_ERROR);
- return EFalse;
- }
-
-
-/*
- aKernelWidth or aKernelHeight must be >0 and <= [Size Limit], otherwise a VG_ILLEGAL_ARGUMENT_ERROR is flagged
- */
-TBool XOpenVgState::CheckKernelWidthAndHeight(MVgContext& aVgContext, VGint aKernelWidth, VGint aKernelHeight, VGParamType aLimitType)
- {
- VGPANIC_ASSERT_DEBUG(iStateLock.IsHeld(), EVgPanicStateLockMutexNotHeld);
- VGint limit = 0;
- // aLimitType must be either VG_MAX_KERNEL_SIZE or VG_MAX_SEPARABLE_KERNEL_SIZE
- if (aLimitType == VG_MAX_KERNEL_SIZE)
- {
- if (iKVgMaxKernelSize == 0)
- { // first access, so fetch value from Host
- iKVgMaxKernelSize = TGuestOpenVg::HostGeti(aVgContext, VG_MAX_KERNEL_SIZE);
- }
- limit = iKVgMaxKernelSize;
- }
- else if (aLimitType == VG_MAX_SEPARABLE_KERNEL_SIZE)
- {
- if (iKVgMaxSeparableKernelSize == 0)
- { // first access, so fetch value from Host
- iKVgMaxSeparableKernelSize = TGuestOpenVg::HostGeti(aVgContext, VG_MAX_SEPARABLE_KERNEL_SIZE);
- }
- limit = iKVgMaxSeparableKernelSize;
- }
- VGPANIC_ASSERT(limit > 0, EVgPanicValueFromHostVgIsInvalid);
-
- if ( (aKernelHeight > 0) && (aKernelHeight <= limit) && (aKernelWidth > 0) && (aKernelWidth <= limit) )
- {
- return ETrue;
- }
- OPENVG_TRACE("XOpenVgState::CheckKernelWidthAndHeight setting VG_ILLEGAL_ARGUMENT_ERROR");
- aVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR);
- return EFalse;
- }
-
-
-TBool XOpenVgState::AddToHashMap(MVgContext& aVgContext, CVgHandleBase* aHandleInfo, VGHandle aHostHandle)
- {
- VGPANIC_ASSERT_DEBUG(iStateLock.IsHeld(), EVgPanicStateLockMutexNotHeld);
-
- OPENVG_TRACE(" XOpenVgState::AddToHashMap aHandleInfo=0x%x, aHostHandle=0x%x, ClientHandle=0x%x",
- aHandleInfo, aHostHandle, aHandleInfo->ClientHandle());
- aHandleInfo->SetHostHandle(aHostHandle);
-
- iMapLock.Wait();
- RHeap* clientHeap = CVghwUtils::SwitchToVghwHeap();
- // ClientHandle is key to finding object, its Host Handle, object type, etc...
- TInt err = iHandleHashMap.Insert(aHandleInfo->ClientHandle(), aHandleInfo);
- CVghwUtils::SwitchFromVghwHeap(clientHeap);
- iMapLock.Signal();
-
- if (err == KErrNone)
- {
- return ETrue;
- }
-
- // Failed, Cleanup ...
- OPENVG_TRACE(" XOpenVgState::AddToHashMap insert error = %d", err);
- aVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
- return EFalse;
- }
-
-
-void XOpenVgState::UnMapHandle(TUint32 aClientHandle)
- {
- OPENVG_TRACE(" XOpenVgState::UnMapHandle aHandleInfo=0x%x -->", aClientHandle);
- VGPANIC_ASSERT_DEBUG(iStateLock.IsHeld(), EVgPanicStateLockMutexNotHeld);
- VGPANIC_ASSERT_DEBUG( CVghwUtils::UsingVghwHeap(), EVgPanicTemp);
-
- iMapLock.Wait();
-#ifdef _DEBUG
- TInt dbgErr =
-#endif
- iHandleHashMap.Remove(aClientHandle);
- iMapLock.Signal();
-
- OPENVG_TRACE(" XOpenVgState::UnMapHandle ... dbgErr =%d <--", dbgErr);
- }
-
-
-TBool XOpenVgState::EglImageOpenForVgImage(EGLImageKHR aImage, TSize& aSize, VGHandle& aVgHandle, TUint64& aSgImageId)
- {
- if (!iEglManagementApi)
- { // try to get EGL interface via VghwUtils
- iEglManagementApi = CVghwUtils::EglManagementApi();
- VGPANIC_ASSERT_DEBUG(iEglManagementApi, EVgPanicMissingEglInterface);
- }
- if (iEglManagementApi)
- {
- return iEglManagementApi->EglImageOpenForVgImage(aImage, aSize, aVgHandle, aSgImageId);
- }
- return EFalse;
- }
-
-
-void XOpenVgState::EglImageClose(EGLImageKHR aImage)
- {
- if (iEglManagementApi)
- {
- iEglManagementApi->EglImageClose(aImage);
- }
- }
-
-
-// Guest Open VG extension export support for eglGetProcAddress
-typedef struct
- {
- const char* procName; // procedure name
- ExtensionProcPointer procAddr;
- } TVgExtnInfo;
-
-// VG extension functions
-static const TVgExtnInfo vgProcedures[] =
- {
- { "vgCreateEGLImageTargetKHR", (ExtensionProcPointer)vgCreateEGLImageTargetKHR },
- };
-
-const TInt KVgProcCount = sizeof(vgProcedures) / sizeof(TVgExtnInfo);
-
-ExtensionProcPointer XOpenVgState::guestGetVgProcAddress (const char *aProcName)
- {
- // exhaustive search
- for (TInt idx = 0; idx < KVgProcCount; idx++)
- {
- if (!strcmp(aProcName, vgProcedures[idx].procName))
- return vgProcedures[idx].procAddr;
- }
- return NULL;
- }
-
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-// TCleanupVgLocks
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-TCleanupVgLocks::TCleanupVgLocks(MVgContext& aVgContext) :
- iVgContext(aVgContext), iMutex(OpenVgState.MutexWait()), iIsHeld(ETrue)
- {}
-
-TCleanupVgLocks::~TCleanupVgLocks()
- {
- if (iIsHeld)
- {
- SignalMutex();
- }
- }
-
-void TCleanupVgLocks::SignalMutex()
- {
- VGPANIC_ASSERT_DEBUG(iIsHeld && iMutex.IsHeld(), EVgPanicTemp);
- iMutex.Signal();
- iIsHeld = EFalse;
- }
-
-
-/*
- Returns false & sets VG error to VG_ILLEGAL_ARGUMENT_ERROR if VGMaskOperation is not a supported operation
- */
-TBool TCleanupVgLocks::CheckVGMaskOperationAndHandle(VGMaskOperation aOperation, VGHandle aMask, CVgImageBase** aHandleInfo)
- {
- VGPANIC_ASSERT_DEBUG(iIsHeld, EVgPanicStateLockMutexNotHeld);
- *aHandleInfo = NULL;
- switch (aOperation)
- {
- case VG_CLEAR_MASK:
- case VG_FILL_MASK:
- // aMask is not used for these operations
- return ETrue;
- case VG_SET_MASK:
- case VG_UNION_MASK:
- case VG_INTERSECT_MASK:
- case VG_SUBTRACT_MASK:
- {
- if (aMask == VG_INVALID_HANDLE)
- return ETrue;
-
- CVgHandleBase* tempInfo;
- if (CheckVGAnyHandle(aMask, &tempInfo))
- {
- if ( (tempInfo->HandleType() == EVgHandleForMaskLayer) || (tempInfo->HandleType() == EVgHandleForImage) )
- {
- *aHandleInfo = (CVgImageBase*)tempInfo;
- // TODO if handle is a VgImage verify that it is not a rendering target
- return ETrue;
- }
- OPENVG_TRACE("TCleanupVgLocks::CheckVGMaskOperationAndHandle setting VG_BAD_HANDLE_ERROR");
- iVgContext.SetVgError(VG_BAD_HANDLE_ERROR);
- }
- return EFalse;
- }
- default:
- OPENVG_TRACE("TCleanupVgLocks::CheckVGMaskOperationAndHandle setting VG_ILLEGAL_ARGUMENT_ERROR");
- iVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR);
- return EFalse;
- }
- }
-
-
-VGFont TCleanupVgLocks::CreateFont(VGint aGlyphCapacityHint)
- {
- VGPANIC_ASSERT_DEBUG(iIsHeld && iMutex.IsHeld(), EVgPanicTemp);
-
- CVgFontInfo* fontInfo = CVgFontInfo::New();
- if (fontInfo == NULL)
- {
- OPENVG_TRACE(" TGuestOpenVg::vgCreateFont - CVgFontInfo::New() failed");
- iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
- }
- else
- {
- RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
- vgApiData.Init(OpenVgRFC::EvgCreateFont);
- vgApiData.AppendParam(aGlyphCapacityHint);
- VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
- iVgContext.ExecuteVgCommand(vgApiData);
- VGFont hostFont = static_cast<VGFont>(vgApiData.ReturnValue());
- OPENVG_TRACE(" TCleanupVgLocks::CreateFont - CVgFontInfo::New() success, hostFont=0x%x", hostFont);
-
- if ( (hostFont != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, fontInfo, hostFont) )
- {
- return fontInfo->ClientHandle();
- }
-
- fontInfo->Destroy(iVgContext);
- }
-
- return VG_INVALID_HANDLE;
- }
-
-
-VGImage TCleanupVgLocks::ChildImage(CVgImageInfo& aParentInfo, VGint aX, VGint aY, VGint aWidth, VGint aHeight)
- {
- CVgImageInfo* imageInfo = CVgImageInfo::New(aWidth, aHeight, &aParentInfo);
- if (imageInfo == NULL)
- {
- iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
- OPENVG_TRACE(" TCleanupVgLocks::ChildImage - CVgImageInfo::New() failed");
- }
- else
- {
- RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
- vgApiData.Init(OpenVgRFC::EvgChildImage);
- vgApiData.AppendParam(aParentInfo.HostHandle());
- vgApiData.AppendParam(aX);
- vgApiData.AppendParam(aY);
- vgApiData.AppendParam(aWidth);
- vgApiData.AppendParam(aHeight);
- VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
- iVgContext.ExecuteVgCommand(vgApiData);
- VGImage hostImageHandle = static_cast<VGImage>(vgApiData.ReturnValue());
-
- OPENVG_TRACE(" TCleanupVgLocks::ChildImage - CVgImageInfo::New() success, hostImageHandle=0x%x", hostImageHandle);
- if ( (hostImageHandle != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, imageInfo, hostImageHandle) )
- {
- return imageInfo->ClientHandle();
- }
- imageInfo->Destroy(iVgContext);
- }
-
- return VG_INVALID_HANDLE;
- }
-
-
-VGImage TCleanupVgLocks::CreateImage(VGImageFormat aFormat, VGint aWidth, VGint aHeight, VGbitfield aAllowedQuality)
- {
- CVgImageInfo* imageInfo = CVgImageInfo::New(aFormat, aWidth, aHeight, aAllowedQuality);
- if (imageInfo == NULL)
- {
- iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
- OPENVG_TRACE(" TCleanupVgLocks::CreateImage - CVgImageInfo::New() failed");
- }
- else
- {
- RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
- vgApiData.Init(OpenVgRFC::EvgCreateImage);
- vgApiData.AppendParam(aFormat);
- vgApiData.AppendParam(aWidth);
- vgApiData.AppendParam(aHeight);
- vgApiData.AppendParam(aAllowedQuality);
- VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
- iVgContext.ExecuteVgCommand(vgApiData);
- VGImage hostImageHandle = static_cast<VGImage>(vgApiData.ReturnValue());
-
- OPENVG_TRACE(" TCleanupVgLocks::CreateImage - CVgImageInfo::New() success, hostImageHandle=0x%x", hostImageHandle);
- if ( (hostImageHandle != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, imageInfo, hostImageHandle) )
- {
- return imageInfo->ClientHandle();
- }
- imageInfo->Destroy(iVgContext);
- }
-
- return VG_INVALID_HANDLE;
- }
-
-
-VGMaskLayer TCleanupVgLocks::CreateMaskLayer(VGint aWidth, VGint aHeight)
- {
- CVgMaskLayerInfo* maskLayerInfo = CVgMaskLayerInfo::New(aWidth, aHeight);
- if (maskLayerInfo == NULL)
- {
- OPENVG_TRACE(" TCleanupVgLocks::CreateMaskLayer - CVgMaskLayerInfo::New() failed");
- iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
- }
- else
- {
- RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
- vgApiData.Init(OpenVgRFC::EvgCreateMaskLayer);
- vgApiData.AppendParam(aWidth);
- vgApiData.AppendParam(aHeight);
- VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
- iVgContext.ExecuteVgCommand(vgApiData);
- VGMaskLayer hostMaskHandle = static_cast<VGMaskLayer>(vgApiData.ReturnValue());
-
- OPENVG_TRACE(" TCleanupVgLocks::CreateMaskLayer - CVgMaskLayerInfo::New() success, hostMaskHandle=0x%x", hostMaskHandle);
- if ( (hostMaskHandle != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, maskLayerInfo, hostMaskHandle) )
- {
- return maskLayerInfo->ClientHandle();
- }
- maskLayerInfo->Destroy(iVgContext);
- }
-
- return VG_INVALID_HANDLE;
- }
-
-
-VGPaint TCleanupVgLocks::CreatePaint()
- {
- CVgPaintInfo* paintInfo = CVgPaintInfo::New();
- if (paintInfo == NULL)
- {
- OPENVG_TRACE(" TCleanupVgLocks::CreatePaint - CVgPaintInfo::New() failed");
- iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
- }
- else
- {
- RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
- vgApiData.Init(OpenVgRFC::EvgCreatePaint);
- VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
- iVgContext.ExecuteVgCommand(vgApiData);
- VGPaint hostPaint = static_cast<VGPaint>(vgApiData.ReturnValue());
-
- OPENVG_TRACE(" TCleanupVgLocks::CreatePaint - CVgPaintInfo::New() success, clientHandle=0x%x, hostHandle=0x%x",
- paintInfo->ClientHandle(), hostPaint);
- if ( (hostPaint != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, paintInfo, hostPaint) )
- {
- return paintInfo->ClientHandle();
- }
- paintInfo->Destroy(iVgContext);
- }
-
- return VG_INVALID_HANDLE;
- }
-
-
-VGPaint TCleanupVgLocks::GetPaint(VGPaintMode aPaintMode)
- {
- CVgPaintInfo* paintInfo = CVgPaintInfo::New();
- if (paintInfo == NULL)
- {
- iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
- OPENVG_TRACE(" TCleanupVgLocks::GetPaint - CVgPaintInfo::New() failed");
- }
- else
- {
- RemoteFunctionCallData rfcdata; OpenVgRFC vgApiData(rfcdata);
- vgApiData.Init(OpenVgRFC::EvgGetPaint);
- vgApiData.AppendParam(aPaintMode);
- VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
- iVgContext.ExecuteVgCommand(vgApiData);
- VGPaint hostPaint = static_cast<VGPaint>(vgApiData.ReturnValue());
-
- OPENVG_TRACE(" TCleanupVgLocks::GetPaint - CVgPaintInfo::New() success, clientHandle=0x%x, hostHandle=0x%x",
- paintInfo->ClientHandle(), hostPaint);
- if ( (hostPaint != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, paintInfo, hostPaint) )
- {
- return paintInfo->ClientHandle();
- }
- paintInfo->Destroy(iVgContext);
- }
-
- return VG_INVALID_HANDLE;
- }
-
-
-VGPath TCleanupVgLocks::CreatePath(VGint aPathFormat, VGPathDatatype aDatatype, VGfloat aScale, VGfloat aBias,
- VGint aSegmentCapacityHint, VGint aCoordCapacityHint, VGbitfield aCapabilities)
- {
- VGPANIC_ASSERT_DEBUG(iIsHeld && iMutex.IsHeld(), EVgPanicTemp);
-
- aCapabilities &= VG_PATH_CAPABILITY_ALL;
- CVgPathInfo* pathInfo = CVgPathInfo::New(aDatatype, aScale, aBias, aCapabilities);
- if (pathInfo == NULL)
- {
- OPENVG_TRACE(" TCleanupVgLocks::CreatePath - CVgPathInfo::New() failed");
- iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
- }
- else
- {
- RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
- vgApiData.Init(OpenVgRFC::EvgCreatePath);
- vgApiData.AppendParam(aPathFormat);
- vgApiData.AppendParam(aDatatype);
- vgApiData.AppendParam(aScale);
- vgApiData.AppendParam(aBias);
- vgApiData.AppendParam(aSegmentCapacityHint);
- vgApiData.AppendParam(aCoordCapacityHint);
- vgApiData.AppendParam(aCapabilities);
- VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
- iVgContext.ExecuteVgCommand(vgApiData);
- VGPath hostPath = static_cast<VGPath>(vgApiData.ReturnValue());
- OPENVG_TRACE(" TCleanupVgLocks::CreatePath - CVgPathInfo::New() success, hostHandle=0x%x", hostPath);
-
- if ( (hostPath != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, pathInfo, hostPath) )
- {
- return pathInfo->ClientHandle();
- }
-
- pathInfo->Destroy(iVgContext);
- }
-
- return VG_INVALID_HANDLE;
- }
-
-
-VGImage TCleanupVgLocks::CreateEGLImageTargetKHR(VGeglImageKHR aImage)
- {
- VGErrorCode error = VG_NO_ERROR;
-
- if (aImage == NULL)
- {
- error = VG_ILLEGAL_ARGUMENT_ERROR;
- }
- else
- {
- // Try to open EGL Image from handle, and get info such as image size
- TSize imageSize;
- TUint64 sgImageId;
- VGHandle vgHandle;
- if (!OpenVgState.EglImageOpenForVgImage((EGLImageKHR) aImage, imageSize, vgHandle, sgImageId))
- {
- error = VG_UNSUPPORTED_IMAGE_FORMAT_ERROR;
- }
- else
- { // Open success, create a CVgImageInfo with all the details ...
- // ToDo get & store VGImageFormat of underlying VGImage
- CVgImageInfo* newImageInfo = CVgImageInfo::New(VG_IMAGE_FORMAT_INVALID, imageSize.iWidth, imageSize.iHeight,
- (EGLImageKHR) aImage, sgImageId);
- OPENVG_TRACE("TGuestOpenVg::vgCreateEGLImageTargetKHR imageSize=%d,%d, vgHandle=0x%x, sgImageId=0x%lx newImageInfo=0x%x",
- imageSize.iWidth, imageSize.iHeight, vgHandle, sgImageId, newImageInfo);
- if (newImageInfo == NULL)
- {
- error = VG_OUT_OF_MEMORY_ERROR;
- OpenVgState.EglImageClose((EGLImageKHR) aImage);
- }
- else
- {
- if (OpenVgState.AddToHashMap(iVgContext, newImageInfo, vgHandle))
- {
- // Notify Command Scheduler & KhronosWrappers
- RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
- vgApiData.Init(OpenVgRFC::EvgCreateEGLImageTargetKHR, RemoteFunctionCallData::EOpRequestWithReply);
- vgApiData.AppendParam(aImage);
- // ToDo any other parameters needed? Is this really a Request with Reply?
- iVgContext.ExecuteVgCommand(vgApiData);
- return newImageInfo->ClientHandle();
- }
- newImageInfo->Destroy(iVgContext);
- }
- }
- }
-
-
- if (error != VG_NO_ERROR)
- {
- iVgContext.SetVgError(error);
- OPENVG_TRACE("TGuestOpenVg::vgCreateEGLImageTargetKHR fail - error=0x%x", error);
- }
-
- return VG_INVALID_HANDLE;
- }
-
-
-
-
-// **** Desirable: could check VGParamType for vgGet & vgSet scalar & vector operations.
-/*
- // Mode settings
- VG_MATRIX_MODE ???
- VG_FILL_RULE ???
- VG_IMAGE_QUALITY ???
- VG_RENDERING_QUALITY ???
- VG_BLEND_MODE ???
- VG_IMAGE_MODE ???
-
- // Scissoring rectangles
- VG_SCISSOR_RECTS ???
-
- // Color Transformation
- VG_COLOR_TRANSFORM ???
- VG_COLOR_TRANSFORM_VALUES ???
-
- // Stroke parameters
- VG_STROKE_LINE_WIDTH ???
- VG_STROKE_CAP_STYLE ???
- VG_STROKE_JOIN_STYLE ???
- VG_STROKE_MITER_LIMIT ???
- VG_STROKE_DASH_PATTERN ???
- VG_STROKE_DASH_PHASE ???
- VG_STROKE_DASH_PHASE_RESET ???
-
- // Edge fill color for VG_TILE_FILL tiling mode
- VG_TILE_FILL_COLOR ???
-
- // Color for vgClear
- VG_CLEAR_COLOR ???
-
- // Glyph origin
- VG_GLYPH_ORIGIN ???
-
- // Enable/disable alpha masking and scissoring
- VG_MASKING ???
- VG_SCISSORING ???
-
- // Pixel layout information
- VG_PIXEL_LAYOUT ???
- VG_SCREEN_LAYOUT ???
-
- // Source format selection for image filters
- VG_FILTER_FORMAT_LINEAR ???
- VG_FILTER_FORMAT_PREMULTIPLIED ???
-
- // Destination write enable mask for image filters
- VG_FILTER_CHANNEL_MASK ???
-
- // Implementation limits (read-only)
- VG_MAX_SCISSOR_RECTS, ReadOnly, Scalar
- VG_MAX_DASH_COUNT ???
- VG_MAX_KERNEL_SIZE ???
- VG_MAX_SEPARABLE_KERNEL_SIZE ???
- VG_MAX_COLOR_RAMP_STOPS ???
- VG_MAX_IMAGE_WIDTH ???
- VG_MAX_IMAGE_HEIGHT ???
- VG_MAX_IMAGE_PIXELS ???
- VG_MAX_IMAGE_BYTES ???
- VG_MAX_FLOAT ???
- VG_MAX_GAUSSIAN_STD_DEVIATION ???
- */
-
-//////////////////////////////////////////////////////////////////////////
-
-// end of file vgstate.cpp
+// 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:
+// Client-side state information for Symbian DLL
+
+#include "vgstate.h"
+#include "remotefunctioncall.h"
+#include "openvgrfc.h"
+
+
+
+// VG Client-side state is Writeable Static Data in the DLL, (holds state information for the process)
+// Constructor/Destructor called on process load/unload to perform initialiser/release of static resources
+XOpenVgState OpenVgState;
+
+
+
+_LIT(KVgPanicCategory, "Guest VG");
+
+void VgPanic(TVgPanic aPanicCode, char* aPanicName, char* aCondition, char* aFile, TInt aLine)
+ {
+ if (aPanicName && aCondition && aFile)
+ { // normal for Debug builds
+ RDebug::Printf("Guest Open VG DLL Panic %s for failed Assert (%s),\n\tat %s:%d", aPanicName, aCondition, aFile, aLine);
+ }
+ else if (aPanicName && aFile)
+ { // Debug builds Assert Always
+ RDebug::Printf("Guest Open VG DLL Panic %s at %s:%d", aPanicName, aFile, aLine);
+ }
+ else
+ { // normal for Release builds
+ RDebug::Printf("Guest Open VG DLL Panic %d (line %d)", aPanicCode, aLine);
+ }
+
+ User::Panic(KVgPanicCategory, aPanicCode);
+ }
+
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// TCheck - parameter checking utility functions
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+
+/*
+ aWidth & aHeight parameters must be >0, also ax, ay, aX + aWidth and aY + aHeight must all
+ be within image size, otherwise a VG_ILLEGAL_ARGUMENT_ERROR is flagged.
+ */
+TBool TCheck::ChkAreaIsWithinImage(MVgContext& aVgContext, CVgImageBase* aImageInfo, VGint aX, VGint aY, VGint aWidth, VGint aHeight)
+ {
+ VGPANIC_ASSERT_DEBUG(aImageInfo, EVgPanicTemp);
+ if ( (aX >= 0) && (aY >= 0) && (aWidth > 0) && (aHeight > 0) )
+ {
+ VGint maxX = aWidth + aX;
+ VGint maxY = aHeight + aY;
+ if ( (maxX > 0) && (maxY > 0) && (aImageInfo->Width() >= maxX) && (aImageInfo->Height() >= maxY) )
+ {
+ return ETrue;
+ }
+ }
+ OPENVG_TRACE("TCheck::ChkAreaIsWithinImage setting VG_ILLEGAL_ARGUMENT_ERROR");
+ aVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR);
+ return EFalse;
+ }
+
+
+VGint TCheck::ImageFormatByteDepth(VGImageFormat aImageFormat)
+ {
+ switch (aImageFormat)
+ {
+ case VG_sRGBX_8888:
+ case VG_sRGBA_8888:
+ case VG_sRGBA_8888_PRE:
+ case VG_lRGBX_8888:
+ case VG_lRGBA_8888:
+ case VG_lRGBA_8888_PRE:
+ case VG_sXRGB_8888:
+ case VG_sARGB_8888:
+ case VG_sARGB_8888_PRE:
+ case VG_lXRGB_8888:
+ case VG_lARGB_8888:
+ case VG_lARGB_8888_PRE:
+ case VG_sBGRX_8888:
+ case VG_sBGRA_8888:
+ case VG_sBGRA_8888_PRE:
+ case VG_lBGRX_8888:
+ case VG_lBGRA_8888:
+ case VG_lBGRA_8888_PRE:
+ case VG_sXBGR_8888:
+ case VG_sABGR_8888:
+ case VG_sABGR_8888_PRE:
+ case VG_lXBGR_8888:
+ case VG_lABGR_8888:
+ case VG_lABGR_8888_PRE:
+ return 4;
+ case VG_sRGB_565:
+ case VG_sRGBA_5551:
+ case VG_sRGBA_4444:
+ case VG_sARGB_1555:
+ case VG_sARGB_4444:
+ case VG_sBGR_565:
+ case VG_sBGRA_5551:
+ case VG_sBGRA_4444:
+ case VG_sABGR_1555:
+ case VG_sABGR_4444:
+ return 2;
+ case VG_sL_8:
+ case VG_lL_8:
+ case VG_A_8:
+ case VG_A_4:
+ case VG_A_1:
+ case VG_BW_1:
+ return 1;
+ case VG_IMAGE_FORMAT_INVALID:
+ default:
+ return 0;
+ }
+ }
+
+
+// Checks aCount & aValues for SetParameteriv & SetParameterfv
+TBool TCheck::ChkParamCountAndValuesPtr(MVgContext& aVgContext, VGint aCount, const void* aValues)
+ {
+ VGErrorCode error = VG_NO_ERROR;
+ if (aValues == NULL)
+ {
+ if (aCount != 0)
+ {
+ error = VG_ILLEGAL_ARGUMENT_ERROR;
+ }
+ }
+ // we should check count for not being too large for serialization, but
+ // there is no limit in spec for VG_SCISSOR_RECTS and VG_STROKE_DASH_PATTERN
+ else if ( (3ul & (unsigned)aValues) || (aCount < 0) || (aCount > 100000) )
+ {
+ error = VG_ILLEGAL_ARGUMENT_ERROR;
+ }
+
+ if (error != VG_NO_ERROR)
+ {
+ OPENVG_TRACE("TCheck::ChkParamCountAndValuesPtr setting error=0x%x", error);
+ aVgContext.SetVgError(error);
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// XOpenVgState
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+// Singleton object is in WSD memory, so this Constructor is called when the DLL is loaded
+XOpenVgState::XOpenVgState() :
+ iEglManagementApi(NULL), iKVgMaxKernelSize(0), iKVgMaxSeparableKernelSize(0)
+ {
+ OPENVG_TRACE("XOpenVgState::XOpenVgState 1. start Process=0x%lx, Thread=0x%lx", RProcess().Id().Id(), RThread().Id().Id());
+
+ TInt createErr1 = iStateLock.CreateLocal(EOwnerProcess);
+ OPENVG_TRACE("XOpenVgState::XOpenVgState 2. iStateLock.CreateLocal error=%d, Handle=0x%x", createErr1, iStateLock.Handle());
+
+ TInt createErr2 = iMapLock.CreateLocal(EOwnerProcess);
+ OPENVG_TRACE("XOpenVgState::XOpenVgState 2. iMapLock.CreateLocal error=%d, Handle=0x%x", createErr2, iMapLock.Handle());
+ // cannot continue if there is an error, so Panic
+ VGPANIC_ASSERT( (createErr1 == KErrNone) && (createErr2 == KErrNone), EVgPanicTemp);
+
+ CVgHandleBase::InitStatics();
+
+ // publish MVgApiforEgl vtable
+ CVghwUtils::SetVgApiForEgl(this);
+ }
+
+
+// Desstructor is called when the DLL is unloaded
+XOpenVgState::~XOpenVgState()
+ {
+ OPENVG_TRACE("XOpenVgState::~XOpenVgState 1. iStateLock handle=0x%x, iMapLock handle=0x%x, Process=0x%lx, Thread=0x%lx",
+ iStateLock.Handle(), iMapLock.Handle(), RProcess().Id().Id(), RThread().Id().Id());
+
+ if (iStateLock.Handle())
+ {
+ iStateLock.Close();
+ OPENVG_TRACE("XOpenVgState::~XOpenVgState 2. iStateLock Handle=0x%x", iStateLock.Handle());
+ }
+ if (iMapLock.Handle())
+ {
+ iMapLock.Close();
+ OPENVG_TRACE("XOpenVgState::~XOpenVgState 3. iMapLock Handle=0x%x", iMapLock.Handle());
+ }
+
+ // unpublish MVgApiforEgl vtable
+ CVghwUtils::SetVgApiForEgl(NULL);
+ }
+
+
+TBool XOpenVgState::CheckVGHandle(MVgContext& aVgContext, VGHandle aHandle, CVgHandleBase** aHandleInfo, TVgHandleType aMatchType)
+ { // client side VGHandle is an opaque data handle to Host Open VG objects such as VGPath or VGImage
+ // only check for logic errors in VG code in Debug builds
+ VGPANIC_ASSERT_DEBUG(iStateLock.IsHeld(), EVgPanicStateLockMutexNotHeld);
+ VGPANIC_ASSERT_DEBUG(aHandleInfo, EVgPanicFunctionParameterIsNull);
+
+ if (aHandle != VG_INVALID_HANDLE)
+ {
+ iMapLock.Wait();
+ CVgHandleBase** pHandleInfo = iHandleHashMap.Find(aHandle);
+ if (pHandleInfo)
+ {
+ CVgHandleBase* handleInfo = *pHandleInfo;
+ if (handleInfo && !handleInfo->IsDestroyed() &&
+ ( (aMatchType == EVgHandleAny) || (aMatchType == handleInfo->HandleType()) ) )
+ {
+ // ToDo confirm handle belongs to this context or is shared with this context
+ *aHandleInfo = handleInfo;
+ OPENVG_TRACE(" XOpenVgState::CheckVGHandle client handle=0x%x, match type=%d; found matching Host VG Handle=0x%x",
+ aHandle, aMatchType, handleInfo->HostHandle());
+ iMapLock.Signal();
+ return ETrue;
+ }
+ }
+ iMapLock.Signal();
+ }
+ OPENVG_TRACE(" XOpenVgState::CheckVGHandle client handle=0x%x, match type=%d, setting VG_BAD_HANDLE_ERROR", aHandle, aMatchType);
+ aVgContext.SetVgError(VG_BAD_HANDLE_ERROR);
+ return EFalse;
+ }
+
+
+/*
+ aKernelWidth or aKernelHeight must be >0 and <= [Size Limit], otherwise a VG_ILLEGAL_ARGUMENT_ERROR is flagged
+ */
+TBool XOpenVgState::CheckKernelWidthAndHeight(MVgContext& aVgContext, VGint aKernelWidth, VGint aKernelHeight, VGParamType aLimitType)
+ {
+ VGPANIC_ASSERT_DEBUG(iStateLock.IsHeld(), EVgPanicStateLockMutexNotHeld);
+ VGint limit = 0;
+ // aLimitType must be either VG_MAX_KERNEL_SIZE or VG_MAX_SEPARABLE_KERNEL_SIZE
+ if (aLimitType == VG_MAX_KERNEL_SIZE)
+ {
+ if (iKVgMaxKernelSize == 0)
+ { // first access, so fetch value from Host
+ iKVgMaxKernelSize = TGuestOpenVg::HostGeti(aVgContext, VG_MAX_KERNEL_SIZE);
+ }
+ limit = iKVgMaxKernelSize;
+ }
+ else if (aLimitType == VG_MAX_SEPARABLE_KERNEL_SIZE)
+ {
+ if (iKVgMaxSeparableKernelSize == 0)
+ { // first access, so fetch value from Host
+ iKVgMaxSeparableKernelSize = TGuestOpenVg::HostGeti(aVgContext, VG_MAX_SEPARABLE_KERNEL_SIZE);
+ }
+ limit = iKVgMaxSeparableKernelSize;
+ }
+ VGPANIC_ASSERT(limit > 0, EVgPanicValueFromHostVgIsInvalid);
+
+ if ( (aKernelHeight > 0) && (aKernelHeight <= limit) && (aKernelWidth > 0) && (aKernelWidth <= limit) )
+ {
+ return ETrue;
+ }
+ OPENVG_TRACE("XOpenVgState::CheckKernelWidthAndHeight setting VG_ILLEGAL_ARGUMENT_ERROR");
+ aVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR);
+ return EFalse;
+ }
+
+
+TBool XOpenVgState::AddToHashMap(MVgContext& aVgContext, CVgHandleBase* aHandleInfo, VGHandle aHostHandle)
+ {
+ VGPANIC_ASSERT_DEBUG(iStateLock.IsHeld(), EVgPanicStateLockMutexNotHeld);
+
+ OPENVG_TRACE(" XOpenVgState::AddToHashMap aHandleInfo=0x%x, aHostHandle=0x%x, ClientHandle=0x%x",
+ aHandleInfo, aHostHandle, aHandleInfo->ClientHandle());
+ aHandleInfo->SetHostHandle(aHostHandle);
+
+ iMapLock.Wait();
+ RHeap* clientHeap = CVghwUtils::SwitchToVghwHeap();
+ // ClientHandle is key to finding object, its Host Handle, object type, etc...
+ TInt err = iHandleHashMap.Insert(aHandleInfo->ClientHandle(), aHandleInfo);
+ CVghwUtils::SwitchFromVghwHeap(clientHeap);
+ iMapLock.Signal();
+
+ if (err == KErrNone)
+ {
+ return ETrue;
+ }
+
+ // Failed, Cleanup ...
+ OPENVG_TRACE(" XOpenVgState::AddToHashMap insert error = %d", err);
+ aVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
+ return EFalse;
+ }
+
+
+void XOpenVgState::UnMapHandle(TUint32 aClientHandle)
+ {
+ OPENVG_TRACE(" XOpenVgState::UnMapHandle aHandleInfo=0x%x -->", aClientHandle);
+ VGPANIC_ASSERT_DEBUG(iStateLock.IsHeld(), EVgPanicStateLockMutexNotHeld);
+ VGPANIC_ASSERT_DEBUG( CVghwUtils::UsingVghwHeap(), EVgPanicTemp);
+
+ iMapLock.Wait();
+#ifdef _DEBUG
+ TInt dbgErr =
+#endif
+ iHandleHashMap.Remove(aClientHandle);
+ iMapLock.Signal();
+
+ OPENVG_TRACE(" XOpenVgState::UnMapHandle ... dbgErr =%d <--", dbgErr);
+ }
+
+
+TBool XOpenVgState::EglImageOpenForVgImage(EGLImageKHR aImage, TSize& aSize, VGHandle& aVgHandle, TUint64& aSgImageId)
+ {
+ if (!iEglManagementApi)
+ { // try to get EGL interface via VghwUtils
+ iEglManagementApi = CVghwUtils::EglManagementApi();
+ VGPANIC_ASSERT_DEBUG(iEglManagementApi, EVgPanicMissingEglInterface);
+ }
+ if (iEglManagementApi)
+ {
+ return iEglManagementApi->EglImageOpenForVgImage(aImage, aSize, aVgHandle, aSgImageId);
+ }
+ return EFalse;
+ }
+
+
+void XOpenVgState::EglImageClose(EGLImageKHR aImage)
+ {
+ if (iEglManagementApi)
+ {
+ iEglManagementApi->EglImageClose(aImage);
+ }
+ }
+
+
+// Guest Open VG extension export support for eglGetProcAddress
+typedef struct
+ {
+ const char* procName; // procedure name
+ ExtensionProcPointer procAddr;
+ } TVgExtnInfo;
+
+// VG extension functions
+static const TVgExtnInfo vgProcedures[] =
+ {
+ { "vgCreateEGLImageTargetKHR", (ExtensionProcPointer)vgCreateEGLImageTargetKHR },
+ };
+
+const TInt KVgProcCount = sizeof(vgProcedures) / sizeof(TVgExtnInfo);
+
+ExtensionProcPointer XOpenVgState::guestGetVgProcAddress (const char *aProcName)
+ {
+ // exhaustive search
+ for (TInt idx = 0; idx < KVgProcCount; idx++)
+ {
+ if (!strcmp(aProcName, vgProcedures[idx].procName))
+ return vgProcedures[idx].procAddr;
+ }
+ return NULL;
+ }
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// TCleanupVgLocks
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+TCleanupVgLocks::TCleanupVgLocks(MVgContext& aVgContext) :
+ iVgContext(aVgContext), iMutex(OpenVgState.MutexWait()), iIsHeld(ETrue)
+ {}
+
+TCleanupVgLocks::~TCleanupVgLocks()
+ {
+ if (iIsHeld)
+ {
+ SignalMutex();
+ }
+ }
+
+void TCleanupVgLocks::SignalMutex()
+ {
+ VGPANIC_ASSERT_DEBUG(iIsHeld && iMutex.IsHeld(), EVgPanicTemp);
+ iMutex.Signal();
+ iIsHeld = EFalse;
+ }
+
+
+/*
+ Returns false & sets VG error to VG_ILLEGAL_ARGUMENT_ERROR if VGMaskOperation is not a supported operation
+ */
+TBool TCleanupVgLocks::CheckVGMaskOperationAndHandle(VGMaskOperation aOperation, VGHandle aMask, CVgImageBase** aHandleInfo)
+ {
+ VGPANIC_ASSERT_DEBUG(iIsHeld, EVgPanicStateLockMutexNotHeld);
+ *aHandleInfo = NULL;
+ switch (aOperation)
+ {
+ case VG_CLEAR_MASK:
+ case VG_FILL_MASK:
+ // aMask is not used for these operations
+ return ETrue;
+ case VG_SET_MASK:
+ case VG_UNION_MASK:
+ case VG_INTERSECT_MASK:
+ case VG_SUBTRACT_MASK:
+ {
+ if (aMask == VG_INVALID_HANDLE)
+ return ETrue;
+
+ CVgHandleBase* tempInfo;
+ if (CheckVGAnyHandle(aMask, &tempInfo))
+ {
+ if ( (tempInfo->HandleType() == EVgHandleForMaskLayer) || (tempInfo->HandleType() == EVgHandleForImage) )
+ {
+ *aHandleInfo = (CVgImageBase*)tempInfo;
+ // TODO if handle is a VgImage verify that it is not a rendering target
+ return ETrue;
+ }
+ OPENVG_TRACE("TCleanupVgLocks::CheckVGMaskOperationAndHandle setting VG_BAD_HANDLE_ERROR");
+ iVgContext.SetVgError(VG_BAD_HANDLE_ERROR);
+ }
+ return EFalse;
+ }
+ default:
+ OPENVG_TRACE("TCleanupVgLocks::CheckVGMaskOperationAndHandle setting VG_ILLEGAL_ARGUMENT_ERROR");
+ iVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR);
+ return EFalse;
+ }
+ }
+
+
+VGFont TCleanupVgLocks::CreateFont(VGint aGlyphCapacityHint)
+ {
+ VGPANIC_ASSERT_DEBUG(iIsHeld && iMutex.IsHeld(), EVgPanicTemp);
+
+ CVgFontInfo* fontInfo = CVgFontInfo::New();
+ if (fontInfo == NULL)
+ {
+ OPENVG_TRACE(" TGuestOpenVg::vgCreateFont - CVgFontInfo::New() failed");
+ iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
+ }
+ else
+ {
+ RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+ vgApiData.Init(OpenVgRFC::EvgCreateFont);
+ vgApiData.AppendParam(aGlyphCapacityHint);
+ VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
+ iVgContext.ExecuteVgCommand(vgApiData);
+ VGFont hostFont = static_cast<VGFont>(vgApiData.ReturnValue());
+ OPENVG_TRACE(" TCleanupVgLocks::CreateFont - CVgFontInfo::New() success, hostFont=0x%x", hostFont);
+
+ if ( (hostFont != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, fontInfo, hostFont) )
+ {
+ return fontInfo->ClientHandle();
+ }
+
+ fontInfo->Destroy(iVgContext);
+ }
+
+ return VG_INVALID_HANDLE;
+ }
+
+
+VGImage TCleanupVgLocks::ChildImage(CVgImageInfo& aParentInfo, VGint aX, VGint aY, VGint aWidth, VGint aHeight)
+ {
+ CVgImageInfo* imageInfo = CVgImageInfo::New(aWidth, aHeight, &aParentInfo);
+ if (imageInfo == NULL)
+ {
+ iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
+ OPENVG_TRACE(" TCleanupVgLocks::ChildImage - CVgImageInfo::New() failed");
+ }
+ else
+ {
+ RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+ vgApiData.Init(OpenVgRFC::EvgChildImage);
+ vgApiData.AppendParam(aParentInfo.HostHandle());
+ vgApiData.AppendParam(aX);
+ vgApiData.AppendParam(aY);
+ vgApiData.AppendParam(aWidth);
+ vgApiData.AppendParam(aHeight);
+ VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
+ iVgContext.ExecuteVgCommand(vgApiData);
+ VGImage hostImageHandle = static_cast<VGImage>(vgApiData.ReturnValue());
+
+ OPENVG_TRACE(" TCleanupVgLocks::ChildImage - CVgImageInfo::New() success, hostImageHandle=0x%x", hostImageHandle);
+ if ( (hostImageHandle != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, imageInfo, hostImageHandle) )
+ {
+ return imageInfo->ClientHandle();
+ }
+ imageInfo->Destroy(iVgContext);
+ }
+
+ return VG_INVALID_HANDLE;
+ }
+
+
+VGImage TCleanupVgLocks::CreateImage(VGImageFormat aFormat, VGint aWidth, VGint aHeight, VGbitfield aAllowedQuality)
+ {
+ CVgImageInfo* imageInfo = CVgImageInfo::New(aFormat, aWidth, aHeight, aAllowedQuality);
+ if (imageInfo == NULL)
+ {
+ iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
+ OPENVG_TRACE(" TCleanupVgLocks::CreateImage - CVgImageInfo::New() failed");
+ }
+ else
+ {
+ RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+ vgApiData.Init(OpenVgRFC::EvgCreateImage);
+ vgApiData.AppendParam(aFormat);
+ vgApiData.AppendParam(aWidth);
+ vgApiData.AppendParam(aHeight);
+ vgApiData.AppendParam(aAllowedQuality);
+ VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
+ iVgContext.ExecuteVgCommand(vgApiData);
+ VGImage hostImageHandle = static_cast<VGImage>(vgApiData.ReturnValue());
+
+ OPENVG_TRACE(" TCleanupVgLocks::CreateImage - CVgImageInfo::New() success, hostImageHandle=0x%x", hostImageHandle);
+ if ( (hostImageHandle != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, imageInfo, hostImageHandle) )
+ {
+ return imageInfo->ClientHandle();
+ }
+ imageInfo->Destroy(iVgContext);
+ }
+
+ return VG_INVALID_HANDLE;
+ }
+
+
+VGMaskLayer TCleanupVgLocks::CreateMaskLayer(VGint aWidth, VGint aHeight)
+ {
+ CVgMaskLayerInfo* maskLayerInfo = CVgMaskLayerInfo::New(aWidth, aHeight);
+ if (maskLayerInfo == NULL)
+ {
+ OPENVG_TRACE(" TCleanupVgLocks::CreateMaskLayer - CVgMaskLayerInfo::New() failed");
+ iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
+ }
+ else
+ {
+ RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+ vgApiData.Init(OpenVgRFC::EvgCreateMaskLayer);
+ vgApiData.AppendParam(aWidth);
+ vgApiData.AppendParam(aHeight);
+ VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
+ iVgContext.ExecuteVgCommand(vgApiData);
+ VGMaskLayer hostMaskHandle = static_cast<VGMaskLayer>(vgApiData.ReturnValue());
+
+ OPENVG_TRACE(" TCleanupVgLocks::CreateMaskLayer - CVgMaskLayerInfo::New() success, hostMaskHandle=0x%x", hostMaskHandle);
+ if ( (hostMaskHandle != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, maskLayerInfo, hostMaskHandle) )
+ {
+ return maskLayerInfo->ClientHandle();
+ }
+ maskLayerInfo->Destroy(iVgContext);
+ }
+
+ return VG_INVALID_HANDLE;
+ }
+
+
+VGPaint TCleanupVgLocks::CreatePaint()
+ {
+ CVgPaintInfo* paintInfo = CVgPaintInfo::New();
+ if (paintInfo == NULL)
+ {
+ OPENVG_TRACE(" TCleanupVgLocks::CreatePaint - CVgPaintInfo::New() failed");
+ iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
+ }
+ else
+ {
+ RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+ vgApiData.Init(OpenVgRFC::EvgCreatePaint);
+ VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
+ iVgContext.ExecuteVgCommand(vgApiData);
+ VGPaint hostPaint = static_cast<VGPaint>(vgApiData.ReturnValue());
+
+ OPENVG_TRACE(" TCleanupVgLocks::CreatePaint - CVgPaintInfo::New() success, clientHandle=0x%x, hostHandle=0x%x",
+ paintInfo->ClientHandle(), hostPaint);
+ if ( (hostPaint != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, paintInfo, hostPaint) )
+ {
+ return paintInfo->ClientHandle();
+ }
+ paintInfo->Destroy(iVgContext);
+ }
+
+ return VG_INVALID_HANDLE;
+ }
+
+
+VGPaint TCleanupVgLocks::GetPaint(VGPaintMode aPaintMode)
+ {
+ CVgPaintInfo* paintInfo = CVgPaintInfo::New();
+ if (paintInfo == NULL)
+ {
+ iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
+ OPENVG_TRACE(" TCleanupVgLocks::GetPaint - CVgPaintInfo::New() failed");
+ }
+ else
+ {
+ RemoteFunctionCallData rfcdata; OpenVgRFC vgApiData(rfcdata);
+ vgApiData.Init(OpenVgRFC::EvgGetPaint);
+ vgApiData.AppendParam(aPaintMode);
+ VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
+ iVgContext.ExecuteVgCommand(vgApiData);
+ VGPaint hostPaint = static_cast<VGPaint>(vgApiData.ReturnValue());
+
+ OPENVG_TRACE(" TCleanupVgLocks::GetPaint - CVgPaintInfo::New() success, clientHandle=0x%x, hostHandle=0x%x",
+ paintInfo->ClientHandle(), hostPaint);
+ if ( (hostPaint != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, paintInfo, hostPaint) )
+ {
+ return paintInfo->ClientHandle();
+ }
+ paintInfo->Destroy(iVgContext);
+ }
+
+ return VG_INVALID_HANDLE;
+ }
+
+
+VGPath TCleanupVgLocks::CreatePath(VGint aPathFormat, VGPathDatatype aDatatype, VGfloat aScale, VGfloat aBias,
+ VGint aSegmentCapacityHint, VGint aCoordCapacityHint, VGbitfield aCapabilities)
+ {
+ VGPANIC_ASSERT_DEBUG(iIsHeld && iMutex.IsHeld(), EVgPanicTemp);
+
+ aCapabilities &= VG_PATH_CAPABILITY_ALL;
+ CVgPathInfo* pathInfo = CVgPathInfo::New(aDatatype, aScale, aBias, aCapabilities);
+ if (pathInfo == NULL)
+ {
+ OPENVG_TRACE(" TCleanupVgLocks::CreatePath - CVgPathInfo::New() failed");
+ iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR);
+ }
+ else
+ {
+ RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+ vgApiData.Init(OpenVgRFC::EvgCreatePath);
+ vgApiData.AppendParam(aPathFormat);
+ vgApiData.AppendParam(aDatatype);
+ vgApiData.AppendParam(aScale);
+ vgApiData.AppendParam(aBias);
+ vgApiData.AppendParam(aSegmentCapacityHint);
+ vgApiData.AppendParam(aCoordCapacityHint);
+ vgApiData.AppendParam(aCapabilities);
+ VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode);
+ iVgContext.ExecuteVgCommand(vgApiData);
+ VGPath hostPath = static_cast<VGPath>(vgApiData.ReturnValue());
+ OPENVG_TRACE(" TCleanupVgLocks::CreatePath - CVgPathInfo::New() success, hostHandle=0x%x", hostPath);
+
+ if ( (hostPath != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, pathInfo, hostPath) )
+ {
+ return pathInfo->ClientHandle();
+ }
+
+ pathInfo->Destroy(iVgContext);
+ }
+
+ return VG_INVALID_HANDLE;
+ }
+
+
+VGImage TCleanupVgLocks::CreateEGLImageTargetKHR(VGeglImageKHR aImage)
+ {
+ VGErrorCode error = VG_NO_ERROR;
+
+ if (aImage == NULL)
+ {
+ error = VG_ILLEGAL_ARGUMENT_ERROR;
+ }
+ else
+ {
+ // Try to open EGL Image from handle, and get info such as image size
+ TSize imageSize;
+ TUint64 sgImageId;
+ VGHandle vgHandle;
+ if (!OpenVgState.EglImageOpenForVgImage((EGLImageKHR) aImage, imageSize, vgHandle, sgImageId))
+ {
+ error = VG_UNSUPPORTED_IMAGE_FORMAT_ERROR;
+ }
+ else
+ { // Open success, create a CVgImageInfo with all the details ...
+ // ToDo get & store VGImageFormat of underlying VGImage
+ CVgImageInfo* newImageInfo = CVgImageInfo::New(VG_IMAGE_FORMAT_INVALID, imageSize.iWidth, imageSize.iHeight,
+ (EGLImageKHR) aImage, sgImageId);
+ OPENVG_TRACE("TGuestOpenVg::vgCreateEGLImageTargetKHR imageSize=%d,%d, vgHandle=0x%x, sgImageId=0x%lx newImageInfo=0x%x",
+ imageSize.iWidth, imageSize.iHeight, vgHandle, sgImageId, newImageInfo);
+ if (newImageInfo == NULL)
+ {
+ error = VG_OUT_OF_MEMORY_ERROR;
+ OpenVgState.EglImageClose((EGLImageKHR) aImage);
+ }
+ else
+ {
+ if (OpenVgState.AddToHashMap(iVgContext, newImageInfo, vgHandle))
+ {
+ // Notify Command Scheduler & KhronosWrappers
+ RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+ vgApiData.Init(OpenVgRFC::EvgCreateEGLImageTargetKHR, RemoteFunctionCallData::EOpRequestWithReply);
+ vgApiData.AppendParam(aImage);
+ // ToDo any other parameters needed? Is this really a Request with Reply?
+ iVgContext.ExecuteVgCommand(vgApiData);
+ return newImageInfo->ClientHandle();
+ }
+ newImageInfo->Destroy(iVgContext);
+ }
+ }
+ }
+
+
+ if (error != VG_NO_ERROR)
+ {
+ iVgContext.SetVgError(error);
+ OPENVG_TRACE("TGuestOpenVg::vgCreateEGLImageTargetKHR fail - error=0x%x", error);
+ }
+
+ return VG_INVALID_HANDLE;
+ }
+
+
+
+
+// **** Desirable: could check VGParamType for vgGet & vgSet scalar & vector operations.
+/*
+ // Mode settings
+ VG_MATRIX_MODE ???
+ VG_FILL_RULE ???
+ VG_IMAGE_QUALITY ???
+ VG_RENDERING_QUALITY ???
+ VG_BLEND_MODE ???
+ VG_IMAGE_MODE ???
+
+ // Scissoring rectangles
+ VG_SCISSOR_RECTS ???
+
+ // Color Transformation
+ VG_COLOR_TRANSFORM ???
+ VG_COLOR_TRANSFORM_VALUES ???
+
+ // Stroke parameters
+ VG_STROKE_LINE_WIDTH ???
+ VG_STROKE_CAP_STYLE ???
+ VG_STROKE_JOIN_STYLE ???
+ VG_STROKE_MITER_LIMIT ???
+ VG_STROKE_DASH_PATTERN ???
+ VG_STROKE_DASH_PHASE ???
+ VG_STROKE_DASH_PHASE_RESET ???
+
+ // Edge fill color for VG_TILE_FILL tiling mode
+ VG_TILE_FILL_COLOR ???
+
+ // Color for vgClear
+ VG_CLEAR_COLOR ???
+
+ // Glyph origin
+ VG_GLYPH_ORIGIN ???
+
+ // Enable/disable alpha masking and scissoring
+ VG_MASKING ???
+ VG_SCISSORING ???
+
+ // Pixel layout information
+ VG_PIXEL_LAYOUT ???
+ VG_SCREEN_LAYOUT ???
+
+ // Source format selection for image filters
+ VG_FILTER_FORMAT_LINEAR ???
+ VG_FILTER_FORMAT_PREMULTIPLIED ???
+
+ // Destination write enable mask for image filters
+ VG_FILTER_CHANNEL_MASK ???
+
+ // Implementation limits (read-only)
+ VG_MAX_SCISSOR_RECTS, ReadOnly, Scalar
+ VG_MAX_DASH_COUNT ???
+ VG_MAX_KERNEL_SIZE ???
+ VG_MAX_SEPARABLE_KERNEL_SIZE ???
+ VG_MAX_COLOR_RAMP_STOPS ???
+ VG_MAX_IMAGE_WIDTH ???
+ VG_MAX_IMAGE_HEIGHT ???
+ VG_MAX_IMAGE_PIXELS ???
+ VG_MAX_IMAGE_BYTES ???
+ VG_MAX_FLOAT ???
+ VG_MAX_GAUSSIAN_STD_DEVIATION ???
+ */
+
+//////////////////////////////////////////////////////////////////////////
+
+// end of file vgstate.cpp