mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
display: reduce GraphicsEngine traversal overhead a bit
This commit is contained in:
parent
4a8819b0bd
commit
53258af876
@ -1328,21 +1328,24 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
nassertv(gsg != (GraphicsStateGuardian *)NULL);
|
||||
|
||||
DisplayRegionPipelineReader *dr_reader =
|
||||
new DisplayRegionPipelineReader(dr, current_thread);
|
||||
PT(SceneSetup) scene_setup;
|
||||
|
||||
win->change_scenes(dr_reader);
|
||||
gsg->prepare_display_region(dr_reader);
|
||||
{
|
||||
DisplayRegionPipelineReader dr_reader(dr, current_thread);
|
||||
win->change_scenes(&dr_reader);
|
||||
gsg->prepare_display_region(&dr_reader);
|
||||
|
||||
if (dr_reader->is_any_clear_active()) {
|
||||
if (dr_reader.is_any_clear_active()) {
|
||||
gsg->clear(dr);
|
||||
}
|
||||
|
||||
PT(SceneSetup) scene_setup = setup_scene(gsg, dr_reader);
|
||||
scene_setup = setup_scene(gsg, &dr_reader);
|
||||
}
|
||||
|
||||
if (scene_setup == (SceneSetup *)NULL) {
|
||||
// Never mind.
|
||||
|
||||
} else if (dr_reader->get_object()->is_stereo()) {
|
||||
} else if (dr->is_stereo()) {
|
||||
// Don't draw stereo DisplayRegions directly.
|
||||
|
||||
} else if (!gsg->set_scene(scene_setup)) {
|
||||
@ -1353,9 +1356,6 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
||||
} else {
|
||||
DrawCullHandler cull_handler(gsg);
|
||||
if (gsg->begin_scene()) {
|
||||
delete dr_reader;
|
||||
dr_reader = NULL;
|
||||
|
||||
CallbackObject *cbobj = dr->get_cull_callback();
|
||||
if (cbobj != (CallbackObject *)NULL) {
|
||||
// Issue the cull callback on this DisplayRegion.
|
||||
@ -1372,10 +1372,6 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
||||
gsg->end_scene();
|
||||
}
|
||||
}
|
||||
|
||||
if (dr_reader != (DisplayRegionPipelineReader *)NULL) {
|
||||
delete dr_reader;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1399,27 +1395,41 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
||||
for (size_t wi = 0; wi < wlist_size; ++wi) {
|
||||
GraphicsOutput *win = wlist[wi];
|
||||
if (win->is_active() && win->get_gsg()->is_active()) {
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
PStatTimer timer(win->get_cull_window_pcollector(), current_thread);
|
||||
int num_display_regions = win->get_num_active_display_regions();
|
||||
for (int i = 0; i < num_display_regions; ++i) {
|
||||
DisplayRegion *dr = win->get_active_display_region(i);
|
||||
if (dr != (DisplayRegion *)NULL) {
|
||||
DisplayRegionPipelineReader *dr_reader =
|
||||
new DisplayRegionPipelineReader(dr, current_thread);
|
||||
|
||||
if (dr != nullptr) {
|
||||
PT(SceneSetup) scene_setup;
|
||||
PT(CullResult) cull_result;
|
||||
CullKey key;
|
||||
key._gsg = win->get_gsg();
|
||||
key._camera = dr_reader->get_camera();
|
||||
key._lens_index = dr_reader->get_lens_index();
|
||||
{
|
||||
PStatTimer timer(_cull_setup_pcollector, current_thread);
|
||||
DisplayRegionPipelineReader dr_reader(dr, current_thread);
|
||||
scene_setup = setup_scene(gsg, &dr_reader);
|
||||
if (scene_setup == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AlreadyCulled::iterator aci = already_culled.insert(AlreadyCulled::value_type(key, (DisplayRegion *)NULL)).first;
|
||||
if ((*aci).second == NULL) {
|
||||
key._gsg = gsg;
|
||||
key._camera = dr_reader.get_camera();
|
||||
key._lens_index = dr_reader.get_lens_index();
|
||||
}
|
||||
|
||||
AlreadyCulled::iterator aci = already_culled.insert(AlreadyCulled::value_type(move(key), nullptr)).first;
|
||||
if ((*aci).second == nullptr) {
|
||||
// We have not used this camera already in this thread. Perform
|
||||
// the cull operation.
|
||||
delete dr_reader;
|
||||
dr_reader = NULL;
|
||||
cull_result = dr->get_cull_result(current_thread);
|
||||
if (cull_result != nullptr) {
|
||||
cull_result = cull_result->make_next();
|
||||
} else {
|
||||
// This DisplayRegion has no cull results; draw it.
|
||||
cull_result = new CullResult(gsg, dr->get_draw_region_pcollector());
|
||||
}
|
||||
(*aci).second = dr;
|
||||
cull_to_bins(win, dr, current_thread);
|
||||
cull_to_bins(win, gsg, dr, scene_setup, cull_result, current_thread);
|
||||
|
||||
} else {
|
||||
// We have already culled a scene using this camera in this
|
||||
@ -1429,14 +1439,11 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
||||
// image.) Of course, the cull result will be the same, so just
|
||||
// use the result from the other DisplayRegion.
|
||||
DisplayRegion *other_dr = (*aci).second;
|
||||
dr->set_cull_result(other_dr->get_cull_result(current_thread),
|
||||
setup_scene(win->get_gsg(), dr_reader),
|
||||
current_thread);
|
||||
cull_result = other_dr->get_cull_result(current_thread);
|
||||
}
|
||||
|
||||
if (dr_reader != (DisplayRegionPipelineReader *)NULL) {
|
||||
delete dr_reader;
|
||||
}
|
||||
// Save the results for next frame.
|
||||
dr->set_cull_result(MOVE(cull_result), MOVE(scene_setup), current_thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1447,30 +1454,10 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
||||
* Called only within the inner loop of cull_to_bins(), above.
|
||||
*/
|
||||
void GraphicsEngine::
|
||||
cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
if (gsg == (GraphicsStateGuardian *)NULL) {
|
||||
return;
|
||||
}
|
||||
cull_to_bins(GraphicsOutput *win, GraphicsStateGuardian *gsg,
|
||||
DisplayRegion *dr, SceneSetup *scene_setup,
|
||||
CullResult *cull_result, Thread *current_thread) {
|
||||
|
||||
PT(CullResult) cull_result;
|
||||
PT(SceneSetup) scene_setup;
|
||||
{
|
||||
PStatTimer timer(_cull_setup_pcollector, current_thread);
|
||||
DisplayRegionPipelineReader dr_reader(dr, current_thread);
|
||||
scene_setup = setup_scene(gsg, &dr_reader);
|
||||
cull_result = dr->get_cull_result(current_thread);
|
||||
|
||||
if (cull_result != (CullResult *)NULL) {
|
||||
cull_result = cull_result->make_next();
|
||||
|
||||
} else {
|
||||
// This DisplayRegion has no cull results; draw it.
|
||||
cull_result = new CullResult(gsg, dr->get_draw_region_pcollector());
|
||||
}
|
||||
}
|
||||
|
||||
if (scene_setup != (SceneSetup *)NULL) {
|
||||
BinCullHandler cull_handler(cull_result);
|
||||
CallbackObject *cbobj = dr->get_cull_callback();
|
||||
if (cbobj != (CallbackObject *)NULL) {
|
||||
@ -1487,10 +1474,6 @@ cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
|
||||
|
||||
PStatTimer timer(_cull_sort_pcollector, current_thread);
|
||||
cull_result->finish_cull(scene_setup, current_thread);
|
||||
}
|
||||
|
||||
// Save the results for next frame.
|
||||
dr->set_cull_result(MOVE(cull_result), MOVE(scene_setup), current_thread);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1538,7 +1521,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
||||
for (int i = 0; i < num_display_regions; ++i) {
|
||||
DisplayRegion *dr = win->get_active_display_region(i);
|
||||
if (dr != (DisplayRegion *)NULL) {
|
||||
draw_bins(win, dr, current_thread);
|
||||
do_draw(win, gsg, dr, current_thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1582,22 +1565,6 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This variant on draw_bins() is only called from draw_bins(), above. It
|
||||
* draws the cull result for a particular DisplayRegion.
|
||||
*/
|
||||
void GraphicsEngine::
|
||||
draw_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
if (gsg == (GraphicsStateGuardian *)NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
PT(CullResult) cull_result = dr->get_cull_result(current_thread);
|
||||
PT(SceneSetup) scene_setup = dr->get_scene_setup(current_thread);
|
||||
do_draw(cull_result, scene_setup, win, dr, current_thread);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in the draw thread, this calls make_context() on each window on the
|
||||
* list to guarantee its gsg and graphics context both get created.
|
||||
@ -1899,15 +1866,20 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) {
|
||||
* Draws the previously-culled scene.
|
||||
*/
|
||||
void GraphicsEngine::
|
||||
do_draw(CullResult *cull_result, SceneSetup *scene_setup,
|
||||
GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
|
||||
|
||||
CallbackObject *cbobj;
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
|
||||
do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thread *current_thread) {
|
||||
// Statistics
|
||||
PStatGPUTimer timer(gsg, dr->get_draw_region_pcollector(), current_thread);
|
||||
|
||||
PT(CullResult) cull_result;
|
||||
PT(SceneSetup) scene_setup;
|
||||
{
|
||||
DisplayRegion::CDCullReader cdata(dr->_cycler_cull, current_thread);
|
||||
cull_result = cdata->_cull_result;
|
||||
scene_setup = cdata->_scene_setup;
|
||||
}
|
||||
|
||||
CallbackObject *cbobj;
|
||||
|
||||
{
|
||||
DisplayRegionPipelineReader dr_reader(dr, current_thread);
|
||||
win->change_scenes(&dr_reader);
|
||||
|
@ -147,9 +147,10 @@ private:
|
||||
Thread *current_thread);
|
||||
|
||||
void cull_to_bins(const Windows &wlist, Thread *current_thread);
|
||||
void cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread);
|
||||
void cull_to_bins(GraphicsOutput *win, GraphicsStateGuardian *gsg,
|
||||
DisplayRegion *dr, SceneSetup *scene_setup,
|
||||
CullResult *cull_result, Thread *current_thread);
|
||||
void draw_bins(const Windows &wlist, Thread *current_thread);
|
||||
void draw_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread);
|
||||
void make_contexts(const Windows &wlist, Thread *current_thread);
|
||||
|
||||
void process_events(const Windows &wlist, Thread *current_thread);
|
||||
@ -162,8 +163,8 @@ private:
|
||||
|
||||
PT(SceneSetup) setup_scene(GraphicsStateGuardian *gsg,
|
||||
DisplayRegionPipelineReader *dr);
|
||||
void do_draw(CullResult *cull_result, SceneSetup *scene_setup,
|
||||
GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread);
|
||||
void do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg,
|
||||
DisplayRegion *dr, Thread *current_thread);
|
||||
|
||||
void do_add_window(GraphicsOutput *window,
|
||||
const GraphicsThreadingModel &threading_model);
|
||||
|
Loading…
x
Reference in New Issue
Block a user