Browse Source

loadAllModules(), etc.

David Rose 23 years ago
parent
commit
62cebed480

+ 9 - 18
panda/src/display/config_display.cxx

@@ -29,12 +29,10 @@
 #include "geomNodeContext.h"
 #include "geomContext.h"
 
-Configure(config_display);
+ConfigureDef(config_display);
 NotifyCategoryDef(display, "");
 NotifyCategoryDef(gsg, display_cat);
 
-static Config::ConfigTable::Symbol *disp;
-
 ConfigureFn(config_display) {
   init_libdisplay();
 }
@@ -59,20 +57,16 @@ const bool pstats_unused_states = config_display.GetBool("pstats-unused-states",
 // system!
 const string threading_model = config_display.GetString("threading-model", "");
 
-// Use this to specify a particular pipe you prefer to use, when more
-// than one GraphicsPipe is available (for instance, if both GL and DX
-// are linked in).  This should be the name of the type preferred, or
-// a substring unique to the type name.
-const string preferred_pipe = config_display.GetString("preferred-pipe", "");
+// Use the variable load-display to specifiy the name of the default
+// graphics display library or GraphicsPipe to load.  It is the name
+// of a shared library (or * for all libraries named in aux-display),
+// optionally followed by the name of the particular GraphicsPipe
+// class to create.
 
+// Also use the variable aux-display to name each of the graphics
+// display libraries that are available on a particular platform.
+// This variable may be repeated several times.
 
-Config::ConfigTable::Symbol::iterator display_modules_begin(void) {
-  return disp->begin();
-}
-
-Config::ConfigTable::Symbol::iterator display_modules_end(void) {
-  return disp->end();
-}
 
 ////////////////////////////////////////////////////////////////////
 //     Function: init_libdisplay
@@ -102,7 +96,4 @@ init_libdisplay() {
   TextureContext::init_type();
   GeomNodeContext::init_type();
   GeomContext::init_type();
-
-  disp = new Config::ConfigTable::Symbol;
-  config_display.GetAll("load-display", *disp);
 }

+ 1 - 4
panda/src/display/config_display.h

@@ -26,6 +26,7 @@
 #include <string>
 #include "pvector.h"
 
+ConfigureDecl(config_display, EXPCL_PANDA, EXPTP_PANDA);
 NotifyCategoryDecl(display, EXPCL_PANDA, EXPTP_PANDA);
 NotifyCategoryDecl(gsg, EXPCL_PANDA, EXPTP_PANDA);
 
@@ -33,10 +34,6 @@ extern const bool view_frustum_cull;
 extern const bool pstats_unused_states;
 
 extern const string threading_model;
-extern const string preferred_pipe;
-
-extern Config::ConfigTable::Symbol::iterator display_modules_begin(void);
-extern Config::ConfigTable::Symbol::iterator display_modules_end(void);
 
 extern EXPCL_PANDA void init_libdisplay();
 

+ 18 - 0
panda/src/display/graphicsPipe.I

@@ -16,3 +16,21 @@
 //
 ////////////////////////////////////////////////////////////////////
 
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsPipe::is_valid
+//       Access: Published
+//  Description: Returns false if this pipe is known to be invalid,
+//               meaning that an attempt to create a GraphicsWindow
+//               with the pipe will certainly fail.  Returns true if
+//               the pipe is probably valid (is this case, an attempt
+//               to create a GraphicsWindow should succeed, but might
+//               still fail).
+//
+//               Use the GraphicsEngine class to create a
+//               GraphicsWindow on a particular pipe.
+////////////////////////////////////////////////////////////////////
+INLINE bool GraphicsPipe::
+is_valid() const {
+  return _is_valid;
+}

+ 4 - 0
panda/src/display/graphicsPipe.cxx

@@ -29,6 +29,9 @@ TypeHandle GraphicsPipe::_type_handle;
 ////////////////////////////////////////////////////////////////////
 GraphicsPipe::
 GraphicsPipe() {
+  // Initially, we assume the GraphicsPipe is valid.  A derived class
+  // should set this to false if it determines otherwise.
+  _is_valid = true;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -38,6 +41,7 @@ GraphicsPipe() {
 ////////////////////////////////////////////////////////////////////
 GraphicsPipe::
 GraphicsPipe(const GraphicsPipe &) {
+  _is_valid = false;
   nassertv(false);
 }
 

+ 8 - 0
panda/src/display/graphicsPipe.h

@@ -59,11 +59,18 @@ PUBLISHED:
   int get_num_windows() const;
   PT(GraphicsWindow) get_window(int n) const;
 
+  INLINE bool is_valid() const;
+  virtual string get_interface_name() const=0;
+
 public:
   virtual int get_num_hw_channels();
   virtual HardwareChannel *get_hw_channel(GraphicsWindow *window, int index);
 
 protected:
+  // The make_window() interface on GraphicsPipe is protected; don't
+  // try to call it directly.  Instead, use
+  // GraphicsEngine::make_window() to make a new window on a
+  // particular pipe.
   virtual PT(GraphicsWindow) make_window()=0;
 
   void add_window(GraphicsWindow *window);
@@ -73,6 +80,7 @@ protected:
   Windows _windows;
   Mutex _lock;
 
+  bool _is_valid;
 
 public:
   static TypeHandle get_class_type() {

+ 21 - 9
panda/src/display/graphicsPipeSelection.I

@@ -16,18 +16,17 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-
 ////////////////////////////////////////////////////////////////////
-//     Function: GraphicsPipeSelection::resolve_modules
+//     Function: GraphicsPipeSelection::get_num_aux_modules
 //       Access: Published
-//  Description: Conditionally calls do_resolve_modules(), if it has
-//               not been called before.
+//  Description: Returns the number of display modules that are still
+//               to be loaded.  If this is nonzero, then calling
+//               load_aux_modules() will likely increase the number of
+//               GraphicsPipes available.
 ////////////////////////////////////////////////////////////////////
-INLINE void GraphicsPipeSelection::
-resolve_modules() const {
-  if (!_resolved_modules) {
-    ((GraphicsPipeSelection *)this)->do_resolve_modules();
-  }
+INLINE int GraphicsPipeSelection::
+get_num_aux_modules() const {
+  return _display_modules.size();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -44,6 +43,19 @@ get_global_ptr() {
   return _global_ptr;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsPipeSelection::load_default_module
+//       Access: Private
+//  Description: Conditionally calls do_load_default_module(), if it has
+//               not been called before.
+////////////////////////////////////////////////////////////////////
+INLINE void GraphicsPipeSelection::
+load_default_module() const {
+  if (!_default_module_loaded) {
+    ((GraphicsPipeSelection *)this)->do_load_default_module();
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsPipeSelection::PipeType::Constructor
 //       Access: Public

+ 138 - 50
panda/src/display/graphicsPipeSelection.cxx

@@ -32,7 +32,43 @@ GraphicsPipeSelection *GraphicsPipeSelection::_global_ptr = NULL;
 ////////////////////////////////////////////////////////////////////
 GraphicsPipeSelection::
 GraphicsPipeSelection() {
-  _resolved_modules = false;
+  // Get the set of modules named in the various aux-display Configrc
+  // variables.  We'll want to know this when we call load_modules()
+  // later.
+  Config::ConfigTable::Symbol disp;
+  config_display.GetAll("aux-display", disp);
+
+  Config::ConfigTable::Symbol::iterator ci;
+  for (ci = disp.begin(); ci != disp.end(); ++ci) {
+    _display_modules.insert((*ci).Val());
+  }
+
+  // Also get the name of the default module from the load-display
+  // variable.  We get this explicitly from Configrc now (instead of
+  // retrieving it in config_display), in case this constructor is
+  // running at static init time.
+  string load_display = config_display.GetString("load-display", "");
+  load_display = trim_right(load_display);
+  size_t space = load_display.rfind(' ');
+  if (space != string::npos) {
+    // If there's a space, it indicates the name of the GraphicsPipe
+    // class to prefer.
+    _default_pipe_name = load_display.substr(space + 1);
+    load_display = trim_right(load_display.substr(0, space));
+  }
+
+  // Everything else is the name of the .dll (or .so) file to load.
+  _default_display_module = load_display;
+
+  if (_default_display_module == "*") {
+    // '*' or empty string is the key for all display modules.
+    _default_display_module = string();
+
+  } else if (!_default_display_module.empty()) {
+    _display_modules.insert(_default_display_module);
+  }
+
+  _default_module_loaded = false;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -53,7 +89,7 @@ GraphicsPipeSelection::
 ////////////////////////////////////////////////////////////////////
 int GraphicsPipeSelection::
 get_num_pipe_types() const {
-  resolve_modules();
+  load_default_module();
 
   int result;
   {
@@ -71,7 +107,7 @@ get_num_pipe_types() const {
 ////////////////////////////////////////////////////////////////////
 TypeHandle GraphicsPipeSelection::
 get_pipe_type(int n) const {
-  resolve_modules();
+  load_default_module();
 
   TypeHandle result;
   {
@@ -83,6 +119,31 @@ get_pipe_type(int n) const {
   return result;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsPipeSelection::print_pipe_types
+//       Access: Published
+//  Description: Writes a list of the currently known GraphicsPipe
+//               types to nout, for the user's information.
+////////////////////////////////////////////////////////////////////
+void GraphicsPipeSelection::
+print_pipe_types() const {
+  load_default_module();
+
+  MutexHolder holder(_lock);
+  nout << "Known pipe types:" << endl;
+  PipeTypes::const_iterator pi;
+  for (pi = _pipe_types.begin(); pi != _pipe_types.end(); ++pi) {
+    const PipeType &pipe_type = (*pi);
+    nout << "  " << pipe_type._type << "\n";
+  }
+  if (_display_modules.empty()) {
+    nout << "(all display modules loaded.)\n";
+  } else {
+    nout << "(" << _display_modules.size() 
+         << " aux display modules not yet loaded.)\n";
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsPipeSelection::make_pipe
 //       Access: Published
@@ -93,7 +154,7 @@ get_pipe_type(int n) const {
 ////////////////////////////////////////////////////////////////////
 PT(GraphicsPipe) GraphicsPipeSelection::
 make_pipe(TypeHandle type) {
-  resolve_modules();
+  load_default_module();
 
   MutexHolder holder(_lock);
   PipeTypes::const_iterator ti;
@@ -135,38 +196,40 @@ make_pipe(TypeHandle type) {
 ////////////////////////////////////////////////////////////////////
 PT(GraphicsPipe) GraphicsPipeSelection::
 make_default_pipe() {
-  resolve_modules();
+  load_default_module();
 
   MutexHolder holder(_lock);
   PipeTypes::const_iterator ti;
 
-  // First, look for an exact match of the requested type (excepting
-  // case and hyphen/underscore).
-  for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
-    const PipeType &ptype = (*ti);
-    if (cmp_nocase_uh(ptype._type.get_name(), preferred_pipe) == 0) {
-      // Here's an exact match.
-      PT(GraphicsPipe) pipe = (*ptype._constructor)();
-      if (pipe != (GraphicsPipe *)NULL) {
-        return pipe;
+  if (!_default_pipe_name.empty()) {
+    // First, look for an exact match of the requested type (excepting
+    // case and hyphen/underscore).
+    for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
+      const PipeType &ptype = (*ti);
+      if (cmp_nocase_uh(ptype._type.get_name(), _default_pipe_name) == 0) {
+        // Here's an exact match.
+        PT(GraphicsPipe) pipe = (*ptype._constructor)();
+        if (pipe != (GraphicsPipe *)NULL) {
+          return pipe;
+        }
       }
     }
-  }
-
-  // No match; look for a substring match.
-  string preferred_name = downcase(preferred_pipe);
-  for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
-    const PipeType &ptype = (*ti);
-    string ptype_name = downcase(ptype._type.get_name());
-    if (ptype_name.find(preferred_name) != string::npos) {
-      // Here's a substring match.
-      PT(GraphicsPipe) pipe = (*ptype._constructor)();
-      if (pipe != (GraphicsPipe *)NULL) {
-        return pipe;
+    
+    // No match; look for a substring match.
+    string preferred_name = downcase(_default_pipe_name);
+    for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
+      const PipeType &ptype = (*ti);
+      string ptype_name = downcase(ptype._type.get_name());
+      if (ptype_name.find(preferred_name) != string::npos) {
+        // Here's a substring match.
+        PT(GraphicsPipe) pipe = (*ptype._constructor)();
+        if (pipe != (GraphicsPipe *)NULL) {
+          return pipe;
+        }
       }
     }
   }
-
+    
   // Couldn't find a matching pipe type; choose one arbitrarily. 
   for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
     const PipeType &ptype = (*ti);
@@ -180,6 +243,24 @@ make_default_pipe() {
   return NULL;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsPipeSelection::load_aux_modules
+//       Access: Published
+//  Description: Loads all the modules named in the aux-display
+//               Configrc variable, making as many graphics pipes as
+//               possible available.
+////////////////////////////////////////////////////////////////////
+void GraphicsPipeSelection::
+load_aux_modules() {
+  DisplayModules::iterator di;
+  for (di = _display_modules.begin(); di != _display_modules.end(); ++di) {
+    load_named_module(*di);
+  }
+
+  _display_modules.clear();
+  _default_module_loaded = true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsPipeSelection::add_pipe_type
 //       Access: Public
@@ -217,35 +298,42 @@ add_pipe_type(TypeHandle type, PipeConstructorFunc *func) {
   return true;
 }
 
+
 ////////////////////////////////////////////////////////////////////
-//     Function: GraphicsPipeSelection::do_resolve_modules
+//     Function: GraphicsPipeSelection::do_load_default_module
 //       Access: Private
-//  Description: Loads the shared objects listed in the load-display
-//               Configrc variable, which should make all of the
-//               dynamic GraphicsPipes available.
+//  Description: Loads the particular display module listed in the
+//               load-display Configrc variable, which should default
+//               the default pipe time.  If this string is empty or
+//               "*", loads all modules named in aux-display.
 ////////////////////////////////////////////////////////////////////
 void GraphicsPipeSelection::
-do_resolve_modules() {
-  Config::ConfigTable::Symbol::iterator ci;
+do_load_default_module() {
+  _default_module_loaded = true;
 
-  // Build up a set of the modules we've already loaded as we go, so
-  // we don't attempt to load a given module more than once.
-  pset<string> already_loaded;
-
-  for (ci = display_modules_begin(); ci != display_modules_end(); ++ci) {
-    string name = (*ci).Val();
-    if (already_loaded.insert(name).second) {
-      Filename dlname = Filename::dso_filename("lib" + name + ".so");
-      display_cat.info()
-        << "loading display module: " << dlname.to_os_specific() << endl;
-      void *tmp = load_dso(dlname);
-      if (tmp == (void *)NULL) {
-        display_cat.info()
-          << "Unable to load: " << load_dso_error() << endl;
-      }
-    }
+  if (_default_display_module.empty()) {
+    load_aux_modules();
+    return;
   }
 
-  _resolved_modules = true;
+  load_named_module(_default_display_module);
+  _display_modules.erase(_default_display_module);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsPipeSelection::load_named_module
+//       Access: Private
+//  Description: Loads the indicated display module by looking for a
+//               matching .dll or .so file.
+////////////////////////////////////////////////////////////////////
+void GraphicsPipeSelection::
+load_named_module(const string &name) {
+  Filename dlname = Filename::dso_filename("lib" + name + ".so");
+  display_cat.info()
+    << "loading display module: " << dlname.to_os_specific() << endl;
+  void *tmp = load_dso(dlname);
+  if (tmp == (void *)NULL) {
+    display_cat.info()
+      << "Unable to load: " << load_dso_error() << endl;
+  }
+}

+ 12 - 3
panda/src/display/graphicsPipeSelection.h

@@ -51,11 +51,13 @@ protected:
 PUBLISHED:
   int get_num_pipe_types() const;
   TypeHandle get_pipe_type(int n) const;
+  void print_pipe_types() const;
 
   PT(GraphicsPipe) make_pipe(TypeHandle type);
   PT(GraphicsPipe) make_default_pipe();
 
-  INLINE void resolve_modules() const;
+  INLINE int get_num_aux_modules() const;
+  void load_aux_modules();
 
   INLINE static GraphicsPipeSelection *get_global_ptr();
 
@@ -64,7 +66,9 @@ public:
   bool add_pipe_type(TypeHandle type, PipeConstructorFunc *func);
 
 private:
-  void do_resolve_modules();
+  INLINE void load_default_module() const;
+  void do_load_default_module();
+  void load_named_module(const string &name);
 
   class PipeType {
   public:
@@ -74,9 +78,14 @@ private:
   };
   typedef pvector<PipeType> PipeTypes;
   PipeTypes _pipe_types;
-  bool _resolved_modules;
   Mutex _lock;
 
+  typedef pset<string> DisplayModules;
+  DisplayModules _display_modules;
+  string _default_display_module;
+  string _default_pipe_name;
+  bool _default_module_loaded;
+
   static GraphicsPipeSelection *_global_ptr;
 };