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
;
56 * Convert a __GLcontextModes object to an _EGLConfig.
59 _eglConfigFromContextModesRec(_EGLConfig
*conf
, const __GLcontextModes
*m
,
60 EGLint conformant
, EGLint renderable_type
)
62 EGLint config_caveat
, surface_type
;
65 if (!m
->rgbMode
|| !(m
->renderType
& GLX_RGBA_BIT
))
68 config_caveat
= EGL_NONE
;
69 if (m
->visualRating
== GLX_SLOW_CONFIG
)
70 config_caveat
= EGL_SLOW_CONFIG
;
72 if (m
->visualRating
== GLX_NON_CONFORMANT_CONFIG
)
73 conformant
&= ~EGL_OPENGL_BIT
;
74 if (!(conformant
& EGL_OPENGL_ES_BIT
))
75 config_caveat
= EGL_NON_CONFORMANT_CONFIG
;
78 if (m
->drawableType
& GLX_WINDOW_BIT
)
79 surface_type
|= EGL_WINDOW_BIT
;
80 if (m
->drawableType
& GLX_PIXMAP_BIT
)
81 surface_type
|= EGL_PIXMAP_BIT
;
82 if (m
->drawableType
& GLX_PBUFFER_BIT
)
83 surface_type
|= EGL_PBUFFER_BIT
;
85 SET_CONFIG_ATTRIB(conf
, EGL_BUFFER_SIZE
, m
->rgbBits
);
86 SET_CONFIG_ATTRIB(conf
, EGL_RED_SIZE
, m
->redBits
);
87 SET_CONFIG_ATTRIB(conf
, EGL_GREEN_SIZE
, m
->greenBits
);
88 SET_CONFIG_ATTRIB(conf
, EGL_BLUE_SIZE
, m
->blueBits
);
89 SET_CONFIG_ATTRIB(conf
, EGL_ALPHA_SIZE
, m
->alphaBits
);
91 SET_CONFIG_ATTRIB(conf
, EGL_BIND_TO_TEXTURE_RGB
, m
->bindToTextureRgb
);
92 SET_CONFIG_ATTRIB(conf
, EGL_BIND_TO_TEXTURE_RGBA
, m
->bindToTextureRgba
);
93 SET_CONFIG_ATTRIB(conf
, EGL_COLOR_BUFFER_TYPE
, EGL_RGB_BUFFER
);
94 SET_CONFIG_ATTRIB(conf
, EGL_CONFIG_CAVEAT
, config_caveat
);
96 SET_CONFIG_ATTRIB(conf
, EGL_CONFORMANT
, conformant
);
97 SET_CONFIG_ATTRIB(conf
, EGL_DEPTH_SIZE
, m
->depthBits
);
98 SET_CONFIG_ATTRIB(conf
, EGL_LEVEL
, m
->level
);
99 SET_CONFIG_ATTRIB(conf
, EGL_MAX_PBUFFER_WIDTH
, m
->maxPbufferWidth
);
100 SET_CONFIG_ATTRIB(conf
, EGL_MAX_PBUFFER_HEIGHT
, m
->maxPbufferHeight
);
101 SET_CONFIG_ATTRIB(conf
, EGL_MAX_PBUFFER_PIXELS
, m
->maxPbufferPixels
);
103 SET_CONFIG_ATTRIB(conf
, EGL_NATIVE_RENDERABLE
, m
->xRenderable
);
104 SET_CONFIG_ATTRIB(conf
, EGL_NATIVE_VISUAL_ID
, m
->visualID
);
106 if (m
->visualType
!= GLX_NONE
)
107 SET_CONFIG_ATTRIB(conf
, EGL_NATIVE_VISUAL_TYPE
, m
->visualType
);
109 SET_CONFIG_ATTRIB(conf
, EGL_NATIVE_VISUAL_TYPE
, EGL_NONE
);
111 SET_CONFIG_ATTRIB(conf
, EGL_RENDERABLE_TYPE
, renderable_type
);
112 SET_CONFIG_ATTRIB(conf
, EGL_SAMPLE_BUFFERS
, m
->sampleBuffers
);
113 SET_CONFIG_ATTRIB(conf
, EGL_SAMPLES
, m
->samples
);
114 SET_CONFIG_ATTRIB(conf
, EGL_STENCIL_SIZE
, m
->stencilBits
);
116 SET_CONFIG_ATTRIB(conf
, EGL_SURFACE_TYPE
, surface_type
);
118 /* what to do with GLX_TRANSPARENT_INDEX? */
119 if (m
->transparentPixel
== GLX_TRANSPARENT_RGB
) {
120 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_TYPE
, EGL_TRANSPARENT_RGB
);
121 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_RED_VALUE
, m
->transparentRed
);
122 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_GREEN_VALUE
, m
->transparentGreen
);
123 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_BLUE_VALUE
, m
->transparentBlue
);
126 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_TYPE
, EGL_NONE
);
134 * Creates a set of \c _EGLConfigs that a driver will expose.
136 * A set of \c __GLcontextModes will be created based on the supplied
137 * parameters. The number of modes processed will be 2 *
138 * \c num_depth_stencil_bits * \c num_db_modes.
140 * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
141 * \c db_modes, and \c visType into each \c __GLcontextModes element.
142 * However, the meanings of \c fb_format and \c fb_type require further
143 * explanation. The \c fb_format specifies which color components are in
144 * each pixel and what the default order is. For example, \c GL_RGB specifies
145 * that red, green, blue are available and red is in the "most significant"
146 * position and blue is in the "least significant". The \c fb_type specifies
147 * the bit sizes of each component and the actual ordering. For example, if
148 * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
149 * are the blue value, bits [10:5] are the green value, and bits [4:0] are
152 * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
153 * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
154 * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or
155 * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
156 * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
157 * still uses 32-bits.
159 * If in doubt, look at the tables used in the function.
161 * \param configs the array of configs generated
162 * \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
163 * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
164 * \param fb_type Type of the pixels in the framebuffer. Currently only
165 * \c GL_UNSIGNED_SHORT_5_6_5,
166 * \c GL_UNSIGNED_SHORT_5_6_5_REV,
167 * \c GL_UNSIGNED_INT_8_8_8_8, and
168 * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
169 * \param depth_bits Array of depth buffer sizes to be exposed.
170 * \param stencil_bits Array of stencil buffer sizes to be exposed.
171 * \param num_depth_stencil_bits Number of entries in both \c depth_bits and
173 * \param db_modes Array of buffer swap modes. If an element has a
174 * value of \c GLX_NONE, then it represents a
175 * single-buffered mode. Other valid values are
176 * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
177 * \c GLX_SWAP_UNDEFINED_OML. See the
178 * GLX_OML_swap_method extension spec for more details.
179 * \param num_db_modes Number of entries in \c db_modes.
180 * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
181 * \c GLX_DIRECT_COLOR.
184 * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
185 * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
189 * There is currently no way to support packed RGB modes (i.e., modes with
190 * exactly 3 bytes per pixel) or floating-point modes. This could probably
191 * be done by creating some new, private enums with clever names likes
192 * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
193 * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
196 _eglFillInConfigs(_EGLConfig
* configs
,
197 GLenum fb_format
, GLenum fb_type
,
198 const uint8_t * depth_bits
, const uint8_t * stencil_bits
,
199 unsigned num_depth_stencil_bits
,
200 const GLenum
* db_modes
, unsigned num_db_modes
,
203 static const uint8_t bits_table
[3][4] = {
205 { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
206 { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
207 { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
210 /* The following arrays are all indexed by the fb_type masked with 0x07.
211 * Given the four supported fb_type values, this results in valid array
212 * indices of 3, 4, 5, and 7.
214 static const uint32_t masks_table_rgb
[8][4] = {
215 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
216 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
217 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
218 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
219 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
220 {0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000}, /* 8_8_8_8 */
221 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
222 {0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000} /* 8_8_8_8_REV */
225 static const uint32_t masks_table_rgba
[8][4] = {
226 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
227 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
228 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
229 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
230 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
231 {0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF}, /* 8_8_8_8 */
232 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
233 {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000}, /* 8_8_8_8_REV */
237 static const uint32_t masks_table_bgr
[8][4] = {
238 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
239 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
240 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
241 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
242 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
243 {0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000}, /* 8_8_8_8 */
244 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
245 {0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000}, /* 8_8_8_8_REV */
248 static const uint32_t masks_table_bgra
[8][4] = {
249 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
250 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
251 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
252 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
253 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
254 {0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF}, /* 8_8_8_8 */
255 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
256 {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, /* 8_8_8_8_REV */
260 static const uint8_t bytes_per_pixel
[8] = {
261 0, 0, 0, 2, 2, 4, 0, 4
264 const uint8_t * bits
;
265 const uint32_t * masks
;
266 const int index
= fb_type
& 0x07;
272 if ( bytes_per_pixel
[index
] == 0 ) {
274 "[_eglFillInConfigs:%u] Framebuffer type 0x%04x has 0 bytes per pixel.",
279 /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
282 * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
284 switch ( fb_format
) {
286 bits
= (bytes_per_pixel
[index
] == 2) ? bits_table
[0] : bits_table
[1];
287 masks
= masks_table_rgb
[index
];
291 bits
= (bytes_per_pixel
[index
] == 2) ? bits_table
[0] : bits_table
[2];
292 masks
= masks_table_rgba
[index
];
297 bits
= (bytes_per_pixel
[index
] == 2) ? bits_table
[0] : bits_table
[1];
298 masks
= masks_table_bgr
[index
];
302 bits
= (bytes_per_pixel
[index
] == 2) ? bits_table
[0] : bits_table
[2];
303 masks
= masks_table_bgra
[index
];
308 _eglLog(_EGL_WARNING
,
309 "[_eglFillInConfigs:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.",
310 __LINE__
, fb_format
);
315 for (k
= 0; k
< num_depth_stencil_bits
; k
++) {
316 for (i
= 0; i
< num_db_modes
; i
++) {
317 for (j
= 0; j
< 2; j
++) {
318 _eglSetConfigAttrib(config
, EGL_RED_SIZE
, bits
[0]);
319 _eglSetConfigAttrib(config
, EGL_GREEN_SIZE
, bits
[1]);
320 _eglSetConfigAttrib(config
, EGL_BLUE_SIZE
, bits
[2]);
321 _eglSetConfigAttrib(config
, EGL_ALPHA_SIZE
, bits
[3]);
322 _eglSetConfigAttrib(config
, EGL_BUFFER_SIZE
,
323 bits
[0] + bits
[1] + bits
[2] + bits
[3]);
325 _eglSetConfigAttrib(config
, EGL_STENCIL_SIZE
, stencil_bits
[k
]);
326 _eglSetConfigAttrib(config
, EGL_DEPTH_SIZE
, depth_bits
[i
]);
328 _eglSetConfigAttrib(config
, EGL_SURFACE_TYPE
, EGL_SCREEN_BIT_MESA
|
329 EGL_PBUFFER_BIT
| EGL_PIXMAP_BIT
| EGL_WINDOW_BIT
);