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() {
85 int GraphicsPipeSelection::
86 get_num_pipe_types()
const {
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 display_cat.warning()
401 <<
"Unable to load: " << load_dso_error() << std::endl;
402 return TypeHandle::none();
407 string symbol_name =
"get_pipe_type_" + name;
408 void *dso_symbol = get_dso_symbol(handle, symbol_name);
409 if (display_cat.is_debug()) {
411 <<
"symbol of " << symbol_name <<
" = " << dso_symbol <<
"\n";
416 if (dso_symbol ==
nullptr) {
418 display_cat.warning()
419 <<
"Unable to find " << symbol_name <<
" in " << dlname.
get_basename()
426 typedef int FuncType();
427 int pipe_type_index = (*(FuncType *)dso_symbol)();
428 if (display_cat.is_debug()) {
430 <<
"pipe_type_index = " << pipe_type_index <<
"\n";
433 if (pipe_type_index != 0) {
436 if (display_cat.is_debug()) {
438 <<
"pipe_type = " << pipe_type <<
"\n";
443 if (pipe_type == TypeHandle::none()) {
448 display_cat.warning()
449 <<
"No default pipe type available for " << dlname.
get_basename()
453 LoadedModule &module = _loaded_modules[name];
454 module._module_name = name;
455 module._module_handle = handle;
456 module._default_pipe_type = pipe_type;
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle find_type_by_id(int id) const
Looks for a previously-registered type with the given id number (as returned by TypeHandle::get_index...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void print_pipe_types() const
Writes a list of the currently known GraphicsPipe types to nout, for the user's information.
string downcase(const string &s)
Returns the input string with all uppercase letters converted to lowercase.
This class is similar to ConfigVariable, but it reports its value as a list of strings.
TypeHandle find_type(const std::string &name) const
Looks for a previously-registered type of the given name.
bool is_derived_from(TypeHandle parent, TypedObject *object=nullptr) const
Returns true if this type is derived from the indicated type, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PT(GraphicsPipe) GraphicsPipeSelection
Creates a new GraphicsPipe of the indicated type (or a type more specific than the indicated type,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The name of a file, such as a texture file or an Egg file.
This is a convenience class to specialize ConfigVariable as a string type.
This maintains a list of GraphicsPipes by type that are available for creation.
Similar to MutexHolder, but for a light mutex.
An object to create GraphicsOutputs that share a particular 3-D API.
std::string get_basename() const
Returns the basename part of the filename.
static TypeRegistry * ptr()
Returns the pointer to the global TypeRegistry object.
void load_aux_modules()
Loads all the modules named in the aux-display Configrc variable, making as many graphics pipes as po...
The TypeRegistry class maintains all the assigned TypeHandles in a given system.
bool add_pipe_type(TypeHandle type, PipeConstructorFunc *func)
Adds a new kind of GraphicsPipe to the list of available pipes for creation.
get_pipe_type
Returns the nth type of GraphicsPipe available through this interface.
TypeHandle is the identifier used to differentiate C++ class types.
std::string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.