📄 names.c
字号:
/**************************************************************************
* Name : names.c
* Author : BCB
* Created : 29/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/10/26 09:10:30 $ $Revision: 1.5.1.3 $
* $Log: names.c $
**************************************************************************/
#define MODULE_ID MODID_NAMES
#include "context.h"
/***********************************************************************************
Function Name : CreateNamedItem
Inputs : gc, psNamesArray, ui32Name
Outputs : -
Returns : New named item
Description : UTILITY: Creates a new named item and links it into namesarray.
Removes the ui32Name from the freelist.
************************************************************************************/
static GLESnamedItem *CreateNamedItem(GLESContext *gc, GLESnamesArray *psNamesArray, IMG_UINT32 ui32Name)
{
GLESnamedItem *psNamedItem, *psTmpItem;
GLESnameSpan *psSpan, *psTmpSpan, **ppsPrevSpan;
IMG_UINT32 ui32HashVal;
ui32HashVal = HASH(ui32Name);
psTmpItem = psNamesArray->apsItem[ui32HashVal];
psNamedItem = GLESCalloc(gc, sizeof(GLESnamedItem));
psNamedItem->ui32Name = ui32Name;
if(psTmpItem)
{
psNamedItem->psNext = psTmpItem->psNext;
psTmpItem->psNext = psNamedItem;
}
else
{
psNamesArray->apsItem[ui32HashVal] = psNamedItem;
}
psSpan = psNamesArray->psFreeNameSpan;
ppsPrevSpan = &psNamesArray->psFreeNameSpan;
/* Remove item from free list */
while (psSpan)
{
if ((ui32Name == psSpan->ui32Start) || (ui32Name == psSpan->ui32End))
{
/* Easy cases: ui32Name is beginning or end of a psSpan - just reduce the psSpan */
if (ui32Name == psSpan->ui32Start)
{
psSpan->ui32Start++;
}
else if (ui32Name == psSpan->ui32End)
{
psSpan->ui32End--;
}
/* Reduced the psSpan to nothing - remove it */
if (psSpan->ui32End < psSpan->ui32Start)
{
*ppsPrevSpan = psSpan->psNext;
GLESFree(gc, psSpan);
}
break;
}
else if ((ui32Name > psSpan->ui32Start) && (ui32Name < psSpan->ui32End))
{
/* ui32Name is in the middle of a psSpan - split it into two */
psTmpSpan = GLESMalloc(gc, sizeof(GLESnameSpan));
psTmpSpan->ui32Start = ui32Name+1;
psTmpSpan->ui32End = psSpan->ui32End;
psTmpSpan->psNext = psSpan->psNext;
psSpan->ui32End = ui32Name-1;
psSpan->psNext = psTmpSpan;
break;
}
ppsPrevSpan = &psSpan->psNext;
psSpan = psSpan->psNext;
}
return psNamedItem;
}
/***********************************************************************************
Function Name : GetNamedItem
Inputs : gc, psNamesArray, ui32Name
Outputs : -
Returns : Named item
Description : UTILITY: Looks up the ui32Name in the namesarray hash table.
************************************************************************************/
static GLESnamedItem *GetNamedItem(GLESContext *gc, GLESnamesArray *psNamesArray, IMG_UINT32 ui32Name)
{
GLESnamedItem *psNamedItem;
UNREFERENCED_PARAMETER(gc);
psNamedItem = psNamesArray->apsItem[HASH(ui32Name)];
while (psNamedItem)
{
if (psNamedItem->ui32Name == ui32Name)
break;
psNamedItem = psNamedItem->psNext;
}
return psNamedItem;
}
/***********************************************************************************
Function Name : AddNameToFreeList
Inputs : gc, psNamesArray, ui32Name
Outputs : -
Returns : -
Description : UTILITY: Returns a ui32Name to the free list
************************************************************************************/
static IMG_VOID AddNameToFreeList(GLESContext *gc, GLESnamesArray *psNamesArray, IMG_UINT32 ui32Name)
{
GLESnameSpan *psSpan, **ppsPrevSpan, *psTmpSpan;
psSpan = psNamesArray->psFreeNameSpan;
ppsPrevSpan = &psNamesArray->psFreeNameSpan;
while (psSpan)
{
/* ui32Name already exists in free list ? */
if ((ui32Name >= psSpan->ui32Start) && (ui32Name <= psSpan->ui32End))
break;
if(ui32Name < psSpan->ui32Start)
{
/* ui32Name sits at the beginning of a psSpan */
if (ui32Name == psSpan->ui32Start-1)
{
psSpan->ui32Start--;
}
else
{
/* Create a new psSpan for this ui32Name */
psTmpSpan = GLESMalloc(gc, sizeof(GLESnameSpan));
psTmpSpan->ui32Start = psTmpSpan->ui32End = ui32Name;
psTmpSpan->psNext = psSpan;
*ppsPrevSpan = psTmpSpan;
}
break;
}
else if(ui32Name == psSpan->ui32End+1)
/* ui32Name sits on the end of a psSpan */
{
/* ui32Name bridges 2 spans - collapse them into 1 */
if (psSpan->psNext && (ui32Name+1 == psSpan->psNext->ui32Start))
{
psSpan->ui32End = psSpan->psNext->ui32End;
psTmpSpan = psSpan->psNext;
psSpan->psNext = psSpan->psNext->psNext;
GLESFree(gc, psTmpSpan);
}
else
{
psSpan->ui32End++;
}
break;
}
else
{
if (psSpan->psNext)
{
if(ui32Name < psSpan->psNext->ui32Start)
{
if (ui32Name == psSpan->psNext->ui32Start-1)
{
psSpan->psNext->ui32Start--;
}
else
{
psTmpSpan = GLESMalloc(gc, sizeof(GLESnameSpan));
psTmpSpan->ui32Start = psTmpSpan->ui32End = ui32Name;
psTmpSpan->psNext = psSpan->psNext;
(*ppsPrevSpan)->psNext = psTmpSpan;
}
break;
}
ppsPrevSpan = &psSpan->psNext;
}
}
psSpan = psSpan->psNext;
}
if (!psSpan)
{
psSpan = GLESMalloc(gc, sizeof(GLESnameSpan));
psSpan->ui32Start = psSpan->ui32End = ui32Name;
psSpan->psNext = *ppsPrevSpan;
*ppsPrevSpan = psSpan;
}
}
/***********************************************************************************
Function Name : DeleteNamedItem
Inputs : gc, psNamesArray, ui32Name
Outputs : -
Returns : -
Description : UTILITY: Deletes a named item and adds its ui32Name to the free list
************************************************************************************/
static IMG_VOID DeleteNamedItem(GLESContext *gc, GLESnamesArray *psNamesArray, IMG_UINT32 ui32Name)
{
GLESnamedItem *psChain;
GLESnamedItem **ppsPrevSpan;
IMG_UINT32 ui32HashVal;
ui32HashVal = HASH(ui32Name);
ppsPrevSpan = &psNamesArray->apsItem[ui32HashVal];
psChain = *ppsPrevSpan;
while (psChain)
{
if (psChain->ui32Name == ui32Name)
{
*ppsPrevSpan = psChain->psNext;
psNamesArray->pfnFree(gc, psChain->pvItem);
GLESFree(gc, psChain);
break;
}
ppsPrevSpan = &psChain->psNext;
psChain = psChain->psNext;
}
AddNameToFreeList(gc, psNamesArray, ui32Name);
}
/***********************************************************************************
Function Name : NewNamedItem
Inputs : gc, psNamesArray, ui32Name, pvData
Outputs : -
Returns : Whether the item was created.
Description : Creates a new named item for data.
************************************************************************************/
IMG_BOOL NewNamedItem(GLESContext *gc, GLESnamesArray *psNamesArray, IMG_UINT32 ui32Name, IMG_VOID *pvData)
{
GLESnamedItem *psNamedItem;
psNamedItem = CreateNamedItem(gc, psNamesArray, ui32Name);
if(psNamedItem)
{
psNamedItem->pvItem = pvData;
/* Set refcount to be 1 on creation */
(*(IMG_UINT32 *)pvData) = 1;
return IMG_TRUE;
}
return IMG_FALSE;
}
/***********************************************************************************
Function Name : LockNamedItem
Inputs : gc, psNamesArray, ui32Name
Outputs : -
Returns : -
Description : Locks a named item (increases the refcount).
************************************************************************************/
IMG_VOID *LockNamedItem(GLESContext *gc, GLESnamesArray *psNamesArray, IMG_UINT32 ui32Name)
{
GLESnamedItem *psNamedItem;
IMG_VOID *pvData = NULL;
psNamedItem = GetNamedItem(gc, psNamesArray, ui32Name);
if(psNamedItem)
{
pvData = psNamedItem->pvItem;
(*(IMG_UINT32 *)pvData)++;
}
return pvData;
}
/***********************************************************************************
Function Name : UnlockDataItem
Inputs : gc, pvData
Outputs : -
Returns : -
Description : Unlocks some data. Doesn't need the ui32Name as the lookup is
assumed to have been done during lock. Will delete the item if
refcount reaches 0.
************************************************************************************/
IMG_VOID UnlockDataItem(GLESContext *gc, IMG_VOID *pvData)
{
IMG_UINT32 *pui32RefCount;
GLES_ASSERT(pvData);
pui32RefCount = pvData;
(*pui32RefCount)--;
if(*pui32RefCount == 0)
{
/*
** We are the last person to see this list alive. Free it.
*/
GLESFree(gc, pvData);
}
}
/***********************************************************************************
Function Name : GenNames
Inputs : gc, psNamesArray, ui32Num
Outputs : puiNames
Returns : -
Description : Generates a range of names. Looks at free list and removes
names from the list as it allocates them.
************************************************************************************/
IMG_VOID GenNames(GLESContext *gc, GLESnamesArray *psNamesArray, IMG_UINT32 ui32Num, GLuint *puiNames)
{
GLESnameSpan *psSpan, **ppsPrevSpan;
IMG_UINT32 ui32Size, ui32Min, i;
psSpan = psNamesArray->psFreeNameSpan;
ppsPrevSpan = &psNamesArray->psFreeNameSpan;
while (ui32Num)
{
ui32Size = psSpan->ui32End - psSpan->ui32Start + 1;
ui32Min = MIN(ui32Size, ui32Num);
for (i=0; i<ui32Min; i++, ui32Num--)
{
*puiNames++ = psSpan->ui32Start++;
}
if(ui32Min == ui32Size)
{
/* collapse psSpan */
*ppsPrevSpan = psSpan->psNext;
GLESFree(gc, psSpan);
psSpan = *ppsPrevSpan;
}
else if(psSpan->psNext)
{
ppsPrevSpan = &psSpan->psNext;
psSpan = psSpan->psNext;
}
else
{
/* Not enough free names in table */
break;
}
}
}
/***********************************************************************************
Function Name : NamedItemDeleteRange
Inputs : gc, psNamesArray, ui32Name, ui32Range
Outputs : -
Returns : -
Description : Deletes a range of named items.
************************************************************************************/
IMG_VOID NamedItemDeleteRange(GLESContext *gc, GLESnamesArray *psNamesArray, IMG_UINT32 ui32Name, IMG_UINT32 ui32Range)
{
IMG_UINT32 i=0;
if(ui32Range == 0)
return;
for(i=0; i < ui32Range; i++)
{
DeleteNamedItem(gc, psNamesArray, i+ui32Name);
}
}
/***********************************************************************************
Function Name : CreateNamesArray
Inputs : gc, ui32Type
Outputs : -
Returns : A pointer to a new namesArray
Description : Creates a new names array with a specific type.
Sets up free fn for this type.
************************************************************************************/
GLESnamesArray * CreateNamesArray(GLESContext *gc, IMG_UINT32 ui32Type)
{
GLESnamesArray *psNamesArray;
psNamesArray = GLESCalloc(gc, sizeof(GLESnamesArray));
psNamesArray->apsItem = GLESCalloc(gc, HASH_TABLE_SIZE * sizeof(GLESnamedItem));
psNamesArray->ui32Refcount = 1;
switch(ui32Type)
{
case GLES_NAMETYPE_TEXOBJ:
SetupTexNameArray(psNamesArray);
break;
#if (defined(SUPPORT_VGP) || defined(SUPPORT_VGP_LITE)) && !defined(PASSTHROUGH_BUILD)
case GLES_NAMETYPE_PROGRAM:
SetupProgramNameArray(psNamesArray);
break;
#endif
default:
DPF((DBG_ERROR,"Invalid name type"));
return IMG_NULL;
}
psNamesArray->psFreeNameSpan = GLESCalloc(gc, sizeof(GLESnameSpan));
psNamesArray->psFreeNameSpan->ui32Start = 1;
psNamesArray->psFreeNameSpan->ui32End = 0xFFFFFFFF;
return psNamesArray;
}
/***********************************************************************************
Function Name : DestroyNamesArray
Inputs : gc, psNamesArray
Outputs : -
Returns : -
Description : Destroys a namesarray - frees all items in it.
************************************************************************************/
IMG_VOID DestroyNamesArray(GLESContext *gc, GLESnamesArray *psNamesArray)
{
IMG_UINT32 i;
GLESnamedItem *psNext;
GLESnameSpan *psSpan, *psNextSpan;
psNamesArray->ui32Refcount--;
if(psNamesArray->ui32Refcount != 0)
{
return;
}
for(i=0; i < HASH_TABLE_SIZE; i++)
{
GLESnamedItem *psItem = psNamesArray->apsItem[i];
while(psItem)
{
psNext = psItem->psNext;
psNamesArray->pfnFree(gc, psItem->pvItem);
GLESFree(gc, psItem);
psItem = psNext;
}
}
psSpan = psNamesArray->psFreeNameSpan;
while(psSpan)
{
psNextSpan = psSpan->psNext;
GLESFree(gc, psSpan);
psSpan = psNextSpan;
}
GLESFree(gc, psNamesArray->apsItem);
GLESFree(gc, psNamesArray);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -