📄 pixelops.c
字号:
ui32Height = psSpanInfo->ui32Height;
i32X1 = psSpanInfo->i32ReadX;
i32Y1 = psSpanInfo->i32ReadY;
i32X2 = i32X1 + psSpanInfo->ui32Width;
i32Y2 = i32Y1 + psSpanInfo->ui32Height;
ui32SkipPixels = 0;
ui32SkipRows = 0;
if (i32X1 < i32ClipLeft)
{
ui32SkipPixels = i32ClipLeft - i32X1;
if (ui32SkipPixels > ui32Width)
return IMG_FALSE;
ui32Width -= ui32SkipPixels;
i32X1 = i32ClipLeft;
psSpanInfo->ui32DstSkipPixels += ui32SkipPixels;
psSpanInfo->i32ReadX = i32X1;
}
if (i32X2 > i32ClipRight)
{
i32Temp = i32X2 - i32ClipRight;
if (i32Temp > (IMG_INT32)ui32Width)
return IMG_FALSE;
ui32Width -= i32Temp;
}
if (i32Y1 < i32ClipTop)
{
ui32SkipRows = i32ClipTop - i32Y1;
if (ui32SkipRows > ui32Height)
return IMG_FALSE;
ui32Height -= ui32SkipRows;
i32Y1 = i32ClipTop;
psSpanInfo->ui32DstSkipLines += ui32SkipRows;
psSpanInfo->i32ReadY = i32Y1;
}
if (i32Y2 > i32ClipBottom)
{
i32Temp = i32Y2 - i32ClipBottom;
if (i32Temp > (IMG_INT32)ui32Height)
return IMG_FALSE;
ui32Height -= i32Temp;
}
psSpanInfo->ui32Width = ui32Width;
psSpanInfo->ui32Height = ui32Height;
return IMG_TRUE;
}
/***********************************************************************************
Function Name : ElementsPerGroup
Inputs : format, type
Outputs : -
Returns : Number of elements per group
Description : UTILITY: Return the number of elements per group of a
specified format. If the type is packed pixel, the number of
elements per group is understood to be one.
************************************************************************************/
static IMG_UINT32 ElementsPerGroup(GLenum format, GLenum type)
{
switch(type)
{
case GL_UNSIGNED_SHORT_5_6_5:
return 1;
default:
break;
}
switch(format)
{
case GL_RGB:
return 3;
case GL_RGBA:
return 4;
case GL_LUMINANCE_ALPHA:
return 2;
default:
return 1;
}
}
/***********************************************************************************
Function Name : BytesPerElement
Inputs : type
Outputs : -
Returns : Number of bytes per element
Description : UTILITY: Return the number of bytes per element, based on the
element type
************************************************************************************/
static IMG_UINT32 BytesPerElement(GLenum type)
{
switch(type)
{
case GL_UNSIGNED_SHORT_5_6_5:
return 2;
case GL_UNSIGNED_BYTE:
return 1;
default:
return 0;
}
}
/***********************************************************************************
Function Name : BytesPerPixel
Inputs : ePixelFormat
Outputs : -
Returns : Number of bytes pixels
Description : UTILITY: Return the number of bytes per element, based on the
element type
************************************************************************************/
static IMG_UINT32 BytesPerPixel(PVRSRV_PIXEL_FORMAT ePixelFormat)
{
switch(ePixelFormat)
{
case PVRSRV_PIXEL_FORMAT_RGB565:
return 2;
case PVRSRV_PIXEL_FORMAT_ARGB8888:
return 4;
default:
DPF((DBG_ERROR,"Unknown pixel format"));
return 0;
}
}
/***********************************************************************************
Function Name : SetupReadPixelsSpanInfo
Inputs : gc, psSpanInfo, i32X, u32Y, ui32Width, ui32Height, format, type,
bUsePackAlignment, psReadParams
Outputs : psSpanInfo
Returns : Anything to read.
Description : UTILITY: Sets up the spanInfo structure for a readpixels.
************************************************************************************/
IMG_BOOL SetupReadPixelsSpanInfo(GLESContext *gc, GLESpixelSpanInfo *psSpanInfo, IMG_INT32 i32X, IMG_INT32 i32Y,
IMG_UINT32 ui32Width, IMG_UINT32 ui32Height, GLenum format, GLenum type, IMG_BOOL bUsePackAlignment,
GLESDrawableParams *psReadParams)
{
IMG_UINT32 ui32Alignment, ui32Padding;
psSpanInfo->i32ReadX = i32X;
psSpanInfo->i32ReadY = i32Y;
psSpanInfo->ui32Width = ui32Width;
psSpanInfo->ui32Height = ui32Height;
if (!ClipReadPixels(gc, psSpanInfo, psReadParams))
{
return IMG_FALSE;
}
/* bUsePackAlignment: This is set for readpixels, but not for copytexture */
ui32Alignment = bUsePackAlignment ? gc->sClientPixel.ui32PackAlignment : 1;
psSpanInfo->i32DstGroupIncrement = BytesPerElement(type) * ElementsPerGroup(format, type);
psSpanInfo->i32DstRowIncrement = ui32Width * psSpanInfo->i32DstGroupIncrement;
ui32Padding = (psSpanInfo->i32DstRowIncrement % ui32Alignment);
if (ui32Padding)
{
psSpanInfo->i32DstRowIncrement += ui32Alignment - ui32Padding;
}
switch(psReadParams->eRotationAngle)
{
case ROTATE_0:
psSpanInfo->i32SrcGroupIncrement = BytesPerPixel(psReadParams->ePixelFormat);
psSpanInfo->i32SrcRowIncrement = -(IMG_INT32)psReadParams->ui32Stride;
psSpanInfo->i32ReadY = 1 + psSpanInfo->i32ReadY - psReadParams->ui32Height;
break;
case ROTATE_90:
psSpanInfo->i32SrcGroupIncrement = -(IMG_INT32)(psReadParams->ui32Stride);
psSpanInfo->i32SrcRowIncrement = -(IMG_INT32)BytesPerPixel(psReadParams->ePixelFormat);
psSpanInfo->i32ReadX = 1 + psSpanInfo->i32ReadX - psReadParams->ui32Height;
psSpanInfo->i32ReadY = 1 + psSpanInfo->i32ReadY - psReadParams->ui32Width;
break;
case ROTATE_180:
psSpanInfo->i32SrcGroupIncrement = -(IMG_INT32)(BytesPerPixel(psReadParams->ePixelFormat));
psSpanInfo->i32SrcRowIncrement = (IMG_INT32)psReadParams->ui32Stride;
psSpanInfo->i32ReadX = 1 + psSpanInfo->i32ReadX - psReadParams->ui32Width;
break;
case ROTATE_270:
psSpanInfo->i32SrcGroupIncrement = psReadParams->ui32Stride;
psSpanInfo->i32SrcRowIncrement = (IMG_INT32)BytesPerPixel(psReadParams->ePixelFormat);
break;
}
return IMG_TRUE;
}
/***********************************************************************************
Function Name : glReadPixels
Inputs : x, y, width, height, format, type
Outputs : pixels
Returns : -
Description : ENTRYPOINT: Reads color pixels from the frame buffer.
Will require a render and wait for completion.
Format conversion follows from this.
************************************************************************************/
GLAPI void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLvoid *pixels)
{
GLESpixelSpanInfo sSpanInfo = {0};
IMG_VOID (*pfnReadSpan)(GLESContext *gc, GLESpixelSpanInfo *psSpanInfo) = IMG_NULL;
GLESDrawableParams sReadParams;
IMG_VOID *pvSurfacePointer;
IMG_UINT32 i;
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMER_READPIXELS_TIME);
GLES_TIME_START(GLES_TIMES_glReadPixels);
if(!CheckReadPixelArgs(gc, width, height, format, type, &pfnReadSpan))
{
GLES_TIME_STOP(GLES_TIMER_READPIXELS_TIME);
return;
}
GLESGetDrawableParameters(gc->hReadDrawable, &sReadParams);
if(!SetupReadPixelsSpanInfo(gc, &sSpanInfo, x, y, (IMG_UINT32)width, (IMG_UINT32)height,
format, type, IMG_TRUE, &sReadParams))
{
GLES_TIME_STOP(GLES_TIMER_READPIXELS_TIME);
return;
}
if(FlushHW(gc, (GLESRenderSurface *)sReadParams.hRenderSurface, IMG_TRUE) != IMG_GLES_NO_ERROR)
{
DPF((DBG_ERROR,"Couldn't flush HW"));
GLES_TIME_STOP(GLES_TIMER_READPIXELS_TIME);
return;
}
pvSurfacePointer = sReadParams.pvLinSurfaceAddress;
sSpanInfo.pvOutData = (IMG_VOID *) (((IMG_UINT8*) pixels) +
sSpanInfo.ui32DstSkipLines * sSpanInfo.i32DstRowIncrement +
sSpanInfo.ui32DstSkipPixels * sSpanInfo.i32DstGroupIncrement);
sSpanInfo.pvInData = (IMG_VOID *) (((IMG_UINT8*) pvSurfacePointer) +
sSpanInfo.i32ReadY * sSpanInfo.i32SrcRowIncrement +
sSpanInfo.i32ReadX * sSpanInfo.i32SrcGroupIncrement);
for (i=0; i<sSpanInfo.ui32Height; i++)
{
(*pfnReadSpan)(gc, &sSpanInfo);
sSpanInfo.pvOutData = (IMG_VOID *) ((IMG_UINT8 *) sSpanInfo.pvOutData + sSpanInfo.i32DstRowIncrement);
sSpanInfo.pvInData = (IMG_VOID *) ((IMG_UINT8 *)sSpanInfo.pvInData + sSpanInfo.i32SrcRowIncrement);
}
GLES_TIME_STOP(GLES_TIMES_glReadPixels);
GLES_TIME_STOP(GLES_TIMER_READPIXELS_TIME);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -