Big re-org of buffer size management.
All buffer resizes now handled by xmesa_check_and_update_buffer_size() which uses the _mesa_resize_framebuffer() function. Moved all low-level XImage/Pixmap resizing into xm_buffers.c file. Also, update lots of comments for Doxygen.
This commit is contained in:
@@ -22,8 +22,10 @@
|
||||
* 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:
|
||||
@@ -68,13 +70,8 @@
|
||||
#include "framebuffer.h"
|
||||
#include "glthread.h"
|
||||
#include "imports.h"
|
||||
#include "matrix.h"
|
||||
#include "mtypes.h"
|
||||
#include "macros.h"
|
||||
#include "renderbuffer.h"
|
||||
#include "texformat.h"
|
||||
#include "texobj.h"
|
||||
#include "texstore.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "array_cache/acache.h"
|
||||
@@ -87,14 +84,14 @@
|
||||
#include <GL/glxtokens.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
/**
|
||||
* Global X driver lock
|
||||
*/
|
||||
_glthread_Mutex _xmesa_lock;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Lookup tables for HPCR pixel format:
|
||||
*/
|
||||
static short hpcr_rgbTbl[3][256] = {
|
||||
@@ -161,7 +158,7 @@ static short hpcr_rgbTbl[3][256] = {
|
||||
/**********************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Return the host's byte order as LSBFirst or MSBFirst ala X.
|
||||
*/
|
||||
#ifndef XFree86Server
|
||||
@@ -174,23 +171,7 @@ static int host_byte_order( void )
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Error handling.
|
||||
*/
|
||||
#ifndef XFree86Server
|
||||
static volatile 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
|
||||
@@ -222,11 +203,12 @@ static int check_for_xshm( XMesaDisplay *display )
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* 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;
|
||||
@@ -239,7 +221,7 @@ static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* 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.
|
||||
@@ -247,10 +229,10 @@ static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
|
||||
* visinfo - desribes the visual to be used for XImages
|
||||
* Return: true number of bits per pixel for XImages
|
||||
*/
|
||||
#ifdef XFree86Server
|
||||
|
||||
static int bits_per_pixel( XMesaVisual xmv )
|
||||
static int
|
||||
bits_per_pixel( XMesaVisual xmv )
|
||||
{
|
||||
#ifdef XFree86Server
|
||||
const int depth = xmv->nplanes;
|
||||
int i;
|
||||
assert(depth > 0);
|
||||
@@ -259,12 +241,7 @@ static int bits_per_pixel( XMesaVisual xmv )
|
||||
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;
|
||||
@@ -285,8 +262,8 @@ static int bits_per_pixel( XMesaVisual xmv )
|
||||
img->data = NULL;
|
||||
XMesaDestroyImage( img );
|
||||
return bitsPerPixel;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -325,6 +302,45 @@ static GLboolean window_exists( XMesaDisplay *dpy, Window win )
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
Window root;
|
||||
Status stat;
|
||||
int xpos, ypos;
|
||||
unsigned int w, h, bw, depth;
|
||||
|
||||
_glthread_LOCK_MUTEX(_xmesa_lock);
|
||||
XSync(b->xm_visual->display, 0); /* added for Chromium */
|
||||
stat = XGetGeometry(dpy, b->frontxrb->pixmap, &root, &xpos, &ypos,
|
||||
&w, &h, &bw, &depth);
|
||||
_glthread_UNLOCK_MUTEX(_xmesa_lock);
|
||||
|
||||
if (stat) {
|
||||
*width = w;
|
||||
*height = h;
|
||||
}
|
||||
else {
|
||||
/* probably querying a window that's recently been destroyed */
|
||||
_mesa_warning(NULL, "XGetGeometry failed!\n");
|
||||
*width = *height = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/***** Linked list of XMesaBuffers *****/
|
||||
/**********************************************************************/
|
||||
@@ -333,15 +349,28 @@ static XMesaBuffer XMesaBufferList = NULL;
|
||||
|
||||
|
||||
/**
|
||||
* Allocate a new XMesaBuffer, initialize basic fields and add to
|
||||
* the list of all buffers.
|
||||
* 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
|
||||
alloc_xmesa_buffer(XMesaVisual vis, BufferType type, XMesaColormap cmap)
|
||||
create_xmesa_buffer(XMesaDrawable d, BufferType type,
|
||||
XMesaVisual vis, XMesaColormap cmap)
|
||||
{
|
||||
XMesaBuffer b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
|
||||
if (b) {
|
||||
GLboolean swAlpha;
|
||||
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;
|
||||
@@ -350,20 +379,33 @@ alloc_xmesa_buffer(XMesaVisual vis, BufferType type, XMesaColormap cmap)
|
||||
|
||||
_mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual);
|
||||
|
||||
/* Allocate the framebuffer's renderbuffers */
|
||||
assert(!b->mesa_buffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
|
||||
assert(!b->mesa_buffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer);
|
||||
|
||||
/* front renderbuffer */
|
||||
/*
|
||||
* 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 */
|
||||
/*
|
||||
* 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;
|
||||
|
||||
@@ -371,7 +413,9 @@ alloc_xmesa_buffer(XMesaVisual vis, BufferType type, XMesaColormap cmap)
|
||||
&b->backxrb->Base);
|
||||
}
|
||||
|
||||
/* determine if we need software alpha planes */
|
||||
/*
|
||||
* Software alpha planes
|
||||
*/
|
||||
if (vis->mesa_visual.alphaBits > 0
|
||||
&& vis->undithered_pf != PF_8A8B8G8R
|
||||
&& vis->undithered_pf != PF_8A8R8G8B) {
|
||||
@@ -384,6 +428,9 @@ alloc_xmesa_buffer(XMesaVisual vis, BufferType type, XMesaColormap cmap)
|
||||
swAlpha = GL_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Other renderbuffer (depth, stencil, etc)
|
||||
*/
|
||||
_mesa_add_soft_renderbuffers(&b->mesa_buffer,
|
||||
GL_FALSE, /* color */
|
||||
vis->mesa_visual.haveDepthBuffer,
|
||||
@@ -392,21 +439,20 @@ alloc_xmesa_buffer(XMesaVisual vis, BufferType type, XMesaColormap cmap)
|
||||
swAlpha,
|
||||
vis->mesa_visual.numAuxBuffers > 0 );
|
||||
|
||||
/* insert into linked list */
|
||||
/* 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)
|
||||
static XMesaBuffer
|
||||
find_xmesa_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis)
|
||||
{
|
||||
XMesaBuffer b;
|
||||
for (b=XMesaBufferList; b; b=b->Next) {
|
||||
@@ -418,11 +464,12 @@ static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Free an XMesaBuffer, remove from linked list, perhaps free X colormap
|
||||
* entries.
|
||||
*/
|
||||
static void free_xmesa_buffer(int client, XMesaBuffer buffer)
|
||||
static void
|
||||
free_xmesa_buffer(int client, XMesaBuffer buffer)
|
||||
{
|
||||
XMesaBuffer prev = NULL, b;
|
||||
(void) client;
|
||||
@@ -461,8 +508,11 @@ static void free_xmesa_buffer(int client, XMesaBuffer buffer)
|
||||
}
|
||||
|
||||
|
||||
/* 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));
|
||||
@@ -481,198 +531,6 @@ static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
|
||||
|
||||
|
||||
/**
|
||||
* 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, GLuint width, GLuint height)
|
||||
{
|
||||
#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 * );
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
/* this will be true the first time we're called on 'b' */
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
b->backxrb->ximage = XShmCreateImage(b->xm_visual->display,
|
||||
b->xm_visual->visinfo->visual,
|
||||
b->xm_visual->visinfo->depth,
|
||||
ZPixmap, NULL, &b->shminfo,
|
||||
width, height);
|
||||
if (b->backxrb->ximage == NULL) {
|
||||
_mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.\n");
|
||||
b->shm = 0;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
b->shminfo.shmid = shmget( IPC_PRIVATE, b->backxrb->ximage->bytes_per_line
|
||||
* b->backxrb->ximage->height, IPC_CREAT|0777 );
|
||||
if (b->shminfo.shmid < 0) {
|
||||
_mesa_warning(NULL, "shmget failed while allocating back buffer.\n");
|
||||
XDestroyImage( b->backxrb->ximage );
|
||||
b->backxrb->ximage = NULL;
|
||||
_mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.\n");
|
||||
b->shm = 0;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
b->shminfo.shmaddr = b->backxrb->ximage->data
|
||||
= (char*)shmat( b->shminfo.shmid, 0, 0 );
|
||||
if (b->shminfo.shmaddr == (char *) -1) {
|
||||
_mesa_warning(NULL, "shmat() failed while allocating back buffer.\n");
|
||||
XDestroyImage( b->backxrb->ximage );
|
||||
shmctl( b->shminfo.shmid, IPC_RMID, 0 );
|
||||
b->backxrb->ximage = NULL;
|
||||
_mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.\n");
|
||||
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->backxrb->ximage );
|
||||
shmdt( b->shminfo.shmaddr );
|
||||
shmctl( b->shminfo.shmid, IPC_RMID, 0 );
|
||||
b->backxrb->ximage = 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->frontxrb->drawable, 0, NULL );
|
||||
XShmPutImage( b->xm_visual->display, b->frontxrb->drawable, gc,
|
||||
b->backxrb->ximage, 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->backxrb->ximage );
|
||||
shmdt( b->shminfo.shmaddr );
|
||||
shmctl( b->shminfo.shmid, IPC_RMID, 0 );
|
||||
b->backxrb->ximage = NULL;
|
||||
b->shm = 0;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
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, GLuint width, GLuint height )
|
||||
{
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
if (b->db_mode == BACK_XIMAGE) {
|
||||
/* Deallocate the old backxrb->ximage, if any */
|
||||
if (b->backxrb->ximage) {
|
||||
#if defined(USE_XSHM) && !defined(XFree86Server)
|
||||
if (b->shm) {
|
||||
XShmDetach( b->xm_visual->display, &b->shminfo );
|
||||
XDestroyImage( b->backxrb->ximage );
|
||||
shmdt( b->shminfo.shmaddr );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
XMesaDestroyImage( b->backxrb->ximage );
|
||||
b->backxrb->ximage = NULL;
|
||||
}
|
||||
|
||||
/* Allocate new back buffer */
|
||||
#ifdef XFree86Server
|
||||
/* Allocate a regular XImage for the back buffer. */
|
||||
b->backxrb->ximage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
|
||||
width, height, NULL);
|
||||
{
|
||||
#else
|
||||
if (b->shm == 0 || !alloc_shm_back_buffer(b, width, height)) {
|
||||
/* Allocate a regular XImage for the back buffer. */
|
||||
b->backxrb->ximage = XCreateImage( b->xm_visual->display,
|
||||
b->xm_visual->visinfo->visual,
|
||||
GET_VISUAL_DEPTH(b->xm_visual),
|
||||
ZPixmap, 0, /* format, offset */
|
||||
NULL,
|
||||
width, height,
|
||||
8, 0 ); /* pad, bytes_per_line */
|
||||
#endif
|
||||
if (!b->backxrb->ximage) {
|
||||
_mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.\n");
|
||||
return;
|
||||
}
|
||||
b->backxrb->ximage->data = (char *) MALLOC( b->backxrb->ximage->height
|
||||
* b->backxrb->ximage->bytes_per_line );
|
||||
if (!b->backxrb->ximage->data) {
|
||||
_mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.\n");
|
||||
XMesaDestroyImage( b->backxrb->ximage );
|
||||
b->backxrb->ximage = NULL;
|
||||
}
|
||||
else {
|
||||
/* this call just updates the width/origin fields in the xrb */
|
||||
b->backxrb->Base.AllocStorage(NULL, &b->backxrb->Base,
|
||||
b->backxrb->Base.InternalFormat,
|
||||
b->backxrb->ximage->width,
|
||||
b->backxrb->ximage->height);
|
||||
}
|
||||
}
|
||||
b->backxrb->pixmap = None;
|
||||
}
|
||||
else if (b->db_mode == BACK_PIXMAP) {
|
||||
if (!width)
|
||||
width = 1;
|
||||
if (!height)
|
||||
height = 1;
|
||||
|
||||
/* Free the old back pixmap */
|
||||
if (b->backxrb->pixmap) {
|
||||
XMesaFreePixmap( b->xm_visual->display, b->backxrb->pixmap );
|
||||
}
|
||||
/* Allocate new back pixmap */
|
||||
b->backxrb->pixmap = XMesaCreatePixmap( b->xm_visual->display,
|
||||
b->frontxrb->drawable,
|
||||
width, height,
|
||||
GET_VISUAL_DEPTH(b->xm_visual) );
|
||||
b->backxrb->ximage = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
@@ -715,10 +573,11 @@ noFaultXAllocColor( int client,
|
||||
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;
|
||||
@@ -808,13 +667,13 @@ noFaultXAllocColor( int client,
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* 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;
|
||||
@@ -893,7 +752,7 @@ static GLboolean setup_grayscale( int client, XMesaVisual v,
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* 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
|
||||
@@ -901,8 +760,9 @@ static GLboolean setup_grayscale( int client, XMesaVisual v,
|
||||
* 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;
|
||||
@@ -972,12 +832,13 @@ static GLboolean setup_dithered_color( int client, XMesaVisual v,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* 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
|
||||
@@ -1027,11 +888,11 @@ static void setup_8bit_hpcr( XMesaVisual v )
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Setup RGB rendering for a window with a True/DirectColor visual.
|
||||
*/
|
||||
static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
|
||||
XMesaColormap cmap )
|
||||
static void
|
||||
setup_truecolor(XMesaVisual v, XMesaBuffer buffer, XMesaColormap cmap)
|
||||
{
|
||||
unsigned long rmask, gmask, bmask;
|
||||
(void) buffer;
|
||||
@@ -1171,10 +1032,11 @@ static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* 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;
|
||||
@@ -1205,7 +1067,7 @@ initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b,
|
||||
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.
|
||||
@@ -1264,14 +1126,14 @@ initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b,
|
||||
if (b && window) {
|
||||
/* Do window-specific initializations */
|
||||
|
||||
b->frontxrb->drawable = window;
|
||||
b->frontxrb->pixmap = (XMesaPixmap) window;
|
||||
/* 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->mesa_visual.doubleBufferMode) {
|
||||
/* Double buffered */
|
||||
b->shm = check_for_xshm( v->display );
|
||||
xmesa_alloc_back_buffer(b, b->mesa_buffer.Width, b->mesa_buffer.Height);
|
||||
}
|
||||
|
||||
/* X11 graphics contexts */
|
||||
@@ -1732,13 +1594,13 @@ void XMesaDestroyContext( XMesaContext 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
|
||||
* \param c context used to initialize the buffer if 3Dfx mode in use.
|
||||
* \return new XMesaBuffer or NULL if error
|
||||
*/
|
||||
XMesaBuffer
|
||||
XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
|
||||
@@ -1754,6 +1616,7 @@ XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
|
||||
XMesaColormap cmap;
|
||||
|
||||
assert(v);
|
||||
assert(w);
|
||||
(void) c;
|
||||
|
||||
/* Check that window depth matches visual depth */
|
||||
@@ -1790,10 +1653,9 @@ XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
|
||||
}
|
||||
#endif
|
||||
|
||||
b = alloc_xmesa_buffer(v, WINDOW, cmap);
|
||||
if (!b) {
|
||||
b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap);
|
||||
if (!b)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode,
|
||||
(XMesaDrawable) w, cmap )) {
|
||||
@@ -1908,10 +1770,9 @@ XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap)
|
||||
|
||||
assert(v);
|
||||
|
||||
b = alloc_xmesa_buffer(v, PIXMAP, cmap);
|
||||
if (!b) {
|
||||
b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
|
||||
if (!b)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef XFree86Server
|
||||
client = CLIENT_ID(((XMesaDrawable)p)->id);
|
||||
@@ -1940,14 +1801,16 @@ XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
|
||||
XMesaDrawable drawable; /* X Pixmap Drawable */
|
||||
XMesaBuffer b;
|
||||
|
||||
b = alloc_xmesa_buffer(v, PBUFFER, cmap);
|
||||
if (!b) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* allocate pixmap for front buffer */
|
||||
root = RootWindow( v->display, v->visinfo->screen );
|
||||
drawable = XCreatePixmap( v->display, root, width, height, v->visinfo->depth );
|
||||
drawable = XCreatePixmap(v->display, root, width, height,
|
||||
v->visinfo->depth);
|
||||
if (!drawable)
|
||||
return NULL;
|
||||
|
||||
b = create_xmesa_buffer(drawable, PBUFFER, v, cmap);
|
||||
if (!b)
|
||||
return NULL;
|
||||
|
||||
if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
|
||||
drawable, cmap)) {
|
||||
@@ -2009,6 +1872,27 @@ void XMesaDestroyBuffer( XMesaBuffer 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.
|
||||
*/
|
||||
void
|
||||
xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
|
||||
{
|
||||
GLuint width, height;
|
||||
xmesa_get_window_size(xmctx->display, drawBuffer, &width, &height);
|
||||
if (drawBuffer->mesa_buffer.Width != width ||
|
||||
drawBuffer->mesa_buffer.Height != height) {
|
||||
_mesa_resize_framebuffer(&(xmctx->mesa),
|
||||
&(drawBuffer->mesa_buffer), width, height);
|
||||
}
|
||||
drawBuffer->mesa_buffer.Initialized = GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Bind buffer b to context c and make c the current rendering context.
|
||||
@@ -2041,7 +1925,7 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
|
||||
if (&(c->mesa) == _mesa_get_current_context()
|
||||
&& c->mesa.DrawBuffer == &drawBuffer->mesa_buffer
|
||||
&& c->mesa.ReadBuffer == &readBuffer->mesa_buffer
|
||||
&& ((XMesaBuffer) c->mesa.DrawBuffer)->wasCurrent) {
|
||||
&& XMESA_BUFFER(c->mesa.DrawBuffer)->wasCurrent) {
|
||||
/* same context and buffer, do nothing */
|
||||
return GL_TRUE;
|
||||
}
|
||||
@@ -2053,6 +1937,12 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
|
||||
*/
|
||||
_glapi_check_multithread();
|
||||
|
||||
if (!drawBuffer->mesa_buffer.Initialized)
|
||||
xmesa_check_and_update_buffer_size(c, drawBuffer);
|
||||
|
||||
if (!readBuffer->mesa_buffer.Initialized)
|
||||
xmesa_check_and_update_buffer_size(c, readBuffer);
|
||||
|
||||
_mesa_make_current(&(c->mesa),
|
||||
&drawBuffer->mesa_buffer,
|
||||
&readBuffer->mesa_buffer);
|
||||
@@ -2123,7 +2013,7 @@ XMesaBuffer XMesaGetCurrentReadBuffer( void )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
if (ctx) {
|
||||
return (XMesaBuffer) (ctx->ReadBuffer);
|
||||
return XMESA_BUFFER(ctx->ReadBuffer);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
@@ -2212,9 +2102,7 @@ static void FXgetImage( XMesaBuffer b )
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
static unsigned short pixbuf[MAX_WIDTH];
|
||||
GLuint x, y;
|
||||
int xpos, ypos;
|
||||
XMesaWindow root;
|
||||
unsigned int bw, depth, width, height;
|
||||
GLuint width, height;
|
||||
XMesaContext xmesa = XMESA_CONTEXT(ctx);
|
||||
|
||||
#ifdef XFree86Server
|
||||
@@ -2224,15 +2112,14 @@ static void FXgetImage( XMesaBuffer b )
|
||||
height = b->frontxrb->pixmap->height;
|
||||
depth = b->frontxrb->pixmap->depth;
|
||||
#else
|
||||
XGetGeometry( b->xm_visual->display, b->frontxrb->pixmap,
|
||||
&root, &xpos, &ypos, &width, &height, &bw, &depth);
|
||||
xmesa_get_window_size(b->display, b, &width, &height);
|
||||
x = y = 0;
|
||||
#endif
|
||||
if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) {
|
||||
b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width);
|
||||
b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height);
|
||||
if (b->mesa_buffer.Width & 1)
|
||||
b->mesa_buffer.Width--; /* prevent odd width */
|
||||
xmesa_alloc_back_buffer(b, b->mesa_buffer.Width, b->mesa_buffer.Height);
|
||||
}
|
||||
|
||||
/* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */
|
||||
@@ -2646,24 +2533,11 @@ unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
|
||||
* This is typically called when the window size changes and we need
|
||||
* to reallocate the buffer's back/depth/stencil/accum buffers.
|
||||
*/
|
||||
void XMesaResizeBuffers( XMesaBuffer b )
|
||||
void
|
||||
XMesaResizeBuffers( XMesaBuffer b )
|
||||
{
|
||||
#ifdef XFree86Server
|
||||
GLuint winwidth, winheight;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
winwidth = MIN2(b->frontxrb->drawable->width, MAX_WIDTH);
|
||||
winheight = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT);
|
||||
|
||||
xmesa_resize_buffers(ctx, &(b->mesa_buffer), winwidth, winheight);
|
||||
#else
|
||||
Window root;
|
||||
int xpos, ypos;
|
||||
unsigned int width, height, bw, depth;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
XGetGeometry( b->xm_visual->display, b->frontxrb->pixmap,
|
||||
&root, &xpos, &ypos, &width, &height, &bw, &depth);
|
||||
xmesa_resize_buffers(ctx, &(b->mesa_buffer), width, height);
|
||||
#endif
|
||||
XMesaContext xmctx = XMESA_CONTEXT(ctx);
|
||||
xmesa_check_and_update_buffer_size(xmctx, b);
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
* Version: 6.5.2
|
||||
*
|
||||
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
|
||||
* Copyright (C) 1999-2006 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"),
|
||||
@@ -23,6 +23,12 @@
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* \file xm_buffer.h
|
||||
* Framebuffer and renderbuffer-related functions.
|
||||
*/
|
||||
|
||||
|
||||
#include "glxheader.h"
|
||||
#include "GL/xmesa.h"
|
||||
#include "xmesaP.h"
|
||||
@@ -30,6 +36,213 @@
|
||||
#include "renderbuffer.h"
|
||||
|
||||
|
||||
#ifndef XFree86Server
|
||||
static volatile int mesaXErrorFlag = 0;
|
||||
|
||||
/**
|
||||
* Catches potential Xlib errors.
|
||||
*/
|
||||
static int
|
||||
mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event)
|
||||
{
|
||||
(void) dpy;
|
||||
(void) event;
|
||||
mesaXErrorFlag = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* 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_back_shm_ximage(XMesaBuffer b, GLuint width, GLuint height)
|
||||
{
|
||||
#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 *);
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
/* this will be true the first time we're called on 'b' */
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
b->backxrb->ximage = XShmCreateImage(b->xm_visual->display,
|
||||
b->xm_visual->visinfo->visual,
|
||||
b->xm_visual->visinfo->depth,
|
||||
ZPixmap, NULL, &b->shminfo,
|
||||
width, height);
|
||||
if (b->backxrb->ximage == NULL) {
|
||||
_mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.\n");
|
||||
b->shm = 0;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
b->shminfo.shmid = shmget(IPC_PRIVATE, b->backxrb->ximage->bytes_per_line
|
||||
* b->backxrb->ximage->height, IPC_CREAT|0777);
|
||||
if (b->shminfo.shmid < 0) {
|
||||
_mesa_warning(NULL, "shmget failed while allocating back buffer.\n");
|
||||
XDestroyImage(b->backxrb->ximage);
|
||||
b->backxrb->ximage = NULL;
|
||||
_mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.\n");
|
||||
b->shm = 0;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
b->shminfo.shmaddr = b->backxrb->ximage->data
|
||||
= (char*)shmat(b->shminfo.shmid, 0, 0);
|
||||
if (b->shminfo.shmaddr == (char *) -1) {
|
||||
_mesa_warning(NULL, "shmat() failed while allocating back buffer.\n");
|
||||
XDestroyImage(b->backxrb->ximage);
|
||||
shmctl(b->shminfo.shmid, IPC_RMID, 0);
|
||||
b->backxrb->ximage = NULL;
|
||||
_mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.\n");
|
||||
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->backxrb->ximage);
|
||||
shmdt(b->shminfo.shmaddr);
|
||||
shmctl(b->shminfo.shmid, IPC_RMID, 0);
|
||||
b->backxrb->ximage = 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->frontxrb->drawable, 0, NULL);
|
||||
XShmPutImage(b->xm_visual->display, b->frontxrb->drawable, gc,
|
||||
b->backxrb->ximage, 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->backxrb->ximage);
|
||||
shmdt(b->shminfo.shmaddr);
|
||||
shmctl(b->shminfo.shmid, IPC_RMID, 0);
|
||||
b->backxrb->ximage = NULL;
|
||||
b->shm = 0;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
static void
|
||||
alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
|
||||
{
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
if (b->db_mode == BACK_XIMAGE) {
|
||||
/* Deallocate the old backxrb->ximage, if any */
|
||||
if (b->backxrb->ximage) {
|
||||
#if defined(USE_XSHM) && !defined(XFree86Server)
|
||||
if (b->shm) {
|
||||
XShmDetach(b->xm_visual->display, &b->shminfo);
|
||||
XDestroyImage(b->backxrb->ximage);
|
||||
shmdt(b->shminfo.shmaddr);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
XMesaDestroyImage(b->backxrb->ximage);
|
||||
b->backxrb->ximage = NULL;
|
||||
}
|
||||
|
||||
/* Allocate new back buffer */
|
||||
#ifdef XFree86Server
|
||||
/* Allocate a regular XImage for the back buffer. */
|
||||
b->backxrb->ximage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
|
||||
width, height, NULL);
|
||||
{
|
||||
#else
|
||||
if (b->shm == 0 || !alloc_back_shm_ximage(b, width, height)) {
|
||||
/* Allocate a regular XImage for the back buffer. */
|
||||
b->backxrb->ximage = XCreateImage(b->xm_visual->display,
|
||||
b->xm_visual->visinfo->visual,
|
||||
GET_VISUAL_DEPTH(b->xm_visual),
|
||||
ZPixmap, 0, /* format, offset */
|
||||
NULL,
|
||||
width, height,
|
||||
8, 0); /* pad, bytes_per_line */
|
||||
#endif
|
||||
if (!b->backxrb->ximage) {
|
||||
_mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.\n");
|
||||
return;
|
||||
}
|
||||
b->backxrb->ximage->data = (char *) MALLOC(b->backxrb->ximage->height
|
||||
* b->backxrb->ximage->bytes_per_line);
|
||||
if (!b->backxrb->ximage->data) {
|
||||
_mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.\n");
|
||||
XMesaDestroyImage(b->backxrb->ximage);
|
||||
b->backxrb->ximage = NULL;
|
||||
}
|
||||
else {
|
||||
/* this call just updates the width/origin fields in the xrb */
|
||||
b->backxrb->Base.AllocStorage(NULL, &b->backxrb->Base,
|
||||
b->backxrb->Base.InternalFormat,
|
||||
b->backxrb->ximage->width,
|
||||
b->backxrb->ximage->height);
|
||||
}
|
||||
}
|
||||
b->backxrb->pixmap = None;
|
||||
}
|
||||
else if (b->db_mode == BACK_PIXMAP) {
|
||||
if (!width)
|
||||
width = 1;
|
||||
if (!height)
|
||||
height = 1;
|
||||
|
||||
/* Free the old back pixmap */
|
||||
if (b->backxrb->pixmap) {
|
||||
XMesaFreePixmap(b->xm_visual->display, b->backxrb->pixmap);
|
||||
}
|
||||
/* Allocate new back pixmap */
|
||||
b->backxrb->pixmap = XMesaCreatePixmap(b->xm_visual->display,
|
||||
b->frontxrb->drawable,
|
||||
width, height,
|
||||
GET_VISUAL_DEPTH(b->xm_visual));
|
||||
b->backxrb->ximage = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
|
||||
{
|
||||
@@ -68,7 +281,6 @@ xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
|
||||
/**
|
||||
* Reallocate renderbuffer storage for back color buffer.
|
||||
* XXX we should resize the back pixmap/ximage here.
|
||||
*/
|
||||
static GLboolean
|
||||
xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
@@ -76,7 +288,12 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
{
|
||||
struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);
|
||||
|
||||
/* reallocate the back buffer XImage or Pixmap */
|
||||
assert(xrb->Parent);
|
||||
alloc_back_buffer(xrb->Parent, width, height);
|
||||
|
||||
/* same as front buffer */
|
||||
/* XXX why is this here? */
|
||||
(void) xmesa_alloc_front_storage(ctx, rb, internalFormat, width, height);
|
||||
|
||||
/* plus... */
|
||||
|
@@ -23,6 +23,11 @@
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* \file xm_dd.h
|
||||
* General device driver functions for Xlib driver.
|
||||
*/
|
||||
|
||||
#include "glxheader.h"
|
||||
#include "bufferobj.h"
|
||||
#include "buffers.h"
|
||||
@@ -89,47 +94,12 @@ const int xmesa_kernel1[16] = {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return the size (width, height) of the X window for the given GLframebuffer.
|
||||
* Output: width - width of buffer in pixels.
|
||||
* height - height of buffer in pixels.
|
||||
*/
|
||||
/** XXX obsolete ***/
|
||||
static void
|
||||
get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
|
||||
{
|
||||
/* We can do this cast because the first field in the XMesaBuffer
|
||||
* struct is a GLframebuffer struct. If this weren't true, we'd
|
||||
* need a pointer from the GLframebuffer to the XMesaBuffer.
|
||||
*/
|
||||
const XMesaBuffer xmBuffer = (XMesaBuffer) buffer;
|
||||
unsigned int winwidth, winheight;
|
||||
#ifdef XFree86Server
|
||||
/* XFree86 GLX renderer */
|
||||
winwidth = MIN2(xmBuffer->frontxrb->drawable->width, MAX_WIDTH);
|
||||
winheight = MIN2(xmBuffer->frontxrb->drawable->height, MAX_HEIGHT);
|
||||
#else
|
||||
Window root;
|
||||
Status stat;
|
||||
int winx, winy;
|
||||
unsigned int bw, d;
|
||||
|
||||
_glthread_LOCK_MUTEX(_xmesa_lock);
|
||||
XSync(xmBuffer->xm_visual->display, 0); /* added for Chromium */
|
||||
|
||||
stat = XGetGeometry( xmBuffer->xm_visual->display, xmBuffer->frontxrb->pixmap,
|
||||
&root, &winx, &winy, &winwidth, &winheight, &bw, &d );
|
||||
_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;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
*width = winwidth;
|
||||
*height = winheight;
|
||||
XMesaBuffer b = XMESA_BUFFER(buffer);
|
||||
xmesa_get_window_size(b->display, b, width, height);
|
||||
}
|
||||
|
||||
|
||||
@@ -567,26 +537,6 @@ clear_buffers( GLcontext *ctx, GLbitfield mask,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by ctx->Driver.ResizeBuffers()
|
||||
* Resize the front/back colorbuffers to match the latest window size.
|
||||
*/
|
||||
void
|
||||
xmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer,
|
||||
GLuint width, GLuint height)
|
||||
{
|
||||
/* We can do this cast because the first field in the XMesaBuffer
|
||||
* struct is a GLframebuffer struct. If this weren't true, we'd
|
||||
* need a pointer from the GLframebuffer to the XMesaBuffer.
|
||||
*/
|
||||
XMesaBuffer xmBuffer = (XMesaBuffer) buffer;
|
||||
|
||||
xmesa_alloc_back_buffer(xmBuffer, width, height);
|
||||
|
||||
_mesa_resize_framebuffer(ctx, buffer, width, height);
|
||||
}
|
||||
|
||||
|
||||
#ifndef XFree86Server
|
||||
/* XXX this was never tested in the Xserver environment */
|
||||
|
||||
@@ -1120,33 +1070,6 @@ choose_tex_format( GLcontext *ctx, GLint internalFormat,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the current drawing (and reading) window's size and update the
|
||||
* corresponding gl_framebuffer(s) if needed.
|
||||
*/
|
||||
static void
|
||||
update_framebuffer_size(GLcontext *ctx)
|
||||
{
|
||||
struct gl_framebuffer *fb = ctx->WinSysDrawBuffer;
|
||||
GLuint newWidth, newHeight;
|
||||
get_buffer_size(fb, &newWidth, &newHeight);
|
||||
if (newWidth != fb->Width || newHeight != fb->Height) {
|
||||
xmesa_resize_buffers(ctx, fb, newWidth, newHeight);
|
||||
}
|
||||
|
||||
if (ctx->WinSysReadBuffer != ctx->WinSysDrawBuffer) {
|
||||
/* Update readbuffer's size */
|
||||
struct gl_framebuffer *fb = ctx->WinSysReadBuffer;
|
||||
GLuint newWidth, newHeight;
|
||||
get_buffer_size(fb, &newWidth, &newHeight);
|
||||
if (newWidth != fb->Width || newHeight != fb->Height) {
|
||||
xmesa_resize_buffers(ctx, fb, newWidth, newHeight);
|
||||
ctx->NewState |= _NEW_BUFFERS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by glViewport.
|
||||
* This is a good time for us to poll the current X window size and adjust
|
||||
@@ -1161,11 +1084,15 @@ update_framebuffer_size(GLcontext *ctx)
|
||||
static void
|
||||
xmesa_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
|
||||
{
|
||||
XMesaContext xmctx = XMESA_CONTEXT(ctx);
|
||||
XMesaBuffer xmdrawbuf = XMESA_BUFFER(ctx->WinSysDrawBuffer);
|
||||
XMesaBuffer xmreadbuf = XMESA_BUFFER(ctx->WinSysReadBuffer);
|
||||
xmesa_check_and_update_buffer_size(xmctx, xmdrawbuf);
|
||||
xmesa_check_and_update_buffer_size(xmctx, xmreadbuf);
|
||||
(void) x;
|
||||
(void) y;
|
||||
(void) w;
|
||||
(void) h;
|
||||
update_framebuffer_size(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -1258,7 +1185,6 @@ xmesa_init_driver_functions( XMesaVisual xmvisual,
|
||||
driver->ColorMask = color_mask;
|
||||
driver->Enable = enable;
|
||||
driver->Clear = clear_buffers;
|
||||
driver->ResizeBuffers = xmesa_resize_buffers;
|
||||
driver->Viewport = xmesa_viewport;
|
||||
#ifndef XFree86Server
|
||||
driver->CopyPixels = xmesa_CopyPixels;
|
||||
|
@@ -81,8 +81,9 @@ enum pixel_format {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* "Derived" from GLvisual. Basically corresponds to an XVisualInfo.
|
||||
/**
|
||||
* Visual inforation, derived from GLvisual.
|
||||
* Basically corresponds to an XVisualInfo.
|
||||
*/
|
||||
struct xmesa_visual {
|
||||
GLvisual mesa_visual; /* Device independent visual parameters */
|
||||
@@ -127,8 +128,9 @@ struct xmesa_visual {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* "Derived" from __GLcontextRec. Basically corresponds to a GLXContext.
|
||||
/**
|
||||
* Context info, dDerived from GLcontext.
|
||||
* Basically corresponds to a GLXContext.
|
||||
*/
|
||||
struct xmesa_context {
|
||||
GLcontext mesa; /* the core library context (containment) */
|
||||
@@ -146,7 +148,9 @@ struct xmesa_context {
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Types of X/GLX drawables we might render into.
|
||||
*/
|
||||
typedef enum {
|
||||
WINDOW, /* An X window */
|
||||
GLXWINDOW, /* GLX window */
|
||||
@@ -155,9 +159,11 @@ typedef enum {
|
||||
} BufferType;
|
||||
|
||||
|
||||
/* Values for db_mode: */
|
||||
/** Values for db_mode: */
|
||||
/*@{*/
|
||||
#define BACK_PIXMAP 1
|
||||
#define BACK_XIMAGE 2
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
@@ -175,6 +181,7 @@ struct xmesa_renderbuffer
|
||||
{
|
||||
struct gl_renderbuffer Base; /* Base class */
|
||||
|
||||
XMesaBuffer Parent; /**< The XMesaBuffer this renderbuffer belongs to */
|
||||
XMesaDrawable drawable; /* Usually the X window ID */
|
||||
XMesaPixmap pixmap; /* Back color buffer */
|
||||
XMesaImage *ximage; /* The back buffer, if not using a Pixmap */
|
||||
@@ -194,8 +201,9 @@ struct xmesa_renderbuffer
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* "Derived" from GLframebuffer. Basically corresponds to a GLXDrawable.
|
||||
/**
|
||||
* Framebuffer information, derived from.
|
||||
* Basically corresponds to a GLXDrawable.
|
||||
*/
|
||||
struct xmesa_buffer {
|
||||
GLframebuffer mesa_buffer; /* depth, stencil, accum, etc buffers */
|
||||
@@ -264,7 +272,7 @@ struct xmesa_buffer {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* If pixelformat==PF_TRUECOLOR:
|
||||
*/
|
||||
#define PACK_TRUECOLOR( PIXEL, R, G, B ) \
|
||||
@@ -273,7 +281,7 @@ struct xmesa_buffer {
|
||||
| xmesa->xm_visual->BtoPixel[B]; \
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* If pixelformat==PF_TRUEDITHER:
|
||||
*/
|
||||
#define PACK_TRUEDITHER( PIXEL, X, Y, R, G, B ) \
|
||||
@@ -286,14 +294,14 @@ struct xmesa_buffer {
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* If pixelformat==PF_8A8B8G8R:
|
||||
*/
|
||||
#define PACK_8A8B8G8R( R, G, B, A ) \
|
||||
( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) )
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
|
||||
* shortcut.
|
||||
*/
|
||||
@@ -301,19 +309,19 @@ struct xmesa_buffer {
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* If pixelformat==PF_8R8G8B:
|
||||
*/
|
||||
#define PACK_8R8G8B( R, G, B) ( ((R) << 16) | ((G) << 8) | (B) )
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* If pixelformat==PF_5R6G5B:
|
||||
*/
|
||||
#define PACK_5R6G5B( R, G, B) ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* If pixelformat==PF_8A8R8G8B:
|
||||
*/
|
||||
#define PACK_8A8R8G8B( R, G, B, A ) \
|
||||
@@ -321,7 +329,7 @@ struct xmesa_buffer {
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* If pixelformat==PF_DITHER:
|
||||
*
|
||||
* Improved 8-bit RGB dithering code contributed by Bob Mercier
|
||||
@@ -398,7 +406,7 @@ extern const int xmesa_kernel8[DITH_DY * DITH_DX];
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* If pixelformat==PF_LOOKUP:
|
||||
*/
|
||||
#define _dither_lookup(C, c) (((unsigned)((DITH_N * (C - 1) + 1) * c)) >> 12)
|
||||
@@ -412,8 +420,7 @@ extern const int xmesa_kernel8[DITH_DY * DITH_DX];
|
||||
_dither_lookup(DITH_B, (B)))]
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* If pixelformat==PF_HPCR:
|
||||
*
|
||||
* HP Color Recovery dithering (ad@lms.be 30/08/95)
|
||||
@@ -433,7 +440,7 @@ extern const short xmesa_HPCR_DRGB[3][2][16];
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* If pixelformat==PF_1BIT:
|
||||
*/
|
||||
extern const int xmesa_kernel1[16];
|
||||
@@ -444,20 +451,20 @@ extern const int xmesa_kernel1[16];
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* If pixelformat==PF_GRAYSCALE:
|
||||
*/
|
||||
#define GRAY_RGB( R, G, B ) XMESA_BUFFER(ctx->DrawBuffer)->color_table[((R) + (G) + (B))/3]
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Converts a GL window Y coord to an X window Y coord:
|
||||
*/
|
||||
#define YFLIP(XRB, Y) ((XRB)->bottom - (Y))
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Return the address of a 1, 2 or 4-byte pixel in the buffer's XImage:
|
||||
* X==0 is left, Y==0 is bottom.
|
||||
*/
|
||||
@@ -475,23 +482,6 @@ extern const int xmesa_kernel1[16];
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Return pointer to XMesaContext corresponding to a Mesa GLcontext.
|
||||
* Since we're using structure containment, it's just a cast!.
|
||||
* XXX should use inlined function for better type safety.
|
||||
*/
|
||||
#define XMESA_CONTEXT(MESACTX) ((XMesaContext) (MESACTX))
|
||||
|
||||
/*
|
||||
* Return pointer to XMesaBuffer corresponding to a Mesa GLframebuffer.
|
||||
* Since we're using structure containment, it's just a cast!.
|
||||
* XXX should use inlined function for better type safety.
|
||||
*/
|
||||
#define XMESA_BUFFER(MESABUFF) ((XMesaBuffer) (MESABUFF))
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* External functions:
|
||||
*/
|
||||
@@ -506,21 +496,25 @@ xmesa_color_to_pixel( GLcontext *ctx,
|
||||
GLuint pixelFormat );
|
||||
|
||||
extern void
|
||||
xmesa_alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height);
|
||||
xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
|
||||
GLuint *width, GLuint *height);
|
||||
|
||||
extern void xmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer,
|
||||
GLuint width, GLuint height);
|
||||
extern void
|
||||
xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer);
|
||||
|
||||
extern void xmesa_init_driver_functions( XMesaVisual xmvisual,
|
||||
extern void
|
||||
xmesa_init_driver_functions( XMesaVisual xmvisual,
|
||||
struct dd_function_table *driver );
|
||||
|
||||
extern void xmesa_update_state( GLcontext *ctx, GLbitfield new_state );
|
||||
extern void
|
||||
xmesa_update_state( GLcontext *ctx, GLbitfield new_state );
|
||||
|
||||
extern void
|
||||
xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb,
|
||||
enum pixel_format pixelformat, GLint depth);
|
||||
|
||||
extern void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy);
|
||||
extern void
|
||||
xmesa_destroy_buffers_on_display(XMesaDisplay *dpy);
|
||||
|
||||
|
||||
/**
|
||||
@@ -533,6 +527,30 @@ xmesa_renderbuffer(struct gl_renderbuffer *rb)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return pointer to XMesaContext corresponding to a Mesa GLcontext.
|
||||
* Since we're using structure containment, it's just a cast!.
|
||||
* XXX should use inlined function for better type safety.
|
||||
*/
|
||||
static INLINE XMesaContext
|
||||
XMESA_CONTEXT(GLcontext *ctx)
|
||||
{
|
||||
return (XMesaContext) ctx;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return pointer to XMesaBuffer corresponding to a Mesa GLframebuffer.
|
||||
* Since we're using structure containment, it's just a cast!.
|
||||
* XXX should use inlined function for better type safety.
|
||||
*/
|
||||
static INLINE XMesaBuffer
|
||||
XMESA_BUFFER(GLframebuffer *b)
|
||||
{
|
||||
return (XMesaBuffer) b;
|
||||
}
|
||||
|
||||
|
||||
/* Plugged into the software rasterizer. Try to use internal
|
||||
* swrast-style point, line and triangle functions.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user