mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -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)
|
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"
|
#include "dxGeomMunger8.h"
|
||||||
|
|
||||||
|
qpGeomMunger *DXGeomMunger8::_deleted_chain = NULL;
|
||||||
TypeHandle DXGeomMunger8::_type_handle;
|
TypeHandle DXGeomMunger8::_type_handle;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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;
|
||||||
|
@ -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()
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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 ©) :
|
qpGeomMunger(const qpGeomMunger ©) :
|
||||||
_is_registered(false)
|
_is_registered(false)
|
||||||
{
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
_registered_key = get_registry()->_mungers.end();
|
_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 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();
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user