示例#1
0
文件: engbrush.c 项目: GYGit/reactos
/**
 * 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;
}
示例#2
0
BOOL APIENTRY
IntEngCopyBits(
    SURFOBJ *psoDest,
    SURFOBJ *psoSource,
    CLIPOBJ *pco,
    XLATEOBJ *pxlo,
    RECTL *prclDest,
    POINTL *ptlSource)
{
    return EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource);
}
示例#3
0
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;
}
示例#5
0
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);
}
示例#6
0
/*****************************************************************************
 * 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);

}