pfFrame(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfFrame(3pf)NAME
pfFrameRate, pfGetFrameRate, pfFieldRate, pfGetFieldRate, pfVideoRate,
pfGetVideoRate, pfSync, pfFrame, pfAppFrame, pfGetFrameCount,
pfFrameTimeStamp, pfGetFrameTimeStamp, pfGetFrameTimeFlux, pfPhase,
pfGetPhase - Set and get system frame and video rate, phase, and frame
count. Synchronize and initiate frame.
FUNCTION SPECIFICATION
#include <Performer/pf.h>
float pfFrameRate(float rate);
float pfGetFrameRate(void);
int pfFieldRate(int fields);
int pfGetFieldRate(void);
void pfVideoRate(float vrate);
float pfGetVideoRate(void);
int pfSync(void);
int pfFrame(void);
int pfAppFrame(void);
int pfGetFrameCount(void);
void pfFrameTimeStamp(double time);
double pfGetFrameTimeStamp(void);
pfFlux* pfGetFrameTimeFlux(void);
void pfPhase(int phase);
int pfGetPhase(void);
DESCRIPTION
OpenGL Performer is designed to run at a fixed frame rate. The rate
argument to pfFrameRate specifies the desired rate in units of frames per
second. The actual rate used is based on the video timing of the display
hardware. rate is rounded to the nearest frame rate which corresponds to
an integral multiple of video fields.
For a 60Hz video rate, possible frame rates are (in Hz) 60.0, 30.0, 20.0,
15.0, 12.0, 10.0, 8.57, 7.5, 6.67, and 6.0. These rates would mean that
the number of fields per frame would range from 1 (for 60Hz) to 10 (for
6Hz). pfFrameRate returns the actual frame rate used or -1.0 if it is
called before pfConfig.
Page 1
pfFrame(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfFrame(3pf)
pfVideoRate specifies the system video rate as vrate fields per second.
If pfVideoRate is not called, then OpenGL Performer determines the video
field rate at pfConfig time and will not be aware of changes in video
timing made during application run-time until pfVideoRate is called.
pfGetVideoRate returns the video timing in number of video fields per
second or -1.0 if it is called before the video rate has been determined.
The OpenGL Performer video clock (see pfInitVClock) runs at this video
field rate and is initialized to 0 by pfConfig.
An alternate way of specifying a desired frame rate is pfFieldRate.
fields is the number of video fields per simulation frame. The
corresponding frame rate will then be the video field rate (see
pfGetVideoRate) divided by fields. pfGetFieldRate returns the number of
video fields per simulation frame.
Frame rate is a per-machine metric and is used by all pfPipes. It
controls the rate at which multiprocessing pipelines run and affects
computed system load and related stress metrics (see
pfChannel::setStress). Since frame rate is global it follows that all
hardware pipelines used by a single OpenGL Performer application should
be genlocked, i.e., the video signals are synchronized by hardware.
Otherwise the video signals of the pipes will be out of phase, reducing
graphics throughput and increasing latency. Genlock is crucial for
proper multipipe operation and requires some simple, platform-specific
cabling and software configuration through the setmon call.
Depending on the phase as is discussed below, pfSync synchronizes the
application process with the frame rate specified by pfFrameRate (when
phase is PFPHASE_LOCK or PFPHASE_FLOAT), or to the system rendering rate
(when phase is PFPHASE_FREE_RUN or PFPHASE_LIMIT). In the first case,
pfSync sleeps until the next frame boundary, then awakens and returns
control to the application. In the second case, pfSync sleeps until the
draw process begins rendering a new frame or returns immediately if in
single-process operation. pfSync returns the current frame count and
should only be called by the application process when multiprocessing.
pfFrame initiates a new frame of OpenGL Performer processing by doing the
following:
1. Calls pfFlux::syncComplete() to complete any pfFlux sync groups
that are ready for completion.
2. Triggers all processing stages that are configured as a
separate process.
3. Inlines all processing stages that are not configured as a
separate process.
Page 2
pfFrame(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfFrame(3pf)
4. Sets the current flux frame (pfFlux::setFrame).
5. Sets the current, global pfCycleBuffer index (see
pfCycleBuffer::setCurIndex) which is guaranteed not to be in
use by any other OpenGL Performer process.
6. Sets the frame's time stamp (pfFrameTimeStamp).
7. Sets the global frame time flux if one has been requested (-
pfGetFrameTimeFlux).
pfFrame triggers all OpenGL Performer processing stages (APP, ISECT,
DBASE, CULL, DRAW, and the optional LPOINT). If a stage is partitioned
into a separate process, pfFrame will allow that process to run.
Otherwise, pfFrame itself will carry out the processing associated with
the stage. pfFrame will directly invoke all user callbacks that are in
the same process as that which called pfFrame. Otherwise, a callback
will be invoked by the process of which it is a part, e.g., the ISECT
callback will be invoked by the ISECT process if PFMP_FORK_ISECT is set
in the argument to pfMultiprocess.
All OpenGL Performer stage callbacks have a block of associated data
known as "user data." User data is passed as an argument to the stage
callback. To simplify data flow in a multiprocessing environment, OpenGL
Performer copies user data into internal buffers and propagates the data
down multiprocessing pipelines. To restrict data copying to only those
frames in which user data changes, use the pfPass<*>Data and
pfChannel::passChanData functions. pfPass<*>Data and
pfChannel::passChanData signify that the user data has changed and needs
to be copied. pfFrame will then copy the data into its internal buffer
and the stage callback will receive the updated user data. Stage
callbacks and user data functions are listed below.
Stage Callback Allocation Pass
___________________________________________________________________________________
APP pfChannel::setTravFunc pfChannel::allocChanData pfChannel::passChanData
CULL pfChannel::setTravFunc pfChannel::allocChanData pfChannel::passChanData
DRAW pfChannel::setTravFunc pfChannel::allocChanData pfChannel::passChanData
ISECT pfIsectFunc pfAllocIsectData pfPassIsectData
DBASE pfDBaseFunc pfAllocDBaseData pfPassDBaseData
|
|
|
pfFrame triggers the APP, CULL and DRAW stages of all pfPipes so it must
be called every frame a new display is desired. OpenGL Performer will
attempt to cull and draw all active pfChannels on all pfPipes within a
single frame period. Multiple pfChannels on a single pfPipe will be
processed in the order they were added to the pfPipe. pfFrame returns
the current frame count and should only be called by the application
process when multiprocessing.
If specified, pfChannel cull and draw callbacks (pfChannel::setTravFunc)
will be invoked by the appropriate process which may or may not be the
same process that called pfFrame. If these callbacks are not specified,
Page 3
pfFrame(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfFrame(3pf)
pfCull and pfDraw will be called instead. pfChannel passthrough data
which is passed to pfChannel function callbacks (see
pfChannel::passChanData) is copied into internal memory at pfFrame time.
If the light points process is used, pfFrame will invoke the
corresponding callback if one is set using pfChannel::setTravFunc. If no
callback is specified, pfLPoint will be called instead. The light points
callback share the same passthrough as the draw process.
In typical operation, pfFrame should closely follow pfSync in the main
application loop. Since the CULL does not start until pfFrame is called,
considerable processing between pfSync and pfFrame can reduce system
throughput. However, any updates to the database or view made at this
time will be applied to the current frame so latency is reduced for these
updates. Updates made after pfFrame will be applied to the next frame.
pfFrame returns the current frame count.
pfFrame will automatically call pfSync if the application did not call
pfSync before calling pfFrame. This means the application need not call
pfSync.
It is crucial to keep the time spent in the application process less than
a frame's time so the system can meet the desired frame rate. If the
application process exceeds a single frame's time, pfFrame will not be
called often enough to meet the frame rate.
The following code fragment is an example of an application's main
processing loop:
Example 1: Main simulation loop.
pfFrameRate(30.0f); /* Set desired frame rate to 30Hz */
while (!done)
{
app_funcs(); /* Perform application-specific functions */
update_positions(); /* Update moving models for frame N */
pfSync(); /* Sleep until next frame boundary */
update_view(); /* Set view for frame N */
pfFrame(); /* Trigger cull and draw for frame N */
}
pfAppFrame triggers a traversal that updates the state of the scene graph
for the next frame. This includes updating the state of pfSequence nodes
and invoking APP callbacks on nodes in the scene graph. If pfAppFrame is
not invoked directly, pfSync or pfFrame invokes it automatically. Note
that when the view is not set until after pfSync, as in the example
above, the view point in the channel during the application traversal
Page 4
pfFrame(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfFrame(3pf)
contains the eye point from the previous frame.
pfGetFrameCount returns the current frame count. The frame count is
initialized to 0 by pfConfig and is incremented by each call to pfFrame.
pfGetFrameRate returns the current system frame rate (possibly rounded)
previously set by pfFrameRate. Note that this is not necessarily the
same as the achieved frame rate.
pfSync synchronizes the application process to a particular rate. This
rate may be fixed, for example a steady 20Hz or may vary with the
rendering rate. In addition, the drawing process may be synchronized to
either a steady or a varying rate. pfPhase specifies the synchronization
methods used by pfSync and the drawing process (if it is a separate
process). phase is a symbolic constant that specifies the phase of all
process pipeline(s). It can take on the following values:
PFPHASE_LOCK
pfSync synchronizes to the next frame boundary and the drawing
process begins drawing and swaps its rendering buffers only at
fixed frame boundaries.
PFPHASE_FLOAT
pfSync synchronizes to the next frame boundary but the drawing
process can begin drawing and swap its rendering buffers at
non-frame boundaries.
PFPHASE_FREE_RUN
pfSync synchronizes to the rendering rate so the application
runs at its peak (and usually non-constant) capability.
PFPHASE_LIMIT
pfSync synchronizes to the rendering rate but the rendering
rate is limited to that frame rate specified by pfFrameRate.
Additionally, the modifier PFPHASE_SPIN_DRAW may be or-ed in with the
main phase mode from the above list.
pfPhase is a global mode so all pfPipes in the system are forced to run
with the same phase.
If running in locked phase, the drawing process will swap buffers only on
frame boundaries. A benefit of locking is that such pipelines are self-
regulating so synchronizing two pfPipes together is simple, even across
different machines. Another benefit is that latency is minimized and
predictable. The major drawback is that if a view takes slightly longer
than a frame to render (it has 'frame-extended'), then an entire frame is
skipped rather than a single vertical retrace period. However, if
minimal distraction is crucial, the phase can float so that buffer
swapping may happen on non-frame boundaries. In this case it is not
guaranteed that the windows on pfPipes will swap together; they may get
out of phase resulting in inconsistent images if the displays are
Page 5
pfFrame(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfFrame(3pf)
adjacent and are displaying the same scene.
The difference between phase lock and phase float becomes less apparent
with increasing frame rate. At a rate equal to the vertical retrace
rate, there is no difference. Also, if pfPipes do not 'frame extend',
then there is no difference.
Applications which do not require a fixed frame rate may use
PFPHASE_FREE_RUN or PFPHASE_LIMIT. PFPHASE_FREE_RUN essentially disables
OpenGL Performer's fixed frame rate mechanisms and will cause the
application to run at its rendering rate so it slows down when rendering
complex scenes and speeds up when rendering simple scenes. In this case,
the frame rate specified by pfFrameRate no longer affects the system
frame rate but is still used to compute system load and stress.
Additionally, if the APP, CULL, and/or DRAW stages are in separate
processes, they will run in lock step and each stage will wait for the
downstream stage to get its results and likewise, downstream stages wait
for upstream stages to finish. This is the desired mode if you need to
be sure that every APP frame is actually drawn and that the APP can not
spin ahead of the draw is slow and extends past its goal frame time.
PFPHASE_LIMIT is equivalent to PFPHASE_FREE_RUN except that the
application can go no faster than the frame rate specified by pfFrameRate
although it may go slower. Thus fixed frame rate behavior is achieved if
the time required to process a frame never takes longer than that
specified by pfFrameRate.
PFPHASE_SPIN_DRAW allows forked draw processes to redraw the previous
frame if an upstream stage slowed down an missed a frame. This only
affects locked and float phase modes. The default behavior is without
PFPHASE_SPIN_DRAW, in which case a forked draw process will wait for new
results from an upstream stage before continuing. In locked or float
modes, the draw process will only check for new upstream results on frame
boundaries.
pfPhase may be called any time after pfConfig.
pfGetPhase returns the current phase. The default phase is
PFPHASE_FREE_RUN.
pfFrameTimeStamp sets the time stamp of the current frame to time. The
frame time stamp is used when evaluating all pfSequences. Normally,
pfFrame sets the frame time stamp immediately before returning control to
the application although the application may set it to account for
varying latency in a non-constant frame rate situation. Time is relative
to pfInit when the system clock is initialized to 0.
pfGetFrameTimeStamp returns the frame time stamp of the current frame.
pfGetFrameTimeFlux returns the global frame time flux. The frame time
flux is a pfFlux that is updated with the frame time stamp of the current
frame whenever it changes. By default the frame time flux is configured
Page 6
pfFrame(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfFrame(3pf)
with the PFFLUX_PUSH mode set to PF_ON. The frame time flux is useful
for automatically driving pfEngine animations.
NOTES
To achieve a steady frame rate synchronized with the graphics display in
an otherwise non-graphical application, a screen must be set on the first
pfPipe with pfPipeScreen and pfFrame should be used in the main loop
which will indirectly call pfSync to obey the current phase.
SEE ALSO
pfChannel, pfPipeWindow, pfConfig, pfIsectFunc, pfInitVClock,
pfCycleBuffer, pfGetTime
Page 7