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