-/* $Id: xm_dd.c,v 1.1 2000/09/07 15:40:30 brianp Exp $ */
-
/*
* Mesa 3-D graphics library
- * Version: 3.3
- *
- * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
- *
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 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"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
#include "glxheader.h"
#include "context.h"
-#include "drawpix.h"
-#include "mem.h"
-#include "state.h"
+#include "colormac.h"
#include "depth.h"
+#include "drawpix.h"
+#include "extensions.h"
#include "macros.h"
-#include "vb.h"
-#include "types.h"
+#include "imports.h"
+#include "mtypes.h"
+#include "state.h"
+#include "texobj.h"
+#include "teximage.h"
+#include "texstore.h"
+#include "texformat.h"
#include "xmesaP.h"
-#include "extensions.h"
+#include "array_cache/acache.h"
+#include "swrast/s_context.h"
+#include "swrast/swrast.h"
+#include "swrast/s_alphabuf.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
/*
- * Return the size (width,height of the current color buffer.
- * This function should be called by the glViewport function because
- * glViewport is often called when the window gets resized. We need to
- * update some X/Mesa stuff when that happens.
+ * 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
-get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
+get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ /* 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;
-#ifndef XFree86Server
+#ifdef XFree86Server
+ /* XFree86 GLX renderer */
+ if (xmBuffer->frontbuffer->width > MAX_WIDTH ||
+ xmBuffer->frontbuffer->height > MAX_HEIGHT) {
+ winwidth = buffer->Width;
+ winheight = buffer->Height;
+ } else {
+ winwidth = xmBuffer->frontbuffer->width;
+ winheight = xmBuffer->frontbuffer->height;
+ }
+#else
Window root;
int winx, winy;
unsigned int bw, d;
_glthread_LOCK_MUTEX(_xmesa_lock);
- XGetGeometry( xmesa->display, xmesa->xm_buffer->frontbuffer, &root,
+ XSync(xmBuffer->xm_visual->display, 0); /* added for Chromium */
+ XGetGeometry( xmBuffer->xm_visual->display, xmBuffer->frontbuffer, &root,
&winx, &winy, &winwidth, &winheight, &bw, &d );
_glthread_UNLOCK_MUTEX(_xmesa_lock);
-#else
-
- winwidth = xmesa->xm_buffer->frontbuffer->width;
- winheight = xmesa->xm_buffer->frontbuffer->height;
#endif
+ (void)kernel8; /* Muffle compiler */
+
*width = winwidth;
*height = winheight;
-
- if ( winwidth!=xmesa->xm_buffer->width
- || winheight!=xmesa->xm_buffer->height) {
- xmesa->xm_buffer->width = winwidth;
- xmesa->xm_buffer->height = winheight;
- xmesa_alloc_back_buffer( xmesa->xm_buffer );
- }
-
- /* Needed by FLIP macro */
- xmesa->xm_buffer->bottom = (int) winheight - 1;
-
- if (xmesa->xm_buffer->backimage) {
- /* Needed by PIXELADDR1 macro */
- xmesa->xm_buffer->ximage_width1
- = xmesa->xm_buffer->backimage->bytes_per_line;
- xmesa->xm_buffer->ximage_origin1
- = (GLubyte *) xmesa->xm_buffer->backimage->data
- + xmesa->xm_buffer->ximage_width1 * (winheight-1);
-
- /* Needed by PIXELADDR2 macro */
- xmesa->xm_buffer->ximage_width2
- = xmesa->xm_buffer->backimage->bytes_per_line / 2;
- xmesa->xm_buffer->ximage_origin2
- = (GLushort *) xmesa->xm_buffer->backimage->data
- + xmesa->xm_buffer->ximage_width2 * (winheight-1);
-
- /* Needed by PIXELADDR3 macro */
- xmesa->xm_buffer->ximage_width3
- = xmesa->xm_buffer->backimage->bytes_per_line;
- xmesa->xm_buffer->ximage_origin3
- = (GLubyte *) xmesa->xm_buffer->backimage->data
- + xmesa->xm_buffer->ximage_width3 * (winheight-1);
-
- /* Needed by PIXELADDR4 macro */
- xmesa->xm_buffer->ximage_width4 = xmesa->xm_buffer->backimage->width;
- xmesa->xm_buffer->ximage_origin4
- = (GLuint *) xmesa->xm_buffer->backimage->data
- + xmesa->xm_buffer->ximage_width4 * (winheight-1);
- }
}
#ifdef XFree86Server
/* NOT_NEEDED */
#else
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
if (xmesa) {
_glthread_LOCK_MUTEX(_xmesa_lock);
XSync( xmesa->display, False );
#ifdef XFree86Server
/* NOT_NEEDED */
#else
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
if (xmesa) {
_glthread_LOCK_MUTEX(_xmesa_lock);
XFlush( xmesa->display );
}
-#if 0
-static GLboolean
-set_buffer( GLcontext *ctx, GLenum mode )
-{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- if (mode == GL_FRONT_LEFT) {
- /* read/write front buffer */
- xmesa->xm_buffer->buffer = xmesa->xm_buffer->frontbuffer;
- ctx->NewState |= NEW_RASTER_OPS;
- gl_update_state(ctx);
- return GL_TRUE;
- }
- else if (mode==GL_BACK_LEFT && xmesa->xm_buffer->db_state) {
- /* read/write back buffer */
- if (xmesa->xm_buffer->backpixmap) {
- xmesa->xm_buffer->buffer =
- (XMesaDrawable)xmesa->xm_buffer->backpixmap;
- }
- else if (xmesa->xm_buffer->backimage) {
- xmesa->xm_buffer->buffer = None;
- }
- else {
- /* just in case there wasn't enough memory for back buffer */
- xmesa->xm_buffer->buffer = xmesa->xm_buffer->frontbuffer;
- }
- ctx->NewState |= NEW_RASTER_OPS;
- gl_update_state(ctx);
- return GL_TRUE;
- }
- else {
- return GL_FALSE;
- }
-}
-#endif
-
-
-static GLboolean
-set_draw_buffer( GLcontext *ctx, GLenum mode )
-{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- if (mode == GL_FRONT_LEFT) {
- /* write to front buffer */
- xmesa->xm_buffer->buffer = xmesa->xm_buffer->frontbuffer;
- xmesa_update_span_funcs(ctx);
- return GL_TRUE;
- }
- else if (mode==GL_BACK_LEFT && xmesa->xm_buffer->db_state) {
- /* write to back buffer */
- if (xmesa->xm_buffer->backpixmap) {
- xmesa->xm_buffer->buffer =
- (XMesaDrawable)xmesa->xm_buffer->backpixmap;
- }
- else if (xmesa->xm_buffer->backimage) {
- xmesa->xm_buffer->buffer = None;
- }
- else {
- /* just in case there wasn't enough memory for back buffer */
- xmesa->xm_buffer->buffer = xmesa->xm_buffer->frontbuffer;
- }
- xmesa_update_span_funcs(ctx);
- return GL_TRUE;
- }
- else {
- return GL_FALSE;
- }
-}
-
+/*
+ * This chooses the color buffer for reading and writing spans, points,
+ * lines, and triangles.
+ */
static void
-set_read_buffer( GLcontext *ctx, GLframebuffer *buffer, GLenum mode )
+set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
{
- XMesaBuffer target;
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ /* We can make this cast since the XMesaBuffer wraps GLframebuffer.
+ * GLframebuffer is the first member in a XMesaBuffer struct.
+ */
+ XMesaBuffer target = (XMesaBuffer) buffer;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
- if (buffer == ctx->DrawBuffer) {
- target = xmesa->xm_buffer;
- xmesa->use_read_buffer = GL_FALSE;
- }
- else {
- ASSERT(buffer == ctx->ReadBuffer);
- target = xmesa->xm_read_buffer;
- xmesa->use_read_buffer = GL_TRUE;
- }
+ /* This assignment tells the span/point/line/triangle functions
+ * which XMesaBuffer to use.
+ */
+ xmesa->xm_buffer = target;
- if (mode == GL_FRONT_LEFT) {
+ /*
+ * Now determine front vs back color buffer.
+ */
+ if (bufferBit == FRONT_LEFT_BIT) {
target->buffer = target->frontbuffer;
- xmesa_update_span_funcs(ctx);
}
- else if (mode==GL_BACK_LEFT && xmesa->xm_read_buffer->db_state) {
+ else if (bufferBit == BACK_LEFT_BIT) {
+ ASSERT(target->db_state);
if (target->backpixmap) {
- target->buffer = (XMesaDrawable)xmesa->xm_buffer->backpixmap;
+ /* back buffer is a pixmape */
+ target->buffer = target->backpixmap; /* incompatible types? */
}
else if (target->backimage) {
+ /* back buffer is an XImage */
target->buffer = None;
}
else {
- /* just in case there wasn't enough memory for back buffer */
+ /* No back buffer!!!! Must be out of memory, use front buffer */
target->buffer = target->frontbuffer;
}
- xmesa_update_span_funcs(ctx);
}
else {
- gl_problem(ctx, "invalid buffer in set_read_buffer() in xmesa2.c");
+ _mesa_problem(ctx, "invalid buffer 0x%x in set_buffer() in xm_dd.c");
+ return;
}
+ xmesa_update_span_funcs(ctx);
}
static void
clear_index( GLcontext *ctx, GLuint index )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
xmesa->clearpixel = (unsigned long) index;
- XMesaSetForeground( xmesa->display, xmesa->xm_buffer->cleargc,
+ XMesaSetForeground( xmesa->display, xmesa->xm_draw_buffer->cleargc,
(unsigned long) index );
}
static void
-clear_color( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
+clear_color( GLcontext *ctx, const GLfloat color[4] )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- xmesa->clearcolor[0] = r;
- xmesa->clearcolor[1] = g;
- xmesa->clearcolor[2] = b;
- xmesa->clearcolor[3] = a;
- xmesa->clearpixel = xmesa_color_to_pixel( xmesa, r, g, b, a,
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
+ CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]);
+ xmesa->clearpixel = xmesa_color_to_pixel( xmesa,
+ xmesa->clearcolor[0],
+ xmesa->clearcolor[1],
+ xmesa->clearcolor[2],
+ xmesa->clearcolor[3],
xmesa->xm_visual->undithered_pf );
_glthread_LOCK_MUTEX(_xmesa_lock);
- XMesaSetForeground( xmesa->display, xmesa->xm_buffer->cleargc,
+ XMesaSetForeground( xmesa->display, xmesa->xm_draw_buffer->cleargc,
xmesa->clearpixel );
_glthread_UNLOCK_MUTEX(_xmesa_lock);
}
-/* Set current color index */
-static void
-set_index( GLcontext *ctx, GLuint index )
-{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- unsigned long p = (unsigned long) index;
- xmesa->pixel = p;
- XMesaSetForeground( xmesa->display, xmesa->xm_buffer->gc1, p );
-}
-
-
-
-/* Set current drawing color */
-static void
-set_color( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
-{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- xmesa->red = r;
- xmesa->green = g;
- xmesa->blue = b;
- xmesa->alpha = a;
- xmesa->pixel = xmesa_color_to_pixel( xmesa, r, g, b, a, xmesa->pixelformat );;
- XMesaSetForeground( xmesa->display, xmesa->xm_buffer->gc1, xmesa->pixel );
-}
-
-
-
/* Set index mask ala glIndexMask */
static void
index_mask( GLcontext *ctx, GLuint mask )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- if (xmesa->xm_buffer->buffer != XIMAGE) {
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
+ if (xmesa->xm_draw_buffer->buffer != XIMAGE) {
unsigned long m;
if (mask==0xffffffff) {
m = ((unsigned long)~0L);
else {
m = (unsigned long) mask;
}
- XMesaSetPlaneMask( xmesa->display, xmesa->xm_buffer->cleargc, m );
+ XMesaSetPlaneMask( xmesa->display, xmesa->xm_draw_buffer->cleargc, m );
+ XMesaSetPlaneMask( xmesa->display, xmesa->xm_draw_buffer->gc, m );
}
}
color_mask(GLcontext *ctx,
GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask)
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
int xclass = GET_VISUAL_CLASS(xmesa->xm_visual);
(void) amask;
- if (xmesa->xm_buffer->buffer != XIMAGE
- && (xclass == TrueColor || xclass == DirectColor)) {
+ if (xclass == TrueColor || xclass == DirectColor) {
unsigned long m;
if (rmask && gmask && bmask) {
m = ((unsigned long)~0L);
if (gmask) m |= GET_GREENMASK(xmesa->xm_visual);
if (bmask) m |= GET_BLUEMASK(xmesa->xm_visual);
}
- XMesaSetPlaneMask( xmesa->display, xmesa->xm_buffer->cleargc, m );
- }
-}
-
-
-/*
- * Enable/disable dithering
- */
-static void
-dither( GLcontext *ctx, GLboolean enable )
-{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- if (enable) {
- xmesa->pixelformat = xmesa->xm_visual->dithered_pf;
- }
- else {
- xmesa->pixelformat = xmesa->xm_visual->undithered_pf;
+ XMesaSetPlaneMask( xmesa->display, xmesa->xm_draw_buffer->cleargc, m );
+ XMesaSetPlaneMask( xmesa->display, xmesa->xm_draw_buffer->gc, m );
}
}
clear_front_pixmap( GLcontext *ctx, GLboolean all,
GLint x, GLint y, GLint width, GLint height )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
if (all) {
- XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->frontbuffer,
- xmesa->xm_buffer->cleargc,
+ XMesaFillRectangle( xmesa->display, xmesa->xm_draw_buffer->frontbuffer,
+ xmesa->xm_draw_buffer->cleargc,
0, 0,
- xmesa->xm_buffer->width+1,
- xmesa->xm_buffer->height+1 );
+ xmesa->xm_draw_buffer->width+1,
+ xmesa->xm_draw_buffer->height+1 );
}
else {
- XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->frontbuffer,
- xmesa->xm_buffer->cleargc,
- x, xmesa->xm_buffer->height - y - height,
+ XMesaFillRectangle( xmesa->display, xmesa->xm_draw_buffer->frontbuffer,
+ xmesa->xm_draw_buffer->cleargc,
+ x, xmesa->xm_draw_buffer->height - y - height,
width, height );
}
}
clear_back_pixmap( GLcontext *ctx, GLboolean all,
GLint x, GLint y, GLint width, GLint height )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
if (all) {
- XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->backpixmap,
- xmesa->xm_buffer->cleargc,
+ XMesaFillRectangle( xmesa->display, xmesa->xm_draw_buffer->backpixmap,
+ xmesa->xm_draw_buffer->cleargc,
0, 0,
- xmesa->xm_buffer->width+1,
- xmesa->xm_buffer->height+1 );
+ xmesa->xm_draw_buffer->width+1,
+ xmesa->xm_draw_buffer->height+1 );
}
else {
- XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->backpixmap,
- xmesa->xm_buffer->cleargc,
- x, xmesa->xm_buffer->height - y - height,
+ XMesaFillRectangle( xmesa->display, xmesa->xm_draw_buffer->backpixmap,
+ xmesa->xm_draw_buffer->cleargc,
+ x, xmesa->xm_draw_buffer->height - y - height,
width, height );
}
}
clear_8bit_ximage( GLcontext *ctx, GLboolean all,
GLint x, GLint y, GLint width, GLint height )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
if (all) {
- size_t n = xmesa->xm_buffer->backimage->bytes_per_line
- * xmesa->xm_buffer->backimage->height;
- MEMSET( xmesa->xm_buffer->backimage->data, xmesa->clearpixel, n );
+ size_t n = xmesa->xm_draw_buffer->backimage->bytes_per_line
+ * xmesa->xm_draw_buffer->backimage->height;
+ MEMSET( xmesa->xm_draw_buffer->backimage->data, xmesa->clearpixel, n );
}
else {
GLint i;
for (i=0;i<height;i++) {
- GLubyte *ptr = PIXELADDR1( xmesa->xm_buffer, x, y+i );
+ GLubyte *ptr = PIXELADDR1( xmesa->xm_draw_buffer, x, y+i );
MEMSET( ptr, xmesa->clearpixel, width );
}
}
clear_HPCR_ximage( GLcontext *ctx, GLboolean all,
GLint x, GLint y, GLint width, GLint height )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
if (all) {
- GLint i, c16 = (xmesa->xm_buffer->backimage->bytes_per_line>>4)<<4;
- GLubyte *ptr = (GLubyte *)xmesa->xm_buffer->backimage->data;
- for (i=0; i<xmesa->xm_buffer->backimage->height; i++) {
+ GLint i, c16 = (xmesa->xm_draw_buffer->backimage->bytes_per_line>>4)<<4;
+ GLubyte *ptr = (GLubyte *)xmesa->xm_draw_buffer->backimage->data;
+ for (i=0; i<xmesa->xm_draw_buffer->backimage->height; i++) {
GLint j;
GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0];
if (i&1) {
ptr[15] = sptr[15];
ptr += 16;
}
- for (; j<xmesa->xm_buffer->backimage->bytes_per_line; j++) {
+ for (; j<xmesa->xm_draw_buffer->backimage->bytes_per_line; j++) {
*ptr = sptr[j&15];
ptr++;
}
else {
GLint i;
for (i=y; i<y+height; i++) {
- GLubyte *ptr = PIXELADDR1( xmesa->xm_buffer, x, i );
+ GLubyte *ptr = PIXELADDR1( xmesa->xm_draw_buffer, x, i );
int j;
GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0];
if (i&1) {
clear_16bit_ximage( GLcontext *ctx, GLboolean all,
GLint x, GLint y, GLint width, GLint height )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
register GLuint pixel = (GLuint) xmesa->clearpixel;
if (xmesa->swapbytes) {
pixel = ((pixel >> 8) & 0x00ff) | ((pixel << 8) & 0xff00);
}
if (all) {
register GLuint n;
- register GLuint *ptr4 = (GLuint *) xmesa->xm_buffer->backimage->data;
+ register GLuint *ptr4 = (GLuint *) xmesa->xm_draw_buffer->backimage->data;
if ((pixel & 0xff) == ((pixel >> 8) & 0xff)) {
/* low and high bytes are equal so use memset() */
- n = xmesa->xm_buffer->backimage->bytes_per_line
- * xmesa->xm_buffer->height;
+ n = xmesa->xm_draw_buffer->backimage->bytes_per_line
+ * xmesa->xm_draw_buffer->height;
MEMSET( ptr4, pixel & 0xff, n );
}
else {
pixel = pixel | (pixel<<16);
- n = xmesa->xm_buffer->backimage->bytes_per_line
- * xmesa->xm_buffer->height / 4;
+ n = xmesa->xm_draw_buffer->backimage->bytes_per_line
+ * xmesa->xm_draw_buffer->height / 4;
do {
*ptr4++ = pixel;
n--;
} while (n!=0);
-
- if ((xmesa->xm_buffer->backimage->bytes_per_line *
- xmesa->xm_buffer->height) & 0x2)
+
+ if ((xmesa->xm_draw_buffer->backimage->bytes_per_line *
+ xmesa->xm_draw_buffer->height) & 0x2)
*(GLushort *)ptr4 = pixel & 0xffff;
}
}
else {
register int i, j;
for (j=0;j<height;j++) {
- register GLushort *ptr2 = PIXELADDR2( xmesa->xm_buffer, x, y+j );
+ register GLushort *ptr2 = PIXELADDR2( xmesa->xm_draw_buffer, x, y+j );
for (i=0;i<width;i++) {
*ptr2++ = pixel;
}
clear_24bit_ximage( GLcontext *ctx, GLboolean all,
GLint x, GLint y, GLint width, GLint height )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
const GLubyte r = xmesa->clearcolor[0];
const GLubyte g = xmesa->clearcolor[1];
const GLubyte b = xmesa->clearcolor[2];
if (all) {
if (r==g && g==b) {
/* same value for all three components (gray) */
- const GLint w3 = xmesa->xm_buffer->width * 3;
- const GLint h = xmesa->xm_buffer->height;
+ const GLint w3 = xmesa->xm_draw_buffer->width * 3;
+ const GLint h = xmesa->xm_draw_buffer->height;
GLint i;
for (i = 0; i < h; i++) {
- bgr_t *ptr3 = PIXELADDR3(xmesa->xm_buffer, 0, i);
+ bgr_t *ptr3 = PIXELADDR3(xmesa->xm_draw_buffer, 0, i);
MEMSET(ptr3, r, w3);
}
}
else {
/* the usual case */
- const GLint w = xmesa->xm_buffer->width;
- const GLint h = xmesa->xm_buffer->height;
+ const GLint w = xmesa->xm_draw_buffer->width;
+ const GLint h = xmesa->xm_draw_buffer->height;
GLint i, j;
for (i = 0; i < h; i++) {
- bgr_t *ptr3 = PIXELADDR3(xmesa->xm_buffer, 0, i);
+ bgr_t *ptr3 = PIXELADDR3(xmesa->xm_draw_buffer, 0, i);
for (j = 0; j < w; j++) {
ptr3->r = r;
ptr3->g = g;
/* same value for all three components (gray) */
GLint j;
for (j=0;j<height;j++) {
- bgr_t *ptr3 = PIXELADDR3( xmesa->xm_buffer, x, y+j );
+ bgr_t *ptr3 = PIXELADDR3( xmesa->xm_draw_buffer, x, y+j );
MEMSET(ptr3, r, 3 * width);
}
}
/* non-gray clear color */
GLint i, j;
for (j = 0; j < height; j++) {
- bgr_t *ptr3 = PIXELADDR3( xmesa->xm_buffer, x, y+j );
+ bgr_t *ptr3 = PIXELADDR3( xmesa->xm_draw_buffer, x, y+j );
for (i = 0; i < width; i++) {
ptr3->r = r;
ptr3->g = g;
pixel4[1] = (clearPixel << 16) | (clearPixel >> 8);
pixel4[2] = (clearPixel << 8) | (clearPixel >> 16);
for (j=0;j<height;j++) {
- bgr_t *ptr3 = PIXELADDR3( xmesa->xm_buffer, x, y+j );
+ bgr_t *ptr3 = PIXELADDR3( xmesa->xm_draw_buffer, x, y+j );
register GLuint *ptr4 = (GLuint *)ptr3;
register GLuint *p, px;
GLuint w = width;
clear_32bit_ximage( GLcontext *ctx, GLboolean all,
GLint x, GLint y, GLint width, GLint height )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- if (all) {
- register GLint n = xmesa->xm_buffer->width * xmesa->xm_buffer->height;
- register GLuint *ptr4 = (GLuint *) xmesa->xm_buffer->backimage->data;
- register GLuint pixel = (GLuint) xmesa->clearpixel;
- if (xmesa->swapbytes) {
- pixel = ((pixel >> 24) & 0x000000ff)
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
+ register GLuint pixel = (GLuint) xmesa->clearpixel;
+ if (xmesa->swapbytes) {
+ pixel = ((pixel >> 24) & 0x000000ff)
| ((pixel >> 8) & 0x0000ff00)
| ((pixel << 8) & 0x00ff0000)
| ((pixel << 24) & 0xff000000);
- }
+ }
+ if (all) {
+ register GLint n = xmesa->xm_draw_buffer->width * xmesa->xm_draw_buffer->height;
+ register GLuint *ptr4 = (GLuint *) xmesa->xm_draw_buffer->backimage->data;
if (pixel==0) {
MEMSET( ptr4, pixel, 4*n );
}
}
else {
register int i, j;
- register GLuint pixel = (GLuint) xmesa->clearpixel;
for (j=0;j<height;j++) {
- register GLuint *ptr4 = PIXELADDR4( xmesa->xm_buffer, x, y+j );
+ register GLuint *ptr4 = PIXELADDR4( xmesa->xm_draw_buffer, x, y+j );
for (i=0;i<width;i++) {
*ptr4++ = pixel;
}
clear_nbit_ximage( GLcontext *ctx, GLboolean all,
GLint x, GLint y, GLint width, GLint height )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- XMesaImage *img = xmesa->xm_buffer->backimage;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
+ XMesaImage *img = xmesa->xm_draw_buffer->backimage;
if (all) {
register int i, j;
- width = xmesa->xm_buffer->width;
- height = xmesa->xm_buffer->height;
+ width = xmesa->xm_draw_buffer->width;
+ height = xmesa->xm_draw_buffer->height;
for (j=0;j<height;j++) {
for (i=0;i<width;i++) {
XMesaPutPixel( img, i, j, xmesa->clearpixel );
else {
/* TODO: optimize this */
register int i, j;
- y = FLIP(xmesa->xm_buffer, y);
+ y = FLIP(xmesa->xm_draw_buffer, y);
for (j=0;j<height;j++) {
for (i=0;i<width;i++) {
XMesaPutPixel( img, x+i, y-j, xmesa->clearpixel );
-static GLbitfield
+static void
clear_buffers( GLcontext *ctx, GLbitfield mask,
GLboolean all, GLint x, GLint y, GLint width, GLint height )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
- /* we can't handle color or index masking */
- if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) {
- if (*colorMask != 0xffffffff || ctx->Color.IndexMask != 0xffffffff)
- return mask;
+ if ((mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) &&
+ xmesa->xm_draw_buffer->mesa_buffer.UseSoftwareAlphaBuffers &&
+ ctx->Color.ColorMask[ACOMP]) {
+ _swrast_clear_alpha_buffers(ctx);
}
- if (mask & DD_FRONT_LEFT_BIT) {
- ASSERT(xmesa->xm_buffer->front_clear_func);
- (*xmesa->xm_buffer->front_clear_func)( ctx, all, x, y, width, height );
- }
- if (mask & DD_BACK_LEFT_BIT) {
- ASSERT(xmesa->xm_buffer->back_clear_func);
- (*xmesa->xm_buffer->back_clear_func)( ctx, all, x, y, width, height );
+ /* we can't handle color or index masking */
+ if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
+ if (mask & DD_FRONT_LEFT_BIT) {
+ ASSERT(xmesa->xm_draw_buffer->front_clear_func);
+ (*xmesa->xm_draw_buffer->front_clear_func)( ctx, all, x, y, width, height );
+ mask &= ~DD_FRONT_LEFT_BIT;
+ }
+ if (mask & DD_BACK_LEFT_BIT) {
+ ASSERT(xmesa->xm_draw_buffer->back_clear_func);
+ (*xmesa->xm_draw_buffer->back_clear_func)( ctx, all, x, y, width, height );
+ mask &= ~DD_BACK_LEFT_BIT;
+ }
}
- return mask & (~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT));
+
+ if (mask)
+ _swrast_Clear( ctx, mask, all, x, y, width, height );
}
+/*
+ * When we detect that the user has resized the window this function will
+ * get called. Here we'll reallocate the back buffer, depth buffer,
+ * stencil buffer etc. to match the new window size.
+ */
+void
+xmesa_resize_buffers( GLframebuffer *buffer )
+{
+ int height = (int) buffer->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;
+
+ xmBuffer->width = buffer->Width;
+ xmBuffer->height = buffer->Height;
+ xmesa_alloc_back_buffer( xmBuffer );
+
+ /* Needed by FLIP macro */
+ xmBuffer->bottom = height - 1;
+
+ if (xmBuffer->backimage) {
+ /* Needed by PIXELADDR1 macro */
+ xmBuffer->ximage_width1 = xmBuffer->backimage->bytes_per_line;
+ xmBuffer->ximage_origin1 = (GLubyte *) xmBuffer->backimage->data
+ + xmBuffer->ximage_width1 * (height-1);
+
+ /* Needed by PIXELADDR2 macro */
+ xmBuffer->ximage_width2 = xmBuffer->backimage->bytes_per_line / 2;
+ xmBuffer->ximage_origin2 = (GLushort *) xmBuffer->backimage->data
+ + xmBuffer->ximage_width2 * (height-1);
+
+ /* Needed by PIXELADDR3 macro */
+ xmBuffer->ximage_width3 = xmBuffer->backimage->bytes_per_line;
+ xmBuffer->ximage_origin3 = (GLubyte *) xmBuffer->backimage->data
+ + xmBuffer->ximage_width3 * (height-1);
-#ifndef XFree86Server
+ /* Needed by PIXELADDR4 macro */
+ xmBuffer->ximage_width4 = xmBuffer->backimage->width;
+ xmBuffer->ximage_origin4 = (GLuint *) xmBuffer->backimage->data
+ + xmBuffer->ximage_width4 * (height-1);
+ }
+
+ _swrast_alloc_buffers( buffer );
+}
+
+#if 0
/*
* This function implements glDrawPixels() with an XPutImage call when
* drawing to the front buffer (X Window drawable).
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
- const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
XMesaDisplay *dpy = xmesa->xm_visual->display;
- XMesaDrawable buffer = xmesa->xm_buffer->buffer;
- XMesaGC gc = xmesa->xm_buffer->gc1;
+ XMesaDrawable buffer = xmesa->xm_draw_buffer->buffer;
+ XMesaGC gc = xmesa->xm_draw_buffer->gc;
assert(dpy);
assert(buffer);
assert(gc);
ximage.red_mask = 0xff0000;
ximage.green_mask = 0x00ff00;
ximage.blue_mask = 0x0000ff;
- dstY = FLIP(xmesa->xm_buffer,dstY) - height + 1;
+ dstY = FLIP(xmesa->xm_draw_buffer,dstY) - height + 1;
XPutImage(dpy, buffer, gc, &ximage, srcX, srcY, dstX, dstY, w, h);
return GL_TRUE;
}
#endif
case GL_VENDOR:
#ifdef XFree86Server
- return (const GLubyte *) "VA Linux Systems, Inc.";
+ return (const GLubyte *) "Mesa project: www.mesa3d.org";
#else
return NULL;
#endif
}
-/*
- * Initialize all the DD.* function pointers depending on the color
- * buffer configuration. This is mainly called by XMesaMakeCurrent.
- */
-void
-xmesa_update_state( GLcontext *ctx )
+static void
+enable( GLcontext *ctx, GLenum pname, GLboolean state )
{
- XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- /*int depth=GET_VISUAL_DEPTH(xmesa->xm_visual);*/
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
+
+ switch (pname) {
+ case GL_DITHER:
+ if (state)
+ xmesa->pixelformat = xmesa->xm_visual->dithered_pf;
+ else
+ xmesa->pixelformat = xmesa->xm_visual->undithered_pf;
+ break;
+ default:
+ ; /* silence compiler warning */
+ }
+}
- (void) DitherValues; /* silenced unused var warning */
-#ifndef XFree86Server
- (void) drawpixels_8R8G8B;
-#endif
- /*
- * Always the same:
+void xmesa_update_state( GLcontext *ctx, GLuint new_state )
+{
+ const XMesaContext xmesa = XMESA_CONTEXT(ctx);
+
+ /* Propogate statechange information to swrast and swrast_setup
+ * modules. The X11 driver has no internal GL-dependent state.
*/
+ _swrast_InvalidateState( ctx, new_state );
+ _ac_InvalidateState( ctx, new_state );
+ _tnl_InvalidateState( ctx, new_state );
+ _swsetup_InvalidateState( ctx, new_state );
+
+
+ /* setup pointers to front and back buffer clear functions */
+ xmesa->xm_draw_buffer->front_clear_func = clear_front_pixmap;
+ if (xmesa->xm_draw_buffer->backpixmap != XIMAGE) {
+ xmesa->xm_draw_buffer->back_clear_func = clear_back_pixmap;
+ }
+ else if (sizeof(GLushort)!=2 || sizeof(GLuint)!=4) {
+ xmesa->xm_draw_buffer->back_clear_func = clear_nbit_ximage;
+ }
+ else switch (xmesa->xm_visual->BitsPerPixel) {
+ case 8:
+ if (xmesa->xm_visual->hpcr_clear_flag) {
+ xmesa->xm_draw_buffer->back_clear_func = clear_HPCR_ximage;
+ }
+ else {
+ xmesa->xm_draw_buffer->back_clear_func = clear_8bit_ximage;
+ }
+ break;
+ case 16:
+ xmesa->xm_draw_buffer->back_clear_func = clear_16bit_ximage;
+ break;
+ case 24:
+ xmesa->xm_draw_buffer->back_clear_func = clear_24bit_ximage;
+ break;
+ case 32:
+ xmesa->xm_draw_buffer->back_clear_func = clear_32bit_ximage;
+ break;
+ default:
+ xmesa->xm_draw_buffer->back_clear_func = clear_nbit_ximage;
+ break;
+ }
+
+ xmesa_update_span_funcs(ctx);
+}
+
+
+
+/**
+ * Called via ctx->Driver.TestProxyTeximage(). Normally, we'd just use
+ * the _mesa_test_proxy_teximage() fallback function, but we're going to
+ * special-case the 3D texture case to allow textures up to 512x512x32
+ * texels.
+ */
+static GLboolean
+test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat, GLenum format, GLenum type,
+ GLint width, GLint height, GLint depth, GLint border)
+{
+ if (target == GL_PROXY_TEXTURE_3D) {
+ /* special case for 3D textures */
+ if (width * height * depth > 512 * 512 * 64 ||
+ width < 2 * border || _mesa_bitcount(width - 2 * border) != 1 ||
+ height < 2 * border || _mesa_bitcount(height - 2 * border) != 1 ||
+ depth < 2 * border || _mesa_bitcount(depth - 2 * border) != 1) {
+ /* Bad size, or too many texels */
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+ }
+ else {
+ /* use the fallback routine for 1D, 2D, cube and rect targets */
+ return _mesa_test_proxy_teximage(ctx, target, level, internalFormat,
+ format, type, width, height, depth,
+ border);
+ }
+}
+
+
+
+
+/* Setup pointers and other driver state that is constant for the life
+ * of a context.
+ */
+void xmesa_init_pointers( GLcontext *ctx )
+{
+ TNLcontext *tnl;
+ struct swrast_device_driver *dd = _swrast_GetDeviceDriverReference( ctx );
+
ctx->Driver.GetString = get_string;
- ctx->Driver.UpdateState = xmesa_update_state;
ctx->Driver.GetBufferSize = get_buffer_size;
ctx->Driver.Flush = flush;
ctx->Driver.Finish = finish;
-
- ctx->Driver.RenderStart = 0;
- ctx->Driver.RenderFinish = 0;
+
+ /* Software rasterizer pixel paths:
+ */
+ ctx->Driver.Accum = _swrast_Accum;
+ ctx->Driver.Bitmap = _swrast_Bitmap;
+ ctx->Driver.Clear = clear_buffers;
+ ctx->Driver.ResizeBuffers = xmesa_resize_buffers;
+ ctx->Driver.CopyPixels = _swrast_CopyPixels;
+ ctx->Driver.DrawPixels = _swrast_DrawPixels;
+ ctx->Driver.ReadPixels = _swrast_ReadPixels;
+ ctx->Driver.DrawBuffer = _swrast_DrawBuffer;
- ctx->Driver.SetDrawBuffer = set_draw_buffer;
- ctx->Driver.SetReadBuffer = set_read_buffer;
+ /* Software texture functions:
+ */
+ ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
+ ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+ ctx->Driver.TexImage2D = _mesa_store_teximage2d;
+ ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+ ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
+ ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
+ ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+ ctx->Driver.TestProxyTexImage = test_proxy_teximage;
+
+ ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
+ ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
+ ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+ ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+ ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+
+ ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
+ ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
+ ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
+ ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
+ ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
+ ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
+
+ /* Swrast hooks for imaging extensions:
+ */
+ ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+ ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+ ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+ ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
- ctx->Driver.Index = set_index;
- ctx->Driver.Color = set_color;
+
+ /* Statechange callbacks:
+ */
ctx->Driver.ClearIndex = clear_index;
ctx->Driver.ClearColor = clear_color;
- ctx->Driver.Clear = clear_buffers;
ctx->Driver.IndexMask = index_mask;
ctx->Driver.ColorMask = color_mask;
- ctx->Driver.Dither = dither;
+ ctx->Driver.Enable = enable;
- ctx->Driver.PointsFunc = xmesa_get_points_func( ctx );
- ctx->Driver.LineFunc = xmesa_get_line_func( ctx );
- ctx->Driver.TriangleFunc = xmesa_get_triangle_func( ctx );
-/* ctx->Driver.TriangleCaps = DD_TRI_CULL; */
+ /* Initialize the TNL driver interface:
+ */
+ tnl = TNL_CONTEXT(ctx);
+ tnl->Driver.RunPipeline = _tnl_run_pipeline;
+
+ dd->SetBuffer = set_buffer;
- /* setup pointers to front and back buffer clear functions */
- /* XXX this bit of code could be moved to a one-time init */
- xmesa->xm_buffer->front_clear_func = clear_front_pixmap;
- if (xmesa->xm_buffer->backpixmap != XIMAGE) {
- /* back buffer is a pixmap */
- xmesa->xm_buffer->back_clear_func = clear_back_pixmap;
- }
- else if (sizeof(GLushort)!=2 || sizeof(GLuint)!=4) {
- /* Do this on Crays */
- xmesa->xm_buffer->back_clear_func = clear_nbit_ximage;
- }
- else {
- /* Do this on most machines */
- switch (xmesa->xm_visual->BitsPerPixel) {
- case 8:
- if (xmesa->xm_visual->hpcr_clear_flag) {
- xmesa->xm_buffer->back_clear_func = clear_HPCR_ximage;
- }
- else {
- xmesa->xm_buffer->back_clear_func = clear_8bit_ximage;
- }
- break;
- case 16:
- xmesa->xm_buffer->back_clear_func = clear_16bit_ximage;
- break;
- case 24:
- xmesa->xm_buffer->back_clear_func = clear_24bit_ximage;
- break;
- case 32:
- xmesa->xm_buffer->back_clear_func = clear_32bit_ximage;
- break;
- default:
- xmesa->xm_buffer->back_clear_func = clear_nbit_ximage;
- break;
- }
- }
+ /* Install swsetup for tnl->Driver.Render.*:
+ */
+ _swsetup_Wakeup(ctx);
- xmesa_update_span_funcs(ctx);
+ (void) DitherValues; /* silenced unused var warning */
+}
+
+
+
+
+
+#define XMESA_NEW_POINT (_NEW_POINT | \
+ _NEW_RENDERMODE | \
+ _SWRAST_NEW_RASTERMASK)
+
+#define XMESA_NEW_LINE (_NEW_LINE | \
+ _NEW_TEXTURE | \
+ _NEW_LIGHT | \
+ _NEW_DEPTH | \
+ _NEW_RENDERMODE | \
+ _SWRAST_NEW_RASTERMASK)
+
+#define XMESA_NEW_TRIANGLE (_NEW_POLYGON | \
+ _NEW_TEXTURE | \
+ _NEW_LIGHT | \
+ _NEW_DEPTH | \
+ _NEW_RENDERMODE | \
+ _SWRAST_NEW_RASTERMASK)
+
+
+/* Extend the software rasterizer with our line/point/triangle
+ * functions.
+ */
+void xmesa_register_swrast_functions( GLcontext *ctx )
+{
+ SWcontext *swrast = SWRAST_CONTEXT( ctx );
+
+ swrast->choose_point = xmesa_choose_point;
+ swrast->choose_line = xmesa_choose_line;
+ swrast->choose_triangle = xmesa_choose_triangle;
+
+ swrast->invalidate_point |= XMESA_NEW_POINT;
+ swrast->invalidate_line |= XMESA_NEW_LINE;
+ swrast->invalidate_triangle |= XMESA_NEW_TRIANGLE;
}