📄 fb.c
字号:
/**************************************************************************
* Name : fb.c
* Author : BCB
* Created : 01/05/2003
*
* Copyright : 2003 by Imagination Technologies Limited. All rights reserved.
* : No part of this software, either material or conceptual
* : may be copied or distributed, transmitted, transcribed,
* : stored in a retrieval system or translated into any
* : human or computer language in any form by any means,
* : electronic, mechanical, manual or other-wise, or
* : disclosed to third parties without the express written
* : permission of Imagination Technologies Limited, Unit 8, HomePark
* : Industrial Estate, King's Langley, Hertfordshire,
* : WD4 8LZ, U.K.
*
* Platform : ANSI
*
* $Date: 2004/11/04 17:26:44 $ $Revision: 1.77.1.1 $
* $Log: fb.c $
*
* --- Revision Logs Removed ---
**************************************************************************/
#define MODULE_ID MODID_FB
#include "context.h"
#include "pvr3dif.h"
#include "slaveport.h"
#include "mbx1defs.h"
/***********************************************************************************
Function Name : glDepthMask
Inputs : flag
Outputs : -
Returns : -
Description : ENTRYPOINT: Sets depthbuffer writemask state. Sets the depth
write disable bit directly in ISPTSP control word.
************************************************************************************/
GLAPI void APIENTRY glDepthMask(GLboolean flag)
{
IMG_BOOL bEnabled;
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMES_glDepthMask);
bEnabled = (gc->sState.sDepth.ui32TestFunc & MBX1_ISPTSPCTL_DWDISABLE) ? IMG_FALSE : IMG_TRUE;
if(bEnabled != flag)
{
if(flag)
{
gc->sState.sDepth.ui32TestFunc &= ~MBX1_ISPTSPCTL_DWDISABLE;
}
else
{
gc->sState.sDepth.ui32TestFunc |= MBX1_ISPTSPCTL_DWDISABLE;
}
gc->ui32DirtyMask |= GLES_DIRTY_HW_ISPTSP;
}
GLES_TIME_STOP(GLES_TIMES_glDepthMask);
}
/***********************************************************************************
Function Name : glColorMask
Inputs : red, green, blue, alpha
Outputs : -
Returns : -
Description : ENTRYPOINT: Sets colorbuffer writemask state. Cannot be handled
fully. Some cases can be achieved using TAG write disable/
frame buffer blending.
************************************************************************************/
GLAPI void APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
{
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMES_glColorMask);
gc->sState.sRaster.ui32ColorMask = (alpha << 3) | (blue << 2) | (green << 1) | red;
gc->ui32DirtyMask |= GLES_DIRTY_HW_ISPTSP;
GLES_TIME_STOP(GLES_TIMES_glColorMask);
}
/***********************************************************************************
Function Name : glStencilMask
Inputs : mask
Outputs : -
Returns : -
Description : ENTRYPOINT: Sets stencilbuffer writemask state. Unsupported.
************************************************************************************/
GLAPI void APIENTRY glStencilMask(GLuint mask)
{
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMES_glStencilMask);
gc->sState.sStencil.ui32WriteMask = mask;
GLES_TIME_STOP(GLES_TIMES_glStencilMask);
}
/***********************************************************************************
Function Name : glScissor
Inputs : x, y, width, height
Outputs : -
Returns : -
Description : ENTRYPOINT: Sets current scissor state. Implemented with ISP
viewport objects. We should cache scissor calls and enables if
possible to avoid sending too much geometry.
Note: clears are affected by scissor as well
************************************************************************************/
GLAPI void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
IMG_UINT32 ui32Width, ui32Height;
IMG_INT32 i32X, i32Y;
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMES_glScissor);
if ((width < 0) || (height < 0))
{
SetError(gc, GL_INVALID_VALUE);
GLES_TIME_STOP(GLES_TIMES_glScissor);
return;
}
switch(gc->sDrawableParams.eRotationAngle)
{
case ROTATE_0:
case ROTATE_180:
default:
i32X = x;
i32Y = y;
ui32Width = (IMG_UINT32) width;
ui32Height = (IMG_UINT32) height;
break;
case ROTATE_90:
case ROTATE_270:
i32X = y;
i32Y = x;
ui32Width = (IMG_UINT32) height;
ui32Height = (IMG_UINT32) width;
break;
}
/* return if nothing changed */
if ((i32X == gc->sState.sScissor.i32ScissorX) &&
(i32Y == gc->sState.sScissor.i32ScissorY) &&
(ui32Width == gc->sState.sScissor.ui32ScissorWidth) &&
(ui32Height == gc->sState.sScissor.ui32ScissorHeight))
{
return;
}
/* Flush a clear if needed */
if (gc->sClear.ui32ClearFlags)
{
/* If we can't flush clears - just continue to record state. */
if(PrepareToDraw(gc))
{
GLESReleaseTA(gc, IMG_FALSE);
}
else
{
DPF((DBG_ERROR,"Can't flush clears"));
}
}
gc->sState.sScissor.i32ScissorX = i32X;
gc->sState.sScissor.i32ScissorY = i32Y;
gc->sState.sScissor.ui32ScissorWidth = ui32Width;
gc->sState.sScissor.ui32ScissorHeight = ui32Height;
gc->bDrawMaskInvalid = IMG_TRUE;
if(i32X == 0 && i32Y == 0 && ui32Width == gc->sDrawableParams.ui32Width && ui32Height == gc->sDrawableParams.ui32Height)
gc->bFullScreenScissor = IMG_TRUE;
else
gc->bFullScreenScissor = IMG_FALSE;
GLES_TIME_STOP(GLES_TIMES_glScissor);
}
/***********************************************************************************
Function Name : RotateViewportScissor
Inputs : gc
Outputs : -
Returns : -
Description : Rotates the viewport + scissor state
************************************************************************************/
static IMG_VOID RotateViewportScissor(GLESContext *gc)
{
IMG_INT32 i32X;
IMG_UINT32 ui32Width;
i32X = gc->sState.sViewport.i32X;
gc->sState.sViewport.i32X = gc->sState.sViewport.i32Y;
gc->sState.sViewport.i32Y = i32X;
ui32Width = gc->sState.sViewport.ui32Width;
gc->sState.sViewport.ui32Width = gc->sState.sViewport.ui32Height;
gc->sState.sViewport.ui32Height = ui32Width;
i32X = gc->sState.sScissor.i32ScissorX;
gc->sState.sScissor.i32ScissorX = gc->sState.sScissor.i32ScissorY;
gc->sState.sScissor.i32ScissorY = i32X;
ui32Width = gc->sState.sScissor.ui32ScissorWidth;
gc->sState.sScissor.ui32ScissorWidth = gc->sState.sScissor.ui32ScissorHeight;
gc->sState.sScissor.ui32ScissorHeight = ui32Width;
}
/***********************************************************************************
Function Name : SetClearSize
Inputs : gc
Outputs : -
Returns : -
Description : Attempts to generate correct clear primitive size, based on
scissor state, drawable size & window clipping.
************************************************************************************/
static IMG_VOID SetClearSize(GLESContext *gc)
{
GLESDrawableParams *psDrawParams = &gc->sDrawableParams;
GLESclearMachine *psClear = &gc->sClear;
IMG_INT32 i32NewClearX0, i32NewClearY0, i32NewClearX1, i32NewClearY1;
if(gc->ui32FrameEnables & GLES_FS_SCISSOR_ENABLE)
{
switch(psDrawParams->eRotationAngle)
{
case ROTATE_0:
default:
i32NewClearX0 = gc->sState.sScissor.i32ScissorX;
i32NewClearY0 = psDrawParams->ui32Height - (gc->sState.sScissor.i32ScissorY + gc->sState.sScissor.ui32ScissorHeight);
break;
case ROTATE_90:
i32NewClearX0 = psDrawParams->ui32Width - (gc->sState.sScissor.i32ScissorX + gc->sState.sScissor.ui32ScissorWidth);
i32NewClearY0 = psDrawParams->ui32Height - (gc->sState.sScissor.i32ScissorY + gc->sState.sScissor.ui32ScissorHeight);
break;
case ROTATE_180:
i32NewClearX0 = psDrawParams->ui32Width - (gc->sState.sScissor.i32ScissorX + gc->sState.sScissor.ui32ScissorWidth);
i32NewClearY0 = gc->sState.sScissor.i32ScissorY;
break;
case ROTATE_270:
i32NewClearX0 = gc->sState.sScissor.i32ScissorX;
i32NewClearY0 = gc->sState.sScissor.i32ScissorY;
break;
}
i32NewClearX1 = i32NewClearX0 + gc->sState.sScissor.ui32ScissorWidth;
i32NewClearY1 = i32NewClearY0 + gc->sState.sScissor.ui32ScissorHeight;
if(i32NewClearX1 > (IMG_INT32)psDrawParams->ui32Width)
i32NewClearX1 = psDrawParams->ui32Width;
if(i32NewClearY1 > (IMG_INT32)psDrawParams->ui32Height)
i32NewClearY1 = psDrawParams->ui32Height;
}
else
{
i32NewClearX0 = 0;
i32NewClearY0 = 0;
i32NewClearX1 = psDrawParams->ui32Width;
i32NewClearY1 = psDrawParams->ui32Height;
}
if (psClear->ui32ClearFlags
&& (psClear->i32ClearX0 != i32NewClearX0
|| psClear->i32ClearY0 != i32NewClearY0
|| psClear->i32ClearX1 != i32NewClearX1
|| psClear->i32ClearY1 != i32NewClearY1))
{
/* If we can't flush clears - just continue to record state. */
if(PrepareToDraw(gc))
{
GLESReleaseTA(gc, IMG_FALSE);
}
else
{
DPF((DBG_ERROR,"Can't flush clears"));
}
}
psClear->i32ClearX0 = i32NewClearX0;
psClear->i32ClearY0 = i32NewClearY0;
psClear->i32ClearX1 = i32NewClearX1;
psClear->i32ClearY1 = i32NewClearY1;
}
/***********************************************************************************
Function Name : glClear
Inputs : mask
Outputs : -
Returns : -
Description : ENTRYPOINT: Clears buffers specified by mask.
Stencil clears will be ignored.
If a frame has not been started clears can go through start of
frame, otherwise they are sent as primitives - they ARE affected
by current scissor. Most stored ISPTSP state must be overridden
for these primitives.
All clears will be sent with Depth func always.
A color clear will be sent with depth write disable.
A depth clear will be sent with depth write enable and TAG write disable.
A clear of both color and depth will be sent depth write enable and
TAG write enable.
************************************************************************************/
GLAPI void APIENTRY glClear(GLbitfield mask)
{
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMES_glClear);
if (mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT))
{
SetError(gc, GL_INVALID_VALUE);
GLES_TIME_STOP(GLES_TIMES_glClear);
return;
}
SetClearSize(gc);
if (mask & GL_COLOR_BUFFER_BIT)
{
if(gc->sState.sRaster.ui32ColorMask)
{
gc->sClear.ui32ClearColor = gc->sState.sRaster.ui32ClearColor;
gc->sClear.ui32ClearFlags |= GLES_CLEARFLAG_COLOR;
}
}
if ((mask & GL_DEPTH_BUFFER_BIT) && gc->psMode->bHaveDepthBuffer &&
!(gc->sState.sDepth.ui32TestFunc & MBX1_ISPTSPCTL_DWDISABLE))
{
gc->sClear.fClearDepth = gc->sState.sDepth.fClear;
gc->sClear.ui32ClearFlags |= GLES_CLEARFLAG_DEPTH;
}
GLES_TIME_STOP(GLES_TIMES_glClear);
}
/***********************************************************************************
Function Name : glClearColor(x)
Inputs : red, green, blue, alpha
Outputs : -
Returns : -
Description : ENTRYPOINT: Stores color of clear internally.
Used when clear primitives/start of frame clears are sent.
************************************************************************************/
#if defined(PROFILE_COMMON)
GLAPI void APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
GLEScolor sCol;
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMES_glClearColor);
sCol.fRed = Clampf(red, GLES_Zero, GLES_One);
sCol.fGreen = Clampf(green, GLES_Zero, GLES_One);
sCol.fBlue = Clampf(blue, GLES_Zero, GLES_One);
sCol.fAlpha = Clampf(alpha, GLES_Zero, GLES_One);
gc->sState.sRaster.ui32ClearColor = ColorConvertToHWFormat(&sCol);
GLES_TIME_STOP(GLES_TIMES_glClearColor);
}
#endif
GLAPI void APIENTRY glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
{
GLEScolor sCol;
__GL_GET_CONTEXT();
GLES_TIME_STOP(GLES_TIMES_glClearColorx);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -