You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
221 lines
6.3 KiB
221 lines
6.3 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: dl_init.c
|
|
*
|
|
* Display list initialization and sharing rountines.
|
|
*
|
|
* Copyright (c) 1995-96 Microsoft Corporation
|
|
\**************************************************************************/
|
|
/*
|
|
** Copyright 1991-1993, 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.
|
|
**
|
|
** Display list init/destroy code.
|
|
**
|
|
** $Revision: 1.7 $
|
|
** $Date: 1993/09/29 00:44:06 $
|
|
*/
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
/*
|
|
** Empty data structure for display lists.
|
|
*/
|
|
static __GLdlist emptyDlist = {
|
|
2, /* refcount, two so that it can never die */
|
|
0 /* Everything else, some initialized later */
|
|
};
|
|
|
|
static __GLnamesArrayTypeInfo dlistTypeInfo =
|
|
{
|
|
&emptyDlist,
|
|
sizeof(__GLdlist),
|
|
__glDisposeDlist,
|
|
NULL
|
|
};
|
|
|
|
/*
|
|
** Used to share display lists between two different contexts.
|
|
*/
|
|
#ifdef NT_SERVER_SHARE_LISTS
|
|
GLboolean FASTCALL __glCanShareDlist(__GLcontext *gc, __GLcontext *shareMe)
|
|
{
|
|
GLboolean canShare = GL_TRUE;
|
|
|
|
if (gc->dlist.namesArray != NULL)
|
|
{
|
|
__glNamesLockArray(gc, gc->dlist.namesArray);
|
|
|
|
// Make sure we're not trying to replace a shared list
|
|
// The spec also says that it is illegal for the new context
|
|
// to have any display lists
|
|
canShare = gc->dlist.namesArray->refcount == 1 &&
|
|
gc->dlist.namesArray->tree == NULL &&
|
|
shareMe->dlist.namesArray != NULL;
|
|
|
|
__glNamesUnlockArray(gc, gc->dlist.namesArray);
|
|
}
|
|
|
|
return canShare;
|
|
}
|
|
#endif
|
|
|
|
void FASTCALL __glShareDlist(__GLcontext *gc, __GLcontext *shareMe)
|
|
{
|
|
#ifdef NT_SERVER_SHARE_LISTS
|
|
__glFreeDlistState(gc);
|
|
__glNamesLockArray(gc, shareMe->dlist.namesArray);
|
|
#endif
|
|
|
|
gc->dlist.namesArray = shareMe->dlist.namesArray;
|
|
gc->dlist.namesArray->refcount++;
|
|
|
|
#ifdef NT_SERVER_SHARE_LISTS
|
|
DBGLEVEL3(LEVEL_INFO, "Sharing dlists %p with %p, count %d\n", gc, shareMe,
|
|
gc->dlist.namesArray->refcount);
|
|
|
|
__glNamesUnlockArray(gc, shareMe->dlist.namesArray);
|
|
#endif
|
|
}
|
|
|
|
void FASTCALL __glInitDlistState(__GLcontext *gc)
|
|
{
|
|
__GLdlistMachine *dlist;
|
|
|
|
// This is required by the names management code
|
|
ASSERTOPENGL(offsetof(__GLdlist, refcount) == 0,
|
|
"Dlist refcount not at offset zero\n");
|
|
|
|
// Set empty dlist to contain no entries
|
|
emptyDlist.end = emptyDlist.head;
|
|
|
|
dlist = &gc->dlist;
|
|
|
|
dlist->nesting = 0;
|
|
dlist->currentList = 0;
|
|
dlist->listData = NULL;
|
|
dlist->beginRec = NULL;
|
|
|
|
ASSERTOPENGL(dlist->namesArray == NULL, "Dlist namesArray not NULL\n");
|
|
dlist->namesArray = __glNamesNewArray(gc, &dlistTypeInfo);
|
|
}
|
|
|
|
void FASTCALL __glFreeDlistState(__GLcontext *gc)
|
|
{
|
|
__GLnamesArray *narray;
|
|
|
|
narray = gc->dlist.namesArray;
|
|
|
|
if (narray == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
#ifdef NT_SERVER_SHARE_LISTS
|
|
__glNamesLockArray(gc, narray);
|
|
|
|
// Clean up any lists that this context may have locked
|
|
DlReleaseLocks(gc);
|
|
#endif
|
|
|
|
DBGLEVEL2(LEVEL_INFO, "Freeing dlists for %p, ref %d\n", gc,
|
|
narray->refcount);
|
|
|
|
narray->refcount--;
|
|
if (narray->refcount == 0)
|
|
{
|
|
// NULL the array pointer first, preventing its reuse
|
|
// after we unlock it. We need to unlock before we free it
|
|
// because the critical section will be cleaned up in the
|
|
// free
|
|
gc->dlist.namesArray = NULL;
|
|
// Decrement dlist refcounts and free them if they reach 0
|
|
__glNamesFreeArray(gc, narray);
|
|
}
|
|
else
|
|
{
|
|
__glNamesUnlockArray(gc, narray);
|
|
gc->dlist.namesArray = NULL;
|
|
}
|
|
|
|
if (gc->dlist.listData != NULL)
|
|
{
|
|
// We were in the middle of compiling a display list when this
|
|
// function is called! Free the display list data.
|
|
__glFreeDlist(gc, gc->dlist.listData);
|
|
gc->dlist.listData = NULL;
|
|
gc->dlist.currentList = 0;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* glsrvShareLists
|
|
*
|
|
* Server side implementation of wglShareLists
|
|
*
|
|
* History:
|
|
* Tue Dec 13 17:14:18 1994 -by- Drew Bliss [drewb]
|
|
* Created
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#ifdef NT_SERVER_SHARE_LISTS
|
|
ULONG APIENTRY glsrvShareLists(__GLcontext *gcShare, __GLcontext *gcSource)
|
|
{
|
|
if (!__glCanShareDlist(gcShare, gcSource) ||
|
|
!__glCanShareTextures(gcShare, gcSource))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
__glShareDlist(gcShare, gcSource);
|
|
__glShareTextures(gcShare, gcSource);
|
|
return ERROR_SUCCESS;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* __glDlistThreadCleanup
|
|
*
|
|
* Performs thread-exit cleanup for dlist state
|
|
*
|
|
* History:
|
|
* Mon Dec 19 13:22:38 1994 -by- Drew Bliss [drewb]
|
|
* Created
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#ifdef NT_SERVER_SHARE_LISTS
|
|
|
|
#if DBG
|
|
// Critical section check routine from usersrv
|
|
extern void APIENTRY CheckCritSectionOut(LPCRITICAL_SECTION pcs);
|
|
#endif
|
|
|
|
void __glDlistThreadCleanup(__GLcontext *gc)
|
|
{
|
|
#if DBG
|
|
// Make sure we're not holding the display list critical section
|
|
// We only hold this for short periods of time in our own code
|
|
// so we should never be holding it unless we have bugs
|
|
// In other words, it's ok to just assert this because no
|
|
// client action can cause us to hold it
|
|
CheckCritSectionOut(&gc->dlist.namesArray->critsec);
|
|
#endif
|
|
}
|
|
#endif
|