further simplification of thread-related code, misc clean-up

This commit is contained in:
Brian Paul 1999-12-17 14:52:35 +00:00
parent 8f91fb630c
commit 0003778847
2 changed files with 213 additions and 227 deletions

View file

@ -1,4 +1,4 @@
/* $Id: context.c,v 1.28 1999/12/17 12:21:38 brianp Exp $ */
/* $Id: context.c,v 1.29 1999/12/17 14:52:35 brianp Exp $ */
/*
* Mesa 3-D graphics library
@ -83,24 +83,11 @@
/**********************************************************************/
#ifdef THREADS
#if !defined(THREADS)
#include "glthread.h"
static _glthread_TSD ContextTSD;
static void ctx_thread_init()
{
_glthread_InitTSD(&ContextTSD);
}
#else
/* One Current Context pointer for all threads in the address space */
GLcontext *_mesa_current_context = NULL;
struct immediate *CURRENT_INPUT = NULL;
#endif /*THREADS*/
#endif
@ -1102,6 +1089,93 @@ void gl_destroy_visual( GLvisual *vis )
/*
* Create a new framebuffer. A GLframebuffer is a struct which
* encapsulates the depth, stencil and accum buffers and related
* parameters.
* Input: visual - a GLvisual pointer
* softwareDepth - create/use a software depth buffer?
* softwareStencil - create/use a software stencil buffer?
* softwareAccum - create/use a software accum buffer?
* softwareAlpha - create/use a software alpha buffer?
* Return: pointer to new GLframebuffer struct or NULL if error.
*/
GLframebuffer *gl_create_framebuffer( GLvisual *visual,
GLboolean softwareDepth,
GLboolean softwareStencil,
GLboolean softwareAccum,
GLboolean softwareAlpha )
{
GLframebuffer *buffer;
buffer = CALLOC_STRUCT(gl_frame_buffer);
if (!buffer) {
return NULL;
}
/* sanity checks */
if (softwareDepth ) {
assert(visual->DepthBits > 0);
}
if (softwareStencil) {
assert(visual->StencilBits > 0);
}
if (softwareAccum) {
assert(visual->RGBAflag);
assert(visual->AccumBits > 0);
}
if (softwareAlpha) {
assert(visual->RGBAflag);
assert(visual->AlphaBits > 0);
}
buffer->Visual = visual;
buffer->UseSoftwareDepthBuffer = softwareDepth;
buffer->UseSoftwareStencilBuffer = softwareStencil;
buffer->UseSoftwareAccumBuffer = softwareAccum;
buffer->UseSoftwareAlphaBuffers = softwareAlpha;
return buffer;
}
/*
* Free a framebuffer struct and its buffers.
*/
void gl_destroy_framebuffer( GLframebuffer *buffer )
{
if (buffer) {
if (buffer->Depth) {
FREE( buffer->Depth );
}
if (buffer->Accum) {
FREE( buffer->Accum );
}
if (buffer->Stencil) {
FREE( buffer->Stencil );
}
if (buffer->FrontLeftAlpha) {
FREE( buffer->FrontLeftAlpha );
}
if (buffer->BackLeftAlpha) {
FREE( buffer->BackLeftAlpha );
}
if (buffer->FrontRightAlpha) {
FREE( buffer->FrontRightAlpha );
}
if (buffer->BackRightAlpha) {
FREE( buffer->BackRightAlpha );
}
FREE(buffer);
}
}
/*
* Allocate the proxy textures. If we run out of memory part way through
* the allocations clean up and return GL_FALSE.
@ -1289,14 +1363,6 @@ GLcontext *gl_create_context( GLvisual *visual,
return ctx;
}
/* Just reads the config files...
*/
void gl_context_initialize( GLcontext *ctx )
{
gl_read_config_file( ctx );
}
/*
@ -1407,179 +1473,11 @@ void gl_destroy_context( GLcontext *ctx )
/*
* Create a new framebuffer. A GLframebuffer is a struct which
* encapsulates the depth, stencil and accum buffers and related
* parameters.
* Input: visual - a GLvisual pointer
* softwareDepth - create/use a software depth buffer?
* softwareStencil - create/use a software stencil buffer?
* softwareAccum - create/use a software accum buffer?
* softwareAlpha - create/use a software alpha buffer?
* Return: pointer to new GLframebuffer struct or NULL if error.
* Just reads the config files...
*/
GLframebuffer *gl_create_framebuffer( GLvisual *visual,
GLboolean softwareDepth,
GLboolean softwareStencil,
GLboolean softwareAccum,
GLboolean softwareAlpha )
void gl_context_initialize( GLcontext *ctx )
{
GLframebuffer *buffer;
buffer = CALLOC_STRUCT(gl_frame_buffer);
if (!buffer) {
return NULL;
}
/* sanity checks */
if (softwareDepth ) {
assert(visual->DepthBits > 0);
}
if (softwareStencil) {
assert(visual->StencilBits > 0);
}
if (softwareAccum) {
assert(visual->RGBAflag);
assert(visual->AccumBits > 0);
}
if (softwareAlpha) {
assert(visual->RGBAflag);
assert(visual->AlphaBits > 0);
}
buffer->Visual = visual;
buffer->UseSoftwareDepthBuffer = softwareDepth;
buffer->UseSoftwareStencilBuffer = softwareStencil;
buffer->UseSoftwareAccumBuffer = softwareAccum;
buffer->UseSoftwareAlphaBuffers = softwareAlpha;
return buffer;
}
/*
* Free a framebuffer struct and its buffers.
*/
void gl_destroy_framebuffer( GLframebuffer *buffer )
{
if (buffer) {
if (buffer->Depth) {
FREE( buffer->Depth );
}
if (buffer->Accum) {
FREE( buffer->Accum );
}
if (buffer->Stencil) {
FREE( buffer->Stencil );
}
if (buffer->FrontLeftAlpha) {
FREE( buffer->FrontLeftAlpha );
}
if (buffer->BackLeftAlpha) {
FREE( buffer->BackLeftAlpha );
}
if (buffer->FrontRightAlpha) {
FREE( buffer->FrontRightAlpha );
}
if (buffer->BackRightAlpha) {
FREE( buffer->BackRightAlpha );
}
FREE(buffer);
}
}
/*
* Set the current context, binding the given frame buffer to the context.
*/
void gl_make_current( GLcontext *newCtx, GLframebuffer *buffer )
{
gl_make_current2( newCtx, buffer, buffer );
}
/*
* Bind the given context to the given draw-buffer and read-buffer
* and make it the current context for this thread.
*/
void gl_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
GLframebuffer *readBuffer )
{
#if 0
GLcontext *oldCtx = gl_get_current_context();
/* Flush the old context
*/
if (oldCtx) {
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(oldCtx, "gl_make_current");
/* unbind frame buffers from context */
if (oldCtx->DrawBuffer) {
oldCtx->DrawBuffer = NULL;
}
if (oldCtx->ReadBuffer) {
oldCtx->ReadBuffer = NULL;
}
}
#endif
_glapi_check_multithread();
#ifdef THREADS
_glthread_SetTSD(&ContextTSD, (void *) newCtx, ctx_thread_init);
ASSERT(gl_get_current_context() == newCtx);
#else
_mesa_current_context = newCtx;
#endif
if (newCtx) {
SET_IMMEDIATE(newCtx, newCtx->input);
_glapi_set_dispatch(newCtx->CurrentDispatch);
}
else {
_glapi_set_dispatch(NULL); /* none current */
}
if (MESA_VERBOSE) fprintf(stderr, "gl_make_current()\n");
if (newCtx && drawBuffer && readBuffer) {
/* TODO: check if newCtx and buffer's visual match??? */
newCtx->DrawBuffer = drawBuffer;
newCtx->ReadBuffer = readBuffer;
newCtx->NewState = NEW_ALL; /* just to be safe */
gl_update_state( newCtx );
}
/* We can use this to help debug user's problems. Tell the to set
* the MESA_INFO env variable before running their app. Then the
* first time each context is made current we'll print some useful
* information.
*/
if (newCtx && newCtx->FirstTimeCurrent) {
if (getenv("MESA_INFO")) {
fprintf(stderr, "Mesa GL_VERSION = %s\n", (char *) _mesa_GetString(GL_VERSION));
fprintf(stderr, "Mesa GL_RENDERER = %s\n", (char *) _mesa_GetString(GL_RENDERER));
fprintf(stderr, "Mesa GL_VENDOR = %s\n", (char *) _mesa_GetString(GL_VENDOR));
fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", (char *) _mesa_GetString(GL_EXTENSIONS));
}
newCtx->FirstTimeCurrent = GL_FALSE;
}
}
/*
* Return current context handle for the calling thread.
*/
GLcontext *gl_get_current_context( void )
{
#ifdef THREADS
GLcontext *c = (GLcontext *) _glthread_GetTSD(&ContextTSD);
return c;
#else
return _mesa_current_context;
#endif
gl_read_config_file( ctx );
}
@ -1618,7 +1516,7 @@ void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
}
if (mask & GL_LIGHTING_BIT) {
MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) );
/* gl_reinit_light_attrib( &dst->Light ); */
/* gl_reinit_light_attrib( &dst->Light ); */
}
if (mask & GL_LINE_BIT) {
MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) );
@ -1662,6 +1560,95 @@ void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
}
/*
* Set the current context, binding the given frame buffer to the context.
*/
void gl_make_current( GLcontext *newCtx, GLframebuffer *buffer )
{
gl_make_current2( newCtx, buffer, buffer );
}
/*
* Bind the given context to the given draw-buffer and read-buffer
* and make it the current context for this thread.
*/
void gl_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
GLframebuffer *readBuffer )
{
#if 0
GLcontext *oldCtx = gl_get_current_context();
/* Flush the old context
*/
if (oldCtx) {
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(oldCtx, "gl_make_current");
/* unbind frame buffers from context */
if (oldCtx->DrawBuffer) {
oldCtx->DrawBuffer = NULL;
}
if (oldCtx->ReadBuffer) {
oldCtx->ReadBuffer = NULL;
}
}
#endif
/* We call this function periodically (just here for now) in
* order to detect when multithreading has begun.
*/
_glapi_check_multithread();
_glapi_set_current_context((void *) newCtx);
ASSERT(gl_get_current_context() == newCtx);
if (newCtx) {
SET_IMMEDIATE(newCtx, newCtx->input);
_glapi_set_dispatch(newCtx->CurrentDispatch);
}
else {
_glapi_set_dispatch(NULL); /* none current */
}
if (MESA_VERBOSE) fprintf(stderr, "gl_make_current()\n");
if (newCtx && drawBuffer && readBuffer) {
/* TODO: check if newCtx and buffer's visual match??? */
newCtx->DrawBuffer = drawBuffer;
newCtx->ReadBuffer = readBuffer;
newCtx->NewState = NEW_ALL; /* just to be safe */
gl_update_state( newCtx );
}
/* We can use this to help debug user's problems. Tell the to set
* the MESA_INFO env variable before running their app. Then the
* first time each context is made current we'll print some useful
* information.
*/
if (newCtx && newCtx->FirstTimeCurrent) {
if (getenv("MESA_INFO")) {
fprintf(stderr, "Mesa GL_VERSION = %s\n", (char *) _mesa_GetString(GL_VERSION));
fprintf(stderr, "Mesa GL_RENDERER = %s\n", (char *) _mesa_GetString(GL_RENDERER));
fprintf(stderr, "Mesa GL_VENDOR = %s\n", (char *) _mesa_GetString(GL_VENDOR));
fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", (char *) _mesa_GetString(GL_EXTENSIONS));
}
newCtx->FirstTimeCurrent = GL_FALSE;
}
}
/*
* Return current context handle for the calling thread.
* This isn't the fastest way to get the current context.
* If you need speed, see the GET_CURRENT_CONTEXT() macro in context.h
*/
GLcontext *gl_get_current_context( void )
{
return (GLcontext *) _glapi_get_current_context();
}
/*
* This should be called by device drivers just before they do a
* swapbuffers. Any pending rendering commands will be executed.
@ -1673,6 +1660,7 @@ _mesa_swapbuffers(GLcontext *ctx)
}
/*
* Return pointer to this context's current API dispatch table.
* It'll either be the immediate-mode execute dispatcher or the
@ -1689,7 +1677,7 @@ _mesa_get_dispatch(GLcontext *ctx)
void
_mesa_ResizeBuffersMESA( void )
{
GET_CURRENT_CONTEXT(ctx);
GLcontext *ctx = gl_get_current_context();
GLuint buf_width, buf_height;
@ -1712,15 +1700,12 @@ _mesa_ResizeBuffersMESA( void )
/* Reallocate other buffers if needed. */
if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
/* reallocate depth buffer */
gl_alloc_depth_buffer( ctx );
}
if (ctx->DrawBuffer->UseSoftwareStencilBuffer) {
/* reallocate stencil buffer */
gl_alloc_stencil_buffer( ctx );
}
if (ctx->DrawBuffer->UseSoftwareAccumBuffer) {
/* reallocate accum buffer */
gl_alloc_accum_buffer( ctx );
}
if (ctx->Visual->SoftwareAlpha) {

View file

@ -1,4 +1,4 @@
/* $Id: context.h,v 1.6 1999/12/17 12:21:39 brianp Exp $ */
/* $Id: context.h,v 1.7 1999/12/17 14:52:37 brianp Exp $ */
/*
* Mesa 3-D graphics library
@ -29,6 +29,7 @@
#define CONTEXT_H
#include "glapi.h"
#include "types.h"
@ -72,6 +73,21 @@ extern GLvisual *gl_create_visual( GLboolean rgbFlag,
extern void gl_destroy_visual( GLvisual *vis );
/*
* Create/destroy a GLframebuffer. A GLframebuffer is like a GLX drawable.
* It bundles up the depth buffer, stencil buffer and accum buffers into a
* single entity.
*/
extern GLframebuffer *gl_create_framebuffer( GLvisual *visual,
GLboolean softwareDepth,
GLboolean softwareStencil,
GLboolean softwareAccum,
GLboolean softwareAlpha );
extern void gl_destroy_framebuffer( GLframebuffer *buffer );
/*
* Create/destroy a GLcontext. A GLcontext is like a GLX context. It
* contains the rendering state.
@ -92,36 +108,24 @@ extern void gl_context_initialize( GLcontext *ctx );
extern void gl_copy_context(const GLcontext *src, GLcontext *dst, GLuint mask);
/*
* Create/destroy a GLframebuffer. A GLframebuffer is like a GLX drawable.
* It bundles up the depth buffer, stencil buffer and accum buffers into a
* single entity.
*/
extern GLframebuffer *gl_create_framebuffer( GLvisual *visual,
GLboolean softwareDepth,
GLboolean softwareStencil,
GLboolean softwareAccum,
GLboolean softwareAlpha );
extern void gl_destroy_framebuffer( GLframebuffer *buffer );
extern void gl_make_current( GLcontext *ctx, GLframebuffer *buffer );
extern void gl_make_current2( GLcontext *ctx, GLframebuffer *drawBuffer,
GLframebuffer *readBuffer );
extern GLcontext *gl_get_current_context(void);
/*
* Macros for fetching current context, input buffer, etc.
*/
#ifdef THREADS
/*
* A seperate GLcontext for each thread
*/
#define GET_CURRENT_CONTEXT(C) GLcontext *C = gl_get_current_context()
#define GET_IMMEDIATE struct immediate *IM = (gl_get_current_context())->input;
#define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) (_glapi_ThreadSafe ? _glapi_get_current_context() : _glapi_CurrentContext)
#define GET_IMMEDIATE struct immediate *IM = ((GLcontext *) _glapi_get_current_context())->input;
#define SET_IMMEDIATE(ctx, im) \
do { \
ctx->input = im; \
@ -129,12 +133,8 @@ do { \
#else
/*
* All threads use same pointer to current context.
*/
extern GLcontext *_mesa_current_context;
extern struct immediate *CURRENT_INPUT;
#define GET_CURRENT_CONTEXT(C) GLcontext *C = _mesa_current_context
#define GET_CURRENT_CONTEXT(C) GLcontext *C = _glapi_CurrentContext
#define GET_IMMEDIATE struct immediate *IM = CURRENT_INPUT
#define SET_IMMEDIATE(ctx, im) \
do { \
@ -149,6 +149,7 @@ do { \
extern void
_mesa_swapbuffers(GLcontext *ctx);
extern struct _glapi_table *
_mesa_get_dispatch(GLcontext *ctx);
@ -170,8 +171,8 @@ extern void gl_problem( const GLcontext *ctx, const char *s );
extern void gl_warning( const GLcontext *ctx, const char *s );
extern void gl_error( GLcontext *ctx, GLenum error, const char *s );
extern void gl_compile_error( GLcontext *ctx, GLenum error, const char *s );
extern void gl_compile_error( GLcontext *ctx, GLenum error, const char *s );
extern void gl_update_state( GLcontext *ctx );