32 GraphicsPipeSelection::
33 GraphicsPipeSelection() : _lock(
"GraphicsPipeSelection") {
38 PRC_DESC(
"Specify the name of the default graphics display library or "
39 "GraphicsPipe to load. It is the name of a shared library (or * for "
40 "all libraries named in aux-display), optionally followed by the "
41 "name of the particular GraphicsPipe class to create."));
45 PRC_DESC(
"Names each of the graphics display libraries that are available on "
46 "a particular platform. This variable may be repeated several "
47 "times. These libraries will be tried one at a time if the library "
48 "specified by load_display cannot be loaded."));
50 _default_display_module = load_display.get_word(0);
51 _default_pipe_name = load_display.get_word(1);
53 if (_default_display_module ==
"*") {
55 _default_display_module = string();
57 }
else if (!_default_display_module.empty()) {
58 _display_modules.push_back(_default_display_module);
63 size_t num_aux = aux_display.get_num_unique_values();
64 for (
size_t i = 0; i < num_aux; ++i) {
65 string name = aux_display.get_unique_value(i);
66 if (name != _default_display_module) {
67 _display_modules.push_back(name);
71 _default_module_loaded =
false;
77 GraphicsPipeSelection::
78 ~GraphicsPipeSelection() {
87 load_default_module();
92 result = _pipe_types.size();
102 load_default_module();
107 if (n >= 0 && n < (
int)_pipe_types.size()) {
108 result = _pipe_types[n]._type;
110 result = TypeHandle::none();
122 load_default_module();
125 nout <<
"Known pipe types:" << std::endl;
126 for (
const PipeType &pipe_type : _pipe_types) {
127 nout <<
" " << pipe_type._type <<
"\n";
129 if (_display_modules.empty()) {
130 nout <<
"(all display modules loaded.)\n";
132 nout <<
"(" << _display_modules.size()
133 <<
" aux display modules not yet loaded.)\n";
146 make_pipe(
const string &type_name,
const string &module_name) {
153 if (type == TypeHandle::none()) {
154 if (!module_name.empty()) {
155 load_named_module(module_name);
161 if (type == TypeHandle::none()) {
162 load_default_module();
167 if (type == TypeHandle::none()) {
172 if (type == TypeHandle::none()) {
176 return make_pipe(type);
189 for (
const PipeType &ptype : _pipe_types) {
190 if (ptype._type == type) {
193 if (pipe !=
nullptr) {
200 for (
const PipeType &ptype : _pipe_types) {
201 if (ptype._type.is_derived_from(type)) {
204 if (pipe !=
nullptr) {
211 load_default_module();
212 for (
const PipeType &ptype : _pipe_types) {
213 if (ptype._type.is_derived_from(type)) {
216 if (pipe !=
nullptr) {
232 make_module_pipe(
const string &module_name) {
233 if (display_cat.is_debug()) {
235 <<
"make_module_pipe(" << module_name <<
")\n";
238 TypeHandle pipe_type = load_named_module(module_name);
239 if (pipe_type == TypeHandle::none()) {
243 return make_pipe(pipe_type);
252 make_default_pipe() {
253 load_default_module();
257 if (!_default_pipe_name.empty()) {
260 for (
const PipeType &ptype : _pipe_types) {
261 if (cmp_nocase_uh(ptype._type.get_name(), _default_pipe_name) == 0) {
264 if (pipe !=
nullptr) {
271 string preferred_name =
downcase(_default_pipe_name);
272 for (
const PipeType &ptype : _pipe_types) {
273 string ptype_name =
downcase(ptype._type.get_name());
274 if (ptype_name.find(preferred_name) != string::npos) {
277 if (pipe !=
nullptr) {
285 for (
const PipeType &ptype : _pipe_types) {
287 if (pipe !=
nullptr) {
302 for (
const string &module : _display_modules) {
303 load_named_module(module);
306 _display_modules.clear();
307 _default_module_loaded =
true;
318 nassertr(func !=
nullptr,
false);
321 display_cat->warning()
322 <<
"Attempt to register " << type <<
" as a GraphicsPipe type.\n";
328 for (
const PipeType &ptype : _pipe_types) {
329 if (ptype._type == type) {
330 display_cat->warning()
331 <<
"Attempt to register GraphicsPipe type " << type
332 <<
" more than once.\n";
337 if (display_cat->is_debug()) {
339 <<
"Registering " << type <<
" as a GraphicsPipe type.\n";
343 _pipe_types.push_back(PipeType(type, func));
354 void GraphicsPipeSelection::
355 do_load_default_module() {
356 if (_default_display_module.empty()) {
361 load_named_module(_default_display_module);
363 DisplayModules::iterator di =
364 std::find(_display_modules.begin(), _display_modules.end(),
365 _default_display_module);
366 if (di != _display_modules.end()) {
367 _display_modules.erase(di);
370 _default_module_loaded =
true;
372 if (_pipe_types.empty()) {
385 load_named_module(
const string &name) {
388 LoadedModules::iterator mi = _loaded_modules.find(name);
389 if (mi != _loaded_modules.end()) {
391 return (*mi).second._default_pipe_type;
395 Filename dlname = Filename::dso_filename(
"lib" + name +
".so");
397 <<
"loading display module: " << dlname.
to_os_specific() << std::endl;
398 void *handle = load_dso(get_plugin_path().get_value(), dlname);
399 if (handle ==
nullptr) {
400 std::string error = load_dso_error();
401 display_cat.warning()
402 <<
"Unable to load " << dlname.
get_basename() <<
": " << error << std::endl;
403 return TypeHandle::none();
408 string symbol_name =
"get_pipe_type_" + name;
409 void *dso_symbol = get_dso_symbol(handle, symbol_name);
410 if (display_cat.is_debug()) {
412 <<
"symbol of " << symbol_name <<
" = " << dso_symbol <<
"\n";
417 if (dso_symbol ==
nullptr) {
419 display_cat.warning()
420 <<
"Unable to find " << symbol_name <<
" in " << dlname.
get_basename()
427 typedef int FuncType();
428 int pipe_type_index = (*(FuncType *)dso_symbol)();
429 if (display_cat.is_debug()) {
431 <<
"pipe_type_index = " << pipe_type_index <<
"\n";
434 if (pipe_type_index != 0) {
437 if (display_cat.is_debug()) {
439 <<
"pipe_type = " << pipe_type <<
"\n";
444 if (pipe_type == TypeHandle::none()) {
449 display_cat.warning()
450 <<
"No default pipe type available for " << dlname.
get_basename()
454 LoadedModule &module = _loaded_modules[name];
455 module._module_name = name;
456 module._module_handle = handle;
457 module._default_pipe_type = pipe_type;