|
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 // Client-side state information for Symbian DLL |
|
15 |
|
16 #include "vgstate.h" |
|
17 #include "remotefunctioncall.h" |
|
18 #include "openvgrfc.h" |
|
19 |
|
20 |
|
21 |
|
22 // VG Client-side state is Writeable Static Data in the DLL, (holds state information for the process) |
|
23 // Constructor/Destructor called on process load/unload to perform initialiser/release of static resources |
|
24 XOpenVgState OpenVgState; |
|
25 |
|
26 |
|
27 |
|
28 _LIT(KVgPanicCategory, "Guest VG"); |
|
29 |
|
30 void VgPanic(TVgPanic aPanicCode, char* aPanicName, char* aCondition, char* aFile, TInt aLine) |
|
31 { |
|
32 if (aPanicName && aCondition && aFile) |
|
33 { // normal for Debug builds |
|
34 RDebug::Printf("Guest Open VG DLL Panic %s for failed Assert (%s),\n\tat %s:%d", aPanicName, aCondition, aFile, aLine); |
|
35 } |
|
36 else if (aPanicName && aFile) |
|
37 { // Debug builds Assert Always |
|
38 RDebug::Printf("Guest Open VG DLL Panic %s at %s:%d", aPanicName, aFile, aLine); |
|
39 } |
|
40 else |
|
41 { // normal for Release builds |
|
42 RDebug::Printf("Guest Open VG DLL Panic %d (line %d)", aPanicCode, aLine); |
|
43 } |
|
44 |
|
45 User::Panic(KVgPanicCategory, aPanicCode); |
|
46 } |
|
47 |
|
48 |
|
49 |
|
50 ///////////////////////////////////////////////////////////////////////////////////////////// |
|
51 // TCheck - parameter checking utility functions |
|
52 ///////////////////////////////////////////////////////////////////////////////////////////// |
|
53 |
|
54 |
|
55 /* |
|
56 aWidth & aHeight parameters must be >0, also ax, ay, aX + aWidth and aY + aHeight must all |
|
57 be within image size, otherwise a VG_ILLEGAL_ARGUMENT_ERROR is flagged. |
|
58 */ |
|
59 TBool TCheck::ChkAreaIsWithinImage(MVgContext& aVgContext, CVgImageBase* aImageInfo, VGint aX, VGint aY, VGint aWidth, VGint aHeight) |
|
60 { |
|
61 VGPANIC_ASSERT_DEBUG(aImageInfo, EVgPanicTemp); |
|
62 if ( (aX >= 0) && (aY >= 0) && (aWidth > 0) && (aHeight > 0) ) |
|
63 { |
|
64 VGint maxX = aWidth + aX; |
|
65 VGint maxY = aHeight + aY; |
|
66 if ( (maxX > 0) && (maxY > 0) && (aImageInfo->Width() >= maxX) && (aImageInfo->Height() >= maxY) ) |
|
67 { |
|
68 return ETrue; |
|
69 } |
|
70 } |
|
71 OPENVG_TRACE("TCheck::ChkAreaIsWithinImage setting VG_ILLEGAL_ARGUMENT_ERROR"); |
|
72 aVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR); |
|
73 return EFalse; |
|
74 } |
|
75 |
|
76 |
|
77 VGint TCheck::ImageFormatByteDepth(VGImageFormat aImageFormat) |
|
78 { |
|
79 switch (aImageFormat) |
|
80 { |
|
81 case VG_sRGBX_8888: |
|
82 case VG_sRGBA_8888: |
|
83 case VG_sRGBA_8888_PRE: |
|
84 case VG_lRGBX_8888: |
|
85 case VG_lRGBA_8888: |
|
86 case VG_lRGBA_8888_PRE: |
|
87 case VG_sXRGB_8888: |
|
88 case VG_sARGB_8888: |
|
89 case VG_sARGB_8888_PRE: |
|
90 case VG_lXRGB_8888: |
|
91 case VG_lARGB_8888: |
|
92 case VG_lARGB_8888_PRE: |
|
93 case VG_sBGRX_8888: |
|
94 case VG_sBGRA_8888: |
|
95 case VG_sBGRA_8888_PRE: |
|
96 case VG_lBGRX_8888: |
|
97 case VG_lBGRA_8888: |
|
98 case VG_lBGRA_8888_PRE: |
|
99 case VG_sXBGR_8888: |
|
100 case VG_sABGR_8888: |
|
101 case VG_sABGR_8888_PRE: |
|
102 case VG_lXBGR_8888: |
|
103 case VG_lABGR_8888: |
|
104 case VG_lABGR_8888_PRE: |
|
105 return 4; |
|
106 case VG_sRGB_565: |
|
107 case VG_sRGBA_5551: |
|
108 case VG_sRGBA_4444: |
|
109 case VG_sARGB_1555: |
|
110 case VG_sARGB_4444: |
|
111 case VG_sBGR_565: |
|
112 case VG_sBGRA_5551: |
|
113 case VG_sBGRA_4444: |
|
114 case VG_sABGR_1555: |
|
115 case VG_sABGR_4444: |
|
116 return 2; |
|
117 case VG_sL_8: |
|
118 case VG_lL_8: |
|
119 case VG_A_8: |
|
120 case VG_A_4: |
|
121 case VG_A_1: |
|
122 case VG_BW_1: |
|
123 return 1; |
|
124 case VG_IMAGE_FORMAT_INVALID: |
|
125 default: |
|
126 return 0; |
|
127 } |
|
128 } |
|
129 |
|
130 |
|
131 // Checks aCount & aValues for SetParameteriv & SetParameterfv |
|
132 TBool TCheck::ChkParamCountAndValuesPtr(MVgContext& aVgContext, VGint aCount, const void* aValues) |
|
133 { |
|
134 VGErrorCode error = VG_NO_ERROR; |
|
135 if (aValues == NULL) |
|
136 { |
|
137 if (aCount != 0) |
|
138 { |
|
139 error = VG_ILLEGAL_ARGUMENT_ERROR; |
|
140 } |
|
141 } |
|
142 // we should check count for not being too large for serialization, but |
|
143 // there is no limit in spec for VG_SCISSOR_RECTS and VG_STROKE_DASH_PATTERN |
|
144 else if ( (3ul & (unsigned)aValues) || (aCount < 0) || (aCount > 100000) ) |
|
145 { |
|
146 error = VG_ILLEGAL_ARGUMENT_ERROR; |
|
147 } |
|
148 |
|
149 if (error != VG_NO_ERROR) |
|
150 { |
|
151 OPENVG_TRACE("TCheck::ChkParamCountAndValuesPtr setting error=0x%x", error); |
|
152 aVgContext.SetVgError(error); |
|
153 return EFalse; |
|
154 } |
|
155 return ETrue; |
|
156 } |
|
157 |
|
158 |
|
159 ///////////////////////////////////////////////////////////////////////////////////////////// |
|
160 // XOpenVgState |
|
161 ///////////////////////////////////////////////////////////////////////////////////////////// |
|
162 |
|
163 // Singleton object is in WSD memory, so this Constructor is called when the DLL is loaded |
|
164 XOpenVgState::XOpenVgState() : |
|
165 iEglManagementApi(NULL), iKVgMaxKernelSize(0), iKVgMaxSeparableKernelSize(0) |
|
166 { |
|
167 OPENVG_TRACE("XOpenVgState::XOpenVgState 1. start Process=0x%lx, Thread=0x%lx", RProcess().Id().Id(), RThread().Id().Id()); |
|
168 |
|
169 TInt createErr1 = iStateLock.CreateLocal(EOwnerProcess); |
|
170 OPENVG_TRACE("XOpenVgState::XOpenVgState 2. iStateLock.CreateLocal error=%d, Handle=0x%x", createErr1, iStateLock.Handle()); |
|
171 |
|
172 TInt createErr2 = iMapLock.CreateLocal(EOwnerProcess); |
|
173 OPENVG_TRACE("XOpenVgState::XOpenVgState 2. iMapLock.CreateLocal error=%d, Handle=0x%x", createErr2, iMapLock.Handle()); |
|
174 // cannot continue if there is an error, so Panic |
|
175 VGPANIC_ASSERT( (createErr1 == KErrNone) && (createErr2 == KErrNone), EVgPanicTemp); |
|
176 |
|
177 CVgHandleBase::InitStatics(); |
|
178 |
|
179 // publish MVgApiforEgl vtable |
|
180 CVghwUtils::SetVgApiForEgl(this); |
|
181 } |
|
182 |
|
183 |
|
184 // Desstructor is called when the DLL is unloaded |
|
185 XOpenVgState::~XOpenVgState() |
|
186 { |
|
187 OPENVG_TRACE("XOpenVgState::~XOpenVgState 1. iStateLock handle=0x%x, iMapLock handle=0x%x, Process=0x%lx, Thread=0x%lx", |
|
188 iStateLock.Handle(), iMapLock.Handle(), RProcess().Id().Id(), RThread().Id().Id()); |
|
189 |
|
190 if (iStateLock.Handle()) |
|
191 { |
|
192 iStateLock.Close(); |
|
193 OPENVG_TRACE("XOpenVgState::~XOpenVgState 2. iStateLock Handle=0x%x", iStateLock.Handle()); |
|
194 } |
|
195 if (iMapLock.Handle()) |
|
196 { |
|
197 iMapLock.Close(); |
|
198 OPENVG_TRACE("XOpenVgState::~XOpenVgState 3. iMapLock Handle=0x%x", iMapLock.Handle()); |
|
199 } |
|
200 |
|
201 // unpublish MVgApiforEgl vtable |
|
202 CVghwUtils::SetVgApiForEgl(NULL); |
|
203 } |
|
204 |
|
205 |
|
206 TBool XOpenVgState::CheckVGHandle(MVgContext& aVgContext, VGHandle aHandle, CVgHandleBase** aHandleInfo, TVgHandleType aMatchType) |
|
207 { // client side VGHandle is an opaque data handle to Host Open VG objects such as VGPath or VGImage |
|
208 // only check for logic errors in VG code in Debug builds |
|
209 VGPANIC_ASSERT_DEBUG(iStateLock.IsHeld(), EVgPanicStateLockMutexNotHeld); |
|
210 VGPANIC_ASSERT_DEBUG(aHandleInfo, EVgPanicFunctionParameterIsNull); |
|
211 |
|
212 if (aHandle != VG_INVALID_HANDLE) |
|
213 { |
|
214 iMapLock.Wait(); |
|
215 CVgHandleBase** pHandleInfo = iHandleHashMap.Find(aHandle); |
|
216 if (pHandleInfo) |
|
217 { |
|
218 CVgHandleBase* handleInfo = *pHandleInfo; |
|
219 if (handleInfo && !handleInfo->IsDestroyed() && |
|
220 ( (aMatchType == EVgHandleAny) || (aMatchType == handleInfo->HandleType()) ) ) |
|
221 { |
|
222 // ToDo confirm handle belongs to this context or is shared with this context |
|
223 *aHandleInfo = handleInfo; |
|
224 OPENVG_TRACE(" XOpenVgState::CheckVGHandle client handle=0x%x, match type=%d; found matching Host VG Handle=0x%x", |
|
225 aHandle, aMatchType, handleInfo->HostHandle()); |
|
226 iMapLock.Signal(); |
|
227 return ETrue; |
|
228 } |
|
229 } |
|
230 iMapLock.Signal(); |
|
231 } |
|
232 OPENVG_TRACE(" XOpenVgState::CheckVGHandle client handle=0x%x, match type=%d, setting VG_BAD_HANDLE_ERROR", aHandle, aMatchType); |
|
233 aVgContext.SetVgError(VG_BAD_HANDLE_ERROR); |
|
234 return EFalse; |
|
235 } |
|
236 |
|
237 |
|
238 /* |
|
239 aKernelWidth or aKernelHeight must be >0 and <= [Size Limit], otherwise a VG_ILLEGAL_ARGUMENT_ERROR is flagged |
|
240 */ |
|
241 TBool XOpenVgState::CheckKernelWidthAndHeight(MVgContext& aVgContext, VGint aKernelWidth, VGint aKernelHeight, VGParamType aLimitType) |
|
242 { |
|
243 VGPANIC_ASSERT_DEBUG(iStateLock.IsHeld(), EVgPanicStateLockMutexNotHeld); |
|
244 VGint limit = 0; |
|
245 // aLimitType must be either VG_MAX_KERNEL_SIZE or VG_MAX_SEPARABLE_KERNEL_SIZE |
|
246 if (aLimitType == VG_MAX_KERNEL_SIZE) |
|
247 { |
|
248 if (iKVgMaxKernelSize == 0) |
|
249 { // first access, so fetch value from Host |
|
250 iKVgMaxKernelSize = TGuestOpenVg::HostGeti(aVgContext, VG_MAX_KERNEL_SIZE); |
|
251 } |
|
252 limit = iKVgMaxKernelSize; |
|
253 } |
|
254 else if (aLimitType == VG_MAX_SEPARABLE_KERNEL_SIZE) |
|
255 { |
|
256 if (iKVgMaxSeparableKernelSize == 0) |
|
257 { // first access, so fetch value from Host |
|
258 iKVgMaxSeparableKernelSize = TGuestOpenVg::HostGeti(aVgContext, VG_MAX_SEPARABLE_KERNEL_SIZE); |
|
259 } |
|
260 limit = iKVgMaxSeparableKernelSize; |
|
261 } |
|
262 VGPANIC_ASSERT(limit > 0, EVgPanicValueFromHostVgIsInvalid); |
|
263 |
|
264 if ( (aKernelHeight > 0) && (aKernelHeight <= limit) && (aKernelWidth > 0) && (aKernelWidth <= limit) ) |
|
265 { |
|
266 return ETrue; |
|
267 } |
|
268 OPENVG_TRACE("XOpenVgState::CheckKernelWidthAndHeight setting VG_ILLEGAL_ARGUMENT_ERROR"); |
|
269 aVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR); |
|
270 return EFalse; |
|
271 } |
|
272 |
|
273 |
|
274 TBool XOpenVgState::AddToHashMap(MVgContext& aVgContext, CVgHandleBase* aHandleInfo, VGHandle aHostHandle) |
|
275 { |
|
276 VGPANIC_ASSERT_DEBUG(iStateLock.IsHeld(), EVgPanicStateLockMutexNotHeld); |
|
277 |
|
278 OPENVG_TRACE(" XOpenVgState::AddToHashMap aHandleInfo=0x%x, aHostHandle=0x%x, ClientHandle=0x%x", |
|
279 aHandleInfo, aHostHandle, aHandleInfo->ClientHandle()); |
|
280 aHandleInfo->SetHostHandle(aHostHandle); |
|
281 |
|
282 iMapLock.Wait(); |
|
283 RHeap* clientHeap = CVghwUtils::SwitchToVghwHeap(); |
|
284 // ClientHandle is key to finding object, its Host Handle, object type, etc... |
|
285 TInt err = iHandleHashMap.Insert(aHandleInfo->ClientHandle(), aHandleInfo); |
|
286 CVghwUtils::SwitchFromVghwHeap(clientHeap); |
|
287 iMapLock.Signal(); |
|
288 |
|
289 if (err == KErrNone) |
|
290 { |
|
291 return ETrue; |
|
292 } |
|
293 |
|
294 // Failed, Cleanup ... |
|
295 OPENVG_TRACE(" XOpenVgState::AddToHashMap insert error = %d", err); |
|
296 aVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR); |
|
297 return EFalse; |
|
298 } |
|
299 |
|
300 |
|
301 void XOpenVgState::UnMapHandle(TUint32 aClientHandle) |
|
302 { |
|
303 OPENVG_TRACE(" XOpenVgState::UnMapHandle aHandleInfo=0x%x -->", aClientHandle); |
|
304 VGPANIC_ASSERT_DEBUG(iStateLock.IsHeld(), EVgPanicStateLockMutexNotHeld); |
|
305 VGPANIC_ASSERT_DEBUG( CVghwUtils::UsingVghwHeap(), EVgPanicTemp); |
|
306 |
|
307 iMapLock.Wait(); |
|
308 #ifdef _DEBUG |
|
309 TInt dbgErr = |
|
310 #endif |
|
311 iHandleHashMap.Remove(aClientHandle); |
|
312 iMapLock.Signal(); |
|
313 |
|
314 OPENVG_TRACE(" XOpenVgState::UnMapHandle ... dbgErr =%d <--", dbgErr); |
|
315 } |
|
316 |
|
317 |
|
318 TBool XOpenVgState::EglImageOpenForVgImage(EGLImageKHR aImage, TSize& aSize, VGHandle& aVgHandle, TUint64& aSgImageId) |
|
319 { |
|
320 if (!iEglManagementApi) |
|
321 { // try to get EGL interface via VghwUtils |
|
322 iEglManagementApi = CVghwUtils::EglManagementApi(); |
|
323 VGPANIC_ASSERT_DEBUG(iEglManagementApi, EVgPanicMissingEglInterface); |
|
324 } |
|
325 if (iEglManagementApi) |
|
326 { |
|
327 return iEglManagementApi->EglImageOpenForVgImage(aImage, aSize, aVgHandle, aSgImageId); |
|
328 } |
|
329 return EFalse; |
|
330 } |
|
331 |
|
332 |
|
333 void XOpenVgState::EglImageClose(EGLImageKHR aImage) |
|
334 { |
|
335 if (iEglManagementApi) |
|
336 { |
|
337 iEglManagementApi->EglImageClose(aImage); |
|
338 } |
|
339 } |
|
340 |
|
341 |
|
342 // Guest Open VG extension export support for eglGetProcAddress |
|
343 typedef struct |
|
344 { |
|
345 const char* procName; // procedure name |
|
346 ExtensionProcPointer procAddr; |
|
347 } TVgExtnInfo; |
|
348 |
|
349 // VG extension functions |
|
350 static const TVgExtnInfo vgProcedures[] = |
|
351 { |
|
352 { "vgCreateEGLImageTargetKHR", (ExtensionProcPointer)vgCreateEGLImageTargetKHR }, |
|
353 }; |
|
354 |
|
355 const TInt KVgProcCount = sizeof(vgProcedures) / sizeof(TVgExtnInfo); |
|
356 |
|
357 ExtensionProcPointer XOpenVgState::guestGetVgProcAddress (const char *aProcName) |
|
358 { |
|
359 // exhaustive search |
|
360 for (TInt idx = 0; idx < KVgProcCount; idx++) |
|
361 { |
|
362 if (!strcmp(aProcName, vgProcedures[idx].procName)) |
|
363 return vgProcedures[idx].procAddr; |
|
364 } |
|
365 return NULL; |
|
366 } |
|
367 |
|
368 |
|
369 ///////////////////////////////////////////////////////////////////////////////////////////// |
|
370 // TCleanupVgLocks |
|
371 ///////////////////////////////////////////////////////////////////////////////////////////// |
|
372 |
|
373 TCleanupVgLocks::TCleanupVgLocks(MVgContext& aVgContext) : |
|
374 iVgContext(aVgContext), iMutex(OpenVgState.MutexWait()), iIsHeld(ETrue) |
|
375 {} |
|
376 |
|
377 TCleanupVgLocks::~TCleanupVgLocks() |
|
378 { |
|
379 if (iIsHeld) |
|
380 { |
|
381 SignalMutex(); |
|
382 } |
|
383 } |
|
384 |
|
385 void TCleanupVgLocks::SignalMutex() |
|
386 { |
|
387 VGPANIC_ASSERT_DEBUG(iIsHeld && iMutex.IsHeld(), EVgPanicTemp); |
|
388 iMutex.Signal(); |
|
389 iIsHeld = EFalse; |
|
390 } |
|
391 |
|
392 |
|
393 /* |
|
394 Returns false & sets VG error to VG_ILLEGAL_ARGUMENT_ERROR if VGMaskOperation is not a supported operation |
|
395 */ |
|
396 TBool TCleanupVgLocks::CheckVGMaskOperationAndHandle(VGMaskOperation aOperation, VGHandle aMask, CVgImageBase** aHandleInfo) |
|
397 { |
|
398 VGPANIC_ASSERT_DEBUG(iIsHeld, EVgPanicStateLockMutexNotHeld); |
|
399 *aHandleInfo = NULL; |
|
400 switch (aOperation) |
|
401 { |
|
402 case VG_CLEAR_MASK: |
|
403 case VG_FILL_MASK: |
|
404 // aMask is not used for these operations |
|
405 return ETrue; |
|
406 case VG_SET_MASK: |
|
407 case VG_UNION_MASK: |
|
408 case VG_INTERSECT_MASK: |
|
409 case VG_SUBTRACT_MASK: |
|
410 { |
|
411 if (aMask == VG_INVALID_HANDLE) |
|
412 return ETrue; |
|
413 |
|
414 CVgHandleBase* tempInfo; |
|
415 if (CheckVGAnyHandle(aMask, &tempInfo)) |
|
416 { |
|
417 if ( (tempInfo->HandleType() == EVgHandleForMaskLayer) || (tempInfo->HandleType() == EVgHandleForImage) ) |
|
418 { |
|
419 *aHandleInfo = (CVgImageBase*)tempInfo; |
|
420 // TODO if handle is a VgImage verify that it is not a rendering target |
|
421 return ETrue; |
|
422 } |
|
423 OPENVG_TRACE("TCleanupVgLocks::CheckVGMaskOperationAndHandle setting VG_BAD_HANDLE_ERROR"); |
|
424 iVgContext.SetVgError(VG_BAD_HANDLE_ERROR); |
|
425 } |
|
426 return EFalse; |
|
427 } |
|
428 default: |
|
429 OPENVG_TRACE("TCleanupVgLocks::CheckVGMaskOperationAndHandle setting VG_ILLEGAL_ARGUMENT_ERROR"); |
|
430 iVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR); |
|
431 return EFalse; |
|
432 } |
|
433 } |
|
434 |
|
435 |
|
436 VGFont TCleanupVgLocks::CreateFont(VGint aGlyphCapacityHint) |
|
437 { |
|
438 VGPANIC_ASSERT_DEBUG(iIsHeld && iMutex.IsHeld(), EVgPanicTemp); |
|
439 |
|
440 CVgFontInfo* fontInfo = CVgFontInfo::New(); |
|
441 if (fontInfo == NULL) |
|
442 { |
|
443 OPENVG_TRACE(" TGuestOpenVg::vgCreateFont - CVgFontInfo::New() failed"); |
|
444 iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR); |
|
445 } |
|
446 else |
|
447 { |
|
448 RemoteFunctionCallData data; OpenVgRFC vgApiData(data); |
|
449 vgApiData.Init(OpenVgRFC::EvgCreateFont); |
|
450 vgApiData.AppendParam(aGlyphCapacityHint); |
|
451 VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode); |
|
452 iVgContext.ExecuteVgCommand(vgApiData); |
|
453 VGFont hostFont = static_cast<VGFont>(vgApiData.ReturnValue()); |
|
454 OPENVG_TRACE(" TCleanupVgLocks::CreateFont - CVgFontInfo::New() success, hostFont=0x%x", hostFont); |
|
455 |
|
456 if ( (hostFont != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, fontInfo, hostFont) ) |
|
457 { |
|
458 return fontInfo->ClientHandle(); |
|
459 } |
|
460 |
|
461 fontInfo->Destroy(iVgContext); |
|
462 } |
|
463 |
|
464 return VG_INVALID_HANDLE; |
|
465 } |
|
466 |
|
467 |
|
468 VGImage TCleanupVgLocks::ChildImage(CVgImageInfo& aParentInfo, VGint aX, VGint aY, VGint aWidth, VGint aHeight) |
|
469 { |
|
470 CVgImageInfo* imageInfo = CVgImageInfo::New(aWidth, aHeight, &aParentInfo); |
|
471 if (imageInfo == NULL) |
|
472 { |
|
473 iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR); |
|
474 OPENVG_TRACE(" TCleanupVgLocks::ChildImage - CVgImageInfo::New() failed"); |
|
475 } |
|
476 else |
|
477 { |
|
478 RemoteFunctionCallData data; OpenVgRFC vgApiData(data); |
|
479 vgApiData.Init(OpenVgRFC::EvgChildImage); |
|
480 vgApiData.AppendParam(aParentInfo.HostHandle()); |
|
481 vgApiData.AppendParam(aX); |
|
482 vgApiData.AppendParam(aY); |
|
483 vgApiData.AppendParam(aWidth); |
|
484 vgApiData.AppendParam(aHeight); |
|
485 VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode); |
|
486 iVgContext.ExecuteVgCommand(vgApiData); |
|
487 VGImage hostImageHandle = static_cast<VGImage>(vgApiData.ReturnValue()); |
|
488 |
|
489 OPENVG_TRACE(" TCleanupVgLocks::ChildImage - CVgImageInfo::New() success, hostImageHandle=0x%x", hostImageHandle); |
|
490 if ( (hostImageHandle != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, imageInfo, hostImageHandle) ) |
|
491 { |
|
492 return imageInfo->ClientHandle(); |
|
493 } |
|
494 imageInfo->Destroy(iVgContext); |
|
495 } |
|
496 |
|
497 return VG_INVALID_HANDLE; |
|
498 } |
|
499 |
|
500 |
|
501 VGImage TCleanupVgLocks::CreateImage(VGImageFormat aFormat, VGint aWidth, VGint aHeight, VGbitfield aAllowedQuality) |
|
502 { |
|
503 CVgImageInfo* imageInfo = CVgImageInfo::New(aFormat, aWidth, aHeight, aAllowedQuality); |
|
504 if (imageInfo == NULL) |
|
505 { |
|
506 iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR); |
|
507 OPENVG_TRACE(" TCleanupVgLocks::CreateImage - CVgImageInfo::New() failed"); |
|
508 } |
|
509 else |
|
510 { |
|
511 RemoteFunctionCallData data; OpenVgRFC vgApiData(data); |
|
512 vgApiData.Init(OpenVgRFC::EvgCreateImage); |
|
513 vgApiData.AppendParam(aFormat); |
|
514 vgApiData.AppendParam(aWidth); |
|
515 vgApiData.AppendParam(aHeight); |
|
516 vgApiData.AppendParam(aAllowedQuality); |
|
517 VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode); |
|
518 iVgContext.ExecuteVgCommand(vgApiData); |
|
519 VGImage hostImageHandle = static_cast<VGImage>(vgApiData.ReturnValue()); |
|
520 |
|
521 OPENVG_TRACE(" TCleanupVgLocks::CreateImage - CVgImageInfo::New() success, hostImageHandle=0x%x", hostImageHandle); |
|
522 if ( (hostImageHandle != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, imageInfo, hostImageHandle) ) |
|
523 { |
|
524 return imageInfo->ClientHandle(); |
|
525 } |
|
526 imageInfo->Destroy(iVgContext); |
|
527 } |
|
528 |
|
529 return VG_INVALID_HANDLE; |
|
530 } |
|
531 |
|
532 |
|
533 VGMaskLayer TCleanupVgLocks::CreateMaskLayer(VGint aWidth, VGint aHeight) |
|
534 { |
|
535 CVgMaskLayerInfo* maskLayerInfo = CVgMaskLayerInfo::New(aWidth, aHeight); |
|
536 if (maskLayerInfo == NULL) |
|
537 { |
|
538 OPENVG_TRACE(" TCleanupVgLocks::CreateMaskLayer - CVgMaskLayerInfo::New() failed"); |
|
539 iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR); |
|
540 } |
|
541 else |
|
542 { |
|
543 RemoteFunctionCallData data; OpenVgRFC vgApiData(data); |
|
544 vgApiData.Init(OpenVgRFC::EvgCreateMaskLayer); |
|
545 vgApiData.AppendParam(aWidth); |
|
546 vgApiData.AppendParam(aHeight); |
|
547 VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode); |
|
548 iVgContext.ExecuteVgCommand(vgApiData); |
|
549 VGMaskLayer hostMaskHandle = static_cast<VGMaskLayer>(vgApiData.ReturnValue()); |
|
550 |
|
551 OPENVG_TRACE(" TCleanupVgLocks::CreateMaskLayer - CVgMaskLayerInfo::New() success, hostMaskHandle=0x%x", hostMaskHandle); |
|
552 if ( (hostMaskHandle != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, maskLayerInfo, hostMaskHandle) ) |
|
553 { |
|
554 return maskLayerInfo->ClientHandle(); |
|
555 } |
|
556 maskLayerInfo->Destroy(iVgContext); |
|
557 } |
|
558 |
|
559 return VG_INVALID_HANDLE; |
|
560 } |
|
561 |
|
562 |
|
563 VGPaint TCleanupVgLocks::CreatePaint() |
|
564 { |
|
565 CVgPaintInfo* paintInfo = CVgPaintInfo::New(); |
|
566 if (paintInfo == NULL) |
|
567 { |
|
568 OPENVG_TRACE(" TCleanupVgLocks::CreatePaint - CVgPaintInfo::New() failed"); |
|
569 iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR); |
|
570 } |
|
571 else |
|
572 { |
|
573 RemoteFunctionCallData data; OpenVgRFC vgApiData(data); |
|
574 vgApiData.Init(OpenVgRFC::EvgCreatePaint); |
|
575 VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode); |
|
576 iVgContext.ExecuteVgCommand(vgApiData); |
|
577 VGPaint hostPaint = static_cast<VGPaint>(vgApiData.ReturnValue()); |
|
578 |
|
579 OPENVG_TRACE(" TCleanupVgLocks::CreatePaint - CVgPaintInfo::New() success, clientHandle=0x%x, hostHandle=0x%x", |
|
580 paintInfo->ClientHandle(), hostPaint); |
|
581 if ( (hostPaint != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, paintInfo, hostPaint) ) |
|
582 { |
|
583 return paintInfo->ClientHandle(); |
|
584 } |
|
585 paintInfo->Destroy(iVgContext); |
|
586 } |
|
587 |
|
588 return VG_INVALID_HANDLE; |
|
589 } |
|
590 |
|
591 |
|
592 VGPaint TCleanupVgLocks::GetPaint(VGPaintMode aPaintMode) |
|
593 { |
|
594 CVgPaintInfo* paintInfo = CVgPaintInfo::New(); |
|
595 if (paintInfo == NULL) |
|
596 { |
|
597 iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR); |
|
598 OPENVG_TRACE(" TCleanupVgLocks::GetPaint - CVgPaintInfo::New() failed"); |
|
599 } |
|
600 else |
|
601 { |
|
602 RemoteFunctionCallData rfcdata; OpenVgRFC vgApiData(rfcdata); |
|
603 vgApiData.Init(OpenVgRFC::EvgGetPaint); |
|
604 vgApiData.AppendParam(aPaintMode); |
|
605 VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode); |
|
606 iVgContext.ExecuteVgCommand(vgApiData); |
|
607 VGPaint hostPaint = static_cast<VGPaint>(vgApiData.ReturnValue()); |
|
608 |
|
609 OPENVG_TRACE(" TCleanupVgLocks::GetPaint - CVgPaintInfo::New() success, clientHandle=0x%x, hostHandle=0x%x", |
|
610 paintInfo->ClientHandle(), hostPaint); |
|
611 if ( (hostPaint != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, paintInfo, hostPaint) ) |
|
612 { |
|
613 return paintInfo->ClientHandle(); |
|
614 } |
|
615 paintInfo->Destroy(iVgContext); |
|
616 } |
|
617 |
|
618 return VG_INVALID_HANDLE; |
|
619 } |
|
620 |
|
621 |
|
622 VGPath TCleanupVgLocks::CreatePath(VGint aPathFormat, VGPathDatatype aDatatype, VGfloat aScale, VGfloat aBias, |
|
623 VGint aSegmentCapacityHint, VGint aCoordCapacityHint, VGbitfield aCapabilities) |
|
624 { |
|
625 VGPANIC_ASSERT_DEBUG(iIsHeld && iMutex.IsHeld(), EVgPanicTemp); |
|
626 |
|
627 aCapabilities &= VG_PATH_CAPABILITY_ALL; |
|
628 CVgPathInfo* pathInfo = CVgPathInfo::New(aDatatype, aScale, aBias, aCapabilities); |
|
629 if (pathInfo == NULL) |
|
630 { |
|
631 OPENVG_TRACE(" TCleanupVgLocks::CreatePath - CVgPathInfo::New() failed"); |
|
632 iVgContext.SetVgError(VG_OUT_OF_MEMORY_ERROR); |
|
633 } |
|
634 else |
|
635 { |
|
636 RemoteFunctionCallData data; OpenVgRFC vgApiData(data); |
|
637 vgApiData.Init(OpenVgRFC::EvgCreatePath); |
|
638 vgApiData.AppendParam(aPathFormat); |
|
639 vgApiData.AppendParam(aDatatype); |
|
640 vgApiData.AppendParam(aScale); |
|
641 vgApiData.AppendParam(aBias); |
|
642 vgApiData.AppendParam(aSegmentCapacityHint); |
|
643 vgApiData.AppendParam(aCoordCapacityHint); |
|
644 vgApiData.AppendParam(aCapabilities); |
|
645 VGPANIC_ASSERT_DEBUG(vgApiData.Data().Header().iOpType == RemoteFunctionCallData::EOpRequestWithReply, EVgPanicNotReplyOpcode); |
|
646 iVgContext.ExecuteVgCommand(vgApiData); |
|
647 VGPath hostPath = static_cast<VGPath>(vgApiData.ReturnValue()); |
|
648 OPENVG_TRACE(" TCleanupVgLocks::CreatePath - CVgPathInfo::New() success, hostHandle=0x%x", hostPath); |
|
649 |
|
650 if ( (hostPath != VG_INVALID_HANDLE) && OpenVgState.AddToHashMap(iVgContext, pathInfo, hostPath) ) |
|
651 { |
|
652 return pathInfo->ClientHandle(); |
|
653 } |
|
654 |
|
655 pathInfo->Destroy(iVgContext); |
|
656 } |
|
657 |
|
658 return VG_INVALID_HANDLE; |
|
659 } |
|
660 |
|
661 |
|
662 VGImage TCleanupVgLocks::CreateEGLImageTargetKHR(VGeglImageKHR aImage) |
|
663 { |
|
664 VGErrorCode error = VG_NO_ERROR; |
|
665 |
|
666 if (aImage == NULL) |
|
667 { |
|
668 error = VG_ILLEGAL_ARGUMENT_ERROR; |
|
669 } |
|
670 else |
|
671 { |
|
672 // Try to open EGL Image from handle, and get info such as image size |
|
673 TSize imageSize; |
|
674 TUint64 sgImageId; |
|
675 VGHandle vgHandle; |
|
676 if (!OpenVgState.EglImageOpenForVgImage((EGLImageKHR) aImage, imageSize, vgHandle, sgImageId)) |
|
677 { |
|
678 error = VG_UNSUPPORTED_IMAGE_FORMAT_ERROR; |
|
679 } |
|
680 else |
|
681 { // Open success, create a CVgImageInfo with all the details ... |
|
682 // ToDo get & store VGImageFormat of underlying VGImage |
|
683 CVgImageInfo* newImageInfo = CVgImageInfo::New(VG_IMAGE_FORMAT_INVALID, imageSize.iWidth, imageSize.iHeight, |
|
684 (EGLImageKHR) aImage, sgImageId); |
|
685 OPENVG_TRACE("TGuestOpenVg::vgCreateEGLImageTargetKHR imageSize=%d,%d, vgHandle=0x%x, sgImageId=0x%lx newImageInfo=0x%x", |
|
686 imageSize.iWidth, imageSize.iHeight, vgHandle, sgImageId, newImageInfo); |
|
687 if (newImageInfo == NULL) |
|
688 { |
|
689 error = VG_OUT_OF_MEMORY_ERROR; |
|
690 OpenVgState.EglImageClose((EGLImageKHR) aImage); |
|
691 } |
|
692 else |
|
693 { |
|
694 if (OpenVgState.AddToHashMap(iVgContext, newImageInfo, vgHandle)) |
|
695 { |
|
696 // Notify Command Scheduler & KhronosWrappers |
|
697 RemoteFunctionCallData data; OpenVgRFC vgApiData(data); |
|
698 vgApiData.Init(OpenVgRFC::EvgCreateEGLImageTargetKHR, RemoteFunctionCallData::EOpRequestWithReply); |
|
699 vgApiData.AppendParam(aImage); |
|
700 // ToDo any other parameters needed? Is this really a Request with Reply? |
|
701 iVgContext.ExecuteVgCommand(vgApiData); |
|
702 return newImageInfo->ClientHandle(); |
|
703 } |
|
704 newImageInfo->Destroy(iVgContext); |
|
705 } |
|
706 } |
|
707 } |
|
708 |
|
709 |
|
710 if (error != VG_NO_ERROR) |
|
711 { |
|
712 iVgContext.SetVgError(error); |
|
713 OPENVG_TRACE("TGuestOpenVg::vgCreateEGLImageTargetKHR fail - error=0x%x", error); |
|
714 } |
|
715 |
|
716 return VG_INVALID_HANDLE; |
|
717 } |
|
718 |
|
719 |
|
720 |
|
721 |
|
722 // **** Desirable: could check VGParamType for vgGet & vgSet scalar & vector operations. |
|
723 /* |
|
724 // Mode settings |
|
725 VG_MATRIX_MODE ??? |
|
726 VG_FILL_RULE ??? |
|
727 VG_IMAGE_QUALITY ??? |
|
728 VG_RENDERING_QUALITY ??? |
|
729 VG_BLEND_MODE ??? |
|
730 VG_IMAGE_MODE ??? |
|
731 |
|
732 // Scissoring rectangles |
|
733 VG_SCISSOR_RECTS ??? |
|
734 |
|
735 // Color Transformation |
|
736 VG_COLOR_TRANSFORM ??? |
|
737 VG_COLOR_TRANSFORM_VALUES ??? |
|
738 |
|
739 // Stroke parameters |
|
740 VG_STROKE_LINE_WIDTH ??? |
|
741 VG_STROKE_CAP_STYLE ??? |
|
742 VG_STROKE_JOIN_STYLE ??? |
|
743 VG_STROKE_MITER_LIMIT ??? |
|
744 VG_STROKE_DASH_PATTERN ??? |
|
745 VG_STROKE_DASH_PHASE ??? |
|
746 VG_STROKE_DASH_PHASE_RESET ??? |
|
747 |
|
748 // Edge fill color for VG_TILE_FILL tiling mode |
|
749 VG_TILE_FILL_COLOR ??? |
|
750 |
|
751 // Color for vgClear |
|
752 VG_CLEAR_COLOR ??? |
|
753 |
|
754 // Glyph origin |
|
755 VG_GLYPH_ORIGIN ??? |
|
756 |
|
757 // Enable/disable alpha masking and scissoring |
|
758 VG_MASKING ??? |
|
759 VG_SCISSORING ??? |
|
760 |
|
761 // Pixel layout information |
|
762 VG_PIXEL_LAYOUT ??? |
|
763 VG_SCREEN_LAYOUT ??? |
|
764 |
|
765 // Source format selection for image filters |
|
766 VG_FILTER_FORMAT_LINEAR ??? |
|
767 VG_FILTER_FORMAT_PREMULTIPLIED ??? |
|
768 |
|
769 // Destination write enable mask for image filters |
|
770 VG_FILTER_CHANNEL_MASK ??? |
|
771 |
|
772 // Implementation limits (read-only) |
|
773 VG_MAX_SCISSOR_RECTS, ReadOnly, Scalar |
|
774 VG_MAX_DASH_COUNT ??? |
|
775 VG_MAX_KERNEL_SIZE ??? |
|
776 VG_MAX_SEPARABLE_KERNEL_SIZE ??? |
|
777 VG_MAX_COLOR_RAMP_STOPS ??? |
|
778 VG_MAX_IMAGE_WIDTH ??? |
|
779 VG_MAX_IMAGE_HEIGHT ??? |
|
780 VG_MAX_IMAGE_PIXELS ??? |
|
781 VG_MAX_IMAGE_BYTES ??? |
|
782 VG_MAX_FLOAT ??? |
|
783 VG_MAX_GAUSSIAN_STD_DEVIATION ??? |
|
784 */ |
|
785 |
|
786 ////////////////////////////////////////////////////////////////////////// |
|
787 |
|
788 // end of file vgstate.cpp |