From d548bf41d3a0fe443494f94f745d1fe49e5e432c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 27 Nov 2005 23:57:19 +0000 Subject: [PATCH] Redo _eglInitSurface() so it can be used with all surface types. Redo _eglInitContext() to do error checking, attribute list parsing, etc. --- src/egl/main/eglconfig.c | 20 +-- src/egl/main/eglcontext.c | 62 ++++++--- src/egl/main/eglcontext.h | 5 +- src/egl/main/eglscreen.c | 63 ++------- src/egl/main/eglscreen.h | 14 +- src/egl/main/eglsurface.c | 276 +++++++++++++++++++++++++------------- src/egl/main/eglsurface.h | 11 +- 7 files changed, 273 insertions(+), 178 deletions(-) diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c index eba608b0ba8..dea60028506 100644 --- a/src/egl/main/eglconfig.c +++ b/src/egl/main/eglconfig.c @@ -303,7 +303,8 @@ _eglCompareConfigs(const _EGLConfig *a, const _EGLConfig *b) * Typical fallback routine for eglChooseConfig */ EGLBoolean -_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) +_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, + EGLConfig *configs, EGLint config_size, EGLint *num_config) { _EGLDisplay *disp = _eglLookupDisplay(dpy); _EGLConfig criteria; @@ -339,7 +340,8 @@ _eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGL * Fallback for eglGetConfigAttrib. */ EGLBoolean -_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) +_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + EGLint attribute, EGLint *value) { const _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); const EGLint k = attribute - FIRST_ATTRIB; @@ -358,7 +360,8 @@ _eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint at * Fallback for eglGetConfigs. */ EGLBoolean -_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) +_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, + EGLint config_size, EGLint *num_config) { _EGLDisplay *disp = _eglLookupDisplay(dpy); @@ -449,11 +452,12 @@ _eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint confi */ GLboolean _eglFillInConfigs(_EGLConfig * configs, - GLenum fb_format, GLenum fb_type, - const u_int8_t * depth_bits, const u_int8_t * stencil_bits, - unsigned num_depth_stencil_bits, - const GLenum * db_modes, unsigned num_db_modes, - int visType) { + GLenum fb_format, GLenum fb_type, + const u_int8_t * depth_bits, const u_int8_t * stencil_bits, + unsigned num_depth_stencil_bits, + const GLenum * db_modes, unsigned num_db_modes, + int visType) +{ static const u_int8_t bits_table[3][4] = { /* R G B A */ { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */ diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index 42edd1f77e0..b760ebcb40a 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -3,6 +3,7 @@ #include #include "eglconfig.h" #include "eglcontext.h" +#include "egldisplay.h" #include "egldriver.h" #include "eglglobals.h" #include "eglhash.h" @@ -12,11 +13,36 @@ /** * Initialize the given _EGLContext object to defaults. */ -void -_eglInitContext(_EGLContext *ctx) +EGLBoolean +_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx, + EGLConfig config, const EGLint *attrib_list) { - /* just init to zero for now */ + _EGLConfig *conf; + _EGLDisplay *display = _eglLookupDisplay(dpy); + EGLint i; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreateContext"); + return EGL_FALSE; + } + + for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { + switch (attrib_list[i]) { + /* no attribs defined for now */ + default: + _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); + return EGL_NO_CONTEXT; + } + } + memset(ctx, 0, sizeof(_EGLContext)); + ctx->Display = display; + ctx->Config = conf; + ctx->DrawSurface = EGL_NO_SURFACE; + ctx->ReadSurface = EGL_NO_SURFACE; + + return EGL_TRUE; } @@ -70,22 +96,24 @@ _eglGetCurrentContext(void) * Just a placeholder/demo function. Real driver will never use this! */ EGLContext -_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) +_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + EGLContext share_list, const EGLint *attrib_list) { - _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreateContext"); +#if 0 /* example code */ + _EGLContext *context; + + context = (_EGLContext *) calloc(1, sizeof(_EGLContext)); + if (!context) return EGL_NO_CONTEXT; - } - if (share_list != EGL_NO_CONTEXT) { - _EGLContext *shareCtx = _eglLookupContext(share_list); - if (!shareCtx) { - _eglError(EGL_BAD_CONTEXT, "eglCreateContext(share_list)"); - return EGL_NO_CONTEXT; - } + if (!_eglInitContext(drv, dpy, context, config, attrib_list)) { + free(context); + return EGL_NO_CONTEXT; } + _eglSaveContext(context); + return context->Handle; +#endif return EGL_NO_CONTEXT; } @@ -115,7 +143,8 @@ _eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx) EGLBoolean -_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) +_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, + EGLint attribute, EGLint *value) { _EGLContext *c = _eglLookupContext(ctx); @@ -144,7 +173,8 @@ _eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribu * Then, the driver will do its device-dependent Make-Current stuff. */ EGLBoolean -_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, EGLSurface r, EGLContext context) +_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, + EGLSurface r, EGLContext context) { _EGLContext *ctx = _eglLookupContext(context); _EGLSurface *draw = _eglLookupSurface(d); diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h index d74d6e3253e..4b0eaf3107d 100644 --- a/src/egl/main/eglcontext.h +++ b/src/egl/main/eglcontext.h @@ -25,8 +25,9 @@ struct _egl_context }; -extern void -_eglInitContext(_EGLContext *ctx); +extern EGLBoolean +_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx, + EGLConfig config, const EGLint *attrib_list); extern void diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c index e213e9a8472..c4cc8bfe1ac 100644 --- a/src/egl/main/eglscreen.c +++ b/src/egl/main/eglscreen.c @@ -106,67 +106,30 @@ _eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, /** - * Initialize the given _EGLSurface object. Do error checking. - * Assign it an EGLSurface handle and insert into hash table. - * \return EGLSurface handle or EGL_NO_SURFACE if error. + * Example function - drivers should do a proper implementation. */ EGLSurface -_eglInitScreenSurface(_EGLSurface *surf, _EGLDriver *drv, EGLDisplay dpy, - EGLConfig config, const EGLint *attrib_list) +_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + const EGLint *attrib_list) { - EGLint width = 0, height = 0; - EGLint i; +#if 0 /* THIS IS JUST EXAMPLE CODE */ + _EGLSurface *surf; - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - case EGL_WIDTH: - width = attrib_list[++i]; - break; - case EGL_HEIGHT: - height = attrib_list[++i]; - break; - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreateScreenSurfaceMESA"); - return EGL_NO_SURFACE; - } - } + surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); + if (!surf) + return EGL_NO_SURFACE; - if (width <= 0 || height <= 0) { - _eglError(EGL_BAD_ATTRIBUTE, - "eglCreateScreenSurfaceMESA(width or height)"); + if (!_eglInitSurface(drv, dpy, surf, EGL_SCREEN_BIT_MESA, + config, attrib_list)) { + free(surf); return EGL_NO_SURFACE; } - _eglInitSurface(surf); - surf->Width = width; - surf->Height = height; - surf->Type = EGL_SCREEN_BIT_MESA; - surf->Config = _eglLookupConfig(drv, dpy, config); - - /* insert into hash table */ _eglSaveSurface(surf); - assert(surf->Handle); return surf->Handle; -} - - -/** - * Create a drawing surface which can be directly displayed on a screen. - */ -EGLSurface -_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, - const EGLint *attrib_list) -{ - _EGLSurface *surf; - EGLSurface surface; - - surf = (_EGLSurface *) malloc(sizeof(_EGLSurface)); - surface = _eglInitScreenSurface(surf, drv, dpy, config, attrib_list); - if (surface == EGL_NO_SURFACE) - free(surf); - - return surface; +#endif + return EGL_NO_SURFACE; } diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h index afc52a5ecb7..64198446aee 100644 --- a/src/egl/main/eglscreen.h +++ b/src/egl/main/eglscreen.h @@ -6,6 +6,16 @@ * an integer. */ + +/** + * Per-screen information. + * Note that an EGL screen doesn't have a size. A screen may be set to + * one of several display modes (width/height/scanrate). The screen + * then displays a drawing surface. The drawing surface must be at least + * as large as the display mode's resolution. If it's larger, the + * OriginX and OriginY fields control what part of the surface is visible + * on the screen. + */ struct _egl_screen { EGLScreenMESA Handle; /* The public/opaque handle which names this object */ @@ -35,10 +45,6 @@ extern EGLBoolean _eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens); -extern EGLSurface -_eglInitScreenSurface(_EGLSurface *surf, _EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); - - extern EGLSurface _eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index fdc2de62361..82f47f116b6 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -10,16 +10,134 @@ #include #include "eglcontext.h" #include "eglconfig.h" -#include "eglsurface.h" #include "eglglobals.h" #include "eglhash.h" +#include "egllog.h" +#include "eglsurface.h" -void -_eglInitSurface(_EGLSurface *surf) +/** + * Do error check on parameters and initialize the given _EGLSurface object. + * \return EGL_TRUE if no errors, EGL_FALSE otherwise. + */ +EGLBoolean +_eglInitSurface(_EGLDriver *drv, EGLDisplay dpy, + _EGLSurface *surf, EGLint type, EGLConfig config, + const EGLint *attrib_list) { - /* XXX fix this up */ + const char *func; + _EGLConfig *conf; + EGLint width = 0, height = 0, largest = 0; + EGLint texFormat = 0, texTarget = 0, mipmapTex = 0; + EGLint i; + + switch (type) { + case EGL_WINDOW_BIT: + func = "eglCreateWindowSurface"; + break; + case EGL_PIXMAP_BIT: + func = "eglCreatePixmapSurface"; + break; + case EGL_PBUFFER_BIT: + func = "eglCreatePBufferSurface"; + break; + case EGL_SCREEN_BIT_MESA: + func = "eglCreateScreenSurface"; + break; + default: + _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface"); + return EGL_FALSE; + } + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _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; + 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->Type = type; + surf->Width = width; + surf->Height = height; + surf->TextureFormat = texFormat; + surf->TextureTarget = texTarget; + surf->MipmapTexture = mipmapTex; + surf->MipmapLevel = 0; + surf->SwapInterval = 0; + + return EGL_TRUE; } @@ -27,7 +145,9 @@ void _eglSaveSurface(_EGLSurface *surf) { assert(surf); + assert(!surf->Handle); surf->Handle = _eglHashGenKey(_eglGlobal.Contexts); + assert(surf->Handle); _eglHashInsert(_eglGlobal.Surfaces, surf->Handle, surf); } @@ -86,7 +206,8 @@ _eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) EGLBoolean -_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target) +_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, + NativePixmapType target) { /* copy surface to native pixmap */ /* All implementation burdon for this is in the device driver */ @@ -95,7 +216,8 @@ _eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixma EGLBoolean -_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, EGLint attribute, EGLint *value) +_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, + EGLint attribute, EGLint *value) { _EGLSurface *surface = _eglLookupSurface(surf); if (surface == NULL) { @@ -140,34 +262,82 @@ _eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, EGLint attrib /** - * Default fallback routine - drivers should usually override this. + * Example function - drivers should do a proper implementation. */ EGLSurface -_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) +_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + NativeWindowType window, const EGLint *attrib_list) { - /* nothing - just a placeholder */ +#if 0 /* THIS IS JUST EXAMPLE CODE */ + _EGLSurface *surf; + + surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); + if (!surf) + return EGL_NO_SURFACE; + + if (!_eglInitSurface(drv, dpy, surf, EGL_WINDOW_BIT, config, attrib_list)) { + free(surf); + return EGL_NO_SURFACE; + } + + _eglSaveSurface(surf); + + return surf->Handle; +#endif return EGL_NO_SURFACE; } /** - * Default fallback routine - drivers should usually override this. + * Example function - drivers should do a proper implementation. */ EGLSurface -_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) +_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + NativePixmapType pixmap, const EGLint *attrib_list) { - /* nothing - just a placeholder */ +#if 0 /* THIS IS JUST EXAMPLE CODE */ + _EGLSurface *surf; + + surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); + if (!surf) + return EGL_NO_SURFACE; + + if (!_eglInitSurface(drv, dpy, surf, EGL_PIXMAP_BIT, config, attrib_list)) { + free(surf); + return EGL_NO_SURFACE; + } + + _eglSaveSurface(surf); + + return surf->Handle; +#endif return EGL_NO_SURFACE; } /** - * Default fallback routine - drivers should usually override this. + * Example function - drivers should do a proper implementation. */ EGLSurface -_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) +_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + const EGLint *attrib_list) { - /* nothing - just a placeholder */ +#if 0 /* THIS IS JUST EXAMPLE CODE */ + _EGLSurface *surf; + + surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); + if (!surf) + return EGL_NO_SURFACE; + + if (!_eglInitSurface(drv, dpy, surf, EGL_PBUFFER_BIT, config, attrib_list)) { + free(surf); + return EGL_NO_SURFACE; + } + + _eglSaveSurface(surf); + + return surf->Handle; +#endif return EGL_NO_SURFACE; } @@ -248,79 +418,3 @@ _eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval) surf->SwapInterval = interval; return EGL_TRUE; } - - - -/** - ** EGL Surface Utility Functions. This could be handy for device drivers. - **/ - - -/** - * Initialize the fields of the given _EGLSurface object from the other - * parameters. Do error checking too. Allocate EGLSurface handle and - * insert into hash table. - * \return EGLSurface handle or EGL_NO_SURFACE if any error - */ -EGLSurface -_eglInitPbufferSurface(_EGLSurface *surface, _EGLDriver *drv, EGLDisplay dpy, - EGLConfig config, const EGLint *attrib_list) -{ - _EGLConfig *conf; - EGLint width = 0, height = 0, largest = 0; - EGLint texFormat = 0, texTarget = 0, mipmapTex = 0; - EGLint i; - - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface"); - return EGL_NO_SURFACE; - } - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - case EGL_WIDTH: - width = attrib_list[++i]; - break; - case EGL_HEIGHT: - height = attrib_list[++i]; - break; - case EGL_LARGEST_PBUFFER: - largest = attrib_list[++i]; - break; - case EGL_TEXTURE_FORMAT: - texFormat = attrib_list[++i]; - break; - case EGL_TEXTURE_TARGET: - texTarget = attrib_list[++i]; - break; - case EGL_MIPMAP_TEXTURE: - mipmapTex = attrib_list[++i]; - break; - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); - return EGL_NO_SURFACE; - } - } - - if (width <= 0 || height <= 0) { - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface(width or height)"); - return EGL_NO_SURFACE; - } - - surface->Config = conf; - surface->Type = EGL_PBUFFER_BIT; - surface->Width = width; - surface->Height = height; - surface->TextureFormat = texFormat; - surface->TextureTarget = texTarget; - surface->MipmapTexture = mipmapTex; - surface->MipmapLevel = 0; - surface->SwapInterval = 0; - - /* insert into hash table */ - _eglSaveSurface(surface); - assert(surface->Handle); - - return surface->Handle; -} diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h index 4853edfcd1e..bbe399211fd 100644 --- a/src/egl/main/eglsurface.h +++ b/src/egl/main/eglsurface.h @@ -28,8 +28,10 @@ struct _egl_surface }; -extern void -_eglInitSurface(_EGLSurface *surf); +extern EGLBoolean +_eglInitSurface(_EGLDriver *drv, EGLDisplay dpy, + _EGLSurface *surf, EGLint type, EGLConfig config, + const EGLint *attrib_list); extern void @@ -92,9 +94,4 @@ extern EGLBoolean _eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval); - -extern EGLSurface -_eglInitPbufferSurface(_EGLSurface *surface, _EGLDriver *drv, EGLDisplay dpy, - EGLConfig config, const EGLint *attrib_list); - #endif /* EGLSURFACE_INCLUDED */ -- 2.30.2