Files
Arquivotheca.SunOS-4.1.4/usr.lib/libpixrect/cg12/cg12_vector.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

205 lines
5.8 KiB
C

#ifndef lint
static char sccsid[] = "@(#)cg12_vector.c 1.1 94/10/31 SMI";
#endif
/* Copyright 1990 Sun Microsystems, Inc. */
#include <pixrect/pixrect.h>
#include <pixrect/gp1cmds.h>
#include <pixrect/cg12_var.h>
#include <pixrect/mem32_var.h>
#include <pixrect/pr_planegroups.h> /* PIX_ALL_PLANES */
#include <pixrect/pr_impl_util.h>
#include <pixrect/pr_dblbuf.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <math.h>
#include <sunwindow/rect.h>
#include <sunwindow/rectlist.h>
#include <sunwindow/win_screen.h>
#include <sunwindow/win_input.h>
#include <sunwindow/win_ioctl.h>
/* !!!### remove this line to re-enable acceleration ###!!! */
#define VECTOR_DEBUG
/******************************************************************************/
/* */
/* cg12_vector
Basic outline:
translate x and y according to md_offset.x and md_offset.y
gp1_alloc block in which to post buffer
get op, planegroup, and color from parameters
build op and planegroup
build dx_dy from x and y
build dw_dh from dpr->pr_size.x and dpr->pr_size.y, use fb size if
PIX_DONCLIP is set
put data in buffer
post buffer */
/* */
/******************************************************************************/
cg12_vector(dpr, x0, y0, x1, y1, op, color)
Pixrect *dpr;
int x0,
y0,
x1,
y1,
op,
color;
{
register int dpr_plngrp,planes_mask;
register int op_color=PIXOP_COLOR(op),rop = PIXOP_OP(op),dw_dh,dbl_status_ok;
register struct cg12_data *dprd = cg12_d(dpr);
int result;
extern int cg12_width, cg12_height;
#ifndef VECTOR_DEBUG
dpr_plngrp = PIX_ATTRGROUP(dprd->planes);
/* do only if 8 or 24 bit, */
/* punt if the sum of dx and dy is less then 41. This was derived
empirically. First, we found a cutoff based on the length of the line
between mem_vector and cg12_vector. This cutoff was around 29
pixels in length, i.e. lines shorter than 29 should not be drawn
with GP3_PR_VEC24 but with mem_vector instead. Second, to avoid
calculating the length of the line for each call to this routine,
we determined that on average the sum of dx and dy was about 41.
Note, this is purely an average and based on integer arithmetic only.
This turns out to be quicker than any multiplication for a bounding
box and roughly equivalent. This fix was implemented for an RFE.
See the sccs history for more info. */
if (!((_ABS((x1 - x0)) + _ABS((y1 - y0))) >= 41) ||
(dpr_plngrp != PIXPG_8BIT_COLOR && dpr_plngrp != PIXPG_24BIT_COLOR) )
{
Pixrect mem32_pr;
struct mprp32_data mem32_pr_data;
CG12_PR_TO_MEM(dpr, mem32_pr);
return mem_vector(dpr, x0, y0, x1, y1, op, color);
}
if (dprd->windowfd >= 0)
ioctl(dprd->windowfd, WINWIDGET, &dprd->wid_dbl_info);
/* assign color and plane_mask if 8 bit mode */
if (op_color)
{
color = op_color;
}
planes_mask = dprd->planes & 0x00FFFFFF;
if (dpr_plngrp == PIXPG_8BIT_COLOR)
{
color &= 0xFF;
color = (color << 16) | (color << 8) | color;
planes_mask &= 0xFF;
planes_mask = (planes_mask << 16) | (planes_mask << 8) | planes_mask;
}
else
{
if (dprd->wid_dbl_info.dbl_write_state == PR_DBL_A ||
dprd->wid_dbl_info.dbl_write_state == PR_DBL_B)
{
register int i;
i = ((dprd->wid_dbl_info.dbl_write_state == PR_DBL_A)
? dprd->wid_dbl_info.dbl_fore
: dprd->wid_dbl_info.dbl_back);
if (i == PR_DBL_B)
{
color = (color >> 4);
planes_mask = 0x0f0f0f;
}
else
planes_mask = 0xf0f0f0;
}
}
{
/* build gpsi buffer and post it */
register int *shmem_ptr;
unsigned int bitvec;
int shmem_off;
/*
* 0x230 = flag set by kernel indicating we need to run gpconfig. a
* really ugly situation that should never occur but if the gp is totally
* hung, well, there's not a lot we can do.
*/
if (dprd->gp_shmem[0x230])
cg12_restart(dpr);
/* 0x231 = flag indicating to turn off acceleration */
if (dprd->gp_shmem[0x231] ||
(shmem_off = gp1_alloc((caddr_t) dprd->gp_shmem, 1, &bitvec,
dprd->minordev, dprd->ioctl_fd)) == 0)
{
Pixrect mem32_pr;
struct mprp32_data mem32_pr_data;
CG12_PR_TO_MEM(dpr, mem32_pr);
return mem_vector(dpr, x0, y0, x1, y1, op, color);
}
shmem_ptr = (int *)(dprd->gp_shmem);
shmem_ptr += (shmem_off >> 1);
*shmem_ptr++ = (GP3_PR_VEC24 << 16) | (dpr_plngrp << 8) | (rop << 1);
/* build dx_dy and dw_dh */
if (op & PIX_DONTCLIP)
{
*shmem_ptr++ = 0; /* dx = 0, dy = 0 */
*shmem_ptr++ = (cg12_width << 16) | cg12_height;
}
else
{
*shmem_ptr++ = (dprd->mprp.mpr.md_offset.x << 16) |
dprd->mprp.mpr.md_offset.y;
*shmem_ptr++ = (dpr->pr_size.x << 16) | dpr->pr_size.y;
}
/* build P0 and P1 */
*shmem_ptr++ = ((y0 + dprd->mprp.mpr.md_offset.y) << 16) | ((x0 + dprd->mprp.mpr.md_offset.x) & 0xFFFF);
*shmem_ptr++ = ((y1 + dprd->mprp.mpr.md_offset.y) << 16) | ((x1 + dprd->mprp.mpr.md_offset.x) & 0xFFFF);
/* build color and planes_mask */
*shmem_ptr++ = color;
*shmem_ptr++ = planes_mask;
/* finish off buffer */
*shmem_ptr++ = ((GP1_EOCL | GP1_FREEBLKS) << 16) | (bitvec >> 16);
*shmem_ptr++ = (bitvec << 16);
result = gp1_post(dprd->gp_shmem, shmem_off, dprd->ioctl_fd);
gp1_sync((caddr_t)dprd->gp_shmem, dprd->fd);
return result;
}
#endif
#ifdef VECTOR_DEBUG
{
Pixrect mem32_pr;
CG12_PR_TO_MEM(dpr, mem32_pr);
return mem_vector(dpr, x0, y0, x1, y1, op, color);
}
#endif VECTOR_DEBUG
}