diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4f92c01..024dcc0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,8 +19,10 @@ verify_and_build: - python3 -m pip install -r requirements.txt script: - ./verify_schema.sh - - ./extension_support_report.py + - make artifacts: paths: - public/extension_support.html - expose_as: "Extension Support Report" + - public/runtime_extension_support.html + - public/client_extension_support.html + expose_as: "Extension Support Reports" diff --git a/Makefile b/Makefile index ac64584..e268386 100644 --- a/Makefile +++ b/Makefile @@ -3,10 +3,13 @@ # # SPDX-License-Identifier: Apache-2.0 -HTML_REPORT_FILES := public/extension_support.html +HTML_REPORT_FILES := public/runtime_extension_support.html public/client_extension_support.html public/extension_support.html SHARED_DEPS := $(wildcard openxr_inventory/*.py) \ $(wildcard runtimes/*.json) \ - openxr_inventory/templates/base.jinja2.html + $(wildcard clients/*.json) \ + openxr_inventory/templates/base.jinja2.html \ + openxr_inventory/templates/runtime_extension_support.jinja2.html \ + openxr_inventory/templates/client_extension_support.jinja2.html all: $(HTML_REPORT_FILES) @@ -15,5 +18,11 @@ all: $(HTML_REPORT_FILES) public: mkdir -p $@ -$(HTML_REPORT_FILES): public/%.html : %_report.py openxr_inventory/templates/%.jinja2.html public $(SHARED_DEPS) +public/runtime_extension_support.html: extension_support_report.py public $(SHARED_DEPS) python3 $< + +public/client_extension_support.html: extension_support_report.py public $(SHARED_DEPS) + python3 $< + +public/extension_support.html: openxr_inventory/templates/extension_support.html public + cp $< $@ diff --git a/extension_support_report.py b/extension_support_report.py index c20176f..6f7b750 100755 --- a/extension_support_report.py +++ b/extension_support_report.py @@ -3,11 +3,12 @@ # # SPDX-License-Identifier: Apache-2.0 -from openxr_inventory.extensions import generate_report +from openxr_inventory.extensions import generate_runtime_report, generate_client_report from openxr_inventory.runtime_inventory import load_all_runtimes from openxr_inventory.client_inventory import load_all_clients if __name__ == "__main__": runtimes = load_all_runtimes() clients = load_all_clients() - generate_report(runtimes, clients) + generate_runtime_report(runtimes, clients) + generate_client_report(runtimes, clients) diff --git a/openxr_inventory/extensions.py b/openxr_inventory/extensions.py index d222ae1..8b14690 100644 --- a/openxr_inventory/extensions.py +++ b/openxr_inventory/extensions.py @@ -209,18 +209,50 @@ def compute_extension_support( return extension_support -_FILENAME_STEM = "extension_support" +def generate_runtime_report( + runtimes: List[RuntimeData], + clients: List[ClientData], + template_filename: str = "runtime_extension_support.jinja2.html", + out_filename: str = "public/runtime_extension_support.html", +): + """ + Write an HTML file containing information about runtime extension support. + """ + from .inventory_jinja import make_jinja_environment + + env = make_jinja_environment() + env.globals["cat"] = ExtensionCategory + env.globals["cat_captions"] = _category_captions + env.globals["categorize_ext"] = categorize_ext_name + template = env.get_template(template_filename) + spec_url = "https://www.khronos.org/registry/OpenXR/specs/1.1/html/xrspec.html" + contents = template.render( + extensions=compute_known_extensions(runtimes, clients), + extension_support=compute_extension_support(runtimes, clients), + runtime_support=compute_runtime_support(runtimes), + client_support=compute_client_support(clients), + known_form_factors=compute_known_form_factors(runtimes, clients), + form_factor_support=compute_form_factor_support(runtimes, clients), + runtimes=runtimes, + clients=clients, + spec_url=spec_url, + ) + + if contents: + out_file = Path(__file__).parent.parent / out_filename + print("Writing {}".format(out_file)) + with open(out_file, "w", encoding="utf-8") as fp: + fp.write(contents) -def generate_report( +def generate_client_report( runtimes: List[RuntimeData], clients: List[ClientData], - template_filename: str = _FILENAME_STEM + ".jinja2.html", - out_filename: str = "public/" + _FILENAME_STEM + ".html", + template_filename: str = "client_extension_support.jinja2.html", + out_filename: str = "public/client_extension_support.html", ): """ - Write an HTML file in the parent directory containing information about the available extensions - and the runtimes that support them. + Write an HTML file containing information about client extension support. """ from .inventory_jinja import make_jinja_environment @@ -255,4 +287,5 @@ def generate_report( runtimes = load_all_runtimes() clients = load_all_clients() - generate_report(runtimes, clients) + generate_runtime_report(runtimes, clients) + generate_client_report(runtimes, clients) diff --git a/openxr_inventory/templates/extension_support.jinja2.html b/openxr_inventory/templates/client_extension_support.jinja2.html similarity index 54% rename from openxr_inventory/templates/extension_support.jinja2.html rename to openxr_inventory/templates/client_extension_support.jinja2.html index 7fe215d..3ac70b0 100644 --- a/openxr_inventory/templates/extension_support.jinja2.html +++ b/openxr_inventory/templates/client_extension_support.jinja2.html @@ -6,19 +6,17 @@ {% extends "base.jinja2.html" %} {% block title -%} - OpenXR Runtime Extension Support Report + OpenXR Client Extension Support Report {%- endblock title %} {% block navbar_brand_text -%} - OpenXR Runtime Extension Support Report + OpenXR Client Extension Support Report {%- endblock navbar_brand_text %} {% block navbar_list_items %} +
  • Client Support Matrix
  • Extensions
  • -
  • Runtimes
  • -
  • Runtime Support Matrix
  • Clients
  • -
  • Client Support Matrix
  • {% endblock navbar_list_items %} {% block style %} @@ -46,109 +44,25 @@ {% endblock style %} {% block container_contents %} -
    - - -
    -

    Extensions

    - {% for col in extensions | slice(3) %} -
    - -
    - {% endfor %} -
    - - {% for extension_name in extensions %} - {% set support = extension_support[extension_name] %} - -
    -

    {{ extension_name }} ({{ support.runtime_count }} runtime{{ "s" if support.runtime_count != 1 }}, {{ support.client_count }} client{{ "s" if support.client_count != 1 }})

    -

    - Specification - for {{ extension_name }} -

    - Runtimes:
    - - {% if support.client_count > 0 %} - Clients:
    - - {% endif %} -
    - {% endfor %} -
    - -
    - -
    -

    Runtimes

    - - -
    - - {% for runtime in runtimes %} -
    -

    {{ runtime.name }}

    - -
    - {% endfor %} -
    -
    -
    -

    Runtime support matrix

    +
    +

    Client support matrix

    - {% for runtime in runtimes | sort %} - {# pragmatic check if the runtime name fits in the layout or if it needs to be truncated and put the full name in tooltip #} - {% if runtime.name|length < 34 %} - - {% else %} - - {% endif %} + {% for client in clients | sort %} + {# pragmatic check if the client name fits in the layout or if it needs to be truncated and put the full name in tooltip #} + {% endfor %} @@ -162,9 +76,17 @@

    Runtime support matrix

    - {% for runtime in runtimes | sort %} - {% if extension_name in runtime_support[runtime.name] %} - + {% for client in clients | sort %} + {% set components = client.get_component_for_extension(extension_name) %} + {% if components|length > 0 %} + {% else %} {% endif %} @@ -180,7 +102,7 @@

    Runtime support matrix

    {# this header is inside the loop so it is skipped if we have no items in this category #} {# it is inside this "if" so it only shows up once for each category. #} - + {% endif %} {# Write out a row in the table for this extension #} @@ -189,7 +111,7 @@

    Runtime support matrix

    {% endfor %} - + {% for ff, view_configurations in known_form_factors.items() %} @@ -201,7 +123,7 @@

    Runtime support matrix

    - {% for runtime in runtimes | sort %} + {% for client in clients | sort %} {% endfor %} @@ -215,7 +137,7 @@

    Runtime support matrix

    - {% for runtime in runtimes | sort %} + {% for client in clients | sort %} {% endfor %} @@ -227,8 +149,8 @@

    Runtime support matrix

    - {% for runtime in runtimes | sort %} - {% if ff in form_factor_support[runtime.name] and vc in form_factor_support[runtime.name][ff] and ebm in form_factor_support[runtime.name][ff][vc] %} + {% for client in clients | sort %} + {% if ff in form_factor_support[client.name] and vc in form_factor_support[client.name][ff] and ebm in form_factor_support[client.name][ff][vc] %} {% else %} @@ -246,6 +168,47 @@

    Runtime support matrix

    {{ runtime.name }}
    {{ runtime.name|truncate(34, True) }}
    + {% if client.name|length < 34 %} + {{ client.name }} + {% else %} + {{ client.name|truncate(34, True) }} + {% endif %} + + +
    Supported + {% for component in components %} + {{ component.abbreviation }} + {% if not loop.last %} +
    + {% endif %} + {% endfor %} +
    Not supported or not applicable
    {{ cat_captions[c] }} Extensions{{ cat_captions[c] }} Extensions
    Runtime FeaturesClient Features
    SupportedNot supported or not applicable
    +
    + + +
    +

    Extensions

    + {% for col in extensions | slice(3) %} +
    + +
    + {% endfor %} +
    + + {% for extension_name in extensions %} + {% set support = extension_support[extension_name] %} + +
    +

    {{ extension_name }} ({{ support.client_count }} client{{ "s" if support.client_count != 1 }})

    +

    + Specification + for {{ extension_name }} +

    + {% if support.client_count > 0 %} + Clients:
    + + {% else %} +

    No clients support this extension.

    + {% endif %} +
    + {% endfor %} +
    +
    @@ -283,128 +246,4 @@

    {{ client.name }}

    {% endfor %}
    - -
    -
    -

    Client support matrix

    -
    - - - - - {% for client in clients | sort %} - {# pragmatic check if the client name fits in the layout or if it needs to be truncated and put the full name in tooltip #} - - {% endfor %} - - - - - {% macro extension_matrix_row(extension_name) %} - - - {% for client in clients | sort %} - {% set components = client.get_component_for_extension(extension_name) %} - {% if components|length > 0 %} - - {% else %} - - {% endif %} - {% endfor %} - - {% endmacro %} - - {# Loop through all categories of extension (KHR, EXT, vendor, KHX, EXTX, Vendor-X) #} - {% for c in cat.all_categories() %} - {# Loop through all extensions in that category #} - {% for extension_name in extensions if categorize_ext(extension_name) == c %} - {% if loop.first %} - {# this header is inside the loop so it is skipped if we have no items in this category #} - {# it is inside this "if" so it only shows up once for each category. #} - - - - {% endif %} - {# Write out a row in the table for this extension #} - {{ extension_matrix_row(extension_name) }} - {% endfor %} - {% endfor %} - - - - - - {% for ff, view_configurations in known_form_factors.items() %} - - - - {% for client in clients | sort %} - - {% endfor %} - - - {% for vc, environment_blend_modes in view_configurations.items() %} - - - - {% for client in clients | sort %} - - {% endfor %} - - {% for ebm in environment_blend_modes %} - - - {% for client in clients | sort %} - {% if ff in form_factor_support[client.name] and vc in form_factor_support[client.name][ff] and ebm in form_factor_support[client.name][ff][vc] %} - - {% else %} - - {% endif %} - {% endfor %} - - {% endfor %} - - - {% endfor %} - - {% endfor %} - - -
    - {% if client.name|length < 34 %} - {{ client.name }} - {% else %} - {{ client.name|truncate(34, True) }} - {% endif %} - - -
    - {{ extension_name }} - - - - - {% for component in components %} - {{ component.abbreviation }} - {% if not loop.last %} -
    - {% endif %} - {% endfor %} -
    Not supported or not applicable
    {{ cat_captions[c] }} Extensions
    Client Features
    - {{ ff }} - - - -
    - → {{ vc }} - - - -
    - → → {{ ebm }} - - - - SupportedNot supported or not applicable
    -
    {% endblock container_contents %} diff --git a/openxr_inventory/templates/extension_support.html b/openxr_inventory/templates/extension_support.html new file mode 100644 index 0000000..faa3f74 --- /dev/null +++ b/openxr_inventory/templates/extension_support.html @@ -0,0 +1,46 @@ + + + + + + + + + OpenXR Extension Support + + + + +
    +
    +

    OpenXR Extension Support

    +

    + These reports show the support coverage for OpenXR extensions across runtimes and clients in the ecosystem.
    + OpenXR Runtimes are implementations of the OpenXR API that run on various platforms and devices. + They provide the core OpenXR functionality that applications depend on.
    + Clients (such as game engines or middleware) use the OpenXR API but do not implement it themselves; + instead, they interface with runtimes to access XR capabilities. +

    +

    Choose which report you'd like to view:

    + +
    +
    +

    + Maintained by the OpenXR community at + github.com/KhronosGroup/OpenXR-Inventory +

    +
    + + + diff --git a/openxr_inventory/templates/runtime_extension_support.jinja2.html b/openxr_inventory/templates/runtime_extension_support.jinja2.html new file mode 100644 index 0000000..9085f77 --- /dev/null +++ b/openxr_inventory/templates/runtime_extension_support.jinja2.html @@ -0,0 +1,236 @@ +{# +Copyright 2022, The Khronos Group Inc. + +SPDX-License-Identifier: CC-BY-4.0 +#} + +{% extends "base.jinja2.html" %} +{% block title -%} + OpenXR Runtime Extension Support Report +{%- endblock title %} + +{% block navbar_brand_text -%} + OpenXR Runtime Extension Support Report +{%- endblock navbar_brand_text %} + +{% block navbar_list_items %} +
  • Runtime Support Matrix
  • +
  • Extensions
  • +
  • Runtimes
  • +{% endblock navbar_list_items %} + +{% block style %} +{{ super() }} + +table.table-sticky-col-headers thead tr { + position: sticky; + background: white; + z-index: 2; + /* from min height of nav bar */ + top: 50px; +} + +th.rotate { + height: 170px; + white-space: nowrap; +} + +th.rotate > div { + transform: rotate(-45deg); + width: 32px; + padding: 5px; +} + +{% endblock style %} + +{% block container_contents %} +
    +
    +

    Runtime support matrix

    +
    + + + + + {% for runtime in runtimes | sort %} + {# pragmatic check if the runtime name fits in the layout or if it needs to be truncated and put the full name in tooltip #} + {% if runtime.name|length < 34 %} + + {% else %} + + {% endif %} + {% endfor %} + + + + + {% macro extension_matrix_row(extension_name) %} + + + {% for runtime in runtimes | sort %} + {% if extension_name in runtime_support[runtime.name] %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endmacro %} + + {# Loop through all categories of extension (KHR, EXT, vendor, KHX, EXTX, Vendor-X) #} + {% for c in cat.all_categories() %} + {# Loop through all extensions in that category #} + {% for extension_name in extensions if categorize_ext(extension_name) == c %} + {% if loop.first %} + {# this header is inside the loop so it is skipped if we have no items in this category #} + {# it is inside this "if" so it only shows up once for each category. #} + + + + {% endif %} + {# Write out a row in the table for this extension #} + {{ extension_matrix_row(extension_name) }} + {% endfor %} + {% endfor %} + + + + + + {% for ff, view_configurations in known_form_factors.items() %} + + + + {% for runtime in runtimes | sort %} + + {% endfor %} + + + {% for vc, environment_blend_modes in view_configurations.items() %} + + + + {% for runtime in runtimes | sort %} + + {% endfor %} + + {% for ebm in environment_blend_modes %} + + + {% for runtime in runtimes | sort %} + {% if ff in form_factor_support[runtime.name] and vc in form_factor_support[runtime.name][ff] and ebm in form_factor_support[runtime.name][ff][vc] %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} + + + {% endfor %} + + {% endfor %} + + +
    {{ runtime.name }}
    {{ runtime.name|truncate(34, True) }}
    + {{ extension_name }} + + + + SupportedNot supported or not applicable
    {{ cat_captions[c] }} Extensions
    Runtime Features
    + {{ ff }} + + + +
    + → {{ vc }} + + + +
    + → → {{ ebm }} + + + + SupportedNot supported or not applicable
    +
    + +
    + + +
    +

    Extensions

    + {% for col in extensions | slice(3) %} +
    + +
    + {% endfor %} +
    + + {% for extension_name in extensions %} + {% set support = extension_support[extension_name] %} + +
    +

    {{ extension_name }} ({{ support.runtime_count }} runtime{{ "s" if support.runtime_count != 1 }})

    +

    + Specification + for {{ extension_name }} +

    + Runtimes:
    + +
    + {% endfor %} +
    + +
    + +
    +

    Runtimes

    + + +
    + + {% for runtime in runtimes %} +
    +

    {{ runtime.name }}

    + +
    + {% endfor %} +
    +{% endblock container_contents %}