X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fegl%2Fmain%2Feglsurface.c;h=3bd14a8cd034e1c2d1583c4ef758cac6d65dafb1;hp=3564ecd01b0a54e21d1a41ec5d683c0c336e2b93;hb=2714a8f3e95139d2c473f99e913562929ae3f5d7;hpb=f8e6d19f3f40931be741b44d3edf210c38e13f0f diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index 3564ecd01b0..3bd14a8cd03 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2008 VMware, Inc. * Copyright 2009-2010 Chia-I Wu * Copyright 2010 LunarG, Inc. * All Rights Reserved. @@ -37,6 +37,7 @@ #include #include #include "egldisplay.h" +#include "egldriver.h" #include "eglcontext.h" #include "eglconfig.h" #include "eglcurrent.h" @@ -44,66 +45,6 @@ #include "eglsurface.h" -static void -_eglClampSwapInterval(_EGLSurface *surf, EGLint interval) -{ - EGLint bound = surf->Config->MaxSwapInterval; - if (interval >= bound) { - interval = bound; - } - else { - bound = surf->Config->MinSwapInterval; - if (interval < bound) - interval = bound; - } - surf->SwapInterval = interval; -} - - -#ifdef EGL_MESA_screen_surface -static EGLint -_eglParseScreenSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) -{ - EGLint i, err = EGL_SUCCESS; - - if (!attrib_list) - return EGL_SUCCESS; - - for (i = 0; attrib_list[i] != EGL_NONE; i++) { - EGLint attr = attrib_list[i++]; - EGLint val = attrib_list[i]; - - switch (attr) { - case EGL_WIDTH: - if (val < 0) { - err = EGL_BAD_PARAMETER; - break; - } - surf->Width = val; - break; - case EGL_HEIGHT: - if (val < 0) { - err = EGL_BAD_PARAMETER; - break; - } - surf->Height = val; - break; - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - - if (err != EGL_SUCCESS) { - _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr); - break; - } - } - - return err; -} -#endif /* EGL_MESA_screen_surface */ - - /** * Parse the list of surface attributes and return the proper error code. */ @@ -114,24 +55,37 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) EGLint type = surf->Type; EGLint texture_type = EGL_PBUFFER_BIT; EGLint i, err = EGL_SUCCESS; + EGLint attr = EGL_NONE; + EGLint val = EGL_NONE; if (!attrib_list) return EGL_SUCCESS; -#ifdef EGL_MESA_screen_surface - if (type == EGL_SCREEN_BIT_MESA) - return _eglParseScreenSurfaceAttribList(surf, attrib_list); -#endif - if (dpy->Extensions.NOK_texture_from_pixmap) texture_type |= EGL_PIXMAP_BIT; for (i = 0; attrib_list[i] != EGL_NONE; i++) { - EGLint attr = attrib_list[i++]; - EGLint val = attrib_list[i]; + attr = attrib_list[i++]; + val = attrib_list[i]; switch (attr) { /* common attributes */ + case EGL_GL_COLORSPACE_KHR: + if (!dpy->Extensions.KHR_gl_colorspace) { + err = EGL_BAD_ATTRIBUTE; + break; + } + switch (val) { + case EGL_GL_COLORSPACE_SRGB_KHR: + case EGL_GL_COLORSPACE_LINEAR_KHR: + break; + default: + err = EGL_BAD_ATTRIBUTE; + } + if (err != EGL_SUCCESS) + break; + surf->GLColorspace = val; + break; case EGL_VG_COLORSPACE: switch (val) { case EGL_VG_COLORSPACE_sRGB: @@ -170,6 +124,18 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) } surf->RenderBuffer = val; break; + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: + if (!dpy->Extensions.NV_post_sub_buffer || + type != EGL_WINDOW_BIT) { + err = EGL_BAD_ATTRIBUTE; + break; + } + if (val != EGL_TRUE && val != EGL_FALSE) { + err = EGL_BAD_PARAMETER; + break; + } + surf->PostSubBufferSupportedNV = val; + break; /* pbuffer surface attributes */ case EGL_WIDTH: if (type != EGL_PBUFFER_BIT) { @@ -206,6 +172,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) err = EGL_BAD_ATTRIBUTE; break; } + switch (val) { case EGL_TEXTURE_RGB: case EGL_TEXTURE_RGBA: @@ -224,6 +191,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) err = EGL_BAD_ATTRIBUTE; break; } + switch (val) { case EGL_TEXTURE_2D: case EGL_NO_TEXTURE: @@ -249,12 +217,21 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) break; } - if (err != EGL_SUCCESS) { - _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr); + if (err != EGL_SUCCESS) break; + } + + if (err == EGL_SUCCESS && type == EGL_PBUFFER_BIT) { + if ((surf->TextureTarget == EGL_NO_TEXTURE && surf->TextureFormat != EGL_NO_TEXTURE) || + (surf->TextureFormat == EGL_NO_TEXTURE && surf->TextureTarget != EGL_NO_TEXTURE)) { + attr = surf->TextureTarget == EGL_NO_TEXTURE ? EGL_TEXTURE_TARGET : EGL_TEXTURE_FORMAT; + err = EGL_BAD_MATCH; } } + if (err != EGL_SUCCESS) + _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr); + return err; } @@ -269,9 +246,13 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, { const char *func; EGLint renderBuffer = EGL_BACK_BUFFER; - EGLint swapBehavior = EGL_BUFFER_PRESERVED; + EGLint swapBehavior = EGL_BUFFER_DESTROYED; EGLint err; + /* Swap behavior can be preserved only if config supports this. */ + if (conf->SurfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) + swapBehavior = EGL_BUFFER_PRESERVED; + switch (type) { case EGL_WINDOW_BIT: func = "eglCreateWindowSurface"; @@ -284,26 +265,19 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, case EGL_PBUFFER_BIT: func = "eglCreatePBufferSurface"; break; -#ifdef EGL_MESA_screen_surface - case EGL_SCREEN_BIT_MESA: - func = "eglCreateScreenSurface"; - renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */ - break; -#endif default: _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface"); return EGL_FALSE; } - if ((conf->SurfaceType & type) == 0) { + if ((conf->SurfaceType & type) == 0) /* The config can't be used to create a surface of this type */ - _eglError(EGL_BAD_CONFIG, func); - return EGL_FALSE; - } + return _eglError(EGL_BAD_MATCH, func); _eglInitResource(&surf->Resource, sizeof(*surf), dpy); surf->Type = type; surf->Config = conf; + surf->Lost = EGL_FALSE; surf->Width = 0; surf->Height = 0; @@ -314,6 +288,7 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, surf->RenderBuffer = renderBuffer; surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE; surf->VGColorspace = EGL_VG_COLORSPACE_sRGB; + surf->GLColorspace = EGL_GL_COLORSPACE_LINEAR_KHR; surf->MipmapLevel = 0; surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT; @@ -323,13 +298,23 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, surf->VerticalResolution = EGL_UNKNOWN; surf->AspectRatio = EGL_UNKNOWN; + surf->PostSubBufferSupportedNV = EGL_FALSE; + surf->SetDamageRegionCalled = EGL_FALSE; + surf->BufferAgeRead = EGL_FALSE; + /* the default swap interval is 1 */ - _eglClampSwapInterval(surf, 1); + surf->SwapInterval = 1; err = _eglParseSurfaceAttribList(surf, attrib_list); if (err != EGL_SUCCESS) return _eglError(err, func); + /* if EGL_LARGEST_PBUFFER in use, clamp width and height */ + if (surf->LargestPbuffer) { + surf->Width = MIN2(surf->Width, _EGL_MAX_PBUFFER_WIDTH); + surf->Height = MIN2(surf->Height, _EGL_MAX_PBUFFER_HEIGHT); + } + return EGL_TRUE; } @@ -349,7 +334,8 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, *value = surface->Config->ConfigID; break; case EGL_LARGEST_PBUFFER: - *value = surface->LargestPbuffer; + if (surface->Type == EGL_PBUFFER_BIT) + *value = surface->LargestPbuffer; break; case EGL_TEXTURE_FORMAT: /* texture attributes: only for pbuffers, no error otherwise */ @@ -392,9 +378,33 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, case EGL_VG_COLORSPACE: *value = surface->VGColorspace; break; + case EGL_GL_COLORSPACE_KHR: + if (!dpy->Extensions.KHR_gl_colorspace) + return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); + + *value = surface->GLColorspace; + break; + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: + *value = surface->PostSubBufferSupportedNV; + break; + case EGL_BUFFER_AGE_EXT: + if (!dpy->Extensions.EXT_buffer_age) + return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); + + _EGLContext *ctx = _eglGetCurrentContext(); + EGLint result = drv->API.QueryBufferAge(drv, dpy, surface); + /* error happened */ + if (result < 0) + return EGL_FALSE; + if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || + ctx->DrawSurface != surface) + return _eglError(EGL_BAD_SURFACE, "eglQuerySurface"); + + *value = result; + surface->BufferAgeRead = EGL_TRUE; + break; default: - _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); - return EGL_FALSE; + return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); } return EGL_TRUE; @@ -410,11 +420,14 @@ _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, { EGLint confval; EGLint err = EGL_SUCCESS; + EGLint all_es_bits = EGL_OPENGL_ES_BIT | + EGL_OPENGL_ES2_BIT | + EGL_OPENGL_ES3_BIT_KHR; switch (attribute) { case EGL_MIPMAP_LEVEL: confval = surface->Config->RenderableType; - if (!(confval & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT))) { + if (!(confval & all_es_bits)) { err = EGL_BAD_PARAMETER; break; } @@ -478,36 +491,63 @@ _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, if (dpy->Extensions.NOK_texture_from_pixmap) texture_type |= EGL_PIXMAP_BIT; - if (!(surface->Type & texture_type)) { - _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); - return EGL_FALSE; - } + if (!(surface->Type & texture_type)) + return _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); - if (surface->TextureFormat == EGL_NO_TEXTURE) { - _eglError(EGL_BAD_MATCH, "eglBindTexImage"); - return EGL_FALSE; - } + if (surface->TextureFormat == EGL_NO_TEXTURE) + return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); - if (surface->TextureTarget == EGL_NO_TEXTURE) { - _eglError(EGL_BAD_MATCH, "eglBindTexImage"); - return EGL_FALSE; - } + if (surface->TextureTarget == EGL_NO_TEXTURE) + return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); - if (buffer != EGL_BACK_BUFFER) { - _eglError(EGL_BAD_PARAMETER, "eglBindTexImage"); - return EGL_FALSE; - } + if (buffer != EGL_BACK_BUFFER) + return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage"); surface->BoundToTexture = EGL_TRUE; return EGL_TRUE; } +EGLBoolean +_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, + EGLint buffer) +{ + /* Just do basic error checking and return success/fail. + * Drivers must implement the real stuff. + */ + + EGLint texture_type = EGL_PBUFFER_BIT; + + if (surf == EGL_NO_SURFACE) + return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage"); + + if (!surf->BoundToTexture) + { + /* Not an error, simply nothing to do */ + return EGL_TRUE; + } + + if (surf->TextureFormat == EGL_NO_TEXTURE) + return _eglError(EGL_BAD_MATCH, "eglReleaseTexImage"); + + if (buffer != EGL_BACK_BUFFER) + return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage"); + + if (dpy->Extensions.NOK_texture_from_pixmap) + texture_type |= EGL_PIXMAP_BIT; + + if (!(surf->Type & texture_type)) + return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage"); + + surf->BoundToTexture = EGL_FALSE; + + return EGL_TRUE; +} + EGLBoolean _eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint interval) { - _eglClampSwapInterval(surf, interval); return EGL_TRUE; }