|
1 // Copyright (c) 2008-2009 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 #include "confighelper.h" |
|
17 #include "directgdiadapter.h" |
|
18 #include <pixelformats.h> |
|
19 #include <EGL/egltypes.h> |
|
20 #include <fbs.h> |
|
21 |
|
22 /** |
|
23 Symbian Config Attributes for EGL pixmaps / pbuffers / windows. |
|
24 */ |
|
25 const EGLint TConfigHelper::KSurfaceAttribs[][19] = |
|
26 { |
|
27 { |
|
28 // EColor64K == EUidPixelFormatRGB_565 |
|
29 // 16 bpp: 5 bits red, 6 bits green, 5 bits blue |
|
30 // |
|
31 EGL_BUFFER_SIZE, 16, |
|
32 EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, |
|
33 EGL_RED_SIZE, 5, |
|
34 EGL_GREEN_SIZE, 6, |
|
35 EGL_BLUE_SIZE, 5, |
|
36 EGL_ALPHA_SIZE, 0, |
|
37 EGL_LUMINANCE_SIZE, 0, |
|
38 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
|
39 EGL_SURFACE_TYPE, EGL_PIXMAP_BIT, |
|
40 EGL_NONE |
|
41 }, |
|
42 { |
|
43 //EColor16MAP == EUidPixelFormatARGB_8888_PRE |
|
44 // 32 bpp: 8 bits premultiplied alpha, 8 bits red, 8 bits green, 8 bits blue |
|
45 // |
|
46 EGL_BUFFER_SIZE, 32, |
|
47 EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, |
|
48 EGL_RED_SIZE, 8, |
|
49 EGL_GREEN_SIZE, 8, |
|
50 EGL_BLUE_SIZE, 8, |
|
51 EGL_ALPHA_SIZE, 8, |
|
52 EGL_LUMINANCE_SIZE, 0, |
|
53 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
|
54 EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT, |
|
55 EGL_NONE |
|
56 }, |
|
57 { |
|
58 // EColor16MU == EUidPixelFormatXRGB_8888 |
|
59 // 32 bpp: 8 bits alpha (ignored), 8 bits red, 8 bits green, 8 bits blue |
|
60 // |
|
61 EGL_BUFFER_SIZE, 24, |
|
62 EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, |
|
63 EGL_RED_SIZE, 8, |
|
64 EGL_GREEN_SIZE, 8, |
|
65 EGL_BLUE_SIZE, 8, |
|
66 EGL_ALPHA_SIZE, 0, |
|
67 EGL_LUMINANCE_SIZE, 0, |
|
68 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
|
69 EGL_SURFACE_TYPE, EGL_PIXMAP_BIT, |
|
70 EGL_NONE |
|
71 }, |
|
72 { |
|
73 //EColor16MA == EUidPixelFormatARGB_8888 |
|
74 // 32 bpp: 8 bits alpha, 8 bits red, 8 bits green, 8 bits blue |
|
75 // |
|
76 EGL_BUFFER_SIZE, 32, |
|
77 EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, |
|
78 EGL_RED_SIZE, 8, |
|
79 EGL_GREEN_SIZE, 8, |
|
80 EGL_BLUE_SIZE, 8, |
|
81 EGL_ALPHA_SIZE, 8, |
|
82 EGL_LUMINANCE_SIZE, 0, |
|
83 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
|
84 EGL_SURFACE_TYPE, EGL_PIXMAP_BIT, |
|
85 EGL_NONE |
|
86 }, |
|
87 { |
|
88 // EGray256 == EUidPixelFormatL_8 |
|
89 // 8 bpp: 8 bits luminance |
|
90 // |
|
91 EGL_BUFFER_SIZE, 8, |
|
92 EGL_COLOR_BUFFER_TYPE, EGL_LUMINANCE_BUFFER, |
|
93 EGL_RED_SIZE, 0, |
|
94 EGL_GREEN_SIZE, 0, |
|
95 EGL_BLUE_SIZE, 0, |
|
96 EGL_ALPHA_SIZE, 0, |
|
97 EGL_LUMINANCE_SIZE, 8, |
|
98 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
|
99 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, |
|
100 EGL_NONE |
|
101 }, |
|
102 { |
|
103 // EGray2 == EUidPixelFormatL_1 |
|
104 // 1 bpp: 1 bit luminance |
|
105 // |
|
106 EGL_BUFFER_SIZE, 1, |
|
107 EGL_COLOR_BUFFER_TYPE, EGL_LUMINANCE_BUFFER, |
|
108 EGL_RED_SIZE, 0, |
|
109 EGL_GREEN_SIZE, 0, |
|
110 EGL_BLUE_SIZE, 0, |
|
111 EGL_ALPHA_SIZE, 0, |
|
112 EGL_LUMINANCE_SIZE, 1, |
|
113 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
|
114 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, |
|
115 EGL_NONE |
|
116 } |
|
117 }; |
|
118 |
|
119 /** |
|
120 Finds the exact matching configuration from the available configurations, based on the attribute values. |
|
121 |
|
122 @pre aConfigs should not be NULL and EGL has been initialised. |
|
123 @return The index of the matching config if successful, otherwise -1. |
|
124 */ |
|
125 TInt TConfigHelper::GetSuitablePixmapConfigIndex(EGLDisplay aDisplay, EGLConfig *aConfigs, TInt aNumConfigs, TInt aColorAttrib) |
|
126 { |
|
127 EGLint value; |
|
128 |
|
129 #ifdef _DEBUG_DIRECTGDI |
|
130 TBuf16<256> message; |
|
131 message.Format(_L("ColorAtrib : %d"), aColorAttrib); |
|
132 GRAPHICS_LOGD_DEBUG(message); |
|
133 |
|
134 const TPtrC KEglAttribs[] = |
|
135 { |
|
136 _L("EGL_BUFFER_SIZE"), |
|
137 _L("EGL_COLOR_BUFFER_TYPE"), |
|
138 _L("EGL_RED_SIZE"), |
|
139 _L("EGL_GREEN_SIZE"), |
|
140 _L("EGL_BLUE_SIZE"), |
|
141 _L("EGL_ALPHA_SIZE"), |
|
142 _L("EGL_LUMINANCE_SIZE"), |
|
143 _L("EGL_RENDERABLE_TYPE"), |
|
144 _L("EGL_SURFACE_TYPE"), |
|
145 }; |
|
146 #endif |
|
147 |
|
148 TBool found = EFalse; |
|
149 for (TInt i=0; i<aNumConfigs && !found && aConfigs; i++) |
|
150 { |
|
151 found = ETrue; |
|
152 #ifdef _DEBUG_DIRECTGDI |
|
153 message.Format(_L("Trying to match with config number: %d"), i); |
|
154 GRAPHICS_LOGD_DEBUG(message); |
|
155 #endif |
|
156 for(TInt j=EEglBufferSize; j<ELast && found; ++++j) |
|
157 { |
|
158 eglGetConfigAttrib(aDisplay, aConfigs[i], KSurfaceAttribs[aColorAttrib][j], &value); |
|
159 found = EglAttributeMatches(KSurfaceAttribs[aColorAttrib][j], KSurfaceAttribs[aColorAttrib][j+1], value); |
|
160 |
|
161 #ifdef _DEBUG_DIRECTGDI |
|
162 message.Format(_L("%S: Trying to match: %d From EGL: %d\n"), &KEglAttribs[j>>1], KSurfaceAttribs[aColorAttrib][j+1], value); |
|
163 GRAPHICS_LOGD_DEBUG(message); |
|
164 #endif |
|
165 } |
|
166 if (found) |
|
167 { |
|
168 #ifdef _DEBUG_DIRECTGDI |
|
169 message.Format(_L("Found a suitable EGL Config: %d\n"), i); |
|
170 GRAPHICS_LOGD_DEBUG(message); |
|
171 #endif |
|
172 return i; |
|
173 } |
|
174 } |
|
175 return -1; |
|
176 } |
|
177 |
|
178 /** |
|
179 Helper function for GetSuitablePixmapConfigIndex(). Returns, for the given attribute, whether or not the |
|
180 expected value matches the value received from egl. The kind of match is dependant on the attribute being tested. |
|
181 |
|
182 @param aAttribute The EGL attribute ID. |
|
183 @param aExpected The value we require the attribute to have for the current config we are testing. |
|
184 @param aActual The value read from the current EGL config for this attribute. |
|
185 @return ETrue, if aActual is deemed to match aExpected, otherwise EFalse. |
|
186 */ |
|
187 TBool TConfigHelper::EglAttributeMatches(EGLint aAttribute, TInt aExpected, TInt aActual) |
|
188 { |
|
189 switch(aAttribute) |
|
190 { |
|
191 case EGL_RENDERABLE_TYPE: |
|
192 case EGL_SURFACE_TYPE: |
|
193 // These are bitwise masks, so we don't need an exact match, just the bits to be set. |
|
194 return ((aExpected & aActual) == aExpected); |
|
195 default: |
|
196 return (aExpected == aActual); |
|
197 } |
|
198 } |
|
199 |
|
200 /** |
|
201 Converts the pixel type into an enum of supported pixel types. If a pixel type is not supported, it |
|
202 is scaled to the nearest one. |
|
203 Six destination pixel types are supported. |
|
204 |
|
205 @panic DGDIAdapter 1009, if the pixel type is not supported. |
|
206 |
|
207 @return Equivalent pixel type, as an index into KPixmapAttribs[]. |
|
208 */ |
|
209 TInt TConfigHelper::MatchPixelType(TInt aPixelType) |
|
210 { |
|
211 TInt selPixmapAttribs = 0; |
|
212 switch(aPixelType) |
|
213 { |
|
214 case EUidPixelFormatP_4: |
|
215 case EUidPixelFormatP_8: |
|
216 case EUidPixelFormatXRGB_4444: |
|
217 case EUidPixelFormatRGB_565: |
|
218 selPixmapAttribs = EPixmapAttribsColor64K; |
|
219 break; |
|
220 case EUidPixelFormatARGB_8888_PRE: |
|
221 selPixmapAttribs = EPixmapAttribsColor16MAP; |
|
222 break; |
|
223 case EUidPixelFormatRGB_888: |
|
224 case EUidPixelFormatXRGB_8888: |
|
225 selPixmapAttribs = EPixmapAttribsColor16MU; |
|
226 break; |
|
227 case EUidPixelFormatARGB_8888: |
|
228 selPixmapAttribs = EPixmapAttribsColor16MA; |
|
229 break; |
|
230 case EUidPixelFormatL_1: |
|
231 selPixmapAttribs = EPixmapAttribsLuminance1L; |
|
232 break; |
|
233 case EUidPixelFormatL_2: |
|
234 case EUidPixelFormatL_4: |
|
235 case EUidPixelFormatL_8: |
|
236 selPixmapAttribs = EPixmapAttribsLuminance8L; |
|
237 break; |
|
238 default: |
|
239 GRAPHICS_PANIC_ALWAYS(EDirectGdiPanicInvalidDisplayMode); |
|
240 } |
|
241 return selPixmapAttribs; |
|
242 } |
|
243 |
|
244 /** |
|
245 Given a TUidPixelFormat, returns an EGLConfig matching it. |
|
246 If no exact match can be found, then returns the first available config. |
|
247 |
|
248 @param aAttributeArrayIndex Index into config attribute array. |
|
249 @param aResult The resulting EGL config. |
|
250 |
|
251 @pre EGL has been initialised. |
|
252 |
|
253 @return KErrNone if a suitable config was found, otherwise one of the system-wide error codes. |
|
254 */ |
|
255 TInt TConfigHelper::GetConfig (TInt aAttributeArrayIndex, EGLConfig& aResult) |
|
256 { |
|
257 // Choose config |
|
258 EGLint numConfigs = 0; |
|
259 EGLDisplay display = eglGetCurrentDisplay(); |
|
260 |
|
261 if (!eglGetConfigs(display, NULL, 0, &numConfigs)) |
|
262 return KErrGeneral; |
|
263 |
|
264 if (numConfigs == 0) |
|
265 return KErrNotFound; |
|
266 |
|
267 EGLConfig* configs = new EGLConfig[numConfigs]; |
|
268 if (configs == NULL) |
|
269 return KErrNoMemory; |
|
270 |
|
271 TInt match = -1; |
|
272 if (eglChooseConfig(display, KSurfaceAttribs[aAttributeArrayIndex], configs, numConfigs, &numConfigs)) |
|
273 { |
|
274 match = GetSuitablePixmapConfigIndex(display, configs, numConfigs, aAttributeArrayIndex); |
|
275 //If no exact match can be found, then take the first config. |
|
276 if(match == -1) |
|
277 match = 0; |
|
278 aResult = configs[match]; |
|
279 } |
|
280 delete [] configs; |
|
281 return (match == -1) ? KErrNotFound : KErrNone; |
|
282 } |
|
283 |
|
284 /** |
|
285 Given a CFbsBitmap, return an EGLConfig that matches its display mode. |
|
286 |
|
287 @param aBitmap Bitmap to get config for. |
|
288 @param aResult The resulting EGL config, if found. |
|
289 |
|
290 @pre aBitmap has already been validated by ValidateBitmap(). |
|
291 |
|
292 @return KErrNone if successful, otherwise one of the system-wide error codes. |
|
293 */ |
|
294 TInt TConfigHelper::GetConfigForFbsBitmap (const CFbsBitmap& aBitmap, EGLConfig& aResult) |
|
295 { |
|
296 TInt pixelType = -1; |
|
297 switch (aBitmap.DisplayMode()) |
|
298 { |
|
299 case EGray2: |
|
300 pixelType = EUidPixelFormatL_1; |
|
301 break; |
|
302 case EGray4: |
|
303 pixelType = EUidPixelFormatL_2; |
|
304 break; |
|
305 case EGray16: |
|
306 pixelType = EUidPixelFormatL_4; |
|
307 break; |
|
308 case EGray256: |
|
309 pixelType = EUidPixelFormatL_8; |
|
310 break; |
|
311 case EColor16: |
|
312 pixelType = EUidPixelFormatP_4; |
|
313 break; |
|
314 case EColor256: |
|
315 pixelType = EUidPixelFormatP_8; |
|
316 break; |
|
317 case EColor4K: |
|
318 pixelType = EUidPixelFormatXRGB_4444; |
|
319 break; |
|
320 case EColor64K: |
|
321 pixelType = EUidPixelFormatRGB_565; |
|
322 break; |
|
323 case EColor16M: |
|
324 pixelType = EUidPixelFormatRGB_888; |
|
325 break; |
|
326 case EColor16MU: |
|
327 pixelType = EUidPixelFormatXRGB_8888; |
|
328 break; |
|
329 case EColor16MA: |
|
330 pixelType = EUidPixelFormatARGB_8888; |
|
331 break; |
|
332 case EColor16MAP: |
|
333 pixelType = EUidPixelFormatARGB_8888_PRE; |
|
334 break; |
|
335 default: |
|
336 return KErrNotSupported; |
|
337 } |
|
338 return GetConfig(MatchPixelType(pixelType), aResult); |
|
339 } |
|
340 |
|
341 |
|
342 //Currently not called anywhere. However, it may be useful for performance improvement |
|
343 //in the future. Will defer removing/reinstating until then. |
|
344 #ifdef _DEBUG |
|
345 /** |
|
346 Debug method to iterate over supported configurations and print significant attributes. |
|
347 Currently only EGL_OPENVG renderable types are displayed. |
|
348 |
|
349 @pre EGL is initialised. |
|
350 @leave PushL(). |
|
351 */ |
|
352 void TConfigHelper::SupportedSurfacePixelFormatsL() |
|
353 { |
|
354 EGLDisplay currentDisplay = eglGetCurrentDisplay(); |
|
355 EGLint numConfigs; |
|
356 EGLConfig* configs; |
|
357 TInt bufferSize, depthSize, stencilSize, luminance, renderableType, surfaceType, A, R, G, B; |
|
358 |
|
359 _LIT(KAttribFormat, "%3d: BDS-ARGBL: %2d, %2d, %2d - %d, %d, %d, %d, %d"); |
|
360 _LIT(KEGL_OPENVG_BIT, ", EGL_OPENVG_BIT"); |
|
361 _LIT(KEGL_PBUFFER_BIT, ", EGL_PBUFFER_BIT"); |
|
362 _LIT(KEGL_PIXMAP_BIT, ", EGL_PIXMAP_BIT"); |
|
363 _LIT(KEGL_VG_ALPHA_FORMAT_PRE_BIT, ", EGL_VG_ALPHA_FORMAT_PRE_BIT"); |
|
364 |
|
365 if (eglGetConfigs(currentDisplay, NULL, 0x00, &numConfigs) == EGL_TRUE) |
|
366 { |
|
367 configs = (EGLConfig*)User::Alloc (numConfigs * sizeof(EGLConfig)); |
|
368 if (configs) |
|
369 { |
|
370 CleanupStack::PushL(configs); |
|
371 if (eglGetConfigs(currentDisplay, configs, numConfigs, &numConfigs) == EGL_TRUE) |
|
372 { |
|
373 for (TUint i = 0; i < numConfigs; i++) |
|
374 { |
|
375 eglGetConfigAttrib(currentDisplay, configs[i], EGL_BUFFER_SIZE, (EGLint*)&bufferSize); |
|
376 eglGetConfigAttrib(currentDisplay, configs[i], EGL_DEPTH_SIZE, (EGLint*)&depthSize); |
|
377 eglGetConfigAttrib(currentDisplay, configs[i], EGL_STENCIL_SIZE, (EGLint*)&stencilSize); |
|
378 eglGetConfigAttrib(currentDisplay, configs[i], EGL_ALPHA_SIZE, (EGLint*)&A); |
|
379 eglGetConfigAttrib(currentDisplay, configs[i], EGL_RED_SIZE, (EGLint*)&R); |
|
380 eglGetConfigAttrib(currentDisplay, configs[i], EGL_GREEN_SIZE, (EGLint*)&G); |
|
381 eglGetConfigAttrib(currentDisplay, configs[i], EGL_BLUE_SIZE, (EGLint*)&B); |
|
382 eglGetConfigAttrib(currentDisplay, configs[i], EGL_LUMINANCE_SIZE, (EGLint*)&luminance); |
|
383 eglGetConfigAttrib(currentDisplay, configs[i], EGL_RENDERABLE_TYPE, (EGLint*)&renderableType); |
|
384 eglGetConfigAttrib(currentDisplay, configs[i], EGL_RENDERABLE_TYPE, (EGLint*)&renderableType); |
|
385 eglGetConfigAttrib(currentDisplay, configs[i], EGL_SURFACE_TYPE, (EGLint*)&surfaceType); |
|
386 |
|
387 if (renderableType & EGL_OPENVG_BIT) |
|
388 { |
|
389 TBuf<256> buf; |
|
390 buf.Format(KAttribFormat, i, bufferSize, depthSize, stencilSize, A, R, G, B, luminance); |
|
391 buf.Append(KEGL_OPENVG_BIT); |
|
392 |
|
393 if (surfaceType & EGL_PBUFFER_BIT) buf.Append(KEGL_PBUFFER_BIT); |
|
394 if (surfaceType & EGL_PIXMAP_BIT) buf.Append(KEGL_PIXMAP_BIT); |
|
395 if (surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT) buf.Append(KEGL_VG_ALPHA_FORMAT_PRE_BIT); |
|
396 RDebug::Print(buf); |
|
397 } |
|
398 } |
|
399 } |
|
400 |
|
401 CleanupStack::PopAndDestroy(1, configs); |
|
402 } |
|
403 } |
|
404 } |
|
405 #endif |
|
406 |