|
|
| |
vga_accel(3) |
Svgalib User Manual |
vga_accel(3) |
vga_accel - calls the graphics accelerator
#include <vga.h>
int vga_accel(unsigned operation,
...);
This is the major function of the new accelerator interface which was sketched
in version 1.2.3 (Michael: Hmm, it must have been later) but was implemented
much later.
The main goal is to define functions that can be used as part of
certain kinds of interesting graphical operations (not necessarily
interesting primitives on their own). Obvious useful primitives in their own
are FillBox, ScreenCopy, DrawHLineList (solid polygon), DrawLine.
An interesting purpose is the fast drawing of color bitmaps, both
straight and transparent (masked, certain color not written). For masked
bitmaps ("sprites"), there is a number of possible methods, the
availability of which depends on the chips. Caching in non-visible video
memory is often useful. One way is to use a transparency color compare
feature of a BITBLT chip, either transferring the image from system memory
or cached in video memory. If transparency compare is not available, it may
be possible to first clear (zeroe) the mask in the destination area, and
then use BITBLT raster-operation to OR the image into the destination (this
requires the mask color to be 0). A higher level (library) interface should
control this kind of operation.
vga.h contains several macros which may be used for
operation. Most of them accept several optional arguments which you
may specify after them. The accel(6) svgalib demo shows basic usage
of this function. The function returns -1 if the operation is not available
and 0 if it is (or better: wasi and could be performed).
Currently the following parameters for vga_accel() are
defined:
- vga_accel(ACCEL_FILLBOX, int x, int y, int
w, int h)
- Simple solid fill of a box at pixels x, y with width
w and height h in the current foreground color
- vga_accel(ACCEL_SCREENCOPY, int x1, int y1,
int x2, int y2, int w, int
h)
- Simple screen-to-screen blit. It copies a box of width w and height
h pixels from position x1, y1 to position x2,
y2. You may assume that the copy is non corrupting in case of
overlapping source and destination areas.
- vga_accel(ACCEL_SCREENCOPYMONO, int x1, int
y1, int x2, int y2, int
w, int h)
- Monochrome screen-to-screen blit. It copies a box of width w and
height h pixels from position x1, y1 to position
x2, y2.
However, each pixel will all bits set to 0 is drawn in the
background color, each pixel with all bits set to 1 is drawn in the
foreground color. To allow many different architectures supporting this
routine, behaviour is undefined for other values. Bitmap transparency
might be supported as well.
You should not expect ACCEL_SCREENCOPYBITMAP handling
overlapping screen areas gracefully.
- vga_accel(ACCEL_PUTIMAGE, int x, int y, int
w, int h, void *p)
- Straight image transfer. It fills the given box with the data in memory
area p. The memory buffer must contain the pixels in the same
representation as used in the vga memory, starting at the top left corner,
from left to right, and then, line by line, from up to down, without any
gaps and interline spaces.
- vga_accel(ACCEL_DRAWLINE, int x1, int y1,
int x2, int y2))
- General line draw. Draws a line from x1, y1 to position
x2, y2 in the foreground color. You should not expect the
reverse line from x2, y2 to position x1, y1 to
use the exact same pixels on the screen. Several, esp. hardware,
algorithms tend to yield to surprising results.
- vga_accel(ACCEL_SETFGCOLOR, int color)
- Sets foreground color. It is used by most other draw commands.
- vga_accel(ACCEL_SETBGCOLOR, int color)
- Set background color. It is used by draw commands which might also
- vga_accel(ACCEL_SETTRANSPARENCY, int mode,
...)
- Set transparency mode, see the table below for an explanation parameters.
- vga_accel(ACCEL_SETRASTEROP, int mode)
- Set raster-operation, see the table below for an explanation of
parameters.
- vga_accel(ACCEL_PUTBITMAP, int x, int y,
int w, int h, void *p)
- Color-expand bitmap. This works similar to ACCEL_PUTIMAGE but the
bitmap *p is a one bit bitmap. Each pixel related to a set bit in
*p is drawn in the foreground color, the other pixels are drawn in
the background color.
Each byte at *p contains 8 pixels. The lowest order bit
of each byte is leftmost on the screen (contrary to the VGA tradition),
irrespective of the bitmap bit order flag. Each scanline is aligned to a
multiple of 32-bits.
If the transparency mode is enabled (irrespective of the
transparency color), then bits that are zero in the bitmap are not
written (the background color is not used).
- vga_accel(ACCEL_SCREENCOPYBITMAP, int x1, int
y1, int x2, int y2, int
w, int h)
- Color-expand from screen. This works similar to ACCEL_PUTBITMAP but
the bitmap lies at position x1, y1 and the destination box
at x2, y2.
Alas, the sizes of the pixels in both bitmap are different.
The bitmap *p must have the format corresponding to
ACCEL_PUTBITMAP but will start at the screen memory location
where the pixel (x1, y1) would be (probably in off screen
memory).
In modes where pixel will not start at byte boundaries
(typically those with less then 256 colors), the pixel (x1,
y1) must start at a byte boundary (for example in a 16 color mode
(4bpp rather than 8bpp for 256 colors) this means that x1 should
be an even number).
The easiest way to achieve this is probably to choose
x1 == 0 in these situations.
You should not expect ACCEL_SCREENCOPYBITMAP handling
overlapping screen areas gracefully.
- vga_accel(ACCEL_DRAWHLINELIST, int y, int
n, int *x1, int *x2)
- Draw horizontal spans. Each of the *x1 and *x2 arrays
contains n x-coordinate pairs. Starting with a horizontal line from
*x1,y to *x2,y consecutive horizontal lines
(with increasing y values) are drawn using the start and end points
in *x1 and *x2. This is usually a very quick operation and
useful to draw arbitrary polygons (when the accelerator cannot do an
arbitrary polygon fill itself).
- vga_accel(ACCEL_POLYLINE, int flag, int n,
unsigned short *coords)
- draws a contiguous line through the n points listed in
*coords. *coords contains n pairs of shorts, the
first is the x coordinate, the second is the y coordinate.
Normally flag should have the value ACCEL_START |
ACCEL_END. However, if the evaluation of the points is costly, you
can mix calculations and drawings. Your first call to
vga_accel(ACCEL_POLYLINE, ...) must have
ACCEL_START set. This will initialize the accelerator. If you do
not specify ACCEL_END, you can (actually you have to) follow your
call with another vga_accel(ACCEL_POLYLINE, ...)
call which will give additional points to connect.
It is important that no other operations (even no color
settings) take place between a call with ACCEL_START and the one
with the corresponding ACCEL_END. Because of this, it is also
important that you lock the console with vga_lockvc(3) and
vga_unlockvc(3), s.t. you cannot be interrupted by a console
switch.
It is allowed not to set ACCEL_END for your last call
to vga_accel(ACCEL_POLYLINE,
...).Thiswillnotdrawthelastpixelofthelast
line which is important for some raster operations when drawing closed
polygons. The accelerator will automatically deinitialize when called
with another operation in this situation.
It is undefined what happens when you specify other values for
flag and when your polyline contains only a single point. The
line segments must also not be of length zero.
For implementors: In conjunction with raster operations
(ROP_XOR, ROP_INV) it is important that endpoints of inner
line section are only drawn once. If you cannot achieve that, you must
signal that this function cannot be used in conjunction with raster
operations. In this case it is valid to always draw all points of the
line segments including the endpoints regardless of the existence of a
ACCEL_END parameter.
- vga_accel(ACCEL_POLYHLINE, int flag, int y,
int n, unsigned short *xcoords)
- This function combines the features of ACCEL_POLYLINE and
ACCEL_DRAWHLINELIST. Starting in row y horizontal lines are
drawn from top to bottom. For each horizontal scanline the *coords
array will contain a number m followed by m x coordinates in
left to right order. Horizontal lines are drawn between the first and the
second, the third and the fourth x coordinates, and so on. If the m
coordinates are exhausted, y is increased, a new number m is
read from the *coords array and operation continues.
This procedure is done for n scan lines.
In addition there is a flag parameter which works similar
to ACCEL_POLYLINE. Your first call to
ACCEL_DRAWHLINELIST must have the ACCEL_START bit set for
proper initialization. The y parameter is ignored when
ACCEL_START is not given.
On contrary to ACCEL_POLYLINE it is required that the
last call has the ACCEL_END bit set.
The function is intended for drawing complex filled polygons
using horizontal scanlines. By issuing small and fast calls for few
scanlines only it is possible to intermix drawing and calculations.
The operation of ACCEL_POLYHLINE is undefined if the x
coordinates are not sorted from left to right or there are zero length
segments in any scan line or if n or one of the m counters
are zero, or one of the m's is not even.
- vga_accel(ACCEL_POLYFILLMODE, onoff)
- Switches polygon fill mode on (onoff non-zero) or off.
When in polygon fill mode, ACCEL_DRAWLINE and
ACCEL_POLYLINE will only draw a single point on each scanline of
each line segment. ACCEL_SCREENCOPYMONO will horizontally scan
it's source area and start drawing in the foreground color when it
encounters a set pixel. When the next pixel is encountered, it will
start using the background color and so on.
This can be used for hardware filled polygons:
- 1.
- Enable polygon fill mode.
- 2.
- Fill an offscreen rectangular area with a the color with all bits zero
(usually black).
- 3.
- Draw a (usually closed) polygon outline in this offscreen area in the
color with all bits set (usually white). To get the proper bits set for
the polygon outline, it is recommended to use ROP_XOR s.t. outlines
intersecting in a single point are handled correctly. To ensure that
polygon corners are handled right, both start and end points must be drawn
(in ROP_XOR mode). Thus it is best to use ACCEL_DRAWLINE
instead of ACCEL_POLYLINE. Finally, skip drawing all horizontal
lines (which would confuse ACCEL_SCREENCOPYMONO).
- 4.
- Set fore- and background colors, raster operation, bitmap transparency to
those you want for your polygon.
- 5.
- Use ACCEL_SCREENCOPYMONO to copy the offscreen pattern to the
screen.
- The rasteroperations and transparency which are signalled to be supported
for ACCEL_POLYFILLMODE by vga_ext_set(3) are actually meant
to apply to the last ACCEL_SCREENCOPYMONO call.
Because this polygon drawing uses more screen read/write
operations it is probably slower than using ACCEL_DRAWHLINELIST
or ACCEL_POLYHLINE for drawing a polygon scanline by scanline.
However, it is easier to use and it will work mostly without
intervention of the CPU which can do other calculations then. See
BUGS below.
It is unspecified if the left or right end points of the
scanlines are drawn, and most probably some cards (like Mach32) will
omit them on one end, at least. Because of that you should always draw
the boundary line in the fill color (or another color) after filling the
polygon.
- vga_accel(ACCEL_SETMODE, mode)
- Set blit strategy. There are two choices for mode, namely
BLITS_SYNC and BLITS_IN_BACKGROUND. The first ensures that a
vga_accel() call only returns when the accelerator has finished its
operation. The second allows for an immediate return and thus allows
parallel operation of the CPU and the accelerator. Consecutive accelerator
operations will wait for each other to complete (and block if necessary).
However, direct screen memory access (also when done implicitly by some
call to an svgalib function) may find any intermediate state in vga memory
or even corrupt the running accelerator operation.
- vga_accel(ACCEL_SYNC)
- Wait for accelerator to finish when in
vga_accel(BLITS_IN_BACKGROUND) mode.
- vga_accel(ACCEL_SETOFFSET, int address)
- set a screen offset as vga_setdisplaystart(3) does. The same
restrictions for this function as reported by
vga_getmodeinfo(3) apply to address.
Whenever the video screen offset is modified, the
accelerator's offset will follow. However you can modify it later with
this function.
The following mode values are defined for
vga_accel(ACCEL_SETTRANSPARENCY, int mode,
...)
- vga_accel(ACCEL_SETTRANSPARENCY, ENABLE_TRANSPARENCY_COLOR, int
color)
- Whenever one of the vga_accel() operations would draw a pixel in
color color, no operation is performed and the destination pixel is
left unchanged. In fact that color is defined to be transparent.
- vga_accel(ACCEL_SETTRANSPARENCY, DISABLE_TRANSPARENCY_COLOR)
- disables the previous functionality.
- vga_accel(ACCEL_SETTRANSPARENCY, ENABLE_BITMAP_TRANSPARENCY)
- in the bitmap expanding operations ACCEL_PUTBITMAP and
ACCEL_SCREENCOPYBITMAP whenever a non set bit is encountered, to
not perform any draw operation. The 0 bits do not draw in the background
color. Instead they are defined to be transparent.
- vga_accel(ACCEL_SETTRANSPARENCY, DISABLE_BITMAP_TRANSPARENCY)
- disables the previous functionality.
The following mode values are defined for
vga_accel(ACCEL_SETRASTEROP, int mode)
- vga_accel(ACCEL_SETRASTEROP, ROP_COPY)
- Straight copy. Pixels drawn by vga_accel() replace the
destination.
- vga_accel(ACCEL_SETRASTEROP, ROP_OR)
- Logical or. Pixels drawn by vga_accel() are logical (bitwise) ored
to the destination.
- vga_accel(ACCEL_SETRASTEROP, ROP_AND)
- Logical and. Pixels drawn by vga_accel() are logical (bitwise)
anded to the destination.
- vga_accel(ACCEL_SETRASTEROP, ROP_XOR)
- Logical exclusive or. Pixels drawn by vga_accel() are logical
(bitwise) exclusive ored to the destination (bits set in the drawn pixels
flip those pits in the destination).
- vga_accel(ACCEL_SETRASTEROP, ROP_INV)
- Inversion. Pixels drawn by vga_accel() are inverted. Which color is
drawn is actually ignored. Any pixel which would be overwritten is simply
inverted (bitwise) instead.
IMPORTANT! Please note that a 0 returned by
vga_accel(ACCEL_SETTRANSPARENCY, int mode,
...) and vga_accel(ACCEL_SETRASTEROP, int
mode) simply means that the set function is available (and
thus probably some of above features) but only partial functionality
may be available. The VGA_AVAIL_ROPMODES and
VGA_AVAIL_TRANSMODES subfunctions of vga_ext_set(3) allow you
to check for valid parameters. The VGA_AVAIL_ROP and
VGA_AVAIL_TRANSPARENCY subfunctions return which of the
vga_accel operations are actually affected by these set
functions.
Instead of calling vga_accel() for each operation to find
out if it is supported, you can call:
#include <vga.h>
int vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ACCEL)
When the logical bitwise and of the return value with one of the
following predefined (one bit set only) integer constants is non zero, the
corresponding operation is available: ACCELFLAG_FILLBOX,
ACCELFLAG_SCREENCOPY, ACCELFLAG_PUTIMAGE,
ACCELFLAG_DRAWLINE, ACCELFLAG_SETFGCOLOR,
ACCELFLAG_SETBGCOLOR, ACCELFLAG_SETTRANSPARENCY,
ACCELFLAG_SETRASTEROP, ACCELFLAG_PUTBITMAP,
ACCELFLAG_SCREENCOPYBITMAP, ACCELFLAG_DRAWHLINELIST,
ACCELFLAG_SETMODE and ACCELFLAG_SYNC.
In addition, calling
#include <vga.h>
int vga_ext_set(VGA_EXT_AVAILABLE,
VGA_AVAIL_TRANSPARENCY)
or
int vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ROP)
does not list the supported values for raster operations
and transparency but instead returns the ACCELFLAG_ values for the
accelerator operations which respond the raster operation resp. transparency
settings.
The availability of the operations will usually depend on the
current video mode selected. You should not try to use them or check for
availability prior to selecting the mode you want to use with
set_mode(3).
I found the Mach32 buggy in that it occasionally omits drawing last pixels of
lines when in polygon fill modes (that means, a single point for the last
scanline touched by a line). Obviously this confuses the polygon fill
hardware. However, screen corruption will always be restricted to a small area
as ACCEL_SCREENCOPYMONO will work only on a limited area. It is not
clear if this is a driver error, but it seems to be a hardware bug, and I
don't know a clutch to avoid it yet. In case you experience problems with
certain applications, try blit nopolyfillmode in the configuration file
or the SVGALIB_CONFIG environment variable.
You must ensure that the given screen coordinates lie in screen
memory. Actually you may not really be sure how offscreen areas are handled,
you can only really trust that coordinates which are visible are supported.
For example, the Mach32 restricts the allowable x and y coordinates to the
range -512 .. 1535. However, even on a 1MB VGA memory card, the offscreen
point (0, 1599) would identify a valid screen memory location (if you could
use it).
Where supported, the vga_accel(ACCEL_SETOFFSET,
...) directive might help to ease things a bit in such
situations.
Svgalib's accelerator support is a mess. Right now, only the Ark,
the Cirrus, the Chips&Technologies, and the Mach32 svga drivers really
support this function. The Mach32 still also supports the old style
accelerator functions vga_bitblt(3), vga_blitwait(3),
vga_fillblt(3), vga_hlinelistblt(3) and vga_imageblt(3)
which were first designed for the Cirrus cards and thus the Mach32 has its
problems emulating them. The gl_ functions use the accelerator to
some extend. Currently the use both the new and the old style accelerator.
You should avoid mixing calls of the new and the old style kinds.
These functions are not well tested. You should expect weird bugs.
In any case, the accelerator is of not much use in many typical svgalib
applications. Best if you are not using them.
BEWARE! You should not use the graphics accelerator
together with the background feature of vga_runinbackground(3).
However, you can try using vga_lockvc(3) to lock the vc prior to
using the accelerator.
The Mach32 driver does this on it's own, and even keeps the
console locked while background accelerator functions are in progress. Other
drivers might not be as graceful.
svgalib(7), vgagl(7), libvga.config(5), accel(6),
vga_bitblt(3), vga_blitwait(3), vga_ext_set(3),
vga_fillblt(3), vga_getmodeinfo(3), vga_hlinelistblt(3),
vga_imageblt(3), vga_runinbackground(3),
vga_runinbackground_version(3)
This manual page was edited by Michael Weller
<eowmob@exp-math.uni-essen.de>. The exact source of the referenced
function as well as of the original documentation is unknown.
It is very likely that both are at least to some extent are due to
Harm Hanemaayer <H.Hanemaayer@inter.nl.net>.
Occasionally this might be wrong. I hereby asked to be excused by
the original author and will happily accept any additions or corrections to
this first version of the svgalib manual.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |