Skip to content

Commit

Permalink
Option to list rendering backends (#1831)
Browse files Browse the repository at this point in the history
  • Loading branch information
Meakk authored Dec 30, 2024
1 parent 93d7dee commit 2be0ac5
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 20 deletions.
29 changes: 24 additions & 5 deletions application/F3DOptionsTools.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,13 @@ static inline const std::array<CLIGroup, 8> CLIOptions = {{
{ { "output", "", "Render to file", "<png file>", "" },
{ "no-background", "", "No background when render to file", "<bool>", "1" },
{ "help", "h", "Print help", "", "" }, { "version", "", "Print version details", "", "" },
{ "readers-list", "", "Print the list of readers", "", "" },
{ "bindings-list", "", "Print the list of interaction bindings and exits, ignored with `--no-render`, only considers the first file group.", "", "" },
{ "list-readers", "", "Print the list of readers", "", "" },
{ "list-bindings", "", "Print the list of interaction bindings and exits, ignored with `--no-render`, only considers the first file group.", "", "" },
{ "config", "", "Specify the configuration file to use. absolute/relative path or filename/filestem to search in configuration file locations", "<filePath/filename/fileStem>", "" },
{ "no-config", "", "Do not read the configuration file", "<bool>", "1" },
{ "no-render", "", "Do not render anything and quit right after loading the first file, use with --verbose to recover information about a file.", "<bool>", "1" },
{ "rendering-backend", "", "Backend to use when rendering (auto|glx|wgl|egl|osmesa)", "<string>", "" },
{ "list-rendering-backends", "", "Print the list of rendering backends available on this system", "", "" },
{ "max-size", "", "Maximum size in Mib of a file to load, leave empty for unlimited", "<size in Mib>", "" },
#if F3D_MODULE_DMON
{ "watch", "", "Watch current file and automatically reload it whenever it is modified on disk", "<bool>", "1" },
Expand Down Expand Up @@ -176,7 +177,7 @@ static inline const std::array<CLIGroup, 8> CLIOptions = {{
* True boolean options need to be filtered out in ParseCLIOptions
* This is the easiest, compile time way to do it
*/
constexpr std::array<std::string_view, 4> CLIBooleans = {"version", "help", "readers-list", "scan-plugins"};
constexpr std::array CLIBooleans = {"version", "help", "list-readers", "scan-plugins", "list-rendering-backends"};

//----------------------------------------------------------------------------
/**
Expand Down Expand Up @@ -270,6 +271,19 @@ void PrintVersion()
f3d::log::setUseColoring(true);
}

//----------------------------------------------------------------------------
void PrintRenderingBackendList()
{
auto backends = f3d::engine::getRenderingBackendList();

f3d::log::setUseColoring(false);
f3d::log::info("Rendering backends:");
for (const auto& [name, available] : backends)
{
f3d::log::info(name + ": " + (available ? "available" : "unavailable"));
}
}

//----------------------------------------------------------------------------
void PrintReadersList()
{
Expand Down Expand Up @@ -485,14 +499,19 @@ F3DOptionsTools::OptionsDict F3DOptionsTools::ParseCLIOptions(
::PrintVersion();
throw F3DExNoProcess("version requested");
}
if (result.count("list-rendering-backends") > 0)
{
::PrintRenderingBackendList();
throw F3DExNoProcess("rendering backend list requested");
}
if (result.count("scan-plugins") > 0)
{
::PrintPluginsScan();
throw F3DExNoProcess("scan plugins requested");
}
if (result.count("readers-list") > 0)
if (result.count("list-readers") > 0)
{
// `--readers-list` needs plugin to be loaded to be useful
// `--list-readers` needs plugin to be loaded to be useful
// Load them manually
std::vector<std::string> plugins;
if (result.count("load-plugins") > 0)
Expand Down
2 changes: 1 addition & 1 deletion application/F3DOptionsTools.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ using OptionsEntries = std::vector<OptionsEntry>;
static inline const OptionsDict DefaultAppOptions = {
{ "input", "" },
{ "output", "" },
{ "bindings-list", "false" },
{ "list-bindings", "false" },
{ "no-background", "false" },
{ "config", "" },
{ "no-config", "false" },
Expand Down
2 changes: 1 addition & 1 deletion application/F3DStarter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ class F3DStarter::F3DInternals
{
// Update typed app options from app options
this->AppOptions.Output = f3d::options::parse<std::string>(appOptions.at("output"));
this->AppOptions.BindingsList = f3d::options::parse<bool>(appOptions.at("bindings-list"));
this->AppOptions.BindingsList = f3d::options::parse<bool>(appOptions.at("list-bindings"));
this->AppOptions.NoBackground = f3d::options::parse<bool>(appOptions.at("no-background"));
this->AppOptions.NoRender = f3d::options::parse<bool>(appOptions.at("no-render"));
this->AppOptions.RenderingBackend =
Expand Down
37 changes: 28 additions & 9 deletions application/testing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1039,9 +1039,9 @@ f3d_test(NAME TestConfigFileNoOptions DATA cow.vtp CONFIG ${F3D_SOURCE_DIR}/test
# Test update interaction verbose
f3d_test(NAME TestConfigFileBindingsVerbose DATA dragon.vtu ARGS --verbose CONFIG ${F3D_SOURCE_DIR}/testing/configs/bindings.json REGEXP "'Shift.O' : '`toggle model.point_sprites.enable` '" NO_BASELINE)

# Test bindings-list display with config file
f3d_test(NAME TestConfigFileBindingsList ARGS --bindings-list CONFIG ${F3D_SOURCE_DIR}/testing/configs/bindings.json REGEXP "Ctrl.Shift.O `toggle ui.filename`" NO_BASELINE)
f3d_test(NAME TestConfigFileBindingsListData DATA dragon.vtu ARGS --bindings-list CONFIG ${F3D_SOURCE_DIR}/testing/configs/bindings.json REGEXP "Any.3 `roll_camera 90`" NO_BASELINE)
# Test list-bindings display with config file
f3d_test(NAME TestConfigFileBindingsList ARGS --list-bindings CONFIG ${F3D_SOURCE_DIR}/testing/configs/bindings.json REGEXP "Ctrl.Shift.O `toggle ui.filename`" NO_BASELINE)
f3d_test(NAME TestConfigFileBindingsListData DATA dragon.vtu ARGS --list-bindings CONFIG ${F3D_SOURCE_DIR}/testing/configs/bindings.json REGEXP "Any.3 `roll_camera 90`" NO_BASELINE)

# Test invalid value in config file
f3d_test(NAME TestConfigFileInvalidValue DATA cow.vtp CONFIG ${F3D_SOURCE_DIR}/testing/configs/invalid_value.json REGEXP "must be a string, a boolean or a number" NO_BASELINE)
Expand All @@ -1068,19 +1068,19 @@ f3d_test(NAME TestHelpPositional ARGS --help REGEXP "file1 file2 \.\.\.")
# Test version display
f3d_test(NAME TestVersion ARGS --version REGEXP "Version:")

# Test readers-list display
f3d_test(NAME TestReadersList ARGS --readers-list REGEXP_FAIL "No registered reader found")
# Test list-readers display
f3d_test(NAME TestReadersList ARGS --list-readers REGEXP_FAIL "No registered reader found")

# Test invalid component string coverage
f3d_test(NAME TestInteractionInvalidComponent INTERACTION UI DATA cow.vtp ARGS --coloring-component=1 NO_BASELINE) #H

# Test multi plugin readers-lists
# Test multi plugin list-readers
if(F3D_PLUGIN_BUILD_ALEMBIC AND F3D_PLUGIN_BUILD_ASSIMP)
f3d_test(NAME TestReadersListMultiplePlugins ARGS --readers-list --load-plugins=assimp,alembic NO_BASELINE REGEXP_FAIL "Plugin failed to load")
f3d_test(NAME TestReadersListMultiplePlugins ARGS --list-readers --load-plugins=assimp,alembic NO_BASELINE REGEXP_FAIL "Plugin failed to load")
endif()

# Test bindings-list display
f3d_test(NAME TestBindingsList ARGS --bindings-list REGEXP "Any.Question Print scene descr to terminal")
# Test list-bindings display
f3d_test(NAME TestBindingsList ARGS --list-bindings REGEXP "Any.Question Print scene descr to terminal")

# Test rendering backends
# For some reason the sanitizer detects leaks because of EGL and OSMesa
Expand Down Expand Up @@ -1156,6 +1156,25 @@ f3d_test(NAME TestHelpPrecedenceWithUnknownOption ARGS --help --unknown REGEXP "
# Test that --version is displayed even when there is an unknown option
f3d_test(NAME TestVersionPrecedenceWithUnknownOption ARGS --version --unknown REGEXP "Version:" NO_BASELINE)

# Test rendering backend list
if(WIN32)
f3d_test(NAME TestRenderingBackenListWGL ARGS --list-rendering-backends NO_RENDER NO_BASELINE REGEXP "wgl: available")
elseif(APPLE)
f3d_test(NAME TestRenderingBackenListCOCOA ARGS --list-rendering-backends NO_RENDER NO_BASELINE REGEXP "cocoa: available")
endif()

if(F3D_TESTING_ENABLE_GLX_TESTS AND VTK_VERSION VERSION_GREATER_EQUAL 9.3.20240914)
f3d_test(NAME TestRenderingBackenListGLX ARGS --list-rendering-backends NO_RENDER NO_BASELINE REGEXP "glx: available")
endif()

if(F3D_TESTING_ENABLE_EGL_TESTS AND VTK_VERSION VERSION_GREATER_EQUAL 9.3.20240914)
f3d_test(NAME TestRenderingBackenListEGL ARGS --list-rendering-backends NO_RENDER NO_BASELINE REGEXP "egl: available")
endif()

if(F3D_TESTING_ENABLE_OSMESA_TESTS)
f3d_test(NAME TestRenderingBackenListOSMesa ARGS --list-rendering-backends NO_RENDER NO_BASELINE REGEXP "osmesa: available")
endif()

# Test scan plugins
if(NOT F3D_MACOS_BUNDLE)
f3d_test(NAME TestScanPluginsCheckNative ARGS --scan-plugins NO_RENDER NO_BASELINE REGEXP " - native")
Expand Down
4 changes: 2 additions & 2 deletions doc/user/CONFIGURATION_FILE.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ The third block specifies raytracing usage for .gltf and .glb files.
The last block specifies that volume rendering should be used with .mhd files.

The following options <b> cannot </b> be set via config file:
`help`, `version`, `readers-list`, `config`, `no-config` and `input`.
`help`, `version`, `list-readers`, `list-rendering-backends`, `scan-plugins`, `config`, `no-config` and `input`.

The following options <b>are only taken on the first load</b>:
`no-render`, `output`, `position`, `resolution`, `frame-rate` and all testing options.
Expand Down Expand Up @@ -115,7 +115,7 @@ interaction on the `Any+3` bind and even define a bindings that have multiple co
on the `Ctrl+O` bind.

Please note this configuration feature is only available through config file and not through the command line.
However, it is possible to check your current binding configuration by using the `--bindings-list` CLI options.
However, it is possible to check your current binding configuration by using the `--list-bindings` CLI options.

### Bind

Expand Down
4 changes: 3 additions & 1 deletion doc/user/OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ Options|Type<br>Default|Description
\-\-no-background|bool<br>false|Use with \-\-output to output a png file with a transparent background.
-h, \-\-help||Print *help* and exit. Ignore `--verbose`.
\-\-version||Show *version* information and exit. Ignore `--verbose`.
\-\-readers-list||List available *readers* and exit. Ignore `--verbose`.
\-\-list-readers||List available *readers* and exit. Ignore `--verbose`.
\-\-list-bindings||List available *bindings* and exit. Ignore `--verbose`.
\-\-list-rendering-backends||List available *rendering backends* and exit. Ignore `--verbose`.
\-\-config=\<config file path/name/stem\>|string<br>config|Specify the [configuration file](CONFIGURATION_FILE.md) to use. Supports absolute/relative path but also filename/filestem to search for in standard configuration file locations.
\-\-no-config|bool<br>false|Do not read any configuration file and consider only the command line options.
\-\-no-render|bool<br>false|Do not render anything and quit just after loading the first file, use with \-\-verbose to recover information about a file.
Expand Down
6 changes: 6 additions & 0 deletions library/public/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,12 @@ class F3D_EXPORT engine
*/
[[nodiscard]] interactor& getInteractor();

/**
* List rendering backends supported by libf3d.
* All backends have an associated boolean flag indicating if it can be used.
*/
static std::map<std::string, bool> getRenderingBackendList();

/**
* Load a plugin.
* Supports full path, relative path, and plugin name.
Expand Down
27 changes: 27 additions & 0 deletions library/src/engine.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ namespace f3d
class engine::internals
{
public:
template<typename F>
static bool BackendAvailable(F&& func)
{
try
{
return func() != nullptr;
}
catch (const context::loading_exception&)
{
return false;
}
}

std::unique_ptr<options> Options;
std::unique_ptr<detail::window_impl> Window;
std::unique_ptr<detail::scene_impl> Scene;
Expand Down Expand Up @@ -212,6 +225,20 @@ interactor& engine::getInteractor()
return *this->Internals->Interactor;
}

//----------------------------------------------------------------------------
std::map<std::string, bool> engine::getRenderingBackendList()
{
std::map<std::string, bool> backends;

backends["glx"] = engine::internals::BackendAvailable(context::glx);
backends["wgl"] = engine::internals::BackendAvailable(context::wgl);
backends["cocoa"] = engine::internals::BackendAvailable(context::cocoa);
backends["egl"] = engine::internals::BackendAvailable(context::egl);
backends["osmesa"] = engine::internals::BackendAvailable(context::osmesa);

return backends;
}

//----------------------------------------------------------------------------
void engine::loadPlugin(const std::string& pathOrName, const std::vector<std::string>& searchPaths)
{
Expand Down
3 changes: 2 additions & 1 deletion python/F3DPythonBindings.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,8 @@ PYBIND11_MODULE(pyf3d, module)
"autoload_plugins", &f3d::engine::autoloadPlugins, "Automatically load internal plugins")
.def_static("get_plugins_list", &f3d::engine::getPluginsList)
.def_static("get_lib_info", &f3d::engine::getLibInfo, py::return_value_policy::reference)
.def_static("get_readers_info", &f3d::engine::getReadersInfo);
.def_static("get_readers_info", &f3d::engine::getReadersInfo)
.def_static("get_rendering_backend_list", &f3d::engine::getRenderingBackendList);

// libInformation
py::class_<f3d::engine::libInformation>(module, "LibInformation")
Expand Down
6 changes: 6 additions & 0 deletions python/testing/test_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,9 @@ def test_get_readers_info():
assert isinstance(reader.plugin_name, str) and reader.plugin_name
assert isinstance(reader.has_scene_reader, bool)
assert isinstance(reader.has_geometry_reader, bool)


def test_get_rendering_backend_list():
backends = f3d.Engine.get_rendering_backend_list()

assert isinstance(backends, dict) and len(backends) == 5

0 comments on commit 2be0ac5

Please sign in to comment.