mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
explicit sync_frame and flip_frame
This commit is contained in:
parent
8c6e59f6a9
commit
8b9c2ae9c6
@ -57,6 +57,12 @@ const bool pstats_unused_states = config_display.GetBool("pstats-unused-states",
|
|||||||
// system!
|
// system!
|
||||||
const string threading_model = config_display.GetString("threading-model", "");
|
const string threading_model = config_display.GetString("threading-model", "");
|
||||||
|
|
||||||
|
// This indicates the initial setting of the auto-flip flag. Set it
|
||||||
|
// true (the default) to cause render_frame() to flip all the windows
|
||||||
|
// before it returns (in single-threaded mode only), or false to wait
|
||||||
|
// until an explicit call to flip_frame() or the next render_frame().
|
||||||
|
const bool auto_flip = config_display.GetBool("auto-flip", true);
|
||||||
|
|
||||||
// Use the variable load-display to specifiy the name of the default
|
// Use the variable load-display to specifiy the name of the default
|
||||||
// graphics display library or GraphicsPipe to load. It is the name
|
// graphics display library or GraphicsPipe to load. It is the name
|
||||||
// of a shared library (or * for all libraries named in aux-display),
|
// of a shared library (or * for all libraries named in aux-display),
|
||||||
|
@ -34,6 +34,7 @@ extern const bool view_frustum_cull;
|
|||||||
extern const bool pstats_unused_states;
|
extern const bool pstats_unused_states;
|
||||||
|
|
||||||
extern const string threading_model;
|
extern const string threading_model;
|
||||||
|
extern const bool auto_flip;
|
||||||
|
|
||||||
extern EXPCL_PANDA void init_libdisplay();
|
extern EXPCL_PANDA void init_libdisplay();
|
||||||
|
|
||||||
|
@ -17,6 +17,44 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsEngine::set_auto_flip
|
||||||
|
// Access: Published
|
||||||
|
// Description: Set this flag true to indicate the GraphicsEngine
|
||||||
|
// should automatically cause windows to sync and flip
|
||||||
|
// at the end of render_frame().
|
||||||
|
//
|
||||||
|
// This only applies to a single-threaded rendering
|
||||||
|
// model. In the presence of threading, the windows are
|
||||||
|
// never auto-flipped, regardless of this flag.
|
||||||
|
//
|
||||||
|
// This only affects the timing of when the flip occurs.
|
||||||
|
// If this is true (the default), the flip occurs before
|
||||||
|
// render_frame() returns. If this is false, the flip
|
||||||
|
// occurs whenever flip_frame() is called, or at the
|
||||||
|
// beginning of the next call to render_frame(), if
|
||||||
|
// flip_frame() is never called.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void GraphicsEngine::
|
||||||
|
set_auto_flip(bool auto_flip) {
|
||||||
|
// We don't bother with the mutex here. It's just a bool, after
|
||||||
|
// all.
|
||||||
|
_auto_flip = auto_flip;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsEngine::get_auto_flip
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the current setting for the auto-flip flag.
|
||||||
|
// See set_auto_flip.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool GraphicsEngine::
|
||||||
|
get_auto_flip() const {
|
||||||
|
// We don't bother with the mutex here. It's just a bool, after
|
||||||
|
// all.
|
||||||
|
return _auto_flip;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsEngine::make_window
|
// Function: GraphicsEngine::make_window
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -55,7 +55,8 @@ GraphicsEngine(Pipeline *pipeline) :
|
|||||||
display_cat.info()
|
display_cat.info()
|
||||||
<< "Using threading model " << _threading_model << "\n";
|
<< "Using threading model " << _threading_model << "\n";
|
||||||
}
|
}
|
||||||
_needs_sync = false;
|
_auto_flip = auto_flip;
|
||||||
|
_flip_state = FS_flip;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -280,9 +281,8 @@ render_frame() {
|
|||||||
// don't do that.
|
// don't do that.
|
||||||
MutexHolder holder(_lock);
|
MutexHolder holder(_lock);
|
||||||
|
|
||||||
if (_needs_sync) {
|
if (_flip_state != FS_flip) {
|
||||||
// Flip the windows from the previous frame, if necessary.
|
do_flip_frame();
|
||||||
do_sync_frame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab each thread's mutex again after all windows have flipped.
|
// Grab each thread's mutex again after all windows have flipped.
|
||||||
@ -310,12 +310,12 @@ render_frame() {
|
|||||||
|
|
||||||
// Some threads may still be drawing, so indicate that we have to
|
// Some threads may still be drawing, so indicate that we have to
|
||||||
// wait for those threads before we can flip.
|
// wait for those threads before we can flip.
|
||||||
_needs_sync = true;
|
_flip_state = FS_draw;
|
||||||
|
|
||||||
// But if we don't have any threads, go ahead and flip the frame
|
// But if we don't have any threads, go ahead and flip the frame
|
||||||
// now. No point in waiting if we're single-threaded.
|
// now. No point in waiting if we're single-threaded.
|
||||||
if (_threads.empty()) {
|
if (_threads.empty() && _auto_flip) {
|
||||||
do_sync_frame();
|
do_flip_frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,20 +323,35 @@ render_frame() {
|
|||||||
// Function: GraphicsEngine::sync_frame
|
// Function: GraphicsEngine::sync_frame
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Waits for all the threads that started drawing their
|
// Description: Waits for all the threads that started drawing their
|
||||||
|
// last frame to finish drawing. The windows are not
|
||||||
|
// yet flipped when this returns; see also flip_frame().
|
||||||
|
// It is not usually necessary to call this explicitly,
|
||||||
|
// unless you need to see the previous frame right away.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void GraphicsEngine::
|
||||||
|
sync_frame() {
|
||||||
|
MutexHolder holder(_lock);
|
||||||
|
|
||||||
|
if (_flip_state == FS_draw) {
|
||||||
|
do_sync_frame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsEngine::flip_frame
|
||||||
|
// Access: Published
|
||||||
|
// Description: Waits for all the threads that started drawing their
|
||||||
// last frame to finish drawing, and then flips all the
|
// last frame to finish drawing, and then flips all the
|
||||||
// windows. It is not usually necessary to call this
|
// windows. It is not usually necessary to call this
|
||||||
// explicitly, unless you need to see the previous frame
|
// explicitly, unless you need to see the previous frame
|
||||||
// right away.
|
// right away.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void GraphicsEngine::
|
void GraphicsEngine::
|
||||||
sync_frame() {
|
flip_frame() {
|
||||||
// We hold the GraphicsEngine mutex while we wait for all of the
|
|
||||||
// threads. Doing this puts us at risk for deadlock if any of the
|
|
||||||
// threads tries to call any methods on the GraphicsEngine. So
|
|
||||||
// don't do that.
|
|
||||||
MutexHolder holder(_lock);
|
MutexHolder holder(_lock);
|
||||||
if (_needs_sync) {
|
|
||||||
do_sync_frame();
|
if (_flip_state != FS_flip) {
|
||||||
|
do_flip_frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,8 +545,32 @@ flip_windows(const GraphicsEngine::Windows &wlist) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void GraphicsEngine::
|
void GraphicsEngine::
|
||||||
do_sync_frame() {
|
do_sync_frame() {
|
||||||
// First, wait for all the threads to finish their current frame.
|
nassertv(_flip_state == FS_draw);
|
||||||
// Grabbing the mutex should achieve that.
|
|
||||||
|
// Wait for all the threads to finish their current frame. Grabbing
|
||||||
|
// and releasing the mutex should achieve that.
|
||||||
|
Threads::const_iterator ti;
|
||||||
|
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
||||||
|
RenderThread *thread = (*ti).second;
|
||||||
|
thread->_cv_mutex.lock();
|
||||||
|
thread->_cv_mutex.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
_flip_state = FS_sync;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsEngine::do_flip_frame
|
||||||
|
// Access: Private
|
||||||
|
// Description: The implementation of flip_frame(). We assume _lock
|
||||||
|
// is already held before this method is called.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void GraphicsEngine::
|
||||||
|
do_flip_frame() {
|
||||||
|
nassertv(_flip_state == FS_draw || _flip_state == FS_sync);
|
||||||
|
|
||||||
|
// First, wait for all the threads to finish their current frame, if
|
||||||
|
// necessary. Grabbing the mutex should achieve that.
|
||||||
Threads::const_iterator ti;
|
Threads::const_iterator ti;
|
||||||
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
||||||
RenderThread *thread = (*ti).second;
|
RenderThread *thread = (*ti).second;
|
||||||
@ -549,7 +588,7 @@ do_sync_frame() {
|
|||||||
thread->_cv_mutex.release();
|
thread->_cv_mutex.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
_needs_sync = false;
|
_flip_state = FS_flip;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -56,6 +56,9 @@ PUBLISHED:
|
|||||||
void set_threading_model(const string &threading_model);
|
void set_threading_model(const string &threading_model);
|
||||||
string get_threading_model() const;
|
string get_threading_model() const;
|
||||||
|
|
||||||
|
INLINE void set_auto_flip(bool auto_flip);
|
||||||
|
INLINE bool get_auto_flip() const;
|
||||||
|
|
||||||
INLINE GraphicsWindow *make_window(GraphicsPipe *pipe);
|
INLINE GraphicsWindow *make_window(GraphicsPipe *pipe);
|
||||||
GraphicsWindow *make_window(GraphicsPipe *pipe,
|
GraphicsWindow *make_window(GraphicsPipe *pipe,
|
||||||
const string &threading_model);
|
const string &threading_model);
|
||||||
@ -64,6 +67,7 @@ PUBLISHED:
|
|||||||
|
|
||||||
void render_frame();
|
void render_frame();
|
||||||
void sync_frame();
|
void sync_frame();
|
||||||
|
void flip_frame();
|
||||||
|
|
||||||
void render_subframe(GraphicsStateGuardian *gsg, DisplayRegion *dr,
|
void render_subframe(GraphicsStateGuardian *gsg, DisplayRegion *dr,
|
||||||
bool cull_sorting);
|
bool cull_sorting);
|
||||||
@ -80,6 +84,7 @@ private:
|
|||||||
void process_events(const GraphicsEngine::Windows &wlist);
|
void process_events(const GraphicsEngine::Windows &wlist);
|
||||||
void flip_windows(const GraphicsEngine::Windows &wlist);
|
void flip_windows(const GraphicsEngine::Windows &wlist);
|
||||||
void do_sync_frame();
|
void do_sync_frame();
|
||||||
|
void do_flip_frame();
|
||||||
|
|
||||||
PT(SceneSetup) setup_scene(const NodePath &camera,
|
PT(SceneSetup) setup_scene(const NodePath &camera,
|
||||||
GraphicsStateGuardian *gsg);
|
GraphicsStateGuardian *gsg);
|
||||||
@ -143,8 +148,14 @@ private:
|
|||||||
typedef pmap<string, PT(RenderThread) > Threads;
|
typedef pmap<string, PT(RenderThread) > Threads;
|
||||||
Threads _threads;
|
Threads _threads;
|
||||||
string _threading_model;
|
string _threading_model;
|
||||||
|
bool _auto_flip;
|
||||||
|
|
||||||
bool _needs_sync;
|
enum FlipState {
|
||||||
|
FS_draw, // Still drawing.
|
||||||
|
FS_sync, // All windows are done drawing.
|
||||||
|
FS_flip, // All windows are done drawing and have flipped.
|
||||||
|
};
|
||||||
|
FlipState _flip_state;
|
||||||
Mutex _lock;
|
Mutex _lock;
|
||||||
|
|
||||||
static PStatCollector _cull_pcollector;
|
static PStatCollector _cull_pcollector;
|
||||||
|
@ -110,8 +110,12 @@ project(const LPoint3f &point3d, LPoint3f &point2d) const {
|
|||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Sets the name of the event that will be generated
|
// Description: Sets the name of the event that will be generated
|
||||||
// whenever any properties of the Lens have
|
// whenever any properties of the Lens have
|
||||||
// changed. This can be used to automatically track
|
// changed. If this is not set for a particular lens,
|
||||||
// changes to camera fov, etc. in the simulation.
|
// no event will be generated.
|
||||||
|
//
|
||||||
|
// The event is thrown with one parameter, the lens
|
||||||
|
// itself. This can be used to automatically track
|
||||||
|
// changes to camera fov, etc. in the application.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void Lens::
|
INLINE void Lens::
|
||||||
set_change_event(const string &event) {
|
set_change_event(const string &event) {
|
||||||
@ -122,7 +126,7 @@ set_change_event(const string &event) {
|
|||||||
// Function: Lens::get_change_event
|
// Function: Lens::get_change_event
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns the name of the event that will be generated
|
// Description: Returns the name of the event that will be generated
|
||||||
// whenever any properties of the Lens have
|
// whenever any properties of this particular Lens have
|
||||||
// changed.
|
// changed.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE const string &Lens::
|
INLINE const string &Lens::
|
||||||
|
@ -998,7 +998,7 @@ throw_change_event() {
|
|||||||
++_last_change;
|
++_last_change;
|
||||||
|
|
||||||
if (!_change_event.empty()) {
|
if (!_change_event.empty()) {
|
||||||
throw_event(_change_event);
|
throw_event(_change_event, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also update the _geom_coords, if it is in use.
|
// Also update the _geom_coords, if it is in use.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user