add GraphicsOutput::sort

This commit is contained in:
David Rose 2004-02-19 02:53:23 +00:00
parent 6039e182c0
commit c26166c9cc
7 changed files with 147 additions and 16 deletions

View File

@ -380,10 +380,10 @@ class ShowBase(DirectObject.DirectObject):
# Temporary try .. except for old Pandas.
try:
if type == 'onscreen':
win = self.graphicsEngine.makeWindow(gsg, name)
win = self.graphicsEngine.makeWindow(gsg, name, 0)
elif type == 'offscreen':
win = self.graphicsEngine.makeBuffer(
gsg, name, props.getXSize(), props.getYSize(), 0)
gsg, name, 0, props.getXSize(), props.getYSize(), 0)
except:
if type == 'onscreen':
win = self.graphicsEngine.makeWindow(pipe, gsg)

View File

@ -67,6 +67,8 @@ GraphicsEngine(Pipeline *pipeline) :
_pipeline = Pipeline::get_render_pipeline();
}
_windows_sorted = true;
// Default frame buffer properties.
_frame_buffer_properties.set_depth_bits(1);
_frame_buffer_properties.set_color_bits(1);
@ -203,7 +205,7 @@ make_gsg(GraphicsPipe *pipe, const FrameBufferProperties &properties) {
// later.
////////////////////////////////////////////////////////////////////
GraphicsWindow *GraphicsEngine::
make_window(GraphicsStateGuardian *gsg, const string &name) {
make_window(GraphicsStateGuardian *gsg, const string &name, int sort) {
GraphicsThreadingModel threading_model = get_threading_model();
nassertr(gsg != (GraphicsStateGuardian *)NULL, NULL);
@ -213,6 +215,7 @@ make_window(GraphicsStateGuardian *gsg, const string &name) {
// TODO: ask the window thread to make the window.
PT(GraphicsWindow) window = gsg->get_pipe()->make_window(gsg, name);
window->_sort = sort;
do_add_window(window, gsg, threading_model);
return window;
}
@ -232,9 +235,9 @@ make_window(GraphicsStateGuardian *gsg, const string &name) {
////////////////////////////////////////////////////////////////////
GraphicsOutput *GraphicsEngine::
make_buffer(GraphicsStateGuardian *gsg, const string &name,
int x_size, int y_size, bool want_texture) {
int sort, int x_size, int y_size, bool want_texture) {
if (show_buffers) {
GraphicsWindow *window = make_window(gsg, name);
GraphicsWindow *window = make_window(gsg, name, sort);
if (window != (GraphicsWindow *)NULL) {
WindowProperties props;
props.set_size(x_size, y_size);
@ -261,6 +264,7 @@ make_buffer(GraphicsStateGuardian *gsg, const string &name,
// TODO: ask the window thread to make the buffer.
PT(GraphicsBuffer) buffer =
gsg->get_pipe()->make_buffer(gsg, name, x_size, y_size, want_texture);
buffer->_sort = sort;
do_add_window(buffer, gsg, threading_model);
return buffer;
}
@ -378,6 +382,10 @@ render_frame() {
// don't do that.
MutexHolder holder(_lock);
if (!_windows_sorted) {
do_resort_windows();
}
if (_flip_state != FS_flip) {
do_flip_frame();
}
@ -502,6 +510,23 @@ render_subframe(GraphicsStateGuardian *gsg, DisplayRegion *dr,
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::set_window_sort
// Access: Private
// Description: Changes the sort value of a particular window (or
// buffer) on the GraphicsEngine. This requires
// securing the mutex.
//
// Users shouldn't call this directly; use
// GraphicsOutput::set_sort() instead.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::
set_window_sort(GraphicsOutput *window, int sort) {
MutexHolder holder(_lock);
window->_sort = sort;
_windows_sorted = false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::cull_and_draw_together
// Access: Private
@ -895,7 +920,8 @@ do_add_window(GraphicsOutput *window, GraphicsStateGuardian *gsg,
const GraphicsThreadingModel &threading_model) {
if (window != (GraphicsOutput *)NULL) {
MutexHolder holder(_lock);
_windows.insert(window);
_windows_sorted = false;
_windows.push_back(window);
WindowRenderer *cull = get_window_renderer(threading_model.get_cull_name());
WindowRenderer *draw = get_window_renderer(threading_model.get_draw_name());
@ -937,6 +963,10 @@ do_remove_window(GraphicsOutput *window) {
PT(GraphicsPipe) pipe = window->get_pipe();
window->_pipe = (GraphicsPipe *)NULL;
if (!_windows_sorted) {
do_resort_windows();
}
// Now remove the window from all threads that know about it.
_app.remove_window(window);
Threads::const_iterator ti;
@ -950,6 +980,26 @@ do_remove_window(GraphicsOutput *window) {
_app.do_pending(this);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::do_resort_windows
// Access: Private
// Description: Resorts all of the Windows lists. This may need to
// be done if one or more of the windows' sort
// properties has changed.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::
do_resort_windows() {
_windows_sorted = true;
_app.resort_windows();
Threads::const_iterator ti;
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
RenderThread *thread = (*ti).second;
thread->resort_windows();
}
_windows.sort();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::terminate_threads
// Access: Private
@ -1077,7 +1127,7 @@ remove_window(GraphicsOutput *window) {
// Move it to the pending release thread so we can release the GSG
// when the thread next runs. We can't do this immediately,
// because we might not have been called from the subthread.
_pending_release.insert(ptwin);
_pending_release.push_back(ptwin);
_cdraw.erase(wi);
}
@ -1089,7 +1139,7 @@ remove_window(GraphicsOutput *window) {
// Move it to the pending release thread so we can release the GSG
// when the thread next runs. We can't do this immediately,
// because we might not have been called from the subthread.
_pending_release.insert(ptwin);
_pending_release.push_back(ptwin);
_draw.erase(wi);
}
@ -1106,13 +1156,29 @@ remove_window(GraphicsOutput *window) {
// it can be closed later. We can't close it immediately, because
// we might not have been called from the subthread.
if (ptwin->is_valid()) {
_pending_close.insert(ptwin);
_pending_close.push_back(ptwin);
}
_window.erase(wi);
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::WindowRenderer::resort_windows
// Access: Public
// Description: Resorts all the lists of windows, assuming they may
// have become unsorted.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::WindowRenderer::
resort_windows() {
MutexHolder holder(_wl_lock);
_cull.sort();
_cdraw.sort();
_draw.sort();
_window.sort();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::WindowRenderer::do_frame
// Access: Public
@ -1242,7 +1308,7 @@ do_pending(GraphicsEngine *engine) {
} else {
// If the GSG hasn't been released yet, we have to save the
// close operation for next frame.
new_pending_close.insert(win);
new_pending_close.push_back(win);
}
}
_pending_close.swap(new_pending_close);

View File

@ -29,8 +29,10 @@
#include "thread.h"
#include "pmutex.h"
#include "conditionVar.h"
#include "pset.h"
#include "pStatCollector.h"
#include "pset.h"
#include "ordered_vector.h"
#include "indirectLess.h"
class Pipeline;
class DisplayRegion;
@ -71,8 +73,10 @@ PUBLISHED:
PT(GraphicsStateGuardian) make_gsg(GraphicsPipe *pipe,
const FrameBufferProperties &properties);
GraphicsWindow *make_window(GraphicsStateGuardian *gsg, const string &name);
GraphicsWindow *make_window(GraphicsStateGuardian *gsg, const string &name,
int sort);
GraphicsOutput *make_buffer(GraphicsStateGuardian *gsg, const string &name,
int sort,
int x_size, int y_size, bool want_texture);
bool remove_window(GraphicsOutput *window);
@ -97,17 +101,19 @@ public:
};
private:
typedef pset< PT(GraphicsOutput) > Windows;
typedef ov_multiset< PT(GraphicsOutput), IndirectLess<GraphicsOutput> > Windows;
typedef pset< PT(GraphicsStateGuardian) > GSGs;
void set_window_sort(GraphicsOutput *window, int sort);
void cull_and_draw_together(const Windows &wlist);
void cull_and_draw_together(GraphicsStateGuardian *gsg, DisplayRegion *dr);
void cull_bin_draw(const Windows &wlist);
void cull_bin_draw(GraphicsStateGuardian *gsg, DisplayRegion *dr);
void process_events(const GraphicsEngine::Windows &wlist);
void flip_windows(const GraphicsEngine::Windows &wlist);
void process_events(const Windows &wlist);
void flip_windows(const Windows &wlist);
void do_sync_frame();
void do_flip_frame();
INLINE void close_gsg(GraphicsPipe *pipe, GraphicsStateGuardian *gsg);
@ -124,6 +130,7 @@ private:
void do_add_window(GraphicsOutput *window, GraphicsStateGuardian *gsg,
const GraphicsThreadingModel &threading_model);
void do_remove_window(GraphicsOutput *window);
void do_resort_windows();
void terminate_threads();
// The WindowRenderer class records the stages of the pipeline that
@ -134,6 +141,7 @@ private:
void add_gsg(GraphicsStateGuardian *gsg);
void add_window(Windows &wlist, GraphicsOutput *window);
void remove_window(GraphicsOutput *window);
void resort_windows();
void do_frame(GraphicsEngine *engine);
void do_flip(GraphicsEngine *engine);
void do_release(GraphicsEngine *engine);
@ -145,8 +153,11 @@ private:
Windows _cdraw; // cull-and-draw-together stage
Windows _draw; // draw stage
Windows _window; // window stage, i.e. process windowing events
// These two are not kept sorted.
Windows _pending_release; // moved from _draw, pending release_gsg.
Windows _pending_close; // moved from _window, pending close.
GSGs _gsgs; // draw stage
Mutex _wl_lock;
};
@ -166,6 +177,7 @@ private:
Pipeline *_pipeline;
Windows _windows;
bool _windows_sorted;
WindowRenderer _app;
typedef pmap<string, PT(RenderThread) > Threads;
@ -192,7 +204,9 @@ private:
static PStatCollector _transform_states_unused_pcollector;
static PStatCollector _render_states_pcollector;
static PStatCollector _render_states_unused_pcollector;
friend class WindowRenderer;
friend class GraphicsOutput;
};
#include "graphicsEngine.I"

View File

@ -160,6 +160,19 @@ is_valid() const {
return _is_valid;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::get_sort
// Access: Published
// Description: Returns the sorting order of this particular
// GraphicsOutput. The various GraphicsOutputs within a
// particular thread will be rendered in the indicated
// order.
////////////////////////////////////////////////////////////////////
INLINE int GraphicsOutput::
get_sort() const {
return _sort;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::win_display_regions_changed
// Access: Public
@ -173,6 +186,19 @@ win_display_regions_changed() {
_display_regions_stale = true;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::operator <
// Access: Public
// Description: The sorting operator is used to order the
// GraphicsOutput object in order by their sort number,
// so that they will render in the correct order in the
// GraphicsEngine.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsOutput::
operator < (const GraphicsOutput &other) const {
return _sort < other._sort;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::determine_display_regions

View File

@ -18,6 +18,7 @@
#include "graphicsOutput.h"
#include "graphicsPipe.h"
#include "graphicsEngine.h"
#include "config_display.h"
#include "mutexHolder.h"
#include "hardwareChannel.h"
@ -49,6 +50,7 @@ GraphicsOutput(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
_has_size = false;
_is_valid = false;
_copy_texture = false;
_sort = 0;
_display_regions_stale = false;
@ -112,6 +114,22 @@ is_active() const {
return is_valid();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::set_sort
// Access: Published
// Description: Adjusts the sorting order of this particular
// GraphicsOutput, relative to other GraphicsOutputs.
////////////////////////////////////////////////////////////////////
void GraphicsOutput::
set_sort(int sort) {
if (_sort != sort) {
if (_gsg != (GraphicsStateGuardian *)NULL &&
_gsg->get_engine() != (GraphicsEngine *)NULL) {
_gsg->get_engine()->set_window_sort(this, sort);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::get_channel
// Access: Public

View File

@ -83,6 +83,9 @@ PUBLISHED:
virtual bool is_active() const;
INLINE int get_sort() const;
void set_sort(int sort);
GraphicsChannel *get_channel(int index);
void remove_channel(int index);
@ -104,6 +107,8 @@ public:
// These are not intended to be called directly by the user.
INLINE void win_display_regions_changed();
INLINE bool operator < (const GraphicsOutput &other) const;
virtual void request_open();
virtual void request_close();
@ -146,6 +151,8 @@ private:
INLINE void determine_display_regions() const;
void do_determine_display_regions();
int _sort;
protected:
Mutex _lock;
// protects _channels, _display_regions.

View File

@ -117,7 +117,7 @@ open_window(const WindowProperties &props, GraphicsEngine *engine,
next_window_index++;
string name = stream.str();
_window = engine->make_window(ptgsg, name);
_window = engine->make_window(ptgsg, name, 0);
if (_window != (GraphicsWindow *)NULL) {
_window->request_properties(props);
set_background_type(_background_type);