10 // |
10 // |
11 // Contributors: |
11 // Contributors: |
12 // |
12 // |
13 // Description: |
13 // Description: |
14 |
14 |
|
15 #include "eglrendering.h" |
15 #include <string.h> |
16 #include <string.h> |
16 #include "eglrendering.h" |
|
17 #include "openvgengine.h" |
|
18 #include <hal.h> |
|
19 |
17 |
20 const TInt KTimerDelay = 0; |
18 const TInt KTimerDelay = 0; |
21 |
19 |
22 |
|
23 /** Attributes to be passed into eglChooseConfig */ |
20 /** Attributes to be passed into eglChooseConfig */ |
24 const EGLint KColorRGBA8888AttribList[] = |
21 const EGLint KAttribList[] = |
25 { |
22 { |
26 EGL_RED_SIZE, 8, |
23 EGL_RED_SIZE, 8, |
27 EGL_GREEN_SIZE, 8, |
24 EGL_GREEN_SIZE, 8, |
28 EGL_BLUE_SIZE, 8, |
25 EGL_BLUE_SIZE, 8, |
29 EGL_ALPHA_SIZE, 8, |
26 EGL_ALPHA_SIZE, 8, |
30 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
27 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
31 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
28 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
32 EGL_NONE |
29 EGL_NONE |
33 }; |
30 }; |
34 |
31 |
35 |
32 void CEGLRendering::EGLCheckError() |
36 CEGLRendering* CEGLRendering::NewL(RWindow& aWindow, TBool aQhd) |
33 { |
37 { |
34 EGLint error = eglGetError(); |
38 CEGLRendering* self = CEGLRendering::NewLC(aWindow, aQhd); |
35 if(EGL_SUCCESS != error) |
39 CleanupStack::Pop(self); |
36 { |
|
37 RDebug::Printf("[EBT] CEglRendering::EGLCheckError error %d", error); |
|
38 User::Panic(_L("EBT-EGL"), error); |
|
39 } |
|
40 } |
|
41 |
|
42 void CEGLRendering::EGLCheckReturnError(EGLBoolean aBool) |
|
43 { |
|
44 if(!aBool) |
|
45 { |
|
46 RDebug::Printf("[EBT] CEglRendering::EGLCheckReturnError false"); |
|
47 User::Panic(_L("EGL-EGL-RTN"), eglGetError()); |
|
48 } |
|
49 } |
|
50 |
|
51 void CEGLRendering::VGCheckError() |
|
52 { |
|
53 VGint error = vgGetError(); |
|
54 if(VG_NO_ERROR != error) |
|
55 { |
|
56 RDebug::Printf("[EBT] CEglRendering::VGCheckError error %d", error); |
|
57 User::Panic(_L("EBT-VG"), error); |
|
58 } |
|
59 } |
|
60 |
|
61 CEGLRendering* CEGLRendering::NewL(RWindow& aWindow) |
|
62 { |
|
63 CEGLRendering* self = new (ELeave) CEGLRendering(aWindow); |
|
64 CleanupStack::PushL(self); |
|
65 self->ConstructL(); |
|
66 CleanupStack::Pop(self); |
40 return self; |
67 return self; |
41 } |
68 } |
42 |
69 |
43 |
|
44 CEGLRendering* CEGLRendering::NewLC(RWindow& aWindow, TBool aQhd) |
|
45 { |
|
46 CEGLRendering* self = new(ELeave) CEGLRendering(aWindow); |
|
47 CleanupStack::PushL(self); |
|
48 self->ConstructL(aQhd); |
|
49 return self; |
|
50 } |
|
51 |
|
52 CEGLRendering::~CEGLRendering() |
|
53 { |
|
54 Stop(); |
|
55 |
|
56 delete iTimer; |
|
57 |
|
58 if (iContextVG!=EGL_NO_CONTEXT) |
|
59 { |
|
60 EGLCheckReturnError(eglDestroyContext(iDisplay,iContextVG)); |
|
61 } |
|
62 |
|
63 if (iSurface!=EGL_NO_SURFACE) |
|
64 { |
|
65 EGLCheckReturnError(eglDestroySurface(iDisplay,iSurface)); |
|
66 } |
|
67 |
|
68 // Call eglMakeCurrent() to ensure the surfaces and contexts are truly destroyed. |
|
69 EGLCheckReturnError(eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
|
70 |
|
71 EGLCheckReturnError(eglTerminate(iDisplay)); |
|
72 EGLCheckReturnError(eglReleaseThread()); |
|
73 |
|
74 delete iBitmap; |
|
75 } |
|
76 |
|
77 void CEGLRendering::Start() |
|
78 { |
|
79 // Start drawing the screen periodically |
|
80 iTimer->Start(0, KTimerDelay, TCallBack(TimerCallBack,this)); |
|
81 } |
|
82 |
|
83 void CEGLRendering::Stop() |
|
84 { |
|
85 if(iTimer) |
|
86 { |
|
87 iTimer->Cancel(); |
|
88 } |
|
89 } |
|
90 |
|
91 void CEGLRendering::EGLCheckError() |
|
92 { |
|
93 EGLint error = eglGetError(); |
|
94 if(error != EGL_SUCCESS) |
|
95 { |
|
96 User::Panic(_L("EGL error"), error); |
|
97 } |
|
98 } |
|
99 |
|
100 void CEGLRendering::VGCheckError() |
|
101 { |
|
102 VGint error = vgGetError(); |
|
103 if(error != VG_NO_ERROR) |
|
104 { |
|
105 User::Panic(_L("OpenVG error"), error); |
|
106 } |
|
107 } |
|
108 |
|
109 void CEGLRendering::EGLCheckReturnError(EGLBoolean aBool) |
|
110 { |
|
111 if (!aBool) |
|
112 { |
|
113 User::Panic(_L("EGL return error"),eglGetError()); |
|
114 } |
|
115 } |
|
116 |
|
117 |
|
118 CEGLRendering::CEGLRendering(RWindow& aWindow) |
70 CEGLRendering::CEGLRendering(RWindow& aWindow) |
119 : iWindow(aWindow),iCount(0) |
71 : iWindow(aWindow) |
|
72 , iCount(0) |
120 { |
73 { |
121 } |
74 } |
122 |
75 |
123 /* |
76 /* |
124 * Construct EGL objects, and OpenVG binding. |
77 * Construct EGL objects, and OpenVG binding. |
125 * |
78 * |
126 * Here we collaborate with EGL to associate a session, pick and configuration, assign |
79 * Here we collaborate with EGL to associate a session, pick and configuration, assign |
127 * it to the window we have, and then bind the OpenVG rendering API to our newly created |
80 * it to the window we have, and then bind the OpenVG rendering API to our newly created |
128 * context. |
81 * context. |
129 * |
82 * |
130 * In bring up terms, here is where the first EGL code entry points are called from. Its |
83 * In bring up terms, here is where the first EGL code entry points are called from. Its |
131 * the natural point where an EGL bringup starts debugging from, assuming the core EGL |
84 * the natural point where an EGL bringup starts debugging from, assuming the core EGL |
132 * works in terms of supporting EGL sync objects (needed for boot before we get to the |
85 * works in terms of supporting EGL sync objects (needed for boot before we get to the |
133 * ESHELL command prompt). |
86 * ESHELL command prompt). |
134 */ |
87 */ |
135 void CEGLRendering::ConstructL(TBool aQhd) |
88 void CEGLRendering::ConstructL() |
136 { |
89 { |
137 RDebug::Printf("CEGLRendering::ConstructL"); |
90 RDebug::Printf("[EBT] CEGLRendering::ConstructL"); |
138 |
|
139 // Refresh timer |
|
140 iTimer = CPeriodic::NewL(CActive::EPriorityIdle); |
91 iTimer = CPeriodic::NewL(CActive::EPriorityIdle); |
141 |
92 EglSetupL(); |
142 const TDisplayMode dispMode = iWindow.DisplayMode(); |
93 VgSetup(); |
143 const TSize windowSize(iWindow.Size()); |
94 VgPaint(); |
144 |
95 } |
145 // Create display object |
96 |
146 iDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
97 void CEGLRendering::EglSetupL() |
147 RDebug::Printf("CEGLRendering::ConstructL 1"); |
98 { |
148 EGLCheckError(); |
99 RDebug::Printf("[EBT] CEGLRendering::EglSetupL eglGetDisplay"); |
149 |
100 iDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
150 // Initialize display object |
101 EGLCheckError(); |
151 EGLCheckReturnError(eglInitialize(iDisplay, NULL, NULL)); |
102 |
152 RDebug::Printf("CEGLRendering::ConstructL 2"); |
103 RDebug::Printf("[EBT] CEGLRendering::EglSetupL eglInitialize"); |
153 |
104 EGLCheckReturnError(eglInitialize(iDisplay, NULL, NULL)); |
154 RDebug::Printf("Vendor string %s", eglQueryString(iDisplay, EGL_VENDOR)); |
105 |
155 RDebug::Printf("Version string %s", eglQueryString(iDisplay, EGL_VERSION)); |
106 RDebug::Printf("[EBT] CEGLRendering::EglSetupL vendor %s", eglQueryString(iDisplay, EGL_VENDOR)); |
156 RDebug::Printf("Version string %s", eglQueryString(iDisplay, EGL_EXTENSIONS)); |
107 RDebug::Printf("[EBT] CEGLRendering::EglSetupL version %s", eglQueryString(iDisplay, EGL_VERSION)); |
157 |
108 RDebug::Printf("[EBT] CEGLRendering::EglSetupL extensions %s", eglQueryString(iDisplay, EGL_EXTENSIONS)); |
158 |
109 |
159 // Check that EGL provides the capabilities for this app. |
110 // Check that EGL provides the capabilities for this app. |
160 TInt error = KErrNone; |
111 if(NULL == strstr(eglQueryString(iDisplay, EGL_CLIENT_APIS), "OpenVG")) |
161 if ( NULL == strstr(eglQueryString(iDisplay, EGL_CLIENT_APIS), "OpenVG") ) |
112 { |
162 { |
113 RDebug::Printf("[EBT] CEGLRendering::EglSetupL OpenVG not listed in supported client APIs %s", eglQueryString(iDisplay, EGL_CLIENT_APIS)); |
163 RDebug::Printf("OpenVG not listed in supported client APIs %s", eglQueryString(iDisplay, EGL_CLIENT_APIS)); |
114 User::Leave(KErrNotSupported); |
164 error = KErrNotSupported; |
115 } |
165 } |
116 |
166 |
117 if(NULL == strstr(eglQueryString(iDisplay, EGL_EXTENSIONS), "EGL_SYMBIAN_COMPOSITION") ) |
167 |
118 { |
168 if ( NULL == strstr(eglQueryString(iDisplay, EGL_EXTENSIONS), "EGL_SYMBIAN_COMPOSITION") ) |
119 RDebug::Printf("[EBT] CEGLRendering::EglSetupL EGL_SYMBIAN_COMPOSITION not listed in extension string %s", eglQueryString(iDisplay, EGL_EXTENSIONS)); |
169 { |
120 User::Leave(KErrNotSupported); |
170 RDebug::Printf("EGL_SYMBIAN_COMPOSITION not listed in extension string %s", eglQueryString(iDisplay, EGL_EXTENSIONS)); |
121 } |
171 error = KErrNotSupported; |
122 |
172 } |
123 RDebug::Printf("[EBT] CEGLRendering::EglSetupL eglChooseConfig"); |
173 if (error != KErrNone) |
124 EGLint numConfigs = 0; |
174 { |
125 EGLConfig chosenConfig = 0; |
175 User::Leave(error); |
126 EGLCheckReturnError(eglChooseConfig(iDisplay, KAttribList, &chosenConfig, 1, &numConfigs)); |
176 } |
127 if (0 == numConfigs) |
177 |
128 { |
178 EGLint numConfigs; |
129 RDebug::Printf("[EBT] No matching configs found", eglQueryString(iDisplay, EGL_EXTENSIONS)); |
179 EGLConfig chosenConfig = 0; |
130 User::Leave(KErrNotSupported); |
180 |
131 } |
181 // Choose the config to use |
132 |
182 EGLCheckReturnError(eglChooseConfig(iDisplay, KColorRGBA8888AttribList, &chosenConfig, 1, &numConfigs)); |
133 RDebug::Printf("[EBT] CEGLRendering::EglSetupL eglBindApi"); |
183 RDebug::Printf("CEGLRendering::ConstructL 3"); |
134 EGLCheckReturnError(eglBindAPI(EGL_OPENVG_API)); |
184 if (numConfigs == 0) |
135 |
185 { |
136 RDebug::Printf("[EBT] CEGLRendering::EglSetupL eglCreateWindowSurface"); |
186 RDebug::Printf("No matching configs found", eglQueryString(iDisplay, EGL_EXTENSIONS)); |
137 iSurface = eglCreateWindowSurface(iDisplay, chosenConfig, &iWindow, NULL); |
187 User::Leave(KErrNotSupported); |
138 EGLCheckError(); |
188 } |
139 |
189 |
140 RDebug::Printf("[EBT] CEGLRendering::EglSetupL eglGetConfigAttrib"); |
190 // Create window surface to draw direct to. |
141 TInt redSize, greenSize, blueSize, alphaSize; |
191 EGLCheckReturnError(eglBindAPI(EGL_OPENVG_API)); |
142 EGLCheckReturnError(eglGetConfigAttrib(iDisplay, chosenConfig, EGL_ALPHA_SIZE, &alphaSize)); |
192 RDebug::Printf("CEGLRendering::ConstructL 4"); |
143 EGLCheckReturnError(eglGetConfigAttrib(iDisplay, chosenConfig, EGL_RED_SIZE, &redSize)); |
193 iSurface = eglCreateWindowSurface(iDisplay, chosenConfig, &iWindow, NULL); |
144 EGLCheckReturnError(eglGetConfigAttrib(iDisplay, chosenConfig, EGL_GREEN_SIZE, &greenSize)); |
194 RDebug::Printf("CEGLRendering::ConstructL 5"); |
145 EGLCheckReturnError(eglGetConfigAttrib(iDisplay, chosenConfig, EGL_BLUE_SIZE, &blueSize)); |
195 EGLCheckError(); |
146 RDebug::Printf("[EBT] CEGLRendering::EglSetupL id:%d alpha:%d red:%d green:%d blue:%d", |
196 |
147 chosenConfig, alphaSize, redSize, greenSize, blueSize); |
197 TInt redSize, greenSize, blueSize, alphaSize; |
148 |
198 |
149 RDebug::Printf("[EBT] CEGLRendering::EglSetupL eglCreateContext"); |
199 EGLCheckReturnError(eglGetConfigAttrib(iDisplay, chosenConfig, EGL_ALPHA_SIZE, &alphaSize)); |
150 iContext = eglCreateContext(iDisplay, chosenConfig, EGL_NO_CONTEXT, NULL); |
200 EGLCheckReturnError(eglGetConfigAttrib(iDisplay, chosenConfig, EGL_RED_SIZE, &redSize)); |
151 EGLCheckError(); |
201 EGLCheckReturnError(eglGetConfigAttrib(iDisplay, chosenConfig, EGL_GREEN_SIZE, &greenSize)); |
152 |
202 EGLCheckReturnError(eglGetConfigAttrib(iDisplay, chosenConfig, EGL_BLUE_SIZE, &blueSize)); |
153 RDebug::Printf("[EBT] CEGLRendering::EglSetupL eglMakeCurrent"); |
203 RDebug::Print(_L("EGLConfig id:%d alpha:%d red:%d green:%d blue:%d"), chosenConfig, |
154 CEGLRendering::EGLCheckReturnError(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext)); |
204 alphaSize, redSize, greenSize, blueSize); |
155 } |
205 RDebug::Printf("CEGLRendering::ConstructL 6"); |
156 |
206 |
157 void CEGLRendering::VgSetup() |
207 // Create context to store surface settings |
158 { |
208 iContextVG = eglCreateContext(iDisplay, chosenConfig, EGL_NO_CONTEXT, NULL); |
159 static VGubyte const Segments[] = |
209 RDebug::Printf("CEGLRendering::ConstructL 7"); |
|
210 EGLCheckError(); |
|
211 |
|
212 CEGLRendering::EGLCheckReturnError(eglMakeCurrent(iDisplay, iSurface, iSurface, iContextVG)); |
|
213 RDebug::Printf("CEGLRendering::ConstructL 8"); |
|
214 |
|
215 // Now try and draw a line (blue) |
|
216 static VGubyte const starSegments[] = |
|
217 { |
160 { |
218 VG_MOVE_TO_ABS, |
161 VG_MOVE_TO_ABS, |
219 VG_LINE_TO_REL, |
162 VG_LINE_TO_REL, |
220 VG_CLOSE_PATH |
163 VG_CLOSE_PATH |
221 }; |
164 }; |
222 |
165 |
223 static VGfloat const starCoords[] = |
166 static VGfloat const Coords[] = |
224 { |
167 { |
225 110, 35, |
168 110, 35, |
226 50, 160, |
169 50, 160, |
227 }; |
170 }; |
228 |
171 |
229 |
|
230 VGfloat strokeColor[4] = {1.f, 0.f, 0.f, 1.f}; |
172 VGfloat strokeColor[4] = {1.f, 0.f, 0.f, 1.f}; |
231 |
173 |
232 VGPaint strokePaint = vgCreatePaint(); |
174 RDebug::Printf("[EBT] CEGLRendering::VgSetup vgCreatePaint"); |
233 |
175 iVGPaint = vgCreatePaint(); |
234 vgSetParameteri(strokePaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); |
176 VGCheckError(); |
235 vgSetParameterfv(strokePaint, VG_PAINT_COLOR, 4, strokeColor); |
177 |
236 |
178 RDebug::Printf("[EBT] CEGLRendering::VgSetup vgSetParameterX"); |
237 VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
179 vgSetParameteri(iVGPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); |
|
180 VGCheckError(); |
|
181 vgSetParameterfv(iVGPaint, VG_PAINT_COLOR, 4, strokeColor); |
|
182 VGCheckError(); |
|
183 |
|
184 RDebug::Printf("[EBT] CEGLRendering::VgSetup vgCreatePath"); |
|
185 iVGPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
238 VG_PATH_DATATYPE_F, |
186 VG_PATH_DATATYPE_F, |
239 1.0f, // scale |
187 1.0f, // scale |
240 0.0f, // bias |
188 0.0f, // bias |
241 3, // segmentCapacityHint |
189 3, // segmentCapacityHint |
242 4, // coordCapacityHint |
190 4, // coordCapacityHint |
243 VG_PATH_CAPABILITY_ALL); |
191 VG_PATH_CAPABILITY_ALL); |
244 |
192 VGCheckError(); |
245 ASSERT(vgGetError() == VG_NO_ERROR); |
193 |
246 RDebug::Printf("vgCreatePath"); |
194 RDebug::Printf("[EBT] CEGLRendering::VgSetup vgAppendPathData"); |
247 |
195 vgAppendPathData(iVGPath, sizeof(Segments), Segments, Coords); |
248 |
196 VGCheckError(); |
249 vgAppendPathData(path, sizeof(starSegments), starSegments, starCoords); |
197 } |
250 ASSERT(vgGetError() == VG_NO_ERROR); |
198 |
251 RDebug::Printf("vgAppendPathData"); |
199 void CEGLRendering::VgPaint() |
252 |
200 { |
253 vgSetPaint(strokePaint, VG_STROKE_PATH); |
201 RDebug::Printf("[EBT] CEGLRendering::VgPaint vgSetPaint"); |
254 |
202 vgSetPaint(iVGPaint, VG_STROKE_PATH); |
255 // Draw the star directly using the OpenVG API. |
203 VGCheckError(); |
256 vgDrawPath(path, VG_FILL_PATH | VG_STROKE_PATH); |
204 |
257 ASSERT(vgGetError() == VG_NO_ERROR); |
205 RDebug::Printf("[EBT] CEGLRendering::VgPaint vgDrawPath"); |
258 RDebug::Printf("vgDrawPath"); |
206 vgDrawPath(iVGPath, VG_STROKE_PATH); |
259 |
207 VGCheckError(); |
|
208 |
|
209 RDebug::Printf("[EBT] CEGLRendering::VgPaint eglSwapBuffers"); |
260 eglSwapBuffers(iDisplay, iSurface); |
210 eglSwapBuffers(iDisplay, iSurface); |
261 RDebug::Printf("eglSwapBuffers"); |
211 EGLCheckError(); |
262 EGLCheckError(); |
212 } |
263 } |
213 |
264 |
214 CEGLRendering::~CEGLRendering() |
|
215 { |
|
216 RDebug::Printf("[EBT] CEGLRendering::~CEGLRendering"); |
|
217 |
|
218 Stop(); |
|
219 |
|
220 delete iTimer; |
|
221 |
|
222 if (EGL_NO_CONTEXT != iContext) |
|
223 { |
|
224 EGLCheckReturnError(eglDestroyContext(iDisplay, iContext)); |
|
225 } |
|
226 |
|
227 if (EGL_NO_SURFACE != iSurface) |
|
228 { |
|
229 EGLCheckReturnError(eglDestroySurface(iDisplay,iSurface)); |
|
230 } |
|
231 |
|
232 // Call eglMakeCurrent() to ensure the surfaces and contexts are truly destroyed. |
|
233 EGLCheckReturnError(eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
|
234 EGLCheckReturnError(eglTerminate(iDisplay)); |
|
235 EGLCheckReturnError(eglReleaseThread()); |
|
236 |
|
237 delete iBitmap; |
|
238 } |
|
239 |
|
240 void CEGLRendering::Start() |
|
241 { |
|
242 // Start drawing the screen periodically |
|
243 iTimer->Start(0, KTimerDelay, TCallBack(TimerCallBack, this)); |
|
244 } |
|
245 |
|
246 void CEGLRendering::Stop() |
|
247 { |
|
248 if(iTimer) |
|
249 { |
|
250 iTimer->Cancel(); |
|
251 } |
|
252 } |
265 |
253 |
266 /** Update the display */ |
254 /** Update the display */ |
267 void CEGLRendering::UpdateDisplay() |
255 void CEGLRendering::UpdateDisplay() |
268 { |
256 { |
269 // Flush colour buffer to the window surface |
257 // Flush colour buffer to the window surface |