/***************************************************************************** * XGA DrvBitBlt ****************************************************************************/ BOOL DrvBitBlt( SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclTrg, POINTL *pptlSrc, POINTL *pptlMask, BRUSHOBJ *pbo, POINTL *pptlBrush, ROP4 rop4) { BOOL b; b = bSpecialBlits(psoTrg, psoSrc, psoMask, pco, pxlo, prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4); if (b == TRUE) { return (TRUE); } if ((psoTrg) && (psoTrg->iType == STYPE_DEVICE)) psoTrg = ((PPDEV)(psoTrg->dhpdev))->pSurfObj; if ((psoSrc) && (psoSrc->iType == STYPE_DEVICE)) psoSrc = ((PPDEV)(psoSrc->dhpdev))->pSurfObj; EngBitBlt(psoTrg, psoSrc, psoMask, pco, pxlo, prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4); }
BOOL APIENTRY VBoxDispDrvBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclTrg, POINTL *pptlSrc, POINTL *pptlMask, BRUSHOBJ *pbo, POINTL *pptlBrush, ROP4 rop4) { BOOL bRc; LOGF_ENTER(); STATDRVENTRY(BitBlt, psoTrg); LOG(("psoTrg = %p, psoSrc = %p, psoMask = %p, pco = %p, pxlo = %p, prclTrg = %p, pptlSrc = %p, " "pptlMask = %p, pbo = %p, pptlBrush = %p, rop4 = %08X", psoTrg, psoSrc, psoMask, pco, pxlo, prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4)); bRc = EngBitBlt(getSurfObj(psoTrg), getSurfObj(psoSrc), psoMask, pco, pxlo, prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4); VBVA_OPERATION(psoTrg, BitBlt, (psoTrg, psoSrc, psoMask, pco, pxlo, prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4)); LOGF_LEAVE(); return bRc; }
VOID vShowSimPointer ( PPDEV ppdev, SURFOBJ *pso, RECTL *prcl, BOOL bShow ) { PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes; RECTL rclScreen, rclPointer; POINTL ptlPointerOffset; ULONG ulOffset; BOOL b; SURFOBJ *psoMask; SURFOBJ *psoColor; ulOffset = ppdev->cyScreen * ppdev->lDeltaScreen; ulOffset += 64; // skip over solid color pattern used in bitblt.c ulOffset += 1024; // skip over hardware pointer bitmap if (bShow) { rclScreen.top = 0; rclScreen.bottom = ppdev->cyScreen; rclScreen.left = 0; rclScreen.right = ppdev->cxScreen; rclPointer.top = pPointerAttributes->Row - ppdev->ptlHotSpot.y; rclPointer.bottom = rclPointer.top + pPointerAttributes->Height; rclPointer.left = pPointerAttributes->Column - ppdev->ptlHotSpot.x; rclPointer.right = rclPointer.left + pPointerAttributes->Width; // // Trim down the simulation cursor beyond the screen // if (bIntersect(&rclScreen, &rclPointer, &ppdev->rclPrevPointer)) { prcl->top = ppdev->rclPrevPointer.top; prcl->bottom = ppdev->rclPrevPointer.bottom; prcl->left = ppdev->rclPrevPointer.left; prcl->right = ppdev->rclPrevPointer.right; ptlPointerOffset.x = (rclPointer.left >= 0) ? 0 : (rclPointer.left * (-1)); ptlPointerOffset.y = (rclPointer.top >= 0) ? 0 : (rclPointer.top * (-1)); // // Save the screen image where the pointer affects // vHwSaveScreen(ppdev, &ppdev->rclPrevPointer, ulOffset); // // Draw the pointer // // Note: Clipping the transparent portion of pointer is required for // better performance. // if ((pso != NULL) && (pso->iType == STYPE_DEVICE)) pso = (SURFOBJ *)(((PPDEV)(pso->dhpdev))->pSurfObj); psoMask = EngLockSurface(ppdev->hsurfMask); psoColor = EngLockSurface(ppdev->hsurfColor); b = EngBitBlt(pso, // Target surface psoColor, // Source surface psoMask, // Mask (CLIPOBJ *) NULL, // Clip through this (XLATEOBJ *) NULL, // Color translation prcl, // Target offset and extent &ptlPointerOffset, // Source offset &ptlPointerOffset, // Mask offset (BRUSHOBJ *) NULL, // Brush data (from cbRealizeBrush) (POINTL *) NULL, // Brush offset (origin) 0x0000CC66); // Raster operation EngUnlockSurface(psoMask); EngUnlockSurface(psoColor); } else { // // The entire pointer is outside of screen // pPointerAttributes->Enable = 0; } /* endif */ } else { // // Restore the screen image corrupted by the simulation pointer // vHwRestoreScreen(ppdev, &ppdev->rclPrevPointer, ulOffset); } /* endif */ }
BOOL DoMix2( PPDEV pPDev, SURFOBJ *psoDst, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, PRECTL prclDst, PRECTL prclSrc, PPOINTL pptlSrcOrg, DWORD Mix2 ) /*++ Routine Description: This function is responsible for doing a device copy of a bitmap with/without tiling and activating the proper Rop2 Arguments: pPDev - Pointer to the PDEV psoDst - pointer to the destination surface object psoSrc - pointer to the source surface object pco - Pointer to the CLIPOBJ pxlo - the translate object from the source to the destination prclDst - the output destination rectangle area prclSrc - the source rectangle area pptlSrcOrg - brush origin for the source rectangle, if this is NULL then prclSrc will not have to be aligned on the destination Mix2 - a rop2 mode 0 - 0x0F Return Value: BOOLEAN Author: 08-Feb-1994 Tue 16:33:41 updated fixed ptlSrcOrg problem, we need to modulate with source size before it get used. 27-Jan-1994 Thu 23:45:46 updated Re-write so that it can handle the tiling more efficient. 13-Jan-1994 Sat 09:34:06 created Revision History: --*/ { RECTL rclSrc; RECTL rclDst; POINTL ptlSrcOrg; LONG cxSrc; LONG cySrc; DWORD OHTFlags = 0; BOOL MemMix2; // // The final ROP is either a ROP3 or a ROP4 (no mask) and it is always // a rop2 operation which deals with the source and destination // // First make it into a Rop3 representation of Rop2 (Mix2) // PLOTASSERT(1, "DoMix2: Passed INVALID psoSrc (%08lx) = STYPE_DEVICE", (psoSrc) && (psoSrc->iType != STYPE_DEVICE), psoSrc); PLOTASSERT(1, "DoMix2: Unexpected Mix2 = %u, SHOULD NOT BE HERE", (Mix2 != MIX2_0) && (Mix2 != MIX2_1) && (Mix2 != MIX2_D) && (Mix2 != MIX2_nD), Mix2); Mix2 &= 0x0F; Mix2 |= (DWORD)(Mix2 << 4); switch (Mix2) { case 0x00: // 0 case 0xFF: // 1 case 0x55: // ~D DoSpecialRop3(psoDst, pco, prclDst, Mix2); case 0xAA: // D return(TRUE); } if (MemMix2 = (BOOL)(psoDst->iType != STYPE_DEVICE)) { // // Now make it into Rop4 representation of Rop2 (Mix2) // Mix2 |= (Mix2 << 8); } else { if (!IsHTCompatibleSurfObj(pPDev, psoSrc, pxlo, ((pxlo) ? ISHTF_ALTFMT : 0) | ISHTF_HTXB | ISHTF_DSTPRIM_OK)) { PLOTERR(("DoMix2: The psoSrc is not HT compatible format (%08lx", psoSrc->iBitmapFormat)); return(FALSE); } } cxSrc = prclSrc->right - prclSrc->left; cySrc = prclSrc->bottom - prclSrc->top; if (pptlSrcOrg) { ptlSrcOrg = *pptlSrcOrg; if ((ptlSrcOrg.x = (LONG)(prclDst->left - ptlSrcOrg.x) % cxSrc) < 0) { ptlSrcOrg.x += cxSrc; } if ((ptlSrcOrg.y = (LONG)(prclDst->top - ptlSrcOrg.y) % cySrc) < 0) { ptlSrcOrg.y += cySrc; } PLOTDBG(DBG_DOMIX2, ("DoMix2: ORG ptlSrcOrg=(%ld, %ld) -> (%ld, %ld)", pptlSrcOrg->x, pptlSrcOrg->y, ptlSrcOrg.x, ptlSrcOrg.y)); } else { ptlSrcOrg.x = ptlSrcOrg.y = 0; PLOTDBG(DBG_DOMIX2, ("DoMix2: >>> DO NOT NEED TO ALIGN SRC on DEST <<<")); } rclSrc.top = prclSrc->top + ptlSrcOrg.y; rclSrc.bottom = prclSrc->bottom; rclDst.top = prclDst->top; rclDst.bottom = rclDst.top + (rclSrc.bottom - rclSrc.top); PLOTDBG(DBG_DOMIX2, ("DoMix2: SrcFormat=%ld, DstFormat=%ld %hs", psoSrc->iBitmapFormat, psoDst->iBitmapFormat, (MemMix2) ? "[MemMix2]" : "")); PLOTDBG(DBG_DOMIX2, ("DoMix2: ORG: Dst=(%ld, %ld)-(%ld,%ld), Src=(%ld, %ld)-(%ld, %ld)", prclDst->left, prclDst->top, prclDst->right, prclDst->bottom, prclSrc->left, prclSrc->top, prclSrc->right, prclSrc->bottom)); while (rclDst.top < prclDst->bottom) { // // check if the destination bottom is overhanging, clip it, // // NOTE: This could happen the first time. // if (rclDst.bottom > prclDst->bottom) { // // Clip the source/destination rectangle, because we may do // EngBitBlt() or OutputHTBitmap() // rclSrc.bottom -= (rclDst.bottom - prclDst->bottom); rclDst.bottom = prclDst->bottom; } rclSrc.left = prclSrc->left + ptlSrcOrg.x; rclSrc.right = prclSrc->right; rclDst.left = prclDst->left; rclDst.right = rclDst.left + (rclSrc.right - rclSrc.left); while (rclDst.left < prclDst->right) { // // check if the destination right edge is overhanging, clip it if // necessary. // // NOTE: This could happen the first time. // if (rclDst.right > prclDst->right) { // // Clip the source/destination rectangle, because we may do a // EngBitBlt() or OutputHTBitmap() // rclSrc.right -= (rclDst.right - prclDst->right); rclDst.right = prclDst->right; } PLOTDBG(DBG_DOMIX2, ("DoMix2: TILE: Dst=(%ld, %ld)-(%ld,%ld), Src=(%ld, %ld)-(%ld, %ld)", rclDst.left, rclDst.top, rclDst.right, rclDst.bottom, rclSrc.left, rclSrc.top, rclSrc.right, rclSrc.bottom)); if (MemMix2) { // // In the memory version we don't have to worry about PCO so // just call EngBitBlt to do the work. // if (!(EngBitBlt(psoDst, // psoDst psoSrc, // psoSrc NULL, // psoMask pco, // pco NULL, // pxlo &rclDst, // prclDst (PPOINTL)&rclSrc, // pptlSrc NULL, // pptlMask NULL, // pbo (PPOINTL)&ptlZeroOrigin, // pptlBrushOrg Mix2))) { PLOTERR(("DoMix2: EngBitBlt(MemMix2=%04lx) Failed!!!",Mix2)); return(FALSE); } } else { if (!OutputHTBitmap(pPDev, psoSrc, pco, (PPOINTL)&rclDst, &rclSrc, Mix2, &OHTFlags)) { PLOTERR(("DoMix2: OutputHTBitmap() Failed!!!")); return(FALSE); } } // // Reset <source left> to the original left margin and move the // destination right to the left for the next destination RECTL. // rclSrc.left = prclSrc->left; rclDst.left = rclDst.right; rclDst.right += cxSrc; } // // Reset <source top> to the original top margin and move the // destination bottom to the top, and set bottom for the next destination // RECTL. // rclSrc.top = prclSrc->top; rclDst.top = rclDst.bottom; rclDst.bottom += cySrc; } if (OHTFlags & OHTF_MASK) { OHTFlags |= OHTF_EXIT_TO_HPGL2; OutputHTBitmap(pPDev, psoSrc, NULL, NULL, NULL, 0xAA, &OHTFlags); } return(TRUE); }
BOOL DrvBitBlt( IN SURFOBJ *psoDst, // Target surface IN SURFOBJ *psoSrc, // Source surface IN SURFOBJ *psoMask, // Mask IN CLIPOBJ *pco, // Clip through this IN XLATEOBJ *pxlo, // Color translation IN PRECTL prclDst, // Target offset and extent IN PPOINTL pptlSrc, // Source offset IN PPOINTL pptlMask, // Mask offset IN BRUSHOBJ *pdbrush, // Brush data (from cbRealizeBrush) IN PPOINTL pptlBrush, // Brush offset (origin) IN ROP4 rop4 // Raster operation ) /*++ Routine Description: Code for "hooking" Bit Blt functions for Jaguar VXL. Arguments: Return Value: --*/ { FLONG BltDir; BOOL JaguarDir; RECTL BltRectl; ENUMRECTLIST ClipEnum; BOOL MoreClipRects; ULONG ClipRegions; POINTL SrcPoint; PPDEV ppdev = (PPDEV) psoDst->dhpdev; BYTE FixedComplexity; // // Check that there is no color translation. // if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) { // // Check that the blt operation has the screen as target surface. // if (psoDst->pvBits == (PVOID)Vxl.ScreenBase) { // // Check for rops that Jaguar handles. // Solid Fills, // SRCCOPPY // switch(rop4) { case 0x00000000: // DDx (BLACKNESS) DrvpSolidFill(prclDst,pco,0); return(TRUE); case 0x0000FFFF: // DDxn (WHITENESS) DrvpSolidFill(prclDst,pco,0xFFFFFF); return(TRUE); case 0x0000F0F0: // P (PATCOPY) case 0x00000F0F: // Pn (NOTPATCOPY) // // This is a pattern fill. Check if the brush pattern // is just a plain color, in this case procede with the // Solid Color Fill. // if (pdbrush->iSolidColor != 0xFFFFFFFF) { DrvpSolidFill(prclDst, pco, (rop4 == 0xF0F) ? ~(pdbrush->iSolidColor) : pdbrush->iSolidColor); return(TRUE); } break; // // Source copy // case 0x0000CCCC: // // Check that Source and Destination Surfaces are the same. // This is enough as we already checked that the dst is the frame buffer // if (psoDst->pvBits == psoSrc->pvBits) { // // check BLT direction for setting up clip regions // And for Jaguar BitBlt Commands as follows: // - If BltDir is UPWARDS do the BitBlt RightToLeft Bottom // to Top except when Src & Dst are in the same scan line // and BltDir is not LEFTWARDS // BltDir = 0; JaguarDir = FALSE; if (pptlSrc->y <= prclDst->top) { BltDir = CD_UPWARDS; JaguarDir = TRUE; } if (pptlSrc->x <= prclDst->left) { BltDir |= CD_LEFTWARDS; } else { if ((JaguarDir) && (pptlSrc->y == prclDst->top)) { JaguarDir = FALSE; } } // // Figure out the real clipping complexity // if (pco == (CLIPOBJ *)NULL) { FixedComplexity = DC_TRIVIAL; } else { FixedComplexity = pco->iDComplexity; } switch (FixedComplexity) { // // Entire destination is to be updated. // Proceed with the BitBlt. // case DC_TRIVIAL: DrvpBitBlt(prclDst, // Target rectangle pptlSrc, // Source offset JaguarDir // Direction ); return(TRUE); // // Only one clip region. // case DC_RECT: // // only do the BLT if there is an intersection // if (DrvpIntersectRect(prclDst,&pco->rclBounds,&BltRectl)) { // // Adjust the Source for the intersection rectangle. // pptlSrc->x += BltRectl.left - prclDst->left; pptlSrc->y += BltRectl.top - prclDst->top; DrvpBitBlt(&BltRectl, // Target rectangle pptlSrc, // Source offset JaguarDir // Direction ); } return(TRUE); // // Multiple clip regions. // case DC_COMPLEX: CLIPOBJ_cEnumStart(pco,FALSE,CT_RECTANGLES,BltDir,BB_RECT_LIMIT); do { // // Get list of clip rectangles. // MoreClipRects = CLIPOBJ_bEnum(pco,sizeof(ClipEnum),(PVOID)&ClipEnum); for (ClipRegions=0;ClipRegions<ClipEnum.c;ClipRegions++) { // // If the rectangles intersect calculate the offset to the // source start location to match and do the BitBlt. // if (DrvpIntersectRect(prclDst, &ClipEnum.arcl[ClipRegions], &BltRectl)) { SrcPoint.x = pptlSrc->x + BltRectl.left - prclDst->left; SrcPoint.y = pptlSrc->y + BltRectl.top - prclDst->top; DrvpBitBlt(&BltRectl, // Target rectangle &SrcPoint, // Source offset JaguarDir // Direction ); } } } while (MoreClipRects); return(TRUE); // // Unknown Clip complexity // default: break; } // end switch complexity } // end if Src surface = Dst surface } // end switch rop4 } } // // Call GDI to do the Blt for us. No need to syncrhonize here since // EngXXX routines call DrvSynchronize. // return(EngBitBlt(psoDst, // Target surface psoSrc, // Source surface psoMask, // Mask pco, // Clip through this pxlo, // Color translation prclDst, // Target offset and extent pptlSrc, // Source offset pptlMask, // Mask offset pdbrush, // Brush data (from cbRealizeBrush) pptlBrush, // Brush offset (origin) rop4 // Raster operation ) ); }