Panda3D

renderAttrib.cxx

00001 // Filename: renderAttrib.cxx
00002 // Created by:  drose (21Feb02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "renderAttrib.h"
00016 #include "bamReader.h"
00017 #include "indent.h"
00018 #include "config_pgraph.h"
00019 #include "lightReMutexHolder.h"
00020 
00021 LightReMutex *RenderAttrib::_attribs_lock = NULL;
00022 RenderAttrib::Attribs *RenderAttrib::_attribs = NULL;
00023 TypeHandle RenderAttrib::_type_handle;
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //     Function: RenderAttrib::Constructor
00027 //       Access: Protected
00028 //  Description:
00029 ////////////////////////////////////////////////////////////////////
00030 RenderAttrib::
00031 RenderAttrib() {
00032   if (_attribs == (Attribs *)NULL) {
00033     init_attribs();
00034   }
00035   _saved_entry = _attribs->end();
00036 
00037   _always_reissue = false;
00038 }
00039 
00040 ////////////////////////////////////////////////////////////////////
00041 //     Function: RenderAttrib::Copy Constructor
00042 //       Access: Private
00043 //  Description: RenderAttribs are not meant to be copied.
00044 ////////////////////////////////////////////////////////////////////
00045 RenderAttrib::
00046 RenderAttrib(const RenderAttrib &) {
00047   nassertv(false);
00048 }
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: RenderAttrib::Copy Assignment Operator
00052 //       Access: Private
00053 //  Description: RenderAttribs are not meant to be copied.
00054 ////////////////////////////////////////////////////////////////////
00055 void RenderAttrib::
00056 operator = (const RenderAttrib &) {
00057   nassertv(false);
00058 }
00059 
00060 ////////////////////////////////////////////////////////////////////
00061 //     Function: RenderAttrib::Destructor
00062 //       Access: Public, Virtual
00063 //  Description: The destructor is responsible for removing the
00064 //               RenderAttrib from the global set if it is there.
00065 ////////////////////////////////////////////////////////////////////
00066 RenderAttrib::
00067 ~RenderAttrib() {
00068   LightReMutexHolder holder(*_attribs_lock);
00069 
00070   // unref() should have cleared this.
00071   nassertv(_saved_entry == _attribs->end());
00072 }
00073 
00074 ////////////////////////////////////////////////////////////////////
00075 //     Function: RenderAttrib::lower_attrib_can_override
00076 //       Access: Public, Virtual
00077 //  Description: Intended to be overridden by derived RenderAttrib
00078 //               types to specify how two consecutive RenderAttrib
00079 //               objects of the same type interact.
00080 //
00081 //               This should return false if a RenderAttrib on a
00082 //               higher node will compose into a RenderAttrib on a
00083 //               lower node that has a higher override value, or true
00084 //               if the lower RenderAttrib will completely replace the
00085 //               state.
00086 //
00087 //               The default behavior is false: normally, a
00088 //               RenderAttrib in the graph cannot completely override
00089 //               a RenderAttrib above it, regardless of its override
00090 //               value--instead, the two attribs are composed.  But
00091 //               for some kinds of RenderAttribs, it is useful to
00092 //               allow this kind of override.
00093 //
00094 //               This method only handles the one special case of a
00095 //               lower RenderAttrib with a higher override value.  If
00096 //               the higher RenderAttrib has a higher override value,
00097 //               it always completely overrides.  And if both
00098 //               RenderAttribs have the same override value, they are
00099 //               always composed.
00100 ////////////////////////////////////////////////////////////////////
00101 bool RenderAttrib::
00102 lower_attrib_can_override() const {
00103   return false;
00104 }
00105 
00106 ////////////////////////////////////////////////////////////////////
00107 //     Function: RenderAttrib::has_cull_callback
00108 //       Access: Public, Virtual
00109 //  Description: Should be overridden by derived classes to return
00110 //               true if cull_callback() has been defined.  Otherwise,
00111 //               returns false to indicate cull_callback() does not
00112 //               need to be called for this node during the cull
00113 //               traversal.
00114 ////////////////////////////////////////////////////////////////////
00115 bool RenderAttrib::
00116 has_cull_callback() const {
00117   return false;
00118 }
00119 
00120 ////////////////////////////////////////////////////////////////////
00121 //     Function: RenderAttrib::cull_callback
00122 //       Access: Public, Virtual
00123 //  Description: If has_cull_callback() returns true, this function
00124 //               will be called during the cull traversal to perform
00125 //               any additional operations that should be performed at
00126 //               cull time.
00127 //
00128 //               This is called each time the RenderAttrib is
00129 //               discovered applied to a Geom in the traversal.  It
00130 //               should return true if the Geom is visible, false if
00131 //               it should be omitted.
00132 ////////////////////////////////////////////////////////////////////
00133 bool RenderAttrib::
00134 cull_callback(CullTraverser *, const CullTraverserData &) const {
00135   return true;
00136 }
00137 
00138 ////////////////////////////////////////////////////////////////////
00139 //     Function: RenderAttrib::unref
00140 //       Access: Published, Virtual
00141 //  Description: This method overrides ReferenceCount::unref() to
00142 //               clear the pointer from the global object pool when
00143 //               its reference count goes to zero.
00144 ////////////////////////////////////////////////////////////////////
00145 bool RenderAttrib::
00146 unref() const {
00147   // We always have to grab the lock, since we will definitely need to
00148   // be holding it if we happen to drop the reference count to 0.
00149   LightReMutexHolder holder(*_attribs_lock);
00150 
00151   if (ReferenceCount::unref()) {
00152     // The reference count is still nonzero.
00153     return true;
00154   }
00155 
00156   // The reference count has just reached zero.  Make sure the object
00157   // is removed from the global object pool, before anyone else finds
00158   // it and tries to ref it.
00159   ((RenderAttrib *)this)->release_new();
00160 
00161   return false;
00162 }
00163 
00164 ////////////////////////////////////////////////////////////////////
00165 //     Function: RenderAttrib::output
00166 //       Access: Published, Virtual
00167 //  Description: 
00168 ////////////////////////////////////////////////////////////////////
00169 void RenderAttrib::
00170 output(ostream &out) const {
00171   out << get_type();
00172 }
00173 
00174 ////////////////////////////////////////////////////////////////////
00175 //     Function: RenderAttrib::write
00176 //       Access: Published, Virtual
00177 //  Description: 
00178 ////////////////////////////////////////////////////////////////////
00179 void RenderAttrib::
00180 write(ostream &out, int indent_level) const {
00181   indent(out, indent_level) << *this << "\n";
00182 }
00183 
00184 ////////////////////////////////////////////////////////////////////
00185 //     Function: RenderAttrib::get_num_attribs
00186 //       Access: Published, Static
00187 //  Description: Returns the total number of unique RenderAttrib
00188 //               objects allocated in the world.  This will go up and
00189 //               down during normal operations.
00190 ////////////////////////////////////////////////////////////////////
00191 int RenderAttrib::
00192 get_num_attribs() {
00193   LightReMutexHolder holder(*_attribs_lock);
00194 
00195   if (_attribs == (Attribs *)NULL) {
00196     return 0;
00197   }
00198   return _attribs->size();
00199 }
00200 
00201 ////////////////////////////////////////////////////////////////////
00202 //     Function: RenderAttrib::list_attribs
00203 //       Access: Published, Static
00204 //  Description: Lists all of the RenderAttribs in the cache to the
00205 //               output stream, one per line.  This can be quite a lot
00206 //               of output if the cache is large, so be prepared.
00207 ////////////////////////////////////////////////////////////////////
00208 void RenderAttrib::
00209 list_attribs(ostream &out) {
00210   LightReMutexHolder holder(*_attribs_lock);
00211 
00212   out << _attribs->size() << " attribs:\n";
00213   Attribs::const_iterator si;
00214   for (si = _attribs->begin(); si != _attribs->end(); ++si) {
00215     const RenderAttrib *attrib = (*si);
00216     attrib->write(out, 2);
00217   }
00218 }
00219 
00220 ////////////////////////////////////////////////////////////////////
00221 //     Function: RenderAttrib::validate_attribs
00222 //       Access: Published, Static
00223 //  Description: Ensures that the cache is still stored in sorted
00224 //               order.  Returns true if so, false if there is a
00225 //               problem (which implies someone has modified one of
00226 //               the supposedly-const RenderAttrib objects).
00227 ////////////////////////////////////////////////////////////////////
00228 bool RenderAttrib::
00229 validate_attribs() {
00230   LightReMutexHolder holder(*_attribs_lock);
00231 
00232   if (_attribs->empty()) {
00233     return true;
00234   }
00235 
00236   Attribs::const_iterator si = _attribs->begin();
00237   Attribs::const_iterator snext = si;
00238   ++snext;
00239   while (snext != _attribs->end()) {
00240     if ((*si)->compare_to(*(*snext)) >= 0) {
00241       pgraph_cat.error()
00242         << "RenderAttribs out of order!\n";
00243       (*si)->write(pgraph_cat.error(false), 2);
00244       (*snext)->write(pgraph_cat.error(false), 2);
00245       return false;
00246     }
00247     si = snext;
00248     ++snext;
00249   }
00250 
00251   return true;
00252 }
00253 
00254 ////////////////////////////////////////////////////////////////////
00255 //     Function: RenderAttrib::return_new
00256 //       Access: Protected, Static
00257 //  Description: This function is used by derived RenderAttrib types
00258 //               to share a common RenderAttrib pointer for all
00259 //               equivalent RenderAttrib objects.
00260 //
00261 //               This is different from return_unique() in that it
00262 //               does not actually guarantee a unique pointer, unless
00263 //               uniquify-attribs is set.
00264 ////////////////////////////////////////////////////////////////////
00265 CPT(RenderAttrib) RenderAttrib::
00266 return_new(RenderAttrib *attrib) {
00267   nassertr(attrib != (RenderAttrib *)NULL, attrib);
00268   if (!uniquify_attribs) {
00269     return attrib;
00270   }
00271 
00272   return return_unique(attrib);
00273 }
00274 
00275 ////////////////////////////////////////////////////////////////////
00276 //     Function: RenderAttrib::return_unique
00277 //       Access: Protected, Static
00278 //  Description: This function is used by derived RenderAttrib types
00279 //               to share a common RenderAttrib pointer for all
00280 //               equivalent RenderAttrib objects.
00281 //
00282 //               The make() function of the derived type should create
00283 //               a new RenderAttrib and pass it through return_new(),
00284 //               which will either save the pointer and return it
00285 //               unchanged (if this is the first similar such object)
00286 //               or delete it and return an equivalent pointer (if
00287 //               there was already a similar object saved).
00288 ////////////////////////////////////////////////////////////////////
00289 CPT(RenderAttrib) RenderAttrib::
00290 return_unique(RenderAttrib *attrib) {
00291   nassertr(attrib != (RenderAttrib *)NULL, attrib);
00292 
00293 #ifndef NDEBUG
00294   if (!state_cache) {
00295     return attrib;
00296   }
00297 #endif
00298 
00299 #ifndef NDEBUG
00300   if (paranoid_const) {
00301     nassertr(validate_attribs(), attrib);
00302   }
00303 #endif
00304 
00305   LightReMutexHolder holder(*_attribs_lock);
00306 
00307   if (attrib->_saved_entry != _attribs->end()) {
00308     // This attrib is already in the cache.
00309     nassertr(_attribs->find(attrib) == attrib->_saved_entry, attrib);
00310     return attrib;
00311   }
00312 
00313   // Save the attrib in a local PointerTo so that it will be freed at
00314   // the end of this function if no one else uses it.
00315   CPT(RenderAttrib) pt_attrib = attrib;
00316 
00317   pair<Attribs::iterator, bool> result = _attribs->insert(attrib);
00318   if (result.second) {
00319     // The attribute was inserted; save the iterator and return the
00320     // input attribute.
00321     attrib->_saved_entry = result.first;
00322 
00323     return pt_attrib;
00324   }
00325 
00326   // The attribute was not inserted; there must be an equivalent one
00327   // already in the set.  Return that one.
00328   return *(result.first);
00329 }
00330 
00331 ////////////////////////////////////////////////////////////////////
00332 //     Function: RenderAttrib::compare_to_impl
00333 //       Access: Protected, Virtual
00334 //  Description: Intended to be overridden by derived RenderAttrib
00335 //               types to return a unique number indicating whether
00336 //               this RenderAttrib is equivalent to the other one.
00337 //
00338 //               This should return 0 if the two RenderAttrib objects
00339 //               are equivalent, a number less than zero if this one
00340 //               should be sorted before the other one, and a number
00341 //               greater than zero otherwise.
00342 //
00343 //               This will only be called with two RenderAttrib
00344 //               objects whose get_type() functions return the same.
00345 ////////////////////////////////////////////////////////////////////
00346 int RenderAttrib::
00347 compare_to_impl(const RenderAttrib *other) const {
00348   return 0;
00349 }
00350 
00351 ////////////////////////////////////////////////////////////////////
00352 //     Function: RenderAttrib::compose_impl
00353 //       Access: Protected, Virtual
00354 //  Description: Intended to be overridden by derived RenderAttrib
00355 //               types to specify how two consecutive RenderAttrib
00356 //               objects of the same type interact.
00357 //
00358 //               This should return the result of applying the other
00359 //               RenderAttrib to a node in the scene graph below this
00360 //               RenderAttrib, which was already applied.  In most
00361 //               cases, the result is the same as the other
00362 //               RenderAttrib (that is, a subsequent RenderAttrib
00363 //               completely replaces the preceding one).  On the other
00364 //               hand, some kinds of RenderAttrib (for instance,
00365 //               ColorTransformAttrib) might combine in meaningful
00366 //               ways.
00367 ////////////////////////////////////////////////////////////////////
00368 CPT(RenderAttrib) RenderAttrib::
00369 compose_impl(const RenderAttrib *other) const {
00370   return other;
00371 }
00372 
00373 ////////////////////////////////////////////////////////////////////
00374 //     Function: RenderAttrib::invert_compose_impl
00375 //       Access: Protected, Virtual
00376 //  Description: Intended to be overridden by derived RenderAttrib
00377 //               types to specify how two consecutive RenderAttrib
00378 //               objects of the same type interact.
00379 //
00380 //               See invert_compose() and compose_impl().
00381 ////////////////////////////////////////////////////////////////////
00382 CPT(RenderAttrib) RenderAttrib::
00383 invert_compose_impl(const RenderAttrib *other) const {
00384   return other;
00385 }
00386 
00387 ////////////////////////////////////////////////////////////////////
00388 //     Function: RenderAttrib::output_comparefunc
00389 //       Access: Protected
00390 //  Description: Outputs a string representation of the given
00391 //               PandaCompareFunc object.
00392 ////////////////////////////////////////////////////////////////////
00393 void RenderAttrib::
00394 output_comparefunc(ostream &out, PandaCompareFunc fn) const {
00395   switch (fn) {
00396   case M_none:
00397     out << "none";
00398     break;
00399 
00400   case M_never:
00401     out << "never";
00402     break;
00403 
00404   case M_less:
00405     out << "less";
00406     break;
00407 
00408   case M_equal:
00409     out << "equal";
00410     break;
00411 
00412   case M_less_equal:
00413     out << "less_equal";
00414     break;
00415 
00416   case M_greater:
00417     out << "greater";
00418     break;
00419 
00420   case M_not_equal:
00421     out << "not_equal";
00422     break;
00423 
00424   case M_greater_equal:
00425     out << "greater_equal";
00426     break;
00427 
00428   case M_always:
00429     out << "always";
00430     break;
00431   }
00432 }
00433 
00434 ////////////////////////////////////////////////////////////////////
00435 //     Function: RenderAttrib::release_new
00436 //       Access: Private
00437 //  Description: This inverse of return_new, this releases this object
00438 //               from the global RenderAttrib table.
00439 //
00440 //               You must already be holding _attribs_lock before you
00441 //               call this method.
00442 ////////////////////////////////////////////////////////////////////
00443 void RenderAttrib::
00444 release_new() {
00445   nassertv(_attribs_lock->debug_is_locked());
00446 
00447   if (_saved_entry != _attribs->end()) {
00448 
00449 #ifndef NDEBUG
00450     nassertd(_attribs->find(this) == _saved_entry) {
00451       cerr << "Tried to release " << *this << " (" << (void *)this << "), not found!\n";
00452       validate_attribs();
00453       Attribs::const_iterator si = _attribs->begin();
00454       if (si == _attribs->end()) {
00455         cerr << "  Attribs list is empty.\n";
00456       } else {
00457         cerr << "  Attribs list contains " << _attribs->size() << " entries.\n";
00458         const RenderAttrib *attrib = (*si);
00459         cerr << "    " << *attrib << " (" << (void *)attrib << ")\n";
00460 
00461         Attribs::const_iterator sprev = si;
00462         ++si;
00463         while (si != _attribs->end()) {
00464           const RenderAttrib *attrib = (*si);
00465           cerr << "    " << *attrib << " (" << (void *)attrib << ")\n";
00466           if (((*sprev)->compare_to(*attrib)) >= 0) {
00467             cerr << "*** above out of order!\n";
00468           }
00469           sprev = si;
00470           ++si;
00471         }
00472         cerr << "  Done.\n";
00473       }
00474     }
00475 #endif  // NDEBUG
00476 
00477     _attribs->erase(_saved_entry);
00478     _saved_entry = _attribs->end();
00479   }
00480 }
00481 
00482 ////////////////////////////////////////////////////////////////////
00483 //     Function: RenderAttrib::init_attribs
00484 //       Access: Public, Static
00485 //  Description: Make sure the global _attribs map is allocated.  This
00486 //               only has to be done once.  We could make this map
00487 //               static, but then we run into problems if anyone
00488 //               creates a RenderAttrib object at static init time;
00489 //               it also seems to cause problems when the Panda shared
00490 //               library is unloaded at application exit time.
00491 ////////////////////////////////////////////////////////////////////
00492 void RenderAttrib::
00493 init_attribs() {
00494   _attribs = new Attribs;
00495 
00496   // TODO: we should have a global Panda mutex to allow us to safely
00497   // create _attribs_lock without a startup race condition.  For the
00498   // meantime, this is OK because we guarantee that this method is
00499   // called at static init time, presumably when there is still only
00500   // one thread in the world.
00501   _attribs_lock = new LightReMutex("RenderAttrib::_attribs_lock");
00502   nassertv(Thread::get_current_thread() == Thread::get_main_thread());
00503 }
00504 
00505 ////////////////////////////////////////////////////////////////////
00506 //     Function: RenderAttrib::write_datagram
00507 //       Access: Public, Virtual
00508 //  Description: Writes the contents of this object to the datagram
00509 //               for shipping out to a Bam file.
00510 ////////////////////////////////////////////////////////////////////
00511 void RenderAttrib::
00512 write_datagram(BamWriter *manager, Datagram &dg) {
00513   TypedWritable::write_datagram(manager, dg);
00514 }
00515 
00516 ////////////////////////////////////////////////////////////////////
00517 //     Function: RenderAttrib::change_this
00518 //       Access: Public, Static
00519 //  Description: Called immediately after complete_pointers(), this
00520 //               gives the object a chance to adjust its own pointer
00521 //               if desired.  Most objects don't change pointers after
00522 //               completion, but some need to.
00523 //
00524 //               Once this function has been called, the old pointer
00525 //               will no longer be accessed.
00526 ////////////////////////////////////////////////////////////////////
00527 TypedWritable *RenderAttrib::
00528 change_this(TypedWritable *old_ptr, BamReader *manager) {
00529   // First, uniquify the pointer.
00530   RenderAttrib *attrib = DCAST(RenderAttrib, old_ptr);
00531   CPT(RenderAttrib) pointer = return_unique(attrib);
00532 
00533   // But now we have a problem, since we have to hold the reference
00534   // count and there's no way to return a TypedWritable while still
00535   // holding the reference count!  We work around this by explicitly
00536   // upping the count, and also setting a finalize() callback to down
00537   // it later.
00538   if (pointer == attrib) {
00539     pointer->ref();
00540     manager->register_finalize(attrib);
00541   }
00542   
00543   // We have to cast the pointer back to non-const, because the bam
00544   // reader expects that.
00545   return (RenderAttrib *)pointer.p();
00546 }
00547 
00548 ////////////////////////////////////////////////////////////////////
00549 //     Function: RenderAttrib::finalize
00550 //       Access: Public, Virtual
00551 //  Description: Called by the BamReader to perform any final actions
00552 //               needed for setting up the object after all objects
00553 //               have been read and all pointers have been completed.
00554 ////////////////////////////////////////////////////////////////////
00555 void RenderAttrib::
00556 finalize(BamReader *) {
00557   // Unref the pointer that we explicitly reffed in change_this().
00558   unref();
00559 
00560   // We should never get back to zero after unreffing our own count,
00561   // because we expect to have been stored in a pointer somewhere.  If
00562   // we do get to zero, it's a memory leak; the way to avoid this is
00563   // to call unref_delete() above instead of unref(), but this is
00564   // dangerous to do from within a virtual function.
00565   nassertv(get_ref_count() != 0);
00566 }
00567 
00568 ////////////////////////////////////////////////////////////////////
00569 //     Function: RenderAttrib::fillin
00570 //       Access: Protected
00571 //  Description: This internal function is called by make_from_bam to
00572 //               read in all of the relevant data from the BamFile for
00573 //               the new RenderAttrib.
00574 ////////////////////////////////////////////////////////////////////
00575 void RenderAttrib::
00576 fillin(DatagramIterator &scan, BamReader *manager) {
00577   TypedWritable::fillin(scan, manager);
00578   manager->register_change_this(change_this, this);
00579 }
 All Classes Functions Variables Enumerations