1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the copyright holder nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#include "interface/khronos/common/khrn_int_common.h"
29#include "interface/khronos/common/khrn_client_platform.h"
30#include "interface/khronos/include/EGL/eglext.h"
31
32#include "interface/khronos/egl/egl_client_config.h"
33
34//#define BGR_FB
35
36typedef uint32_t FEATURES_T;
37
38#define FEATURES_PACK(r, g, b, a, d, s, m, mask, lockable) ((FEATURES_T)((((uint32_t)(r)) << 28 | (g) << 24 | (b) << 20 | (a) << 16 | (d) << 8 | (s) << 4 | (m) << 3 | ((mask) >> 3) << 2) | (lockable) << 1))
39
40typedef struct {
41 FEATURES_T features;
42 KHRN_IMAGE_FORMAT_T color, depth, multisample, mask;
43} FEATURES_AND_FORMATS_T;
44
45/*
46 formats
47
48 For 0 <= id < EGL_MAX_CONFIGS:
49 formats[id].features is valid
50*/
51
52static FEATURES_AND_FORMATS_T formats[EGL_MAX_CONFIGS] = {
53// LOCKABLE
54// MASK |
55// R G B A D S M | | COLOR DEPTH MULTISAMPLE MASK
56 {FEATURES_PACK(8, 8, 8, 8, 24, 8, 0, 0, 0), ABGR_8888, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
57 {FEATURES_PACK(8, 8, 8, 0, 24, 8, 0, 0, 0), XBGR_8888, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
58 {FEATURES_PACK(8, 8, 8, 8, 24, 0, 0, 0, 0), ABGR_8888, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
59 {FEATURES_PACK(8, 8, 8, 0, 24, 0, 0, 0, 0), XBGR_8888, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
60 {FEATURES_PACK(8, 8, 8, 8, 0, 8, 0, 0, 0), ABGR_8888, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
61 {FEATURES_PACK(8, 8, 8, 0, 0, 8, 0, 0, 0), XBGR_8888, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
62 {FEATURES_PACK(8, 8, 8, 8, 0, 0, 0, 0, 0), ABGR_8888, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
63 {FEATURES_PACK(8, 8, 8, 0, 0, 0, 0, 0, 0), XBGR_8888, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
64
65 {FEATURES_PACK(8, 8, 8, 8, 24, 8, 1, 0, 0), ABGR_8888, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
66 {FEATURES_PACK(8, 8, 8, 0, 24, 8, 1, 0, 0), XBGR_8888, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
67 {FEATURES_PACK(8, 8, 8, 8, 24, 0, 1, 0, 0), ABGR_8888, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
68 {FEATURES_PACK(8, 8, 8, 0, 24, 0, 1, 0, 0), XBGR_8888, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
69 {FEATURES_PACK(8, 8, 8, 8, 0, 8, 1, 0, 0), ABGR_8888, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
70 {FEATURES_PACK(8, 8, 8, 0, 0, 8, 1, 0, 0), XBGR_8888, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
71 {FEATURES_PACK(8, 8, 8, 8, 0, 0, 1, 0, 0), ABGR_8888, IMAGE_FORMAT_INVALID, COL_32_TLBD, IMAGE_FORMAT_INVALID},
72 {FEATURES_PACK(8, 8, 8, 0, 0, 0, 1, 0, 0), XBGR_8888, IMAGE_FORMAT_INVALID, COL_32_TLBD, IMAGE_FORMAT_INVALID},
73
74 {FEATURES_PACK(5, 6, 5, 0, 24, 8, 0, 0, 0), RGB_565, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
75 {FEATURES_PACK(5, 6, 5, 0, 24, 0, 0, 0, 0), RGB_565, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
76 {FEATURES_PACK(5, 6, 5, 0, 0, 8, 0, 0, 0), RGB_565, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
77 {FEATURES_PACK(5, 6, 5, 0, 0, 0, 0, 0, 0), RGB_565, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
78
79 {FEATURES_PACK(5, 6, 5, 0, 24, 8, 1, 0, 0), RGB_565, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
80 {FEATURES_PACK(5, 6, 5, 0, 24, 0, 1, 0, 0), RGB_565, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
81 {FEATURES_PACK(5, 6, 5, 0, 0, 8, 1, 0, 0), RGB_565, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
82 {FEATURES_PACK(5, 6, 5, 0, 0, 0, 1, 0, 0), RGB_565, IMAGE_FORMAT_INVALID, COL_32_TLBD, IMAGE_FORMAT_INVALID},
83
84#ifndef EGL_NO_ALPHA_MASK_CONFIGS
85 {FEATURES_PACK(8, 8, 8, 8, 0, 0, 0, 8, 0), ABGR_8888, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID, A_8_RSO},
86 {FEATURES_PACK(8, 8, 8, 0, 0, 0, 0, 8, 0), XBGR_8888, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID, A_8_RSO},
87 {FEATURES_PACK(5, 6, 5, 0, 0, 0, 0, 8, 0), RGB_565, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID, A_8_RSO},
88#endif
89
90 {FEATURES_PACK(5, 6, 5, 0, 16, 0, 0, 0, 0), RGB_565, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
91
92};
93
94void egl_config_install_configs(int type)
95{
96 uint32_t i;
97 for (i = 0; i != ARR_COUNT(formats); ++i) {
98 formats[i].color = (type == 0) ?
99 khrn_image_to_rso_format(formats[i].color) :
100 khrn_image_to_tf_format(formats[i].color);
101 }
102}
103
104static bool bindable_rgb(FEATURES_T features);
105static bool bindable_rgba(FEATURES_T features);
106
107#include "interface/khronos/egl/egl_client_config_cr.c"
108
109/*
110 KHRN_IMAGE_FORMAT_T egl_config_get_color_format(int id)
111
112 Implementation notes:
113
114 We may return an image format which cannot be rendered to.
115
116 Preconditions:
117
118 0 <= id < EGL_MAX_CONFIGS
119
120 Postconditions:
121
122 Return value is a hardware framebuffer-supported uncompressed color KHRN_IMAGE_FORMAT_T
123*/
124
125KHRN_IMAGE_FORMAT_T egl_config_get_color_format(int id)
126{
127 vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
128
129 return formats[id].color;
130}
131
132/*
133 KHRN_IMAGE_FORMAT_T egl_config_get_depth_format(int id)
134
135 Preconditions:
136
137 0 <= id < EGL_MAX_CONFIGS
138
139 Postconditions:
140
141 Return value is a hardware framebuffer-supported depth KHRN_IMAGE_FORMAT_T or IMAGE_FORMAT_INVALID
142*/
143
144KHRN_IMAGE_FORMAT_T egl_config_get_depth_format(int id)
145{
146 vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
147
148 return formats[id].depth;
149}
150
151/*
152 KHRN_IMAGE_FORMAT_T egl_config_get_mask_format(int id)
153
154 Preconditions:
155
156 0 <= id < EGL_MAX_CONFIGS
157
158 Postconditions:
159
160 Return value is a hardware framebuffer-supported mask KHRN_IMAGE_FORMAT_T or IMAGE_FORMAT_INVALID
161*/
162
163KHRN_IMAGE_FORMAT_T egl_config_get_mask_format(int id)
164{
165 vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
166
167 return formats[id].mask;
168}
169
170/*
171 KHRN_IMAGE_FORMAT_T egl_config_get_multisample_format(int id)
172
173 Preconditions:
174
175 0 <= id < EGL_MAX_CONFIGS
176
177 Postconditions:
178
179 Return value is a hardware framebuffer-supported multisample color format or IMAGE_FORMAT_INVALID
180*/
181
182KHRN_IMAGE_FORMAT_T egl_config_get_multisample_format(int id)
183{
184 vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
185
186 return formats[id].multisample;
187}
188
189/*
190 bool egl_config_get_multisample(int id)
191
192 Preconditions:
193
194 0 <= id < EGL_MAX_CONFIGS
195
196 Postconditions:
197
198 -
199*/
200
201bool egl_config_get_multisample(int id)
202{
203 vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
204
205 return FEATURES_UNPACK_MULTI(formats[id].features);
206}
207
208/*
209 bool bindable_rgb(FEATURES_T features)
210 bool bindable_rgba(FEATURES_T features)
211
212 Preconditions:
213
214 features is a valid FEATURES_T
215
216 Postconditions:
217
218 -
219*/
220
221static bool bindable_rgb(FEATURES_T features)
222{
223 return !FEATURES_UNPACK_MULTI(features) && !FEATURES_UNPACK_ALPHA(features);
224}
225
226static bool bindable_rgba(FEATURES_T features)
227{
228 return !FEATURES_UNPACK_MULTI(features);
229}
230
231bool egl_config_bindable(int id, EGLenum format)
232{
233 vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
234 switch (format) {
235 case EGL_NO_TEXTURE:
236 return true;
237 case EGL_TEXTURE_RGB:
238 return bindable_rgb(formats[id].features);
239 case EGL_TEXTURE_RGBA:
240 return bindable_rgba(formats[id].features);
241 default:
242 UNREACHABLE();
243 return false;
244 }
245}
246
247/*
248 bool egl_config_match_pixmap_info(int id, KHRN_IMAGE_WRAP_T *image)
249
250 TODO: decide how tolerant we should be when matching to native pixmaps.
251 At present they match if the red, green, blue and alpha channels
252 all have the same bit depths.
253
254 Preconditions:
255
256 0 <= id < EGL_MAX_CONFIGS
257 image is a pointer to a valid KHRN_IMAGE_WRAP_T, possibly with null data pointer
258 match is a bitmask which is a subset of PLATFORM_PIXMAP_MATCH_NONRENDERABLE|PLATFORM_PIXMAP_MATCH_RENDERABLE
259
260 Postconditions:
261
262 -
263*/
264
265bool egl_config_match_pixmap_info(int id, KHRN_IMAGE_WRAP_T *image)
266{
267 FEATURES_T features = formats[id].features;
268 KHRN_IMAGE_FORMAT_T format = image->format;
269
270 vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
271
272 return
273 khrn_image_get_red_size(format) == FEATURES_UNPACK_RED(features) &&
274 khrn_image_get_green_size(format) == FEATURES_UNPACK_GREEN(features) &&
275 khrn_image_get_blue_size(format) == FEATURES_UNPACK_BLUE(features) &&
276 khrn_image_get_alpha_size(format) == FEATURES_UNPACK_ALPHA(features);
277}
278
279/*
280 uint32_t egl_config_get_api_support(int id)
281
282 Preconditions:
283
284 0 <= id < EGL_MAX_CONFIGS
285
286 Postconditions:
287
288 Result is a bitmap which is a subset of (EGL_OPENGL_ES_BIT | EGL_OPENVG_BIT | EGL_OPENGL_ES2_BIT)
289*/
290
291uint32_t egl_config_get_api_support(int id)
292{
293 /* no configs are api-specific (ie if you can use a config with gl, you can
294 * use it with vg too, and vice-versa). however, some configs have color
295 * buffer formats that are incompatible with the hardware, and so can't be
296 * used with any api. such configs may still be useful eg with the surface
297 * locking extension... */
298
299#if EGL_KHR_lock_surface
300 /* to reduce confusion, just say no for all lockable configs. this #if can be
301 * safely commented out -- the color buffer format check below will catch
302 * lockable configs we actually can't use */
303 if (egl_config_is_lockable(id)) {
304 return 0;
305 }
306#endif
307
308 switch (egl_config_get_color_format(id)) {
309 case ABGR_8888_RSO: case ABGR_8888_TF: case ABGR_8888_LT:
310 case XBGR_8888_RSO: case XBGR_8888_TF: case XBGR_8888_LT:
311 case ARGB_8888_RSO: case ARGB_8888_TF: case ARGB_8888_LT:
312 case XRGB_8888_RSO: case XRGB_8888_TF: case XRGB_8888_LT:
313 case RGB_565_RSO: case RGB_565_TF: case RGB_565_LT:
314#ifndef NO_OPENVG
315 return (uint32_t)(EGL_OPENGL_ES_BIT | EGL_OPENVG_BIT | EGL_OPENGL_ES2_BIT);
316#else
317 return (uint32_t)(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
318#endif
319 default:
320 break;
321 }
322 return 0;
323}
324
325/*
326 uint32_t egl_config_get_api_conformance(int id)
327
328 Preconditions:
329
330 0 <= id < EGL_MAX_CONFIGS
331
332 Postconditions:
333
334 Result is a bitmap which is a subset of (EGL_OPENGL_ES_BIT | EGL_OPENVG_BIT | EGL_OPENGL_ES2_BIT)
335*/
336
337uint32_t egl_config_get_api_conformance(int id)
338{
339 /* vg doesn't support multisampled surfaces properly */
340 return egl_config_get_api_support(id) & ~(FEATURES_UNPACK_MULTI(formats[id].features) ? EGL_OPENVG_BIT : 0);
341}
342
343bool egl_config_bpps_match(int id0, int id1) /* bpps of all buffers match */
344{
345 FEATURES_T config0 = formats[id0].features;
346 FEATURES_T config1 = formats[id1].features;
347
348 return
349 FEATURES_UNPACK_RED(config0) == FEATURES_UNPACK_RED(config1) &&
350 FEATURES_UNPACK_GREEN(config0) == FEATURES_UNPACK_GREEN(config1) &&
351 FEATURES_UNPACK_BLUE(config0) == FEATURES_UNPACK_BLUE(config1) &&
352 FEATURES_UNPACK_ALPHA(config0) == FEATURES_UNPACK_ALPHA(config1) &&
353 FEATURES_UNPACK_DEPTH(config0) == FEATURES_UNPACK_DEPTH(config1) &&
354 FEATURES_UNPACK_STENCIL(config0) == FEATURES_UNPACK_STENCIL(config1) &&
355 FEATURES_UNPACK_MASK(config0) == FEATURES_UNPACK_MASK(config1);
356}
357
358#if EGL_KHR_lock_surface
359
360/*
361 KHRN_IMAGE_FORMAT_T egl_config_get_mapped_format(int id)
362
363 Returns the format of the mapped buffer when an EGL surface is locked.
364
365 Preconditions:
366
367 0 <= id < EGL_MAX_CONFIGS
368 egl_config_is_lockable(id)
369
370 Postconditions:
371
372 Return value is RGB_565_RSO or ARGB_8888_RSO
373*/
374
375KHRN_IMAGE_FORMAT_T egl_config_get_mapped_format(int id)
376{
377 KHRN_IMAGE_FORMAT_T result;
378
379 vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
380 vcos_assert(FEATURES_UNPACK_LOCKABLE(formats[id].features));
381
382 /* If any t-format images were lockable, we would convert to raster format here */
383 result = egl_config_get_color_format(id);
384 vcos_assert(khrn_image_is_rso(result));
385 return result;
386}
387
388/*
389 bool egl_config_is_lockable(int id)
390
391 Preconditions:
392
393 0 <= id < EGL_MAX_CONFIGS
394
395 Postconditions:
396
397 -
398*/
399
400bool egl_config_is_lockable(int id)
401{
402 vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
403 return FEATURES_UNPACK_LOCKABLE(formats[id].features);
404}
405
406#endif
407
408
409
410
411