#include <ggi/mesa/ggimesa_int.h>
#include <ggi/mesa/debug.h>
#include "extensions.h"
+#include "colormac.h"
#include "imports.h"
#include "matrix.h"
#include "swrast/swrast.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "array_cache/acache.h"
+#include "teximage.h"
#include "texformat.h"
#include "texstore.h"
-ggi_extid ggiMesaID = -1;
+/* We use LibGG to manage config files */
+#include <ggi/gg.h>
+
+
+/* XXX: Those #defines should be provided via
+ * config.h
+ */
+#define GGIMESAPATHTAG "pAtHTAg"
+#define GGIMESACONFDIR "pAtHTAg/usr/local/etc/ggi"
+#define GGIMESATAGLEN 7
+#define GGIMESACONFFILE "ggimesa.conf"
+
+
+/* Static variables
+ */
static int _ggimesaLibIsUp = 0;
static void *_ggimesaConfigHandle;
-
-static char ggimesaconffile[] = GGIMESACONFFILE;
+static char _ggimesaconfstub[512] = GGIMESACONFDIR;
+static char *_ggimesaconfdir = _ggimesaconfstub+GGIMESATAGLEN;
int _ggimesaDebugSync = 0;
uint32 _ggimesaDebugState = 0;
-static void gl_ggiUpdateState(GLcontext *ctx, GLuint new_state);
-static int changed(ggi_visual_t vis, int whatchanged);
+/* Extension ID. Defaulting to -1 should make segfault on abuse more likely...
+ */
+ggi_extid _ggiMesaID = -1;
+
+
+#define SUBLIB_PREFIX "MesaGGIdl_"
+
+
+/*
+ * Returns the directory where global config files are kept
+ */
+
+const char *ggiMesaGetConfDir(void)
+{
+#ifdef __WIN32__
+ /* On Win32 we allow overriding of the compiled in path. */
+ const char *envdir = getenv("GGI_CONFDIR");
+ if (envdir) return envdir;
+#endif
+ return _ggimesaconfdir;
+}
+
+
+/* Dummy function which returns -1
+ We use this to reset the function pointers */
static int _ggi_error(void)
{
GGIMESADPRINT_CORE("_ggi_error() called\n");
return -1;
}
+
+static int changed(ggi_visual_t vis, int whatchanged)
+{
+ GLcontext *ctx;
+ ctx = _mesa_get_current_context();
+
+ GGIMESADPRINT_CORE("changed() called\n");
+
+ switch (whatchanged) {
+ case GGI_CHG_APILIST:
+ {
+ char api[GGI_MAX_APILEN];
+ char args[GGI_MAX_APILEN];
+ int i;
+ const char *fname;
+ ggi_dlhandle *lib;
+
+ GLvisual *gl_vis = &(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual);
+ GLframebuffer *gl_fb = &(LIBGGI_MESAEXT(vis)->mesa_buffer);
+
+ /* Initialize the framebuffer to provide all necessary
+ buffers in software. The target libraries that are loaded
+ next are free to modify this according to their
+ capabilities.
+ */
+ /* FIXME: if the target changes capabilities we'll leak
+ swrast's memory !!! Need to deallocate first */
+ _mesa_initialize_framebuffer(gl_fb, gl_vis,
+ gl_vis->depthBits > 0,
+ gl_vis->stencilBits > 0,
+ gl_vis->accumRedBits > 0,
+ gl_vis->alphaBits > 0);
+
+ for (i = 0; ggiGetAPI(vis, i, api, args) == 0; i++) {
+ strcat(api, "-mesa");
+ GGIMESADPRINT_CORE("GGIMesa: looking for"
+ "a sublib named %s\n", api);
+ fname = ggMatchConfig(_ggimesaConfigHandle, api, NULL);
+ if (fname == NULL) {
+ /* No special implementation for this sublib */
+ continue;
+ }
+ lib = ggiExtensionLoadDL(vis, fname, args, NULL,
+ SUBLIB_PREFIX);
+ }
+
+ /* The targets have cleared everything they can do from
+ the framebuffer structure so we provide the rest in sw
+ */
+ _swrast_alloc_buffers(gl_fb);
+
+ break;
+ }
+ }
+ return 0;
+}
+
+
+int ggiMesaInit()
+{
+ int err;
+ char *str;
+ char *conffile;
+
+ GGIMESADPRINT_CORE("ggiMesaInit() called\n");
+
+ _ggimesaLibIsUp++;
+ if (_ggimesaLibIsUp > 1) return 0; /* Initialize only at first call */
+
+ str = getenv("GGIMESA_DEBUGSYNC");
+ if (str != NULL) {
+ _ggimesaDebugSync = 1;
+ }
+
+ str = getenv("GGIMESA_DEBUG");
+ if (str != NULL) {
+ _ggimesaDebugState = atoi(str);
+ GGIMESADPRINT_CORE("%s Debugging=%d\n",
+ _ggimesaDebugSync ? "sync" : "async",
+ _ggimesaDebugState);
+ }
+
+
+ conffile = malloc(strlen(ggiMesaGetConfDir()) + 1
+ + strlen(GGIMESACONFFILE) +1);
+ if (conffile == NULL) {
+ fprintf(stderr, "GGIMesa: unable to allocate memory for config filename.\n");
+ return GGI_ENOMEM;
+ }
+ sprintf(conffile, "%s%c%s",
+ ggiMesaGetConfDir(), '/', GGIMESACONFFILE);
+ err = ggLoadConfig(conffile, &_ggimesaConfigHandle);
+ if (err != GGI_OK) {
+ fprintf(stderr, "GGIMesa: Couldn't open %s\n",
+ conffile);
+ free(conffile);
+ _ggimesaLibIsUp--;
+ return err;
+ }
+ free(conffile);
+
+ _ggiMesaID = ggiExtensionRegister("GGIMesa",
+ sizeof(struct ggi_mesa_ext), changed);
+ if (_ggiMesaID < 0) {
+ fprintf(stderr, "GGIMesa: failed to register as extension\n");
+ _ggimesaLibIsUp--;
+ ggFreeConfig(_ggimesaConfigHandle);
+ return _ggiMesaID;
+ }
+
+ return 0;
+}
+
+int ggiMesaExit(void)
+{
+ int rc;
+
+ GGIMESADPRINT_CORE("ggiMesaExit() called\n");
+
+ if (!_ggimesaLibIsUp) return -1;
+
+ if (_ggimesaLibIsUp > 1) {
+ /* Exit only at last call */
+ _ggimesaLibIsUp--;
+ return 0;
+ }
+
+ rc = ggiExtensionUnregister(_ggiMesaID);
+ ggFreeConfig(_ggimesaConfigHandle);
+
+ _ggimesaLibIsUp = 0;
+
+ return rc;
+}
+
+
+
+
+static void gl_ggiUpdateState(GLcontext *ctx, GLuint new_state);
+
+
static void gl_ggiGetSize(GLframebuffer *fb, GLuint *width, GLuint *height)
{
/* FIXME: this is a hack to work around the new interface */
GGIMESADPRINT_CORE("gl_ggiGetSize() called\n");
- *width = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.x;
- *height = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y;
+ *width = LIBGGI_VIRTX(ggi_ctx->ggi_visual);
+ *height = LIBGGI_VIRTY(ggi_ctx->ggi_visual);
printf("returning %d, %d\n", *width, *height);
}
static void gl_ggiSetClearIndex(GLcontext *ctx, GLuint ci)
{
ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
-
+
GGIMESADPRINT_CORE("gl_ggiSetClearIndex() called\n");
-
+
ggiSetGCForeground(ggi_ctx->ggi_visual, ci);
ggi_ctx->clearcolor = (ggi_pixel)ci;
}
-static void gl_ggiSetClearColor(GLcontext *ctx, const GLchan color[4])
+static void gl_ggiSetClearColor(GLcontext *ctx, const GLfloat color[4])
{
ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
ggi_color rgb;
ggi_pixel col;
-
+ GLubyte byteColor[3];
+
GGIMESADPRINT_CORE("gl_ggiSetClearColor() called\n");
- rgb.r = (uint16)color[0] << SHIFT;
- rgb.g = (uint16)color[1] << SHIFT;
- rgb.b = (uint16)color[2] << SHIFT;
+ CLAMPED_FLOAT_TO_UBYTE(byteColor[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(byteColor[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(byteColor[2], color[2]);
+
+ rgb.r = (uint16)byteColor[0] << SHIFT;
+ rgb.g = (uint16)byteColor[1] << SHIFT;
+ rgb.b = (uint16)byteColor[2] << SHIFT;
col = ggiMapColor(ggi_ctx->ggi_visual, &rgb);
ggiSetGCForeground(ggi_ctx->ggi_visual, col);
ggi_ctx->clearcolor = col;
GGIMESADPRINT_CORE("gl_ggiClear() called\n");
- if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT))
- {
+ if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) {
ggiSetGCForeground(ggi_ctx->ggi_visual, ggi_ctx->clearcolor);
- if (all)
- {
+ if (all) {
int w, h;
- w = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.x;
- h = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y;
+ w = LIBGGI_VIRTX(ggi_ctx->ggi_visual);
+ h = LIBGGI_VIRTX(ggi_ctx->ggi_visual);
ggiDrawBox(ggi_ctx->ggi_visual, 0, 0, w, h);
- }
- else
- {
+ } else {
ggiDrawBox(ggi_ctx->ggi_visual, x, y, //FLIP(y),
width, height);
}
}
-/* Set the buffer used for drawing */
-static GLboolean gl_ggiSetDrawBuffer(GLcontext *ctx, GLenum mode)
-{
- ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
-
- printf("set draw %d\n", mode);
- GGIMESADPRINT_CORE("gl_ggiSetDrawBuffer() called\n");
-
- if (mode == GL_FRONT_LEFT)
- {
- ggiSetWriteFrame(ggi_ctx->ggi_visual,
- ggiGetDisplayFrame(ggi_ctx->ggi_visual));
- return GL_TRUE;
- }
- else if (mode == GL_BACK_LEFT)
- {
- ggiSetWriteFrame(ggi_ctx->ggi_visual,
- ggiGetDisplayFrame(ggi_ctx->ggi_visual)?0 : 1);
- return GL_TRUE;
- }
- else
- {
- return GL_FALSE;
- }
-}
-
/* Set the buffer used for reading */
/* XXX support for separate read/draw buffers hasn't been tested */
-static GLboolean gl_ggiSetReadBuffer(GLcontext *ctx, GLframebuffer *buffer, GLenum mode)
+static GLboolean gl_ggiSetBuffer(GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit)
{
ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
-
- printf("set read %d\n", mode);
- GGIMESADPRINT_CORE("gl_ggiSetReadBuffer() called\n");
- if (mode == GL_FRONT_LEFT)
+ printf("set read %d\n", bufferBit);
+ GGIMESADPRINT_CORE("gl_ggiSetBuffer() called\n");
+
+ if (bufferBit == DD_FRONT_LEFT_BIT)
{
ggiSetReadFrame(ggi_ctx->ggi_visual,
ggiGetDisplayFrame(ggi_ctx->ggi_visual));
+ ggiSetWriteFrame(ggi_ctx->ggi_visual,
+ ggiGetDisplayFrame(ggi_ctx->ggi_visual));
return GL_TRUE;
}
- else if (mode == GL_BACK_LEFT)
+ else if (bufferBit == DD_BACK_LEFT_BIT)
{
ggiSetReadFrame(ggi_ctx->ggi_visual,
ggiGetDisplayFrame(ggi_ctx->ggi_visual)?0 : 1);
+ ggiSetWriteFrame(ggi_ctx->ggi_visual,
+ ggiGetDisplayFrame(ggi_ctx->ggi_visual)?0 : 1);
return GL_TRUE;
}
else
static const GLubyte * gl_ggiGetString(GLcontext *ctx, GLenum name)
{
GGIMESADPRINT_CORE("gl_ggiGetString() called\n");
-
- if (name == GL_RENDERER)
- return (GLubyte *) "Mesa GGI";
- else
+
+ if (name == GL_RENDERER) {
+ return (GLubyte *) "Mesa GGI";
+ } else {
return NULL;
+ }
}
static void gl_ggiFlush(GLcontext *ctx)
static void gl_ggiSetupPointers(GLcontext *ctx)
{
TNLcontext *tnl;
-
+
GGIMESADPRINT_CORE("gl_ggiSetupPointers() called\n");
/* General information */
ctx->Driver.CopyPixels = _swrast_CopyPixels;
ctx->Driver.DrawPixels = _swrast_DrawPixels;
ctx->Driver.ReadPixels = _swrast_ReadPixels;
+ ctx->Driver.DrawBuffer = _swrast_DrawBuffer;
/* Software texturing */
ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
+ 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;
+
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.BaseCompressedTexFormat = _mesa_base_compressed_texformat;
- ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size;
- ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage;
-
/* Imaging extensions */
ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
/* State change callbacks */
- ctx->Driver.SetDrawBuffer = gl_ggiSetDrawBuffer;
ctx->Driver.ClearIndex = gl_ggiSetClearIndex;
ctx->Driver.ClearColor = gl_ggiSetClearColor;
ctx->Driver.IndexMask = gl_ggiIndexMask;
static void get_mode_info(ggi_visual_t vis, int *r, int *g, int *b,
GLboolean *rgb, GLboolean *db, int *ci)
{
- int i;
+ unsigned int i;
*r = 0;
*g = 0;
*b = 0;
- for(i = 0; i < sizeof(ggi_pixel)*8; ++i){
+ for(i = 0; i < sizeof(ggi_pixel)*8; ++i) {
int mask = 1 << i;
- if(LIBGGI_PIXFMT(vis)->red_mask & mask)
+ if (LIBGGI_PIXFMT(vis)->red_mask & mask)
++(*r);
- if(LIBGGI_PIXFMT(vis)->green_mask & mask)
+ if (LIBGGI_PIXFMT(vis)->green_mask & mask)
++(*g);
- if(LIBGGI_PIXFMT(vis)->blue_mask & mask)
+ if (LIBGGI_PIXFMT(vis)->blue_mask & mask)
++(*b);
}
printf("rgb (%d, %d, %d) db %d, rgb %d ci %d\n",*r,*g,*b,*db,*rgb,*ci);
}
-int ggiMesaInit()
-{
- int err;
- char *str;
-
- GGIMESADPRINT_CORE("ggiMesaInit() called\n");
-
- str = getenv("GGIMESA_DEBUG");
- if (str != NULL) {
- _ggimesaDebugState = atoi(str);
- GGIMESADPRINT_CORE("Debugging=%d\n", _ggimesaDebugState);
- }
-
- str = getenv("GGIMESA_DEBUGSYNC");
- if (str != NULL) {
- _ggimesaDebugSync = 1;
- }
-
- GGIMESADPRINT_CORE("ggiMesaInit()\n");
-
- _ggimesaLibIsUp++;
- if (_ggimesaLibIsUp > 1)
- return 0; /* Initialize only at first call */
-
- err = ggLoadConfig(ggimesaconffile, &_ggimesaConfigHandle);
- if (err != GGI_OK)
- {
- GGIMESADPRINT_CORE("GGIMesa: Couldn't open %s\n",
- ggimesaconffile);
- _ggimesaLibIsUp--;
- return err;
- }
-
- ggiMesaID = ggiExtensionRegister("GGIMesa",
- sizeof(struct ggi_mesa_ext), changed);
-
- if (ggiMesaID < 0)
- {
- GGIMESADPRINT_CORE("GGIMesa: failed to register as extension\n");
- _ggimesaLibIsUp--;
- ggFreeConfig(_ggimesaConfigHandle);
- return ggiMesaID;
- }
-
- return 0;
-}
-
-int ggiMesaExit(void)
-{
- int rc;
-
- GGIMESADPRINT_CORE("ggiMesaExit() called\n");
-
- if (!_ggimesaLibIsUp)
- return -1;
-
- if (_ggimesaLibIsUp > 1)
- {
- /* Exit only at last call */
- _ggimesaLibIsUp--;
- return 0;
- }
-
- rc = ggiExtensionUnregister(ggiMesaID);
- ggFreeConfig(_ggimesaConfigHandle);
-
- _ggimesaLibIsUp = 0;
-
- return rc;
-}
int ggiMesaAttach(ggi_visual_t vis)
{
int rc;
-
+
GGIMESADPRINT_CORE("ggiMesaAttach() called\n");
-
- rc = ggiExtensionAttach(vis, ggiMesaID);
+
+ rc = ggiExtensionAttach(vis, _ggiMesaID);
if (rc == 0)
{
int r, g, b, ci;
GLboolean rgb, db;
GLvisual *gl_visual;
- GLframebuffer *gl_fb;
/* We are creating the primary instance */
memset(LIBGGI_MESAEXT(vis), 0, sizeof(struct ggi_mesa_ext));
{
GGIMESADPRINT_CORE("ggiMesaDetach() called\n");
- return ggiExtensionDetach(vis, ggiMesaID);
+ return ggiExtensionDetach(vis, _ggiMesaID);
}
int ggiMesaExtendVisual(ggi_visual_t vis, GLboolean alpha_flag,
get_mode_info(vis, &r, &g, &b, &rgb, &db, &ci);
/* Initialize the visual with the provided information */
- _mesa_initialize_visual(&(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual),
+ _mesa_initialize_visual(gl_vis,
rgb, db, stereo_flag,
r, g, b, 0 /* FIXME */, ci,
depth_size, stencil_size,
{
ggi_mesa_context_t ctx;
int err;
- ggi_color pal[256];
- int i;
- __GLimports imports;
GGIMESADPRINT_CORE("ggiMesaCreateContext() called\n");
ctx->ggi_visual = vis;
ctx->color = 0;
- _mesa_init_default_imports( &imports, (void *) ctx);
ctx->gl_ctx =
_mesa_create_context(&(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual),
- NULL, &imports);
+ NULL, (void *) ctx, GL_FALSE);
if (!ctx->gl_ctx)
goto free_context;
if (ctx->gl_ctx->Viewport.Width == 0)
{
_mesa_Viewport(0, 0,
- LIBGGI_MODE(vis)->visible.x,
- LIBGGI_MODE(vis)->visible.y);
- ctx->gl_ctx->Scissor.Width = LIBGGI_MODE(vis)->visible.x;
- ctx->gl_ctx->Scissor.Height = LIBGGI_MODE(vis)->visible.y;
+ LIBGGI_VIRTX(vis),
+ LIBGGI_VIRTY(vis));
+ ctx->gl_ctx->Scissor.Width = LIBGGI_VIRTX(vis);
+ ctx->gl_ctx->Scissor.Height = LIBGGI_VIRTY(vis);
}
}
GGIMESADPRINT_CORE("ggiMesaSwapBuffers() called\n");
- _mesa_swapbuffers(ctx);
+ _mesa_notifySwapBuffers(ctx);
gl_ggiFlush(ctx);
ggiSetDisplayFrame(ggi_ctx->ggi_visual,
_swsetup_InvalidateState(ctx, new_state);
_tnl_InvalidateState(ctx, new_state);
+ /* XXX: Better use an assertion that bails out here on failure */
if (!LIBGGI_MESAEXT(ggi_ctx->ggi_visual)->update_state) {
GGIMESADPRINT_CORE("update_state == NULL!\n");
GGIMESADPRINT_CORE("Please check your config files!\n");
LIBGGI_MESAEXT(ggi_ctx->ggi_visual)->update_state(ggi_ctx);
}
-static int changed(ggi_visual_t vis, int whatchanged)
-{
- GLcontext *ctx;
- ctx = _mesa_get_current_context();
-
- GGIMESADPRINT_CORE("changed() called\n");
-
- switch (whatchanged)
- {
- case GGI_CHG_APILIST:
- {
- char api[256];
- char args[256];
- int i;
- const char *fname;
- ggi_dlhandle *lib;
- GLvisual *gl_vis=&(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual);
- GLframebuffer *gl_fb = &(LIBGGI_MESAEXT(vis)->mesa_buffer);
-
- /* Initialize the framebuffer to provide all necessary
- buffers in software. The target libraries that are loaded
- next are free to modify this according to their
- capabilities.
- */
- /* FIXME: if the target changes capabilities we'll leak
- swrast's memory !!! Need to deallocate first */
- _mesa_initialize_framebuffer(gl_fb, gl_vis,
- gl_vis->depthBits > 0,
- gl_vis->stencilBits > 0,
- gl_vis->accumRedBits > 0,
- gl_vis->alphaBits > 0);
-
- for (i = 0; ggiGetAPI(vis, i, api, args) == 0; i++)
- {
- strcat(api, "-mesa");
- fname = ggMatchConfig(_ggimesaConfigHandle, api, NULL);
- if (fname == NULL)
- {
- /* No special implementation for this sublib */
- continue;
- }
- lib = ggiExtensionLoadDL(vis, fname, args, NULL,
- GGI_SYMNAME_PREFIX);
- }
-
- /* The targets have cleared everything they can do from
- the framebuffer structure so we provide the rest in sw
- */
- _swrast_alloc_buffers(gl_fb);
-
- break;
- }
- }
- return 0;
-}
-