/** * This function is not exported, because it makes no sense for * The driver to punt back to this function */ BOOL APIENTRY EngRealizeBrush( BRUSHOBJ *pbo, SURFOBJ *psoDst, SURFOBJ *psoPattern, SURFOBJ *psoMask, XLATEOBJ *pxlo, ULONG iHatch) { EBRUSHOBJ *pebo; HBITMAP hbmpRealize; SURFOBJ *psoRealize; PSURFACE psurfRealize; POINTL ptlSrc = {0, 0}; RECTL rclDest; ULONG lWidth; /* Calculate width in bytes of the realized brush */ lWidth = WIDTH_BYTES_ALIGN32(psoPattern->sizlBitmap.cx, BitsPerFormat(psoDst->iBitmapFormat)); /* Allocate a bitmap */ hbmpRealize = EngCreateBitmap(psoPattern->sizlBitmap, lWidth, psoDst->iBitmapFormat, BMF_NOZEROINIT, NULL); if (!hbmpRealize) { return FALSE; } /* Lock the bitmap */ psurfRealize = SURFACE_ShareLockSurface(hbmpRealize); /* Already delete the pattern bitmap (will be kept until dereferenced) */ EngDeleteSurface((HSURF)hbmpRealize); if (!psurfRealize) { return FALSE; } /* Copy the bits to the new format bitmap */ rclDest.left = rclDest.top = 0; rclDest.right = psoPattern->sizlBitmap.cx; rclDest.bottom = psoPattern->sizlBitmap.cy; psoRealize = &psurfRealize->SurfObj; EngCopyBits(psoRealize, psoPattern, NULL, pxlo, &rclDest, &ptlSrc); pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject); pebo->pengbrush = (PVOID)psurfRealize; return TRUE; }
BOOL APIENTRY IntEngCopyBits( SURFOBJ *psoDest, SURFOBJ *psoSource, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclDest, POINTL *ptlSource) { return EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource); }
BOOL bSetSimPointerShape ( SURFOBJ *pso, SURFOBJ *psoMask, SURFOBJ *psoColor, XLATEOBJ *pxlo, LONG x, LONG y, FLONG fl ) { PPDEV ppdev = (PPDEV) pso->dhpdev; PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes; ULONG cxSrc, cySrc, cxSrcBytes; ULONG ulOffset; HSURF hsurf; SIZEL sizl; ULONG ulBitmapType; FLONG flBitmap; SURFOBJ *psoSrc; SURFOBJ *psoDst; RECTL prclDst; POINTL pptlSrc; XLATEOBJ xlo; ULONG ulXlate[2]; if (!(ppdev->flCaps & CAPS_NEED_SW_POINTER)) { return FALSE; } /* endif */ // // Check if we have enough off-screen memory to hold the screen image underneath // the new pointer // cxSrc = psoMask->sizlBitmap.cx; cySrc = psoMask->sizlBitmap.cy >> 1; cxSrcBytes = (cxSrc + 7) / 8; ulOffset = ppdev->cyScreen * ppdev->lDeltaScreen; ulOffset += 64; // skip over solid color pattern used in bitblt.c ulOffset += 1024; // skip over hardware pointer bitmap if ((ppdev->cScreenSize < ulOffset + cxSrc * cySrc * (ppdev->ulBitCount/8)) || (psoMask->iType & STYPE_BITMAP) || (!(psoMask->fjBitmap & BMF_TOPDOWN))) { return FALSE; } /* endif */ // // Update the attributes of pointer // pPointerAttributes->Width = cxSrc; pPointerAttributes->Height = cySrc; pPointerAttributes->WidthInBytes = cxSrcBytes; // // Discard the old pointer // if (ppdev->hsurfMask != NULL) { EngDeleteSurface(ppdev->hsurfMask); EngDeleteSurface(ppdev->hsurfColor); } /* endif */ // // Create a copy of mask bitmap // sizl.cx = cxSrc; sizl.cy = cySrc; flBitmap = BMF_TOPDOWN; prclDst.top = 0; prclDst.bottom = cySrc; prclDst.left = 0; prclDst.right = cxSrc; psoSrc = psoMask; ulBitmapType = BMF_1BPP; pptlSrc.x = 0; pptlSrc.y = 0; if (NULL == (hsurf = (HSURF) EngCreateBitmap(sizl, 0, // Let GDI choose ulWidth ulBitmapType, flBitmap, NULL))) { // Let GDI allocate return FALSE; } else { ppdev->hsurfMask = hsurf; } /* endif */ psoDst = EngLockSurface(ppdev->hsurfMask); if (!EngCopyBits(psoDst, // Target surface psoSrc, // Source surface (CLIPOBJ *) NULL, // Clip through this (XLATEOBJ *) NULL, // Color translation &prclDst, // Target offset and extent &pptlSrc)) { // Source offset EngDeleteSurface(ppdev->hsurfMask); return FALSE; } /* endif */ EngUnlockSurface(psoDst); // // Create a copy of pointer bitmap // ulBitmapType = pso->iBitmapFormat; if (psoColor == (SURFOBJ *) NULL) { // // Use second half of mask bitmap if it is monochrome // pPointerAttributes->Flags |= VIDEO_MODE_MONO_POINTER; pPointerAttributes->Flags &= ~VIDEO_MODE_COLOR_POINTER; psoSrc = psoMask; pptlSrc.x = 0; pptlSrc.y = cySrc; // // Create the translation table for monochrome-to-color conversion // pxlo = &xlo; xlo.iUniq = 0; xlo.flXlate = XO_TABLE; xlo.iSrcType = PAL_INDEXED; xlo.iDstType = (ppdev->ulBitCount == 8) ? PAL_INDEXED : PAL_RGB; xlo.cEntries = 2; xlo.pulXlate = (ULONG *)ulXlate; ulXlate[0] = 0x00000000; // Black ulXlate[1] = (ppdev->ulBitCount == 8) ? 0x000000FF : 0x00FFFFFF; // White } else { pPointerAttributes->Flags &= ~VIDEO_MODE_MONO_POINTER; pPointerAttributes->Flags |= VIDEO_MODE_COLOR_POINTER; psoSrc = psoColor; pptlSrc.x = 0; pptlSrc.y = 0; } /* endif */ if (NULL == (hsurf = (HSURF) EngCreateBitmap(sizl, 0, // Let GDI choose ulWidth ulBitmapType, flBitmap, NULL))) { // Let GDI allocate EngDeleteSurface(ppdev->hsurfMask); return FALSE; } else { ppdev->hsurfColor = hsurf; } /* endif */ psoDst = EngLockSurface(ppdev->hsurfColor); if (!EngCopyBits(psoDst, // Target surface psoSrc, // Source surface (CLIPOBJ *) NULL, // Clip through this pxlo, // Color translation &prclDst, // Target offset and extent &pptlSrc)) { // Source offset EngDeleteSurface(ppdev->hsurfMask); EngDeleteSurface(ppdev->hsurfColor); return FALSE; } /* endif */ EngUnlockSurface(psoDst); return TRUE; }
BOOL APIENTRY VBoxDispDrvCopyBits(SURFOBJ *psoDest, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclDest, POINTL *pptlSrc) { BOOL bRc; RECTL rclDest = *prclDest; POINTL ptlSrc = *pptlSrc; BOOL bDo = TRUE; LOGF_ENTER(); STATDRVENTRY(CopyBits, psoDest); LOG(("psoDest = %p, psoSrc = %p, pco = %p, pxlo = %p, prclDest = %p, pptlSrc = %p", psoDest, psoSrc, pco, pxlo, prclDest, pptlSrc)); DUMPSURF(psoSrc, "psoSrc"); DUMPSURF(psoDest, "psoDest"); STATPRINT; #ifdef VBOX_VBVA_ADJUST_RECT /* Experimental fix for too large bitmap updates. * * Some application do a large bitmap update event if only * a small part of the bitmap is actually changed. * * The driver will find the changed rectangle by comparing * the current framebuffer content with the source bitmap. * * The optimization is only active when: * - the VBVA extension is enabled; * - the source bitmap is not cacheable; * - the bitmap formats of both the source and the screen surfaces are equal. * */ if ( psoSrc && !VBoxDispIsScreenSurface(psoSrc) && VBoxDispIsScreenSurface(psoDest)) { PVBOXDISPDEV pDev = ((PVBOXDISPDEV))psoDest->dhpdev; LOG(("offscreen->screen")); if ( pDev->vbvaCtx.pVBVA && (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED)) { if ( (psoSrc->fjBitmap & BMF_DONTCACHE) != 0 || psoSrc->iUniq == 0) { LOG(("non-cacheable %d->%d (pDev %p)", psoSrc->iBitmapFormat, psoDest->iBitmapFormat, pDev)); /* It is possible to apply the fix. */ bDo = vbvaFindChangedRect(getSurfObj(psoDest), getSurfObj(psoSrc), &rclDest, &ptlSrc); } } } if (!bDo) { /* The operation is a NOP. Just return success. */ LOGF_LEAVE(); return TRUE; } #endif /* VBOX_VBVA_ADJUST_RECT */ bRc = EngCopyBits(getSurfObj(psoDest), getSurfObj(psoSrc), pco, pxlo, &rclDest, &ptlSrc); VBVA_OPERATION(psoDest, CopyBits, (psoDest, psoSrc, pco, pxlo, &rclDest, &ptlSrc)); LOGF_LEAVE(); return bRc; }
BOOL DrvCopyBits( SURFOBJ *psoDst, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclDst, POINTL *pptlSrc) /*++ Routine Description: Code for "hooking" CopyBits function for Jaguar VXL. Arguments: Return Value: --*/ { RECTL BltRectl; ENUMRECTLIST ClipEnum; BYTE FixedComplexity; BOOL MoreClipRects; FLONG BltDir; BOOL JaguarDir; ULONG ClipRegions; POINTL SrcPoint; // // Check that there is no color translation. // if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) { // // Check that source and destination surfaces are the frame buffer. // if ((psoSrc->pvBits == (PVOID)Vxl.ScreenBase) && (psoDst->pvBits == (PVOID)Vxl.ScreenBase)) { // // 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 } } // // If the copy operation could be performed by the accelerator, // this routine has already returned. // If execution falls here, call the Engine routine. // No need to Synchronize here since the Eng routine will call DrvSyncrhonize. // return EngCopyBits(psoDst, psoSrc, pco, pxlo, prclDst, pptlSrc); }
/***************************************************************************** * XGA DrvCopyBits ****************************************************************************/ BOOL DrvCopyBits( SURFOBJ *psoDest, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclDest, POINTL *pptlSrc) { BOOL b; CLIPOBJ coLocal; SURFOBJ *pso; DISPDBG((2, "XGA.DLL: DrvCopyBits - Entry\n")); // Need to determine which surface is the display. // So we can pickup the address of the XGA coprocessor regs. if ((psoDest) && (psoDest->iType == STYPE_DEVICE)) pso = psoDest; else if ((psoSrc) && (psoSrc->iType == STYPE_DEVICE)) pso = psoSrc; else { RIP ("XGA.DLL!DrvCopyBits - neither surface is a device surface\n"); return (TRUE); } // Wait for the coprocessor. vWaitForCoProcessor((PPDEV)pso->dhpdev, 100); // Protect this routine from a potentially NULL clip object if (pco == NULL) { coLocal.iDComplexity = DC_RECT; coLocal.rclBounds.left = 0; coLocal.rclBounds.top = 0; coLocal.rclBounds.right = ((PPDEV)pso->dhpdev)->cxScreen; coLocal.rclBounds.bottom = ((PPDEV)pso->dhpdev)->cyScreen; pco = &coLocal; } // Check for a Screen to Screen or a Host to Screen blit. b = FALSE; if ((psoDest->iType == STYPE_DEVICE) && (psoSrc->iType == STYPE_DEVICE) && (((PPDEV)psoDest->dhpdev)->ulfBlitAccelerations_debug & SCRN_TO_SCRN_CPY)) { b = bScrnToScrnCpy(psoDest, psoSrc, NULL, pco, pxlo, prclDest, pptlSrc, NULL, NULL, NULL, 0xcccc); } if (b == FALSE) { if ((psoDest) && (psoDest->iType == STYPE_DEVICE)) psoDest = ((PPDEV)(psoDest->dhpdev))->pSurfObj; if ((psoSrc) && (psoSrc->iType == STYPE_DEVICE)) psoSrc = ((PPDEV)(psoSrc->dhpdev))->pSurfObj; EngCopyBits(psoDest, psoSrc, pco, pxlo, prclDest, pptlSrc); } return (TRUE); }