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 */ 53static 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_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 */ 358EGLBoolean 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 456EGLBoolean 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 */ 630EGLBoolean 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 755EGLBoolean 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 784EGLBoolean 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 819EGLBoolean 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 827EGLBoolean 828_eglSurfaceInSharedBufferMode(_EGLSurface *surf) 829{ 830 return _eglSurfaceHasMutableRenderBuffer(surf) && 831 surf->ActiveRenderBuffer == EGL_SINGLE_BUFFER; 832} 833