Man

Command Section
vga_accel(3)                  Svgalib User Manual                 vga_accel(3)

NAME
       vga_accel - calls the graphics accelerator

SYNOPSIS
       #include <vga.h>

       int vga_accel(unsigned operation, ...);

DESCRIPTION
       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).

BUGS
       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.

SEE ALSO
       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)

AUTHOR
       This manual page was edited by Michael Weller <[email protected]
       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 <[email protected]>.

       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.

Svgalib (>= 1.2.11)              27 July 1997                     vga_accel(3)
Command Section