source: trunk/src/gui/egl/qeglproperties.cpp@ 605

Last change on this file since 605 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 17.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qeglproperties_p.h"
43
44QT_BEGIN_NAMESPACE
45
46#include <QtCore/qdebug.h>
47#include <QtCore/qstringlist.h>
48
49#include "qegl_p.h"
50
51
52// Initialize a property block.
53QEglProperties::QEglProperties()
54{
55 props.append(EGL_NONE);
56}
57
58QEglProperties::QEglProperties(EGLConfig cfg)
59{
60 props.append(EGL_NONE);
61 for (int name = 0x3020; name <= 0x304F; ++name) {
62 EGLint value;
63 if (name != EGL_NONE && eglGetConfigAttrib(QEglContext::defaultDisplay(0), cfg, name, &value))
64 setValue(name, value);
65 }
66 eglGetError(); // Clear the error state.
67}
68
69// Fetch the current value associated with a property.
70int QEglProperties::value(int name) const
71{
72 for (int index = 0; index < (props.size() - 1); index += 2) {
73 if (props[index] == name)
74 return props[index + 1];
75 }
76
77 // If the attribute has not been explicitly set, return the EGL default
78 // The following defaults were taken from the EGL 1.4 spec:
79 switch(name) {
80 case EGL_BUFFER_SIZE: return 0;
81 case EGL_RED_SIZE: return 0;
82 case EGL_GREEN_SIZE: return 0;
83 case EGL_BLUE_SIZE: return 0;
84 case EGL_ALPHA_SIZE: return 0;
85#if defined(EGL_LUMINANCE_SIZE)
86 case EGL_LUMINANCE_SIZE: return 0;
87#endif
88#if defined(EGL_ALPHA_MASK_SIZE)
89 case EGL_ALPHA_MASK_SIZE: return 0;
90#endif
91#if defined(EGL_BIND_TO_TEXTURE_RGB)
92 case EGL_BIND_TO_TEXTURE_RGB: return EGL_DONT_CARE;
93#endif
94#if defined(EGL_BIND_TO_TEXTURE_RGBA)
95 case EGL_BIND_TO_TEXTURE_RGBA: return EGL_DONT_CARE;
96#endif
97#if defined(EGL_COLOR_BUFFER_TYPE)
98 case EGL_COLOR_BUFFER_TYPE: return EGL_RGB_BUFFER;
99#endif
100 case EGL_CONFIG_CAVEAT: return EGL_DONT_CARE;
101 case EGL_CONFIG_ID: return EGL_DONT_CARE;
102 case EGL_DEPTH_SIZE: return 0;
103 case EGL_LEVEL: return 0;
104 case EGL_NATIVE_RENDERABLE: return EGL_DONT_CARE;
105 case EGL_NATIVE_VISUAL_TYPE: return EGL_DONT_CARE;
106 case EGL_MAX_SWAP_INTERVAL: return EGL_DONT_CARE;
107 case EGL_MIN_SWAP_INTERVAL: return EGL_DONT_CARE;
108#if defined(EGL_RENDERABLE_TYPE)
109 case EGL_RENDERABLE_TYPE: return EGL_OPENGL_ES_BIT;
110#endif
111 case EGL_SAMPLE_BUFFERS: return 0;
112 case EGL_SAMPLES: return 0;
113 case EGL_STENCIL_SIZE: return 0;
114 case EGL_SURFACE_TYPE: return EGL_WINDOW_BIT;
115 case EGL_TRANSPARENT_TYPE: return EGL_NONE;
116 case EGL_TRANSPARENT_RED_VALUE: return EGL_DONT_CARE;
117 case EGL_TRANSPARENT_GREEN_VALUE: return EGL_DONT_CARE;
118 case EGL_TRANSPARENT_BLUE_VALUE: return EGL_DONT_CARE;
119
120#if defined(EGL_VERSION_1_3)
121 case EGL_CONFORMANT: return 0;
122 case EGL_MATCH_NATIVE_PIXMAP: return EGL_NONE;
123#endif
124
125 case EGL_MAX_PBUFFER_HEIGHT:
126 case EGL_MAX_PBUFFER_WIDTH:
127 case EGL_MAX_PBUFFER_PIXELS:
128 case EGL_NATIVE_VISUAL_ID:
129 case EGL_NONE:
130 // Attribute does not affect config selection.
131 return EGL_DONT_CARE;
132 default:
133 // Attribute is unknown in EGL <= 1.4.
134 return EGL_DONT_CARE;
135 }
136}
137
138// Set the value associated with a property, replacing an existing
139// value if there is one.
140void QEglProperties::setValue(int name, int value)
141{
142 for (int index = 0; index < (props.size() - 1); index += 2) {
143 if (props[index] == name) {
144 props[index + 1] = value;
145 return;
146 }
147 }
148 props[props.size() - 1] = name;
149 props.append(value);
150 props.append(EGL_NONE);
151}
152
153// Remove a property value. Returns false if the property is not present.
154bool QEglProperties::removeValue(int name)
155{
156 for (int index = 0; index < (props.size() - 1); index += 2) {
157 if (props[index] == name) {
158 while ((index + 2) < props.size()) {
159 props[index] = props[index + 2];
160 ++index;
161 }
162 props.resize(props.size() - 2);
163 return true;
164 }
165 }
166 return false;
167}
168
169// Sets the red, green, blue, and alpha sizes based on a pixel format.
170// Normally used to match a configuration request to the screen format.
171void QEglProperties::setPixelFormat(QImage::Format pixelFormat)
172{
173 int red, green, blue, alpha;
174 switch (pixelFormat) {
175 case QImage::Format_RGB32:
176 case QImage::Format_RGB888:
177 red = green = blue = 8; alpha = 0; break;
178 case QImage::Format_ARGB32:
179 case QImage::Format_ARGB32_Premultiplied:
180 red = green = blue = alpha = 8; break;
181 case QImage::Format_RGB16:
182 red = 5; green = 6; blue = 5; alpha = 0; break;
183 case QImage::Format_ARGB8565_Premultiplied:
184 red = 5; green = 6; blue = 5; alpha = 8; break;
185 case QImage::Format_RGB666:
186 red = green = blue = 6; alpha = 0; break;
187 case QImage::Format_ARGB6666_Premultiplied:
188 red = green = blue = alpha = 6; break;
189 case QImage::Format_RGB555:
190 red = green = blue = 5; alpha = 0; break;
191 case QImage::Format_ARGB8555_Premultiplied:
192 red = green = blue = 5; alpha = 8; break;
193 case QImage::Format_RGB444:
194 red = green = blue = 4; alpha = 0; break;
195 case QImage::Format_ARGB4444_Premultiplied:
196 red = green = blue = alpha = 4; break;
197 default:
198 qWarning() << "QEglProperties::setPixelFormat(): Unsupported pixel format";
199 red = green = blue = alpha = 1; break;
200 }
201 setValue(EGL_RED_SIZE, red);
202 setValue(EGL_GREEN_SIZE, green);
203 setValue(EGL_BLUE_SIZE, blue);
204 setValue(EGL_ALPHA_SIZE, alpha);
205}
206
207void QEglProperties::setRenderableType(QEgl::API api)
208{
209#if defined(EGL_RENDERABLE_TYPE)
210#if defined(QT_OPENGL_ES_2)
211 if (api == QEgl::OpenGL)
212 setValue(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT);
213#elif defined(QT_OPENGL_ES)
214 if (api == QEgl::OpenGL)
215 setValue(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT);
216#endif
217#if defined(EGL_OPENVG_BIT)
218 if (api == QEgl::OpenVG)
219 setValue(EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT);
220#endif
221#else
222 Q_UNUSED(api);
223#endif
224}
225
226// Reduce the complexity of a configuration request to ask for less
227// because the previous request did not result in success. Returns
228// true if the complexity was reduced, or false if no further
229// reductions in complexity are possible.
230bool QEglProperties::reduceConfiguration()
231{
232 // EGL chooses configs with the highest color depth over
233 // those with smaller (but faster) lower color depths. One
234 // way around this is to set EGL_BUFFER_SIZE to 16, which
235 // trumps the others. Of course, there may not be a 16-bit
236 // config avaliable, so it's the first restraint we remove.
237 if (value(EGL_BUFFER_SIZE) == 16) {
238 removeValue(EGL_BUFFER_SIZE);
239 return true;
240 }
241 if (removeValue(EGL_SAMPLE_BUFFERS)) {
242 removeValue(EGL_SAMPLES);
243 return true;
244 }
245 if (removeValue(EGL_ALPHA_SIZE)) {
246#if defined(EGL_BIND_TO_TEXTURE_RGBA) && defined(EGL_BIND_TO_TEXTURE_RGB)
247 if (removeValue(EGL_BIND_TO_TEXTURE_RGBA))
248 setValue(EGL_BIND_TO_TEXTURE_RGB, TRUE);
249#endif
250 return true;
251 }
252 if (removeValue(EGL_STENCIL_SIZE))
253 return true;
254 if (removeValue(EGL_DEPTH_SIZE))
255 return true;
256#if defined(EGL_BIND_TO_TEXTURE_RGB)
257 if (removeValue(EGL_BIND_TO_TEXTURE_RGB))
258 return true;
259#endif
260 return false;
261}
262
263static void addTag(QString& str, const QString& tag)
264{
265 int lastnl = str.lastIndexOf(QLatin1String("\n"));
266 if (lastnl == -1)
267 lastnl = 0;
268 if ((str.length() - lastnl) >= 50)
269 str += QLatin1String("\n ");
270 str += tag;
271}
272
273void QEglProperties::dumpAllConfigs()
274{
275 EGLint count = 0;
276 eglGetConfigs(QEglContext::defaultDisplay(0), 0, 0, &count);
277 if (count < 1)
278 return;
279
280 EGLConfig *configs = new EGLConfig [count];
281 eglGetConfigs(QEglContext::defaultDisplay(0), configs, count, &count);
282 for (EGLint index = 0; index < count; ++index)
283 qWarning() << QEglProperties(configs[index]).toString();
284 delete [] configs;
285}
286
287// Convert a property list to a string suitable for debug output.
288QString QEglProperties::toString() const
289{
290 QString str;
291 int val;
292
293 val = value(EGL_CONFIG_ID);
294 if (val != EGL_DONT_CARE) {
295 str += QLatin1String("id=");
296 str += QString::number(val);
297 str += QLatin1Char(' ');
298 }
299
300#ifdef EGL_RENDERABLE_TYPE
301 val = value(EGL_RENDERABLE_TYPE);
302 if (val != EGL_DONT_CARE) {
303 str += QLatin1String("type=");
304 QStringList types;
305 if ((val & EGL_OPENGL_ES_BIT) != 0)
306 types += QLatin1String("es1");
307#ifdef EGL_OPENGL_ES2_BIT
308 if ((val & EGL_OPENGL_ES2_BIT) != 0)
309 types += QLatin1String("es2");
310#endif
311 if ((val & EGL_OPENVG_BIT) != 0)
312 types += QLatin1String("vg");
313 if ((val & ~7) != 0)
314 types += QString::number(val);
315 str += types.join(QLatin1String(","));
316 } else {
317 str += QLatin1String("type=any");
318 }
319#else
320 str += QLatin1String("type=es1");
321#endif
322
323 int red = value(EGL_RED_SIZE);
324 int green = value(EGL_GREEN_SIZE);
325 int blue = value(EGL_BLUE_SIZE);
326 int alpha = value(EGL_ALPHA_SIZE);
327 int bufferSize = value(EGL_BUFFER_SIZE);
328 if (bufferSize == (red + green + blue + alpha))
329 bufferSize = 0;
330 str += QLatin1String(" rgba=");
331 str += QString::number(red);
332 str += QLatin1Char(',');
333 str += QString::number(green);
334 str += QLatin1Char(',');
335 str += QString::number(blue);
336 str += QLatin1Char(',');
337 str += QString::number(alpha);
338 if (bufferSize != 0) {
339 // Only report buffer size if different than r+g+b+a.
340 str += QLatin1String(" buffer-size=");
341 str += QString::number(bufferSize);
342 }
343
344#ifdef EGL_COLOR_BUFFER_TYPE
345 val = value(EGL_COLOR_BUFFER_TYPE);
346 if (val == EGL_LUMINANCE_BUFFER) {
347 addTag(str, QLatin1String(" color-buffer-type=luminance"));
348 } else if (val != EGL_DONT_CARE && val != EGL_RGB_BUFFER) {
349 addTag(str, QLatin1String(" color-buffer-type="));
350 str += QString::number(val, 16);
351 }
352#endif
353
354 val = value(EGL_DEPTH_SIZE);
355 if (val != 0) {
356 addTag(str, QLatin1String(" depth="));
357 str += QString::number(val);
358 }
359
360 val = value(EGL_STENCIL_SIZE);
361 if (val != 0) {
362 addTag(str, QLatin1String(" stencil="));
363 str += QString::number(val);
364 }
365
366 val = value(EGL_SURFACE_TYPE);
367 if (val != EGL_DONT_CARE) {
368 addTag(str, QLatin1String(" surface-type="));
369 QStringList types;
370 if ((val & EGL_WINDOW_BIT) != 0)
371 types += QLatin1String("window");
372 if ((val & EGL_PIXMAP_BIT) != 0)
373 types += QLatin1String("pixmap");
374 if ((val & EGL_PBUFFER_BIT) != 0)
375 types += QLatin1String("pbuffer");
376#ifdef EGL_VG_COLORSPACE_LINEAR_BIT
377 if ((val & EGL_VG_COLORSPACE_LINEAR_BIT) != 0)
378 types += QLatin1String("vg-colorspace-linear");
379#endif
380#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
381 if ((val & EGL_VG_ALPHA_FORMAT_PRE_BIT) != 0)
382 types += QLatin1String("vg-alpha-format-pre");
383#endif
384 if ((val & ~(EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT
385#ifdef EGL_VG_COLORSPACE_LINEAR_BIT
386 | EGL_VG_COLORSPACE_LINEAR_BIT
387#endif
388#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
389 | EGL_VG_ALPHA_FORMAT_PRE_BIT
390#endif
391 )) != 0) {
392 types += QString::number(val);
393 }
394 str += types.join(QLatin1String(","));
395 }
396
397 val = value(EGL_CONFIG_CAVEAT);
398 if (val != EGL_DONT_CARE) {
399 addTag(str, QLatin1String(" caveat="));
400 if (val == EGL_NONE)
401 str += QLatin1String("none");
402 else if (val == EGL_SLOW_CONFIG)
403 str += QLatin1String("slow");
404 else if (val == EGL_NON_CONFORMANT_CONFIG)
405 str += QLatin1String("non-conformant");
406 else
407 str += QString::number(val, 16);
408 }
409
410 val = value(EGL_LEVEL);
411 if (val != 0) {
412 addTag(str, QLatin1String(" level="));
413 str += QString::number(val);
414 }
415
416 int width, height, pixels;
417 width = value(EGL_MAX_PBUFFER_WIDTH);
418 height = value(EGL_MAX_PBUFFER_HEIGHT);
419 pixels = value(EGL_MAX_PBUFFER_PIXELS);
420 if (height != EGL_DONT_CARE || width != EGL_DONT_CARE) {
421 addTag(str, QLatin1String(" max-pbuffer-size="));
422 str += QString::number(width);
423 str += QLatin1Char('x');
424 str += QString::number(height);
425 if (pixels != (width * height)) {
426 addTag(str, QLatin1String(" max-pbuffer-pixels="));
427 str += QString::number(pixels);
428 }
429 }
430
431 val = value(EGL_NATIVE_RENDERABLE);
432 if (val != EGL_DONT_CARE) {
433 if (val)
434 addTag(str, QLatin1String(" native-renderable=true"));
435 else
436 addTag(str, QLatin1String(" native-renderable=false"));
437 }
438
439 val = value(EGL_NATIVE_VISUAL_ID);
440 if (val != EGL_DONT_CARE) {
441 addTag(str, QLatin1String(" visual-id="));
442 str += QString::number(val);
443 }
444
445 val = value(EGL_NATIVE_VISUAL_TYPE);
446 if (val != EGL_DONT_CARE) {
447 addTag(str, QLatin1String(" visual-type="));
448 str += QString::number(val);
449 }
450
451#ifdef EGL_PRESERVED_RESOURCES
452 val = value(EGL_PRESERVED_RESOURCES);
453 if (val != EGL_DONT_CARE) {
454 if (val)
455 addTag(str, QLatin1String(" preserved-resources=true"));
456 else
457 addTag(str, QLatin1String(" preserved-resources=false"));
458 }
459#endif
460
461 val = value(EGL_SAMPLES);
462 if (val != 0) {
463 addTag(str, QLatin1String(" samples="));
464 str += QString::number(val);
465 }
466
467 val = value(EGL_SAMPLE_BUFFERS);
468 if (val != 0) {
469 addTag(str, QLatin1String(" sample-buffers="));
470 str += QString::number(val);
471 }
472
473 val = value(EGL_TRANSPARENT_TYPE);
474 if (val == EGL_TRANSPARENT_RGB) {
475 addTag(str, QLatin1String(" transparent-rgb="));
476 str += QString::number(value(EGL_TRANSPARENT_RED_VALUE));
477 str += QLatin1Char(',');
478 str += QString::number(value(EGL_TRANSPARENT_GREEN_VALUE));
479 str += QLatin1Char(',');
480 str += QString::number(value(EGL_TRANSPARENT_BLUE_VALUE));
481 }
482
483#if defined(EGL_BIND_TO_TEXTURE_RGB) && defined(EGL_BIND_TO_TEXTURE_RGBA)
484 val = value(EGL_BIND_TO_TEXTURE_RGB);
485 int val2 = value(EGL_BIND_TO_TEXTURE_RGBA);
486 if (val != EGL_DONT_CARE || val2 != EGL_DONT_CARE) {
487 addTag(str, QLatin1String(" bind-texture="));
488 if (val == EGL_TRUE)
489 str += QLatin1String("rgb");
490 else
491 str += QLatin1String("no-rgb");
492 if (val2 == EGL_TRUE)
493 str += QLatin1String(",rgba");
494 else
495 str += QLatin1String(",no-rgba");
496 }
497#endif
498
499#ifdef EGL_MIN_SWAP_INTERVAL
500 val = value(EGL_MIN_SWAP_INTERVAL);
501 if (val != EGL_DONT_CARE) {
502 addTag(str, QLatin1String(" min-swap-interval="));
503 str += QString::number(val);
504 }
505#endif
506
507#ifdef EGL_MIN_SWAP_INTERVAL
508 val = value(EGL_MAX_SWAP_INTERVAL);
509 if (val != EGL_DONT_CARE) {
510 addTag(str, QLatin1String(" max-swap-interval="));
511 str += QString::number(val);
512 }
513#endif
514
515#ifdef EGL_LUMINANCE_SIZE
516 val = value(EGL_LUMINANCE_SIZE);
517 if (val != 0) {
518 addTag(str, QLatin1String(" luminance="));
519 str += QString::number(val);
520 }
521#endif
522
523#ifdef EGL_ALPHA_MASK_SIZE
524 val = value(EGL_ALPHA_MASK_SIZE);
525 if (val != 0) {
526 addTag(str, QLatin1String(" alpha-mask="));
527 str += QString::number(val);
528 }
529#endif
530
531#ifdef EGL_CONFORMANT
532 val = value(EGL_CONFORMANT);
533 if (val != 0) {
534 if (val)
535 addTag(str, QLatin1String(" conformant=true"));
536 else
537 addTag(str, QLatin1String(" conformant=false"));
538 }
539#endif
540
541 return str;
542}
543
544QT_END_NAMESPACE
545
546
Note: See TracBrowser for help on using the repository browser.