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.
|
* 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:
|
* NOTES:
|
||||||
@@ -68,13 +70,8 @@
|
|||||||
#include "framebuffer.h"
|
#include "framebuffer.h"
|
||||||
#include "glthread.h"
|
#include "glthread.h"
|
||||||
#include "imports.h"
|
#include "imports.h"
|
||||||
#include "matrix.h"
|
|
||||||
#include "mtypes.h"
|
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "renderbuffer.h"
|
#include "renderbuffer.h"
|
||||||
#include "texformat.h"
|
|
||||||
#include "texobj.h"
|
|
||||||
#include "texstore.h"
|
|
||||||
#include "swrast/swrast.h"
|
#include "swrast/swrast.h"
|
||||||
#include "swrast_setup/swrast_setup.h"
|
#include "swrast_setup/swrast_setup.h"
|
||||||
#include "array_cache/acache.h"
|
#include "array_cache/acache.h"
|
||||||
@@ -87,14 +84,14 @@
|
|||||||
#include <GL/glxtokens.h>
|
#include <GL/glxtokens.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Global X driver lock
|
* Global X driver lock
|
||||||
*/
|
*/
|
||||||
_glthread_Mutex _xmesa_lock;
|
_glthread_Mutex _xmesa_lock;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Lookup tables for HPCR pixel format:
|
* Lookup tables for HPCR pixel format:
|
||||||
*/
|
*/
|
||||||
static short hpcr_rgbTbl[3][256] = {
|
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.
|
* Return the host's byte order as LSBFirst or MSBFirst ala X.
|
||||||
*/
|
*/
|
||||||
#ifndef XFree86Server
|
#ifndef XFree86Server
|
||||||
@@ -174,23 +171,7 @@ static int host_byte_order( void )
|
|||||||
#endif
|
#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.
|
* Check if the X Shared Memory extension is available.
|
||||||
* Return: 0 = not available
|
* Return: 0 = not available
|
||||||
* 1 = shared XImage support 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
|
* Apply gamma correction to an intensity value in [0..max]. Return the
|
||||||
* new intensity value.
|
* 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) {
|
if (gamma == 1.0) {
|
||||||
return value;
|
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.
|
* 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
|
* For example, if we request a 24-bit deep visual we may actually need/get
|
||||||
* 32bpp XImages. This function returns the appropriate bpp.
|
* 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
|
* visinfo - desribes the visual to be used for XImages
|
||||||
* Return: true number of bits per pixel 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;
|
const int depth = xmv->nplanes;
|
||||||
int i;
|
int i;
|
||||||
assert(depth > 0);
|
assert(depth > 0);
|
||||||
@@ -259,12 +241,7 @@ static int bits_per_pixel( XMesaVisual xmv )
|
|||||||
return screenInfo.formats[i].bitsPerPixel;
|
return screenInfo.formats[i].bitsPerPixel;
|
||||||
}
|
}
|
||||||
return depth; /* should never get here, but this should be safe */
|
return depth; /* should never get here, but this should be safe */
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static int bits_per_pixel( XMesaVisual xmv )
|
|
||||||
{
|
|
||||||
XMesaDisplay *dpy = xmv->display;
|
XMesaDisplay *dpy = xmv->display;
|
||||||
XMesaVisualInfo visinfo = xmv->visinfo;
|
XMesaVisualInfo visinfo = xmv->visinfo;
|
||||||
XMesaImage *img;
|
XMesaImage *img;
|
||||||
@@ -285,8 +262,8 @@ static int bits_per_pixel( XMesaVisual xmv )
|
|||||||
img->data = NULL;
|
img->data = NULL;
|
||||||
XMesaDestroyImage( img );
|
XMesaDestroyImage( img );
|
||||||
return bitsPerPixel;
|
return bitsPerPixel;
|
||||||
}
|
|
||||||
#endif
|
#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 *****/
|
/***** Linked list of XMesaBuffers *****/
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
@@ -333,80 +349,110 @@ static XMesaBuffer XMesaBufferList = NULL;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a new XMesaBuffer, initialize basic fields and add to
|
* Allocate a new XMesaBuffer object which corresponds to the given drawable.
|
||||||
* the list of all buffers.
|
* 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
|
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);
|
GLboolean swAlpha;
|
||||||
if (b) {
|
XMesaBuffer b;
|
||||||
GLboolean swAlpha;
|
|
||||||
|
|
||||||
b->display = vis->display;
|
ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
|
||||||
b->xm_visual = vis;
|
|
||||||
b->type = type;
|
|
||||||
b->cmap = cmap;
|
|
||||||
|
|
||||||
_mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual);
|
b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
|
||||||
|
if (!b)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* Allocate the framebuffer's renderbuffers */
|
b->display = vis->display;
|
||||||
assert(!b->mesa_buffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
|
b->xm_visual = vis;
|
||||||
assert(!b->mesa_buffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer);
|
b->type = type;
|
||||||
|
b->cmap = cmap;
|
||||||
|
|
||||||
/* front renderbuffer */
|
_mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual);
|
||||||
b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
|
|
||||||
|
/*
|
||||||
|
* Front renderbuffer
|
||||||
|
*/
|
||||||
|
b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
|
||||||
GL_FALSE);
|
GL_FALSE);
|
||||||
_mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT,
|
if (!b->frontxrb) {
|
||||||
&b->frontxrb->Base);
|
_mesa_free(b);
|
||||||
|
return NULL;
|
||||||
/* back renderbuffer */
|
|
||||||
if (vis->mesa_visual.doubleBufferMode) {
|
|
||||||
b->backxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
|
|
||||||
GL_TRUE);
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* determine if we need 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.
|
|
||||||
*/
|
|
||||||
swAlpha = GL_TRUE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
swAlpha = GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_mesa_add_soft_renderbuffers(&b->mesa_buffer,
|
|
||||||
GL_FALSE, /* color */
|
|
||||||
vis->mesa_visual.haveDepthBuffer,
|
|
||||||
vis->mesa_visual.haveStencilBuffer,
|
|
||||||
vis->mesa_visual.haveAccumBuffer,
|
|
||||||
swAlpha,
|
|
||||||
vis->mesa_visual.numAuxBuffers > 0 );
|
|
||||||
|
|
||||||
/* insert into linked list */
|
|
||||||
b->Next = XMesaBufferList;
|
|
||||||
XMesaBufferList = b;
|
|
||||||
}
|
}
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
swAlpha = GL_TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
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,
|
||||||
|
swAlpha,
|
||||||
|
vis->mesa_visual.numAuxBuffers > 0 );
|
||||||
|
|
||||||
|
/* insert buffer into linked list */
|
||||||
|
b->Next = XMesaBufferList;
|
||||||
|
XMesaBufferList = b;
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Find an XMesaBuffer by matching X display and colormap but NOT matching
|
* Find an XMesaBuffer by matching X display and colormap but NOT matching
|
||||||
* the notThis buffer.
|
* the notThis buffer.
|
||||||
*/
|
*/
|
||||||
static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy,
|
static XMesaBuffer
|
||||||
XMesaColormap cmap,
|
find_xmesa_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis)
|
||||||
XMesaBuffer notThis)
|
|
||||||
{
|
{
|
||||||
XMesaBuffer b;
|
XMesaBuffer b;
|
||||||
for (b=XMesaBufferList; b; b=b->Next) {
|
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
|
* Free an XMesaBuffer, remove from linked list, perhaps free X colormap
|
||||||
* entries.
|
* entries.
|
||||||
*/
|
*/
|
||||||
static void free_xmesa_buffer(int client, XMesaBuffer buffer)
|
static void
|
||||||
|
free_xmesa_buffer(int client, XMesaBuffer buffer)
|
||||||
{
|
{
|
||||||
XMesaBuffer prev = NULL, b;
|
XMesaBuffer prev = NULL, b;
|
||||||
(void) client;
|
(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->color_table, src->color_table, sizeof(src->color_table));
|
||||||
MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r));
|
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
|
* A replacement for XAllocColor. This function should never
|
||||||
* fail to allocate a color. When XAllocColor fails, we return
|
* fail to allocate a color. When XAllocColor fails, we return
|
||||||
* the nearest matching color. If we have to allocate many colors
|
* the nearest matching color. If we have to allocate many colors
|
||||||
@@ -715,10 +573,11 @@ noFaultXAllocColor( int client,
|
|||||||
if (AllocColor(cmap,
|
if (AllocColor(cmap,
|
||||||
&color->red, &color->green, &color->blue,
|
&color->red, &color->green, &color->blue,
|
||||||
&color->pixel,
|
&color->pixel,
|
||||||
client) == Success) {
|
client) == Success)
|
||||||
#else
|
#else
|
||||||
if (XAllocColor(dpy, cmap, color)) {
|
if (XAllocColor(dpy, cmap, color))
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
*exact = 1;
|
*exact = 1;
|
||||||
*alloced = 1;
|
*alloced = 1;
|
||||||
return;
|
return;
|
||||||
@@ -808,13 +667,13 @@ noFaultXAllocColor( int client,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
/*
|
|
||||||
* Do setup for PF_GRAYSCALE pixel format.
|
* Do setup for PF_GRAYSCALE pixel format.
|
||||||
* Note that buffer may be NULL.
|
* Note that buffer may be NULL.
|
||||||
*/
|
*/
|
||||||
static GLboolean setup_grayscale( int client, XMesaVisual v,
|
static GLboolean
|
||||||
XMesaBuffer buffer, XMesaColormap cmap )
|
setup_grayscale(int client, XMesaVisual v,
|
||||||
|
XMesaBuffer buffer, XMesaColormap cmap)
|
||||||
{
|
{
|
||||||
if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
|
if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
|
||||||
return GL_FALSE;
|
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,
|
* Setup RGB rendering for a window with a PseudoColor, StaticColor,
|
||||||
* or 8-bit TrueColor visual visual. We try to allocate a palette of 225
|
* 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
|
* 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.
|
* visuals, it has also proven to work from 4-bit up to 16-bit visuals.
|
||||||
* Dithering code contributed by Bob Mercier.
|
* Dithering code contributed by Bob Mercier.
|
||||||
*/
|
*/
|
||||||
static GLboolean setup_dithered_color( int client, XMesaVisual v,
|
static GLboolean
|
||||||
XMesaBuffer buffer, XMesaColormap cmap )
|
setup_dithered_color(int client, XMesaVisual v,
|
||||||
|
XMesaBuffer buffer, XMesaColormap cmap)
|
||||||
{
|
{
|
||||||
if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
|
if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
|
||||||
return GL_FALSE;
|
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.
|
* Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode.
|
||||||
* HPCR simulates 24-bit color fidelity with an 8-bit frame buffer.
|
* HPCR simulates 24-bit color fidelity with an 8-bit frame buffer.
|
||||||
* Special dithering tables have to be initialized.
|
* 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)
|
/* HP Color Recovery contributed by: Alex De Bruyn (ad@lms.be)
|
||||||
* To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined
|
* 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.
|
* Setup RGB rendering for a window with a True/DirectColor visual.
|
||||||
*/
|
*/
|
||||||
static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
|
static void
|
||||||
XMesaColormap cmap )
|
setup_truecolor(XMesaVisual v, XMesaBuffer buffer, XMesaColormap cmap)
|
||||||
{
|
{
|
||||||
unsigned long rmask, gmask, bmask;
|
unsigned long rmask, gmask, bmask;
|
||||||
(void) buffer;
|
(void) buffer;
|
||||||
@@ -1171,10 +1032,11 @@ static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Setup RGB rendering for a window with a monochrome visual.
|
* 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;
|
(void) b;
|
||||||
v->dithered_pf = v->undithered_pf = PF_1Bit;
|
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);
|
v->BitsPerPixel = bits_per_pixel(v);
|
||||||
assert(v->BitsPerPixel > 0);
|
assert(v->BitsPerPixel > 0);
|
||||||
|
|
||||||
if (rgb_flag==GL_FALSE) {
|
if (rgb_flag == GL_FALSE) {
|
||||||
/* COLOR-INDEXED WINDOW:
|
/* COLOR-INDEXED WINDOW:
|
||||||
* Even if the visual is TrueColor or DirectColor we treat it as
|
* Even if the visual is TrueColor or DirectColor we treat it as
|
||||||
* being color indexed. This is weird but might be useful to someone.
|
* 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) {
|
if (b && window) {
|
||||||
/* Do window-specific initializations */
|
/* Do window-specific initializations */
|
||||||
|
|
||||||
b->frontxrb->drawable = window;
|
/* these should have been set in create_xmesa_buffer */
|
||||||
b->frontxrb->pixmap = (XMesaPixmap) window;
|
ASSERT(b->frontxrb->drawable == window);
|
||||||
|
ASSERT(b->frontxrb->pixmap == (XMesaPixmap) window);
|
||||||
|
|
||||||
/* Setup for single/double buffering */
|
/* Setup for single/double buffering */
|
||||||
if (v->mesa_visual.doubleBufferMode) {
|
if (v->mesa_visual.doubleBufferMode) {
|
||||||
/* Double buffered */
|
/* Double buffered */
|
||||||
b->shm = check_for_xshm( v->display );
|
b->shm = check_for_xshm( v->display );
|
||||||
xmesa_alloc_back_buffer(b, b->mesa_buffer.Width, b->mesa_buffer.Height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* X11 graphics contexts */
|
/* 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.
|
* Private function for creating an XMesaBuffer which corresponds to an
|
||||||
* Create a new XMesaBuffer from an X window.
|
* X window or pixmap.
|
||||||
* Input: v - the XMesaVisual
|
* \param v the window's XMesaVisual
|
||||||
* w - the window
|
* \param w the window we're wrapping
|
||||||
* c - the context
|
* \param c context used to initialize the buffer if 3Dfx mode in use.
|
||||||
* Return: new XMesaBuffer or NULL if error
|
* \return new XMesaBuffer or NULL if error
|
||||||
*/
|
*/
|
||||||
XMesaBuffer
|
XMesaBuffer
|
||||||
XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
|
XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
|
||||||
@@ -1754,6 +1616,7 @@ XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
|
|||||||
XMesaColormap cmap;
|
XMesaColormap cmap;
|
||||||
|
|
||||||
assert(v);
|
assert(v);
|
||||||
|
assert(w);
|
||||||
(void) c;
|
(void) c;
|
||||||
|
|
||||||
/* Check that window depth matches visual depth */
|
/* Check that window depth matches visual depth */
|
||||||
@@ -1790,10 +1653,9 @@ XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
b = alloc_xmesa_buffer(v, WINDOW, cmap);
|
b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap);
|
||||||
if (!b) {
|
if (!b)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode,
|
if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode,
|
||||||
(XMesaDrawable) w, cmap )) {
|
(XMesaDrawable) w, cmap )) {
|
||||||
@@ -1908,10 +1770,9 @@ XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap)
|
|||||||
|
|
||||||
assert(v);
|
assert(v);
|
||||||
|
|
||||||
b = alloc_xmesa_buffer(v, PIXMAP, cmap);
|
b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
|
||||||
if (!b) {
|
if (!b)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef XFree86Server
|
#ifdef XFree86Server
|
||||||
client = CLIENT_ID(((XMesaDrawable)p)->id);
|
client = CLIENT_ID(((XMesaDrawable)p)->id);
|
||||||
@@ -1940,14 +1801,16 @@ XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
|
|||||||
XMesaDrawable drawable; /* X Pixmap Drawable */
|
XMesaDrawable drawable; /* X Pixmap Drawable */
|
||||||
XMesaBuffer b;
|
XMesaBuffer b;
|
||||||
|
|
||||||
b = alloc_xmesa_buffer(v, PBUFFER, cmap);
|
|
||||||
if (!b) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate pixmap for front buffer */
|
/* allocate pixmap for front buffer */
|
||||||
root = RootWindow( v->display, v->visinfo->screen );
|
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,
|
if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
|
||||||
drawable, cmap)) {
|
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.
|
* 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()
|
if (&(c->mesa) == _mesa_get_current_context()
|
||||||
&& c->mesa.DrawBuffer == &drawBuffer->mesa_buffer
|
&& c->mesa.DrawBuffer == &drawBuffer->mesa_buffer
|
||||||
&& c->mesa.ReadBuffer == &readBuffer->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 */
|
/* same context and buffer, do nothing */
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
@@ -2053,6 +1937,12 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
|
|||||||
*/
|
*/
|
||||||
_glapi_check_multithread();
|
_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),
|
_mesa_make_current(&(c->mesa),
|
||||||
&drawBuffer->mesa_buffer,
|
&drawBuffer->mesa_buffer,
|
||||||
&readBuffer->mesa_buffer);
|
&readBuffer->mesa_buffer);
|
||||||
@@ -2123,7 +2013,7 @@ XMesaBuffer XMesaGetCurrentReadBuffer( void )
|
|||||||
{
|
{
|
||||||
GET_CURRENT_CONTEXT(ctx);
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
return (XMesaBuffer) (ctx->ReadBuffer);
|
return XMESA_BUFFER(ctx->ReadBuffer);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2212,9 +2102,7 @@ static void FXgetImage( XMesaBuffer b )
|
|||||||
GET_CURRENT_CONTEXT(ctx);
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
static unsigned short pixbuf[MAX_WIDTH];
|
static unsigned short pixbuf[MAX_WIDTH];
|
||||||
GLuint x, y;
|
GLuint x, y;
|
||||||
int xpos, ypos;
|
GLuint width, height;
|
||||||
XMesaWindow root;
|
|
||||||
unsigned int bw, depth, width, height;
|
|
||||||
XMesaContext xmesa = XMESA_CONTEXT(ctx);
|
XMesaContext xmesa = XMESA_CONTEXT(ctx);
|
||||||
|
|
||||||
#ifdef XFree86Server
|
#ifdef XFree86Server
|
||||||
@@ -2224,15 +2112,14 @@ static void FXgetImage( XMesaBuffer b )
|
|||||||
height = b->frontxrb->pixmap->height;
|
height = b->frontxrb->pixmap->height;
|
||||||
depth = b->frontxrb->pixmap->depth;
|
depth = b->frontxrb->pixmap->depth;
|
||||||
#else
|
#else
|
||||||
XGetGeometry( b->xm_visual->display, b->frontxrb->pixmap,
|
xmesa_get_window_size(b->display, b, &width, &height);
|
||||||
&root, &xpos, &ypos, &width, &height, &bw, &depth);
|
x = y = 0;
|
||||||
#endif
|
#endif
|
||||||
if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) {
|
if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) {
|
||||||
b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width);
|
b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width);
|
||||||
b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height);
|
b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height);
|
||||||
if (b->mesa_buffer.Width & 1)
|
if (b->mesa_buffer.Width & 1)
|
||||||
b->mesa_buffer.Width--; /* prevent odd width */
|
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? */
|
/* [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
|
* This is typically called when the window size changes and we need
|
||||||
* to reallocate the buffer's back/depth/stencil/accum buffers.
|
* 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);
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
|
XMesaContext xmctx = XMESA_CONTEXT(ctx);
|
||||||
winwidth = MIN2(b->frontxrb->drawable->width, MAX_WIDTH);
|
xmesa_check_and_update_buffer_size(xmctx, b);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* 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
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* 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 "glxheader.h"
|
||||||
#include "GL/xmesa.h"
|
#include "GL/xmesa.h"
|
||||||
#include "xmesaP.h"
|
#include "xmesaP.h"
|
||||||
@@ -30,6 +36,213 @@
|
|||||||
#include "renderbuffer.h"
|
#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
|
static void
|
||||||
xmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
|
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.
|
* Reallocate renderbuffer storage for back color buffer.
|
||||||
* XXX we should resize the back pixmap/ximage here.
|
|
||||||
*/
|
*/
|
||||||
static GLboolean
|
static GLboolean
|
||||||
xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
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);
|
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 */
|
/* same as front buffer */
|
||||||
|
/* XXX why is this here? */
|
||||||
(void) xmesa_alloc_front_storage(ctx, rb, internalFormat, width, height);
|
(void) xmesa_alloc_front_storage(ctx, rb, internalFormat, width, height);
|
||||||
|
|
||||||
/* plus... */
|
/* plus... */
|
||||||
|
@@ -23,6 +23,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file xm_dd.h
|
||||||
|
* General device driver functions for Xlib driver.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glxheader.h"
|
#include "glxheader.h"
|
||||||
#include "bufferobj.h"
|
#include "bufferobj.h"
|
||||||
#include "buffers.h"
|
#include "buffers.h"
|
||||||
@@ -89,47 +94,12 @@ const int xmesa_kernel1[16] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/** XXX obsolete ***/
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
static void
|
static void
|
||||||
get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
|
get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
|
||||||
{
|
{
|
||||||
/* We can do this cast because the first field in the XMesaBuffer
|
XMesaBuffer b = XMESA_BUFFER(buffer);
|
||||||
* struct is a GLframebuffer struct. If this weren't true, we'd
|
xmesa_get_window_size(b->display, b, width, height);
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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
|
#ifndef XFree86Server
|
||||||
/* XXX this was never tested in the Xserver environment */
|
/* 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.
|
* Called by glViewport.
|
||||||
* This is a good time for us to poll the current X window size and adjust
|
* 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
|
static void
|
||||||
xmesa_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
|
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) x;
|
||||||
(void) y;
|
(void) y;
|
||||||
(void) w;
|
(void) w;
|
||||||
(void) h;
|
(void) h;
|
||||||
update_framebuffer_size(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1258,7 +1185,6 @@ xmesa_init_driver_functions( XMesaVisual xmvisual,
|
|||||||
driver->ColorMask = color_mask;
|
driver->ColorMask = color_mask;
|
||||||
driver->Enable = enable;
|
driver->Enable = enable;
|
||||||
driver->Clear = clear_buffers;
|
driver->Clear = clear_buffers;
|
||||||
driver->ResizeBuffers = xmesa_resize_buffers;
|
|
||||||
driver->Viewport = xmesa_viewport;
|
driver->Viewport = xmesa_viewport;
|
||||||
#ifndef XFree86Server
|
#ifndef XFree86Server
|
||||||
driver->CopyPixels = xmesa_CopyPixels;
|
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 {
|
struct xmesa_visual {
|
||||||
GLvisual mesa_visual; /* Device independent visual parameters */
|
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 {
|
struct xmesa_context {
|
||||||
GLcontext mesa; /* the core library context (containment) */
|
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 {
|
typedef enum {
|
||||||
WINDOW, /* An X window */
|
WINDOW, /* An X window */
|
||||||
GLXWINDOW, /* GLX window */
|
GLXWINDOW, /* GLX window */
|
||||||
@@ -155,9 +159,11 @@ typedef enum {
|
|||||||
} BufferType;
|
} BufferType;
|
||||||
|
|
||||||
|
|
||||||
/* Values for db_mode: */
|
/** Values for db_mode: */
|
||||||
|
/*@{*/
|
||||||
#define BACK_PIXMAP 1
|
#define BACK_PIXMAP 1
|
||||||
#define BACK_XIMAGE 2
|
#define BACK_XIMAGE 2
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -175,6 +181,7 @@ struct xmesa_renderbuffer
|
|||||||
{
|
{
|
||||||
struct gl_renderbuffer Base; /* Base class */
|
struct gl_renderbuffer Base; /* Base class */
|
||||||
|
|
||||||
|
XMesaBuffer Parent; /**< The XMesaBuffer this renderbuffer belongs to */
|
||||||
XMesaDrawable drawable; /* Usually the X window ID */
|
XMesaDrawable drawable; /* Usually the X window ID */
|
||||||
XMesaPixmap pixmap; /* Back color buffer */
|
XMesaPixmap pixmap; /* Back color buffer */
|
||||||
XMesaImage *ximage; /* The back buffer, if not using a Pixmap */
|
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 {
|
struct xmesa_buffer {
|
||||||
GLframebuffer mesa_buffer; /* depth, stencil, accum, etc buffers */
|
GLframebuffer mesa_buffer; /* depth, stencil, accum, etc buffers */
|
||||||
@@ -264,7 +272,7 @@ struct xmesa_buffer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* If pixelformat==PF_TRUECOLOR:
|
* If pixelformat==PF_TRUECOLOR:
|
||||||
*/
|
*/
|
||||||
#define PACK_TRUECOLOR( PIXEL, R, G, B ) \
|
#define PACK_TRUECOLOR( PIXEL, R, G, B ) \
|
||||||
@@ -273,7 +281,7 @@ struct xmesa_buffer {
|
|||||||
| xmesa->xm_visual->BtoPixel[B]; \
|
| xmesa->xm_visual->BtoPixel[B]; \
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* If pixelformat==PF_TRUEDITHER:
|
* If pixelformat==PF_TRUEDITHER:
|
||||||
*/
|
*/
|
||||||
#define PACK_TRUEDITHER( PIXEL, X, Y, R, G, B ) \
|
#define PACK_TRUEDITHER( PIXEL, X, Y, R, G, B ) \
|
||||||
@@ -286,14 +294,14 @@ struct xmesa_buffer {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* If pixelformat==PF_8A8B8G8R:
|
* If pixelformat==PF_8A8B8G8R:
|
||||||
*/
|
*/
|
||||||
#define PACK_8A8B8G8R( R, G, B, A ) \
|
#define PACK_8A8B8G8R( R, G, B, A ) \
|
||||||
( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) )
|
( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) )
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
|
* Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
|
||||||
* shortcut.
|
* shortcut.
|
||||||
*/
|
*/
|
||||||
@@ -301,19 +309,19 @@ struct xmesa_buffer {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* If pixelformat==PF_8R8G8B:
|
* If pixelformat==PF_8R8G8B:
|
||||||
*/
|
*/
|
||||||
#define PACK_8R8G8B( R, G, B) ( ((R) << 16) | ((G) << 8) | (B) )
|
#define PACK_8R8G8B( R, G, B) ( ((R) << 16) | ((G) << 8) | (B) )
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* If pixelformat==PF_5R6G5B:
|
* If pixelformat==PF_5R6G5B:
|
||||||
*/
|
*/
|
||||||
#define PACK_5R6G5B( R, G, B) ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
|
#define PACK_5R6G5B( R, G, B) ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* If pixelformat==PF_8A8R8G8B:
|
* If pixelformat==PF_8A8R8G8B:
|
||||||
*/
|
*/
|
||||||
#define PACK_8A8R8G8B( R, G, B, A ) \
|
#define PACK_8A8R8G8B( R, G, B, A ) \
|
||||||
@@ -321,7 +329,7 @@ struct xmesa_buffer {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* If pixelformat==PF_DITHER:
|
* If pixelformat==PF_DITHER:
|
||||||
*
|
*
|
||||||
* Improved 8-bit RGB dithering code contributed by Bob Mercier
|
* 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:
|
* If pixelformat==PF_LOOKUP:
|
||||||
*/
|
*/
|
||||||
#define _dither_lookup(C, c) (((unsigned)((DITH_N * (C - 1) + 1) * c)) >> 12)
|
#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)))]
|
_dither_lookup(DITH_B, (B)))]
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
/*
|
|
||||||
* If pixelformat==PF_HPCR:
|
* If pixelformat==PF_HPCR:
|
||||||
*
|
*
|
||||||
* HP Color Recovery dithering (ad@lms.be 30/08/95)
|
* 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:
|
* If pixelformat==PF_1BIT:
|
||||||
*/
|
*/
|
||||||
extern const int xmesa_kernel1[16];
|
extern const int xmesa_kernel1[16];
|
||||||
@@ -444,20 +451,20 @@ extern const int xmesa_kernel1[16];
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* If pixelformat==PF_GRAYSCALE:
|
* If pixelformat==PF_GRAYSCALE:
|
||||||
*/
|
*/
|
||||||
#define GRAY_RGB( R, G, B ) XMESA_BUFFER(ctx->DrawBuffer)->color_table[((R) + (G) + (B))/3]
|
#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:
|
* Converts a GL window Y coord to an X window Y coord:
|
||||||
*/
|
*/
|
||||||
#define YFLIP(XRB, Y) ((XRB)->bottom - (Y))
|
#define YFLIP(XRB, Y) ((XRB)->bottom - (Y))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Return the address of a 1, 2 or 4-byte pixel in the buffer's XImage:
|
* Return the address of a 1, 2 or 4-byte pixel in the buffer's XImage:
|
||||||
* X==0 is left, Y==0 is bottom.
|
* 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:
|
* External functions:
|
||||||
*/
|
*/
|
||||||
@@ -506,21 +496,25 @@ xmesa_color_to_pixel( GLcontext *ctx,
|
|||||||
GLuint pixelFormat );
|
GLuint pixelFormat );
|
||||||
|
|
||||||
extern void
|
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,
|
extern void
|
||||||
GLuint width, GLuint height);
|
xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer);
|
||||||
|
|
||||||
extern void xmesa_init_driver_functions( XMesaVisual xmvisual,
|
extern void
|
||||||
struct dd_function_table *driver );
|
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
|
extern void
|
||||||
xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb,
|
xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb,
|
||||||
enum pixel_format pixelformat, GLint depth);
|
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
|
/* Plugged into the software rasterizer. Try to use internal
|
||||||
* swrast-style point, line and triangle functions.
|
* swrast-style point, line and triangle functions.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user