pfAsyncDelete man page on IRIX

Man page or keyword search:  
man Server   31559 pages
apropos Keyword Search (all sections)
Output format
IRIX logo
[printable version]



pfBuffer(3pf)  OpenGL Performer 3.2.2 libpf C++ Reference Pages	 pfBuffer(3pf)

NAME
     pfBuffer, pfAsyncDelete, pfGetCurBuffer - Create, select, and merge a
     pfBuffer.

FUNCTION SPECIFICATION
     #include <Performer/pf/pfBuffer.h>

		  pfBuffer::pfBuffer();

     void	  pfBuffer::select(void);

     static int	  pfBuffer::merge(void);

     void	  pfBuffer::setScope(pfObject *obj, int scope);

     int	  pfBuffer::getScope(pfObject *obj);

     static int	  pfBuffer::add(void *parent, void *child);

     static int	  pfBuffer::remove(void *parent, void *child);

     static int	  pfBuffer::insert(void *parent, int index, void *child);

     static int	  pfBuffer::replace(void *parent, void *oldChild,
		    void *newChild);

     static int	  pfBuffer::set(void *parent, int index, void *child);

     int	  pfAsyncDelete(void *mem);

     pfBuffer*	  pfGetCurBuffer(void);

PARAMETERS
     buf  identifies a pfBuffer

     obj  identifies a pfObject

DESCRIPTION
     A pfBuffer is a data structure that logically encompasses libpf objects
     such as pfNodes. Newly created objects are automatically "attached" to
     the current pfBuffer specified by pfBuffer::select.  Later, any objects
     created in the pfBuffer may be merged into the main OpenGL Performer
     processing stream with pfBuffer::merge. In conjunction with a forked
     DBASE process (see pfMultiprocess and pfDBaseFunc), the pfBuffer
     mechanism supports asynchronous parallel creation and deletion of
     database objects.	This is the foundation of a real-time database paging
     system.

     new pfBuffer creates and returns a handle to a pfBuffer.  pfBuffers
     cannot be created statically, on the stack, from the heap or in arrays.

     pfBuffer::select makes the pfBuffer the current pfBuffer. Once the

									Page 1

pfBuffer(3pf)  OpenGL Performer 3.2.2 libpf C++ Reference Pages	 pfBuffer(3pf)

     pfBuffer is current, all subsequently created libpf objects will be
     automatically associated with the pfBuffer and these objects may only be
     accessed through OpenGL Performer routines when the pfBuffer is the
     current pfBuffer (except for pfGroup::bufferAddChild and
     pfGroup::bufferRemoveChild, see the pfGroup man page).  A given pfBuffer
     should only be current in a single process at any given time.  In this
     way, a pfBuffer restricts access to a given object to a single process,
     avoiding hard-to-find errors due to multiprocessed data collisions.
     pfGetCurBuffer returns the current pfBuffer.

     Only libpf objects are subject to pfBuffer access restrictions.  libpf
     objects include pfNodes such as pfGroup, pfGeode and pfUpdatables such as
     pfLODState, pfChannel, pfEarthSky. libpr objects such as pfGeoSets,
     pfGeoStates, and pfMaterials have no pfBuffer restrictions so they may be
     accessed by any process at any time although care must be taken by the
     application to avoid multiprocessed collisions on these data structures.

     pfBuffer::merge merges the current pfBuffer with the main OpenGL
     Performer pfBuffer.  This main pfBuffer is created by pfConfig and will
     resist deletion and merging and should only be made current in the APP
     process (however, it is legal to select a different buffer in the APP
     process). If called in a process other than the APP, pfBuffer::merge will
     block until the APP calls pfSync, at which time the APP will merge the
     current pfBuffer into the main pfBuffer and then allow the process that
     requested the merge to continue. If called in the APP, pfBuffer::merge
     will immediately execute the merge.  After pfBuffer::merge returns, any
     objects that were created in the current pfBuffer may only be accessed in
     the APP process when the APP pfBuffer has been selected as the current
     pfBuffer.	In other words, the merged pfBuffer has been "reset" and its
     objects now "exist" only in the APP pfBuffer. The addresses of libpf
     objects are not changed by pfBuffer::merge.

     Any number of pfBuffers may be used and merged (pfBuffer::merge) by any
     number of processes for multithreaded database manipulation, subject to
     the following restrictions:

	  1.   A given pfBuffer should be current (via pfBuffer::select) in
	       only a single process at any given time.

	  2.   Each process which selects a pfBuffer must be forked, not
	       sproced.

     Specifically, pfBuffer usage is not restricted to the DBASE process (see
     pfConfig).

     pfGroup::bufferAddChild and pfGroup::bufferRemoveChild provide access to
     nodes that do not exist in the current pfBuffer.  Either, none, or both
     of the pfBuffer and node may exist outside the current pfBuffer.
     pfGroup::bufferAddChild and pfGroup::bufferRemoveChild act just like
     their non-buffered counterparts pfGroup::addChild and
     pfGroup::removeChild except that the addition or removal request is not

									Page 2

pfBuffer(3pf)  OpenGL Performer 3.2.2 libpf C++ Reference Pages	 pfBuffer(3pf)

     carried out immediately but is recorded by the current pfBuffer. The
     request is delayed until the first pfBuffer::merge when both the parent
     pfGroup and node are found in the main OpenGL Performer pfBuffer. The
     list of pfGroup::bufferAddChild and pfGroup::bufferRemoveChild requests
     is traversed in pfBuffer::merge after all nodes have been merged.
     pfGroup::bufferAddChild and pfGroup::bufferRemoveChild return TRUE if the
     request was recorded and FALSE otherwise.

     pfBuffer::set sets the specified child index of a parent node to the
     given child. It acts as a replace command but uses an index to identify
     the replaced child. The current implementation supports pfBuffer::set
     only for setting a source array in a pfAlign node.

     In addition to the pfGroup-specific pfGroup::bufferAddChild and
     pfGroup::bufferRemoveChild routines, a pfBuffer allows generic list
     management for pfGroup, pfGeode, pfText, and pfPipeWindow objects. These
     functions, pfGroup::bufferAdd, pfGroup::bufferRemove,
     pfGroup::bufferInsert, pfGroup::bufferReplace can be used to manage a
     pfGroup's list of pfNodes, a pfGeode's list of pfGeoSets, a pfText's list
     of pfStrings, or a pfPipeWindow's list of pfChannels respectively.	 These
     routines infer the proper action to take from the argument types.	For
     example, the following code fragment is equivalent to
     group->bufferAddChild(geode):

	  pfGroup   *group;
	  pfGeode   *geode;

	  pfBuffer::add(group, geode);

     pfGroup::bufferAdd, pfGroup::bufferRemove, pfGroup::bufferInsert,
     pfGroup::bufferReplace, pfBuffer::set all act similarly in that they do
     not have effect until pfBuffer::merge is called and all parties have been
     merged into the main OpenGL Performer buffer. They return -1 if the
     argument types are not consistent (e.g., pfBuffer::remove(group,
     geoset)), 0 if the request is immediately processed (this happens when
     all parties already have scope in the current pfBuffer), and 1 if the
     request is buffered until the next pfBuffer::merge.

     pfBuffer::setScope sets the scope of obj with respect to the pfBuffer. If
     scope is TRUE, then obj is "added" to the pfBuffer so that when the
     pfBuffer is made current (pfBuffer::select) in a process, obj may be
     accessed through OpenGL Performer routines in that same process.  When
     scope is FALSE, obj is "removed" from the pfBuffer.  pfBuffer::setScope's
     primary purpose is to move objects between pfBuffers, particularly from
     the main APP pfBuffer into an application pfBuffer typically used for
     asynchronous database manipulations.  In this case the object's scope
     would be set to FALSE in the old pfBuffer and TRUE in the new pfBuffer.
     It is undefined when an object has scope in multiple pfBuffers since this
     violates the multiprocessing data exclusion requirement of OpenGL

									Page 3

pfBuffer(3pf)  OpenGL Performer 3.2.2 libpf C++ Reference Pages	 pfBuffer(3pf)

     Performer.	 pfBuffer::getScope returns TRUE or FALSE indicating the scope
     of obj in pfBuffer the pfBuffer.

     When using pfBuffers for database paging, it is sometimes desirable to
     retain certain, common database models ("library models") in memory.
     Examples are trees, houses, and other "culture" which are instanced on
     paged terrain patches. One instancing mechanism is to create the library
     models in one pfBuffer and later use pfGroup::bufferAddChild to attach
     the models to scene graphs created in another pfBuffer. This is classic
     instancing which uses transformations (pfSCS) to properly position the
     models.  However, this mechanism suffers from 2 performance problems:

	  1.   pfBuffer::merge will adversely impact the APP process,
	       proportional to the number of pfBuffer::addChild and
	       pfBuffer::removeChild requests.

	  2.   Transformations in the scene graph reduce OpenGL Performer's
	       ability to sort the database (see pfChannel::setBinSort) and
	       matrix operations have some cost in the graphics pipeline.

     An alternative to classic instancing is "flattening" which creates a
     clone of the instanced subtree and then applies the transformation to all
     geometry in the cloned subtree. This method eliminates the performance
     problems listed above but does increase memory usage.

	  pfNode* pfNode::bufferClone(int mode, pfBuffer *buf)

     is a version of pfNode::clone which clones the pfBuffer and its subtree,
     which resides in buf, into the current pfBuffer. mode is the same
     argument as that passed to pfNode::clone (it is currently ignored). Once
     cloned, a subtree may be flattened with pfNode::flatten.:

     Example 1: Instancing with pfGroup::bufferAddChild

	  libraryBuffer = new pfBuffer;
	  libraryBuffer->select();

	  loadLibraryObjects();

	  pagingBuffer = new pfBuffer;
	  pagingBuffer->select();

	  while (!done)
	  {
	      pfNode	 *newStuff;
	      pfSCS *treeLocation;

	      /* Load new terrain tile or whatever */
	      newStuff = loadStuff();

									Page 4

pfBuffer(3pf)  OpenGL Performer 3.2.2 libpf C++ Reference Pages	 pfBuffer(3pf)

	      /* Create pfSCS which is location of tree */
	      treeLocation = new pfSCS(treeMatrix);

	      /* Add library model of a tree to treeLocation */
	      treeLocation->bufferAddChild(libraryTree);

	      /* Add instanced tree to newly loaded stuff */
	      newStuff->addChild(treeLocation);
	  }

     Example 2: Instancing with pfBufferClone and pfFlatten

	  libraryBuffer = new pfBuffer;
	  libraryBuffer->select();

	  loadLibraryObjects();

	  pagingBuffer = new pfBuffer;
	  pagingBuffer->select();

	  while (!done)
	  {
	      pfNode	 *newStuff;
	      pfSCS *treeLocation;

	      /* Load new terrain tile or whatever */
	      newStuff = loadStuff();

	      /* Create pfSCS which is location of tree */
	      treeLocation = new pfSCS(treeMatrix);

	      /* Clone tree model from library into current, paging buffer */
	      newTree = libraryTree->bufferClone(0, libraryBuffer);

	      /* Transform cloned tree */
	      treeLocation->addChild(newTree);
	      treeLocation->flatten();

	      /* Get rid of unneeded treeLocation */
	      treeLocation->removeChild(newTree);
	      pfDelete(treeLocation);

	      /* Add cloned, flattened tree to newly loaded stuff */
	      newStuff->addChild(newTree);
	  }

									Page 5

pfBuffer(3pf)  OpenGL Performer 3.2.2 libpf C++ Reference Pages	 pfBuffer(3pf)

     pfAsyncDelete is a special version of pfDelete which is useful for
     asynchronous database deletion. Instead of having immediate effect,
     pfAsyncDelete simply registers a deletion request at the time of
     invocation.  These deletion requests are then processed in the DBASE
     trigger routine, pfDBase (pfDBase is automatically called if you have not
     registered a DBASE callback with pfDBaseFunc).  Thus, if the DBASE
     processing stage is configured as its own process via pfMultiprocess,
     then the deletion will be carried out asynchronously without affecting
     (slowing down) the main processing pipelines.

     pfAsyncDelete may be called from any process and returns -1 if mem is
     NULL or not derived from pfMemory and returns TRUE otherwise.  Note that
     unlike pfDelete pfAsyncDelete does not check mem's reference count and
     return TRUE or FALSE indicating whether mem was successfully deleted or
     not. Instead, the reference count check is delayed until the next call to
     pfDBase.  At this time there is no way to query the success of an
     pfAsyncDelete request.

     Note that pfDBase should only be called from within the database callback
     function (pfDBaseFunc) in the DBASE process just like pfCull and pfDraw
     should only be called in the pfChannel CULL and DRAW callbacks
     respectively (pfChanTravFunc).

     Example 2: How to use a pfBuffer

	  /* Must create these in shared memory */
	  static pfGroup **Tiles;
	  static int	 *TileStatus;

	  /*
	   * Load new tiles and delete old ones.
	   */
	  void
	  pageDBase(void *data)
	  {
	      static pfBuffer	   *buf = NULL;
	      pfGroup	      *root;

	      if (buf == NULL)
	      {
	       buf = new pfBuffer;
	       buf->select();
	      }

	      /* Asynchronously delete unneeded tiles and update their status */
	      for (allUnneededTiles)
	      {
	       /*
		   * Scene does not have scope in 'buf' so use pfBufferRemoveChild
		* Tiles[i] is not really removed until pfMergeBuffer
		*/
	       Scene->bufferRemoveChild(Tiles[i]);

									Page 6

pfBuffer(3pf)  OpenGL Performer 3.2.2 libpf C++ Reference Pages	 pfBuffer(3pf)

	       /* Delete Tiles[i] at pfDBase time if Tiles[i] only has Scene as
		  a parent.
		*/
	       pfAsyncDelete(Tiles[i]);

	       /* Update tile status */
	       TileStatus[i] = TILE_DELETED;
	      }

	      /*
	       * Synchronously load needed tiles and update their status.
	       */
	      LoadNeededDatabaseTiles(Tiles, TileStatus);

	      for (allLoadedTiles)
	      {
	       /*
		   * Scene does not have scope in 'buf' so use pfBufferAddChild
		* loadedTile[i] is not really added until pfMergeBuffer
		*/
	       Scene->bufferAddChild(loadedTile[i]);
	      }

	      /*
	       * Merge newly loaded tiles into main pfBuffer then carry out
	       * all pfBufferAdd/RemoveChild requests.
	       */
	      pfBuffer::merge();

	      /*
	       * Carry out pfAsyncDelete requests. Call *after* pfBuffer::merge()
	       * so that all pfBufferRemoveChild requests have been processed
	       * and child reference counts have been properly decremented.
	       */
	      pfDBase();
	  }

	      :

	  pfInit();
	  Tiles = pfMalloc(sizeof(pfGroup*) * NUM_TILES, pfGetSharedArena());
	  TileStatus = pfMalloc(sizeof(int) * NUM_TILES, pfGetSharedArena());
	  pfMultiprocess(PFMP_APP_CULL_DRAW | PFMP_FORK_DBASE);
	  pfConfig();
	      :
	  pfDBaseFunc(pageDBase);

	  while(!done)
	  {
	      pfSync();

	      /* Remove and request deletion of unneeded tiles */

									Page 7

pfBuffer(3pf)  OpenGL Performer 3.2.2 libpf C++ Reference Pages	 pfBuffer(3pf)

	      UpdateTileStatus(Tiles, TileStatus);

	      pfFrame();
	  }

NOTES
     pfGetCurBuffer will return the APP pfBuffer immediately after pfConfig
     returns.

SEE ALSO
     pfBuffer, pfConfig, pfDBaseFunc, pfFrame, pfMultiprocess, pfGroup

									Page 8

[top]

List of man pages available for IRIX

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net