Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a2b46e134 |
@@ -1,23 +0,0 @@
|
||||
name: 'Get and cache glTF Assets'
|
||||
description: 'Downloads and caches glTF assets by calling the get-gltf-sample-assets.sh script.'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- uses: ./.github/actions/dep-versions
|
||||
- name: Hash models file
|
||||
id: hash-models
|
||||
shell: bash
|
||||
run: echo "hash=$(cat test/renderdiff/tests/gltf_models.txt | md5sum | sed 's/ -//g')" >> $GITHUB_OUTPUT
|
||||
- name: Cache glTF assets
|
||||
id: cache-gltf
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: gltf
|
||||
key: gltf-assets-${{ env.GITHUB_GLTF_SAMPLE_ASSETS_COMMIT }}-${{ steps.hash-models.outputs.hash }}
|
||||
- name: Download assets via script if cache not found
|
||||
if: steps.cache-gltf.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Cache miss for commit ${{ env.GITHUB_GLTF_SAMPLE_ASSETS_COMMIT }}. Running download script..."
|
||||
xargs bash build/common/get-gltf-sample-assets.sh < test/renderdiff/tests/gltf_models.txt
|
||||
@@ -1,6 +1,5 @@
|
||||
name: 'Get and cache Mesa'
|
||||
description: 'Get and cache Mesa'
|
||||
|
||||
name: 'Get Mesa'
|
||||
description: 'Caches and installs Mesa'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
|
||||
@@ -8,8 +8,8 @@ runs:
|
||||
uses: actions/cache@v3
|
||||
id: cache-vulkan-sdk
|
||||
with:
|
||||
path: ~/VulkanSDK
|
||||
key: vulkansdk-${{ env.GITHUB_VULKANSDK_VERSION }}-2-${{ runner.os }}
|
||||
path: vulkansdk
|
||||
key: vulkansdk-${{ env.GITHUB_VULKANSDK_VERSION }}-${{ runner.os }}
|
||||
- name: Download Vulkan SDK
|
||||
if: steps.cache-vulkan-sdk.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
@@ -21,11 +21,4 @@ runs:
|
||||
run: |
|
||||
source ${{ github.workspace }}/build/common/get-vulkan-sdk.sh
|
||||
unpack_vulkan_installer
|
||||
shell: bash
|
||||
- name: Run Vulkan SDK setup
|
||||
run: |
|
||||
pushd .
|
||||
cd ~/VulkanSDK/${GITHUB_VULKANSDK_VERSION}
|
||||
sudo ./install_vulkan.py
|
||||
popd
|
||||
shell: bash
|
||||
@@ -14,12 +14,10 @@ runs:
|
||||
id: brew-cache
|
||||
uses: actions/cache@v4 # Use a specific version
|
||||
with:
|
||||
path: ~/Library/Caches/Homebrew
|
||||
path: $HOME/Library/Caches/Homebrew
|
||||
key: ${{ runner.os }}-brew-20250424
|
||||
- name: Install Mac Prerequisites
|
||||
shell: bash
|
||||
run: |
|
||||
# Install brew prereqs
|
||||
brew install coreutils
|
||||
# Install ninja
|
||||
source ./build/common/get-ninja.sh
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
name: build-android
|
||||
# We intentially use a larger runner here to enable larger disk space
|
||||
# (standard linux runner will fail on disk space and faster build time).
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
runs-on: 'ubuntu-24.04-32core'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
|
||||
+180
-173
@@ -9,36 +9,6 @@ on:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-desktop-mac:
|
||||
name: build-mac
|
||||
runs-on: macos-14-xlarge
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: ./.github/actions/mac-prereq
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/mac && printf "y" | ./build.sh presubmit
|
||||
- name: Test material parser
|
||||
run: |
|
||||
out/cmake-release/filament/test/test_material_parser
|
||||
|
||||
build-desktop-linux:
|
||||
name: build-linux
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: ./.github/actions/linux-prereq
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/linux && printf "y" | ./build.sh presubmit
|
||||
- name: Test material parser
|
||||
run: |
|
||||
out/cmake-release/filament/test/test_material_parser
|
||||
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-2022-32core
|
||||
@@ -48,157 +18,194 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- name: Run build script
|
||||
run: |
|
||||
build\windows\build-github.bat presubmit
|
||||
build\windows\build-github.bat continuous
|
||||
shell: cmd
|
||||
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: ./.github/actions/linux-prereq
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- name: Run build script
|
||||
# Only build 1 64 bit target during presubmit to cut down build times during presubmit
|
||||
# Continuous builds will build everything
|
||||
run: |
|
||||
cd build/android && printf "y" | ./build.sh presubmit arm64-v8a
|
||||
# build-desktop-mac:
|
||||
# name: build-mac
|
||||
# runs-on: macos-14-xlarge
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4.1.6
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# - uses: ./.github/actions/mac-prereq
|
||||
# - name: Run build script
|
||||
# run: |
|
||||
# cd build/mac && printf "y" | ./build.sh presubmit
|
||||
# - name: Test material parser
|
||||
# run: |
|
||||
# out/cmake-release/filament/test/test_material_parser
|
||||
|
||||
build-ios:
|
||||
name: build-iOS
|
||||
runs-on: macos-14-xlarge
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: ./.github/actions/mac-prereq
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/ios && printf "y" | ./build.sh presubmit
|
||||
- name: Build iOS samples
|
||||
run: |
|
||||
cd build/ios && ./build-samples.sh presubmit
|
||||
# build-desktop-linux:
|
||||
# name: build-linux
|
||||
# runs-on: ubuntu-22.04-16core
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4.1.6
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# - uses: ./.github/actions/linux-prereq
|
||||
# - name: Run build script
|
||||
# run: |
|
||||
# cd build/linux && printf "y" | ./build.sh presubmit
|
||||
# - name: Test material parser
|
||||
# run: |
|
||||
# out/cmake-release/filament/test/test_material_parser
|
||||
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: ./.github/actions/linux-prereq
|
||||
- uses: ./.github/actions/web-prereq
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/web && printf "y" | ./build.sh presubmit
|
||||
# build-windows:
|
||||
# name: build-windows
|
||||
# runs-on: windows-2022-32core
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4.1.6
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# - name: Run build script
|
||||
# run: |
|
||||
# build\windows\build-github.bat presubmit
|
||||
# shell: cmd
|
||||
|
||||
validate-docs:
|
||||
name: validate-docs
|
||||
runs-on: 'ubuntu-24.04-4core'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- id: get_commit_msg
|
||||
uses: ./.github/actions/get-commit-msg
|
||||
- name: Check for manual edits to /docs
|
||||
run: |
|
||||
COMMIT_ID=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | head -n 1 | sed "s/commit //g")
|
||||
bash docs_src/build/presubmit_check.sh ${COMMIT_ID}
|
||||
# build-android:
|
||||
# name: build-android
|
||||
# runs-on: 'ubuntu-24.04-16core'
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4.1.6
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# - uses: ./.github/actions/linux-prereq
|
||||
# - uses: actions/setup-java@v3
|
||||
# with:
|
||||
# distribution: 'temurin'
|
||||
# java-version: '17'
|
||||
# - name: Run build script
|
||||
# # Only build 1 64 bit target during presubmit to cut down build times during presubmit
|
||||
# # Continuous builds will build everything
|
||||
# run: |
|
||||
# cd build/android && printf "y" | ./build.sh presubmit arm64-v8a
|
||||
|
||||
test-renderdiff:
|
||||
name: test-renderdiff
|
||||
runs-on: macos-14-xlarge
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: ./.github/actions/mac-prereq
|
||||
- uses: ./.github/actions/get-gltf-assets
|
||||
- uses: ./.github/actions/get-mesa
|
||||
- uses: ./.github/actions/get-vulkan-sdk
|
||||
- id: get_commit_msg
|
||||
uses: ./.github/actions/get-commit-msg
|
||||
- name: Prerequisites
|
||||
run: |
|
||||
pip install tifffile numpy
|
||||
# Must have at least clang-16 for a webgpu/dawn build.
|
||||
sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
|
||||
shell: bash
|
||||
- name: Render and compare
|
||||
id: render_compare
|
||||
run: |
|
||||
ls ./gltf/Models
|
||||
TEST_DIR=test/renderdiff
|
||||
source ${TEST_DIR}/src/preamble.sh
|
||||
start_
|
||||
GOLDEN_BRANCH=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | python3 ${TEST_DIR}/src/commit_msg.py)
|
||||
bash ${TEST_DIR}/generate.sh && \
|
||||
python3 ${TEST_DIR}/src/golden_manager.py \
|
||||
--branch=${GOLDEN_BRANCH} \
|
||||
--output=${GOLDEN_OUTPUT_DIR}
|
||||
# build-ios:
|
||||
# name: build-iOS
|
||||
# runs-on: macos-14-xlarge
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4.1.6
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# - uses: ./.github/actions/mac-prereq
|
||||
# - name: Run build script
|
||||
# run: |
|
||||
# cd build/ios && printf "y" | ./build.sh presubmit
|
||||
# - name: Build iOS samples
|
||||
# run: |
|
||||
# cd build/ios && ./build-samples.sh presubmit
|
||||
|
||||
# Note that we need to upload the output even if comparison fails, so we undo `set -ex`
|
||||
end_
|
||||
# build-web:
|
||||
# name: build-web
|
||||
# runs-on: 'ubuntu-24.04-16core'
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4.1.6
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# - uses: ./.github/actions/linux-prereq
|
||||
# - uses: ./.github/actions/web-prereq
|
||||
# - name: Run build script
|
||||
# run: |
|
||||
# cd build/web && printf "y" | ./build.sh presubmit
|
||||
|
||||
python3 ${TEST_DIR}/src/compare.py \
|
||||
--src=${GOLDEN_OUTPUT_DIR} \
|
||||
--dest=${RENDER_OUTPUT_DIR} \
|
||||
--out=${DIFF_OUTPUT_DIR} 2>&1 | tee compare_output.txt
|
||||
# validate-docs:
|
||||
# name: validate-docs
|
||||
# runs-on: 'ubuntu-24.04-4core'
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4.1.6
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# - id: get_commit_msg
|
||||
# uses: ./.github/actions/get-commit-msg
|
||||
# - name: Check for manual edits to /docs
|
||||
# run: |
|
||||
# COMMIT_ID=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | head -n 1 | sed "s/commit //g")
|
||||
# bash docs_src/build/presubmit_check.sh ${COMMIT_ID}
|
||||
|
||||
if grep "Failed" compare_output.txt > /dev/null; then
|
||||
DELIMITER="EOF_FILE_CONTENT_$(date +%s)" # Using timestamp to make it more unique
|
||||
echo "err<<$DELIMITER" >> "$GITHUB_OUTPUT"
|
||||
cat compare_output.txt >> "$GITHUB_OUTPUT"
|
||||
echo "$DELIMITER" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: presubmit-renderdiff-result
|
||||
path: ./out/renderdiff
|
||||
- name: Compare result
|
||||
run: |
|
||||
ERROR_STR="${{ steps.render_compare.outputs.err }}"
|
||||
if [ -n "${ERROR_STR}" ]; then
|
||||
echo "${ERROR_STR}"
|
||||
exit 1
|
||||
fi
|
||||
# test-renderdiff:
|
||||
# name: test-renderdiff
|
||||
# runs-on: macos-14-xlarge
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4.1.6
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# - id: get_commit_msg
|
||||
# uses: ./.github/actions/get-commit-msg
|
||||
# - uses: ./.github/actions/mac-prereq
|
||||
# - uses: ./.github/actions/get-mesa
|
||||
# - name: Prerequisites
|
||||
# run: |
|
||||
# pip install tifffile numpy
|
||||
# shell: bash
|
||||
# - name: Render and compare
|
||||
# id: render_compare
|
||||
# run: |
|
||||
# TEST_DIR=test/renderdiff
|
||||
# source ${TEST_DIR}/src/preamble.sh
|
||||
# start_
|
||||
# GOLDEN_BRANCH=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | python3 ${TEST_DIR}/src/commit_msg.py)
|
||||
# bash ${TEST_DIR}/generate.sh && \
|
||||
# python3 ${TEST_DIR}/src/golden_manager.py \
|
||||
# --branch=${GOLDEN_BRANCH} \
|
||||
# --output=${GOLDEN_OUTPUT_DIR}
|
||||
|
||||
validate-wgsl-webgpu:
|
||||
name: validate-wgsl-webgpu
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: ./.github/actions/linux-prereq
|
||||
- name: Run build script
|
||||
run: ./build.sh -W debug test_filamat filament
|
||||
- name: Run test
|
||||
run: ./out/cmake-debug/libs/filamat/test_filamat --gtest_filter=MaterialCompiler.Wgsl*
|
||||
# # Note that we need to upload the output even if comparison fails, so we undo `set -ex`
|
||||
# end_
|
||||
|
||||
test-code-correctness:
|
||||
name: test-code-correctness
|
||||
runs-on: 'macos-14-xlarge'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: ./.github/actions/mac-prereq
|
||||
- name: Install clang-tidy and deps
|
||||
run: |
|
||||
pip install pyyaml
|
||||
brew install llvm@${GITHUB_LLVM_VERSION}
|
||||
sudo ln -s "$(brew --prefix llvm)@${GITHUB_LLVM_VERSION}/bin/clang-tidy" "/usr/local/bin/clang-tidy"
|
||||
- name: Run build script
|
||||
# We need to build before clang-tidy can run analysis
|
||||
run: |
|
||||
# This will build for all three desktop backends on mac
|
||||
./build.sh -p desktop debug gltf_viewer
|
||||
- name: Run test
|
||||
run: bash test/code-correctness/test.sh
|
||||
# python3 ${TEST_DIR}/src/compare.py \
|
||||
# --src=${GOLDEN_OUTPUT_DIR} \
|
||||
# --dest=${RENDER_OUTPUT_DIR} \
|
||||
# --out=${DIFF_OUTPUT_DIR} 2>&1 | tee compare_output.txt
|
||||
|
||||
# if grep "Failed" compare_output.txt > /dev/null; then
|
||||
# DELIMITER="EOF_FILE_CONTENT_$(date +%s)" # Using timestamp to make it more unique
|
||||
# echo "err<<$DELIMITER" >> "$GITHUB_OUTPUT"
|
||||
# cat compare_output.txt >> "$GITHUB_OUTPUT"
|
||||
# echo "$DELIMITER" >> "$GITHUB_OUTPUT"
|
||||
# fi
|
||||
# - uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: presubmit-renderdiff-result
|
||||
# path: ./out/renderdiff
|
||||
# - name: Compare result
|
||||
# run: |
|
||||
# ERROR_STR="${{ steps.render_compare.outputs.err }}"
|
||||
# if [ -n "${ERROR_STR}" ]; then
|
||||
# echo "${ERROR_STR}"
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# validate-wgsl-webgpu:
|
||||
# name: validate-wgsl-webgpu
|
||||
# runs-on: 'ubuntu-24.04-8core'
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4.1.6
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# - uses: ./.github/actions/linux-prereq
|
||||
# - name: Run build script
|
||||
# run: ./build.sh -W debug test_filamat filament
|
||||
# - name: Run test
|
||||
# run: ./out/cmake-debug/libs/filamat/test_filamat --gtest_filter=MaterialCompiler.Wgsl*
|
||||
|
||||
# test-code-correctness:
|
||||
# name: test-code-correctness
|
||||
# runs-on: 'macos-14-xlarge'
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4.1.6
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# - uses: ./.github/actions/mac-prereq
|
||||
# - name: Install clang-tidy and deps
|
||||
# run: |
|
||||
# pip install pyyaml
|
||||
# brew install llvm@${GITHUB_LLVM_VERSION}
|
||||
# sudo ln -s "$(brew --prefix llvm)@${GITHUB_LLVM_VERSION}/bin/clang-tidy" "/usr/local/bin/clang-tidy"
|
||||
# - name: Run build script
|
||||
# # We need to build before clang-tidy can run analysis
|
||||
# run: |
|
||||
# # This will build for all three desktop backends on mac
|
||||
# ./build.sh -p desktop debug gltf_viewer
|
||||
# - name: Run test
|
||||
# run: bash test/code-correctness/test.sh
|
||||
|
||||
@@ -31,7 +31,7 @@ on:
|
||||
jobs:
|
||||
build-linux:
|
||||
name: build-linux
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
runs-on: ubuntu-22.04-32core
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'desktop'
|
||||
|
||||
steps:
|
||||
|
||||
@@ -18,9 +18,3 @@ test*.json
|
||||
results
|
||||
/compile_commands.json
|
||||
/.cache
|
||||
|
||||
# For /test/renderdiff dependencies
|
||||
/mesa
|
||||
/gltf
|
||||
/filament-assets
|
||||
/venv
|
||||
+2
-10
@@ -532,15 +532,6 @@ if (FILAMENT_SUPPORTS_OPENGL)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_OPENGL)
|
||||
endif()
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
|
||||
option(FILAMENT_ENABLE_PERFETTO "Enable perfetto SDK on Android" OFF)
|
||||
else()
|
||||
option(FILAMENT_ENABLE_PERFETTO "Enable perfetto SDK on Android" ON)
|
||||
endif()
|
||||
if (FILAMENT_ENABLE_PERFETTO)
|
||||
add_definitions(-DFILAMENT_ENABLE_PERFETTO)
|
||||
endif()
|
||||
|
||||
# By default, build with Vulkan support on desktop platforms, although clients must request to use
|
||||
# it at run time.
|
||||
if (WIN32 OR WEBGL OR IOS)
|
||||
@@ -553,6 +544,7 @@ if (FILAMENT_SUPPORTS_VULKAN)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_SUPPORTS_WEBGPU)
|
||||
message(AUTHOR_WARNING "WebGPU is in development stage and broken at this stage. Its support is very limited.")
|
||||
add_definitions(-DFILAMENT_SUPPORTS_WEBGPU)
|
||||
endif()
|
||||
|
||||
@@ -642,7 +634,7 @@ endif()
|
||||
# With WebGPU, Tint does not support ClipDistance which is used in Stereo. Mentioned in comment
|
||||
# https://github.com/google/dawn/blob/855d17b08abdf02f9142bf5a8f14d0ea088810a4/src/tint/lang/spirv/reader/ast_parser/function.cc#L4434
|
||||
if (FILAMENT_SUPPORTS_WEBGPU)
|
||||
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a webgpu --variant-filter=stereo)
|
||||
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a webgpu --variant-filter=skinning,stereo)
|
||||
endif()
|
||||
|
||||
# Disable ESSL 1.0 code generation.
|
||||
|
||||
@@ -7,3 +7,6 @@ We are chaning the way Vulkan buffers are handled. We need to switch over to a m
|
||||
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
|
||||
|
||||
## Release notes for next branch cut
|
||||
|
||||
- Update CMake minimum version to 3.22.1
|
||||
- material: Add a material parameter to control shadow far attenuation (b/436680157)
|
||||
|
||||
@@ -18,7 +18,7 @@ Filament release archives contains host-side tools that are required to generate
|
||||
Make sure you always use tools from the same release as the runtime library. This is particularly
|
||||
important for `matc` (material compiler).
|
||||
|
||||
If you'd rather build Filament yourself, please refer to our [build manual](/BUILDING.md).
|
||||
If you'd rather build Filament yourself, please refer to our [build manual](BUILDING.md).
|
||||
|
||||
### Android
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.65.4'
|
||||
implementation 'com.google.android.filament:filament-android:1.63.1'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```shell
|
||||
pod 'Filament', '~> 1.65.4'
|
||||
pod 'Filament', '~> 1.63.1'
|
||||
```
|
||||
|
||||
## Documentation
|
||||
@@ -222,7 +222,7 @@ MaterialInstance* materialInstance = material->createInstance();
|
||||
```
|
||||
|
||||
To learn more about materials and `matc`, please refer to the
|
||||
[materials documentation](https://google.github.io/filament/Materials.html).
|
||||
[materials documentation](./docs/Materials.md.html).
|
||||
|
||||
To render, simply pass the `View` to the `Renderer`:
|
||||
|
||||
@@ -240,7 +240,7 @@ in the `samples/` directory. These samples are all based on `libs/filamentapp/`
|
||||
code that creates a native window with SDL2 and initializes the Filament engine, renderer and views.
|
||||
|
||||
For more information on how to prepare environment maps for image-based lighting please refer to
|
||||
[BUILDING.md](/BUILDING.md#running-the-native-samples).
|
||||
[BUILDING.md](https://github.com/google/filament/blob/main/BUILDING.md#running-the-native-samples).
|
||||
|
||||
### Android
|
||||
|
||||
@@ -272,7 +272,7 @@ To get started you can use the textures and environment maps found respectively
|
||||
refer to their respective `URL.txt` files to know more about the original authors.
|
||||
|
||||
Environments must be pre-processed using
|
||||
[`cmgen`](/BUILDING.md#running-the-native-samples) or
|
||||
[`cmgen`](https://github.com/google/filament/blob/main/BUILDING.md#running-the-native-samples) or
|
||||
using the `libiblprefilter` library.
|
||||
|
||||
## How to make contributions
|
||||
|
||||
@@ -7,32 +7,6 @@ A new header is inserted each time a *tag* is created.
|
||||
Instead, if you are authoring a PR for the main branch, add your release note to
|
||||
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
|
||||
|
||||
## v1.65.4
|
||||
|
||||
|
||||
## v1.65.3
|
||||
|
||||
|
||||
## v1.65.2
|
||||
|
||||
|
||||
## v1.65.1
|
||||
|
||||
- `setFrameScheduledCallback` now works on all backends (frame presentation scheduling is still only
|
||||
available on Metal). Non-Metal backends can use the callback to be notified when Filament has
|
||||
finished processing a frame on the CPU.
|
||||
- materials: added `getEyeFromViewMatrix()` for vertex shader [⚠️ **Recompile Materials**]
|
||||
- matc: make `--workarounds=none` the default [**Recompile Materials to take effect**]
|
||||
|
||||
## v1.65.0
|
||||
|
||||
lighting: the intermediate froxel record buffer is now dynamically sized [⚠️ **New Material Version**]
|
||||
|
||||
## v1.64.1
|
||||
|
||||
- Update CMake minimum version to 3.22.1
|
||||
- material: Add a material parameter to control shadow far attenuation (b/436680157)
|
||||
|
||||
## v1.64.0
|
||||
|
||||
- engine: add a `linearFog` material parameter. [⚠️ **New Material Version**]
|
||||
|
||||
@@ -178,8 +178,6 @@ nexusPublishing {
|
||||
repositories {
|
||||
sonatype {
|
||||
stagingProfileId = '9a75a224a4f17b'
|
||||
nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
|
||||
snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ abstract class MaterialCompiler extends TaskWithBinary {
|
||||
.gradleProperty("com.google.android.filament.include-webgpu")
|
||||
.forUseAtConfigurationTime().present
|
||||
if (include_webgpu) {
|
||||
matcArgs += ['-a', 'webgpu', '--variant-filter=stereo']
|
||||
matcArgs += ['-a', 'webgpu', '--variant-filter=skinning,stereo']
|
||||
}
|
||||
|
||||
def mat_no_opt = providers
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(filamat-android)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
|
||||
|
||||
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
|
||||
|
||||
@@ -7,8 +7,6 @@ option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
|
||||
option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF)
|
||||
option(FILAMENT_SUPPORTS_WEBGPU "Enables WebGPU on Android" OFF)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
|
||||
|
||||
add_library(filament STATIC IMPORTED)
|
||||
@@ -132,14 +130,6 @@ add_library(filament-jni SHARED
|
||||
../common/NioUtils.cpp
|
||||
)
|
||||
|
||||
target_include_directories(filament-jni PRIVATE
|
||||
..
|
||||
${FILAMENT_DIR}/include
|
||||
../../filament/backend/include
|
||||
../../third_party/robin-map
|
||||
../../third_party/perfetto
|
||||
../../libs/utils/include)
|
||||
|
||||
# Ordering is significant in the following list. The PRIVATE qualifier prevents transitive deps.
|
||||
target_link_libraries(filament-jni
|
||||
PRIVATE filament-generatePrefilterMipmap
|
||||
@@ -154,21 +144,29 @@ target_link_libraries(filament-jni
|
||||
PRIVATE android
|
||||
PRIVATE jnigraphics
|
||||
PRIVATE utils
|
||||
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
|
||||
PRIVATE abseil # needed only when FILAMENT_USE_ABSEIL_LOGGING is defined
|
||||
PRIVATE perfetto
|
||||
PRIVATE abseil
|
||||
PRIVATE zstd
|
||||
|
||||
# libgeometry is PUBLIC because gltfio uses it.
|
||||
PUBLIC geometry
|
||||
|
||||
PRIVATE $<$<STREQUAL:${FILAMENT_ENABLE_FGVIEWER},ON>:fgviewer>
|
||||
PRIVATE $<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:matdbg>
|
||||
PRIVATE $<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:filamat>
|
||||
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:bluevk>
|
||||
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:vkshaders>
|
||||
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:smol-v>
|
||||
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_WEBGPU},ON>:webgpu_dawn>
|
||||
$<$<STREQUAL:${FILAMENT_ENABLE_FGVIEWER},ON>:fgviewer>
|
||||
$<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:matdbg>
|
||||
$<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:filamat>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:bluevk>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:vkshaders>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_WEBGPU},ON>:webgpu_dawn>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:smol-v>
|
||||
)
|
||||
|
||||
target_include_directories(filament-jni PRIVATE
|
||||
..
|
||||
${FILAMENT_DIR}/include
|
||||
../../filament/backend/include
|
||||
../../third_party/robin-map
|
||||
../../third_party/perfetto
|
||||
../../libs/utils/include)
|
||||
|
||||
# Force a relink when the version script is changed:
|
||||
set_target_properties(filament-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
|
||||
|
||||
@@ -450,13 +450,6 @@ Java_com_google_android_filament_RenderableManager_nGetPrimitiveCount(JNIEnv*, j
|
||||
return (jint) rm->getPrimitiveCount((RenderableManager::Instance) i);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nGetInstanceCount(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
return (jint) rm->getInstanceCount((RenderableManager::Instance) i);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetMaterialInstanceAt(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jint primitiveIndex, jlong nativeMaterialInstance) {
|
||||
|
||||
@@ -28,8 +28,9 @@ Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* en
|
||||
jlong nativeSwapChain, jobject handler, jobject runnable) {
|
||||
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
|
||||
auto* callback = JniCallback::make(env, handler, runnable);
|
||||
swapChain->setFrameCompletedCallback(callback->getHandler(),
|
||||
[callback](SwapChain* swapChain) { JniCallback::postToJavaAndDestroy(callback); });
|
||||
swapChain->setFrameCompletedCallback(nullptr, [callback](SwapChain* swapChain) {
|
||||
JniCallback::postToJavaAndDestroy(callback);
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
@@ -39,35 +40,9 @@ Java_com_google_android_filament_SwapChain_nIsSRGBSwapChainSupported(
|
||||
return (jboolean)SwapChain::isSRGBSwapChainSupported(*engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_SwapChain_nIsMSAASwapChainSupported(
|
||||
JNIEnv *, jclass, jlong nativeEngine, jint samples) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jboolean)SwapChain::isMSAASwapChainSupported(*engine, samples);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_SwapChain_nIsProtectedContentSupported(
|
||||
JNIEnv *, jclass, jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jboolean)SwapChain::isProtectedContentSupported(*engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SwapChain_nSetFrameScheduledCallback(JNIEnv* env, jclass,
|
||||
jlong nativeSwapChain, jobject handler, jobject runnable) {
|
||||
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
|
||||
auto* callback = JniCallback::make(env, handler, runnable);
|
||||
swapChain->setFrameScheduledCallback(callback->getHandler(),
|
||||
[callback](backend::PresentCallable) {
|
||||
// Ignore PresentCallable, which is only meaningful with the Metal backend.
|
||||
JniCallback::postToJavaAndDestroy(callback);
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_SwapChain_nIsFrameScheduledCallbackSet(
|
||||
JNIEnv *, jclass, jlong nativeSwapChain) {
|
||||
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
|
||||
return (jboolean)swapChain->isFrameScheduledCallbackSet();
|
||||
}
|
||||
|
||||
-9
@@ -851,14 +851,6 @@ public class RenderableManager {
|
||||
return nGetPrimitiveCount(mNativeObject, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the immutable number of instances in the given renderable.
|
||||
*/
|
||||
@IntRange(from = 0)
|
||||
public int getInstanceCount(@EntityInstance int i) {
|
||||
return nGetInstanceCount(mNativeObject, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the material instance binding for the given primitive.
|
||||
*
|
||||
@@ -1026,7 +1018,6 @@ public class RenderableManager {
|
||||
private static native boolean nIsShadowReceiver(long nativeRenderableManager, int i);
|
||||
private static native void nGetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float[] center, float[] halfExtent);
|
||||
private static native int nGetPrimitiveCount(long nativeRenderableManager, int i);
|
||||
private static native int nGetInstanceCount(long nativeRenderableManager, int i);
|
||||
private static native void nSetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex, long nativeMaterialInstance);
|
||||
private static native void nClearMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex);
|
||||
private static native long nGetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex);
|
||||
|
||||
@@ -97,19 +97,6 @@ public class SwapChain {
|
||||
return nIsSRGBSwapChainSupported(engine.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether createSwapChain supports the CONFIG_MSAA_*_SAMPLES flag.
|
||||
* The default implementation returns false.
|
||||
*
|
||||
* @param engine A reference to the filament Engine
|
||||
* @param samples The number of samples
|
||||
* @return true if CONFIG_MSAA_*_SAMPLES is supported, false otherwise.
|
||||
* @see SwapChainFlags#CONFIG_MSAA_*_SAMPLES
|
||||
*/
|
||||
public static boolean isMSAASwapChainSupported(@NonNull Engine engine, int samples) {
|
||||
return nIsMSAASwapChainSupported(engine.getNativeObject(), samples);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the native <code>Object</code> this <code>SwapChain</code> was created from or null
|
||||
* for a headless SwapChain.
|
||||
@@ -139,78 +126,6 @@ public class SwapChain {
|
||||
nSetFrameCompletedCallback(getNativeObject(), handler, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* FrameScheduledCallback is a callback function that notifies an application about the status
|
||||
* of a frame after Filament has finished its processing.
|
||||
*
|
||||
* <p>
|
||||
* The exact timing and semantics of this callback differ depending on the graphics backend in
|
||||
* use.
|
||||
* </p>
|
||||
*
|
||||
* <h3>Metal Backend</h3>
|
||||
* <p>
|
||||
* With the Metal backend, this callback signifies that Filament has completed all CPU-side
|
||||
* processing for a frame and the frame is ready to be scheduled for presentation.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Typically, Filament is responsible for scheduling the frame's presentation to the SwapChain.
|
||||
* If a FrameScheduledCallback is set, however, the application bears the responsibility of
|
||||
* scheduling the frame for presentation by calling the PresentCallable passed to the callback
|
||||
* function. In this mode, Filament will not automatically schedule the frame for presentation.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* When using the Metal backend, if your application delays the call to the PresentCallable
|
||||
* (e.g., by invoking it on a separate thread), you must ensure all PresentCallables have been
|
||||
* called before shutting down the Filament Engine. You can guarantee this by calling
|
||||
* Engine.flushAndWait() before Engine.shutdown(). This is necessary to ensure the Engine has
|
||||
* a chance to clean up all memory related to frame presentation.
|
||||
* </p>
|
||||
*
|
||||
* <h3>Other Backends (OpenGL, Vulkan, WebGPU)</h3>
|
||||
* <p>
|
||||
* On other backends, this callback serves as a notification that Filament has completed all
|
||||
* CPU-side processing for a frame. Filament proceeds with its normal presentation logic
|
||||
* automatically, and the PresentCallable passed to the callback is a no-op that can be safely
|
||||
* ignored.
|
||||
* </p>
|
||||
*
|
||||
* <h3>General Behavior</h3>
|
||||
* <p>
|
||||
* A FrameScheduledCallback can be set on an individual SwapChain through
|
||||
* setFrameScheduledCallback. Each SwapChain can have only one callback set per frame. If
|
||||
* setFrameScheduledCallback is called multiple times on the same SwapChain before
|
||||
* Renderer.endFrame(), the most recent call effectively overwrites any previously set callback.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The callback set by setFrameScheduledCallback is "latched" when Renderer.endFrame() is
|
||||
* executed. At this point, the callback is fixed for the frame that was just encoded.
|
||||
* Subsequent calls to setFrameScheduledCallback after endFrame() will apply to the next frame.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Use setFrameScheduledCallback() (with default arguments) to unset the callback.
|
||||
* </p>
|
||||
*
|
||||
* @param handler A {@link java.util.concurrent.Executor Executor}.
|
||||
* @param callback The Runnable callback to invoke when frame processing is complete.
|
||||
*/
|
||||
public void setFrameScheduledCallback(@NonNull Object handler, @NonNull Runnable callback) {
|
||||
nSetFrameScheduledCallback(getNativeObject(), handler, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this SwapChain currently has a FrameScheduledCallback set.
|
||||
*
|
||||
* @return true, if the last call to setFrameScheduledCallback set a callback
|
||||
*/
|
||||
public boolean isFrameScheduledCallbackSet() {
|
||||
return nIsFrameScheduledCallbackSet(getNativeObject());
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed SwapChain");
|
||||
@@ -223,9 +138,6 @@ public class SwapChain {
|
||||
}
|
||||
|
||||
private static native void nSetFrameCompletedCallback(long nativeSwapChain, Object handler, Runnable callback);
|
||||
private static native void nSetFrameScheduledCallback(long nativeSwapChain, Object handler, Runnable callback);
|
||||
private static native boolean nIsFrameScheduledCallbackSet(long nativeSwapChain);
|
||||
private static native boolean nIsSRGBSwapChainSupported(long nativeEngine);
|
||||
private static native boolean nIsMSAASwapChainSupported(long nativeEngine, int samples);
|
||||
private static native boolean nIsProtectedContentSupported(long nativeEngine);
|
||||
}
|
||||
|
||||
+2
-11
@@ -92,15 +92,6 @@ public final class SwapChainFlags {
|
||||
* The SwapChain contains protected content. Only supported when isProtectedContentSupported()
|
||||
* is true.
|
||||
*/
|
||||
public static final long CONFIG_PROTECTED_CONTENT = 0x40;
|
||||
|
||||
/**
|
||||
* Indicates that the SwapChain is configured to use Multi-Sample Anti-Aliasing (MSAA) with the
|
||||
* given sample points within each pixel. Only supported when isMSAASwapChainSupported(4) is
|
||||
* true.
|
||||
*
|
||||
* This is only supported by EGL(Android). Other GL platforms (GLX, WGL, etc) don't support it
|
||||
* because the swapchain MSAA settings must be configured before window creation.
|
||||
*/
|
||||
public static final long CONFIG_MSAA_4_SAMPLES = 0x80;
|
||||
public static final long CONFIG_PROTECTED_CONTENT = 0x40;
|
||||
}
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ public class View {
|
||||
*
|
||||
* <p>
|
||||
* The View does not take ownership of the Scene pointer. Before destroying a Camera, be sure
|
||||
* to remove it from all associated Views. If the camera isn't set, Renderer::render() will result in a no-op.
|
||||
* to remove it from all assoicated Views.
|
||||
* </p>
|
||||
*
|
||||
* @see #getCamera
|
||||
@@ -1949,18 +1949,6 @@ public class View {
|
||||
* Ground Truth-base Ambient Occlusion (GTAO) options
|
||||
*/
|
||||
public float gtaoThicknessHeuristic = 0.004f;
|
||||
/**
|
||||
* Ground Truth-base Ambient Occlusion (GTAO) options
|
||||
*/
|
||||
public boolean gtaoUseVisibilityBitmasks = false;
|
||||
/**
|
||||
* Ground Truth-base Ambient Occlusion (GTAO) options
|
||||
*/
|
||||
public float gtaoConstThickness = 0.5f;
|
||||
/**
|
||||
* Ground Truth-base Ambient Occlusion (GTAO) options
|
||||
*/
|
||||
public boolean gtaoLinearThickness = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(filament-utils-android)
|
||||
|
||||
option(FILAMENT_SUPPORTS_VULKAN "Enables Vulkan on Android" OFF)
|
||||
option(FILAMENT_ENABLE_FGVIEWER "Enables Frame Graph Viewer" OFF)
|
||||
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
|
||||
option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF)
|
||||
option(FILAMENT_SUPPORTS_WEBGPU "Enables WebGPU on Android" OFF)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
|
||||
set(IMAGEIO_DIR ../../libs/imageio)
|
||||
|
||||
@@ -38,16 +30,7 @@ add_library(iblprefilter STATIC IMPORTED)
|
||||
set_target_properties(iblprefilter PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilament-iblprefilter.a)
|
||||
|
||||
add_library(utils STATIC IMPORTED)
|
||||
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
|
||||
|
||||
add_library(perfetto STATIC IMPORTED)
|
||||
set_target_properties(perfetto PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libperfetto.a)
|
||||
|
||||
set(VERSION_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.map")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${VERSION_SCRIPT}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.map")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
|
||||
|
||||
add_library(filament-utils-jni SHARED
|
||||
@@ -70,25 +53,22 @@ add_library(filament-utils-jni SHARED
|
||||
target_compile_definitions(filament-utils-jni PUBLIC IMAGEIO_LITE=1)
|
||||
|
||||
target_include_directories(filament-utils-jni PRIVATE
|
||||
..
|
||||
${FILAMENT_DIR}/include
|
||||
..
|
||||
../../filament/backend/include
|
||||
${IMAGEIO_DIR}/include
|
||||
../../libs/utils/include)
|
||||
|
||||
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
|
||||
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.symbols)
|
||||
|
||||
# The ordering in the following list is important because CMake does not have dependency information.
|
||||
target_link_libraries(filament-utils-jni
|
||||
PRIVATE gltfio-jni
|
||||
PRIVATE civetweb
|
||||
PRIVATE camutils
|
||||
PRIVATE iblprefilter
|
||||
PRIVATE image
|
||||
PRIVATE filament-jni
|
||||
PRIVATE ktxreader
|
||||
PRIVATE viewer
|
||||
PRIVATE log
|
||||
PRIVATE utils
|
||||
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
|
||||
gltfio-jni
|
||||
civetweb
|
||||
camutils
|
||||
iblprefilter
|
||||
image
|
||||
ktxreader
|
||||
viewer
|
||||
)
|
||||
|
||||
@@ -1,27 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(gltfio-android)
|
||||
|
||||
option(FILAMENT_SUPPORTS_VULKAN "Enables Vulkan on Android" OFF)
|
||||
option(FILAMENT_ENABLE_FGVIEWER "Enables Frame Graph Viewer" OFF)
|
||||
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
|
||||
option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF)
|
||||
option(FILAMENT_SUPPORTS_WEBGPU "Enables WebGPU on Android" OFF)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
|
||||
set(GLTFIO_DIR ../../libs/gltfio)
|
||||
set(DRACO_DIR ../../third_party/draco)
|
||||
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../filament-android ${CMAKE_CURRENT_BINARY_DIR}/filament-android)
|
||||
|
||||
add_library(gltfio_core STATIC IMPORTED)
|
||||
set_target_properties(gltfio_core PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_core.a)
|
||||
|
||||
add_library(dracodec STATIC IMPORTED)
|
||||
set_target_properties(dracodec PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libdracodec.a)
|
||||
|
||||
add_library(meshoptimizer STATIC IMPORTED)
|
||||
set_target_properties(meshoptimizer PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libmeshoptimizer.a)
|
||||
|
||||
add_library(ktxreader STATIC IMPORTED)
|
||||
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
|
||||
@@ -34,6 +27,10 @@ add_library(basis_transcoder STATIC IMPORTED)
|
||||
set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a)
|
||||
|
||||
add_library(zstd STATIC IMPORTED)
|
||||
set_target_properties(zstd PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libzstd.a)
|
||||
|
||||
add_library(utils STATIC IMPORTED)
|
||||
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
|
||||
@@ -50,11 +47,60 @@ add_library(uberarchive STATIC IMPORTED)
|
||||
set_target_properties(uberarchive PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libuberarchive.a)
|
||||
|
||||
set(VERSION_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${VERSION_SCRIPT}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
|
||||
|
||||
set(GLTFIO_SRCS
|
||||
${GLTFIO_DIR}/include/gltfio/Animator.h
|
||||
${GLTFIO_DIR}/include/gltfio/AssetLoader.h
|
||||
${GLTFIO_DIR}/include/gltfio/FilamentAsset.h
|
||||
${GLTFIO_DIR}/include/gltfio/FilamentInstance.h
|
||||
${GLTFIO_DIR}/include/gltfio/MaterialProvider.h
|
||||
${GLTFIO_DIR}/include/gltfio/NodeManager.h
|
||||
${GLTFIO_DIR}/include/gltfio/TrsTransformManager.h
|
||||
${GLTFIO_DIR}/include/gltfio/ResourceLoader.h
|
||||
${GLTFIO_DIR}/include/gltfio/TextureProvider.h
|
||||
${GLTFIO_DIR}/include/gltfio/math.h
|
||||
|
||||
${GLTFIO_DIR}/src/ArchiveCache.cpp
|
||||
${GLTFIO_DIR}/src/ArchiveCache.h
|
||||
${GLTFIO_DIR}/src/Animator.cpp
|
||||
${GLTFIO_DIR}/src/AssetLoader.cpp
|
||||
${GLTFIO_DIR}/src/DependencyGraph.cpp
|
||||
${GLTFIO_DIR}/src/DependencyGraph.h
|
||||
${GLTFIO_DIR}/src/DracoCache.cpp
|
||||
${GLTFIO_DIR}/src/DracoCache.h
|
||||
${GLTFIO_DIR}/src/FFilamentAsset.h
|
||||
${GLTFIO_DIR}/src/FFilamentInstance.h
|
||||
${GLTFIO_DIR}/src/FilamentAsset.cpp
|
||||
${GLTFIO_DIR}/src/FilamentInstance.cpp
|
||||
${GLTFIO_DIR}/src/FNodeManager.h
|
||||
${GLTFIO_DIR}/src/FTrsTransformManager.h
|
||||
${GLTFIO_DIR}/src/GltfEnums.h
|
||||
${GLTFIO_DIR}/src/Ktx2Provider.cpp
|
||||
${GLTFIO_DIR}/src/MaterialProvider.cpp
|
||||
${GLTFIO_DIR}/src/NodeManager.cpp
|
||||
${GLTFIO_DIR}/src/TrsTransformManager.cpp
|
||||
${GLTFIO_DIR}/src/ResourceLoader.cpp
|
||||
${GLTFIO_DIR}/src/StbProvider.cpp
|
||||
${GLTFIO_DIR}/src/TangentsJob.cpp
|
||||
${GLTFIO_DIR}/src/TangentsJob.h
|
||||
${GLTFIO_DIR}/src/UbershaderProvider.cpp
|
||||
${GLTFIO_DIR}/src/Utility.cpp
|
||||
${GLTFIO_DIR}/src/Utility.h
|
||||
${GLTFIO_DIR}/src/Wireframe.cpp
|
||||
${GLTFIO_DIR}/src/Wireframe.h
|
||||
${GLTFIO_DIR}/src/downcast.h
|
||||
${GLTFIO_DIR}/src/extended/AssetLoaderExtended.cpp
|
||||
${GLTFIO_DIR}/src/extended/AssetLoaderExtended.h
|
||||
${GLTFIO_DIR}/src/extended/ResourceLoaderExtended.cpp
|
||||
${GLTFIO_DIR}/src/extended/ResourceLoaderExtended.h
|
||||
${GLTFIO_DIR}/src/extended/TangentsJobExtended.cpp
|
||||
${GLTFIO_DIR}/src/extended/TangentsJobExtended.h
|
||||
${GLTFIO_DIR}/src/extended/TangentSpaceMeshWrapper.cpp
|
||||
${GLTFIO_DIR}/src/extended/TangentSpaceMeshWrapper.h
|
||||
|
||||
|
||||
src/main/cpp/Animator.cpp
|
||||
src/main/cpp/AssetLoader.cpp
|
||||
src/main/cpp/FilamentAsset.cpp
|
||||
@@ -72,38 +118,24 @@ set(GLTFIO_SRCS
|
||||
set(GLTFIO_INCLUDE_DIRS
|
||||
..
|
||||
${FILAMENT_DIR}/include
|
||||
${FILAMENT_DIR}/backend/include
|
||||
../../filament/backend/include
|
||||
../../libs/gltfio/include
|
||||
../../third_party/zstd/lib
|
||||
../../third_party/cgltf
|
||||
../../third_party/meshoptimizer/src
|
||||
../../third_party/robin-map
|
||||
../../third_party/stb
|
||||
../../third_party/perfetto
|
||||
../../libs/utils/include
|
||||
../../libs/ktxreader/include
|
||||
)
|
||||
|
||||
add_library(gltfio-jni SHARED ${GLTFIO_SRCS})
|
||||
|
||||
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1)
|
||||
|
||||
target_include_directories(gltfio-jni PRIVATE ${GLTFIO_INCLUDE_DIRS})
|
||||
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.symbols)
|
||||
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map)
|
||||
target_link_libraries(gltfio-jni filament-jni utils perfetto uberzlib log stb ktxreader basis_transcoder zstd uberarchive)
|
||||
target_link_libraries(gltfio-jni dracodec meshoptimizer)
|
||||
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1)
|
||||
target_include_directories(gltfio-jni PRIVATE ${DRACO_DIR}/src)
|
||||
target_include_directories(gltfio-jni PRIVATE ${DRACO_DIR}/tnt)
|
||||
|
||||
# Force a relink when the version script is changed:
|
||||
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.symbols;${VERSION_SCRIPT}")
|
||||
|
||||
# The ordering in the following list is important because CMake does not have dependency information.
|
||||
target_link_libraries(gltfio-jni
|
||||
PRIVATE gltfio_core
|
||||
PRIVATE ktxreader
|
||||
PUBLIC filament-jni
|
||||
PRIVATE stb
|
||||
PRIVATE basis_transcoder
|
||||
PRIVATE uberarchive
|
||||
PRIVATE dracodec
|
||||
PRIVATE utils
|
||||
PRIVATE uberzlib
|
||||
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
|
||||
PRIVATE log # needed only when perfetto above is used
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.65.4
|
||||
VERSION_NAME=1.63.1
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ android {
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.hellocam"
|
||||
applicationId "com.google.android.filament.hellocamera"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion versions.targetSdk
|
||||
}
|
||||
|
||||
@@ -75,8 +75,6 @@ function print_help {
|
||||
echo " -S type"
|
||||
echo " Enable stereoscopic rendering where type is one of [instanced|multiview]. This is only"
|
||||
echo " meant for building the samples."
|
||||
echo " -P"
|
||||
echo " Enable perfetto traces on Android. Disabled by default on the Release build, enabled otherwise."
|
||||
echo ""
|
||||
echo "Build types:"
|
||||
echo " release"
|
||||
@@ -206,7 +204,6 @@ MATOPT_GRADLE_OPTION=""
|
||||
|
||||
ASAN_UBSAN_OPTION=""
|
||||
COVERAGE_OPTION=""
|
||||
ENABLE_PERFETTO=""
|
||||
|
||||
BACKEND_DEBUG_FLAG_OPTION=""
|
||||
|
||||
@@ -416,7 +413,6 @@ function build_android_target {
|
||||
${WEBGPU_OPTION} \
|
||||
${BACKEND_DEBUG_FLAG_OPTION} \
|
||||
${STEREOSCOPIC_OPTION} \
|
||||
${ENABLE_PERFETTO} \
|
||||
../..
|
||||
ln -sf "out/cmake-android-${lc_target}-${arch}/compile_commands.json" \
|
||||
../../compile_commands.json
|
||||
@@ -810,7 +806,7 @@ function check_debug_release_build {
|
||||
|
||||
pushd "$(dirname "$0")" > /dev/null
|
||||
|
||||
while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:P" opt; do
|
||||
while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:" opt; do
|
||||
case ${opt} in
|
||||
h)
|
||||
print_help
|
||||
@@ -958,9 +954,6 @@ while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:P" opt; do
|
||||
V) COVERAGE_OPTION="-DFILAMENT_ENABLE_COVERAGE=ON"
|
||||
echo "Enabled coverage"
|
||||
;;
|
||||
P) ENABLE_PERFETTO="-DFILAMENT_ENABLE_PERFETTO=ON"
|
||||
echo "Enabled perfetto"
|
||||
;;
|
||||
x) BACKEND_DEBUG_FLAG_OPTION="-DFILAMENT_BACKEND_DEBUG_FLAG=${OPTARG}"
|
||||
;;
|
||||
S) case $(echo "${OPTARG}" | tr '[:upper:]' '[:lower:]') in
|
||||
|
||||
@@ -1,349 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2025 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
This script automates the process of closing a Sonatype OSSRH staging repository.
|
||||
|
||||
To run the script:
|
||||
python3 ./close-sonatype-staging-repository.py
|
||||
|
||||
To run the embedded unit tests:
|
||||
python3 ./close-sonatype-staging-repository.py test
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import base64
|
||||
import json
|
||||
import pathlib
|
||||
import unittest
|
||||
import io
|
||||
from unittest import mock
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
PROPERTIES_PATH = pathlib.Path.home() / ".gradle" / "gradle.properties"
|
||||
API_BASE_URL = "https://ossrh-staging-api.central.sonatype.com/manual"
|
||||
|
||||
def get_gradle_credentials(file_path: pathlib.Path) -> (str, str):
|
||||
"""
|
||||
Reads sonatypeUsername and sonatypePassword from the properties file.
|
||||
"""
|
||||
if not file_path.exists():
|
||||
print(f"Error: Properties file not found at {file_path}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
username = None
|
||||
password = None
|
||||
|
||||
try:
|
||||
with open(file_path, 'r') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
|
||||
# Ignore blank lines and comments
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
|
||||
if line.startswith("sonatypeUsername="):
|
||||
username = line.split("=", 1)[1].strip()
|
||||
elif line.startswith("sonatypePassword="):
|
||||
password = line.split("=", 1)[1].strip()
|
||||
|
||||
if not username or not password:
|
||||
print(f"Error: 'sonatypeUsername' or 'sonatypePassword' not found in {file_path}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
return username, password
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error reading properties file: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def generate_auth_token(username: str, password: str) -> str:
|
||||
"""
|
||||
Generates a Base64 encoded auth token from username and password.
|
||||
"""
|
||||
auth_string = f"{username}:{password}"
|
||||
auth_bytes = auth_string.encode('utf-8')
|
||||
token_bytes = base64.b64encode(auth_bytes)
|
||||
return token_bytes.decode('utf-8')
|
||||
|
||||
|
||||
def find_staging_repository(token: str) -> str:
|
||||
"""
|
||||
Finds the 'open' staging repository key from the Sonatype API.
|
||||
"""
|
||||
print("Searching for staging repository...")
|
||||
|
||||
url = f"{API_BASE_URL}/search/repositories"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Accept": "application/json"
|
||||
}
|
||||
|
||||
req = urllib.request.Request(url, headers=headers, method="GET")
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
response_body = response.read().decode('utf-8')
|
||||
data = json.loads(response_body)
|
||||
|
||||
repositories = data.get("repositories", [])
|
||||
|
||||
open_repositories = list(filter(lambda repo: repo.get("state") == "open", repositories))
|
||||
|
||||
if len(open_repositories) == 0:
|
||||
print("Error: No 'open' staging repositories found.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if len(open_repositories) > 1:
|
||||
print(f"Error: Expected 1 'open' repository, but found {len(repositories)}.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
repo_key = open_repositories[0].get("key")
|
||||
if not repo_key:
|
||||
print("Error: Repository found, but it has no 'key'.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
return repo_key
|
||||
|
||||
except urllib.error.HTTPError as e:
|
||||
# Handle HTTP errors (e.g., 401 Unauthorized, 404 Not Found, 500 Server Error)
|
||||
print(f"Error during repository search: HTTP {e.code} {e.reason}", file=sys.stderr)
|
||||
try:
|
||||
# Try to read the error response body for more context
|
||||
error_body = e.read().decode('utf-8')
|
||||
print(f"Response body: {error_body}", file=sys.stderr)
|
||||
except Exception:
|
||||
pass # Ignore if we can't read the body
|
||||
sys.exit(1)
|
||||
except urllib.error.URLError as e:
|
||||
# Handle network errors (e.g., connection refused)
|
||||
print(f"Error during repository search: {e.reason}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except json.JSONDecodeError:
|
||||
print("Error: Failed to decode JSON response from server.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def close_staging_repository(token: str, repo_key: str):
|
||||
"""
|
||||
Closes (promotes) the staging repository with the given key.
|
||||
"""
|
||||
print(f"Attempting to close staging repository: {repo_key}")
|
||||
|
||||
url = f"{API_BASE_URL}/upload/repository/{repo_key}"
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
|
||||
req = urllib.request.Request(url, headers=headers, method="POST")
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
print(f"Successfully submitted request. Server responded with: {response.status} {response.reason}")
|
||||
print("It may take a few moments to process.")
|
||||
|
||||
except urllib.error.HTTPError as e:
|
||||
print(f"Error closing repository: HTTP {e.code} {e.reason}", file=sys.stderr)
|
||||
try:
|
||||
error_body = e.read().decode('utf-8')
|
||||
print(f"Response body: {error_body}", file=sys.stderr)
|
||||
except Exception:
|
||||
pass
|
||||
sys.exit(1)
|
||||
except urllib.error.URLError as e:
|
||||
print(f"Error closing repository: {e.reason}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
username, password = get_gradle_credentials(PROPERTIES_PATH)
|
||||
token = generate_auth_token(username, password)
|
||||
print("Successfully generated auth token.")
|
||||
|
||||
repo_key = find_staging_repository(token)
|
||||
print(f"Found staging repository: {repo_key}")
|
||||
|
||||
close_staging_repository(token, repo_key)
|
||||
|
||||
print("\nScript completed successfully.")
|
||||
|
||||
|
||||
# --- Unit Tests ---
|
||||
|
||||
class TestSonatypeScript(unittest.TestCase):
|
||||
|
||||
@mock.patch('pathlib.Path.exists', return_value=True)
|
||||
@mock.patch('builtins.open', new_callable=mock.mock_open,
|
||||
read_data="# This is a comment\nsonatypeUsername=testuser\n\nsonatypePassword=testpass\nother=data")
|
||||
def test_get_gradle_credentials_success(self, mock_file, mock_exists):
|
||||
"""Tests successful credential parsing, ignoring comments."""
|
||||
user, pw = get_gradle_credentials(pathlib.Path("/fake/path"))
|
||||
self.assertEqual(user, "testuser")
|
||||
self.assertEqual(pw, "testpass")
|
||||
|
||||
@mock.patch('pathlib.Path.exists', return_value=False)
|
||||
def test_get_gradle_credentials_no_file(self, mock_exists):
|
||||
"""Tests error exit when file is missing."""
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
get_gradle_credentials(pathlib.Path("/fake/path"))
|
||||
|
||||
@mock.patch('pathlib.Path.exists', return_value=True)
|
||||
@mock.patch('builtins.open', new_callable=mock.mock_open, read_data="# Only comments\nsonatypeUsername=testuser")
|
||||
def test_get_gradle_credentials_missing_key(self, mock_file, mock_exists):
|
||||
"""Tests error exit when a key is missing."""
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
get_gradle_credentials(pathlib.Path("/fake/path"))
|
||||
|
||||
def test_generate_auth_token(self):
|
||||
"""Tests the Base64 token encoding."""
|
||||
token = generate_auth_token("foobar", "abc123")
|
||||
# echo -n "foobar:abc123" | base64
|
||||
self.assertEqual(token, "Zm9vYmFyOmFiYzEyMw==")
|
||||
|
||||
@mock.patch('urllib.request.urlopen')
|
||||
def test_find_repository_success(self, mock_urlopen):
|
||||
"""Tests finding exactly one open repository."""
|
||||
mock_response = mock.Mock()
|
||||
mock_response.status = 200
|
||||
mock_response.reason = "OK"
|
||||
mock_response.read.return_value = json.dumps({
|
||||
"repositories": [{"key": "test-repo-key-123", "state": "open"}]
|
||||
}).encode('utf-8')
|
||||
mock_urlopen.return_value.__enter__.return_value = mock_response
|
||||
|
||||
key = find_staging_repository("fake-token")
|
||||
self.assertEqual(key, "test-repo-key-123")
|
||||
|
||||
@mock.patch('urllib.request.urlopen')
|
||||
def test_find_repository_success(self, mock_urlopen):
|
||||
"""Tests finding exactly one open repository."""
|
||||
mock_response = mock.Mock()
|
||||
mock_response.status = 200
|
||||
mock_response.reason = "OK"
|
||||
mock_response.read.return_value = json.dumps({
|
||||
"repositories": [{"key": "test-repo-key-123", "state": "open"}, {"key": "test-repo-key-456", "state": "closed"}]
|
||||
}).encode('utf-8')
|
||||
mock_urlopen.return_value.__enter__.return_value = mock_response
|
||||
|
||||
key = find_staging_repository("fake-token")
|
||||
self.assertEqual(key, "test-repo-key-123")
|
||||
|
||||
@mock.patch('urllib.request.urlopen')
|
||||
def test_find_repository_success(self, mock_urlopen):
|
||||
"""Tests error exit when only a closed repository is found."""
|
||||
mock_response = mock.Mock()
|
||||
mock_response.status = 200
|
||||
mock_response.reason = "OK"
|
||||
mock_response.read.return_value = json.dumps({
|
||||
"repositories": [{"key": "test-repo-key-123", "state": "closed"}]
|
||||
}).encode('utf-8')
|
||||
mock_urlopen.return_value.__enter__.return_value = mock_response
|
||||
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
key = find_staging_repository("fake-token")
|
||||
|
||||
@mock.patch('urllib.request.urlopen')
|
||||
def test_find_repository_not_found(self, mock_urlopen):
|
||||
"""Tests error exit when zero repositories are found."""
|
||||
mock_response = mock.Mock()
|
||||
mock_response.status = 200
|
||||
mock_response.read.return_value = json.dumps({"repositories": []}).encode('utf-8')
|
||||
mock_urlopen.return_value.__enter__.return_value = mock_response
|
||||
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
find_staging_repository("fake-token")
|
||||
|
||||
@mock.patch('urllib.request.urlopen')
|
||||
def test_find_repository_too_many(self, mock_urlopen):
|
||||
"""Tests error exit when multiple open repositories are found."""
|
||||
mock_response = mock.Mock()
|
||||
mock_response.status = 200
|
||||
mock_response.read.return_value = json.dumps({
|
||||
"repositories": [{"key": "key1", "state": "open"}, {"key": "key2", "state": "open"}]
|
||||
}).encode('utf-8')
|
||||
mock_urlopen.return_value.__enter__.return_value = mock_response
|
||||
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
find_staging_repository("fake-token")
|
||||
|
||||
@mock.patch('urllib.request.urlopen')
|
||||
def test_find_repository_http_error(self, mock_urlopen):
|
||||
"""Tests error exit on a network HTTP error."""
|
||||
# Mock an HTTPError
|
||||
mock_urlopen.side_effect = urllib.error.HTTPError(
|
||||
url='http://fake.com',
|
||||
code=401,
|
||||
msg="Unauthorized",
|
||||
hdrs={},
|
||||
fp=io.BytesIO(b'{"error":"bad token"}')
|
||||
)
|
||||
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
find_staging_repository("fake-token")
|
||||
|
||||
@mock.patch('urllib.request.urlopen')
|
||||
def test_close_repository_success(self, mock_urlopen):
|
||||
"""Tests successful repository close."""
|
||||
mock_response = mock.Mock()
|
||||
mock_response.status = 202 # 202 Accepted is a common response for POST
|
||||
mock_response.reason = "Accepted"
|
||||
mock_urlopen.return_value.__enter__.return_value = mock_response
|
||||
|
||||
close_staging_repository("fake-token", "test-repo-key")
|
||||
|
||||
# Check that the request object was created correctly
|
||||
called_request = mock_urlopen.call_args[0][0]
|
||||
self.assertEqual(called_request.full_url, f"{API_BASE_URL}/upload/repository/test-repo-key")
|
||||
self.assertEqual(called_request.method, "POST")
|
||||
self.assertEqual(called_request.headers["Authorization"], "Bearer fake-token")
|
||||
|
||||
@mock.patch('urllib.request.urlopen')
|
||||
def test_close_repository_http_error(self, mock_urlopen):
|
||||
"""Tests error exit on close network failure."""
|
||||
mock_urlopen.side_effect = urllib.error.HTTPError(
|
||||
url='http://fake.com',
|
||||
code=500,
|
||||
msg="Server Error",
|
||||
hdrs={},
|
||||
fp=io.BytesIO(b'{"error":"failed to close"}')
|
||||
)
|
||||
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
close_staging_repository("fake-token", "test-repo-key")
|
||||
|
||||
|
||||
def run_unit_tests():
|
||||
"""
|
||||
Configures and runs the unit tests.
|
||||
"""
|
||||
print("Running unit tests...")
|
||||
# We replace sys.argv to prevent unittest.main from
|
||||
# trying to parse the 'test' argument.
|
||||
original_argv = sys.argv
|
||||
sys.argv = [original_argv[0]] # Keep only the script name
|
||||
unittest.main()
|
||||
sys.argv = original_argv # Restore original args
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Check if the user wants to run tests
|
||||
if len(sys.argv) > 1 and sys.argv[1].lower() == 'test':
|
||||
run_unit_tests()
|
||||
else:
|
||||
# Run the main script logic
|
||||
main()
|
||||
@@ -1,60 +0,0 @@
|
||||
# Copyright (C) 2025 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
#!/usr/bin/bash
|
||||
set -e
|
||||
|
||||
GLTF_SAMPLE_ASSETS_COMMIT=${GITHUB_GLTF_SAMPLE_ASSETS_COMMIT:-d441dfdb87413ff412c620849a649d61789a470f}
|
||||
COMMIT_HASH="${GLTF_SAMPLE_ASSETS_COMMIT}"
|
||||
REPO_URL="https://github.com/KhronosGroup/glTF-Sample-Assets.git"
|
||||
TARGET_DIR="gltf"
|
||||
|
||||
# The default directories to check out if none are specified
|
||||
DEFAULT_SPARSE_PATHS=(
|
||||
"Models/Box/"
|
||||
"Models/Triangle/"
|
||||
"Models/AnimatedCube/"
|
||||
)
|
||||
|
||||
# Check if command-line arguments are provided
|
||||
if [ "$#" -gt 0 ]; then
|
||||
# If arguments are provided, use them as the paths
|
||||
SPARSE_PATHS=()
|
||||
for model_name in "$@"; do
|
||||
SPARSE_PATHS+=("Models/${model_name}/")
|
||||
done
|
||||
echo "Downloading specified models: $@"
|
||||
else
|
||||
# Otherwise, use the default list
|
||||
SPARSE_PATHS=("${DEFAULT_SPARSE_PATHS[@]}")
|
||||
echo "No models specified, downloading default set."
|
||||
fi
|
||||
|
||||
echo "Removing old directory..."
|
||||
rm -rf "${TARGET_DIR}"
|
||||
|
||||
# Clone the repository using a "treeless" clone, which is highly efficient.
|
||||
# --filter=tree:0: Clones only the repository structure without file content (no historical directory listings), making the initial clone very small.
|
||||
# --no-checkout: Prevents automatically checking out the main branch. We will check out a specific commit later.
|
||||
# --sparse: Initializes the repository for sparse checkout, allowing us to fetch only specific directories.
|
||||
git clone --filter=tree:0 --no-checkout --sparse "${REPO_URL}" "${TARGET_DIR}"
|
||||
|
||||
cd "${TARGET_DIR}"
|
||||
|
||||
git sparse-checkout set "${SPARSE_PATHS[@]}"
|
||||
|
||||
echo "Checking out commit ${COMMIT_HASH}..."
|
||||
git checkout "${COMMIT_HASH}"
|
||||
|
||||
echo "Successfully checked out the specified models into the '${TARGET_DIR}' directory."
|
||||
@@ -137,9 +137,6 @@ if [[ "$OS_NAME" == "Darwin" ]]; then
|
||||
|
||||
# This is necessary to be able to build vk (lavapipe) on macOS. Doesn't seem like a real dependency.
|
||||
sed -I '' "s/error('Vulkan drivers require dri3 for X11 support')//g" meson.build
|
||||
# This is to properly link lib-xcb-present on the mac build (though we won't be drawing to any
|
||||
# real hardware surface).
|
||||
sed -I '' "s/dep_xcb_present = null_dep/dep_xcb_present = dependency('xcb-present')/g" meson.build
|
||||
fi
|
||||
|
||||
# -Dosmesa=true => builds OSMesa, which is an offscreen GL context
|
||||
|
||||
@@ -109,8 +109,13 @@ function install_mac() {
|
||||
unzip -t vulkan_sdk.zip
|
||||
fi
|
||||
echo "recognized zip layout 'vulkan_sdk.zip' ${InstallVulkan}.app/Contents" >&2
|
||||
${InstallVulkan}.app/Contents/MacOS/${InstallVulkan} --accept-licenses --default-answer --confirm-command install
|
||||
local sdk_temp=${VULKAN_SDK_DIR}.tmp
|
||||
sudo ${InstallVulkan}.app/Contents/MacOS/${InstallVulkan} --root "$sdk_temp" --accept-licenses --default-answer --confirm-command install
|
||||
du -hs $sdk_temp
|
||||
test -d $sdk_temp/macOS || { echo "unrecognized dmg folder layout: $sdk_temp" ; ls -l $sdk_temp ; }
|
||||
cp -r $sdk_temp/macOS/* $VULKAN_SDK_DIR/
|
||||
if [[ -d ${InstallVulkan}.app/Contents ]] ; then
|
||||
sudo rm -rf "$sdk_temp"
|
||||
rm -rf ${InstallVulkan}.app
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -5,5 +5,4 @@ GITHUB_MESA_VERSION=24.2.1
|
||||
GITHUB_LLVM_VERSION=16
|
||||
GITHUB_NDK_VERSION=27.0.11718014
|
||||
GITHUB_EMSDK_VERSION=3.1.60
|
||||
GITHUB_VULKANSDK_VERSION=1.4.321.0
|
||||
GITHUB_GLTF_SAMPLE_ASSETS_COMMIT=d441dfdb87413ff412c620849a649d61789a470f
|
||||
GITHUB_VULKANSDK_VERSION=1.4.321.0
|
||||
@@ -135,7 +135,9 @@ set build_flags=-j %NUMBER_OF_PROCESSORS%
|
||||
:: cmake --build . --target sample-resources --config %config% %build_flags% || exit /b
|
||||
:: cmake --build . --target suzanne-resources --config %config% %build_flags% || exit /b
|
||||
|
||||
cmake --build . %INSTALL% --config %config% %build_flags% -- /m || exit /b
|
||||
cmake --build . --target sample-resources --config %config% %build_flags% -- /m || exit /b
|
||||
|
||||
:: cmake --build . %INSTALL% --config %config% %build_flags% -- /m || exit /b
|
||||
@echo off
|
||||
|
||||
echo Disk info after building variant: %variant%
|
||||
|
||||
+22
-25
@@ -212,7 +212,7 @@ when using textures.
|
||||
This property can dramatically change the appearance of a surface. Non-metallic surfaces have
|
||||
chromatic diffuse reflection and achromatic specular reflection (reflected light does not change
|
||||
color). Metallic surfaces do not have any diffuse reflection and chromatic specular reflection
|
||||
(reflected light takes on the color of the surfaced as defined by `baseColor`).
|
||||
(reflected light takes on the color of the surfaced as defined by `baseColor`).
|
||||
|
||||
The effect of `metallic` is shown in figure [metallicProperty] (click on the image to see a
|
||||
larger version).
|
||||
@@ -248,7 +248,7 @@ The effect of `roughness` on metallic surfaces is shown in figure [roughnessCond
|
||||
When refraction through an object is enabled (using a `refractonType` of `thin` or `solid`), the
|
||||
`roughness` property will also affect the refractions, as shown in figure
|
||||
[roughnessRefractionProperty] (click on the image to see a larger version).
|
||||
|
||||
|
||||
![Figure [roughnessRefractionProperty]: Refractive sphere with `roughness` varying from 0.0
|
||||
(left) to 1.0 (right)](images/materials/refraction_roughness.png)
|
||||
|
||||
@@ -307,7 +307,7 @@ The sheen color controls the color appearance and strength of an optional sheen
|
||||
base layer described by the properties above. The sheen layer always sits below the clear coat layer
|
||||
if such a layer is present.
|
||||
|
||||
The sheen layer can be used to represent cloth and fabric materials. Please refer to
|
||||
The sheen layer can be used to represent cloth and fabric materials. Please refer to
|
||||
section [Cloth model] for more information about cloth and fabric materials.
|
||||
|
||||
The effect of `sheenColor` is shown in figure [materialSheenColor]
|
||||
@@ -520,14 +520,14 @@ light to bend further away from the initial path.
|
||||
|
||||
Table [commonMatIOR] describes acceptable refractive indices for various types of materials.
|
||||
|
||||
Material | IOR
|
||||
Material | IOR
|
||||
--------------------------:|:-----------------
|
||||
Air | 1.0
|
||||
Water | 1.33
|
||||
Common liquids | 1.33 to 1.5
|
||||
Common gemstones | 1.58 to 2.33
|
||||
Plastics, glass | 1.5 to 1.58
|
||||
Other dielectric materials | 1.33 to 1.58
|
||||
Water | 1.33
|
||||
Common liquids | 1.33 to 1.5
|
||||
Common gemstones | 1.58 to 2.33
|
||||
Plastics, glass | 1.5 to 1.58
|
||||
Other dielectric materials | 1.33 to 1.58
|
||||
[Table [commonMatIOR]: Index of refraction of common materials]
|
||||
|
||||
The appearance of a refractive material will greatly depend on the `refractionType` and
|
||||
@@ -995,10 +995,10 @@ Value
|
||||
name must be a valid GLSL identifier. Entries have an optional `precision`, which can be
|
||||
one of `default` (best precision for the platform, typically `high` on desktop, `medium` on
|
||||
mobile), `low`, `medium`, `high`. The type must be one of the types described in
|
||||
table [materialParamsTypes]. For Android external textures, entries also have an optional
|
||||
transformName parameter to specify the name of the material parameter that will be
|
||||
table [materialParamsTypes]. For Android external textures, entries also have an optional
|
||||
transformName parameter to specify the name of the material parameter that will be
|
||||
used to expose the transform matrix associated with the external sampler. In iOS and Vulkan,
|
||||
this will always be identity.
|
||||
this will always be identity.
|
||||
|
||||
Type | Description
|
||||
:----------------------|:---------------------------------
|
||||
@@ -2476,17 +2476,14 @@ type aliases:
|
||||
|
||||
### Matrices
|
||||
|
||||
Name | Type | Description
|
||||
:-----------------------------------------|:--------:|:------------------------------------
|
||||
**getViewFromWorldMatrix()** | float4x4 | Matrix that converts from world space to view/eye space
|
||||
**getWorldFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to world space
|
||||
**getClipFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to clip (NDC) space
|
||||
**getViewFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to view/eye space
|
||||
**getEyeFromViewMatrix()** | float4x4 | Matrix that converts from view space to eye space
|
||||
**getEyeFromViewMatrix(int eyeIndex)** | float4x4 | Matrix that converts from view space to eye space for the eye referred to by eyeIndex
|
||||
**getClipFromWorldMatrix()** | float4x4 | Matrix that converts from world to clip (NDC) space
|
||||
**getClipFromWorldMatrix(int eyeIndex)** | float4x4 | Matrix that converts from world to clip (NDC) space for the eye referred to by eyeIndex
|
||||
**getWorldFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to world space
|
||||
Name | Type | Description
|
||||
:-----------------------------------|:--------:|:------------------------------------
|
||||
**getViewFromWorldMatrix()** | float4x4 | Matrix that converts from world space to view/eye space
|
||||
**getWorldFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to world space
|
||||
**getClipFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to clip (NDC) space
|
||||
**getViewFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to view/eye space
|
||||
**getClipFromWorldMatrix()** | float4x4 | Matrix that converts from world to clip (NDC) space
|
||||
**getWorldFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to world space
|
||||
|
||||
### Frame constants
|
||||
|
||||
@@ -2642,7 +2639,7 @@ standard skybox material. It produces a list of 2 parameters, named `showSun` an
|
||||
respectively a boolean and a cubemap texture.
|
||||
|
||||
```text
|
||||
$ matc --reflect parameters filament/src/materials/skybox.mat
|
||||
$ matc --reflect parameters filament/src/materials/skybox.mat
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
@@ -2658,7 +2655,7 @@ $ matc --reflect parameters filament/src/materials/skybox.mat
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
### --variant-filter
|
||||
|
||||
|
||||
Vendored
-267
@@ -1,267 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Maven Release - Filament</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
<!-- MathJax -->
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
|
||||
</script>
|
||||
<!-- Start loading toc.js asap -->
|
||||
<script src="../toc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="body-container">
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
const html = document.documentElement;
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add("js");
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div style="display:flex;align-items:center;justify-content:center">
|
||||
<img class="flogo" src="../images/filament_logo_small.png"></img>
|
||||
</div>
|
||||
<!-- populated by js -->
|
||||
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
|
||||
<noscript>
|
||||
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
|
||||
</noscript>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
|
||||
<!--
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
-->
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Filament</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="maven-release"><a class="header" href="#maven-release">Maven Release</a></h1>
|
||||
<h2 id="register-for-a-sonatype-account"><a class="header" href="#register-for-a-sonatype-account">Register for a Sonatype Account</a></h2>
|
||||
<p>First, you'll need to register for a Sonatype account at the <a href="https://central.sonatype.org/register/central-portal/">Central
|
||||
Portal</a>.</p>
|
||||
<p>To publish under the <code>com.google.android</code> namespace, you'll also need to email
|
||||
<code>central-support@sonatype.com</code> with your account information to request access.</p>
|
||||
<p>Then, generate a user token through the Sonatype website. Navigate to
|
||||
<a href="https://central.sonatype.com/account">https://central.sonatype.com/account</a> and select <strong>Generate
|
||||
User Token</strong>.</p>
|
||||
<p>Finally, add the generated token credentials to <code>~/.gradle/gradle.properties</code>. (Note: these are
|
||||
different from the credentials used to log into your Sonatype account):</p>
|
||||
<pre><code class="language-gradle"># Generated Sonatype token
|
||||
sonatypeUsername=<username>
|
||||
sonatypePassword=<password>
|
||||
</code></pre>
|
||||
<hr />
|
||||
<h2 id="signing-key"><a class="header" href="#signing-key">Signing Key</a></h2>
|
||||
<p>All release artifacts must be signed. You'll need to create an OpenPGP key pair. See Gradle's
|
||||
documentation on <a href="https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials">Signatory
|
||||
credentials</a>
|
||||
for instructions.</p>
|
||||
<p>Update <code>~/.gradle/gradle.properties</code> with your new key's credentials:</p>
|
||||
<pre><code class="language-gradle">signing.keyId=<key id>
|
||||
signing.password=<key password>
|
||||
signing.secretKeyRingFile=<secret key ring file>
|
||||
</code></pre>
|
||||
<hr />
|
||||
<h2 id="build-the-android-release"><a class="header" href="#build-the-android-release">Build the Android Release</a></h2>
|
||||
<p>Make sure <code>JAVA_HOME</code> is set correctly. For example:</p>
|
||||
<pre><code class="language-bash">export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home
|
||||
./build.sh -C -i -p android release
|
||||
</code></pre>
|
||||
<hr />
|
||||
<h2 id="publish-to-sonatype"><a class="header" href="#publish-to-sonatype">Publish to Sonatype</a></h2>
|
||||
<h3 id="a-note-on-the-legacy-staging-service"><a class="header" href="#a-note-on-the-legacy-staging-service">A Note on the Legacy Staging Service</a></h3>
|
||||
<p>Previously, Filament was published to Maven via OSSRH (Open Source Software Repository Hosting). In
|
||||
2025, this service was <a href="https://central.sonatype.org/pages/ossrh-eol/">sunsetted</a>. Now, we use
|
||||
Sonatype's <a href="https://central.sonatype.org/">Central Publisher Portal</a>.</p>
|
||||
<p>The new Central Publisher Portal does not officially support Gradle. However, Sonatype provides a
|
||||
staging API compatibility service, which works with Filament's Gradle setup.</p>
|
||||
<hr />
|
||||
<h3 id="1-upload-to-the-staging-api-compatibility-service"><a class="header" href="#1-upload-to-the-staging-api-compatibility-service">1. Upload to the Staging API Compatibility Service</a></h3>
|
||||
<pre><code class="language-bash">cd android
|
||||
./gradlew publishToSonatype
|
||||
</code></pre>
|
||||
<h3 id="2-move-the-repository-to-the-central-publisher-portal"><a class="header" href="#2-move-the-repository-to-the-central-publisher-portal">2. Move the Repository to the Central Publisher Portal</a></h3>
|
||||
<p>We have a script to automate this. It reads the <code>sonatypeUsername</code> and <code>sonatypePassword</code> from your
|
||||
<code>~/.gradle/gradle.properties</code> file.</p>
|
||||
<pre><code class="language-bash">python3 build/common/close-sonatype-staging-repository.py
|
||||
</code></pre>
|
||||
<h3 id="3-publish-the-release-on-sonatype"><a class="header" href="#3-publish-the-release-on-sonatype">3. Publish the Release on Sonatype</a></h3>
|
||||
<p>Navigate to <a href="https://central.sonatype.com/publishing/deployments">Maven Central Repository Deployments</a>.</p>
|
||||
<p>Here, you should see a new deployment with a <strong>Validated</strong> status and all your artifacts listed. Click
|
||||
the <strong>Publish</strong> button to publish the artifacts. It typically takes around 5 minutes after clicking
|
||||
<strong>Publish</strong> for the artifacts to go live.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../build/windows_android.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../dup/contributing.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../build/windows_android.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../dup/contributing.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js"></script>
|
||||
<script src="../mark.min.js"></script>
|
||||
<script src="../searcher.js"></script>
|
||||
|
||||
<script src="../clipboard.min.js"></script>
|
||||
<script src="../highlight.js"></script>
|
||||
<script src="../book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Vendored
+2
-2
@@ -273,7 +273,7 @@ copy filament-android\build\outputs\aar\filament-android-release.aar ..\..\out\
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../build/maven_release.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<a rel="next prefetch" href="../dup/contributing.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
@@ -287,7 +287,7 @@ copy filament-android\build\outputs\aar\filament-android-release.aar ..\..\out\
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../build/maven_release.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<a rel="next prefetch" href="../dup/contributing.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
@@ -209,7 +209,7 @@ as possible. The current external dependencies of the runtime library include:</
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../build/maven_release.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<a rel="prev" href="../build/windows_android.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
@@ -223,7 +223,7 @@ as possible. The current external dependencies of the runtime library include:</
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../build/maven_release.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<a rel="prev" href="../build/windows_android.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
|
||||
+2
-4
@@ -221,8 +221,6 @@ export is an html with the output captured in a <code><pre></code> tag).</
|
||||
<li>Replace css styling in the exported output as needed (so they don't interfere with the book's css.</li>
|
||||
<li>Replace resource urls to refer to locations relative to the mdbook structure.</li>
|
||||
</ul>
|
||||
<p>Any <code>markdeep</code> doc can be placed in <code>docs_src/src_markdeep/</code> and they will be parsed to html and included
|
||||
in the book as above.</p>
|
||||
<h3 id="readmes"><a class="header" href="#readmes">READMEs</a></h3>
|
||||
<p>Filament depends on a number of libraries, which reside in the directory <code>libs</code>. These individual
|
||||
libaries often have README.md in their root to describe itself. We collect these descriptions into our
|
||||
@@ -231,7 +229,7 @@ located in <code>tools</code>. Some of tools also have README.md as description.
|
||||
<p>The process for copying and processing these READMEs is outlined in <a href="#introductory-doc">Introductory docs</a>.</p>
|
||||
<h3 id="other-technical-notes"><a class="header" href="#other-technical-notes">Other technical notes</a></h3>
|
||||
<p>These are technical documents that do not fit into a library, tool, or directory of the
|
||||
Filament source tree. We collect them into the <code>docs_src/src_mdbook/src/notes</code> directory. No additional
|
||||
Filament source tree. We collect them into the <code>docs_src/src/notes</code> directory. No additional
|
||||
processing is needed for these documents.</p>
|
||||
<h3 id="raw-source-files"><a class="header" href="#raw-source-files">Raw source files</a></h3>
|
||||
<p>These are files that are not part of the <code>mdbook</code> generation, but should be included output in <code>/docs</code>
|
||||
@@ -244,7 +242,7 @@ add a link in <code>SUMMARY.md</code>, and perform the steps outlined in
|
||||
<a href="#how-to-create">how-to create section</a>.</p>
|
||||
<p>For example, if you are adding a general technical note, then you would</p>
|
||||
<ul>
|
||||
<li>Place the document (file with extension <code>.md</code>) in <code>docs_src/src_mdbook/src/notes</code></li>
|
||||
<li>Place the document (file with extension <code>.md</code>) in <code>docs_src/src/notes</code></li>
|
||||
<li>Add a link in <a href="https://github.com/google/filament/blob/main/docs_src/src_mdbook/src/SUMMARY.md"><code>docs_src/src_mdbook/src/SUMMARY.md</code></a></li>
|
||||
<li>Run the commands in the <a href="#how-to-generate">Generate</a> section</li>
|
||||
</ul>
|
||||
|
||||
+9
-9
@@ -181,7 +181,7 @@ important for <code>matc</code> (material compiler).</p>
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.65.2'
|
||||
implementation 'com.google.android.filament:filament-android:1.63.1'
|
||||
}
|
||||
</code></pre>
|
||||
<p>Here are all the libraries available in the group <code>com.google.android.filament</code>:</p>
|
||||
@@ -196,18 +196,18 @@ dependencies {
|
||||
</div>
|
||||
<h3 id="ios"><a class="header" href="#ios">iOS</a></h3>
|
||||
<p>iOS projects can use CocoaPods to install the latest release:</p>
|
||||
<pre><code class="language-shell">pod 'Filament', '~> 1.65.2'
|
||||
<pre><code class="language-shell">pod 'Filament', '~> 1.63.1'
|
||||
</code></pre>
|
||||
<h2 id="documentation"><a class="header" href="#documentation">Documentation</a></h2>
|
||||
<ul>
|
||||
<li><a href="../main/filament.html">Filament</a>, an in-depth explanation of
|
||||
<li><a href="https://google.github.io/filament/Filament.html">Filament</a>, an in-depth explanation of
|
||||
real-time physically based rendering, the graphics capabilities and implementation of Filament.
|
||||
This document explains the math and reasoning behind most of our decisions. This document is a
|
||||
good introduction to PBR for graphics programmers.</li>
|
||||
<li><a href="../main/materials.html">Materials</a>, the full reference
|
||||
<li><a href="https://google.github.io/filament/Materials.html">Materials</a>, the full reference
|
||||
documentation for our material system. This document explains our different material models, how
|
||||
to use the material compiler <code>matc</code> and how to write custom materials.</li>
|
||||
<li><a href="../notes/material_properties.html">Material Properties</a>, a reference
|
||||
<li><a href="https://google.github.io/filament/notes/material_properties.html">Material Properties</a>, a reference
|
||||
sheet for the standard material model.</li>
|
||||
</ul>
|
||||
<h2 id="examples"><a class="header" href="#examples">Examples</a></h2>
|
||||
@@ -395,7 +395,7 @@ by <code>matc</code>:</p>
|
||||
MaterialInstance* materialInstance = material->createInstance();
|
||||
</code></pre>
|
||||
<p>To learn more about materials and <code>matc</code>, please refer to the
|
||||
<a href="../main/materials.html">materials documentation</a>.</p>
|
||||
<a href="./docs/Materials.html">materials documentation</a>.</p>
|
||||
<p>To render, simply pass the <code>View</code> to the <code>Renderer</code>:</p>
|
||||
<pre><code class="language-c++">// beginFrame() returns false if we need to skip a frame
|
||||
if (renderer->beginFrame(swapChain)) {
|
||||
@@ -408,7 +408,7 @@ if (renderer->beginFrame(swapChain)) {
|
||||
in the <code>samples/</code> directory. These samples are all based on <code>libs/filamentapp/</code> which contains the
|
||||
code that creates a native window with SDL2 and initializes the Filament engine, renderer and views.</p>
|
||||
<p>For more information on how to prepare environment maps for image-based lighting please refer to
|
||||
<a href="building.html#running-the-native-samples">BUILDING.md</a>.</p>
|
||||
<a href="https://github.com/google/filament/blob/main/BUILDING.md#running-the-native-samples">BUILDING.md</a>.</p>
|
||||
<h3 id="android-1"><a class="header" href="#android-1">Android</a></h3>
|
||||
<p>See <code>android/samples</code> for examples of how to use Filament on Android.</p>
|
||||
<p>You must always first initialize Filament by calling <code>Filament.init()</code>.</p>
|
||||
@@ -430,7 +430,7 @@ OpenGL ES.</p>
|
||||
<code>third_party/textures</code> and <code>third_party/environments</code>. These assets are under CC0 license. Please
|
||||
refer to their respective <code>URL.txt</code> files to know more about the original authors.</p>
|
||||
<p>Environments must be pre-processed using
|
||||
<a href="building.html#running-the-native-samples"><code>cmgen</code></a> or
|
||||
<a href="https://github.com/google/filament/blob/main/BUILDING.md#running-the-native-samples"><code>cmgen</code></a> or
|
||||
using the <code>libiblprefilter</code> library.</p>
|
||||
<h2 id="how-to-make-contributions"><a class="header" href="#how-to-make-contributions">How to make contributions</a></h2>
|
||||
<p>Please read and follow the steps in <a href="contributing.html">CONTRIBUTING.md</a>. Make sure you are
|
||||
@@ -513,7 +513,7 @@ and tools.</p>
|
||||
<li><code>web</code>: JavaScript bindings, documentation, and samples</li>
|
||||
</ul>
|
||||
<h2 id="license"><a class="header" href="#license">License</a></h2>
|
||||
<p>Please see <a href="https://github.com/google/filament/blob/main/LICENSE">LICENSE</a>.</p>
|
||||
<p>Please see <a href="/LICENSE">LICENSE</a>.</p>
|
||||
<h2 id="disclaimer"><a class="header" href="#disclaimer">Disclaimer</a></h2>
|
||||
<p>This is not an officially supported Google product.</p>
|
||||
|
||||
|
||||
@@ -1,330 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>renderdiff - Filament</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
<!-- MathJax -->
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
|
||||
</script>
|
||||
<!-- Start loading toc.js asap -->
|
||||
<script src="../toc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="body-container">
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
const html = document.documentElement;
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add("js");
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div style="display:flex;align-items:center;justify-content:center">
|
||||
<img class="flogo" src="../images/filament_logo_small.png"></img>
|
||||
</div>
|
||||
<!-- populated by js -->
|
||||
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
|
||||
<noscript>
|
||||
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
|
||||
</noscript>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
|
||||
<!--
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
-->
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Filament</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="rendering-difference-test"><a class="header" href="#rendering-difference-test">Rendering Difference Test</a></h1>
|
||||
<p>We created a few scripts to run <code>gltf_viewer</code> and produce headless renderings.</p>
|
||||
<p>This is mainly useful for continuous integration where GPUs are generally not available on cloud
|
||||
machines. To perform software rasterization, these scripts are centered around <a href="https://docs.mesa3d.org">Mesa</a>'s
|
||||
software rasterizers, but nothing bars us from using another rasterizer like <a href="https://github.com/google/swiftshader">SwiftShader</a>.
|
||||
Additionally, we should be able to use GPUs where available (though this is more of a future
|
||||
work).</p>
|
||||
<p>The script <code>render.py</code> contains the core logic for taking input parameters (such as the test
|
||||
description file) and then running gltf_viewer to produce the renderings.</p>
|
||||
<p>In the <code>test</code> directory is a list of test descriptions that are specified in json. Please see
|
||||
<code>sample.json</code> to parse the structure.</p>
|
||||
<h2 id="setting-up-python"><a class="header" href="#setting-up-python">Setting up python</a></h2>
|
||||
<p>The <code>renderdiff</code> project uses <code>python</code> extensively. To install the dependencies for producing
|
||||
renderings, do the following step</p>
|
||||
<ul>
|
||||
<li>Set up a virtual environment (from the root directory)
|
||||
<pre><code>python3 -m venv venv
|
||||
. ./venv/bin/activate
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>Install the rendering dependencies
|
||||
<pre><code>pip install -r test/renderdiff/src/rendering_requirements.txt
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>Install the viewer depdencies
|
||||
<pre><code>pip install -r test/renderdiff/src/viewer_requirements.txt
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>For the commands in the following section, do not exit the virtual environment. Once you've
|
||||
completed all your work, you can exit with
|
||||
<pre><code>deactivate
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="running-the-test-locally"><a class="header" href="#running-the-test-locally">Running the test locally</a></h2>
|
||||
<ul>
|
||||
<li>To run the same presbumit as <a href="presubmit-renderdiff"><code>test-renderdiff</code></a>, you can do
|
||||
<pre><code>bash test/renderdiff/local_test.sh
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>This script will generate the renderings based on the current state of your repo.
|
||||
Additionally, it will also compare the generated images with corresponding images in the
|
||||
golden repo.</li>
|
||||
<li>To just render without running the test, you could use the following script
|
||||
<pre><code>bash test/renderdiff/generate.sh
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="filtering-tests"><a class="header" href="#filtering-tests">Filtering Tests</a></h2>
|
||||
<p>You can run a subset of the tests by passing the <code>--test_filter</code> flag to <code>local_test.sh</code>. The
|
||||
filter supports wildcards (<code>*</code>) to match test names. For example, to run all tests in the
|
||||
<code>ClearCoat</code> suite, you can use the following command:</p>
|
||||
<pre><code>bash test/renderdiff/local_test.sh --test_filter='ClearCoat.*.*'
|
||||
</code></pre>
|
||||
<h2 id="update-the-golden-images"><a class="header" href="#update-the-golden-images">Update the golden images</a></h2>
|
||||
<p>The golden images are stored in a github repository:
|
||||
https://github.com/google/filament-assets. Filament team members should have access to write
|
||||
to the repository. A typical flow for updating the goldens is to upload your changed images
|
||||
into <strong>branch</strong> of <code>filament-assets</code>. This branch is paired with a PR or commit on the
|
||||
<code>filament</code> repo.</p>
|
||||
<p>As an example, imagine I am working on a PR, and I've uploaded my change, which is in a
|
||||
branch called <code>my-pr-branch</code>, to <code>filament</code>. This PR requires updating the golden. We would do
|
||||
it in the following fashion</p>
|
||||
<h3 id="using-a-script-to-update-the-golden-repo"><a class="header" href="#using-a-script-to-update-the-golden-repo">Using a script to update the golden repo</a></h3>
|
||||
<ul>
|
||||
<li>Run interactive mode in the <code>update_golden.py</code> script.
|
||||
<pre><code>python3 test/renderdiff/src/update_golden.py
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>This will guide you through a series of steps to push the changes to a remote branch on
|
||||
<code>filament-assets</code>.</li>
|
||||
</ul>
|
||||
<h3 id="manually-updating-the-golden-repo"><a class="header" href="#manually-updating-the-golden-repo">Manually updating the golden repo</a></h3>
|
||||
<ul>
|
||||
<li>Check out the golden repo
|
||||
<pre><code>git clone git@github.com:google/filament-assets.git
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>Create a branch on the golden repo
|
||||
<pre><code>cd filament-assets
|
||||
git switch -c my-pr-branch-golden
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>Copy the new images to their appropriate place in <code>filament-assets</code></li>
|
||||
<li>Push the <code>filament-assets</code> working branch to remote
|
||||
<pre><code>git push origin my-pr-branch-golden
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>In the commit message of your working branch on <code>filament</code>, add the following line
|
||||
<pre><code>RDIFF_BBRANCH=my-pr-branch-golden
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Doing the above has multiple effects:</p>
|
||||
<ul>
|
||||
<li>The presubmit test <a href="https://github.com/google/filament/blob/e85dfe75c86106a05019e13ccdbef67e030af675/.github/workflows/presubmit.yml#L118"><code>test-renderdiff</code></a> will test against the provided
|
||||
branch of the golden repo (i.e. <code>my-pr-branch-golden</code>).</li>
|
||||
<li>If the PR is merged, then there is another workflow that will merge <code>my-pr-branch-golden</code>
|
||||
to the <code>main</code> branch of the golden repo.</li>
|
||||
</ul>
|
||||
<h2 id="viewing-test-results"><a class="header" href="#viewing-test-results">Viewing test results</a></h2>
|
||||
<p>We provide a viewer for looking at the result of a test run. The viewer is a webapp that can
|
||||
be used by pointing your browser to a localhost port. If you input the viewer with a PR or a
|
||||
directory, it will parse the test result and show the results and the rendered and/or golden
|
||||
images.</p>
|
||||
<p><img src="../images/renderdiff_example.png" alt="Viewer" /></p>
|
||||
<p>To run the viewer of a test output directory that has been generated locally, you would run
|
||||
the following</p>
|
||||
<pre><code>python3 test/renderdiff/src/viewer.py --diff=[test output]
|
||||
</code></pre>
|
||||
<p>where <code>[test output]</code> is a directory containing the <code>compare_results.json</code> of the test run.
|
||||
For example, it could be <code>out/renderdiff/diffs/presubmit</code> for the standard path to the
|
||||
<code>presubmit</code> test output.</p>
|
||||
<p>To see the results of a Pull Request initiated test run, you would do the following</p>
|
||||
<pre><code>python3 test/renderdiff/src/viewer.py --pr_number=[PR #] --github_token=[github token]
|
||||
</code></pre>
|
||||
<p>where <code>[PR #]</code> is the numeric ID of your pull request, and the <code>[github token]</code> is an acess
|
||||
token that you (as a github user) needs to generate (<a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens">reference</a>).</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../notes/tests.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../notes/libs.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../notes/tests.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../notes/libs.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js"></script>
|
||||
<script src="../mark.min.js"></script>
|
||||
<script src="../searcher.js"></script>
|
||||
|
||||
<script src="../clipboard.min.js"></script>
|
||||
<script src="../highlight.js"></script>
|
||||
<script src="../book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -162,7 +162,7 @@
|
||||
<p>This tool makes it easy to analyze the composition of Android applications that use Filament.</p>
|
||||
<ul>
|
||||
<li>Filament materials are shown in the treemap if <code>resgen --json</code> was used in the build.</li>
|
||||
<li>The input path can be a <code>.so</code> or <code>.a</code> file, a folder, or a zip archive (apk or aar).</li>
|
||||
<li>The input path can be a so file, folder, or zip archive (apk or aar).</li>
|
||||
<li>If the path is a zip or folder, interactively finds the file to analyze.</li>
|
||||
<li>The generated web report is a self-contained HTML file.</li>
|
||||
<li>Reports the gzipped size of all Filament materials.</li>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 361 KiB |
+563
-10
@@ -1,11 +1,564 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Redirecting...</title>
|
||||
<meta http-equiv="refresh" content="0; url=./dup/intro.html">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Introduction - Filament</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="shortcut icon" href="favicon.png">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
<!-- MathJax -->
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
|
||||
</script>
|
||||
<!-- Start loading toc.js asap -->
|
||||
<script src="toc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="body-container">
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
const html = document.documentElement;
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add("js");
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div style="display:flex;align-items:center;justify-content:center">
|
||||
<img class="flogo" src="images/filament_logo_small.png"></img>
|
||||
</div>
|
||||
<!-- populated by js -->
|
||||
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
|
||||
<noscript>
|
||||
<iframe class="sidebar-iframe-outer" src="toc.html"></iframe>
|
||||
</noscript>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
|
||||
<!--
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
-->
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Filament</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="filament"><a class="header" href="#filament">Filament</a></h1>
|
||||
<p><a href="https://github.com/google/filament/actions?query=workflow%3AAndroid"><img src="https://github.com/google/filament/workflows/Android/badge.svg" alt="Android Build Status" /></a>
|
||||
<a href="https://github.com/google/filament/actions?query=workflow%3AiOS"><img src="https://github.com/google/filament/workflows/iOS/badge.svg" alt="iOS Build Status" /></a>
|
||||
<a href="https://github.com/google/filament/actions?query=workflow%3ALinux"><img src="https://github.com/google/filament/workflows/Linux/badge.svg" alt="Linux Build Status" /></a>
|
||||
<a href="https://github.com/google/filament/actions?query=workflow%3AmacOS"><img src="https://github.com/google/filament/workflows/macOS/badge.svg" alt="macOS Build Status" /></a>
|
||||
<a href="https://github.com/google/filament/actions?query=workflow%3AWindows"><img src="https://github.com/google/filament/workflows/Windows/badge.svg" alt="Windows Build Status" /></a>
|
||||
<a href="https://github.com/google/filament/actions?query=workflow%3AWeb"><img src="https://github.com/google/filament/workflows/Web/badge.svg" alt="Web Build Status" /></a></p>
|
||||
<p>Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows,
|
||||
and WebGL. It is designed to be as small as possible and as efficient as possible on Android.</p>
|
||||
<h2 id="download"><a class="header" href="#download">Download</a></h2>
|
||||
<p><a href="https://github.com/google/filament/releases">Download Filament releases</a> to access stable builds.
|
||||
Filament release archives contains host-side tools that are required to generate assets.</p>
|
||||
<p>Make sure you always use tools from the same release as the runtime library. This is particularly
|
||||
important for <code>matc</code> (material compiler).</p>
|
||||
<p>If you'd rather build Filament yourself, please refer to our <a href="building.html">build manual</a>.</p>
|
||||
<h3 id="android"><a class="header" href="#android">Android</a></h3>
|
||||
<p>Android projects can simply declare Filament libraries as Maven dependencies:</p>
|
||||
<pre><code class="language-gradle">repositories {
|
||||
// ...
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.63.1'
|
||||
}
|
||||
</code></pre>
|
||||
<p>Here are all the libraries available in the group <code>com.google.android.filament</code>:</p>
|
||||
<div class="table-wrapper"><table><thead><tr><th>Artifact</th><th>Description</th></tr></thead><tbody>
|
||||
<tr><td><a href="https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android"><img src="https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android/badge.svg?subject=filament-android" alt="filament-android" /></a></td><td>The Filament rendering engine itself.</td></tr>
|
||||
<tr><td><a href="https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android-debug"><img src="https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android-debug/badge.svg?subject=filament-android-debug" alt="filament-android-debug" /></a></td><td>Debug version of <code>filament-android</code>.</td></tr>
|
||||
<tr><td><a href="https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android"><img src="https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android/badge.svg?subject=gltfio-android" alt="gltfio-android" /></a></td><td>A glTF 2.0 loader for Filament, depends on <code>filament-android</code>.</td></tr>
|
||||
<tr><td><a href="https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android"><img src="https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android/badge.svg?subject=filament-utils-android" alt="filament-utils-android" /></a></td><td>KTX loading, Kotlin math, and camera utilities, depends on <code>gltfio-android</code>.</td></tr>
|
||||
<tr><td><a href="https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android"><img src="https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android/badge.svg?subject=filamat-android" alt="filamat-android" /></a></td><td>A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan.</td></tr>
|
||||
<tr><td><a href="https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite"><img src="https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite/badge.svg?subject=filamat-android-lite" alt="filamat-android-lite" /></a></td><td>A much smaller alternative to <code>filamat-android</code> that can only generate OpenGL shaders. It does not provide validation or optimizations.</td></tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
<h3 id="ios"><a class="header" href="#ios">iOS</a></h3>
|
||||
<p>iOS projects can use CocoaPods to install the latest release:</p>
|
||||
<pre><code class="language-shell">pod 'Filament', '~> 1.63.1'
|
||||
</code></pre>
|
||||
<h2 id="documentation"><a class="header" href="#documentation">Documentation</a></h2>
|
||||
<ul>
|
||||
<li><a href="https://google.github.io/filament/Filament.html">Filament</a>, an in-depth explanation of
|
||||
real-time physically based rendering, the graphics capabilities and implementation of Filament.
|
||||
This document explains the math and reasoning behind most of our decisions. This document is a
|
||||
good introduction to PBR for graphics programmers.</li>
|
||||
<li><a href="https://google.github.io/filament/Materials.html">Materials</a>, the full reference
|
||||
documentation for our material system. This document explains our different material models, how
|
||||
to use the material compiler <code>matc</code> and how to write custom materials.</li>
|
||||
<li><a href="https://google.github.io/filament/notes/material_properties.html">Material Properties</a>, a reference
|
||||
sheet for the standard material model.</li>
|
||||
</ul>
|
||||
<h2 id="examples"><a class="header" href="#examples">Examples</a></h2>
|
||||
<p><img src="../images/samples/example_bistro1.jpg" alt="Night scene" />
|
||||
<img src="../images/samples/example_bistro2.jpg" alt="Night scene" />
|
||||
<img src="../images/samples/example_materials1.jpg" alt="Materials" />
|
||||
<img src="../images/samples/example_materials2.jpg" alt="Materials" />
|
||||
<img src="../images/samples/example_helmet.jpg" alt="Helmet" />
|
||||
<img src="../images/samples/example_ssr.jpg" alt="Screen-space refraction" /></p>
|
||||
<h2 id="features"><a class="header" href="#features">Features</a></h2>
|
||||
<h3 id="apis"><a class="header" href="#apis">APIs</a></h3>
|
||||
<ul>
|
||||
<li>Native C++ API for Android, iOS, Linux, macOS and Windows</li>
|
||||
<li>Java/JNI API for Android</li>
|
||||
<li>JavaScript API</li>
|
||||
</ul>
|
||||
<h3 id="backends"><a class="header" href="#backends">Backends</a></h3>
|
||||
<ul>
|
||||
<li>OpenGL 4.1+ for Linux, macOS and Windows</li>
|
||||
<li>OpenGL ES 3.0+ for Android and iOS</li>
|
||||
<li>Metal for macOS and iOS</li>
|
||||
<li>Vulkan 1.0 for Android, Linux, macOS, and Windows</li>
|
||||
<li>WebGL 2.0 for all platforms</li>
|
||||
</ul>
|
||||
<h3 id="rendering"><a class="header" href="#rendering">Rendering</a></h3>
|
||||
<ul>
|
||||
<li>Clustered forward renderer</li>
|
||||
<li>Cook-Torrance microfacet specular BRDF</li>
|
||||
<li>Lambertian diffuse BRDF</li>
|
||||
<li>Custom lighting/surface shading</li>
|
||||
<li>HDR/linear lighting</li>
|
||||
<li>Metallic workflow</li>
|
||||
<li>Clear coat</li>
|
||||
<li>Anisotropic lighting</li>
|
||||
<li>Approximated translucent (subsurface) materials</li>
|
||||
<li>Cloth/fabric/sheen shading</li>
|
||||
<li>Normal mapping & ambient occlusion mapping</li>
|
||||
<li>Image-based lighting</li>
|
||||
<li>Physically-based camera (shutter speed, sensitivity and aperture)</li>
|
||||
<li>Physical light units</li>
|
||||
<li>Point lights, spot lights, and directional light</li>
|
||||
<li>Specular anti-aliasing</li>
|
||||
<li>Point, spot, and directional light shadows</li>
|
||||
<li>Cascaded shadows</li>
|
||||
<li>EVSM, PCSS, DPCF, or PCF shadows</li>
|
||||
<li>Transparent shadows</li>
|
||||
<li>Contact shadows</li>
|
||||
<li>Screen-space ambient occlusion</li>
|
||||
<li>Screen-space reflections</li>
|
||||
<li>Screen-space refraction</li>
|
||||
<li>Global fog</li>
|
||||
<li>Dynamic resolution (with support for AMD FidelityFX FSR)</li>
|
||||
</ul>
|
||||
<h3 id="post-processing"><a class="header" href="#post-processing">Post processing</a></h3>
|
||||
<ul>
|
||||
<li>HDR bloom</li>
|
||||
<li>Depth of field bokeh</li>
|
||||
<li>Multiple tone mappers: generic (customizable), ACES, filmic, etc.</li>
|
||||
<li>Color and tone management: luminance scaling, gamut mapping</li>
|
||||
<li>Color grading: exposure, night adaptation, white balance, channel mixer,
|
||||
shadows/mid-tones/highlights, ASC CDL, contrast, saturation, etc.</li>
|
||||
<li>TAA, FXAA, MSAA</li>
|
||||
<li>Screen-space lens flares</li>
|
||||
</ul>
|
||||
<h3 id="gltf-20"><a class="header" href="#gltf-20">glTF 2.0</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<p>Encodings</p>
|
||||
<ul>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Embeded</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Binary</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>Primitive Types</p>
|
||||
<ul>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Points</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Lines</li>
|
||||
<li><input disabled="" type="checkbox"/>
|
||||
Line Loop</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Line Strip</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Triangles</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Triangle Strip</li>
|
||||
<li><input disabled="" type="checkbox"/>
|
||||
Triangle Fan</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>Animation</p>
|
||||
<ul>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Transform animation</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Linear interpolation</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Morph animation
|
||||
<ul>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Sparse accessor</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Skin animation</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
Joint animation</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>Extensions</p>
|
||||
<ul>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_draco_mesh_compression</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_lights_punctual</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_materials_clearcoat</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_materials_emissive_strength</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_materials_ior</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_materials_pbrSpecularGlossiness</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_materials_sheen</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_materials_transmission</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_materials_unlit</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_materials_variants</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_materials_volume</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_materials_specular</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_mesh_quantization</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_texture_basisu</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
KHR_texture_transform</li>
|
||||
<li><input disabled="" type="checkbox" checked=""/>
|
||||
EXT_meshopt_compression</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="rendering-with-filament"><a class="header" href="#rendering-with-filament">Rendering with Filament</a></h2>
|
||||
<h3 id="native-linux-macos-and-windows"><a class="header" href="#native-linux-macos-and-windows">Native Linux, macOS and Windows</a></h3>
|
||||
<p>You must create an <code>Engine</code>, a <code>Renderer</code> and a <code>SwapChain</code>. The <code>SwapChain</code> is created from a
|
||||
native window pointer (an <code>NSView</code> on macOS or a <code>HWND</code> on Windows for instance):</p>
|
||||
<pre><code class="language-c++">Engine* engine = Engine::create();
|
||||
SwapChain* swapChain = engine->createSwapChain(nativeWindow);
|
||||
Renderer* renderer = engine->createRenderer();
|
||||
</code></pre>
|
||||
<p>To render a frame you must then create a <code>View</code>, a <code>Scene</code> and a <code>Camera</code>:</p>
|
||||
<pre><code class="language-c++">Camera* camera = engine->createCamera(EntityManager::get().create());
|
||||
View* view = engine->createView();
|
||||
Scene* scene = engine->createScene();
|
||||
|
||||
view->setCamera(camera);
|
||||
view->setScene(scene);
|
||||
</code></pre>
|
||||
<p>Renderables are added to the scene:</p>
|
||||
<pre><code class="language-c++">Entity renderable = EntityManager::get().create();
|
||||
// build a quad
|
||||
RenderableManager::Builder(1)
|
||||
.boundingBox({{ -1, -1, -1 }, { 1, 1, 1 }})
|
||||
.material(0, materialInstance)
|
||||
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vertexBuffer, indexBuffer, 0, 6)
|
||||
.culling(false)
|
||||
.build(*engine, renderable);
|
||||
scene->addEntity(renderable);
|
||||
</code></pre>
|
||||
<p>The material instance is obtained from a material, itself loaded from a binary blob generated
|
||||
by <code>matc</code>:</p>
|
||||
<pre><code class="language-c++">Material* material = Material::Builder()
|
||||
.package((void*) BAKED_MATERIAL_PACKAGE, sizeof(BAKED_MATERIAL_PACKAGE))
|
||||
.build(*engine);
|
||||
MaterialInstance* materialInstance = material->createInstance();
|
||||
</code></pre>
|
||||
<p>To learn more about materials and <code>matc</code>, please refer to the
|
||||
<a href="./docs/Materials.html">materials documentation</a>.</p>
|
||||
<p>To render, simply pass the <code>View</code> to the <code>Renderer</code>:</p>
|
||||
<pre><code class="language-c++">// beginFrame() returns false if we need to skip a frame
|
||||
if (renderer->beginFrame(swapChain)) {
|
||||
// for each View
|
||||
renderer->render(view);
|
||||
renderer->endFrame();
|
||||
}
|
||||
</code></pre>
|
||||
<p>For complete examples of Linux, macOS and Windows Filament applications, look at the source files
|
||||
in the <code>samples/</code> directory. These samples are all based on <code>libs/filamentapp/</code> which contains the
|
||||
code that creates a native window with SDL2 and initializes the Filament engine, renderer and views.</p>
|
||||
<p>For more information on how to prepare environment maps for image-based lighting please refer to
|
||||
<a href="https://github.com/google/filament/blob/main/BUILDING.md#running-the-native-samples">BUILDING.md</a>.</p>
|
||||
<h3 id="android-1"><a class="header" href="#android-1">Android</a></h3>
|
||||
<p>See <code>android/samples</code> for examples of how to use Filament on Android.</p>
|
||||
<p>You must always first initialize Filament by calling <code>Filament.init()</code>.</p>
|
||||
<p>Rendering with Filament on Android is similar to rendering from native code (the APIs are largely
|
||||
the same across languages). You can render into a <code>Surface</code> by passing a <code>Surface</code> to the
|
||||
<code>createSwapChain</code> method. This allows you to render to a <code>SurfaceTexture</code>, a <code>TextureView</code> or
|
||||
a <code>SurfaceView</code>. To make things easier we provide an Android specific API called <code>UiHelper</code> in the
|
||||
package <code>com.google.android.filament.android</code>. All you need to do is set a render callback on the
|
||||
helper and attach your <code>SurfaceView</code> or <code>TextureView</code> to it. You are still responsible for
|
||||
creating the swap chain in the <code>onNativeWindowChanged()</code> callback.</p>
|
||||
<h3 id="ios-1"><a class="header" href="#ios-1">iOS</a></h3>
|
||||
<p>Filament is supported on iOS 11.0 and above. See <code>ios/samples</code> for examples of using Filament on
|
||||
iOS.</p>
|
||||
<p>Filament on iOS is largely the same as native rendering with C++. A <code>CAEAGLLayer</code> or <code>CAMetalLayer</code>
|
||||
is passed to the <code>createSwapChain</code> method. Filament for iOS supports both Metal (preferred) and
|
||||
OpenGL ES.</p>
|
||||
<h2 id="assets"><a class="header" href="#assets">Assets</a></h2>
|
||||
<p>To get started you can use the textures and environment maps found respectively in
|
||||
<code>third_party/textures</code> and <code>third_party/environments</code>. These assets are under CC0 license. Please
|
||||
refer to their respective <code>URL.txt</code> files to know more about the original authors.</p>
|
||||
<p>Environments must be pre-processed using
|
||||
<a href="https://github.com/google/filament/blob/main/BUILDING.md#running-the-native-samples"><code>cmgen</code></a> or
|
||||
using the <code>libiblprefilter</code> library.</p>
|
||||
<h2 id="how-to-make-contributions"><a class="header" href="#how-to-make-contributions">How to make contributions</a></h2>
|
||||
<p>Please read and follow the steps in <a href="contributing.html">CONTRIBUTING.md</a>. Make sure you are
|
||||
familiar with the <a href="code_style.html">code style</a>.</p>
|
||||
<h2 id="directory-structure"><a class="header" href="#directory-structure">Directory structure</a></h2>
|
||||
<p>This repository not only contains the core Filament engine, but also its supporting libraries
|
||||
and tools.</p>
|
||||
<ul>
|
||||
<li><code>android</code>: Android libraries and projects
|
||||
<ul>
|
||||
<li><code>filamat-android</code>: Filament material generation library (AAR) for Android</li>
|
||||
<li><code>filament-android</code>: Filament library (AAR) for Android</li>
|
||||
<li><code>filament-utils-android</code>: Extra utilities (KTX loader, math types, etc.)</li>
|
||||
<li><code>gltfio-android</code>: Filament glTF loading library (AAR) for Android</li>
|
||||
<li><code>samples</code>: Android-specific Filament samples</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><code>art</code>: Source for various artworks (logos, PDF manuals, etc.)</li>
|
||||
<li><code>assets</code>: 3D assets to use with sample applications</li>
|
||||
<li><code>build</code>: CMake build scripts</li>
|
||||
<li><code>docs</code>: Documentation
|
||||
<ul>
|
||||
<li><code>math</code>: Mathematica notebooks used to explore BRDFs, equations, etc.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><code>filament</code>: Filament rendering engine (minimal dependencies)
|
||||
<ul>
|
||||
<li><code>backend</code>: Rendering backends/drivers (Vulkan, Metal, OpenGL/ES)</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><code>ide</code>: Configuration files for IDEs (CLion, etc.)</li>
|
||||
<li><code>ios</code>: Sample projects for iOS</li>
|
||||
<li><code>libs</code>: Libraries
|
||||
<ul>
|
||||
<li><code>bluegl</code>: OpenGL bindings for macOS, Linux and Windows</li>
|
||||
<li><code>bluevk</code>: Vulkan bindings for macOS, Linux, Windows and Android</li>
|
||||
<li><code>camutils</code>: Camera manipulation utilities</li>
|
||||
<li><code>filabridge</code>: Library shared by the Filament engine and host tools</li>
|
||||
<li><code>filaflat</code>: Serialization/deserialization library used for materials</li>
|
||||
<li><code>filagui</code>: Helper library for <a href="https://github.com/ocornut/imgui">Dear ImGui</a></li>
|
||||
<li><code>filamat</code>: Material generation library</li>
|
||||
<li><code>filamentapp</code>: SDL2 skeleton to build sample apps</li>
|
||||
<li><code>filameshio</code>: Tiny filamesh parsing library (see also <code>tools/filamesh</code>)</li>
|
||||
<li><code>geometry</code>: Mesh-related utilities</li>
|
||||
<li><code>gltfio</code>: Loader for glTF 2.0</li>
|
||||
<li><code>ibl</code>: IBL generation tools</li>
|
||||
<li><code>image</code>: Image filtering and simple transforms</li>
|
||||
<li><code>imageio</code>: Image file reading / writing, only intended for internal use</li>
|
||||
<li><code>matdbg</code>: DebugServer for inspecting shaders at run-time (debug builds only)</li>
|
||||
<li><code>math</code>: Math library</li>
|
||||
<li><code>mathio</code>: Math types support for output streams</li>
|
||||
<li><code>utils</code>: Utility library (threads, memory, data structures, etc.)</li>
|
||||
<li><code>viewer</code>: glTF viewer library (requires gltfio)</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><code>samples</code>: Sample desktop applications</li>
|
||||
<li><code>shaders</code>: Shaders used by <code>filamat</code> and <code>matc</code></li>
|
||||
<li><code>third_party</code>: External libraries and assets
|
||||
<ul>
|
||||
<li><code>environments</code>: Environment maps under CC0 license that can be used with <code>cmgen</code></li>
|
||||
<li><code>models</code>: Models under permissive licenses</li>
|
||||
<li><code>textures</code>: Textures under CC0 license</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><code>tools</code>: Host tools
|
||||
<ul>
|
||||
<li><code>cmgen</code>: Image-based lighting asset generator</li>
|
||||
<li><code>filamesh</code>: Mesh converter</li>
|
||||
<li><code>glslminifier</code>: Minifies GLSL source code</li>
|
||||
<li><code>matc</code>: Material compiler</li>
|
||||
<li><code>filament-matp</code>: Material parser</li>
|
||||
<li><code>matinfo</code> Displays information about materials compiled with <code>matc</code></li>
|
||||
<li><code>mipgen</code> Generates a series of miplevels from a source image</li>
|
||||
<li><code>normal-blending</code>: Tool to blend normal maps</li>
|
||||
<li><code>resgen</code> Aggregates binary blobs into embeddable resources</li>
|
||||
<li><code>roughness-prefilter</code>: Pre-filters a roughness map from a normal map to reduce aliasing</li>
|
||||
<li><code>specular-color</code>: Computes the specular color of conductors based on spectral data</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><code>web</code>: JavaScript bindings, documentation, and samples</li>
|
||||
</ul>
|
||||
<h2 id="license"><a class="header" href="#license">License</a></h2>
|
||||
<p>Please see <a href="/LICENSE">LICENSE</a>.</p>
|
||||
<h2 id="disclaimer"><a class="header" href="#disclaimer">Disclaimer</a></h2>
|
||||
<p>This is not an officially supported Google product.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
|
||||
<a rel="next prefetch" href="dup/building.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
|
||||
<a rel="next prefetch" href="dup/building.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -178,9 +178,9 @@ content:counter(h1) "."counter(h2) "."counter(h3) "."counter(h4) "."counter(h5)
|
||||
counter-increment: h6;margin-right:10px}
|
||||
</style><style>.hljs{display:block;overflow-x:auto;padding:0.5em;background:#fff;color:#000;-webkit-text-size-adjust:none}.hljs-comment{color:#006a00}.hljs-keyword{color:#02E}.hljs-literal,.nginx .hljs-title{color:#aa0d91}.method,.hljs-list .hljs-title,.hljs-tag .hljs-title,.setting .hljs-value,.hljs-winutils,.tex .hljs-command,.http .hljs-title,.hljs-request,.hljs-status,.hljs-name{color:#008}.hljs-envvar,.tex .hljs-special{color:#660}.hljs-string{color:#c41a16}.hljs-tag .hljs-value,.hljs-cdata,.hljs-filter .hljs-argument,.hljs-attr_selector,.apache .hljs-cbracket,.hljs-date,.hljs-regexp{color:#080}.hljs-sub .hljs-identifier,.hljs-pi,.hljs-tag,.hljs-tag .hljs-keyword,.hljs-decorator,.ini .hljs-title,.hljs-shebang,.hljs-prompt,.hljs-hexcolor,.hljs-rule .hljs-value,.hljs-symbol,.hljs-symbol .hljs-string,.hljs-number,.css .hljs-function,.hljs-function .hljs-title,.coffeescript .hljs-attribute{color:#A0C}.hljs-function .hljs-title{font-weight:bold;color:#000}.hljs-class .hljs-title,.smalltalk .hljs-class,.hljs-type,.hljs-typename,.hljs-tag .hljs-attribute,.hljs-doctype,.hljs-class .hljs-id,.hljs-built_in,.setting,.hljs-params,.clojure .hljs-attribute{color:#5c2699}.hljs-variable{color:#3f6e74}.css .hljs-tag,.hljs-rule .hljs-property,.hljs-pseudo,.hljs-subst{color:#000}.css .hljs-class,.css .hljs-id{color:#9b703f}.hljs-value .hljs-important{color:#ff7700;font-weight:bold}.hljs-rule .hljs-keyword{color:#c5af75}.hljs-annotation,.apache .hljs-sqbracket,.nginx .hljs-built_in{color:#9b859d}.hljs-preprocessor,.hljs-preprocessor *,.hljs-pragma{color:#643820}.tex .hljs-formula{background-color:#eee;font-style:italic}.diff .hljs-header,.hljs-chunk{color:#808080;font-weight:bold}.diff .hljs-change{background-color:#bccff9}.hljs-addition{background-color:#baeeba}.hljs-deletion{background-color:#ffc8bd}.hljs-comment .hljs-doctag{font-weight:bold}.method .hljs-id{color:#000}</style><style>div.title { padding-top: 40px; } div.afterTitles { height: 15px; }</style><meta charset="utf-8"></p>
|
||||
<style>img { max-width: 100%; }</style>
|
||||
<p><span style="display:none">$$\newcommand{\n}{\hat{n}}\newcommand{\thetai}{\theta_\mathrm{i}}\newcommand{\thetao}{\theta_\mathrm{o}}\newcommand{\d}[1]{\mathrm{d}#1}\newcommand{\w}{\hat{\omega}}\newcommand{\wi}{\w_\mathrm{i}}\newcommand{\wo}{\w_\mathrm{o}}\newcommand{\wh}{\w_\mathrm{h}}\newcommand{\Li}{L_\mathrm{i}}\newcommand{\Lo}{L_\mathrm{o}}\newcommand{\Le}{L_\mathrm{e}}\newcommand{\Lr}{L_\mathrm{r}}\newcommand{\Lt}{L_\mathrm{t}}\newcommand{\O}{\mathrm{O}}\newcommand{\degrees}{{^{\large\circ}}}\newcommand{\T}{\mathsf{T}}\newcommand{\mathset}[1]{\mathbb{#1}}\newcommand{\Real}{\mathset{R}}\newcommand{\Integer}{\mathset{Z}}\newcommand{\Boolean}{\mathset{B}}\newcommand{\Complex}{\mathset{C}}\newcommand{\un}[1]{,\mathrm{#1}}$$
|
||||
<script type="text/x-mathjax-config">MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "AMS"} } });</script><span style="display:none">$$\newcommand{\n}{\hat{n}}\newcommand{\thetai}{\theta_\mathrm{i}}\newcommand{\thetao}{\theta_\mathrm{o}}\newcommand{\d}[1]{\mathrm{d}#1}\newcommand{\w}{\hat{\omega}}\newcommand{\wi}{\w_\mathrm{i}}\newcommand{\wo}{\w_\mathrm{o}}\newcommand{\wh}{\w_\mathrm{h}}\newcommand{\Li}{L_\mathrm{i}}\newcommand{\Lo}{L_\mathrm{o}}\newcommand{\Le}{L_\mathrm{e}}\newcommand{\Lr}{L_\mathrm{r}}\newcommand{\Lt}{L_\mathrm{t}}\newcommand{\O}{\mathrm{O}}\newcommand{\degrees}{{^{\large\circ}}}\newcommand{\T}{\mathsf{T}}\newcommand{\mathset}[1]{\mathbb{#1}}\newcommand{\Real}{\mathset{R}}\newcommand{\Integer}{\mathset{Z}}\newcommand{\Boolean}{\mathset{B}}\newcommand{\Complex}{\mathset{C}}\newcommand{\un}[1]{\,\mathrm{#1}}$$
|
||||
</span>
|
||||
<span class="md"><p><title>Physically Based Rendering in Filament</title><div class="title"> Physically Based Rendering in Filament </div></p>
|
||||
<span class="md"><p><title>Physically Based Rendering in Filament</title><div class="title"> Physically Based Rendering in Filament </div>
|
||||
<div class="afterTitles"></div>
|
||||
</p><p>
|
||||
</p>
|
||||
@@ -2060,7 +2060,7 @@ In practice only 4 or 9 coefficients (i.e.: 2 or 3 bands) are enough for \(\cosT
|
||||
In practice we pre-convolve \(\Lt\) with \(\cosTheta\) and pre-scale these coefficients by the basis scaling factors \(K_l^m\) so that the reconstruction code is as simple as possible in the shader:
|
||||
</p><a class="target" name="listing_irradiancesh"> </a><pre class="listing tilde"><code><span class="line"></span>vec3 irradianceSH(vec3 n) {
|
||||
<span class="line"></span> // uniform vec3 sphericalHarmonics<span class="hljs-selector-attr">[9]</span>
|
||||
<span class="line"></span> // We can <span class="hljs-selector-tag">use</span> only the first <span class="hljs-number">2</span> bands for better performance
|
||||
<span class="line"></span> // We can use only the first <span class="hljs-number">2</span> bands for better performance
|
||||
<span class="line"></span> return
|
||||
<span class="line"></span> sphericalHarmonics<span class="hljs-selector-attr">[0]</span>
|
||||
<span class="line"></span> + sphericalHarmonics<span class="hljs-selector-attr">[1]</span> * (n<span class="hljs-selector-class">.y</span>)
|
||||
@@ -4395,7 +4395,7 @@ For Fast Realistic Image Display. <em class="asterisk">SIGGRAPH '00 Proceedings
|
||||
</div><div class="bib">[<a class="target" name="citation-schlick94"> </a><b>Schlick94</b>] Christophe Schlick. 1994. An Inexpensive BRDF Model for Physically-Based Rendering. <em class="asterisk">Computer Graphics Forum</em>, 13 (3), 233–246.
|
||||
</div><div class="bib">[<a class="target" name="citation-walter07"> </a><b>Walter07</b>] Bruce Walter et al. 2007. Microfacet Models for Refraction through Rough Surfaces. <em class="asterisk">Proceedings of the Eurographics Symposium on Rendering</em>.
|
||||
</div>
|
||||
</sample></float></sample></float></float></p></span><div id="mdContextMenu" style="visibility:hidden"></div><div class="markdeepFooter"><i>formatted by <a href="https://casual-effects.com/markdeep" style="color:#999">Markdeep 1.18 </a></i><div style="display:inline-block;font-size:13px;font-family:'Times New Roman',serif;vertical-align:middle;transform:translate(-3px,-1px)rotate(135deg);">✒</div></div><script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
|
||||
</sample></float></sample></float></float></p></span><div id="mdContextMenu" style="visibility:hidden"></div><div class="markdeepFooter"><i>formatted by <a href="https://casual-effects.com/markdeep" style="color:#999">Markdeep 1.18 </a></i><div style="display:inline-block;font-size:13px;font-family:'Times New Roman',serif;vertical-align:middle;transform:translate(-3px,-1px)rotate(135deg);">✒</div></div><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.6/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
|
||||
@@ -160,8 +160,8 @@
|
||||
<main>
|
||||
<h1 id="core-concepts"><a class="header" href="#core-concepts">Core Concepts</a></h1>
|
||||
<ul>
|
||||
<li><a href="filament.html">Filament</a> - High-level designs; Filament's PBR/math assumptions; implementation details.</li>
|
||||
<li><a href="materials.html">Materials</a> - A guide to Filament's material definition.</li>
|
||||
<li><a href="main/filament.html">Filament</a> - High-level designs; Filament's PBR/math assumptions; implementation details.</li>
|
||||
<li><a href="main/materials.html">Materials</a> - A guide to Filament's material definition.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
|
||||
@@ -178,9 +178,9 @@ content:counter(h1) "."counter(h2) "."counter(h3) "."counter(h4) "."counter(h5)
|
||||
counter-increment: h6;margin-right:10px}
|
||||
</style><style>.hljs{display:block;overflow-x:auto;padding:0.5em;background:#fff;color:#000;-webkit-text-size-adjust:none}.hljs-comment{color:#006a00}.hljs-keyword{color:#02E}.hljs-literal,.nginx .hljs-title{color:#aa0d91}.method,.hljs-list .hljs-title,.hljs-tag .hljs-title,.setting .hljs-value,.hljs-winutils,.tex .hljs-command,.http .hljs-title,.hljs-request,.hljs-status,.hljs-name{color:#008}.hljs-envvar,.tex .hljs-special{color:#660}.hljs-string{color:#c41a16}.hljs-tag .hljs-value,.hljs-cdata,.hljs-filter .hljs-argument,.hljs-attr_selector,.apache .hljs-cbracket,.hljs-date,.hljs-regexp{color:#080}.hljs-sub .hljs-identifier,.hljs-pi,.hljs-tag,.hljs-tag .hljs-keyword,.hljs-decorator,.ini .hljs-title,.hljs-shebang,.hljs-prompt,.hljs-hexcolor,.hljs-rule .hljs-value,.hljs-symbol,.hljs-symbol .hljs-string,.hljs-number,.css .hljs-function,.hljs-function .hljs-title,.coffeescript .hljs-attribute{color:#A0C}.hljs-function .hljs-title{font-weight:bold;color:#000}.hljs-class .hljs-title,.smalltalk .hljs-class,.hljs-type,.hljs-typename,.hljs-tag .hljs-attribute,.hljs-doctype,.hljs-class .hljs-id,.hljs-built_in,.setting,.hljs-params,.clojure .hljs-attribute{color:#5c2699}.hljs-variable{color:#3f6e74}.css .hljs-tag,.hljs-rule .hljs-property,.hljs-pseudo,.hljs-subst{color:#000}.css .hljs-class,.css .hljs-id{color:#9b703f}.hljs-value .hljs-important{color:#ff7700;font-weight:bold}.hljs-rule .hljs-keyword{color:#c5af75}.hljs-annotation,.apache .hljs-sqbracket,.nginx .hljs-built_in{color:#9b859d}.hljs-preprocessor,.hljs-preprocessor *,.hljs-pragma{color:#643820}.tex .hljs-formula{background-color:#eee;font-style:italic}.diff .hljs-header,.hljs-chunk{color:#808080;font-weight:bold}.diff .hljs-change{background-color:#bccff9}.hljs-addition{background-color:#baeeba}.hljs-deletion{background-color:#ffc8bd}.hljs-comment .hljs-doctag{font-weight:bold}.method .hljs-id{color:#000}</style><style>div.title { padding-top: 40px; } div.afterTitles { height: 15px; }</style><meta charset="utf-8"></p>
|
||||
<style>img { max-width: 100%; }</style>
|
||||
<p><span style="display:none">$$\newcommand{\n}{\hat{n}}\newcommand{\thetai}{\theta_\mathrm{i}}\newcommand{\thetao}{\theta_\mathrm{o}}\newcommand{\d}[1]{\mathrm{d}#1}\newcommand{\w}{\hat{\omega}}\newcommand{\wi}{\w_\mathrm{i}}\newcommand{\wo}{\w_\mathrm{o}}\newcommand{\wh}{\w_\mathrm{h}}\newcommand{\Li}{L_\mathrm{i}}\newcommand{\Lo}{L_\mathrm{o}}\newcommand{\Le}{L_\mathrm{e}}\newcommand{\Lr}{L_\mathrm{r}}\newcommand{\Lt}{L_\mathrm{t}}\newcommand{\O}{\mathrm{O}}\newcommand{\degrees}{{^{\large\circ}}}\newcommand{\T}{\mathsf{T}}\newcommand{\mathset}[1]{\mathbb{#1}}\newcommand{\Real}{\mathset{R}}\newcommand{\Integer}{\mathset{Z}}\newcommand{\Boolean}{\mathset{B}}\newcommand{\Complex}{\mathset{C}}\newcommand{\un}[1]{,\mathrm{#1}}$$
|
||||
<script type="text/x-mathjax-config">MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "AMS"} } });</script><span style="display:none">$$\newcommand{\n}{\hat{n}}\newcommand{\thetai}{\theta_\mathrm{i}}\newcommand{\thetao}{\theta_\mathrm{o}}\newcommand{\d}[1]{\mathrm{d}#1}\newcommand{\w}{\hat{\omega}}\newcommand{\wi}{\w_\mathrm{i}}\newcommand{\wo}{\w_\mathrm{o}}\newcommand{\wh}{\w_\mathrm{h}}\newcommand{\Li}{L_\mathrm{i}}\newcommand{\Lo}{L_\mathrm{o}}\newcommand{\Le}{L_\mathrm{e}}\newcommand{\Lr}{L_\mathrm{r}}\newcommand{\Lt}{L_\mathrm{t}}\newcommand{\O}{\mathrm{O}}\newcommand{\degrees}{{^{\large\circ}}}\newcommand{\T}{\mathsf{T}}\newcommand{\mathset}[1]{\mathbb{#1}}\newcommand{\Real}{\mathset{R}}\newcommand{\Integer}{\mathset{Z}}\newcommand{\Boolean}{\mathset{B}}\newcommand{\Complex}{\mathset{C}}\newcommand{\un}[1]{\,\mathrm{#1}}$$
|
||||
</span>
|
||||
<span class="md"><p><title>Filament Materials Guide</title><div class="title"> Filament Materials Guide </div></p>
|
||||
<span class="md"><p><title>Filament Materials Guide</title><div class="title"> Filament Materials Guide </div>
|
||||
<div class="afterTitles"></div>
|
||||
</p><p>
|
||||
</p>
|
||||
@@ -504,7 +504,7 @@ when using textures.</p>
|
||||
This property can dramatically change the appearance of a surface. Non-metallic surfaces have
|
||||
chromatic diffuse reflection and achromatic specular reflection (reflected light does not change
|
||||
color). Metallic surfaces do not have any diffuse reflection and chromatic specular reflection
|
||||
(reflected light takes on the color of the surfaced as defined by <code>baseColor</code>).
|
||||
(reflected light takes on the color of the surfaced as defined by <code>baseColor</code>).
|
||||
</p><p>
|
||||
The effect of <code>metallic</code> is shown in <a href="#figure_metallicproperty" target="_self">figure 1</a> (click on the image to see a
|
||||
larger version).
|
||||
@@ -597,7 +597,7 @@ indices.
|
||||
base layer described by the properties above. The sheen layer always sits below the clear coat layer
|
||||
if such a layer is present.</p>
|
||||
</p><p>
|
||||
The sheen layer can be used to represent cloth and fabric materials. Please refer to
|
||||
The sheen layer can be used to represent cloth and fabric materials. Please refer to
|
||||
section <a href="#toc3.3" target="_self">3.3</a> for more information about cloth and fabric materials.
|
||||
</p><p>
|
||||
The effect of <code>sheenColor</code> is shown in <a href="#figure_materialsheencolor" target="_self">figure 7</a>
|
||||
@@ -1220,10 +1220,10 @@ non-shader data.</p>
|
||||
name must be a valid GLSL identifier. Entries have an optional <code>precision</code>, which can be
|
||||
one of <code>default</code> (best precision for the platform, typically <code>high</code> on desktop, <code>medium</code> on
|
||||
mobile), <code>low</code>, <code>medium</code>, <code>high</code>. The type must be one of the types described in
|
||||
<a href="#table_materialparamstypes" target="_self">table 14</a>. For Android external textures, entries also have an optional
|
||||
transformName parameter to specify the name of the material parameter that will be
|
||||
<a href="#table_materialparamstypes" target="_self">table 14</a>. For Android external textures, entries also have an optional
|
||||
transformName parameter to specify the name of the material parameter that will be
|
||||
used to expose the transform matrix associated with the external sampler. In iOS and Vulkan,
|
||||
this will always be identity.
|
||||
this will always be identity.
|
||||
</p></dd></dl><div class='table'>
|
||||
<a class="target" name="table_materialparamstypes"> </a><table class="table longtable"><tr><th style="text-align:left"> Type </th><th style="text-align:left"> Description </th></tr>
|
||||
<tr><td style="text-align:left"> bool </td><td style="text-align:left"> Single boolean </td></tr>
|
||||
@@ -2361,10 +2361,7 @@ type aliases:</p>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getWorldFromViewMatrix()</strong> </td><td style="text-align:center"> float4×4 </td><td style="text-align:left"> Matrix that converts from view/eye space to world space </td></tr>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getClipFromViewMatrix()</strong> </td><td style="text-align:center"> float4×4 </td><td style="text-align:left"> Matrix that converts from view/eye space to clip (NDC) space </td></tr>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getViewFromClipMatrix()</strong> </td><td style="text-align:center"> float4×4 </td><td style="text-align:left"> Matrix that converts from clip (NDC) space to view/eye space </td></tr>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getEyeFromViewMatrix()</strong> </td><td style="text-align:center"> float4×4 </td><td style="text-align:left"> Matrix that converts from view space to eye space </td></tr>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getEyeFromViewMatrix(int eyeIndex)</strong> </td><td style="text-align:center"> float4×4 </td><td style="text-align:left"> Matrix that converts from view space to eye space for the eye referred to by eyeIndex </td></tr>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getClipFromWorldMatrix()</strong> </td><td style="text-align:center"> float4×4 </td><td style="text-align:left"> Matrix that converts from world to clip (NDC) space </td></tr>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getClipFromWorldMatrix(int eyeIndex)</strong> </td><td style="text-align:center"> float4×4 </td><td style="text-align:left"> Matrix that converts from world to clip (NDC) space for the eye referred to by eyeIndex </td></tr>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getWorldFromClipMatrix()</strong> </td><td style="text-align:center"> float4×4 </td><td style="text-align:left"> Matrix that converts from clip (NDC) space to world space </td></tr>
|
||||
</table></div>
|
||||
</p>
|
||||
@@ -2504,7 +2501,7 @@ a good compromise between runtime performance and size.</p>
|
||||
metadata in JSON format. The example below prints out the list of parameters defined in Filament's
|
||||
standard skybox material. It produces a list of 2 parameters, named <code>showSun</code> and <code>skybox</code>,
|
||||
respectively a boolean and a cubemap texture.</p>
|
||||
</p><pre class="listing backtick"><code><span class="line"></span>$ matc --reflect parameters filament/src/materials/skybox.mat
|
||||
</p><pre class="listing backtick"><code><span class="line"></span>$ matc --reflect parameters filament/src/materials/skybox.mat
|
||||
<span class="line"></span>{
|
||||
<span class="line"></span> "parameters": [
|
||||
<span class="line"></span> {
|
||||
@@ -2603,7 +2600,7 @@ Finally if <code>variantFilter</code> contains the <code>fog</code> filter, an e
|
||||
</p><p>
|
||||
Be aware that <code>external</code> samplers account for 2 regular samplers.</div>
|
||||
</p><p>
|
||||
</p></span><div id="mdContextMenu" style="visibility:hidden"></div><div class="markdeepFooter"><i>formatted by <a href="https://casual-effects.com/markdeep" style="color:#999">Markdeep 1.18 </a></i><div style="display:inline-block;font-size:13px;font-family:'Times New Roman',serif;vertical-align:middle;transform:translate(-3px,-1px)rotate(135deg);">✒</div></div><script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
|
||||
</p></span><div id="mdContextMenu" style="visibility:hidden"></div><div class="markdeepFooter"><i>formatted by <a href="https://casual-effects.com/markdeep" style="color:#999">Markdeep 1.18 </a></i><div style="display:inline-block;font-size:13px;font-family:'Times New Roman',serif;vertical-align:middle;transform:translate(-3px,-1px)rotate(135deg);">✒</div></div><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.6/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
|
||||
@@ -250,7 +250,7 @@ execution profile data.</p>
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../notes/performance_analysis.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<a rel="next prefetch" href="../notes/framegraph.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
@@ -264,7 +264,7 @@ execution profile data.</p>
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../notes/performance_analysis.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<a rel="next prefetch" href="../notes/framegraph.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
@@ -331,11 +331,11 @@ nodes</li>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../notes/performance_analysis.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<a rel="prev" href="../notes/coverage.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../notes/tests.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<a rel="next prefetch" href="../notes/libs.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
@@ -345,11 +345,11 @@ nodes</li>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../notes/performance_analysis.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<a rel="prev" href="../notes/coverage.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../notes/tests.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<a rel="next prefetch" href="../notes/libs.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../dup/renderdiff.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<a rel="prev" href="../notes/framegraph.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../dup/renderdiff.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<a rel="prev" href="../notes/framegraph.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1,352 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Performance analysis - Filament</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
<!-- MathJax -->
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
|
||||
</script>
|
||||
<!-- Start loading toc.js asap -->
|
||||
<script src="../toc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="body-container">
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
const html = document.documentElement;
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add("js");
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div style="display:flex;align-items:center;justify-content:center">
|
||||
<img class="flogo" src="../images/filament_logo_small.png"></img>
|
||||
</div>
|
||||
<!-- populated by js -->
|
||||
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
|
||||
<noscript>
|
||||
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
|
||||
</noscript>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
|
||||
<!--
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
-->
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Filament</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="performance-analysis"><a class="header" href="#performance-analysis">Performance Analysis</a></h1>
|
||||
<h2 id="android"><a class="header" href="#android">Android</a></h2>
|
||||
<h3 id="prerequisites"><a class="header" href="#prerequisites">Prerequisites</a></h3>
|
||||
<ul>
|
||||
<li>Download and install Android GPU Inspector (AGI). See https://developer.android.com/agi.</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h4 id="profiling"><a class="header" href="#profiling">Profiling</a></h4>
|
||||
<ol>
|
||||
<li>
|
||||
<p>Before profiling the application or analyzing the performance in a consistent way, ideally
|
||||
the <strong>GPU frequency on the target hardware should get locked</strong>. In order to do this, you need to do the following:</p>
|
||||
<ol>
|
||||
<li>Ensure your device is OEM unlocked. If your phone is carrier-locked, you may need
|
||||
to wait a period, such as 60 or 90 days after activation to be eligible for unlocking.
|
||||
Some phones don't support this at all. You will need to enable developer options
|
||||
(e.g. Settings > About Phone and tap the Build number 7 times). You need to go to
|
||||
Settings > System > Developer options and toggle on "OEM unlocking".</li>
|
||||
<li>Next, you need to unlock the phone. You will need to install Android SDK Platform
|
||||
Tools on you computer, enable "USB debugging" in your phone's Settings > System > Developer options.</li>
|
||||
<li>Connect the phone to the computer via a USB cable and run from the command line:
|
||||
<pre><code class="language-shell">adb reboot bootloader
|
||||
# once the phone is in bootloader mode, run the following to begin the unlocking
|
||||
# process:
|
||||
fastboot flashing unlock
|
||||
</code></pre>
|
||||
A warning will appear on your phone's screen. Use the volume buttons to navigate and
|
||||
the power button to select the "Unlock the bootloader" option. The phone will perform
|
||||
a factory data reset and reboot with an unlocked bootloader.</li>
|
||||
<li>You would need to flash an image to the phone with root permissions, such as a *-userdebug or *-eng
|
||||
build. One way to do this is with the <a href="https://flash.android.com/">Android Flash Tool</a>. Connect the
|
||||
tool to your device and find a build to flash ending in <code>-userdebug</code> or <code>-eng</code>. Once you have that
|
||||
selected run <code>Install build</code>.</li>
|
||||
<li>Shell into your device as root and configure the gpu frequency to be locked, e.g.:
|
||||
<pre><code class="language-shell">adb shell
|
||||
su
|
||||
# navigate to the system GPU directory. this varies on different phones. One phone might have
|
||||
# it at /sys/class/kgsl/kgsl-3d0 and another might be in something similar, maybe with "mali" instead
|
||||
# of "kgsl". At the time of writing this for the device at hand it was /sys/devices/platform/1f000000.mali
|
||||
cd /sys/devices/platform/1f000000.mali
|
||||
# get the current available GPU governors and frequencies.
|
||||
# note that some systems may have these at gpu_available_governors and gpu_available_frequencies, but
|
||||
# the system at the time of writing this had available_governors and available_frequences
|
||||
cat available_governors
|
||||
cat available_frequencies
|
||||
# depending on the governors, you may want to set it prioritize performance over other things like
|
||||
# battery. Some systems allow you to do this with something like (although, for the device used at the
|
||||
# time of writing this did not have an equivalent option):
|
||||
echo performance > gpu_governor
|
||||
# finally, lock your frequency in, usually to something high like 897 MHz. Some systems may have you
|
||||
# pipe the value to gpu_min_freq and gpu_max_freq, but the system used at the time of writing this had:
|
||||
echo 940000 > hint_min_freq
|
||||
echo 940000 > hint_max_freq
|
||||
# you can typically verify the GPU is running at that frequency consistently by running something like
|
||||
# the following a few times over time, which should show the frequency you want to lock the device to:
|
||||
cat cur_freq
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>You may need to re-apply the <code>hint_min_freq</code> just before starting the profiling trace and check before and after
|
||||
that the frequency remained at the value expected. Some systems may adjust the frequency on you, but you
|
||||
may want to ensure the frequency remains the same through the analysis.</li>
|
||||
<li>The GPU frequency settings should be undone after restarting the device, but after you have done your app profiling,
|
||||
you can revert the state of the device, such as the OS build image, back to the way you had it
|
||||
initially, as needed.</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>
|
||||
<p>Build a release build of Filament with the applicable backend(s) enabled
|
||||
<em>(+ any special flags for enabling sys strace. Nothing special is needed for Vulkan or WebGPU aside from
|
||||
building a release build with no flags)</em> <em>(debug builds for this are useless)</em></p>
|
||||
<pre><code class="language-shell"># the following command assumes you are in the root filament directory
|
||||
# and ANDROID_HOME is exported (and possibly also CC and CXX on linux as needed)
|
||||
#
|
||||
# NOTE: to build with WebGPU support you need to explicitly include the -W flag
|
||||
# (it doesn't get compiled in by default), e.g.:
|
||||
# ./build.sh -W -p android,desktop -i release
|
||||
#
|
||||
# Note that you can speed this up a bit (and reduce disk space usage) by limiting the target to just
|
||||
# the ABI you plan on testing with the -q flag, e.g. -q arm64-v8a. If you do this, you
|
||||
# will need to update the android/gradle.properties file to specify the ABI(s) you are targeting
|
||||
# with the com.google.android.filament.abis property.
|
||||
# Thus, a build command that would target BOTH Vulkan AND WebGPU AND only target the ARM64 ABI would look something
|
||||
# like:
|
||||
# ./build.sh -W -q arm64-v8a -p android,desktop -i release
|
||||
./build.sh -p android,desktop -i release
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>
|
||||
<p>Connect your Android device to your computer via a USB cord with USB debugging enabled and configure
|
||||
the system property to default to the desired backend, e.g.
|
||||
<em>(to determine how these numbers map to the backends, see the <code>enum class Backend</code>
|
||||
definition in <a href="../../../../filament/backend/include/backend/DriverEnums.h">filament/filament/backend/include/backend/DriverEnums.h</a>)</em>:</p>
|
||||
<pre><code class="language-shell"># to set the backend to Vulkan:
|
||||
adb shell setprop debug.filament.backend 2
|
||||
# to set the backend to WebGPU:
|
||||
adb shell setprop debug.filament.backend 4
|
||||
# to view the current property:
|
||||
adb shell getprop debug.filament.backend
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>
|
||||
<p>Build and run a sample, e.g. sample-gltf-viewer, on your Android device
|
||||
<em>(<a href="https://developer.android.com/studio">Android Studio</a> recommended)</em>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Run <a href="https://developer.android.com/agi">AGI</a> and follow instructions to profile the app/system
|
||||
with trace capture(s). See https://developer.android.com/agi/start for more details to
|
||||
get started.</p>
|
||||
<ul>
|
||||
<li>We typically only run "Capture System Profiler trace" <em>(not necessarily "Capture Frame Profiler trace")</em></li>
|
||||
<li>When configuring the trace:
|
||||
<ul>
|
||||
<li>For both the WebGPU and Vulkan backends configure the profiler for the Vulkan API
|
||||
<em>(since WebGPU should be using Vulkan under the hood as well)</em></li>
|
||||
<li>Running for ~1 seconds should suffice</li>
|
||||
<li>Hit the "Configure" button in Trace objects, select "Switch to advanced mode" and add:
|
||||
<pre><code>data_sources {
|
||||
config {
|
||||
name: "track_event"
|
||||
track_event_config {
|
||||
disabled_categories: "*"
|
||||
enabled_categories: "filament/filament"
|
||||
enabled_categories: "filament/jobsystem"
|
||||
enabled_categories: "filament/gltfio"
|
||||
}
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>One you open the trace, zoom into a series of frames to get a sense of generally how long they typically take
|
||||
<em>(use <code>W</code>, <code>S</code>, <code>A</code> and <code>D</code> keys and mouse wheel for navigation)</em> and find a representative one.
|
||||
We are most interested in the performance of the
|
||||
<code>FEngine::loop</code> thread, how long it takes, overlap in activities/processes/commands, reduction in queue submissions,
|
||||
etc. Similarly, we can view GPU timeline as it relates to that. We want to see overlapping
|
||||
shader invocations and non-interrupted fragment shader runs.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../notes/coverage.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../notes/framegraph.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../notes/coverage.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../notes/framegraph.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js"></script>
|
||||
<script src="../mark.min.js"></script>
|
||||
<script src="../searcher.js"></script>
|
||||
|
||||
<script src="../clipboard.min.js"></script>
|
||||
<script src="../highlight.js"></script>
|
||||
<script src="../book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,215 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Tests - Filament</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
<!-- MathJax -->
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
|
||||
</script>
|
||||
<!-- Start loading toc.js asap -->
|
||||
<script src="../toc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="body-container">
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
const html = document.documentElement;
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add("js");
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div style="display:flex;align-items:center;justify-content:center">
|
||||
<img class="flogo" src="../images/filament_logo_small.png"></img>
|
||||
</div>
|
||||
<!-- populated by js -->
|
||||
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
|
||||
<noscript>
|
||||
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
|
||||
</noscript>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
|
||||
<!--
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
-->
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Filament</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="tests"><a class="header" href="#tests">Tests</a></h1>
|
||||
<p>Filament has a collection of tests that can be run locally. Many of them are used
|
||||
for in our Continuation Integration flow <a href="https://https://github.com/google/filament/tree/main/.github/workflows">on github</a>.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../notes/framegraph.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../dup/renderdiff.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../notes/framegraph.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../dup/renderdiff.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js"></script>
|
||||
<script src="../mark.min.js"></script>
|
||||
<script src="../searcher.js"></script>
|
||||
|
||||
<script src="../clipboard.min.js"></script>
|
||||
<script src="../highlight.js"></script>
|
||||
<script src="../book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+2
-5
@@ -65,9 +65,6 @@ We describe step 1 in detail for the sake of record:
|
||||
- Replace css styling in the exported output as needed (so they don't interfere with the book's css.
|
||||
- Replace resource urls to refer to locations relative to the mdbook structure.
|
||||
|
||||
Any `markdeep` doc can be placed in `docs_src/src_markdeep/` and they will be parsed to html and included
|
||||
in the book as above.
|
||||
|
||||
### READMEs
|
||||
Filament depends on a number of libraries, which reside in the directory `libs`. These individual
|
||||
libaries often have README.md in their root to describe itself. We collect these descriptions into our
|
||||
@@ -78,7 +75,7 @@ The process for copying and processing these READMEs is outlined in [Introductor
|
||||
|
||||
### Other technical notes
|
||||
These are technical documents that do not fit into a library, tool, or directory of the
|
||||
Filament source tree. We collect them into the `docs_src/src_mdbook/src/notes` directory. No additional
|
||||
Filament source tree. We collect them into the `docs_src/src/notes` directory. No additional
|
||||
processing is needed for these documents.
|
||||
|
||||
### Raw source files
|
||||
@@ -93,7 +90,7 @@ add a link in `SUMMARY.md`, and perform the steps outlined in
|
||||
[how-to create section](#how-to-create).
|
||||
|
||||
For example, if you are adding a general technical note, then you would
|
||||
- Place the document (file with extension `.md`) in `docs_src/src_mdbook/src/notes`
|
||||
- Place the document (file with extension `.md`) in `docs_src/src/notes`
|
||||
- Add a link in [`docs_src/src_mdbook/src/SUMMARY.md`]
|
||||
- Run the commands in the [Generate](#how-to-generate) section
|
||||
|
||||
|
||||
@@ -2,14 +2,9 @@
|
||||
"README.md": {
|
||||
"dest": "dup/intro.md",
|
||||
"link_transforms": {
|
||||
"/BUILDING.md#running-the-native-samples": "building.md#running-the-native-samples",
|
||||
"/BUILDING.md": "building.md",
|
||||
"BUILDING.md": "building.md",
|
||||
"/CONTRIBUTING.md": "contributing.md",
|
||||
"/CODE_STYLE.md": "code_style.md",
|
||||
"/LICENSE": "https://github.com/google/filament/blob/main/LICENSE",
|
||||
"https://google.github.io/filament/Filament.html": "../main/filament.md",
|
||||
"https://google.github.io/filament/Materials.html": "../main/materials.md",
|
||||
"https://google.github.io/filament/notes/material_properties.html": "../notes/material_properties.md",
|
||||
"docs/images/samples": "../images/samples"
|
||||
}
|
||||
},
|
||||
@@ -78,11 +73,5 @@
|
||||
},
|
||||
"docs_src/README.md": {
|
||||
"dest": "dup/docs.md"
|
||||
},
|
||||
"test/renderdiff/README.md": {
|
||||
"dest": "dup/renderdiff.md",
|
||||
"link_transforms": {
|
||||
"docs/images/": "../images/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ when using textures.
|
||||
This property can dramatically change the appearance of a surface. Non-metallic surfaces have
|
||||
chromatic diffuse reflection and achromatic specular reflection (reflected light does not change
|
||||
color). Metallic surfaces do not have any diffuse reflection and chromatic specular reflection
|
||||
(reflected light takes on the color of the surfaced as defined by `baseColor`).
|
||||
(reflected light takes on the color of the surfaced as defined by `baseColor`).
|
||||
|
||||
The effect of `metallic` is shown in figure [metallicProperty] (click on the image to see a
|
||||
larger version).
|
||||
@@ -248,7 +248,7 @@ The effect of `roughness` on metallic surfaces is shown in figure [roughnessCond
|
||||
When refraction through an object is enabled (using a `refractonType` of `thin` or `solid`), the
|
||||
`roughness` property will also affect the refractions, as shown in figure
|
||||
[roughnessRefractionProperty] (click on the image to see a larger version).
|
||||
|
||||
|
||||
![Figure [roughnessRefractionProperty]: Refractive sphere with `roughness` varying from 0.0
|
||||
(left) to 1.0 (right)](images/materials/refraction_roughness.png)
|
||||
|
||||
@@ -307,7 +307,7 @@ The sheen color controls the color appearance and strength of an optional sheen
|
||||
base layer described by the properties above. The sheen layer always sits below the clear coat layer
|
||||
if such a layer is present.
|
||||
|
||||
The sheen layer can be used to represent cloth and fabric materials. Please refer to
|
||||
The sheen layer can be used to represent cloth and fabric materials. Please refer to
|
||||
section [Cloth model] for more information about cloth and fabric materials.
|
||||
|
||||
The effect of `sheenColor` is shown in figure [materialSheenColor]
|
||||
@@ -520,14 +520,14 @@ light to bend further away from the initial path.
|
||||
|
||||
Table [commonMatIOR] describes acceptable refractive indices for various types of materials.
|
||||
|
||||
Material | IOR
|
||||
Material | IOR
|
||||
--------------------------:|:-----------------
|
||||
Air | 1.0
|
||||
Water | 1.33
|
||||
Common liquids | 1.33 to 1.5
|
||||
Common gemstones | 1.58 to 2.33
|
||||
Plastics, glass | 1.5 to 1.58
|
||||
Other dielectric materials | 1.33 to 1.58
|
||||
Water | 1.33
|
||||
Common liquids | 1.33 to 1.5
|
||||
Common gemstones | 1.58 to 2.33
|
||||
Plastics, glass | 1.5 to 1.58
|
||||
Other dielectric materials | 1.33 to 1.58
|
||||
[Table [commonMatIOR]: Index of refraction of common materials]
|
||||
|
||||
The appearance of a refractive material will greatly depend on the `refractionType` and
|
||||
@@ -995,10 +995,10 @@ Value
|
||||
name must be a valid GLSL identifier. Entries have an optional `precision`, which can be
|
||||
one of `default` (best precision for the platform, typically `high` on desktop, `medium` on
|
||||
mobile), `low`, `medium`, `high`. The type must be one of the types described in
|
||||
table [materialParamsTypes]. For Android external textures, entries also have an optional
|
||||
transformName parameter to specify the name of the material parameter that will be
|
||||
table [materialParamsTypes]. For Android external textures, entries also have an optional
|
||||
transformName parameter to specify the name of the material parameter that will be
|
||||
used to expose the transform matrix associated with the external sampler. In iOS and Vulkan,
|
||||
this will always be identity.
|
||||
this will always be identity.
|
||||
|
||||
Type | Description
|
||||
:----------------------|:---------------------------------
|
||||
@@ -2476,17 +2476,14 @@ type aliases:
|
||||
|
||||
### Matrices
|
||||
|
||||
Name | Type | Description
|
||||
:-----------------------------------------|:--------:|:------------------------------------
|
||||
**getViewFromWorldMatrix()** | float4x4 | Matrix that converts from world space to view/eye space
|
||||
**getWorldFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to world space
|
||||
**getClipFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to clip (NDC) space
|
||||
**getViewFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to view/eye space
|
||||
**getEyeFromViewMatrix()** | float4x4 | Matrix that converts from view space to eye space
|
||||
**getEyeFromViewMatrix(int eyeIndex)** | float4x4 | Matrix that converts from view space to eye space for the eye referred to by eyeIndex
|
||||
**getClipFromWorldMatrix()** | float4x4 | Matrix that converts from world to clip (NDC) space
|
||||
**getClipFromWorldMatrix(int eyeIndex)** | float4x4 | Matrix that converts from world to clip (NDC) space for the eye referred to by eyeIndex
|
||||
**getWorldFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to world space
|
||||
Name | Type | Description
|
||||
:-----------------------------------|:--------:|:------------------------------------
|
||||
**getViewFromWorldMatrix()** | float4x4 | Matrix that converts from world space to view/eye space
|
||||
**getWorldFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to world space
|
||||
**getClipFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to clip (NDC) space
|
||||
**getViewFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to view/eye space
|
||||
**getClipFromWorldMatrix()** | float4x4 | Matrix that converts from world to clip (NDC) space
|
||||
**getWorldFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to world space
|
||||
|
||||
### Frame constants
|
||||
|
||||
@@ -2642,7 +2639,7 @@ standard skybox material. It produces a list of 2 parameters, named `showSun` an
|
||||
respectively a boolean and a cubemap texture.
|
||||
|
||||
```text
|
||||
$ matc --reflect parameters filament/src/materials/skybox.mat
|
||||
$ matc --reflect parameters filament/src/materials/skybox.mat
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
@@ -2658,7 +2655,7 @@ $ matc --reflect parameters filament/src/materials/skybox.mat
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
### --variant-filter
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- [Introduction](./dup/intro.md)
|
||||
- [Build](./dup/building.md)
|
||||
- [Build for Android on Windows](./build/windows_android.md)
|
||||
- [Maven Release](./build/maven_release.md)
|
||||
- [Contribute](./dup/contributing.md)
|
||||
- [Coding Style](./dup/code_style.md)
|
||||
- [Core Concepts](./main/README.md)
|
||||
@@ -25,10 +24,7 @@
|
||||
- [Running with ASAN and UBSAN](./notes/asan_ubsan.md)
|
||||
- [Using Instruments on macOS](./notes/instruments.md)
|
||||
- [Code coverage analysis](./notes/coverage.md)
|
||||
- [Performance analysis](./notes/performance_analysis.md)
|
||||
- [Framegraph](./notes/framegraph.md)
|
||||
- [Tests](./notes/tests.md)
|
||||
- [renderdiff](./dup/renderdiff.md)
|
||||
- [Libraries](./notes/libs.md)
|
||||
- [bluegl](./dup/bluegl.md)
|
||||
- [bluevk](./dup/bluevk.md)
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
# Maven Release
|
||||
|
||||
## Register for a Sonatype Account
|
||||
|
||||
First, you'll need to register for a Sonatype account at the [Central
|
||||
Portal](https://central.sonatype.org/register/central-portal/).
|
||||
|
||||
To publish under the `com.google.android` namespace, you'll also need to email
|
||||
`central-support@sonatype.com` with your account information to request access.
|
||||
|
||||
Then, generate a user token through the Sonatype website. Navigate to
|
||||
[https://central.sonatype.com/account](https://central.sonatype.com/account) and select **Generate
|
||||
User Token**.
|
||||
|
||||
Finally, add the generated token credentials to `~/.gradle/gradle.properties`. (Note: these are
|
||||
different from the credentials used to log into your Sonatype account):
|
||||
|
||||
```gradle
|
||||
# Generated Sonatype token
|
||||
sonatypeUsername=<username>
|
||||
sonatypePassword=<password>
|
||||
```
|
||||
|
||||
-----
|
||||
|
||||
## Signing Key
|
||||
|
||||
All release artifacts must be signed. You'll need to create an OpenPGP key pair. See Gradle's
|
||||
documentation on [Signatory
|
||||
credentials](https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials)
|
||||
for instructions.
|
||||
|
||||
Update `~/.gradle/gradle.properties` with your new key's credentials:
|
||||
|
||||
```gradle
|
||||
signing.keyId=<key id>
|
||||
signing.password=<key password>
|
||||
signing.secretKeyRingFile=<secret key ring file>
|
||||
```
|
||||
|
||||
-----
|
||||
|
||||
## Build the Android Release
|
||||
|
||||
Make sure `JAVA_HOME` is set correctly. For example:
|
||||
|
||||
```bash
|
||||
export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home
|
||||
./build.sh -C -i -p android release
|
||||
```
|
||||
|
||||
-----
|
||||
|
||||
## Publish to Sonatype
|
||||
|
||||
### A Note on the Legacy Staging Service
|
||||
|
||||
Previously, Filament was published to Maven via OSSRH (Open Source Software Repository Hosting). In
|
||||
2025, this service was [sunsetted](https://central.sonatype.org/pages/ossrh-eol/). Now, we use
|
||||
Sonatype's [Central Publisher Portal](https://central.sonatype.org/).
|
||||
|
||||
The new Central Publisher Portal does not officially support Gradle. However, Sonatype provides a
|
||||
staging API compatibility service, which works with Filament's Gradle setup.
|
||||
|
||||
-----
|
||||
|
||||
### 1\. Upload to the Staging API Compatibility Service
|
||||
|
||||
```bash
|
||||
cd android
|
||||
./gradlew publishToSonatype
|
||||
```
|
||||
|
||||
### 2\. Move the Repository to the Central Publisher Portal
|
||||
|
||||
We have a script to automate this. It reads the `sonatypeUsername` and `sonatypePassword` from your
|
||||
`~/.gradle/gradle.properties` file.
|
||||
|
||||
```bash
|
||||
python3 build/common/close-sonatype-staging-repository.py
|
||||
```
|
||||
|
||||
### 3\. Publish the Release on Sonatype
|
||||
|
||||
Navigate to [Maven Central Repository Deployments](https://central.sonatype.com/publishing/deployments).
|
||||
|
||||
Here, you should see a new deployment with a **Validated** status and all your artifacts listed. Click
|
||||
the **Publish** button to publish the artifacts. It typically takes around 5 minutes after clicking
|
||||
**Publish** for the artifacts to go live.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 361 KiB |
@@ -1,5 +1,5 @@
|
||||
# Core Concepts
|
||||
|
||||
|
||||
- [Filament](filament.md) - High-level designs; Filament's PBR/math assumptions; implementation details.
|
||||
- [Materials](materials.md) - A guide to Filament's material definition.
|
||||
- [Filament](main/filament.md) - High-level designs; Filament's PBR/math assumptions; implementation details.
|
||||
- [Materials](main/materials.md) - A guide to Filament's material definition.
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
# Performance Analysis
|
||||
|
||||
## Android
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Download and install Android GPU Inspector (AGI). See https://developer.android.com/agi.
|
||||
|
||||
---
|
||||
|
||||
#### Profiling
|
||||
|
||||
1. Before profiling the application or analyzing the performance in a consistent way, ideally
|
||||
the **GPU frequency on the target hardware should get locked**. In order to do this, you need to do the following:
|
||||
1. Ensure your device is OEM unlocked. If your phone is carrier-locked, you may need
|
||||
to wait a period, such as 60 or 90 days after activation to be eligible for unlocking.
|
||||
Some phones don't support this at all. You will need to enable developer options
|
||||
(e.g. Settings > About Phone and tap the Build number 7 times). You need to go to
|
||||
Settings > System > Developer options and toggle on "OEM unlocking".
|
||||
1. Next, you need to unlock the phone. You will need to install Android SDK Platform
|
||||
Tools on you computer, enable "USB debugging" in your phone's Settings > System > Developer options.
|
||||
1. Connect the phone to the computer via a USB cable and run from the command line:
|
||||
```shell
|
||||
adb reboot bootloader
|
||||
# once the phone is in bootloader mode, run the following to begin the unlocking
|
||||
# process:
|
||||
fastboot flashing unlock
|
||||
```
|
||||
A warning will appear on your phone's screen. Use the volume buttons to navigate and
|
||||
the power button to select the "Unlock the bootloader" option. The phone will perform
|
||||
a factory data reset and reboot with an unlocked bootloader.
|
||||
1. You would need to flash an image to the phone with root permissions, such as a *-userdebug or *-eng
|
||||
build. One way to do this is with the [Android Flash Tool](https://flash.android.com/). Connect the
|
||||
tool to your device and find a build to flash ending in `-userdebug` or `-eng`. Once you have that
|
||||
selected run `Install build`.
|
||||
1. Shell into your device as root and configure the gpu frequency to be locked, e.g.:
|
||||
```shell
|
||||
adb shell
|
||||
su
|
||||
# navigate to the system GPU directory. this varies on different phones. One phone might have
|
||||
# it at /sys/class/kgsl/kgsl-3d0 and another might be in something similar, maybe with "mali" instead
|
||||
# of "kgsl". At the time of writing this for the device at hand it was /sys/devices/platform/1f000000.mali
|
||||
cd /sys/devices/platform/1f000000.mali
|
||||
# get the current available GPU governors and frequencies.
|
||||
# note that some systems may have these at gpu_available_governors and gpu_available_frequencies, but
|
||||
# the system at the time of writing this had available_governors and available_frequences
|
||||
cat available_governors
|
||||
cat available_frequencies
|
||||
# depending on the governors, you may want to set it prioritize performance over other things like
|
||||
# battery. Some systems allow you to do this with something like (although, for the device used at the
|
||||
# time of writing this did not have an equivalent option):
|
||||
echo performance > gpu_governor
|
||||
# finally, lock your frequency in, usually to something high like 897 MHz. Some systems may have you
|
||||
# pipe the value to gpu_min_freq and gpu_max_freq, but the system used at the time of writing this had:
|
||||
echo 940000 > hint_min_freq
|
||||
echo 940000 > hint_max_freq
|
||||
# you can typically verify the GPU is running at that frequency consistently by running something like
|
||||
# the following a few times over time, which should show the frequency you want to lock the device to:
|
||||
cat cur_freq
|
||||
```
|
||||
1. You may need to re-apply the `hint_min_freq` just before starting the profiling trace and check before and after
|
||||
that the frequency remained at the value expected. Some systems may adjust the frequency on you, but you
|
||||
may want to ensure the frequency remains the same through the analysis.
|
||||
1. The GPU frequency settings should be undone after restarting the device, but after you have done your app profiling,
|
||||
you can revert the state of the device, such as the OS build image, back to the way you had it
|
||||
initially, as needed.
|
||||
1. Build a release build of Filament with the applicable backend(s) enabled
|
||||
_(+ any special flags for enabling sys strace. Nothing special is needed for Vulkan or WebGPU aside from
|
||||
building a release build with no flags)_ _(debug builds for this are useless)_
|
||||
|
||||
```shell
|
||||
# the following command assumes you are in the root filament directory
|
||||
# and ANDROID_HOME is exported (and possibly also CC and CXX on linux as needed)
|
||||
#
|
||||
# NOTE: to build with WebGPU support you need to explicitly include the -W flag
|
||||
# (it doesn't get compiled in by default), e.g.:
|
||||
# ./build.sh -W -p android,desktop -i release
|
||||
#
|
||||
# Note that you can speed this up a bit (and reduce disk space usage) by limiting the target to just
|
||||
# the ABI you plan on testing with the -q flag, e.g. -q arm64-v8a. If you do this, you
|
||||
# will need to update the android/gradle.properties file to specify the ABI(s) you are targeting
|
||||
# with the com.google.android.filament.abis property.
|
||||
# Thus, a build command that would target BOTH Vulkan AND WebGPU AND only target the ARM64 ABI would look something
|
||||
# like:
|
||||
# ./build.sh -W -q arm64-v8a -p android,desktop -i release
|
||||
./build.sh -p android,desktop -i release
|
||||
```
|
||||
1. Connect your Android device to your computer via a USB cord with USB debugging enabled and configure
|
||||
the system property to default to the desired backend, e.g.
|
||||
_(to determine how these numbers map to the backends, see the `enum class Backend`
|
||||
definition in [filament/filament/backend/include/backend/DriverEnums.h](../../../../filament/backend/include/backend/DriverEnums.h))_:
|
||||
```shell
|
||||
# to set the backend to Vulkan:
|
||||
adb shell setprop debug.filament.backend 2
|
||||
# to set the backend to WebGPU:
|
||||
adb shell setprop debug.filament.backend 4
|
||||
# to view the current property:
|
||||
adb shell getprop debug.filament.backend
|
||||
```
|
||||
1. Build and run a sample, e.g. sample-gltf-viewer, on your Android device
|
||||
_([Android Studio](https://developer.android.com/studio) recommended)_.
|
||||
1. Run [AGI](https://developer.android.com/agi) and follow instructions to profile the app/system
|
||||
with trace capture(s). See https://developer.android.com/agi/start for more details to
|
||||
get started.
|
||||
- We typically only run "Capture System Profiler trace" _(not necessarily "Capture Frame Profiler trace")_
|
||||
- When configuring the trace:
|
||||
- For both the WebGPU and Vulkan backends configure the profiler for the Vulkan API
|
||||
_(since WebGPU should be using Vulkan under the hood as well)_
|
||||
- Running for ~1 seconds should suffice
|
||||
- Hit the "Configure" button in Trace objects, select "Switch to advanced mode" and add:
|
||||
```
|
||||
data_sources {
|
||||
config {
|
||||
name: "track_event"
|
||||
track_event_config {
|
||||
disabled_categories: "*"
|
||||
enabled_categories: "filament/filament"
|
||||
enabled_categories: "filament/jobsystem"
|
||||
enabled_categories: "filament/gltfio"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
- One you open the trace, zoom into a series of frames to get a sense of generally how long they typically take
|
||||
_(use `W`, `S`, `A` and `D` keys and mouse wheel for navigation)_ and find a representative one.
|
||||
We are most interested in the performance of the
|
||||
`FEngine::loop` thread, how long it takes, overlap in activities/processes/commands, reduction in queue submissions,
|
||||
etc. Similarly, we can view GPU timeline as it relates to that. We want to see overlapping
|
||||
shader invocations and non-interrupted fragment shader runs.
|
||||
@@ -1,4 +0,0 @@
|
||||
# Tests
|
||||
|
||||
Filament has a collection of tests that can be run locally. Many of them are used
|
||||
for in our Continuation Integration flow [on github](https://https://github.com/google/filament/tree/main/.github/workflows).
|
||||
@@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Redirecting...</title>
|
||||
<meta http-equiv="refresh" content="0; url=./dup/intro.html">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -40,7 +40,6 @@ set(PUBLIC_HDRS
|
||||
include/filament/Skybox.h
|
||||
include/filament/Stream.h
|
||||
include/filament/SwapChain.h
|
||||
include/filament/Sync.h
|
||||
include/filament/Texture.h
|
||||
include/filament/TextureSampler.h
|
||||
include/filament/ToneMapper.h
|
||||
@@ -84,8 +83,6 @@ set(SRCS
|
||||
src/InstanceBuffer.cpp
|
||||
src/LightManager.cpp
|
||||
src/Material.cpp
|
||||
src/MaterialCache.cpp
|
||||
src/MaterialDefinition.cpp
|
||||
src/MaterialInstance.cpp
|
||||
src/MaterialInstanceManager.cpp
|
||||
src/MaterialParser.cpp
|
||||
@@ -106,7 +103,6 @@ set(SRCS
|
||||
src/Skybox.cpp
|
||||
src/Stream.cpp
|
||||
src/SwapChain.cpp
|
||||
src/Sync.cpp
|
||||
src/Texture.cpp
|
||||
src/ToneMapper.cpp
|
||||
src/TransformManager.cpp
|
||||
@@ -136,7 +132,6 @@ set(SRCS
|
||||
src/details/Skybox.cpp
|
||||
src/details/Stream.cpp
|
||||
src/details/SwapChain.cpp
|
||||
src/details/Sync.cpp
|
||||
src/details/Texture.cpp
|
||||
src/details/VertexBuffer.cpp
|
||||
src/details/View.cpp
|
||||
@@ -177,8 +172,6 @@ set(PRIVATE_HDRS
|
||||
src/HwRenderPrimitiveFactory.h
|
||||
src/HwVertexBufferInfoFactory.h
|
||||
src/Intersections.h
|
||||
src/MaterialCache.h
|
||||
src/MaterialDefinition.h
|
||||
src/MaterialParser.h
|
||||
src/MaterialInstanceManager.h
|
||||
src/PIDController.h
|
||||
|
||||
@@ -78,8 +78,6 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3)
|
||||
src/opengl/GLTexture.h
|
||||
src/opengl/GLUtils.cpp
|
||||
src/opengl/GLUtils.h
|
||||
src/opengl/GLMemoryMappedBuffer.cpp
|
||||
src/opengl/GLMemoryMappedBuffer.h
|
||||
src/opengl/OpenGLBlobCache.cpp
|
||||
src/opengl/OpenGLBlobCache.h
|
||||
src/opengl/OpenGLContext.cpp
|
||||
@@ -179,7 +177,6 @@ endif()
|
||||
if (FILAMENT_SUPPORTS_VULKAN)
|
||||
list(APPEND SRCS
|
||||
include/backend/platforms/VulkanPlatform.h
|
||||
src/vulkan/VulkanAsyncHandles.cpp
|
||||
src/vulkan/VulkanAsyncHandles.h
|
||||
src/vulkan/VulkanBlitter.cpp
|
||||
src/vulkan/VulkanBlitter.h
|
||||
@@ -218,10 +215,6 @@ if (FILAMENT_SUPPORTS_VULKAN)
|
||||
src/vulkan/VulkanReadPixels.h
|
||||
src/vulkan/VulkanSamplerCache.cpp
|
||||
src/vulkan/VulkanSamplerCache.h
|
||||
src/vulkan/VulkanSemaphore.cpp
|
||||
src/vulkan/VulkanSemaphore.h
|
||||
src/vulkan/VulkanSemaphoreManager.cpp
|
||||
src/vulkan/VulkanSemaphoreManager.h
|
||||
src/vulkan/VulkanStagePool.cpp
|
||||
src/vulkan/VulkanStagePool.h
|
||||
src/vulkan/VulkanSwapChain.cpp
|
||||
@@ -265,8 +258,6 @@ if (FILAMENT_SUPPORTS_WEBGPU)
|
||||
include/backend/platforms/WebGPUPlatform.h
|
||||
src/webgpu/platform/WebGPUPlatform.cpp
|
||||
src/webgpu/SpdMipmapGenerator/SpdMipmapGenerator.cpp
|
||||
src/webgpu/utils/AsyncTaskCounter.cpp
|
||||
src/webgpu/utils/AsyncTaskCounter.h
|
||||
src/webgpu/utils/StringPlaceholderTemplateProcessor.cpp
|
||||
src/webgpu/utils/StringPlaceholderTemplateProcessor.h
|
||||
src/webgpu/WebGPUBlitter.cpp
|
||||
@@ -302,7 +293,6 @@ if (FILAMENT_SUPPORTS_WEBGPU)
|
||||
src/webgpu/WebGPUStrings.h
|
||||
src/webgpu/WebGPUSwapChain.cpp
|
||||
src/webgpu/WebGPUSwapChain.h
|
||||
src/webgpu/WebGPUSync.h
|
||||
src/webgpu/WebGPUTexture.cpp
|
||||
src/webgpu/WebGPUTexture.h
|
||||
src/webgpu/WebGPUTextureHelpers.h
|
||||
@@ -422,7 +412,6 @@ endif()
|
||||
|
||||
if (APPLE AND NOT IOS)
|
||||
target_link_libraries(${TARGET} PRIVATE "-framework Cocoa")
|
||||
target_link_libraries(${TARGET} PRIVATE "-framework QuartzCore")
|
||||
endif()
|
||||
|
||||
target_link_libraries(${TARGET} PUBLIC math)
|
||||
@@ -502,6 +491,9 @@ else()
|
||||
-Wover-aligned -Wreorder-init-list
|
||||
-Werror
|
||||
)
|
||||
if (CMAKE_CXX_STANDARD EQUAL 20)
|
||||
list(APPEND FILAMENT_WARNINGS -Wno-deprecated-this-capture)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
@@ -535,7 +527,7 @@ target_link_libraries(${TARGET} PRIVATE
|
||||
if (LINUX AND FILAMENT_SUPPORTS_WEBGPU)
|
||||
# Unclear why this needs to be explicit while other linux libs do not, but it is necessary for
|
||||
# WebGPU to build on linux.
|
||||
target_link_libraries(${TARGET} PRIVATE -lxcb -lX11)
|
||||
target_link_libraries(${TARGET} PRIVATE -lxcb)
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
@@ -573,7 +565,6 @@ if (APPLE OR LINUX)
|
||||
test/test_ReadPixels.cpp
|
||||
test/test_BufferUpdates.cpp
|
||||
test/test_Callbacks.cpp
|
||||
test/test_MemoryMappedBuffer.cpp
|
||||
test/test_MRT.cpp
|
||||
test/test_PushConstants.cpp
|
||||
test/test_LoadImage.cpp
|
||||
@@ -585,11 +576,6 @@ if (APPLE OR LINUX)
|
||||
test/test_CommandBufferQueue.cpp
|
||||
test/test_Template.cpp
|
||||
)
|
||||
if (FILAMENT_SUPPORTS_WEBGPU)
|
||||
list(APPEND BACKEND_TEST_SRC
|
||||
test/test_WebGPUAsyncTaskCounter.cpp
|
||||
test/test_WebGPUComposeSwizzle.cpp)
|
||||
endif()
|
||||
if (APPLE)
|
||||
# Metal-specific tests
|
||||
list(APPEND BACKEND_TEST_SRC
|
||||
@@ -607,7 +593,6 @@ if (APPLE OR LINUX)
|
||||
spirv-cross-glsl)
|
||||
# Create input/output directories for test result images.
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/images/actual_images)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/images/diff_images)
|
||||
file(COPY test/expected_images DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/images)
|
||||
endif()
|
||||
|
||||
@@ -637,10 +622,6 @@ if (APPLE AND NOT IOS)
|
||||
target_link_libraries(backend_test PRIVATE image imageio)
|
||||
list(APPEND BACKEND_TEST_DEPS image)
|
||||
endif()
|
||||
if (FILAMENT_SUPPORTS_WEBGPU)
|
||||
target_link_libraries(backend_test PRIVATE webgpu_dawn dawncpp_headers)
|
||||
list(APPEND BACKEND_TEST_DEPS webgpu_dawn dawncpp_headers)
|
||||
endif()
|
||||
|
||||
set(BACKEND_TEST_COMBINED_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libbackendtest_combined.a")
|
||||
combine_static_libs(backend_test "${BACKEND_TEST_COMBINED_OUTPUT}" "${BACKEND_TEST_DEPS}")
|
||||
@@ -672,9 +653,6 @@ if (LINUX)
|
||||
add_executable(backend_test_linux test/linux_runner.cpp ${BACKEND_TEST_SRC})
|
||||
target_link_libraries(backend_test_linux PRIVATE ${BACKEND_TEST_LIBS})
|
||||
set_target_properties(backend_test_linux PROPERTIES FOLDER Tests)
|
||||
if (FILAMENT_SUPPORTS_WEBGPU)
|
||||
target_link_libraries(backend_test_linux PRIVATE webgpu_dawn dawncpp_headers)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
@@ -101,16 +101,6 @@ static constexpr uint64_t SWAP_CHAIN_HAS_STENCIL_BUFFER = SWAP_CHAIN_CON
|
||||
*/
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_PROTECTED_CONTENT = 0x40;
|
||||
|
||||
/**
|
||||
* Indicates that the SwapChain is configured to use Multi-Sample Anti-Aliasing (MSAA) with the
|
||||
* given sample points within each pixel. Only supported when isMSAASwapChainSupported(4) is
|
||||
* true.
|
||||
*
|
||||
* This is only supported by EGL(Android). Other GL platforms (GLX, WGL, etc) don't support it
|
||||
* because the swapchain MSAA settings must be configured before window creation.
|
||||
*/
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_MSAA_4_SAMPLES = 0x80;
|
||||
|
||||
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_SAMPLER_COUNT = 62; // Maximum needed at feature level 3.
|
||||
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
|
||||
@@ -197,7 +187,6 @@ constexpr std::string_view to_string(Backend const backend) noexcept {
|
||||
* - The Metal backend can prefer precompiled Metal libraries, while falling back to MSL.
|
||||
*/
|
||||
enum class ShaderLanguage {
|
||||
UNSPECIFIED = -1,
|
||||
ESSL1 = 0,
|
||||
ESSL3 = 1,
|
||||
SPIRV = 2,
|
||||
@@ -220,8 +209,6 @@ constexpr const char* shaderLanguageToString(ShaderLanguage shaderLanguage) noex
|
||||
return "Metal precompiled library";
|
||||
case ShaderLanguage::WGSL:
|
||||
return "WGSL";
|
||||
case ShaderLanguage::UNSPECIFIED:
|
||||
return "Unspecified";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
@@ -559,21 +546,12 @@ constexpr TargetBufferFlags getTargetBufferFlagsAt(size_t index) noexcept {
|
||||
}
|
||||
|
||||
/**
|
||||
* How the buffer will be used.
|
||||
* Frequency at which a buffer is expected to be modified and used. This is used as an hint
|
||||
* for the driver to make better decisions about managing memory internally.
|
||||
*/
|
||||
enum class BufferUsage : uint8_t {
|
||||
STATIC = 0, //!< (legacy) content modified once, used many times
|
||||
DYNAMIC = 1, //!< (legacy) content modified frequently, used many times
|
||||
DYNAMIC_BIT = 0x1, //!< buffer can be modified frequently, used many times
|
||||
SHARED_WRITE_BIT = 0x04, //!< buffer can be memory mapped for write operations
|
||||
};
|
||||
|
||||
/**
|
||||
* How the buffer will be mapped.
|
||||
*/
|
||||
enum class MapBufferAccessFlags : uint8_t {
|
||||
WRITE_BIT = 0x2, //!< buffer is mapped from writing
|
||||
INVALIDATE_RANGE_BIT = 0x4, //!< the mapped range content is lost
|
||||
STATIC, //!< content modified once, used many times
|
||||
DYNAMIC, //!< content modified frequently, used many times
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -639,15 +617,6 @@ enum class ShaderModel : uint8_t {
|
||||
};
|
||||
static constexpr size_t SHADER_MODEL_COUNT = 2;
|
||||
|
||||
constexpr std::string_view to_string(ShaderModel model) noexcept {
|
||||
switch (model) {
|
||||
case ShaderModel::MOBILE:
|
||||
return "mobile";
|
||||
case ShaderModel::DESKTOP:
|
||||
return "desktop";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Primitive types
|
||||
*/
|
||||
@@ -660,18 +629,6 @@ enum class PrimitiveType : uint8_t {
|
||||
TRIANGLE_STRIP = 5 //!< triangle strip
|
||||
};
|
||||
|
||||
[[nodiscard]] constexpr bool isStripPrimitiveType(const PrimitiveType type) {
|
||||
switch (type) {
|
||||
case PrimitiveType::POINTS:
|
||||
case PrimitiveType::LINES:
|
||||
case PrimitiveType::TRIANGLES:
|
||||
return false;
|
||||
case PrimitiveType::LINE_STRIP:
|
||||
case PrimitiveType::TRIANGLE_STRIP:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported uniform types
|
||||
*/
|
||||
@@ -1713,11 +1670,6 @@ template<> struct utils::EnableBitMaskOperators<filament::backend::TextureUsage>
|
||||
: public std::true_type {};
|
||||
template<> struct utils::EnableBitMaskOperators<filament::backend::StencilFace>
|
||||
: public std::true_type {};
|
||||
template<> struct utils::EnableBitMaskOperators<filament::backend::BufferUsage>
|
||||
: public std::true_type {};
|
||||
template<> struct utils::EnableBitMaskOperators<filament::backend::MapBufferAccessFlags>
|
||||
: public std::true_type {};
|
||||
|
||||
template<> struct utils::EnableIntegerOperators<filament::backend::TextureCubemapFace>
|
||||
: public std::true_type {};
|
||||
template<> struct utils::EnableIntegerOperators<filament::backend::FeatureLevel>
|
||||
|
||||
@@ -38,14 +38,12 @@ struct HwRenderPrimitive;
|
||||
struct HwRenderTarget;
|
||||
struct HwStream;
|
||||
struct HwSwapChain;
|
||||
struct HwSync;
|
||||
struct HwTexture;
|
||||
struct HwTimerQuery;
|
||||
struct HwVertexBufferInfo;
|
||||
struct HwVertexBuffer;
|
||||
struct HwDescriptorSetLayout;
|
||||
struct HwDescriptorSet;
|
||||
struct HwMemoryMappedBuffer;
|
||||
|
||||
/*
|
||||
* A handle to a backend resource. HandleBase is for internal use only.
|
||||
@@ -153,14 +151,12 @@ using RenderPrimitiveHandle = Handle<HwRenderPrimitive>;
|
||||
using RenderTargetHandle = Handle<HwRenderTarget>;
|
||||
using StreamHandle = Handle<HwStream>;
|
||||
using SwapChainHandle = Handle<HwSwapChain>;
|
||||
using SyncHandle = Handle<HwSync>;
|
||||
using TextureHandle = Handle<HwTexture>;
|
||||
using TimerQueryHandle = Handle<HwTimerQuery>;
|
||||
using VertexBufferHandle = Handle<HwVertexBuffer>;
|
||||
using VertexBufferInfoHandle = Handle<HwVertexBufferInfo>;
|
||||
using DescriptorSetLayoutHandle = Handle<HwDescriptorSetLayout>;
|
||||
using DescriptorSetHandle = Handle<HwDescriptorSet>;
|
||||
using MemoryMappedBufferHandle = Handle<HwMemoryMappedBuffer>;
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class CallbackHandler;
|
||||
class Driver;
|
||||
|
||||
/**
|
||||
@@ -43,9 +42,6 @@ public:
|
||||
struct SwapChain {};
|
||||
struct Fence {};
|
||||
struct Stream {};
|
||||
struct Sync {};
|
||||
|
||||
using SyncCallback = void(*)(Sync* UTILS_NONNULL sync, void* UTILS_NULLABLE userData);
|
||||
|
||||
class ExternalImageHandle;
|
||||
|
||||
@@ -160,7 +156,7 @@ public:
|
||||
* Set to `true` to forcibly disable amortized shader compilation in the backend.
|
||||
* Currently only honored by the GL backend.
|
||||
*/
|
||||
bool disableAmortizedShaderCompile = true;
|
||||
bool disableAmortizedShaderCompile = false;
|
||||
|
||||
/**
|
||||
* Disable backend handles use-after-free checks.
|
||||
|
||||
@@ -27,12 +27,12 @@ namespace filament::backend {
|
||||
* A PresentCallable is a callable object that, when called, schedules a frame for presentation on
|
||||
* a SwapChain.
|
||||
*
|
||||
* Typically, Filament's backend is responsible for scheduling a frame's presentation. However,
|
||||
* there are certain cases where the application might want to control when a frame is scheduled for
|
||||
* Typically, Filament's backend is responsible scheduling a frame's presentation. However, there
|
||||
* are certain cases where the application might want to control when a frame is scheduled for
|
||||
* presentation.
|
||||
*
|
||||
* For example, on iOS, UIKit elements can be synchronized to 3D content by scheduling a present
|
||||
* within a CATransaction:
|
||||
* within a CATransation:
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* void myFrameScheduledCallback(PresentCallable presentCallable, void* user) {
|
||||
@@ -55,13 +55,12 @@ namespace filament::backend {
|
||||
* }
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* @remark The PresentCallable mechanism for user-controlled presentation is only supported by
|
||||
* Filament's Metal backend. On other backends, the FrameScheduledCallback is still invoked, but the
|
||||
* PresentCallable passed to it is a no-op and calling it has no effect.
|
||||
* @remark Only Filament's Metal backend supports PresentCallables and frame callbacks. Other
|
||||
* backends ignore the callback (which will never be called) and proceed normally.
|
||||
*
|
||||
* When using the Metal backend, applications *must* call each PresentCallable they receive. Each
|
||||
* PresentCallable represents a frame that is waiting to be presented, and failing to call it
|
||||
* will result in a memory leak. To "cancel" the presentation of a frame, pass false to the
|
||||
* Applications *must* call each PresentCallable they receive. Each PresentCallable represents a
|
||||
* frame that is waiting to be presented. If an application fails to call a PresentCallable, a
|
||||
* memory leak could occur. To "cancel" the presentation of a frame, pass false to the
|
||||
* PresentCallable, which will cancel the presentation of the frame and release associated memory.
|
||||
*
|
||||
* @see Renderer, SwapChain::setFrameScheduledCallback
|
||||
@@ -70,7 +69,6 @@ class UTILS_PUBLIC PresentCallable {
|
||||
public:
|
||||
|
||||
using PresentFn = void(*)(bool presentFrame, void* user);
|
||||
static void noopPresent(bool, void*) {}
|
||||
|
||||
PresentCallable(PresentFn fn, void* user) noexcept;
|
||||
~PresentCallable() noexcept = default;
|
||||
|
||||
@@ -85,15 +85,6 @@ public:
|
||||
*/
|
||||
virtual bool isSRGBSwapChainSupported() const noexcept;
|
||||
|
||||
/**
|
||||
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_MSAA_*_SAMPLES flag.
|
||||
* The default implementation returns false.
|
||||
*
|
||||
* @param samples The number of samples
|
||||
* @return true if SWAP_CHAIN_CONFIG_MSAA_*_SAMPLES is supported, false otherwise.
|
||||
*/
|
||||
virtual bool isMSAASwapChainSupported(uint32_t samples) const noexcept;
|
||||
|
||||
/**
|
||||
* Return whether protected contexts are supported by this backend.
|
||||
* If protected context are supported, the SWAP_CHAIN_CONFIG_PROTECTED_CONTENT flag can be
|
||||
@@ -285,26 +276,6 @@ public:
|
||||
*/
|
||||
virtual backend::FenceStatus waitFence(Fence* UTILS_NONNULL fence, uint64_t timeout) noexcept;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Sync support
|
||||
|
||||
/**
|
||||
* Creates a Sync. These can be used for frame synchronization externally
|
||||
* (certain platform implementations can be exported to handles that can
|
||||
* be used in other processes).
|
||||
*
|
||||
* @return A Sync object.
|
||||
*/
|
||||
virtual Platform::Sync* UTILS_NONNULL createSync() noexcept;
|
||||
|
||||
/**
|
||||
* Destroys a sync. If called with a sync not created by this platform
|
||||
* object, this will lead to undefined behavior.
|
||||
*
|
||||
* @param sync The sync to destroy, that was created by this platform
|
||||
* instance.
|
||||
*/
|
||||
virtual void destroySync(Platform::Sync* UTILS_NONNULL sync) noexcept;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Streaming support
|
||||
|
||||
@@ -98,9 +98,8 @@ protected:
|
||||
void terminate() noexcept override;
|
||||
|
||||
bool isProtectedContextSupported() const noexcept override;
|
||||
bool isSRGBSwapChainSupported() const noexcept override;
|
||||
bool isMSAASwapChainSupported(uint32_t samples) const noexcept override;
|
||||
|
||||
bool isSRGBSwapChainSupported() const noexcept override;
|
||||
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
|
||||
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
|
||||
void destroySwapChain(SwapChain* swapChain) noexcept override;
|
||||
@@ -168,7 +167,6 @@ protected:
|
||||
EGLConfig mEGLConfig = EGL_NO_CONFIG_KHR;
|
||||
Config mContextAttribs;
|
||||
std::vector<EGLContext> mAdditionalContexts;
|
||||
bool mMSAA4XSupport = false;
|
||||
|
||||
// supported extensions detected at runtime
|
||||
struct {
|
||||
@@ -219,8 +217,6 @@ private:
|
||||
return makeCurrent(mCurrentContext, drawSurface, readSurface);
|
||||
}
|
||||
} egl{ mEGLDisplay };
|
||||
|
||||
bool checkIfMSAASwapChainSupported(uint32_t samples) const noexcept;
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -58,17 +58,6 @@ public:
|
||||
|
||||
ExternalImageDescAndroid UTILS_PUBLIC getExternalImageDesc(ExternalImageHandle externalImage) noexcept;
|
||||
|
||||
/**
|
||||
* Converts a sync to an external file descriptor, if possible. Accepts an
|
||||
* opaque handle to a sync, as well as a pointer to where the fd should be
|
||||
* stored.
|
||||
* @param sync The sync to be converted to a file descriptor.
|
||||
* @param fd A pointer to where the file descriptor should be stored.
|
||||
* @return `true` on success, `false` on failure. The default implementation
|
||||
* returns `false`.
|
||||
*/
|
||||
bool convertSyncToFd(Platform::Sync* sync, int* fd) noexcept;
|
||||
|
||||
protected:
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Platform Interface
|
||||
@@ -85,10 +74,6 @@ protected:
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// OpenGLPlatform Interface
|
||||
|
||||
struct SyncEGLAndroid : public Platform::Sync {
|
||||
EGLSyncKHR sync;
|
||||
};
|
||||
|
||||
void terminate() noexcept override;
|
||||
|
||||
void beginFrame(
|
||||
@@ -104,10 +89,9 @@ protected:
|
||||
*/
|
||||
void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept override;
|
||||
|
||||
|
||||
Stream* createStream(void* nativeStream) noexcept override;
|
||||
void destroyStream(Stream* stream) noexcept override;
|
||||
Platform::Sync* createSync() noexcept override;
|
||||
void destroySync(Platform::Sync* sync) noexcept override;
|
||||
void attach(Stream* stream, intptr_t tname) noexcept override;
|
||||
void detach(Stream* stream) noexcept override;
|
||||
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept override;
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
#ifndef TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H
|
||||
#define TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H
|
||||
|
||||
#include <backend/CallbackHandler.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Platform.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
#include <bluevk/BlueVK.h>
|
||||
|
||||
@@ -30,9 +29,9 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <unordered_set>
|
||||
#include <string>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@@ -46,10 +45,6 @@ using SwapChain = Platform::SwapChain;
|
||||
*/
|
||||
struct VulkanPlatformPrivate;
|
||||
|
||||
// Forward declare the fence status that will be maintained by the command
|
||||
// buffer manager.
|
||||
struct VulkanCmdFence;
|
||||
|
||||
/**
|
||||
* A Platform interface that creates a Vulkan backend.
|
||||
*/
|
||||
@@ -234,25 +229,6 @@ public:
|
||||
virtual SwapChainPtr createSwapChain(void* nativeWindow, uint64_t flags = 0,
|
||||
VkExtent2D extent = {0, 0});
|
||||
|
||||
/**
|
||||
* Creates a Platform::Sync object, which tracks a fence and its status,
|
||||
* and allows conversion to an external sync.
|
||||
* @param fence The underlying VkFence to use for synchronization.
|
||||
* @param fenceStatus An object tracking the fence's state
|
||||
* @return A Platform::Sync object tracking the provided fence.
|
||||
*/
|
||||
virtual Platform::Sync* createSync(VkFence fence,
|
||||
std::shared_ptr<VulkanCmdFence> fenceStatus) noexcept;
|
||||
|
||||
/**
|
||||
* Destroys a sync. If called with a sync not created by this platform
|
||||
* object, this will lead to undefined behavior.
|
||||
*
|
||||
* @param sync The sync to destroy, which was created by this platform
|
||||
* instance.
|
||||
*/
|
||||
virtual void destroySync(Platform::Sync* sync) noexcept;
|
||||
|
||||
/**
|
||||
* Allows implementers to provide instance extensions that they'd like to include in the
|
||||
* instance creation.
|
||||
@@ -432,19 +408,12 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
struct VulkanSync : public Platform::Sync {
|
||||
VkFence fence;
|
||||
std::shared_ptr<VulkanCmdFence> fenceStatus;
|
||||
};
|
||||
|
||||
virtual ExtensionSet getSwapchainInstanceExtensions() const;
|
||||
|
||||
using SurfaceBundle = std::tuple<VkSurfaceKHR, VkExtent2D>;
|
||||
virtual SurfaceBundle createVkSurfaceKHR(void* nativeWindow, VkInstance instance,
|
||||
uint64_t flags) const noexcept;
|
||||
|
||||
virtual VkExternalFenceHandleTypeFlagBits getFenceExportFlags() const noexcept;
|
||||
|
||||
private:
|
||||
// Platform dependent helper methods
|
||||
static ExtensionSet getSwapchainInstanceExtensionsImpl();
|
||||
|
||||
@@ -44,17 +44,6 @@ public:
|
||||
|
||||
virtual ImageData createVkImageFromExternal(ExternalImageHandleRef image) const override;
|
||||
|
||||
/**
|
||||
* Converts a sync to an external file descriptor, if possible. Accepts an
|
||||
* opaque handle to a sync, as well as a pointer to where the fd should be
|
||||
* stored.
|
||||
* @param sync The sync to be converted to a file descriptor.
|
||||
* @param fd A pointer to where the file descriptor should be stored.
|
||||
* @return `true` on success, `false` on failure. The default implementation
|
||||
* returns `false`.
|
||||
*/
|
||||
bool convertSyncToFd(Platform::Sync* sync, int* fd) const noexcept;
|
||||
|
||||
protected:
|
||||
virtual ExtensionSet getSwapchainInstanceExtensions() const override;
|
||||
|
||||
@@ -62,8 +51,6 @@ protected:
|
||||
virtual SurfaceBundle createVkSurfaceKHR(void* nativeWindow, VkInstance instance,
|
||||
uint64_t flags) const noexcept override;
|
||||
|
||||
virtual VkExternalFenceHandleTypeFlagBits getFenceExportFlags() const noexcept override;
|
||||
|
||||
private:
|
||||
struct ExternalImageVulkanAndroid : public Platform::ExternalImage {
|
||||
AHardwareBuffer* aHardwareBuffer = nullptr;
|
||||
|
||||
@@ -19,16 +19,6 @@
|
||||
|
||||
#include <backend/Platform.h>
|
||||
|
||||
#if defined(__linux__) && defined(FILAMENT_SUPPORTS_X11)
|
||||
// Resolve the conflicts between webgpu_cpp.h and X11 defines
|
||||
#undef Always
|
||||
#undef Success
|
||||
#undef None
|
||||
#undef True
|
||||
#undef False
|
||||
#undef Status
|
||||
#undef Bool
|
||||
#endif
|
||||
#include <webgpu/webgpu_cpp.h>
|
||||
|
||||
#include <cstdint>
|
||||
@@ -40,7 +30,7 @@ namespace filament::backend {
|
||||
* A Platform interface, handling the environment-specific concerns, e.g. OS, for creating a WebGPU
|
||||
* driver (backend).
|
||||
*/
|
||||
class WebGPUPlatform : public Platform {
|
||||
class WebGPUPlatform final : public Platform {
|
||||
public:
|
||||
WebGPUPlatform();
|
||||
~WebGPUPlatform() override = default;
|
||||
@@ -62,14 +52,6 @@ public:
|
||||
// either returns a valid device or panics
|
||||
[[nodiscard]] wgpu::Device requestDevice(wgpu::Adapter const& adapter);
|
||||
|
||||
struct Configuration {
|
||||
wgpu::BackendType forceBackendType = wgpu::BackendType::Undefined;
|
||||
};
|
||||
|
||||
[[nodiscard]] virtual Configuration getConfiguration() const noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
protected:
|
||||
[[nodiscard]] Driver* createDriver(void* sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <backend/AcquiredImage.h>
|
||||
|
||||
#include <utils/CString.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/compiler.h>
|
||||
|
||||
#include <functional>
|
||||
@@ -72,11 +71,7 @@ public:
|
||||
|
||||
virtual ShaderModel getShaderModel() const noexcept = 0;
|
||||
|
||||
// The shader languages used for shaders for this driver in order of preference, used to inform
|
||||
// matdbg.
|
||||
//
|
||||
// The `preferredLanguage` is only a hint. If the backend supports it, it will appear first in
|
||||
// the list.
|
||||
// The shader language used for shaders for this driver, used to inform matdbg.
|
||||
//
|
||||
// For OpenGL, this distinguishes whether the driver's shaders are powered by ESSL1 or ESSL3.
|
||||
// This information is used by matdbg to display the correct shader code to the web UI and patch
|
||||
@@ -84,8 +79,7 @@ public:
|
||||
//
|
||||
// Metal shaders can either be MSL or Metal libraries, but at time of writing, matdbg can only
|
||||
// interface with MSL.
|
||||
virtual utils::FixedCapacityVector<ShaderLanguage> getShaderLanguages(
|
||||
ShaderLanguage preferredLanguage) const noexcept = 0;
|
||||
virtual ShaderLanguage getShaderLanguage() const noexcept = 0;
|
||||
|
||||
// Returns the dispatcher. This is only called once during initialization of the CommandStream,
|
||||
// so it doesn't matter that it's virtual.
|
||||
|
||||
@@ -107,17 +107,9 @@
|
||||
#define DECL_DRIVER_API_R_N(R, N, ...) \
|
||||
DECL_DRIVER_API_RETURN(R, N, PAIR_ARGS_N(ARG, ##__VA_ARGS__), PAIR_ARGS_N(PARAM, ##__VA_ARGS__))
|
||||
|
||||
#define DECL_DRIVER_API_TAGGED_R_N(R, N, ...) \
|
||||
DECL_DRIVER_API_RETURN(R, N, PAIR_ARGS_N(ARG, ##__VA_ARGS__, utils::CString&&, tag = {}), \
|
||||
PAIR_ARGS_N(PARAM, ##__VA_ARGS__, utils::CString&&, tag))
|
||||
|
||||
#define DECL_DRIVER_API_SYNCHRONOUS_N(R, N, ...) \
|
||||
DECL_DRIVER_API_SYNCHRONOUS(R, N, PAIR_ARGS_N(ARG, ##__VA_ARGS__), PAIR_ARGS_N(PARAM, ##__VA_ARGS__))
|
||||
|
||||
#define DECL_DRIVER_API_SYNCHRONOUS_TAGGED_N(R, N, ...) \
|
||||
DECL_DRIVER_API_SYNCHRONOUS(R, N, PAIR_ARGS_N(ARG, ##__VA_ARGS__, utils::CString, tag = {}), \
|
||||
PAIR_ARGS_N(PARAM, ##__VA_ARGS__, utils::CString, tag))
|
||||
|
||||
// on some compilers the ##__VA_ARGS__ hack is not supported, so we can't handle 0-parameter APIs
|
||||
// with DECL_DRIVER_API_SYNCHRONOUS_N
|
||||
#define DECL_DRIVER_API_SYNCHRONOUS_0(R, N) \
|
||||
@@ -173,31 +165,35 @@ DECL_DRIVER_API_0(finish)
|
||||
// reset state tracking, if the driver does any state tracking (e.g. GL)
|
||||
DECL_DRIVER_API_0(resetState)
|
||||
|
||||
DECL_DRIVER_API_N(setDebugTag,
|
||||
backend::HandleBase::HandleId, handleId,
|
||||
utils::CString, tag)
|
||||
|
||||
/*
|
||||
* Creating driver objects
|
||||
* -----------------------
|
||||
*/
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::VertexBufferInfoHandle, createVertexBufferInfo,
|
||||
DECL_DRIVER_API_R_N(backend::VertexBufferInfoHandle, createVertexBufferInfo,
|
||||
uint8_t, bufferCount,
|
||||
uint8_t, attributeCount,
|
||||
backend::AttributeArray, attributes)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::VertexBufferHandle, createVertexBuffer,
|
||||
DECL_DRIVER_API_R_N(backend::VertexBufferHandle, createVertexBuffer,
|
||||
uint32_t, vertexCount,
|
||||
backend::VertexBufferInfoHandle, vbih)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::IndexBufferHandle, createIndexBuffer,
|
||||
DECL_DRIVER_API_R_N(backend::IndexBufferHandle, createIndexBuffer,
|
||||
backend::ElementType, elementType,
|
||||
uint32_t, indexCount,
|
||||
backend::BufferUsage, usage)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::BufferObjectHandle, createBufferObject,
|
||||
DECL_DRIVER_API_R_N(backend::BufferObjectHandle, createBufferObject,
|
||||
uint32_t, byteCount,
|
||||
backend::BufferObjectBinding, bindingType,
|
||||
backend::BufferUsage, usage)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTexture,
|
||||
DECL_DRIVER_API_R_N(backend::TextureHandle, createTexture,
|
||||
backend::SamplerType, target,
|
||||
uint8_t, levels,
|
||||
backend::TextureFormat, format,
|
||||
@@ -207,19 +203,19 @@ DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTexture,
|
||||
uint32_t, depth,
|
||||
backend::TextureUsage, usage)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureView,
|
||||
DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureView,
|
||||
backend::TextureHandle, texture,
|
||||
uint8_t, baseLevel,
|
||||
uint8_t, levelCount)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureViewSwizzle,
|
||||
DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureViewSwizzle,
|
||||
backend::TextureHandle, texture,
|
||||
backend::TextureSwizzle, r,
|
||||
backend::TextureSwizzle, g,
|
||||
backend::TextureSwizzle, b,
|
||||
backend::TextureSwizzle, a)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureExternalImage2,
|
||||
DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureExternalImage2,
|
||||
backend::SamplerType, target,
|
||||
backend::TextureFormat, format,
|
||||
uint32_t, width,
|
||||
@@ -227,7 +223,7 @@ DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureExternalImage2,
|
||||
backend::TextureUsage, usage,
|
||||
backend::Platform::ExternalImageHandleRef, image)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureExternalImage,
|
||||
DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureExternalImage,
|
||||
backend::SamplerType, target,
|
||||
backend::TextureFormat, format,
|
||||
uint32_t, width,
|
||||
@@ -235,7 +231,7 @@ DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureExternalImage,
|
||||
backend::TextureUsage, usage,
|
||||
void*, image)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureExternalImagePlane,
|
||||
DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureExternalImagePlane,
|
||||
backend::TextureFormat, format,
|
||||
uint32_t, width,
|
||||
uint32_t, height,
|
||||
@@ -243,7 +239,7 @@ DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureExternalImagePla
|
||||
void*, image,
|
||||
uint32_t, plane)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, importTexture,
|
||||
DECL_DRIVER_API_R_N(backend::TextureHandle, importTexture,
|
||||
intptr_t, id,
|
||||
backend::SamplerType, target,
|
||||
uint8_t, levels,
|
||||
@@ -254,17 +250,17 @@ DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, importTexture,
|
||||
uint32_t, depth,
|
||||
backend::TextureUsage, usage)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::RenderPrimitiveHandle, createRenderPrimitive,
|
||||
DECL_DRIVER_API_R_N(backend::RenderPrimitiveHandle, createRenderPrimitive,
|
||||
backend::VertexBufferHandle, vbh,
|
||||
backend::IndexBufferHandle, ibh,
|
||||
backend::PrimitiveType, pt)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::ProgramHandle, createProgram,
|
||||
DECL_DRIVER_API_R_N(backend::ProgramHandle, createProgram,
|
||||
backend::Program&&, program)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::RenderTargetHandle, createDefaultRenderTarget)
|
||||
DECL_DRIVER_API_R_0(backend::RenderTargetHandle, createDefaultRenderTarget)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::RenderTargetHandle, createRenderTarget,
|
||||
DECL_DRIVER_API_R_N(backend::RenderTargetHandle, createRenderTarget,
|
||||
backend::TargetBufferFlags, targetBufferFlags,
|
||||
uint32_t, width,
|
||||
uint32_t, height,
|
||||
@@ -274,32 +270,46 @@ DECL_DRIVER_API_TAGGED_R_N(backend::RenderTargetHandle, createRenderTarget,
|
||||
backend::TargetBufferInfo, depth,
|
||||
backend::TargetBufferInfo, stencil)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::FenceHandle, createFence)
|
||||
DECL_DRIVER_API_R_0(backend::FenceHandle, createFence)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::SyncHandle, createSync)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::SwapChainHandle, createSwapChain,
|
||||
DECL_DRIVER_API_R_N(backend::SwapChainHandle, createSwapChain,
|
||||
void*, nativeWindow,
|
||||
uint64_t, flags)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::SwapChainHandle, createSwapChainHeadless,
|
||||
DECL_DRIVER_API_R_N(backend::SwapChainHandle, createSwapChainHeadless,
|
||||
uint32_t, width,
|
||||
uint32_t, height,
|
||||
uint64_t, flags)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::TimerQueryHandle, createTimerQuery)
|
||||
DECL_DRIVER_API_R_0(backend::TimerQueryHandle, createTimerQuery)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::DescriptorSetLayoutHandle, createDescriptorSetLayout,
|
||||
DECL_DRIVER_API_R_N(backend::DescriptorSetLayoutHandle, createDescriptorSetLayout,
|
||||
backend::DescriptorSetLayout&&, info)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::DescriptorSetHandle, createDescriptorSet,
|
||||
DECL_DRIVER_API_R_N(backend::DescriptorSetHandle, createDescriptorSet,
|
||||
backend::DescriptorSetLayoutHandle, dslh)
|
||||
|
||||
DECL_DRIVER_API_TAGGED_R_N(backend::MemoryMappedBufferHandle, mapBuffer,
|
||||
DECL_DRIVER_API_N(updateDescriptorSetBuffer,
|
||||
backend::DescriptorSetHandle, dsh,
|
||||
backend::descriptor_binding_t, binding,
|
||||
backend::BufferObjectHandle, boh,
|
||||
size_t, offset,
|
||||
size_t, size,
|
||||
backend::MapBufferAccessFlags, access)
|
||||
uint32_t, offset,
|
||||
uint32_t, size
|
||||
)
|
||||
|
||||
DECL_DRIVER_API_N(updateDescriptorSetTexture,
|
||||
backend::DescriptorSetHandle, dsh,
|
||||
backend::descriptor_binding_t, binding,
|
||||
backend::TextureHandle, th,
|
||||
SamplerParams, params
|
||||
)
|
||||
|
||||
DECL_DRIVER_API_N(bindDescriptorSet,
|
||||
backend::DescriptorSetHandle, dsh,
|
||||
backend::descriptor_set_t, set,
|
||||
backend::DescriptorSetOffsetArray&&, offsets
|
||||
)
|
||||
|
||||
|
||||
/*
|
||||
* Destroying driver objects
|
||||
@@ -309,7 +319,7 @@ DECL_DRIVER_API_TAGGED_R_N(backend::MemoryMappedBufferHandle, mapBuffer,
|
||||
DECL_DRIVER_API_N(destroyVertexBuffer, backend::VertexBufferHandle, vbh)
|
||||
DECL_DRIVER_API_N(destroyVertexBufferInfo, backend::VertexBufferInfoHandle, vbih)
|
||||
DECL_DRIVER_API_N(destroyIndexBuffer, backend::IndexBufferHandle, ibh)
|
||||
DECL_DRIVER_API_N(destroyBufferObject, backend::BufferObjectHandle, boh)
|
||||
DECL_DRIVER_API_N(destroyBufferObject, backend::BufferObjectHandle, ibh)
|
||||
DECL_DRIVER_API_N(destroyRenderPrimitive, backend::RenderPrimitiveHandle, rph)
|
||||
DECL_DRIVER_API_N(destroyProgram, backend::ProgramHandle, ph)
|
||||
DECL_DRIVER_API_N(destroyTexture, backend::TextureHandle, th)
|
||||
@@ -318,10 +328,8 @@ DECL_DRIVER_API_N(destroySwapChain, backend::SwapChainHandle, sch)
|
||||
DECL_DRIVER_API_N(destroyStream, backend::StreamHandle, sh)
|
||||
DECL_DRIVER_API_N(destroyTimerQuery, backend::TimerQueryHandle, sh)
|
||||
DECL_DRIVER_API_N(destroyFence, backend::FenceHandle, fh)
|
||||
DECL_DRIVER_API_N(destroySync, backend::SyncHandle, sh)
|
||||
DECL_DRIVER_API_N(destroyDescriptorSetLayout, backend::DescriptorSetLayoutHandle, dslh)
|
||||
DECL_DRIVER_API_N(destroyDescriptorSet, backend::DescriptorSetHandle, dsh)
|
||||
DECL_DRIVER_API_N(unmapBuffer, backend::MemoryMappedBufferHandle, mmbh)
|
||||
|
||||
/*
|
||||
* Synchronous APIs
|
||||
@@ -329,16 +337,13 @@ DECL_DRIVER_API_N(unmapBuffer, backend::MemoryMappedBufferHandl
|
||||
*/
|
||||
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(void, terminate)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_TAGGED_N(backend::StreamHandle, createStreamNative, void*, stream)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_TAGGED_N(backend::StreamHandle, createStreamAcquired)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(backend::StreamHandle, createStreamNative, void*, stream)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(backend::StreamHandle, createStreamAcquired)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(void, setAcquiredImage, backend::StreamHandle, stream, void*, image, const math::mat3f&, transform, backend::CallbackHandler*, handler, backend::StreamCallback, cb, void*, userData)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(void, setStreamDimensions, backend::StreamHandle, stream, uint32_t, width, uint32_t, height)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(int64_t, getStreamTimestamp, backend::StreamHandle, stream)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(void, updateStreams, backend::DriverApi*, driver)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(backend::FenceStatus, getFenceStatus, backend::FenceHandle, fh)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(backend::FenceStatus, fenceWait, backend::FenceHandle, fh, uint64_t, timeout)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(void, getPlatformSync, backend::SyncHandle, sh,
|
||||
backend::CallbackHandler*, handler, backend::Platform::SyncCallback, cb, void*, userData)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isTextureFormatSupported, backend::TextureFormat, format)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isTextureSwizzleSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isTextureFormatMipmappable, backend::TextureFormat, format)
|
||||
@@ -348,7 +353,6 @@ DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchMultiSampleSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameTimeSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isAutoDepthResolveSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isSRGBSwapChainSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isMSAASwapChainSupported, uint32_t, samples)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isProtectedContentSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isStereoSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isParallelShaderCompileSupported)
|
||||
@@ -363,7 +367,7 @@ DECL_DRIVER_API_SYNCHRONOUS_0(size_t, getMaxArrayTextureLayers)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(math::float2, getClipSpaceParams)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(void, setupExternalImage2, backend::Platform::ExternalImageHandleRef, image)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(void, setupExternalImage, void*, image)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(backend::TimerQueryResult, getTimerQueryValue, backend::TimerQueryHandle, tqh, uint64_t*, elapsedTime)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(backend::TimerQueryResult, getTimerQueryValue, backend::TimerQueryHandle, query, uint64_t*, elapsedTime)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isWorkaroundNeeded, backend::Workaround, workaround)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(backend::FeatureLevel, getFeatureLevel)
|
||||
|
||||
@@ -388,16 +392,16 @@ DECL_DRIVER_API_N(updateBufferObject,
|
||||
uint32_t, byteOffset)
|
||||
|
||||
DECL_DRIVER_API_N(registerBufferObjectStreams,
|
||||
backend::BufferObjectHandle, boh,
|
||||
backend::BufferObjectHandle, ibh,
|
||||
backend::BufferObjectStreamDescriptor&&, streams)
|
||||
|
||||
DECL_DRIVER_API_N(updateBufferObjectUnsynchronized,
|
||||
backend::BufferObjectHandle, boh,
|
||||
backend::BufferObjectHandle, ibh,
|
||||
backend::BufferDescriptor&&, data,
|
||||
uint32_t, byteOffset)
|
||||
|
||||
DECL_DRIVER_API_N(resetBufferObject,
|
||||
backend::BufferObjectHandle, boh)
|
||||
backend::BufferObjectHandle, ibh)
|
||||
|
||||
DECL_DRIVER_API_N(update3DImage,
|
||||
backend::TextureHandle, th,
|
||||
@@ -426,10 +430,10 @@ DECL_DRIVER_API_0(endRenderPass)
|
||||
DECL_DRIVER_API_0(nextSubpass)
|
||||
|
||||
DECL_DRIVER_API_N(beginTimerQuery,
|
||||
backend::TimerQueryHandle, tqh)
|
||||
backend::TimerQueryHandle, query)
|
||||
|
||||
DECL_DRIVER_API_N(endTimerQuery,
|
||||
backend::TimerQueryHandle, tqh)
|
||||
backend::TimerQueryHandle, query)
|
||||
|
||||
DECL_DRIVER_API_N(compilePrograms,
|
||||
backend::CompilerPriorityQueue, priority,
|
||||
@@ -437,26 +441,6 @@ DECL_DRIVER_API_N(compilePrograms,
|
||||
backend::CallbackHandler::Callback, callback,
|
||||
void*, user)
|
||||
|
||||
DECL_DRIVER_API_N(updateDescriptorSetBuffer,
|
||||
backend::DescriptorSetHandle, dsh,
|
||||
backend::descriptor_binding_t, binding,
|
||||
backend::BufferObjectHandle, boh,
|
||||
uint32_t, offset,
|
||||
uint32_t, size
|
||||
)
|
||||
|
||||
DECL_DRIVER_API_N(updateDescriptorSetTexture,
|
||||
backend::DescriptorSetHandle, dsh,
|
||||
backend::descriptor_binding_t, binding,
|
||||
backend::TextureHandle, th,
|
||||
SamplerParams, params
|
||||
)
|
||||
|
||||
DECL_DRIVER_API_N(copyToMemoryMappedBuffer,
|
||||
backend::MemoryMappedBufferHandle, mmbh,
|
||||
size_t, offset,
|
||||
backend::BufferDescriptor&&, data)
|
||||
|
||||
/*
|
||||
* Swap chain
|
||||
*/
|
||||
@@ -545,12 +529,6 @@ DECL_DRIVER_API_N(bindPipeline,
|
||||
DECL_DRIVER_API_N(bindRenderPrimitive,
|
||||
backend::RenderPrimitiveHandle, rph)
|
||||
|
||||
DECL_DRIVER_API_N(bindDescriptorSet,
|
||||
backend::DescriptorSetHandle, dsh,
|
||||
backend::descriptor_set_t, set,
|
||||
backend::DescriptorSetOffsetArray&&, offsets
|
||||
)
|
||||
|
||||
DECL_DRIVER_API_N(draw2,
|
||||
uint32_t, indexOffset,
|
||||
uint32_t, indexCount,
|
||||
|
||||
@@ -249,9 +249,8 @@ public:
|
||||
}
|
||||
|
||||
void associateTagToHandle(HandleBase::HandleId id, utils::CString&& tag) noexcept {
|
||||
if (tag.empty()) {
|
||||
return;
|
||||
}
|
||||
// TODO: for now, only pool handles check for use-after-free, so we only keep tags for
|
||||
// those
|
||||
uint32_t key = id;
|
||||
if (UTILS_LIKELY(isPoolHandle(id))) {
|
||||
// Truncate the age to get the debug tag
|
||||
|
||||
@@ -18,16 +18,10 @@
|
||||
|
||||
#include "DataReshaper.h"
|
||||
|
||||
#include <backend/PixelBufferDescriptor.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
#include <utils/BitmaskEnum.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/CString.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <string_view>
|
||||
|
||||
namespace filament::backend {
|
||||
@@ -642,7 +636,7 @@ bool reshape(const PixelBufferDescriptor& data, PixelBufferDescriptor& reshaped)
|
||||
switch (data.type) {
|
||||
case PixelDataType::BYTE:
|
||||
case PixelDataType::UBYTE: {
|
||||
uint8_t* bytes = static_cast<uint8_t*>(malloc(reshapedSize));
|
||||
uint8_t* bytes = (uint8_t*) malloc(reshapedSize);
|
||||
DataReshaper::reshape<uint8_t, 3, 4>(bytes, data.buffer, data.size);
|
||||
PixelBufferDescriptor pbd(bytes, reshapedSize, reshapedFormat, data.type,
|
||||
data.alignment, data.left, data.top, data.stride, freeFunc);
|
||||
@@ -652,7 +646,7 @@ bool reshape(const PixelBufferDescriptor& data, PixelBufferDescriptor& reshaped)
|
||||
case PixelDataType::SHORT:
|
||||
case PixelDataType::USHORT:
|
||||
case PixelDataType::HALF: {
|
||||
uint8_t* bytes = static_cast<uint8_t*>(malloc(reshapedSize));
|
||||
uint8_t* bytes = (uint8_t*) malloc(reshapedSize);
|
||||
DataReshaper::reshape<uint16_t, 3, 4>(bytes, data.buffer, data.size);
|
||||
PixelBufferDescriptor pbd(bytes, reshapedSize, reshapedFormat, data.type,
|
||||
data.alignment, data.left, data.top, data.stride, freeFunc);
|
||||
@@ -661,7 +655,7 @@ bool reshape(const PixelBufferDescriptor& data, PixelBufferDescriptor& reshaped)
|
||||
}
|
||||
case PixelDataType::INT:
|
||||
case PixelDataType::UINT: {
|
||||
uint8_t* bytes = static_cast<uint8_t*>(malloc(reshapedSize));
|
||||
uint8_t* bytes = (uint8_t*) malloc(reshapedSize);
|
||||
DataReshaper::reshape<uint32_t, 3, 4>(bytes, data.buffer, data.size);
|
||||
PixelBufferDescriptor pbd(bytes, reshapedSize, reshapedFormat, data.type,
|
||||
data.alignment, data.left, data.top, data.stride, freeFunc);
|
||||
@@ -669,7 +663,7 @@ bool reshape(const PixelBufferDescriptor& data, PixelBufferDescriptor& reshaped)
|
||||
return true;
|
||||
}
|
||||
case PixelDataType::FLOAT: {
|
||||
uint8_t* bytes = static_cast<uint8_t*>(malloc(reshapedSize));
|
||||
uint8_t* bytes = (uint8_t*) malloc(reshapedSize);
|
||||
DataReshaper::reshape<float, 3, 4>(bytes, data.buffer, data.size);
|
||||
PixelBufferDescriptor pbd(bytes, reshapedSize, reshapedFormat, data.type,
|
||||
data.alignment, data.left, data.top, data.stride, freeFunc);
|
||||
|
||||
@@ -38,11 +38,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(WIN32)
|
||||
# include <windows.h> // for VirtualAlloc, VirtualProtect, VirtualFree
|
||||
# include <utils/unwindows.h>
|
||||
#endif
|
||||
|
||||
using namespace utils;
|
||||
|
||||
namespace filament::backend {
|
||||
@@ -139,21 +134,6 @@ void* CircularBuffer::alloc(size_t size) {
|
||||
mprotect(guard, BLOCK_SIZE, PROT_NONE);
|
||||
}
|
||||
return data;
|
||||
#elif defined(WIN32)
|
||||
size_t const BLOCK_SIZE = getBlockSize();
|
||||
// On Windows, use VirtualAlloc instead of malloc to allocate virtual memory.
|
||||
// This allows us to set page protection by VirtualProtect.
|
||||
void* data = VirtualAlloc(nullptr, size * 2 + BLOCK_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
FILAMENT_CHECK_POSTCONDITION(data != nullptr)
|
||||
<< "couldn't allocate " << (size * 2 / 1024)
|
||||
<< " KiB of virtual address space for the command buffer";
|
||||
|
||||
// guard page at the end
|
||||
void* guard = (void*)(uintptr_t(data) + size * 2);
|
||||
DWORD oldProtect = 0;
|
||||
BOOL ok = VirtualProtect(guard, BLOCK_SIZE, PAGE_NOACCESS, &oldProtect);
|
||||
FILAMENT_CHECK_POSTCONDITION(ok) << "VirtualProtect failed to set guard page";
|
||||
return data;
|
||||
#else
|
||||
return ::malloc(2 * size);
|
||||
#endif
|
||||
@@ -170,10 +150,6 @@ void CircularBuffer::dealloc() noexcept {
|
||||
mAshmemFd = -1;
|
||||
}
|
||||
}
|
||||
#elif defined(WIN32)
|
||||
if (mData) {
|
||||
VirtualFree(mData, 0, MEM_RELEASE);
|
||||
}
|
||||
#else
|
||||
::free(mData);
|
||||
#endif
|
||||
|
||||
@@ -57,7 +57,7 @@ static void printParameterPack(io::ostream& out, const FIRST& first, const REMAI
|
||||
printParameterPack(out, rest...);
|
||||
}
|
||||
|
||||
static UTILS_NOINLINE UTILS_UNUSED std::string_view extractMethodName(std::string_view command) noexcept {
|
||||
static UTILS_NOINLINE UTILS_UNUSED std::string extractMethodName(std::string& command) noexcept {
|
||||
constexpr const char startPattern[] = "::Command<&filament::backend::Driver::";
|
||||
auto pos = command.rfind(startPattern);
|
||||
auto end = command.rfind('(');
|
||||
@@ -97,13 +97,11 @@ void CommandStream::execute(void* buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
Driver& UTILS_RESTRICT driver = mDriver;
|
||||
CommandBase* UTILS_RESTRICT base = static_cast<CommandBase*>(buffer);
|
||||
mDriver.execute([&driver, base] {
|
||||
auto& d = driver;
|
||||
auto p = base;
|
||||
while (UTILS_LIKELY(p)) {
|
||||
p = p->execute(d);
|
||||
mDriver.execute([this, buffer]() {
|
||||
Driver& UTILS_RESTRICT driver = mDriver;
|
||||
CommandBase* UTILS_RESTRICT base = static_cast<CommandBase*>(buffer);
|
||||
while (UTILS_LIKELY(base)) {
|
||||
base = base->execute(driver);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -133,9 +131,9 @@ template<std::size_t... I>
|
||||
void CommandType<void (Driver::*)(ARGS...)>::Command<METHOD>::log(std::index_sequence<I...>) noexcept {
|
||||
#if DEBUG_COMMAND_STREAM
|
||||
static_assert(UTILS_HAS_RTTI, "DEBUG_COMMAND_STREAM can only be used with RTTI");
|
||||
CString command = CallStack::demangleTypeName(typeid(Command).name());
|
||||
DLOG(INFO) << extractMethodName({command.data(), command.size()}) << " : size=" << sizeof(Command);
|
||||
io::sstream parameterPack;
|
||||
std::string command = utils::CallStack::demangleTypeName(typeid(Command).name()).c_str();
|
||||
DLOG(INFO) << extractMethodName(command) << " : size=" << sizeof(Command);
|
||||
utils::io::sstream parameterPack;
|
||||
printParameterPack(parameterPack, std::get<I>(mArgs)...);
|
||||
DLOG(INFO) << "\t" << parameterPack.c_str();
|
||||
#endif
|
||||
@@ -164,7 +162,7 @@ void CommandType<void (Driver::*)(ARGS...)>::Command<METHOD>::log() noexcept {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
void CustomCommand::execute(Driver&, CommandBase* base, intptr_t* next) {
|
||||
*next = align(sizeof(CustomCommand));
|
||||
*next = CustomCommand::align(sizeof(CustomCommand));
|
||||
static_cast<CustomCommand*>(base)->mCommand();
|
||||
static_cast<CustomCommand*>(base)->~CustomCommand();
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ public:
|
||||
static void copyImage(uint8_t* UTILS_RESTRICT dest,
|
||||
const uint8_t* UTILS_RESTRICT src,
|
||||
size_t srcBytesPerRow, size_t /*srcChannelCount*/,
|
||||
size_t /*dstRowOffset */, size_t /*dstColumnOffset */,
|
||||
size_t dstBytesPerRow, size_t /*dstChannelCount*/,
|
||||
size_t /*width*/, size_t height, bool /*swizzle*/) {
|
||||
if (srcBytesPerRow == dstBytesPerRow) {
|
||||
@@ -80,20 +79,17 @@ public:
|
||||
template<typename dstComponentType, typename srcComponentType>
|
||||
static void reshapeImage(uint8_t* UTILS_RESTRICT dest, const uint8_t* UTILS_RESTRICT src,
|
||||
size_t srcBytesPerRow,
|
||||
size_t srcChannelCount,
|
||||
size_t dstRowOffset, size_t dstColumnOffset,
|
||||
size_t dstBytesPerRow, size_t dstChannelCount,
|
||||
size_t srcChannelCount, size_t dstBytesPerRow, size_t dstChannelCount,
|
||||
size_t width, size_t height, bool swizzle) {
|
||||
const dstComponentType dstMaxValue = getMaxValue<dstComponentType>();
|
||||
const srcComponentType srcMaxValue = getMaxValue<srcComponentType>();
|
||||
const size_t minChannelCount = math::min(srcChannelCount, dstChannelCount);
|
||||
assert_invariant(minChannelCount <= 4);
|
||||
UTILS_ASSUME(minChannelCount <= 4);
|
||||
dest += (dstRowOffset * dstBytesPerRow);
|
||||
const int inds[4] = { swizzle ? 2 : 0, 1, swizzle ? 0 : 2, 3 };
|
||||
for (size_t row = 0; row < height; ++row) {
|
||||
const srcComponentType* in = (const srcComponentType*) src;
|
||||
dstComponentType* out = (dstComponentType*)dest + (dstColumnOffset * dstChannelCount);
|
||||
const srcComponentType* in = (const srcComponentType*)src;
|
||||
dstComponentType* out = (dstComponentType*)dest;
|
||||
for (size_t column = 0; column < width; ++column) {
|
||||
for (size_t channel = 0; channel < minChannelCount; ++channel) {
|
||||
if constexpr (std::is_same_v<dstComponentType, srcComponentType>) {
|
||||
@@ -132,23 +128,17 @@ public:
|
||||
default: return false;
|
||||
}
|
||||
void (*reshaper)(uint8_t* dest, const uint8_t* src, size_t srcBytesPerRow,
|
||||
size_t srcChannelCount,
|
||||
size_t srcRowOffset, size_t srcColumnOffset,
|
||||
size_t dstBytesPerRow, size_t dstChannelCount,
|
||||
size_t srcChannelCount, size_t dstBytesPerRow, size_t dstChannelCount,
|
||||
size_t width, size_t height, bool swizzle) = nullptr;
|
||||
constexpr auto UBYTE = PixelDataType::UBYTE;
|
||||
constexpr auto FLOAT = PixelDataType::FLOAT;
|
||||
constexpr auto UINT = PixelDataType::UINT;
|
||||
constexpr auto INT = PixelDataType::INT;
|
||||
constexpr auto HALF = PixelDataType::HALF;
|
||||
constexpr auto UBYTE = PixelDataType::UBYTE, FLOAT = PixelDataType::FLOAT,
|
||||
UINT = PixelDataType::UINT, INT = PixelDataType::INT;
|
||||
switch (dst->type) {
|
||||
case UBYTE:
|
||||
switch (srcType) {
|
||||
case UBYTE:
|
||||
reshaper = reshapeImage<uint8_t, uint8_t>;
|
||||
if (dst->format == PixelDataFormat::RGBA &&
|
||||
dstChannelCount == srcChannelCount && !swizzle && dst->top == 0 &&
|
||||
dst->left == 0) {
|
||||
dstChannelCount == srcChannelCount && !swizzle) {
|
||||
reshaper = copyImage;
|
||||
}
|
||||
break;
|
||||
@@ -185,20 +175,13 @@ public:
|
||||
default: return false;
|
||||
}
|
||||
break;
|
||||
case HALF:
|
||||
switch (srcType) {
|
||||
case HALF: reshaper = copyImage; break;
|
||||
default: return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
uint8_t* dstBytes = (uint8_t*) dst->buffer;
|
||||
const int dstBytesPerRow = PixelBufferDescriptor::computeDataSize(dst->format, dst->type,
|
||||
dst->stride ? dst->stride : width, 1, dst->alignment);
|
||||
reshaper(dstBytes, srcBytes, srcBytesPerRow, srcChannelCount,
|
||||
dst->top, dst->left, dstBytesPerRow,
|
||||
reshaper(dstBytes, srcBytes, srcBytesPerRow, srcChannelCount, dstBytesPerRow,
|
||||
dstChannelCount, width, height, swizzle);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -78,9 +78,6 @@ struct HwBufferObject : public HwBase {
|
||||
explicit HwBufferObject(uint32_t byteCount) noexcept : byteCount(byteCount) {}
|
||||
};
|
||||
|
||||
struct HwMemoryMappedBuffer : public HwBase {
|
||||
};
|
||||
|
||||
struct HwIndexBuffer : public HwBase {
|
||||
uint32_t count : 27;
|
||||
uint32_t elementSize : 5;
|
||||
@@ -143,10 +140,6 @@ struct HwFence : public HwBase {
|
||||
Platform::Fence* fence = nullptr;
|
||||
};
|
||||
|
||||
struct HwSync : public HwBase {
|
||||
Platform::Sync* sync = nullptr;
|
||||
};
|
||||
|
||||
struct HwSwapChain : public HwBase {
|
||||
Platform::SwapChain* swapChain = nullptr;
|
||||
};
|
||||
@@ -214,7 +207,7 @@ public:
|
||||
protected:
|
||||
class CallbackDataDetails;
|
||||
|
||||
void scheduleDestroy(BufferDescriptor&& buffer) noexcept {
|
||||
inline void scheduleDestroy(BufferDescriptor&& buffer) noexcept {
|
||||
if (buffer.hasCallback()) {
|
||||
scheduleDestroySlow(std::move(buffer));
|
||||
}
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#ifndef NDEBUG
|
||||
# include <utils/CString.h>
|
||||
# include <string_view>
|
||||
# include <string>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -37,11 +36,11 @@ static char const * const kOurNamespace = "filament::backend::";
|
||||
|
||||
// removes all occurrences of "what" from "str"
|
||||
UTILS_NOINLINE
|
||||
static CString& removeAll(CString& str, const std::string_view what) noexcept {
|
||||
static std::string& removeAll(std::string& str, const std::string& what) noexcept {
|
||||
if (!what.empty()) {
|
||||
const CString empty;
|
||||
const std::string empty;
|
||||
size_t pos = 0;
|
||||
while ((pos = std::string_view{ str.data(), str.size() }.find(what, pos)) != std::string_view::npos) {
|
||||
while ((pos = str.find(what, pos)) != std::string::npos) {
|
||||
str.replace(pos, what.length(), empty);
|
||||
}
|
||||
}
|
||||
@@ -50,13 +49,13 @@ static CString& removeAll(CString& str, const std::string_view what) noexcept {
|
||||
|
||||
template <typename T>
|
||||
UTILS_NOINLINE
|
||||
static io::ostream& logHandle(io::ostream& out, CString& typeName, T id) noexcept {
|
||||
static io::ostream& logHandle(io::ostream& out, std::string& typeName, T id) noexcept {
|
||||
return out << removeAll(typeName, kOurNamespace) << " @ " << id;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
io::ostream& operator<<(io::ostream& out, const Handle<T>& h) noexcept {
|
||||
CString s{ CallStack::typeName<Handle<T>>() };
|
||||
std::string s(CallStack::typeName<Handle<T>>().c_str());
|
||||
return logHandle(out, s, h.getId());
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#define TNT_FILAMENT_DRIVER_METALBUFFER_H
|
||||
|
||||
#include "MetalContext.h"
|
||||
#include "MetalFlags.h"
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/platforms/PlatformMetal.h>
|
||||
@@ -192,15 +191,6 @@ public:
|
||||
|
||||
void* getCpuBuffer() const noexcept { return mCpuBuffer; }
|
||||
|
||||
void setLabel(const utils::CString& label) {
|
||||
#if FILAMENT_METAL_DEBUG_LABELS
|
||||
if (label.empty()) {
|
||||
return;
|
||||
}
|
||||
mBuffer.get().label = @(label.c_str_safe());
|
||||
#endif
|
||||
}
|
||||
|
||||
enum Stage : uint8_t {
|
||||
VERTEX = 1u << 0u,
|
||||
FRAGMENT = 1u << 1u,
|
||||
|
||||
@@ -102,7 +102,7 @@ id<MTLCommandBuffer> getPendingCommandBuffer(MetalContext* context) {
|
||||
context->pendingCommandBuffer = [context->commandQueue commandBuffer];
|
||||
// It's safe for this block to capture the context variable. MetalDriver::terminate will ensure
|
||||
// all frames and their completion handlers finish before context is deallocated.
|
||||
const uint64_t thisCommandBufferId = context->pendingCommandBufferId;
|
||||
uint64_t thisCommandBufferId = context->pendingCommandBufferId;
|
||||
[context->pendingCommandBuffer addCompletedHandler:^(id <MTLCommandBuffer> buffer) {
|
||||
context->resourceTracker.clearResources((__bridge void*) buffer);
|
||||
|
||||
@@ -118,11 +118,6 @@ id<MTLCommandBuffer> getPendingCommandBuffer(MetalContext* context) {
|
||||
context->memorylessLimitsReached = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (UTILS_UNLIKELY(errorCode != MTLCommandBufferErrorNone)) {
|
||||
LOG(ERROR) << "Filament Metal command buffer errored with code: " << errorCode << " ("
|
||||
<< stringifyMTLCommandBufferError(errorCode) << ").";
|
||||
}
|
||||
}];
|
||||
FILAMENT_CHECK_POSTCONDITION(context->pendingCommandBuffer)
|
||||
<< "Could not obtain command buffer.";
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
|
||||
#include <backend/SamplerDescriptor.h>
|
||||
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <functional>
|
||||
@@ -70,8 +69,7 @@ private:
|
||||
MetalContext* mContext;
|
||||
|
||||
ShaderModel getShaderModel() const noexcept final;
|
||||
utils::FixedCapacityVector<ShaderLanguage> getShaderLanguages(
|
||||
ShaderLanguage preferredLanguage) const noexcept final;
|
||||
ShaderLanguage getShaderLanguage() const noexcept final;
|
||||
|
||||
// Overrides the default implementation by wrapping the call to fn in an @autoreleasepool block.
|
||||
void execute(std::function<void(void)> const& fn) noexcept final;
|
||||
|
||||
@@ -418,42 +418,49 @@ void MetalDriver::finish(int) {
|
||||
}
|
||||
|
||||
void MetalDriver::createVertexBufferInfoR(Handle<HwVertexBufferInfo> vbih, uint8_t bufferCount,
|
||||
uint8_t attributeCount, AttributeArray attributes, utils::CString&& tag) {
|
||||
uint8_t attributeCount, AttributeArray attributes) {
|
||||
construct_handle<MetalVertexBufferInfo>(vbih, *mContext,
|
||||
bufferCount, attributeCount, attributes);
|
||||
mHandleAllocator.associateTagToHandle(vbih.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::createVertexBufferR(Handle<HwVertexBuffer> vbh,
|
||||
uint32_t vertexCount, Handle<HwVertexBufferInfo> vbih, utils::CString&& tag) {
|
||||
uint32_t vertexCount, Handle<HwVertexBufferInfo> vbih) {
|
||||
MetalVertexBufferInfo const* const vbi = handle_cast<const MetalVertexBufferInfo>(vbih);
|
||||
construct_handle<MetalVertexBuffer>(vbh, *mContext, vertexCount, vbi->bufferCount, vbih);
|
||||
mHandleAllocator.associateTagToHandle(vbh.getId(), std::move(tag));
|
||||
// No actual GPU memory is allocated here, so no need to check for allocation success.
|
||||
}
|
||||
|
||||
void MetalDriver::createIndexBufferR(Handle<HwIndexBuffer> ibh, ElementType elementType,
|
||||
uint32_t indexCount, BufferUsage usage, utils::CString&& tag) {
|
||||
uint32_t indexCount, BufferUsage usage) {
|
||||
auto elementSize = (uint8_t)getElementTypeSize(elementType);
|
||||
auto* indexBuffer =
|
||||
construct_handle<MetalIndexBuffer>(ibh, *mContext, usage, elementSize, indexCount);
|
||||
auto& buffer = indexBuffer->buffer;
|
||||
FILAMENT_CHECK_POSTCONDITION(buffer.wasAllocationSuccessful())
|
||||
<< "Could not allocate Metal index buffer of size " << buffer.getSize()
|
||||
<< ", tag=" << tag.c_str_safe();
|
||||
buffer.setLabel(tag);
|
||||
mHandleAllocator.associateTagToHandle(ibh.getId(), std::move(tag));
|
||||
// If the allocation was not successful, postpone the error message until the next tick, to give
|
||||
// Filament a chance to call setDebugTag on the handle; this way we get a nicer error message.
|
||||
if (UTILS_UNLIKELY(!buffer.wasAllocationSuccessful())) {
|
||||
const size_t byteCount = buffer.getSize();
|
||||
runAtNextTick([byteCount, this, ibh]() {
|
||||
FILAMENT_CHECK_POSTCONDITION(false)
|
||||
<< "Could not allocate Metal index buffer of size " << byteCount
|
||||
<< ", tag=" << mHandleAllocator.getHandleTag(ibh.getId()).c_str_safe();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void MetalDriver::createBufferObjectR(Handle<HwBufferObject> boh, uint32_t byteCount,
|
||||
BufferObjectBinding bindingType, BufferUsage usage, utils::CString&& tag) {
|
||||
BufferObjectBinding bindingType, BufferUsage usage) {
|
||||
auto* bufferObject =
|
||||
construct_handle<MetalBufferObject>(boh, *mContext, bindingType, usage, byteCount);
|
||||
FILAMENT_CHECK_POSTCONDITION(bufferObject->getBuffer()->wasAllocationSuccessful())
|
||||
<< "Could not allocate Metal buffer of size " << byteCount
|
||||
<< ", tag=" << tag.c_str_safe();
|
||||
bufferObject->getBuffer()->setLabel(tag);
|
||||
mHandleAllocator.associateTagToHandle(boh.getId(), std::move(tag));
|
||||
// If the allocation was not successful, postpone the error message until the next tick, to give
|
||||
// Filament a chance to call setDebugTag on the handle; this way we get a nicer error message.
|
||||
if (UTILS_UNLIKELY(!bufferObject->getBuffer()->wasAllocationSuccessful())) {
|
||||
runAtNextTick([byteCount, this, boh]() {
|
||||
FILAMENT_CHECK_POSTCONDITION(false)
|
||||
<< "Could not allocate Metal buffer of size " << byteCount
|
||||
<< ", tag=" << mHandleAllocator.getHandleTag(boh.getId()).c_str_safe();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// fixme: TextureUsage is a bitfield
|
||||
@@ -488,83 +495,67 @@ inline const char* stringify(SamplerType samplerType) {
|
||||
|
||||
void MetalDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint8_t levels,
|
||||
TextureFormat format, uint8_t samples, uint32_t width, uint32_t height,
|
||||
uint32_t depth, TextureUsage usage, utils::CString&& tag) {
|
||||
uint32_t depth, TextureUsage usage) {
|
||||
// Clamp sample count to what the device supports.
|
||||
auto& sc = mContext->sampleCountLookup;
|
||||
samples = sc[std::min(MAX_SAMPLE_COUNT, samples)];
|
||||
|
||||
MetalTexture* texture = construct_handle<MetalTexture>(th, *mContext, target, levels, format,
|
||||
samples, width, height, depth, usage);
|
||||
mContext->textures.insert(texture);
|
||||
|
||||
texture->setLabel(tag);
|
||||
mContext->textures.insert(construct_handle<MetalTexture>(
|
||||
th, *mContext, target, levels, format, samples, width, height, depth, usage));
|
||||
|
||||
DEBUG_LOG(
|
||||
"createTextureR(th = %d, target = %s, levels = %d, format = ?, samples = %d, width = "
|
||||
"%d, height = %d, depth = %d, usage = %s)\n",
|
||||
th.getId(), stringify(target), levels, samples, width, height, depth, stringify(usage));
|
||||
|
||||
mHandleAllocator.associateTagToHandle(th.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::createTextureViewR(Handle<HwTexture> th, Handle<HwTexture> srch,
|
||||
uint8_t baseLevel, uint8_t levelCount, utils::CString&& tag) {
|
||||
void MetalDriver::createTextureViewR(
|
||||
Handle<HwTexture> th, Handle<HwTexture> srch, uint8_t baseLevel, uint8_t levelCount) {
|
||||
MetalTexture const* src = handle_cast<MetalTexture>(srch);
|
||||
MetalTexture* texture =
|
||||
construct_handle<MetalTexture>(th, *mContext, src, baseLevel, levelCount);
|
||||
mContext->textures.insert(texture);
|
||||
texture->setLabel(tag);
|
||||
mHandleAllocator.associateTagToHandle(th.getId(), std::move(tag));
|
||||
mContext->textures.insert(
|
||||
construct_handle<MetalTexture>(th, *mContext, src, baseLevel, levelCount));
|
||||
}
|
||||
|
||||
void MetalDriver::createTextureViewSwizzleR(Handle<HwTexture> th, Handle<HwTexture> srch,
|
||||
backend::TextureSwizzle r, backend::TextureSwizzle g, backend::TextureSwizzle b,
|
||||
backend::TextureSwizzle a, utils::CString&& tag) {
|
||||
backend::TextureSwizzle a) {
|
||||
MetalTexture const* src = handle_cast<MetalTexture>(srch);
|
||||
MetalTexture* texture = construct_handle<MetalTexture>(th, *mContext, src, r, g, b, a);
|
||||
mContext->textures.insert(texture);
|
||||
texture->setLabel(tag);
|
||||
mHandleAllocator.associateTagToHandle(th.getId(), std::move(tag));
|
||||
mContext->textures.insert(construct_handle<MetalTexture>(th, *mContext, src, r, g, b, a));
|
||||
}
|
||||
|
||||
void MetalDriver::createTextureExternalImage2R(Handle<HwTexture> th,
|
||||
backend::SamplerType target,
|
||||
backend::TextureFormat format,
|
||||
uint32_t width, uint32_t height, backend::TextureUsage usage,
|
||||
Platform::ExternalImageHandleRef image, utils::CString&& tag) {
|
||||
Platform::ExternalImageHandleRef image) {
|
||||
// FIXME: implement createTextureExternalImage2R
|
||||
}
|
||||
|
||||
void MetalDriver::createTextureExternalImageR(Handle<HwTexture> th, backend::SamplerType target,
|
||||
backend::TextureFormat format, uint32_t width, uint32_t height, backend::TextureUsage usage,
|
||||
void* image, utils::CString&& tag) {
|
||||
MetalTexture* texture = construct_handle<MetalTexture>(th, *mContext, format, width, height,
|
||||
usage, (CVPixelBufferRef) image);
|
||||
mContext->textures.insert(texture);
|
||||
texture->setLabel(tag);
|
||||
void MetalDriver::createTextureExternalImageR(Handle<HwTexture> th,
|
||||
backend::SamplerType target,
|
||||
backend::TextureFormat format,
|
||||
uint32_t width, uint32_t height, backend::TextureUsage usage, void* image) {
|
||||
mContext->textures.insert(construct_handle<MetalTexture>(
|
||||
th, *mContext, format, width, height, usage, (CVPixelBufferRef)image));
|
||||
// This release matches the retain call in setupExternalImage. The MetalTexture will have
|
||||
// retained the buffer by now.
|
||||
CVPixelBufferRelease((CVPixelBufferRef)image);
|
||||
mHandleAllocator.associateTagToHandle(th.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::createTextureExternalImagePlaneR(Handle<HwTexture> th,
|
||||
backend::TextureFormat format, uint32_t width, uint32_t height, backend::TextureUsage usage,
|
||||
void* image, uint32_t plane, utils::CString&& tag) {
|
||||
MetalTexture* texture = construct_handle<MetalTexture>(th, *mContext, format, width, height,
|
||||
usage, (CVPixelBufferRef) image, plane);
|
||||
mContext->textures.insert(texture);
|
||||
texture->setLabel(tag);
|
||||
void* image, uint32_t plane) {
|
||||
mContext->textures.insert(construct_handle<MetalTexture>(
|
||||
th, *mContext, format, width, height, usage, (CVPixelBufferRef)image, plane));
|
||||
// This release matches the retain call in setupExternalImage. The MetalTexture will have
|
||||
// retained the buffer by now.
|
||||
CVPixelBufferRelease((CVPixelBufferRef)image);
|
||||
mHandleAllocator.associateTagToHandle(th.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::importTextureR(Handle<HwTexture> th, intptr_t i,
|
||||
SamplerType target, uint8_t levels,
|
||||
TextureFormat format, uint8_t samples, uint32_t width, uint32_t height,
|
||||
uint32_t depth, TextureUsage usage, utils::CString&& tag) {
|
||||
uint32_t depth, TextureUsage usage) {
|
||||
id<MTLTexture> metalTexture = (id<MTLTexture>) CFBridgingRelease((void*) i);
|
||||
FILAMENT_CHECK_PRECONDITION(metalTexture.width == width)
|
||||
<< "Imported id<MTLTexture> width (" << metalTexture.width
|
||||
@@ -579,40 +570,34 @@ void MetalDriver::importTextureR(Handle<HwTexture> th, intptr_t i,
|
||||
FILAMENT_CHECK_PRECONDITION(metalTexture.textureType == filamentMetalType)
|
||||
<< "Imported id<MTLTexture> type (" << metalTexture.textureType
|
||||
<< ") != Filament texture type (" << filamentMetalType << ")";
|
||||
MetalTexture* texture = construct_handle<MetalTexture>(th, *mContext, target, levels, format,
|
||||
samples, width, height, depth, usage, metalTexture);
|
||||
mContext->textures.insert(texture);
|
||||
texture->setLabel(tag);
|
||||
mHandleAllocator.associateTagToHandle(th.getId(), std::move(tag));
|
||||
mContext->textures.insert(construct_handle<MetalTexture>(th, *mContext,
|
||||
target, levels, format, samples, width, height, depth, usage, metalTexture));
|
||||
}
|
||||
|
||||
void MetalDriver::createRenderPrimitiveR(Handle<HwRenderPrimitive> rph,
|
||||
Handle<HwVertexBuffer> vbh, Handle<HwIndexBuffer> ibh,
|
||||
PrimitiveType pt, utils::CString&& tag) {
|
||||
PrimitiveType pt) {
|
||||
construct_handle<MetalRenderPrimitive>(rph);
|
||||
MetalDriver::setRenderPrimitiveBuffer(rph, pt, vbh, ibh);
|
||||
mHandleAllocator.associateTagToHandle(rph.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::createProgramR(Handle<HwProgram> rph, Program&& program, utils::CString&& tag) {
|
||||
void MetalDriver::createProgramR(Handle<HwProgram> rph, Program&& program) {
|
||||
#if FILAMENT_METAL_DEBUG_LOG
|
||||
auto handleId = rph.getId();
|
||||
DEBUG_LOG("createProgramR(rph = %d, program = ", handleId);
|
||||
DLOG(INFO) << program;
|
||||
#endif
|
||||
construct_handle<MetalProgram>(rph, *mContext, std::move(program));
|
||||
mHandleAllocator.associateTagToHandle(rph.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::createDefaultRenderTargetR(Handle<HwRenderTarget> rth, utils::CString&& tag) {
|
||||
void MetalDriver::createDefaultRenderTargetR(Handle<HwRenderTarget> rth, int dummy) {
|
||||
construct_handle<MetalRenderTarget>(rth, mContext);
|
||||
mHandleAllocator.associateTagToHandle(rth.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
|
||||
TargetBufferFlags targetBufferFlags, uint32_t width, uint32_t height,
|
||||
uint8_t samples, uint8_t layerCount, MRT color,
|
||||
TargetBufferInfo depth, TargetBufferInfo stencil, utils::CString&& tag) {
|
||||
TargetBufferInfo depth, TargetBufferInfo stencil) {
|
||||
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
|
||||
<< "createRenderTarget must be called outside of a render pass.";
|
||||
// Clamp sample count to what the device supports.
|
||||
@@ -655,20 +640,14 @@ void MetalDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
|
||||
|
||||
construct_handle<MetalRenderTarget>(rth, mContext, width, height, samples,
|
||||
colorAttachments, depthAttachment, stencilAttachment);
|
||||
|
||||
mHandleAllocator.associateTagToHandle(rth.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::createFenceR(Handle<HwFence> fh, utils::CString&& tag) {
|
||||
void MetalDriver::createFenceR(Handle<HwFence> fh, int dummy) {
|
||||
auto* fence = handle_cast<MetalFence>(fh);
|
||||
fence->encode();
|
||||
mHandleAllocator.associateTagToHandle(fh.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow, uint64_t flags,
|
||||
utils::CString&& tag) {
|
||||
// TODO: support MSAA swapchain
|
||||
|
||||
void MetalDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow, uint64_t flags) {
|
||||
if (UTILS_UNLIKELY(flags & SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER)) {
|
||||
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef) nativeWindow;
|
||||
construct_handle<MetalSwapChain>(sch, *mContext, mPlatform, pixelBuffer, flags);
|
||||
@@ -679,24 +658,15 @@ void MetalDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow,
|
||||
auto* metalLayer = (__bridge CAMetalLayer*) nativeWindow;
|
||||
construct_handle<MetalSwapChain>(sch, *mContext, mPlatform, metalLayer, flags);
|
||||
}
|
||||
mHandleAllocator.associateTagToHandle(sch.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::createSwapChainHeadlessR(Handle<HwSwapChain> sch,
|
||||
uint32_t width, uint32_t height, uint64_t flags, utils::CString&& tag) {
|
||||
uint32_t width, uint32_t height, uint64_t flags) {
|
||||
construct_handle<MetalSwapChain>(sch, *mContext, mPlatform, width, height, flags);
|
||||
mHandleAllocator.associateTagToHandle(sch.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::createSyncR(Handle<HwSync> sh, utils::CString&& tag) {
|
||||
// TODO: Ensure sync is active, and then invoke and clear all pending
|
||||
// callbacks.
|
||||
mHandleAllocator.associateTagToHandle(sh.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, utils::CString&& tag) {
|
||||
void MetalDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, int) {
|
||||
// nothing to do, timer query was constructed in createTimerQueryS
|
||||
mHandleAllocator.associateTagToHandle(tqh.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
UTILS_UNUSED
|
||||
@@ -733,7 +703,7 @@ const char* toString(DescriptorFlags flags) {
|
||||
}
|
||||
|
||||
void MetalDriver::createDescriptorSetLayoutR(
|
||||
Handle<HwDescriptorSetLayout> dslh, DescriptorSetLayout&& info, utils::CString&& tag) {
|
||||
Handle<HwDescriptorSetLayout> dslh, DescriptorSetLayout&& info) {
|
||||
#if FILAMENT_METAL_DEBUG_LOG == 1
|
||||
const char* labelStr = "";
|
||||
std::visit([&labelStr](auto&& arg) {
|
||||
@@ -754,16 +724,13 @@ void MetalDriver::createDescriptorSetLayoutR(
|
||||
DEBUG_LOG("})\n");
|
||||
#endif
|
||||
construct_handle<MetalDescriptorSetLayout>(dslh, std::move(info));
|
||||
mHandleAllocator.associateTagToHandle(dslh.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::createDescriptorSetR(
|
||||
Handle<HwDescriptorSet> dsh, Handle<HwDescriptorSetLayout> dslh, utils::CString&& tag) {
|
||||
Handle<HwDescriptorSet> dsh, Handle<HwDescriptorSetLayout> dslh) {
|
||||
DEBUG_LOG("createDescriptorSetR(dsh = %d, dslh = %d)\n", dsh.getId(), dslh.getId());
|
||||
MetalDescriptorSetLayout* layout = handle_cast<MetalDescriptorSetLayout>(dslh);
|
||||
MetalDescriptorSet* ds = construct_handle<MetalDescriptorSet>(dsh, layout);
|
||||
ds->setLabel(tag);
|
||||
mHandleAllocator.associateTagToHandle(dsh.getId(), std::move(tag));
|
||||
construct_handle<MetalDescriptorSet>(dsh, layout);
|
||||
}
|
||||
|
||||
Handle<HwVertexBufferInfo> MetalDriver::createVertexBufferInfoS() noexcept {
|
||||
@@ -840,10 +807,6 @@ Handle<HwSwapChain> MetalDriver::createSwapChainHeadlessS() noexcept {
|
||||
return alloc_handle<MetalSwapChain>();
|
||||
}
|
||||
|
||||
Handle<HwSync> MetalDriver::createSyncS() noexcept {
|
||||
return alloc_handle<MetalSync>();
|
||||
}
|
||||
|
||||
Handle<HwTimerQuery> MetalDriver::createTimerQueryS() noexcept {
|
||||
// The handle must be constructed here, as a synchronous call to getTimerQueryValue might happen
|
||||
// before createTimerQueryR is executed.
|
||||
@@ -1002,19 +965,15 @@ ShaderModel MetalDriver::getShaderModel() const noexcept {
|
||||
#endif
|
||||
}
|
||||
|
||||
utils::FixedCapacityVector<ShaderLanguage> MetalDriver::getShaderLanguages(
|
||||
ShaderLanguage preferredLanguage) const noexcept {
|
||||
if (preferredLanguage == backend::ShaderLanguage::MSL) {
|
||||
return { backend::ShaderLanguage::MSL, backend::ShaderLanguage::METAL_LIBRARY };
|
||||
}
|
||||
return { backend::ShaderLanguage::METAL_LIBRARY, backend::ShaderLanguage::MSL };
|
||||
ShaderLanguage MetalDriver::getShaderLanguage() const noexcept {
|
||||
return ShaderLanguage::MSL;
|
||||
}
|
||||
|
||||
Handle<HwStream> MetalDriver::createStreamNative(void* stream, utils::CString tag) {
|
||||
Handle<HwStream> MetalDriver::createStreamNative(void* stream) {
|
||||
return {};
|
||||
}
|
||||
|
||||
Handle<HwStream> MetalDriver::createStreamAcquired(utils::CString tag) {
|
||||
Handle<HwStream> MetalDriver::createStreamAcquired() {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -1042,30 +1001,13 @@ void MetalDriver::destroyFence(Handle<HwFence> fh) {
|
||||
}
|
||||
|
||||
FenceStatus MetalDriver::getFenceStatus(Handle<HwFence> fh) {
|
||||
return fenceWait(fh, 0);
|
||||
}
|
||||
|
||||
FenceStatus MetalDriver::fenceWait(FenceHandle fh, uint64_t const timeout) {
|
||||
auto* fence = handle_cast<MetalFence>(fh);
|
||||
if (!fence) {
|
||||
return FenceStatus::ERROR;
|
||||
}
|
||||
return fence->wait(timeout);
|
||||
return fence->wait(0);
|
||||
}
|
||||
|
||||
void MetalDriver::destroySync(Handle<HwSync> sh) {
|
||||
if (sh) {
|
||||
destruct_handle<MetalSync>(sh);
|
||||
}
|
||||
}
|
||||
|
||||
void MetalDriver::getPlatformSync(Handle<HwSync> sh, CallbackHandler* handler,
|
||||
Platform::SyncCallback cb, void* userData) {
|
||||
// TODO: If the sync has been inserted into the command stream, execute
|
||||
// the callback. Otherwise, enqueue it.
|
||||
}
|
||||
|
||||
|
||||
bool MetalDriver::isTextureFormatSupported(TextureFormat format) {
|
||||
return MetalTexture::decidePixelFormat(mContext, format) != MTLPixelFormatInvalid;
|
||||
}
|
||||
@@ -1147,11 +1089,6 @@ bool MetalDriver::isSRGBSwapChainSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MetalDriver::isMSAASwapChainSupported(uint32_t) {
|
||||
// TODO: support MSAA swapchain
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MetalDriver::isProtectedContentSupported() {
|
||||
// the SWAP_CHAIN_CONFIG_PROTECTED_CONTENT flag is not supported
|
||||
return false;
|
||||
@@ -2198,6 +2135,10 @@ void MetalDriver::endTimerQuery(Handle<HwTimerQuery> tqh) {
|
||||
void MetalDriver::resetState(int) {
|
||||
}
|
||||
|
||||
void MetalDriver::setDebugTag(HandleBase::HandleId handleId, utils::CString tag) {
|
||||
mHandleAllocator.associateTagToHandle(handleId, std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::runAtNextTick(const std::function<void()>& fn) noexcept {
|
||||
mTickOps.push_back(fn);
|
||||
}
|
||||
@@ -2225,38 +2166,6 @@ void MetalDriver::executeDeferredOps() noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
MemoryMappedBufferHandle MetalDriver::mapBufferS() noexcept {
|
||||
return alloc_handle<MetalMemoryMappedBuffer>();
|
||||
}
|
||||
|
||||
void MetalDriver::mapBufferR(MemoryMappedBufferHandle mmbh,
|
||||
BufferObjectHandle boh, size_t offset,
|
||||
size_t size, MapBufferAccessFlags access, utils::CString&& tag) {
|
||||
construct_handle<MetalMemoryMappedBuffer>(mmbh, boh, offset, size, access);
|
||||
mHandleAllocator.associateTagToHandle(mmbh.getId(), std::move(tag));
|
||||
}
|
||||
|
||||
void MetalDriver::unmapBuffer(MemoryMappedBufferHandle mmbh) {
|
||||
if (UTILS_UNLIKELY(!mmbh)) {
|
||||
return;
|
||||
}
|
||||
destruct_handle<MetalMemoryMappedBuffer>(mmbh);
|
||||
}
|
||||
|
||||
void MetalDriver::copyToMemoryMappedBuffer(MemoryMappedBufferHandle mmbh, size_t offset,
|
||||
BufferDescriptor&& data) {
|
||||
auto mmb = handle_cast<MetalMemoryMappedBuffer>(mmbh);
|
||||
|
||||
assert_invariant(any(mmb->access & MapBufferAccessFlags::WRITE_BIT));
|
||||
assert_invariant(offset + data.size <= mmb->size);
|
||||
|
||||
// TODO: this isa zero-effort implementation of copyToMemoryMappedBuffer(), where we just
|
||||
// call updateBufferObject(). This could be a fallback implementation for when
|
||||
// shared memory is not available.
|
||||
// On UMA systems, this should just be a memcpy into the memory-mapped buffer.
|
||||
updateBufferObject(mmb->boh, std::move(data), mmb->offset + offset);
|
||||
}
|
||||
|
||||
// explicit instantiation of the Dispatcher
|
||||
template class ConcreteDispatcher<MetalDriver>;
|
||||
|
||||
|
||||
@@ -451,38 +451,6 @@ inline MTLTextureSwizzleChannels getSwizzleChannels(TextureSwizzle r, TextureSwi
|
||||
getSwizzle(a));
|
||||
}
|
||||
|
||||
inline const char* stringifyMTLCommandBufferError(MTLCommandBufferError error) {
|
||||
#if !defined(FILAMENT_IOS)
|
||||
if (error == MTLCommandBufferErrorDeviceRemoved) {
|
||||
return "MTLCommandBufferErrorDeviceRemoved";
|
||||
}
|
||||
#endif
|
||||
switch (error) {
|
||||
case MTLCommandBufferErrorNone:
|
||||
return "MTLCommandBufferErrorNone";
|
||||
case MTLCommandBufferErrorInternal:
|
||||
return "MTLCommandBufferErrorInternal";
|
||||
case MTLCommandBufferErrorTimeout:
|
||||
return "MTLCommandBufferErrorTimeout";
|
||||
case MTLCommandBufferErrorPageFault:
|
||||
return "MTLCommandBufferErrorPageFault";
|
||||
case MTLCommandBufferErrorAccessRevoked:
|
||||
return "MTLCommandBufferErrorAccessRevoked";
|
||||
case MTLCommandBufferErrorNotPermitted:
|
||||
return "MTLCommandBufferErrorNotPermitted";
|
||||
case MTLCommandBufferErrorOutOfMemory:
|
||||
return "MTLCommandBufferErrorOutOfMemory";
|
||||
case MTLCommandBufferErrorInvalidResource:
|
||||
return "MTLCommandBufferErrorInvalidResource";
|
||||
case MTLCommandBufferErrorMemoryless:
|
||||
return "MTLCommandBufferErrorMemoryless";
|
||||
case MTLCommandBufferErrorStackOverflow:
|
||||
return "MTLCommandBufferErrorStackOverflow";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_DRIVER_METALFLAGS_H
|
||||
#define TNT_FILAMENT_DRIVER_METALFLAGS_H
|
||||
|
||||
#ifndef FILAMENT_METAL_DEBUG_LABELS
|
||||
#ifndef NDEBUG
|
||||
#define FILAMENT_METAL_DEBUG_LABELS 1
|
||||
#else
|
||||
#define FILAMENT_METAL_DEBUG_LABELS 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "MetalContext.h"
|
||||
#include "MetalEnums.h"
|
||||
#include "MetalExternalImage.h"
|
||||
#include "MetalFlags.h"
|
||||
#include "MetalState.h" // for MetalState::VertexDescription
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
@@ -267,16 +266,6 @@ public:
|
||||
|
||||
static MTLPixelFormat decidePixelFormat(MetalContext* context, TextureFormat format);
|
||||
|
||||
void setLabel(const utils::CString& label) {
|
||||
#if FILAMENT_METAL_DEBUG_LABELS
|
||||
if (label.empty()) {
|
||||
return;
|
||||
}
|
||||
texture.label = @(label.c_str_safe());
|
||||
swizzledTextureView.label = @(label.c_str_safe());
|
||||
#endif
|
||||
}
|
||||
|
||||
MetalContext& context;
|
||||
|
||||
// A "sidecar" texture used to implement automatic MSAA resolve.
|
||||
@@ -448,10 +437,6 @@ private:
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
// TODO: Provide implementation for MetalSync.
|
||||
class MetalSync : public HwSync {
|
||||
};
|
||||
|
||||
struct MetalTimerQuery : public HwTimerQuery {
|
||||
MetalTimerQuery() : status(std::make_shared<Status>()) {}
|
||||
|
||||
@@ -494,15 +479,6 @@ struct MetalDescriptorSet : public HwDescriptorSet {
|
||||
|
||||
void finalize(MetalDriver* driver);
|
||||
|
||||
void setLabel(const utils::CString& l) {
|
||||
#if FILAMENT_METAL_DEBUG_LABELS
|
||||
if (l.empty()) {
|
||||
return;
|
||||
}
|
||||
label = l;
|
||||
#endif
|
||||
}
|
||||
|
||||
id<MTLBuffer> finalizeAndGetBuffer(MetalDriver* driver, ShaderStage stage);
|
||||
|
||||
MetalDescriptorSetLayout* layout;
|
||||
@@ -525,22 +501,6 @@ struct MetalDescriptorSet : public HwDescriptorSet {
|
||||
std::vector<std::shared_ptr<MetalExternalImage>> externalImages;
|
||||
|
||||
std::array<TrackedMetalBuffer, Program::SHADER_TYPE_COUNT> cachedBuffer = { nil };
|
||||
|
||||
#if FILAMENT_METAL_DEBUG_LABELS
|
||||
utils::CString label;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct MetalMemoryMappedBuffer : public HwMemoryMappedBuffer {
|
||||
MetalMemoryMappedBuffer(BufferObjectHandle boh, size_t const offset,
|
||||
size_t const size, MapBufferAccessFlags const access)
|
||||
: boh(boh), access(access), size(size), offset(offset) {
|
||||
}
|
||||
BufferObjectHandle boh{};
|
||||
MapBufferAccessFlags access{};
|
||||
uint32_t size = 0;
|
||||
uint32_t offset = 0;
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
|
||||
@@ -118,10 +118,6 @@ MetalSwapChain::MetalSwapChain(
|
||||
layerDrawableMutex(std::make_shared<std::mutex>()),
|
||||
type(SwapChainType::CAMETALLAYER) {
|
||||
|
||||
FILAMENT_CHECK_PRECONDITION([nativeWindow isKindOfClass:[CAMetalLayer class]])
|
||||
<< "nativeWindow pointer of class "
|
||||
<< [NSStringFromClass([nativeWindow class]) UTF8String] << " is not a CAMetalLayer";
|
||||
|
||||
if (!(flags & SwapChain::CONFIG_TRANSPARENT) && !nativeWindow.opaque) {
|
||||
LOG(WARNING) << "Warning: Filament SwapChain has no CONFIG_TRANSPARENT flag, but the "
|
||||
"CAMetaLayer("
|
||||
@@ -295,12 +291,6 @@ void MetalSwapChain::ensureDepthStencilTexture() {
|
||||
|
||||
void MetalSwapChain::setFrameScheduledCallback(
|
||||
CallbackHandler* handler, FrameScheduledCallback&& callback, uint64_t flags) {
|
||||
if (!callback) {
|
||||
frameScheduled.handler = nullptr;
|
||||
frameScheduled.callback.reset();
|
||||
frameScheduled.flags = 0;
|
||||
return;
|
||||
}
|
||||
frameScheduled.handler = handler;
|
||||
frameScheduled.callback = std::make_shared<FrameScheduledCallback>(std::move(callback));
|
||||
frameScheduled.flags = flags;
|
||||
@@ -1492,11 +1482,6 @@ id<MTLBuffer> MetalDescriptorSet::finalizeAndGetBuffer(MetalDriver* driver, Shad
|
||||
buffer = { [context.device newBufferWithLength:encoder.encodedLength
|
||||
options:MTLResourceStorageModeShared],
|
||||
TrackedMetalBuffer::Type::DESCRIPTOR_SET };
|
||||
#if FILAMENT_METAL_DEBUG_LABELS
|
||||
if (!label.empty()) {
|
||||
buffer.get().label = @(label.c_str_safe());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
[encoder setArgumentBuffer:buffer.get() offset:0];
|
||||
|
||||
|
||||
@@ -134,7 +134,6 @@ bool MetalShaderCompiler::isParallelShaderCompileSupported() const noexcept {
|
||||
case ShaderLanguage::ESSL3:
|
||||
case ShaderLanguage::SPIRV:
|
||||
case ShaderLanguage::WGSL:
|
||||
case ShaderLanguage::UNSPECIFIED:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -155,11 +155,9 @@ id<MTLSamplerState> SamplerStateCreator::operator()(id<MTLDevice> device,
|
||||
// Older Apple devices (and the simulator) don't support setting a comparison function in
|
||||
// MTLSamplerDescriptor.
|
||||
// In practice, this means shadows are not supported when running in the simulator.
|
||||
if (samplerDescriptor.compareFunction != MTLCompareFunctionNever) {
|
||||
if (![device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v1]) {
|
||||
LOG(WARNING) << "Warning: sample comparison not supported by this GPU";
|
||||
samplerDescriptor.compareFunction = MTLCompareFunctionNever;
|
||||
}
|
||||
if (![device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v1]) {
|
||||
LOG(WARNING) << "Warning: sample comparison not supported by this GPU";
|
||||
samplerDescriptor.compareFunction = MTLCompareFunctionNever;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user