pfSelectBuffer 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
     pfNewBuffer, pfSelectBuffer, pfMergeBuffer, pfBufferScope,
     pfGetBufferScope, pfBufferAdd, pfBufferRemove, pfBufferInsert,
     pfBufferReplace, pfBufferSet, pfAsyncDelete, pfGetCurBuffer - Create,
     select, and merge a pfBuffer.

FUNCTION SPECIFICATION
     #include <Performer/pf.h>

     pfBuffer *	  pfNewBuffer(void);

     void	  pfSelectBuffer(pfBuffer* buf);

     int	  pfMergeBuffer(void);

     void	  pfBufferScope(pfBuffer *buf, pfObject *obj, int scope);

     int	  pfGetBufferScope(pfBuffer *buf, pfObject *obj);

     int	  pfBufferAdd(void *parent, void *child);

     int	  pfBufferRemove(void *parent, void *child);

     int	  pfBufferInsert(void *parent, int index, void *child);

     int	  pfBufferReplace(void *parent, void *oldChild,
		    void *newChild);

     int	  pfBufferSet(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 pfSelectBuffer.	Later, any objects
     created in buf may be merged into the main OpenGL Performer processing
     stream with pfMergeBuffer. 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.

     pfNewBuffer creates and returns a handle to a pfBuffer.

     pfSelectBuffer makes buf the current pfBuffer. Once buf is current, all

									Page 1

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

     subsequently created libpf objects will be automatically associated with
     buf and these objects may only be accessed through OpenGL Performer
     routines when buf is the current pfBuffer (except for pfBufferAddChild
     and pfBufferRemoveChild, 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.

     pfMergeBuffer 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, pfMergeBuffer 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, pfMergeBuffer will
     immediately execute the merge.  After pfMergeBuffer 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 pfMergeBuffer.

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

	  1.   A given pfBuffer should be current (via pfSelectBuffer) 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).

     pfBufferAddChild and pfBufferRemoveChild provide access to nodes that do
     not exist in the current pfBuffer.	 Either, none, or both of group and
     node may exist outside the current pfBuffer.  pfBufferAddChild and
     pfBufferRemoveChild act just like their non-buffered counterparts
     pfAddChild and pfRemoveChild except that the addition or removal request
     is not carried out immediately but is recorded by the current pfBuffer.
     The request is delayed until the first pfMergeBuffer when both group and

									Page 2

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

     node are found in the main OpenGL Performer pfBuffer. The list of
     pfBufferAddChild and pfBufferRemoveChild requests is traversed in
     pfMergeBuffer after all nodes have been merged.  pfBufferAddChild and
     pfBufferRemoveChild return TRUE if the request was recorded and FALSE
     otherwise.

     pfBufferSet 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 pfBufferSet only for
     setting a source array in a pfAlign node.

     In addition to the pfGroup-specific pfBufferAddChild and
     pfBufferRemoveChild routines, a pfBuffer allows generic list management
     for pfGroup, pfGeode, pfText, and pfPipeWindow objects. These functions,
     pfBufferAdd, pfBufferRemove, pfBufferInsert, pfBufferReplace 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 pfBufferAddChild(group, geode):

	  pfGroup   *group;
	  pfGeode   *geode;

	  pfBufferAdd(group, geode);

     pfBufferAdd, pfBufferRemove, pfBufferInsert, pfBufferReplace, pfBufferSet
     all act similarly in that they do not have effect until pfMergeBuffer 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.,
     pfBufferRemove(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 pfMergeBuffer.

     pfBufferScope sets the scope of obj with respect to pfBuffer buf. If
     scope is TRUE, then obj is "added" to buf so that when buf is made
     current (pfSelectBuffer) in a process, obj may be accessed through OpenGL
     Performer routines in that same process.  When scope is FALSE, obj is
     "removed" from buf.  pfBufferScope'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 Performer.
     pfGetBufferScope returns TRUE or FALSE indicating the scope of obj in
     pfBuffer buf.

     When using pfBuffers for database paging, it is sometimes desirable to

									Page 3

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

     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 pfBufferAddChild 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.   pfMergeBuffer will adversely impact the APP process,
	       proportional to the number of pfBufferAddChild and
	       pfBufferRemoveChild requests.

	  2.   Transformations in the scene graph reduce OpenGL Performer's
	       ability to sort the database (see pfChanBinSort) 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* pfBufferClone(pfNode *node, int mode, pfBuffer *buf)

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

     Example 1: Instancing with pfBufferAddChild

	  libraryBuffer = pfNewBuffer();
	  pfSelectBuffer(libraryBuffer);

	  loadLibraryObjects();

	  pagingBuffer = pfNewBuffer();
	  pfSelectBuffer(pagingBuffer);

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

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

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

	      /* Add library model of a tree to treeLocation */

									Page 4

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

	      pfBufferAddChild(treeLocation, libraryTree);

	      /* Add instanced tree to newly loaded stuff */
	      pfAddChild(newStuff, treeLocation);
	  }

     Example 2: Instancing with pfBufferClone and pfFlatten

	  libraryBuffer = pfNewBuffer();
	  pfSelectBuffer(libraryBuffer);

	  loadLibraryObjects();

	  pagingBuffer = pfNewBuffer();
	  pfSelectBuffer(pagingBuffer);

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

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

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

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

	      /* Transform cloned tree */
	      pfAddChild(treeLocation, newTree);
	      pfFlatten(treeLocation);

	      /* Get rid of unneeded treeLocation */
	      pfRemoveChild(treeLocation, newTree);
	      pfDelete(treeLocation);

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

     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

									Page 5

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

     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 = pfNewBuffer();
	       pfSelectBuffer(buf);
	      }

	      /* 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
		*/
	       pfBufferRemoveChild(Scene, Tiles[i]);

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

									Page 6

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

	       */
	       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
		*/
	       pfBufferAddChild(Scene, loadedTile[i]);
	      }

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

	      /*
	       * Carry out pfAsyncDelete requests. Call *after* pfMergeBuffer()
	       * 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 */
	      UpdateTileStatus(Tiles, TileStatus);

									Page 7

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

	      pfFrame();
	  }

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

SEE ALSO
     pfBufferAddChild, pfBufferRemoveChild, pfConfig, pfDBaseFunc, pfDelete,
     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