| /* GGI-Driver for MESA |
| * |
| * Copyright (C) 1997 Uwe Maurer |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with this library; if not, write to the Free |
| * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| * --------------------------------------------------------------------- |
| * This code was derived from the following source of information: |
| * |
| * svgamesa.c and ddsample.c by Brian Paul |
| * |
| */ |
| |
| #include <ggi/mesa/ggimesa.h> |
| #include <ggi/mesa/ggimesa_int.h> |
| #include <ggi/mesa/debug.h> |
| #include "swrast/swrast.h" |
| |
| #define RMASK ((1<<R)-1) |
| #define GMASK ((1<<G)-1) |
| #define BMASK ((1<<B)-1) |
| |
| #define RS (8-R) |
| #define GS (8-G) |
| #define BS (8-B) |
| |
| #define PACK(color) (((color[RCOMP]>>RS) << (G+B)) | \ |
| ((color[GCOMP]>>GS) << B) | \ |
| ((color[BCOMP]>>BS))) |
| |
| #define FLIP(coord) (LIBGGI_VIRTY(ggi_ctx->ggi_visual) - (coord) - 1) |
| |
| |
| /**********************************************************************/ |
| /***** Write spans of pixels *****/ |
| /**********************************************************************/ |
| |
| void GGIwrite_ci32_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, |
| const GLuint ci[], const GLubyte mask[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| FB_TYPE *fb; |
| fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) + |
| FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x; |
| |
| if (mask) { |
| while (n--) { |
| if (*mask++) |
| *fb = *ci; |
| fb++; |
| ci++; |
| } |
| } else { |
| while (n--) *fb++ = *ci++; |
| } |
| } |
| |
| void GGIwrite_ci8_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, |
| const GLubyte ci[], const GLubyte mask[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| FB_TYPE *fb; |
| fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) + |
| FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x; |
| |
| if (mask) { |
| while (n--) { |
| if (*mask++) |
| *fb = *ci; |
| fb++; |
| ci++; |
| } |
| } else { |
| while (n--) *fb++ = *ci++; |
| } |
| } |
| |
| |
| void GGIwrite_rgba_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, |
| const GLchan rgba[][4], const GLubyte mask[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| FB_TYPE *fb; |
| fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) + |
| FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x; |
| |
| if (mask) { |
| while (n--) { |
| if (*mask++) |
| *fb = PACK(rgba[0]); |
| fb++; |
| rgba++; |
| } |
| } else { |
| while (n--) { |
| *fb++ = PACK(rgba[0]); |
| rgba++; |
| } |
| } |
| } |
| |
| void GGIwrite_rgb_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, |
| const GLchan rgba[][3], const GLubyte mask[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| FB_TYPE *fb; |
| fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) + |
| FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x; |
| |
| if (mask) { |
| while (n--) { |
| if (*mask++) |
| *fb = PACK(rgba[0]); |
| fb++; |
| rgba++; |
| } |
| } else { |
| while (n--) { |
| *fb++ = PACK(rgba[0]); |
| rgba++; |
| } |
| } |
| } |
| |
| |
| void GGIwrite_mono_rgba_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, |
| const GLchan color[4], const GLubyte mask[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| FB_TYPE *fb; |
| fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) + |
| FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x; |
| |
| if (mask) { |
| while (n--){ |
| if (*mask++) |
| *fb = PACK(color); |
| ++fb; |
| } |
| } else { |
| while (n--) |
| *fb++ = PACK(color); |
| |
| /* Alternatively we could write a potentialy faster HLine |
| ggiSetGCForeground(ggi_ctx->ggi_visual, color); |
| ggiDrawHLine(ggi_ctx->ggi_visual,x,FLIP(y),n); |
| */ |
| } |
| } |
| |
| void GGIwrite_mono_ci_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, |
| const GLuint ci, const GLubyte mask[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| FB_TYPE *fb; |
| fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) + |
| FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x; |
| |
| if (mask){ |
| while (n--){ |
| if (*mask++) |
| *fb = ci; |
| ++fb; |
| } |
| } else { |
| while (n--) |
| *fb++ = ci; |
| |
| /* Alternatively we could write a potentialy faster HLine |
| ggiSetGCForeground(ggi_ctx->ggi_visual, ci); |
| ggiDrawHLine(ggi_ctx->ggi_visual, x, FLIP(y), n); |
| */ |
| } |
| } |
| |
| |
| /**********************************************************************/ |
| /***** Read spans of pixels *****/ |
| /**********************************************************************/ |
| |
| |
| void GGIread_ci32_span(const GLcontext *ctx, |
| GLuint n, GLint x, GLint y, GLuint ci[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| FB_TYPE *fb; |
| fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) + |
| FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x; |
| |
| while (n--) |
| *ci++ = (GLuint)*fb++; |
| } |
| |
| void GGIread_rgba_span(const GLcontext *ctx, |
| GLuint n, GLint x, GLint y, GLchan rgba[][4]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| FB_TYPE color; |
| FB_TYPE *fb; |
| fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) + |
| FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x; |
| |
| while (n--) { |
| color = *fb++; |
| rgba[0][RCOMP] = (GLubyte) (color>>(G+B))<<RS; |
| rgba[0][GCOMP] = (GLubyte) ((color>>B)& ((1<<G)-1))<<GS; |
| rgba[0][BCOMP] = (GLubyte) (color & ((1<<B)-1))<<BS; |
| rgba[0][ACOMP] = 0; |
| rgba++; |
| } |
| } |
| |
| /**********************************************************************/ |
| /***** Write arrays of pixels *****/ |
| /**********************************************************************/ |
| |
| void GGIwrite_ci32_pixels(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| const GLuint ci[], const GLubyte mask[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual); |
| char *fb = (char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual); |
| |
| while (n--) { |
| if (*mask++){ |
| FB_TYPE *dst = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x; |
| *dst = *ci; |
| } |
| ci++; |
| x++; |
| y++; |
| } |
| } |
| |
| void GGIwrite_mono_ci_pixels(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLuint ci, const GLubyte mask[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual); |
| char *fb = (char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual); |
| |
| while (n--) { |
| if (*mask++){ |
| FB_TYPE *dst = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x; |
| *dst = ci; |
| } |
| x++; |
| y++; |
| } |
| } |
| |
| void GGIwrite_rgba_pixels(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| const GLchan rgba[][4], const GLubyte mask[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual); |
| char *fb = (char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual); |
| |
| while (n--) { |
| if (*mask++){ |
| FB_TYPE *dst = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x; |
| *dst = PACK(rgba[0]); |
| } |
| x++; |
| y++; |
| rgba++; |
| } |
| } |
| |
| void GGIwrite_mono_rgba_pixels(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| const GLchan rgba[4], const GLubyte mask[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual); |
| char *fb = (char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual); |
| |
| while (n--) { |
| if (*mask++){ |
| FB_TYPE *dst = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x; |
| *dst = PACK(rgba); |
| } |
| |
| x++; |
| y++; |
| } |
| } |
| |
| /**********************************************************************/ |
| /***** Read arrays of pixels *****/ |
| /**********************************************************************/ |
| |
| void GGIread_ci32_pixels(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLuint ci[], const GLubyte mask[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual); |
| char *fb = (char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual); |
| |
| while (n--) { |
| if (*mask++){ |
| FB_TYPE *src = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x; |
| *ci = *src; |
| } |
| ci++; |
| x++; |
| y++; |
| } |
| } |
| |
| void GGIread_rgba_pixels(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLubyte rgba[][4], const GLubyte mask[]) |
| { |
| ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; |
| int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual); |
| char *fb = (char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual); |
| FB_TYPE color; |
| |
| while (n--) { |
| if (*mask++) { |
| FB_TYPE *src = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x; |
| color = *src; |
| |
| rgba[0][RCOMP] = (GLubyte)(color>>(G+B))<<RS; |
| rgba[0][GCOMP] = (GLubyte)((color>>B)& ((1<<G)-1))<<GS; |
| rgba[0][BCOMP] = (GLubyte) (color & ((1<<B)-1))<<BS; |
| rgba[0][ACOMP] = 0; |
| } |
| x++; |
| y++; |
| rgba++; |
| } |
| } |
| |
| void GGIset_buffer(GLcontext *ctx, GLframebuffer *buffer, GLenum mode) |
| { |
| } |
| |
| int GGIsetup_driver(ggi_mesa_context_t ggi_ctx) |
| { |
| struct swrast_device_driver *swdd = |
| _swrast_GetDeviceDriverReference(ggi_ctx->gl_ctx); |
| |
| GGIMESADPRINT_LIBS("linear_%d: GGIsetup_driver\n", sizeof(FB_TYPE)*8); |
| |
| swdd->WriteRGBASpan = GGIwrite_rgba_span; |
| swdd->WriteRGBSpan = GGIwrite_rgb_span; |
| swdd->WriteMonoRGBASpan = GGIwrite_mono_rgba_span; |
| swdd->WriteRGBAPixels = GGIwrite_rgba_pixels; |
| swdd->WriteMonoRGBAPixels = GGIwrite_mono_rgba_pixels; |
| |
| swdd->WriteCI32Span = GGIwrite_ci32_span; |
| swdd->WriteCI8Span = GGIwrite_ci8_span; |
| swdd->WriteMonoCISpan = GGIwrite_mono_ci_span; |
| swdd->WriteCI32Pixels = GGIwrite_ci32_pixels; |
| swdd->WriteMonoCIPixels = GGIwrite_mono_ci_pixels; |
| |
| swdd->ReadCI32Span = GGIread_ci32_span; |
| swdd->ReadRGBASpan = GGIread_rgba_span; |
| swdd->ReadCI32Pixels = GGIread_ci32_pixels; |
| swdd->ReadRGBAPixels = GGIread_rgba_pixels; |
| |
| swdd->SetBuffer = GGIset_buffer; |
| |
| return 0; |
| } |
| |
| static int GGIopen(ggi_visual_t vis,struct ggi_dlhandle *dlh, |
| const char *args,void *argptr, uint32 *dlret) |
| { |
| GGIMESADPRINT_CORE("linear_%d: GGIOpen\n", sizeof(FB_TYPE)*8); |
| LIBGGI_MESAEXT(vis)->setup_driver = GGIsetup_driver; |
| |
| *dlret = GGI_DL_OPDRAW; |
| return 0; |
| } |
| |
| int DLOPENFUNC(int func, void **funcptr) |
| { |
| switch (func) { |
| case GGIFUNC_open: |
| *funcptr = GGIopen; |
| return 0; |
| case GGIFUNC_exit: |
| case GGIFUNC_close: |
| *funcptr = NULL; |
| return 0; |
| default: |
| *funcptr = NULL; |
| } |
| return GGI_ENOTFOUND; |
| } |
| |