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