## Display Device Driver Reference for OS/2

[prev][next][parent][TOC]

### eddb_BitBlt (EDDNBBLT.C)

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.