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