2 * Extra utility functions related to EGL configs.
9 #include "eglconfigutil.h"
14 * Convert an _EGLConfig to a __GLcontextModes object.
15 * NOTE: This routine may be incomplete - we're only making sure that
16 * the fields needed by Mesa (for _mesa_create_context/framebuffer) are
20 _eglConfigToContextModesRec(const _EGLConfig
*config
, __GLcontextModes
*mode
)
22 memset(mode
, 0, sizeof(*mode
));
24 mode
->rgbMode
= GL_TRUE
; /* no color index */
25 mode
->colorIndexMode
= GL_FALSE
;
26 mode
->doubleBufferMode
= GL_TRUE
; /* always DB for now */
27 mode
->stereoMode
= GL_FALSE
;
29 mode
->redBits
= GET_CONFIG_ATTRIB(config
, EGL_RED_SIZE
);
30 mode
->greenBits
= GET_CONFIG_ATTRIB(config
, EGL_GREEN_SIZE
);
31 mode
->blueBits
= GET_CONFIG_ATTRIB(config
, EGL_BLUE_SIZE
);
32 mode
->alphaBits
= GET_CONFIG_ATTRIB(config
, EGL_ALPHA_SIZE
);
33 mode
->rgbBits
= GET_CONFIG_ATTRIB(config
, EGL_BUFFER_SIZE
);
35 /* no rgba masks - fix? */
37 mode
->depthBits
= GET_CONFIG_ATTRIB(config
, EGL_DEPTH_SIZE
);
38 mode
->haveDepthBuffer
= mode
->depthBits
> 0;
40 mode
->stencilBits
= GET_CONFIG_ATTRIB(config
, EGL_STENCIL_SIZE
);
41 mode
->haveStencilBuffer
= mode
->stencilBits
> 0;
45 mode
->level
= GET_CONFIG_ATTRIB(config
, EGL_LEVEL
);
46 mode
->samples
= GET_CONFIG_ATTRIB(config
, EGL_SAMPLES
);
47 mode
->sampleBuffers
= GET_CONFIG_ATTRIB(config
, EGL_SAMPLE_BUFFERS
);
49 /* surface type - not really needed */
50 mode
->visualType
= GLX_TRUE_COLOR
;
51 mode
->renderType
= GLX_RGBA_BIT
;
57 * Creates a set of \c _EGLConfigs that a driver will expose.
59 * A set of \c __GLcontextModes will be created based on the supplied
60 * parameters. The number of modes processed will be 2 *
61 * \c num_depth_stencil_bits * \c num_db_modes.
63 * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
64 * \c db_modes, and \c visType into each \c __GLcontextModes element.
65 * However, the meanings of \c fb_format and \c fb_type require further
66 * explanation. The \c fb_format specifies which color components are in
67 * each pixel and what the default order is. For example, \c GL_RGB specifies
68 * that red, green, blue are available and red is in the "most significant"
69 * position and blue is in the "least significant". The \c fb_type specifies
70 * the bit sizes of each component and the actual ordering. For example, if
71 * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
72 * are the blue value, bits [10:5] are the green value, and bits [4:0] are
75 * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
76 * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
77 * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or
78 * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
79 * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
82 * If in doubt, look at the tables used in the function.
84 * \param configs the array of configs generated
85 * \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
86 * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
87 * \param fb_type Type of the pixels in the framebuffer. Currently only
88 * \c GL_UNSIGNED_SHORT_5_6_5,
89 * \c GL_UNSIGNED_SHORT_5_6_5_REV,
90 * \c GL_UNSIGNED_INT_8_8_8_8, and
91 * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
92 * \param depth_bits Array of depth buffer sizes to be exposed.
93 * \param stencil_bits Array of stencil buffer sizes to be exposed.
94 * \param num_depth_stencil_bits Number of entries in both \c depth_bits and
96 * \param db_modes Array of buffer swap modes. If an element has a
97 * value of \c GLX_NONE, then it represents a
98 * single-buffered mode. Other valid values are
99 * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
100 * \c GLX_SWAP_UNDEFINED_OML. See the
101 * GLX_OML_swap_method extension spec for more details.
102 * \param num_db_modes Number of entries in \c db_modes.
103 * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
104 * \c GLX_DIRECT_COLOR.
107 * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
108 * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
112 * There is currently no way to support packed RGB modes (i.e., modes with
113 * exactly 3 bytes per pixel) or floating-point modes. This could probably
114 * be done by creating some new, private enums with clever names likes
115 * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
116 * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
119 _eglFillInConfigs(_EGLConfig
* configs
,
120 GLenum fb_format
, GLenum fb_type
,
121 const uint8_t * depth_bits
, const uint8_t * stencil_bits
,
122 unsigned num_depth_stencil_bits
,
123 const GLenum
* db_modes
, unsigned num_db_modes
,
126 static const uint8_t bits_table
[3][4] = {
128 { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
129 { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
130 { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
133 /* The following arrays are all indexed by the fb_type masked with 0x07.
134 * Given the four supported fb_type values, this results in valid array
135 * indices of 3, 4, 5, and 7.
137 static const uint32_t masks_table_rgb
[8][4] = {
138 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
139 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
140 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
141 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
142 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
143 {0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000}, /* 8_8_8_8 */
144 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
145 {0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000} /* 8_8_8_8_REV */
148 static const uint32_t masks_table_rgba
[8][4] = {
149 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
150 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
151 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
152 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
153 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
154 {0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF}, /* 8_8_8_8 */
155 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
156 {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000}, /* 8_8_8_8_REV */
160 static const uint32_t masks_table_bgr
[8][4] = {
161 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
162 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
163 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
164 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
165 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
166 {0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000}, /* 8_8_8_8 */
167 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
168 {0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000}, /* 8_8_8_8_REV */
171 static const uint32_t masks_table_bgra
[8][4] = {
172 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
173 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
174 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
175 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
176 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
177 {0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF}, /* 8_8_8_8 */
178 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
179 {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, /* 8_8_8_8_REV */
183 static const uint8_t bytes_per_pixel
[8] = {
184 0, 0, 0, 2, 2, 4, 0, 4
187 const uint8_t * bits
;
188 const uint32_t * masks
;
189 const int index
= fb_type
& 0x07;
195 if ( bytes_per_pixel
[index
] == 0 ) {
197 "[_eglFillInConfigs:%u] Framebuffer type 0x%04x has 0 bytes per pixel.",
202 /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
205 * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
207 switch ( fb_format
) {
209 bits
= (bytes_per_pixel
[index
] == 2) ? bits_table
[0] : bits_table
[1];
210 masks
= masks_table_rgb
[index
];
214 bits
= (bytes_per_pixel
[index
] == 2) ? bits_table
[0] : bits_table
[2];
215 masks
= masks_table_rgba
[index
];
220 bits
= (bytes_per_pixel
[index
] == 2) ? bits_table
[0] : bits_table
[1];
221 masks
= masks_table_bgr
[index
];
225 bits
= (bytes_per_pixel
[index
] == 2) ? bits_table
[0] : bits_table
[2];
226 masks
= masks_table_bgra
[index
];
231 _eglLog(_EGL_WARNING
,
232 "[_eglFillInConfigs:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.",
233 __LINE__
, fb_format
);
238 for (k
= 0; k
< num_depth_stencil_bits
; k
++) {
239 for (i
= 0; i
< num_db_modes
; i
++) {
240 for (j
= 0; j
< 2; j
++) {
241 _eglSetConfigAttrib(config
, EGL_RED_SIZE
, bits
[0]);
242 _eglSetConfigAttrib(config
, EGL_GREEN_SIZE
, bits
[1]);
243 _eglSetConfigAttrib(config
, EGL_BLUE_SIZE
, bits
[2]);
244 _eglSetConfigAttrib(config
, EGL_ALPHA_SIZE
, bits
[3]);
245 _eglSetConfigAttrib(config
, EGL_BUFFER_SIZE
,
246 bits
[0] + bits
[1] + bits
[2] + bits
[3]);
248 _eglSetConfigAttrib(config
, EGL_STENCIL_SIZE
, stencil_bits
[k
]);
249 _eglSetConfigAttrib(config
, EGL_DEPTH_SIZE
, depth_bits
[i
]);
251 _eglSetConfigAttrib(config
, EGL_SURFACE_TYPE
, EGL_SCREEN_BIT_MESA
|
252 EGL_PBUFFER_BIT
| EGL_PIXMAP_BIT
| EGL_WINDOW_BIT
);