Annotation of ntddk/src/perf/vgacode/bitblt.c, revision 1.1.1.1

1.1       root        1: /******************************Module*Header*******************************\
                      2: * Module Name: bitblt.c
                      3: *
                      4: * BitBlt
                      5: *
                      6: * Copyright (c) 1992 Microsoft Corporation
                      7: \**************************************************************************/
                      8: #include "driver.h"
                      9: #include "bitblt.h"
                     10: #include <winperf.h>    // include performance API definitions (PERFCTR)
                     11: 
                     12: // Global counter block for performance data (PERFCTR)
                     13: extern PPERF_COUNTER_BLOCK pCounterBlock;
                     14: 
                     15: 
                     16: BOOL bConvertBrush(BRUSHINST *pbri);
                     17: VOID vCompiledBlt(PDEVSURF,LONG,LONG,PDEVSURF,LONG,LONG,
                     18:                   LONG,LONG,ULONG,BRUSHINST *,ULONG,ULONG,ULONG *,POINTL *);
                     19: 
                     20: /******************************Public*Data*********************************\
                     21: * ROP translation table
                     22: *
                     23: * Translates the usual ternary rop into A-vector notation.  Each bit in
                     24: * this new notation corresponds to a term in a polynomial translation of
                     25: * the rop.
                     26: *
                     27: * Rop(D,S,P) = a + a D + a S + a P + a  DS + a  DP + a  SP + a   DSP
                     28: *               0   d     s     p     ds      dp      sp      dsp
                     29: *
                     30: * History:
                     31: *  24-Aug-1990 -by- Donald Sidoroff [donalds]
                     32: * Added it as a global table for the VGA driver.
                     33: \**************************************************************************/
                     34: 
                     35: BYTE gajRop[] =
                     36: {
                     37:     0x00, 0xff, 0xb2, 0x4d, 0xd4, 0x2b, 0x66, 0x99,
                     38:     0x90, 0x6f, 0x22, 0xdd, 0x44, 0xbb, 0xf6, 0x09,
                     39:     0xe8, 0x17, 0x5a, 0xa5, 0x3c, 0xc3, 0x8e, 0x71,
                     40:     0x78, 0x87, 0xca, 0x35, 0xac, 0x53, 0x1e, 0xe1,
                     41:     0xa0, 0x5f, 0x12, 0xed, 0x74, 0x8b, 0xc6, 0x39,
                     42:     0x30, 0xcf, 0x82, 0x7d, 0xe4, 0x1b, 0x56, 0xa9,
                     43:     0x48, 0xb7, 0xfa, 0x05, 0x9c, 0x63, 0x2e, 0xd1,
                     44:     0xd8, 0x27, 0x6a, 0x95, 0x0c, 0xf3, 0xbe, 0x41,
                     45:     0xc0, 0x3f, 0x72, 0x8d, 0x14, 0xeb, 0xa6, 0x59,
                     46:     0x50, 0xaf, 0xe2, 0x1d, 0x84, 0x7b, 0x36, 0xc9,
                     47:     0x28, 0xd7, 0x9a, 0x65, 0xfc, 0x03, 0x4e, 0xb1,
                     48:     0xb8, 0x47, 0x0a, 0xf5, 0x6c, 0x93, 0xde, 0x21,
                     49:     0x60, 0x9f, 0xd2, 0x2d, 0xb4, 0x4b, 0x06, 0xf9,
                     50:     0xf0, 0x0f, 0x42, 0xbd, 0x24, 0xdb, 0x96, 0x69,
                     51:     0x88, 0x77, 0x3a, 0xc5, 0x5c, 0xa3, 0xee, 0x11,
                     52:     0x18, 0xe7, 0xaa, 0x55, 0xcc, 0x33, 0x7e, 0x81,
                     53:     0x80, 0x7f, 0x32, 0xcd, 0x54, 0xab, 0xe6, 0x19,
                     54:     0x10, 0xef, 0xa2, 0x5d, 0xc4, 0x3b, 0x76, 0x89,
                     55:     0x68, 0x97, 0xda, 0x25, 0xbc, 0x43, 0x0e, 0xf1,
                     56:     0xf8, 0x07, 0x4a, 0xb5, 0x2c, 0xd3, 0x9e, 0x61,
                     57:     0x20, 0xdf, 0x92, 0x6d, 0xf4, 0x0b, 0x46, 0xb9,
                     58:     0xb0, 0x4f, 0x02, 0xfd, 0x64, 0x9b, 0xd6, 0x29,
                     59:     0xc8, 0x37, 0x7a, 0x85, 0x1c, 0xe3, 0xae, 0x51,
                     60:     0x58, 0xa7, 0xea, 0x15, 0x8c, 0x73, 0x3e, 0xc1,
                     61:     0x40, 0xbf, 0xf2, 0x0d, 0x94, 0x6b, 0x26, 0xd9,
                     62:     0xd0, 0x2f, 0x62, 0x9d, 0x04, 0xfb, 0xb6, 0x49,
                     63:     0xa8, 0x57, 0x1a, 0xe5, 0x7c, 0x83, 0xce, 0x31,
                     64:     0x38, 0xc7, 0x8a, 0x75, 0xec, 0x13, 0x5e, 0xa1,
                     65:     0xe0, 0x1f, 0x52, 0xad, 0x34, 0xcb, 0x86, 0x79,
                     66:     0x70, 0x8f, 0xc2, 0x3d, 0xa4, 0x5b, 0x16, 0xe9,
                     67:     0x08, 0xf7, 0xba, 0x45, 0xdc, 0x23, 0x6e, 0x91,
                     68:     0x98, 0x67, 0x2a, 0xd5, 0x4c, 0xb3, 0xfe, 0x01
                     69: };
                     70: 
                     71: 
                     72: /******************************Public*Data*********************************\
                     73: * ROP to mix translation table
                     74: *
                     75: * Table to translate ternary raster ops to mixes (binary raster ops). Ternary
                     76: * raster ops that can't be translated to mixes are translated to 0 (0 is not
                     77: * a valid mix).
                     78: *
                     79: \**************************************************************************/
                     80: 
                     81: UCHAR jRop3ToMix[256] = {
                     82:     R2_BLACK, 0, 0, 0, 0, R2_NOTMERGEPEN, 0, 0,
                     83:     0, 0, R2_MASKNOTPEN, 0, 0, 0, 0, R2_NOTCOPYPEN,
                     84:     0, 0, 0, 0, 0, 0, 0, 0,
                     85:     0, 0, 0, 0, 0, 0, 0, 0,
                     86:     0, 0, 0, 0, 0, 0, 0, 0,
                     87:     0, 0, 0, 0, 0, 0, 0, 0,
                     88:     0, 0, 0, 0, 0, 0, 0, 0,
                     89:     0, 0, 0, 0, 0, 0, 0, 0,
                     90:     0, 0, 0, 0, 0, 0, 0, 0,
                     91:     0, 0, 0, 0, 0, 0, 0, 0,
                     92:     R2_MASKPENNOT, 0, 0, 0, 0, R2_NOT, 0, 0,
                     93:     0, 0, R2_XORPEN, 0, 0, 0, 0, R2_NOTMASKPEN,
                     94:     0, 0, 0, 0, 0, 0, 0, 0,
                     95:     0, 0, 0, 0, 0, 0, 0, 0,
                     96:     0, 0, 0, 0, 0, 0, 0, 0,
                     97:     0, 0, 0, 0, 0, 0, 0, 0,
                     98:     0, 0, 0, 0, 0, 0, 0, 0,
                     99:     0, 0, 0, 0, 0, 0, 0, 0,
                    100:     0, 0, 0, 0, 0, 0, 0, 0,
                    101:     0, 0, 0, 0, 0, 0, 0, 0,
                    102:     R2_MASKPEN, 0, 0, 0, 0, R2_NOTXORPEN, 0, 0,
                    103:     0, 0, R2_NOP, 0, 0, 0, 0, R2_MERGENOTPEN,
                    104:     0, 0, 0, 0, 0, 0, 0, 0,
                    105:     0, 0, 0, 0, 0, 0, 0, 0,
                    106:     0, 0, 0, 0, 0, 0, 0, 0,
                    107:     0, 0, 0, 0, 0, 0, 0, 0,
                    108:     0, 0, 0, 0, 0, 0, 0, 0,
                    109:     0, 0, 0, 0, 0, 0, 0, 0,
                    110:     0, 0, 0, 0, 0, 0, 0, 0,
                    111:     0, 0, 0, 0, 0, 0, 0, 0,
                    112:     R2_COPYPEN, 0, 0, 0, 0, R2_MERGEPENNOT, 0, 0,
                    113:     0, 0, R2_MERGEPEN, 0, 0, 0, 0, R2_WHITE
                    114: };
                    115: 
                    116: 
                    117: /******************************Public*Routine******************************\
                    118: * VOID DrvBitBlt(pso,pso,pso,pco,pxlo,prcl,pptl,pptl,pdbrush,pptl,rop4)
                    119: *
                    120: * Bitblt.
                    121: *
                    122: \**************************************************************************/
                    123: 
                    124: BOOL DrvBitBlt
                    125: (
                    126:     SURFOBJ    *psoTrg,             // Target surface
                    127:     SURFOBJ    *psoSrc,             // Source surface
                    128:     SURFOBJ    *psoMask,            // Mask
                    129:     CLIPOBJ    *pco,                // Clip through this
                    130:     XLATEOBJ   *pxlo,               // Color translation
                    131:     RECTL      *prclTrg,            // Target offset and extent
                    132:     POINTL     *pptlSrc,            // Source offset
                    133:     POINTL     *pptlMask,           // Mask offset
                    134:     BRUSHOBJ   *pbo,                // Pointer to brush object
                    135:     POINTL     *pptlBrush,          // Brush offset
                    136:     ROP4        rop4                // Raster operation
                    137: )
                    138: {
                    139:     BYTE        jForeRop;           // Foreground rop in A-vector notation
                    140:     BYTE        jBackRop;           // Background rop in A-vector notation
                    141:     BYTE        jORedRops;          // jForeRop | jBackRop
                    142:     BRUSHINST   bri;                // Instance of a brush
                    143:     BRUSHINST  *pbri;               // Pointer to a brush instance
                    144: 
                    145:     DEVSURF     dsurfSrc;           // For source if a DIB
                    146:     PDEVSURF    pdsurfTrg;          // Pointer for target
                    147:     PDEVSURF    pdsurfSrc;          // Pointer for source if present
                    148: 
                    149:     ULONG       iSolidColor;        // Solid color for solid brushes
                    150:     BOOL        bMore;              // Clip continuation flag
                    151:     ULONG       ircl;               // Clip enumeration rectangle index
                    152:     RECT_ENUM   bben;               // Clip enumerator
                    153:     ULONG      *pulXlate;           // Pointer to color xlate vector
                    154:     BYTE        jClipping;
                    155:     MIX         mix;                // Mix, when solid fill performed
                    156:     RECTL       rclTemp;
                    157:     ULONG       ulBkColor;
                    158:     ULONG       ulFgColor;
                    159:     PRECTL      prcl;
                    160:     POINTL      ptlTemp;
                    161:     UCHAR      *pucDIB4ToVGAConvTables;
                    162:     VOID        (*pfnPatBlt)(PDEVSURF,ULONG,PRECTL,MIX, BRUSHINST *,PPOINTL);
                    163: 
                    164:     PDWORD     pdwCounter;         // Pointer to counter to increment  (PERFCTR)
                    165: 
                    166: // Increment BitBlt counter  (PERFCTR)
                    167:     pdwCounter = (PDWORD) pCounterBlock;
                    168:     (*pdwCounter)++;
                    169: 
                    170: 
                    171: // Let the engine handle the stuff we can't yet do.
                    172:     if (psoSrc != (SURFOBJ *) NULL) {
                    173:         if ((psoSrc->iBitmapFormat != BMF_1BPP)   &&
                    174:             (psoSrc->iBitmapFormat != BMF_4BPP)   &&
                    175:             (psoSrc->iBitmapFormat != BMF_8BPP)) {
                    176: 
                    177:             return(EngBitBlt(psoTrg,psoSrc,psoMask,
                    178:                              pco,pxlo,prclTrg,pptlSrc,pptlMask,
                    179:                              pbo,pptlBrush,rop4));
                    180: 
                    181:         } else {
                    182:             // We only handle SRCCOPY screen-to-screen blts right now
                    183:             if ((psoSrc->dhsurf == psoTrg->dhsurf) && (rop4 != 0x0000CCCC)) {
                    184: 
                    185:                 return(EngBitBlt(psoTrg,psoSrc,psoMask,
                    186:                                   pco,pxlo,prclTrg,pptlSrc,pptlMask,
                    187:                                   pbo,pptlBrush,rop4));
                    188:             }
                    189:         }
                    190:     }
                    191: 
                    192:     if ((rop4 & 0x000000FF) != ((rop4 >> 8) & 0x000000FF)) {
                    193: 
                    194:         return(EngBitBlt(psoTrg,psoSrc,psoMask,
                    195:                           pco,pxlo,prclTrg,pptlSrc,pptlMask,
                    196:                           pbo,pptlBrush,rop4));
                    197:     }
                    198: 
                    199:     // Get the target surface's pointer. The target must always be a device
                    200:     // surface
                    201: 
                    202:     pdsurfTrg = (PDEVSURF) psoTrg->dhsurf;
                    203: 
                    204:     // Set up the clipping type
                    205:     if (pco == (CLIPOBJ *) NULL) {
                    206:         // No CLIPOBJ provided, so we don't have to worry about clipping
                    207:         jClipping = DC_TRIVIAL;
                    208:     } else {
                    209:         // Use the CLIPOBJ-provided clipping
                    210:         jClipping = pco->iDComplexity;
                    211:     }
                    212: 
                    213: 
                    214:     // Break the rops with the VGA as the destination surface into two classes,
                    215:     // those that can call special case static code (currently: vTrgBlt(solid
                    216:     // fills) and vAlignedSrcCopy (aligned srccopy blts)), and those that must
                    217:     // call the compiled blt code
                    218: 
                    219:     if (pdsurfTrg->iFormat == BMF_PHYSDEVICE) {
                    220: 
                    221:         // Masked cases must be handled differently
                    222: 
                    223:         if ((rop4 & 0xFF) == ((rop4 >> 8) & 0xFF)) {
                    224: 
                    225:             // Special case static code for no-mask cases
                    226: 
                    227:             // Calculate mix from ROP if possible (not possible if it's truly a
                    228:             // ternary rop or a real rop4, but we can treat all pure binary
                    229:             // rops as mixes rather than rop4s)
                    230:             mix = jRop3ToMix[rop4 & 0xFF];
                    231:             pbri = (BRUSHINST *)NULL;
                    232: 
                    233:             switch (mix) {
                    234:                 case R2_MASKNOTPEN:
                    235:                 case R2_NOTCOPYPEN:
                    236:                 case R2_XORPEN:
                    237:                 case R2_MASKPEN:
                    238:                 case R2_NOTXORPEN:
                    239:                 case R2_MERGENOTPEN:
                    240:                 case R2_COPYPEN:
                    241:                 case R2_MERGEPEN:
                    242:                 case R2_NOTMERGEPEN:
                    243:                 case R2_MASKPENNOT:
                    244:                 case R2_NOTMASKPEN:
                    245:                 case R2_MERGEPENNOT:
                    246:                     // vTrgBlt can only handle solid color fills
                    247:                     if (pbo->iSolidColor != 0xffffffff)
                    248:                     {
                    249:                         iSolidColor = pbo->iSolidColor;
                    250:                     }
                    251:                     else
                    252:                     {
                    253:                         // TrgBlt can only handle solid brushes, but let's
                    254:                         // see if we can use our special case pattern code.
                    255:                         //
                    256:                         pbri = (BRUSHINST *)pbo->pvRbrush;
                    257:                         if (pbri == (BRUSHINST *)NULL)
                    258:                         {
                    259:                             pbri = (BRUSHINST *)BRUSHOBJ_pvGetRbrush(pbo);
                    260: 
                    261:                             if (pbri == (BRUSHINST *)NULL)
                    262:                             {
                    263:                                 return(EngBitBlt(psoTrg, psoSrc, psoMask, pco,
                    264:                                         pxlo, prclTrg, pptlSrc, pptlMask, pbo,
                    265:                                         pptlBrush, rop4));
                    266:                             }
                    267:                         }
                    268: 
                    269:                         // We currently only do mono patterns.
                    270: 
                    271:                         pfnPatBlt = vMonoPatBlt;
                    272: 
                    273:                         if (pbri->usStyle != BRI_MONO_PATTERN)
                    274:                                pfnPatBlt = vClrPatBlt;
                    275: 
                    276:                         // We only support non-8 wide brushes with R2_COPYPEN
                    277: 
                    278:                         if ((mix != R2_COPYPEN) && (pbri->RealWidth != 8))
                    279:                             break;
                    280: 
                    281:                     }
                    282:                 // Rops that are implicit solid colors
                    283: 
                    284:                 case R2_NOT:
                    285:                 case R2_WHITE:
                    286:                 case R2_BLACK:
                    287:                     // We can do a special-case solid fill
                    288: 
                    289:                     switch(jClipping) {
                    290:                         case DC_TRIVIAL:
                    291: 
                    292:                             // Just fill the rectangle with a solid color
                    293:                             if (pbri == (BRUSHINST *)NULL)
                    294:                             {
                    295:                                 vTrgBlt(pdsurfTrg, 1, prclTrg, mix,
                    296:                                         iSolidColor);
                    297:                             }
                    298:                             else
                    299:                             {
                    300:                                 (*pfnPatBlt)(pdsurfTrg, 1, prclTrg, mix,
                    301:                                         pbri, pptlBrush);
                    302:                             }
                    303:                             break;
                    304: 
                    305:                         case DC_RECT:
                    306: 
                    307:                             // Clip the solid fill to the clip rectangle
                    308:                             if (!DrvIntersectRect(&rclTemp, prclTrg,
                    309:                                     &pco->rclBounds)) {
                    310:                                 return(TRUE);
                    311:                             }
                    312: 
                    313:                             // Fill the clipped rectangle
                    314:                             if (pbri == (BRUSHINST *)NULL)
                    315:                             {
                    316:                                 vTrgBlt(pdsurfTrg, 1, &rclTemp, mix,
                    317:                                         iSolidColor);
                    318:                             }
                    319:                             else
                    320:                             {
                    321:                                 (*pfnPatBlt)(pdsurfTrg, 1, &rclTemp, mix,
                    322:                                         pbri, pptlBrush);
                    323:                             }
                    324:                             break;
                    325: 
                    326:                         case DC_COMPLEX:
                    327: 
                    328:                             CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES,
                    329:                                                CD_ANY, ENUM_RECT_LIMIT);
                    330: 
                    331:                             do {
                    332:                                 bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
                    333:                                                       (PVOID) &bben);
                    334: 
                    335:                                 for (ircl = 0; ircl < bben.c; ircl++) {
                    336:                                     PRECTL prcl = &bben.arcl[ircl];
                    337: 
                    338:                                     DrvIntersectRect(prcl,prcl,prclTrg);
                    339: 
                    340:                                     if (pbri == (BRUSHINST *)NULL) {
                    341: 
                    342:                                         vTrgBlt(pdsurfTrg, 1, prcl, mix,
                    343:                                                 iSolidColor);
                    344:                                     } else  {
                    345: 
                    346:                                         (*pfnPatBlt)(pdsurfTrg, 1, prcl, mix,
                    347:                                             pbri, pptlBrush);
                    348:                                     }
                    349:                                 }
                    350:                             } while(bMore);
                    351:                     }
                    352: 
                    353:                 case R2_NOP:
                    354:                     return TRUE;
                    355: 
                    356:                 default:
                    357:                     break;
                    358:             }
                    359: 
                    360:             // Not a special-case solid fill; see if it's a screen-to-screen
                    361:             // SRCCOPY blt, another of our special cases
                    362: 
                    363:             if (rop4 == 0x0000CCCC) {
                    364: 
                    365:                 // SRCCOPY blt
                    366: 
                    367:                 if (psoSrc->dhsurf == psoTrg->dhsurf) {
                    368: 
                    369:                     INT iCopyDir;
                    370:                     PFN_ScreenToScreenBlt pfn_Blt;
                    371: 
                    372:                     // It's a screen-to-screen SRCCOPY; special-case it
                    373: 
                    374:                     // Determine the direction in which the copy must proceed
                    375:                     // Note that although we could detect cases where the source
                    376:                     // and dest don't overlap and handle them top to bottom, all
                    377:                     // copy directions are equally fast, so there's no reason to go
                    378:                     // top to bottom except possibly that it looks better. But it
                    379:                     // also takes time to detect non-overlap, so I'm not doing it
                    380: 
                    381:                     if (pptlSrc->y >= prclTrg->top) {
                    382:                         if (pptlSrc->x >= prclTrg->left) {
                    383:                             iCopyDir = CD_RIGHTDOWN;
                    384:                         } else {
                    385:                             iCopyDir = CD_LEFTDOWN;
                    386:                         }
                    387:                     } else {
                    388:                         if (pptlSrc->x >= prclTrg->left) {
                    389:                             iCopyDir = CD_RIGHTUP;
                    390:                         } else {
                    391:                             iCopyDir = CD_LEFTUP;
                    392:                         }
                    393:                     }
                    394: 
                    395:                     // These values are expected by vAlignedSrcCopy
                    396: 
                    397:                     switch(jClipping) {
                    398: 
                    399:                     case DC_TRIVIAL:
                    400:                         // Just copy the rectangle
                    401:                         if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) {
                    402:                             vAlignedSrcCopy(pdsurfTrg, prclTrg,
                    403:                                             pptlSrc, iCopyDir);
                    404:                         } else {
                    405:                             vNonAlignedSrcCopy(pdsurfTrg, prclTrg,
                    406:                                                pptlSrc, iCopyDir);
                    407:                         }
                    408:                         break;
                    409: 
                    410:                     case DC_RECT:
                    411:                         // Clip the solid fill to the clip rectangle
                    412:                         if (!DrvIntersectRect(&rclTemp, prclTrg, &pco->rclBounds))
                    413:                         {
                    414:                             return(TRUE);
                    415:                         }
                    416: 
                    417:                         // Adjust the source point for clipping too
                    418:                         ptlTemp.x = pptlSrc->x + rclTemp.left - prclTrg->left;
                    419:                         ptlTemp.y = pptlSrc->y + rclTemp.top - prclTrg->top;
                    420: 
                    421:                         // Copy the clipped rectangle
                    422:                         if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) {
                    423:                             vAlignedSrcCopy(pdsurfTrg, &rclTemp, &ptlTemp,
                    424:                                             iCopyDir);
                    425:                         } else {
                    426:                             vNonAlignedSrcCopy(pdsurfTrg, &rclTemp, &ptlTemp,
                    427:                                                iCopyDir);
                    428:                         }
                    429:                         break;
                    430: 
                    431:                     case DC_COMPLEX:
                    432: 
                    433:                         if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) {
                    434:                             pfn_Blt = vAlignedSrcCopy;
                    435:                         } else {
                    436:                             pfn_Blt = vNonAlignedSrcCopy;
                    437:                         }
                    438: 
                    439:                         CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES,
                    440:                                            iCopyDir, ENUM_RECT_LIMIT);
                    441: 
                    442:                         do {
                    443:                             bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
                    444:                                                   (PVOID) &bben);
                    445: 
                    446:                             for (ircl = 0; ircl < bben.c; ircl++) {
                    447:                                 PRECTL prcl = &bben.arcl[ircl];
                    448: 
                    449:                                 DrvIntersectRect(prcl,prcl,prclTrg);
                    450: 
                    451:                                 // Adjust the source point for clipping too
                    452:                                 ptlTemp.x = pptlSrc->x + prcl->left -
                    453:                                         prclTrg->left;
                    454:                                 ptlTemp.y = pptlSrc->y + prcl->top -
                    455:                                         prclTrg->top;
                    456:                                 pfn_Blt(pdsurfTrg, prcl,
                    457:                                         &ptlTemp, iCopyDir);
                    458:                             }
                    459:                         } while(bMore);
                    460:                         break;
                    461:                     }
                    462: 
                    463:                     return TRUE;
                    464: 
                    465:                 } else if ((psoSrc->iType == STYPE_BITMAP) &&
                    466:                          (psoSrc->iBitmapFormat == BMF_4BPP) &&
                    467:                          ((pxlo == NULL) || (pxlo->flXlate == XO_TRIVIAL))) {
                    468: 
                    469:                     // Special case DIB4 to VGA copy if no translation
                    470: 
                    471:                     pucDIB4ToVGAConvTables =
                    472:                             ((PDEVSURF) psoTrg->dhsurf)->ppdev->
                    473:                             pucDIB4ToVGAConvTables;
                    474: 
                    475:                     // Make just enough of a fake DEVSURF for the source so
                    476:                     // that the DIB to VGA code can work
                    477: 
                    478:                     dsurfSrc.lNextScan = psoSrc->lDelta;
                    479:                     dsurfSrc.pvBitmapStart = psoSrc->pvScan0;
                    480: 
                    481:                     // Clip as needed
                    482: 
                    483:                     if ((pco == NULL) || (pco->iDComplexity == DC_TRIVIAL)) {
                    484: 
                    485:                         // No clipping, just copy the DIB to the VGA
                    486: 
                    487:                         vDIB2VGA((PDEVSURF) psoTrg->dhsurf, &dsurfSrc,
                    488:                                 prclTrg, pptlSrc, pucDIB4ToVGAConvTables);
                    489: 
                    490:                     } else if (pco->iDComplexity == DC_RECT) {
                    491: 
                    492:                         // Clip the destination to the clip rectangle; we
                    493:                         // should never get a NULL result
                    494:                         if (DrvIntersectRect(&rclTemp, prclTrg, &pco->rclBounds)) {
                    495: 
                    496:                             // Adjust the source point for clipping too
                    497:                             ptlTemp.x = pptlSrc->x + rclTemp.left - prclTrg->left;
                    498:                             ptlTemp.y = pptlSrc->y + rclTemp.top - prclTrg->top;
                    499: 
                    500:                             // Blt the clipped rectangle
                    501:                             vDIB2VGA((PDEVSURF) psoTrg->dhsurf, &dsurfSrc,
                    502:                                     &rclTemp, &ptlTemp, pucDIB4ToVGAConvTables);
                    503:                         }
                    504:                         return(TRUE);
                    505: 
                    506:                     } else {    // DC_COMPLEX:
                    507: 
                    508:                         CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES,
                    509:                                            CD_ANY, ENUM_RECT_LIMIT);
                    510: 
                    511:                         do {
                    512:                             bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
                    513:                                                   (PVOID) &bben);
                    514:                             prcl = bben.arcl;
                    515:                             for (ircl = 0; ircl < bben.c; ircl++, prcl++) {
                    516: 
                    517:                                 // Clip the destination to the clip rectangle;
                    518:                                 // we should never get a NULL result
                    519: 
                    520:                                 DrvIntersectRect(prcl,prcl,prclTrg);
                    521: 
                    522:                                 // Adjust the source point for clipping too
                    523:                                 ptlTemp.x = pptlSrc->x + prcl->left -
                    524:                                         prclTrg->left;
                    525:                                 ptlTemp.y = pptlSrc->y + prcl->top -
                    526:                                         prclTrg->top;
                    527: 
                    528:                                 // Blt the clipped rectangle
                    529:                                 vDIB2VGA((PDEVSURF) psoTrg->dhsurf,
                    530:                                         &dsurfSrc, prcl, &ptlTemp,
                    531:                                         pucDIB4ToVGAConvTables);
                    532:                             }
                    533:                         } while(bMore);
                    534:                     }
                    535: 
                    536:                     return(TRUE);
                    537: 
                    538:                 }
                    539:             }
                    540:         }
                    541:     }
                    542: 
                    543: 
                    544: // Couldn't be special cased.  Set up to call the old kludged compiling code.
                    545: 
                    546: 
                    547:     {
                    548:         LONG    xSrc;
                    549:         LONG    ySrc;
                    550:         RECTL  *prcl;
                    551: 
                    552: 
                    553:         // Translate the rop from old notation into two A-vector rops
                    554: 
                    555:         jForeRop = gajRop[rop4 & 0xff];
                    556:         jBackRop = gajRop[(rop4 >> 8) & 0xff];
                    557:         jORedRops = jForeRop | jBackRop;
                    558: 
                    559: 
                    560:         // Get the source surface if a source is needed.  The source may be any of
                    561:         // 1) the screen, 2) a device managed bitmap, 3) an engine bitmap
                    562: 
                    563:         if (jORedRops & AVEC_NEED_SOURCE) {
                    564: 
                    565:             if (psoSrc->dhsurf == (DHSURF) 0) {
                    566:                 // Source is an engine bitmap
                    567: #ifdef FIREWALLS
                    568:                 dsurfSrc.ident = 0x46525354;         // "TSRF"
                    569: #endif
                    570:                 dsurfSrc.flSurf   = DS_DIB;          // Supporting a DIB
                    571:                 dsurfSrc.iFormat  = (BYTE)psoSrc->iBitmapFormat;
                    572:                 dsurfSrc.sizlSurf = psoSrc->sizlBitmap;
                    573:                 dsurfSrc.lNextScan = psoSrc->lDelta;
                    574:                 dsurfSrc.pvScan0   = psoSrc->pvScan0;
                    575:                 dsurfSrc.pvBitmapStart = psoSrc->pvScan0;
                    576:                 dsurfSrc.pvConv    = pdsurfTrg->pvConv;
                    577: 
                    578:                 pdsurfSrc = &dsurfSrc;      // Construct source into here
                    579: 
                    580:             } else {
                    581:                 // Source is a device format bitmap or the device itself
                    582:                 pdsurfSrc = (PDEVSURF) psoSrc->dhsurf;
                    583:             }
                    584:         } else {
                    585:             pdsurfSrc  = (PDEVSURF) NULL;       // Assume no source
                    586:         }
                    587: 
                    588: 
                    589:         // If a brush is required, do what is necessary to get it.  We might be
                    590:         // able to just use the solid color accelerator, we might have to force it
                    591:         // to be realized (which could fail).
                    592: 
                    593:         if (jORedRops & AVEC_NEED_PATTERN) {
                    594: 
                    595:             // See if there is a solid color accelerator for the brush.  If so
                    596:             // we can just pick it up and use it.
                    597: 
                    598:             if (pbo->iSolidColor != 0xffffffff) {
                    599:                 bri.usStyle = BRI_SOLID;
                    600:                 bri.fjAccel =
                    601:                         (BYTE)((pbo->iSolidColor & COLOR_BITS) | SOLID_BRUSH);
                    602:                 pbri = &bri;
                    603:             } else {
                    604:             // If there is no realization of the brush, we must force it
                    605: 
                    606:                 if (pbo->pvRbrush == (PVOID)NULL)
                    607:                 {
                    608:                     pbri = (BRUSHINST *)BRUSHOBJ_pvGetRbrush(pbo);
                    609: 
                    610:                     if (pbri == (BRUSHINST *)NULL)
                    611:                     {
                    612:                         return(EngBitBlt(psoTrg, psoSrc, psoMask, pco, pxlo,
                    613:                                 prclTrg, pptlSrc, pptlMask, pbo, pptlBrush,
                    614:                                 rop4));
                    615:                     }
                    616:                 }
                    617:                 else
                    618:                 {
                    619:                     pbri = (BRUSHINST *)pbo->pvRbrush;
                    620:                 }
                    621: 
                    622:                 if (!bConvertBrush(pbri)) {
                    623:                     return(EngBitBlt(psoTrg, psoSrc, psoMask, pco, pxlo,
                    624:                             prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4));
                    625:                 }
                    626:             }
                    627:         }
                    628: 
                    629: 
                    630: 
                    631:         // Determine if color translation is required.  If so, then get the
                    632:         // color translation vector.  if no source is involved, then no
                    633:         // xlateobj will have been passed.
                    634: 
                    635:         if ((jORedRops & AVEC_NEED_SOURCE) &&
                    636:             (pxlo != NULL) &&
                    637:             (pxlo->flXlate & XO_TABLE))
                    638:         {
                    639:             pulXlate = pxlo->pulXlate;
                    640:             ulFgColor = pulXlate[0] << 24;  // Mono --> color translation
                    641:             ulBkColor = pulXlate[1] << 24;
                    642:         }
                    643:         else
                    644:         {
                    645:             pulXlate   = (PULONG) NULL;         // No xlate vector
                    646:         }
                    647: 
                    648: 
                    649:         // Note: blts where VGA memory is both the source and the destination
                    650:         // should never make it to this point; it's assumed that the VGA is the
                    651:         // destination and the destination only
                    652:         // BUGBUG this must be changed when we support DFBs, to make VGAs
                    653:         // possibly neither source nor destination, and (maybe?) source but DFB
                    654:         // dest
                    655: 
                    656:         // Perform blt with specified clipping.
                    657:         // BUGBUG only top->bottom blts are currently supported
                    658: 
                    659:         switch(jClipping) {
                    660: 
                    661:             RECTL   rclTemp;
                    662: 
                    663:             case DC_RECT:
                    664:                 if (!DrvIntersectRect(&rclTemp, prclTrg, &pco->rclBounds)) {
                    665:                     break;
                    666:                 }
                    667: 
                    668:                 // Adjust the source (if any) accordingly
                    669:                 if (jORedRops & AVEC_NEED_SOURCE) {
                    670:                     pptlSrc->x += rclTemp.left - prclTrg->left;
                    671:                     pptlSrc->y += rclTemp.top - prclTrg->top;
                    672:                 }
                    673: 
                    674:                 *prclTrg = rclTemp;
                    675: 
                    676:             case DC_TRIVIAL:
                    677: 
                    678:                 // Cycle through all banks that the blt dest spans
                    679: 
                    680:                 // If the proper bank for the top scan line of
                    681:                 // the blt dest isn't mapped in, map it in
                    682:                 if ((prclTrg->top < pdsurfTrg->rcl1WindowClip.top) ||
                    683:                        (prclTrg->top >= pdsurfTrg->rcl1WindowClip.bottom)) {
                    684: 
                    685:                     // Map in the bank containing the top line of the blt dest
                    686:                     pdsurfTrg->pfnBankControl(pdsurfTrg,
                    687:                                            prclTrg->top,
                    688:                                            JustifyTop);
                    689:                 }
                    690: 
                    691:                 // Now draw the part of the rect that's in each bank
                    692:                 for (;;) {
                    693: 
                    694:                     // Clip the blt dest to the bank
                    695:                     DrvIntersectRect(&rclTemp, prclTrg,
                    696:                             &pdsurfTrg->rcl1WindowClip);
                    697: 
                    698:                     // Adjust the source (if any) accordingly
                    699:                     if (jORedRops & AVEC_NEED_SOURCE) {
                    700:                         xSrc = pptlSrc->x + rclTemp.left - prclTrg->left;
                    701:                         ySrc = pptlSrc->y + rclTemp.top - prclTrg->top;
                    702:                     }
                    703: 
                    704:                     vCompiledBlt(pdsurfTrg,
                    705:                                  rclTemp.left,
                    706:                                  rclTemp.top,
                    707:                                  pdsurfSrc,
                    708:                                  xSrc,
                    709:                                  ySrc,
                    710:                                  rclTemp.right  - rclTemp.left,
                    711:                                  rclTemp.bottom - rclTemp.top,
                    712:                                  rop4,
                    713:                                  pbri,
                    714:                                  ulBkColor,
                    715:                                  ulFgColor,
                    716:                                  pulXlate,
                    717:                                  pptlBrush);
                    718: 
                    719:                     // Done if this bank contains the last line of the blt
                    720:                     if (prclTrg->bottom <=
                    721:                             pdsurfTrg->rcl1WindowClip.bottom) {
                    722:                         break;
                    723:                     }
                    724: 
                    725:                     // Map in the next bank
                    726:                     pdsurfTrg->pfnBankControl(pdsurfTrg,
                    727:                                               pdsurfTrg->rcl1WindowClip.bottom,
                    728:                                               JustifyTop);
                    729:                 }
                    730: 
                    731:                 break;
                    732: 
                    733: 
                    734:             case DC_COMPLEX:
                    735: 
                    736:                 CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
                    737:                 bMore = TRUE;
                    738: 
                    739:                 do {
                    740:                     if (bMore) {
                    741:                         // Enumerate more clip rects
                    742:                         bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
                    743:                                               (PVOID) &bben);
                    744:                     }
                    745: 
                    746:                     // Draw the portion of the blt dest that intersects each
                    747:                     // clip rect in turn
                    748:                     for (ircl = 0; ircl < bben.c; ircl++) {
                    749: 
                    750:                         prcl = &bben.arcl[ircl];
                    751: 
                    752:                         // Find the intersection of the target rect and the
                    753:                         // current clip rect, then draw all banks of the
                    754:                         // clipped target rect, if it's not NULL
                    755:                         DrvIntersectRect(prcl, prcl, prclTrg);
                    756: 
                    757:                         // Cycle through all banks that the blt dest spans
                    758: 
                    759:                         // If the proper bank for the top scan line of
                    760:                         // the blt dest isn't mapped in, map it in
                    761:                         if ((prcl->top <
                    762:                              pdsurfTrg->rcl1WindowClip.top) ||
                    763:                             (prcl->top >=
                    764:                              pdsurfTrg->rcl1WindowClip.bottom)) {
                    765: 
                    766:                             // Map in the bank containing the top line of
                    767:                             // the blt dest
                    768:                             pdsurfTrg->pfnBankControl(pdsurfTrg,
                    769:                                                       prcl->top,
                    770:                                                       JustifyTop);
                    771:                         }
                    772: 
                    773:                         // Now draw the part of the clipped rect that's in
                    774:                         // each bank
                    775:                         for (;;) {
                    776: 
                    777:                             RECTL   rclTemp;
                    778: 
                    779:                             // Clip the blt dest to the bank
                    780:                             DrvIntersectRect(&rclTemp, prcl,
                    781:                                              &pdsurfTrg->rcl1WindowClip);
                    782: 
                    783:                             // Adjust the source (if any) accordingly
                    784:                             if (jORedRops & AVEC_NEED_SOURCE) {
                    785:                                 xSrc = pptlSrc->x + rclTemp.left -
                    786:                                         prclTrg->left;
                    787:                                 ySrc = pptlSrc->y + rclTemp.top -
                    788:                                         prclTrg->top;
                    789:                             }
                    790: 
                    791:                             vCompiledBlt(pdsurfTrg,
                    792:                                          rclTemp.left,
                    793:                                          rclTemp.top,
                    794:                                          pdsurfSrc,
                    795:                                          xSrc,
                    796:                                          ySrc,
                    797:                                          rclTemp.right  - rclTemp.left,
                    798:                                          rclTemp.bottom - rclTemp.top,
                    799:                                          rop4,
                    800:                                          pbri,
                    801:                                          ulBkColor,
                    802:                                          ulFgColor,
                    803:                                          pulXlate,
                    804:                                          pptlBrush);
                    805: 
                    806:                             // Done if this bank contains the last line of
                    807:                             // the blt
                    808:                             if (prcl->bottom <=
                    809:                                     pdsurfTrg->rcl1WindowClip.bottom) {
                    810:                                 break;
                    811:                             }
                    812: 
                    813:                             // Map in the next bank
                    814:                             pdsurfTrg->pfnBankControl(pdsurfTrg,
                    815:                                           pdsurfTrg->rcl1WindowClip.bottom,
                    816:                                           JustifyTop);
                    817:                         }
                    818:                     }
                    819:                 } while(bMore);
                    820: 
                    821:                 break;
                    822: 
                    823:         }   // switch(jClipping);
                    824: 
                    825:     }
                    826: 
                    827:     return TRUE;
                    828: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.