📄 blitsw.c
字号:
do
{
if((*psDestMemInfo->psSyncInfo->pui32LastWriteOp == ui32DstNextWriteOpVal - 1)
&& (psDestMemInfo->psSyncInfo->ui32ReadOpsComplete == ui32DstReadOpsPending))
{
if(psSourceSurface != IMG_NULL)
{
if(*psSourceMemInfo->psSyncInfo->pui32LastWriteOp == ui32SrcNextWriteOpVal - 1)
{
bTimeout = IMG_FALSE;
break;
}
}
else
{
bTimeout = IMG_FALSE;
break;
}
}
if(bStart == IMG_FALSE)
{
bStart = IMG_TRUE;
uiStart = HostClockus();
}
HostWaitus(MAX_HW_TIME_US/(WAIT_TRY_COUNT));
if(GetDevInfo(psDestSurface->psContext)->sDeviceSpecific.s3D.b3DIdle)
{
SysKickCmdProc(GetKickerAddress(psDestSurface->psContext));
}
} while ((HostClockus() - uiStart) < MAX_HW_TIME_US);
if(bTimeout == IMG_TRUE)
{
D3DM_DPF((DPF_ERROR,"SoftwareBlit: Dependencies failed - Blitting anyway -"));
}
/* Get dest details */
psDestFMT = GetFormatDescriptorD3DM(psDestSurface->psContext, psDestSurface->eFormat);
if(psDestFMT == IMG_NULL) return FALSE;
ui32TargetWidth = (psDestRect->right - psDestRect->left);
ui32TargetHeight = (psDestRect->bottom - psDestRect->top);
bFilter = Filter == D3DMTEXF_LINEAR;
ui32DestBytesPerPixel = psDestFMT->dwBpp / 8;
ui32DestStrideBytes = psDestSurface->dwStrideByte;
ui32DestSurfaceWidth = (psDestSurface->eSurfaceType == D3DMRTYPE_TEXTURE) ?
psDestSurface->sDescription.sTexture.dwScaledWidth :
psDestSurface->dwWidth;
ui32DestSurfaceHeight = (psDestSurface->eSurfaceType == D3DMRTYPE_TEXTURE) ?
psDestSurface->sDescription.sTexture.dwScaledHeight :
psDestSurface->dwHeight;
/* Catch and perform ColourFill case */
if(psSourceSurface == IMG_NULL)
{
ui32TargetColour = ConvertFillColourToHWFormat(psDestSurface->eFormat, dwFillColour);
pui8Dest = ((IMG_UINT8*)psDestSurface->psMemInfo->pvLinAddr) +
psDestRect->top * ui32DestStrideBytes +
psDestRect->left * ui32DestBytesPerPixel;
for(i=0; i < ui32TargetHeight; i++)
{
for(j=0; j < ui32TargetWidth; j++)
{
WritePixelToBuffer(pui8Dest,
ui32TargetColour,
ui32DestStrideBytes,
j,
i,
ui32DestBytesPerPixel);
}
}
/* Update Syncs */
(*psDestMemInfo->psSyncInfo->pui32LastWriteOp)++;
return TRUE;
}
/* Get Source details */
psSourceFMT = GetFormatDescriptorD3DM(psSourceSurface->psContext, psSourceSurface->eFormat);
if(psSourceFMT == IMG_NULL) return FALSE;
ui32SourceWidth = (psSourceRect->right - psSourceRect->left);
ui32SourceHeight = (psSourceRect->bottom - psSourceRect->top);
if(dwRotationAngle == 0 || dwRotationAngle == 180)
{
bStretch = (ui32TargetWidth != ui32SourceWidth) ||
(ui32TargetHeight != ui32SourceHeight);
}
else
{
bStretch = (ui32TargetWidth != ui32SourceHeight) ||
(ui32TargetHeight != ui32SourceWidth);
}
ui32SrcBytesPerPixel = psSourceFMT->dwBpp / 8;
ui32SrcStrideBytes = psSourceSurface->dwStrideByte;
ui32SourceSurfaceWidth = (psSourceSurface->eSurfaceType == D3DMRTYPE_TEXTURE) ?
psSourceSurface->sDescription.sTexture.dwScaledWidth :
psSourceSurface->dwWidth;
ui32SourceSurfaceHeight = (psSourceSurface->eSurfaceType == D3DMRTYPE_TEXTURE) ?
psSourceSurface->sDescription.sTexture.dwScaledHeight :
psSourceSurface->dwHeight;
/* We need to assess the twiddle status of these surfaces */
if(psSourceSurface->dwFlags & D3DM_SURFACE_FLAGS_TWIDDLED)
{
UnTwiddleSurface(psSourceSurface);
}
if(psDestSurface->dwFlags & D3DM_SURFACE_FLAGS_TWIDDLED)
{
UnTwiddleSurface(psDestSurface);
}
/* Setup pointer to source Data */
pui8Src = ((IMG_UINT8*)psSourceSurface->psMemInfo->pvLinAddr) +
psSourceRect->top * ui32SrcStrideBytes +
psSourceRect->left * ui32SrcBytesPerPixel;
if(bStretch)
{
IMG_FLOAT fX, fY, fXRatio, fYRatio;
IMG_UINT32 ui32X1, ui32Y1, ui32X2, ui32Y2, ui32X3, ui32Y3, ui32X4, ui32Y4;
/* Allocate temporary surface for scale */
pui8Dest = D3DMAllocate((psDestRect->right - psDestRect->left) *
(psDestRect->bottom - psDestRect->top) *
(psSourceFMT->dwBpp / 8));
if(dwRotationAngle == 0 || dwRotationAngle == 180)
{
fXRatio = ((IMG_FLOAT) ui32SourceWidth) / ((IMG_FLOAT) ui32TargetWidth);
fYRatio = ((IMG_FLOAT) ui32SourceHeight) / ((IMG_FLOAT) ui32TargetHeight);
}
else
{
fXRatio = ((IMG_FLOAT) ui32SourceWidth) / ((IMG_FLOAT) ui32TargetHeight);
fYRatio = ((IMG_FLOAT) ui32SourceHeight) / ((IMG_FLOAT) ui32TargetWidth);
}
fX = 0.0f;
fY = 0.0f;
/* Scale and filter to temporary surface */
for(i=0; i < ui32TargetHeight; i++)
{
for(j=0; j < ui32TargetWidth; j++)
{
fX = ((IMG_FLOAT) j) * fXRatio;
fY = ((IMG_FLOAT) i) * fYRatio;
if(bFilter)
{
/* Linear interpolation of pixel values */
IMG_FLOAT fXFractPart, fXInvFractPart, fYFractPart, fYInvFractPart;
IMG_UINT32 ui32XPairInterpolated1, ui32XPairInterpolated2;
fXFractPart = fX - ((IMG_FLOAT)((IMG_UINT32)fX));
fYFractPart = fY - ((IMG_FLOAT)((IMG_UINT32)fY));
fXInvFractPart = 1.0f - fXFractPart;
fYInvFractPart = 1.0f - fYFractPart;
/* Grab the 4 nearest pixels */
GetNearestPixels(fX, fY, &ui32X1, &ui32Y1, &ui32X2, &ui32Y2, &ui32X3, &ui32Y3, &ui32X4, &ui32Y4);
/* Interpolate 1st horizontal pair */
ui32XPairInterpolated1 = InterpolatePixels(psSourceFMT,
GetPixelFromBuffer(pui8Src, ui32SrcStrideBytes, ui32X1, ui32Y1, ui32SrcBytesPerPixel),
fXInvFractPart,
GetPixelFromBuffer(pui8Src, ui32SrcStrideBytes, ui32X2, ui32Y2, ui32SrcBytesPerPixel),
fXFractPart);
/* Interpolate 2nd horizontal pair */
ui32XPairInterpolated2 = InterpolatePixels(psSourceFMT,
GetPixelFromBuffer(pui8Src, ui32SrcStrideBytes, ui32X3, ui32Y3, ui32SrcBytesPerPixel),
fXInvFractPart,
GetPixelFromBuffer(pui8Src, ui32SrcStrideBytes, ui32X4, ui32Y4, ui32SrcBytesPerPixel),
fXFractPart);
/* Interpolate Vertically */
ui32TargetColour = InterpolatePixels(psSourceFMT,
ui32XPairInterpolated1,
fYInvFractPart,
ui32XPairInterpolated2,
fYFractPart);
}
else
{
/* Find nearest pixel */
RoundPixel(fX, fY, &ui32X1, &ui32Y1);
ui32TargetColour = GetPixelFromBuffer(pui8Src,
ui32SrcStrideBytes,
ui32X1,
ui32Y1,
ui32SrcBytesPerPixel);
}
/* Copy pixel to temp buffer */
WritePixelToBuffer(pui8Dest,
ui32TargetColour,
(ui32TargetWidth * ui32SrcBytesPerPixel),
j,
i,
ui32SrcBytesPerPixel);
}
}
/* Modify the Src stride value */
ui32SrcStrideBytes = (ui32TargetWidth * ui32SrcBytesPerPixel);
/* Modify source width and height */
ui32SourceHeight = ui32TargetHeight;
ui32SourceWidth = ui32TargetWidth;
pui8Src = pui8Dest;
}
/* Set up pointer to destination buffer */
pui8Dest = ((IMG_UINT8*)psDestSurface->psMemInfo->pvLinAddr) +
psDestRect->top * ui32DestStrideBytes +
psDestRect->left * ui32DestBytesPerPixel;
/* Do copy convert with clipping and rotation */
for(i=0; i < ui32SourceHeight; i++)
{
for(j=0; j < ui32SourceWidth; j++)
{
IMG_UINT32 ui32X, ui32Y;
switch(dwRotationAngle)
{
case 0:
{
ui32X = j;
ui32Y = i;
break;
}
case 90:
case 180:
case 270:
{
RotatePixelCoords(j, i, &ui32X, &ui32Y, ui32TargetWidth, ui32TargetHeight, dwRotationAngle);
break;
}
}
if(dwNumClipRects > 0 && PixelIsClipped(psClipRects, dwNumClipRects, psDestSurface, psDestRect, ui32X, ui32Y))
{
continue;
}
else
{
if(psSourceFMT->sD3DDevFormat.Format == psDestFMT->sD3DDevFormat.Format)
{
/* Staight pixel copy */
WritePixelToBuffer(pui8Dest,
GetPixelFromBuffer(pui8Src, ui32SrcStrideBytes, j, i, ui32SrcBytesPerPixel),
ui32DestStrideBytes,
ui32X,
ui32Y,
ui32DestBytesPerPixel);
}
else
{
/* Copy Convert Pixel */
CopyConvertPixel(psSourceFMT,
pui8Src,
ui32SrcStrideBytes,
ui32SrcBytesPerPixel,
psDestFMT,
pui8Dest,
ui32DestStrideBytes,
ui32DestBytesPerPixel,
j,
i,
dwRotationAngle,
ui32TargetWidth,
ui32TargetHeight);
}
}
}
}
/* Update Sync Objects */
(*psDestMemInfo->psSyncInfo->pui32LastWriteOp)++;
psSourceMemInfo->psSyncInfo->ui32ReadOpsComplete++;
if(bStretch)
{
D3DMFree(pui8Src);
}
PROFILE_STOP_FUNC(SOFTWARE_BLIT);
return TRUE;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : SoftwareRotateBlit
PURPOSE : performs a software rotation blit to or from a temp buffer
RETURNS :
</function>
------------------------------------------------------------------------------*/
IMG_VOID SoftwareRotateBlit(LPD3DM_CONTEXT psContext,
LPD3DM_SURFACE psSourceSurface,
RECT *psSourceRect,
IMG_UINT8 *pui8DestSurface,
IMG_BOOL bBlitDesttoSource)
{
LONG i, j;
DWORD k;
DWORD dwDestByteStride, dwDestWidth, dwDestHeight, dwBytesPerPixel;
IMG_BOOL bFullScreen = IMG_FALSE;
D3DMRECT sRotatedSourceRect;
DWORD dwDestX, dwDestY;
IMG_UINT8 *pui8SourceData = (IMG_UINT8*)psSourceSurface->psMemInfo->pvLinAddr;
bFullScreen = (IMG_BOOL) RotateRects(psContext,
&sRotatedSourceRect,
(LPD3DMRECT)psSourceRect,
1,
psSourceSurface->dwWidth,
psSourceSurface->dwHeight);
dwDestWidth = (psSourceRect->right - psSourceRect->left);
dwDestHeight = (psSourceRect->bottom - psSourceRect->top);
dwBytesPerPixel = (psSourceSurface->dwBpp / 8);
dwDestByteStride = dwDestWidth * dwBytesPerPixel;
/* Select dest starting pixel */
switch(psContext->dwRotationAngle)
{
case 90:
{
dwDestX = dwDestWidth - 1;
dwDestY = 0;
break;
}
case 180:
{
dwDestX = dwDestWidth - 1;
dwDestY = dwDestHeight - 1;
break;
}
case 270:
{
dwDestX = 0;
dwDestY = dwDestHeight - 1;
break;
}
}
for(i = sRotatedSourceRect.y1; i < sRotatedSourceRect.y2; i++)
{
for(j = sRotatedSourceRect.x1; j < sRotatedSourceRect.x2; j++)
{
for(k = 0; k < dwBytesPerPixel; k++)
{
if(bBlitDesttoSource)
{
pui8SourceData[(i * psSourceSurface->dwStrideByte) + (j * dwBytesPerPixel) + k] =
pui8DestSurface[(dwDestY * dwDestByteStride) + (dwDestX * dwBytesPerPixel) + k];
}
else
{
pui8DestSurface[(dwDestY * dwDestByteStride) + (dwDestX * dwBytesPerPixel) + k] =
pui8SourceData[(i * psSourceSurface->dwStrideByte) + (j * dwBytesPerPixel) + k];
}
}
/* Select dest target pixel movement */
switch(psContext->dwRotationAngle)
{
case 90:
{
dwDestY++;
break;
}
case 180:
{
dwDestX--;
break;
}
case 270:
{
dwDestY--;
break;
}
}
}
/* Select dest target pixel movement */
switch(psContext->dwRotationAngle)
{
case 90:
{
dwDestX--;
dwDestY = 0;
break;
}
case 180:
{
dwDestX = dwDestWidth - 1;
dwDestY--;
break;
}
case 270:
{
dwDestX++;
dwDestY = dwDestHeight - 1;
break;
}
}
}
}
/*****************************************************************************
End of file (Blitsw.c)
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -