egl: setup fds array correctly when exporting dmabuf
[mesa.git] / src / egl / main / eglsurface.c
1 /**************************************************************************
2 *
3 * Copyright 2008 VMware, Inc.
4 * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5 * Copyright 2010 LunarG, Inc.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 **************************************************************************/
29
30
31 /**
32 * Surface-related functions.
33 */
34
35
36 #include <assert.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include "egldefines.h"
40 #include "egldisplay.h"
41 #include "egldriver.h"
42 #include "eglcontext.h"
43 #include "eglconfig.h"
44 #include "eglcurrent.h"
45 #include "egllog.h"
46 #include "eglsurface.h"
47
48 #include "util/macros.h"
49
50 /**
51 * Parse the list of surface attributes and return the proper error code.
52 */
53 static EGLint
54 _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
55 {
56 _EGLDisplay *disp = surf->Resource.Display;
57 EGLint type = surf->Type;
58 EGLint texture_type = EGL_PBUFFER_BIT;
59 EGLint i, err = EGL_SUCCESS;
60 EGLint attr = EGL_NONE;
61 EGLint val = EGL_NONE;
62
63 if (!attrib_list)
64 return EGL_SUCCESS;
65
66 if (disp->Extensions.NOK_texture_from_pixmap)
67 texture_type |= EGL_PIXMAP_BIT;
68
69 for (i = 0; attrib_list[i] != EGL_NONE; i++) {
70 attr = attrib_list[i++];
71 val = attrib_list[i];
72
73 switch (attr) {
74 /* common attributes */
75 case EGL_GL_COLORSPACE_KHR:
76 if (!disp->Extensions.KHR_gl_colorspace) {
77 err = EGL_BAD_ATTRIBUTE;
78 break;
79 }
80 switch (val) {
81 case EGL_GL_COLORSPACE_SRGB_KHR:
82 case EGL_GL_COLORSPACE_LINEAR_KHR:
83 break;
84 default:
85 err = EGL_BAD_ATTRIBUTE;
86 }
87 if (err != EGL_SUCCESS)
88 break;
89 surf->GLColorspace = val;
90 break;
91 case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
92 if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
93 err = EGL_BAD_ATTRIBUTE;
94 break;
95 }
96 surf->HdrMetadata.display_primary_r.x = val;
97 break;
98 case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
99 if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
100 err = EGL_BAD_ATTRIBUTE;
101 break;
102 }
103 surf->HdrMetadata.display_primary_r.y = val;
104 break;
105 case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
106 if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
107 err = EGL_BAD_ATTRIBUTE;
108 break;
109 }
110 surf->HdrMetadata.display_primary_g.x = val;
111 break;
112 case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
113 if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
114 err = EGL_BAD_ATTRIBUTE;
115 break;
116 }
117 surf->HdrMetadata.display_primary_g.y = val;
118 break;
119 case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
120 if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
121 err = EGL_BAD_ATTRIBUTE;
122 break;
123 }
124 surf->HdrMetadata.display_primary_b.x = val;
125 break;
126 case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
127 if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
128 err = EGL_BAD_ATTRIBUTE;
129 break;
130 }
131 surf->HdrMetadata.display_primary_b.y = val;
132 break;
133 case EGL_SMPTE2086_WHITE_POINT_X_EXT:
134 if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
135 err = EGL_BAD_ATTRIBUTE;
136 break;
137 }
138 surf->HdrMetadata.white_point.x = val;
139 break;
140 case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
141 if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
142 err = EGL_BAD_ATTRIBUTE;
143 break;
144 }
145 surf->HdrMetadata.white_point.y = val;
146 break;
147 case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
148 if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
149 err = EGL_BAD_ATTRIBUTE;
150 break;
151 }
152 surf->HdrMetadata.max_luminance = val;
153 break;
154 case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
155 if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
156 err = EGL_BAD_ATTRIBUTE;
157 break;
158 }
159 surf->HdrMetadata.min_luminance = val;
160 break;
161 case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
162 if (!disp->Extensions.EXT_surface_CTA861_3_metadata) {
163 err = EGL_BAD_ATTRIBUTE;
164 break;
165 }
166 surf->HdrMetadata.max_cll = val;
167 break;
168 case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
169 if (!disp->Extensions.EXT_surface_CTA861_3_metadata) {
170 err = EGL_BAD_ATTRIBUTE;
171 break;
172 }
173 surf->HdrMetadata.max_fall = val;
174 break;
175 case EGL_VG_COLORSPACE:
176 switch (val) {
177 case EGL_VG_COLORSPACE_sRGB:
178 case EGL_VG_COLORSPACE_LINEAR:
179 break;
180 default:
181 err = EGL_BAD_ATTRIBUTE;
182 break;
183 }
184 if (err != EGL_SUCCESS)
185 break;
186 surf->VGColorspace = val;
187 break;
188 case EGL_VG_ALPHA_FORMAT:
189 switch (val) {
190 case EGL_VG_ALPHA_FORMAT_NONPRE:
191 case EGL_VG_ALPHA_FORMAT_PRE:
192 break;
193 default:
194 err = EGL_BAD_ATTRIBUTE;
195 break;
196 }
197 if (err != EGL_SUCCESS)
198 break;
199 surf->VGAlphaFormat = val;
200 break;
201 /* window surface attributes */
202 case EGL_RENDER_BUFFER:
203 if (type != EGL_WINDOW_BIT) {
204 err = EGL_BAD_ATTRIBUTE;
205 break;
206 }
207 if (val != EGL_BACK_BUFFER && val != EGL_SINGLE_BUFFER) {
208 err = EGL_BAD_ATTRIBUTE;
209 break;
210 }
211 surf->RequestedRenderBuffer = val;
212 if (surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR) {
213 /* Unlike normal EGLSurfaces, one with a mutable render buffer
214 * uses the application-chosen render buffer.
215 */
216 surf->ActiveRenderBuffer = val;
217 }
218 break;
219 case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
220 if (!disp->Extensions.NV_post_sub_buffer ||
221 type != EGL_WINDOW_BIT) {
222 err = EGL_BAD_ATTRIBUTE;
223 break;
224 }
225 if (val != EGL_TRUE && val != EGL_FALSE) {
226 err = EGL_BAD_PARAMETER;
227 break;
228 }
229 surf->PostSubBufferSupportedNV = val;
230 break;
231 /* pbuffer surface attributes */
232 case EGL_WIDTH:
233 if (type != EGL_PBUFFER_BIT) {
234 err = EGL_BAD_ATTRIBUTE;
235 break;
236 }
237 if (val < 0) {
238 err = EGL_BAD_PARAMETER;
239 break;
240 }
241 surf->Width = val;
242 break;
243 case EGL_HEIGHT:
244 if (type != EGL_PBUFFER_BIT) {
245 err = EGL_BAD_ATTRIBUTE;
246 break;
247 }
248 if (val < 0) {
249 err = EGL_BAD_PARAMETER;
250 break;
251 }
252 surf->Height = val;
253 break;
254 case EGL_LARGEST_PBUFFER:
255 if (type != EGL_PBUFFER_BIT) {
256 err = EGL_BAD_ATTRIBUTE;
257 break;
258 }
259 surf->LargestPbuffer = !!val;
260 break;
261 /* for eglBindTexImage */
262 case EGL_TEXTURE_FORMAT:
263 if (!(type & texture_type)) {
264 err = EGL_BAD_ATTRIBUTE;
265 break;
266 }
267
268 switch (val) {
269 case EGL_TEXTURE_RGB:
270 case EGL_TEXTURE_RGBA:
271 case EGL_NO_TEXTURE:
272 break;
273 default:
274 err = EGL_BAD_ATTRIBUTE;
275 break;
276 }
277 if (err != EGL_SUCCESS)
278 break;
279 surf->TextureFormat = val;
280 break;
281 case EGL_TEXTURE_TARGET:
282 if (!(type & texture_type)) {
283 err = EGL_BAD_ATTRIBUTE;
284 break;
285 }
286
287 switch (val) {
288 case EGL_TEXTURE_2D:
289 case EGL_NO_TEXTURE:
290 break;
291 default:
292 err = EGL_BAD_ATTRIBUTE;
293 break;
294 }
295 if (err != EGL_SUCCESS)
296 break;
297 surf->TextureTarget = val;
298 break;
299 case EGL_MIPMAP_TEXTURE:
300 if (!(type & texture_type)) {
301 err = EGL_BAD_ATTRIBUTE;
302 break;
303 }
304 surf->MipmapTexture = !!val;
305 break;
306 /* no pixmap surface specific attributes */
307 default:
308 err = EGL_BAD_ATTRIBUTE;
309 break;
310 }
311
312 if (err != EGL_SUCCESS)
313 break;
314 }
315
316 if (err == EGL_SUCCESS && type == EGL_PBUFFER_BIT) {
317 if ((surf->TextureTarget == EGL_NO_TEXTURE && surf->TextureFormat != EGL_NO_TEXTURE) ||
318 (surf->TextureFormat == EGL_NO_TEXTURE && surf->TextureTarget != EGL_NO_TEXTURE)) {
319 attr = surf->TextureTarget == EGL_NO_TEXTURE ? EGL_TEXTURE_TARGET : EGL_TEXTURE_FORMAT;
320 err = EGL_BAD_MATCH;
321 }
322 }
323
324 if (err != EGL_SUCCESS)
325 _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
326
327 return err;
328 }
329
330
331 /**
332 * Do error check on parameters and initialize the given _EGLSurface object.
333 * \return EGL_TRUE if no errors, EGL_FALSE otherwise.
334 */
335 EGLBoolean
336 _eglInitSurface(_EGLSurface *surf, _EGLDisplay *disp, EGLint type,
337 _EGLConfig *conf, const EGLint *attrib_list)
338 {
339 const char *func;
340 EGLint renderBuffer = EGL_BACK_BUFFER;
341 EGLint swapBehavior = EGL_BUFFER_DESTROYED;
342 EGLint err;
343
344 /* Swap behavior can be preserved only if config supports this. */
345 if (conf->SurfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
346 swapBehavior = EGL_BUFFER_PRESERVED;
347
348 switch (type) {
349 case EGL_WINDOW_BIT:
350 func = "eglCreateWindowSurface";
351 swapBehavior = EGL_BUFFER_DESTROYED;
352 break;
353 case EGL_PIXMAP_BIT:
354 func = "eglCreatePixmapSurface";
355 renderBuffer = EGL_SINGLE_BUFFER;
356 break;
357 case EGL_PBUFFER_BIT:
358 func = "eglCreatePBufferSurface";
359 break;
360 default:
361 _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
362 return EGL_FALSE;
363 }
364
365 if ((conf->SurfaceType & type) == 0)
366 /* The config can't be used to create a surface of this type */
367 return _eglError(EGL_BAD_MATCH, func);
368
369 _eglInitResource(&surf->Resource, sizeof(*surf), disp);
370 surf->Type = type;
371 surf->Config = conf;
372 surf->Lost = EGL_FALSE;
373
374 surf->Width = 0;
375 surf->Height = 0;
376 surf->TextureFormat = EGL_NO_TEXTURE;
377 surf->TextureTarget = EGL_NO_TEXTURE;
378 surf->MipmapTexture = EGL_FALSE;
379 surf->LargestPbuffer = EGL_FALSE;
380 surf->RequestedRenderBuffer = renderBuffer;
381 surf->ActiveRenderBuffer = renderBuffer;
382 surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
383 surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
384 surf->GLColorspace = EGL_GL_COLORSPACE_LINEAR_KHR;
385
386 surf->MipmapLevel = 0;
387 surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
388 surf->SwapBehavior = swapBehavior;
389
390 surf->HorizontalResolution = EGL_UNKNOWN;
391 surf->VerticalResolution = EGL_UNKNOWN;
392 surf->AspectRatio = EGL_UNKNOWN;
393
394 surf->PostSubBufferSupportedNV = EGL_FALSE;
395 surf->SetDamageRegionCalled = EGL_FALSE;
396 surf->BufferAgeRead = EGL_FALSE;
397
398 /* the default swap interval is 1 */
399 surf->SwapInterval = 1;
400
401 surf->HdrMetadata.display_primary_r.x = EGL_DONT_CARE;
402 surf->HdrMetadata.display_primary_r.y = EGL_DONT_CARE;
403 surf->HdrMetadata.display_primary_g.x = EGL_DONT_CARE;
404 surf->HdrMetadata.display_primary_g.y = EGL_DONT_CARE;
405 surf->HdrMetadata.display_primary_b.x = EGL_DONT_CARE;
406 surf->HdrMetadata.display_primary_b.y = EGL_DONT_CARE;
407 surf->HdrMetadata.white_point.x = EGL_DONT_CARE;
408 surf->HdrMetadata.white_point.y = EGL_DONT_CARE;
409 surf->HdrMetadata.max_luminance = EGL_DONT_CARE;
410 surf->HdrMetadata.min_luminance = EGL_DONT_CARE;
411 surf->HdrMetadata.max_cll = EGL_DONT_CARE;
412 surf->HdrMetadata.max_fall = EGL_DONT_CARE;
413
414 err = _eglParseSurfaceAttribList(surf, attrib_list);
415 if (err != EGL_SUCCESS)
416 return _eglError(err, func);
417
418 /* if EGL_LARGEST_PBUFFER in use, clamp width and height */
419 if (surf->LargestPbuffer) {
420 surf->Width = MIN2(surf->Width, _EGL_MAX_PBUFFER_WIDTH);
421 surf->Height = MIN2(surf->Height, _EGL_MAX_PBUFFER_HEIGHT);
422 }
423
424 return EGL_TRUE;
425 }
426
427
428 EGLBoolean
429 _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface,
430 EGLint attribute, EGLint *value)
431 {
432 switch (attribute) {
433 case EGL_WIDTH:
434 *value = surface->Width;
435 break;
436 case EGL_HEIGHT:
437 *value = surface->Height;
438 break;
439 case EGL_CONFIG_ID:
440 *value = surface->Config->ConfigID;
441 break;
442 case EGL_LARGEST_PBUFFER:
443 if (surface->Type == EGL_PBUFFER_BIT)
444 *value = surface->LargestPbuffer;
445 break;
446 case EGL_TEXTURE_FORMAT:
447 /* texture attributes: only for pbuffers, no error otherwise */
448 if (surface->Type == EGL_PBUFFER_BIT)
449 *value = surface->TextureFormat;
450 break;
451 case EGL_TEXTURE_TARGET:
452 if (surface->Type == EGL_PBUFFER_BIT)
453 *value = surface->TextureTarget;
454 break;
455 case EGL_MIPMAP_TEXTURE:
456 if (surface->Type == EGL_PBUFFER_BIT)
457 *value = surface->MipmapTexture;
458 break;
459 case EGL_MIPMAP_LEVEL:
460 if (surface->Type == EGL_PBUFFER_BIT)
461 *value = surface->MipmapLevel;
462 break;
463 case EGL_SWAP_BEHAVIOR:
464 *value = surface->SwapBehavior;
465 break;
466 case EGL_RENDER_BUFFER:
467 /* From the EGL_KHR_mutable_render_buffer spec (v12):
468 *
469 * Querying EGL_RENDER_BUFFER returns the buffer which client API
470 * rendering is requested to use. For a window surface, this is the
471 * attribute value specified when the surface was created or last set
472 * via eglSurfaceAttrib.
473 *
474 * In other words, querying a window surface returns the value most
475 * recently *requested* by the user.
476 *
477 * The paragraph continues in the EGL 1.5 spec (2014.08.27):
478 *
479 * For a pbuffer surface, it is always EGL_BACK_BUFFER . For a pixmap
480 * surface, it is always EGL_SINGLE_BUFFER . To determine the actual
481 * buffer being rendered to by a context, call eglQueryContext.
482 */
483 switch (surface->Type) {
484 default:
485 unreachable("bad EGLSurface type");
486 case EGL_WINDOW_BIT:
487 *value = surface->RequestedRenderBuffer;
488 break;
489 case EGL_PBUFFER_BIT:
490 *value = EGL_BACK_BUFFER;
491 break;
492 case EGL_PIXMAP_BIT:
493 *value = EGL_SINGLE_BUFFER;
494 break;
495 }
496 break;
497 case EGL_PIXEL_ASPECT_RATIO:
498 *value = surface->AspectRatio;
499 break;
500 case EGL_HORIZONTAL_RESOLUTION:
501 *value = surface->HorizontalResolution;
502 break;
503 case EGL_VERTICAL_RESOLUTION:
504 *value = surface->VerticalResolution;
505 break;
506 case EGL_MULTISAMPLE_RESOLVE:
507 *value = surface->MultisampleResolve;
508 break;
509 case EGL_VG_ALPHA_FORMAT:
510 *value = surface->VGAlphaFormat;
511 break;
512 case EGL_VG_COLORSPACE:
513 *value = surface->VGColorspace;
514 break;
515 case EGL_GL_COLORSPACE_KHR:
516 if (!disp->Extensions.KHR_gl_colorspace)
517 return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
518
519 *value = surface->GLColorspace;
520 break;
521 case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
522 *value = surface->PostSubBufferSupportedNV;
523 break;
524 case EGL_BUFFER_AGE_EXT:
525 /* Both EXT_buffer_age and KHR_partial_update accept EGL_BUFFER_AGE_EXT.
526 * To be precise, the KHR one accepts EGL_BUFFER_AGE_KHR which is an
527 * alias with the same numeric value.
528 */
529 if (!disp->Extensions.EXT_buffer_age &&
530 !disp->Extensions.KHR_partial_update)
531 return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
532
533 _EGLContext *ctx = _eglGetCurrentContext();
534 EGLint result = drv->API.QueryBufferAge(drv, disp, surface);
535 /* error happened */
536 if (result < 0)
537 return EGL_FALSE;
538 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
539 ctx->DrawSurface != surface)
540 return _eglError(EGL_BAD_SURFACE, "eglQuerySurface");
541
542 *value = result;
543 surface->BufferAgeRead = EGL_TRUE;
544 break;
545 case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
546 *value = surface->HdrMetadata.display_primary_r.x;
547 break;
548 case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
549 *value = surface->HdrMetadata.display_primary_r.y;
550 break;
551 case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
552 *value = surface->HdrMetadata.display_primary_g.x;
553 break;
554 case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
555 *value = surface->HdrMetadata.display_primary_g.y;
556 break;
557 case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
558 *value = surface->HdrMetadata.display_primary_b.x;
559 break;
560 case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
561 *value = surface->HdrMetadata.display_primary_b.y;
562 break;
563 case EGL_SMPTE2086_WHITE_POINT_X_EXT:
564 *value = surface->HdrMetadata.white_point.x;
565 break;
566 case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
567 *value = surface->HdrMetadata.white_point.y;
568 break;
569 case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
570 *value = surface->HdrMetadata.max_luminance;
571 break;
572 case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
573 *value = surface->HdrMetadata.min_luminance;
574 break;
575 case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
576 *value = surface->HdrMetadata.max_cll;
577 break;
578 case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
579 *value = surface->HdrMetadata.max_fall;
580 break;
581 default:
582 return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
583 }
584
585 return EGL_TRUE;
586 }
587
588
589 /**
590 * Default fallback routine - drivers might override this.
591 */
592 EGLBoolean
593 _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface,
594 EGLint attribute, EGLint value)
595 {
596 EGLint confval;
597 EGLint err = EGL_SUCCESS;
598 EGLint all_es_bits = EGL_OPENGL_ES_BIT |
599 EGL_OPENGL_ES2_BIT |
600 EGL_OPENGL_ES3_BIT_KHR;
601
602 switch (attribute) {
603 case EGL_MIPMAP_LEVEL:
604 confval = surface->Config->RenderableType;
605 if (!(confval & all_es_bits)) {
606 err = EGL_BAD_PARAMETER;
607 break;
608 }
609 surface->MipmapLevel = value;
610 break;
611 case EGL_MULTISAMPLE_RESOLVE:
612 switch (value) {
613 case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
614 break;
615 case EGL_MULTISAMPLE_RESOLVE_BOX:
616 confval = surface->Config->SurfaceType;
617 if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
618 err = EGL_BAD_MATCH;
619 break;
620 default:
621 err = EGL_BAD_ATTRIBUTE;
622 break;
623 }
624 if (err != EGL_SUCCESS)
625 break;
626 surface->MultisampleResolve = value;
627 break;
628 case EGL_RENDER_BUFFER:
629 if (!disp->Extensions.KHR_mutable_render_buffer) {
630 err = EGL_BAD_ATTRIBUTE;
631 break;
632 }
633
634 if (value != EGL_BACK_BUFFER && value != EGL_SINGLE_BUFFER) {
635 err = EGL_BAD_PARAMETER;
636 break;
637 }
638
639 /* From the EGL_KHR_mutable_render_buffer spec (v12):
640 *
641 * If attribute is EGL_RENDER_BUFFER, and the EGL_SURFACE_TYPE
642 * attribute of the EGLConfig used to create surface does not contain
643 * EGL_MUTABLE_RENDER_BUFFER_BIT_KHR, [...] an EGL_BAD_MATCH error is
644 * generated [...].
645 */
646 if (!(surface->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR)) {
647 err = EGL_BAD_MATCH;
648 break;
649 }
650
651 surface->RequestedRenderBuffer = value;
652 break;
653 case EGL_SWAP_BEHAVIOR:
654 switch (value) {
655 case EGL_BUFFER_DESTROYED:
656 break;
657 case EGL_BUFFER_PRESERVED:
658 confval = surface->Config->SurfaceType;
659 if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
660 err = EGL_BAD_MATCH;
661 break;
662 default:
663 err = EGL_BAD_ATTRIBUTE;
664 break;
665 }
666 if (err != EGL_SUCCESS)
667 break;
668 surface->SwapBehavior = value;
669 break;
670 case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
671 surface->HdrMetadata.display_primary_r.x = value;
672 break;
673 case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
674 surface->HdrMetadata.display_primary_r.y = value;
675 break;
676 case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
677 surface->HdrMetadata.display_primary_g.x = value;
678 break;
679 case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
680 surface->HdrMetadata.display_primary_g.y = value;
681 break;
682 case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
683 surface->HdrMetadata.display_primary_b.x = value;
684 break;
685 case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
686 surface->HdrMetadata.display_primary_b.y = value;
687 break;
688 case EGL_SMPTE2086_WHITE_POINT_X_EXT:
689 surface->HdrMetadata.white_point.x = value;
690 break;
691 case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
692 surface->HdrMetadata.white_point.y = value;
693 break;
694 case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
695 surface->HdrMetadata.max_luminance = value;
696 break;
697 case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
698 surface->HdrMetadata.min_luminance = value;
699 break;
700 case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
701 surface->HdrMetadata.max_cll = value;
702 break;
703 case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
704 surface->HdrMetadata.max_fall = value;
705 break;
706 default:
707 err = EGL_BAD_ATTRIBUTE;
708 break;
709 }
710
711 if (err != EGL_SUCCESS)
712 return _eglError(err, "eglSurfaceAttrib");
713 return EGL_TRUE;
714 }
715
716
717 EGLBoolean
718 _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface,
719 EGLint buffer)
720 {
721 EGLint texture_type = EGL_PBUFFER_BIT;
722
723 /* Just do basic error checking and return success/fail.
724 * Drivers must implement the real stuff.
725 */
726
727 if (disp->Extensions.NOK_texture_from_pixmap)
728 texture_type |= EGL_PIXMAP_BIT;
729
730 if (!(surface->Type & texture_type))
731 return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
732
733 if (surface->TextureFormat == EGL_NO_TEXTURE)
734 return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
735
736 if (surface->TextureTarget == EGL_NO_TEXTURE)
737 return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
738
739 if (buffer != EGL_BACK_BUFFER)
740 return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
741
742 surface->BoundToTexture = EGL_TRUE;
743
744 return EGL_TRUE;
745 }
746
747 EGLBoolean
748 _eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
749 EGLint buffer)
750 {
751 /* Just do basic error checking and return success/fail.
752 * Drivers must implement the real stuff.
753 */
754
755 EGLint texture_type = EGL_PBUFFER_BIT;
756
757 if (surf == EGL_NO_SURFACE)
758 return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
759
760 if (!surf->BoundToTexture)
761 {
762 /* Not an error, simply nothing to do */
763 return EGL_TRUE;
764 }
765
766 if (surf->TextureFormat == EGL_NO_TEXTURE)
767 return _eglError(EGL_BAD_MATCH, "eglReleaseTexImage");
768
769 if (buffer != EGL_BACK_BUFFER)
770 return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
771
772 if (disp->Extensions.NOK_texture_from_pixmap)
773 texture_type |= EGL_PIXMAP_BIT;
774
775 if (!(surf->Type & texture_type))
776 return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
777
778 surf->BoundToTexture = EGL_FALSE;
779
780 return EGL_TRUE;
781 }
782
783
784 EGLBoolean
785 _eglSwapInterval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
786 EGLint interval)
787 {
788 return EGL_TRUE;
789 }
790
791 EGLBoolean
792 _eglSurfaceHasMutableRenderBuffer(_EGLSurface *surf)
793 {
794 return surf->Type == EGL_WINDOW_BIT &&
795 surf->Config &&
796 (surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR);
797 }
798
799 EGLBoolean
800 _eglSurfaceInSharedBufferMode(_EGLSurface *surf)
801 {
802 return _eglSurfaceHasMutableRenderBuffer(surf) &&
803 surf->ActiveRenderBuffer == EGL_SINGLE_BUFFER;
804 }