This is the entry point in the driver for BitBlt. It handles the device-independent portions of BitBlt. It validates parameters, transforms coordinates, and handles error logging. When it has completed some setup, eddb_BitBlt looks at the raster operation and splits into one of several cases, such as a three-way raster operation, a raster operation involving the source and destination, a raster operation involving a pattern and the destination, or a raster operation involving the destination-only. The following is a simplified pseudocode for eddb_BitBlt:
eddb_BitBlt() // check for stretch blt if not COM_DEVICE if ArgCount == 4 and src_coords != dst_coords stretch_return_code = IsValidStretchRequest() //can the driver handle the stretch blt? if stretch_return_code != OK Perform call-back to the engine to do stretchblt // at this point, eddb_BitBlt checks for a valid rop, and checks to see // if the request is for correlation or drawing, etc. if COM_CORRELATE if not eddg_ClipPickWindow() // get correlation rectangles goto BITBLT_EXIT //error! //if the PM desktop is in the background and the destination is the //display, disable drawing if fXGADead and Destination is display COMMANDBITS = COMMANDBITS and not(COM_DRAW) //convert target coordinates to device coordinates TransformCoordinates() //Examine the rop and determine which case it falls into if source_is_required(rop) goto SOURCE_3WAY_COMMON else goto PAT_DSTONLY_COMMON SOURCE_3WAY_COMMON: //handle all blts with a source, including blts involving source, //pattern, and destination if not(Stretching) //no need to setup if this is a stretchblt if source is a bit map convert handle to pointer and assign to AIxfer.pbmhSrc else //source is a device context handle convert handle to pointer to DC and assign to pdcSrc //get a pointer to the bit map defining the device AIxfer.pbmhsrc = pdcSrc->DCISelListEntry Build rectangles defining the source and destination //correlation involves determining if a pick is inside the area //of the drawing operation. if COM_CORRELATE perform correlation //see if we need to draw if not(COM_DRAW) goto BITBLT_EXIT Calculate BitBlt dimensions and store in AIxfer.rcsTrg and AIxfer.rcsSrc if software_cursor calculate exclusion rectangle eddm_ExcludeCursor() if pattern(rop) goto THREE_WAY_BLT //there is a pattern involved else goto SRC_DST_BLT //no pattern involved SRC_DST_BLT: if palette mapping is required create palette mapping if the source is cached evict source bit map from the cache //is the destination the display? if AIxfer.pbmhDest == DirectListEntry SetDrawModeHard //drawing to the display else SetDrawModeSoft //drawing to a bit map //check for monochrome expansion if mono(source) and not(mono(destination)) //source is 1 bpp and destination isn't, so this is a monochrome //expansion blt setup foreground and background colors in Shadow8514Regs if destination is cached evict destination from the cache else //both source and destination are in the same format //or source is color and destination is monochrome if source and destination are the same bit map if source and destination overlap determine direction in which to blt note that clipping rectangles need to be re-ordered store blt directions in pixelop else if source is color and destination is monochrome AIxfer.pbmhSrc = convert_colour_to_mono Set source and mix in Shadow8514Regs TransferShadowRegisters SPad.BltFunction = either eddf_SrcDestBlt or eddh_SrcDestBlt if src and dest are system memory or src and dest are display PixBltThroughClips else PixBltThroughClipsViaPhunk if destination is cached evict destination from the cache goto BITBLT_EXIT THREE_WAY_BLT: //source, pattern, and destination are involved in this rop Save a copy of AIxfer.pbmhDest Save a copy of AIxfer.pbmhSrc Setup the pattern Save a copy of the source & target rectangles if source bit map == destination bit map if source and destination overlap determine order for clipping regions determine blt directions else if source is monochrome and destination is color get foreground and background colors for mono bit map else if destination is monochrome and source is color source = convert_colour_to_mono(source) if bit 7 of the rop is set rop = 0ffh - rop calculate starting blt instruction add trailing "not" to last blt instruction else get pointer to starting instruction if Blt3WayBuffer[rop].CreateNew == TRUE allocate a temporary bit map to hold intermediate results instruction_count = Blt3WayBuffer[rop].Size while (instruction_count > 0) if Instruction->Destination == BT_DEST fThreeWayBlt = False //clip the destination set up destination map in AIxfer else if Instruction->Destination == BT_WORK fThreeWayBlt = True //don't clip the destination set up work map in AIxfer if Instruction->Source == BT_PAT set up the pattern in AIxfer if destination is the display SetDrawModeHard() else SetDrawModeSoft() else if Instruction->Source == BT_DEST set AIxfer source to destination bit map else if Instruction->Source == BT_WORK set AIxfer source to temporary bit map else if Instruction->Source == BT_SRC set AIxfer source to actual source bit map else no source, so do nothing! if destination is the display SetDrawModeHard() else SetDrawModeSoft() set up palette mapping if needed set up foreground and background colors and mixes based on if the blt is expanding from monochrome to color. TransferShadowRegisters() if src and dest are system memory or src and dest are display PixBltThroughClips else PixBltThroughClipsViaPhunk Instruction = next(Instruction) instruction_count = instruction_count - 1 fThreeWayWorkBlt = False if the original rop >= 0x80 remove trailing "not" from last Instruction goto BITBLT_EXIT PAT_DSTONLY_COMMON: //more of the same.... PAT_DST_BLT: //not shown lest the pseudocode become as complicated as the original DST_ONLY_BLT: //ditto BITBLT_EXIT: //end of BitBlt
Blting from source to destination involves several cases. First, there is the possibility that a palette mapping will be needed. (Palette mapping is necessary when the source and destination use differing palettes. Refer to eddb_CreatePalMapping in the EDDBPHNK.C file for details.) If the source is monochrome and the destination is not, the color_0 and Shadow8514Regs.color_1 fields must be set up. Finally, if both the source and destination are in system memory, or both are in VRAM, PixBltThroughClips is called to perform the blt. Otherwise, PixBltThroughClipsViaPhunk is called. The Phunk is always used when copying to or from system memory to VRAM. Using bus mastering via the Phunk was an optimization in the XGA driver, because copying to or from the Phunk to VRAM was fast. For the S3 driver, the Phunk is still useful if the source must be changed to a different format or if it must be stretched.
THREE_WAY_BLT involves a raster operation, a pattern, a source, and a destination. The key to understanding three-way blts is that they are interpreted. The blt interpreter breaks the raster operation down into a series of two-way blt operations that can be performed in either hardware or software. The following are examples of data structures:
// eddbtypt.h typedef struct { BYTE Source; BYTE Destination; BYTE Mix; SHORT BltFunction ; } BltInst; typedef BltInst NEAR * pBltInst; typedef struct { BYTE CreateNew; BYTE Size; pBltInst Instruction; } BltBuffEntry; typedef BltBuffEntry NEAR * pBltBuffEntry;
In the EDDBDATA.C file, there is a large array called Blt3WayInsts, which is an array of BltInst structures. Each BltInst in the array is one step in the construction of a three-way BitBlt. BltInst.Source lists the source for this stage of the blt. Likewise, BltInst.Destination is the destination. BltInst.Source can have the following values:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³BT_DEST ³0 ³Use the ³ ³ ³ ³destination ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³BT_WORK ³1 ³Use the ³ ³ ³ ³temporary ³ ³ ³ ³work buffer ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³BT_SRC ³2 ³Use the ³ ³ ³ ³source ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³BT_PAT ³3 ³Use the ³ ³ ³ ³pattern ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³BT_NONE ³4 ³Use none or ³ ³ ³ ³the same as ³ ³ ³ ³last time ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ
BltInst.Destination can have as a value of either BT_DEST, BT_WORK, or BT_SRC. (BT_SRC implies no destination or specifies the use of the same destination as last time.)
The Mix field holds the hardware mix to use (XOR, OR, AND, COPY, and so forth), and the BltFunction field holds an index into the pDrawFunctionsTable. BltFunction selects which of three types of blt this instruction is to perform, such as a blt with a source and destination, a pattern blt, or a destination-only blt. For example, the following entry uses the source as the source for this step, uses the destination as the destination, uses a raster operation of (not source) and (not destination), and uses either eddf_SrcDestBlt or eddh_SrcDestBlt to perform this step. In effect, each entry in Blt3WayInsts is an instruction, with BltFunction and Mix forming the operation code.
BT_SRC, BT_DEST, HWMIX_NOTSOURCE_AND_NOTDEST, index_SrcDestBlt,
Blt3WayBuffer is composed of structures of type BltBuffEntry. The CreateNew field of this structure is a Boolean value. When it is set to TRUE, a temporary buffer must be created for use during the blt. The Size field is the number of instructions it will take to perform this blt, (each instruction is a single entry in Blt3WayInsts), and Instruction field is a pointer to the first entry in Blt3WayInsts used for this blt.
Only raster operations from 0 to 7f hex are encoded this way. If the raster operation for the blt is greater than 80 hex, it is changed to the corresponding raster operation that is less than 80 hex, and a "not" operation is added to the final instruction for the blt. Performing the blt sets up the source and destination bit maps in AIxfer, and then calls either PixBltThroughClipsViaPhunk or PixBltThroughClips. When this has been completed, the next instruction in the blt is taken, and the cycle is repeated until no instructions remain.
The fThreeWayWorkBlt flag is true when the temporary bit map is being used as the destination for the blt. This flag exists so the PixBlt routines will not clip the work bit map against any clipping rectangles. It is necessary to avoid clipping the work bit map because it is an intermediate result, while the clipping rectangles refer to the destination bit map.
The pseudocode for pattern blts and destination-only blts generally follows a similar pattern to blts that involve a source and destination.