X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fegl%2Fmain%2Feglsurface.c;h=8026a6314d3629e83acd47f1fea527770528b35a;hb=12297f1f98c5daf177938b2598e6fb8ed97a9a66;hp=940a1b760cf1321844e7d52608deb464882f4580;hpb=b605f4ff11c894500f2d0273c5d4653ff413448d;p=mesa.git diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index 940a1b760cf..8026a6314d3 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -9,8 +9,7 @@ #include "egldisplay.h" #include "eglcontext.h" #include "eglconfig.h" -#include "egldriver.h" -#include "eglglobals.h" +#include "eglcurrent.h" #include "egllog.h" #include "eglsurface.h" @@ -31,24 +30,169 @@ _eglClampSwapInterval(_EGLSurface *surf, EGLint interval) } +/** + * Parse the list of surface attributes and return the proper error code. + */ +static EGLint +_eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) +{ + EGLint type = surf->Type; + 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) { + /* common (except for screen surfaces) attributes */ + case EGL_VG_COLORSPACE: + if (type == EGL_SCREEN_BIT_MESA) { + err = EGL_BAD_ATTRIBUTE; + break; + } + switch (val) { + case EGL_VG_COLORSPACE_sRGB: + case EGL_VG_COLORSPACE_LINEAR: + break; + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + if (err != EGL_SUCCESS) + break; + surf->VGColorspace = val; + break; + case EGL_VG_ALPHA_FORMAT: + if (type == EGL_SCREEN_BIT_MESA) { + err = EGL_BAD_ATTRIBUTE; + break; + } + switch (val) { + case EGL_VG_ALPHA_FORMAT_NONPRE: + case EGL_VG_ALPHA_FORMAT_PRE: + break; + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + if (err != EGL_SUCCESS) + break; + surf->VGAlphaFormat = val; + break; + /* window surface attributes */ + case EGL_RENDER_BUFFER: + if (type != EGL_WINDOW_BIT) { + err = EGL_BAD_ATTRIBUTE; + break; + } + if (val != EGL_BACK_BUFFER && val != EGL_SINGLE_BUFFER) { + err = EGL_BAD_ATTRIBUTE; + break; + } + surf->RenderBuffer = val; + break; + /* pbuffer surface attributes */ + case EGL_WIDTH: + if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) { + err = EGL_BAD_ATTRIBUTE; + break; + } + if (val < 0) { + err = EGL_BAD_PARAMETER; + break; + } + surf->Width = val; + break; + case EGL_HEIGHT: + if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) { + err = EGL_BAD_ATTRIBUTE; + break; + } + if (val < 0) { + err = EGL_BAD_PARAMETER; + break; + } + surf->Height = val; + break; + case EGL_LARGEST_PBUFFER: + if (type != EGL_PBUFFER_BIT) { + err = EGL_BAD_ATTRIBUTE; + break; + } + surf->LargestPbuffer = !!val; + break; + case EGL_TEXTURE_FORMAT: + if (type != EGL_PBUFFER_BIT) { + err = EGL_BAD_ATTRIBUTE; + break; + } + switch (val) { + case EGL_TEXTURE_RGB: + case EGL_TEXTURE_RGBA: + case EGL_NO_TEXTURE: + break; + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + if (err != EGL_SUCCESS) + break; + surf->TextureFormat = val; + break; + case EGL_TEXTURE_TARGET: + if (type != EGL_PBUFFER_BIT) { + err = EGL_BAD_ATTRIBUTE; + break; + } + switch (val) { + case EGL_TEXTURE_2D: + case EGL_NO_TEXTURE: + break; + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + if (err != EGL_SUCCESS) + break; + surf->TextureTarget = val; + break; + case EGL_MIPMAP_TEXTURE: + if (type != EGL_PBUFFER_BIT) { + err = EGL_BAD_ATTRIBUTE; + break; + } + surf->MipmapTexture = !!val; + break; + /* no pixmap surface specific attributes */ + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + + if (err != EGL_SUCCESS) { + _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr); + break; + } + } + + return err; +} + + /** * Do error check on parameters and initialize the given _EGLSurface object. * \return EGL_TRUE if no errors, EGL_FALSE otherwise. */ EGLBoolean -_eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type, +_eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, _EGLConfig *conf, const EGLint *attrib_list) { const char *func; - EGLint width = 0, height = 0, largest = 0; - EGLint texFormat = EGL_NO_TEXTURE, texTarget = EGL_NO_TEXTURE; - EGLint mipmapTex = EGL_FALSE; EGLint renderBuffer = EGL_BACK_BUFFER; -#ifdef EGL_VERSION_1_2 - EGLint colorspace = EGL_COLORSPACE_sRGB; - EGLint alphaFormat = EGL_ALPHA_FORMAT_NONPRE; -#endif - EGLint i; + EGLint err; switch (type) { case EGL_WINDOW_BIT: @@ -70,158 +214,41 @@ _eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type, return EGL_FALSE; } - if (!conf) { - _eglError(EGL_BAD_CONFIG, func); - return EGL_FALSE; - } - if ((GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE) & type) == 0) { /* The config can't be used to create a surface of this type */ _eglError(EGL_BAD_CONFIG, func); return EGL_FALSE; } - /* - * Parse attribute list. Different kinds of surfaces support different - * attributes. - */ - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - case EGL_WIDTH: - if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) { - width = attrib_list[++i]; - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_HEIGHT: - if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) { - height = attrib_list[++i]; - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_LARGEST_PBUFFER: - if (type == EGL_PBUFFER_BIT) { - largest = attrib_list[++i]; - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_TEXTURE_FORMAT: - if (type == EGL_PBUFFER_BIT) { - texFormat = attrib_list[++i]; - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_TEXTURE_TARGET: - if (type == EGL_PBUFFER_BIT) { - texTarget = attrib_list[++i]; - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_MIPMAP_TEXTURE: - if (type == EGL_PBUFFER_BIT) { - mipmapTex = attrib_list[++i]; - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; -#ifdef EGL_VERSION_1_2 - case EGL_RENDER_BUFFER: - if (type == EGL_WINDOW_BIT) { - renderBuffer = attrib_list[++i]; - if (renderBuffer != EGL_BACK_BUFFER && - renderBuffer != EGL_SINGLE_BUFFER) { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_COLORSPACE: - if (type == EGL_WINDOW_BIT || - type == EGL_PBUFFER_BIT || - type == EGL_PIXMAP_BIT) { - colorspace = attrib_list[++i]; - if (colorspace != EGL_COLORSPACE_sRGB && - colorspace != EGL_COLORSPACE_LINEAR) { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_ALPHA_FORMAT: - if (type == EGL_WINDOW_BIT || - type == EGL_PBUFFER_BIT || - type == EGL_PIXMAP_BIT) { - alphaFormat = attrib_list[++i]; - if (alphaFormat != EGL_ALPHA_FORMAT_NONPRE && - alphaFormat != EGL_ALPHA_FORMAT_PRE) { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - -#endif /* EGL_VERSION_1_2 */ - default: - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - } - - if (width < 0 || height < 0) { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - memset(surf, 0, sizeof(_EGLSurface)); - surf->Config = conf; + surf->Resource.Display = dpy; surf->Type = type; - surf->Width = width; - surf->Height = height; - surf->TextureFormat = texFormat; - surf->TextureTarget = texTarget; - surf->MipmapTexture = mipmapTex; + surf->Config = conf; + + surf->Width = 0; + surf->Height = 0; + surf->TextureFormat = EGL_NO_TEXTURE; + surf->TextureTarget = EGL_NO_TEXTURE; + surf->MipmapTexture = EGL_FALSE; + surf->LargestPbuffer = EGL_FALSE; + surf->RenderBuffer = renderBuffer; + surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE; + surf->VGColorspace = EGL_VG_COLORSPACE_sRGB; + surf->MipmapLevel = 0; + surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT; + surf->SwapBehavior = EGL_BUFFER_DESTROYED; + + surf->HorizontalResolution = EGL_UNKNOWN; + surf->VerticalResolution = EGL_UNKNOWN; + surf->AspectRatio = EGL_UNKNOWN; + /* the default swap interval is 1 */ _eglClampSwapInterval(surf, 1); -#ifdef EGL_VERSION_1_2 - surf->SwapBehavior = EGL_BUFFER_DESTROYED; /* XXX ok? */ - surf->HorizontalResolution = EGL_UNKNOWN; /* set by caller */ - surf->VerticalResolution = EGL_UNKNOWN; /* set by caller */ - surf->AspectRatio = EGL_UNKNOWN; /* set by caller */ - surf->RenderBuffer = renderBuffer; - surf->AlphaFormat = alphaFormat; - surf->Colorspace = colorspace; -#endif + err = _eglParseSurfaceAttribList(surf, attrib_list); + if (err != EGL_SUCCESS) + return _eglError(err, func); return EGL_TRUE; } @@ -237,7 +264,7 @@ _eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) EGLBoolean _eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, - NativePixmapType target) + EGLNativePixmapType target) { /* copy surface to native pixmap */ /* All implementation burdon for this is in the device driver */ @@ -252,139 +279,95 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, switch (attribute) { case EGL_WIDTH: *value = surface->Width; - return EGL_TRUE; + break; case EGL_HEIGHT: *value = surface->Height; - return EGL_TRUE; + break; case EGL_CONFIG_ID: *value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID); - return EGL_TRUE; + break; case EGL_LARGEST_PBUFFER: - *value = dpy->LargestPbuffer; - return EGL_TRUE; - case EGL_SURFACE_TYPE: - *value = surface->Type; - return EGL_TRUE; -#ifdef EGL_VERSION_1_1 + *value = surface->LargestPbuffer; + break; case EGL_TEXTURE_FORMAT: /* texture attributes: only for pbuffers, no error otherwise */ if (surface->Type == EGL_PBUFFER_BIT) *value = surface->TextureFormat; - return EGL_TRUE; + break; case EGL_TEXTURE_TARGET: if (surface->Type == EGL_PBUFFER_BIT) *value = surface->TextureTarget; - return EGL_TRUE; + break; case EGL_MIPMAP_TEXTURE: if (surface->Type == EGL_PBUFFER_BIT) *value = surface->MipmapTexture; - return EGL_TRUE; + break; case EGL_MIPMAP_LEVEL: if (surface->Type == EGL_PBUFFER_BIT) *value = surface->MipmapLevel; - return EGL_TRUE; -#endif /* EGL_VERSION_1_1 */ -#ifdef EGL_VERSION_1_2 + break; case EGL_SWAP_BEHAVIOR: *value = surface->SwapBehavior; - return EGL_TRUE; + break; case EGL_RENDER_BUFFER: *value = surface->RenderBuffer; - return EGL_TRUE; + break; case EGL_PIXEL_ASPECT_RATIO: *value = surface->AspectRatio; - return EGL_TRUE; + break; case EGL_HORIZONTAL_RESOLUTION: *value = surface->HorizontalResolution; - return EGL_TRUE; + break; case EGL_VERTICAL_RESOLUTION: *value = surface->VerticalResolution; - return EGL_TRUE; - case EGL_ALPHA_FORMAT: - *value = surface->AlphaFormat; - return EGL_TRUE; - case EGL_COLORSPACE: - *value = surface->Colorspace; - return EGL_TRUE; -#endif /* EGL_VERSION_1_2 */ + break; + case EGL_MULTISAMPLE_RESOLVE: + *value = surface->MultisampleResolve; + break; + case EGL_VG_ALPHA_FORMAT: + *value = surface->VGAlphaFormat; + break; + case EGL_VG_COLORSPACE: + *value = surface->VGColorspace; + break; default: _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); return EGL_FALSE; } + + return EGL_TRUE; } /** - * Example function - drivers should do a proper implementation. + * Drivers should do a proper implementation. */ _EGLSurface * _eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - NativeWindowType window, const EGLint *attrib_list) + EGLNativeWindowType window, const EGLint *attrib_list) { -#if 0 /* THIS IS JUST EXAMPLE CODE */ - _EGLSurface *surf; - - surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); - if (!surf) - return NULL; - - if (!_eglInitSurface(drv, surf, EGL_WINDOW_BIT, conf, attrib_list)) { - free(surf); - return NULL; - } - - return surf; -#endif return NULL; } /** - * Example function - drivers should do a proper implementation. + * Drivers should do a proper implementation. */ _EGLSurface * _eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - NativePixmapType pixmap, const EGLint *attrib_list) + EGLNativePixmapType pixmap, const EGLint *attrib_list) { -#if 0 /* THIS IS JUST EXAMPLE CODE */ - _EGLSurface *surf; - - surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); - if (!surf) - return NULL; - - if (!_eglInitSurface(drv, surf, EGL_PIXMAP_BIT, conf, attrib_list)) { - free(surf); - return NULL; - } - - return surf; -#endif return NULL; } /** - * Example function - drivers should do a proper implementation. + * Drivers should do a proper implementation. */ _EGLSurface * _eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list) { -#if 0 /* THIS IS JUST EXAMPLE CODE */ - _EGLSurface *surf; - - surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); - if (!surf) - return NULL; - - if (!_eglInitSurface(drv, surf, EGL_PBUFFER_BIT, conf, attrib_list)) { - free(surf); - return NULL; - } - - return NULL; -#endif return NULL; } @@ -408,14 +391,59 @@ EGLBoolean _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint value) { + EGLint confval; + EGLint err = EGL_SUCCESS; + switch (attribute) { case EGL_MIPMAP_LEVEL: + confval = GET_CONFIG_ATTRIB(surface->Config, EGL_RENDERABLE_TYPE); + if (!(confval & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT))) { + err = EGL_BAD_PARAMETER; + break; + } surface->MipmapLevel = value; break; + case EGL_MULTISAMPLE_RESOLVE: + switch (value) { + case EGL_MULTISAMPLE_RESOLVE_DEFAULT: + break; + case EGL_MULTISAMPLE_RESOLVE_BOX: + confval = GET_CONFIG_ATTRIB(surface->Config, EGL_SURFACE_TYPE); + if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT)) + err = EGL_BAD_MATCH; + break; + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + if (err != EGL_SUCCESS) + break; + surface->MultisampleResolve = value; + break; + case EGL_SWAP_BEHAVIOR: + switch (value) { + case EGL_BUFFER_DESTROYED: + break; + case EGL_BUFFER_PRESERVED: + confval = GET_CONFIG_ATTRIB(surface->Config, EGL_SURFACE_TYPE); + if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)) + err = EGL_BAD_MATCH; + break; + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + if (err != EGL_SUCCESS) + break; + surface->SwapBehavior = value; + break; default: - _eglError(EGL_BAD_ATTRIBUTE, "eglSurfaceAttrib"); - return EGL_FALSE; + err = EGL_BAD_ATTRIBUTE; + break; } + + if (err != EGL_SUCCESS) + return _eglError(err, "eglSurfaceAttrib"); return EGL_TRUE; }