|
|
/******************************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; } }
|