more caching/munger optimizations

This commit is contained in:
David Rose 2005-03-22 18:33:55 +00:00
parent 08a1d4227f
commit 699fe45d8b
18 changed files with 143 additions and 26 deletions

View File

@ -27,3 +27,15 @@ DXGeomMunger8(GraphicsStateGuardian *gsg, const RenderState *state) :
ColorMunger(gsg, state, 1, qpGeomVertexDataType::NT_packed_argb) ColorMunger(gsg, state, 1, qpGeomVertexDataType::NT_packed_argb)
{ {
} }
////////////////////////////////////////////////////////////////////
// Function: DXGeomMunger8::operator new
// Access: Public
// Description: Calls up to do_operator_new() to implement the
// low-overhead allocation/deallocation for this type of
// GeomMunger.
////////////////////////////////////////////////////////////////////
INLINE void *DXGeomMunger8::
operator new(size_t size) {
return do_operator_new(size, _deleted_chain);
}

View File

@ -18,6 +18,7 @@
#include "dxGeomMunger8.h" #include "dxGeomMunger8.h"
qpGeomMunger *DXGeomMunger8::_deleted_chain = NULL;
TypeHandle DXGeomMunger8::_type_handle; TypeHandle DXGeomMunger8::_type_handle;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -40,6 +40,12 @@ protected:
virtual void munge_geom_impl(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &data); virtual void munge_geom_impl(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &data);
virtual int compare_to_impl(const qpGeomMunger *other) const; virtual int compare_to_impl(const qpGeomMunger *other) const;
public:
INLINE void *operator new(size_t size);
private:
static qpGeomMunger *_deleted_chain;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;

View File

@ -28,7 +28,7 @@ CLP(GeomContext)::
nassertv(_display_lists.empty()); nassertv(_display_lists.empty());
} }
//////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
// Function: CLP(GeomContext)::get_display_list // Function: CLP(GeomContext)::get_display_list
// Access: Public // Access: Public
// Description: Looks up the display list index associated with the // Description: Looks up the display list index associated with the
@ -46,7 +46,9 @@ get_display_list(GLuint &index, const CLP(GeomMunger) *munger,
if (dl._index == 0) { if (dl._index == 0) {
dl._index = GLP(GenLists)(1); dl._index = GLP(GenLists)(1);
list_current = false; list_current = false;
((CLP(GeomMunger) *)munger)->_geom_contexts.insert(this); if (munger != (CLP(GeomMunger) *)NULL) {
((CLP(GeomMunger) *)munger)->_geom_contexts.insert(this);
}
} }
index = dl._index; index = dl._index;
@ -78,7 +80,9 @@ release_display_lists() {
++dli) { ++dli) {
CLP(GeomMunger) *munger = (*dli).first; CLP(GeomMunger) *munger = (*dli).first;
const DisplayList &dl = (*dli).second; const DisplayList &dl = (*dli).second;
munger->_geom_contexts.erase(this); if (munger != (CLP(GeomMunger) *)NULL) {
munger->_geom_contexts.erase(this);
}
if (GLCAT.is_debug()) { if (GLCAT.is_debug()) {
GLCAT.debug() GLCAT.debug()

View File

@ -41,3 +41,15 @@ INLINE GraphicsStateGuardian *CLP(GeomMunger)::
get_gsg() const { get_gsg() const {
return _gsg; return _gsg;
} }
////////////////////////////////////////////////////////////////////
// Function: CLP(GeomMunger)::operator new
// Access: Public
// Description: Calls up to do_operator_new() to implement the
// low-overhead allocation/deallocation for this type of
// GeomMunger.
////////////////////////////////////////////////////////////////////
INLINE void *CLP(GeomMunger)::
operator new(size_t size) {
return do_operator_new(size, _deleted_chain);
}

View File

@ -18,6 +18,7 @@
#include "dcast.h" #include "dcast.h"
qpGeomMunger *CLP(GeomMunger)::_deleted_chain = NULL;
TypeHandle CLP(GeomMunger)::_type_handle; TypeHandle CLP(GeomMunger)::_type_handle;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -43,6 +43,9 @@ protected:
virtual int compare_to_impl(const qpGeomMunger *other) const; virtual int compare_to_impl(const qpGeomMunger *other) const;
virtual int geom_compare_to_impl(const qpGeomMunger *other) const; virtual int geom_compare_to_impl(const qpGeomMunger *other) const;
public:
INLINE void *operator new(size_t size);
private: private:
PT(GraphicsStateGuardian) _gsg; PT(GraphicsStateGuardian) _gsg;
CPT(TextureAttrib) _texture; CPT(TextureAttrib) _texture;
@ -51,6 +54,8 @@ private:
typedef pset<CLP(GeomContext) *> GeomContexts; typedef pset<CLP(GeomContext) *> GeomContexts;
GeomContexts _geom_contexts; GeomContexts _geom_contexts;
static qpGeomMunger *_deleted_chain;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;

View File

@ -2142,7 +2142,8 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger,
if (_vertex_data->get_array_info(InternalName::get_color(), if (_vertex_data->get_array_info(InternalName::get_color(),
array_data, num_components, numeric_type, array_data, num_components, numeric_type,
start, stride)) { start, stride) &&
numeric_type != qpGeomVertexDataType::NT_packed_argb) {
const unsigned char *client_pointer = setup_array_data(array_data); const unsigned char *client_pointer = setup_array_data(array_data);
GLP(ColorPointer)(num_components, get_numeric_type(numeric_type), GLP(ColorPointer)(num_components, get_numeric_type(numeric_type),
stride, client_pointer + start); stride, client_pointer + start);
@ -2209,7 +2210,6 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger,
void CLP(GraphicsStateGuardian):: void CLP(GraphicsStateGuardian)::
draw_triangles(const qpGeomTriangles *primitive) { draw_triangles(const qpGeomTriangles *primitive) {
// setup_antialias_polygon(); // setup_antialias_polygon();
_vertices_tri_pcollector.add_level(primitive->get_num_vertices()); _vertices_tri_pcollector.add_level(primitive->get_num_vertices());
const unsigned short *client_pointer = setup_primitive(primitive); const unsigned short *client_pointer = setup_primitive(primitive);
@ -4379,9 +4379,6 @@ get_numeric_type(qpGeomVertexDataType::NumericType numeric_type) {
case qpGeomVertexDataType::NT_uint8: case qpGeomVertexDataType::NT_uint8:
return GL_UNSIGNED_BYTE; return GL_UNSIGNED_BYTE;
case qpGeomVertexDataType::NT_packed_argb:
return GL_UNSIGNED_INT;
case qpGeomVertexDataType::NT_float: case qpGeomVertexDataType::NT_float:
return GL_FLOAT; return GL_FLOAT;
} }

View File

@ -256,8 +256,11 @@ munge_geom(const qpGeomMunger *munger,
PStatTimer timer(qpGeomMunger::_munge_pcollector); PStatTimer timer(qpGeomMunger::_munge_pcollector);
result = this; result = this;
data = munger->munge_data(get_vertex_data()); data = get_vertex_data();
((qpGeomMunger *)munger)->munge_geom_impl(result, data); if (munger != (qpGeomMunger *)NULL) {
data = munger->munge_data(data);
((qpGeomMunger *)munger)->munge_geom_impl(result, data);
}
{ {
// Record the new result in the cache. // Record the new result in the cache.

View File

@ -123,6 +123,49 @@ munge_data(const qpGeomVertexData *data) const {
return ((qpGeomMunger *)this)->munge_data_impl(data); return ((qpGeomMunger *)this)->munge_data_impl(data);
} }
////////////////////////////////////////////////////////////////////
// Function: qpGeomMunger::operator delete
// Access: Public
// Description: This balances do_operator_new(), below, and adds the
// deleted object to the stored deleted_chain, rather
// than returning its memory to the heap.
////////////////////////////////////////////////////////////////////
INLINE void qpGeomMunger::
operator delete(void *ptr) {
qpGeomMunger *obj = (qpGeomMunger *)ptr;
nassertv(obj->_deleted_chain != (qpGeomMunger **)NULL);
nassertv(obj->_next == (qpGeomMunger *)NULL);
obj->_next = (*obj->_deleted_chain);
(*obj->_deleted_chain) = obj;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomMunger::do_operator_new
// Access: Protected, Static
// Description: Intended to be called from a derived class's operator
// new method, this allocates a new object from the
// indicated deleted_chain, if there is an object
// available there, or from the heap if not.
//
// In either case, the indicated deleted_chain pointer
// is cleverly stored on the new object, even before its
// constructor is called, so that it can be returned
// there when it is deleted.
////////////////////////////////////////////////////////////////////
INLINE void *qpGeomMunger::
do_operator_new(size_t size, qpGeomMunger *&deleted_chain) {
qpGeomMunger *obj;
if (deleted_chain != (qpGeomMunger *)NULL) {
obj = deleted_chain;
deleted_chain = deleted_chain->_next;
} else {
obj = (qpGeomMunger *)::operator new(size);
}
obj->_deleted_chain = &deleted_chain;
return obj;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: qpGeomMunger::get_registry // Function: qpGeomMunger::get_registry
// Access: Private // Access: Private

View File

@ -35,7 +35,10 @@ qpGeomMunger::
qpGeomMunger(const GraphicsStateGuardianBase *, const RenderState *) : qpGeomMunger(const GraphicsStateGuardianBase *, const RenderState *) :
_is_registered(false) _is_registered(false)
{ {
#ifndef NDEBUG
_registered_key = get_registry()->_mungers.end(); _registered_key = get_registry()->_mungers.end();
_next = NULL;
#endif
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -47,7 +50,10 @@ qpGeomMunger::
qpGeomMunger(const qpGeomMunger &copy) : qpGeomMunger(const qpGeomMunger &copy) :
_is_registered(false) _is_registered(false)
{ {
#ifndef NDEBUG
_registered_key = get_registry()->_mungers.end(); _registered_key = get_registry()->_mungers.end();
_next = NULL;
#endif
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -88,6 +88,21 @@ protected:
virtual int compare_to_impl(const qpGeomMunger *other) const; virtual int compare_to_impl(const qpGeomMunger *other) const;
virtual int geom_compare_to_impl(const qpGeomMunger *other) const; virtual int geom_compare_to_impl(const qpGeomMunger *other) const;
public:
// To minimize overhead, each type of GeomMunger will implement new
// and delete using their own deleted_chain. This is the base class
// implementation, which requires a pointer to deleted_chain be
// stored on each instance.
INLINE void operator delete(void *ptr);
protected:
INLINE static void *do_operator_new(size_t size, qpGeomMunger *&_deleted_chain);
private:
qpGeomMunger **_deleted_chain;
// This is the next pointer along the deleted_chain.
qpGeomMunger *_next;
private: private:
class Registry; class Registry;
INLINE static Registry *get_registry(); INLINE static Registry *get_registry();

View File

@ -54,3 +54,22 @@ get_bin(int bin_index) {
} }
return make_new_bin(bin_index); return make_new_bin(bin_index);
} }
////////////////////////////////////////////////////////////////////
// Function: CullResult::get_geom_munger
// Access: Private
// Description: Returns a suitable GeomMunger for the indicated
// state. This will ask the GSG to create a new munger
// if we haven't already created one for this state;
// otherwise, it will return the existing one.
////////////////////////////////////////////////////////////////////
INLINE CPT(qpGeomMunger) CullResult::
get_geom_munger(const RenderState *state) {
Mungers::iterator mi = _mungers.find(state);
if (mi != _mungers.end()) {
return (*mi).second;
}
CPT(qpGeomMunger) munger = _gsg->get_geom_munger(state);
_mungers.insert(Mungers::value_type(state, munger));
return munger;
}

View File

@ -128,7 +128,7 @@ add_object(CullableObject *object) {
get_dual_transparent_state_decals() : get_dual_transparent_state_decals() :
get_dual_transparent_state(); get_dual_transparent_state();
transparent_part->_state = state->compose(transparent_state); transparent_part->_state = state->compose(transparent_state);
transparent_part->munge_geom(_gsg); transparent_part->munge_geom(get_geom_munger(transparent_part->_state));
CullBin *bin = get_bin(transparent_part->_state->get_bin_index()); CullBin *bin = get_bin(transparent_part->_state->get_bin_index());
nassertv(bin != (CullBin *)NULL); nassertv(bin != (CullBin *)NULL);
bin->add_object(transparent_part); bin->add_object(transparent_part);
@ -155,7 +155,7 @@ add_object(CullableObject *object) {
// Munge vertices as needed for the GSG's requirements, and the // Munge vertices as needed for the GSG's requirements, and the
// object's current state. // object's current state.
object->munge_geom(_gsg); object->munge_geom(get_geom_munger(object->_state));
CullBin *bin = get_bin(object->_state->get_bin_index()); CullBin *bin = get_bin(object->_state->get_bin_index());
nassertv(bin != (CullBin *)NULL); nassertv(bin != (CullBin *)NULL);

View File

@ -23,11 +23,13 @@
#include "cullBin.h" #include "cullBin.h"
#include "renderState.h" #include "renderState.h"
#include "cullableObject.h" #include "cullableObject.h"
#include "qpgeomMunger.h"
#include "referenceCount.h" #include "referenceCount.h"
#include "pointerTo.h" #include "pointerTo.h"
#include "pvector.h" #include "pvector.h"
#include "pset.h" #include "pset.h"
#include "pmap.h"
class GraphicsStateGuardianBase; class GraphicsStateGuardianBase;
@ -63,6 +65,7 @@ public:
private: private:
CullBin *make_new_bin(int bin_index); CullBin *make_new_bin(int bin_index);
INLINE CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
static CPT(RenderState) get_binary_state(); static CPT(RenderState) get_binary_state();
static CPT(RenderState) get_dual_transparent_state(); static CPT(RenderState) get_dual_transparent_state();
@ -71,6 +74,9 @@ private:
GraphicsStateGuardianBase *_gsg; GraphicsStateGuardianBase *_gsg;
typedef pmap<CPT(RenderState), CPT(qpGeomMunger) > Mungers;
Mungers _mungers;
typedef pvector< PT(CullBin) > Bins; typedef pvector< PT(CullBin) > Bins;
Bins _bins; Bins _bins;
}; };

View File

@ -103,18 +103,6 @@ has_decals() const {
return (_next != (CullableObject *)NULL); return (_next != (CullableObject *)NULL);
} }
////////////////////////////////////////////////////////////////////
// Function: CullableObject::munge_geom
// Access: Public
// Description: Gets a GeomMunger from the GSG to transform the
// geom and/or its vertices to meet the GSG's vertex
// requirements for the current state.
////////////////////////////////////////////////////////////////////
INLINE void CullableObject::
munge_geom(GraphicsStateGuardianBase *gsg) {
munge_geom(gsg->get_geom_munger(_state));
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CullableObject::draw // Function: CullableObject::draw
// Access: Public // Access: Public

View File

@ -54,7 +54,6 @@ public:
INLINE bool has_decals() const; INLINE bool has_decals() const;
INLINE void munge_geom(GraphicsStateGuardianBase *gsg);
void munge_geom(const qpGeomMunger *munger); void munge_geom(const qpGeomMunger *munger);
INLINE void draw(GraphicsStateGuardianBase *gsg); INLINE void draw(GraphicsStateGuardianBase *gsg);

View File

@ -35,7 +35,7 @@ void DrawCullHandler::
record_object(CullableObject *object) { record_object(CullableObject *object) {
// Munge vertices as needed for the GSG's requirements, and the // Munge vertices as needed for the GSG's requirements, and the
// object's current state. // object's current state.
object->munge_geom(_gsg); object->munge_geom(_gsg->get_geom_munger(object->_state));
// And draw the object, then dispense with it. // And draw the object, then dispense with it.
draw(object, _gsg); draw(object, _gsg);