eglsurface.c revision ecb3b3102a3022e31cf9d75ae099eddbe298517f
1/** 2 * Surface-related functions. 3 */ 4 5 6#include <assert.h> 7#include <stdlib.h> 8#include <string.h> 9#include "egldisplay.h" 10#include "eglcontext.h" 11#include "eglconfig.h" 12#include "egldriver.h" 13#include "eglglobals.h" 14#include "egllog.h" 15#include "eglsurface.h" 16 17 18static void 19_eglClampSwapInterval(_EGLSurface *surf, EGLint interval) 20{ 21 EGLint bound = GET_CONFIG_ATTRIB(surf->Config, EGL_MAX_SWAP_INTERVAL); 22 if (interval >= bound) { 23 interval = bound; 24 } 25 else { 26 bound = GET_CONFIG_ATTRIB(surf->Config, EGL_MIN_SWAP_INTERVAL); 27 if (interval < bound) 28 interval = bound; 29 } 30 surf->SwapInterval = interval; 31} 32 33 34/** 35 * Do error check on parameters and initialize the given _EGLSurface object. 36 * \return EGL_TRUE if no errors, EGL_FALSE otherwise. 37 */ 38EGLBoolean 39_eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type, 40 _EGLConfig *conf, const EGLint *attrib_list) 41{ 42 const char *func; 43 EGLint width = 0, height = 0, largest = 0; 44 EGLint texFormat = EGL_NO_TEXTURE, texTarget = EGL_NO_TEXTURE; 45 EGLint mipmapTex = EGL_FALSE; 46 EGLint renderBuffer = EGL_BACK_BUFFER; 47#ifdef EGL_VERSION_1_2 48 EGLint colorspace = EGL_COLORSPACE_sRGB; 49 EGLint alphaFormat = EGL_ALPHA_FORMAT_NONPRE; 50#endif 51 EGLint i; 52 53 switch (type) { 54 case EGL_WINDOW_BIT: 55 func = "eglCreateWindowSurface"; 56 break; 57 case EGL_PIXMAP_BIT: 58 func = "eglCreatePixmapSurface"; 59 renderBuffer = EGL_SINGLE_BUFFER; 60 break; 61 case EGL_PBUFFER_BIT: 62 func = "eglCreatePBufferSurface"; 63 break; 64 case EGL_SCREEN_BIT_MESA: 65 func = "eglCreateScreenSurface"; 66 renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */ 67 break; 68 default: 69 _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface"); 70 return EGL_FALSE; 71 } 72 73 if (!conf) { 74 _eglError(EGL_BAD_CONFIG, func); 75 return EGL_FALSE; 76 } 77 78 if ((GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE) & type) == 0) { 79 /* The config can't be used to create a surface of this type */ 80 _eglError(EGL_BAD_CONFIG, func); 81 return EGL_FALSE; 82 } 83 84 /* 85 * Parse attribute list. Different kinds of surfaces support different 86 * attributes. 87 */ 88 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { 89 switch (attrib_list[i]) { 90 case EGL_WIDTH: 91 if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) { 92 width = attrib_list[++i]; 93 } 94 else { 95 _eglError(EGL_BAD_ATTRIBUTE, func); 96 return EGL_FALSE; 97 } 98 break; 99 case EGL_HEIGHT: 100 if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) { 101 height = attrib_list[++i]; 102 } 103 else { 104 _eglError(EGL_BAD_ATTRIBUTE, func); 105 return EGL_FALSE; 106 } 107 break; 108 case EGL_LARGEST_PBUFFER: 109 if (type == EGL_PBUFFER_BIT) { 110 largest = attrib_list[++i]; 111 } 112 else { 113 _eglError(EGL_BAD_ATTRIBUTE, func); 114 return EGL_FALSE; 115 } 116 break; 117 case EGL_TEXTURE_FORMAT: 118 if (type == EGL_PBUFFER_BIT) { 119 texFormat = attrib_list[++i]; 120 } 121 else { 122 _eglError(EGL_BAD_ATTRIBUTE, func); 123 return EGL_FALSE; 124 } 125 break; 126 case EGL_TEXTURE_TARGET: 127 if (type == EGL_PBUFFER_BIT) { 128 texTarget = attrib_list[++i]; 129 } 130 else { 131 _eglError(EGL_BAD_ATTRIBUTE, func); 132 return EGL_FALSE; 133 } 134 break; 135 case EGL_MIPMAP_TEXTURE: 136 if (type == EGL_PBUFFER_BIT) { 137 mipmapTex = attrib_list[++i]; 138 } 139 else { 140 _eglError(EGL_BAD_ATTRIBUTE, func); 141 return EGL_FALSE; 142 } 143 break; 144#ifdef EGL_VERSION_1_2 145 case EGL_RENDER_BUFFER: 146 if (type == EGL_WINDOW_BIT) { 147 renderBuffer = attrib_list[++i]; 148 if (renderBuffer != EGL_BACK_BUFFER && 149 renderBuffer != EGL_SINGLE_BUFFER) { 150 _eglError(EGL_BAD_ATTRIBUTE, func); 151 return EGL_FALSE; 152 } 153 } 154 else { 155 _eglError(EGL_BAD_ATTRIBUTE, func); 156 return EGL_FALSE; 157 } 158 break; 159 case EGL_COLORSPACE: 160 if (type == EGL_WINDOW_BIT || 161 type == EGL_PBUFFER_BIT || 162 type == EGL_PIXMAP_BIT) { 163 colorspace = attrib_list[++i]; 164 if (colorspace != EGL_COLORSPACE_sRGB && 165 colorspace != EGL_COLORSPACE_LINEAR) { 166 _eglError(EGL_BAD_ATTRIBUTE, func); 167 return EGL_FALSE; 168 } 169 } 170 else { 171 _eglError(EGL_BAD_ATTRIBUTE, func); 172 return EGL_FALSE; 173 } 174 break; 175 case EGL_ALPHA_FORMAT: 176 if (type == EGL_WINDOW_BIT || 177 type == EGL_PBUFFER_BIT || 178 type == EGL_PIXMAP_BIT) { 179 alphaFormat = attrib_list[++i]; 180 if (alphaFormat != EGL_ALPHA_FORMAT_NONPRE && 181 alphaFormat != EGL_ALPHA_FORMAT_PRE) { 182 _eglError(EGL_BAD_ATTRIBUTE, func); 183 return EGL_FALSE; 184 } 185 } 186 else { 187 _eglError(EGL_BAD_ATTRIBUTE, func); 188 return EGL_FALSE; 189 } 190 break; 191 192#endif /* EGL_VERSION_1_2 */ 193 default: 194 _eglError(EGL_BAD_ATTRIBUTE, func); 195 return EGL_FALSE; 196 } 197 } 198 199 if (width < 0 || height < 0) { 200 _eglError(EGL_BAD_ATTRIBUTE, func); 201 return EGL_FALSE; 202 } 203 204 memset(surf, 0, sizeof(_EGLSurface)); 205 surf->Config = conf; 206 surf->Type = type; 207 surf->Width = width; 208 surf->Height = height; 209 surf->TextureFormat = texFormat; 210 surf->TextureTarget = texTarget; 211 surf->MipmapTexture = mipmapTex; 212 surf->MipmapLevel = 0; 213 /* the default swap interval is 1 */ 214 _eglClampSwapInterval(surf, 1); 215 216#ifdef EGL_VERSION_1_2 217 surf->SwapBehavior = EGL_BUFFER_DESTROYED; /* XXX ok? */ 218 surf->HorizontalResolution = EGL_UNKNOWN; /* set by caller */ 219 surf->VerticalResolution = EGL_UNKNOWN; /* set by caller */ 220 surf->AspectRatio = EGL_UNKNOWN; /* set by caller */ 221 surf->RenderBuffer = renderBuffer; 222 surf->AlphaFormat = alphaFormat; 223 surf->Colorspace = colorspace; 224#endif 225 226 return EGL_TRUE; 227} 228 229 230EGLBoolean 231_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) 232{ 233 /* Drivers have to do the actual buffer swap. */ 234 return EGL_TRUE; 235} 236 237 238EGLBoolean 239_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, 240 NativePixmapType target) 241{ 242 /* copy surface to native pixmap */ 243 /* All implementation burdon for this is in the device driver */ 244 return EGL_FALSE; 245} 246 247 248EGLBoolean 249_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, 250 EGLint attribute, EGLint *value) 251{ 252 switch (attribute) { 253 case EGL_WIDTH: 254 *value = surface->Width; 255 return EGL_TRUE; 256 case EGL_HEIGHT: 257 *value = surface->Height; 258 return EGL_TRUE; 259 case EGL_CONFIG_ID: 260 *value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID); 261 return EGL_TRUE; 262 case EGL_LARGEST_PBUFFER: 263 *value = dpy->LargestPbuffer; 264 return EGL_TRUE; 265 case EGL_SURFACE_TYPE: 266 *value = surface->Type; 267 return EGL_TRUE; 268#ifdef EGL_VERSION_1_1 269 case EGL_TEXTURE_FORMAT: 270 /* texture attributes: only for pbuffers, no error otherwise */ 271 if (surface->Type == EGL_PBUFFER_BIT) 272 *value = surface->TextureFormat; 273 return EGL_TRUE; 274 case EGL_TEXTURE_TARGET: 275 if (surface->Type == EGL_PBUFFER_BIT) 276 *value = surface->TextureTarget; 277 return EGL_TRUE; 278 case EGL_MIPMAP_TEXTURE: 279 if (surface->Type == EGL_PBUFFER_BIT) 280 *value = surface->MipmapTexture; 281 return EGL_TRUE; 282 case EGL_MIPMAP_LEVEL: 283 if (surface->Type == EGL_PBUFFER_BIT) 284 *value = surface->MipmapLevel; 285 return EGL_TRUE; 286#endif /* EGL_VERSION_1_1 */ 287#ifdef EGL_VERSION_1_2 288 case EGL_SWAP_BEHAVIOR: 289 *value = surface->SwapBehavior; 290 return EGL_TRUE; 291 case EGL_RENDER_BUFFER: 292 *value = surface->RenderBuffer; 293 return EGL_TRUE; 294 case EGL_PIXEL_ASPECT_RATIO: 295 *value = surface->AspectRatio; 296 return EGL_TRUE; 297 case EGL_HORIZONTAL_RESOLUTION: 298 *value = surface->HorizontalResolution; 299 return EGL_TRUE; 300 case EGL_VERTICAL_RESOLUTION: 301 *value = surface->VerticalResolution; 302 return EGL_TRUE; 303 case EGL_ALPHA_FORMAT: 304 *value = surface->AlphaFormat; 305 return EGL_TRUE; 306 case EGL_COLORSPACE: 307 *value = surface->Colorspace; 308 return EGL_TRUE; 309#endif /* EGL_VERSION_1_2 */ 310 default: 311 _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); 312 return EGL_FALSE; 313 } 314} 315 316 317/** 318 * Example function - drivers should do a proper implementation. 319 */ 320_EGLSurface * 321_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, 322 NativeWindowType window, const EGLint *attrib_list) 323{ 324#if 0 /* THIS IS JUST EXAMPLE CODE */ 325 _EGLSurface *surf; 326 327 surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); 328 if (!surf) 329 return NULL; 330 331 if (!_eglInitSurface(drv, surf, EGL_WINDOW_BIT, conf, attrib_list)) { 332 free(surf); 333 return NULL; 334 } 335 336 return surf; 337#endif 338 return NULL; 339} 340 341 342/** 343 * Example function - drivers should do a proper implementation. 344 */ 345_EGLSurface * 346_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, 347 NativePixmapType pixmap, const EGLint *attrib_list) 348{ 349#if 0 /* THIS IS JUST EXAMPLE CODE */ 350 _EGLSurface *surf; 351 352 surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); 353 if (!surf) 354 return NULL; 355 356 if (!_eglInitSurface(drv, surf, EGL_PIXMAP_BIT, conf, attrib_list)) { 357 free(surf); 358 return NULL; 359 } 360 361 return surf; 362#endif 363 return NULL; 364} 365 366 367/** 368 * Example function - drivers should do a proper implementation. 369 */ 370_EGLSurface * 371_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, 372 const EGLint *attrib_list) 373{ 374#if 0 /* THIS IS JUST EXAMPLE CODE */ 375 _EGLSurface *surf; 376 377 surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); 378 if (!surf) 379 return NULL; 380 381 if (!_eglInitSurface(drv, surf, EGL_PBUFFER_BIT, conf, attrib_list)) { 382 free(surf); 383 return NULL; 384 } 385 386 return NULL; 387#endif 388 return NULL; 389} 390 391 392/** 393 * Default fallback routine - drivers should usually override this. 394 */ 395EGLBoolean 396_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) 397{ 398 if (!_eglIsSurfaceBound(surf)) 399 free(surf); 400 return EGL_TRUE; 401} 402 403 404/** 405 * Default fallback routine - drivers might override this. 406 */ 407EGLBoolean 408_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, 409 EGLint attribute, EGLint value) 410{ 411 switch (attribute) { 412 case EGL_MIPMAP_LEVEL: 413 surface->MipmapLevel = value; 414 break; 415 default: 416 _eglError(EGL_BAD_ATTRIBUTE, "eglSurfaceAttrib"); 417 return EGL_FALSE; 418 } 419 return EGL_TRUE; 420} 421 422 423EGLBoolean 424_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, 425 EGLint buffer) 426{ 427 /* Just do basic error checking and return success/fail. 428 * Drivers must implement the real stuff. 429 */ 430 431 if (surface->Type != EGL_PBUFFER_BIT) { 432 _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); 433 return EGL_FALSE; 434 } 435 436 if (surface->TextureFormat == EGL_NO_TEXTURE) { 437 _eglError(EGL_BAD_MATCH, "eglBindTexImage"); 438 return EGL_FALSE; 439 } 440 441 if (buffer != EGL_BACK_BUFFER) { 442 _eglError(EGL_BAD_PARAMETER, "eglBindTexImage"); 443 return EGL_FALSE; 444 } 445 446 surface->BoundToTexture = EGL_TRUE; 447 448 return EGL_TRUE; 449} 450 451 452EGLBoolean 453_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, 454 EGLint buffer) 455{ 456 /* Just do basic error checking and return success/fail. 457 * Drivers must implement the real stuff. 458 */ 459 460 if (surface->Type != EGL_PBUFFER_BIT) { 461 _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); 462 return EGL_FALSE; 463 } 464 465 if (surface->TextureFormat == EGL_NO_TEXTURE) { 466 _eglError(EGL_BAD_MATCH, "eglBindTexImage"); 467 return EGL_FALSE; 468 } 469 470 if (buffer != EGL_BACK_BUFFER) { 471 _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage"); 472 return EGL_FALSE; 473 } 474 475 if (!surface->BoundToTexture) { 476 _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage"); 477 return EGL_FALSE; 478 } 479 480 surface->BoundToTexture = EGL_FALSE; 481 482 return EGL_TRUE; 483} 484 485 486EGLBoolean 487_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, 488 EGLint interval) 489{ 490 _eglClampSwapInterval(surf, interval); 491 return EGL_TRUE; 492} 493 494 495#ifdef EGL_VERSION_1_2 496 497/** 498 * Example function - drivers should do a proper implementation. 499 */ 500_EGLSurface * 501_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy, 502 EGLenum buftype, EGLClientBuffer buffer, 503 _EGLConfig *conf, const EGLint *attrib_list) 504{ 505 if (buftype != EGL_OPENVG_IMAGE) { 506 _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer"); 507 return NULL; 508 } 509 510 return NULL; 511} 512 513#endif /* EGL_VERSION_1_2 */ 514