validationEGL.cpp (232294B)
1 // 2 // Copyright 2016 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // validationEGL.cpp: Validation functions for generic EGL entry point parameters 8 9 #include "libANGLE/validationEGL_autogen.h" 10 11 #include "common/utilities.h" 12 #include "libANGLE/Config.h" 13 #include "libANGLE/Context.h" 14 #include "libANGLE/Device.h" 15 #include "libANGLE/Display.h" 16 #include "libANGLE/EGLSync.h" 17 #include "libANGLE/Image.h" 18 #include "libANGLE/Stream.h" 19 #include "libANGLE/Surface.h" 20 #include "libANGLE/Texture.h" 21 #include "libANGLE/Thread.h" 22 #include "libANGLE/formatutils.h" 23 #include "libANGLE/renderer/DisplayImpl.h" 24 25 #include <EGL/eglext.h> 26 27 namespace egl 28 { 29 namespace 30 { 31 size_t GetMaximumMipLevel(const gl::Context *context, gl::TextureType type) 32 { 33 const gl::Caps &caps = context->getCaps(); 34 35 int maxDimension = 0; 36 switch (type) 37 { 38 case gl::TextureType::_2D: 39 case gl::TextureType::_2DArray: 40 case gl::TextureType::_2DMultisample: 41 maxDimension = caps.max2DTextureSize; 42 break; 43 case gl::TextureType::Rectangle: 44 maxDimension = caps.maxRectangleTextureSize; 45 break; 46 case gl::TextureType::CubeMap: 47 maxDimension = caps.maxCubeMapTextureSize; 48 break; 49 case gl::TextureType::_3D: 50 maxDimension = caps.max3DTextureSize; 51 break; 52 53 default: 54 UNREACHABLE(); 55 } 56 57 return gl::log2(maxDimension); 58 } 59 60 bool TextureHasNonZeroMipLevelsSpecified(const gl::Context *context, const gl::Texture *texture) 61 { 62 size_t maxMip = GetMaximumMipLevel(context, texture->getType()); 63 for (size_t level = 1; level < maxMip; level++) 64 { 65 if (texture->getType() == gl::TextureType::CubeMap) 66 { 67 for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets()) 68 { 69 if (texture->getFormat(face, level).valid()) 70 { 71 return true; 72 } 73 } 74 } 75 else 76 { 77 if (texture->getFormat(gl::NonCubeTextureTypeToTarget(texture->getType()), level) 78 .valid()) 79 { 80 return true; 81 } 82 } 83 } 84 85 return false; 86 } 87 88 bool CubeTextureHasUnspecifiedLevel0Face(const gl::Texture *texture) 89 { 90 ASSERT(texture->getType() == gl::TextureType::CubeMap); 91 for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets()) 92 { 93 if (!texture->getFormat(face, 0).valid()) 94 { 95 return true; 96 } 97 } 98 99 return false; 100 } 101 102 bool ValidateStreamAttribute(const ValidationContext *val, 103 const EGLAttrib attribute, 104 const EGLAttrib value, 105 const DisplayExtensions &extensions) 106 { 107 switch (attribute) 108 { 109 case EGL_STREAM_STATE_KHR: 110 case EGL_PRODUCER_FRAME_KHR: 111 case EGL_CONSUMER_FRAME_KHR: 112 val->setError(EGL_BAD_ACCESS, "Attempt to initialize readonly parameter"); 113 return false; 114 case EGL_CONSUMER_LATENCY_USEC_KHR: 115 // Technically not in spec but a latency < 0 makes no sense so we check it 116 if (value < 0) 117 { 118 val->setError(EGL_BAD_PARAMETER, "Latency must be positive"); 119 return false; 120 } 121 break; 122 case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR: 123 if (!extensions.streamConsumerGLTexture) 124 { 125 val->setError(EGL_BAD_ATTRIBUTE, "Consumer GL extension not enabled"); 126 return false; 127 } 128 // Again not in spec but it should be positive anyways 129 if (value < 0) 130 { 131 val->setError(EGL_BAD_PARAMETER, "Timeout must be positive"); 132 return false; 133 } 134 break; 135 default: 136 val->setError(EGL_BAD_ATTRIBUTE, "Invalid stream attribute"); 137 return false; 138 } 139 return true; 140 } 141 142 bool ValidateCreateImageMipLevelCommon(const ValidationContext *val, 143 const gl::Context *context, 144 const gl::Texture *texture, 145 EGLAttrib level) 146 { 147 // Note that the spec EGL_create_image spec does not explicitly specify an error 148 // when the level is outside the base/max level range, but it does mention that the 149 // level "must be a part of the complete texture object <buffer>". It can be argued 150 // that out-of-range levels are not a part of the complete texture. 151 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel(); 152 if (level > 0 && 153 (!texture->isMipmapComplete() || static_cast<GLuint>(level) < effectiveBaseLevel || 154 static_cast<GLuint>(level) > texture->getTextureState().getMipmapMaxLevel())) 155 { 156 val->setError(EGL_BAD_PARAMETER, "texture must be complete if level is non-zero."); 157 return false; 158 } 159 160 if (level == 0 && !texture->isMipmapComplete() && 161 TextureHasNonZeroMipLevelsSpecified(context, texture)) 162 { 163 val->setError(EGL_BAD_PARAMETER, 164 "if level is zero and the texture is incomplete, it must " 165 "have no mip levels specified except zero."); 166 return false; 167 } 168 169 return true; 170 } 171 172 bool ValidateConfigAttribute(const ValidationContext *val, 173 const Display *display, 174 EGLAttrib attribute) 175 { 176 switch (attribute) 177 { 178 case EGL_BUFFER_SIZE: 179 case EGL_ALPHA_SIZE: 180 case EGL_BLUE_SIZE: 181 case EGL_GREEN_SIZE: 182 case EGL_RED_SIZE: 183 case EGL_DEPTH_SIZE: 184 case EGL_STENCIL_SIZE: 185 case EGL_CONFIG_CAVEAT: 186 case EGL_CONFIG_ID: 187 case EGL_LEVEL: 188 case EGL_NATIVE_RENDERABLE: 189 case EGL_NATIVE_VISUAL_ID: 190 case EGL_NATIVE_VISUAL_TYPE: 191 case EGL_SAMPLES: 192 case EGL_SAMPLE_BUFFERS: 193 case EGL_SURFACE_TYPE: 194 case EGL_TRANSPARENT_TYPE: 195 case EGL_TRANSPARENT_BLUE_VALUE: 196 case EGL_TRANSPARENT_GREEN_VALUE: 197 case EGL_TRANSPARENT_RED_VALUE: 198 case EGL_BIND_TO_TEXTURE_RGB: 199 case EGL_BIND_TO_TEXTURE_RGBA: 200 case EGL_MIN_SWAP_INTERVAL: 201 case EGL_MAX_SWAP_INTERVAL: 202 case EGL_LUMINANCE_SIZE: 203 case EGL_ALPHA_MASK_SIZE: 204 case EGL_COLOR_BUFFER_TYPE: 205 case EGL_RENDERABLE_TYPE: 206 case EGL_MATCH_NATIVE_PIXMAP: 207 case EGL_CONFORMANT: 208 case EGL_MAX_PBUFFER_WIDTH: 209 case EGL_MAX_PBUFFER_HEIGHT: 210 case EGL_MAX_PBUFFER_PIXELS: 211 break; 212 213 case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE: 214 if (!display->getExtensions().surfaceOrientation) 215 { 216 val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_surface_orientation is not enabled."); 217 return false; 218 } 219 break; 220 221 case EGL_COLOR_COMPONENT_TYPE_EXT: 222 if (!display->getExtensions().pixelFormatFloat) 223 { 224 val->setError(EGL_BAD_ATTRIBUTE, "EGL_EXT_pixel_format_float is not enabled."); 225 return false; 226 } 227 break; 228 229 case EGL_RECORDABLE_ANDROID: 230 if (!display->getExtensions().recordable) 231 { 232 val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANDROID_recordable is not enabled."); 233 return false; 234 } 235 break; 236 237 case EGL_FRAMEBUFFER_TARGET_ANDROID: 238 if (!display->getExtensions().framebufferTargetANDROID) 239 { 240 val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANDROID_framebuffer_target is not enabled."); 241 return false; 242 } 243 break; 244 245 case EGL_BIND_TO_TEXTURE_TARGET_ANGLE: 246 if (!display->getExtensions().iosurfaceClientBuffer) 247 { 248 val->setError(EGL_BAD_ATTRIBUTE, 249 "EGL_ANGLE_iosurface_client_buffer is not enabled."); 250 return false; 251 } 252 break; 253 254 case EGL_Y_INVERTED_NOK: 255 if (!display->getExtensions().textureFromPixmapNOK) 256 { 257 val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled."); 258 return false; 259 } 260 break; 261 262 case EGL_MATCH_FORMAT_KHR: 263 if (!display->getExtensions().lockSurface3KHR) 264 { 265 val->setError(EGL_BAD_ATTRIBUTE, "EGL_KHR_lock_surface3 is not enabled."); 266 return false; 267 } 268 break; 269 270 default: 271 val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04" PRIxPTR "X", attribute); 272 return false; 273 } 274 275 return true; 276 } 277 278 bool ValidateConfigAttributeValue(const ValidationContext *val, 279 const Display *display, 280 EGLAttrib attribute, 281 EGLAttrib value) 282 { 283 switch (attribute) 284 { 285 286 case EGL_BIND_TO_TEXTURE_RGB: 287 case EGL_BIND_TO_TEXTURE_RGBA: 288 switch (value) 289 { 290 case EGL_DONT_CARE: 291 case EGL_TRUE: 292 case EGL_FALSE: 293 break; 294 default: 295 val->setError(EGL_BAD_ATTRIBUTE, "EGL_bind_to_texture invalid attribute: 0x%X", 296 static_cast<uint32_t>(value)); 297 return false; 298 } 299 break; 300 301 case EGL_COLOR_BUFFER_TYPE: 302 switch (value) 303 { 304 case EGL_RGB_BUFFER: 305 case EGL_LUMINANCE_BUFFER: 306 // EGL_DONT_CARE doesn't match the spec, but does match dEQP usage 307 case EGL_DONT_CARE: 308 break; 309 default: 310 val->setError(EGL_BAD_ATTRIBUTE, 311 "EGL_color_buffer_type invalid attribute: 0x%X", 312 static_cast<uint32_t>(value)); 313 return false; 314 } 315 break; 316 317 case EGL_NATIVE_RENDERABLE: 318 switch (value) 319 { 320 case EGL_DONT_CARE: 321 case EGL_TRUE: 322 case EGL_FALSE: 323 break; 324 default: 325 val->setError(EGL_BAD_ATTRIBUTE, 326 "EGL_native_renderable invalid attribute: 0x%X", 327 static_cast<uint32_t>(value)); 328 return false; 329 } 330 break; 331 332 case EGL_TRANSPARENT_TYPE: 333 switch (value) 334 { 335 case EGL_NONE: 336 case EGL_TRANSPARENT_RGB: 337 // EGL_DONT_CARE doesn't match the spec, but does match dEQP usage 338 case EGL_DONT_CARE: 339 break; 340 default: 341 val->setError(EGL_BAD_ATTRIBUTE, "EGL_transparent_type invalid attribute: 0x%X", 342 static_cast<uint32_t>(value)); 343 return false; 344 } 345 break; 346 347 case EGL_RECORDABLE_ANDROID: 348 switch (value) 349 { 350 case EGL_TRUE: 351 case EGL_FALSE: 352 case EGL_DONT_CARE: 353 break; 354 default: 355 val->setError(EGL_BAD_ATTRIBUTE, 356 "EGL_RECORDABLE_ANDROID invalid attribute: 0x%X", 357 static_cast<uint32_t>(value)); 358 return false; 359 } 360 break; 361 362 case EGL_COLOR_COMPONENT_TYPE_EXT: 363 switch (value) 364 { 365 case EGL_COLOR_COMPONENT_TYPE_FIXED_EXT: 366 case EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT: 367 case EGL_DONT_CARE: 368 break; 369 default: 370 val->setError(EGL_BAD_ATTRIBUTE, 371 "EGL_COLOR_COMPONENT_TYPE_EXT invalid attribute: 0x%X", 372 static_cast<uint32_t>(value)); 373 return false; 374 } 375 break; 376 377 case EGL_MATCH_FORMAT_KHR: 378 switch (value) 379 { 380 case EGL_FORMAT_RGB_565_KHR: 381 case EGL_FORMAT_RGBA_8888_KHR: 382 case EGL_FORMAT_RGB_565_EXACT_KHR: 383 case EGL_FORMAT_RGBA_8888_EXACT_KHR: 384 break; 385 default: 386 val->setError(EGL_BAD_ATTRIBUTE, 387 "EGL_KHR_lock_surface3 invalid attribute: 0x%X", 388 static_cast<uint32_t>(value)); 389 return false; 390 } 391 break; 392 393 default: 394 break; 395 } 396 397 return true; 398 } 399 400 bool ValidateConfigAttributes(const ValidationContext *val, 401 const Display *display, 402 const AttributeMap &attributes) 403 { 404 ANGLE_VALIDATION_TRY(attributes.validate(val, display, ValidateConfigAttribute)); 405 406 for (const auto &attrib : attributes) 407 { 408 EGLAttrib pname = attrib.first; 409 EGLAttrib value = attrib.second; 410 ANGLE_VALIDATION_TRY(ValidateConfigAttributeValue(val, display, pname, value)); 411 } 412 413 return true; 414 } 415 416 bool ValidateColorspaceAttribute(const ValidationContext *val, 417 const DisplayExtensions &displayExtensions, 418 EGLAttrib colorSpace) 419 { 420 switch (colorSpace) 421 { 422 case EGL_GL_COLORSPACE_SRGB: 423 break; 424 case EGL_GL_COLORSPACE_LINEAR: 425 break; 426 case EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT: 427 if (!displayExtensions.glColorspaceDisplayP3Linear && 428 !displayExtensions.eglColorspaceAttributePassthroughANGLE) 429 { 430 val->setError(EGL_BAD_ATTRIBUTE, 431 "EXT_gl_colorspace_display_p3_linear is not available."); 432 return false; 433 } 434 break; 435 case EGL_GL_COLORSPACE_DISPLAY_P3_EXT: 436 if (!displayExtensions.glColorspaceDisplayP3 && 437 !displayExtensions.eglColorspaceAttributePassthroughANGLE) 438 { 439 val->setError(EGL_BAD_ATTRIBUTE, "EXT_gl_colorspace_display_p3 is not available."); 440 return false; 441 } 442 break; 443 case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT: 444 if (!displayExtensions.glColorspaceDisplayP3Passthrough && 445 !displayExtensions.eglColorspaceAttributePassthroughANGLE) 446 { 447 val->setError(EGL_BAD_ATTRIBUTE, 448 "EGL_EXT_gl_colorspace_display_p3_passthrough is not available."); 449 return false; 450 } 451 break; 452 case EGL_GL_COLORSPACE_SCRGB_EXT: 453 if (!displayExtensions.glColorspaceScrgb && 454 !displayExtensions.eglColorspaceAttributePassthroughANGLE) 455 { 456 val->setError(EGL_BAD_ATTRIBUTE, "EXT_gl_colorspace_scrgb is not available."); 457 return false; 458 } 459 break; 460 case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT: 461 if (!displayExtensions.glColorspaceScrgbLinear && 462 !displayExtensions.eglColorspaceAttributePassthroughANGLE) 463 { 464 val->setError(EGL_BAD_ATTRIBUTE, 465 "EXT_gl_colorspace_scrgb_linear is not available."); 466 return false; 467 } 468 break; 469 default: 470 val->setError(EGL_BAD_ATTRIBUTE); 471 return false; 472 } 473 return true; 474 } 475 bool ValidatePlatformType(const ValidationContext *val, 476 const ClientExtensions &clientExtensions, 477 EGLAttrib platformType) 478 { 479 switch (platformType) 480 { 481 case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: 482 break; 483 484 case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: 485 case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: 486 if (!clientExtensions.platformANGLED3D) 487 { 488 val->setError(EGL_BAD_ATTRIBUTE, "Direct3D platform is unsupported."); 489 return false; 490 } 491 break; 492 493 case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: 494 case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: 495 if (!clientExtensions.platformANGLEOpenGL) 496 { 497 val->setError(EGL_BAD_ATTRIBUTE, "OpenGL platform is unsupported."); 498 return false; 499 } 500 break; 501 502 case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE: 503 if (!clientExtensions.platformANGLENULL) 504 { 505 val->setError(EGL_BAD_ATTRIBUTE, 506 "Display type EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE " 507 "requires EGL_ANGLE_platform_angle_null."); 508 return false; 509 } 510 break; 511 512 case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE: 513 if (!clientExtensions.platformANGLEVulkan) 514 { 515 val->setError(EGL_BAD_ATTRIBUTE, "Vulkan platform is unsupported."); 516 return false; 517 } 518 break; 519 520 case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE: 521 if (!clientExtensions.platformANGLEMetal) 522 { 523 val->setError(EGL_BAD_ATTRIBUTE, "Metal platform is unsupported."); 524 return false; 525 } 526 break; 527 528 default: 529 val->setError(EGL_BAD_ATTRIBUTE, "Unknown platform type."); 530 return false; 531 } 532 533 return true; 534 } 535 536 bool ValidateGetPlatformDisplayCommon(const ValidationContext *val, 537 EGLenum platform, 538 const void *native_display, 539 const AttributeMap &attribMap) 540 { 541 const ClientExtensions &clientExtensions = Display::GetClientExtensions(); 542 543 switch (platform) 544 { 545 case EGL_PLATFORM_ANGLE_ANGLE: 546 if (!clientExtensions.platformANGLE) 547 { 548 val->setError(EGL_BAD_PARAMETER, "Platform ANGLE extension is not active"); 549 return false; 550 } 551 break; 552 case EGL_PLATFORM_DEVICE_EXT: 553 if (!clientExtensions.platformDevice) 554 { 555 val->setError(EGL_BAD_PARAMETER, "Platform Device extension is not active"); 556 return false; 557 } 558 break; 559 case EGL_PLATFORM_GBM_KHR: 560 if (!clientExtensions.platformGbmKHR) 561 { 562 val->setError(EGL_BAD_PARAMETER, "Platform GBM extension is not active"); 563 return false; 564 } 565 break; 566 case EGL_PLATFORM_WAYLAND_EXT: 567 if (!clientExtensions.platformWaylandEXT) 568 { 569 val->setError(EGL_BAD_PARAMETER, "Platform Wayland extension is not active"); 570 return false; 571 } 572 break; 573 default: 574 val->setError(EGL_BAD_CONFIG, "Bad platform type."); 575 return false; 576 } 577 578 attribMap.initializeWithoutValidation(); 579 580 if (platform != EGL_PLATFORM_DEVICE_EXT) 581 { 582 EGLAttrib platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; 583 bool enableAutoTrimSpecified = false; 584 bool enableD3D11on12 = false; 585 bool presentPathSpecified = false; 586 bool luidSpecified = false; 587 bool deviceIdSpecified = false; 588 589 Optional<EGLAttrib> majorVersion; 590 Optional<EGLAttrib> minorVersion; 591 Optional<EGLAttrib> deviceType; 592 Optional<EGLAttrib> eglHandle; 593 594 for (const auto &curAttrib : attribMap) 595 { 596 const EGLAttrib value = curAttrib.second; 597 598 switch (curAttrib.first) 599 { 600 case EGL_PLATFORM_ANGLE_TYPE_ANGLE: 601 { 602 ANGLE_VALIDATION_TRY(ValidatePlatformType(val, clientExtensions, value)); 603 platformType = value; 604 break; 605 } 606 607 case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE: 608 if (value != EGL_DONT_CARE) 609 { 610 majorVersion = value; 611 } 612 break; 613 614 case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE: 615 if (value != EGL_DONT_CARE) 616 { 617 minorVersion = value; 618 } 619 break; 620 621 case EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE: 622 switch (value) 623 { 624 case EGL_TRUE: 625 case EGL_FALSE: 626 break; 627 default: 628 val->setError(EGL_BAD_ATTRIBUTE, "Invalid automatic trim attribute"); 629 return false; 630 } 631 enableAutoTrimSpecified = true; 632 break; 633 634 case EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE: 635 if (!clientExtensions.platformANGLED3D || 636 !clientExtensions.platformANGLED3D11ON12) 637 { 638 val->setError(EGL_BAD_ATTRIBUTE, 639 "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE extension not active."); 640 return false; 641 } 642 643 switch (value) 644 { 645 case EGL_TRUE: 646 case EGL_FALSE: 647 break; 648 default: 649 val->setError(EGL_BAD_ATTRIBUTE, "Invalid D3D11on12 attribute"); 650 return false; 651 } 652 enableD3D11on12 = true; 653 break; 654 655 case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE: 656 if (!clientExtensions.experimentalPresentPath) 657 { 658 val->setError(EGL_BAD_ATTRIBUTE, 659 "EGL_ANGLE_experimental_present_path extension not active"); 660 return false; 661 } 662 663 switch (value) 664 { 665 case EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE: 666 case EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE: 667 break; 668 default: 669 val->setError(EGL_BAD_ATTRIBUTE, 670 "Invalid value for EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE"); 671 return false; 672 } 673 presentPathSpecified = true; 674 break; 675 676 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE: 677 switch (value) 678 { 679 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: 680 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: 681 break; 682 683 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE: 684 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE: 685 if (!clientExtensions.platformANGLED3D) 686 { 687 val->setError(EGL_BAD_ATTRIBUTE, 688 "EGL_ANGLE_platform_angle_d3d is not supported"); 689 return false; 690 } 691 break; 692 693 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE: 694 if (!clientExtensions.platformANGLEDeviceTypeEGLANGLE) 695 { 696 val->setError(EGL_BAD_ATTRIBUTE, 697 "EGL_ANGLE_platform_angle_device_type_" 698 "egl_angle is not supported"); 699 return false; 700 } 701 break; 702 703 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE: 704 if (!clientExtensions.platformANGLEDeviceTypeSwiftShader) 705 { 706 val->setError(EGL_BAD_ATTRIBUTE, 707 "EGL_ANGLE_platform_angle_device_type_" 708 "swiftshader is not supported"); 709 return false; 710 } 711 break; 712 713 default: 714 val->setError(EGL_BAD_ATTRIBUTE, 715 "Invalid value for " 716 "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE " 717 "attrib"); 718 return false; 719 } 720 deviceType = value; 721 break; 722 723 case EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE: 724 if (!clientExtensions.platformANGLE) 725 { 726 val->setError(EGL_BAD_ATTRIBUTE, 727 "EGL_ANGLE_platform_angle extension not active"); 728 return false; 729 } 730 if (value != EGL_TRUE && value != EGL_FALSE && value != EGL_DONT_CARE) 731 { 732 val->setError(EGL_BAD_ATTRIBUTE, 733 "EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE " 734 "must be EGL_TRUE, EGL_FALSE, or " 735 "EGL_DONT_CARE."); 736 return false; 737 } 738 break; 739 740 case EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE: 741 if (value != EGL_DONT_CARE) 742 { 743 eglHandle = value; 744 } 745 break; 746 747 case EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE: 748 case EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE: 749 luidSpecified = true; 750 break; 751 case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_EAGL_ANGLE: 752 // The property does not have an effect if it's not active, so do not check 753 // for non-support. 754 switch (value) 755 { 756 case EGL_FALSE: 757 case EGL_TRUE: 758 break; 759 default: 760 val->setError(EGL_BAD_ATTRIBUTE, 761 "Invalid value for " 762 "EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_" 763 "EAGL_ANGLE attrib"); 764 return false; 765 } 766 break; 767 case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE: 768 // The property does not have an effect if it's not active, so do not check 769 // for non-support. 770 switch (value) 771 { 772 case EGL_FALSE: 773 case EGL_TRUE: 774 break; 775 default: 776 val->setError(EGL_BAD_ATTRIBUTE, 777 "Invalid value for " 778 "EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_" 779 "CGL_ANGLE attrib"); 780 return false; 781 } 782 break; 783 case EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE: 784 case EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE: 785 if (!clientExtensions.platformANGLEDeviceId) 786 { 787 val->setError(EGL_BAD_ATTRIBUTE, 788 "EGL_ANGLE_platform_angle_device_id is not supported"); 789 return false; 790 } 791 deviceIdSpecified = true; 792 break; 793 default: 794 break; 795 } 796 } 797 798 if (!majorVersion.valid() && minorVersion.valid()) 799 { 800 val->setError(EGL_BAD_ATTRIBUTE, 801 "Must specify major version if you specify a minor version."); 802 return false; 803 } 804 805 if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE && 806 platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) 807 { 808 val->setError(EGL_BAD_ATTRIBUTE, 809 "EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a " 810 "device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."); 811 return false; 812 } 813 814 if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) 815 { 816 val->setError(EGL_BAD_ATTRIBUTE, 817 "EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE " 818 "requires a device type of " 819 "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."); 820 return false; 821 } 822 823 if (enableD3D11on12) 824 { 825 if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) 826 { 827 val->setError(EGL_BAD_ATTRIBUTE, 828 "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE " 829 "requires a platform type of " 830 "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."); 831 return false; 832 } 833 834 if (deviceType.valid() && deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE && 835 deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE) 836 { 837 val->setError(EGL_BAD_ATTRIBUTE, 838 "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE requires a device " 839 "type of EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE " 840 "or EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE"); 841 return false; 842 } 843 } 844 845 if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) 846 { 847 val->setError(EGL_BAD_ATTRIBUTE, 848 "EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a " 849 "device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."); 850 return false; 851 } 852 853 if (luidSpecified) 854 { 855 if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) 856 { 857 val->setError(EGL_BAD_ATTRIBUTE, 858 "EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE and " 859 "EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE " 860 "require a platform type of " 861 "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."); 862 return false; 863 } 864 865 if (attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 0) == 0 && 866 attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE, 0) == 0) 867 { 868 val->setError(EGL_BAD_ATTRIBUTE, 869 "If either EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE " 870 "and/or EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE are " 871 "specified, at least one must non-zero."); 872 return false; 873 } 874 } 875 876 if (deviceIdSpecified) 877 { 878 if (attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0) == 0 && 879 attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0) == 0) 880 { 881 val->setError(EGL_BAD_ATTRIBUTE, 882 "If either EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE " 883 "and/or EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE are " 884 "specified, at least one must non-zero."); 885 return false; 886 } 887 } 888 889 if (deviceType.valid()) 890 { 891 switch (deviceType.value()) 892 { 893 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE: 894 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE: 895 if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE && 896 platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) 897 { 898 val->setError(EGL_BAD_ATTRIBUTE, 899 "This device type requires a " 900 "platform type of EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or " 901 "EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE."); 902 return false; 903 } 904 break; 905 906 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE: 907 if (platformType != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) 908 { 909 val->setError(EGL_BAD_ATTRIBUTE, 910 "This device type requires a " 911 "platform type of EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE."); 912 return false; 913 } 914 break; 915 916 default: 917 break; 918 } 919 } 920 921 if (platformType == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) 922 { 923 if ((majorVersion.valid() && majorVersion.value() != 1) || 924 (minorVersion.valid() && minorVersion.value() != 0)) 925 { 926 val->setError(EGL_BAD_ATTRIBUTE, 927 "EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE currently " 928 "only supports Vulkan 1.0."); 929 return false; 930 } 931 } 932 933 if (eglHandle.valid() && platformType != EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE && 934 platformType != EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE) 935 { 936 val->setError(EGL_BAD_ATTRIBUTE, 937 "EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE requires a " 938 "device type of EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE."); 939 return false; 940 } 941 } 942 else 943 { 944 const Device *eglDevice = static_cast<const Device *>(native_display); 945 if (eglDevice == nullptr || !Device::IsValidDevice(eglDevice)) 946 { 947 val->setError(EGL_BAD_ATTRIBUTE, 948 "native_display should be a valid EGL device if " 949 "platform equals EGL_PLATFORM_DEVICE_EXT"); 950 return false; 951 } 952 } 953 954 if (attribMap.contains(EGL_POWER_PREFERENCE_ANGLE)) 955 { 956 if (!clientExtensions.displayPowerPreferenceANGLE) 957 { 958 val->setError(EGL_BAD_ATTRIBUTE, 959 "Attribute EGL_POWER_PREFERENCE_ANGLE " 960 "requires EGL_ANGLE_display_power_preference."); 961 return false; 962 } 963 EGLAttrib value = attribMap.get(EGL_POWER_PREFERENCE_ANGLE, 0); 964 if (value != EGL_LOW_POWER_ANGLE && value != EGL_HIGH_POWER_ANGLE) 965 { 966 val->setError(EGL_BAD_ATTRIBUTE, 967 "EGL_POWER_PREFERENCE_ANGLE must be " 968 "either EGL_LOW_POWER_ANGLE or EGL_HIGH_POWER_ANGLE."); 969 return false; 970 } 971 } 972 973 if (attribMap.contains(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE)) 974 { 975 if (!clientExtensions.featureControlANGLE) 976 { 977 val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_feature_control is not supported"); 978 return false; 979 } 980 else if (attribMap.get(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE, 0) == 0) 981 { 982 val->setError(EGL_BAD_ATTRIBUTE, 983 "EGL_FEATURE_OVERRIDES_ENABLED_ANGLE must be a valid pointer"); 984 return false; 985 } 986 } 987 if (attribMap.contains(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE)) 988 { 989 if (!clientExtensions.featureControlANGLE) 990 { 991 val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_feature_control is not supported"); 992 return false; 993 } 994 else if (attribMap.get(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE, 0) == 0) 995 { 996 val->setError(EGL_BAD_ATTRIBUTE, 997 "EGL_FEATURE_OVERRIDES_DISABLED_ANGLE must be a valid pointer"); 998 return false; 999 } 1000 } 1001 1002 return true; 1003 } 1004 1005 bool ValidateStream(const ValidationContext *val, const Display *display, const Stream *stream) 1006 { 1007 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 1008 1009 const DisplayExtensions &displayExtensions = display->getExtensions(); 1010 if (!displayExtensions.stream) 1011 { 1012 val->setError(EGL_BAD_ACCESS, "Stream extension not active"); 1013 return false; 1014 } 1015 1016 if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) 1017 { 1018 val->setError(EGL_BAD_STREAM_KHR, "Invalid stream"); 1019 return false; 1020 } 1021 1022 return true; 1023 } 1024 1025 bool ValidateLabeledObject(const ValidationContext *val, 1026 const Display *display, 1027 ObjectType objectType, 1028 EGLObjectKHR object, 1029 LabeledObject **outLabeledObject) 1030 { 1031 switch (objectType) 1032 { 1033 case ObjectType::Context: 1034 { 1035 gl::Context *context = static_cast<gl::Context *>(object); 1036 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 1037 *outLabeledObject = context; 1038 break; 1039 } 1040 1041 case ObjectType::Display: 1042 { 1043 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 1044 if (display != object) 1045 { 1046 if (val) 1047 { 1048 val->setError(EGL_BAD_PARAMETER, 1049 "when object type is EGL_OBJECT_DISPLAY_KHR, the " 1050 "object must be the same as the display."); 1051 } 1052 return false; 1053 } 1054 1055 *outLabeledObject = static_cast<Display *>(object); 1056 break; 1057 } 1058 1059 case ObjectType::Image: 1060 { 1061 Image *image = static_cast<Image *>(object); 1062 ANGLE_VALIDATION_TRY(ValidateImage(val, display, image)); 1063 *outLabeledObject = image; 1064 break; 1065 } 1066 1067 case ObjectType::Stream: 1068 { 1069 Stream *stream = static_cast<Stream *>(object); 1070 ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); 1071 *outLabeledObject = stream; 1072 break; 1073 } 1074 1075 case ObjectType::Surface: 1076 { 1077 Surface *surface = static_cast<Surface *>(object); 1078 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 1079 *outLabeledObject = surface; 1080 break; 1081 } 1082 1083 case ObjectType::Sync: 1084 { 1085 Sync *sync = static_cast<Sync *>(object); 1086 ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); 1087 *outLabeledObject = sync; 1088 break; 1089 } 1090 1091 case ObjectType::Thread: 1092 { 1093 ASSERT(val); 1094 *outLabeledObject = val->eglThread; 1095 break; 1096 } 1097 1098 default: 1099 if (val) 1100 { 1101 val->setError(EGL_BAD_PARAMETER, "unknown object type."); 1102 } 1103 return false; 1104 } 1105 1106 return true; 1107 } 1108 1109 // This is a common sub-check of Display status that's shared by multiple functions 1110 bool ValidateDisplayPointer(const ValidationContext *val, const Display *display) 1111 { 1112 if (display == EGL_NO_DISPLAY) 1113 { 1114 if (val) 1115 { 1116 val->setError(EGL_BAD_DISPLAY, "display is EGL_NO_DISPLAY."); 1117 } 1118 return false; 1119 } 1120 1121 if (!Display::isValidDisplay(display)) 1122 { 1123 if (val) 1124 { 1125 val->setError(EGL_BAD_DISPLAY, "display is not a valid display: 0x%p", display); 1126 } 1127 return false; 1128 } 1129 1130 return true; 1131 } 1132 1133 bool ValidCompositorTimingName(CompositorTiming name) 1134 { 1135 switch (name) 1136 { 1137 case CompositorTiming::CompositeDeadline: 1138 case CompositorTiming::CompositInterval: 1139 case CompositorTiming::CompositToPresentLatency: 1140 return true; 1141 1142 default: 1143 return false; 1144 } 1145 } 1146 1147 bool ValidTimestampType(Timestamp timestamp) 1148 { 1149 switch (timestamp) 1150 { 1151 case Timestamp::RequestedPresentTime: 1152 case Timestamp::RenderingCompleteTime: 1153 case Timestamp::CompositionLatchTime: 1154 case Timestamp::FirstCompositionStartTime: 1155 case Timestamp::LastCompositionStartTime: 1156 case Timestamp::FirstCompositionGPUFinishedTime: 1157 case Timestamp::DisplayPresentTime: 1158 case Timestamp::DequeueReadyTime: 1159 case Timestamp::ReadsDoneTime: 1160 return true; 1161 1162 default: 1163 return false; 1164 } 1165 } 1166 1167 bool ValidateCompatibleSurface(const ValidationContext *val, 1168 const Display *display, 1169 const gl::Context *context, 1170 const Surface *surface) 1171 { 1172 const Config *contextConfig = context->getConfig(); 1173 const Config *surfaceConfig = surface->getConfig(); 1174 1175 if (context->getClientType() != EGL_OPENGL_API) 1176 { 1177 // Surface compatible with client API - only OPENGL_ES supported 1178 switch (context->getClientMajorVersion()) 1179 { 1180 case 1: 1181 if (!(surfaceConfig->renderableType & EGL_OPENGL_ES_BIT)) 1182 { 1183 val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL ES 1.x."); 1184 return false; 1185 } 1186 break; 1187 case 2: 1188 if (!(surfaceConfig->renderableType & EGL_OPENGL_ES2_BIT)) 1189 { 1190 val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL ES 2.x."); 1191 return false; 1192 } 1193 break; 1194 case 3: 1195 if (!(surfaceConfig->renderableType & (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT))) 1196 { 1197 val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL ES 3.x."); 1198 return false; 1199 } 1200 break; 1201 default: 1202 val->setError(EGL_BAD_MATCH, "Surface not compatible with Context API."); 1203 return false; 1204 } 1205 } 1206 else 1207 { 1208 if (!(surfaceConfig->renderableType & EGL_OPENGL_BIT)) 1209 { 1210 val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL Desktop."); 1211 return false; 1212 } 1213 } 1214 1215 // EGL KHR no config context 1216 if (context->getConfig() == EGL_NO_CONFIG_KHR) 1217 { 1218 const DisplayExtensions &displayExtensions = display->getExtensions(); 1219 if (displayExtensions.noConfigContext) 1220 { 1221 return true; 1222 } 1223 val->setError(EGL_BAD_MATCH, "Context with no config is not supported."); 1224 return false; 1225 } 1226 1227 // Config compatibility is defined in section 2.2 of the EGL 1.5 spec 1228 1229 bool colorBufferCompat = surfaceConfig->colorBufferType == contextConfig->colorBufferType; 1230 if (!colorBufferCompat) 1231 { 1232 val->setError(EGL_BAD_MATCH, "Color buffer types are not compatible."); 1233 return false; 1234 } 1235 1236 bool colorCompat = surfaceConfig->redSize == contextConfig->redSize && 1237 surfaceConfig->greenSize == contextConfig->greenSize && 1238 surfaceConfig->blueSize == contextConfig->blueSize && 1239 surfaceConfig->alphaSize == contextConfig->alphaSize && 1240 surfaceConfig->luminanceSize == contextConfig->luminanceSize; 1241 if (!colorCompat) 1242 { 1243 val->setError(EGL_BAD_MATCH, "Color buffer sizes are not compatible."); 1244 return false; 1245 } 1246 1247 bool componentTypeCompat = 1248 surfaceConfig->colorComponentType == contextConfig->colorComponentType; 1249 if (!componentTypeCompat) 1250 { 1251 val->setError(EGL_BAD_MATCH, "Color buffer component types are not compatible."); 1252 return false; 1253 } 1254 1255 bool dsCompat = surfaceConfig->depthSize == contextConfig->depthSize && 1256 surfaceConfig->stencilSize == contextConfig->stencilSize; 1257 if (!dsCompat) 1258 { 1259 val->setError(EGL_BAD_MATCH, "Depth-stencil buffer types are not compatible."); 1260 return false; 1261 } 1262 1263 bool surfaceTypeCompat = (surfaceConfig->surfaceType & contextConfig->surfaceType) != 0; 1264 if (!surfaceTypeCompat) 1265 { 1266 val->setError(EGL_BAD_MATCH, "Surface type is not compatible."); 1267 return false; 1268 } 1269 1270 return true; 1271 } 1272 1273 bool ValidateCreateSyncBase(const ValidationContext *val, 1274 const Display *display, 1275 EGLenum type, 1276 const AttributeMap &attribs, 1277 bool isExt) 1278 { 1279 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 1280 1281 attribs.initializeWithoutValidation(); 1282 1283 gl::Context *currentContext = val->eglThread->getContext(); 1284 egl::Display *currentDisplay = currentContext ? currentContext->getDisplay() : nullptr; 1285 1286 switch (type) 1287 { 1288 case EGL_SYNC_FENCE_KHR: 1289 if (!attribs.isEmpty()) 1290 { 1291 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); 1292 return false; 1293 } 1294 1295 if (!display->getExtensions().fenceSync) 1296 { 1297 val->setError(EGL_BAD_MATCH, "EGL_KHR_fence_sync extension is not available"); 1298 return false; 1299 } 1300 1301 if (display != currentDisplay) 1302 { 1303 val->setError(EGL_BAD_MATCH, 1304 "CreateSync can only be called on the current display"); 1305 return false; 1306 } 1307 1308 ANGLE_VALIDATION_TRY(ValidateContext(val, currentDisplay, currentContext)); 1309 1310 if (!currentContext->getExtensions().EGLSyncOES) 1311 { 1312 val->setError(EGL_BAD_MATCH, 1313 "EGL_SYNC_FENCE_KHR cannot be used without " 1314 "GL_OES_EGL_sync support."); 1315 return false; 1316 } 1317 break; 1318 1319 case EGL_SYNC_NATIVE_FENCE_ANDROID: 1320 if (!display->getExtensions().fenceSync) 1321 { 1322 val->setError(EGL_BAD_MATCH, "EGL_KHR_fence_sync extension is not available"); 1323 return false; 1324 } 1325 1326 if (!display->getExtensions().nativeFenceSyncANDROID) 1327 { 1328 val->setError(EGL_BAD_DISPLAY, 1329 "EGL_ANDROID_native_fence_sync extension is not available."); 1330 return false; 1331 } 1332 1333 if (display != currentDisplay) 1334 { 1335 val->setError(EGL_BAD_MATCH, 1336 "CreateSync can only be called on the current display"); 1337 return false; 1338 } 1339 1340 ANGLE_VALIDATION_TRY(ValidateContext(val, currentDisplay, currentContext)); 1341 1342 if (!currentContext->getExtensions().EGLSyncOES) 1343 { 1344 val->setError(EGL_BAD_MATCH, 1345 "EGL_SYNC_FENCE_KHR cannot be used without " 1346 "GL_OES_EGL_sync support."); 1347 return false; 1348 } 1349 1350 for (const auto &attributeIter : attribs) 1351 { 1352 EGLAttrib attribute = attributeIter.first; 1353 1354 switch (attribute) 1355 { 1356 case EGL_SYNC_NATIVE_FENCE_FD_ANDROID: 1357 break; 1358 1359 default: 1360 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); 1361 return false; 1362 } 1363 } 1364 break; 1365 1366 case EGL_SYNC_REUSABLE_KHR: 1367 if (!attribs.isEmpty()) 1368 { 1369 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); 1370 return false; 1371 } 1372 1373 if (!display->getExtensions().reusableSyncKHR) 1374 { 1375 val->setError(EGL_BAD_MATCH, "EGL_KHR_reusable_sync extension is not available."); 1376 return false; 1377 } 1378 break; 1379 1380 case EGL_SYNC_METAL_SHARED_EVENT_ANGLE: 1381 if (!display->getExtensions().fenceSync) 1382 { 1383 val->setError(EGL_BAD_MATCH, "EGL_KHR_fence_sync extension is not available"); 1384 return false; 1385 } 1386 1387 if (!display->getExtensions().mtlSyncSharedEventANGLE) 1388 { 1389 val->setError(EGL_BAD_DISPLAY, 1390 "EGL_ANGLE_metal_shared_event_sync is not available"); 1391 return false; 1392 } 1393 1394 if (display != currentDisplay) 1395 { 1396 val->setError(EGL_BAD_MATCH, 1397 "CreateSync can only be called on the current display"); 1398 return false; 1399 } 1400 1401 ANGLE_VALIDATION_TRY(ValidateContext(val, currentDisplay, currentContext)); 1402 1403 // This should be implied by exposing EGL_KHR_fence_sync 1404 ASSERT(currentContext->getExtensions().EGLSyncOES); 1405 1406 for (const auto &attributeIter : attribs) 1407 { 1408 EGLAttrib attribute = attributeIter.first; 1409 EGLAttrib value = attributeIter.second; 1410 1411 switch (attribute) 1412 { 1413 case EGL_SYNC_METAL_SHARED_EVENT_OBJECT_ANGLE: 1414 if (!value) 1415 { 1416 val->setError(EGL_BAD_ATTRIBUTE, 1417 "EGL_SYNC_METAL_SHARED_EVENT_ANGLE can't be NULL"); 1418 return false; 1419 } 1420 break; 1421 1422 case EGL_SYNC_METAL_SHARED_EVENT_SIGNAL_VALUE_LO_ANGLE: 1423 case EGL_SYNC_METAL_SHARED_EVENT_SIGNAL_VALUE_HI_ANGLE: 1424 break; 1425 1426 default: 1427 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); 1428 return false; 1429 } 1430 } 1431 break; 1432 1433 default: 1434 if (isExt) 1435 { 1436 val->setError(EGL_BAD_ATTRIBUTE, "Invalid type parameter"); 1437 return false; 1438 } 1439 else 1440 { 1441 val->setError(EGL_BAD_PARAMETER, "Invalid type parameter"); 1442 return false; 1443 } 1444 } 1445 1446 return true; 1447 } 1448 1449 bool ValidateGetSyncAttribBase(const ValidationContext *val, 1450 const Display *display, 1451 const Sync *sync, 1452 EGLint attribute) 1453 { 1454 ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); 1455 1456 switch (attribute) 1457 { 1458 case EGL_SYNC_CONDITION_KHR: 1459 switch (sync->getType()) 1460 { 1461 case EGL_SYNC_FENCE_KHR: 1462 case EGL_SYNC_NATIVE_FENCE_ANDROID: 1463 case EGL_SYNC_METAL_SHARED_EVENT_ANGLE: 1464 break; 1465 1466 default: 1467 val->setError(EGL_BAD_ATTRIBUTE, 1468 "EGL_SYNC_CONDITION_KHR is not valid for this sync type."); 1469 return false; 1470 } 1471 break; 1472 1473 // The following attributes are accepted by all types 1474 case EGL_SYNC_TYPE_KHR: 1475 case EGL_SYNC_STATUS_KHR: 1476 break; 1477 1478 default: 1479 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); 1480 return false; 1481 } 1482 1483 return true; 1484 } 1485 1486 bool ValidateQueryDisplayAttribBase(const ValidationContext *val, 1487 const Display *display, 1488 const EGLint attribute) 1489 { 1490 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 1491 1492 switch (attribute) 1493 { 1494 case EGL_DEVICE_EXT: 1495 if (!Display::GetClientExtensions().deviceQueryEXT) 1496 { 1497 val->setError(EGL_BAD_DISPLAY, "EGL_EXT_device_query extension is not available."); 1498 return false; 1499 } 1500 break; 1501 1502 case EGL_FEATURE_COUNT_ANGLE: 1503 if (!Display::GetClientExtensions().featureControlANGLE) 1504 { 1505 val->setError(EGL_BAD_DISPLAY, 1506 "EGL_ANGLE_feature_control extension is not available."); 1507 return false; 1508 } 1509 break; 1510 1511 default: 1512 val->setError(EGL_BAD_ATTRIBUTE, "attribute is not valid."); 1513 return false; 1514 } 1515 1516 return true; 1517 } 1518 1519 bool ValidateCreateContextAttribute(const ValidationContext *val, 1520 const Display *display, 1521 EGLAttrib attribute) 1522 { 1523 switch (attribute) 1524 { 1525 case EGL_CONTEXT_CLIENT_VERSION: 1526 case EGL_CONTEXT_MINOR_VERSION: 1527 case EGL_CONTEXT_FLAGS_KHR: 1528 case EGL_CONTEXT_OPENGL_DEBUG: 1529 break; 1530 1531 case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR: 1532 if (val->eglThread->getAPI() != EGL_OPENGL_API) 1533 { 1534 // Only valid for OpenGL (non-ES) contexts 1535 val->setError(EGL_BAD_ATTRIBUTE, "OpenGL profile mask requires an OpenGL context."); 1536 return false; 1537 } 1538 break; 1539 1540 case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: 1541 if (!display->getExtensions().createContextRobustness) 1542 { 1543 val->setError(EGL_BAD_ATTRIBUTE); 1544 return false; 1545 } 1546 break; 1547 1548 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: 1549 if (!display->getExtensions().createContextRobustness) 1550 { 1551 val->setError(EGL_BAD_ATTRIBUTE); 1552 return false; 1553 } 1554 break; 1555 1556 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY: 1557 { 1558 // We either need to have - 1559 // 1. EGL 1.5 which added support for this as part of core spec 1560 // 2. EGL_KHR_create_context extension which requires EGL 1.4 1561 constexpr EGLint kRequiredMajorVersion = 1; 1562 constexpr EGLint kRequiredMinorVersion = 5; 1563 if ((kEglMajorVersion < kRequiredMajorVersion || 1564 kEglMinorVersion < kRequiredMinorVersion) && 1565 !display->getExtensions().createContext) 1566 { 1567 val->setError(EGL_BAD_ATTRIBUTE); 1568 return false; 1569 } 1570 break; 1571 } 1572 1573 case EGL_CONTEXT_OPENGL_NO_ERROR_KHR: 1574 if (!display->getExtensions().createContextNoError) 1575 { 1576 val->setError(EGL_BAD_ATTRIBUTE, "Invalid Context attribute."); 1577 return false; 1578 } 1579 break; 1580 1581 case EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE: 1582 if (!display->getExtensions().createContextWebGLCompatibility) 1583 { 1584 val->setError(EGL_BAD_ATTRIBUTE, 1585 "Attribute " 1586 "EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE requires " 1587 "EGL_ANGLE_create_context_webgl_compatibility."); 1588 return false; 1589 } 1590 break; 1591 1592 case EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM: 1593 if (!display->getExtensions().createContextBindGeneratesResource) 1594 { 1595 val->setError(EGL_BAD_ATTRIBUTE, 1596 "Attribute EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM requires " 1597 "EGL_CHROMIUM_create_context_bind_generates_resource."); 1598 return false; 1599 } 1600 break; 1601 1602 case EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE: 1603 if (!display->getExtensions().displayTextureShareGroup) 1604 { 1605 val->setError(EGL_BAD_ATTRIBUTE, 1606 "Attribute " 1607 "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE requires " 1608 "EGL_ANGLE_display_texture_share_group."); 1609 return false; 1610 } 1611 break; 1612 1613 case EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE: 1614 if (!display->getExtensions().displayTextureShareGroup) 1615 { 1616 val->setError(EGL_BAD_ATTRIBUTE, 1617 "Attribute " 1618 "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE requires " 1619 "EGL_ANGLE_display_semaphore_share_group."); 1620 return false; 1621 } 1622 break; 1623 1624 case EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE: 1625 if (!display->getExtensions().createContextClientArrays) 1626 { 1627 val->setError(EGL_BAD_ATTRIBUTE, 1628 "Attribute EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE requires " 1629 "EGL_ANGLE_create_context_client_arrays."); 1630 return false; 1631 } 1632 break; 1633 1634 case EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE: 1635 if (!display->getExtensions().programCacheControlANGLE) 1636 { 1637 val->setError(EGL_BAD_ATTRIBUTE, 1638 "Attribute EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE " 1639 "requires EGL_ANGLE_program_cache_control."); 1640 return false; 1641 } 1642 break; 1643 1644 case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: 1645 if (!display->getExtensions().robustResourceInitializationANGLE) 1646 { 1647 val->setError(EGL_BAD_ATTRIBUTE, 1648 "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE " 1649 "requires EGL_ANGLE_robust_resource_initialization."); 1650 return false; 1651 } 1652 break; 1653 1654 case EGL_EXTENSIONS_ENABLED_ANGLE: 1655 if (!display->getExtensions().createContextExtensionsEnabled) 1656 { 1657 val->setError(EGL_BAD_ATTRIBUTE, 1658 "Attribute EGL_EXTENSIONS_ENABLED_ANGLE " 1659 "requires EGL_ANGLE_create_context_extensions_enabled."); 1660 return false; 1661 } 1662 break; 1663 1664 case EGL_POWER_PREFERENCE_ANGLE: 1665 if (!display->getExtensions().powerPreference) 1666 { 1667 val->setError(EGL_BAD_ATTRIBUTE, 1668 "Attribute EGL_POWER_PREFERENCE_ANGLE " 1669 "requires EGL_ANGLE_power_preference."); 1670 return false; 1671 } 1672 break; 1673 1674 case EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE: 1675 if (!display->getExtensions().createContextBackwardsCompatible) 1676 { 1677 val->setError(EGL_BAD_ATTRIBUTE, 1678 "Attribute EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE " 1679 "requires EGL_ANGLE_create_context_backwards_compatible."); 1680 return false; 1681 } 1682 break; 1683 1684 case EGL_CONTEXT_PRIORITY_LEVEL_IMG: 1685 if (!display->getExtensions().contextPriority) 1686 { 1687 val->setError(EGL_BAD_ATTRIBUTE, 1688 "Attribute EGL_CONTEXT_PRIORITY_LEVEL_IMG requires " 1689 "extension EGL_IMG_context_priority."); 1690 return false; 1691 } 1692 break; 1693 1694 case EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV: 1695 if (!display->getExtensions().robustnessVideoMemoryPurgeNV) 1696 { 1697 val->setError(EGL_BAD_ATTRIBUTE, 1698 "Attribute EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV requires " 1699 "extension EGL_NV_robustness_video_memory_purge."); 1700 return false; 1701 } 1702 break; 1703 1704 case EGL_EXTERNAL_CONTEXT_ANGLE: 1705 if (!display->getExtensions().externalContextAndSurface) 1706 { 1707 val->setError(EGL_BAD_ATTRIBUTE, 1708 "Attribute " 1709 "EGL_EXTERNAL_CONTEXT_ANGLE requires " 1710 "EGL_ANGLE_external_context_and_surface."); 1711 return false; 1712 } 1713 break; 1714 case EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE: 1715 if (!display->getExtensions().externalContextAndSurface) 1716 { 1717 val->setError(EGL_BAD_ATTRIBUTE, 1718 "Attribute " 1719 "EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE requires " 1720 "EGL_ANGLE_external_context_and_surface."); 1721 return false; 1722 } 1723 break; 1724 1725 case EGL_PROTECTED_CONTENT_EXT: 1726 if (!display->getExtensions().protectedContentEXT) 1727 { 1728 val->setError(EGL_BAD_ATTRIBUTE, 1729 "Attribute EGL_PROTECTED_CONTEXT_EXT requires " 1730 "extension EGL_EXT_protected_content."); 1731 return false; 1732 } 1733 break; 1734 1735 case EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE: 1736 if (!display->getExtensions().contextVirtualizationANGLE) 1737 { 1738 val->setError(EGL_BAD_ATTRIBUTE, 1739 "Attribute EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE requires " 1740 "extension EGL_ANGLE_context_virtualization."); 1741 return false; 1742 } 1743 break; 1744 1745 case EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE: 1746 if (!display->getExtensions().metalCreateContextOwnershipIdentityANGLE) 1747 { 1748 val->setError(EGL_BAD_ATTRIBUTE, 1749 "Attribute EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE requires " 1750 "EGL_ANGLE_metal_create_context_ownership_identity."); 1751 } 1752 break; 1753 1754 default: 1755 val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04" PRIxPTR "X", attribute); 1756 return false; 1757 } 1758 1759 return true; 1760 } 1761 1762 bool ValidateCreateContextAttributeValue(const ValidationContext *val, 1763 const Display *display, 1764 const gl::Context *shareContext, 1765 EGLAttrib attribute, 1766 EGLAttrib value) 1767 { 1768 switch (attribute) 1769 { 1770 case EGL_CONTEXT_CLIENT_VERSION: 1771 case EGL_CONTEXT_MINOR_VERSION: 1772 case EGL_CONTEXT_OPENGL_DEBUG: 1773 case EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE: 1774 break; 1775 1776 case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR: 1777 { 1778 constexpr EGLint kValidProfileMaskFlags = 1779 (EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT | 1780 EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT); 1781 if ((value & ~kValidProfileMaskFlags) != 0) 1782 { 1783 val->setError(EGL_BAD_ATTRIBUTE, "Invalid OpenGL profile mask."); 1784 return false; 1785 } 1786 break; 1787 } 1788 1789 case EGL_CONTEXT_FLAGS_KHR: 1790 { 1791 // Note: EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR does not apply to ES 1792 constexpr EGLint kValidContextFlags = 1793 (EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR); 1794 if ((value & ~kValidContextFlags) != 0) 1795 { 1796 val->setError(EGL_BAD_ATTRIBUTE); 1797 return false; 1798 } 1799 break; 1800 } 1801 1802 case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: 1803 if (value != EGL_TRUE && value != EGL_FALSE) 1804 { 1805 val->setError(EGL_BAD_ATTRIBUTE); 1806 return false; 1807 } 1808 break; 1809 1810 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: 1811 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY: 1812 if (value != EGL_LOSE_CONTEXT_ON_RESET_EXT && value != EGL_NO_RESET_NOTIFICATION_EXT) 1813 { 1814 val->setError(EGL_BAD_ATTRIBUTE); 1815 return false; 1816 } 1817 1818 if (shareContext && shareContext->isResetNotificationEnabled() != 1819 (value == EGL_LOSE_CONTEXT_ON_RESET_EXT)) 1820 { 1821 val->setError(EGL_BAD_MATCH); 1822 return false; 1823 } 1824 break; 1825 1826 case EGL_CONTEXT_OPENGL_NO_ERROR_KHR: 1827 if (value != EGL_TRUE && value != EGL_FALSE) 1828 { 1829 val->setError(EGL_BAD_ATTRIBUTE, "Attribute must be EGL_TRUE or EGL_FALSE."); 1830 return false; 1831 } 1832 break; 1833 1834 case EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE: 1835 if (value != EGL_TRUE && value != EGL_FALSE) 1836 { 1837 val->setError(EGL_BAD_ATTRIBUTE, 1838 "EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE must be " 1839 "EGL_TRUE or EGL_FALSE."); 1840 return false; 1841 } 1842 break; 1843 1844 case EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM: 1845 if (value != EGL_TRUE && value != EGL_FALSE) 1846 { 1847 val->setError(EGL_BAD_ATTRIBUTE, 1848 "EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM " 1849 "must be EGL_TRUE or EGL_FALSE."); 1850 return false; 1851 } 1852 break; 1853 1854 case EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE: 1855 if (value != EGL_TRUE && value != EGL_FALSE) 1856 { 1857 val->setError(EGL_BAD_ATTRIBUTE, 1858 "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE must be " 1859 "EGL_TRUE or EGL_FALSE."); 1860 return false; 1861 } 1862 if (shareContext && 1863 shareContext->usingDisplayTextureShareGroup() != (value == EGL_TRUE)) 1864 { 1865 val->setError(EGL_BAD_ATTRIBUTE, 1866 "All contexts within a share group must be " 1867 "created with the same value of " 1868 "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE."); 1869 return false; 1870 } 1871 break; 1872 1873 case EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE: 1874 if (value != EGL_TRUE && value != EGL_FALSE) 1875 { 1876 val->setError(EGL_BAD_ATTRIBUTE, 1877 "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE must be " 1878 "EGL_TRUE or EGL_FALSE."); 1879 return false; 1880 } 1881 if (shareContext && 1882 shareContext->usingDisplaySemaphoreShareGroup() != (value == EGL_TRUE)) 1883 { 1884 val->setError(EGL_BAD_ATTRIBUTE, 1885 "All contexts within a share group must be " 1886 "created with the same value of " 1887 "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE."); 1888 return false; 1889 } 1890 break; 1891 1892 case EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE: 1893 if (value != EGL_TRUE && value != EGL_FALSE) 1894 { 1895 val->setError(EGL_BAD_ATTRIBUTE, 1896 "EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE must " 1897 "be EGL_TRUE or EGL_FALSE."); 1898 return false; 1899 } 1900 break; 1901 1902 case EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE: 1903 if (value != EGL_TRUE && value != EGL_FALSE) 1904 { 1905 val->setError(EGL_BAD_ATTRIBUTE, 1906 "EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE must " 1907 "be EGL_TRUE or EGL_FALSE."); 1908 return false; 1909 } 1910 break; 1911 1912 case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: 1913 if (value != EGL_TRUE && value != EGL_FALSE) 1914 { 1915 val->setError(EGL_BAD_ATTRIBUTE, 1916 "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be " 1917 "either EGL_TRUE or EGL_FALSE."); 1918 return false; 1919 } 1920 break; 1921 1922 case EGL_EXTENSIONS_ENABLED_ANGLE: 1923 if (value != EGL_TRUE && value != EGL_FALSE) 1924 { 1925 val->setError(EGL_BAD_ATTRIBUTE, 1926 "EGL_EXTENSIONS_ENABLED_ANGLE must be " 1927 "either EGL_TRUE or EGL_FALSE."); 1928 return false; 1929 } 1930 break; 1931 1932 case EGL_POWER_PREFERENCE_ANGLE: 1933 if (value != EGL_LOW_POWER_ANGLE && value != EGL_HIGH_POWER_ANGLE) 1934 { 1935 val->setError(EGL_BAD_ATTRIBUTE, 1936 "EGL_POWER_PREFERENCE_ANGLE must be " 1937 "either EGL_LOW_POWER_ANGLE or EGL_HIGH_POWER_ANGLE."); 1938 return false; 1939 } 1940 break; 1941 1942 case EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE: 1943 if (value != EGL_TRUE && value != EGL_FALSE) 1944 { 1945 val->setError(EGL_BAD_ATTRIBUTE, 1946 "EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE must be " 1947 "either EGL_TRUE or EGL_FALSE."); 1948 return false; 1949 } 1950 break; 1951 1952 case EGL_CONTEXT_PRIORITY_LEVEL_IMG: 1953 switch (value) 1954 { 1955 case EGL_CONTEXT_PRIORITY_LOW_IMG: 1956 case EGL_CONTEXT_PRIORITY_MEDIUM_IMG: 1957 case EGL_CONTEXT_PRIORITY_HIGH_IMG: 1958 break; 1959 default: 1960 val->setError(EGL_BAD_ATTRIBUTE, 1961 "Attribute EGL_CONTEXT_PRIORITY_LEVEL_IMG " 1962 "must be one of: EGL_CONTEXT_PRIORITY_LOW_IMG, " 1963 "EGL_CONTEXT_PRIORITY_MEDIUM_IMG, or " 1964 "EGL_CONTEXT_PRIORITY_HIGH_IMG."); 1965 return false; 1966 } 1967 break; 1968 1969 case EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV: 1970 if (value != EGL_TRUE && value != EGL_FALSE) 1971 { 1972 val->setError(EGL_BAD_ATTRIBUTE, 1973 "EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV must " 1974 "be either EGL_TRUE or EGL_FALSE."); 1975 return false; 1976 } 1977 break; 1978 1979 case EGL_EXTERNAL_CONTEXT_ANGLE: 1980 if (value != EGL_TRUE && value != EGL_FALSE) 1981 { 1982 val->setError(EGL_BAD_ATTRIBUTE, 1983 "EGL_EXTERNAL_CONTEXT_ANGLE must " 1984 "be either EGL_TRUE or EGL_FALSE."); 1985 return false; 1986 } 1987 if (shareContext && (value == EGL_TRUE)) 1988 { 1989 val->setError( 1990 EGL_BAD_ATTRIBUTE, 1991 "EGL_EXTERNAL_CONTEXT_ANGLE doesn't allow creating with sharedContext."); 1992 return false; 1993 } 1994 break; 1995 case EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE: 1996 if (value != EGL_TRUE && value != EGL_FALSE) 1997 { 1998 val->setError(EGL_BAD_ATTRIBUTE, 1999 "EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE must " 2000 "be either EGL_TRUE or EGL_FALSE."); 2001 return false; 2002 } 2003 break; 2004 2005 case EGL_PROTECTED_CONTENT_EXT: 2006 if (value != EGL_TRUE && value != EGL_FALSE) 2007 { 2008 val->setError(EGL_BAD_ATTRIBUTE, 2009 "EGL_PROTECTED_CONTENT_EXT must " 2010 "be either EGL_TRUE or EGL_FALSE."); 2011 return false; 2012 } 2013 break; 2014 2015 case EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE: 2016 if (value == 0) 2017 { 2018 val->setError(EGL_BAD_ATTRIBUTE, 2019 "EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE must" 2020 "be non-zero."); 2021 return false; 2022 } 2023 break; 2024 2025 default: 2026 UNREACHABLE(); 2027 return false; 2028 } 2029 2030 return true; 2031 } 2032 2033 bool ValidateCreatePbufferSurfaceAttribute(const ValidationContext *val, 2034 const Display *display, 2035 EGLAttrib attribute) 2036 { 2037 const DisplayExtensions &displayExtensions = display->getExtensions(); 2038 2039 switch (attribute) 2040 { 2041 case EGL_WIDTH: 2042 case EGL_HEIGHT: 2043 case EGL_LARGEST_PBUFFER: 2044 case EGL_TEXTURE_FORMAT: 2045 case EGL_TEXTURE_TARGET: 2046 case EGL_MIPMAP_TEXTURE: 2047 case EGL_VG_COLORSPACE: 2048 case EGL_GL_COLORSPACE: 2049 case EGL_VG_ALPHA_FORMAT: 2050 break; 2051 2052 case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: 2053 if (!displayExtensions.robustResourceInitializationANGLE) 2054 { 2055 val->setError(EGL_BAD_ATTRIBUTE, 2056 "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE " 2057 "requires EGL_ANGLE_robust_resource_initialization."); 2058 return false; 2059 } 2060 break; 2061 2062 case EGL_PROTECTED_CONTENT_EXT: 2063 if (!displayExtensions.protectedContentEXT) 2064 { 2065 val->setError(EGL_BAD_ATTRIBUTE, 2066 "Attribute EGL_PROTECTED_CONTEXT_EXT requires " 2067 "extension EGL_EXT_protected_content."); 2068 return false; 2069 } 2070 break; 2071 2072 default: 2073 val->setError(EGL_BAD_ATTRIBUTE); 2074 return false; 2075 } 2076 2077 return true; 2078 } 2079 2080 bool ValidateCreatePbufferSurfaceAttributeValue(const ValidationContext *val, 2081 const Display *display, 2082 EGLAttrib attribute, 2083 EGLAttrib value) 2084 { 2085 const DisplayExtensions &displayExtensions = display->getExtensions(); 2086 2087 switch (attribute) 2088 { 2089 case EGL_WIDTH: 2090 case EGL_HEIGHT: 2091 if (value < 0) 2092 { 2093 val->setError(EGL_BAD_PARAMETER); 2094 return false; 2095 } 2096 break; 2097 2098 case EGL_LARGEST_PBUFFER: 2099 break; 2100 2101 case EGL_TEXTURE_FORMAT: 2102 switch (value) 2103 { 2104 case EGL_NO_TEXTURE: 2105 case EGL_TEXTURE_RGB: 2106 case EGL_TEXTURE_RGBA: 2107 break; 2108 default: 2109 val->setError(EGL_BAD_ATTRIBUTE); 2110 return false; 2111 } 2112 break; 2113 2114 case EGL_TEXTURE_TARGET: 2115 switch (value) 2116 { 2117 case EGL_NO_TEXTURE: 2118 case EGL_TEXTURE_2D: 2119 break; 2120 default: 2121 val->setError(EGL_BAD_ATTRIBUTE); 2122 return false; 2123 } 2124 break; 2125 2126 case EGL_MIPMAP_TEXTURE: 2127 break; 2128 2129 case EGL_VG_COLORSPACE: 2130 break; 2131 2132 case EGL_GL_COLORSPACE: 2133 ANGLE_VALIDATION_TRY(ValidateColorspaceAttribute(val, displayExtensions, value)); 2134 break; 2135 2136 case EGL_VG_ALPHA_FORMAT: 2137 break; 2138 2139 case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: 2140 ASSERT(displayExtensions.robustResourceInitializationANGLE); 2141 if (value != EGL_TRUE && value != EGL_FALSE) 2142 { 2143 val->setError(EGL_BAD_ATTRIBUTE, 2144 "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be " 2145 "either EGL_TRUE or EGL_FALSE."); 2146 return false; 2147 } 2148 break; 2149 2150 case EGL_PROTECTED_CONTENT_EXT: 2151 ASSERT(displayExtensions.protectedContentEXT); 2152 if (value != EGL_TRUE && value != EGL_FALSE) 2153 { 2154 val->setError(EGL_BAD_ATTRIBUTE, 2155 "EGL_PROTECTED_CONTENT_EXT must " 2156 "be either EGL_TRUE or EGL_FALSE."); 2157 return false; 2158 } 2159 break; 2160 2161 default: 2162 UNREACHABLE(); 2163 return false; 2164 } 2165 2166 return true; 2167 } 2168 } // anonymous namespace 2169 2170 void ValidationContext::setError(EGLint error) const 2171 { 2172 eglThread->setError(error, entryPoint, labeledObject, nullptr); 2173 } 2174 2175 void ValidationContext::setError(EGLint error, const char *message...) const 2176 { 2177 ASSERT(message); 2178 2179 constexpr uint32_t kBufferSize = 1000; 2180 char buffer[kBufferSize]; 2181 2182 va_list args; 2183 va_start(args, message); 2184 vsnprintf(buffer, kBufferSize, message, args); 2185 2186 eglThread->setError(error, entryPoint, labeledObject, buffer); 2187 } 2188 2189 bool ValidateDisplay(const ValidationContext *val, const Display *display) 2190 { 2191 ANGLE_VALIDATION_TRY(ValidateDisplayPointer(val, display)); 2192 2193 if (!display->isInitialized()) 2194 { 2195 if (val) 2196 { 2197 val->setError(EGL_NOT_INITIALIZED, "display is not initialized."); 2198 } 2199 return false; 2200 } 2201 2202 if (display->isDeviceLost()) 2203 { 2204 if (val) 2205 { 2206 val->setError(EGL_CONTEXT_LOST, "display had a context loss"); 2207 } 2208 return false; 2209 } 2210 2211 return true; 2212 } 2213 2214 bool ValidateSurface(const ValidationContext *val, const Display *display, const Surface *surface) 2215 { 2216 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 2217 2218 if (!display->isValidSurface(surface)) 2219 { 2220 if (val) 2221 { 2222 val->setError(EGL_BAD_SURFACE); 2223 } 2224 return false; 2225 } 2226 2227 return true; 2228 } 2229 2230 bool ValidateConfig(const ValidationContext *val, const Display *display, const Config *config) 2231 { 2232 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 2233 2234 if (!display->isValidConfig(config)) 2235 { 2236 if (val) 2237 { 2238 val->setError(EGL_BAD_CONFIG); 2239 } 2240 return false; 2241 } 2242 2243 return true; 2244 } 2245 2246 bool ValidateContext(const ValidationContext *val, 2247 const Display *display, 2248 const gl::Context *context) 2249 { 2250 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 2251 2252 if (!display->isValidContext(context)) 2253 { 2254 if (val) 2255 { 2256 val->setError(EGL_BAD_CONTEXT); 2257 } 2258 return false; 2259 } 2260 2261 return true; 2262 } 2263 2264 bool ValidateImage(const ValidationContext *val, const Display *display, const Image *image) 2265 { 2266 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 2267 2268 if (!display->isValidImage(image)) 2269 { 2270 if (val) 2271 { 2272 val->setError(EGL_BAD_PARAMETER, "image is not valid."); 2273 } 2274 return false; 2275 } 2276 2277 return true; 2278 } 2279 2280 bool ValidateDevice(const ValidationContext *val, const Device *device) 2281 { 2282 if (device == EGL_NO_DEVICE_EXT) 2283 { 2284 if (val) 2285 { 2286 val->setError(EGL_BAD_ACCESS, "device is EGL_NO_DEVICE."); 2287 } 2288 return false; 2289 } 2290 2291 if (!Device::IsValidDevice(device)) 2292 { 2293 if (val) 2294 { 2295 val->setError(EGL_BAD_ACCESS, "device is not valid."); 2296 } 2297 return false; 2298 } 2299 2300 return true; 2301 } 2302 2303 bool ValidateSync(const ValidationContext *val, const Display *display, const Sync *sync) 2304 { 2305 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 2306 2307 if (!display->isValidSync(sync)) 2308 { 2309 if (val) 2310 { 2311 val->setError(EGL_BAD_PARAMETER, "sync object is not valid."); 2312 } 2313 return false; 2314 } 2315 2316 return true; 2317 } 2318 2319 const Thread *GetThreadIfValid(const Thread *thread) 2320 { 2321 // Threads should always be valid 2322 return thread; 2323 } 2324 2325 const Display *GetDisplayIfValid(const Display *display) 2326 { 2327 return ValidateDisplay(nullptr, display) ? display : nullptr; 2328 } 2329 2330 const Surface *GetSurfaceIfValid(const Display *display, const Surface *surface) 2331 { 2332 return ValidateSurface(nullptr, display, surface) ? surface : nullptr; 2333 } 2334 2335 const Image *GetImageIfValid(const Display *display, const Image *image) 2336 { 2337 return ValidateImage(nullptr, display, image) ? image : nullptr; 2338 } 2339 2340 const Stream *GetStreamIfValid(const Display *display, const Stream *stream) 2341 { 2342 return ValidateStream(nullptr, display, stream) ? stream : nullptr; 2343 } 2344 2345 const gl::Context *GetContextIfValid(const Display *display, const gl::Context *context) 2346 { 2347 return ValidateContext(nullptr, display, context) ? context : nullptr; 2348 } 2349 2350 const Device *GetDeviceIfValid(const Device *device) 2351 { 2352 return ValidateDevice(nullptr, device) ? device : nullptr; 2353 } 2354 2355 const Sync *GetSyncIfValid(const Display *display, const Sync *sync) 2356 { 2357 return ValidateSync(nullptr, display, sync) ? sync : nullptr; 2358 } 2359 2360 LabeledObject *GetLabeledObjectIfValid(Thread *thread, 2361 const Display *display, 2362 ObjectType objectType, 2363 EGLObjectKHR object) 2364 { 2365 if (objectType == ObjectType::Thread) 2366 { 2367 return thread; 2368 } 2369 2370 LabeledObject *labeledObject = nullptr; 2371 if (ValidateLabeledObject(nullptr, display, objectType, object, &labeledObject)) 2372 { 2373 return labeledObject; 2374 } 2375 2376 return nullptr; 2377 } 2378 2379 bool ValidateInitialize(const ValidationContext *val, 2380 const Display *display, 2381 const EGLint *major, 2382 const EGLint *minor) 2383 { 2384 return ValidateDisplayPointer(val, display); 2385 } 2386 2387 bool ValidateTerminate(const ValidationContext *val, const Display *display) 2388 { 2389 return ValidateDisplayPointer(val, display); 2390 } 2391 2392 bool ValidateCreateContext(const ValidationContext *val, 2393 const Display *display, 2394 const Config *configuration, 2395 const gl::Context *shareContext, 2396 const AttributeMap &attributes) 2397 { 2398 if (configuration) 2399 { 2400 ANGLE_VALIDATION_TRY(ValidateConfig(val, display, configuration)); 2401 } 2402 else 2403 { 2404 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 2405 const DisplayExtensions &displayExtensions = display->getExtensions(); 2406 if (!displayExtensions.noConfigContext) 2407 { 2408 val->setError(EGL_BAD_CONFIG); 2409 return false; 2410 } 2411 } 2412 2413 ANGLE_VALIDATION_TRY(attributes.validate(val, display, ValidateCreateContextAttribute)); 2414 2415 for (const auto &attributePair : attributes) 2416 { 2417 EGLAttrib attribute = attributePair.first; 2418 EGLAttrib value = attributePair.second; 2419 ANGLE_VALIDATION_TRY( 2420 ValidateCreateContextAttributeValue(val, display, shareContext, attribute, value)); 2421 } 2422 2423 // Get the requested client version (default is 1) and check it is 2 or 3. 2424 EGLAttrib clientMajorVersion = attributes.get(EGL_CONTEXT_CLIENT_VERSION, 1); 2425 EGLAttrib clientMinorVersion = attributes.get(EGL_CONTEXT_MINOR_VERSION, 0); 2426 EGLenum api = val->eglThread->getAPI(); 2427 2428 switch (api) 2429 { 2430 case EGL_OPENGL_ES_API: 2431 switch (clientMajorVersion) 2432 { 2433 case 1: 2434 if (clientMinorVersion != 0 && clientMinorVersion != 1) 2435 { 2436 val->setError(EGL_BAD_ATTRIBUTE); 2437 return false; 2438 } 2439 if (configuration == EGL_NO_CONFIG_KHR) 2440 { 2441 val->setError(EGL_BAD_MATCH); 2442 return false; 2443 } 2444 if ((configuration != EGL_NO_CONFIG_KHR) && 2445 !(configuration->renderableType & EGL_OPENGL_ES_BIT)) 2446 { 2447 val->setError(EGL_BAD_MATCH); 2448 return false; 2449 } 2450 break; 2451 2452 case 2: 2453 if (clientMinorVersion != 0) 2454 { 2455 val->setError(EGL_BAD_ATTRIBUTE); 2456 return false; 2457 } 2458 if ((configuration != EGL_NO_CONFIG_KHR) && 2459 !(configuration->renderableType & EGL_OPENGL_ES2_BIT)) 2460 { 2461 val->setError(EGL_BAD_MATCH); 2462 return false; 2463 } 2464 break; 2465 case 3: 2466 if (clientMinorVersion < 0 || clientMinorVersion > 2) 2467 { 2468 val->setError(EGL_BAD_ATTRIBUTE); 2469 return false; 2470 } 2471 if ((configuration != EGL_NO_CONFIG_KHR) && 2472 !(configuration->renderableType & EGL_OPENGL_ES3_BIT)) 2473 { 2474 val->setError(EGL_BAD_MATCH); 2475 return false; 2476 } 2477 if (display->getMaxSupportedESVersion() < 2478 gl::Version(static_cast<GLuint>(clientMajorVersion), 2479 static_cast<GLuint>(clientMinorVersion))) 2480 { 2481 gl::Version max = display->getMaxSupportedESVersion(); 2482 val->setError(EGL_BAD_ATTRIBUTE, 2483 "Requested GLES version (%" PRIxPTR ".%" PRIxPTR 2484 ") is greater than " 2485 "max supported (%d, %d).", 2486 clientMajorVersion, clientMinorVersion, max.major, max.minor); 2487 return false; 2488 } 2489 if ((attributes.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == 2490 EGL_TRUE) && 2491 (clientMinorVersion > 1)) 2492 { 2493 val->setError(EGL_BAD_ATTRIBUTE, 2494 "Requested GLES version (%" PRIxPTR ".%" PRIxPTR 2495 ") is greater than " 2496 "max supported 3.1 for WebGL.", 2497 clientMajorVersion, clientMinorVersion); 2498 return false; 2499 } 2500 break; 2501 default: 2502 val->setError(EGL_BAD_ATTRIBUTE); 2503 return false; 2504 } 2505 break; 2506 2507 case EGL_OPENGL_API: 2508 // The requested configuration must use EGL_OPENGL_BIT if EGL_OPENGL_BIT is the 2509 // currently bound API. 2510 if ((configuration != EGL_NO_CONFIG_KHR) && 2511 !(configuration->renderableType & EGL_OPENGL_BIT)) 2512 { 2513 val->setError(EGL_BAD_CONFIG); 2514 return false; 2515 } 2516 // TODO(http://anglebug.com/7533): validate desktop OpenGL versions and profile mask 2517 break; 2518 2519 default: 2520 val->setError(EGL_BAD_MATCH, "Unsupported API."); 2521 return false; 2522 } 2523 2524 if (shareContext) 2525 { 2526 // Shared context is invalid or is owned by another display 2527 if (!display->isValidContext(shareContext)) 2528 { 2529 val->setError(EGL_BAD_MATCH); 2530 return false; 2531 } 2532 } 2533 2534 return true; 2535 } 2536 2537 bool ValidateCreateWindowSurface(const ValidationContext *val, 2538 const Display *display, 2539 const Config *config, 2540 EGLNativeWindowType window, 2541 const AttributeMap &attributes) 2542 { 2543 ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config)); 2544 2545 if (!display->isValidNativeWindow(window)) 2546 { 2547 val->setError(EGL_BAD_NATIVE_WINDOW); 2548 return false; 2549 } 2550 2551 const DisplayExtensions &displayExtensions = display->getExtensions(); 2552 2553 attributes.initializeWithoutValidation(); 2554 2555 for (const auto &attributeIter : attributes) 2556 { 2557 EGLAttrib attribute = attributeIter.first; 2558 EGLAttrib value = attributeIter.second; 2559 2560 switch (attribute) 2561 { 2562 case EGL_RENDER_BUFFER: 2563 switch (value) 2564 { 2565 case EGL_BACK_BUFFER: 2566 break; 2567 case EGL_SINGLE_BUFFER: 2568 break; 2569 default: 2570 val->setError(EGL_BAD_ATTRIBUTE); 2571 return false; 2572 } 2573 break; 2574 2575 case EGL_POST_SUB_BUFFER_SUPPORTED_NV: 2576 if (!displayExtensions.postSubBuffer) 2577 { 2578 val->setError(EGL_BAD_ATTRIBUTE); 2579 return false; 2580 } 2581 break; 2582 2583 case EGL_WIDTH: 2584 case EGL_HEIGHT: 2585 if (!displayExtensions.windowFixedSize) 2586 { 2587 val->setError(EGL_BAD_ATTRIBUTE); 2588 return false; 2589 } 2590 if (value < 0) 2591 { 2592 val->setError(EGL_BAD_PARAMETER); 2593 return false; 2594 } 2595 break; 2596 2597 case EGL_FIXED_SIZE_ANGLE: 2598 if (!displayExtensions.windowFixedSize) 2599 { 2600 val->setError(EGL_BAD_ATTRIBUTE); 2601 return false; 2602 } 2603 break; 2604 2605 case EGL_SURFACE_ORIENTATION_ANGLE: 2606 if (!displayExtensions.surfaceOrientation) 2607 { 2608 val->setError(EGL_BAD_ATTRIBUTE, 2609 "EGL_ANGLE_surface_orientation is not enabled."); 2610 return false; 2611 } 2612 break; 2613 2614 case EGL_VG_COLORSPACE: 2615 if (value != EGL_VG_COLORSPACE_sRGB) 2616 { 2617 val->setError(EGL_BAD_MATCH); 2618 return false; 2619 } 2620 break; 2621 2622 case EGL_GL_COLORSPACE: 2623 ANGLE_VALIDATION_TRY(ValidateColorspaceAttribute(val, displayExtensions, value)); 2624 break; 2625 2626 case EGL_VG_ALPHA_FORMAT: 2627 val->setError(EGL_BAD_MATCH); 2628 return false; 2629 2630 case EGL_DIRECT_COMPOSITION_ANGLE: 2631 if (!displayExtensions.directComposition) 2632 { 2633 val->setError(EGL_BAD_ATTRIBUTE); 2634 return false; 2635 } 2636 break; 2637 2638 case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: 2639 if (!display->getExtensions().robustResourceInitializationANGLE) 2640 { 2641 val->setError(EGL_BAD_ATTRIBUTE, 2642 "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE " 2643 "requires EGL_ANGLE_robust_resource_initialization."); 2644 return false; 2645 } 2646 if (value != EGL_TRUE && value != EGL_FALSE) 2647 { 2648 val->setError(EGL_BAD_ATTRIBUTE, 2649 "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be " 2650 "either EGL_TRUE or EGL_FALSE."); 2651 return false; 2652 } 2653 break; 2654 2655 case EGL_GGP_STREAM_DESCRIPTOR_ANGLE: 2656 if (!display->getExtensions().ggpStreamDescriptor) 2657 { 2658 val->setError(EGL_BAD_ATTRIBUTE, 2659 "EGL_GGP_STREAM_DESCRIPTOR_ANGLE requires " 2660 "EGL_ANGLE_ggp_stream_descriptor."); 2661 return false; 2662 } 2663 break; 2664 2665 case EGL_PROTECTED_CONTENT_EXT: 2666 if (!displayExtensions.protectedContentEXT) 2667 { 2668 val->setError(EGL_BAD_ATTRIBUTE, 2669 "Attribute EGL_PROTECTED_CONTEXT_EXT requires " 2670 "extension EGL_EXT_protected_content."); 2671 return false; 2672 } 2673 if (value != EGL_TRUE && value != EGL_FALSE) 2674 { 2675 val->setError(EGL_BAD_ATTRIBUTE, 2676 "EGL_PROTECTED_CONTENT_EXT must " 2677 "be either EGL_TRUE or EGL_FALSE."); 2678 return false; 2679 } 2680 break; 2681 2682 case EGL_SWAP_INTERVAL_ANGLE: 2683 if (!displayExtensions.createSurfaceSwapIntervalANGLE) 2684 { 2685 val->setError(EGL_BAD_ATTRIBUTE, 2686 "Attribute EGL_SWAP_INTERVAL_ANGLE requires " 2687 "extension EGL_ANGLE_create_surface_swap_interval."); 2688 return false; 2689 } 2690 if (value < config->minSwapInterval || value > config->maxSwapInterval) 2691 { 2692 val->setError(EGL_BAD_ATTRIBUTE, 2693 "EGL_SWAP_INTERVAL_ANGLE must " 2694 "be within the EGLConfig min and max swap intervals."); 2695 return false; 2696 } 2697 break; 2698 2699 default: 2700 val->setError(EGL_BAD_ATTRIBUTE); 2701 return false; 2702 } 2703 } 2704 2705 if (Display::hasExistingWindowSurface(window)) 2706 { 2707 val->setError(EGL_BAD_ALLOC); 2708 return false; 2709 } 2710 2711 return true; 2712 } 2713 2714 bool ValidateCreatePbufferSurface(const ValidationContext *val, 2715 const Display *display, 2716 const Config *config, 2717 const AttributeMap &attributes) 2718 { 2719 ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config)); 2720 ANGLE_VALIDATION_TRY(attributes.validate(val, display, ValidateCreatePbufferSurfaceAttribute)); 2721 2722 for (const auto &attributeIter : attributes) 2723 { 2724 EGLAttrib attribute = attributeIter.first; 2725 EGLAttrib value = attributeIter.second; 2726 2727 ANGLE_VALIDATION_TRY( 2728 ValidateCreatePbufferSurfaceAttributeValue(val, display, attribute, value)); 2729 } 2730 2731 if ((config->surfaceType & EGL_PBUFFER_BIT) == 0) 2732 { 2733 val->setError(EGL_BAD_MATCH); 2734 return false; 2735 } 2736 2737 const Caps &caps = display->getCaps(); 2738 2739 EGLAttrib textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); 2740 EGLAttrib textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); 2741 2742 if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) || 2743 (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE)) 2744 { 2745 val->setError(EGL_BAD_MATCH); 2746 return false; 2747 } 2748 2749 if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) || 2750 (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE)) 2751 { 2752 val->setError(EGL_BAD_ATTRIBUTE); 2753 return false; 2754 } 2755 2756 EGLint width = static_cast<EGLint>(attributes.get(EGL_WIDTH, 0)); 2757 EGLint height = static_cast<EGLint>(attributes.get(EGL_HEIGHT, 0)); 2758 if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && 2759 (!gl::isPow2(width) || !gl::isPow2(height))) 2760 { 2761 val->setError(EGL_BAD_MATCH); 2762 return false; 2763 } 2764 2765 return true; 2766 } 2767 2768 bool ValidateCreatePbufferFromClientBuffer(const ValidationContext *val, 2769 const Display *display, 2770 EGLenum buftype, 2771 EGLClientBuffer buffer, 2772 const Config *config, 2773 const AttributeMap &attributes) 2774 { 2775 ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config)); 2776 2777 const DisplayExtensions &displayExtensions = display->getExtensions(); 2778 2779 attributes.initializeWithoutValidation(); 2780 2781 switch (buftype) 2782 { 2783 case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: 2784 if (!displayExtensions.d3dShareHandleClientBuffer) 2785 { 2786 val->setError(EGL_BAD_PARAMETER); 2787 return false; 2788 } 2789 if (buffer == nullptr) 2790 { 2791 val->setError(EGL_BAD_PARAMETER); 2792 return false; 2793 } 2794 break; 2795 2796 case EGL_D3D_TEXTURE_ANGLE: 2797 if (!displayExtensions.d3dTextureClientBuffer) 2798 { 2799 val->setError(EGL_BAD_PARAMETER); 2800 return false; 2801 } 2802 if (buffer == nullptr) 2803 { 2804 val->setError(EGL_BAD_PARAMETER); 2805 return false; 2806 } 2807 break; 2808 2809 case EGL_IOSURFACE_ANGLE: 2810 if (!displayExtensions.iosurfaceClientBuffer) 2811 { 2812 val->setError(EGL_BAD_PARAMETER, 2813 "<buftype> EGL_IOSURFACE_ANGLE requires the " 2814 "EGL_ANGLE_iosurface_client_buffer extension."); 2815 return false; 2816 } 2817 if (buffer == nullptr) 2818 { 2819 val->setError(EGL_BAD_PARAMETER, "<buffer> must be non null"); 2820 return false; 2821 } 2822 break; 2823 case EGL_EXTERNAL_SURFACE_ANGLE: 2824 if (!display->getExtensions().externalContextAndSurface) 2825 { 2826 val->setError(EGL_BAD_ATTRIBUTE, 2827 "Attribute " 2828 "EGL_EXTERNAL_SURFACE_ANGLE requires " 2829 "EGL_ANGLE_external_context_and_surface."); 2830 return false; 2831 } 2832 if (buffer != nullptr) 2833 { 2834 val->setError(EGL_BAD_PARAMETER, "<buffer> must be null"); 2835 return false; 2836 } 2837 break; 2838 2839 default: 2840 val->setError(EGL_BAD_PARAMETER); 2841 return false; 2842 } 2843 2844 for (AttributeMap::const_iterator attributeIter = attributes.begin(); 2845 attributeIter != attributes.end(); attributeIter++) 2846 { 2847 EGLAttrib attribute = attributeIter->first; 2848 EGLAttrib value = attributeIter->second; 2849 2850 switch (attribute) 2851 { 2852 case EGL_WIDTH: 2853 case EGL_HEIGHT: 2854 if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE && 2855 buftype != EGL_D3D_TEXTURE_ANGLE && buftype != EGL_IOSURFACE_ANGLE && 2856 buftype != EGL_EXTERNAL_SURFACE_ANGLE) 2857 { 2858 val->setError(EGL_BAD_PARAMETER, 2859 "Width and Height are not supported for this <buftype>"); 2860 return false; 2861 } 2862 if (value < 0) 2863 { 2864 val->setError(EGL_BAD_PARAMETER, "Width and Height must be positive"); 2865 return false; 2866 } 2867 break; 2868 2869 case EGL_TEXTURE_FORMAT: 2870 switch (value) 2871 { 2872 case EGL_NO_TEXTURE: 2873 case EGL_TEXTURE_RGB: 2874 case EGL_TEXTURE_RGBA: 2875 break; 2876 default: 2877 val->setError(EGL_BAD_ATTRIBUTE, "Invalid value for EGL_TEXTURE_FORMAT"); 2878 return false; 2879 } 2880 break; 2881 2882 case EGL_TEXTURE_TARGET: 2883 switch (value) 2884 { 2885 case EGL_NO_TEXTURE: 2886 case EGL_TEXTURE_2D: 2887 break; 2888 case EGL_TEXTURE_RECTANGLE_ANGLE: 2889 if (buftype != EGL_IOSURFACE_ANGLE) 2890 { 2891 val->setError(EGL_BAD_PARAMETER, 2892 "<buftype> doesn't support rectangle texture targets"); 2893 return false; 2894 } 2895 break; 2896 2897 default: 2898 val->setError(EGL_BAD_ATTRIBUTE, "Invalid value for EGL_TEXTURE_TARGET"); 2899 return false; 2900 } 2901 break; 2902 2903 case EGL_MIPMAP_TEXTURE: 2904 break; 2905 2906 case EGL_IOSURFACE_PLANE_ANGLE: 2907 if (buftype != EGL_IOSURFACE_ANGLE) 2908 { 2909 val->setError(EGL_BAD_ATTRIBUTE, "<buftype> doesn't support iosurface plane"); 2910 return false; 2911 } 2912 break; 2913 2914 case EGL_TEXTURE_TYPE_ANGLE: 2915 if (buftype != EGL_IOSURFACE_ANGLE) 2916 { 2917 val->setError(EGL_BAD_ATTRIBUTE, "<buftype> doesn't support texture type"); 2918 return false; 2919 } 2920 break; 2921 2922 case EGL_TEXTURE_INTERNAL_FORMAT_ANGLE: 2923 if (buftype != EGL_IOSURFACE_ANGLE && buftype != EGL_D3D_TEXTURE_ANGLE) 2924 { 2925 val->setError(EGL_BAD_ATTRIBUTE, 2926 "<buftype> doesn't support texture internal format"); 2927 return false; 2928 } 2929 break; 2930 2931 case EGL_GL_COLORSPACE: 2932 if (buftype != EGL_D3D_TEXTURE_ANGLE) 2933 { 2934 val->setError(EGL_BAD_ATTRIBUTE, 2935 "<buftype> doesn't support setting GL colorspace"); 2936 return false; 2937 } 2938 break; 2939 2940 case EGL_IOSURFACE_USAGE_HINT_ANGLE: 2941 if (value & ~(EGL_IOSURFACE_READ_HINT_ANGLE | EGL_IOSURFACE_WRITE_HINT_ANGLE)) 2942 { 2943 val->setError(EGL_BAD_ATTRIBUTE, 2944 "IOSurface usage hint must only contain READ or WRITE"); 2945 return false; 2946 } 2947 break; 2948 2949 case EGL_TEXTURE_OFFSET_X_ANGLE: 2950 case EGL_TEXTURE_OFFSET_Y_ANGLE: 2951 if (buftype != EGL_D3D_TEXTURE_ANGLE) 2952 { 2953 val->setError(EGL_BAD_ATTRIBUTE, 2954 "<buftype> doesn't support setting texture offset"); 2955 return false; 2956 } 2957 break; 2958 2959 case EGL_PROTECTED_CONTENT_EXT: 2960 if (!displayExtensions.protectedContentEXT) 2961 { 2962 val->setError(EGL_BAD_ATTRIBUTE, 2963 "Attribute EGL_PROTECTED_CONTEXT_EXT requires " 2964 "extension EGL_EXT_protected_content."); 2965 return false; 2966 } 2967 if (value != EGL_TRUE && value != EGL_FALSE) 2968 { 2969 val->setError(EGL_BAD_ATTRIBUTE, 2970 "EGL_PROTECTED_CONTENT_EXT must " 2971 "be either EGL_TRUE or EGL_FALSE."); 2972 return false; 2973 } 2974 break; 2975 2976 default: 2977 val->setError(EGL_BAD_ATTRIBUTE); 2978 return false; 2979 } 2980 } 2981 2982 EGLAttrib colorspace = attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR); 2983 if (colorspace != EGL_GL_COLORSPACE_LINEAR && colorspace != EGL_GL_COLORSPACE_SRGB) 2984 { 2985 val->setError(EGL_BAD_ATTRIBUTE, "invalid GL colorspace"); 2986 return false; 2987 } 2988 2989 if (!(config->surfaceType & EGL_PBUFFER_BIT)) 2990 { 2991 val->setError(EGL_BAD_MATCH); 2992 return false; 2993 } 2994 2995 EGLAttrib textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); 2996 EGLAttrib textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); 2997 if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) || 2998 (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE)) 2999 { 3000 val->setError(EGL_BAD_MATCH); 3001 return false; 3002 } 3003 if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) || 3004 (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE)) 3005 { 3006 // TODO(cwallez@chromium.org): For IOSurface pbuffers we require that EGL_TEXTURE_RGBA is 3007 // set so that eglBindTexImage works. Normally this is only allowed if the config exposes 3008 // the bindToTextureRGB/RGBA flag. This issue is that enabling this flags means that 3009 // eglBindTexImage should also work for regular pbuffers which isn't implemented on macOS. 3010 // Instead of adding the flag we special case the check here to be ignored for IOSurfaces. 3011 // The TODO is to find a proper solution for this, maybe by implementing eglBindTexImage on 3012 // OSX? 3013 if (buftype != EGL_IOSURFACE_ANGLE) 3014 { 3015 val->setError(EGL_BAD_ATTRIBUTE); 3016 return false; 3017 } 3018 } 3019 3020 if (buftype == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE) 3021 { 3022 EGLint width = static_cast<EGLint>(attributes.get(EGL_WIDTH, 0)); 3023 EGLint height = static_cast<EGLint>(attributes.get(EGL_HEIGHT, 0)); 3024 3025 if (width == 0 || height == 0) 3026 { 3027 val->setError(EGL_BAD_ATTRIBUTE); 3028 return false; 3029 } 3030 3031 const Caps &caps = display->getCaps(); 3032 if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && 3033 (!gl::isPow2(width) || !gl::isPow2(height))) 3034 { 3035 val->setError(EGL_BAD_MATCH); 3036 return false; 3037 } 3038 } 3039 3040 if (buftype == EGL_IOSURFACE_ANGLE) 3041 { 3042 if (static_cast<EGLenum>(textureTarget) != config->bindToTextureTarget) 3043 { 3044 val->setError(EGL_BAD_ATTRIBUTE, 3045 "EGL_IOSURFACE requires the texture target to match the config"); 3046 return false; 3047 } 3048 if (textureFormat != EGL_TEXTURE_RGBA) 3049 { 3050 val->setError(EGL_BAD_ATTRIBUTE, "EGL_IOSURFACE requires the EGL_TEXTURE_RGBA format"); 3051 return false; 3052 } 3053 3054 if (!attributes.contains(EGL_WIDTH) || !attributes.contains(EGL_HEIGHT) || 3055 !attributes.contains(EGL_TEXTURE_FORMAT) || 3056 !attributes.contains(EGL_TEXTURE_TYPE_ANGLE) || 3057 !attributes.contains(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE) || 3058 !attributes.contains(EGL_IOSURFACE_PLANE_ANGLE)) 3059 { 3060 val->setError(EGL_BAD_PARAMETER, "Missing required attribute for EGL_IOSURFACE"); 3061 return false; 3062 } 3063 } 3064 3065 ANGLE_EGL_TRY_RETURN(val->eglThread, 3066 display->validateClientBuffer(config, buftype, buffer, attributes), 3067 val->entryPoint, val->labeledObject, false); 3068 3069 return true; 3070 } 3071 3072 bool ValidateCreatePixmapSurface(const ValidationContext *val, 3073 const Display *display, 3074 const Config *config, 3075 EGLNativePixmapType pixmap, 3076 const AttributeMap &attributes) 3077 { 3078 ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config)); 3079 3080 const DisplayExtensions &displayExtensions = display->getExtensions(); 3081 3082 attributes.initializeWithoutValidation(); 3083 3084 for (const auto &attributePair : attributes) 3085 { 3086 EGLAttrib attribute = attributePair.first; 3087 EGLAttrib value = attributePair.second; 3088 3089 switch (attribute) 3090 { 3091 case EGL_GL_COLORSPACE: 3092 ANGLE_VALIDATION_TRY(ValidateColorspaceAttribute(val, displayExtensions, value)); 3093 break; 3094 3095 case EGL_VG_COLORSPACE: 3096 break; 3097 case EGL_VG_ALPHA_FORMAT: 3098 break; 3099 3100 case EGL_TEXTURE_FORMAT: 3101 if (!displayExtensions.textureFromPixmapNOK) 3102 { 3103 val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled."); 3104 return false; 3105 } 3106 switch (value) 3107 { 3108 case EGL_NO_TEXTURE: 3109 case EGL_TEXTURE_RGB: 3110 case EGL_TEXTURE_RGBA: 3111 break; 3112 default: 3113 val->setError(EGL_BAD_ATTRIBUTE); 3114 return false; 3115 } 3116 break; 3117 3118 case EGL_TEXTURE_TARGET: 3119 if (!displayExtensions.textureFromPixmapNOK) 3120 { 3121 val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled."); 3122 return false; 3123 } 3124 switch (value) 3125 { 3126 case EGL_NO_TEXTURE: 3127 case EGL_TEXTURE_2D: 3128 break; 3129 default: 3130 val->setError(EGL_BAD_ATTRIBUTE); 3131 return false; 3132 } 3133 break; 3134 3135 case EGL_MIPMAP_TEXTURE: 3136 if (!displayExtensions.textureFromPixmapNOK) 3137 { 3138 val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled."); 3139 return false; 3140 } 3141 break; 3142 3143 case EGL_PROTECTED_CONTENT_EXT: 3144 if (!displayExtensions.protectedContentEXT) 3145 { 3146 val->setError(EGL_BAD_ATTRIBUTE, 3147 "Attribute EGL_PROTECTED_CONTEXT_EXT requires " 3148 "extension EGL_EXT_protected_content."); 3149 return false; 3150 } 3151 if (value != EGL_TRUE && value != EGL_FALSE) 3152 { 3153 val->setError(EGL_BAD_ATTRIBUTE, 3154 "EGL_PROTECTED_CONTENT_EXT must " 3155 "be either EGL_TRUE or EGL_FALSE."); 3156 return false; 3157 } 3158 break; 3159 3160 default: 3161 val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04" PRIxPTR, attribute); 3162 return false; 3163 } 3164 } 3165 3166 if (!(config->surfaceType & EGL_PIXMAP_BIT)) 3167 { 3168 val->setError(EGL_BAD_MATCH, "Congfig does not suport pixmaps."); 3169 return false; 3170 } 3171 3172 ANGLE_EGL_TRY_RETURN(val->eglThread, display->valdiatePixmap(config, pixmap, attributes), 3173 val->entryPoint, val->labeledObject, false); 3174 3175 return true; 3176 } 3177 3178 bool ValidateMakeCurrent(const ValidationContext *val, 3179 const Display *display, 3180 const Surface *draw, 3181 const Surface *read, 3182 const gl::Context *context) 3183 { 3184 if (context == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) 3185 { 3186 val->setError(EGL_BAD_MATCH, "If ctx is EGL_NO_CONTEXT, surfaces must be EGL_NO_SURFACE"); 3187 return false; 3188 } 3189 3190 // If ctx is EGL_NO_CONTEXT and either draw or read are not EGL_NO_SURFACE, an EGL_BAD_MATCH 3191 // error is generated. EGL_KHR_surfaceless_context allows both surfaces to be EGL_NO_SURFACE. 3192 if (context != EGL_NO_CONTEXT && (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE)) 3193 { 3194 if (display->getExtensions().surfacelessContext) 3195 { 3196 if ((draw == EGL_NO_SURFACE) != (read == EGL_NO_SURFACE)) 3197 { 3198 val->setError(EGL_BAD_MATCH, 3199 "If ctx is not EGL_NOT_CONTEXT, draw or read must " 3200 "both be EGL_NO_SURFACE, or both not"); 3201 return false; 3202 } 3203 } 3204 else 3205 { 3206 val->setError(EGL_BAD_MATCH, 3207 "If ctx is not EGL_NO_CONTEXT, surfaces must not be EGL_NO_SURFACE"); 3208 return false; 3209 } 3210 } 3211 3212 // If either of draw or read is a valid surface and the other is EGL_NO_SURFACE, an 3213 // EGL_BAD_MATCH error is generated. 3214 if ((read == EGL_NO_SURFACE) != (draw == EGL_NO_SURFACE)) 3215 { 3216 val->setError(EGL_BAD_MATCH, 3217 "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE"); 3218 return false; 3219 } 3220 3221 if (display == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) 3222 { 3223 val->setError(EGL_BAD_DISPLAY, "'dpy' not a valid EGLDisplay handle"); 3224 return false; 3225 } 3226 3227 // EGL 1.5 spec: dpy can be uninitialized if all other parameters are null 3228 if (!display->isInitialized() && 3229 (context != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) 3230 { 3231 val->setError(EGL_NOT_INITIALIZED, "'dpy' not initialized"); 3232 return false; 3233 } 3234 3235 if (context != EGL_NO_CONTEXT) 3236 { 3237 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 3238 } 3239 3240 if (display->isInitialized() && display->isDeviceLost()) 3241 { 3242 val->setError(EGL_CONTEXT_LOST); 3243 return false; 3244 } 3245 3246 if (draw != EGL_NO_SURFACE) 3247 { 3248 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, draw)); 3249 } 3250 3251 if (read != EGL_NO_SURFACE) 3252 { 3253 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, read)); 3254 ANGLE_VALIDATION_TRY(ValidateCompatibleSurface(val, display, context, read)); 3255 } 3256 3257 if (draw != read) 3258 { 3259 if (draw) 3260 { 3261 ANGLE_VALIDATION_TRY(ValidateCompatibleSurface(val, display, context, draw)); 3262 } 3263 if (read) 3264 { 3265 ANGLE_VALIDATION_TRY(ValidateCompatibleSurface(val, display, context, read)); 3266 } 3267 } 3268 return true; 3269 } 3270 3271 bool ValidateCreateImage(const ValidationContext *val, 3272 const Display *display, 3273 const gl::Context *context, 3274 EGLenum target, 3275 EGLClientBuffer buffer, 3276 const AttributeMap &attributes) 3277 { 3278 3279 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 3280 3281 attributes.initializeWithoutValidation(); 3282 3283 const DisplayExtensions &displayExtensions = display->getExtensions(); 3284 3285 // TODO(geofflang): Complete validation from EGL_KHR_image_base: 3286 // If the resource specified by <dpy>, <ctx>, <target>, <buffer> and <attrib_list> is itself an 3287 // EGLImage sibling, the error EGL_BAD_ACCESS is generated. 3288 3289 for (AttributeMap::const_iterator attributeIter = attributes.begin(); 3290 attributeIter != attributes.end(); attributeIter++) 3291 { 3292 EGLAttrib attribute = attributeIter->first; 3293 EGLAttrib value = attributeIter->second; 3294 3295 switch (attribute) 3296 { 3297 case EGL_IMAGE_PRESERVED: 3298 switch (value) 3299 { 3300 case EGL_TRUE: 3301 case EGL_FALSE: 3302 break; 3303 3304 default: 3305 val->setError(EGL_BAD_PARAMETER, 3306 "EGL_IMAGE_PRESERVED must be EGL_TRUE or EGL_FALSE."); 3307 return false; 3308 } 3309 break; 3310 3311 case EGL_GL_TEXTURE_LEVEL: 3312 if (!displayExtensions.glTexture2DImage && 3313 !displayExtensions.glTextureCubemapImage && !displayExtensions.glTexture3DImage) 3314 { 3315 val->setError(EGL_BAD_PARAMETER, 3316 "EGL_GL_TEXTURE_LEVEL cannot be used " 3317 "without KHR_gl_texture_*_image support."); 3318 return false; 3319 } 3320 3321 if (value < 0) 3322 { 3323 val->setError(EGL_BAD_PARAMETER, "EGL_GL_TEXTURE_LEVEL cannot be negative."); 3324 return false; 3325 } 3326 break; 3327 3328 case EGL_GL_TEXTURE_ZOFFSET: 3329 if (!displayExtensions.glTexture3DImage) 3330 { 3331 val->setError(EGL_BAD_PARAMETER, 3332 "EGL_GL_TEXTURE_ZOFFSET cannot be used " 3333 "without KHR_gl_texture_3D_image support."); 3334 return false; 3335 } 3336 break; 3337 3338 case EGL_GL_COLORSPACE: 3339 if (!displayExtensions.glColorspace) 3340 { 3341 val->setError(EGL_BAD_PARAMETER, 3342 "EGL_GL_COLORSPACE cannot be used " 3343 "without EGL_KHR_gl_colorspace support."); 3344 return false; 3345 } 3346 switch (value) 3347 { 3348 case EGL_GL_COLORSPACE_DEFAULT_EXT: 3349 break; 3350 default: 3351 ANGLE_VALIDATION_TRY( 3352 ValidateColorspaceAttribute(val, displayExtensions, value)); 3353 break; 3354 } 3355 break; 3356 3357 case EGL_TEXTURE_INTERNAL_FORMAT_ANGLE: 3358 if (!displayExtensions.imageD3D11Texture && !displayExtensions.vulkanImageANGLE) 3359 { 3360 val->setError( 3361 EGL_BAD_PARAMETER, 3362 "EGL_TEXTURE_INTERNAL_FORMAT_ANGLE cannot be used without " 3363 "EGL_ANGLE_image_d3d11_texture or EGL_ANGLE_vulkan_image support."); 3364 return false; 3365 } 3366 break; 3367 3368 case EGL_D3D11_TEXTURE_PLANE_ANGLE: 3369 if (!displayExtensions.imageD3D11Texture) 3370 { 3371 val->setError(EGL_BAD_ATTRIBUTE, 3372 "EGL_D3D11_TEXTURE_PLANE_ANGLE cannot be used without " 3373 "EGL_ANGLE_image_d3d11_texture support."); 3374 return false; 3375 } 3376 break; 3377 3378 case EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE: 3379 if (!displayExtensions.imageD3D11Texture) 3380 { 3381 val->setError(EGL_BAD_ATTRIBUTE, 3382 "EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE cannot be used without " 3383 "EGL_ANGLE_image_d3d11_texture support."); 3384 return false; 3385 } 3386 break; 3387 3388 case EGL_WIDTH: 3389 case EGL_HEIGHT: 3390 if (target != EGL_LINUX_DMA_BUF_EXT) 3391 { 3392 val->setError( 3393 EGL_BAD_PARAMETER, 3394 "Parameter cannot be used if target is not EGL_LINUX_DMA_BUF_EXT"); 3395 return false; 3396 } 3397 break; 3398 3399 case EGL_LINUX_DRM_FOURCC_EXT: 3400 case EGL_DMA_BUF_PLANE0_FD_EXT: 3401 case EGL_DMA_BUF_PLANE0_OFFSET_EXT: 3402 case EGL_DMA_BUF_PLANE0_PITCH_EXT: 3403 case EGL_DMA_BUF_PLANE1_FD_EXT: 3404 case EGL_DMA_BUF_PLANE1_OFFSET_EXT: 3405 case EGL_DMA_BUF_PLANE1_PITCH_EXT: 3406 case EGL_DMA_BUF_PLANE2_FD_EXT: 3407 case EGL_DMA_BUF_PLANE2_OFFSET_EXT: 3408 case EGL_DMA_BUF_PLANE2_PITCH_EXT: 3409 if (!displayExtensions.imageDmaBufImportEXT) 3410 { 3411 val->setError(EGL_BAD_PARAMETER, 3412 "Parameter cannot be used without " 3413 "EGL_EXT_image_dma_buf_import support."); 3414 return false; 3415 } 3416 break; 3417 3418 case EGL_YUV_COLOR_SPACE_HINT_EXT: 3419 if (!displayExtensions.imageDmaBufImportEXT) 3420 { 3421 val->setError(EGL_BAD_PARAMETER, 3422 "Parameter cannot be used without " 3423 "EGL_EXT_image_dma_buf_import support."); 3424 return false; 3425 } 3426 3427 switch (value) 3428 { 3429 case EGL_ITU_REC601_EXT: 3430 case EGL_ITU_REC709_EXT: 3431 case EGL_ITU_REC2020_EXT: 3432 break; 3433 3434 default: 3435 val->setError(EGL_BAD_PARAMETER, 3436 "Invalid value for EGL_YUV_COLOR_SPACE_HINT_EXT."); 3437 return false; 3438 } 3439 break; 3440 3441 case EGL_SAMPLE_RANGE_HINT_EXT: 3442 if (!displayExtensions.imageDmaBufImportEXT) 3443 { 3444 val->setError(EGL_BAD_PARAMETER, 3445 "Parameter cannot be used without " 3446 "EGL_EXT_image_dma_buf_import support."); 3447 return false; 3448 } 3449 3450 switch (value) 3451 { 3452 case EGL_YUV_FULL_RANGE_EXT: 3453 case EGL_YUV_NARROW_RANGE_EXT: 3454 break; 3455 3456 default: 3457 val->setError(EGL_BAD_PARAMETER, 3458 "Invalid value for EGL_SAMPLE_RANGE_HINT_EXT."); 3459 return false; 3460 } 3461 break; 3462 3463 case EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT: 3464 case EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT: 3465 if (!displayExtensions.imageDmaBufImportEXT) 3466 { 3467 val->setError(EGL_BAD_PARAMETER, 3468 "Parameter cannot be used without " 3469 "EGL_EXT_image_dma_buf_import support."); 3470 return false; 3471 } 3472 3473 switch (value) 3474 { 3475 case EGL_YUV_CHROMA_SITING_0_EXT: 3476 case EGL_YUV_CHROMA_SITING_0_5_EXT: 3477 break; 3478 3479 default: 3480 val->setError( 3481 EGL_BAD_PARAMETER, 3482 "Invalid value for EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT or " 3483 "EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT."); 3484 return false; 3485 } 3486 break; 3487 3488 case EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT: 3489 case EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT: 3490 case EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT: 3491 case EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT: 3492 case EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT: 3493 case EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT: 3494 case EGL_DMA_BUF_PLANE3_FD_EXT: 3495 case EGL_DMA_BUF_PLANE3_OFFSET_EXT: 3496 case EGL_DMA_BUF_PLANE3_PITCH_EXT: 3497 case EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT: 3498 case EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT: 3499 if (!displayExtensions.imageDmaBufImportModifiersEXT) 3500 { 3501 val->setError(EGL_BAD_PARAMETER, 3502 "Parameter cannot be used without " 3503 "EGL_EXT_image_dma_buf_import_modifiers support."); 3504 return false; 3505 } 3506 break; 3507 3508 case EGL_PROTECTED_CONTENT_EXT: 3509 if (!displayExtensions.protectedContentEXT) 3510 { 3511 val->setError(EGL_BAD_ATTRIBUTE, 3512 "Attribute EGL_PROTECTED_CONTEXT_EXT requires " 3513 "extension EGL_EXT_protected_content."); 3514 return false; 3515 } 3516 if (value != EGL_TRUE && value != EGL_FALSE) 3517 { 3518 val->setError(EGL_BAD_ATTRIBUTE, 3519 "EGL_PROTECTED_CONTENT_EXT must " 3520 "be either EGL_TRUE or EGL_FALSE."); 3521 return false; 3522 } 3523 break; 3524 3525 case EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE: 3526 case EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE: 3527 if (!displayExtensions.vulkanImageANGLE) 3528 { 3529 val->setError(EGL_BAD_ATTRIBUTE, 3530 "Attribute EGL_VULKAN_IMAGE_CREATE_INFO_{HI,LO}_ANGLE require " 3531 "extension EGL_ANGLE_vulkan_image."); 3532 return false; 3533 } 3534 break; 3535 3536 default: 3537 val->setError(EGL_BAD_PARAMETER, "invalid attribute: 0x%04" PRIxPTR "X", attribute); 3538 return false; 3539 } 3540 } 3541 3542 switch (target) 3543 { 3544 case EGL_GL_TEXTURE_2D: 3545 { 3546 if (!displayExtensions.glTexture2DImage) 3547 { 3548 val->setError(EGL_BAD_PARAMETER, "KHR_gl_texture_2D_image not supported."); 3549 return false; 3550 } 3551 3552 if (buffer == 0) 3553 { 3554 val->setError(EGL_BAD_PARAMETER, 3555 "buffer cannot reference a 2D texture with the name 0."); 3556 return false; 3557 } 3558 3559 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 3560 const gl::Texture *texture = 3561 context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)}); 3562 if (texture == nullptr || texture->getType() != gl::TextureType::_2D) 3563 { 3564 val->setError(EGL_BAD_PARAMETER, "target is not a 2D texture."); 3565 return false; 3566 } 3567 3568 if (texture->getBoundSurface() != nullptr) 3569 { 3570 val->setError(EGL_BAD_ACCESS, "texture has a surface bound to it."); 3571 return false; 3572 } 3573 3574 EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0); 3575 if (texture->getWidth(gl::TextureTarget::_2D, static_cast<size_t>(level)) == 0 || 3576 texture->getHeight(gl::TextureTarget::_2D, static_cast<size_t>(level)) == 0) 3577 { 3578 val->setError(EGL_BAD_PARAMETER, 3579 "target 2D texture does not have a valid size at specified level."); 3580 return false; 3581 } 3582 3583 bool protectedContentAttrib = 3584 (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE); 3585 if (protectedContentAttrib != texture->hasProtectedContent()) 3586 { 3587 val->setError(EGL_BAD_PARAMETER, 3588 "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state " 3589 "of target."); 3590 return false; 3591 } 3592 3593 ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level)); 3594 } 3595 break; 3596 3597 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X: 3598 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 3599 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 3600 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 3601 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 3602 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 3603 { 3604 if (!displayExtensions.glTextureCubemapImage) 3605 { 3606 val->setError(EGL_BAD_PARAMETER, "KHR_gl_texture_cubemap_image not supported."); 3607 return false; 3608 } 3609 3610 if (buffer == 0) 3611 { 3612 val->setError(EGL_BAD_PARAMETER, 3613 "buffer cannot reference a cubemap texture with the name 0."); 3614 return false; 3615 } 3616 3617 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 3618 const gl::Texture *texture = 3619 context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)}); 3620 if (texture == nullptr || texture->getType() != gl::TextureType::CubeMap) 3621 { 3622 val->setError(EGL_BAD_PARAMETER, "target is not a cubemap texture."); 3623 return false; 3624 } 3625 3626 if (texture->getBoundSurface() != nullptr) 3627 { 3628 val->setError(EGL_BAD_ACCESS, "texture has a surface bound to it."); 3629 return false; 3630 } 3631 3632 EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0); 3633 gl::TextureTarget cubeMapFace = egl_gl::EGLCubeMapTargetToCubeMapTarget(target); 3634 if (texture->getWidth(cubeMapFace, static_cast<size_t>(level)) == 0 || 3635 texture->getHeight(cubeMapFace, static_cast<size_t>(level)) == 0) 3636 { 3637 val->setError(EGL_BAD_PARAMETER, 3638 "target cubemap texture does not have a valid " 3639 "size at specified level and face."); 3640 return false; 3641 } 3642 3643 ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level)); 3644 3645 if (level == 0 && !texture->isMipmapComplete() && 3646 CubeTextureHasUnspecifiedLevel0Face(texture)) 3647 { 3648 val->setError(EGL_BAD_PARAMETER, 3649 "if level is zero and the texture is incomplete, " 3650 "it must have all of its faces specified at level " 3651 "zero."); 3652 return false; 3653 } 3654 3655 bool protectedContentAttrib = 3656 (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE); 3657 if (protectedContentAttrib != texture->hasProtectedContent()) 3658 { 3659 val->setError(EGL_BAD_PARAMETER, 3660 "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state " 3661 "of target."); 3662 return false; 3663 } 3664 } 3665 break; 3666 3667 case EGL_GL_TEXTURE_3D: 3668 { 3669 if (!displayExtensions.glTexture3DImage) 3670 { 3671 val->setError(EGL_BAD_PARAMETER, "KHR_gl_texture_3D_image not supported."); 3672 return false; 3673 } 3674 3675 if (buffer == 0) 3676 { 3677 val->setError(EGL_BAD_PARAMETER, 3678 "buffer cannot reference a 3D texture with the name 0."); 3679 return false; 3680 } 3681 3682 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 3683 const gl::Texture *texture = 3684 context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)}); 3685 if (texture == nullptr || texture->getType() != gl::TextureType::_3D) 3686 { 3687 val->setError(EGL_BAD_PARAMETER, "target is not a 3D texture."); 3688 return false; 3689 } 3690 3691 if (texture->getBoundSurface() != nullptr) 3692 { 3693 val->setError(EGL_BAD_ACCESS, "texture has a surface bound to it."); 3694 return false; 3695 } 3696 3697 EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0); 3698 EGLAttrib zOffset = attributes.get(EGL_GL_TEXTURE_ZOFFSET, 0); 3699 if (texture->getWidth(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0 || 3700 texture->getHeight(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0 || 3701 texture->getDepth(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0) 3702 { 3703 val->setError(EGL_BAD_PARAMETER, 3704 "target 3D texture does not have a valid size at specified level."); 3705 return false; 3706 } 3707 3708 if (static_cast<size_t>(zOffset) >= 3709 texture->getDepth(gl::TextureTarget::_3D, static_cast<size_t>(level))) 3710 { 3711 val->setError(EGL_BAD_PARAMETER, 3712 "target 3D texture does not have enough layers " 3713 "for the specified Z offset at the specified " 3714 "level."); 3715 return false; 3716 } 3717 3718 bool protectedContentAttrib = 3719 (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE); 3720 if (protectedContentAttrib != texture->hasProtectedContent()) 3721 { 3722 val->setError(EGL_BAD_PARAMETER, 3723 "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state " 3724 "of target."); 3725 return false; 3726 } 3727 3728 ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level)); 3729 } 3730 break; 3731 3732 case EGL_GL_RENDERBUFFER: 3733 { 3734 if (!displayExtensions.glRenderbufferImage) 3735 { 3736 val->setError(EGL_BAD_PARAMETER, "KHR_gl_renderbuffer_image not supported."); 3737 return false; 3738 } 3739 3740 if (attributes.contains(EGL_GL_TEXTURE_LEVEL)) 3741 { 3742 val->setError(EGL_BAD_PARAMETER, 3743 "EGL_GL_TEXTURE_LEVEL cannot be used in " 3744 "conjunction with a renderbuffer target."); 3745 return false; 3746 } 3747 3748 if (buffer == 0) 3749 { 3750 val->setError(EGL_BAD_PARAMETER, 3751 "buffer cannot reference a renderbuffer with the name 0."); 3752 return false; 3753 } 3754 3755 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 3756 const gl::Renderbuffer *renderbuffer = 3757 context->getRenderbuffer({egl_gl::EGLClientBufferToGLObjectHandle(buffer)}); 3758 if (renderbuffer == nullptr) 3759 { 3760 val->setError(EGL_BAD_PARAMETER, "target is not a renderbuffer."); 3761 return false; 3762 } 3763 3764 if (renderbuffer->getSamples() > 0) 3765 { 3766 val->setError(EGL_BAD_PARAMETER, "target renderbuffer cannot be multisampled."); 3767 return false; 3768 } 3769 3770 bool protectedContentAttrib = 3771 (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE); 3772 if (protectedContentAttrib != renderbuffer->hasProtectedContent()) 3773 { 3774 val->setError(EGL_BAD_ACCESS, 3775 "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state " 3776 "of target."); 3777 return false; 3778 } 3779 } 3780 break; 3781 3782 case EGL_NATIVE_BUFFER_ANDROID: 3783 { 3784 if (!displayExtensions.imageNativeBuffer) 3785 { 3786 val->setError(EGL_BAD_PARAMETER, "EGL_ANDROID_image_native_buffer not supported."); 3787 return false; 3788 } 3789 3790 if (context != nullptr) 3791 { 3792 val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT."); 3793 return false; 3794 } 3795 3796 ANGLE_EGL_TRY_RETURN( 3797 val->eglThread, 3798 display->validateImageClientBuffer(context, target, buffer, attributes), 3799 val->entryPoint, val->labeledObject, false); 3800 } 3801 break; 3802 3803 case EGL_D3D11_TEXTURE_ANGLE: 3804 if (!displayExtensions.imageD3D11Texture) 3805 { 3806 val->setError(EGL_BAD_PARAMETER, "EGL_ANGLE_image_d3d11_texture not supported."); 3807 return false; 3808 } 3809 3810 if (context != nullptr) 3811 { 3812 val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT."); 3813 return false; 3814 } 3815 3816 ANGLE_EGL_TRY_RETURN( 3817 val->eglThread, 3818 display->validateImageClientBuffer(context, target, buffer, attributes), 3819 val->entryPoint, val->labeledObject, false); 3820 break; 3821 3822 case EGL_LINUX_DMA_BUF_EXT: 3823 if (!displayExtensions.imageDmaBufImportEXT) 3824 { 3825 val->setError(EGL_BAD_PARAMETER, "EGL_EXT_image_dma_buf_import not supported."); 3826 return false; 3827 } 3828 3829 if (context != nullptr) 3830 { 3831 val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT."); 3832 return false; 3833 } 3834 3835 if (buffer != nullptr) 3836 { 3837 val->setError(EGL_BAD_PARAMETER, "buffer must be NULL."); 3838 return false; 3839 } 3840 3841 { 3842 EGLenum kRequiredParameters[] = {EGL_WIDTH, 3843 EGL_HEIGHT, 3844 EGL_LINUX_DRM_FOURCC_EXT, 3845 EGL_DMA_BUF_PLANE0_FD_EXT, 3846 EGL_DMA_BUF_PLANE0_OFFSET_EXT, 3847 EGL_DMA_BUF_PLANE0_PITCH_EXT}; 3848 for (EGLenum requiredParameter : kRequiredParameters) 3849 { 3850 if (!attributes.contains(requiredParameter)) 3851 { 3852 val->setError(EGL_BAD_PARAMETER, 3853 "Missing required parameter 0x%X for image target " 3854 "EGL_LINUX_DMA_BUF_EXT.", 3855 requiredParameter); 3856 return false; 3857 } 3858 } 3859 3860 bool containPlane0ModifierLo = 3861 attributes.contains(EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT); 3862 bool containPlane0ModifierHi = 3863 attributes.contains(EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT); 3864 bool containPlane1ModifierLo = 3865 attributes.contains(EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT); 3866 bool containPlane1ModifierHi = 3867 attributes.contains(EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT); 3868 bool containPlane2ModifierLo = 3869 attributes.contains(EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT); 3870 bool containPlane2ModifierHi = 3871 attributes.contains(EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT); 3872 bool containPlane3ModifierLo = 3873 attributes.contains(EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT); 3874 bool containPlane3ModifierHi = 3875 attributes.contains(EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT); 3876 if ((containPlane0ModifierLo ^ containPlane0ModifierHi) || 3877 (containPlane1ModifierLo ^ containPlane1ModifierHi) || 3878 (containPlane2ModifierLo ^ containPlane2ModifierHi) || 3879 (containPlane3ModifierLo ^ containPlane3ModifierHi)) 3880 { 3881 val->setError( 3882 EGL_BAD_PARAMETER, 3883 "the list of attributes contains EGL_DMA_BUF_PLANE*_MODIFIER_LO_EXT " 3884 "but not EGL_DMA_BUF_PLANE*_MODIFIER_HI_EXT or vice versa."); 3885 return false; 3886 } 3887 } 3888 break; 3889 3890 case EGL_METAL_TEXTURE_ANGLE: 3891 if (!displayExtensions.mtlTextureClientBuffer) 3892 { 3893 val->setError(EGL_BAD_PARAMETER, 3894 "EGL_ANGLE_metal_texture_client_buffer not supported."); 3895 return false; 3896 } 3897 3898 if (context != nullptr) 3899 { 3900 val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT."); 3901 return false; 3902 } 3903 3904 ANGLE_EGL_TRY_RETURN( 3905 val->eglThread, 3906 display->validateImageClientBuffer(context, target, buffer, attributes), 3907 val->entryPoint, val->labeledObject, false); 3908 break; 3909 case EGL_VULKAN_IMAGE_ANGLE: 3910 if (!displayExtensions.vulkanImageANGLE) 3911 { 3912 val->setError(EGL_BAD_PARAMETER, "EGL_ANGLE_vulkan_image not supported."); 3913 return false; 3914 } 3915 3916 if (context != nullptr) 3917 { 3918 val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT."); 3919 return false; 3920 } 3921 3922 { 3923 const EGLenum kRequiredParameters[] = { 3924 EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE, 3925 EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE, 3926 }; 3927 for (EGLenum requiredParameter : kRequiredParameters) 3928 { 3929 if (!attributes.contains(requiredParameter)) 3930 { 3931 val->setError(EGL_BAD_PARAMETER, 3932 "Missing required parameter 0x%X for image target " 3933 "EGL_VULKAN_IMAGE_ANGLE.", 3934 requiredParameter); 3935 return false; 3936 } 3937 } 3938 } 3939 3940 ANGLE_EGL_TRY_RETURN( 3941 val->eglThread, 3942 display->validateImageClientBuffer(context, target, buffer, attributes), 3943 val->entryPoint, val->labeledObject, false); 3944 break; 3945 default: 3946 val->setError(EGL_BAD_PARAMETER, "invalid target: 0x%X", target); 3947 return false; 3948 } 3949 3950 if (attributes.contains(EGL_GL_TEXTURE_ZOFFSET) && target != EGL_GL_TEXTURE_3D) 3951 { 3952 val->setError(EGL_BAD_PARAMETER, 3953 "EGL_GL_TEXTURE_ZOFFSET must be used with a 3D texture target."); 3954 return false; 3955 } 3956 3957 return true; 3958 } 3959 3960 bool ValidateDestroyImage(const ValidationContext *val, const Display *display, const Image *image) 3961 { 3962 ANGLE_VALIDATION_TRY(ValidateImage(val, display, image)); 3963 3964 return true; 3965 } 3966 3967 bool ValidateCreateImageKHR(const ValidationContext *val, 3968 const Display *display, 3969 const gl::Context *context, 3970 EGLenum target, 3971 EGLClientBuffer buffer, 3972 const AttributeMap &attributes) 3973 { 3974 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 3975 3976 if (!display->getExtensions().imageBase && !display->getExtensions().image) 3977 { 3978 // It is out of spec what happens when calling an extension function when the extension is 3979 // not available. 3980 // EGL_BAD_DISPLAY seems like a reasonable error. 3981 val->setError(EGL_BAD_DISPLAY, "EGL_KHR_image not supported."); 3982 return false; 3983 } 3984 3985 return ValidateCreateImage(val, display, context, target, buffer, attributes); 3986 } 3987 3988 bool ValidateDestroyImageKHR(const ValidationContext *val, 3989 const Display *display, 3990 const Image *image) 3991 { 3992 ANGLE_VALIDATION_TRY(ValidateImage(val, display, image)); 3993 3994 if (!display->getExtensions().imageBase && !display->getExtensions().image) 3995 { 3996 // It is out of spec what happens when calling an extension function when the extension is 3997 // not available. 3998 // EGL_BAD_DISPLAY seems like a reasonable error. 3999 val->setError(EGL_BAD_DISPLAY); 4000 return false; 4001 } 4002 4003 return true; 4004 } 4005 4006 bool ValidateCreateDeviceANGLE(const ValidationContext *val, 4007 EGLint device_type, 4008 const void *native_device, 4009 const EGLAttrib *attrib_list) 4010 { 4011 const ClientExtensions &clientExtensions = Display::GetClientExtensions(); 4012 if (!clientExtensions.deviceCreation) 4013 { 4014 val->setError(EGL_BAD_ACCESS, "Device creation extension not active"); 4015 return false; 4016 } 4017 4018 if (attrib_list != nullptr && attrib_list[0] != EGL_NONE) 4019 { 4020 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attrib_list parameter"); 4021 return false; 4022 } 4023 4024 switch (device_type) 4025 { 4026 case EGL_D3D11_DEVICE_ANGLE: 4027 if (!clientExtensions.deviceCreationD3D11) 4028 { 4029 val->setError(EGL_BAD_ATTRIBUTE, "D3D11 device creation extension not active"); 4030 return false; 4031 } 4032 break; 4033 default: 4034 val->setError(EGL_BAD_ATTRIBUTE, "Invalid device_type parameter"); 4035 return false; 4036 } 4037 4038 return true; 4039 } 4040 4041 bool ValidateReleaseDeviceANGLE(const ValidationContext *val, const Device *device) 4042 { 4043 const ClientExtensions &clientExtensions = Display::GetClientExtensions(); 4044 if (!clientExtensions.deviceCreation) 4045 { 4046 val->setError(EGL_BAD_ACCESS, "Device creation extension not active"); 4047 return false; 4048 } 4049 4050 if (device == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(device)) 4051 { 4052 val->setError(EGL_BAD_DEVICE_EXT, "Invalid device parameter"); 4053 return false; 4054 } 4055 4056 Display *owningDisplay = device->getOwningDisplay(); 4057 if (owningDisplay != nullptr) 4058 { 4059 val->setError(EGL_BAD_DEVICE_EXT, "Device must have been created using eglCreateDevice"); 4060 return false; 4061 } 4062 4063 return true; 4064 } 4065 4066 bool ValidateCreateSync(const ValidationContext *val, 4067 const Display *display, 4068 EGLenum type, 4069 const AttributeMap &attribs) 4070 { 4071 return ValidateCreateSyncBase(val, display, type, attribs, false); 4072 } 4073 4074 bool ValidateCreateSyncKHR(const ValidationContext *val, 4075 const Display *display, 4076 EGLenum type, 4077 const AttributeMap &attribs) 4078 { 4079 return ValidateCreateSyncBase(val, display, type, attribs, true); 4080 } 4081 4082 bool ValidateDestroySync(const ValidationContext *val, const Display *display, const Sync *sync) 4083 { 4084 ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); 4085 return true; 4086 } 4087 4088 bool ValidateDestroySyncKHR(const ValidationContext *val, 4089 const Display *dpyPacked, 4090 const Sync *syncPacked) 4091 { 4092 return ValidateDestroySync(val, dpyPacked, syncPacked); 4093 } 4094 4095 bool ValidateClientWaitSync(const ValidationContext *val, 4096 const Display *display, 4097 const Sync *sync, 4098 EGLint flags, 4099 EGLTime timeout) 4100 { 4101 ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); 4102 return true; 4103 } 4104 4105 bool ValidateClientWaitSyncKHR(const ValidationContext *val, 4106 const Display *dpyPacked, 4107 const Sync *syncPacked, 4108 EGLint flags, 4109 EGLTimeKHR timeout) 4110 { 4111 return ValidateClientWaitSync(val, dpyPacked, syncPacked, flags, timeout); 4112 } 4113 4114 bool ValidateWaitSync(const ValidationContext *val, 4115 const Display *display, 4116 const Sync *sync, 4117 EGLint flags) 4118 { 4119 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 4120 4121 const DisplayExtensions &extensions = display->getExtensions(); 4122 if (!extensions.waitSync) 4123 { 4124 val->setError(EGL_BAD_ACCESS, "EGL_KHR_wait_sync extension is not available"); 4125 return false; 4126 } 4127 4128 ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); 4129 4130 gl::Context *context = val->eglThread->getContext(); 4131 if (context == nullptr) 4132 { 4133 val->setError(EGL_BAD_MATCH, "No context is current."); 4134 return false; 4135 } 4136 4137 if (!context->getExtensions().EGLSyncOES) 4138 { 4139 val->setError(EGL_BAD_MATCH, 4140 "Server-side waits cannot be performed without " 4141 "GL_OES_EGL_sync support."); 4142 return false; 4143 } 4144 4145 if (flags != 0) 4146 { 4147 val->setError(EGL_BAD_PARAMETER, "flags must be zero"); 4148 return false; 4149 } 4150 4151 return true; 4152 } 4153 4154 bool ValidateWaitSyncKHR(const ValidationContext *val, 4155 const Display *dpyPacked, 4156 const Sync *syncPacked, 4157 EGLint flags) 4158 { 4159 return ValidateWaitSync(val, dpyPacked, syncPacked, flags); 4160 } 4161 4162 bool ValidateGetSyncAttrib(const ValidationContext *val, 4163 const Display *display, 4164 const Sync *sync, 4165 EGLint attribute, 4166 const EGLAttrib *value) 4167 { 4168 if (value == nullptr) 4169 { 4170 val->setError(EGL_BAD_PARAMETER, "Invalid value parameter"); 4171 return false; 4172 } 4173 return ValidateGetSyncAttribBase(val, display, sync, attribute); 4174 } 4175 4176 bool ValidateGetSyncAttribKHR(const ValidationContext *val, 4177 const Display *display, 4178 const Sync *sync, 4179 EGLint attribute, 4180 const EGLint *value) 4181 { 4182 if (value == nullptr) 4183 { 4184 val->setError(EGL_BAD_PARAMETER, "Invalid value parameter"); 4185 return false; 4186 } 4187 return ValidateGetSyncAttribBase(val, display, sync, attribute); 4188 } 4189 4190 bool ValidateCreateStreamKHR(const ValidationContext *val, 4191 const Display *display, 4192 const AttributeMap &attributes) 4193 { 4194 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 4195 4196 const DisplayExtensions &displayExtensions = display->getExtensions(); 4197 if (!displayExtensions.stream) 4198 { 4199 val->setError(EGL_BAD_ALLOC, "Stream extension not active"); 4200 return false; 4201 } 4202 4203 attributes.initializeWithoutValidation(); 4204 4205 for (const auto &attributeIter : attributes) 4206 { 4207 EGLAttrib attribute = attributeIter.first; 4208 EGLAttrib value = attributeIter.second; 4209 4210 ANGLE_VALIDATION_TRY(ValidateStreamAttribute(val, attribute, value, displayExtensions)); 4211 } 4212 4213 return true; 4214 } 4215 4216 bool ValidateDestroyStreamKHR(const ValidationContext *val, 4217 const Display *display, 4218 const Stream *stream) 4219 { 4220 ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); 4221 return true; 4222 } 4223 4224 bool ValidateStreamAttribKHR(const ValidationContext *val, 4225 const Display *display, 4226 const Stream *stream, 4227 EGLenum attribute, 4228 EGLint value) 4229 { 4230 ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); 4231 4232 if (stream->getState() == EGL_STREAM_STATE_DISCONNECTED_KHR) 4233 { 4234 val->setError(EGL_BAD_STATE_KHR, "Bad stream state"); 4235 return false; 4236 } 4237 4238 return ValidateStreamAttribute(val, attribute, value, display->getExtensions()); 4239 } 4240 4241 bool ValidateQueryStreamKHR(const ValidationContext *val, 4242 const Display *display, 4243 const Stream *stream, 4244 EGLenum attribute, 4245 const EGLint *value) 4246 { 4247 ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); 4248 4249 switch (attribute) 4250 { 4251 case EGL_STREAM_STATE_KHR: 4252 case EGL_CONSUMER_LATENCY_USEC_KHR: 4253 break; 4254 case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR: 4255 if (!display->getExtensions().streamConsumerGLTexture) 4256 { 4257 val->setError(EGL_BAD_ATTRIBUTE, "Consumer GLTexture extension not active"); 4258 return false; 4259 } 4260 break; 4261 default: 4262 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); 4263 return false; 4264 } 4265 4266 return true; 4267 } 4268 4269 bool ValidateQueryStreamu64KHR(const ValidationContext *val, 4270 const Display *display, 4271 const Stream *stream, 4272 EGLenum attribute, 4273 const EGLuint64KHR *value) 4274 { 4275 ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); 4276 4277 switch (attribute) 4278 { 4279 case EGL_CONSUMER_FRAME_KHR: 4280 case EGL_PRODUCER_FRAME_KHR: 4281 break; 4282 default: 4283 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); 4284 return false; 4285 } 4286 4287 return true; 4288 } 4289 4290 bool ValidateStreamConsumerGLTextureExternalKHR(const ValidationContext *val, 4291 const Display *display, 4292 const Stream *stream) 4293 { 4294 gl::Context *context = val->eglThread->getContext(); 4295 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 4296 4297 const DisplayExtensions &displayExtensions = display->getExtensions(); 4298 if (!displayExtensions.streamConsumerGLTexture) 4299 { 4300 val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active"); 4301 return false; 4302 } 4303 4304 if (!context->getExtensions().EGLStreamConsumerExternalNV) 4305 { 4306 val->setError(EGL_BAD_ACCESS, "EGL stream consumer external GL extension not enabled"); 4307 return false; 4308 } 4309 4310 if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) 4311 { 4312 val->setError(EGL_BAD_STREAM_KHR, "Invalid stream"); 4313 return false; 4314 } 4315 4316 if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR) 4317 { 4318 val->setError(EGL_BAD_STATE_KHR, "Invalid stream state"); 4319 return false; 4320 } 4321 4322 // Lookup the texture and ensure it is correct 4323 gl::Texture *texture = context->getState().getTargetTexture(gl::TextureType::External); 4324 if (texture == nullptr || texture->id().value == 0) 4325 { 4326 val->setError(EGL_BAD_ACCESS, "No external texture bound"); 4327 return false; 4328 } 4329 4330 return true; 4331 } 4332 4333 bool ValidateStreamConsumerAcquireKHR(const ValidationContext *val, 4334 const Display *display, 4335 const Stream *stream) 4336 { 4337 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 4338 4339 const DisplayExtensions &displayExtensions = display->getExtensions(); 4340 if (!displayExtensions.streamConsumerGLTexture) 4341 { 4342 val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active"); 4343 return false; 4344 } 4345 4346 if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) 4347 { 4348 val->setError(EGL_BAD_STREAM_KHR, "Invalid stream"); 4349 return false; 4350 } 4351 4352 gl::Context *context = val->eglThread->getContext(); 4353 if (!context) 4354 { 4355 val->setError(EGL_BAD_ACCESS, "No GL context current to calling thread."); 4356 return false; 4357 } 4358 4359 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 4360 4361 if (!stream->isConsumerBoundToContext(context)) 4362 { 4363 val->setError(EGL_BAD_ACCESS, "Current GL context not associated with stream consumer"); 4364 return false; 4365 } 4366 4367 if (stream->getConsumerType() != Stream::ConsumerType::GLTextureRGB && 4368 stream->getConsumerType() != Stream::ConsumerType::GLTextureYUV) 4369 { 4370 val->setError(EGL_BAD_ACCESS, "Invalid stream consumer type"); 4371 return false; 4372 } 4373 4374 // Note: technically EGL_STREAM_STATE_EMPTY_KHR is a valid state when the timeout is non-zero. 4375 // However, the timeout is effectively ignored since it has no useful functionality with the 4376 // current producers that are implemented, so we don't allow that state 4377 if (stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR && 4378 stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR) 4379 { 4380 val->setError(EGL_BAD_STATE_KHR, "Invalid stream state"); 4381 return false; 4382 } 4383 4384 return true; 4385 } 4386 4387 bool ValidateStreamConsumerReleaseKHR(const ValidationContext *val, 4388 const Display *display, 4389 const Stream *stream) 4390 { 4391 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 4392 4393 const DisplayExtensions &displayExtensions = display->getExtensions(); 4394 if (!displayExtensions.streamConsumerGLTexture) 4395 { 4396 val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active"); 4397 return false; 4398 } 4399 4400 if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) 4401 { 4402 val->setError(EGL_BAD_STREAM_KHR, "Invalid stream"); 4403 return false; 4404 } 4405 4406 gl::Context *context = val->eglThread->getContext(); 4407 if (!context) 4408 { 4409 val->setError(EGL_BAD_ACCESS, "No GL context current to calling thread."); 4410 return false; 4411 } 4412 4413 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 4414 4415 if (!stream->isConsumerBoundToContext(context)) 4416 { 4417 val->setError(EGL_BAD_ACCESS, "Current GL context not associated with stream consumer"); 4418 return false; 4419 } 4420 4421 if (stream->getConsumerType() != Stream::ConsumerType::GLTextureRGB && 4422 stream->getConsumerType() != Stream::ConsumerType::GLTextureYUV) 4423 { 4424 val->setError(EGL_BAD_ACCESS, "Invalid stream consumer type"); 4425 return false; 4426 } 4427 4428 if (stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR && 4429 stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR) 4430 { 4431 val->setError(EGL_BAD_STATE_KHR, "Invalid stream state"); 4432 return false; 4433 } 4434 4435 return true; 4436 } 4437 4438 bool ValidateStreamConsumerGLTextureExternalAttribsNV(const ValidationContext *val, 4439 const Display *display, 4440 const Stream *stream, 4441 const AttributeMap &attribs) 4442 { 4443 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 4444 4445 const DisplayExtensions &displayExtensions = display->getExtensions(); 4446 if (!displayExtensions.streamConsumerGLTexture) 4447 { 4448 val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active"); 4449 return false; 4450 } 4451 4452 gl::Context *context = val->eglThread->getContext(); 4453 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 4454 4455 // Although technically not a requirement in spec, the context needs to be checked for support 4456 // for external textures or future logic will cause assertations. This extension is also 4457 // effectively useless without external textures. 4458 if (!context->getExtensions().EGLStreamConsumerExternalNV) 4459 { 4460 val->setError(EGL_BAD_ACCESS, "EGL stream consumer external GL extension not enabled"); 4461 return false; 4462 } 4463 4464 if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) 4465 { 4466 val->setError(EGL_BAD_STREAM_KHR, "Invalid stream"); 4467 return false; 4468 } 4469 4470 if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR) 4471 { 4472 val->setError(EGL_BAD_STATE_KHR, "Invalid stream state"); 4473 return false; 4474 } 4475 4476 const gl::Caps &glCaps = context->getCaps(); 4477 4478 EGLAttrib colorBufferType = EGL_RGB_BUFFER; 4479 EGLAttrib planeCount = -1; 4480 EGLAttrib plane[3]; 4481 for (int i = 0; i < 3; i++) 4482 { 4483 plane[i] = -1; 4484 } 4485 4486 attribs.initializeWithoutValidation(); 4487 4488 for (const auto &attributeIter : attribs) 4489 { 4490 EGLAttrib attribute = attributeIter.first; 4491 EGLAttrib value = attributeIter.second; 4492 4493 switch (attribute) 4494 { 4495 case EGL_COLOR_BUFFER_TYPE: 4496 if (value != EGL_RGB_BUFFER && value != EGL_YUV_BUFFER_EXT) 4497 { 4498 val->setError(EGL_BAD_PARAMETER, "Invalid color buffer type"); 4499 return false; 4500 } 4501 colorBufferType = value; 4502 break; 4503 case EGL_YUV_NUMBER_OF_PLANES_EXT: 4504 // planeCount = -1 is a tag for the default plane count so the value must be checked 4505 // to be positive here to ensure future logic doesn't break on invalid negative 4506 // inputs 4507 if (value < 0) 4508 { 4509 val->setError(EGL_BAD_MATCH, "Invalid plane count"); 4510 return false; 4511 } 4512 planeCount = value; 4513 break; 4514 default: 4515 if (attribute >= EGL_YUV_PLANE0_TEXTURE_UNIT_NV && 4516 attribute <= EGL_YUV_PLANE2_TEXTURE_UNIT_NV) 4517 { 4518 if ((value < 0 || 4519 value >= static_cast<EGLAttrib>(glCaps.maxCombinedTextureImageUnits)) && 4520 value != EGL_NONE) 4521 { 4522 val->setError(EGL_BAD_ACCESS, "Invalid texture unit"); 4523 return false; 4524 } 4525 plane[attribute - EGL_YUV_PLANE0_TEXTURE_UNIT_NV] = value; 4526 } 4527 else 4528 { 4529 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); 4530 return false; 4531 } 4532 } 4533 } 4534 4535 if (colorBufferType == EGL_RGB_BUFFER) 4536 { 4537 if (planeCount > 0) 4538 { 4539 val->setError(EGL_BAD_MATCH, "Plane count must be 0 for RGB buffer"); 4540 return false; 4541 } 4542 for (int i = 0; i < 3; i++) 4543 { 4544 if (plane[i] != -1) 4545 { 4546 val->setError(EGL_BAD_MATCH, "Planes cannot be specified"); 4547 return false; 4548 } 4549 } 4550 4551 // Lookup the texture and ensure it is correct 4552 gl::Texture *texture = context->getState().getTargetTexture(gl::TextureType::External); 4553 if (texture == nullptr || texture->id().value == 0) 4554 { 4555 val->setError(EGL_BAD_ACCESS, "No external texture bound"); 4556 return false; 4557 } 4558 } 4559 else 4560 { 4561 if (planeCount == -1) 4562 { 4563 planeCount = 2; 4564 } 4565 if (planeCount < 1 || planeCount > 3) 4566 { 4567 val->setError(EGL_BAD_MATCH, "Invalid YUV plane count"); 4568 return false; 4569 } 4570 for (EGLAttrib i = planeCount; i < 3; i++) 4571 { 4572 if (plane[i] != -1) 4573 { 4574 val->setError(EGL_BAD_MATCH, "Invalid plane specified"); 4575 return false; 4576 } 4577 } 4578 4579 // Set to ensure no texture is referenced more than once 4580 std::set<gl::Texture *> textureSet; 4581 for (EGLAttrib i = 0; i < planeCount; i++) 4582 { 4583 if (plane[i] == -1) 4584 { 4585 val->setError(EGL_BAD_MATCH, "Not all planes specified"); 4586 return false; 4587 } 4588 if (plane[i] != EGL_NONE) 4589 { 4590 gl::Texture *texture = context->getState().getSamplerTexture( 4591 static_cast<unsigned int>(plane[i]), gl::TextureType::External); 4592 if (texture == nullptr || texture->id().value == 0) 4593 { 4594 val->setError( 4595 EGL_BAD_ACCESS, 4596 "No external texture bound at one or more specified texture units"); 4597 return false; 4598 } 4599 if (textureSet.find(texture) != textureSet.end()) 4600 { 4601 val->setError(EGL_BAD_ACCESS, "Multiple planes bound to same texture object"); 4602 return false; 4603 } 4604 textureSet.insert(texture); 4605 } 4606 } 4607 } 4608 4609 return true; 4610 } 4611 4612 bool ValidateCreateStreamProducerD3DTextureANGLE(const ValidationContext *val, 4613 const Display *display, 4614 const Stream *stream, 4615 const AttributeMap &attribs) 4616 { 4617 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 4618 4619 const DisplayExtensions &displayExtensions = display->getExtensions(); 4620 if (!displayExtensions.streamProducerD3DTexture) 4621 { 4622 val->setError(EGL_BAD_ACCESS, "Stream producer extension not active"); 4623 return false; 4624 } 4625 4626 ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); 4627 4628 attribs.initializeWithoutValidation(); 4629 4630 if (!attribs.isEmpty()) 4631 { 4632 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); 4633 return false; 4634 } 4635 4636 if (stream->getState() != EGL_STREAM_STATE_CONNECTING_KHR) 4637 { 4638 val->setError(EGL_BAD_STATE_KHR, "Stream not in connecting state"); 4639 return false; 4640 } 4641 4642 switch (stream->getConsumerType()) 4643 { 4644 case Stream::ConsumerType::GLTextureYUV: 4645 if (stream->getPlaneCount() != 2) 4646 { 4647 val->setError(EGL_BAD_MATCH, "Incompatible stream consumer type"); 4648 return false; 4649 } 4650 break; 4651 4652 case Stream::ConsumerType::GLTextureRGB: 4653 if (stream->getPlaneCount() != 1) 4654 { 4655 val->setError(EGL_BAD_MATCH, "Incompatible stream consumer type"); 4656 return false; 4657 } 4658 break; 4659 4660 default: 4661 val->setError(EGL_BAD_MATCH, "Incompatible stream consumer type"); 4662 return false; 4663 } 4664 4665 return true; 4666 } 4667 4668 bool ValidateStreamPostD3DTextureANGLE(const ValidationContext *val, 4669 const Display *display, 4670 const Stream *stream, 4671 const void *texture, 4672 const AttributeMap &attribs) 4673 { 4674 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 4675 4676 const DisplayExtensions &displayExtensions = display->getExtensions(); 4677 if (!displayExtensions.streamProducerD3DTexture) 4678 { 4679 val->setError(EGL_BAD_ACCESS, "Stream producer extension not active"); 4680 return false; 4681 } 4682 4683 ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); 4684 4685 attribs.initializeWithoutValidation(); 4686 4687 for (auto &attributeIter : attribs) 4688 { 4689 EGLAttrib attribute = attributeIter.first; 4690 EGLAttrib value = attributeIter.second; 4691 4692 switch (attribute) 4693 { 4694 case EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE: 4695 if (value < 0) 4696 { 4697 val->setError(EGL_BAD_PARAMETER, "Invalid subresource index"); 4698 return false; 4699 } 4700 break; 4701 case EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG: 4702 if (value < 0) 4703 { 4704 val->setError(EGL_BAD_PARAMETER, "Invalid plane offset"); 4705 return false; 4706 } 4707 break; 4708 default: 4709 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); 4710 return false; 4711 } 4712 } 4713 4714 if (stream->getState() != EGL_STREAM_STATE_EMPTY_KHR && 4715 stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR && 4716 stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR) 4717 { 4718 val->setError(EGL_BAD_STATE_KHR, "Stream not fully configured"); 4719 return false; 4720 } 4721 4722 if (stream->getProducerType() != Stream::ProducerType::D3D11Texture) 4723 { 4724 val->setError(EGL_BAD_MATCH, "Incompatible stream producer"); 4725 return false; 4726 } 4727 4728 if (texture == nullptr) 4729 { 4730 val->setError(EGL_BAD_PARAMETER, "Texture is null"); 4731 return false; 4732 } 4733 4734 ANGLE_EGL_TRY_RETURN(val->eglThread, stream->validateD3D11Texture(texture, attribs), 4735 val->entryPoint, val->labeledObject, false); 4736 4737 return true; 4738 } 4739 4740 bool ValidateSyncControlCHROMIUM(const ValidationContext *val, 4741 const Display *display, 4742 const Surface *eglSurface) 4743 { 4744 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 4745 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface)); 4746 4747 const DisplayExtensions &displayExtensions = display->getExtensions(); 4748 if (!displayExtensions.syncControlCHROMIUM) 4749 { 4750 val->setError(EGL_BAD_ACCESS, "syncControlCHROMIUM extension not active"); 4751 return false; 4752 } 4753 4754 return true; 4755 } 4756 4757 bool ValidateSyncControlRateANGLE(const ValidationContext *val, 4758 const Display *display, 4759 const Surface *eglSurface) 4760 { 4761 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 4762 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface)); 4763 4764 const DisplayExtensions &displayExtensions = display->getExtensions(); 4765 if (!displayExtensions.syncControlRateANGLE) 4766 { 4767 val->setError(EGL_BAD_ACCESS, "syncControlRateANGLE extension not active"); 4768 return false; 4769 } 4770 4771 return true; 4772 } 4773 4774 bool ValidateGetMscRateANGLE(const ValidationContext *val, 4775 const Display *display, 4776 const Surface *eglSurface, 4777 const EGLint *numerator, 4778 const EGLint *denominator) 4779 { 4780 ANGLE_VALIDATION_TRY(ValidateSyncControlRateANGLE(val, display, eglSurface)); 4781 4782 if (numerator == nullptr) 4783 { 4784 val->setError(EGL_BAD_PARAMETER, "numerator is null"); 4785 return false; 4786 } 4787 if (denominator == nullptr) 4788 { 4789 val->setError(EGL_BAD_PARAMETER, "denominator is null"); 4790 return false; 4791 } 4792 4793 return true; 4794 } 4795 4796 bool ValidateGetSyncValuesCHROMIUM(const ValidationContext *val, 4797 const Display *display, 4798 const Surface *eglSurface, 4799 const EGLuint64KHR *ust, 4800 const EGLuint64KHR *msc, 4801 const EGLuint64KHR *sbc) 4802 { 4803 ANGLE_VALIDATION_TRY(ValidateSyncControlCHROMIUM(val, display, eglSurface)); 4804 4805 if (ust == nullptr) 4806 { 4807 val->setError(EGL_BAD_PARAMETER, "ust is null"); 4808 return false; 4809 } 4810 if (msc == nullptr) 4811 { 4812 val->setError(EGL_BAD_PARAMETER, "msc is null"); 4813 return false; 4814 } 4815 if (sbc == nullptr) 4816 { 4817 val->setError(EGL_BAD_PARAMETER, "sbc is null"); 4818 return false; 4819 } 4820 4821 return true; 4822 } 4823 4824 bool ValidateDestroySurface(const ValidationContext *val, 4825 const Display *display, 4826 const Surface *surface) 4827 { 4828 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 4829 return true; 4830 } 4831 4832 bool ValidateDestroyContext(const ValidationContext *val, 4833 const Display *display, 4834 const gl::Context *glCtx) 4835 { 4836 ANGLE_VALIDATION_TRY(ValidateContext(val, display, glCtx)); 4837 return true; 4838 } 4839 4840 bool ValidateSwapBuffers(const ValidationContext *val, 4841 const Display *display, 4842 const Surface *eglSurface) 4843 { 4844 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface)); 4845 4846 if (display->isDeviceLost()) 4847 { 4848 val->setError(EGL_CONTEXT_LOST); 4849 return false; 4850 } 4851 4852 if (eglSurface->isLocked()) 4853 { 4854 val->setError(EGL_BAD_ACCESS); 4855 return false; 4856 } 4857 4858 if (eglSurface == EGL_NO_SURFACE || !val->eglThread->getContext() || 4859 val->eglThread->getCurrentDrawSurface() != eglSurface) 4860 { 4861 val->setError(EGL_BAD_SURFACE); 4862 return false; 4863 } 4864 4865 return true; 4866 } 4867 4868 bool ValidateSwapBuffersWithDamageKHR(const ValidationContext *val, 4869 const Display *display, 4870 const Surface *surface, 4871 const EGLint *rects, 4872 EGLint n_rects) 4873 { 4874 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 4875 4876 if (!display->getExtensions().swapBuffersWithDamage) 4877 { 4878 // It is out of spec what happens when calling an extension function when the extension is 4879 // not available. EGL_BAD_DISPLAY seems like a reasonable error. 4880 val->setError(EGL_BAD_DISPLAY, "EGL_KHR_swap_buffers_with_damage is not available."); 4881 return false; 4882 } 4883 4884 if (surface == EGL_NO_SURFACE) 4885 { 4886 val->setError(EGL_BAD_SURFACE, "Swap surface cannot be EGL_NO_SURFACE."); 4887 return false; 4888 } 4889 4890 if (n_rects < 0) 4891 { 4892 val->setError(EGL_BAD_PARAMETER, "n_rects cannot be negative."); 4893 return false; 4894 } 4895 4896 if (n_rects > 0 && rects == nullptr) 4897 { 4898 val->setError(EGL_BAD_PARAMETER, "n_rects cannot be greater than zero when rects is NULL."); 4899 return false; 4900 } 4901 4902 if (surface->isLocked()) 4903 { 4904 val->setError(EGL_BAD_ACCESS); 4905 return false; 4906 } 4907 4908 // TODO(jmadill): Validate Surface is bound to the thread. 4909 4910 return true; 4911 } 4912 4913 bool ValidateWaitNative(const ValidationContext *val, const EGLint engine) 4914 { 4915 if (val->eglThread->getDisplay() == nullptr) 4916 { 4917 // EGL spec says this about eglWaitNative - 4918 // eglWaitNative is ignored if there is no current EGL rendering context. 4919 return true; 4920 } 4921 4922 ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay())); 4923 4924 if (engine != EGL_CORE_NATIVE_ENGINE) 4925 { 4926 val->setError(EGL_BAD_PARAMETER, "the 'engine' parameter has an unrecognized value"); 4927 return false; 4928 } 4929 4930 return true; 4931 } 4932 4933 bool ValidateCopyBuffers(const ValidationContext *val, 4934 const Display *display, 4935 const Surface *surface, 4936 EGLNativePixmapType target) 4937 { 4938 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 4939 4940 if (display->isDeviceLost()) 4941 { 4942 val->setError(EGL_CONTEXT_LOST); 4943 return false; 4944 } 4945 4946 return true; 4947 } 4948 4949 bool ValidateBindTexImage(const ValidationContext *val, 4950 const Display *display, 4951 const Surface *surface, 4952 const EGLint buffer) 4953 { 4954 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 4955 4956 if (buffer != EGL_BACK_BUFFER) 4957 { 4958 val->setError(EGL_BAD_PARAMETER); 4959 return false; 4960 } 4961 4962 if (surface->getType() == EGL_WINDOW_BIT) 4963 { 4964 val->setError(EGL_BAD_SURFACE); 4965 return false; 4966 } 4967 4968 if (surface->getBoundTexture()) 4969 { 4970 val->setError(EGL_BAD_ACCESS); 4971 return false; 4972 } 4973 4974 if (surface->getTextureFormat() == TextureFormat::NoTexture) 4975 { 4976 val->setError(EGL_BAD_MATCH); 4977 return false; 4978 } 4979 4980 if (surface->isLocked()) 4981 { 4982 val->setError(EGL_BAD_ACCESS); 4983 return false; 4984 } 4985 4986 gl::Context *context = val->eglThread->getContext(); 4987 if (context && !context->isContextLost()) 4988 { 4989 gl::TextureType type = egl_gl::EGLTextureTargetToTextureType(surface->getTextureTarget()); 4990 gl::Texture *textureObject = context->getTextureByType(type); 4991 ASSERT(textureObject != nullptr); 4992 4993 if (textureObject->getImmutableFormat()) 4994 { 4995 val->setError(EGL_BAD_MATCH); 4996 return false; 4997 } 4998 } 4999 5000 return true; 5001 } 5002 5003 bool ValidateReleaseTexImage(const ValidationContext *val, 5004 const Display *display, 5005 const Surface *surface, 5006 const EGLint buffer) 5007 { 5008 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 5009 5010 if (buffer != EGL_BACK_BUFFER) 5011 { 5012 val->setError(EGL_BAD_PARAMETER); 5013 return false; 5014 } 5015 5016 if (surface->getType() == EGL_WINDOW_BIT) 5017 { 5018 val->setError(EGL_BAD_SURFACE); 5019 return false; 5020 } 5021 5022 if (surface->getTextureFormat() == TextureFormat::NoTexture) 5023 { 5024 val->setError(EGL_BAD_MATCH); 5025 return false; 5026 } 5027 5028 return true; 5029 } 5030 5031 bool ValidateSwapInterval(const ValidationContext *val, const Display *display, EGLint interval) 5032 { 5033 const gl::Context *context = val->eglThread->getContext(); 5034 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 5035 5036 Surface *drawSurface = val->eglThread->getCurrentDrawSurface(); 5037 if (drawSurface == nullptr) 5038 { 5039 val->setError(EGL_BAD_SURFACE); 5040 return false; 5041 } 5042 5043 return true; 5044 } 5045 5046 bool ValidateBindAPI(const ValidationContext *val, const EGLenum api) 5047 { 5048 switch (api) 5049 { 5050 case EGL_OPENGL_ES_API: 5051 case EGL_OPENGL_API: 5052 break; 5053 case EGL_OPENVG_API: 5054 val->setError(EGL_BAD_PARAMETER); 5055 return false; // Not supported by this implementation 5056 default: 5057 val->setError(EGL_BAD_PARAMETER); 5058 return false; 5059 } 5060 5061 return true; 5062 } 5063 5064 bool ValidatePresentationTimeANDROID(const ValidationContext *val, 5065 const Display *display, 5066 const Surface *surface, 5067 EGLnsecsANDROID time) 5068 { 5069 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5070 5071 if (!display->getExtensions().presentationTime) 5072 { 5073 // It is out of spec what happens when calling an extension function when the extension is 5074 // not available. EGL_BAD_DISPLAY seems like a reasonable error. 5075 val->setError(EGL_BAD_DISPLAY, "EGL_ANDROID_presentation_time is not available."); 5076 return false; 5077 } 5078 5079 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 5080 5081 return true; 5082 } 5083 5084 bool ValidateSetBlobCacheFuncsANDROID(const ValidationContext *val, 5085 const Display *display, 5086 EGLSetBlobFuncANDROID set, 5087 EGLGetBlobFuncANDROID get) 5088 { 5089 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5090 5091 if (display->areBlobCacheFuncsSet()) 5092 { 5093 val->setError(EGL_BAD_PARAMETER, 5094 "Blob cache functions can only be set once in the lifetime of a Display"); 5095 return false; 5096 } 5097 5098 if (set == nullptr || get == nullptr) 5099 { 5100 val->setError(EGL_BAD_PARAMETER, "Blob cache callbacks cannot be null."); 5101 return false; 5102 } 5103 5104 return true; 5105 } 5106 5107 bool ValidateGetConfigAttrib(const ValidationContext *val, 5108 const Display *display, 5109 const Config *config, 5110 EGLint attribute, 5111 const EGLint *value) 5112 { 5113 ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config)); 5114 ANGLE_TRY(ValidateConfigAttribute(val, display, static_cast<EGLAttrib>(attribute))); 5115 return true; 5116 } 5117 5118 bool ValidateChooseConfig(const ValidationContext *val, 5119 const Display *display, 5120 const AttributeMap &attribs, 5121 const EGLConfig *configs, 5122 EGLint configSize, 5123 const EGLint *numConfig) 5124 { 5125 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5126 ANGLE_VALIDATION_TRY(ValidateConfigAttributes(val, display, attribs)); 5127 5128 if (numConfig == nullptr) 5129 { 5130 val->setError(EGL_BAD_PARAMETER, "num_config cannot be null."); 5131 return false; 5132 } 5133 5134 return true; 5135 } 5136 5137 bool ValidateGetConfigs(const ValidationContext *val, 5138 const Display *display, 5139 const EGLConfig *configs, 5140 EGLint configSize, 5141 const EGLint *numConfig) 5142 { 5143 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5144 5145 if (numConfig == nullptr) 5146 { 5147 val->setError(EGL_BAD_PARAMETER, "num_config cannot be null."); 5148 return false; 5149 } 5150 5151 return true; 5152 } 5153 5154 bool ValidateGetPlatformDisplay(const ValidationContext *val, 5155 EGLenum platform, 5156 const void *native_display, 5157 const AttributeMap &attribMap) 5158 { 5159 return ValidateGetPlatformDisplayCommon(val, platform, native_display, attribMap); 5160 } 5161 5162 bool ValidateGetPlatformDisplayEXT(const ValidationContext *val, 5163 EGLenum platform, 5164 const void *native_display, 5165 const AttributeMap &attribMap) 5166 { 5167 return ValidateGetPlatformDisplayCommon(val, platform, native_display, attribMap); 5168 } 5169 5170 bool ValidateCreatePlatformWindowSurfaceEXT(const ValidationContext *val, 5171 const Display *display, 5172 const Config *configuration, 5173 const void *nativeWindow, 5174 const AttributeMap &attributes) 5175 { 5176 if (!Display::GetClientExtensions().platformBase) 5177 { 5178 val->setError(EGL_BAD_ACCESS, "EGL_EXT_platform_base not supported"); 5179 return false; 5180 } 5181 5182 const void *actualNativeWindow = display->getImplementation()->isX11() 5183 ? *reinterpret_cast<const void *const *>(nativeWindow) 5184 : nativeWindow; 5185 5186 return ValidateCreatePlatformWindowSurface(val, display, configuration, actualNativeWindow, 5187 attributes); 5188 } 5189 5190 bool ValidateCreatePlatformPixmapSurfaceEXT(const ValidationContext *val, 5191 const Display *display, 5192 const Config *configuration, 5193 const void *nativePixmap, 5194 const AttributeMap &attributes) 5195 { 5196 if (!Display::GetClientExtensions().platformBase) 5197 { 5198 val->setError(EGL_BAD_ACCESS, "EGL_EXT_platform_base not supported"); 5199 return false; 5200 } 5201 5202 ANGLE_VALIDATION_TRY(ValidateConfig(val, display, configuration)); 5203 5204 val->setError(EGL_BAD_DISPLAY, "ValidateCreatePlatformPixmapSurfaceEXT unimplemented."); 5205 return false; 5206 } 5207 5208 bool ValidateProgramCacheGetAttribANGLE(const ValidationContext *val, 5209 const Display *display, 5210 EGLenum attrib) 5211 { 5212 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5213 5214 if (!display->getExtensions().programCacheControlANGLE) 5215 { 5216 val->setError(EGL_BAD_ACCESS, "Extension not supported"); 5217 return false; 5218 } 5219 5220 switch (attrib) 5221 { 5222 case EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE: 5223 case EGL_PROGRAM_CACHE_SIZE_ANGLE: 5224 break; 5225 5226 default: 5227 val->setError(EGL_BAD_PARAMETER, "Invalid program cache attribute."); 5228 return false; 5229 } 5230 5231 return true; 5232 } 5233 5234 bool ValidateProgramCacheQueryANGLE(const ValidationContext *val, 5235 const Display *display, 5236 EGLint index, 5237 const void *key, 5238 const EGLint *keysize, 5239 const void *binary, 5240 const EGLint *binarysize) 5241 { 5242 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5243 5244 if (!display->getExtensions().programCacheControlANGLE) 5245 { 5246 val->setError(EGL_BAD_ACCESS, "Extension not supported"); 5247 return false; 5248 } 5249 5250 if (index < 0 || index >= display->programCacheGetAttrib(EGL_PROGRAM_CACHE_SIZE_ANGLE)) 5251 { 5252 val->setError(EGL_BAD_PARAMETER, "Program index out of range."); 5253 return false; 5254 } 5255 5256 if (keysize == nullptr || binarysize == nullptr) 5257 { 5258 val->setError(EGL_BAD_PARAMETER, "keysize and binarysize must always be valid pointers."); 5259 return false; 5260 } 5261 5262 if (binary && *keysize != static_cast<EGLint>(egl::BlobCache::kKeyLength)) 5263 { 5264 val->setError(EGL_BAD_PARAMETER, "Invalid program key size."); 5265 return false; 5266 } 5267 5268 if ((key == nullptr) != (binary == nullptr)) 5269 { 5270 val->setError(EGL_BAD_PARAMETER, "key and binary must both be null or both non-null."); 5271 return false; 5272 } 5273 5274 return true; 5275 } 5276 5277 bool ValidateProgramCachePopulateANGLE(const ValidationContext *val, 5278 const Display *display, 5279 const void *key, 5280 EGLint keysize, 5281 const void *binary, 5282 EGLint binarysize) 5283 { 5284 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5285 5286 if (!display->getExtensions().programCacheControlANGLE) 5287 { 5288 val->setError(EGL_BAD_ACCESS, "Extension not supported"); 5289 return false; 5290 } 5291 5292 if (keysize != static_cast<EGLint>(egl::BlobCache::kKeyLength)) 5293 { 5294 val->setError(EGL_BAD_PARAMETER, "Invalid program key size."); 5295 return false; 5296 } 5297 5298 if (key == nullptr || binary == nullptr) 5299 { 5300 val->setError(EGL_BAD_PARAMETER, "null pointer in arguments."); 5301 return false; 5302 } 5303 5304 // Upper bound for binarysize is arbitrary. 5305 if (binarysize <= 0 || binarysize > egl::kProgramCacheSizeAbsoluteMax) 5306 { 5307 val->setError(EGL_BAD_PARAMETER, "binarysize out of valid range."); 5308 return false; 5309 } 5310 5311 return true; 5312 } 5313 5314 bool ValidateProgramCacheResizeANGLE(const ValidationContext *val, 5315 const Display *display, 5316 EGLint limit, 5317 EGLint mode) 5318 { 5319 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5320 5321 if (!display->getExtensions().programCacheControlANGLE) 5322 { 5323 val->setError(EGL_BAD_ACCESS, "Extension not supported"); 5324 return false; 5325 } 5326 5327 if (limit < 0) 5328 { 5329 val->setError(EGL_BAD_PARAMETER, "limit must be non-negative."); 5330 return false; 5331 } 5332 5333 switch (mode) 5334 { 5335 case EGL_PROGRAM_CACHE_RESIZE_ANGLE: 5336 case EGL_PROGRAM_CACHE_TRIM_ANGLE: 5337 break; 5338 5339 default: 5340 val->setError(EGL_BAD_PARAMETER, "Invalid cache resize mode."); 5341 return false; 5342 } 5343 5344 return true; 5345 } 5346 5347 bool ValidateSurfaceAttrib(const ValidationContext *val, 5348 const Display *display, 5349 const Surface *surface, 5350 EGLint attribute, 5351 EGLint value) 5352 { 5353 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5354 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 5355 5356 if (surface == EGL_NO_SURFACE) 5357 { 5358 val->setError(EGL_BAD_SURFACE, "Surface cannot be EGL_NO_SURFACE."); 5359 return false; 5360 } 5361 5362 switch (attribute) 5363 { 5364 case EGL_MIPMAP_LEVEL: 5365 break; 5366 5367 case EGL_MULTISAMPLE_RESOLVE: 5368 switch (value) 5369 { 5370 case EGL_MULTISAMPLE_RESOLVE_DEFAULT: 5371 break; 5372 5373 case EGL_MULTISAMPLE_RESOLVE_BOX: 5374 if ((surface->getConfig()->surfaceType & EGL_MULTISAMPLE_RESOLVE_BOX_BIT) == 0) 5375 { 5376 val->setError(EGL_BAD_MATCH, 5377 "Surface does not support EGL_MULTISAMPLE_RESOLVE_BOX."); 5378 return false; 5379 } 5380 break; 5381 5382 default: 5383 val->setError(EGL_BAD_ATTRIBUTE, "Invalid multisample resolve type."); 5384 return false; 5385 } 5386 break; 5387 5388 case EGL_SWAP_BEHAVIOR: 5389 switch (value) 5390 { 5391 case EGL_BUFFER_PRESERVED: 5392 if ((surface->getConfig()->surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == 0) 5393 { 5394 val->setError(EGL_BAD_MATCH, 5395 "Surface does not support EGL_SWAP_BEHAVIOR_PRESERVED."); 5396 return false; 5397 } 5398 break; 5399 5400 case EGL_BUFFER_DESTROYED: 5401 break; 5402 5403 default: 5404 val->setError(EGL_BAD_ATTRIBUTE, "Invalid swap behaviour."); 5405 return false; 5406 } 5407 break; 5408 5409 case EGL_WIDTH: 5410 case EGL_HEIGHT: 5411 if (!display->getExtensions().windowFixedSize) 5412 { 5413 val->setError(EGL_BAD_ATTRIBUTE, 5414 "EGL_WIDTH or EGL_HEIGHT cannot be set without " 5415 "EGL_ANGLE_window_fixed_size support."); 5416 return false; 5417 } 5418 if (!surface->isFixedSize()) 5419 { 5420 val->setError(EGL_BAD_MATCH, 5421 "EGL_WIDTH or EGL_HEIGHT cannot be set without " 5422 "EGL_FIXED_SIZE_ANGLE being enabled on the surface."); 5423 return false; 5424 } 5425 break; 5426 5427 case EGL_TIMESTAMPS_ANDROID: 5428 if (!display->getExtensions().getFrameTimestamps && 5429 !display->getExtensions().timestampSurfaceAttributeANGLE) 5430 { 5431 val->setError(EGL_BAD_ATTRIBUTE, 5432 "EGL_TIMESTAMPS_ANDROID cannot be used without " 5433 "EGL_ANDROID_get_frame_timestamps support."); 5434 return false; 5435 } 5436 switch (value) 5437 { 5438 case EGL_TRUE: 5439 case EGL_FALSE: 5440 break; 5441 5442 default: 5443 val->setError(EGL_BAD_ATTRIBUTE, "Invalid value."); 5444 return false; 5445 } 5446 break; 5447 5448 case EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID: 5449 ASSERT(value == EGL_TRUE || value == EGL_FALSE); 5450 break; 5451 5452 case EGL_RENDER_BUFFER: 5453 if (value != EGL_BACK_BUFFER && value != EGL_SINGLE_BUFFER) 5454 { 5455 val->setError(EGL_BAD_ATTRIBUTE, 5456 "EGL_RENDER_BUFFER must be EGL_BACK_BUFFER or EGL_SINGLE_BUFFER."); 5457 return false; 5458 } 5459 5460 if (value == EGL_SINGLE_BUFFER) 5461 { 5462 if (!display->getExtensions().mutableRenderBufferKHR) 5463 { 5464 val->setError( 5465 EGL_BAD_ATTRIBUTE, 5466 "Attribute EGL_RENDER_BUFFER requires EGL_KHR_mutable_render_buffer."); 5467 return false; 5468 } 5469 5470 if ((surface->getConfig()->surfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR) == 0) 5471 { 5472 val->setError(EGL_BAD_MATCH, 5473 "EGL_RENDER_BUFFER requires the surface type bit " 5474 "EGL_MUTABLE_RENDER_BUFFER_BIT_KHR."); 5475 return false; 5476 } 5477 } 5478 break; 5479 5480 default: 5481 val->setError(EGL_BAD_ATTRIBUTE, "Invalid surface attribute: 0x%04X", attribute); 5482 return false; 5483 } 5484 5485 return true; 5486 } 5487 5488 bool ValidateQuerySurface(const ValidationContext *val, 5489 const Display *display, 5490 const Surface *surface, 5491 EGLint attribute, 5492 const EGLint *value) 5493 { 5494 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5495 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 5496 5497 if (surface == EGL_NO_SURFACE) 5498 { 5499 val->setError(EGL_BAD_SURFACE, "Surface cannot be EGL_NO_SURFACE."); 5500 return false; 5501 } 5502 5503 switch (attribute) 5504 { 5505 case EGL_GL_COLORSPACE: 5506 case EGL_VG_ALPHA_FORMAT: 5507 case EGL_VG_COLORSPACE: 5508 case EGL_CONFIG_ID: 5509 case EGL_HEIGHT: 5510 case EGL_HORIZONTAL_RESOLUTION: 5511 case EGL_LARGEST_PBUFFER: 5512 case EGL_MIPMAP_TEXTURE: 5513 case EGL_MIPMAP_LEVEL: 5514 case EGL_MULTISAMPLE_RESOLVE: 5515 case EGL_PIXEL_ASPECT_RATIO: 5516 case EGL_RENDER_BUFFER: 5517 case EGL_SWAP_BEHAVIOR: 5518 case EGL_TEXTURE_FORMAT: 5519 case EGL_TEXTURE_TARGET: 5520 case EGL_VERTICAL_RESOLUTION: 5521 case EGL_WIDTH: 5522 break; 5523 5524 case EGL_POST_SUB_BUFFER_SUPPORTED_NV: 5525 if (!display->getExtensions().postSubBuffer) 5526 { 5527 val->setError(EGL_BAD_ATTRIBUTE, 5528 "EGL_POST_SUB_BUFFER_SUPPORTED_NV cannot be used " 5529 "without EGL_ANGLE_surface_orientation support."); 5530 return false; 5531 } 5532 break; 5533 5534 case EGL_FIXED_SIZE_ANGLE: 5535 if (!display->getExtensions().windowFixedSize) 5536 { 5537 val->setError(EGL_BAD_ATTRIBUTE, 5538 "EGL_FIXED_SIZE_ANGLE cannot be used without " 5539 "EGL_ANGLE_window_fixed_size support."); 5540 return false; 5541 } 5542 break; 5543 5544 case EGL_SURFACE_ORIENTATION_ANGLE: 5545 if (!display->getExtensions().surfaceOrientation) 5546 { 5547 val->setError(EGL_BAD_ATTRIBUTE, 5548 "EGL_SURFACE_ORIENTATION_ANGLE cannot be " 5549 "queried without " 5550 "EGL_ANGLE_surface_orientation support."); 5551 return false; 5552 } 5553 break; 5554 5555 case EGL_DIRECT_COMPOSITION_ANGLE: 5556 if (!display->getExtensions().directComposition) 5557 { 5558 val->setError(EGL_BAD_ATTRIBUTE, 5559 "EGL_DIRECT_COMPOSITION_ANGLE cannot be " 5560 "used without " 5561 "EGL_ANGLE_direct_composition support."); 5562 return false; 5563 } 5564 break; 5565 5566 case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: 5567 if (!display->getExtensions().robustResourceInitializationANGLE) 5568 { 5569 val->setError(EGL_BAD_ATTRIBUTE, 5570 "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE cannot be " 5571 "used without EGL_ANGLE_robust_resource_initialization " 5572 "support."); 5573 return false; 5574 } 5575 break; 5576 5577 case EGL_TIMESTAMPS_ANDROID: 5578 if (!display->getExtensions().getFrameTimestamps && 5579 !display->getExtensions().timestampSurfaceAttributeANGLE) 5580 { 5581 val->setError(EGL_BAD_ATTRIBUTE, 5582 "EGL_TIMESTAMPS_ANDROID cannot be used without " 5583 "EGL_ANDROID_get_frame_timestamps support."); 5584 return false; 5585 } 5586 break; 5587 5588 case EGL_BUFFER_AGE_EXT: 5589 { 5590 if (!display->getExtensions().bufferAgeEXT) 5591 { 5592 val->setError(EGL_BAD_ATTRIBUTE, 5593 "EGL_BUFFER_AGE_EXT cannot be used without " 5594 "EGL_EXT_buffer_age support."); 5595 return false; 5596 } 5597 gl::Context *context = val->eglThread->getContext(); 5598 if ((context == nullptr) || (context->getCurrentDrawSurface() != surface)) 5599 { 5600 val->setError(EGL_BAD_SURFACE, 5601 "The surface must be current to the current context " 5602 "in order to query buffer age per extension " 5603 "EGL_EXT_buffer_age."); 5604 return false; 5605 } 5606 } 5607 break; 5608 5609 case EGL_BITMAP_PITCH_KHR: 5610 case EGL_BITMAP_ORIGIN_KHR: 5611 case EGL_BITMAP_PIXEL_RED_OFFSET_KHR: 5612 case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR: 5613 case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR: 5614 case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR: 5615 case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR: 5616 case EGL_BITMAP_PIXEL_SIZE_KHR: 5617 if (!display->getExtensions().lockSurface3KHR) 5618 { 5619 val->setError(EGL_BAD_ATTRIBUTE, "EGL_KHR_lock_surface3 is not supported."); 5620 return false; 5621 } 5622 break; 5623 5624 case EGL_PROTECTED_CONTENT_EXT: 5625 if (!display->getExtensions().protectedContentEXT) 5626 { 5627 val->setError(EGL_BAD_ATTRIBUTE, "EGL_EXT_protected_content not supported"); 5628 return false; 5629 } 5630 break; 5631 5632 default: 5633 val->setError(EGL_BAD_ATTRIBUTE, "Invalid surface attribute: 0x%04X", attribute); 5634 return false; 5635 } 5636 5637 return true; 5638 } 5639 5640 bool ValidateQueryContext(const ValidationContext *val, 5641 const Display *display, 5642 const gl::Context *context, 5643 EGLint attribute, 5644 const EGLint *value) 5645 { 5646 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 5647 5648 switch (attribute) 5649 { 5650 case EGL_CONFIG_ID: 5651 case EGL_CONTEXT_CLIENT_TYPE: 5652 case EGL_CONTEXT_CLIENT_VERSION: 5653 case EGL_RENDER_BUFFER: 5654 break; 5655 5656 case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: 5657 if (!display->getExtensions().robustResourceInitializationANGLE) 5658 { 5659 val->setError(EGL_BAD_ATTRIBUTE, 5660 "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE cannot be " 5661 "used without EGL_ANGLE_robust_resource_initialization " 5662 "support."); 5663 return false; 5664 } 5665 break; 5666 5667 case EGL_CONTEXT_PRIORITY_LEVEL_IMG: 5668 if (!display->getExtensions().contextPriority) 5669 { 5670 val->setError(EGL_BAD_ATTRIBUTE, 5671 "Attribute EGL_CONTEXT_PRIORITY_LEVEL_IMG requires " 5672 "extension EGL_IMG_context_priority."); 5673 return false; 5674 } 5675 break; 5676 5677 case EGL_PROTECTED_CONTENT_EXT: 5678 if (!display->getExtensions().protectedContentEXT) 5679 { 5680 val->setError(EGL_BAD_ATTRIBUTE, "EGL_EXT_protected_content not supported"); 5681 return false; 5682 } 5683 break; 5684 5685 default: 5686 val->setError(EGL_BAD_ATTRIBUTE, "Invalid context attribute: 0x%04X", attribute); 5687 return false; 5688 } 5689 5690 return true; 5691 } 5692 5693 bool ValidateDebugMessageControlKHR(const ValidationContext *val, 5694 EGLDEBUGPROCKHR callback, 5695 const AttributeMap &attribs) 5696 { 5697 const ClientExtensions &clientExtensions = Display::GetClientExtensions(); 5698 if (!clientExtensions.debug) 5699 { 5700 val->setError(EGL_BAD_ACCESS, "EGL_KHR_debug extension is not available."); 5701 return false; 5702 } 5703 5704 attribs.initializeWithoutValidation(); 5705 5706 for (const auto &attrib : attribs) 5707 { 5708 switch (attrib.first) 5709 { 5710 case EGL_DEBUG_MSG_CRITICAL_KHR: 5711 case EGL_DEBUG_MSG_ERROR_KHR: 5712 case EGL_DEBUG_MSG_WARN_KHR: 5713 case EGL_DEBUG_MSG_INFO_KHR: 5714 if (attrib.second != EGL_TRUE && attrib.second != EGL_FALSE) 5715 { 5716 val->setError(EGL_BAD_ATTRIBUTE, 5717 "message controls must be EGL_TRUE or EGL_FALSE."); 5718 return false; 5719 } 5720 break; 5721 } 5722 } 5723 5724 return true; 5725 } 5726 5727 bool ValidateQueryDebugKHR(const ValidationContext *val, EGLint attribute, const EGLAttrib *value) 5728 { 5729 const ClientExtensions &clientExtensions = Display::GetClientExtensions(); 5730 if (!clientExtensions.debug) 5731 { 5732 val->setError(EGL_BAD_ACCESS, "EGL_KHR_debug extension is not available."); 5733 return false; 5734 } 5735 5736 switch (attribute) 5737 { 5738 case EGL_DEBUG_MSG_CRITICAL_KHR: 5739 case EGL_DEBUG_MSG_ERROR_KHR: 5740 case EGL_DEBUG_MSG_WARN_KHR: 5741 case EGL_DEBUG_MSG_INFO_KHR: 5742 case EGL_DEBUG_CALLBACK_KHR: 5743 break; 5744 5745 default: 5746 val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04X", attribute); 5747 return false; 5748 } 5749 5750 return true; 5751 } 5752 5753 bool ValidateLabelObjectKHR(const ValidationContext *val, 5754 const Display *display, 5755 ObjectType objectType, 5756 EGLObjectKHR object, 5757 EGLLabelKHR label) 5758 { 5759 const ClientExtensions &clientExtensions = Display::GetClientExtensions(); 5760 if (!clientExtensions.debug) 5761 { 5762 val->setError(EGL_BAD_ACCESS, "EGL_KHR_debug extension is not available."); 5763 return false; 5764 } 5765 5766 LabeledObject *labeledObject = nullptr; 5767 ANGLE_VALIDATION_TRY(ValidateLabeledObject(val, display, objectType, object, &labeledObject)); 5768 5769 return true; 5770 } 5771 5772 bool ValidateGetCompositorTimingSupportedANDROID(const ValidationContext *val, 5773 const Display *display, 5774 const Surface *surface, 5775 CompositorTiming name) 5776 { 5777 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5778 5779 if (!display->getExtensions().getFrameTimestamps) 5780 { 5781 val->setError(EGL_BAD_DISPLAY, 5782 "EGL_ANDROID_get_frame_timestamps extension is not available."); 5783 return false; 5784 } 5785 5786 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 5787 5788 if (!ValidCompositorTimingName(name)) 5789 { 5790 val->setError(EGL_BAD_PARAMETER, "invalid timing name."); 5791 return false; 5792 } 5793 5794 return true; 5795 } 5796 5797 bool ValidateGetCompositorTimingANDROID(const ValidationContext *val, 5798 const Display *display, 5799 const Surface *surface, 5800 EGLint numTimestamps, 5801 const EGLint *names, 5802 const EGLnsecsANDROID *values) 5803 { 5804 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5805 5806 if (!display->getExtensions().getFrameTimestamps) 5807 { 5808 val->setError(EGL_BAD_DISPLAY, 5809 "EGL_ANDROID_get_frame_timestamps extension is not available."); 5810 return false; 5811 } 5812 5813 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 5814 5815 if (names == nullptr && numTimestamps > 0) 5816 { 5817 val->setError(EGL_BAD_PARAMETER, "names is NULL."); 5818 return false; 5819 } 5820 5821 if (values == nullptr && numTimestamps > 0) 5822 { 5823 val->setError(EGL_BAD_PARAMETER, "values is NULL."); 5824 return false; 5825 } 5826 5827 if (numTimestamps < 0) 5828 { 5829 val->setError(EGL_BAD_PARAMETER, "numTimestamps must be at least 0."); 5830 return false; 5831 } 5832 5833 for (EGLint i = 0; i < numTimestamps; i++) 5834 { 5835 CompositorTiming name = FromEGLenum<CompositorTiming>(names[i]); 5836 5837 if (!ValidCompositorTimingName(name)) 5838 { 5839 val->setError(EGL_BAD_PARAMETER, "invalid compositor timing."); 5840 return false; 5841 } 5842 5843 if (!surface->getSupportedCompositorTimings().test(name)) 5844 { 5845 val->setError(EGL_BAD_PARAMETER, "compositor timing not supported by surface."); 5846 return false; 5847 } 5848 } 5849 5850 return true; 5851 } 5852 5853 bool ValidateGetNextFrameIdANDROID(const ValidationContext *val, 5854 const Display *display, 5855 const Surface *surface, 5856 const EGLuint64KHR *frameId) 5857 { 5858 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5859 5860 if (!display->getExtensions().getFrameTimestamps) 5861 { 5862 val->setError(EGL_BAD_DISPLAY, 5863 "EGL_ANDROID_get_frame_timestamps extension is not available."); 5864 return false; 5865 } 5866 5867 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 5868 5869 if (frameId == nullptr) 5870 { 5871 val->setError(EGL_BAD_PARAMETER, "frameId is NULL."); 5872 return false; 5873 } 5874 5875 return true; 5876 } 5877 5878 bool ValidateGetFrameTimestampSupportedANDROID(const ValidationContext *val, 5879 const Display *display, 5880 const Surface *surface, 5881 Timestamp timestamp) 5882 { 5883 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5884 5885 if (!display->getExtensions().getFrameTimestamps) 5886 { 5887 val->setError(EGL_BAD_DISPLAY, 5888 "EGL_ANDROID_get_frame_timestamps extension is not available."); 5889 return false; 5890 } 5891 5892 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 5893 5894 if (!ValidTimestampType(timestamp)) 5895 { 5896 val->setError(EGL_BAD_PARAMETER, "invalid timestamp type."); 5897 return false; 5898 } 5899 5900 return true; 5901 } 5902 5903 bool ValidateGetFrameTimestampsANDROID(const ValidationContext *val, 5904 const Display *display, 5905 const Surface *surface, 5906 EGLuint64KHR frameId, 5907 EGLint numTimestamps, 5908 const EGLint *timestamps, 5909 const EGLnsecsANDROID *values) 5910 { 5911 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5912 5913 if (!display->getExtensions().getFrameTimestamps) 5914 { 5915 val->setError(EGL_BAD_DISPLAY, 5916 "EGL_ANDROID_get_frame_timestamps extension is not available."); 5917 return false; 5918 } 5919 5920 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 5921 5922 if (!surface->isTimestampsEnabled()) 5923 { 5924 val->setError(EGL_BAD_SURFACE, "timestamp collection is not enabled for this surface."); 5925 return false; 5926 } 5927 5928 if (timestamps == nullptr && numTimestamps > 0) 5929 { 5930 val->setError(EGL_BAD_PARAMETER, "timestamps is NULL."); 5931 return false; 5932 } 5933 5934 if (values == nullptr && numTimestamps > 0) 5935 { 5936 val->setError(EGL_BAD_PARAMETER, "values is NULL."); 5937 return false; 5938 } 5939 5940 if (numTimestamps < 0) 5941 { 5942 val->setError(EGL_BAD_PARAMETER, "numTimestamps must be at least 0."); 5943 return false; 5944 } 5945 5946 for (EGLint i = 0; i < numTimestamps; i++) 5947 { 5948 Timestamp timestamp = FromEGLenum<Timestamp>(timestamps[i]); 5949 5950 if (!ValidTimestampType(timestamp)) 5951 { 5952 val->setError(EGL_BAD_PARAMETER, "invalid timestamp type."); 5953 return false; 5954 } 5955 5956 if (!surface->getSupportedTimestamps().test(timestamp)) 5957 { 5958 val->setError(EGL_BAD_PARAMETER, "timestamp not supported by surface."); 5959 return false; 5960 } 5961 } 5962 5963 return true; 5964 } 5965 5966 bool ValidateQueryStringiANGLE(const ValidationContext *val, 5967 const Display *display, 5968 EGLint name, 5969 EGLint index) 5970 { 5971 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 5972 5973 if (!Display::GetClientExtensions().featureControlANGLE) 5974 { 5975 val->setError(EGL_BAD_DISPLAY, "EGL_ANGLE_feature_control extension is not available."); 5976 return false; 5977 } 5978 5979 if (index < 0) 5980 { 5981 val->setError(EGL_BAD_PARAMETER, "index is negative."); 5982 return false; 5983 } 5984 5985 switch (name) 5986 { 5987 case EGL_FEATURE_NAME_ANGLE: 5988 case EGL_FEATURE_CATEGORY_ANGLE: 5989 case EGL_FEATURE_DESCRIPTION_ANGLE: 5990 case EGL_FEATURE_BUG_ANGLE: 5991 case EGL_FEATURE_STATUS_ANGLE: 5992 case EGL_FEATURE_CONDITION_ANGLE: 5993 break; 5994 default: 5995 val->setError(EGL_BAD_PARAMETER, "name is not valid."); 5996 return false; 5997 } 5998 5999 if (static_cast<size_t>(index) >= display->getFeatures().size()) 6000 { 6001 val->setError(EGL_BAD_PARAMETER, "index is too big."); 6002 return false; 6003 } 6004 6005 return true; 6006 } 6007 6008 bool ValidateQueryDisplayAttribEXT(const ValidationContext *val, 6009 const Display *display, 6010 const EGLint attribute, 6011 const EGLAttrib *value) 6012 { 6013 ANGLE_VALIDATION_TRY(ValidateQueryDisplayAttribBase(val, display, attribute)); 6014 return true; 6015 } 6016 6017 bool ValidateQueryDisplayAttribANGLE(const ValidationContext *val, 6018 const Display *display, 6019 const EGLint attribute, 6020 const EGLAttrib *value) 6021 { 6022 ANGLE_VALIDATION_TRY(ValidateQueryDisplayAttribBase(val, display, attribute)); 6023 return true; 6024 } 6025 6026 bool ValidateGetNativeClientBufferANDROID(const ValidationContext *val, 6027 const AHardwareBuffer *buffer) 6028 { 6029 // No extension check is done because no display is passed to eglGetNativeClientBufferANDROID 6030 // despite it being a display extension. No display is needed for the implementation though. 6031 if (buffer == nullptr) 6032 { 6033 val->setError(EGL_BAD_PARAMETER, "NULL buffer."); 6034 return false; 6035 } 6036 6037 return true; 6038 } 6039 6040 bool ValidateCreateNativeClientBufferANDROID(const ValidationContext *val, 6041 const egl::AttributeMap &attribMap) 6042 { 6043 attribMap.initializeWithoutValidation(); 6044 6045 if (attribMap.isEmpty() || attribMap.begin()->second == EGL_NONE) 6046 { 6047 val->setError(EGL_BAD_PARAMETER, "invalid attribute list."); 6048 return false; 6049 } 6050 6051 int width = attribMap.getAsInt(EGL_WIDTH, 0); 6052 int height = attribMap.getAsInt(EGL_HEIGHT, 0); 6053 int redSize = attribMap.getAsInt(EGL_RED_SIZE, 0); 6054 int greenSize = attribMap.getAsInt(EGL_GREEN_SIZE, 0); 6055 int blueSize = attribMap.getAsInt(EGL_BLUE_SIZE, 0); 6056 int alphaSize = attribMap.getAsInt(EGL_ALPHA_SIZE, 0); 6057 int usage = attribMap.getAsInt(EGL_NATIVE_BUFFER_USAGE_ANDROID, 0); 6058 6059 for (AttributeMap::const_iterator attributeIter = attribMap.begin(); 6060 attributeIter != attribMap.end(); attributeIter++) 6061 { 6062 EGLAttrib attribute = attributeIter->first; 6063 switch (attribute) 6064 { 6065 case EGL_WIDTH: 6066 case EGL_HEIGHT: 6067 // Validation done after the switch statement 6068 break; 6069 case EGL_RED_SIZE: 6070 case EGL_GREEN_SIZE: 6071 case EGL_BLUE_SIZE: 6072 case EGL_ALPHA_SIZE: 6073 if (redSize < 0 || greenSize < 0 || blueSize < 0 || alphaSize < 0) 6074 { 6075 val->setError(EGL_BAD_PARAMETER, "incorrect channel size requested"); 6076 return false; 6077 } 6078 break; 6079 case EGL_NATIVE_BUFFER_USAGE_ANDROID: 6080 // The buffer must be used for either a texture or a renderbuffer. 6081 if ((usage & ~(EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID | 6082 EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID | 6083 EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID)) != 0) 6084 { 6085 val->setError(EGL_BAD_PARAMETER, "invalid usage flag"); 6086 return false; 6087 } 6088 break; 6089 case EGL_NONE: 6090 break; 6091 default: 6092 val->setError(EGL_BAD_ATTRIBUTE, "invalid attribute"); 6093 return false; 6094 } 6095 } 6096 6097 // Validate EGL_WIDTH and EGL_HEIGHT values passed in. Done here to account 6098 // for the case where EGL_WIDTH and EGL_HEIGHT were not part of the attribute list. 6099 if (width <= 0 || height <= 0) 6100 { 6101 val->setError(EGL_BAD_PARAMETER, "incorrect buffer dimensions requested"); 6102 return false; 6103 } 6104 6105 if (gl::GetAndroidHardwareBufferFormatFromChannelSizes(attribMap) == 0) 6106 { 6107 val->setError(EGL_BAD_PARAMETER, "unsupported format"); 6108 return false; 6109 } 6110 return true; 6111 } 6112 6113 bool ValidateCopyMetalSharedEventANGLE(const ValidationContext *val, 6114 const Display *display, 6115 const Sync *sync) 6116 { 6117 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 6118 6119 if (!display->getExtensions().mtlSyncSharedEventANGLE) 6120 { 6121 val->setError(EGL_BAD_DISPLAY, "EGL_ANGLE_metal_shared_event_sync is not available."); 6122 return false; 6123 } 6124 6125 ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); 6126 6127 return true; 6128 } 6129 6130 bool ValidateDupNativeFenceFDANDROID(const ValidationContext *val, 6131 const Display *display, 6132 const Sync *sync) 6133 { 6134 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 6135 6136 if (!display->getExtensions().nativeFenceSyncANDROID) 6137 { 6138 val->setError(EGL_BAD_DISPLAY, "EGL_ANDROID_native_fence_sync extension is not available."); 6139 return false; 6140 } 6141 6142 ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); 6143 6144 return true; 6145 } 6146 6147 bool ValidateSwapBuffersWithFrameTokenANGLE(const ValidationContext *val, 6148 const Display *display, 6149 const Surface *surface, 6150 EGLFrameTokenANGLE frametoken) 6151 { 6152 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 6153 6154 if (!display->getExtensions().swapWithFrameToken) 6155 { 6156 val->setError(EGL_BAD_DISPLAY, "EGL_ANGLE_swap_buffers_with_frame_token is not available."); 6157 return false; 6158 } 6159 6160 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 6161 6162 return true; 6163 } 6164 6165 bool ValidatePrepareSwapBuffersANGLE(const ValidationContext *val, 6166 const Display *display, 6167 const Surface *surface) 6168 { 6169 return ValidateSwapBuffers(val, display, surface); 6170 } 6171 6172 bool ValidateSignalSyncKHR(const ValidationContext *val, 6173 const Display *display, 6174 const Sync *sync, 6175 EGLenum mode) 6176 { 6177 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 6178 6179 ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); 6180 6181 if (sync->getType() == EGL_SYNC_REUSABLE_KHR) 6182 { 6183 if (!display->getExtensions().reusableSyncKHR) 6184 { 6185 val->setError(EGL_BAD_MATCH, "EGL_KHR_reusable_sync extension is not available."); 6186 return false; 6187 } 6188 6189 if ((mode != EGL_SIGNALED_KHR) && (mode != EGL_UNSIGNALED_KHR)) 6190 { 6191 val->setError(EGL_BAD_PARAMETER, "eglSignalSyncKHR invalid mode."); 6192 return false; 6193 } 6194 6195 return true; 6196 } 6197 6198 val->setError(EGL_BAD_MATCH); 6199 return false; 6200 } 6201 6202 bool ValidateQuerySurfacePointerANGLE(const ValidationContext *val, 6203 const Display *display, 6204 const Surface *eglSurface, 6205 EGLint attribute, 6206 void *const *value) 6207 { 6208 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 6209 6210 if (!display->getExtensions().querySurfacePointer) 6211 { 6212 val->setError(EGL_BAD_ACCESS); 6213 return false; 6214 } 6215 6216 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface)); 6217 6218 // validate the attribute parameter 6219 switch (attribute) 6220 { 6221 case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: 6222 if (!display->getExtensions().surfaceD3DTexture2DShareHandle) 6223 { 6224 val->setError(EGL_BAD_ATTRIBUTE); 6225 return false; 6226 } 6227 break; 6228 case EGL_DXGI_KEYED_MUTEX_ANGLE: 6229 if (!display->getExtensions().keyedMutex) 6230 { 6231 val->setError(EGL_BAD_ATTRIBUTE); 6232 return false; 6233 } 6234 break; 6235 default: 6236 val->setError(EGL_BAD_ATTRIBUTE); 6237 return false; 6238 } 6239 6240 return true; 6241 } 6242 6243 bool ValidatePostSubBufferNV(const ValidationContext *val, 6244 const Display *display, 6245 const Surface *eglSurface, 6246 EGLint x, 6247 EGLint y, 6248 EGLint width, 6249 EGLint height) 6250 { 6251 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 6252 6253 if (!display->getExtensions().postSubBuffer) 6254 { 6255 val->setError(EGL_BAD_ACCESS); 6256 return false; 6257 } 6258 6259 if (x < 0 || y < 0 || width < 0 || height < 0) 6260 { 6261 val->setError(EGL_BAD_PARAMETER); 6262 return false; 6263 } 6264 6265 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface)); 6266 6267 if (display->isDeviceLost()) 6268 { 6269 val->setError(EGL_CONTEXT_LOST); 6270 return false; 6271 } 6272 6273 return true; 6274 } 6275 6276 bool ValidateQueryDeviceAttribEXT(const ValidationContext *val, 6277 const Device *device, 6278 EGLint attribute, 6279 const EGLAttrib *value) 6280 { 6281 ANGLE_VALIDATION_TRY(ValidateDevice(val, device)); 6282 6283 if (!Display::GetClientExtensions().deviceQueryEXT) 6284 { 6285 val->setError(EGL_BAD_ACCESS, "EGL_EXT_device_query not supported."); 6286 return false; 6287 } 6288 6289 // validate the attribute parameter 6290 switch (attribute) 6291 { 6292 case EGL_D3D11_DEVICE_ANGLE: 6293 case EGL_D3D9_DEVICE_ANGLE: 6294 if (!device->getExtensions().deviceD3D || device->getType() != attribute) 6295 { 6296 val->setError(EGL_BAD_ATTRIBUTE); 6297 return false; 6298 } 6299 break; 6300 case EGL_EAGL_CONTEXT_ANGLE: 6301 if (!device->getExtensions().deviceEAGL) 6302 { 6303 val->setError(EGL_BAD_ATTRIBUTE); 6304 return false; 6305 } 6306 break; 6307 case EGL_METAL_DEVICE_ANGLE: 6308 if (!device->getExtensions().deviceMetal) 6309 { 6310 val->setError(EGL_BAD_ATTRIBUTE); 6311 return false; 6312 } 6313 break; 6314 case EGL_VULKAN_VERSION_ANGLE: 6315 case EGL_VULKAN_INSTANCE_ANGLE: 6316 case EGL_VULKAN_INSTANCE_EXTENSIONS_ANGLE: 6317 case EGL_VULKAN_PHYSICAL_DEVICE_ANGLE: 6318 case EGL_VULKAN_DEVICE_ANGLE: 6319 case EGL_VULKAN_DEVICE_EXTENSIONS_ANGLE: 6320 case EGL_VULKAN_FEATURES_ANGLE: 6321 case EGL_VULKAN_QUEUE_ANGLE: 6322 case EGL_VULKAN_QUEUE_FAMILIY_INDEX_ANGLE: 6323 case EGL_VULKAN_GET_INSTANCE_PROC_ADDR: 6324 if (!device->getExtensions().deviceVulkan) 6325 { 6326 val->setError(EGL_BAD_ATTRIBUTE); 6327 return false; 6328 } 6329 break; 6330 case EGL_CGL_CONTEXT_ANGLE: 6331 case EGL_CGL_PIXEL_FORMAT_ANGLE: 6332 if (!device->getExtensions().deviceCGL) 6333 { 6334 val->setError(EGL_BAD_ATTRIBUTE); 6335 return false; 6336 } 6337 break; 6338 default: 6339 val->setError(EGL_BAD_ATTRIBUTE); 6340 return false; 6341 } 6342 return true; 6343 } 6344 6345 bool ValidateQueryDeviceStringEXT(const ValidationContext *val, const Device *device, EGLint name) 6346 { 6347 ANGLE_VALIDATION_TRY(ValidateDevice(val, device)); 6348 return true; 6349 } 6350 6351 bool ValidateReleaseHighPowerGPUANGLE(const ValidationContext *val, 6352 const Display *display, 6353 const gl::Context *context) 6354 { 6355 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 6356 return true; 6357 } 6358 6359 bool ValidateReacquireHighPowerGPUANGLE(const ValidationContext *val, 6360 const Display *display, 6361 const gl::Context *context) 6362 { 6363 ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); 6364 return true; 6365 } 6366 6367 bool ValidateHandleGPUSwitchANGLE(const ValidationContext *val, const Display *display) 6368 { 6369 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 6370 return true; 6371 } 6372 6373 bool ValidateForceGPUSwitchANGLE(const ValidationContext *val, 6374 const Display *display, 6375 EGLint gpuIDHigh, 6376 EGLint gpuIDLow) 6377 { 6378 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 6379 return true; 6380 } 6381 6382 bool ValidateGetCurrentDisplay(const ValidationContext *val) 6383 { 6384 return true; 6385 } 6386 6387 bool ValidateGetCurrentSurface(const ValidationContext *val, EGLint readdraw) 6388 { 6389 return true; 6390 } 6391 6392 bool ValidateGetDisplay(const ValidationContext *val, EGLNativeDisplayType display_id) 6393 { 6394 return true; 6395 } 6396 6397 bool ValidateGetError(const ValidationContext *val) 6398 { 6399 return true; 6400 } 6401 6402 bool ValidateGetProcAddress(const ValidationContext *val, const char *procname) 6403 { 6404 return true; 6405 } 6406 6407 bool ValidateQueryString(const ValidationContext *val, const Display *dpyPacked, EGLint name) 6408 { 6409 // The only situation where EGL_NO_DISPLAY is allowed is when querying 6410 // EGL_EXTENSIONS or EGL_VERSION. 6411 const bool canQueryWithoutDisplay = (name == EGL_VERSION || name == EGL_EXTENSIONS); 6412 6413 if (dpyPacked != nullptr || !canQueryWithoutDisplay) 6414 { 6415 ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpyPacked)); 6416 } 6417 6418 switch (name) 6419 { 6420 case EGL_CLIENT_APIS: 6421 case EGL_EXTENSIONS: 6422 case EGL_VENDOR: 6423 case EGL_VERSION: 6424 break; 6425 default: 6426 val->setError(EGL_BAD_PARAMETER); 6427 return false; 6428 } 6429 return true; 6430 } 6431 6432 bool ValidateWaitGL(const ValidationContext *val) 6433 { 6434 if (val->eglThread->getDisplay() == nullptr) 6435 { 6436 // EGL spec says this about eglWaitGL - 6437 // eglWaitGL is ignored if there is no current EGL rendering context for OpenGL ES. 6438 return true; 6439 } 6440 6441 ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay())); 6442 return true; 6443 } 6444 6445 bool ValidateQueryAPI(const ValidationContext *val) 6446 { 6447 return true; 6448 } 6449 6450 bool ValidateReleaseThread(const ValidationContext *val) 6451 { 6452 return true; 6453 } 6454 6455 bool ValidateWaitClient(const ValidationContext *val) 6456 { 6457 if (val->eglThread->getDisplay() == nullptr) 6458 { 6459 // EGL spec says this about eglWaitClient - 6460 // If there is no current context for the current rendering API, 6461 // the function has no effect but still returns EGL_TRUE. 6462 return true; 6463 } 6464 6465 ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay())); 6466 return true; 6467 } 6468 6469 bool ValidateGetCurrentContext(const ValidationContext *val) 6470 { 6471 return true; 6472 } 6473 6474 bool ValidateCreatePlatformPixmapSurface(const ValidationContext *val, 6475 const Display *dpyPacked, 6476 const Config *configPacked, 6477 const void *native_pixmap, 6478 const AttributeMap &attrib_listPacked) 6479 { 6480 EGLNativePixmapType nativePixmap = 6481 reinterpret_cast<EGLNativePixmapType>(const_cast<void *>(native_pixmap)); 6482 return ValidateCreatePixmapSurface(val, dpyPacked, configPacked, nativePixmap, 6483 attrib_listPacked); 6484 } 6485 6486 bool ValidateCreatePlatformWindowSurface(const ValidationContext *val, 6487 const Display *dpyPacked, 6488 const Config *configPacked, 6489 const void *native_window, 6490 const AttributeMap &attrib_listPacked) 6491 { 6492 EGLNativeWindowType nativeWindow = 6493 reinterpret_cast<EGLNativeWindowType>(const_cast<void *>(native_window)); 6494 return ValidateCreateWindowSurface(val, dpyPacked, configPacked, nativeWindow, 6495 attrib_listPacked); 6496 } 6497 6498 bool ValidateLockSurfaceKHR(const ValidationContext *val, 6499 const egl::Display *dpy, 6500 const Surface *surface, 6501 const AttributeMap &attributes) 6502 { 6503 ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy)); 6504 ANGLE_VALIDATION_TRY(ValidateSurface(val, dpy, surface)); 6505 6506 if (!dpy->getExtensions().lockSurface3KHR) 6507 { 6508 val->setError(EGL_BAD_ACCESS); 6509 return false; 6510 } 6511 6512 if (surface->isLocked()) 6513 { 6514 val->setError(EGL_BAD_ACCESS); 6515 return false; 6516 } 6517 6518 if ((surface->getConfig()->surfaceType & EGL_LOCK_SURFACE_BIT_KHR) == false) 6519 { 6520 val->setError(EGL_BAD_ACCESS, "Config does not support EGL_LOCK_SURFACE_BIT"); 6521 return false; 6522 } 6523 6524 if (surface->isCurrentOnAnyContext()) 6525 { 6526 val->setError(EGL_BAD_ACCESS, 6527 "Surface cannot be current to a context for eglLockSurface()"); 6528 return false; 6529 } 6530 6531 if (surface->hasProtectedContent()) 6532 { 6533 val->setError(EGL_BAD_ACCESS, "Surface cannot be protected content for eglLockSurface()"); 6534 return false; 6535 } 6536 6537 attributes.initializeWithoutValidation(); 6538 6539 for (const auto &attributeIter : attributes) 6540 { 6541 EGLAttrib attribute = attributeIter.first; 6542 EGLAttrib value = attributeIter.second; 6543 6544 switch (attribute) 6545 { 6546 case EGL_MAP_PRESERVE_PIXELS_KHR: 6547 if (!((value == EGL_FALSE) || (value == EGL_TRUE))) 6548 { 6549 val->setError(EGL_BAD_ATTRIBUTE, "Invalid EGL_MAP_PRESERVE_PIXELS_KHR value"); 6550 return false; 6551 } 6552 break; 6553 case EGL_LOCK_USAGE_HINT_KHR: 6554 if ((value & (EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR)) != value) 6555 { 6556 val->setError(EGL_BAD_ATTRIBUTE, "Invalid EGL_LOCK_USAGE_HINT_KHR value"); 6557 return false; 6558 } 6559 break; 6560 default: 6561 val->setError(EGL_BAD_ATTRIBUTE, "Invalid query surface64 attribute"); 6562 return false; 6563 } 6564 } 6565 6566 return true; 6567 } 6568 6569 bool ValidateQuerySurface64KHR(const ValidationContext *val, 6570 const egl::Display *dpy, 6571 const Surface *surface, 6572 EGLint attribute, 6573 const EGLAttribKHR *value) 6574 { 6575 ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy)); 6576 ANGLE_VALIDATION_TRY(ValidateSurface(val, dpy, surface)); 6577 6578 if (!dpy->getExtensions().lockSurface3KHR) 6579 { 6580 val->setError(EGL_BAD_ACCESS); 6581 return false; 6582 } 6583 6584 switch (attribute) 6585 { 6586 case EGL_BITMAP_PITCH_KHR: 6587 case EGL_BITMAP_ORIGIN_KHR: 6588 case EGL_BITMAP_PIXEL_RED_OFFSET_KHR: 6589 case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR: 6590 case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR: 6591 case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR: 6592 case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR: 6593 case EGL_BITMAP_PIXEL_SIZE_KHR: 6594 case EGL_BITMAP_POINTER_KHR: 6595 break; 6596 default: 6597 val->setError(EGL_BAD_ATTRIBUTE, "Invalid eglQuerySurface64 attribute"); 6598 return false; 6599 } 6600 6601 if (value == nullptr) 6602 { 6603 val->setError(EGL_BAD_PARAMETER, "value is NULL."); 6604 return false; 6605 } 6606 6607 if (!surface->isLocked()) 6608 { 6609 val->setError(EGL_BAD_ACCESS, "Surface is not locked"); 6610 return false; 6611 } 6612 6613 return true; 6614 } 6615 6616 bool ValidateUnlockSurfaceKHR(const ValidationContext *val, 6617 const egl::Display *dpy, 6618 const Surface *surface) 6619 { 6620 ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy)); 6621 ANGLE_VALIDATION_TRY(ValidateSurface(val, dpy, surface)); 6622 6623 if (!dpy->getExtensions().lockSurface3KHR) 6624 { 6625 val->setError(EGL_BAD_ACCESS); 6626 return false; 6627 } 6628 6629 if (!surface->isLocked()) 6630 { 6631 val->setError(EGL_BAD_PARAMETER, "Surface is not locked."); 6632 return false; 6633 } 6634 6635 return true; 6636 } 6637 6638 bool ValidateExportVkImageANGLE(const ValidationContext *val, 6639 const Display *dpy, 6640 const Image *image, 6641 const void *vkImage, 6642 const void *vkImageCreateInfo) 6643 { 6644 ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy)); 6645 ANGLE_VALIDATION_TRY(ValidateImage(val, dpy, image)); 6646 6647 if (!dpy->getExtensions().vulkanImageANGLE) 6648 { 6649 val->setError(EGL_BAD_ACCESS); 6650 return false; 6651 } 6652 6653 if (!vkImage) 6654 { 6655 val->setError(EGL_BAD_PARAMETER, "Output VkImage pointer is null."); 6656 return false; 6657 } 6658 6659 if (!vkImageCreateInfo) 6660 { 6661 val->setError(EGL_BAD_PARAMETER, "Output VkImageCreateInfo pointer is null."); 6662 return false; 6663 } 6664 6665 return true; 6666 } 6667 6668 bool ValidateSetDamageRegionKHR(const ValidationContext *val, 6669 const Display *display, 6670 const Surface *surface, 6671 const EGLint *rects, 6672 EGLint n_rects) 6673 { 6674 ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); 6675 ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); 6676 6677 if (!(surface->getType() & EGL_WINDOW_BIT)) 6678 { 6679 val->setError(EGL_BAD_MATCH, "surface is not a postable surface"); 6680 return false; 6681 } 6682 6683 if (surface != val->eglThread->getCurrentDrawSurface()) 6684 { 6685 val->setError(EGL_BAD_MATCH, 6686 "surface is not the current draw surface for the calling thread"); 6687 return false; 6688 } 6689 6690 if (surface->getSwapBehavior() != EGL_BUFFER_DESTROYED) 6691 { 6692 val->setError(EGL_BAD_MATCH, "surface's swap behavior is not EGL_BUFFER_DESTROYED"); 6693 return false; 6694 } 6695 6696 if (surface->isDamageRegionSet()) 6697 { 6698 val->setError( 6699 EGL_BAD_ACCESS, 6700 "damage region has already been set on surface since the most recent frame boundary"); 6701 return false; 6702 } 6703 6704 if (!surface->bufferAgeQueriedSinceLastSwap()) 6705 { 6706 val->setError(EGL_BAD_ACCESS, 6707 "EGL_BUFFER_AGE_KHR attribute of surface has not been queried since the most " 6708 "recent frame boundary"); 6709 return false; 6710 } 6711 6712 return true; 6713 } 6714 6715 bool ValidateQueryDmaBufFormatsEXT(ValidationContext const *val, 6716 Display const *dpy, 6717 EGLint max_formats, 6718 const EGLint *formats, 6719 const EGLint *num_formats) 6720 { 6721 ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy)); 6722 6723 if (!dpy->getExtensions().imageDmaBufImportModifiersEXT) 6724 { 6725 val->setError(EGL_BAD_ACCESS, "EGL_EXT_dma_buf_import_modfier not supported"); 6726 return false; 6727 } 6728 6729 if (max_formats < 0) 6730 { 6731 val->setError(EGL_BAD_PARAMETER, "max_formats should not be negative"); 6732 return false; 6733 } 6734 6735 if (max_formats > 0 && formats == nullptr) 6736 { 6737 val->setError(EGL_BAD_PARAMETER, "if max_formats is positive, formats should not be NULL"); 6738 return false; 6739 } 6740 6741 return true; 6742 } 6743 6744 bool ValidateQueryDmaBufModifiersEXT(ValidationContext const *val, 6745 Display const *dpy, 6746 EGLint format, 6747 EGLint max_modifiers, 6748 const EGLuint64KHR *modifiers, 6749 const EGLBoolean *external_only, 6750 const EGLint *num_modifiers) 6751 { 6752 ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy)); 6753 6754 if (!dpy->getExtensions().imageDmaBufImportModifiersEXT) 6755 { 6756 val->setError(EGL_BAD_ACCESS, "EGL_EXT_dma_buf_import_modfier not supported"); 6757 return false; 6758 } 6759 6760 if (max_modifiers < 0) 6761 { 6762 val->setError(EGL_BAD_PARAMETER, "max_modifiers should not be negative"); 6763 return false; 6764 } 6765 6766 if (max_modifiers > 0 && modifiers == nullptr) 6767 { 6768 val->setError(EGL_BAD_PARAMETER, 6769 "if max_modifiers is positive, modifiers should not be NULL"); 6770 return false; 6771 } 6772 6773 if (!dpy->supportsDmaBufFormat(format)) 6774 { 6775 val->setError(EGL_BAD_PARAMETER, 6776 "format should be one of the formats advertised by QueryDmaBufFormatsEXT"); 6777 return false; 6778 } 6779 return true; 6780 } 6781 6782 } // namespace egl