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 |
|
15 |
|
16 #ifndef __VGHWUTILS_H__ |
|
17 #define __VGHWUTILS_H__ |
|
18 |
|
19 // Include Files |
|
20 #include <e32base.h> // CBase |
|
21 #include <EGL/egl.h> |
|
22 #include <VG/openvg.h> |
|
23 #include <GLES/gl.h> |
|
24 #include "eglrfc.h" |
|
25 |
|
26 |
|
27 class RGuestVideoDriver; |
|
28 |
|
29 // Virtual Graphics Hardware per thread data: TEglThreadState is concrete, MVgContext & MGlesContext are per API interfaces |
|
30 class TEglThreadState; |
|
31 class MGlesContext; |
|
32 class MVgContext; |
|
33 |
|
34 // data serialisation packages |
|
35 class OpenVgRFC; |
|
36 class EglRFC; |
|
37 class RemoteFunctionCall; |
|
38 class RemoteFunctionCallData; |
|
39 |
|
40 // tracing |
|
41 #ifdef _DEBUG |
|
42 #include <e32debug.h> |
|
43 #define UTIL_TRACE(fmt, args...) RDebug::Printf(fmt, ##args) |
|
44 #define VGHWPANIC_ASSERT(condition, panic) if (!(condition)) { VghwPanic(panic, #panic, #condition, __FILE__, __LINE__); } |
|
45 #define VGHWPANIC_ASSERT_DEBUG(condition, panic) if (!(condition)) { VghwPanic(panic, #panic, #condition, __FILE__, __LINE__); } |
|
46 #else |
|
47 #define UTIL_TRACE(fmt, args...) |
|
48 #define VGHWPANIC_ASSERT(condition, panic) if (!(condition)) { VghwPanic(panic, NULL, NULL, NULL, __LINE__); } |
|
49 #define VGHWPANIC_ASSERT_DEBUG(condition, panic) |
|
50 #endif |
|
51 |
|
52 |
|
53 // Simulator Virtual Graphics Hardware panic codes |
|
54 typedef enum |
|
55 { |
|
56 EVghwPanicNoVideoChannel = 1, |
|
57 EVghwPanicOperationDataTooBig, |
|
58 EVghwPanicDriverOpenError, |
|
59 EVghwPanicVghwHeapDoesNotExist, |
|
60 EVghwPanicInitializeFailed, |
|
61 EVghwPanicGraphicsDriverNotOpen, |
|
62 EVghwPanicSwitchToVghwHeapOldHeapIsVghwHeap, |
|
63 EVghwPanicSwitchFromVghwHeapParamIsNull, |
|
64 EVghwPanicSwitchFromVghwHeapOldHeapIsNotVghwHeap, |
|
65 EVghwPanicSwitchFromVghwHeapParamIsVghwHeap, // 10 |
|
66 EVghwPanicGraphicsCreationLockDoesNotExist, |
|
67 EVghwPanicExecuteCommandFailed, |
|
68 EVghwPanicBadVgErrorValue, |
|
69 EVghwPanicBadGlesErrorValue, |
|
70 EVghwPanicBadEglErrorValue, |
|
71 EVghwPanicBadEglBoundApi, |
|
72 } TVghwPanic; |
|
73 |
|
74 // This panic function is exported to allow inline functions to use it |
|
75 IMPORT_C void VghwPanic(TVghwPanic aPanicCode, char* aPanicName, char* aCondition, char* aFile, TInt aLine); |
|
76 |
|
77 |
|
78 // Mix-in class: EGL support functions, including SgImage support, expected to be called by Open VG and Open GL ES |
|
79 class MEglManagementApi |
|
80 { |
|
81 public: |
|
82 virtual TBool EglImageOpenForVgImage(EGLImageKHR aImage, TSize& aSize, VGHandle& aVgHandle, TUint64& aSgImageId) = 0; |
|
83 virtual void EglImageClose(EGLImageKHR aImage) = 0; |
|
84 // ToDo add an API so that Open VG can query the size of the current Context's surface |
|
85 }; |
|
86 |
|
87 |
|
88 typedef void (*ExtensionProcPointer)(...); |
|
89 |
|
90 |
|
91 // Private interfaces for EGL to call into Open VG |
|
92 class MVgApiForEgl |
|
93 { |
|
94 public: |
|
95 virtual ExtensionProcPointer guestGetVgProcAddress (const char *aProcName) = 0; |
|
96 }; |
|
97 |
|
98 |
|
99 // Private interfaces for EGL to call into Open GL ES 1.1 |
|
100 class MGles11ApiForEgl |
|
101 { |
|
102 public: |
|
103 virtual ExtensionProcPointer guestGetGles11ProcAddress (const char *aProcName) = 0; |
|
104 }; |
|
105 |
|
106 |
|
107 // Private interfaces for EGL to call into Open GL ES 2 |
|
108 class MGles2ApiForEgl |
|
109 { |
|
110 public: |
|
111 virtual ExtensionProcPointer guestGetGles2ProcAddress (const char *aProcName) = 0; |
|
112 }; |
|
113 |
|
114 |
|
115 /* |
|
116 VGHWUtils APIs are static for ease of use by the other Simulator Graphics DLLs. |
|
117 |
|
118 One (singleton) instance is created as Writeable Static Data when the DLL is loaded. |
|
119 After initialization this will hold process-wide data - e.g. a memory heap for Graphics DLLs |
|
120 to store local Symbian client state information. |
|
121 |
|
122 ToDo maybe make this a Symbian X class because it owns resources, but only as static data. |
|
123 */ |
|
124 NONSHARABLE_CLASS(CVghwUtils): public CBase |
|
125 { |
|
126 friend class TEglThreadState; // to limit visibility of DriverExecuteCommand |
|
127 public: |
|
128 // open Driver connection, create Memory Heap, etc... |
|
129 IMPORT_C static void InitStatics(); |
|
130 IMPORT_C static void DestroyStatics(); |
|
131 |
|
132 IMPORT_C static TInt MapToHWAddress(const TInt aChunkHandle, TUint32& aHWAddress); |
|
133 IMPORT_C static TInt GetSurfaceBufferBaseAddress(TUint32& aHWAddress); |
|
134 IMPORT_C static TInt EglGetSgHandles(const TUint64 aId, TUint64 *aSgHandles); |
|
135 |
|
136 // VG Memory Pool APIs (One heap is created for the process, for use by all Simulator Graphics DLLs) |
|
137 IMPORT_C static TAny* Alloc(TInt aSize); |
|
138 IMPORT_C static void Free(TAny* aPtr); |
|
139 IMPORT_C static RHeap* GetHeap(); |
|
140 IMPORT_C static RHeap* SwitchToVghwHeap(); |
|
141 IMPORT_C static void SwitchFromVghwHeap(RHeap* aOldHeapPtr); |
|
142 // handy function for Debug Asserts |
|
143 static inline TBool UsingVghwHeap() { return &User::Heap() == GetHeap(); } |
|
144 |
|
145 // if this thread does not have a state object try to alloc a new one |
|
146 IMPORT_C static TEglThreadState* CreateThreadState(); |
|
147 // current state object, if any, for this thread (for EGL) |
|
148 IMPORT_C static TEglThreadState* EglThreadState(); |
|
149 // current state object, if Open VG, for this thread (as tracked by EGL DLL) |
|
150 IMPORT_C static MVgContext* VgContext(); |
|
151 // current state object for Open GL ES 1.1, for this thread (as tracked by EGL DLL) |
|
152 IMPORT_C static MGlesContext* GlesContext(); |
|
153 // free current state object, if any, for this thread |
|
154 IMPORT_C static void ReleaseThreadState(); |
|
155 |
|
156 IMPORT_C static void SetEglManagementApi(MEglManagementApi* aEglManagementApi); |
|
157 IMPORT_C static MEglManagementApi* EglManagementApi(); |
|
158 |
|
159 // Private interfaces for EGL to call into Open GL ES and Open VG (avoids breaking DEF file compatibility) |
|
160 IMPORT_C static void SetVgApiForEgl(MVgApiForEgl* aVgApiForEgl); |
|
161 IMPORT_C static MVgApiForEgl* VgApiForEgl(); |
|
162 |
|
163 IMPORT_C static void SetGles11ApiForEgl(MGles11ApiForEgl* aGles11ApiForEgl); |
|
164 IMPORT_C static MGles11ApiForEgl* Gles11ApiForEgl(); |
|
165 |
|
166 IMPORT_C static void SetGles2ApiForEgl(MGles2ApiForEgl* aGles2ApiForEgl); |
|
167 IMPORT_C static MGles2ApiForEgl* Gles2ApiForEgl(); |
|
168 |
|
169 protected: |
|
170 IMPORT_C static void DriverExecuteCommand(RemoteFunctionCallData& aRequestData); |
|
171 |
|
172 private: |
|
173 inline static RGuestVideoDriver& Driver(); |
|
174 |
|
175 private: |
|
176 // everything is zeroed on construction, call Initialize() to prepare |
|
177 volatile static TBool iInitialized; // NB "volatile" used for thread safety in InitStaticse() |
|
178 static TInt iVghwInitMutex; // required for thread safety in Initialize() |
|
179 |
|
180 // static member objects |
|
181 static RGuestVideoDriver* iDriver; |
|
182 static RHeap* iHeap; |
|
183 static MEglManagementApi* iEglManagementApi; |
|
184 static MVgApiForEgl* iVgApiForEgl; |
|
185 static MGles11ApiForEgl* iGles11ApiForEgl; |
|
186 static MGles2ApiForEgl* iGles2ApiForEgl; |
|
187 static TBool iLoadedOpenVgDll; |
|
188 static TBool iLoadedOpenGles11Dll; |
|
189 static TBool iLoadedOpenGles2Dll; |
|
190 }; |
|
191 |
|
192 |
|
193 // Basic interface for sending GL ES 1.1 commands down to Host Open GL ES implementation - can be expanded later |
|
194 class MGlesContext |
|
195 { |
|
196 public: |
|
197 // Execute Open GL ES 1.1 commands |
|
198 virtual void ExecuteGlesCommand(RemoteFunctionCall& aGlesRequestData) = 0; |
|
199 virtual void ExecuteGlesFlushCommand() = 0; |
|
200 virtual void ExecuteGlesFinishCommand() = 0; |
|
201 // GLES state |
|
202 virtual void SetGlesError(GLenum aGlesErrorCode) = 0; |
|
203 virtual GLenum GlesError() = 0; |
|
204 // ToDo make context tracking work for VG & GL ES |
|
205 virtual EGLContext GlesEglContext() = 0; |
|
206 }; |
|
207 |
|
208 |
|
209 // Basic interface for sending VG commands down to Host Open VG implementation - can be expanded later |
|
210 class MVgContext |
|
211 { |
|
212 public: |
|
213 // Execute Open VG commands |
|
214 virtual void ExecuteVgCommand(OpenVgRFC& aVgApiData) = 0; |
|
215 virtual void ExecuteVgFlushCommand() = 0; |
|
216 virtual void ExecuteVgFinishCommand() = 0; |
|
217 // VG state |
|
218 virtual void SetVgError(VGErrorCode aVgErrorCode) = 0; |
|
219 virtual VGErrorCode VgError() = 0; |
|
220 virtual EGLContext VgEglContext() = 0; |
|
221 }; |
|
222 |
|
223 |
|
224 NONSHARABLE_CLASS(TEglThreadState) : public MGlesContext, public MVgContext |
|
225 { |
|
226 friend class CVghwUtils; // to manage creation / delete of per thread state |
|
227 public: |
|
228 // Execute EGL commands, and analyse for success |
|
229 IMPORT_C EGLBoolean ExecEglBooleanCmd(EglRFC& aEglApiData); |
|
230 IMPORT_C EGLContext ExecEglContextCmd(EglRFC& aEglApiData); |
|
231 IMPORT_C EGLSurface ExecEglSurfaceCmd(EglRFC& aEglApiData); |
|
232 // ToDo add static export for eglTerminate |
|
233 |
|
234 // Execute EGL commands whose return value cannot be tested for fail/success |
|
235 inline void ExecuteEglNeverErrorCmd(EglRFC& aEglApiData); |
|
236 // EGL thread state |
|
237 inline void ClearEglError(); |
|
238 inline void SetEglError(EGLint aEglError); |
|
239 IMPORT_C EGLint EglError(); |
|
240 inline void SetEglBoundApi(EGLenum aEglBoundApi); |
|
241 inline EGLenum EglBoundApi(); |
|
242 inline EGLint PeekEglError(); // reads DLL set error code (only) |
|
243 |
|
244 // MGlesContext: Execute Open GL ES 1.1 commands & manage Open GL ES state |
|
245 virtual void ExecuteGlesCommand(RemoteFunctionCall& aGlesRequestData); |
|
246 virtual void ExecuteGlesFlushCommand(); |
|
247 virtual void ExecuteGlesFinishCommand(); |
|
248 virtual void SetGlesError(GLenum aGlesErrorCode); |
|
249 virtual GLenum GlesError(); |
|
250 virtual EGLContext GlesEglContext(); |
|
251 |
|
252 // MVgContext: Execute Open VG commands & manage Open VG state |
|
253 virtual void ExecuteVgCommand(OpenVgRFC& aVgApiData); |
|
254 virtual void ExecuteVgFlushCommand(); |
|
255 virtual void ExecuteVgFinishCommand(); |
|
256 virtual void SetVgError(VGErrorCode aVgErrorCode); |
|
257 virtual VGErrorCode VgError(); |
|
258 virtual EGLContext VgEglContext(); |
|
259 |
|
260 protected: |
|
261 static TEglThreadState* New(); |
|
262 void Destroy(); |
|
263 TEglThreadState(); |
|
264 ~TEglThreadState(); |
|
265 |
|
266 private: |
|
267 GLenum GetHostGlesError(); |
|
268 VGErrorCode GetHostVgError(); |
|
269 |
|
270 private: |
|
271 // EGL thread state |
|
272 EGLint iEglError; |
|
273 TBool iEglHostHasRecentError; |
|
274 // currently bound graphics API |
|
275 EGLenum iEglBoundApi; |
|
276 |
|
277 // Open VG context for thread |
|
278 VGErrorCode iVgError; |
|
279 EGLContext iVgEglContext; |
|
280 TBool iVgCommandsSinceGetError; |
|
281 TBool iVgCommandsSinceFlush; |
|
282 TBool iVgCommandsSinceFinish; |
|
283 |
|
284 // Open GL ES 1.1 context for thread |
|
285 GLenum iGlesError; |
|
286 EGLContext iGlesEglContext; |
|
287 TBool iGlesCommandsSinceGetError; |
|
288 TBool iGlesCommandsSinceFlush; |
|
289 TBool iGlesCommandsSinceFinish; |
|
290 }; |
|
291 |
|
292 |
|
293 |
|
294 |
|
295 /////////////////////////////////////////////////////////////////////////////////////////////////// |
|
296 // TVghwThreadState inline functions |
|
297 |
|
298 void TEglThreadState::ClearEglError() |
|
299 { |
|
300 UTIL_TRACE(" TVghwThreadState::ClearEglError"); |
|
301 iEglError = EGL_SUCCESS; |
|
302 iEglHostHasRecentError = EFalse; |
|
303 } |
|
304 |
|
305 |
|
306 void TEglThreadState::SetEglError(EGLint aEglError) |
|
307 { |
|
308 UTIL_TRACE(" TVghwThreadState::SetEglError error=0x%x", aEglError); |
|
309 VGHWPANIC_ASSERT_DEBUG((aEglError >= EGL_SUCCESS) && (aEglError <= 0x301F), EVghwPanicBadEglErrorValue); |
|
310 iEglError = aEglError; |
|
311 iEglHostHasRecentError = EFalse; |
|
312 } |
|
313 |
|
314 |
|
315 EGLint TEglThreadState::PeekEglError() // reads DLL set error code |
|
316 { |
|
317 return iEglError; |
|
318 } |
|
319 |
|
320 |
|
321 void TEglThreadState::SetEglBoundApi(EGLenum aEglBoundApi) |
|
322 { |
|
323 VGHWPANIC_ASSERT_DEBUG((aEglBoundApi == EGL_OPENGL_ES_API) || (aEglBoundApi == EGL_OPENVG_API), EVghwPanicBadEglBoundApi); |
|
324 iEglBoundApi = aEglBoundApi; |
|
325 } |
|
326 |
|
327 |
|
328 EGLenum TEglThreadState::EglBoundApi() |
|
329 { |
|
330 return iEglBoundApi; |
|
331 } |
|
332 |
|
333 // Execute EGL Command simple variants |
|
334 |
|
335 void TEglThreadState::ExecuteEglNeverErrorCmd(EglRFC& aEglApiData) |
|
336 { // for EGL commands which cannot have a host error |
|
337 CVghwUtils::DriverExecuteCommand(aEglApiData.Data()); |
|
338 iEglHostHasRecentError = EFalse; |
|
339 iEglError = EGL_SUCCESS; |
|
340 } |
|
341 |
|
342 #endif // __VGHWUTILS_H__ |
|