-/* $Id: xm_api.c,v 1.11 2000/12/08 17:37:00 brianp Exp $ */
-
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 7.1
*
- * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
-/*
- * This file contains the implementations of all the XMesa* functions.
+/**
+ * \file xm_api.c
+ *
+ * All the XMesa* API functions.
*
*
* NOTES:
#include "xmesaP.h"
#include "context.h"
#include "extensions.h"
+#include "framebuffer.h"
#include "glthread.h"
-#include "matrix.h"
-#include "mem.h"
-#include "mtypes.h"
-#ifdef HAVE_CONFIG_H
-#include "conf.h"
-#endif
+#include "imports.h"
#include "macros.h"
+#include "renderbuffer.h"
+#include "teximage.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+#include "drivers/common/driverfuncs.h"
-#ifndef GLX_NONE_EXT
-#define GLX_NONE_EXT 0x8000
-#endif
-
-
-/*
+/**
* Global X driver lock
*/
_glthread_Mutex _xmesa_lock;
-/*
+/**
* Lookup tables for HPCR pixel format:
*/
static short hpcr_rgbTbl[3][256] = {
/**********************************************************************/
-/*
- * X/Mesa error reporting function:
- */
-static void error( const char *msg )
-{
- if (getenv("MESA_DEBUG"))
- fprintf( stderr, "X/Mesa error: %s\n", msg );
-}
-
-
-/*
+/**
* Return the host's byte order as LSBFirst or MSBFirst ala X.
*/
#ifndef XFree86Server
#endif
-/*
- * Error handling.
- */
-#ifndef XFree86Server
-static int mesaXErrorFlag = 0;
-
-static int mesaHandleXError( XMesaDisplay *dpy, XErrorEvent *event )
-{
- (void) dpy;
- (void) event;
- mesaXErrorFlag = 1;
- return 0;
-}
-#endif
-
-
-/*
+/**
* Check if the X Shared Memory extension is available.
* Return: 0 = not available
* 1 = shared XImage support available
* 2 = shared Pixmap support available also
*/
-#ifndef XFree86Server
static int check_for_xshm( XMesaDisplay *display )
{
-#ifdef USE_XSHM
+#if defined(USE_XSHM) && !defined(XFree86Server)
int major, minor, ignore;
Bool pixmaps;
return 0;
}
#else
- /* Can't compile XSHM support */
+ /* No XSHM support */
return 0;
#endif
}
-#endif
-
-
-/*
- * Return the width and height of the given drawable.
- */
-static void get_drawable_size( XMesaDisplay *dpy, XMesaDrawable d,
- unsigned int *width, unsigned int *height)
-{
-#ifdef XFree86Server
- (void) dpy;
- *width = d->width;
- *height = d->height;
-#else
- Window root;
- int x, y;
- unsigned int bw, depth;
-
- _glthread_LOCK_MUTEX(_xmesa_lock);
- XGetGeometry( dpy, d, &root, &x, &y, width, height, &bw, &depth );
- _glthread_UNLOCK_MUTEX(_xmesa_lock);
-#endif
-}
-/*
+/**
* Apply gamma correction to an intensity value in [0..max]. Return the
* new intensity value.
*/
-static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
+static GLint
+gamma_adjust( GLfloat gamma, GLint value, GLint max )
{
if (gamma == 1.0) {
return value;
}
else {
double x = (double) value / (double) max;
- return (GLint) ((GLfloat) max * pow( x, 1.0F/gamma ) + 0.5F);
+ return IROUND_POS((GLfloat) max * _mesa_pow(x, 1.0F/gamma));
}
}
-/*
+/**
* Return the true number of bits per pixel for XImages.
* For example, if we request a 24-bit deep visual we may actually need/get
* 32bpp XImages. This function returns the appropriate bpp.
* visinfo - desribes the visual to be used for XImages
* Return: true number of bits per pixel for XImages
*/
-#define GET_BITS_PER_PIXEL(xmv) bits_per_pixel(xmv)
-
-#ifdef XFree86Server
-
-static int bits_per_pixel( XMesaVisual xmv )
+static int
+bits_per_pixel( XMesaVisual xmv )
{
- XMesaVisualInfo visinfo = xmv->visinfo;
- const int depth = visinfo->nplanes;
+#ifdef XFree86Server
+ const int depth = xmv->nplanes;
int i;
+ assert(depth > 0);
for (i = 0; i < screenInfo.numPixmapFormats; i++) {
if (screenInfo.formats[i].depth == depth)
return screenInfo.formats[i].bitsPerPixel;
}
return depth; /* should never get here, but this should be safe */
-}
-
#else
-
-static int bits_per_pixel( XMesaVisual xmv )
-{
XMesaDisplay *dpy = xmv->display;
XMesaVisualInfo visinfo = xmv->visinfo;
XMesaImage *img;
/* grab the bits/pixel value */
bitsPerPixel = img->bits_per_pixel;
/* free the XImage */
- FREE( img->data );
+ _mesa_free( img->data );
img->data = NULL;
XMesaDestroyImage( img );
return bitsPerPixel;
-}
#endif
+}
#endif
+static Status
+get_drawable_size(Display *dpy, Drawable d, GLuint *width, GLuint *height)
+{
+ Window root;
+ Status stat;
+ int xpos, ypos;
+ unsigned int w, h, bw, depth;
+ stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth);
+ *width = w;
+ *height = h;
+ return stat;
+}
+
+
+/**
+ * Return the size of the window (or pixmap) that corresponds to the
+ * given XMesaBuffer.
+ * \param width returns width in pixels
+ * \param height returns height in pixels
+ */
+void
+xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
+ GLuint *width, GLuint *height)
+{
+#ifdef XFree86Server
+ *width = MIN2(b->frontxrb->drawable->width, MAX_WIDTH);
+ *height = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT);
+#else
+ Status stat;
+
+ _glthread_LOCK_MUTEX(_xmesa_lock);
+ XSync(b->xm_visual->display, 0); /* added for Chromium */
+ stat = get_drawable_size(dpy, b->frontxrb->pixmap, width, height);
+ _glthread_UNLOCK_MUTEX(_xmesa_lock);
+
+ if (!stat) {
+ /* probably querying a window that's recently been destroyed */
+ _mesa_warning(NULL, "XGetGeometry failed!\n");
+ *width = *height = 1;
+ }
+#endif
+}
+
+
/**********************************************************************/
/***** Linked list of XMesaBuffers *****/
/**********************************************************************/
-static XMesaBuffer XMesaBufferList = NULL;
+XMesaBuffer XMesaBufferList = NULL;
-/* Allocate a new XMesaBuffer, add to linked list */
-static XMesaBuffer alloc_xmesa_buffer(void)
+/**
+ * Allocate a new XMesaBuffer object which corresponds to the given drawable.
+ * Note that XMesaBuffer is derived from GLframebuffer.
+ * The new XMesaBuffer will not have any size (Width=Height=0).
+ *
+ * \param d the corresponding X drawable (window or pixmap)
+ * \param type either WINDOW, PIXMAP or PBUFFER, describing d
+ * \param vis the buffer's visual
+ * \param cmap the window's colormap, if known.
+ * \return new XMesaBuffer or NULL if any problem
+ */
+static XMesaBuffer
+create_xmesa_buffer(XMesaDrawable d, BufferType type,
+ XMesaVisual vis, XMesaColormap cmap)
{
- XMesaBuffer b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
- if (b) {
- b->Next = XMesaBufferList;
- XMesaBufferList = b;
+ XMesaBuffer b;
+
+ ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
+
+ b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
+ if (!b)
+ return NULL;
+
+ b->display = vis->display;
+ b->xm_visual = vis;
+ b->type = type;
+ b->cmap = cmap;
+
+ _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual);
+ b->mesa_buffer.Delete = xmesa_delete_framebuffer;
+
+ /*
+ * Front renderbuffer
+ */
+ b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual, GL_FALSE);
+ if (!b->frontxrb) {
+ _mesa_free(b);
+ return NULL;
+ }
+ b->frontxrb->Parent = b;
+ b->frontxrb->drawable = d;
+ b->frontxrb->pixmap = (XMesaPixmap) d;
+ _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT,
+ &b->frontxrb->Base);
+
+ /*
+ * Back renderbuffer
+ */
+ if (vis->mesa_visual.doubleBufferMode) {
+ b->backxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual, GL_TRUE);
+ if (!b->backxrb) {
+ /* XXX free front xrb too */
+ _mesa_free(b);
+ return NULL;
+ }
+ b->backxrb->Parent = b;
+ /* determine back buffer implementation */
+ b->db_mode = vis->ximage_flag ? BACK_XIMAGE : BACK_PIXMAP;
+
+ _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT,
+ &b->backxrb->Base);
+ }
+
+ /*
+ * Software alpha planes
+ */
+ if (vis->mesa_visual.alphaBits > 0
+ && vis->undithered_pf != PF_8A8B8G8R
+ && vis->undithered_pf != PF_8A8R8G8B) {
+ /* Visual has alpha, but pixel format doesn't support it.
+ * We'll use an alpha renderbuffer wrapper.
+ */
+ b->swAlpha = GL_TRUE;
+ }
+ else {
+ b->swAlpha = GL_FALSE;
}
+
+ /*
+ * Other renderbuffer (depth, stencil, etc)
+ */
+ _mesa_add_soft_renderbuffers(&b->mesa_buffer,
+ GL_FALSE, /* color */
+ vis->mesa_visual.haveDepthBuffer,
+ vis->mesa_visual.haveStencilBuffer,
+ vis->mesa_visual.haveAccumBuffer,
+ b->swAlpha,
+ vis->mesa_visual.numAuxBuffers > 0 );
+
+ /* GLX_EXT_texture_from_pixmap */
+ b->TextureTarget = 0;
+ b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT;
+ b->TextureMipmap = 0;
+
+ /* insert buffer into linked list */
+ b->Next = XMesaBufferList;
+ XMesaBufferList = b;
+
return b;
}
-/*
+/**
* Find an XMesaBuffer by matching X display and colormap but NOT matching
* the notThis buffer.
*/
-static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy,
- XMesaColormap cmap,
- XMesaBuffer notThis)
+XMesaBuffer
+xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis)
{
XMesaBuffer b;
for (b=XMesaBufferList; b; b=b->Next) {
}
-/*
- * Free an XMesaBuffer, remove from linked list, perhaps free X colormap
- * entries.
+/**
+ * Remove buffer from linked list, delete if no longer referenced.
*/
-static void free_xmesa_buffer(int client, XMesaBuffer buffer)
+static void
+xmesa_free_buffer(XMesaBuffer buffer)
{
XMesaBuffer prev = NULL, b;
- (void) client;
- for (b=XMesaBufferList; b; b=b->Next) {
- if (b==buffer) {
- /* unlink bufer from list */
+
+ for (b = XMesaBufferList; b; b = b->Next) {
+ if (b == buffer) {
+ struct gl_framebuffer *fb = &buffer->mesa_buffer;
+
+ /* unlink buffer from list */
if (prev)
prev->Next = buffer->Next;
else
XMesaBufferList = buffer->Next;
- /* Check to free X colors */
- if (buffer->num_alloced>0) {
- /* If no other buffer uses this X colormap then free the colors. */
- if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) {
-#ifdef XFree86Server
- (void)FreeColors(buffer->cmap, client,
- buffer->num_alloced, buffer->alloced_colors,
- 0);
-#else
- XFreeColors(buffer->display, buffer->cmap,
- buffer->alloced_colors, buffer->num_alloced, 0);
-#endif
- }
- }
- FREE(buffer);
+
+ /* mark as delete pending */
+ fb->DeletePending = GL_TRUE;
+
+ /* Since the X window for the XMesaBuffer is going away, we don't
+ * want to dereference this pointer in the future.
+ */
+ b->frontxrb->drawable = 0;
+
+ /* Unreference. If count = zero we'll really delete the buffer */
+ _mesa_unreference_framebuffer(&fb);
+
return;
}
/* continue search */
prev = b;
}
/* buffer not found in XMesaBufferList */
- gl_problem(NULL,"free_xmesa_buffer() - buffer not found\n");
+ _mesa_problem(NULL,"xmesa_free_buffer() - buffer not found\n");
}
-/* Copy X color table stuff from one XMesaBuffer to another. */
-static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
+/**
+ * Copy X color table stuff from one XMesaBuffer to another.
+ */
+static void
+copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
{
MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table));
MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r));
/**********************************************************************/
-/*
- * Return number of bits set in n.
- */
-static int bitcount( unsigned long n )
-{
- int bits;
- for (bits=0; n>0; n=n>>1) {
- if (n&1) {
- bits++;
- }
- }
- return bits;
-}
-
-
-
-/*
- * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
- * Return: GL_TRUE if success, GL_FALSE if error
- */
-#ifndef XFree86Server
-static GLboolean alloc_shm_back_buffer( XMesaBuffer b )
-{
-#ifdef USE_XSHM
- /*
- * We have to do a _lot_ of error checking here to be sure we can
- * really use the XSHM extension. It seems different servers trigger
- * errors at different points if the extension won't work. Therefore
- * we have to be very careful...
- */
- GC gc;
- int (*old_handler)( XMesaDisplay *, XErrorEvent * );
-
- b->backimage = XShmCreateImage( b->xm_visual->display,
- b->xm_visual->visinfo->visual,
- b->xm_visual->visinfo->depth,
- ZPixmap, NULL, &b->shminfo,
- b->width, b->height );
- if (b->backimage == NULL) {
- error("alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.");
- b->shm = 0;
- return GL_FALSE;
- }
-
- b->shminfo.shmid = shmget( IPC_PRIVATE, b->backimage->bytes_per_line
- * b->backimage->height, IPC_CREAT|0777 );
- if (b->shminfo.shmid < 0) {
- if (getenv("MESA_DEBUG"))
- perror("alloc_back_buffer");
- XDestroyImage( b->backimage );
- b->backimage = NULL;
- error("alloc_back_buffer: Shared memory error (shmget), disabling.");
- b->shm = 0;
- return GL_FALSE;
- }
-
- b->shminfo.shmaddr = b->backimage->data
- = (char*)shmat( b->shminfo.shmid, 0, 0 );
- if (b->shminfo.shmaddr == (char *) -1) {
- if (getenv("MESA_DEBUG"))
- perror("alloc_back_buffer");
- XDestroyImage( b->backimage );
- shmctl( b->shminfo.shmid, IPC_RMID, 0 );
- b->backimage = NULL;
- error("alloc_back_buffer: Shared memory error (shmat), disabling.");
- b->shm = 0;
- return GL_FALSE;
- }
-
- b->shminfo.readOnly = False;
- mesaXErrorFlag = 0;
- old_handler = XSetErrorHandler( mesaHandleXError );
- /* This may trigger the X protocol error we're ready to catch: */
- XShmAttach( b->xm_visual->display, &b->shminfo );
- XSync( b->xm_visual->display, False );
-
- if (mesaXErrorFlag) {
- /* we are on a remote display, this error is normal, don't print it */
- XFlush( b->xm_visual->display );
- mesaXErrorFlag = 0;
- XDestroyImage( b->backimage );
- shmdt( b->shminfo.shmaddr );
- shmctl( b->shminfo.shmid, IPC_RMID, 0 );
- b->backimage = NULL;
- b->shm = 0;
- (void) XSetErrorHandler( old_handler );
- return GL_FALSE;
- }
-
- shmctl( b->shminfo.shmid, IPC_RMID, 0 ); /* nobody else needs it */
-
- /* Finally, try an XShmPutImage to be really sure the extension works */
- gc = XCreateGC( b->xm_visual->display, b->frontbuffer, 0, NULL );
- XShmPutImage( b->xm_visual->display, b->frontbuffer, gc,
- b->backimage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False );
- XSync( b->xm_visual->display, False );
- XFreeGC( b->xm_visual->display, gc );
- (void) XSetErrorHandler( old_handler );
- if (mesaXErrorFlag) {
- XFlush( b->xm_visual->display );
- mesaXErrorFlag = 0;
- XDestroyImage( b->backimage );
- shmdt( b->shminfo.shmaddr );
- shmctl( b->shminfo.shmid, IPC_RMID, 0 );
- b->backimage = NULL;
- b->shm = 0;
- return GL_FALSE;
- }
-
- if (b->backimage) {
- int height = b->backimage->height;
- /* Needed by PIXELADDR1 macro */
- b->ximage_width1 = b->backimage->bytes_per_line;
- b->ximage_origin1 = (GLubyte *) b->backimage->data
- + b->ximage_width1 * (height-1);
- /* Needed by PIXELADDR2 macro */
- b->ximage_width2 = b->backimage->bytes_per_line / 2;
- b->ximage_origin2 = (GLushort *) b->backimage->data
- + b->ximage_width2 * (height-1);
- /* Needed by PIXELADDR3 macro */
- b->ximage_width3 = b->backimage->bytes_per_line;
- b->ximage_origin3 = (GLubyte *) b->backimage->data
- + b->ximage_width3 * (height-1);
- /* Needed by PIXELADDR4 macro */
- b->ximage_width4 = b->backimage->width;
- b->ximage_origin4 = (GLuint *) b->backimage->data
- + b->ximage_width4 * (height-1);
- }
-
- return GL_TRUE;
-#else
- /* Can't compile XSHM support */
- return GL_FALSE;
-#endif
-}
-#endif
-
-
-
-/*
- * Setup an off-screen pixmap or Ximage to use as the back buffer.
- * Input: b - the X/Mesa buffer
- */
-void xmesa_alloc_back_buffer( XMesaBuffer b )
-{
- if (b->db_state==BACK_XIMAGE) {
- /* Deallocate the old backimage, if any */
- if (b->backimage) {
-#if defined(USE_XSHM) && !defined(XFree86Server)
- if (b->shm) {
- XShmDetach( b->xm_visual->display, &b->shminfo );
- XDestroyImage( b->backimage );
- shmdt( b->shminfo.shmaddr );
- }
- else
-#endif
- XMesaDestroyImage( b->backimage );
- b->backimage = NULL;
- }
-
- /* Allocate new back buffer */
-#ifdef XFree86Server
- {
- /* Allocate a regular XImage for the back buffer. */
- b->backimage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
- b->width, b->height, NULL);
-#else
- if (b->shm==0
- || alloc_shm_back_buffer(b)==GL_FALSE
- ) {
- /* Allocate a regular XImage for the back buffer. */
- b->backimage = XCreateImage( b->xm_visual->display,
- b->xm_visual->visinfo->visual,
- GET_VISUAL_DEPTH(b->xm_visual),
- ZPixmap, 0, /* format, offset */
- NULL, b->width, b->height,
- 8, 0 ); /* pad, bytes_per_line */
-#endif
- if (!b->backimage) {
- error("alloc_back_buffer: XCreateImage failed.");
- }
- b->backimage->data = (char *) MALLOC( b->backimage->height
- * b->backimage->bytes_per_line );
- if (!b->backimage->data) {
- error("alloc_back_buffer: MALLOC failed.");
- XMesaDestroyImage( b->backimage );
- b->backimage = NULL;
- }
- }
- b->backpixmap = None;
- }
- else if (b->db_state==BACK_PIXMAP) {
- XMesaPixmap old_pixmap = b->backpixmap;
- /* Free the old back pixmap */
- if (b->backpixmap) {
- XMesaFreePixmap( b->xm_visual->display, b->backpixmap );
- }
- /* Allocate new back pixmap */
- b->backpixmap = XMesaCreatePixmap( b->xm_visual->display, b->frontbuffer,
- b->width, b->height,
- GET_VISUAL_DEPTH(b->xm_visual) );
- b->backimage = NULL;
- /* update other references to backpixmap */
- if (b->buffer==(XMesaDrawable)old_pixmap) {
- b->buffer = (XMesaDrawable)b->backpixmap;
- }
- }
-}
-
-
-
-/*
+/**
* A replacement for XAllocColor. This function should never
* fail to allocate a color. When XAllocColor fails, we return
* the nearest matching color. If we have to allocate many colors
if (AllocColor(cmap,
&color->red, &color->green, &color->blue,
&color->pixel,
- client) == Success) {
+ client) == Success)
#else
- if (XAllocColor(dpy, cmap, color)) {
+ if (XAllocColor(dpy, cmap, color))
#endif
+ {
*exact = 1;
*alloced = 1;
return;
|| prevCmapSize != cmapSize || !ctable) {
/* free previously cached color table */
if (ctable)
- FREE(ctable);
+ _mesa_free(ctable);
/* Get the color table from X */
ctable = (XMesaColor *) MALLOC(cmapSize * sizeof(XMesaColor));
assert(ctable);
*alloced = 0;
}
#ifdef XFree86Server
- FREE(ppixIn);
- FREE(ctable);
+ _mesa_free(ppixIn);
+ _mesa_free(ctable);
#else
/* don't free table, save it for next time */
#endif
-
-/*
+/**
* Do setup for PF_GRAYSCALE pixel format.
* Note that buffer may be NULL.
*/
-static GLboolean setup_grayscale( int client, XMesaVisual v,
- XMesaBuffer buffer, XMesaColormap cmap )
+static GLboolean
+setup_grayscale(int client, XMesaVisual v,
+ XMesaBuffer buffer, XMesaColormap cmap)
{
if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
return GL_FALSE;
return GL_FALSE;
}
- prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
+ prevBuffer = xmesa_find_buffer(v->display, cmap, buffer);
if (prevBuffer &&
- (buffer->xm_visual->gl_visual->RGBAflag ==
- prevBuffer->xm_visual->gl_visual->RGBAflag)) {
+ (buffer->xm_visual->mesa_visual.rgbMode ==
+ prevBuffer->xm_visual->mesa_visual.rgbMode)) {
/* Copy colormap stuff from previous XMesaBuffer which uses same
* X colormap. Do this to avoid time spent in noFaultXAllocColor.
*/
buffer->pixel_to_b[xcol.pixel] = gray;
}
- if (colorsfailed && getenv("MESA_DEBUG")) {
- fprintf( stderr,
+ if (colorsfailed && _mesa_getenv("MESA_DEBUG")) {
+ _mesa_warning(NULL,
"Note: %d out of 256 needed colors do not match exactly.\n",
colorsfailed );
}
}
}
- v->dithered_pf = PF_GRAYSCALE;
- v->undithered_pf = PF_GRAYSCALE;
+ v->dithered_pf = PF_Grayscale;
+ v->undithered_pf = PF_Grayscale;
return GL_TRUE;
}
-/*
+/**
* Setup RGB rendering for a window with a PseudoColor, StaticColor,
* or 8-bit TrueColor visual visual. We try to allocate a palette of 225
* colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB
* visuals, it has also proven to work from 4-bit up to 16-bit visuals.
* Dithering code contributed by Bob Mercier.
*/
-static GLboolean setup_dithered_color( int client, XMesaVisual v,
- XMesaBuffer buffer, XMesaColormap cmap )
+static GLboolean
+setup_dithered_color(int client, XMesaVisual v,
+ XMesaBuffer buffer, XMesaColormap cmap)
{
if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
return GL_FALSE;
return GL_FALSE;
}
- prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
+ prevBuffer = xmesa_find_buffer(v->display, cmap, buffer);
if (prevBuffer &&
- (buffer->xm_visual->gl_visual->RGBAflag ==
- prevBuffer->xm_visual->gl_visual->RGBAflag)) {
+ (buffer->xm_visual->mesa_visual.rgbMode ==
+ prevBuffer->xm_visual->mesa_visual.rgbMode)) {
/* Copy colormap stuff from previous, matching XMesaBuffer.
* Do this to avoid time spent in noFaultXAllocColor.
*/
/* Allocate X colors and initialize color_table[], red_table[], etc */
int r, g, b, i;
int colorsfailed = 0;
- for (r = 0; r < _R; r++) {
- for (g = 0; g < _G; g++) {
- for (b = 0; b < _B; b++) {
+ for (r = 0; r < DITH_R; r++) {
+ for (g = 0; g < DITH_G; g++) {
+ for (b = 0; b < DITH_B; b++) {
XMesaColor xcol;
int exact, alloced;
- xcol.red =gamma_adjust(v->RedGamma, r*65535/(_R-1),65535);
- xcol.green=gamma_adjust(v->GreenGamma, g*65535/(_G-1),65535);
- xcol.blue =gamma_adjust(v->BlueGamma, b*65535/(_B-1),65535);
+ xcol.red =gamma_adjust(v->RedGamma, r*65535/(DITH_R-1),65535);
+ xcol.green=gamma_adjust(v->GreenGamma, g*65535/(DITH_G-1),65535);
+ xcol.blue =gamma_adjust(v->BlueGamma, b*65535/(DITH_B-1),65535);
noFaultXAllocColor( client, v->display,
cmap, GET_COLORMAP_SIZE(v),
&xcol, &exact, &alloced );
buffer->alloced_colors[buffer->num_alloced] = xcol.pixel;
buffer->num_alloced++;
}
- i = _MIX( r, g, b );
+ i = DITH_MIX( r, g, b );
assert(i < 576);
buffer->color_table[i] = xcol.pixel;
assert(xcol.pixel < 65536);
- buffer->pixel_to_r[xcol.pixel] = r * 255 / (_R-1);
- buffer->pixel_to_g[xcol.pixel] = g * 255 / (_G-1);
- buffer->pixel_to_b[xcol.pixel] = b * 255 / (_B-1);
+ buffer->pixel_to_r[xcol.pixel] = r * 255 / (DITH_R-1);
+ buffer->pixel_to_g[xcol.pixel] = g * 255 / (DITH_G-1);
+ buffer->pixel_to_b[xcol.pixel] = b * 255 / (DITH_B-1);
}
}
}
- if (colorsfailed && getenv("MESA_DEBUG")) {
- fprintf( stderr,
+ if (colorsfailed && _mesa_getenv("MESA_DEBUG")) {
+ _mesa_warning(NULL,
"Note: %d out of %d needed colors do not match exactly.\n",
- colorsfailed, _R*_G*_B );
+ colorsfailed, DITH_R * DITH_G * DITH_B );
}
}
}
- v->dithered_pf = PF_DITHER;
- v->undithered_pf = PF_LOOKUP;
+ v->dithered_pf = PF_Dither;
+ v->undithered_pf = PF_Lookup;
return GL_TRUE;
}
-/*
+/**
* Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode.
* HPCR simulates 24-bit color fidelity with an 8-bit frame buffer.
* Special dithering tables have to be initialized.
*/
-static void setup_8bit_hpcr( XMesaVisual v )
+static void
+setup_8bit_hpcr(XMesaVisual v)
{
/* HP Color Recovery contributed by: Alex De Bruyn (ad@lms.be)
* To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined
g = 1.0 / v->RedGamma;
for (i=0; i<256; i++) {
- GLint red = (GLint) (255.0 * pow( hpcr_rgbTbl[0][i]/255.0, g ) + 0.5);
+ GLint red = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[0][i]/255.0, g ));
v->hpcr_rgbTbl[0][i] = CLAMP( red, 16, 239 );
}
g = 1.0 / v->GreenGamma;
for (i=0; i<256; i++) {
- GLint green = (GLint) (255.0 * pow( hpcr_rgbTbl[1][i]/255.0, g ) + 0.5);
+ GLint green = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[1][i]/255.0, g ));
v->hpcr_rgbTbl[1][i] = CLAMP( green, 16, 239 );
}
g = 1.0 / v->BlueGamma;
for (i=0; i<256; i++) {
- GLint blue = (GLint) (255.0 * pow( hpcr_rgbTbl[2][i]/255.0, g ) + 0.5);
+ GLint blue = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[2][i]/255.0, g ));
v->hpcr_rgbTbl[2][i] = CLAMP( blue, 32, 223 );
}
v->undithered_pf = PF_HPCR; /* can't really disable dithering for now */
/* which method should I use to clear */
/* GL_FALSE: keep the ordinary method */
/* GL_TRUE : clear with dither pattern */
- v->hpcr_clear_flag = getenv("MESA_HPCR_CLEAR") ? GL_TRUE : GL_FALSE;
+ v->hpcr_clear_flag = _mesa_getenv("MESA_HPCR_CLEAR") ? GL_TRUE : GL_FALSE;
if (v->hpcr_clear_flag) {
v->hpcr_clear_pixmap = XMesaCreatePixmap(v->display,
}
-/*
+/**
* Setup RGB rendering for a window with a True/DirectColor visual.
*/
-static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
- XMesaWindow window, XMesaColormap cmap )
+static void
+setup_truecolor(XMesaVisual v, XMesaBuffer buffer, XMesaColormap cmap)
{
unsigned long rmask, gmask, bmask;
(void) buffer;
- (void) window;
(void) cmap;
/* Compute red multiplier (mask) and bit shift */
3*16, 11*16, 1*16, 9*16,
15*16, 7*16, 13*16, 5*16,
};
- GLint rBits = bitcount(rmask);
- GLint gBits = bitcount(gmask);
- GLint bBits = bitcount(bmask);
- GLint minBits;
+ GLint rBits = _mesa_bitcount(rmask);
+ GLint gBits = _mesa_bitcount(gmask);
+ GLint bBits = _mesa_bitcount(bmask);
+ GLint maxBits;
GLuint i;
/* convert pixel components in [0,_mask] to RGB values in [0,255] */
}
/* setup dithering kernel */
- minBits = rBits;
- if (gBits < minBits) minBits = gBits;
- if (bBits < minBits) minBits = bBits;
+ maxBits = rBits;
+ if (gBits > maxBits) maxBits = gBits;
+ if (bBits > maxBits) maxBits = bBits;
for (i=0;i<16;i++) {
- v->Kernel[i] = kernel[i] >> minBits;
+ v->Kernel[i] = kernel[i] >> maxBits;
}
- v->undithered_pf = PF_TRUECOLOR;
- v->dithered_pf = (GET_VISUAL_DEPTH(v)<24) ? PF_TRUEDITHER : PF_TRUECOLOR;
+ v->undithered_pf = PF_Truecolor;
+ v->dithered_pf = (GET_VISUAL_DEPTH(v)<24) ? PF_Dither_True : PF_Truecolor;
}
/*
&& GET_BLUEMASK(v) ==0xff0000
&& CHECK_BYTE_ORDER(v)
&& v->BitsPerPixel==32
- && sizeof(GLuint)==4
&& v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
/* common 32 bpp config used on SGI, Sun */
- v->undithered_pf = v->dithered_pf = PF_8A8B8G8R;
- }
- else if (GET_REDMASK(v) ==0xff0000
- && GET_GREENMASK(v)==0x00ff00
- && GET_BLUEMASK(v) ==0x0000ff
- && CHECK_BYTE_ORDER(v)
- && v->BitsPerPixel==32
- && sizeof(GLuint)==4
- && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
- /* common 32 bpp config used on Linux, HP, IBM */
- v->undithered_pf = v->dithered_pf = PF_8R8G8B;
- }
- else if (GET_REDMASK(v) ==0xff0000
- && GET_GREENMASK(v)==0x00ff00
- && GET_BLUEMASK(v) ==0x0000ff
- && CHECK_BYTE_ORDER(v)
- && v->BitsPerPixel==24
- && sizeof(GLuint)==4
- && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
- /* common packed 24 bpp config used on Linux */
- v->undithered_pf = v->dithered_pf = PF_8R8G8B24;
+ v->undithered_pf = v->dithered_pf = PF_8A8B8G8R; /* ABGR */
+ }
+ else if (GET_REDMASK(v) == 0xff0000
+ && GET_GREENMASK(v)== 0x00ff00
+ && GET_BLUEMASK(v) == 0x0000ff
+ && CHECK_BYTE_ORDER(v)
+ && v->RedGamma == 1.0 && v->GreenGamma == 1.0 && v->BlueGamma == 1.0){
+ if (v->BitsPerPixel==32) {
+ /* if 32 bpp, and visual indicates 8 bpp alpha channel */
+ if (GET_VISUAL_DEPTH(v) == 32 && v->mesa_visual.alphaBits == 8)
+ v->undithered_pf = v->dithered_pf = PF_8A8R8G8B; /* ARGB */
+ else
+ v->undithered_pf = v->dithered_pf = PF_8R8G8B; /* xRGB */
+ }
+ else if (v->BitsPerPixel == 24) {
+ v->undithered_pf = v->dithered_pf = PF_8R8G8B24; /* RGB */
+ }
}
else if (GET_REDMASK(v) ==0xf800
&& GET_GREENMASK(v)==0x07e0
&& GET_BLUEMASK(v) ==0x001f
&& CHECK_BYTE_ORDER(v)
&& v->BitsPerPixel==16
- && sizeof(GLushort)==2
&& v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
- /* 5-6-5 color weight on common PC VGA boards */
+ /* 5-6-5 RGB */
v->undithered_pf = PF_5R6G5B;
- v->dithered_pf = PF_DITHER_5R6G5B;
+ v->dithered_pf = PF_Dither_5R6G5B;
}
else if (GET_REDMASK(v) ==0xe0
&& GET_GREENMASK(v)==0x1c
&& GET_BLUEMASK(v) ==0x03
&& CHECK_FOR_HPCR(v)) {
+ /* 8-bit HP color recovery */
setup_8bit_hpcr( v );
}
}
-/*
+/**
* Setup RGB rendering for a window with a monochrome visual.
*/
-static void setup_monochrome( XMesaVisual v, XMesaBuffer b )
+static void
+setup_monochrome( XMesaVisual v, XMesaBuffer b )
{
(void) b;
- v->dithered_pf = v->undithered_pf = PF_1BIT;
+ v->dithered_pf = v->undithered_pf = PF_1Bit;
/* if black=1 then we must flip pixel values */
v->bitFlip = (GET_BLACK_PIXEL(v) != 0);
}
-/*
- * When a context is "made current" for the first time, we can finally
- * finish initializing the context's visual and buffer information.
- * Input: v - the XMesaVisual to initialize
- * b - the XMesaBuffer to initialize (may be NULL)
- * rgb_flag - TRUE = RGBA mode, FALSE = color index mode
- * window - the window/pixmap we're rendering into
- * cmap - the colormap associated with the window/pixmap
- * Return: GL_TRUE=success, GL_FALSE=failure
+/**
+ * When a context is bound for the first time, we can finally finish
+ * initializing the context's visual and buffer information.
+ * \param v the XMesaVisual to initialize
+ * \param b the XMesaBuffer to initialize (may be NULL)
+ * \param rgb_flag TRUE = RGBA mode, FALSE = color index mode
+ * \param window the window/pixmap we're rendering into
+ * \param cmap the colormap associated with the window/pixmap
+ * \return GL_TRUE=success, GL_FALSE=failure
*/
-static GLboolean initialize_visual_and_buffer( int client,
- XMesaVisual v,
- XMesaBuffer b,
- GLboolean rgb_flag,
- XMesaDrawable window,
- XMesaColormap cmap
- )
+static GLboolean
+initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
+ GLboolean rgb_flag, XMesaDrawable window,
+ XMesaColormap cmap)
{
-#ifndef XFree86Server
- XGCValues gcvalues;
+ int client = 0;
+
+#ifdef XFree86Server
+ client = (window) ? CLIENT_ID(window->id) : 0;
#endif
- if (b) {
- assert(b->xm_visual == v);
- }
+ ASSERT(!b || b->xm_visual == v);
/* Save true bits/pixel */
- v->BitsPerPixel = GET_BITS_PER_PIXEL(v);
+ v->BitsPerPixel = bits_per_pixel(v);
assert(v->BitsPerPixel > 0);
-
- if (rgb_flag==GL_FALSE) {
+ if (rgb_flag == GL_FALSE) {
/* COLOR-INDEXED WINDOW:
* Even if the visual is TrueColor or DirectColor we treat it as
* being color indexed. This is weird but might be useful to someone.
*/
- v->dithered_pf = v->undithered_pf = PF_INDEX;
- v->index_bits = GET_VISUAL_DEPTH(v);
+ v->dithered_pf = v->undithered_pf = PF_Index;
+ v->mesa_visual.indexBits = GET_VISUAL_DEPTH(v);
}
else {
/* RGB WINDOW:
* We support RGB rendering into almost any kind of visual.
*/
- int xclass;
- xclass = GET_VISUAL_CLASS(v);
- if (xclass==TrueColor || xclass==DirectColor) {
- setup_truecolor( v, b, (XMesaWindow)window, cmap );
+ const int xclass = v->mesa_visual.visualType;
+ if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) {
+ setup_truecolor( v, b, cmap );
}
- else if (xclass==StaticGray && GET_VISUAL_DEPTH(v)==1) {
+ else if (xclass == GLX_STATIC_GRAY && GET_VISUAL_DEPTH(v) == 1) {
setup_monochrome( v, b );
}
- else if (xclass==GrayScale || xclass==StaticGray) {
+ else if (xclass == GLX_GRAY_SCALE || xclass == GLX_STATIC_GRAY) {
if (!setup_grayscale( client, v, b, cmap )) {
return GL_FALSE;
}
}
- else if ((xclass==PseudoColor || xclass==StaticColor)
+ else if ((xclass == GLX_PSEUDO_COLOR || xclass == GLX_STATIC_COLOR)
&& GET_VISUAL_DEPTH(v)>=4 && GET_VISUAL_DEPTH(v)<=16) {
if (!setup_dithered_color( client, v, b, cmap )) {
return GL_FALSE;
}
}
else {
- error("XMesa: RGB mode rendering not supported in given visual.");
+ _mesa_warning(NULL, "XMesa: RGB mode rendering not supported in given visual.\n");
return GL_FALSE;
}
- v->index_bits = 0;
+ v->mesa_visual.indexBits = 0;
- if (getenv("MESA_NO_DITHER")) {
+ if (_mesa_getenv("MESA_NO_DITHER")) {
v->dithered_pf = v->undithered_pf;
}
}
* which can help Brian figure out what's going on when a user
* reports bugs.
*/
- if (getenv("MESA_INFO")) {
- fprintf(stderr, "X/Mesa visual = %p\n", v);
- fprintf(stderr, "X/Mesa dithered pf = %u\n", v->dithered_pf);
- fprintf(stderr, "X/Mesa undithered pf = %u\n", v->undithered_pf);
- fprintf(stderr, "X/Mesa level = %d\n", v->level);
- fprintf(stderr, "X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v));
- fprintf(stderr, "X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
+ if (_mesa_getenv("MESA_INFO")) {
+ _mesa_printf("X/Mesa visual = %p\n", (void *) v);
+ _mesa_printf("X/Mesa dithered pf = %u\n", v->dithered_pf);
+ _mesa_printf("X/Mesa undithered pf = %u\n", v->undithered_pf);
+ _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level);
+ _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v));
+ _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
}
if (b && window) {
- /* Do window-specific initializations */
+ char *data;
- /* Window dimensions */
- unsigned int w, h;
- get_drawable_size( v->display, window, &w, &h );
- b->width = w;
- b->height = h;
-
- b->frontbuffer = window;
+ /* Do window-specific initializations */
- assert( v->gl_visual );
+ /* these should have been set in create_xmesa_buffer */
+ ASSERT(b->frontxrb->drawable == window);
+ ASSERT(b->frontxrb->pixmap == (XMesaPixmap) window);
/* Setup for single/double buffering */
- if (v->gl_visual->DBflag) {
+ if (v->mesa_visual.doubleBufferMode) {
/* Double buffered */
-#ifndef XFree86Server
b->shm = check_for_xshm( v->display );
-#endif
- xmesa_alloc_back_buffer( b );
- if (b->db_state==BACK_PIXMAP) {
- b->buffer = (XMesaDrawable)b->backpixmap;
- }
- else {
- b->buffer = XIMAGE;
- }
- }
- else {
- /* Single Buffered */
- b->buffer = b->frontbuffer;
}
/* X11 graphics contexts */
#endif
XMesaSetFunction( v->display, b->gc, GXcopy );
+ /* cleargc - for glClear() */
+#ifdef XFree86Server
+ b->cleargc = CreateScratchGC(v->display, window->depth);
+#else
+ b->cleargc = XCreateGC( v->display, window, 0, NULL );
+#endif
+ XMesaSetFunction( v->display, b->cleargc, GXcopy );
+
/*
* Don't generate Graphics Expose/NoExpose events in swapbuffers().
* Patch contributed by Michael Pichler May 15, 1995.
*/
#ifdef XFree86Server
- b->cleargc = CreateScratchGC(v->display, window->depth);
+ b->swapgc = CreateScratchGC(v->display, window->depth);
{
- CARD32 v[1];
- v[0] = FALSE;
- dixChangeGC(NullClient, b->cleargc, GCGraphicsExposures, v, NULL);
+ CARD32 v[1];
+ v[0] = FALSE;
+ dixChangeGC(NullClient, b->swapgc, GCGraphicsExposures, v, NULL);
}
#else
- gcvalues.graphics_exposures = False;
- b->cleargc = XCreateGC( v->display, window,
- GCGraphicsExposures, &gcvalues);
+ {
+ XGCValues gcvalues;
+ gcvalues.graphics_exposures = False;
+ b->swapgc = XCreateGC(v->display, window,
+ GCGraphicsExposures, &gcvalues);
+ }
#endif
- XMesaSetFunction( v->display, b->cleargc, GXcopy );
+ XMesaSetFunction( v->display, b->swapgc, GXcopy );
/*
* Set fill style and tile pixmap once for all for HPCR stuff
* (instead of doing it each time in clear_color_HPCR_pixmap())
* Initialize whole stuff
* Patch contributed by Jacques Leroy March 8, 1998.
*/
- if (v->hpcr_clear_flag && b->buffer!=XIMAGE) {
- int i;
- for (i=0; i<16; i++)
- {
- XMesaPutPixel(v->hpcr_clear_ximage, i, 0, 0);
- XMesaPutPixel(v->hpcr_clear_ximage, i, 1, 0);
- }
- XMesaPutImage(b->display, (XMesaDrawable)v->hpcr_clear_pixmap,
- b->cleargc, v->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2);
- XMesaSetFillStyle( v->display, b->cleargc, FillTiled);
- XMesaSetTile( v->display, b->cleargc, v->hpcr_clear_pixmap );
+ if (v->hpcr_clear_flag && b->backxrb && b->backxrb->pixmap) {
+ int i;
+ for (i = 0; i < 16; i++) {
+ XMesaPutPixel(v->hpcr_clear_ximage, i, 0, 0);
+ XMesaPutPixel(v->hpcr_clear_ximage, i, 1, 0);
+ }
+ XMesaPutImage(b->display, (XMesaDrawable) v->hpcr_clear_pixmap,
+ b->cleargc, v->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2);
+ XMesaSetFillStyle( v->display, b->cleargc, FillTiled);
+ XMesaSetTile( v->display, b->cleargc, v->hpcr_clear_pixmap );
}
/* Initialize the row buffer XImage for use in write_color_span() */
+ data = (char*) MALLOC(MAX_WIDTH*4);
#ifdef XFree86Server
- b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1,
- (char *)MALLOC(MAX_WIDTH*4));
+ b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1, data);
#else
b->rowimage = XCreateImage( v->display,
v->visinfo->visual,
v->visinfo->depth,
ZPixmap, 0, /*format, offset*/
- (char*) MALLOC(MAX_WIDTH*4), /*data*/
+ data, /*data*/
MAX_WIDTH, 1, /*width, height*/
32, /*bitmap_pad*/
0 /*bytes_per_line*/ );
#endif
+ if (!b->rowimage)
+ return GL_FALSE;
}
return GL_TRUE;
* Convert an RGBA color to a pixel value.
*/
unsigned long
-xmesa_color_to_pixel( XMesaContext xmesa, GLubyte r, GLubyte g, GLubyte b, GLubyte a,
- GLuint pixelFormat)
+xmesa_color_to_pixel(GLcontext *ctx,
+ GLubyte r, GLubyte g, GLubyte b, GLubyte a,
+ GLuint pixelFormat)
{
+ XMesaContext xmesa = XMESA_CONTEXT(ctx);
switch (pixelFormat) {
- case PF_INDEX:
+ case PF_Index:
return 0;
- case PF_TRUECOLOR:
+ case PF_Truecolor:
{
unsigned long p;
PACK_TRUECOLOR( p, r, g, b );
}
case PF_8A8B8G8R:
return PACK_8A8B8G8R( r, g, b, a );
+ case PF_8A8R8G8B:
+ return PACK_8A8R8G8B( r, g, b, a );
case PF_8R8G8B:
/* fall through */
case PF_8R8G8B24:
return PACK_8R8G8B( r, g, b );
case PF_5R6G5B:
return PACK_5R6G5B( r, g, b );
- case PF_DITHER:
+ case PF_Dither:
{
DITHER_SETUP;
return DITHER( 1, 0, r, g, b );
}
- case PF_1BIT:
+ case PF_1Bit:
/* 382 = (3*255)/2 */
return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip;
case PF_HPCR:
return DITHER_HPCR(1, 1, r, g, b);
- case PF_LOOKUP:
+ case PF_Lookup:
{
LOOKUP_SETUP;
return LOOKUP( r, g, b );
}
- case PF_GRAYSCALE:
+ case PF_Grayscale:
return GRAY_RGB( r, g, b );
- case PF_TRUEDITHER:
+ case PF_Dither_True:
/* fall through */
- case PF_DITHER_5R6G5B:
+ case PF_Dither_5R6G5B:
{
unsigned long p;
PACK_TRUEDITHER(p, 1, 0, r, g, b);
return p;
}
default:
- gl_problem(NULL, "Bad pixel format in xmesa_color_to_pixel");
+ _mesa_problem(ctx, "Bad pixel format in xmesa_color_to_pixel");
}
return 0;
}
+#define NUM_VISUAL_TYPES 6
+
+/**
+ * Convert an X visual type to a GLX visual type.
+ *
+ * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.)
+ * to be converted.
+ * \return If \c visualType is a valid X visual type, a GLX visual type will
+ * be returned. Otherwise \c GLX_NONE will be returned.
+ *
+ * \note
+ * This code was lifted directly from lib/GL/glx/glcontextmodes.c in the
+ * DRI CVS tree.
+ */
+static GLint
+xmesa_convert_from_x_visual_type( int visualType )
+{
+ static const int glx_visual_types[ NUM_VISUAL_TYPES ] = {
+ GLX_STATIC_GRAY, GLX_GRAY_SCALE,
+ GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
+ GLX_TRUE_COLOR, GLX_DIRECT_COLOR
+ };
+
+ return ( (unsigned) visualType < NUM_VISUAL_TYPES )
+ ? glx_visual_types[ visualType ] : GLX_NONE;
+}
+
+
/**********************************************************************/
/***** Public Functions *****/
/**********************************************************************/
* accum_alpha_size - requested bits/alpha accum values, or zero
* num_samples - number of samples/pixel if multisampling, or zero
* level - visual level, usually 0
- * visualCaveat - ala the GLX extension, usually GLX_NONE_EXT
+ * visualCaveat - ala the GLX extension, usually GLX_NONE
* Return; a new XMesaVisual or 0 if error.
*/
+PUBLIC
XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
XMesaVisualInfo visinfo,
GLboolean rgb_flag,
XMesaVisual v;
GLint red_bits, green_bits, blue_bits, alpha_bits;
+#ifndef XFree86Server
/* For debugging only */
- if (getenv("MESA_XSYNC")) {
+ if (_mesa_getenv("MESA_XSYNC")) {
/* This makes debugging X easier.
* In your debugger, set a breakpoint on _XError to stop when an
* X protocol error is generated.
*/
-#ifdef XFree86Server
- /* NOT_NEEDED */
-#else
XSynchronize( display, 1 );
-#endif
}
+#endif
v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual);
if (!v) {
return NULL;
}
- /*
- * In the X server, NULL is passed in for the display. It will have
- * to be set before using this visual. See XMesaSetVisualDisplay()
- * below.
- */
v->display = display;
- /* Save a copy of the XVisualInfo struct because the user may XFREE()
+ /* Save a copy of the XVisualInfo struct because the user may X_mesa_free()
* the struct but we may need some of the information contained in it
* at a later time.
*/
-#ifdef XFree86Server
- v->visinfo = visinfo;
-#else
+#ifndef XFree86Server
v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
if(!v->visinfo) {
- FREE(v);
+ _mesa_free(v);
return NULL;
}
MEMCPY(v->visinfo, visinfo, sizeof(*visinfo));
-
- /* Save a copy of the pointer now so we can find this visual again
- * if we need to search for it in find_glx_visual().
- */
- v->vishandle = visinfo;
-#endif
-
-#ifdef XFree86Server
- /* Initialize the depth of the screen */
- {
- PixmapFormatRec *format;
-
- for (format = screenInfo.formats;
- format->depth != display->rootDepth;
- format++)
- ;
- v->screen_depth = format->bitsPerPixel;
- }
#endif
/* check for MESA_GAMMA environment variable */
- gamma = getenv("MESA_GAMMA");
+ gamma = _mesa_getenv("MESA_GAMMA");
if (gamma) {
v->RedGamma = v->GreenGamma = v->BlueGamma = 0.0;
sscanf( gamma, "%f %f %f", &v->RedGamma, &v->GreenGamma, &v->BlueGamma );
}
v->ximage_flag = ximage_flag;
- v->level = level;
- v->VisualCaveat = visualCaveat;
- (void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 );
+#ifdef XFree86Server
+ /* We could calculate these values by ourselves. nplanes is either the sum
+ * of the red, green, and blue bits or the number index bits.
+ * ColormapEntries is either (1U << index_bits) or
+ * (1U << max(redBits, greenBits, blueBits)).
+ */
+ assert(visinfo->nplanes > 0);
+ v->nplanes = visinfo->nplanes;
+ v->ColormapEntries = visinfo->ColormapEntries;
+
+ v->mesa_visual.redMask = visinfo->redMask;
+ v->mesa_visual.greenMask = visinfo->greenMask;
+ v->mesa_visual.blueMask = visinfo->blueMask;
+ v->mesa_visual.visualID = visinfo->vid;
+ v->mesa_visual.screen = 0; /* FIXME: What should be done here? */
+#else
+ v->mesa_visual.redMask = visinfo->red_mask;
+ v->mesa_visual.greenMask = visinfo->green_mask;
+ v->mesa_visual.blueMask = visinfo->blue_mask;
+ v->mesa_visual.visualID = visinfo->visualid;
+ v->mesa_visual.screen = visinfo->screen;
+#endif
+
+#if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus))
+ v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class);
+#else
+ v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class);
+#endif
+
+ v->mesa_visual.visualRating = visualCaveat;
+
+ if (alpha_flag)
+ v->mesa_visual.alphaBits = 8;
+
+ (void) initialize_visual_and_buffer( v, NULL, rgb_flag, 0, 0 );
{
- int xclass;
- xclass = GET_VISUAL_CLASS(v);
- if (xclass==TrueColor || xclass==DirectColor) {
- red_bits = bitcount(GET_REDMASK(v));
- green_bits = bitcount(GET_GREENMASK(v));
- blue_bits = bitcount(GET_BLUEMASK(v));
- alpha_bits = 0;
+ const int xclass = v->mesa_visual.visualType;
+ if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) {
+ red_bits = _mesa_bitcount(GET_REDMASK(v));
+ green_bits = _mesa_bitcount(GET_GREENMASK(v));
+ blue_bits = _mesa_bitcount(GET_BLUEMASK(v));
}
else {
/* this is an approximation */
alpha_bits = 0;
assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) );
}
- }
-
- if (alpha_flag && alpha_bits == 0)
- alpha_bits = 8;
-
- v->gl_visual = _mesa_create_visual( rgb_flag, db_flag, stereo_flag,
- red_bits, green_bits,
- blue_bits, alpha_bits,
- v->index_bits,
- depth_size,
- stencil_size,
- accum_red_size, accum_green_size,
- accum_blue_size, accum_alpha_size,
- 0 );
- if (!v->gl_visual) {
-#ifndef XFree86Server
- FREE(v->visinfo);
-#endif
- FREE(v);
- return NULL;
- }
-
+ alpha_bits = v->mesa_visual.alphaBits;
+ }
+
+ _mesa_initialize_visual( &v->mesa_visual,
+ rgb_flag, db_flag, stereo_flag,
+ red_bits, green_bits,
+ blue_bits, alpha_bits,
+ v->mesa_visual.indexBits,
+ depth_size,
+ stencil_size,
+ accum_red_size, accum_green_size,
+ accum_blue_size, accum_alpha_size,
+ 0 );
+
+ /* XXX minor hack */
+ v->mesa_visual.level = level;
return v;
}
-void XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v )
-{
- v->display = dpy;
-}
-
-
+PUBLIC
void XMesaDestroyVisual( XMesaVisual v )
{
- _mesa_destroy_visual( v->gl_visual );
#ifndef XFree86Server
- FREE(v->visinfo);
+ _mesa_free(v->visinfo);
#endif
- FREE(v);
+ _mesa_free(v);
}
-/*
+/**
* Create a new XMesaContext.
- * Input: v - XMesaVisual
- * share_list - another XMesaContext with which to share display
- * lists or NULL if no sharing is wanted.
- * Return: an XMesaContext or NULL if error.
+ * \param v the XMesaVisual
+ * \param share_list another XMesaContext with which to share display
+ * lists or NULL if no sharing is wanted.
+ * \return an XMesaContext or NULL if error.
*/
+PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{
- XMesaContext c;
- GLcontext *ctx;
- GLboolean direct = GL_TRUE; /* XXXX */
- /* NOT_DONE: should this be GL_FALSE??? */
static GLboolean firstTime = GL_TRUE;
+ XMesaContext c;
+ GLcontext *mesaCtx;
+ struct dd_function_table functions;
+ TNLcontext *tnl;
if (firstTime) {
_glthread_INIT_MUTEX(_xmesa_lock);
firstTime = GL_FALSE;
}
+ /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */
c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
- if (!c) {
+ if (!c)
return NULL;
- }
- ctx = c->gl_ctx = _mesa_create_context( v->gl_visual,
- share_list ? share_list->gl_ctx : (GLcontext *) NULL,
- (void *) c, direct );
- if (!c->gl_ctx) {
- FREE(c);
+ mesaCtx = &(c->mesa);
+
+ /* initialize with default driver functions, then plug in XMesa funcs */
+ _mesa_init_driver_functions(&functions);
+ xmesa_init_driver_functions(v, &functions);
+ if (!_mesa_initialize_context(mesaCtx, &v->mesa_visual,
+ share_list ? &(share_list->mesa) : (GLcontext *) NULL,
+ &functions, (void *) c)) {
+ _mesa_free(c);
return NULL;
}
- _mesa_enable_sw_extensions(ctx);
+ _mesa_enable_sw_extensions(mesaCtx);
+ _mesa_enable_1_3_extensions(mesaCtx);
+ _mesa_enable_1_4_extensions(mesaCtx);
+ _mesa_enable_1_5_extensions(mesaCtx);
+ _mesa_enable_2_0_extensions(mesaCtx);
+#if ENABLE_EXT_texure_compression_s3tc
+ if (c->Mesa_DXTn) {
+ _mesa_enable_extension(mesaCtx, "GL_EXT_texture_compression_s3tc");
+ _mesa_enable_extension(mesaCtx, "GL_S3_s3tc");
+ }
+ _mesa_enable_extension(mesaCtx, "GL_3DFX_texture_compression_FXT1");
+#endif
+#if ENABLE_EXT_timer_query
+ _mesa_enable_extension(mesaCtx, "GL_EXT_timer_query");
+#endif
- if (CHECK_BYTE_ORDER(v)) {
- c->swapbytes = GL_FALSE;
- }
- else {
- c->swapbytes = GL_TRUE;
- }
+#ifdef XFree86Server
+ /* If we're running in the X server, do bounds checking to prevent
+ * segfaults and server crashes!
+ */
+ mesaCtx->Const.CheckArrayBounds = GL_TRUE;
+#endif
+ /* finish up xmesa context initializations */
+ c->swapbytes = CHECK_BYTE_ORDER(v) ? GL_FALSE : GL_TRUE;
c->xm_visual = v;
c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
c->display = v->display;
c->pixelformat = v->dithered_pf; /* Dithering is enabled by default */
- ctx->Driver.UpdateState = xmesa_update_state;
-
-#if defined(GLX_DIRECT_RENDERING) && !defined(XFree86Server)
- c->driContextPriv = driContextPriv;
-#endif
-
- /* Set up some constant pointers:
- */
- xmesa_init_pointers( ctx );
-
/* Initialize the software rasterizer and helper modules.
*/
- _swrast_CreateContext( ctx );
- _swsetup_CreateContext( ctx );
- _tnl_CreateContext( ctx );
-
- xmesa_register_swrast_functions( ctx );
-
- /* Run the config file
- */
- _mesa_context_initialize( ctx );
+ if (!_swrast_CreateContext( mesaCtx ) ||
+ !_vbo_CreateContext( mesaCtx ) ||
+ !_tnl_CreateContext( mesaCtx ) ||
+ !_swsetup_CreateContext( mesaCtx )) {
+ _mesa_free_context_data(&c->mesa);
+ _mesa_free(c);
+ return NULL;
+ }
+ /* tnl setup */
+ tnl = TNL_CONTEXT(mesaCtx);
+ tnl->Driver.RunPipeline = _tnl_run_pipeline;
+ /* swrast setup */
+ xmesa_register_swrast_functions( mesaCtx );
+ _swsetup_Wakeup(mesaCtx);
return c;
}
-
+PUBLIC
void XMesaDestroyContext( XMesaContext c )
{
+ GLcontext *mesaCtx = &c->mesa;
+
#ifdef FX
- if (c->xm_buffer && c->xm_buffer->FXctx)
- fxMesaDestroyContext(c->xm_buffer->FXctx);
+ FXdestroyContext( XMESA_BUFFER(mesaCtx->DrawBuffer) );
#endif
- if (c->gl_ctx) {
- _swsetup_DestroyContext( c->gl_ctx );
- _swrast_DestroyContext( c->gl_ctx );
- _mesa_destroy_context( c->gl_ctx );
- }
- /* Disassociate old buffer with this context */
- if (c->xm_buffer)
- c->xm_buffer->xm_context = NULL;
-
- /* Destroy any buffers which are using this context. If we don't
- * we may have dangling references. Hmm, maybe we should just
- * set the buffer's context pointer to NULL instead of deleting it?
- * Let's see if we get any bug reports...
- * This contributed by Doug Rabson <dfr@calcaphon.com>
- */
- {
- XMesaBuffer b, next;
- for (b = XMesaBufferList; b; b = next) {
- next = b->Next;
- if (!b->pixmap_flag) {
-#ifndef XFree86Server
- XSync(b->display, False);
-#endif
- if (b->xm_context == c) {
- /* found a context created for this context */
- XMesaDestroyBuffer( b );
- }
- }
- }
- }
-
- FREE( c );
+ _swsetup_DestroyContext( mesaCtx );
+ _swrast_DestroyContext( mesaCtx );
+ _tnl_DestroyContext( mesaCtx );
+ _vbo_DestroyContext( mesaCtx );
+ _mesa_free_context_data( mesaCtx );
+ _mesa_free( c );
}
-/*
- * XXX this isn't a public function! It's a hack for the 3Dfx driver.
- * Create a new XMesaBuffer from an X window.
- * Input: v - the XMesaVisual
- * w - the window
- * c - the context
- * Return: new XMesaBuffer or NULL if error
+/**
+ * Private function for creating an XMesaBuffer which corresponds to an
+ * X window or pixmap.
+ * \param v the window's XMesaVisual
+ * \param w the window we're wrapping
+ * \return new XMesaBuffer or NULL if error
*/
-XMesaBuffer XMesaCreateWindowBuffer2( XMesaVisual v, XMesaWindow w,
- XMesaContext c )
+PUBLIC XMesaBuffer
+XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
{
#ifndef XFree86Server
XWindowAttributes attr;
#endif
-#ifdef FX
- char *fxEnvVar;
-#endif
- int client = 0;
-
- XMesaBuffer b = alloc_xmesa_buffer();
- if (!b) {
- return NULL;
- }
-
- (void) c;
-
-#ifdef XFree86Server
- client = CLIENT_ID(((XMesaDrawable)w)->id);
-#endif
+ XMesaBuffer b;
+ XMesaColormap cmap;
+ int depth;
assert(v);
+ assert(w);
+ /* Check that window depth matches visual depth */
#ifdef XFree86Server
- if (GET_VISUAL_DEPTH(v) != ((XMesaDrawable)w)->depth) {
+ depth = ((XMesaDrawable)w)->depth;
#else
XGetWindowAttributes( v->display, w, &attr );
-
- if (GET_VISUAL_DEPTH(v) != attr.depth) {
+ depth = attr.depth;
#endif
- if (getenv("MESA_DEBUG")) {
- fprintf(stderr, "XMesaCreateWindowBuffer: depth mismatch between visual and window!\n");
- }
+ if (GET_VISUAL_DEPTH(v) != depth) {
+ _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n",
+ GET_VISUAL_DEPTH(v), depth);
return NULL;
}
- b->xm_context = NULL; /* Associate no context with this buffer */
-
- b->xm_visual = v;
- b->pixmap_flag = GL_FALSE;
- b->display = v->display;
+ /* Find colormap */
#ifdef XFree86Server
- b->cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP);
+ cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP);
#else
if (attr.colormap) {
- b->cmap = attr.colormap;
+ cmap = attr.colormap;
}
else {
- if (getenv("MESA_DEBUG")) {
- fprintf(stderr, "Window %u has no colormap!\n", (unsigned int) w);
- }
+ _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w);
/* this is weird, a window w/out a colormap!? */
/* OK, let's just allocate a new one and hope for the best */
- b->cmap = XCreateColormap(v->display, w, attr.visual, AllocNone);
+ cmap = XCreateColormap(v->display, w, attr.visual, AllocNone);
}
#endif
- /* determine back buffer implementation */
- if (v->gl_visual->DBflag) {
- if (v->ximage_flag) {
- b->db_state = BACK_XIMAGE;
- }
- else {
- b->db_state = BACK_PIXMAP;
- }
- }
- else {
- b->db_state = 0;
- }
-
- b->gl_buffer = _mesa_create_framebuffer( v->gl_visual,
- v->gl_visual->DepthBits > 0,
- v->gl_visual->StencilBits > 0,
- v->gl_visual->AccumRedBits > 0,
- v->gl_visual->AlphaBits > 0 );
- if (!b->gl_buffer) {
- free_xmesa_buffer(client, b);
+ b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap);
+ if (!b)
return NULL;
- }
- if (!initialize_visual_and_buffer( client, v, b, v->gl_visual->RGBAflag,
- (XMesaDrawable)w, b->cmap )) {
- _mesa_destroy_framebuffer( b->gl_buffer );
- free_xmesa_buffer(client, b);
+ if (!initialize_visual_and_buffer( v, b, v->mesa_visual.rgbMode,
+ (XMesaDrawable) w, cmap )) {
+ xmesa_free_buffer(b);
return NULL;
}
-#ifdef FX
- fxEnvVar = getenv("MESA_GLX_FX");
- if (fxEnvVar) {
- if (fxEnvVar[0]!='d') {
- int attribs[100];
- int numAttribs = 0;
- int hw;
- if (v->gl_visual->DepthBits > 0) {
- attribs[numAttribs++] = FXMESA_DEPTH_SIZE;
- attribs[numAttribs++] = 1;
- }
- if (v->gl_visual->DBflag) {
- attribs[numAttribs++] = FXMESA_DOUBLEBUFFER;
- }
- if (v->gl_visual->AccumRedBits > 0) {
- attribs[numAttribs++] = FXMESA_ACCUM_SIZE;
- attribs[numAttribs++] = v->gl_visual->AccumRedBits;
- }
- if (v->gl_visual->StencilBits > 0) {
- attribs[numAttribs++] = FXMESA_STENCIL_SIZE;
- attribs[numAttribs++] = v->gl_visual->StencilBits;
- }
- if (v->gl_visual->AlphaBits > 0) {
- attribs[numAttribs++] = FXMESA_ALPHA_SIZE;
- attribs[numAttribs++] = 1;
- }
- if (c->gl_ctx) {
-#define FXMESA_SHARE_CONTEXT 990099 /* keep in sync with fxapi.c! */
- attribs[numAttribs++] = FXMESA_SHARE_CONTEXT;
- attribs[numAttribs++] = (int) c->gl_ctx;
- }
- attribs[numAttribs++] = FXMESA_NONE;
-
- if ((hw = fxQueryHardware())==GR_SSTTYPE_VOODOO) {
- b->FXctx = fxMesaCreateBestContext(0, b->width, b->height, attribs);
- if ((v->undithered_pf!=PF_INDEX) && (b->backimage)) {
- b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE;
- if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
- b->FXwindowHack = b->FXctx ? GL_TRUE : GL_FALSE;
- else
- b->FXwindowHack = GL_FALSE;
- }
- }
- else {
- if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
- b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE,
- GR_REFRESH_75Hz, attribs);
- else
- b->FXctx = fxMesaCreateBestContext(0, b->width, b->height, attribs);
- b->FXisHackUsable = GL_FALSE;
- b->FXwindowHack = GL_FALSE;
- }
- /*
- fprintf(stderr,
- "voodoo %d, wid %d height %d hack: usable %d active %d\n",
- hw, b->width, b->height, b->FXisHackUsable, b->FXwindowHack);
- */
- }
- }
- else {
- fprintf(stderr,"WARNING: This Mesa Library includes the Glide driver but\n");
- fprintf(stderr," you have not defined the MESA_GLX_FX env. var.\n");
- fprintf(stderr," (check the README.3DFX file for more information).\n\n");
- fprintf(stderr," you can disable this message with a 'export MESA_GLX_FX=disable'.\n");
- }
-#endif
-
-#if defined(GLX_DIRECT_RENDERING) && !defined(XFree86Server)
- b->driDrawPriv = driDrawPriv;
-#endif
-
return b;
}
-XMesaBuffer XMesaCreateWindowBuffer( XMesaVisual v, XMesaWindow w )
-{
- return XMesaCreateWindowBuffer2( v, w, NULL );
-}
-
-/*
+/**
* Create a new XMesaBuffer from an X pixmap.
- * Input: v - the XMesaVisual
- * p - the pixmap
- * cmap - the colormap, may be 0 if using a TrueColor or DirectColor
- * visual for the pixmap
- * Return: new XMesaBuffer or NULL if error
+ *
+ * \param v the XMesaVisual
+ * \param p the pixmap
+ * \param cmap the colormap, may be 0 if using a \c GLX_TRUE_COLOR or
+ * \c GLX_DIRECT_COLOR visual for the pixmap
+ * \returns new XMesaBuffer or NULL if error
*/
-XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v,
- XMesaPixmap p, XMesaColormap cmap )
+PUBLIC XMesaBuffer
+XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap)
{
- int client = 0;
- XMesaBuffer b = alloc_xmesa_buffer();
- if (!b) {
+ XMesaBuffer b;
+
+ assert(v);
+
+ b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
+ if (!b)
+ return NULL;
+
+ if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode,
+ (XMesaDrawable) p, cmap)) {
+ xmesa_free_buffer(b);
return NULL;
}
+ return b;
+}
-#ifdef XFree86Server
- client = CLIENT_ID(((XMesaDrawable)p)->id);
-#endif
+
+/**
+ * For GLX_EXT_texture_from_pixmap
+ */
+XMesaBuffer
+XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p,
+ XMesaColormap cmap,
+ int format, int target, int mipmap)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ XMesaBuffer b;
+ GLuint width, height;
assert(v);
- b->xm_context = NULL; /* Associate no context with this buffer */
+ b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
+ if (!b)
+ return NULL;
- b->xm_visual = v;
- b->pixmap_flag = GL_TRUE;
- b->display = v->display;
- b->cmap = cmap;
+ /* get pixmap size, update framebuffer/renderbuffer dims */
+ get_drawable_size(v->display, p, &width, &height);
+ _mesa_resize_framebuffer(NULL, &(b->mesa_buffer), width, height);
- /* determine back buffer implementation */
- if (v->gl_visual->DBflag) {
- if (v->ximage_flag) {
- b->db_state = BACK_XIMAGE;
+ if (target == 0) {
+ /* examine dims */
+ if (ctx->Extensions.ARB_texture_non_power_of_two) {
+ target = GLX_TEXTURE_2D_EXT;
+ }
+ else if ( _mesa_bitcount(width) == 1
+ && _mesa_bitcount(height) == 1) {
+ /* power of two size */
+ if (height == 1) {
+ target = GLX_TEXTURE_1D_EXT;
+ }
+ else {
+ target = GLX_TEXTURE_2D_EXT;
+ }
+ }
+ else if (ctx->Extensions.NV_texture_rectangle) {
+ target = GLX_TEXTURE_RECTANGLE_EXT;
}
else {
- b->db_state = BACK_PIXMAP;
+ /* non power of two textures not supported */
+ XMesaDestroyBuffer(b);
+ return 0;
}
}
- else {
- b->db_state = 0;
- }
-
- b->gl_buffer = _mesa_create_framebuffer( v->gl_visual,
- v->gl_visual->DepthBits > 0,
- v->gl_visual->StencilBits > 0,
- v->gl_visual->AccumRedBits +
- v->gl_visual->AccumGreenBits +
- v->gl_visual->AccumBlueBits > 0,
- v->gl_visual->AlphaBits > 0 );
- if (!b->gl_buffer) {
- free_xmesa_buffer(client, b);
- return NULL;
- }
- if (!initialize_visual_and_buffer(client, v, b, v->gl_visual->RGBAflag,
- (XMesaDrawable)p, cmap)) {
- _mesa_destroy_framebuffer( b->gl_buffer );
- free_xmesa_buffer(client, b);
+ b->TextureTarget = target;
+ b->TextureFormat = format;
+ b->TextureMipmap = mipmap;
+
+ if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode,
+ (XMesaDrawable) p, cmap)) {
+ xmesa_free_buffer(b);
return NULL;
}
-#if defined(GLX_DIRECT_RENDERING) && !defined(XFree86Server)
- b->driDrawPriv = driDrawPriv;
-#endif
-
return b;
}
-/*
- * Deallocate an XMesaBuffer structure and all related info.
- */
-void XMesaDestroyBuffer( XMesaBuffer b )
+XMesaBuffer
+XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
+ unsigned int width, unsigned int height)
{
- int client = 0;
+#ifndef XFree86Server
+ XMesaWindow root;
+ XMesaDrawable drawable; /* X Pixmap Drawable */
+ XMesaBuffer b;
-#ifdef XFree86Server
- if (b->frontbuffer)
- client = CLIENT_ID(b->frontbuffer->id);
-#endif
+ /* allocate pixmap for front buffer */
+ root = RootWindow( v->display, v->visinfo->screen );
+ drawable = XCreatePixmap(v->display, root, width, height,
+ v->visinfo->depth);
+ if (!drawable)
+ return NULL;
- if (b->gc) XMesaFreeGC( b->xm_visual->display, b->gc );
- if (b->cleargc) XMesaFreeGC( b->xm_visual->display, b->cleargc );
+ b = create_xmesa_buffer(drawable, PBUFFER, v, cmap);
+ if (!b)
+ return NULL;
- if (b->backimage) {
-#if defined(USE_XSHM) && !defined(XFree86Server)
- if (b->shm) {
- XShmDetach( b->xm_visual->display, &b->shminfo );
- XDestroyImage( b->backimage );
- shmdt( b->shminfo.shmaddr );
- }
- else
-#endif
- XMesaDestroyImage( b->backimage );
- }
- if (b->backpixmap) {
- XMesaFreePixmap( b->xm_visual->display, b->backpixmap );
- if (b->xm_visual->hpcr_clear_flag) {
- XMesaFreePixmap( b->xm_visual->display,
- b->xm_visual->hpcr_clear_pixmap );
- XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage );
- }
- }
- if (b->rowimage) {
- FREE( b->rowimage->data );
- b->rowimage->data = NULL;
- XMesaDestroyImage( b->rowimage );
+ if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode,
+ drawable, cmap)) {
+ xmesa_free_buffer(b);
+ return NULL;
}
- if (b->xm_context)
- b->xm_context->xm_buffer = NULL;
+ return b;
+#else
+ return 0;
+#endif
+}
+
- _mesa_destroy_framebuffer( b->gl_buffer );
- free_xmesa_buffer(client, b);
+
+/*
+ * Deallocate an XMesaBuffer structure and all related info.
+ */
+PUBLIC void
+XMesaDestroyBuffer(XMesaBuffer b)
+{
+ xmesa_free_buffer(b);
}
+/**
+ * Query the current window size and update the corresponding GLframebuffer
+ * and all attached renderbuffers.
+ * Called when:
+ * 1. the first time a buffer is bound to a context.
+ * 2. from glViewport to poll for window size changes
+ * 3. from the XMesaResizeBuffers() API function.
+ * Note: it's possible (and legal) for xmctx to be NULL. That can happen
+ * when resizing a buffer when no rendering context is bound.
+ */
+void
+xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
+{
+ GLuint width, height;
+ xmesa_get_window_size(drawBuffer->display, drawBuffer, &width, &height);
+ if (drawBuffer->mesa_buffer.Width != width ||
+ drawBuffer->mesa_buffer.Height != height) {
+ GLcontext *ctx = xmctx ? &xmctx->mesa : NULL;
+ _mesa_resize_framebuffer(ctx, &(drawBuffer->mesa_buffer), width, height);
+ }
+ drawBuffer->mesa_buffer.Initialized = GL_TRUE; /* XXX TEMPORARY? */
+}
+
/*
* Bind buffer b to context c and make c the current rendering context.
/*
* Bind buffer b to context c and make c the current rendering context.
*/
+PUBLIC
GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
XMesaBuffer readBuffer )
{
if (!drawBuffer || !readBuffer)
return GL_FALSE; /* must specify buffers! */
-#ifdef FX
- if (drawBuffer->FXctx) {
- fxMesaMakeCurrent(drawBuffer->FXctx);
-
- /* Disassociate old buffer from this context */
- if (c->xm_buffer)
- c->xm_buffer->xm_context = NULL;
-
- /* Associate the context with this buffer */
- drawBuffer->xm_context = c;
-
- c->xm_buffer = drawBuffer;
- c->xm_read_buffer = readBuffer;
- c->use_read_buffer = (drawBuffer != readBuffer);
-
- return GL_TRUE;
- }
-#endif
- if (c->gl_ctx == _mesa_get_current_context()
- && c->xm_buffer == drawBuffer
- && c->xm_read_buffer == readBuffer
- && c->xm_buffer->wasCurrent) {
+ if (&(c->mesa) == _mesa_get_current_context()
+ && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer
+ && c->mesa.ReadBuffer == &readBuffer->mesa_buffer
+ && XMESA_BUFFER(c->mesa.DrawBuffer)->wasCurrent) {
/* same context and buffer, do nothing */
return GL_TRUE;
}
- /* Disassociate old buffer with this context */
- if (c->xm_buffer)
- c->xm_buffer->xm_context = NULL;
- drawBuffer->xm_context = c; /* Associate the context with this buffer */
-
c->xm_buffer = drawBuffer;
- c->xm_read_buffer = readBuffer;
- c->use_read_buffer = (drawBuffer != readBuffer);
- _mesa_make_current2(c->gl_ctx, drawBuffer->gl_buffer, readBuffer->gl_buffer);
+#ifdef FX
+ if (FXmakeCurrent( drawBuffer ))
+ return GL_TRUE;
+#endif
- if (c->gl_ctx->Viewport.Width == 0) {
- /* initialize viewport to window size */
- _mesa_Viewport( 0, 0, drawBuffer->width, drawBuffer->height );
- c->gl_ctx->Scissor.Width = drawBuffer->width;
- c->gl_ctx->Scissor.Height = drawBuffer->height;
- }
+ /* Call this periodically to detect when the user has begun using
+ * GL rendering from multiple threads.
+ */
+ _glapi_check_multithread();
+
+ xmesa_check_and_update_buffer_size(c, drawBuffer);
+ if (readBuffer != drawBuffer)
+ xmesa_check_and_update_buffer_size(c, readBuffer);
+
+ _mesa_make_current(&(c->mesa),
+ &drawBuffer->mesa_buffer,
+ &readBuffer->mesa_buffer);
- if (c->xm_visual->gl_visual->RGBAflag) {
+ if (c->xm_visual->mesa_visual.rgbMode) {
/*
* Must recompute and set these pixel values because colormap
* can be different for different windows.
*/
- c->clearpixel = xmesa_color_to_pixel( c,
+ c->clearpixel = xmesa_color_to_pixel( &c->mesa,
c->clearcolor[0],
c->clearcolor[1],
c->clearcolor[2],
c->clearcolor[3],
c->xm_visual->undithered_pf);
- XMesaSetForeground(c->display, c->xm_buffer->cleargc, c->clearpixel);
+ XMesaSetForeground(c->display, drawBuffer->cleargc, c->clearpixel);
}
/* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
- c->xm_buffer->wasCurrent = GL_TRUE;
+ drawBuffer->wasCurrent = GL_TRUE;
}
else {
/* Detach */
- _mesa_make_current2( NULL, NULL, NULL );
+ _mesa_make_current( NULL, NULL, NULL );
}
return GL_TRUE;
}
{
GET_CURRENT_CONTEXT(ctx);
if (ctx) {
- XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ XMesaContext xmesa = XMESA_CONTEXT(ctx);
return xmesa;
}
else {
{
GET_CURRENT_CONTEXT(ctx);
if (ctx) {
- XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- return xmesa->xm_buffer;
+ XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
+ return xmbuf;
}
else {
return 0;
{
GET_CURRENT_CONTEXT(ctx);
if (ctx) {
- XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- return xmesa->xm_buffer;
+ return XMESA_BUFFER(ctx->ReadBuffer);
}
else {
return 0;
}
+#ifdef XFree86Server
+PUBLIC
GLboolean XMesaForceCurrent(XMesaContext c)
{
if (c) {
- if (c->gl_ctx != _mesa_get_current_context()) {
- _mesa_make_current(c->gl_ctx, c->xm_buffer->gl_buffer);
+ _glapi_set_dispatch(c->mesa.CurrentDispatch);
+
+ if (&(c->mesa) != _mesa_get_current_context()) {
+ _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer);
}
}
else {
- _mesa_make_current(NULL, NULL);
+ _mesa_make_current(NULL, NULL, NULL);
}
return GL_TRUE;
}
+PUBLIC
GLboolean XMesaLoseCurrent(XMesaContext c)
{
(void) c;
- _mesa_make_current(NULL, NULL);
+ _mesa_make_current(NULL, NULL, NULL);
return GL_TRUE;
}
-/*
- * Switch 3Dfx support hack between window and full-screen mode.
- */
-GLboolean XMesaSetFXmode( GLint mode )
+PUBLIC
+GLboolean XMesaCopyContext( XMesaContext xm_src, XMesaContext xm_dst, GLuint mask )
{
-#ifdef FX
- const char *fx = getenv("MESA_GLX_FX");
- if (fx && fx[0] != 'd') {
- GET_CURRENT_CONTEXT(ctx);
- GrHwConfiguration hw;
- if (!FX_grSstQueryHardware(&hw)) {
- /*fprintf(stderr, "!grSstQueryHardware\n");*/
- return GL_FALSE;
- }
- if (hw.num_sst < 1) {
- /*fprintf(stderr, "hw.num_sst < 1\n");*/
- return GL_FALSE;
- }
- if (ctx) {
- XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- if (mode == XMESA_FX_WINDOW) {
- if (xmesa->xm_buffer->FXisHackUsable) {
- FX_grSstControl(GR_CONTROL_DEACTIVATE);
- xmesa->xm_buffer->FXwindowHack = GL_TRUE;
- return GL_TRUE;
- }
- }
- else if (mode == XMESA_FX_FULLSCREEN) {
- FX_grSstControl(GR_CONTROL_ACTIVATE);
- xmesa->xm_buffer->FXwindowHack = GL_FALSE;
- return GL_TRUE;
- }
- else {
- /* Error: Bad mode value */
- }
- }
- }
- /*fprintf(stderr, "fallthrough\n");*/
-#else
- (void) mode;
-#endif
- return GL_FALSE;
+ _mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask);
+ return GL_TRUE;
}
+#endif /* XFree86Server */
-
-#ifdef FX
-/*
- * Read image from VooDoo frame buffer into X/Mesa's back XImage.
- */
-static void FXgetImage( XMesaBuffer b )
+#ifndef FX
+GLboolean XMesaSetFXmode( GLint mode )
{
- static unsigned short pixbuf[MAX_WIDTH];
- int x, y;
- XMesaWindow root;
- unsigned int bw, depth, width, height;
- XMesaContext xmesa = (XMesaContext) b->xm_context->gl_ctx->DriverCtx;
-
- assert(xmesa->xm_buffer->FXctx);
-
-#ifdef XFree86Server
- x = b->frontbuffer->x;
- y = b->frontbuffer->y;
- width = b->frontbuffer->width;
- height = b->frontbuffer->height;
- depth = b->frontbuffer->depth;
-#else
- XGetGeometry( xmesa->xm_visual->display, b->frontbuffer,
- &root, &x, &y, &width, &height, &bw, &depth);
-#endif
- if (b->width != width || b->height != height) {
- b->width = MIN2((int)width, xmesa->xm_buffer->FXctx->width);
- b->height = MIN2((int)height, xmesa->xm_buffer->FXctx->height);
- if (b->width & 1)
- b->width--; /* prevent odd width */
- xmesa_alloc_back_buffer( b );
- }
-
- grLfbWriteColorFormat(GR_COLORFORMAT_ARGB);
- if (xmesa->xm_visual->undithered_pf==PF_5R6G5B) {
- /* Special case: 16bpp RGB */
- grLfbReadRegion( GR_BUFFER_FRONTBUFFER, /* src buffer */
- 0, xmesa->xm_buffer->FXctx->height - b->height, /*pos*/
- b->width, b->height, /* size */
- b->width * sizeof(GLushort), /* stride */
- b->backimage->data); /* dest buffer */
- }
- else if (xmesa->xm_visual->dithered_pf==PF_DITHER
- && GET_VISUAL_DEPTH(xmesa->xm_visual)==8) {
- /* Special case: 8bpp RGB */
- for (y=0;y<b->height;y++) {
- GLubyte *ptr = (GLubyte*) xmesa->xm_buffer->backimage->data
- + xmesa->xm_buffer->backimage->bytes_per_line * y;
- XDITHER_SETUP(y);
-
- /* read row from 3Dfx frame buffer */
- grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
- 0, xmesa->xm_buffer->FXctx->height-(b->height-y),
- b->width, 1,
- 0,
- pixbuf );
-
- /* write to XImage back buffer */
- for (x=0;x<b->width;x++) {
- GLubyte r = (pixbuf[x] & 0xf800) >> 8;
- GLubyte g = (pixbuf[x] & 0x07e0) >> 3;
- GLubyte b = (pixbuf[x] & 0x001f) << 3;
- *ptr++ = XDITHER( x, r, g, b);
- }
- }
- }
- else {
- /* General case: slow! */
- for (y=0;y<b->height;y++) {
- /* read row from 3Dfx frame buffer */
- grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
- 0, xmesa->xm_buffer->FXctx->height-(b->height-y),
- b->width, 1,
- 0,
- pixbuf );
-
- /* write to XImage back buffer */
- for (x=0;x<b->width;x++) {
- XMesaPutPixel(b->backimage,x,y,
- xmesa_color_to_pixel(xmesa,
- (pixbuf[x] & 0xf800) >> 8,
- (pixbuf[x] & 0x07e0) >> 3,
- (pixbuf[x] & 0x001f) << 3,
- 0xff, xmesa->pixelformat));
- }
- }
- }
- grLfbWriteColorFormat(GR_COLORFORMAT_ABGR);
+ (void) mode;
+ return GL_FALSE;
}
#endif
+
/*
* Copy the back buffer to the front buffer. If there's no back buffer
* this is a no-op.
*/
+PUBLIC
void XMesaSwapBuffers( XMesaBuffer b )
{
GET_CURRENT_CONTEXT(ctx);
+ if (!b->backxrb) {
+ /* single buffered */
+ return;
+ }
+
/* If we're swapping the buffer associated with the current context
* we have to flush any pending rendering commands first.
*/
- if (b->xm_context && b->xm_context->gl_ctx == ctx)
- _mesa_swapbuffers(ctx);
+ if (ctx && ctx->DrawBuffer == &(b->mesa_buffer))
+ _mesa_notifySwapBuffers(ctx);
- if (b->db_state) {
+ if (b->db_mode) {
#ifdef FX
- if (b->FXctx) {
- fxMesaSwapBuffers();
-
- if (b->FXwindowHack)
- FXgetImage(b);
- else
- return;
- }
+ if (FXswapBuffers(b))
+ return;
#endif
- if (b->backimage) {
- /* Copy Ximage from host's memory to server's window */
+ if (b->backxrb->ximage) {
+ /* Copy Ximage (back buf) from client memory to server window */
#if defined(USE_XSHM) && !defined(XFree86Server)
if (b->shm) {
/*_glthread_LOCK_MUTEX(_xmesa_lock);*/
- XShmPutImage( b->xm_visual->display, b->frontbuffer,
- b->cleargc,
- b->backimage, 0, 0,
- 0, 0, b->width, b->height, False );
+ XShmPutImage( b->xm_visual->display, b->frontxrb->drawable,
+ b->swapgc,
+ b->backxrb->ximage, 0, 0,
+ 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height,
+ False );
/*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
}
else
#endif
{
-#if defined(GLX_DIRECT_RENDERING) && !defined(XFree86Server)
- XMesaDriSwapBuffers( b );
-#else
/*_glthread_LOCK_MUTEX(_xmesa_lock);*/
- XMesaPutImage( b->xm_visual->display, b->frontbuffer,
- b->cleargc,
- b->backimage, 0, 0,
- 0, 0, b->width, b->height );
+ XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable,
+ b->swapgc,
+ b->backxrb->ximage, 0, 0,
+ 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height );
/*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
-#endif
}
}
- else {
- /* Copy pixmap to window on server */
+ else if (b->backxrb->pixmap) {
+ /* Copy pixmap (back buf) to window (front buf) on server */
/*_glthread_LOCK_MUTEX(_xmesa_lock);*/
XMesaCopyArea( b->xm_visual->display,
- b->backpixmap, /* source drawable */
- b->frontbuffer, /* dest. drawable */
- b->cleargc,
- 0, 0, b->width, b->height, /* source region */
+ b->backxrb->pixmap, /* source drawable */
+ b->frontxrb->drawable, /* dest. drawable */
+ b->swapgc,
+ 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height,
0, 0 /* dest region */
);
/*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
}
+
+ if (b->swAlpha)
+ _mesa_copy_soft_alpha_renderbuffers(ctx, &b->mesa_buffer);
}
-#if !defined(GLX_DIRECT_RENDERING) && !defined(XFree86Server)
+#if !defined(XFree86Server)
XSync( b->xm_visual->display, False );
#endif
}
/* If we're swapping the buffer associated with the current context
* we have to flush any pending rendering commands first.
*/
- if (b->xm_context->gl_ctx == ctx)
- _mesa_swapbuffers(ctx);
+ if (ctx && ctx->DrawBuffer == &(b->mesa_buffer))
+ _mesa_notifySwapBuffers(ctx);
+
+ if (!b->backxrb) {
+ /* single buffered */
+ return;
+ }
- if (b->db_state) {
- int yTop = b->height - y - height;
+ if (b->db_mode) {
+ int yTop = b->mesa_buffer.Height - y - height;
#ifdef FX
- if (b->FXctx) {
- fxMesaSwapBuffers();
- if (b->FXwindowHack)
- FXgetImage(b);
- else
- return;
- }
+ if (FXswapBuffers(b))
+ return;
#endif
- if (b->backimage) {
+ if (b->backxrb->ximage) {
/* Copy Ximage from host's memory to server's window */
#if defined(USE_XSHM) && !defined(XFree86Server)
if (b->shm) {
/* XXX assuming width and height aren't too large! */
- XShmPutImage( b->xm_visual->display, b->frontbuffer,
- b->cleargc,
- b->backimage, x, yTop,
+ XShmPutImage( b->xm_visual->display, b->frontxrb->drawable,
+ b->swapgc,
+ b->backxrb->ximage, x, yTop,
x, yTop, width, height, False );
/* wait for finished event??? */
}
#endif
{
/* XXX assuming width and height aren't too large! */
- XMesaPutImage( b->xm_visual->display, b->frontbuffer,
- b->cleargc,
- b->backimage, x, yTop,
+ XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable,
+ b->swapgc,
+ b->backxrb->ximage, x, yTop,
x, yTop, width, height );
}
}
else {
/* Copy pixmap to window on server */
XMesaCopyArea( b->xm_visual->display,
- b->backpixmap, /* source drawable */
- b->frontbuffer, /* dest. drawable */
- b->cleargc,
+ b->backxrb->pixmap, /* source drawable */
+ b->frontxrb->drawable, /* dest. drawable */
+ b->swapgc,
x, yTop, width, height, /* source region */
x, yTop /* dest region */
);
* Return: GL_TRUE = context is double buffered
* GL_FALSE = context is single buffered
*/
+#ifndef XFree86Server
GLboolean XMesaGetBackBuffer( XMesaBuffer b,
XMesaPixmap *pixmap,
XMesaImage **ximage )
{
- if (b->db_state) {
- if (pixmap) *pixmap = b->backpixmap;
- if (ximage) *ximage = b->backimage;
+ if (b->db_mode) {
+ if (pixmap)
+ *pixmap = b->backxrb->pixmap;
+ if (ximage)
+ *ximage = b->backxrb->ximage;
return GL_TRUE;
}
else {
return GL_FALSE;
}
}
+#endif /* XFree86Server */
/*
GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height,
GLint *bytesPerValue, void **buffer )
{
- if ((!b->gl_buffer) || (!b->gl_buffer->DepthBuffer)) {
+ struct gl_renderbuffer *rb
+ = b->mesa_buffer.Attachment[BUFFER_DEPTH].Renderbuffer;
+ if (!rb || !rb->Data) {
*width = 0;
*height = 0;
*bytesPerValue = 0;
return GL_FALSE;
}
else {
- *width = b->gl_buffer->Width;
- *height = b->gl_buffer->Height;
- *bytesPerValue = sizeof(GLdepth);
- *buffer = b->gl_buffer->DepthBuffer;
+ *width = b->mesa_buffer.Width;
+ *height = b->mesa_buffer.Height;
+ *bytesPerValue = b->mesa_buffer.Visual.depthBits <= 16
+ ? sizeof(GLushort) : sizeof(GLuint);
+ *buffer = rb->Data;
return GL_TRUE;
}
}
{
(void) c;
if (name==XMESA_VERSION) {
- return "3.1";
+ return "5.0";
}
else if (name==XMESA_EXTENSIONS) {
return "";
{
XMesaBuffer b;
for (b=XMesaBufferList; b; b=b->Next) {
- if (b->frontbuffer==d && b->display==dpy) {
+ if (b->frontxrb->drawable == d && b->display == dpy) {
return b;
}
}
}
+/**
+ * Free/destroy all XMesaBuffers associated with given display.
+ */
+void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy)
+{
+ XMesaBuffer b, next;
+ for (b = XMesaBufferList; b; b = next) {
+ next = b->Next;
+ if (b->display == dpy) {
+ xmesa_free_buffer(b);
+ }
+ }
+}
+
/*
* Look for XMesaBuffers whose X window has been destroyed.
XMesaBuffer b, next;
for (b=XMesaBufferList; b; b=next) {
next = b->Next;
- if (!b->pixmap_flag) {
+ if (b->display && b->frontxrb->drawable && b->type == WINDOW) {
#ifdef XFree86Server
/* NOT_NEEDED */
#else
XSync(b->display, False);
- if (!window_exists( b->display, b->frontbuffer )) {
+ if (!window_exists( b->display, b->frontxrb->drawable )) {
/* found a dead window, free the ancillary info */
XMesaDestroyBuffer( b );
}
}
-void XMesaReset( void )
-{
- while (XMesaBufferList)
- XMesaDestroyBuffer(XMesaBufferList);
-
- XMesaBufferList = NULL;
-}
-
-
unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
GLfloat red, GLfloat green,
GLfloat blue, GLfloat alpha )
{
+ GLcontext *ctx = &xmesa->mesa;
GLint r = (GLint) (red * 255.0F);
GLint g = (GLint) (green * 255.0F);
GLint b = (GLint) (blue * 255.0F);
GLint a = (GLint) (alpha * 255.0F);
switch (xmesa->pixelformat) {
- case PF_INDEX:
+ case PF_Index:
return 0;
- case PF_TRUECOLOR:
+ case PF_Truecolor:
{
unsigned long p;
PACK_TRUECOLOR( p, r, g, b );
}
case PF_8A8B8G8R:
return PACK_8A8B8G8R( r, g, b, a );
+ case PF_8A8R8G8B:
+ return PACK_8A8R8G8B( r, g, b, a );
case PF_8R8G8B:
return PACK_8R8G8B( r, g, b );
case PF_5R6G5B:
return PACK_5R6G5B( r, g, b );
- case PF_DITHER:
+ case PF_Dither:
{
DITHER_SETUP;
return DITHER( x, y, r, g, b );
}
- case PF_1BIT:
+ case PF_1Bit:
/* 382 = (3*255)/2 */
return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip;
case PF_HPCR:
return DITHER_HPCR(x, y, r, g, b);
- case PF_LOOKUP:
+ case PF_Lookup:
{
LOOKUP_SETUP;
return LOOKUP( r, g, b );
}
- case PF_GRAYSCALE:
+ case PF_Grayscale:
return GRAY_RGB( r, g, b );
- case PF_DITHER_5R6G5B:
+ case PF_Dither_5R6G5B:
/* fall through */
- case PF_TRUEDITHER:
+ case PF_Dither_True:
{
unsigned long p;
PACK_TRUEDITHER(p, x, y, r, g, b);
return p;
}
default:
- gl_problem(NULL, "Bad pixel format in XMesaDitherColor");
+ _mesa_problem(NULL, "Bad pixel format in XMesaDitherColor");
}
return 0;
}
+/*
+ * This is typically called when the window size changes and we need
+ * to reallocate the buffer's back/depth/stencil/accum buffers.
+ */
+PUBLIC void
+XMesaResizeBuffers( XMesaBuffer b )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ XMesaContext xmctx = XMESA_CONTEXT(ctx);
+ if (!xmctx)
+ return;
+ xmesa_check_and_update_buffer_size(xmctx, b);
+}
+
+
+static GLint
+xbuffer_to_renderbuffer(int buffer)
+{
+ assert(MAX_AUX_BUFFERS <= 4);
+
+ switch (buffer) {
+ case GLX_FRONT_LEFT_EXT:
+ return BUFFER_FRONT_LEFT;
+ case GLX_FRONT_RIGHT_EXT:
+ return BUFFER_FRONT_RIGHT;
+ case GLX_BACK_LEFT_EXT:
+ return BUFFER_BACK_LEFT;
+ case GLX_BACK_RIGHT_EXT:
+ return BUFFER_BACK_RIGHT;
+ case GLX_AUX0_EXT:
+ return BUFFER_AUX0;
+ case GLX_AUX1_EXT:
+ return BUFFER_AUX1;
+ case GLX_AUX2_EXT:
+ return BUFFER_AUX2;
+ case GLX_AUX3_EXT:
+ return BUFFER_AUX3;
+ case GLX_AUX4_EXT:
+ case GLX_AUX5_EXT:
+ case GLX_AUX6_EXT:
+ case GLX_AUX7_EXT:
+ case GLX_AUX8_EXT:
+ case GLX_AUX9_EXT:
+ default:
+ /* BadValue error */
+ return -1;
+ }
+}
+
+
+PUBLIC void
+XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer,
+ const int *attrib_list)
+{
+#if 0
+ GET_CURRENT_CONTEXT(ctx);
+ const GLuint unit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *texObj;
+#endif
+ struct gl_renderbuffer *rb;
+ struct xmesa_renderbuffer *xrb;
+ GLint b;
+ XMesaImage *img;
+ GLboolean freeImg = GL_FALSE;
+
+ b = xbuffer_to_renderbuffer(buffer);
+ if (b < 0)
+ return;
+
+ if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_NONE_EXT)
+ return; /* BadMatch error */
+
+ rb = drawable->mesa_buffer.Attachment[b].Renderbuffer;
+ if (!rb) {
+ /* invalid buffer */
+ return;
+ }
+ xrb = xmesa_renderbuffer(rb);
+
+#if 0
+ switch (drawable->TextureTarget) {
+ case GLX_TEXTURE_1D_EXT:
+ texObj = texUnit->Current1D;
+ break;
+ case GLX_TEXTURE_2D_EXT:
+ texObj = texUnit->Current2D;
+ break;
+ case GLX_TEXTURE_RECTANGLE_EXT:
+ texObj = texUnit->CurrentRect;
+ break;
+ default:
+ return; /* BadMatch error */
+ }
+#endif
+
+ /*
+ * The following is a quick and simple way to implement
+ * BindTexImage. The better way is to write some new FetchTexel()
+ * functions which would extract texels from XImages. We'd still
+ * need to use XGetImage when texturing from a Pixmap (front buffer)
+ * but texturing from a back buffer (XImage) would avoid an image
+ * copy.
+ */
+
+ /* get XImage */
+ if (xrb->pixmap) {
+ img = XGetImage(dpy, xrb->pixmap, 0, 0, rb->Width, rb->Height,
+ AllPlanes, ZPixmap );
+ freeImg = GL_TRUE;
+ }
+ else if (xrb->ximage) {
+ img = xrb->ximage;
+ }
+
+ /* store the XImage as a new texture image */
+ if (img) {
+ GLenum format, type, intFormat;
+ if (img->bits_per_pixel == 32) {
+ format = GL_BGRA;
+ type = GL_UNSIGNED_BYTE;
+ intFormat = GL_RGBA;
+ }
+ else if (img->bits_per_pixel == 24) {
+ format = GL_BGR;
+ type = GL_UNSIGNED_BYTE;
+ intFormat = GL_RGB;
+ }
+ else if (img->bits_per_pixel == 16) {
+ format = GL_BGR;
+ type = GL_UNSIGNED_SHORT_5_6_5;
+ intFormat = GL_RGB;
+ }
+ else {
+ _mesa_problem(NULL, "Unexpected XImage format in XMesaBindTexImage");
+ return;
+ }
+ if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_RGBA_EXT) {
+ intFormat = GL_RGBA;
+ }
+ else if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_RGB_EXT) {
+ intFormat = GL_RGB;
+ }
+
+ _mesa_TexImage2D(GL_TEXTURE_2D, 0, intFormat, rb->Width, rb->Height, 0,
+ format, type, img->data);
+
+ if (freeImg) {
+ XMesaDestroyImage(img);
+ }
+ }
+}
+
+
+
+PUBLIC void
+XMesaReleaseTexImage(Display *dpy, XMesaBuffer drawable, int buffer)
+{
+ const GLint b = xbuffer_to_renderbuffer(buffer);
+ if (b < 0)
+ return;
+
+ /* no-op for now */
+}
+