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.
 
 
 
 
 
 

671 lines
18 KiB

/******************************Module*Header*******************************\
* Module Name: srcblt32.cxx
*
* This contains the bitmap simulation functions that blt to a 32 bit/pel
* DIB surface.
*
* Created: 07-Feb-1991 19:27:49
* Author: Patrick Haluptzok patrickh
*
* Copyright (c) 1990-1999 Microsoft Corporation
*
\**************************************************************************/
#include "precomp.hxx"
// Turn off validations
#if 1
// On free builds, don't call any verification code:
#define VERIFYS16D32(psb)
#define VERIFYS24D32(psb)
#else
// On checked builds, verify the RGB conversions:
VOID VERIFYS16D32(PBLTINFO psb)
{
// We assume we are doing left to right top to bottom blting
ASSERTGDI(psb->xDir == 1, "vSrcCopyS16D32 - direction not left to right");
ASSERTGDI(psb->yDir == 1, "vSrcCopyS16D32 - direction not up to down");
// These are our holding variables
PUSHORT pusSrcTemp;
PULONG pulDstTemp;
ULONG cxTemp;
PUSHORT pusSrc = (PUSHORT) (psb->pjSrc + (2 * psb->xSrcStart));
PULONG pulDst = (PULONG) (psb->pjDst + (4 * psb->xDstStart));
ULONG cx = psb->cx;
ULONG cy = psb->cy;
XLATE *pxlo = psb->pxlo;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
while(1)
{
pusSrcTemp = pusSrc;
pulDstTemp = pulDst;
cxTemp = cx;
while(cxTemp--)
{
if (*(pulDstTemp++) != pxlo->ulTranslate((ULONG) *(pusSrcTemp++)))
RIP("RGB mis-match");
}
if (--cy)
{
pusSrc = (PUSHORT) (((PBYTE) pusSrc) + psb->lDeltaSrc);
pulDst = (PULONG) (((PBYTE) pulDst) + psb->lDeltaDst);
}
else
break;
}
}
VOID VERIFYS24D32(PBLTINFO psb)
{
// We assume we are doing left to right top to bottom blting
ASSERTGDI(psb->xDir == 1, "vSrcCopyS24D32 - direction not left to right");
ASSERTGDI(psb->yDir == 1, "vSrcCopyS24D32 - direction not up to down");
// These are our holding variables
ULONG ulDink; // variable to dink around with the bytes in
PBYTE pjSrcTemp;
PULONG pulDstTemp;
ULONG cxTemp;
PBYTE pjSrc = psb->pjSrc + (3 * psb->xSrcStart);
PULONG pulDst = (PULONG) (psb->pjDst + (4 * psb->xDstStart));
ULONG cx = psb->cx;
ULONG cy = psb->cy;
XLATE *pxlo = psb->pxlo;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
while(1)
{
pjSrcTemp = pjSrc;
pulDstTemp = pulDst;
cxTemp = cx;
while(cxTemp--)
{
ulDink = *(pjSrcTemp + 2);
ulDink = ulDink << 8;
ulDink |= (ULONG) *(pjSrcTemp + 1);
ulDink = ulDink << 8;
ulDink |= (ULONG) *pjSrcTemp;
if (*pulDstTemp != pxlo->ulTranslate(ulDink))
RIP("RGB mis-match");
pulDstTemp++;
pjSrcTemp += 3;
}
if (--cy)
{
pjSrc += psb->lDeltaSrc;
pulDst = (PULONG) (((PBYTE) pulDst) + psb->lDeltaDst);
}
else
break;
}
}
#endif
/*******************Public*Routine*****************\
* vSrcCopyS1D32
*
* This function loops through all the lines copying
* each one in three phases according to source
* alignment. The outer loop in x loops through
* the bits in the incomplete bytes (which might
* happen in the begining or the end of the sequence).
* When it comes to the first full byte, it
* goes into an internal x loop that copies 8
* bytes at a time, avoiding some branches, and
* allowing the processor to paraleliza these
* instructions, since there are no dependencies.
*
*
* History:
* 17-Nov-1998 -by- Andre Matos [amatos]
* Wrote it.
*
\**************************************************/
VOID vSrcCopyS1D32(PBLTINFO psb)
{
PBYTE pjSrc;
PBYTE pjDst;
ULONG cx = psb->cx;
ULONG cy = psb->cy;
PBYTE pjSrcTemp;
PULONG pjDstTemp;
ULONG cxTemp;
BYTE jSrc;
ULONG aulTable[2];
BYTE iPosSrc;
// We assume we are doing left to right top to bottom blting
ASSERTGDI(psb->xDir == 1, "vSrcCopyS1D32 - direction not left to right");
ASSERTGDI(psb->yDir == 1, "vSrcCopyS1D32 - direction not up to down");
// We shouldn't be called with an empty rectangle
ASSERTGDI( cx != 0 && cy != 0, "vSrcCopyS1D32 - called with an empty rectangle");
// Generate aulTable. 2 entries.
aulTable[0] = (ULONG)(psb->pxlo->pulXlate[0]);
aulTable[1] = (ULONG)(psb->pxlo->pulXlate[1]);
pjSrc = psb->pjSrc + (psb->xSrcStart >> 3);
pjDst = psb->pjDst + 4*psb->xDstStart;
while(cy--)
{
pjSrcTemp = pjSrc;
pjDstTemp = (PULONG)pjDst;
cxTemp = cx;
iPosSrc = (BYTE)(psb->xSrcStart & 0x07);
if( !iPosSrc )
{
// Decrement this since it will be
// incremented up front ahead
pjSrcTemp--;
}
else
{
jSrc = *pjSrcTemp << iPosSrc;
}
while (cxTemp)
{
if (!iPosSrc)
{
pjSrcTemp++;
if (cxTemp>=8)
{
while(cxTemp>= 8)
{
jSrc = *pjSrcTemp;
pjDstTemp[0] = aulTable[jSrc >> 7];
pjDstTemp[1] = aulTable[(jSrc >> 6) & 1];
pjDstTemp[2] = aulTable[(jSrc >> 5) & 1];
pjDstTemp[3] = aulTable[(jSrc >> 4) & 1];
pjDstTemp[4] = aulTable[(jSrc >> 3) & 1];
pjDstTemp[5] = aulTable[(jSrc >> 2) & 1];
pjDstTemp[6] = aulTable[(jSrc >> 1) & 1];
pjDstTemp[7] = aulTable[(jSrc & 1)];
pjSrcTemp++;
pjDstTemp += 8;
cxTemp -= 8;
}
pjSrcTemp--;
continue;
}
else
{
jSrc = *pjSrcTemp;
}
}
*pjDstTemp = aulTable[(jSrc >> 7) & 1];
jSrc <<= 1;
iPosSrc++;
iPosSrc &= 7;
pjDstTemp++;
cxTemp--;
}
pjSrc = pjSrc + psb->lDeltaSrc;
pjDst = pjDst + psb->lDeltaDst;
}
}
/******************************Public*Routine******************************\
* vSrcCopyS4D32
*
*
* History:
* 06-Feb-1991 -by- Patrick Haluptzok patrickh
* Wrote it.
\**************************************************************************/
VOID vSrcCopyS4D32(PBLTINFO psb)
{
// We assume we are doing left to right top to bottom blting
ASSERTGDI(psb->xDir == 1, "vSrcCopyS4D32 - direction not left to right");
ASSERTGDI(psb->yDir == 1, "vSrcCopyS4D32 - direction not up to down");
BYTE jSrc;
LONG i;
PULONG pulDst;
PBYTE pjSrc;
PULONG pulDstHolder = (PULONG) (psb->pjDst + (4 * psb->xDstStart));
PBYTE pjSrcHolder = psb->pjSrc + (psb->xSrcStart >> 1);
ULONG cy = psb->cy;
PULONG pulXlate = psb->pxlo->pulXlate;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
while(1)
{
pulDst = pulDstHolder;
pjSrc = pjSrcHolder;
i = psb->xSrcStart;
if (i & 0x00000001)
jSrc = *(pjSrc++);
while(i != psb->xSrcEnd)
{
if (i & 0x00000001)
*(pulDst++) = pulXlate[jSrc & 0x0F];
else
{
// We need a new byte
jSrc = *(pjSrc++);
*(pulDst++) = pulXlate[(((ULONG) (jSrc & 0xF0)) >> 4)];
}
++i;
}
if (--cy)
{
pjSrcHolder += psb->lDeltaSrc;
pulDstHolder = (PULONG) (((PBYTE) pulDstHolder) + psb->lDeltaDst);
}
else
break;
}
}
/******************************Public*Routine******************************\
* vSrcCopyS8D32
*
*
* History:
* 06-Feb-1991 -by- Patrick Haluptzok patrickh
* Wrote it.
\**************************************************************************/
VOID vSrcCopyS8D32(PBLTINFO psb)
{
// We assume we are doing left to right top to bottom blting
ASSERTGDI(psb->xDir == 1, "vSrcCopyS8D32 - direction not left to right");
ASSERTGDI(psb->yDir == 1, "vSrcCopyS8D32 - direction not up to down");
// These are our holding variables
PBYTE pjSrcTemp;
PULONG pulDstTemp;
ULONG cxTemp;
PBYTE pjSrc = psb->pjSrc + psb->xSrcStart;
PULONG pulDst = (PULONG) (psb->pjDst + (4 * psb->xDstStart));
ULONG cx = psb->cx;
ULONG cy = psb->cy;
PULONG pulXlate = psb->pxlo->pulXlate;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
while(1)
{
pjSrcTemp = pjSrc;
pulDstTemp = pulDst;
cxTemp = cx;
while(cxTemp--)
{
*(pulDstTemp++) = pulXlate[((ULONG) *(pjSrcTemp++))];
}
if (--cy)
{
pjSrc += psb->lDeltaSrc;
pulDst = (PULONG) (((PBYTE) pulDst) + psb->lDeltaDst);
}
else
break;
}
}
/******************************Public*Routine******************************\
* vSrcCopyS16D32
*
*
* History:
* 07-Feb-1991 -by- Patrick Haluptzok patrickh
* Wrote it.
\**************************************************************************/
VOID vSrcCopyS16D32(PBLTINFO psb)
{
// We assume we are doing left to right top to bottom blting
ASSERTGDI(psb->xDir == 1, "vSrcCopyS16D32 - direction not left to right");
ASSERTGDI(psb->yDir == 1, "vSrcCopyS16D32 - direction not up to down");
// These are our holding variables
PBYTE pjSrc = psb->pjSrc + (2 * psb->xSrcStart);
PBYTE pjDst = psb->pjDst + (4 * psb->xDstStart);
ULONG cx = psb->cx;
ULONG cy = psb->cy;
LONG lSrcSkip = psb->lDeltaSrc - (cx * 2);
LONG lDstSkip = psb->lDeltaDst - (cx * 4);
XLATE *pxlo = psb->pxlo;
XEPALOBJ palSrc(pxlo->ppalSrc);
XEPALOBJ palDst(pxlo->ppalDst);
ULONG ul;
ULONG ul0;
ULONG ul1;
LONG i;
ASSERTGDI(cy != 0,
"ERROR: Src Move cy == 0");
ASSERTGDI(palSrc.bIsBitfields(),
"ERROR: destination not bitfields");
// First, try to optimize 5-6-5 to BGR:
if ((palSrc.flBlu() == 0x001f) &&
(palSrc.flGre() == 0x07e0) &&
(palSrc.flRed() == 0xf800) &&
(palDst.bIsBGR()))
{
while (1)
{
i = cx;
do {
ul = *((USHORT*) pjSrc);
*((ULONG*) pjDst) = ((ul << 8) & 0xf80000)
| ((ul << 3) & 0x070000)
| ((ul << 5) & 0x00fc00)
| ((ul >> 1) & 0x000300)
| ((ul << 3) & 0x0000f8)
| ((ul >> 2) & 0x000007);
pjSrc += 2;
pjDst += 4;
} while (--i != 0);
if (--cy == 0)
break;
pjSrc += lSrcSkip;
pjDst += lDstSkip;
}
VERIFYS16D32(psb);
return;
}
// Next, try to optimize 5-5-5 to BGR:
if ((palSrc.flBlu() == 0x001f) &&
(palSrc.flGre() == 0x03e0) &&
(palSrc.flRed() == 0x7c00) &&
(palDst.bIsBGR()))
{
while (1)
{
i = cx;
do {
ul = *((USHORT*) pjSrc);
*((ULONG*) pjDst) = ((ul << 9) & 0xf80000)
| ((ul << 4) & 0x070000)
| ((ul << 6) & 0x00f800)
| ((ul << 1) & 0x000700)
| ((ul << 3) & 0x0000f8)
| ((ul >> 2) & 0x000007);
pjSrc += 2;
pjDst += 4;
} while (--i != 0);
if (--cy == 0)
break;
pjSrc += lSrcSkip;
pjDst += lDstSkip;
}
VERIFYS16D32(psb);
return;
}
// Finally, fall back to the generic case:
while (1)
{
i = cx;
do {
*((ULONG*) pjDst) = pxlo->ulTranslate(*((USHORT*) pjSrc));
pjSrc += 2;
pjDst += 4;
} while (--i != 0);
if (--cy == 0)
break;
pjSrc += lSrcSkip;
pjDst += lDstSkip;
}
VERIFYS16D32(psb);
}
/******************************Public*Routine******************************\
* vSrcCopyS24D32
*
*
* History:
* 06-Feb-1991 -by- Patrick Haluptzok patrickh
* Wrote it.
\**************************************************************************/
VOID vSrcCopyS24D32(PBLTINFO psb)
{
// We assume we are doing left to right top to bottom blting
ASSERTGDI(psb->xDir == 1, "vSrcCopyS24D32 - direction not left to right");
ASSERTGDI(psb->yDir == 1, "vSrcCopyS24D32 - direction not up to down");
// These are our holding variables
PBYTE pjSrc = psb->pjSrc + (3 * psb->xSrcStart);
PBYTE pjDst = psb->pjDst + (4 * psb->xDstStart);
ULONG cx = psb->cx;
ULONG cy = psb->cy;
LONG lSrcSkip = psb->lDeltaSrc - (cx * 3);
LONG lDstSkip = psb->lDeltaDst - (cx * 4);
PFN_pfnXlate pfnXlate;
XLATE *pxlo = psb->pxlo;
XEPALOBJ palSrc(pxlo->ppalSrc);
XEPALOBJ palDst(pxlo->ppalDst);
ULONG ul;
LONG i;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
// Try to optimize BGR to BGR:
if (palSrc.bIsBGR() && palDst.bIsBGR())
{
while (1)
{
i = cx;
do {
*((ULONG*) pjDst) = (*(pjSrc))
| (*(pjSrc + 1) << 8)
| (*(pjSrc + 2) << 16);
pjDst += 4;
pjSrc += 3;
} while (--i != 0);
if (--cy == 0)
break;
pjSrc += lSrcSkip;
pjDst += lDstSkip;
}
VERIFYS24D32(psb);
return;
}
// Fall back to the generic case:
pfnXlate = pxlo->pfnXlateBetweenBitfields();
while (1)
{
i = cx;
do {
ul = ((ULONG) *(pjSrc))
| ((ULONG) *(pjSrc + 1) << 8)
| ((ULONG) *(pjSrc + 2) << 16);
*((ULONG*) pjDst) = pfnXlate(pxlo, ul);
pjDst += 4;
pjSrc += 3;
} while (--i != 0);
if (--cy == 0)
break;
pjSrc += lSrcSkip;
pjDst += lDstSkip;
}
VERIFYS24D32(psb);
}
/******************************Public*Routine******************************\
* vSrcCopyS32D32
*
*
* History:
* 07-Feb-1991 -by- Patrick Haluptzok patrickh
* Wrote it.
\**************************************************************************/
VOID vSrcCopyS32D32(PBLTINFO psb)
{
// We assume we are doing left to right top to bottom blting.
// If it was on the same surface it would be the identity case.
ASSERTGDI(psb->xDir == 1, "vSrcCopyS32D32 - direction not left to right");
ASSERTGDI(psb->yDir == 1, "vSrcCopyS32D32 - direction not up to down");
// These are our holding variables
PULONG pulSrcTemp;
PULONG pulDstTemp;
ULONG cxTemp;
PULONG pulSrc = (PULONG) (psb->pjSrc + (4 * psb->xSrcStart));
PULONG pulDst = (PULONG) (psb->pjDst + (4 * psb->xDstStart));
ULONG cx = psb->cx;
ULONG cy = psb->cy;
XLATE *pxlo = psb->pxlo;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
while(1)
{
pulSrcTemp = pulSrc;
pulDstTemp = pulDst;
cxTemp = cx;
while(cxTemp--)
{
*(pulDstTemp++) = pxlo->ulTranslate(*(pulSrcTemp++));
}
if (--cy)
{
pulSrc = (PULONG) (((PBYTE) pulSrc) + psb->lDeltaSrc);
pulDst = (PULONG) (((PBYTE) pulDst) + psb->lDeltaDst);
}
else
break;
}
}
/******************************Public*Routine******************************\
* vSrcCopyS32D32Identity
*
* This is the special case no translate blting. All the SmDn should have
* them if m==n. Identity xlates only occur amoung matching format bitmaps.
*
* History:
* 06-Feb-1991 -by- Patrick Haluptzok patrickh
* Wrote it.
\**************************************************************************/
VOID vSrcCopyS32D32Identity(PBLTINFO psb)
{
// These are our holding variables
PULONG pulSrc = (PULONG) (psb->pjSrc + (4 * psb->xSrcStart));
PULONG pulDst = (PULONG) (psb->pjDst + (4 * psb->xDstStart));
ULONG cx = psb->cx;
ULONG cy = psb->cy;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
if (psb->xDir < 0)
{
pulSrc -= (cx - 1);
pulDst -= (cx - 1);
}
cx = cx << 2;
while(1)
{
if(psb->fSrcAlignedRd)
vSrcAlignCopyMemory((PBYTE)pulDst, (PBYTE)pulSrc, cx);
else
RtlMoveMemory((PVOID)pulDst, (PVOID)pulSrc, cx);
if (--cy)
{
pulSrc = (PULONG) (((PBYTE) pulSrc) + psb->lDeltaSrc);
pulDst = (PULONG) (((PBYTE) pulDst) + psb->lDeltaDst);
}
else
break;
}
}