mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-17 20:23:47 -04:00
add GraphicsOutput::sort
This commit is contained in:
parent
6039e182c0
commit
c26166c9cc
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user