windows-nt/Source/XPSP1/NT/multimedia/opengl/server/soft/so_tprls.c
2020-09-26 16:20:57 +08:00

288 lines
8.6 KiB
C

/*
** Copyright 1991,1992, Silicon Graphics, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of Silicon Graphics, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
**
*/
#include "precomp.h"
#pragma hdrstop
#include <namesint.h>
void __glTexPriListRealize(__GLcontext *gc)
{
__GLtextureObject *high, *low;
GLboolean tryUnload = GL_TRUE;
MCDHANDLE loadKey;
__GL_NAMES_ASSERT_LOCKED(gc->texture.shared->namesArray);
// Attempt to load as many of the highest priority textures as
// possible. If a lower priority texture is resident and a
// higher priority texture is unable to load, kick it out
// and try again
high = gc->texture.shared->priorityListHighest;
low = gc->texture.shared->priorityListLowest;
while (high != NULL)
{
// We only want to load textures that have image data
// Consider - Should check all mipmap levels?
if (high->loadKey == 0 && high->texture.map.level[0].buffer != NULL)
{
for (;;)
{
// If high == low then there are no longer any
// lower-priority textures to consider for unloading
if (high == low)
{
tryUnload = GL_FALSE;
}
loadKey = __glGenLoadTexture(gc, &high->texture.map, 0);
if (loadKey != 0)
{
high->resident = GL_TRUE;
high->loadKey = loadKey;
break;
}
if (tryUnload)
{
while (low->loadKey == 0 && low != high)
{
low = low->higherPriority;
}
if (low->loadKey != 0)
{
__glGenFreeTexture(gc, &low->texture.map, low->loadKey);
low->loadKey = 0;
low->resident = GL_FALSE;
}
}
else
{
break;
}
}
}
high = high->lowerPriority;
}
}
void __glTexPriListAddToList(__GLcontext *gc, __GLtextureObject *texobj)
{
__GLtextureObject *texobjLower;
__GL_NAMES_ASSERT_LOCKED(gc->texture.shared->namesArray);
// Walk the priority list to find a lower priority texture object
texobjLower = gc->texture.shared->priorityListHighest;
while (texobjLower != NULL &&
texobjLower->texture.map.texobjs.priority >
texobj->texture.map.texobjs.priority)
{
texobjLower = texobjLower->lowerPriority;
}
if (texobjLower == NULL)
{
// Place at end of list
if (gc->texture.shared->priorityListLowest != NULL)
{
gc->texture.shared->priorityListLowest->lowerPriority = texobj;
}
else
{
gc->texture.shared->priorityListHighest = texobj;
}
texobj->higherPriority = gc->texture.shared->priorityListLowest;
gc->texture.shared->priorityListLowest = texobj;
}
else
{
if (texobjLower->higherPriority != NULL)
{
texobjLower->higherPriority->lowerPriority = texobj;
}
else
{
gc->texture.shared->priorityListHighest = texobj;
}
texobj->higherPriority = texobjLower->higherPriority;
texobjLower->higherPriority = texobj;
}
texobj->lowerPriority = texobjLower;
}
void __glTexPriListAdd(__GLcontext *gc, __GLtextureObject *texobj,
GLboolean realize)
{
__glNamesLockArray(gc, gc->texture.shared->namesArray);
__glTexPriListAddToList(gc, texobj);
if (realize)
{
__glTexPriListRealize(gc);
}
__glNamesUnlockArray(gc, gc->texture.shared->namesArray);
}
void __glTexPriListRemoveFromList(__GLcontext *gc, __GLtextureObject *texobj)
{
__GL_NAMES_ASSERT_LOCKED(gc->texture.shared->namesArray);
#if DBG
{
__GLtextureObject *t;
for (t = gc->texture.shared->priorityListHighest;
t != NULL; t = t->lowerPriority)
{
if (t == texobj)
{
break;
}
}
ASSERTOPENGL(t != NULL, "Removing an unlisted texobj");
}
#endif
if (texobj->higherPriority != NULL)
{
texobj->higherPriority->lowerPriority = texobj->lowerPriority;
}
else
{
gc->texture.shared->priorityListHighest = texobj->lowerPriority;
}
if (texobj->lowerPriority != NULL)
{
texobj->lowerPriority->higherPriority = texobj->higherPriority;
}
else
{
gc->texture.shared->priorityListLowest = texobj->higherPriority;
}
}
void __glTexPriListRemove(__GLcontext *gc, __GLtextureObject *texobj,
GLboolean realize)
{
__glNamesLockArray(gc, gc->texture.shared->namesArray);
__glTexPriListRemoveFromList(gc, texobj);
__glGenFreeTexture(gc, &texobj->texture.map, texobj->loadKey);
texobj->loadKey = 0;
texobj->resident = GL_FALSE;
if (realize)
{
__glTexPriListRealize(gc);
}
__glNamesUnlockArray(gc, gc->texture.shared->namesArray);
}
void __glTexPriListChangePriority(__GLcontext *gc, __GLtextureObject *texobj,
GLboolean realize)
{
__glNamesLockArray(gc, gc->texture.shared->namesArray);
__glTexPriListRemoveFromList(gc, texobj);
__glTexPriListAddToList(gc, texobj);
// If we're re-realizing, don't bother calling the MCD texture-priority
// function:
if (realize) {
__glTexPriListRealize(gc);
} else if (((__GLGENcontext *)gc)->pMcdState && texobj->loadKey) {
GenMcdUpdateTexturePriority((__GLGENcontext *)gc,
&texobj->texture.map, texobj->loadKey);
}
__glNamesUnlockArray(gc, gc->texture.shared->namesArray);
}
void __glTexPriListLoadSubImage(__GLcontext *gc, GLenum target, GLint lod,
GLint xoffset, GLint yoffset,
GLsizei w, GLsizei h)
{
__GLtextureObject *pto;
// Always mark things as resident:
pto = __glLookUpTextureObject(gc, target);
pto->resident = GL_TRUE;
__glGenUpdateTexture(gc, &pto->texture.map, pto->loadKey);
// For MCD, send down the full subimage command:
if (((__GLGENcontext *)gc)->pMcdState && pto->loadKey) {
GenMcdUpdateSubTexture((__GLGENcontext *)gc, &pto->texture.map,
pto->loadKey, lod,
xoffset, yoffset, w, h);
}
}
void __glTexPriListLoadImage(__GLcontext *gc, GLenum target)
{
__GLtextureObject *pto;
// If we're unaccelerated then always mark things as resident
pto = __glLookUpTextureObject(gc, target);
pto->resident = GL_TRUE;
__glGenUpdateTexture(gc, &pto->texture.map, pto->loadKey);
// For simplicity, we will assume that the texture size or format
// has changed, so delete the texture and re-realize the list.
//
// !!! If this becomes a performance issue, we *could* be smart about
// !!! detecting the cases where the texture size and format remains the
// !!! same. However, modifying a texture should really be done through
// !!! SubImage calls.
if (((__GLGENcontext *)gc)->pMcdState) {
if (pto->loadKey) {
GenMcdDeleteTexture((__GLGENcontext *)gc, pto->loadKey);
pto->loadKey = 0;
}
__glNamesLockArray(gc, gc->texture.shared->namesArray);
__glTexPriListRealize(gc);
__glNamesUnlockArray(gc, gc->texture.shared->namesArray);
}
}
void __glTexPriListUnloadAll(__GLcontext *gc)
{
__GLtextureObject *texobj;
__GL_NAMES_ASSERT_LOCKED(gc->texture.shared->namesArray);
texobj = gc->texture.shared->priorityListHighest;
while (texobj != NULL)
{
__glGenFreeTexture(gc, &texobj->texture.map, texobj->loadKey);
texobj->loadKey = 0;
texobj->resident = GL_FALSE;
texobj = texobj->lowerPriority;
}
}