Annotation of ntddk/src/video/displays/vga/savescr.c, revision 1.1.1.1

1.1       root        1: /******************************Module*Header*******************************\
                      2: * Module Name: savescr.c                                                   *
                      3: *                                                                          *
                      4: * DrvSaveScreenBits                                                        *
                      5: *                                                                          *
                      6: * Copyright (c) 1992 Microsoft Corporation                                 *
                      7: \**************************************************************************/
                      8: 
                      9: 
                     10: #include <driver.h>
                     11: 
                     12: 
                     13: //**************************************************************************//
                     14: // Note: if this is turned on, you *MUST* make sure to invalidate and reset //
                     15: // this when going to/returning from fullscreen mode (in DrvAssertMode).    //
                     16: //**************************************************************************//
                     17: #define OFFSCREEN_SUPPORTED 0   // 1 to support saves to offscreen memory
                     18:                                 //  (code currently not written)
                     19: 
                     20: VOID
                     21: vRestoreScreenBitsFromOffscreen(
                     22:    PDEVSURF pdsurf,
                     23:    PRECTL prcl,
                     24:    PBYTE pjSrcBuffer
                     25:    );
                     26: 
                     27: VOID
                     28: vRestoreScreenBitsFromMemory(
                     29:    PDEVSURF pdsurf,
                     30:    PRECTL prcl,
                     31:    PBYTE pjSrcBuffer,
                     32:    ULONG ulRestoreWidthInBytes,
                     33:    ULONG ulSrcDelta
                     34:    );
                     35: 
                     36: VOID
                     37: vSaveScreenBitsToMemory(
                     38:    PDEVSURF pdsurf,
                     39:    PRECTL prcl,
                     40:    PVOID pjDestBuffer,
                     41:    ULONG ulSaveWidthInBytes,
                     42:    ULONG ulSaveHeight,
                     43:    ULONG ulDestScanWidth
                     44:    );
                     45: 
                     46: /******************************Public*Routine******************************\
                     47: * DrvSaveScreenBits(pso,iMode,iIdent,prcl)                                 *
                     48: *                                                                          *
                     49: * Saves and restores the specified area of the screen                      *
                     50: *                                                                          *
                     51: \**************************************************************************/
                     52: 
                     53: ULONG DrvSaveScreenBits(SURFOBJ *pso, ULONG iMode, ULONG iIdent, RECTL *prcl)
                     54: {
                     55:     PDEVSURF pdsurf;
                     56:     PPDEV ppdev;
                     57:     PSAVED_SCREEN_BITS pSSB, *pLastSSBPtr, pSSBTemp;
                     58:     BOOL bIdentFound;
                     59:     ULONG ulSaveSize, ulSaveHeight;
                     60:     ULONG ulSaveWidthInBytes, ulSaveWidthInAlignedBytes;
                     61: 
                     62: //    ASSERT(pso != (SURFOBJ *) NULL,"DrvSaveScreenBits invalid pso");
                     63: 
                     64:     pdsurf = (PDEVSURF) pso->dhsurf;
                     65: 
                     66: //    ASSERT(pdsurf != (PDEVSURF) NULL,"DrvSaveScreenBits invalid dhsurf");
                     67: //    ASSERT(pdsurf->iFormat == BMF_PHYSDEVICE,
                     68: //            "DrvSaveScreenBits DFBs not supported");
                     69: 
                     70:     ppdev = pdsurf->ppdev;  // find the PDEV that goes with this surface
                     71: 
                     72:     //
                     73:     // Save, restore, or free a block of screen bits.
                     74:     //
                     75: 
                     76:     switch(iMode)
                     77:     {
                     78:         //
                     79:         // Save a block of screen bits.
                     80:         //
                     81: 
                     82:         case SS_SAVE:
                     83: 
                     84: //            ASSERT(prcl != (RECTL *) NULL,"DrvSaveScreenBits invalid prcl");
                     85:             // Figure out how big the save area will be
                     86:             ulSaveHeight = prcl->bottom - prcl->top;
                     87:             ulSaveWidthInBytes =
                     88:                     ((ULONG)((prcl->right + 7) - (prcl->left & ~0x07))) >> 3;
                     89: 
                     90: #if OFFSCREEN_SUPPORTED
                     91:             // This is the size of the the save area for one plane, or the
                     92:             // number of addresses required to save this in offscreen memory.
                     93:             // A system memory save area would require four times as many bytes
                     94:             ulSaveSize = ulSaveHeight * pSSB->ulSaveWidthInBytes;
                     95: 
                     96:             // See if there's enough memory left in the display memory heap to
                     97:             // save this rectangle
                     98:             if (ulSaveSize >
                     99:                     (pdsurf->pjAdapterHeapTop - pdsurf->pjAdapterHeapStart))
                    100:             {
                    101: #endif
                    102:                 // Not enough offscreen memory; store in system memory.
                    103:                 // Calculate new buffer width, allowing for padding so we can
                    104:                 // dword align
                    105:                 ulSaveWidthInAlignedBytes =
                    106:                     (((ULONG)((prcl->right + 31) - (prcl->left & ~0x1F)))
                    107:                                   >> 5) << 2;
                    108: 
                    109:                 // # of bytes to hold all 4 planes of save rect in memory
                    110:                 ulSaveSize = ((ulSaveHeight * ulSaveWidthInAlignedBytes) << 2)
                    111:                         + sizeof(SAVED_SCREEN_BITS);
                    112: 
                    113:                 // If the preallocated saved screen bits buffer is free and big
                    114:                 // enough to handle this save, we'll use that
                    115:                 if ((ppdev->flPreallocSSBBufferInUse == FALSE) &&
                    116:                     (ulSaveSize <= ppdev->ulPreallocSSBSize))
                    117:                 {
                    118:                     // Save in preallocated buffer
                    119: 
                    120:                     pSSB = (PSAVED_SCREEN_BITS) ppdev->pjPreallocSSBBuffer;
                    121: 
                    122:                     // Mark that we're saving in the preallocated buffer
                    123:                     pSSB->bFlags = SSB_IN_PREALLOC_BUFFER;
                    124: 
                    125:                     // Make sure no other screen bits save tries to use the
                    126:                     //  buffer
                    127:                     ppdev->flPreallocSSBBufferInUse = TRUE;
                    128:                 }
                    129:                 else
                    130:                 {
                    131:                     // Save in system memory buffer
                    132: 
                    133:                     // Allocate a structure to contain the save info and the
                    134:                     // save buffer (four planes' worth)
                    135:                     pSSB = (PSAVED_SCREEN_BITS)
                    136:                            (LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
                    137:                            ulSaveSize));
                    138:                     if (pSSB == NULL)
                    139:                     {
                    140:                         // Couldn't get memory, so fail this call
                    141:                         return((ULONG)0);
                    142:                     }
                    143: 
                    144:                     // Mark that we're not saving in display memory
                    145:                     pSSB->bFlags = 0;
                    146:                 }
                    147: 
                    148:                 // Start address at which to save, accounting for
                    149:                 // the number of bytes by which to pad on the left to dword
                    150:                 // align (assumes each scan line starts dword aligned, which is
                    151:                 // true in 640, 800, and 1024 wide cases)
                    152:                 pSSB->pjBuffer = ((PBYTE) pSSB) + sizeof(SAVED_SCREEN_BITS) +
                    153:                                  ((prcl->left >> 3) & 0x03);
                    154: 
                    155:                 pSSB->ulSaveWidthInBytes = ulSaveWidthInBytes;
                    156: 
                    157:                 // Distance from end of one scan to start of next (number of
                    158:                 // padding bytes for dword alignment purposes)
                    159:                 pSSB->ulDelta =
                    160:                         ulSaveWidthInAlignedBytes - pSSB->ulSaveWidthInBytes;
                    161: 
                    162:                 // Save the rectangle to system memory
                    163:                 vSaveScreenBitsToMemory(pdsurf,
                    164:                                         prcl,
                    165:                                         pSSB->pjBuffer,
                    166:                                         pSSB->ulSaveWidthInBytes,
                    167:                                         ulSaveHeight,
                    168:                                         ulSaveWidthInAlignedBytes);
                    169: #if OFFSCREEN_SUPPORTED
                    170:             }
                    171:             else
                    172:             {
                    173:                 // Store in offscreen memory
                    174:                 // Allocate a structure to contain the save info
                    175:                 pSSB = (PSAVED_SCREEN_BITS)
                    176:                        (LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
                    177:                        sizeof(SAVED_SCREEN_BITS));
                    178:                 if (pSSB == NULL)
                    179:                 {
                    180:                     // Couldn't get memory, so fail this call
                    181:                     return(0);
                    182:                 }
                    183:                 pSSB->bFlags = SSB_IN_ADAPTER_MEMORY;
                    184: 
                    185:                 pSSB->ulSaveWidthInBytes = ulSaveWidthInBytes;
                    186: 
                    187:                 /***/
                    188: 
                    189:             }
                    190: #endif
                    191: 
                    192:             // Link the new saved screen bits block into the list
                    193:             pSSB->pvNextSSB = pdsurf->ssbList;
                    194:             pdsurf->ssbList = pSSB;
                    195: 
                    196:             return((ULONG) pSSB);
                    197: 
                    198:         //
                    199:         // Restore a saved screen bits block to the screen, then free it.
                    200:         //
                    201: 
                    202:         case SS_RESTORE:
                    203: //            ASSERT(prcl != (RECTL *) NULL,"DrvSaveScreenBits invalid prcl");
                    204: 
                    205:             // Point to the first block in the saved screen bits list
                    206:             pSSB = pdsurf->ssbList;
                    207: 
                    208:             // Try to find the specified saved screen bits block
                    209:             bIdentFound = FALSE;
                    210:             while ((pSSB != (PSAVED_SCREEN_BITS) NULL) && !bIdentFound)
                    211:             {
                    212:                 if (pSSB == (PSAVED_SCREEN_BITS) iIdent)
                    213:                 {
                    214:                     // It's a match; restore this block
                    215: 
                    216:                     // Handle copies from offscreen memory and system memory
                    217:                     // separately
                    218: #if OFFSCREEN_SUPPORTED
                    219:                     if (pSSB->bFlags & SSB_IN_ADAPTER_MEMORY)
                    220:                     {
                    221:                         vRestoreScreenBitsFromOffscreen(pdsurf,
                    222:                                                         prcl,
                    223:                                                         pSSB->pjBuffer);
                    224:                     }
                    225:                     else
                    226:                     {
                    227: #endif
                    228:                         vRestoreScreenBitsFromMemory(pdsurf,
                    229:                                                      prcl,
                    230:                                                      pSSB->pjBuffer,
                    231:                                                      pSSB->ulSaveWidthInBytes,
                    232:                                                      pSSB->ulDelta);
                    233: #if OFFSCREEN_SUPPORTED
                    234:                     }
                    235: #endif
                    236: 
                    237:                     bIdentFound = TRUE;
                    238:                 }
                    239:                 else
                    240:                 {
                    241:                     // Not a match, so check another block, if there is one.
                    242:                     // Point to the next saved screen bits block
                    243:                     pSSB = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB;
                    244:                 }
                    245:             }
                    246: 
                    247:             // See if we succeeded in finding a block to restore
                    248:             if (!bIdentFound)
                    249:             {
                    250:                 // It was a bad identifier, so we'll return failure
                    251: 
                    252:                 DISPDBG((0, "DrvSaveScreenBits SS_RESTORE invalid iIdent"));
                    253:                 return(FALSE);
                    254:             }
                    255: 
                    256:             // Always free the saved screen bits block after restoring it
                    257: 
                    258:         //
                    259:         // Free up the saved screen bits block.
                    260:         //
                    261: 
                    262:         case SS_FREE:
                    263: 
                    264:             // Point to the first block in the saved screen bits list
                    265:             pSSB = pdsurf->ssbList;
                    266: 
                    267:             // Point to the pointer to the first block, so we can unlink the
                    268:             // first block if it's the one we're freeing
                    269:             pLastSSBPtr = &pdsurf->ssbList;
                    270: 
                    271:             // Try to find the specified saved screen bits block
                    272:             while (pSSB != (PSAVED_SCREEN_BITS) NULL)
                    273:             {
                    274:                 if (pSSB == (PSAVED_SCREEN_BITS) iIdent)
                    275:                 {
                    276:                     // It's a match; free up this block
                    277: 
                    278:                     // Unlink the block from the list
                    279:                     *pLastSSBPtr = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB;
                    280: 
                    281:                     // If the block is in offscreen memory, adjust the display
                    282:                     // memory heap to free up the offscreen memory allocated to
                    283:                     // the block
                    284:                     if (pSSB->bFlags & SSB_IN_ADAPTER_MEMORY)
                    285:                     {
                    286:                         if (pSSB->pjBuffer != pdsurf->pjAdapterHeapTop)
                    287:                         {
                    288:                             // The block is not on top of the heap, so compact
                    289:                             // the heap to move the newly freed space to the
                    290:                             // top of the display memory heap
                    291: 
                    292:                             // First, adjust the pointers to all the blocks
                    293:                             // that are above the freed one in the display
                    294:                             // memory heap
                    295:                             pSSBTemp = pdsurf->ssbList;
                    296:                             while (pSSBTemp != NULL)
                    297:                             {
                    298:                                 if (pSSBTemp->pjBuffer < pSSB->pjBuffer)
                    299:                                 {
                    300:                                     // This block is above the one we're
                    301:                                     // freeing in the display memory heap, so
                    302:                                     // shift its pointer down (the actual
                    303:                                     // movement of the bytes happens below)
                    304:                                     pSSBTemp->pjBuffer += pSSB->ulSize;
                    305:                                 }
                    306:                                 pSSBTemp = (PSAVED_SCREEN_BITS)
                    307:                                            pSSBTemp->pvNextSSB;
                    308:                             }
                    309:                             // Now actually shift all the higher blocks to
                    310:                             // squeeze out the block we just freed
                    311: 
                    312:                             memcpy(pdsurf->pjAdapterHeapTop + pSSB->ulSize,
                    313:                                    pdsurf->pjAdapterHeapTop,
                    314:                                    pSSB->pjBuffer - pdsurf->pjAdapterHeapTop);
                    315:                         }
                    316: 
                    317:                         // Adjust the top of the used display memory heap to
                    318:                         // account for the block we just freed
                    319:                         pdsurf->pjAdapterHeapTop += pSSB->ulSize;
                    320:                     }
                    321:                     else if (pSSB->bFlags & SSB_IN_PREALLOC_BUFFER)
                    322:                     {
                    323:                         // If the block's save area is in the preallocated
                    324:                         // buffer, mark that the buffer is no longer in use
                    325:                         // and is free for reuse
                    326:                         ppdev->flPreallocSSBBufferInUse = FALSE;
                    327: 
                    328:                         // We're done; there's nothing to free up
                    329:                         return(TRUE);
                    330:                     }
                    331: 
                    332:                     // Deallocate the block's memory
                    333:                     LocalFree(pSSB);
                    334: 
                    335:                     // We've successfully freed the block
                    336:                     return(TRUE);
                    337:                 }
                    338: 
                    339:                 // Not a match, so check another block, if there is one
                    340:                 // Remember the block that points to the block we're advancing
                    341:                 // to, for unlinking later
                    342:                 pLastSSBPtr = (PSAVED_SCREEN_BITS *) &pSSB->pvNextSSB;
                    343: 
                    344:                 // Point to the next saved screen bits block
                    345:                 pSSB = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB;
                    346:             }
                    347: 
                    348:             // It was a bad identifier, so we'll do nothing. We won't return
                    349:             // FALSE because SS_FREE always returns TRUE
                    350: 
                    351:             DISPDBG((0, "DrvSaveScreenBits SS_FREE invalid iIdent"));
                    352: 
                    353:             return(TRUE);
                    354: 
                    355:         //
                    356:         // An unknown mode was passed in.
                    357:         //
                    358: 
                    359:         default:
                    360: 
                    361:             DISPDBG((0, "DrvSaveScreenBits invalid iMode"));
                    362: 
                    363:             return(FALSE);
                    364:             break;
                    365:     }
                    366: }
                    367: 

unix.superglobalmegacorp.com

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