Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1151 lines
32 KiB

/****************************************************************************
*****************************************************************************
*
* ******************************************
* * Copyright (c) 1995, Cirrus Logic, Inc. *
* * All Rights Reserved *
* ******************************************
*
* PROJECT: Laguna I (CL-GD5462) -
*
* FILE: stretch.c
*
* AUTHOR: Benny Ng
*
* DESCRIPTION:
* This module implements the DrvStretchBlt() function for the
* Laguna NT driver.
*
* MODULES:
* AdjustSrcSize()
* bRectIntersect()
* cRectIntersect()
* Shrink()
* Stretch()
* CopySrcToOffMem()
* bStretchDIB()
* HandleCase_1()
* DrvStretchBlt()
*
* REVISION HISTORY:
* 7/11/95 Benny Ng Initial version
*
* $Log: X:/log/laguna/nt35/displays/cl546x/STRETCH.C $
*
* Rev 1.14 Nov 03 1997 11:10:48 frido
* Added REQUIRE and WRITE_STRING macros.
*
* Rev 1.13 08 Apr 1997 12:29:06 einkauf
*
* add SYNC_W_3D to coordinate MCD/2D access
*
* Rev 1.12 21 Mar 1997 12:22:16 noelv
* Combined "do_flag" and "sw_test_flag" together into "pointer_switch"
*
* Rev 1.11 07 Mar 1997 10:15:58 SueS
* Handle NULL pointer in DrvStretchBlt.
*
* Rev 1.10 06 Sep 1996 15:16:40 noelv
* Updated NULL driver for 4.0
*
* Rev 1.9 20 Aug 1996 11:04:26 noelv
* Bugfix release from Frido 8-19-96
*
* Rev 1.1 15 Aug 1996 11:39:42 frido
* Added precompiled header.
*
* Rev 1.0 14 Aug 1996 17:16:30 frido
* Initial revision.
*
* Rev 1.8 16 May 1996 15:01:40 bennyn
*
* Add PIXEL_ALIGN to allocoffscnmem()
*
* Rev 1.7 04 Apr 1996 13:20:28 noelv
* No change.
*
* Rev 1.6 15 Mar 1996 09:40:00 andys
*
* Removed BITMASK setting from code
*
* Rev 1.5 13 Mar 1996 11:11:20 bennyn
* Added device bitmap support
*
* Rev 1.4 07 Mar 1996 18:23:50 bennyn
*
* Removed read/modify/write on CONTROL reg
*
* Rev 1.3 05 Mar 1996 11:59:10 noelv
* Frido version 19
*
* Rev 1.1 20 Jan 1996 01:16:50 frido
*
*
* Rev 1.5 10 Jan 1996 16:11:12 NOELV
* Added NULL driver ability.
*
* Rev 1.4 18 Oct 1995 14:09:06 NOELV
*
* Fixed the mess I made of STRETCH.C I was writing to the BLT extents instea
*
* Rev 1.3 18 Oct 1995 12:10:26 NOELV
*
* Reworked register writes.
* punted 16,24, and 32 bpp
*
* Rev 1.2 06 Oct 1995 13:50:26 bennyn
*
* Rev 1.1 22 Aug 1995 16:40:38 bennyn
*
* Rev 1.3 15 Aug 1995 11:27:28 bennyn
*
* Rev 1.2 07 Aug 1995 08:02:34 bennyn
*
* Rev 1.1 02 Aug 1995 12:13:04 bennyn
*
* Rev 1.0 11 Jul 1995 15:14:16 BENNYN
* Initial revision.
*
****************************************************************************
****************************************************************************/
/*----------------------------- INCLUDES ----------------------------------*/
#include "precomp.h"
/*----------------------------- DEFINES -----------------------------------*/
//#define PUNTBRK
//#define DBGBRK
#define DBGDISP
#define OPTION_1
//#define OPTION_2
//#define OPTION_3
#define X_INTERP_ENABLE 0x1
#define Y_INTERP_ENABLE 0x2
#define X_SHRINK_ENABLE 0x4
#define Y_SHRINK_ENABLE 0x8
#define _32K 32768
#define SF 0x10000L
/*--------------------- STATIC FUNCTION PROTOTYPES ------------------------*/
/*--------------------------- ENUMERATIONS --------------------------------*/
/*----------------------------- TYPEDEFS ----------------------------------*/
typedef union _HOST_DATA {
BYTE bData[4];
DWORD dwData;
} HOST_DATA;
/*-------------------------- STATIC VARIABLES -----------------------------*/
/*-------------------------- GLOBAL FUNCTIONS -----------------------------*/
/****************************************************************************
* FUNCTION NAME: AdjustSrcSize()
*
* DESCRIPTION: If the destination rectange is changed due to the clipping,
* the source rectange size need to proportional change.
* This routine handles the source size change calcualtion.
*
* RETURN: TRUE: Punt it.
*
* REVISION HISTORY:
* 7/27/95 Benny Ng Initial version
****************************************************************************/
BOOL AdjustSrcSize(LONG dx,
LONG dy,
LONG origdx,
LONG origdy,
LONG dszX,
LONG dszY,
LONG origdszX,
LONG origdszY,
LONG *sszX,
LONG *sszY,
LONG *XsrcOff,
LONG *YsrcOff)
{
LONG ratioX, ratioY;
LONG ltemp;
UINT orig_sszX, orig_sszY;
BOOL bpuntit = FALSE;
BOOL bStretchX = FALSE;
BOOL bStretchY = FALSE;
orig_sszX = *sszX;
orig_sszY = *sszY;
// -------------------------------------------------------
// Calculate the source to destination size ratio
if (*sszX < origdszX)
{
ratioX = (origdszX * SF) / *sszX;
bStretchX = TRUE;
}
else
{
ratioX = (*sszX * SF) / origdszX;
};
if (*sszY < origdszY)
{
ratioY = (origdszY * SF) / *sszY;
bStretchY = TRUE;
}
else
{
ratioY = (*sszY * SF) / origdszY;
};
// -------------------------------------------------------
// Calculate the source X offset
if (origdx != dx)
{
if (bStretchX)
ltemp = ((dx - origdx) * SF) / ratioX;
else
ltemp = ((dx - origdx) * ratioX) / SF;
*XsrcOff = ltemp;
};
// Calculate the source X size change
if (origdszX != dszX)
{
if (bStretchX)
ltemp = ((origdszX - dszX) * SF) / ratioX;
else
ltemp = ((origdszX - dszX) * ratioX) / SF;
*sszX = *sszX - ltemp;
};
// -------------------------------------------------------
// Calculate the source Y offset
if (origdy != dy)
{
if (bStretchY)
ltemp = ((dy - origdy) * SF) / ratioY;
else
ltemp = ((dy - origdy) * ratioY) / SF;
*YsrcOff = ltemp;
};
// Calculate the source Y size change
if (origdszY != dszY)
{
if (bStretchY)
ltemp = ((origdszY - dszY) * SF) / ratioY;
else
ltemp = ((origdszY - dszY) * ratioY) / SF;
*sszY = *sszY - ltemp;
};
#ifdef DBGDISP
DISPDBG((1, "AdjustSrcSize - bpuntit= %x, ratioX=%d, ratioY=%d\n",
bpuntit, ratioX, ratioY));
DISPDBG((1, "dx=%d, dy=%d, origdx=%d, origdy=%d,\n",
dx, dy, origdx, origdy));
DISPDBG((1, "dszX=%d, dszY=%d, origdszX=%d, origdszY=%d,\n",
dszX, dszY, origdszX, origdszY));
DISPDBG((1, "*sszX=%d, *sszY=%d, orig_sszX=%d, orig_sszY=%d,\n",
*sszX, *sszY, orig_sszX, orig_sszY));
DISPDBG((1, "*XsrcOff=%d, *YsrcOff=%d\n", *XsrcOff, *YsrcOff));
#endif
#ifdef DBGBRK
DbgBreakPoint();
#endif
return(bpuntit);
}
/****************************************************************************
* FUNCTION NAME: bRectIntersect()
*
* DESCRIPTION: If 'prcl1' and 'prcl2' intersect, has a return value of
* TRUE and returns the intersection in 'prclResult'.
* If they don't intersect, has a return value of FALSE,
* and 'prclResult' is undefined.
*
* RETURN: TRUE: Rectange intersect.
*
* REVISION HISTORY:
* 8/01/95 Benny Ng Initial version
\**************************************************************************/
BOOL bRectIntersect(RECTL* prcl1,
RECTL* prcl2,
RECTL* prclResult)
{
prclResult->left = max(prcl1->left, prcl2->left);
prclResult->right = min(prcl1->right, prcl2->right);
if (prclResult->left < prclResult->right)
{
prclResult->top = max(prcl1->top, prcl2->top);
prclResult->bottom = min(prcl1->bottom, prcl2->bottom);
if (prclResult->top < prclResult->bottom)
return(TRUE);
};
return(FALSE);
}
/****************************************************************************
* FUNCTION NAME: cRectIntersect()
*
* DESCRIPTION: This routine takes a list of rectangles from 'prclIn'
* and clips them in-place to the rectangle 'prclClip'.
* The input rectangles don't have to intersect 'prclClip';
* the return value will reflect the number of input rectangles
* that did intersect, and the intersecting rectangles will
* be densely packed.
*
* RETURN: TRUE: Rectange intersect.
*
* REVISION HISTORY:
* 8/01/95 Benny Ng Initial version
\**************************************************************************/
LONG cRectIntersect(RECTL* prclClip,
RECTL* prclIn, // List of rectangles
LONG c) // Can be zero
{
LONG cIntersections;
RECTL* prclOut;
cIntersections = 0;
prclOut = prclIn;
for (; c != 0; prclIn++, c--)
{
prclOut->left = max(prclIn->left, prclClip->left);
prclOut->right = min(prclIn->right, prclClip->right);
if (prclOut->left < prclOut->right)
{
prclOut->top = max(prclIn->top, prclClip->top);
prclOut->bottom = min(prclIn->bottom, prclClip->bottom);
if (prclOut->top < prclOut->bottom)
{
prclOut++;
cIntersections++;
};
};
}
return(cIntersections);
}
/****************************************************************************
* FUNCTION NAME: Shrink()
*
* DESCRIPTION: This function calculates the parameters for shrink BLT
* operation.
*
* REVISION HISTORY:
* 7/18/95 Benny Ng Initial version
****************************************************************************/
VOID Shrink(PPDEV ppdev,
LONG lSrc,
LONG lDst,
char chCoord,
ULONG LnCntl,
LONG *sShrinkInc)
{
LONG maj = 0;
LONG min = 0;
LONG accum = 0;
// Set SHRINKINC value,
// for y, SHRINKINC = ratio of src/dst
// for x, SHRINKINC = ratio of src/dst if not interpolating
// SHRINKINC = (ratio of src/dst minus one) if interpolating
// low byte for x coordinate
// high byte for y coordinate
if (chCoord == 'X')
{
*sShrinkInc |= (lSrc / lDst);
if (LnCntl & X_INTERP_ENABLE)
sShrinkInc--;
}
else
{
*sShrinkInc |= ((lSrc / lDst) << 8);
};
// Compute ACCUM_?, MAJ_? and MIN_? values
// MAJ_? = width (for x) or height (for y) of destination
// MIN_? = negative of the remainder of src/dst
// ACCUM_? = MAJ_? - 1 - ( Src%Dst / (shrink factor + 1))
maj = lDst;
min = -(lSrc % lDst);
accum = maj - 1 - ((lSrc % lDst) / ((lSrc / lDst) + 1)) ;
if (chCoord == 'X')
{
REQUIRE(3);
LL16 (grMAJ_X, maj);
LL16 (grMIN_X, min);
LL16 (grACCUM_X, accum);
}
else
{
REQUIRE(3);
LL16 (grMAJ_Y, maj);
LL16 (grMIN_Y, min);
LL16 (grACCUM_Y, accum);
};
#ifdef DBGBRK
DISPDBG((1, "DrvStretchBlt - shrink\n"));
DbgBreakPoint();
#endif
}
/****************************************************************************
* FUNCTION NAME: Stretch()
*
* DESCRIPTION: This function calculates the parameters for stretch BLT
* operation.
*
* REVISION HISTORY:
* 7/18/95 Benny Ng Initial version
****************************************************************************/
VOID Stretch(PPDEV ppdev,
LONG lSrc,
LONG lDst,
char chCoord,
ULONG LnCntl)
{
LONG min = 0;
LONG maj = 0;
LONG accum = 0;
// For interpolated stretches registers values differ from values for
// replicated stretches
if (((chCoord == 'X') && ((LnCntl & X_INTERP_ENABLE) == 0)) ||
((chCoord == 'Y') && ((LnCntl & Y_INTERP_ENABLE) == 0)))
{
// Compute ACCUM_?, MAJ_? and MIN_? for replicated stretch
// MAJ_? = width (for x) or height (for y) of destination
// MIN_? = negative of width (for x) or height (for y) of source
// ACCUM_? = MAJ_? - 1 - ( Dst%Src / (stretch factor + 1))
maj = lDst;
min = -lSrc;
accum = maj - 1 - ((lDst % lSrc) / ((lDst / lSrc) + 1));
}
else
{
// Compute ACCUM_?, MAJ_? and MIN_? for interpolated stretch
// Interpolated strecthes use bits 13 & 14 of ACCUM_? to determine
// whether to use pixel A, 3/4 A + 1/4 B, 1/2 A + 1/2 B or
// 1/4 A + 3/4 B.
// To set DDA values appropriately there are three choices.
// 1) Set MAJ_? to 32k and scale MIN_? to keep ratio approximately
// correct
// MAJ_? = 32k
// MIN_? = (negative of ratio of src/dst) scaled up to 32k
// ACCUM_? = MAJ_? - 1 - (1/2 * Absolute difference of MAJ and MIN)
//
// 2) Scale both src and dst appropriately such that the ratio of
// src/dst is preserved exactly.
// Note: In the following, the division is performed first thus
// there is a possiblity of a rounding error which shows the
// difference between options 1 & 2.
// MAJ_? = (32k / dst) * dst
// MIN_? = (32k / dst) * src
// ACCUM_? = MAJ_? - 1 - (1/2 * Absolute difference of MAJ and MIN)
//
// 3) Scale both SRC and Dest in such a manner as to force the last
// pixels output on a line to match the last source pixels rather
// than the last source interpolated with the pixel past the end
// of the line. Option 3 is used here.
// NOTE: Options 1 and both oversample Src data and so will replicate
// last pixel in X and interpolate past end of data in Y
#ifdef OPTION_1 // Option 1
maj = _32K;
min = -((_32K * lSrc) / lDst);
#endif
#ifdef OPTION_2 // Option 2
maj = ((_32K / lDst) * lDst);
min = -((_32K / lDst) * lSrc);
#else // Option 3
lDst *= 4;
lSrc = lSrc * 4 - 3;
maj = ((_32K / lDst) * lDst);
min = -((_32K / lDst) * lSrc);
#endif
accum = maj - 1 - ((maj % -min) / (lDst/lSrc + 1));
};
if (chCoord == 'X')
{
REQUIRE(3);
LL16 (grMAJ_X, maj);
LL16 (grMIN_X, min);
LL16 (grACCUM_X, accum);
}
else
{
REQUIRE(3);
LL16 (grMAJ_Y, maj);
LL16 (grMIN_Y, min);
LL16 (grACCUM_Y, accum);
};
#ifdef DBGBRK
DISPDBG((1, "DrvStretchBlt - stretch\n"));
DbgBreakPoint();
#endif
}
/****************************************************************************
* FUNCTION NAME: CopySrcToOffMem()
*
* DESCRIPTION: This function copies source data from host memory to
* offscreen memory
*
* REVISION HISTORY:
* 7/18/95 Benny Ng Initial version
****************************************************************************/
VOID CopySrcToOffMem(PPDEV ppdev,
BYTE *pSrcScan0,
LONG sDelta,
LONG sszY,
POFMHDL SrcHandle)
{
LONG DWcnt;
LONG i, j, k;
LONG cnt;
BYTE *pSrcScan;
PDWORD pSrcData;
ULONG ultmp;
LONG Ycord;
HOST_DATA SrcData;
pSrcScan = pSrcScan0;
Ycord = SrcHandle->aligned_y;
// Clear Laguna Command Control Register SWIZ_CNTL bit
ppdev->grCONTROL = ppdev->grCONTROL & ~SWIZ_CNTL;
LL16(grCONTROL, ppdev->grCONTROL);
pSrcData = &SrcData.dwData;
DWcnt = sDelta / sizeof(DWORD);
// Setup the laguna registers for byte to byte BLT extents
REQUIRE(8);
LL16 (grBLTDEF, 0x1020);
LL16 (grDRAWDEF, 0x00CC);
LL16 (grOP1_opRDRAM.pt.X, 0);
// LL (grOP0_opMRDRAM.pt.X, SrcHandle->aligned_x);
// LL (grOP0_opMRDRAM.pt.Y, Ycord);
LL_OP0_MONO (SrcHandle->aligned_x + ppdev->ptlOffset.x, Ycord + ppdev->ptlOffset.y);
// LL (grMBLTEXT_EX.pt.X, sDelta);
// LL (grMBLTEXT_EX.pt.Y, sszY);
LL_MBLTEXT (sDelta, sszY);
cnt = DWcnt;
k = 0;
for (i=0; i < sszY; i++)
{
// Pre-fill the 32-bits pattern with default values
for (j=0; j < 4; j++)
SrcData.bData[j] = 0;
// Copy one screen line mask data from source to destination
for (j=0; j < sDelta; j++)
{
SrcData.bData[k++] = *pSrcScan;
pSrcScan++;
if (k > 3)
{
REQUIRE(1);
LL32 (grHOSTDATA[0], *pSrcData);
k = 0;
cnt--;
}; // endif (k > 3)
}; // endfor j
// Check whether one screen line of data are written to the
// HOSTDATA register.
if (cnt == 0)
{
// Reset the row data count
cnt = DWcnt;
}; // endif (cnt == 0)
}; // end for i
#ifdef DBGBRK
DISPDBG((0, "DrvStretchBlt-CopySrcToOffMem\n"));
DbgBreakPoint();
#endif
}
/****************************************************************************
* FUNCTION NAME: bStretchDIB()
*
* DESCRIPTION: StretchBlt using integer math. Must be from one surface
* to another surface of the same format.
*
* RETURN: TRUE: Punt it.
*
* REVISION HISTORY:
* 7/27/95 Benny Ng Initial version
****************************************************************************/
BOOL bStretchDIB(SURFOBJ* psoSrc,
SURFOBJ* psoMsk,
PDEV* ppdev,
VOID* pvDst,
LONG lDeltaDst,
RECTL* prclDst,
VOID* pvSrc,
LONG lDeltaSrc,
RECTL* prclSrc,
RECTL* prclClip)
{
LONG ltmp;
ULONG ultmp;
SIZEL reqsz;
LONG bpp;
BYTE *pSrcScan;
RECTL rclRes;
BOOL bNoBlt = FALSE;
BOOL bpuntit = TRUE;
POFMHDL SrcHandle = NULL;
long drawdef = 0;
long srcx = 0;
ULONG LnCntl = 0;
LONG sShrinkInc = 0;
LONG XsrcOff = 0;
LONG YsrcOff = 0;
// Calculate the rectange start points and sizes:
//
LONG WidthDst = prclDst->right - prclDst->left;
LONG HeightDst = prclDst->bottom - prclDst->top;
LONG WidthSrc = prclSrc->right - prclSrc->left;
LONG HeightSrc = prclSrc->bottom - prclSrc->top;
LONG XDstStart = prclDst->left;
LONG YDstStart = prclDst->top;
LONG XSrcStart = prclSrc->left;
LONG YSrcStart = prclSrc->top;
// -------------------------------------------------------
// Calculate bytes per pixel
bpp = ppdev->ulBitCount/8;
// Get the informations from source and destination surface
pSrcScan = pvSrc;
if (psoMsk != NULL)
{
#ifdef DBGDISP
DISPDBG((1, "DrvStretchBlt - HandleCase_1 mask pointer != NULL (punt it)\n"));
#endif
goto Punt_It;
};
// -------------------------------------------------------
// Check whether source is from host or video memory
if ((pSrcScan < ppdev->pjScreen) ||
(pSrcScan > (ppdev->pjScreen + ppdev->lTotalMem)))
{
#ifdef DBGDISP
DISPDBG((1, "DrvStretchBlt - HandleCase_1 - src host\n"));
#endif
// Allocate the offscreen memory for the source if not enough offscreen
// memory available punt it.
reqsz.cx = psoSrc->sizlBitmap.cx;
reqsz.cy = psoSrc->sizlBitmap.cy;
if ((SrcHandle = AllocOffScnMem(ppdev, &reqsz, PIXEL_AlIGN, NULL)) == NULL)
{ goto Punt_It; };
//?? bbbbbbbbbb
// Note: The following lines of code takes care the host data HW problem,
// it punt back to GDI when host data size is 29 to 30 to DWORD.
//
if ((lDeltaSrc >= 116) && (lDeltaSrc <= 120))
{
DISPDBG((1, "DrvStretchBlt - src host (punt it)\n"));
goto Punt_It;
};
//?? eeeeeeeeee
// Copy the source data into allocated offscreen memory
CopySrcToOffMem(ppdev,
pSrcScan,
lDeltaSrc,
HeightSrc,
SrcHandle);
XSrcStart = SrcHandle->aligned_x / bpp;
YSrcStart = SrcHandle->aligned_y;
}
else
{
#ifdef DBGDISP
DISPDBG((1, "DrvStretchBlt - HandleCase_1 - src videow\n"));
#endif
if ((WidthSrc * bpp) > ppdev->lDeltaScreen)
WidthSrc = ppdev->lDeltaScreen / bpp;
ltmp = ppdev->lTotalMem / ppdev->lDeltaScreen;
if (HeightSrc > ltmp)
HeightSrc = ltmp;
};
// -------------------------------------------------------
if (prclClip != NULL)
{
// Test for intersection of clipping rectangle and destination
// rectangle. If they don't intersect, go on for stretch BLT.
// For DC_RECT clipping we have a single clipping rectangle.
// We create a new destination rectangle which is the intersection
// between the old destination rectangle and the clipping rectangle.
// Then we adjust our source rectangle accordingly.
//
if (!bRectIntersect(prclDst, prclClip, &rclRes))
{
#ifdef DBGDISP
DISPDBG((1, "DrvStretchBlt - HandleCase_1 - DC_RECT no intersect\n"));
#endif
goto Punt_It;
};
// Adjust the source size
bNoBlt = AdjustSrcSize(rclRes.left, rclRes.top,
XDstStart, YDstStart,
(rclRes.right - rclRes.left),
(rclRes.bottom - rclRes.top),
WidthDst, HeightDst,
&WidthSrc, &HeightSrc,
&XsrcOff, &YsrcOff);
// Adjust the destination rectange size
XDstStart = rclRes.left;
YDstStart = rclRes.top;
WidthDst = rclRes.right - rclRes.left;
HeightDst = rclRes.bottom - rclRes.top;
}; // endif (prclClip != NULL)
if (!bNoBlt)
{
// -------------------------------------------------------
// Perform the shrink or stretch operation
// Set the shrink or interpolate bit in LNCNTL
if (WidthSrc >= WidthDst)
{
LnCntl |= X_SHRINK_ENABLE;
Shrink(ppdev, WidthSrc, WidthDst, 'X', LnCntl, &sShrinkInc);
}
else
{
Stretch(ppdev, WidthSrc, WidthDst, 'X', LnCntl);
};
if (HeightSrc >= HeightDst)
{
LnCntl |= Y_SHRINK_ENABLE;
Shrink(ppdev, HeightSrc, HeightDst, 'Y', LnCntl, &sShrinkInc);
}
else
{
Stretch(ppdev, HeightSrc, HeightDst, 'Y', LnCntl);
};
#ifdef DBGBRK
DISPDBG((1, "DrvStretchBlt - bStretchDIB - before exec\n"));
DbgBreakPoint();
#endif
// -------------------------------------------------------
XSrcStart += XsrcOff;
YSrcStart += YsrcOff;
// LL (grOP1_opRDRAM.pt.X, XSrcStart);
// LL (grOP1_opRDRAM.pt.Y, YSrcStart);
REQUIRE(12);
LL_OP1 (XSrcStart, YSrcStart);
LL16 (grSHRINKINC, sShrinkInc);
LL16 (grBLTDEF, 0x1010);
LL16 (grDRAWDEF, 0x00CC);
// Setup the shrink and interpolate bits in LNCNTL
ultmp = LLDR_SZ (grLNCNTL.w);
ultmp |= LnCntl;
LL16 (grLNCNTL, ultmp);
srcx = WidthSrc * bpp;
LL16 (grSRCX, srcx);
// LL (grOP0_opRDRAM.pt.X, XDstStart);
// LL (grOP0_opRDRAM.pt.Y, YDstStart);
LL_OP0 (XDstStart + ppdev->ptlOffset.x, YDstStart + ppdev->ptlOffset.y);
// LL (grBLTEXTR_EX.pt.X, WidthDst);
// LL (grBLTEXTR_EX.pt.Y, HeightDst);
LL_BLTEXTR (WidthDst, HeightDst);
#ifdef DBGBRK
DISPDBG((1, "DrvStretchBlt - bStretchDIB - after exec\n"));
DbgBreakPoint();
#endif
bpuntit = FALSE;
}; //endif (!bNoBlt)
Punt_It:
// -------------------------------------------------------
// Release the offscreen buffer if allocated
if (SrcHandle != NULL)
FreeOffScnMem(ppdev, SrcHandle);
return(bpuntit);
}
/****************************************************************************
* FUNCTION NAME: HandleCase_1()
*
* DESCRIPTION: This function handle the case when
* Both src and dst surface types are equal to STYPE_BITMAP,
* both src and dst surface have same iBitmapFormat,
* no color translation.
*
* RETURN: TRUE: Punt it.
*
* REVISION HISTORY:
* 7/18/95 Benny Ng Initial version
****************************************************************************/
BOOL HandleCase_1(SURFOBJ* psoDst,
SURFOBJ* psoSrc,
SURFOBJ* psoMsk,
CLIPOBJ* pco,
RECTL* prclDst,
RECTL* prclSrc,
POINTL* pptlMsk,
BOOL* bRet)
{
BOOL bpuntit = TRUE;
PDEV* ppdev = (PDEV*) psoDst->dhpdev;
BYTE iDComplexity;
PRECTL prclClip;
ENUMRECTS ce;
BOOL bMore;
LONG c;
LONG i;
*bRet = FALSE;
// -------------------------------------------------------
// CHeck what kind of clipping is it?
iDComplexity = (pco ? pco->iDComplexity : DC_TRIVIAL);
switch (iDComplexity)
{
case DC_TRIVIAL:
#ifdef DBGDISP
DISPDBG((1, "DrvStretchBlt - HandleCase_1 - DC_TRIVIAL\n"));
#endif
bpuntit = bStretchDIB(psoSrc,
psoMsk,
ppdev,
NULL,
psoDst->lDelta,
prclDst,
psoSrc->pvScan0,
psoSrc->lDelta,
prclSrc,
NULL);
break;
case DC_RECT:
#ifdef DBGDISP
DISPDBG((1, "DrvStretchBlt - HandleCase_1 - DC_RECT\n"));
#endif
// Get the clipping rectangle.
prclClip = &pco->rclBounds;
bpuntit = bStretchDIB(psoSrc,
psoMsk,
ppdev,
NULL,
psoDst->lDelta,
prclDst,
psoSrc->pvScan0,
psoSrc->lDelta,
prclSrc,
prclClip);
break;
case DC_COMPLEX:
#ifdef DBGDISP
DISPDBG((1, "DrvStretchBlt - HandleCase_1 - DC_COMPLEX\n"));
#endif
bpuntit = FALSE;
CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
do
{
bMore = CLIPOBJ_bEnum(pco, sizeof(ce), (ULONG*) &ce);
c = cRectIntersect(prclDst, ce.arcl, ce.c);
if (c != 0)
{
for (i = 0; i < c; i++)
{
bpuntit = bStretchDIB(psoSrc,
psoMsk,
ppdev,
NULL,
psoDst->lDelta,
prclDst,
psoSrc->pvScan0,
psoSrc->lDelta,
prclSrc,
&ce.arcl[i]);
if (bpuntit)
break;
}; // enddo
}; // endif
} while ((bMore) && (!bpuntit));
break;
default:
break;
}; // end switch (iDComplexity)
// -------------------------------------------------------
// Check whether the operation was handled successfully
if (!bpuntit)
*bRet = TRUE;
return (bpuntit);
}
/****************************************************************************
* FUNCTION NAME: DrvStretchBlt()
*
* DESCRIPTION: This function provides stretching bit-block transfer
* capabilities for Laguna NT
*
* REVISION HISTORY:
* 7/11/95 Benny Ng Initial version
****************************************************************************/
#define TSTFRIDO 1
BOOL DrvStretchBlt(SURFOBJ* psoDst,
SURFOBJ* psoSrc,
SURFOBJ* psoMsk,
CLIPOBJ* pco,
XLATEOBJ* pxlo,
COLORADJUSTMENT* pca,
POINTL* pptlHTOrg,
RECTL* prclDst,
RECTL* prclSrc,
POINTL* pptlMsk,
ULONG iMode)
{
BOOL bRet = TRUE;
BOOL bPuntIt = TRUE;
LONG HandleIt = 0;
#if NULL_STRETCH
{
if (pointer_switch) return TRUE;
}
#endif
#ifdef TSTFRIDO
{
PPDEV ppdev = (PPDEV) psoDst->dhpdev;
SYNC_W_3D(ppdev);
if (psoDst->iType == STYPE_DEVBITMAP)
{
PDSURF pdsurf = (PDSURF)psoDst->dhsurf;
if ( pdsurf->pso )
{
if ( !bCreateScreenFromDib(ppdev, pdsurf) )
{
return EngStretchBlt(psoDst, psoSrc, psoMsk, pco,
pxlo, pca, pptlHTOrg,
prclDst, prclSrc, pptlMsk, iMode);
};
};
ppdev->ptlOffset.x = pdsurf->ptl.x;
ppdev->ptlOffset.y = pdsurf->ptl.y;
}
else
{
if (ppdev != NULL)
ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0;
else
return(EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg,
prclDst, prclSrc, pptlMsk, iMode));
};
ppdev = (PPDEV) psoSrc->dhpdev;
if (psoSrc->iType == STYPE_DEVBITMAP)
{
PDSURF pdsurf = (PDSURF)psoSrc->dhsurf;
if ( pdsurf->pso )
{
if ( !bCreateScreenFromDib(ppdev, pdsurf) )
{
return EngStretchBlt(psoDst, psoSrc, psoMsk, pco,
pxlo, pca, pptlHTOrg,
prclDst, prclSrc, pptlMsk, iMode);
};
};
ppdev->ptlOffset.x = pdsurf->ptl.x;
ppdev->ptlOffset.y = pdsurf->ptl.y;
}
else
{
if (ppdev != NULL)
ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0;
else
return(EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg,
prclDst, prclSrc, pptlMsk, iMode));
};
}
#else
{
PPDEV ppdev = (PPDEV) psoDst->dhpdev;
SYNC_W_3D(ppdev);
}
bRet = EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg,
prclDst, prclSrc, pptlMsk, iMode);
return(bRet);
#endif
#ifdef DBGDISP
DISPDBG((1, "DrvStretchBlt - %d\n", iMode));
#endif
if ((psoDst->iType == psoSrc->iType) &&
(psoDst->fjBitmap == psoSrc->fjBitmap) &&
(psoDst->fjBitmap == BMF_TOPDOWN))
{
// If src and dst surface have same iBitmapFormat
if (psoDst->iBitmapFormat == psoSrc->iBitmapFormat)
{
// Check for color translation
if (pxlo == NULL)
{
HandleIt = 1;
}
else if ((pxlo != NULL) && (pxlo->iSrcType == pxlo->iDstType))
{
switch (pxlo->flXlate)
{
case XO_TRIVIAL:
case 0:
HandleIt = 1;
break;
default:
#ifdef DBGDISP
DISPDBG((1, "DrvStretchBlt - pxlo->flXlate (punt it)\n"));
#endif
break;
};
}; // endif (pxlo == NULL)
}; // endif (src and dst surface have same iBitmapFormat)
}; // endif (Both src and dst surface types are equal to STYPE_BITMAP)
// Check whether we can handle this case, if yes call the case
// handle routine to try to handle it. Otherwise punt it back to GDI
if (HandleIt != 0)
{
if (HandleIt == 1)
{
bPuntIt = HandleCase_1(psoDst,
psoSrc,
psoMsk,
pco,
prclDst,
prclSrc,
pptlMsk,
&bRet);
}
else if (HandleIt == 2)
{
};
}; // endif (HandleIt)
// -------------------------------------------------------
// Punt It back to GDI to handle it
if (bPuntIt)
{
DISPDBG((1, "DrvStretchBlt - punt it\n"));
#ifdef PUNTBRK
DbgBreakPoint();
#endif
bRet = EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg,
prclDst, prclSrc, pptlMsk, iMode);
};
return(bRet);
}