From bf7f998f39852f5126ea455b1f48007f02d1ad11 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 17 May 2005 02:18:38 +0000 Subject: [PATCH] Added software-based pbuffer support (untested). Use _eglConfigToContextModesRec() function and remove need for the _EGLConfig->glmode struct. Silence some compiler warnings. --- src/mesa/drivers/dri/fb/fb_egl.c | 177 ++++++++++++++----------------- 1 file changed, 81 insertions(+), 96 deletions(-) diff --git a/src/mesa/drivers/dri/fb/fb_egl.c b/src/mesa/drivers/dri/fb/fb_egl.c index d83d264a970..813afec0352 100644 --- a/src/mesa/drivers/dri/fb/fb_egl.c +++ b/src/mesa/drivers/dri/fb/fb_egl.c @@ -146,8 +146,9 @@ fbFillInConfigs(_EGLDisplay *disp, unsigned pixel_bits, unsigned depth_bits, /* Mark the visual as slow if there are "fake" stencil bits. */ for (i = 0, c = configs; i < num_configs; i++, c++) { - if ((c->glmode.stencilBits != 0) && (c->glmode.stencilBits != stencil_bits)) { - c->glmode.visualRating = GLX_SLOW_CONFIG; + int stencil = GET_CONFIG_ATTRIB(c, EGL_STENCIL_SIZE); + if ((stencil != 0) && (stencil != stencil_bits)) { + SET_CONFIG_ATTRIB(c, EGL_CONFIG_CAVEAT, EGL_SLOW_CONFIG); } } @@ -228,7 +229,7 @@ fbInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) fbScreen *s; _EGLScreen *scrn; char c; - unsigned int i, x, y, r; + unsigned int x, y, r; DIR *dir; FILE *file; struct dirent *dirent; @@ -249,7 +250,7 @@ fbInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) return EGL_FALSE; } - while (dirent = readdir(dir)) { + while ((dirent = readdir(dir))) { /* assignment! */ if (dirent->d_name[0] != 'f') continue; @@ -394,6 +395,7 @@ fbCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext sh fbContext *c; _EGLDisplay *disp = _eglLookupDisplay(dpy); struct dd_function_table functions; + GLvisual vis; int i; conf = _eglLookupConfig(drv, dpy, config); @@ -431,7 +433,9 @@ fbCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext sh _mesa_init_driver_functions(&functions); init_core_functions(&functions); - ctx = c->glCtx = _mesa_create_context(&conf->glmode, NULL, &functions, (void *)c); + _eglConfigToContextModesRec(conf, &vis); + + ctx = c->glCtx = _mesa_create_context(&vis, NULL, &functions, (void *)c); if (!c->glCtx) { _mesa_free(c); return GL_FALSE; @@ -518,66 +522,39 @@ fbCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeP static EGLSurface fbCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { - _EGLConfig *conf; - EGLint i, width = 0, height = 0, largest, texFormat, texTarget, mipmapTex; fbSurface *surf; - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface"); + surf = (fbSurface *) calloc(1, sizeof(fbSurface)); + if (!surf) { 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)"); + if (_eglInitPbufferSurface(&surf->Base, drv, dpy, config, attrib_list)) { + free(surf); return EGL_NO_SURFACE; } - surf = (fbSurface *) calloc(1, sizeof(fbSurface)); - if (!surf) - return EGL_NO_SURFACE; - - surf->Base.Config = conf; - surf->Base.Type = EGL_PBUFFER_BIT; - surf->Base.Width = width; - surf->Base.Height = height; - surf->Base.TextureFormat = texFormat; - surf->Base.TextureTarget = texTarget; - surf->Base.MipmapTexture = mipmapTex; - surf->Base.MipmapLevel = 0; - surf->Base.SwapInterval = 0; - - printf("eglCreatePbufferSurface()\n"); - - /* insert into hash table */ - _eglSaveSurface(&surf->Base); - assert(surf->Base.Handle); + /* create software-based pbuffer */ + { + GLcontext *ctx = NULL; /* this _should_ be OK */ + GLvisual vis; + _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); + assert(conf); /* bad config should be caught earlier */ + _eglConfigToContextModesRec(conf, &vis); + + surf->mesa_framebuffer = _mesa_create_framebuffer(&vis); + _mesa_add_soft_renderbuffers(surf->mesa_framebuffer, + GL_TRUE, /* color bufs */ + vis.haveDepthBuffer, + vis.haveStencilBuffer, + vis.haveAccumBuffer, + GL_FALSE, /* alpha */ + GL_FALSE /* aux */ ); + + /* set pbuffer/framebuffer size */ + _mesa_resize_framebuffer(ctx, surf->mesa_framebuffer, + surf->Base.Width, surf->Base.Height); + } return surf->Base.Handle; } @@ -637,79 +614,82 @@ fbMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, } -static const char * -fbQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name) -{ - if (name == EGL_EXTENSIONS) { - return "EGL_MESA_screen_surface"; - } - else { - return _eglQueryString(drv, dpy, name); - } -} - - /** * Create a drawing surface which can be directly displayed on a screen. */ static EGLSurface fbCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, - const EGLint *attrib_list) + const EGLint *attrib_list) { _EGLConfig *config = _eglLookupConfig(drv, dpy, cfg); fbDisplay *display = Lookup_fbDisplay(dpy); fbSurface *surface; EGLSurface surf; - - const GLboolean swDepth = config->glmode.depthBits > 0; - const GLboolean swAlpha = config->glmode.alphaBits > 0; - const GLboolean swAccum = config->glmode.accumRedBits > 0; - const GLboolean swStencil = config->glmode.stencilBits > 0; - - int bytesPerPixel = config->glmode.rgbBits / 8; - int origin = 0; + GLvisual vis; + GLcontext *ctx = NULL; /* this should be OK */ + int origin, bytesPerPixel; int width, height, stride; - surface = (fbSurface *)malloc(sizeof(*surface)); + surface = (fbSurface *) malloc(sizeof(*surface)); + if (!surface) { + return EGL_NO_SURFACE; + } + + /* init base class, error check, etc. */ surf = _eglInitScreenSurface(&surface->Base, drv, dpy, cfg, attrib_list); if (surf == EGL_NO_SURFACE) { free(surface); return EGL_NO_SURFACE; } - width = surface->Base.Width; - stride = width * bytesPerPixel; - height = surface->Base.Height; - surface->mesa_framebuffer = _mesa_create_framebuffer(&config->glmode); + /* convert EGLConfig to GLvisual */ + _eglConfigToContextModesRec(config, &vis); + + /* create Mesa framebuffer */ + surface->mesa_framebuffer = _mesa_create_framebuffer(&vis); if (!surface->mesa_framebuffer) { free(surface); + _eglRemoveSurface(&surface->Base); return EGL_NO_SURFACE; } - surface->mesa_framebuffer->Width = width; - surface->mesa_framebuffer->Height = height; + + width = surface->Base.Width; + stride = width * bytesPerPixel; + height = surface->Base.Height; + bytesPerPixel = vis.rgbBits / 8; + origin = 0; + + /* front color renderbuffer */ { - driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, bytesPerPixel, origin, stride); - fbSetSpanFunctions(drb, &config->glmode); + driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, bytesPerPixel, + origin, stride); + fbSetSpanFunctions(drb, &vis); drb->Base.Data = display->pFB; _mesa_add_renderbuffer(surface->mesa_framebuffer, BUFFER_FRONT_LEFT, &drb->Base); } - if (config->glmode.doubleBufferMode) { - driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, bytesPerPixel, origin, stride); - fbSetSpanFunctions(drb, &config->glmode); + + /* back color renderbuffer */ + if (vis.doubleBufferMode) { + driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, bytesPerPixel, + origin, stride); + fbSetSpanFunctions(drb, &vis); drb->Base.Data = _mesa_malloc(stride * height); _mesa_add_renderbuffer(surface->mesa_framebuffer, BUFFER_BACK_LEFT, &drb->Base); } + /* other renderbuffers- software based */ _mesa_add_soft_renderbuffers(surface->mesa_framebuffer, GL_FALSE, /* color */ - swDepth, - swStencil, - swAccum, - swAlpha, + vis.haveDepthBuffer, + vis.haveStencilBuffer, + vis.haveAccumBuffer, + GL_FALSE, /* alpha */ GL_FALSE /* aux */); + _mesa_resize_framebuffer(ctx, surface->mesa_framebuffer, width, height); + return surf; } @@ -727,6 +707,7 @@ fbShowSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, fbScreen *scrn = Lookup_fbScreen(dpy, screen); fbSurface *surf = Lookup_fbSurface(surface); _EGLMode *mode = _eglLookupMode(dpy, m); + int bits; if (!_eglShowSurfaceMESA(drv, dpy, screen, surface, m)) return EGL_FALSE; @@ -759,7 +740,8 @@ err: file = fopen(buffer, "r+"); if (!file) goto err; - snprintf(buffer, sizeof(buffer), "%d", surf->Base.Config->glmode.rgbBits); + bits = GET_CONFIG_ATTRIB(surf->Base.Config, EGL_BUFFER_SIZE); + snprintf(buffer, sizeof(buffer), "%d", bits); fputs(buffer, file); fclose(file); @@ -809,9 +791,12 @@ _eglMain(NativeDisplayType dpy) fb->Base.CreatePbufferSurface = fbCreatePbufferSurface; fb->Base.DestroySurface = fbDestroySurface; fb->Base.DestroyContext = fbDestroyContext; - fb->Base.QueryString = fbQueryString; fb->Base.CreateScreenSurfaceMESA = fbCreateScreenSurfaceMESA; fb->Base.ShowSurfaceMESA = fbShowSurfaceMESA; + /* enable supported extensions */ + fb->Base.MESA_screen_surface = EGL_TRUE; + fb->Base.MESA_copy_context = EGL_TRUE; + return &fb->Base; } -- 2.30.2