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();
|
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||||
nassertv(gsg != (GraphicsStateGuardian *)NULL);
|
nassertv(gsg != (GraphicsStateGuardian *)NULL);
|
||||||
|
|
||||||
DisplayRegionPipelineReader *dr_reader =
|
PT(SceneSetup) scene_setup;
|
||||||
new DisplayRegionPipelineReader(dr, current_thread);
|
|
||||||
|
|
||||||
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);
|
gsg->clear(dr);
|
||||||
|
}
|
||||||
|
|
||||||
|
scene_setup = setup_scene(gsg, &dr_reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
PT(SceneSetup) scene_setup = setup_scene(gsg, dr_reader);
|
|
||||||
if (scene_setup == (SceneSetup *)NULL) {
|
if (scene_setup == (SceneSetup *)NULL) {
|
||||||
// Never mind.
|
// Never mind.
|
||||||
|
|
||||||
} else if (dr_reader->get_object()->is_stereo()) {
|
} else if (dr->is_stereo()) {
|
||||||
// Don't draw stereo DisplayRegions directly.
|
// Don't draw stereo DisplayRegions directly.
|
||||||
|
|
||||||
} else if (!gsg->set_scene(scene_setup)) {
|
} else if (!gsg->set_scene(scene_setup)) {
|
||||||
@ -1353,9 +1356,6 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
|||||||
} else {
|
} else {
|
||||||
DrawCullHandler cull_handler(gsg);
|
DrawCullHandler cull_handler(gsg);
|
||||||
if (gsg->begin_scene()) {
|
if (gsg->begin_scene()) {
|
||||||
delete dr_reader;
|
|
||||||
dr_reader = NULL;
|
|
||||||
|
|
||||||
CallbackObject *cbobj = dr->get_cull_callback();
|
CallbackObject *cbobj = dr->get_cull_callback();
|
||||||
if (cbobj != (CallbackObject *)NULL) {
|
if (cbobj != (CallbackObject *)NULL) {
|
||||||
// Issue the cull callback on this DisplayRegion.
|
// Issue the cull callback on this DisplayRegion.
|
||||||
@ -1372,10 +1372,6 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
|||||||
gsg->end_scene();
|
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) {
|
for (size_t wi = 0; wi < wlist_size; ++wi) {
|
||||||
GraphicsOutput *win = wlist[wi];
|
GraphicsOutput *win = wlist[wi];
|
||||||
if (win->is_active() && win->get_gsg()->is_active()) {
|
if (win->is_active() && win->get_gsg()->is_active()) {
|
||||||
|
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||||
PStatTimer timer(win->get_cull_window_pcollector(), current_thread);
|
PStatTimer timer(win->get_cull_window_pcollector(), current_thread);
|
||||||
int num_display_regions = win->get_num_active_display_regions();
|
int num_display_regions = win->get_num_active_display_regions();
|
||||||
for (int i = 0; i < num_display_regions; ++i) {
|
for (int i = 0; i < num_display_regions; ++i) {
|
||||||
DisplayRegion *dr = win->get_active_display_region(i);
|
DisplayRegion *dr = win->get_active_display_region(i);
|
||||||
if (dr != (DisplayRegion *)NULL) {
|
if (dr != nullptr) {
|
||||||
DisplayRegionPipelineReader *dr_reader =
|
PT(SceneSetup) scene_setup;
|
||||||
new DisplayRegionPipelineReader(dr, current_thread);
|
PT(CullResult) cull_result;
|
||||||
|
|
||||||
CullKey key;
|
CullKey key;
|
||||||
key._gsg = win->get_gsg();
|
{
|
||||||
key._camera = dr_reader->get_camera();
|
PStatTimer timer(_cull_setup_pcollector, current_thread);
|
||||||
key._lens_index = dr_reader->get_lens_index();
|
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;
|
key._gsg = gsg;
|
||||||
if ((*aci).second == NULL) {
|
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
|
// We have not used this camera already in this thread. Perform
|
||||||
// the cull operation.
|
// the cull operation.
|
||||||
delete dr_reader;
|
cull_result = dr->get_cull_result(current_thread);
|
||||||
dr_reader = NULL;
|
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;
|
(*aci).second = dr;
|
||||||
cull_to_bins(win, dr, current_thread);
|
cull_to_bins(win, gsg, dr, scene_setup, cull_result, current_thread);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// We have already culled a scene using this camera in this
|
// 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
|
// image.) Of course, the cull result will be the same, so just
|
||||||
// use the result from the other DisplayRegion.
|
// use the result from the other DisplayRegion.
|
||||||
DisplayRegion *other_dr = (*aci).second;
|
DisplayRegion *other_dr = (*aci).second;
|
||||||
dr->set_cull_result(other_dr->get_cull_result(current_thread),
|
cull_result = other_dr->get_cull_result(current_thread);
|
||||||
setup_scene(win->get_gsg(), dr_reader),
|
|
||||||
current_thread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dr_reader != (DisplayRegionPipelineReader *)NULL) {
|
// Save the results for next frame.
|
||||||
delete dr_reader;
|
dr->set_cull_result(MOVE(cull_result), MOVE(scene_setup), current_thread);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1447,50 +1454,26 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
|||||||
* Called only within the inner loop of cull_to_bins(), above.
|
* Called only within the inner loop of cull_to_bins(), above.
|
||||||
*/
|
*/
|
||||||
void GraphicsEngine::
|
void GraphicsEngine::
|
||||||
cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
|
cull_to_bins(GraphicsOutput *win, GraphicsStateGuardian *gsg,
|
||||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
DisplayRegion *dr, SceneSetup *scene_setup,
|
||||||
if (gsg == (GraphicsStateGuardian *)NULL) {
|
CullResult *cull_result, Thread *current_thread) {
|
||||||
return;
|
|
||||||
|
BinCullHandler cull_handler(cull_result);
|
||||||
|
CallbackObject *cbobj = dr->get_cull_callback();
|
||||||
|
if (cbobj != (CallbackObject *)NULL) {
|
||||||
|
// Issue the cull callback on this DisplayRegion.
|
||||||
|
DisplayRegionCullCallbackData cbdata(&cull_handler, scene_setup);
|
||||||
|
cbobj->do_callback(&cbdata);
|
||||||
|
|
||||||
|
// The callback has taken care of the culling.
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Perform the cull normally.
|
||||||
|
dr->do_cull(&cull_handler, scene_setup, gsg, current_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
PT(CullResult) cull_result;
|
PStatTimer timer(_cull_sort_pcollector, current_thread);
|
||||||
PT(SceneSetup) scene_setup;
|
cull_result->finish_cull(scene_setup, current_thread);
|
||||||
{
|
|
||||||
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) {
|
|
||||||
// Issue the cull callback on this DisplayRegion.
|
|
||||||
DisplayRegionCullCallbackData cbdata(&cull_handler, scene_setup);
|
|
||||||
cbobj->do_callback(&cbdata);
|
|
||||||
|
|
||||||
// The callback has taken care of the culling.
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Perform the cull normally.
|
|
||||||
dr->do_cull(&cull_handler, scene_setup, gsg, 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) {
|
for (int i = 0; i < num_display_regions; ++i) {
|
||||||
DisplayRegion *dr = win->get_active_display_region(i);
|
DisplayRegion *dr = win->get_active_display_region(i);
|
||||||
if (dr != (DisplayRegion *)NULL) {
|
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
|
* 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.
|
* 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.
|
* Draws the previously-culled scene.
|
||||||
*/
|
*/
|
||||||
void GraphicsEngine::
|
void GraphicsEngine::
|
||||||
do_draw(CullResult *cull_result, SceneSetup *scene_setup,
|
do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thread *current_thread) {
|
||||||
GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
|
|
||||||
|
|
||||||
CallbackObject *cbobj;
|
|
||||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
|
||||||
|
|
||||||
// Statistics
|
// Statistics
|
||||||
PStatGPUTimer timer(gsg, dr->get_draw_region_pcollector(), current_thread);
|
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);
|
DisplayRegionPipelineReader dr_reader(dr, current_thread);
|
||||||
win->change_scenes(&dr_reader);
|
win->change_scenes(&dr_reader);
|
||||||
|
@ -147,9 +147,10 @@ private:
|
|||||||
Thread *current_thread);
|
Thread *current_thread);
|
||||||
|
|
||||||
void cull_to_bins(const Windows &wlist, 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(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 make_contexts(const Windows &wlist, Thread *current_thread);
|
||||||
|
|
||||||
void process_events(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,
|
PT(SceneSetup) setup_scene(GraphicsStateGuardian *gsg,
|
||||||
DisplayRegionPipelineReader *dr);
|
DisplayRegionPipelineReader *dr);
|
||||||
void do_draw(CullResult *cull_result, SceneSetup *scene_setup,
|
void do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg,
|
||||||
GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread);
|
DisplayRegion *dr, Thread *current_thread);
|
||||||
|
|
||||||
void do_add_window(GraphicsOutput *window,
|
void do_add_window(GraphicsOutput *window,
|
||||||
const GraphicsThreadingModel &threading_model);
|
const GraphicsThreadingModel &threading_model);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user