blob: 9d29761ad5b45336b16ac529ba009950f083acd3 [file] [log] [blame]
/* 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;
}