1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2008 VMware, Inc. 4848b8605Smrg * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com> 5848b8605Smrg * Copyright 2010 LunarG, Inc. 6848b8605Smrg * All Rights Reserved. 7848b8605Smrg * 8848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 9848b8605Smrg * copy of this software and associated documentation files (the 10848b8605Smrg * "Software"), to deal in the Software without restriction, including 11848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 12848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 13848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 14848b8605Smrg * the following conditions: 15848b8605Smrg * 16848b8605Smrg * The above copyright notice and this permission notice (including the 17848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 18848b8605Smrg * of the Software. 19848b8605Smrg * 20848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26848b8605Smrg * DEALINGS IN THE SOFTWARE. 27848b8605Smrg * 28848b8605Smrg **************************************************************************/ 29848b8605Smrg 30848b8605Smrg 31848b8605Smrg/** 32848b8605Smrg * Surface-related functions. 33848b8605Smrg */ 34848b8605Smrg 35848b8605Smrg 36848b8605Smrg#include <assert.h> 37848b8605Smrg#include <stdlib.h> 38848b8605Smrg#include <string.h> 39b8e80941Smrg#include "egldefines.h" 40848b8605Smrg#include "egldisplay.h" 41848b8605Smrg#include "egldriver.h" 42848b8605Smrg#include "eglcontext.h" 43848b8605Smrg#include "eglconfig.h" 44848b8605Smrg#include "eglcurrent.h" 45848b8605Smrg#include "egllog.h" 46848b8605Smrg#include "eglsurface.h" 47848b8605Smrg 48b8e80941Smrg#include "util/macros.h" 49848b8605Smrg 50848b8605Smrg/** 51848b8605Smrg * Parse the list of surface attributes and return the proper error code. 52848b8605Smrg */ 53848b8605Smrgstatic EGLint 54848b8605Smrg_eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) 55848b8605Smrg{ 56b8e80941Smrg _EGLDisplay *disp = surf->Resource.Display; 57848b8605Smrg EGLint type = surf->Type; 58848b8605Smrg EGLint texture_type = EGL_PBUFFER_BIT; 59848b8605Smrg EGLint i, err = EGL_SUCCESS; 60b8e80941Smrg EGLint attr = EGL_NONE; 61b8e80941Smrg EGLint val = EGL_NONE; 62848b8605Smrg 63848b8605Smrg if (!attrib_list) 64848b8605Smrg return EGL_SUCCESS; 65848b8605Smrg 66b8e80941Smrg if (disp->Extensions.NOK_texture_from_pixmap) 67848b8605Smrg texture_type |= EGL_PIXMAP_BIT; 68848b8605Smrg 69848b8605Smrg for (i = 0; attrib_list[i] != EGL_NONE; i++) { 70b8e80941Smrg attr = attrib_list[i++]; 71b8e80941Smrg val = attrib_list[i]; 72848b8605Smrg 73848b8605Smrg switch (attr) { 74848b8605Smrg /* common attributes */ 75b8e80941Smrg case EGL_GL_COLORSPACE_KHR: 76b8e80941Smrg if (!disp->Extensions.KHR_gl_colorspace) { 77b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 78b8e80941Smrg break; 79b8e80941Smrg } 80b8e80941Smrg switch (val) { 81b8e80941Smrg case EGL_GL_COLORSPACE_SRGB_KHR: 82b8e80941Smrg case EGL_GL_COLORSPACE_LINEAR_KHR: 83b8e80941Smrg break; 84b8e80941Smrg default: 85b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 86b8e80941Smrg } 87b8e80941Smrg if (err != EGL_SUCCESS) 88b8e80941Smrg break; 89b8e80941Smrg surf->GLColorspace = val; 90b8e80941Smrg break; 91b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT: 92b8e80941Smrg if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) { 93b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 94b8e80941Smrg break; 95b8e80941Smrg } 96b8e80941Smrg surf->HdrMetadata.display_primary_r.x = val; 97b8e80941Smrg break; 98b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT: 99b8e80941Smrg if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) { 100b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 101b8e80941Smrg break; 102b8e80941Smrg } 103b8e80941Smrg surf->HdrMetadata.display_primary_r.y = val; 104b8e80941Smrg break; 105b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT: 106b8e80941Smrg if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) { 107b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 108b8e80941Smrg break; 109b8e80941Smrg } 110b8e80941Smrg surf->HdrMetadata.display_primary_g.x = val; 111b8e80941Smrg break; 112b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT: 113b8e80941Smrg if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) { 114b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 115b8e80941Smrg break; 116b8e80941Smrg } 117b8e80941Smrg surf->HdrMetadata.display_primary_g.y = val; 118b8e80941Smrg break; 119b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT: 120b8e80941Smrg if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) { 121b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 122b8e80941Smrg break; 123b8e80941Smrg } 124b8e80941Smrg surf->HdrMetadata.display_primary_b.x = val; 125b8e80941Smrg break; 126b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT: 127b8e80941Smrg if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) { 128b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 129b8e80941Smrg break; 130b8e80941Smrg } 131b8e80941Smrg surf->HdrMetadata.display_primary_b.y = val; 132b8e80941Smrg break; 133b8e80941Smrg case EGL_SMPTE2086_WHITE_POINT_X_EXT: 134b8e80941Smrg if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) { 135b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 136b8e80941Smrg break; 137b8e80941Smrg } 138b8e80941Smrg surf->HdrMetadata.white_point.x = val; 139b8e80941Smrg break; 140b8e80941Smrg case EGL_SMPTE2086_WHITE_POINT_Y_EXT: 141b8e80941Smrg if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) { 142b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 143b8e80941Smrg break; 144b8e80941Smrg } 145b8e80941Smrg surf->HdrMetadata.white_point.y = val; 146b8e80941Smrg break; 147b8e80941Smrg case EGL_SMPTE2086_MAX_LUMINANCE_EXT: 148b8e80941Smrg if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) { 149b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 150b8e80941Smrg break; 151b8e80941Smrg } 152b8e80941Smrg surf->HdrMetadata.max_luminance = val; 153b8e80941Smrg break; 154b8e80941Smrg case EGL_SMPTE2086_MIN_LUMINANCE_EXT: 155b8e80941Smrg if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) { 156b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 157b8e80941Smrg break; 158b8e80941Smrg } 159b8e80941Smrg surf->HdrMetadata.min_luminance = val; 160b8e80941Smrg break; 161b8e80941Smrg case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT: 162b8e80941Smrg if (!disp->Extensions.EXT_surface_CTA861_3_metadata) { 163b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 164b8e80941Smrg break; 165b8e80941Smrg } 166b8e80941Smrg surf->HdrMetadata.max_cll = val; 167b8e80941Smrg break; 168b8e80941Smrg case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT: 169b8e80941Smrg if (!disp->Extensions.EXT_surface_CTA861_3_metadata) { 170b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 171b8e80941Smrg break; 172b8e80941Smrg } 173b8e80941Smrg surf->HdrMetadata.max_fall = val; 174b8e80941Smrg break; 175848b8605Smrg case EGL_VG_COLORSPACE: 176848b8605Smrg switch (val) { 177848b8605Smrg case EGL_VG_COLORSPACE_sRGB: 178848b8605Smrg case EGL_VG_COLORSPACE_LINEAR: 179848b8605Smrg break; 180848b8605Smrg default: 181848b8605Smrg err = EGL_BAD_ATTRIBUTE; 182848b8605Smrg break; 183848b8605Smrg } 184848b8605Smrg if (err != EGL_SUCCESS) 185848b8605Smrg break; 186848b8605Smrg surf->VGColorspace = val; 187848b8605Smrg break; 188848b8605Smrg case EGL_VG_ALPHA_FORMAT: 189848b8605Smrg switch (val) { 190848b8605Smrg case EGL_VG_ALPHA_FORMAT_NONPRE: 191848b8605Smrg case EGL_VG_ALPHA_FORMAT_PRE: 192848b8605Smrg break; 193848b8605Smrg default: 194848b8605Smrg err = EGL_BAD_ATTRIBUTE; 195848b8605Smrg break; 196848b8605Smrg } 197848b8605Smrg if (err != EGL_SUCCESS) 198848b8605Smrg break; 199848b8605Smrg surf->VGAlphaFormat = val; 200848b8605Smrg break; 201848b8605Smrg /* window surface attributes */ 202848b8605Smrg case EGL_RENDER_BUFFER: 203848b8605Smrg if (type != EGL_WINDOW_BIT) { 204848b8605Smrg err = EGL_BAD_ATTRIBUTE; 205848b8605Smrg break; 206848b8605Smrg } 207848b8605Smrg if (val != EGL_BACK_BUFFER && val != EGL_SINGLE_BUFFER) { 208848b8605Smrg err = EGL_BAD_ATTRIBUTE; 209848b8605Smrg break; 210848b8605Smrg } 211b8e80941Smrg surf->RequestedRenderBuffer = val; 212b8e80941Smrg if (surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR) { 213b8e80941Smrg /* Unlike normal EGLSurfaces, one with a mutable render buffer 214b8e80941Smrg * uses the application-chosen render buffer. 215b8e80941Smrg */ 216b8e80941Smrg surf->ActiveRenderBuffer = val; 217b8e80941Smrg } 218848b8605Smrg break; 219848b8605Smrg case EGL_POST_SUB_BUFFER_SUPPORTED_NV: 220b8e80941Smrg if (!disp->Extensions.NV_post_sub_buffer || 221848b8605Smrg type != EGL_WINDOW_BIT) { 222848b8605Smrg err = EGL_BAD_ATTRIBUTE; 223848b8605Smrg break; 224848b8605Smrg } 225848b8605Smrg if (val != EGL_TRUE && val != EGL_FALSE) { 226848b8605Smrg err = EGL_BAD_PARAMETER; 227848b8605Smrg break; 228848b8605Smrg } 229848b8605Smrg surf->PostSubBufferSupportedNV = val; 230848b8605Smrg break; 231848b8605Smrg /* pbuffer surface attributes */ 232848b8605Smrg case EGL_WIDTH: 233848b8605Smrg if (type != EGL_PBUFFER_BIT) { 234848b8605Smrg err = EGL_BAD_ATTRIBUTE; 235848b8605Smrg break; 236848b8605Smrg } 237848b8605Smrg if (val < 0) { 238848b8605Smrg err = EGL_BAD_PARAMETER; 239848b8605Smrg break; 240848b8605Smrg } 241848b8605Smrg surf->Width = val; 242848b8605Smrg break; 243848b8605Smrg case EGL_HEIGHT: 244848b8605Smrg if (type != EGL_PBUFFER_BIT) { 245848b8605Smrg err = EGL_BAD_ATTRIBUTE; 246848b8605Smrg break; 247848b8605Smrg } 248848b8605Smrg if (val < 0) { 249848b8605Smrg err = EGL_BAD_PARAMETER; 250848b8605Smrg break; 251848b8605Smrg } 252848b8605Smrg surf->Height = val; 253848b8605Smrg break; 254848b8605Smrg case EGL_LARGEST_PBUFFER: 255848b8605Smrg if (type != EGL_PBUFFER_BIT) { 256848b8605Smrg err = EGL_BAD_ATTRIBUTE; 257848b8605Smrg break; 258848b8605Smrg } 259848b8605Smrg surf->LargestPbuffer = !!val; 260848b8605Smrg break; 261848b8605Smrg /* for eglBindTexImage */ 262848b8605Smrg case EGL_TEXTURE_FORMAT: 263848b8605Smrg if (!(type & texture_type)) { 264848b8605Smrg err = EGL_BAD_ATTRIBUTE; 265848b8605Smrg break; 266848b8605Smrg } 267b8e80941Smrg 268848b8605Smrg switch (val) { 269848b8605Smrg case EGL_TEXTURE_RGB: 270848b8605Smrg case EGL_TEXTURE_RGBA: 271848b8605Smrg case EGL_NO_TEXTURE: 272848b8605Smrg break; 273848b8605Smrg default: 274848b8605Smrg err = EGL_BAD_ATTRIBUTE; 275848b8605Smrg break; 276848b8605Smrg } 277848b8605Smrg if (err != EGL_SUCCESS) 278848b8605Smrg break; 279848b8605Smrg surf->TextureFormat = val; 280848b8605Smrg break; 281848b8605Smrg case EGL_TEXTURE_TARGET: 282848b8605Smrg if (!(type & texture_type)) { 283848b8605Smrg err = EGL_BAD_ATTRIBUTE; 284848b8605Smrg break; 285848b8605Smrg } 286b8e80941Smrg 287848b8605Smrg switch (val) { 288848b8605Smrg case EGL_TEXTURE_2D: 289848b8605Smrg case EGL_NO_TEXTURE: 290848b8605Smrg break; 291848b8605Smrg default: 292848b8605Smrg err = EGL_BAD_ATTRIBUTE; 293848b8605Smrg break; 294848b8605Smrg } 295848b8605Smrg if (err != EGL_SUCCESS) 296848b8605Smrg break; 297848b8605Smrg surf->TextureTarget = val; 298848b8605Smrg break; 299848b8605Smrg case EGL_MIPMAP_TEXTURE: 300848b8605Smrg if (!(type & texture_type)) { 301848b8605Smrg err = EGL_BAD_ATTRIBUTE; 302848b8605Smrg break; 303848b8605Smrg } 304848b8605Smrg surf->MipmapTexture = !!val; 305848b8605Smrg break; 306848b8605Smrg /* no pixmap surface specific attributes */ 307848b8605Smrg default: 308848b8605Smrg err = EGL_BAD_ATTRIBUTE; 309848b8605Smrg break; 310848b8605Smrg } 311848b8605Smrg 312b8e80941Smrg if (err != EGL_SUCCESS) 313848b8605Smrg break; 314b8e80941Smrg } 315b8e80941Smrg 316b8e80941Smrg if (err == EGL_SUCCESS && type == EGL_PBUFFER_BIT) { 317b8e80941Smrg if ((surf->TextureTarget == EGL_NO_TEXTURE && surf->TextureFormat != EGL_NO_TEXTURE) || 318b8e80941Smrg (surf->TextureFormat == EGL_NO_TEXTURE && surf->TextureTarget != EGL_NO_TEXTURE)) { 319b8e80941Smrg attr = surf->TextureTarget == EGL_NO_TEXTURE ? EGL_TEXTURE_TARGET : EGL_TEXTURE_FORMAT; 320b8e80941Smrg err = EGL_BAD_MATCH; 321848b8605Smrg } 322848b8605Smrg } 323848b8605Smrg 324b8e80941Smrg if (err != EGL_SUCCESS) 325b8e80941Smrg _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr); 326b8e80941Smrg 327848b8605Smrg return err; 328848b8605Smrg} 329848b8605Smrg 330848b8605Smrg 331848b8605Smrg/** 332848b8605Smrg * Do error check on parameters and initialize the given _EGLSurface object. 333848b8605Smrg * \return EGL_TRUE if no errors, EGL_FALSE otherwise. 334848b8605Smrg */ 335848b8605SmrgEGLBoolean 336b8e80941Smrg_eglInitSurface(_EGLSurface *surf, _EGLDisplay *disp, EGLint type, 337848b8605Smrg _EGLConfig *conf, const EGLint *attrib_list) 338848b8605Smrg{ 339848b8605Smrg const char *func; 340848b8605Smrg EGLint renderBuffer = EGL_BACK_BUFFER; 341b8e80941Smrg EGLint swapBehavior = EGL_BUFFER_DESTROYED; 342848b8605Smrg EGLint err; 343848b8605Smrg 344b8e80941Smrg /* Swap behavior can be preserved only if config supports this. */ 345b8e80941Smrg if (conf->SurfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) 346b8e80941Smrg swapBehavior = EGL_BUFFER_PRESERVED; 347b8e80941Smrg 348848b8605Smrg switch (type) { 349848b8605Smrg case EGL_WINDOW_BIT: 350848b8605Smrg func = "eglCreateWindowSurface"; 351848b8605Smrg swapBehavior = EGL_BUFFER_DESTROYED; 352848b8605Smrg break; 353848b8605Smrg case EGL_PIXMAP_BIT: 354848b8605Smrg func = "eglCreatePixmapSurface"; 355848b8605Smrg renderBuffer = EGL_SINGLE_BUFFER; 356848b8605Smrg break; 357848b8605Smrg case EGL_PBUFFER_BIT: 358848b8605Smrg func = "eglCreatePBufferSurface"; 359848b8605Smrg break; 360848b8605Smrg default: 361848b8605Smrg _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface"); 362848b8605Smrg return EGL_FALSE; 363848b8605Smrg } 364848b8605Smrg 365b8e80941Smrg if ((conf->SurfaceType & type) == 0) 366848b8605Smrg /* The config can't be used to create a surface of this type */ 367b8e80941Smrg return _eglError(EGL_BAD_MATCH, func); 368848b8605Smrg 369b8e80941Smrg _eglInitResource(&surf->Resource, sizeof(*surf), disp); 370848b8605Smrg surf->Type = type; 371848b8605Smrg surf->Config = conf; 372b8e80941Smrg surf->Lost = EGL_FALSE; 373848b8605Smrg 374848b8605Smrg surf->Width = 0; 375848b8605Smrg surf->Height = 0; 376848b8605Smrg surf->TextureFormat = EGL_NO_TEXTURE; 377848b8605Smrg surf->TextureTarget = EGL_NO_TEXTURE; 378848b8605Smrg surf->MipmapTexture = EGL_FALSE; 379848b8605Smrg surf->LargestPbuffer = EGL_FALSE; 380b8e80941Smrg surf->RequestedRenderBuffer = renderBuffer; 381b8e80941Smrg surf->ActiveRenderBuffer = renderBuffer; 382848b8605Smrg surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE; 383848b8605Smrg surf->VGColorspace = EGL_VG_COLORSPACE_sRGB; 384b8e80941Smrg surf->GLColorspace = EGL_GL_COLORSPACE_LINEAR_KHR; 385848b8605Smrg 386848b8605Smrg surf->MipmapLevel = 0; 387848b8605Smrg surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT; 388848b8605Smrg surf->SwapBehavior = swapBehavior; 389848b8605Smrg 390848b8605Smrg surf->HorizontalResolution = EGL_UNKNOWN; 391848b8605Smrg surf->VerticalResolution = EGL_UNKNOWN; 392848b8605Smrg surf->AspectRatio = EGL_UNKNOWN; 393848b8605Smrg 394848b8605Smrg surf->PostSubBufferSupportedNV = EGL_FALSE; 395b8e80941Smrg surf->SetDamageRegionCalled = EGL_FALSE; 396b8e80941Smrg surf->BufferAgeRead = EGL_FALSE; 397848b8605Smrg 398848b8605Smrg /* the default swap interval is 1 */ 399b8e80941Smrg surf->SwapInterval = 1; 400b8e80941Smrg 401b8e80941Smrg surf->HdrMetadata.display_primary_r.x = EGL_DONT_CARE; 402b8e80941Smrg surf->HdrMetadata.display_primary_r.y = EGL_DONT_CARE; 403b8e80941Smrg surf->HdrMetadata.display_primary_g.x = EGL_DONT_CARE; 404b8e80941Smrg surf->HdrMetadata.display_primary_g.y = EGL_DONT_CARE; 405b8e80941Smrg surf->HdrMetadata.display_primary_b.x = EGL_DONT_CARE; 406b8e80941Smrg surf->HdrMetadata.display_primary_b.y = EGL_DONT_CARE; 407b8e80941Smrg surf->HdrMetadata.white_point.x = EGL_DONT_CARE; 408b8e80941Smrg surf->HdrMetadata.white_point.y = EGL_DONT_CARE; 409b8e80941Smrg surf->HdrMetadata.max_luminance = EGL_DONT_CARE; 410b8e80941Smrg surf->HdrMetadata.min_luminance = EGL_DONT_CARE; 411b8e80941Smrg surf->HdrMetadata.max_cll = EGL_DONT_CARE; 412b8e80941Smrg surf->HdrMetadata.max_fall = EGL_DONT_CARE; 413848b8605Smrg 414848b8605Smrg err = _eglParseSurfaceAttribList(surf, attrib_list); 415848b8605Smrg if (err != EGL_SUCCESS) 416848b8605Smrg return _eglError(err, func); 417848b8605Smrg 418b8e80941Smrg /* if EGL_LARGEST_PBUFFER in use, clamp width and height */ 419b8e80941Smrg if (surf->LargestPbuffer) { 420b8e80941Smrg surf->Width = MIN2(surf->Width, _EGL_MAX_PBUFFER_WIDTH); 421b8e80941Smrg surf->Height = MIN2(surf->Height, _EGL_MAX_PBUFFER_HEIGHT); 422b8e80941Smrg } 423b8e80941Smrg 424848b8605Smrg return EGL_TRUE; 425848b8605Smrg} 426848b8605Smrg 427848b8605Smrg 428848b8605SmrgEGLBoolean 429b8e80941Smrg_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface, 430848b8605Smrg EGLint attribute, EGLint *value) 431848b8605Smrg{ 432848b8605Smrg switch (attribute) { 433848b8605Smrg case EGL_WIDTH: 434848b8605Smrg *value = surface->Width; 435848b8605Smrg break; 436848b8605Smrg case EGL_HEIGHT: 437848b8605Smrg *value = surface->Height; 438848b8605Smrg break; 439848b8605Smrg case EGL_CONFIG_ID: 440848b8605Smrg *value = surface->Config->ConfigID; 441848b8605Smrg break; 442848b8605Smrg case EGL_LARGEST_PBUFFER: 443b8e80941Smrg if (surface->Type == EGL_PBUFFER_BIT) 444b8e80941Smrg *value = surface->LargestPbuffer; 445848b8605Smrg break; 446848b8605Smrg case EGL_TEXTURE_FORMAT: 447848b8605Smrg /* texture attributes: only for pbuffers, no error otherwise */ 448848b8605Smrg if (surface->Type == EGL_PBUFFER_BIT) 449848b8605Smrg *value = surface->TextureFormat; 450848b8605Smrg break; 451848b8605Smrg case EGL_TEXTURE_TARGET: 452848b8605Smrg if (surface->Type == EGL_PBUFFER_BIT) 453848b8605Smrg *value = surface->TextureTarget; 454848b8605Smrg break; 455848b8605Smrg case EGL_MIPMAP_TEXTURE: 456848b8605Smrg if (surface->Type == EGL_PBUFFER_BIT) 457848b8605Smrg *value = surface->MipmapTexture; 458848b8605Smrg break; 459848b8605Smrg case EGL_MIPMAP_LEVEL: 460848b8605Smrg if (surface->Type == EGL_PBUFFER_BIT) 461848b8605Smrg *value = surface->MipmapLevel; 462848b8605Smrg break; 463848b8605Smrg case EGL_SWAP_BEHAVIOR: 464848b8605Smrg *value = surface->SwapBehavior; 465848b8605Smrg break; 466848b8605Smrg case EGL_RENDER_BUFFER: 467b8e80941Smrg /* From the EGL_KHR_mutable_render_buffer spec (v12): 468b8e80941Smrg * 469b8e80941Smrg * Querying EGL_RENDER_BUFFER returns the buffer which client API 470b8e80941Smrg * rendering is requested to use. For a window surface, this is the 471b8e80941Smrg * attribute value specified when the surface was created or last set 472b8e80941Smrg * via eglSurfaceAttrib. 473b8e80941Smrg * 474b8e80941Smrg * In other words, querying a window surface returns the value most 475b8e80941Smrg * recently *requested* by the user. 476b8e80941Smrg * 477b8e80941Smrg * The paragraph continues in the EGL 1.5 spec (2014.08.27): 478b8e80941Smrg * 479b8e80941Smrg * For a pbuffer surface, it is always EGL_BACK_BUFFER . For a pixmap 480b8e80941Smrg * surface, it is always EGL_SINGLE_BUFFER . To determine the actual 481b8e80941Smrg * buffer being rendered to by a context, call eglQueryContext. 482b8e80941Smrg */ 483b8e80941Smrg switch (surface->Type) { 484b8e80941Smrg default: 485b8e80941Smrg unreachable("bad EGLSurface type"); 486b8e80941Smrg case EGL_WINDOW_BIT: 487b8e80941Smrg *value = surface->RequestedRenderBuffer; 488b8e80941Smrg break; 489b8e80941Smrg case EGL_PBUFFER_BIT: 490b8e80941Smrg *value = EGL_BACK_BUFFER; 491b8e80941Smrg break; 492b8e80941Smrg case EGL_PIXMAP_BIT: 493b8e80941Smrg *value = EGL_SINGLE_BUFFER; 494b8e80941Smrg break; 495b8e80941Smrg } 496848b8605Smrg break; 497848b8605Smrg case EGL_PIXEL_ASPECT_RATIO: 498848b8605Smrg *value = surface->AspectRatio; 499848b8605Smrg break; 500848b8605Smrg case EGL_HORIZONTAL_RESOLUTION: 501848b8605Smrg *value = surface->HorizontalResolution; 502848b8605Smrg break; 503848b8605Smrg case EGL_VERTICAL_RESOLUTION: 504848b8605Smrg *value = surface->VerticalResolution; 505848b8605Smrg break; 506848b8605Smrg case EGL_MULTISAMPLE_RESOLVE: 507848b8605Smrg *value = surface->MultisampleResolve; 508848b8605Smrg break; 509848b8605Smrg case EGL_VG_ALPHA_FORMAT: 510848b8605Smrg *value = surface->VGAlphaFormat; 511848b8605Smrg break; 512848b8605Smrg case EGL_VG_COLORSPACE: 513848b8605Smrg *value = surface->VGColorspace; 514848b8605Smrg break; 515b8e80941Smrg case EGL_GL_COLORSPACE_KHR: 516b8e80941Smrg if (!disp->Extensions.KHR_gl_colorspace) 517b8e80941Smrg return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); 518b8e80941Smrg 519b8e80941Smrg *value = surface->GLColorspace; 520b8e80941Smrg break; 521848b8605Smrg case EGL_POST_SUB_BUFFER_SUPPORTED_NV: 522848b8605Smrg *value = surface->PostSubBufferSupportedNV; 523848b8605Smrg break; 524848b8605Smrg case EGL_BUFFER_AGE_EXT: 525b8e80941Smrg /* Both EXT_buffer_age and KHR_partial_update accept EGL_BUFFER_AGE_EXT. 526b8e80941Smrg * To be precise, the KHR one accepts EGL_BUFFER_AGE_KHR which is an 527b8e80941Smrg * alias with the same numeric value. 528b8e80941Smrg */ 529b8e80941Smrg if (!disp->Extensions.EXT_buffer_age && 530b8e80941Smrg !disp->Extensions.KHR_partial_update) 531b8e80941Smrg return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); 532b8e80941Smrg 533b8e80941Smrg _EGLContext *ctx = _eglGetCurrentContext(); 534b8e80941Smrg EGLint result = drv->API.QueryBufferAge(drv, disp, surface); 535b8e80941Smrg /* error happened */ 536b8e80941Smrg if (result < 0) 537848b8605Smrg return EGL_FALSE; 538b8e80941Smrg if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 539b8e80941Smrg ctx->DrawSurface != surface) 540b8e80941Smrg return _eglError(EGL_BAD_SURFACE, "eglQuerySurface"); 541b8e80941Smrg 542b8e80941Smrg *value = result; 543b8e80941Smrg surface->BufferAgeRead = EGL_TRUE; 544b8e80941Smrg break; 545b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT: 546b8e80941Smrg *value = surface->HdrMetadata.display_primary_r.x; 547b8e80941Smrg break; 548b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT: 549b8e80941Smrg *value = surface->HdrMetadata.display_primary_r.y; 550b8e80941Smrg break; 551b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT: 552b8e80941Smrg *value = surface->HdrMetadata.display_primary_g.x; 553b8e80941Smrg break; 554b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT: 555b8e80941Smrg *value = surface->HdrMetadata.display_primary_g.y; 556b8e80941Smrg break; 557b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT: 558b8e80941Smrg *value = surface->HdrMetadata.display_primary_b.x; 559b8e80941Smrg break; 560b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT: 561b8e80941Smrg *value = surface->HdrMetadata.display_primary_b.y; 562b8e80941Smrg break; 563b8e80941Smrg case EGL_SMPTE2086_WHITE_POINT_X_EXT: 564b8e80941Smrg *value = surface->HdrMetadata.white_point.x; 565b8e80941Smrg break; 566b8e80941Smrg case EGL_SMPTE2086_WHITE_POINT_Y_EXT: 567b8e80941Smrg *value = surface->HdrMetadata.white_point.y; 568b8e80941Smrg break; 569b8e80941Smrg case EGL_SMPTE2086_MAX_LUMINANCE_EXT: 570b8e80941Smrg *value = surface->HdrMetadata.max_luminance; 571b8e80941Smrg break; 572b8e80941Smrg case EGL_SMPTE2086_MIN_LUMINANCE_EXT: 573b8e80941Smrg *value = surface->HdrMetadata.min_luminance; 574b8e80941Smrg break; 575b8e80941Smrg case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT: 576b8e80941Smrg *value = surface->HdrMetadata.max_cll; 577b8e80941Smrg break; 578b8e80941Smrg case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT: 579b8e80941Smrg *value = surface->HdrMetadata.max_fall; 580848b8605Smrg break; 581848b8605Smrg default: 582b8e80941Smrg return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); 583848b8605Smrg } 584848b8605Smrg 585848b8605Smrg return EGL_TRUE; 586848b8605Smrg} 587848b8605Smrg 588848b8605Smrg 589848b8605Smrg/** 590848b8605Smrg * Default fallback routine - drivers might override this. 591848b8605Smrg */ 592848b8605SmrgEGLBoolean 593b8e80941Smrg_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface, 594848b8605Smrg EGLint attribute, EGLint value) 595848b8605Smrg{ 596848b8605Smrg EGLint confval; 597848b8605Smrg EGLint err = EGL_SUCCESS; 598848b8605Smrg EGLint all_es_bits = EGL_OPENGL_ES_BIT | 599848b8605Smrg EGL_OPENGL_ES2_BIT | 600848b8605Smrg EGL_OPENGL_ES3_BIT_KHR; 601848b8605Smrg 602848b8605Smrg switch (attribute) { 603848b8605Smrg case EGL_MIPMAP_LEVEL: 604848b8605Smrg confval = surface->Config->RenderableType; 605848b8605Smrg if (!(confval & all_es_bits)) { 606848b8605Smrg err = EGL_BAD_PARAMETER; 607848b8605Smrg break; 608848b8605Smrg } 609848b8605Smrg surface->MipmapLevel = value; 610848b8605Smrg break; 611848b8605Smrg case EGL_MULTISAMPLE_RESOLVE: 612848b8605Smrg switch (value) { 613848b8605Smrg case EGL_MULTISAMPLE_RESOLVE_DEFAULT: 614848b8605Smrg break; 615848b8605Smrg case EGL_MULTISAMPLE_RESOLVE_BOX: 616848b8605Smrg confval = surface->Config->SurfaceType; 617848b8605Smrg if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT)) 618848b8605Smrg err = EGL_BAD_MATCH; 619848b8605Smrg break; 620848b8605Smrg default: 621848b8605Smrg err = EGL_BAD_ATTRIBUTE; 622848b8605Smrg break; 623848b8605Smrg } 624848b8605Smrg if (err != EGL_SUCCESS) 625848b8605Smrg break; 626848b8605Smrg surface->MultisampleResolve = value; 627848b8605Smrg break; 628b8e80941Smrg case EGL_RENDER_BUFFER: 629b8e80941Smrg if (!disp->Extensions.KHR_mutable_render_buffer) { 630b8e80941Smrg err = EGL_BAD_ATTRIBUTE; 631b8e80941Smrg break; 632b8e80941Smrg } 633b8e80941Smrg 634b8e80941Smrg if (value != EGL_BACK_BUFFER && value != EGL_SINGLE_BUFFER) { 635b8e80941Smrg err = EGL_BAD_PARAMETER; 636b8e80941Smrg break; 637b8e80941Smrg } 638b8e80941Smrg 639b8e80941Smrg /* From the EGL_KHR_mutable_render_buffer spec (v12): 640b8e80941Smrg * 641b8e80941Smrg * If attribute is EGL_RENDER_BUFFER, and the EGL_SURFACE_TYPE 642b8e80941Smrg * attribute of the EGLConfig used to create surface does not contain 643b8e80941Smrg * EGL_MUTABLE_RENDER_BUFFER_BIT_KHR, [...] an EGL_BAD_MATCH error is 644b8e80941Smrg * generated [...]. 645b8e80941Smrg */ 646b8e80941Smrg if (!(surface->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR)) { 647b8e80941Smrg err = EGL_BAD_MATCH; 648b8e80941Smrg break; 649b8e80941Smrg } 650b8e80941Smrg 651b8e80941Smrg surface->RequestedRenderBuffer = value; 652b8e80941Smrg break; 653848b8605Smrg case EGL_SWAP_BEHAVIOR: 654848b8605Smrg switch (value) { 655848b8605Smrg case EGL_BUFFER_DESTROYED: 656848b8605Smrg break; 657848b8605Smrg case EGL_BUFFER_PRESERVED: 658848b8605Smrg confval = surface->Config->SurfaceType; 659848b8605Smrg if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)) 660848b8605Smrg err = EGL_BAD_MATCH; 661848b8605Smrg break; 662848b8605Smrg default: 663848b8605Smrg err = EGL_BAD_ATTRIBUTE; 664848b8605Smrg break; 665848b8605Smrg } 666848b8605Smrg if (err != EGL_SUCCESS) 667848b8605Smrg break; 668848b8605Smrg surface->SwapBehavior = value; 669848b8605Smrg break; 670b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT: 671b8e80941Smrg surface->HdrMetadata.display_primary_r.x = value; 672b8e80941Smrg break; 673b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT: 674b8e80941Smrg surface->HdrMetadata.display_primary_r.y = value; 675b8e80941Smrg break; 676b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT: 677b8e80941Smrg surface->HdrMetadata.display_primary_g.x = value; 678b8e80941Smrg break; 679b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT: 680b8e80941Smrg surface->HdrMetadata.display_primary_g.y = value; 681b8e80941Smrg break; 682b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT: 683b8e80941Smrg surface->HdrMetadata.display_primary_b.x = value; 684b8e80941Smrg break; 685b8e80941Smrg case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT: 686b8e80941Smrg surface->HdrMetadata.display_primary_b.y = value; 687b8e80941Smrg break; 688b8e80941Smrg case EGL_SMPTE2086_WHITE_POINT_X_EXT: 689b8e80941Smrg surface->HdrMetadata.white_point.x = value; 690b8e80941Smrg break; 691b8e80941Smrg case EGL_SMPTE2086_WHITE_POINT_Y_EXT: 692b8e80941Smrg surface->HdrMetadata.white_point.y = value; 693b8e80941Smrg break; 694b8e80941Smrg case EGL_SMPTE2086_MAX_LUMINANCE_EXT: 695b8e80941Smrg surface->HdrMetadata.max_luminance = value; 696b8e80941Smrg break; 697b8e80941Smrg case EGL_SMPTE2086_MIN_LUMINANCE_EXT: 698b8e80941Smrg surface->HdrMetadata.min_luminance = value; 699b8e80941Smrg break; 700b8e80941Smrg case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT: 701b8e80941Smrg surface->HdrMetadata.max_cll = value; 702b8e80941Smrg break; 703b8e80941Smrg case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT: 704b8e80941Smrg surface->HdrMetadata.max_fall = value; 705b8e80941Smrg break; 706848b8605Smrg default: 707848b8605Smrg err = EGL_BAD_ATTRIBUTE; 708848b8605Smrg break; 709848b8605Smrg } 710848b8605Smrg 711848b8605Smrg if (err != EGL_SUCCESS) 712848b8605Smrg return _eglError(err, "eglSurfaceAttrib"); 713848b8605Smrg return EGL_TRUE; 714848b8605Smrg} 715848b8605Smrg 716848b8605Smrg 717848b8605SmrgEGLBoolean 718b8e80941Smrg_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface, 719848b8605Smrg EGLint buffer) 720848b8605Smrg{ 721848b8605Smrg EGLint texture_type = EGL_PBUFFER_BIT; 722848b8605Smrg 723848b8605Smrg /* Just do basic error checking and return success/fail. 724848b8605Smrg * Drivers must implement the real stuff. 725848b8605Smrg */ 726848b8605Smrg 727b8e80941Smrg if (disp->Extensions.NOK_texture_from_pixmap) 728848b8605Smrg texture_type |= EGL_PIXMAP_BIT; 729848b8605Smrg 730b8e80941Smrg if (!(surface->Type & texture_type)) 731b8e80941Smrg return _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); 732848b8605Smrg 733b8e80941Smrg if (surface->TextureFormat == EGL_NO_TEXTURE) 734b8e80941Smrg return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); 735848b8605Smrg 736b8e80941Smrg if (surface->TextureTarget == EGL_NO_TEXTURE) 737b8e80941Smrg return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); 738848b8605Smrg 739b8e80941Smrg if (buffer != EGL_BACK_BUFFER) 740b8e80941Smrg return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage"); 741848b8605Smrg 742848b8605Smrg surface->BoundToTexture = EGL_TRUE; 743848b8605Smrg 744848b8605Smrg return EGL_TRUE; 745848b8605Smrg} 746848b8605Smrg 747848b8605SmrgEGLBoolean 748848b8605Smrg_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, 749848b8605Smrg EGLint buffer) 750848b8605Smrg{ 751b8e80941Smrg /* Just do basic error checking and return success/fail. 752848b8605Smrg * Drivers must implement the real stuff. 753848b8605Smrg */ 754848b8605Smrg 755b8e80941Smrg EGLint texture_type = EGL_PBUFFER_BIT; 756b8e80941Smrg 757b8e80941Smrg if (surf == EGL_NO_SURFACE) 758b8e80941Smrg return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage"); 759b8e80941Smrg 760b8e80941Smrg if (!surf->BoundToTexture) 761b8e80941Smrg { 762b8e80941Smrg /* Not an error, simply nothing to do */ 763b8e80941Smrg return EGL_TRUE; 764b8e80941Smrg } 765b8e80941Smrg 766b8e80941Smrg if (surf->TextureFormat == EGL_NO_TEXTURE) 767b8e80941Smrg return _eglError(EGL_BAD_MATCH, "eglReleaseTexImage"); 768b8e80941Smrg 769b8e80941Smrg if (buffer != EGL_BACK_BUFFER) 770b8e80941Smrg return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage"); 771b8e80941Smrg 772b8e80941Smrg if (disp->Extensions.NOK_texture_from_pixmap) 773b8e80941Smrg texture_type |= EGL_PIXMAP_BIT; 774b8e80941Smrg 775b8e80941Smrg if (!(surf->Type & texture_type)) 776b8e80941Smrg return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage"); 777b8e80941Smrg 778b8e80941Smrg surf->BoundToTexture = EGL_FALSE; 779b8e80941Smrg 780b8e80941Smrg return EGL_TRUE; 781848b8605Smrg} 782848b8605Smrg 783848b8605Smrg 784848b8605SmrgEGLBoolean 785b8e80941Smrg_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, 786848b8605Smrg EGLint interval) 787848b8605Smrg{ 788848b8605Smrg return EGL_TRUE; 789848b8605Smrg} 790b8e80941Smrg 791b8e80941SmrgEGLBoolean 792b8e80941Smrg_eglSurfaceHasMutableRenderBuffer(_EGLSurface *surf) 793b8e80941Smrg{ 794b8e80941Smrg return surf->Type == EGL_WINDOW_BIT && 795b8e80941Smrg surf->Config && 796b8e80941Smrg (surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR); 797b8e80941Smrg} 798b8e80941Smrg 799b8e80941SmrgEGLBoolean 800b8e80941Smrg_eglSurfaceInSharedBufferMode(_EGLSurface *surf) 801b8e80941Smrg{ 802b8e80941Smrg return _eglSurfaceHasMutableRenderBuffer(surf) && 803b8e80941Smrg surf->ActiveRenderBuffer == EGL_SINGLE_BUFFER; 804b8e80941Smrg} 805