mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
more caching/munger optimizations
This commit is contained in:
parent
08a1d4227f
commit
699fe45d8b
@ -27,3 +27,15 @@ DXGeomMunger8(GraphicsStateGuardian *gsg, const RenderState *state) :
|
||||
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);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "dxGeomMunger8.h"
|
||||
|
||||
qpGeomMunger *DXGeomMunger8::_deleted_chain = NULL;
|
||||
TypeHandle DXGeomMunger8::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -40,6 +40,12 @@ protected:
|
||||
virtual void munge_geom_impl(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &data);
|
||||
virtual int compare_to_impl(const qpGeomMunger *other) const;
|
||||
|
||||
public:
|
||||
INLINE void *operator new(size_t size);
|
||||
|
||||
private:
|
||||
static qpGeomMunger *_deleted_chain;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
@ -28,7 +28,7 @@ CLP(GeomContext)::
|
||||
nassertv(_display_lists.empty());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GeomContext)::get_display_list
|
||||
// Access: Public
|
||||
// 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) {
|
||||
dl._index = GLP(GenLists)(1);
|
||||
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;
|
||||
@ -78,7 +80,9 @@ release_display_lists() {
|
||||
++dli) {
|
||||
CLP(GeomMunger) *munger = (*dli).first;
|
||||
const DisplayList &dl = (*dli).second;
|
||||
munger->_geom_contexts.erase(this);
|
||||
if (munger != (CLP(GeomMunger) *)NULL) {
|
||||
munger->_geom_contexts.erase(this);
|
||||
}
|
||||
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
|
@ -41,3 +41,15 @@ INLINE GraphicsStateGuardian *CLP(GeomMunger)::
|
||||
get_gsg() const {
|
||||
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);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "dcast.h"
|
||||
|
||||
qpGeomMunger *CLP(GeomMunger)::_deleted_chain = NULL;
|
||||
TypeHandle CLP(GeomMunger)::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -43,6 +43,9 @@ protected:
|
||||
virtual int 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:
|
||||
PT(GraphicsStateGuardian) _gsg;
|
||||
CPT(TextureAttrib) _texture;
|
||||
@ -51,6 +54,8 @@ private:
|
||||
typedef pset<CLP(GeomContext) *> GeomContexts;
|
||||
GeomContexts _geom_contexts;
|
||||
|
||||
static qpGeomMunger *_deleted_chain;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
@ -2142,7 +2142,8 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger,
|
||||
|
||||
if (_vertex_data->get_array_info(InternalName::get_color(),
|
||||
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);
|
||||
GLP(ColorPointer)(num_components, get_numeric_type(numeric_type),
|
||||
stride, client_pointer + start);
|
||||
@ -2209,7 +2210,6 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger,
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
draw_triangles(const qpGeomTriangles *primitive) {
|
||||
// setup_antialias_polygon();
|
||||
|
||||
_vertices_tri_pcollector.add_level(primitive->get_num_vertices());
|
||||
const unsigned short *client_pointer = setup_primitive(primitive);
|
||||
|
||||
@ -4379,9 +4379,6 @@ get_numeric_type(qpGeomVertexDataType::NumericType numeric_type) {
|
||||
case qpGeomVertexDataType::NT_uint8:
|
||||
return GL_UNSIGNED_BYTE;
|
||||
|
||||
case qpGeomVertexDataType::NT_packed_argb:
|
||||
return GL_UNSIGNED_INT;
|
||||
|
||||
case qpGeomVertexDataType::NT_float:
|
||||
return GL_FLOAT;
|
||||
}
|
||||
|
@ -256,8 +256,11 @@ munge_geom(const qpGeomMunger *munger,
|
||||
PStatTimer timer(qpGeomMunger::_munge_pcollector);
|
||||
|
||||
result = this;
|
||||
data = munger->munge_data(get_vertex_data());
|
||||
((qpGeomMunger *)munger)->munge_geom_impl(result, data);
|
||||
data = get_vertex_data();
|
||||
if (munger != (qpGeomMunger *)NULL) {
|
||||
data = munger->munge_data(data);
|
||||
((qpGeomMunger *)munger)->munge_geom_impl(result, data);
|
||||
}
|
||||
|
||||
{
|
||||
// Record the new result in the cache.
|
||||
|
@ -123,6 +123,49 @@ munge_data(const qpGeomVertexData *data) const {
|
||||
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
|
||||
// Access: Private
|
||||
|
@ -35,7 +35,10 @@ qpGeomMunger::
|
||||
qpGeomMunger(const GraphicsStateGuardianBase *, const RenderState *) :
|
||||
_is_registered(false)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
_registered_key = get_registry()->_mungers.end();
|
||||
_next = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -47,7 +50,10 @@ qpGeomMunger::
|
||||
qpGeomMunger(const qpGeomMunger ©) :
|
||||
_is_registered(false)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
_registered_key = get_registry()->_mungers.end();
|
||||
_next = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -88,6 +88,21 @@ protected:
|
||||
virtual int 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:
|
||||
class Registry;
|
||||
INLINE static Registry *get_registry();
|
||||
|
@ -54,3 +54,22 @@ get_bin(int 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;
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ add_object(CullableObject *object) {
|
||||
get_dual_transparent_state_decals() :
|
||||
get_dual_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());
|
||||
nassertv(bin != (CullBin *)NULL);
|
||||
bin->add_object(transparent_part);
|
||||
@ -155,7 +155,7 @@ add_object(CullableObject *object) {
|
||||
|
||||
// Munge vertices as needed for the GSG's requirements, and the
|
||||
// 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());
|
||||
nassertv(bin != (CullBin *)NULL);
|
||||
|
@ -23,11 +23,13 @@
|
||||
#include "cullBin.h"
|
||||
#include "renderState.h"
|
||||
#include "cullableObject.h"
|
||||
#include "qpgeomMunger.h"
|
||||
|
||||
#include "referenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pvector.h"
|
||||
#include "pset.h"
|
||||
#include "pmap.h"
|
||||
|
||||
|
||||
class GraphicsStateGuardianBase;
|
||||
@ -63,6 +65,7 @@ public:
|
||||
|
||||
private:
|
||||
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_dual_transparent_state();
|
||||
@ -71,6 +74,9 @@ private:
|
||||
|
||||
GraphicsStateGuardianBase *_gsg;
|
||||
|
||||
typedef pmap<CPT(RenderState), CPT(qpGeomMunger) > Mungers;
|
||||
Mungers _mungers;
|
||||
|
||||
typedef pvector< PT(CullBin) > Bins;
|
||||
Bins _bins;
|
||||
};
|
||||
|
@ -103,18 +103,6 @@ has_decals() const {
|
||||
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
|
||||
// Access: Public
|
||||
|
@ -54,7 +54,6 @@ public:
|
||||
|
||||
INLINE bool has_decals() const;
|
||||
|
||||
INLINE void munge_geom(GraphicsStateGuardianBase *gsg);
|
||||
void munge_geom(const qpGeomMunger *munger);
|
||||
INLINE void draw(GraphicsStateGuardianBase *gsg);
|
||||
|
||||
|
@ -35,7 +35,7 @@ void DrawCullHandler::
|
||||
record_object(CullableObject *object) {
|
||||
// Munge vertices as needed for the GSG's requirements, and the
|
||||
// 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.
|
||||
draw(object, _gsg);
|
||||
|
Loading…
x
Reference in New Issue
Block a user