pfuReallyInvalidateClipTexture(3pf)NAMEpfuReallyInvalidateClipTexture - force complete reloading of clip texture
from disk
FUNCTION SPECIFICATION
#include <Performer/pfutil.h>
void pfuReallyInvalidateClipTexture(pfClipTexture *clipTex,
pfuBarrier *barr)
DESCRIPTION
This function forces a complete reloading of the clip texture clipTex
from disk to main memory and from main memory to texture memory. It
requires a pfuBarrier barr which must be allocated from the semaphore
arena.
In a libpf application, pfuReallyInvalidateClipTexture() must be called
at the beginning of the CULL process (e.g. in a pre-CULL callback). If
the application uses more than one pipe, there will be a CULL process for
each pipe. In this case pfuReallyInvalidateClipTexture() must be called
in each CULL process, each with its own copy (master or slave) of the
pfClipTexture. You may have to traverse the pipe's MPClipTexture list to
get the appropriate master or slave copy of a clip texture for a given
pipe.
SYNCHRONIZATION AND AVOIDING DEADLOCK
In a multipipe application, all of the CULL processes must call
pfuReallyInvalidateClipTexture() during the same frame, or the
application will deadlock. This can be tricky when the invalidation is
triggered by an asynchronous input event (such as a key press or GUI
selection)-- if implemented naively, the input event can occur before one
CULL process tests for it but after another CULL process tests for it, in
which case the first CULL will call pfuReallyInvalidateClipTexture() and
the second will not, and deadlock will occur.
One way to avoid this deadlock is the method used by the clipfly example
program (invalidate by hitting the "'" key or Invalidate button), which
is described here. Two shared variables are used: invalidate and
invalidateFrame, both initially set to 0. The asynchronous input process
sets invalidate to 1 in response to an input event. When the pre-CULL
callback (called in each CULL process) sees that the invalidate flag is
set, it unsets it and sets invalidateFrame to pfGetFrameCount()+1. (Some
CULL processes may do this and some may not, depending on the timing.)
On the next following CULL frame, all the pre-CULL processes see that
invalidateFrame has been set, and they all proceed to call
pfuReallyInvalidateClipTexture() and then unset invalidateFrame. (It is
safe to unset invalidateFrame here since there is a barrier
synchronization forcing all CULLs to rendezvous both within
pfuReallyInvalidateClipTexture() and at the end of the CULL's frame in
Performer, guaranteeing that this will not interfere with any other CULL
process's setting or testing of this variable).
Page 1
pfuReallyInvalidateClipTexture(3pf)
Note that the pre-CULLs must check for pfGetFrameCount() >=
invalidateFrame rather than pfGetFrameCount() == invalidateFrame since
the CULL processes may drop frames in FLOAT or LOCK phase (but if one
CULL process drops a frame then they all will).
Shared memory structure initialization:
int invalidate = 0;
int invalidateFrame = 0;
pfuBarrier *invalidateBarrier = pfuBarrierCreate(pfGetSemaArena());
if (invalidateBarrier == NULL)
freak out and die;
Async Input process:
if (got INVALIDATE event)
shared->invalidate = 1;
void preCull(pfChannel *chan) /* called by each pipe's CULL process */
{
if (shared->invalidateFrame > 0
&& pfGetFrameCount() >= shared->invalidateFrame) /* not ==! */
{
/* all CULLs get here during the same frame */
pfClipTexture *myCopyOfClipTex =
findThisPipesMasterOrSlaveClipTexture(pfGetChanPipe(chan),
clipTex);
pfuReallyInvalidateClipTexture(myCopyOfClipTex);
shared->invalidateFrame = 0; /* safe; see explanation above */
}
else if (shared->invalidate)
{
/* some or all CULLs may get here during a given frame */
shared->invalidate = 0;
shared->invalidateFrame = pfGetFrameCount()+1;
}
}
For the actual code (including the implementation of
findThisPipesMasterOrSlaveClipTexture()), see the clipfly sample source
code in /usr/share/Performer/src/sample/C/clipfly.
NOTES
ClipTexure functionality is not supported under Linux.
pfuReallyInvalidateClipTexture() only works on the texture levels that
are pfImageCaches (not pfImageTiles). Therefore you may need to convert
the configuration files for your clip texture so that this function will
work on all the levels. When a pfImageTile level is encountered, a
NOTIFY-level message is emitted and the level is otherwise ignored.
Page 2
pfuReallyInvalidateClipTexture(3pf)
This function requires Performer 2.3 or later. Use with earlier versions
of Performer will result in a huge memory leak when running multipipe,
usually causing the program to run out of memory after a few invocations.
This function is a painful workaround for the lack of appropriate
pfClipTexture functionality and robustness. Its use is not recommended
unless you are desperate and you are willing to think.
The libpfutil source code, object code and documentation are provided as
unsupported software. Routines are subject to change in future releases.
SEE ALSO
pfInvalidateClipTexture, pfuBarrier, pfClipTexture, clipfly, pfNotify
Page 3