Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to list rendering backends #1831

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>", "" },
{ "dry-run", "", "Do not read the configuration file", "<bool>", "1" },
{ "no-render", "", "Do not read the configuration 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 @@ -175,7 +176,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 @@ -269,6 +270,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 @@ -484,14 +498,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", "" },
{ "dry-run", "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 @@ -1030,9 +1030,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 @@ -1056,19 +1056,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 @@ -1144,6 +1144,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()
Meakk marked this conversation as resolved.
Show resolved Hide resolved

# 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`, `dry-run` and `input`.
`help`, `version`, `list-readers`, `config`, `dry-run` and `input`.
Meakk marked this conversation as resolved.
Show resolved Hide resolved

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
2 changes: 1 addition & 1 deletion doc/user/OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Options|Default|Description
\-\-no-background||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`.
Meakk marked this conversation as resolved.
Show resolved Hide resolved
\-\-config=\<config file path/name/stem\>|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.
\-\-dry-run||Do not read any configuration file and consider only the command line options.
\-\-no-render||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
*/
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 @@
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 @@
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;
}

Check warning on line 240 in library/src/engine.cxx

View check run for this annotation

Codecov / codecov/patch

library/src/engine.cxx#L240

Added line #L240 was not covered by tests

//----------------------------------------------------------------------------
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
Loading