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
_eglParseSurfaceAttribList(_EGLSurface * surf,const EGLint * attrib_list)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_PRESENT_OPAQUE_EXT:
220 if (!disp->Extensions.EXT_present_opaque) {
221 err = EGL_BAD_ATTRIBUTE;
222 break;
223 }
224 if (type != EGL_WINDOW_BIT) {
225 err = EGL_BAD_ATTRIBUTE;
226 break;
227 }
228 if (val != EGL_TRUE && val != EGL_FALSE) {
229 err = EGL_BAD_PARAMETER;
230 break;
231 }
232 surf->PresentOpaque = val;
233 break;
234 case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
235 if (!disp->Extensions.NV_post_sub_buffer ||
236 type != EGL_WINDOW_BIT) {
237 err = EGL_BAD_ATTRIBUTE;
238 break;
239 }
240 if (val != EGL_TRUE && val != EGL_FALSE) {
241 err = EGL_BAD_PARAMETER;
242 break;
243 }
244 surf->PostSubBufferSupportedNV = val;
245 break;
246 /* pbuffer surface attributes */
247 case EGL_WIDTH:
248 if (type != EGL_PBUFFER_BIT) {
249 err = EGL_BAD_ATTRIBUTE;
250 break;
251 }
252 if (val < 0) {
253 err = EGL_BAD_PARAMETER;
254 break;
255 }
256 surf->Width = val;
257 break;
258 case EGL_HEIGHT:
259 if (type != EGL_PBUFFER_BIT) {
260 err = EGL_BAD_ATTRIBUTE;
261 break;
262 }
263 if (val < 0) {
264 err = EGL_BAD_PARAMETER;
265 break;
266 }
267 surf->Height = val;
268 break;
269 case EGL_LARGEST_PBUFFER:
270 if (type != EGL_PBUFFER_BIT) {
271 err = EGL_BAD_ATTRIBUTE;
272 break;
273 }
274 surf->LargestPbuffer = !!val;
275 break;
276 /* for eglBindTexImage */
277 case EGL_TEXTURE_FORMAT:
278 if (!(type & texture_type)) {
279 err = EGL_BAD_ATTRIBUTE;
280 break;
281 }
282
283 switch (val) {
284 case EGL_TEXTURE_RGB:
285 case EGL_TEXTURE_RGBA:
286 case EGL_NO_TEXTURE:
287 break;
288 default:
289 err = EGL_BAD_ATTRIBUTE;
290 break;
291 }
292 if (err != EGL_SUCCESS)
293 break;
294 surf->TextureFormat = val;
295 break;
296 case EGL_TEXTURE_TARGET:
297 if (!(type & texture_type)) {
298 err = EGL_BAD_ATTRIBUTE;
299 break;
300 }
301
302 switch (val) {
303 case EGL_TEXTURE_2D:
304 case EGL_NO_TEXTURE:
305 break;
306 default:
307 err = EGL_BAD_ATTRIBUTE;
308 break;
309 }
310 if (err != EGL_SUCCESS)
311 break;
312 surf->TextureTarget = val;
313 break;
314 case EGL_MIPMAP_TEXTURE:
315 if (!(type & texture_type)) {
316 err = EGL_BAD_ATTRIBUTE;
317 break;
318 }
319 surf->MipmapTexture = !!val;
320 break;
321 case EGL_PROTECTED_CONTENT_EXT:
322 if (!disp->Extensions.EXT_protected_surface) {
323 err = EGL_BAD_ATTRIBUTE;
324 break;
325 }
326 surf->ProtectedContent = val;
327 break;
328
329 /* no pixmap surface specific attributes */
330 default:
331 err = EGL_BAD_ATTRIBUTE;
332 break;
333 }
334
335 if (err != EGL_SUCCESS)
336 break;
337 }
338
339 if (err == EGL_SUCCESS && type == EGL_PBUFFER_BIT) {
340 if ((surf->TextureTarget == EGL_NO_TEXTURE && surf->TextureFormat != EGL_NO_TEXTURE) ||
341 (surf->TextureFormat == EGL_NO_TEXTURE && surf->TextureTarget != EGL_NO_TEXTURE)) {
342 attr = surf->TextureTarget == EGL_NO_TEXTURE ? EGL_TEXTURE_TARGET : EGL_TEXTURE_FORMAT;
343 err = EGL_BAD_MATCH;
344 }
345 }
346
347 if (err != EGL_SUCCESS)
348 _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
349
350 return err;
351 }
352
353
354 /**
355 * Do error check on parameters and initialize the given _EGLSurface object.
356 * \return EGL_TRUE if no errors, EGL_FALSE otherwise.
357 */
358 EGLBoolean
_eglInitSurface(_EGLSurface * surf,_EGLDisplay * disp,EGLint type,_EGLConfig * conf,const EGLint * attrib_list,void * native_surface)359 _eglInitSurface(_EGLSurface *surf, _EGLDisplay *disp, EGLint type,
360 _EGLConfig *conf, const EGLint *attrib_list,
361 void *native_surface)
362 {
363 const char *func;
364 EGLint renderBuffer = EGL_BACK_BUFFER;
365 EGLint swapBehavior = EGL_BUFFER_DESTROYED;
366 EGLint err;
367
368 /* Swap behavior can be preserved only if config supports this. */
369 if (conf->SurfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
370 swapBehavior = EGL_BUFFER_PRESERVED;
371
372 switch (type) {
373 case EGL_WINDOW_BIT:
374 func = "eglCreateWindowSurface";
375 swapBehavior = EGL_BUFFER_DESTROYED;
376 break;
377 case EGL_PIXMAP_BIT:
378 func = "eglCreatePixmapSurface";
379 renderBuffer = EGL_SINGLE_BUFFER;
380 break;
381 case EGL_PBUFFER_BIT:
382 func = "eglCreatePBufferSurface";
383 break;
384 default:
385 _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
386 return EGL_FALSE;
387 }
388
389 if ((conf->SurfaceType & type) == 0)
390 /* The config can't be used to create a surface of this type */
391 return _eglError(EGL_BAD_MATCH, func);
392
393 _eglInitResource(&surf->Resource, sizeof(*surf), disp);
394 surf->Type = type;
395 surf->Config = conf;
396 surf->Lost = EGL_FALSE;
397
398 surf->Width = 0;
399 surf->Height = 0;
400 surf->TextureFormat = EGL_NO_TEXTURE;
401 surf->TextureTarget = EGL_NO_TEXTURE;
402 surf->MipmapTexture = EGL_FALSE;
403 surf->LargestPbuffer = EGL_FALSE;
404 surf->RequestedRenderBuffer = renderBuffer;
405 surf->ActiveRenderBuffer = renderBuffer;
406 surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
407 surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
408 surf->GLColorspace = EGL_GL_COLORSPACE_LINEAR_KHR;
409 surf->ProtectedContent = EGL_FALSE;
410 surf->PresentOpaque = EGL_FALSE;
411
412 surf->MipmapLevel = 0;
413 surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
414 surf->SwapBehavior = swapBehavior;
415
416 surf->HorizontalResolution = EGL_UNKNOWN;
417 surf->VerticalResolution = EGL_UNKNOWN;
418 surf->AspectRatio = EGL_UNKNOWN;
419
420 surf->PostSubBufferSupportedNV = EGL_FALSE;
421 surf->SetDamageRegionCalled = EGL_FALSE;
422 surf->BufferAgeRead = EGL_FALSE;
423
424 /* the default swap interval is 1 */
425 surf->SwapInterval = 1;
426
427 surf->HdrMetadata.display_primary_r.x = EGL_DONT_CARE;
428 surf->HdrMetadata.display_primary_r.y = EGL_DONT_CARE;
429 surf->HdrMetadata.display_primary_g.x = EGL_DONT_CARE;
430 surf->HdrMetadata.display_primary_g.y = EGL_DONT_CARE;
431 surf->HdrMetadata.display_primary_b.x = EGL_DONT_CARE;
432 surf->HdrMetadata.display_primary_b.y = EGL_DONT_CARE;
433 surf->HdrMetadata.white_point.x = EGL_DONT_CARE;
434 surf->HdrMetadata.white_point.y = EGL_DONT_CARE;
435 surf->HdrMetadata.max_luminance = EGL_DONT_CARE;
436 surf->HdrMetadata.min_luminance = EGL_DONT_CARE;
437 surf->HdrMetadata.max_cll = EGL_DONT_CARE;
438 surf->HdrMetadata.max_fall = EGL_DONT_CARE;
439
440 err = _eglParseSurfaceAttribList(surf, attrib_list);
441 if (err != EGL_SUCCESS)
442 return _eglError(err, func);
443
444 /* if EGL_LARGEST_PBUFFER in use, clamp width and height */
445 if (surf->LargestPbuffer) {
446 surf->Width = MIN2(surf->Width, _EGL_MAX_PBUFFER_WIDTH);
447 surf->Height = MIN2(surf->Height, _EGL_MAX_PBUFFER_HEIGHT);
448 }
449
450 surf->NativeSurface = native_surface;
451
452 return EGL_TRUE;
453 }
454
455
456 EGLBoolean
_eglQuerySurface(_EGLDisplay * disp,_EGLSurface * surface,EGLint attribute,EGLint * value)457 _eglQuerySurface(_EGLDisplay *disp, _EGLSurface *surface,
458 EGLint attribute, EGLint *value)
459 {
460 switch (attribute) {
461 case EGL_WIDTH:
462 *value = surface->Width;
463 break;
464 case EGL_HEIGHT:
465 *value = surface->Height;
466 break;
467 case EGL_CONFIG_ID:
468 *value = surface->Config->ConfigID;
469 break;
470 case EGL_LARGEST_PBUFFER:
471 if (surface->Type == EGL_PBUFFER_BIT)
472 *value = surface->LargestPbuffer;
473 break;
474 case EGL_TEXTURE_FORMAT:
475 /* texture attributes: only for pbuffers, no error otherwise */
476 if (surface->Type == EGL_PBUFFER_BIT)
477 *value = surface->TextureFormat;
478 break;
479 case EGL_TEXTURE_TARGET:
480 if (surface->Type == EGL_PBUFFER_BIT)
481 *value = surface->TextureTarget;
482 break;
483 case EGL_MIPMAP_TEXTURE:
484 if (surface->Type == EGL_PBUFFER_BIT)
485 *value = surface->MipmapTexture;
486 break;
487 case EGL_MIPMAP_LEVEL:
488 if (surface->Type == EGL_PBUFFER_BIT)
489 *value = surface->MipmapLevel;
490 break;
491 case EGL_SWAP_BEHAVIOR:
492 *value = surface->SwapBehavior;
493 break;
494 case EGL_RENDER_BUFFER:
495 /* From the EGL_KHR_mutable_render_buffer spec (v12):
496 *
497 * Querying EGL_RENDER_BUFFER returns the buffer which client API
498 * rendering is requested to use. For a window surface, this is the
499 * attribute value specified when the surface was created or last set
500 * via eglSurfaceAttrib.
501 *
502 * In other words, querying a window surface returns the value most
503 * recently *requested* by the user.
504 *
505 * The paragraph continues in the EGL 1.5 spec (2014.08.27):
506 *
507 * For a pbuffer surface, it is always EGL_BACK_BUFFER . For a pixmap
508 * surface, it is always EGL_SINGLE_BUFFER . To determine the actual
509 * buffer being rendered to by a context, call eglQueryContext.
510 */
511 switch (surface->Type) {
512 default:
513 unreachable("bad EGLSurface type");
514 case EGL_WINDOW_BIT:
515 *value = surface->RequestedRenderBuffer;
516 break;
517 case EGL_PBUFFER_BIT:
518 *value = EGL_BACK_BUFFER;
519 break;
520 case EGL_PIXMAP_BIT:
521 *value = EGL_SINGLE_BUFFER;
522 break;
523 }
524 break;
525 case EGL_PIXEL_ASPECT_RATIO:
526 *value = surface->AspectRatio;
527 break;
528 case EGL_HORIZONTAL_RESOLUTION:
529 *value = surface->HorizontalResolution;
530 break;
531 case EGL_VERTICAL_RESOLUTION:
532 *value = surface->VerticalResolution;
533 break;
534 case EGL_MULTISAMPLE_RESOLVE:
535 *value = surface->MultisampleResolve;
536 break;
537 case EGL_VG_ALPHA_FORMAT:
538 *value = surface->VGAlphaFormat;
539 break;
540 case EGL_VG_COLORSPACE:
541 *value = surface->VGColorspace;
542 break;
543 case EGL_GL_COLORSPACE_KHR:
544 if (!disp->Extensions.KHR_gl_colorspace)
545 return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
546
547 *value = surface->GLColorspace;
548 break;
549 case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
550 *value = surface->PostSubBufferSupportedNV;
551 break;
552 case EGL_BUFFER_AGE_EXT:
553 /* Both EXT_buffer_age and KHR_partial_update accept EGL_BUFFER_AGE_EXT.
554 * To be precise, the KHR one accepts EGL_BUFFER_AGE_KHR which is an
555 * alias with the same numeric value.
556 */
557 if (!disp->Extensions.EXT_buffer_age &&
558 !disp->Extensions.KHR_partial_update)
559 return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
560
561 _EGLContext *ctx = _eglGetCurrentContext();
562 EGLint result = disp->Driver->QueryBufferAge(disp, surface);
563 /* error happened */
564 if (result < 0)
565 return EGL_FALSE;
566 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
567 ctx->DrawSurface != surface)
568 return _eglError(EGL_BAD_SURFACE, "eglQuerySurface");
569
570 *value = result;
571 surface->BufferAgeRead = EGL_TRUE;
572 break;
573 case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
574 *value = surface->HdrMetadata.display_primary_r.x;
575 break;
576 case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
577 *value = surface->HdrMetadata.display_primary_r.y;
578 break;
579 case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
580 *value = surface->HdrMetadata.display_primary_g.x;
581 break;
582 case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
583 *value = surface->HdrMetadata.display_primary_g.y;
584 break;
585 case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
586 *value = surface->HdrMetadata.display_primary_b.x;
587 break;
588 case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
589 *value = surface->HdrMetadata.display_primary_b.y;
590 break;
591 case EGL_SMPTE2086_WHITE_POINT_X_EXT:
592 *value = surface->HdrMetadata.white_point.x;
593 break;
594 case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
595 *value = surface->HdrMetadata.white_point.y;
596 break;
597 case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
598 *value = surface->HdrMetadata.max_luminance;
599 break;
600 case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
601 *value = surface->HdrMetadata.min_luminance;
602 break;
603 case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
604 *value = surface->HdrMetadata.max_cll;
605 break;
606 case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
607 *value = surface->HdrMetadata.max_fall;
608 break;
609 case EGL_PROTECTED_CONTENT_EXT:
610 if (!disp->Extensions.EXT_protected_surface)
611 return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
612 *value = surface->ProtectedContent;
613 break;
614 case EGL_PRESENT_OPAQUE_EXT:
615 if (!disp->Extensions.EXT_present_opaque)
616 return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
617 *value = surface->PresentOpaque;
618 break;
619 default:
620 return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
621 }
622
623 return EGL_TRUE;
624 }
625
626
627 /**
628 * Default fallback routine - drivers might override this.
629 */
630 EGLBoolean
_eglSurfaceAttrib(_EGLDisplay * disp,_EGLSurface * surface,EGLint attribute,EGLint value)631 _eglSurfaceAttrib(_EGLDisplay *disp, _EGLSurface *surface,
632 EGLint attribute, EGLint value)
633 {
634 EGLint confval;
635 EGLint err = EGL_SUCCESS;
636 EGLint all_es_bits = EGL_OPENGL_ES_BIT |
637 EGL_OPENGL_ES2_BIT |
638 EGL_OPENGL_ES3_BIT_KHR;
639
640 switch (attribute) {
641 case EGL_MIPMAP_LEVEL:
642 confval = surface->Config->RenderableType;
643 if (!(confval & all_es_bits)) {
644 err = EGL_BAD_PARAMETER;
645 break;
646 }
647 surface->MipmapLevel = value;
648 break;
649 case EGL_MULTISAMPLE_RESOLVE:
650 switch (value) {
651 case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
652 break;
653 case EGL_MULTISAMPLE_RESOLVE_BOX:
654 confval = surface->Config->SurfaceType;
655 if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
656 err = EGL_BAD_MATCH;
657 break;
658 default:
659 err = EGL_BAD_ATTRIBUTE;
660 break;
661 }
662 if (err != EGL_SUCCESS)
663 break;
664 surface->MultisampleResolve = value;
665 break;
666 case EGL_RENDER_BUFFER:
667 if (!disp->Extensions.KHR_mutable_render_buffer) {
668 err = EGL_BAD_ATTRIBUTE;
669 break;
670 }
671
672 if (value != EGL_BACK_BUFFER && value != EGL_SINGLE_BUFFER) {
673 err = EGL_BAD_PARAMETER;
674 break;
675 }
676
677 /* From the EGL_KHR_mutable_render_buffer spec (v12):
678 *
679 * If attribute is EGL_RENDER_BUFFER, and the EGL_SURFACE_TYPE
680 * attribute of the EGLConfig used to create surface does not contain
681 * EGL_MUTABLE_RENDER_BUFFER_BIT_KHR, [...] an EGL_BAD_MATCH error is
682 * generated [...].
683 */
684 if (!(surface->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR)) {
685 err = EGL_BAD_MATCH;
686 break;
687 }
688
689 surface->RequestedRenderBuffer = value;
690 break;
691 case EGL_SWAP_BEHAVIOR:
692 switch (value) {
693 case EGL_BUFFER_DESTROYED:
694 break;
695 case EGL_BUFFER_PRESERVED:
696 confval = surface->Config->SurfaceType;
697 if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
698 err = EGL_BAD_MATCH;
699 break;
700 default:
701 err = EGL_BAD_ATTRIBUTE;
702 break;
703 }
704 if (err != EGL_SUCCESS)
705 break;
706 surface->SwapBehavior = value;
707 break;
708 case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
709 surface->HdrMetadata.display_primary_r.x = value;
710 break;
711 case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
712 surface->HdrMetadata.display_primary_r.y = value;
713 break;
714 case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
715 surface->HdrMetadata.display_primary_g.x = value;
716 break;
717 case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
718 surface->HdrMetadata.display_primary_g.y = value;
719 break;
720 case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
721 surface->HdrMetadata.display_primary_b.x = value;
722 break;
723 case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
724 surface->HdrMetadata.display_primary_b.y = value;
725 break;
726 case EGL_SMPTE2086_WHITE_POINT_X_EXT:
727 surface->HdrMetadata.white_point.x = value;
728 break;
729 case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
730 surface->HdrMetadata.white_point.y = value;
731 break;
732 case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
733 surface->HdrMetadata.max_luminance = value;
734 break;
735 case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
736 surface->HdrMetadata.min_luminance = value;
737 break;
738 case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
739 surface->HdrMetadata.max_cll = value;
740 break;
741 case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
742 surface->HdrMetadata.max_fall = value;
743 break;
744 default:
745 err = EGL_BAD_ATTRIBUTE;
746 break;
747 }
748
749 if (err != EGL_SUCCESS)
750 return _eglError(err, "eglSurfaceAttrib");
751 return EGL_TRUE;
752 }
753
754
755 EGLBoolean
_eglBindTexImage(_EGLDisplay * disp,_EGLSurface * surface,EGLint buffer)756 _eglBindTexImage(_EGLDisplay *disp, _EGLSurface *surface, EGLint buffer)
757 {
758 EGLint texture_type = EGL_PBUFFER_BIT;
759
760 /* Just do basic error checking and return success/fail.
761 * Drivers must implement the real stuff.
762 */
763
764 if (disp->Extensions.NOK_texture_from_pixmap)
765 texture_type |= EGL_PIXMAP_BIT;
766
767 if (!(surface->Type & texture_type))
768 return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
769
770 if (surface->TextureFormat == EGL_NO_TEXTURE)
771 return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
772
773 if (surface->TextureTarget == EGL_NO_TEXTURE)
774 return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
775
776 if (buffer != EGL_BACK_BUFFER)
777 return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
778
779 surface->BoundToTexture = EGL_TRUE;
780
781 return EGL_TRUE;
782 }
783
784 EGLBoolean
_eglReleaseTexImage(_EGLDisplay * disp,_EGLSurface * surf,EGLint buffer)785 _eglReleaseTexImage(_EGLDisplay *disp, _EGLSurface *surf, EGLint buffer)
786 {
787 /* Just do basic error checking and return success/fail.
788 * Drivers must implement the real stuff.
789 */
790
791 EGLint texture_type = EGL_PBUFFER_BIT;
792
793 if (surf == EGL_NO_SURFACE)
794 return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
795
796 if (!surf->BoundToTexture)
797 {
798 /* Not an error, simply nothing to do */
799 return EGL_TRUE;
800 }
801
802 if (surf->TextureFormat == EGL_NO_TEXTURE)
803 return _eglError(EGL_BAD_MATCH, "eglReleaseTexImage");
804
805 if (buffer != EGL_BACK_BUFFER)
806 return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
807
808 if (disp->Extensions.NOK_texture_from_pixmap)
809 texture_type |= EGL_PIXMAP_BIT;
810
811 if (!(surf->Type & texture_type))
812 return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
813
814 surf->BoundToTexture = EGL_FALSE;
815
816 return EGL_TRUE;
817 }
818
819 EGLBoolean
_eglSurfaceHasMutableRenderBuffer(_EGLSurface * surf)820 _eglSurfaceHasMutableRenderBuffer(_EGLSurface *surf)
821 {
822 return surf->Type == EGL_WINDOW_BIT &&
823 surf->Config &&
824 (surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR);
825 }
826
827 EGLBoolean
_eglSurfaceInSharedBufferMode(_EGLSurface * surf)828 _eglSurfaceInSharedBufferMode(_EGLSurface *surf)
829 {
830 return _eglSurfaceHasMutableRenderBuffer(surf) &&
831 surf->ActiveRenderBuffer == EGL_SINGLE_BUFFER;
832 }
833