|
|
@@ -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;
|
|
|
+ }
|
|
|
+}
|