Compare commits
21
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5462621eb | ||
|
|
e2b195706a | ||
|
|
3ebb2086ed | ||
|
|
052092f553 | ||
|
|
7163aaa627 | ||
|
|
0c7ff3fcf4 | ||
|
|
962756e283 | ||
|
|
48ee727c8d | ||
|
|
2d1e4b8ce2 | ||
|
|
749b03ed2a | ||
|
|
497a1cc42d | ||
|
|
256a494cd0 | ||
|
|
b2531fff15 | ||
|
|
f18afe1d3e | ||
|
|
771eb4c1a4 | ||
|
|
70e7cb2a27 | ||
|
|
f95f127495 | ||
|
|
c0d63e826d | ||
|
|
36583618f1 | ||
|
|
9d322e7208 | ||
|
|
b897d22d20 |
@@ -11,24 +11,13 @@ runs:
|
||||
echo "set man-db/auto-update false" | sudo debconf-communicate
|
||||
sudo dpkg-reconfigure man-db
|
||||
|
||||
# Install ninja
|
||||
source ./build/common/get-ninja.sh
|
||||
|
||||
# Install CMake
|
||||
mkdir -p cmake
|
||||
cd cmake
|
||||
|
||||
sudo wget https://github.com/Kitware/CMake/releases/download/v$GITHUB_CMAKE_VERSION/cmake-$GITHUB_CMAKE_VERSION-Linux-x86_64.sh
|
||||
sudo chmod +x ./cmake-$GITHUB_CMAKE_VERSION-Linux-x86_64.sh
|
||||
sudo ./cmake-$GITHUB_CMAKE_VERSION-Linux-x86_64.sh --skip-license > /dev/null
|
||||
sudo update-alternatives --install /usr/bin/cmake cmake $(pwd)/bin/cmake 1000 --force
|
||||
|
||||
cd ..
|
||||
|
||||
sudo wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||
sudo apt-get update
|
||||
sudo apt-get install clang-$GITHUB_CLANG_VERSION libc++-$GITHUB_CLANG_VERSION-dev libc++abi-$GITHUB_CLANG_VERSION-dev
|
||||
sudo apt-get install mesa-common-dev libxi-dev libxxf86vm-dev
|
||||
sudo apt-get install cmake ninja-build
|
||||
|
||||
# For dawn
|
||||
sudo apt-get install libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libx11-xcb-dev
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM python:3.10.4
|
||||
FROM python:3.12.13
|
||||
|
||||
RUN pip3 install pygithub==1.55
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ runs:
|
||||
uses: actions/cache@v4 # Use a specific version
|
||||
with:
|
||||
path: emsdk
|
||||
key: ${{ runner.os }}-emsdk-${{ env.GITHUB_EMSDK_VERSION }}
|
||||
key: ${{ runner.os }}-${{ runner.arch }}-emsdk-${{ env.GITHUB_EMSDK_VERSION }}
|
||||
- name: Install Web Prerequisites
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
# a branch on filament-assets.
|
||||
update-renderdiff-goldens:
|
||||
name: update-renderdiff-goldens
|
||||
runs-on: 'macos-14-xlarge'
|
||||
runs-on: 'macos-14'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -90,7 +90,7 @@ jobs:
|
||||
# filament-assets
|
||||
update-sizeguard:
|
||||
name: update-sizeguard
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
runs-on: 'ubuntu-24.04-4core'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
|
||||
@@ -12,8 +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-4core'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -26,8 +25,7 @@ jobs:
|
||||
|
||||
build-ios:
|
||||
name: build-ios
|
||||
runs-on: macos-14-xlarge
|
||||
|
||||
runs-on: 'macos-14'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -46,8 +44,7 @@ jobs:
|
||||
|
||||
build-linux:
|
||||
name: build-linux
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
|
||||
runs-on: 'arm-ubuntu-24.04-16core'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -58,13 +55,12 @@ jobs:
|
||||
cd build/linux && printf "y" | ./build.sh continuous
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: filament-linux
|
||||
path: out/filament-release-linux.tgz
|
||||
name: filament-arm-linux
|
||||
path: out/filament-release-arm-linux.tgz
|
||||
|
||||
build-mac:
|
||||
name: build-mac
|
||||
runs-on: macos-14-xlarge
|
||||
|
||||
runs-on: 'macos-14'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -77,14 +73,10 @@ jobs:
|
||||
with:
|
||||
name: filament-mac
|
||||
path: out/filament-release-darwin.tgz
|
||||
- name: Check public headers
|
||||
run: |
|
||||
test/check-headers/test.sh out/release/filament/include
|
||||
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
|
||||
runs-on: 'arm-ubuntu-24.04-16core'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -101,7 +93,7 @@ jobs:
|
||||
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-2022-32core
|
||||
runs-on: 'windows-2022'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
|
||||
+171
-11
@@ -8,10 +8,54 @@ on:
|
||||
branches:
|
||||
- main
|
||||
|
||||
# This will cancel in-flight runs when there is an update to a PR
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
# The conditional 'if' on each job is meant to skip presubmit jobs when a commit is pushed to main
|
||||
# and that commit is cryptographically "verified". Typically, a verified commit (like a GitHub UI
|
||||
# squash-and-merge) has already passed through presubmit during the Pull Request phase.
|
||||
# The conditional explicitly checks:
|
||||
# 1. always() && !cancelled(): Ensures the job runs even if 'check-verification' is skipped, but
|
||||
# aborts if the workflow was manually cancelled.
|
||||
# 2. github.event_name == 'pull_request': Presubmits should always run normally on PRs.
|
||||
# 3. github.event_name == 'push' && ...: If it's a push to main, it only runs if the
|
||||
# 'check-verification' job confirmed the commit is NOT verified.
|
||||
|
||||
jobs:
|
||||
check-verification:
|
||||
if: github.event_name == 'push'
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
verified: ${{ steps.check.outputs.verified }}
|
||||
steps:
|
||||
- name: Check commit verification
|
||||
id: check
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const { data } = await github.rest.repos.getCommit({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
ref: context.sha
|
||||
});
|
||||
core.setOutput('verified', data.commit.verification.verified);
|
||||
|
||||
build-desktop-mac:
|
||||
name: build-mac
|
||||
runs-on: macos-14-xlarge
|
||||
runs-on: 'macos-14-xlarge'
|
||||
needs: [check-verification]
|
||||
if: >
|
||||
always() && !cancelled() &&
|
||||
(
|
||||
github.event_name == 'pull_request' ||
|
||||
(
|
||||
github.event_name == 'push' &&
|
||||
needs.check-verification.result == 'success' &&
|
||||
needs.check-verification.outputs.verified == 'false'
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -20,13 +64,30 @@ jobs:
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/mac && printf "y" | ./build.sh presubmit-with-test
|
||||
- name: Test material parser
|
||||
- name: Test - material parser
|
||||
run: |
|
||||
out/cmake-release/filament/test/test_material_parser
|
||||
- name: Test - public headers
|
||||
run: |
|
||||
# out/cmake-release should have the artifacts ready for installation. Here we install it
|
||||
# to test the public headers
|
||||
ninja -C out/cmake-release install
|
||||
test/check-headers/test.sh out/release/filament/include
|
||||
|
||||
build-desktop-linux:
|
||||
name: build-linux
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
runs-on: 'arm-ubuntu-24.04-16core'
|
||||
needs: [check-verification]
|
||||
if: >
|
||||
always() && !cancelled() &&
|
||||
(
|
||||
github.event_name == 'pull_request' ||
|
||||
(
|
||||
github.event_name == 'push' &&
|
||||
needs.check-verification.result == 'success' &&
|
||||
needs.check-verification.outputs.verified == 'false'
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -41,7 +102,18 @@ jobs:
|
||||
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-2022-32core
|
||||
runs-on: 'windows-2022'
|
||||
needs: [check-verification]
|
||||
if: >
|
||||
always() && !cancelled() &&
|
||||
(
|
||||
github.event_name == 'pull_request' ||
|
||||
(
|
||||
github.event_name == 'push' &&
|
||||
needs.check-verification.result == 'success' &&
|
||||
needs.check-verification.outputs.verified == 'false'
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -53,7 +125,18 @@ jobs:
|
||||
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
runs-on: 'ubuntu-24.04-4core'
|
||||
needs: [check-verification]
|
||||
if: >
|
||||
always() && !cancelled() &&
|
||||
(
|
||||
github.event_name == 'pull_request' ||
|
||||
(
|
||||
github.event_name == 'push' &&
|
||||
needs.check-verification.result == 'success' &&
|
||||
needs.check-verification.outputs.verified == 'false'
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -80,7 +163,18 @@ jobs:
|
||||
|
||||
build-ios:
|
||||
name: build-iOS
|
||||
runs-on: macos-14-xlarge
|
||||
runs-on: 'macos-14-xlarge'
|
||||
needs: [check-verification]
|
||||
if: >
|
||||
always() && !cancelled() &&
|
||||
(
|
||||
github.event_name == 'pull_request' ||
|
||||
(
|
||||
github.event_name == 'push' &&
|
||||
needs.check-verification.result == 'success' &&
|
||||
needs.check-verification.outputs.verified == 'false'
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -95,7 +189,18 @@ jobs:
|
||||
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
runs-on: 'arm-ubuntu-24.04-16core'
|
||||
needs: [check-verification]
|
||||
if: >
|
||||
always() && !cancelled() &&
|
||||
(
|
||||
github.event_name == 'pull_request' ||
|
||||
(
|
||||
github.event_name == 'push' &&
|
||||
needs.check-verification.result == 'success' &&
|
||||
needs.check-verification.outputs.verified == 'false'
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -108,7 +213,18 @@ jobs:
|
||||
|
||||
validate-docs:
|
||||
name: validate-docs
|
||||
runs-on: 'ubuntu-24.04-4core'
|
||||
runs-on: 'ubuntu-24.04'
|
||||
needs: [check-verification]
|
||||
if: >
|
||||
always() && !cancelled() &&
|
||||
(
|
||||
github.event_name == 'pull_request' ||
|
||||
(
|
||||
github.event_name == 'push' &&
|
||||
needs.check-verification.result == 'success' &&
|
||||
needs.check-verification.outputs.verified == 'false'
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -121,7 +237,18 @@ jobs:
|
||||
|
||||
test-renderdiff:
|
||||
name: test-renderdiff
|
||||
runs-on: macos-14-xlarge
|
||||
runs-on: 'macos-14-xlarge'
|
||||
needs: [check-verification]
|
||||
if: >
|
||||
always() && !cancelled() &&
|
||||
(
|
||||
github.event_name == 'pull_request' ||
|
||||
(
|
||||
github.event_name == 'push' &&
|
||||
needs.check-verification.result == 'success' &&
|
||||
needs.check-verification.outputs.verified == 'false'
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -190,7 +317,18 @@ jobs:
|
||||
|
||||
validate-wgsl-webgpu:
|
||||
name: validate-wgsl-webgpu
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
runs-on: 'arm-ubuntu-24.04-16core'
|
||||
needs: [check-verification]
|
||||
if: >
|
||||
always() && !cancelled() &&
|
||||
(
|
||||
github.event_name == 'pull_request' ||
|
||||
(
|
||||
github.event_name == 'push' &&
|
||||
needs.check-verification.result == 'success' &&
|
||||
needs.check-verification.outputs.verified == 'false'
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -204,6 +342,17 @@ jobs:
|
||||
test-code-correctness:
|
||||
name: test-code-correctness
|
||||
runs-on: 'macos-14-xlarge'
|
||||
needs: [check-verification]
|
||||
if: >
|
||||
always() && !cancelled() &&
|
||||
(
|
||||
github.event_name == 'pull_request' ||
|
||||
(
|
||||
github.event_name == 'push' &&
|
||||
needs.check-verification.result == 'success' &&
|
||||
needs.check-verification.outputs.verified == 'false'
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
@@ -224,7 +373,18 @@ jobs:
|
||||
|
||||
test-backend:
|
||||
name: test-backend
|
||||
runs-on: macos-14-xlarge
|
||||
runs-on: 'macos-14-xlarge'
|
||||
needs: [check-verification]
|
||||
if: >
|
||||
always() && !cancelled() &&
|
||||
(
|
||||
github.event_name == 'pull_request' ||
|
||||
(
|
||||
github.event_name == 'push' &&
|
||||
needs.check-verification.result == 'success' &&
|
||||
needs.check-verification.outputs.verified == 'false'
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
|
||||
@@ -63,6 +63,39 @@ jobs:
|
||||
const globber = await glob.create('out/*.tgz');
|
||||
await upload({ github, context }, await globber.glob(), TAG);
|
||||
|
||||
build-arm-linux:
|
||||
name: build-arm-linux
|
||||
runs-on: 'arm-ubuntu-24.04-16core'
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'desktop'
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
id: git_ref
|
||||
run: |
|
||||
REF=${RELEASE_TAG:-${GITHUB_REF}}
|
||||
TAG=${REF##*/}
|
||||
echo "ref=${REF}" >> $GITHUB_OUTPUT
|
||||
echo "tag=${TAG}" >> $GITHUB_OUTPUT
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- uses: ./.github/actions/linux-prereq
|
||||
- name: Run build script
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
run: |
|
||||
cd build/linux && printf "y" | ./build.sh release
|
||||
cd ../..
|
||||
mv out/filament-release-linux.tgz out/filament-${TAG}-arm-linux.tgz
|
||||
- uses: actions/github-script@v6
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
with:
|
||||
script: |
|
||||
const upload = require('./build/common/upload-release-assets');
|
||||
const { TAG } = process.env;
|
||||
const globber = await glob.create('out/*.tgz');
|
||||
await upload({ github, context }, await globber.glob(), TAG);
|
||||
|
||||
build-mac:
|
||||
name: build-mac
|
||||
runs-on: macos-14-xlarge
|
||||
@@ -99,7 +132,7 @@ jobs:
|
||||
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: 'ubuntu-24.04-16core'
|
||||
runs-on: 'arm-ubuntu-24.04-16core'
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'web'
|
||||
|
||||
steps:
|
||||
|
||||
@@ -11,14 +11,11 @@ jobs:
|
||||
name: Verify Release Notes
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# We *only* need to check out the .github/ directory.
|
||||
# The verify RELEASE_NOTES script uses the GitHub API to verify that RELEASE_NOTES was
|
||||
# modified.
|
||||
- name: Check out action
|
||||
uses: Bhacaz/checkout-files@73e17cfbe8d7e0c6b2672b20cb05a718e20d18d4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
files: .github
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
fetch-depth: 0
|
||||
sparse-checkout: |
|
||||
.github
|
||||
- name: Verify release notes
|
||||
uses: ./.github/actions/verify-release-notes
|
||||
with:
|
||||
|
||||
+10
-3
@@ -326,11 +326,13 @@ endif()
|
||||
if (FILAMENT_ENABLE_LTO)
|
||||
include(CheckIPOSupported)
|
||||
|
||||
check_ipo_supported(RESULT IPO_SUPPORT)
|
||||
check_ipo_supported(RESULT IPO_SUPPORT OUTPUT IPO_ERROR)
|
||||
|
||||
if (IPO_SUPPORT)
|
||||
message(STATUS "LTO support is enabled")
|
||||
message(STATUS "IPO / LTO is enabled")
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
else()
|
||||
message(WARNING "IPO / LTO is not supported by this architecture: ${IPO_ERROR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -867,6 +869,12 @@ endfunction()
|
||||
# Sub-projects
|
||||
# ==================================================================================================
|
||||
|
||||
include(CheckSymbolExists)
|
||||
check_symbol_exists(getopt_long "getopt.h" HAS_SYSTEM_GETOPT)
|
||||
if (NOT HAS_SYSTEM_GETOPT)
|
||||
add_subdirectory(${EXTERNAL}/getopt)
|
||||
endif()
|
||||
|
||||
# Common to all platforms
|
||||
add_subdirectory(${EXTERNAL}/libgtest/tnt)
|
||||
add_subdirectory(${LIBRARIES}/camutils)
|
||||
@@ -902,7 +910,6 @@ add_subdirectory(${EXTERNAL}/cgltf/tnt)
|
||||
add_subdirectory(${EXTERNAL}/draco/tnt)
|
||||
add_subdirectory(${EXTERNAL}/jsmn/tnt)
|
||||
add_subdirectory(${EXTERNAL}/stb/tnt)
|
||||
add_subdirectory(${EXTERNAL}/getopt)
|
||||
add_subdirectory(${EXTERNAL}/perfetto/tnt)
|
||||
add_subdirectory(${EXTERNAL}/basisu/tnt)
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#include <imagediff/ImageDiff.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace imagediff;
|
||||
using namespace utils;
|
||||
|
||||
@@ -102,30 +100,48 @@ jobject createResult(JNIEnv* env, ImageDiffResult const& result, bool generateDi
|
||||
|
||||
if (generateDiff && result.diffImage.getWidth() > 0) {
|
||||
jclass bitmapClass = env->FindClass("android/graphics/Bitmap");
|
||||
jmethodID createBitmap = env->GetStaticMethodID(bitmapClass, "createBitmap",
|
||||
jmethodID createBitmap = env->GetStaticMethodID(bitmapClass, "createBitmap",
|
||||
"(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
|
||||
|
||||
|
||||
jclass configClass = env->FindClass("android/graphics/Bitmap$Config");
|
||||
jfieldID argb8888 = env->GetStaticFieldID(configClass, "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
|
||||
jobject configObj = env->GetStaticObjectField(configClass, argb8888);
|
||||
|
||||
uint32_t width = result.diffImage.getWidth();
|
||||
uint32_t height = result.diffImage.getHeight();
|
||||
jobject diffBitmap = env->CallStaticObjectMethod(bitmapClass, createBitmap, (jint)width, (jint)height, configObj);
|
||||
|
||||
jobject diffBitmap = env->CallStaticObjectMethod(bitmapClass, createBitmap, (jint) width,
|
||||
(jint) height, configObj);
|
||||
|
||||
if (diffBitmap) {
|
||||
// We need to transport the bit differences accurately to the java side, so set
|
||||
// premultiplied to false. From the java-side, if the bitmap is used to draw to a
|
||||
// canvas, then client needs to set premultiplied to true again.
|
||||
jmethodID setPremultiplied = env->GetMethodID(bitmapClass, "setPremultiplied", "(Z)V");
|
||||
if (setPremultiplied) {
|
||||
env->CallVoidMethod(diffBitmap, setPremultiplied, JNI_FALSE);
|
||||
}
|
||||
|
||||
void* diffPixels;
|
||||
if (AndroidBitmap_lockPixels(env, diffBitmap, &diffPixels) == 0) {
|
||||
AndroidBitmapInfo info;
|
||||
AndroidBitmap_getInfo(env, diffBitmap, &info);
|
||||
|
||||
float const* src = result.diffImage.getPixelRef();
|
||||
uint8_t* dst = (uint8_t*) diffPixels;
|
||||
uint32_t channels = result.diffImage.getChannels(); // usually 4
|
||||
|
||||
for (size_t i = 0; i < width * height; ++i) {
|
||||
for (int c = 0; c < 4; ++c) {
|
||||
float v = 0.0f;
|
||||
if (c < channels) v = src[i * channels + c];
|
||||
if (c == 3 && channels < 4) v = 1.0f; // Alpha 1.0 if missing
|
||||
dst[i * 4 + c] = (uint8_t) std::min(255.0f, std::max(0.0f, v * 255.0f));
|
||||
uint32_t const channels = result.diffImage.getChannels(); // usually 4
|
||||
|
||||
for (size_t y = 0; y < height; ++y) {
|
||||
uint8_t* row = dst + y * info.stride;
|
||||
for (size_t x = 0; x < width; ++x) {
|
||||
size_t srcIdx = (y * width + x) * channels;
|
||||
for (int c = 0; c < 4; ++c) {
|
||||
float v = 0.0f;
|
||||
if (c < channels) v = src[srcIdx + c];
|
||||
if (c == 3 && channels < 4) v = 1.0f; // Alpha 1.0 if missing
|
||||
|
||||
row[x * 4 + c] = uint8_t(
|
||||
std::min(255.0f, std::max(0.0f, std::round(v * 255.0f))));
|
||||
}
|
||||
}
|
||||
}
|
||||
AndroidBitmap_unlockPixels(env, diffBitmap);
|
||||
@@ -133,7 +149,7 @@ jobject createResult(JNIEnv* env, ImageDiffResult const& result, bool generateDi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return resultObj;
|
||||
}
|
||||
|
||||
@@ -147,7 +163,7 @@ Java_com_google_android_filament_utils_ImageDiff_nCompareBasic(JNIEnv* env, jcla
|
||||
BitmapLock maskArg(env, maskBitmap);
|
||||
|
||||
if (!refArg.isValid() || !candArg.isValid()) {
|
||||
ImageDiffResult emptyResult;
|
||||
ImageDiffResult emptyResult;
|
||||
emptyResult.status = ImageDiffResult::Status::SIZE_MISMATCH; // or ERROR
|
||||
return createResult(env, emptyResult, false);
|
||||
}
|
||||
@@ -175,13 +191,13 @@ Java_com_google_android_filament_utils_ImageDiff_nCompareBasic(JNIEnv* env, jcla
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_com_google_android_filament_utils_ImageDiff_nCompareJson(JNIEnv* env, jclass,
|
||||
jobject refBitmap, jobject candBitmap, jstring jsonConfig, jobject maskBitmap) {
|
||||
|
||||
|
||||
BitmapLock refArg(env, refBitmap);
|
||||
BitmapLock candArg(env, candBitmap);
|
||||
BitmapLock maskArg(env, maskBitmap);
|
||||
|
||||
if (!refArg.isValid() || !candArg.isValid()) {
|
||||
ImageDiffResult emptyResult;
|
||||
ImageDiffResult emptyResult;
|
||||
emptyResult.status = ImageDiffResult::Status::SIZE_MISMATCH; // or ERROR
|
||||
return createResult(env, emptyResult, false);
|
||||
}
|
||||
@@ -189,7 +205,7 @@ Java_com_google_android_filament_utils_ImageDiff_nCompareJson(JNIEnv* env, jclas
|
||||
ImageDiffConfig config;
|
||||
const char* nativeJson = env->GetStringUTFChars(jsonConfig, 0);
|
||||
size_t length = env->GetStringUTFLength(jsonConfig);
|
||||
|
||||
|
||||
bool parsed = parseConfig(nativeJson, length, &config);
|
||||
env->ReleaseStringUTFChars(jsonConfig, nativeJson);
|
||||
|
||||
@@ -214,4 +230,3 @@ Java_com_google_android_filament_utils_ImageDiff_nCompareJson(JNIEnv* env, jclas
|
||||
|
||||
return createResult(env, result, generateDiff);
|
||||
}
|
||||
|
||||
|
||||
+221
-4
@@ -66,10 +66,26 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
private lateinit var inputManager: ValidationInputManager
|
||||
private var currentInput: ValidationInputManager.ValidationInput? = null
|
||||
|
||||
private var currentAlphaDiffBitmap: Bitmap? = null
|
||||
private var globalEnhancementFactor: Float = 1.0f
|
||||
|
||||
private data class TestImages(
|
||||
val testName: String,
|
||||
val golden: Bitmap?,
|
||||
val rendered: Bitmap?,
|
||||
val diff: Bitmap?,
|
||||
val alphaDiff: Bitmap?
|
||||
)
|
||||
|
||||
private val diffImageViews = mutableListOf<ImageView>()
|
||||
|
||||
// UI Elements
|
||||
private lateinit var runButton: Button
|
||||
private lateinit var loadButton: Button
|
||||
private lateinit var optionsButton: Button
|
||||
private lateinit var enhancementContainer: LinearLayout
|
||||
private lateinit var enhancementLabel: TextView
|
||||
private lateinit var enhancementSlider: android.widget.SeekBar
|
||||
|
||||
private var resultManager: ValidationResultManager? = null
|
||||
private var validationRunner: ValidationRunner? = null
|
||||
@@ -98,6 +114,19 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
runButton = findViewById(R.id.run_button)
|
||||
loadButton = findViewById(R.id.load_button)
|
||||
optionsButton = findViewById(R.id.options_button)
|
||||
enhancementContainer = findViewById(R.id.enhancement_container)
|
||||
enhancementLabel = findViewById(R.id.enhancement_label)
|
||||
enhancementSlider = findViewById(R.id.enhancement_slider)
|
||||
|
||||
enhancementSlider.setOnSeekBarChangeListener(object : android.widget.SeekBar.OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: android.widget.SeekBar?, progress: Int, fromUser: Boolean) {
|
||||
globalEnhancementFactor = 1.0f + (progress / 100f) * 49.0f
|
||||
enhancementLabel.text = String.format(Locale.US, "Enhancement: %.1fx", globalEnhancementFactor)
|
||||
applyGlobalEnhancement()
|
||||
}
|
||||
override fun onStartTrackingTouch(seekBar: android.widget.SeekBar?) {}
|
||||
override fun onStopTrackingTouch(seekBar: android.widget.SeekBar?) {}
|
||||
})
|
||||
|
||||
// Setup Run Button
|
||||
runButton.setOnClickListener {
|
||||
@@ -120,6 +149,7 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
popup.menu.add(0, 3, 0, "Export Result")
|
||||
popup.menu.add(0, 4, 0, "Test ADB Info")
|
||||
popup.menu.add(0, 5, 0, "Result ADB Info")
|
||||
popup.menu.add(0, 6, 0, "Toggle Enhancement Slider")
|
||||
|
||||
popup.setOnMenuItemClickListener { item ->
|
||||
when (item.itemId) {
|
||||
@@ -133,6 +163,9 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
3 -> exportTestResultsAction()
|
||||
4 -> showTestAdbInfo()
|
||||
5 -> showResultAdbInfo()
|
||||
6 -> {
|
||||
enhancementContainer.visibility = if (enhancementContainer.visibility == View.VISIBLE) View.GONE else View.VISIBLE
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
@@ -256,6 +289,7 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
|
||||
// Clear existing results UI and state
|
||||
resultsContainer.removeAllViews()
|
||||
diffImageViews.clear()
|
||||
resultManager = null
|
||||
|
||||
val newInput = ValidationInputManager.ValidationInput(
|
||||
@@ -337,6 +371,8 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
private fun startValidation(input: ValidationInputManager.ValidationInput) {
|
||||
try {
|
||||
resultsContainer.removeAllViews()
|
||||
diffImageViews.clear()
|
||||
enhancementSlider.isEnabled = false
|
||||
Log.i(TAG, "Starting validation with config: ${input.config.name}")
|
||||
Log.i(TAG, "Output dir: ${input.outputDir.absolutePath}")
|
||||
|
||||
@@ -420,7 +456,15 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
val imagesRow = LinearLayout(this)
|
||||
imagesRow.orientation = LinearLayout.HORIZONTAL
|
||||
|
||||
fun addImage(label: String, bitmap: Bitmap?) {
|
||||
val testImages = TestImages(
|
||||
testName = result.testName,
|
||||
golden = currentGoldenBitmap,
|
||||
rendered = currentRenderedBitmap,
|
||||
diff = currentDiffBitmap,
|
||||
alphaDiff = currentAlphaDiffBitmap
|
||||
)
|
||||
|
||||
fun addImage(label: String, bitmap: Bitmap?, isDiff: Boolean) {
|
||||
if (bitmap != null) {
|
||||
val container = LinearLayout(this)
|
||||
container.orientation = LinearLayout.VERTICAL
|
||||
@@ -436,16 +480,29 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
iv.layoutParams = LinearLayout.LayoutParams(250, 250) // Smaller thumbnails
|
||||
iv.scaleType = ImageView.ScaleType.FIT_CENTER
|
||||
iv.setBackgroundColor(0xFF404040.toInt())
|
||||
|
||||
if (isDiff) {
|
||||
diffImageViews.add(iv)
|
||||
applyEnhancementToView(iv, globalEnhancementFactor)
|
||||
}
|
||||
|
||||
iv.setOnClickListener {
|
||||
showImageDialog(testImages, label)
|
||||
}
|
||||
|
||||
container.addView(iv)
|
||||
|
||||
imagesRow.addView(container)
|
||||
}
|
||||
}
|
||||
|
||||
addImage("Rendered", currentRenderedBitmap)
|
||||
addImage("Golden", currentGoldenBitmap)
|
||||
addImage("Rendered", currentRenderedBitmap, false)
|
||||
addImage("Golden", currentGoldenBitmap, false)
|
||||
if (!result.passed) {
|
||||
addImage("Diff", currentDiffBitmap)
|
||||
addImage("Diff", currentDiffBitmap, true)
|
||||
}
|
||||
if (currentAlphaDiffBitmap != null) {
|
||||
addImage("Alpha Diff", currentAlphaDiffBitmap, true)
|
||||
}
|
||||
|
||||
resultContainer.addView(imagesRow)
|
||||
@@ -455,12 +512,14 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
currentRenderedBitmap = null
|
||||
currentGoldenBitmap = null
|
||||
currentDiffBitmap = null
|
||||
currentAlphaDiffBitmap = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAllTestsFinished() {
|
||||
runOnUiThread {
|
||||
statusTextView.text = "All tests finished!"
|
||||
enhancementSlider.isEnabled = true
|
||||
Log.i(TAG, "All tests finished " + if (currentInput?.autoExport == true) "Exporting bundle" else "x")
|
||||
|
||||
if (currentInput?.autoExport == true) {
|
||||
@@ -523,7 +582,165 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
"Diff" -> {
|
||||
currentDiffBitmap = bitmap
|
||||
}
|
||||
"Alpha Diff" -> {
|
||||
currentAlphaDiffBitmap = bitmap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyEnhancementToView(iv: ImageView, factor: Float) {
|
||||
val cm = android.graphics.ColorMatrix()
|
||||
cm.setScale(factor, factor, factor, 1.0f)
|
||||
iv.colorFilter = android.graphics.ColorMatrixColorFilter(cm)
|
||||
}
|
||||
|
||||
private fun applyGlobalEnhancement() {
|
||||
for (iv in diffImageViews) {
|
||||
applyEnhancementToView(iv, globalEnhancementFactor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showImageDialog(images: TestImages, initialLabel: String) {
|
||||
val dialogView = layoutInflater.inflate(R.layout.dialog_image_viewer, null)
|
||||
val dialog = AlertDialog.Builder(this)
|
||||
.setView(dialogView)
|
||||
.create()
|
||||
|
||||
val titleView = dialogView.findViewById<TextView>(R.id.dialog_title)
|
||||
val typeView = dialogView.findViewById<TextView>(R.id.dialog_image_type)
|
||||
val imageView = dialogView.findViewById<ImageView>(R.id.dialog_image)
|
||||
val btnClose = dialogView.findViewById<View>(R.id.btn_close)
|
||||
val btnReset = dialogView.findViewById<View>(R.id.btn_reset)
|
||||
val btnPrev = dialogView.findViewById<View>(R.id.btn_prev)
|
||||
val btnNext = dialogView.findViewById<View>(R.id.btn_next)
|
||||
|
||||
val enhancementContainer = dialogView.findViewById<View>(R.id.dialog_enhancement_container)
|
||||
val enhancementLabel = dialogView.findViewById<TextView>(R.id.dialog_enhancement_label)
|
||||
val enhancementSlider = dialogView.findViewById<android.widget.SeekBar>(R.id.dialog_enhancement_slider)
|
||||
|
||||
titleView.text = images.testName
|
||||
|
||||
val availableImages = mutableListOf<Pair<String, Bitmap>>()
|
||||
images.rendered?.let { availableImages.add(Pair("Rendered", it)) }
|
||||
images.golden?.let { availableImages.add(Pair("Golden", it)) }
|
||||
images.diff?.let { availableImages.add(Pair("Diff", it)) }
|
||||
images.alphaDiff?.let { availableImages.add(Pair("Alpha Diff", it)) }
|
||||
|
||||
if (availableImages.isEmpty()) return
|
||||
|
||||
var currentIndex = availableImages.indexOfFirst { it.first == initialLabel }
|
||||
if (currentIndex == -1) currentIndex = 0
|
||||
|
||||
var currentDialogEnhancement = globalEnhancementFactor
|
||||
|
||||
val matrix = android.graphics.Matrix()
|
||||
// Save initial values for translation tracking
|
||||
var lastTouchX = 0f
|
||||
var lastTouchY = 0f
|
||||
var isDragging = false
|
||||
|
||||
val scaleDetector = android.view.ScaleGestureDetector(this, object : android.view.ScaleGestureDetector.SimpleOnScaleGestureListener() {
|
||||
override fun onScale(detector: android.view.ScaleGestureDetector): Boolean {
|
||||
matrix.postScale(detector.scaleFactor, detector.scaleFactor, detector.focusX, detector.focusY)
|
||||
imageView.imageMatrix = matrix
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
imageView.setOnTouchListener { _, event ->
|
||||
scaleDetector.onTouchEvent(event)
|
||||
when (event.actionMasked) {
|
||||
android.view.MotionEvent.ACTION_DOWN -> {
|
||||
lastTouchX = event.x
|
||||
lastTouchY = event.y
|
||||
isDragging = true
|
||||
}
|
||||
android.view.MotionEvent.ACTION_MOVE -> {
|
||||
if (isDragging && !scaleDetector.isInProgress) {
|
||||
val dx = event.x - lastTouchX
|
||||
val dy = event.y - lastTouchY
|
||||
matrix.postTranslate(dx, dy)
|
||||
imageView.imageMatrix = matrix
|
||||
}
|
||||
lastTouchX = event.x
|
||||
lastTouchY = event.y
|
||||
}
|
||||
android.view.MotionEvent.ACTION_UP, android.view.MotionEvent.ACTION_CANCEL -> {
|
||||
isDragging = false
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fun updateView() {
|
||||
val (label, bitmap) = availableImages[currentIndex]
|
||||
typeView.text = label
|
||||
imageView.setImageBitmap(bitmap)
|
||||
(imageView.drawable as? android.graphics.drawable.BitmapDrawable)?.setAntiAlias(false)
|
||||
(imageView.drawable as? android.graphics.drawable.BitmapDrawable)?.setFilterBitmap(false)
|
||||
imageView.imageMatrix = matrix
|
||||
|
||||
if (label == "Diff" || label == "Alpha Diff") {
|
||||
enhancementContainer.visibility = View.VISIBLE
|
||||
applyEnhancementToView(imageView, currentDialogEnhancement)
|
||||
} else {
|
||||
enhancementContainer.visibility = View.GONE
|
||||
imageView.colorFilter = null
|
||||
}
|
||||
}
|
||||
|
||||
fun resetMatrix() {
|
||||
val drawable = imageView.drawable ?: return
|
||||
val width = imageView.width.toFloat()
|
||||
val height = imageView.height.toFloat()
|
||||
val dw = drawable.intrinsicWidth.toFloat()
|
||||
val dh = drawable.intrinsicHeight.toFloat()
|
||||
|
||||
val scaleX = width / dw
|
||||
val scaleY = height / dh
|
||||
val scale = Math.min(scaleX, scaleY)
|
||||
|
||||
val dx = (width - dw * scale) / 2f
|
||||
val dy = (height - dh * scale) / 2f
|
||||
|
||||
matrix.reset()
|
||||
matrix.postScale(scale, scale)
|
||||
matrix.postTranslate(dx, dy)
|
||||
imageView.imageMatrix = matrix
|
||||
}
|
||||
|
||||
btnClose.setOnClickListener { dialog.dismiss() }
|
||||
btnReset.setOnClickListener { resetMatrix() }
|
||||
btnPrev.setOnClickListener {
|
||||
currentIndex = (currentIndex - 1 + availableImages.size) % availableImages.size
|
||||
updateView()
|
||||
}
|
||||
btnNext.setOnClickListener {
|
||||
currentIndex = (currentIndex + 1) % availableImages.size
|
||||
updateView()
|
||||
}
|
||||
|
||||
val defaultProgress = ((currentDialogEnhancement - 1.0f) / 49.0f * 100).toInt()
|
||||
val safeProgress = Math.max(0, Math.min(100, defaultProgress))
|
||||
enhancementSlider.progress = safeProgress
|
||||
enhancementLabel.text = String.format(Locale.US, "Enhance: %.1fx", currentDialogEnhancement)
|
||||
|
||||
enhancementSlider.setOnSeekBarChangeListener(object : android.widget.SeekBar.OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: android.widget.SeekBar?, progress: Int, fromUser: Boolean) {
|
||||
currentDialogEnhancement = 1.0f + (progress / 100f) * 49.0f
|
||||
enhancementLabel.text = String.format(Locale.US, "Enhance: %.1fx", currentDialogEnhancement)
|
||||
updateView()
|
||||
}
|
||||
override fun onStartTrackingTouch(seekBar: android.widget.SeekBar?) {}
|
||||
override fun onStopTrackingTouch(seekBar: android.widget.SeekBar?) {}
|
||||
})
|
||||
|
||||
imageView.post {
|
||||
resetMatrix()
|
||||
}
|
||||
|
||||
updateView()
|
||||
dialog.show()
|
||||
}
|
||||
}
|
||||
|
||||
+47
-8
@@ -115,10 +115,6 @@ class ValidationRunner(
|
||||
}
|
||||
|
||||
fun onFrame(frameTimeNanos: Long) {
|
||||
if (frameCounter % 60 == 0) {
|
||||
Log.i("ValidationRunner", "onFrame: $currentState (frame: $frameCounter)")
|
||||
}
|
||||
|
||||
when (currentState) {
|
||||
State.IDLE -> {}
|
||||
State.WAITING_FOR_RESOURCES -> {
|
||||
@@ -136,7 +132,6 @@ class ValidationRunner(
|
||||
}
|
||||
}
|
||||
State.RUNNING_TEST -> {
|
||||
// Log.i("ValidationRunner", "Running test...")
|
||||
currentEngine?.let { engine ->
|
||||
val content = AutomationEngine.ViewerContent()
|
||||
content.view = modelViewer.view
|
||||
@@ -257,10 +252,54 @@ class ValidationRunner(
|
||||
passed = (result.status == ImageDiff.Result.Status.PASSED)
|
||||
diffMetric = result.failingPixelCount.toFloat()
|
||||
|
||||
if (!passed) {
|
||||
if (!passed) {
|
||||
if (result.diffImage != null) {
|
||||
callback?.onImageResult("Diff", result.diffImage!!)
|
||||
resultManager.saveImage("${testFullName}_diff", result.diffImage!!)
|
||||
val diffImg = result.diffImage!!
|
||||
val width = diffImg.width
|
||||
val height = diffImg.height
|
||||
val pixels = IntArray(width * height)
|
||||
diffImg.getPixels(pixels, 0, width, 0, 0, width, height)
|
||||
|
||||
var hasAlphaDiff = false
|
||||
val alphaPixels = IntArray(width * height)
|
||||
|
||||
for (i in pixels.indices) {
|
||||
val color = pixels[i]
|
||||
|
||||
val a = android.graphics.Color.alpha(color)
|
||||
val r = android.graphics.Color.red(color)
|
||||
val g = android.graphics.Color.green(color)
|
||||
val b = android.graphics.Color.blue(color)
|
||||
|
||||
if (a > 0) {
|
||||
hasAlphaDiff = true
|
||||
}
|
||||
|
||||
// Map alpha diff to grayscale RGB
|
||||
alphaPixels[i] = android.graphics.Color.argb(255, a, a, a)
|
||||
|
||||
// Force main diff image alpha to 255
|
||||
pixels[i] = android.graphics.Color.argb(255, r, g, b)
|
||||
}
|
||||
|
||||
// Apply updated pixels to diff image
|
||||
diffImg.setPixels(pixels, 0, width, 0, 0, width, height)
|
||||
|
||||
// The C++ ImageDiff code sets isPremultiplied to false so Android
|
||||
// doesn't erase RGB diff values when Alpha diff is 0. However, Android's
|
||||
// Canvas will crash if we try to draw a non-premultiplied bitmap.
|
||||
// Since we just forced all alpha values to 255 (fully opaque) in the
|
||||
// loop above, we can safely mark it as premultiplied again here.
|
||||
diffImg.isPremultiplied = true
|
||||
callback?.onImageResult("Diff", diffImg)
|
||||
resultManager.saveImage("${testFullName}_diff", diffImg)
|
||||
|
||||
if (hasAlphaDiff) {
|
||||
val alphaDiffImg = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
alphaDiffImg.setPixels(alphaPixels, 0, width, 0, 0, width, height)
|
||||
callback?.onImageResult("Alpha Diff", alphaDiffImg)
|
||||
resultManager.saveImage("${testFullName}_alpha_diff", alphaDiffImg)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -81,6 +81,33 @@
|
||||
android:contentDescription="More Options"
|
||||
android:layout_marginStart="8dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Global Enhancement Controls (Hidden by default) -->
|
||||
<LinearLayout
|
||||
android:id="@+id/enhancement_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:visibility="gone"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/enhancement_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Enhancement: 1.0x"
|
||||
android:textSize="12sp"
|
||||
android:minWidth="120dp" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/enhancement_slider"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:max="100"
|
||||
android:progress="0" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="#FF202020"
|
||||
android:padding="8dp">
|
||||
|
||||
<!-- Header with title and close button -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Test Result"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
<ImageButton
|
||||
android:id="@+id/btn_close"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@android:drawable/ic_menu_close_clear_cancel" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Subtitle for Image Type -->
|
||||
<TextView
|
||||
android:id="@+id/dialog_image_type"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start"
|
||||
android:text="Rendered"
|
||||
android:textColor="#BBBBBB"
|
||||
android:textSize="14sp"
|
||||
android:paddingBottom="8dp" />
|
||||
|
||||
<!-- Image Area with Arrows -->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<FrameLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintDimensionRatio="1:1">
|
||||
<ImageView
|
||||
android:id="@+id/dialog_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="matrix" />
|
||||
</FrameLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<!-- Navigation Arrows -->
|
||||
<LinearLayout
|
||||
android:id="@+id/dialog_arrow_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btn_prev"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@android:drawable/ic_media_previous"
|
||||
app:tint="#FFFFFF" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btn_reset"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@android:drawable/ic_menu_revert"
|
||||
app:tint="#FFFFFF" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btn_next"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@android:drawable/ic_media_next"
|
||||
app:tint="#FFFFFF" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Enhancement Controls (only for diff images) -->
|
||||
<LinearLayout
|
||||
android:id="@+id/dialog_enhancement_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_enhancement_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Enhance: 1.0x"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="12sp"
|
||||
android:minWidth="100dp" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/dialog_enhancement_slider"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:max="100"
|
||||
android:progress="0" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -46,6 +46,7 @@ list(SORT NDK_VERSIONS)
|
||||
list(GET NDK_VERSIONS -1 NDK_VERSION)
|
||||
get_filename_component(NDK_VERSION ${NDK_VERSION} NAME)
|
||||
set(TOOLCHAIN ${ANDROID_HOME_UNIX}/ndk/${NDK_VERSION}/toolchains/llvm/prebuilt/${HOST_NAME_L}-x86_64)
|
||||
set(CMAKE_ANDROID_NDK_VERSION ${NDK_VERSION})
|
||||
|
||||
# specify the cross compiler
|
||||
set(COMPILER_SUFFIX)
|
||||
|
||||
@@ -47,6 +47,7 @@ list(SORT NDK_VERSIONS)
|
||||
list(GET NDK_VERSIONS -1 NDK_VERSION)
|
||||
get_filename_component(NDK_VERSION ${NDK_VERSION} NAME)
|
||||
set(TOOLCHAIN ${ANDROID_HOME_UNIX}/ndk/${NDK_VERSION}/toolchains/llvm/prebuilt/${HOST_NAME_L}-x86_64)
|
||||
set(CMAKE_ANDROID_NDK_VERSION ${NDK_VERSION})
|
||||
|
||||
# specify the cross compiler
|
||||
set(COMPILER_SUFFIX)
|
||||
|
||||
@@ -46,6 +46,7 @@ list(SORT NDK_VERSIONS)
|
||||
list(GET NDK_VERSIONS -1 NDK_VERSION)
|
||||
get_filename_component(NDK_VERSION ${NDK_VERSION} NAME)
|
||||
set(TOOLCHAIN ${ANDROID_HOME_UNIX}/ndk/${NDK_VERSION}/toolchains/llvm/prebuilt/${HOST_NAME_L}-x86_64)
|
||||
set(CMAKE_ANDROID_NDK_VERSION ${NDK_VERSION})
|
||||
|
||||
# specify the cross compiler
|
||||
set(COMPILER_SUFFIX)
|
||||
|
||||
@@ -46,6 +46,7 @@ list(SORT NDK_VERSIONS)
|
||||
list(GET NDK_VERSIONS -1 NDK_VERSION)
|
||||
get_filename_component(NDK_VERSION ${NDK_VERSION} NAME)
|
||||
set(TOOLCHAIN ${ANDROID_HOME_UNIX}/ndk/${NDK_VERSION}/toolchains/llvm/prebuilt/${HOST_NAME_L}-x86_64)
|
||||
set(CMAKE_ANDROID_NDK_VERSION ${NDK_VERSION})
|
||||
|
||||
# specify the cross compiler
|
||||
set(COMPILER_SUFFIX)
|
||||
|
||||
+2
-2
@@ -181,7 +181,7 @@ important for <code>matc</code> (material compiler).</p>
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.69.5'
|
||||
implementation 'com.google.android.filament:filament-android:1.70.0'
|
||||
}
|
||||
</code></pre>
|
||||
<p>Here are all the libraries available in the group <code>com.google.android.filament</code>:</p>
|
||||
@@ -195,7 +195,7 @@ 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.69.5'
|
||||
<pre><code class="language-shell">pod 'Filament', '~> 1.70.0'
|
||||
</code></pre>
|
||||
<h2 id="documentation"><a class="header" href="#documentation">Documentation</a></h2>
|
||||
<ul>
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -616,7 +616,6 @@ if (FILAMENT_BUILD_TESTING)
|
||||
set(BACKEND_TEST_LIBS
|
||||
absl::str_format
|
||||
backend
|
||||
getopt
|
||||
gtest
|
||||
imageio
|
||||
filamat
|
||||
@@ -725,7 +724,6 @@ if (FILAMENT_BUILD_TESTING)
|
||||
|
||||
target_link_libraries(metal_utils_test PRIVATE
|
||||
backend
|
||||
getopt
|
||||
gtest
|
||||
)
|
||||
|
||||
|
||||
@@ -222,6 +222,7 @@ public:
|
||||
enum class DeviceInfoType {
|
||||
OPENGL_RENDERER, //!< glGetString(GL_RENDERER)
|
||||
OPENGL_VENDOR, //!< glGetString(GL_VENDOR)
|
||||
OPENGL_VERSION, //!< glGetString(GL_VERSION)
|
||||
VULKAN_DEVICE_NAME, //!< VkPhysicalDeviceProperties::deviceName
|
||||
VULKAN_DRIVER_NAME, //!< VkPhysicalDeviceDriverProperties::driverName
|
||||
VULKAN_DRIVER_INFO, //!< VkPhysicalDeviceDriverProperties::driverInfo
|
||||
|
||||
@@ -73,6 +73,12 @@ public:
|
||||
*/
|
||||
static utils::CString getRendererString(Driver const* UTILS_NONNULL driver);
|
||||
|
||||
/**
|
||||
* Return the OpenGL version string of the specified Driver instance.
|
||||
* @return The GL_VERSION string
|
||||
*/
|
||||
static utils::CString getVersionString(Driver const* UTILS_NONNULL driver);
|
||||
|
||||
/**
|
||||
* Called by the driver to destroy the OpenGL context. This should clean up any windows
|
||||
* or buffers from initialization. This is for instance where `eglDestroyContext` would be
|
||||
|
||||
@@ -159,6 +159,12 @@ protected:
|
||||
EGLConfig getEglConfig() const noexcept { return mEGLConfig; }
|
||||
EGLConfig getSuitableConfigForSwapChain(uint64_t flags, bool window, bool pbuffer) const;
|
||||
|
||||
// Sets the EGLDisplay to be used by this platform. This should only be called by derived
|
||||
// classes before invoking createDriver. Calling it after that point will result in
|
||||
// undefined behaviour. This class will take ownership of the display and call eglTerminate
|
||||
// on it during shutdown.
|
||||
void setEglDisplay(EGLDisplay display) noexcept;
|
||||
|
||||
// supported extensions detected at runtime
|
||||
struct {
|
||||
struct {
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <unordered_set>
|
||||
|
||||
@@ -69,7 +68,7 @@ public:
|
||||
|
||||
struct ExtensionHashFn {
|
||||
std::size_t operator()(utils::CString const& s) const noexcept {
|
||||
return std::hash<std::string>{}(s.data());
|
||||
return std::hash<utils::CString>{}(s.data());
|
||||
}
|
||||
};
|
||||
// Note: utils::CString::operator== has an edge case that breaks for the extension set.
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
@@ -716,7 +716,11 @@ Handle<HwSwapChain> OpenGLDriver::createSwapChainHeadlessS() noexcept {
|
||||
}
|
||||
|
||||
Handle<HwTimerQuery> OpenGLDriver::createTimerQueryS() noexcept {
|
||||
return initHandle<GLTimerQuery>();
|
||||
Handle<HwTimerQuery> tqh = initHandle<GLTimerQuery>();
|
||||
// The state must be constructed here, as a synchronous call to getTimerQueryValue might happen
|
||||
// before createTimerQueryR is executed on the backend thread.
|
||||
handle_cast<GLTimerQuery*>(tqh)->state = std::make_shared<GLTimerQuery::State>();
|
||||
return tqh;
|
||||
}
|
||||
|
||||
Handle<HwDescriptorSetLayout> OpenGLDriver::createDescriptorSetLayoutS() noexcept {
|
||||
|
||||
@@ -250,6 +250,10 @@ private:
|
||||
return utils::CString{ mContext.state.renderer };
|
||||
}
|
||||
|
||||
utils::CString getVersionString() const noexcept override {
|
||||
return utils::CString{ mContext.state.version };
|
||||
}
|
||||
|
||||
JobQueue* getJobQueue() const noexcept { return mJobQueue.get(); }
|
||||
JobWorker* getJobWorker() const noexcept { return mJobWorker.get(); }
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ protected:
|
||||
public:
|
||||
virtual utils::CString getVendorString() const noexcept = 0;
|
||||
virtual utils::CString getRendererString() const noexcept = 0;
|
||||
virtual utils::CString getVersionString() const noexcept = 0;
|
||||
};
|
||||
|
||||
} // filament::backend
|
||||
|
||||
@@ -52,6 +52,8 @@ utils::CString OpenGLPlatform::getDeviceInfo(DeviceInfoType infoType,
|
||||
return getRendererString(driver);
|
||||
case DeviceInfoType::OPENGL_VENDOR:
|
||||
return getVendorString(driver);
|
||||
case DeviceInfoType::OPENGL_VERSION:
|
||||
return getVersionString(driver);
|
||||
default:
|
||||
FILAMENT_CHECK_POSTCONDITION(false) << "Unsupported DeviceInfoType for OpenGLPlatform";
|
||||
return {};
|
||||
@@ -76,6 +78,15 @@ utils::CString OpenGLPlatform::getRendererString(Driver const* driver) {
|
||||
return p->getRendererString();
|
||||
}
|
||||
|
||||
utils::CString OpenGLPlatform::getVersionString(Driver const* driver) {
|
||||
auto const p = static_cast<OpenGLDriverBase const*>(driver);
|
||||
#if UTILS_HAS_RTTI
|
||||
FILAMENT_CHECK_POSTCONDITION(dynamic_cast<OpenGLDriverBase const*>(driver))
|
||||
<< "Driver* has not been allocated with OpenGLPlatform";
|
||||
#endif
|
||||
return p->getVersionString();
|
||||
}
|
||||
|
||||
void OpenGLPlatform::makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain,
|
||||
utils::Invocable<void()>, utils::Invocable<void(size_t)>) {
|
||||
makeCurrent(getCurrentContextType(), drawSwapChain, readSwapChain);
|
||||
|
||||
@@ -88,15 +88,14 @@ TimerQueryFactoryInterface::~TimerQueryFactoryInterface() = default;
|
||||
// This is a backend synchronous call
|
||||
TimerQueryResult TimerQueryFactoryInterface::getTimerQueryValue(
|
||||
GLTimerQuery* tq, uint64_t* elapsedTime) noexcept {
|
||||
if (UTILS_LIKELY(tq->state)) {
|
||||
int64_t const elapsed = tq->state->elapsed.load(std::memory_order_relaxed);
|
||||
if (elapsed > 0) {
|
||||
*elapsedTime = elapsed;
|
||||
return TimerQueryResult::AVAILABLE;
|
||||
}
|
||||
return TimerQueryResult(elapsed);
|
||||
assert_invariant(tq->state);
|
||||
|
||||
int64_t const elapsed = tq->state->elapsed.load(std::memory_order_relaxed);
|
||||
if (elapsed > 0) {
|
||||
*elapsedTime = elapsed;
|
||||
return TimerQueryResult::AVAILABLE;
|
||||
}
|
||||
return TimerQueryResult::ERROR;
|
||||
return TimerQueryResult(elapsed);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -110,9 +109,8 @@ TimerQueryNativeFactory::TimerQueryNativeFactory(OpenGLContext& context)
|
||||
TimerQueryNativeFactory::~TimerQueryNativeFactory() = default;
|
||||
|
||||
void TimerQueryNativeFactory::createTimerQuery(GLTimerQuery* tq) {
|
||||
assert_invariant(!tq->state);
|
||||
assert_invariant(tq->state);
|
||||
|
||||
tq->state = std::make_shared<GLTimerQuery::State>();
|
||||
mContext.procs.genQueries(1u, &tq->state->gl.query);
|
||||
CHECK_GL_ERROR()
|
||||
}
|
||||
@@ -181,8 +179,7 @@ TimerQueryFenceFactory::~TimerQueryFenceFactory() {
|
||||
}
|
||||
|
||||
void TimerQueryFenceFactory::createTimerQuery(GLTimerQuery* tq) {
|
||||
assert_invariant(!tq->state);
|
||||
tq->state = std::make_shared<GLTimerQuery::State>();
|
||||
assert_invariant(tq->state);
|
||||
}
|
||||
|
||||
void TimerQueryFenceFactory::destroyTimerQuery(GLTimerQuery* tq) {
|
||||
@@ -238,8 +235,7 @@ TimerQueryFallbackFactory::TimerQueryFallbackFactory() = default;
|
||||
TimerQueryFallbackFactory::~TimerQueryFallbackFactory() = default;
|
||||
|
||||
void TimerQueryFallbackFactory::createTimerQuery(GLTimerQuery* tq) {
|
||||
assert_invariant(!tq->state);
|
||||
tq->state = std::make_shared<GLTimerQuery::State>();
|
||||
assert_invariant(tq->state);
|
||||
}
|
||||
|
||||
void TimerQueryFallbackFactory::destroyTimerQuery(GLTimerQuery* tq) {
|
||||
|
||||
@@ -117,6 +117,13 @@ struct ShaderCompilerService::OpenGLProgramToken : ProgramToken {
|
||||
cond.wait(l, [this] { return signaled; });
|
||||
}
|
||||
|
||||
// Used in THREAD_POOL mode. Returns true if the token is signaled, meaning it's ready to be
|
||||
// used.
|
||||
bool isReady() const noexcept {
|
||||
std::unique_lock const l(lock);
|
||||
return signaled;
|
||||
}
|
||||
|
||||
// This is invoked upon token completion, which occurs after a successful `gl.program`
|
||||
// population or upon cancellation. In either scenario, the callback handle must be submitted
|
||||
// to notify the caller that resource loading has concluded.
|
||||
@@ -524,8 +531,15 @@ GLuint ShaderCompilerService::initialize(program_token_t& token) {
|
||||
}
|
||||
|
||||
void ShaderCompilerService::ensureTokenIsReady(program_token_t const& token) {
|
||||
if (token->gl.program) {
|
||||
return;// It's ready.
|
||||
if (mMode == Mode::THREAD_POOL) {
|
||||
// Check if `token->gl.program` is populated
|
||||
if (token->isReady()) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (token->gl.program) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (mMode) {
|
||||
@@ -935,6 +949,7 @@ void ShaderCompilerService::cancelPendingSynchronousProgram(program_token_t cons
|
||||
return false;
|
||||
}
|
||||
token->retrievedFromBlobCache = true;
|
||||
token->signal(); // notify that `token->gl.program` is ready to use
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include <utils/Invocable.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
@@ -119,31 +120,41 @@ bool PlatformEGL::isOpenGL() const noexcept {
|
||||
|
||||
PlatformEGL::ExternalImageEGL::~ExternalImageEGL() = default;
|
||||
|
||||
void PlatformEGL::setEglDisplay(EGLDisplay display) noexcept {
|
||||
FILAMENT_CHECK_PRECONDITION(mEGLDisplay == EGL_NO_DISPLAY)
|
||||
<< "EGL Display has already been set.";
|
||||
FILAMENT_CHECK_PRECONDITION(display != EGL_NO_DISPLAY)
|
||||
<< "Must specify a valid EGL Display.";
|
||||
mEGLDisplay = display;
|
||||
}
|
||||
|
||||
Driver* PlatformEGL::createDriver(void* sharedContext, const DriverConfig& driverConfig) {
|
||||
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
assert_invariant(mEGLDisplay != EGL_NO_DISPLAY);
|
||||
if (mEGLDisplay == EGL_NO_DISPLAY) {
|
||||
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
assert_invariant(mEGLDisplay != EGL_NO_DISPLAY);
|
||||
|
||||
EGLint major, minor;
|
||||
EGLBoolean initialized = eglInitialize(mEGLDisplay, &major, &minor);
|
||||
EGLint major, minor;
|
||||
EGLBoolean initialized = eglInitialize(mEGLDisplay, &major, &minor);
|
||||
|
||||
if (!initialized) {
|
||||
EGLDeviceEXT eglDevice;
|
||||
EGLint numDevices;
|
||||
PFNEGLQUERYDEVICESEXTPROC const eglQueryDevicesEXT =
|
||||
PFNEGLQUERYDEVICESEXTPROC(eglGetProcAddress("eglQueryDevicesEXT"));
|
||||
if (eglQueryDevicesEXT != nullptr) {
|
||||
eglQueryDevicesEXT(1, &eglDevice, &numDevices);
|
||||
if(auto* getPlatformDisplay = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
|
||||
eglGetProcAddress("eglGetPlatformDisplay"))) {
|
||||
mEGLDisplay = getPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, eglDevice, nullptr);
|
||||
initialized = eglInitialize(mEGLDisplay, &major, &minor);
|
||||
if (!initialized) {
|
||||
EGLDeviceEXT eglDevice;
|
||||
EGLint numDevices;
|
||||
PFNEGLQUERYDEVICESEXTPROC const eglQueryDevicesEXT =
|
||||
PFNEGLQUERYDEVICESEXTPROC(eglGetProcAddress("eglQueryDevicesEXT"));
|
||||
if (eglQueryDevicesEXT != nullptr) {
|
||||
eglQueryDevicesEXT(1, &eglDevice, &numDevices);
|
||||
if(auto* getPlatformDisplay = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
|
||||
eglGetProcAddress("eglGetPlatformDisplay"))) {
|
||||
mEGLDisplay = getPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, eglDevice, nullptr);
|
||||
initialized = eglInitialize(mEGLDisplay, &major, &minor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (UTILS_UNLIKELY(!initialized)) {
|
||||
LOG(ERROR) << "eglInitialize failed";
|
||||
return nullptr;
|
||||
if (UTILS_UNLIKELY(!initialized)) {
|
||||
LOG(ERROR) << "eglInitialize failed";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(FILAMENT_IMPORT_ENTRY_POINTS)
|
||||
|
||||
@@ -106,6 +106,12 @@ void VulkanBufferCache::gc() noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
size_t totalBuffers = 0;
|
||||
for (auto& bufferPool : mGpuBufferPools) {
|
||||
totalBuffers += bufferPool.size();
|
||||
}
|
||||
FVK_LOGD << "VulkanBufferCache sizes: buffers=" << totalBuffers;
|
||||
|
||||
FVK_SYSTRACE_END();
|
||||
}
|
||||
|
||||
@@ -157,6 +163,10 @@ VulkanGpuBuffer const* VulkanBufferCache::allocate(VulkanBufferBinding binding,
|
||||
UTILS_UNUSED_IN_RELEASE VkResult result = vmaCreateBuffer(mAllocator, &bufferInfo, &allocInfo,
|
||||
&gpuBuffer->vkbuffer, &gpuBuffer->vmaAllocation, &gpuBuffer->allocationInfo);
|
||||
|
||||
FVK_LOGD << "VulkanBufferCache - allocated a vkBuffer " << gpuBuffer->vkbuffer
|
||||
<< " of size " << numBytes << " and binding = " << static_cast<int>(binding)
|
||||
<< " result=" << (int)result;
|
||||
|
||||
#if FVK_ENABLED(FVK_DEBUG_VULKAN_BUFFER_CACHE)
|
||||
if (result != VK_SUCCESS) {
|
||||
FVK_LOGE << "VulkanBufferCache - failed to allocate a new vkBuffer of size " << numBytes
|
||||
@@ -173,6 +183,7 @@ VulkanGpuBuffer const* VulkanBufferCache::allocate(VulkanBufferBinding binding,
|
||||
}
|
||||
|
||||
void VulkanBufferCache::destroy(VulkanGpuBuffer const* gpuBuffer) noexcept {
|
||||
FVK_LOGD << "VulkanBufferCache - Destroying vkBuffer " << gpuBuffer->vkbuffer;
|
||||
vmaDestroyBuffer(mAllocator, gpuBuffer->vkbuffer, gpuBuffer->vmaAllocation);
|
||||
delete gpuBuffer;
|
||||
gpuBuffer = nullptr;
|
||||
|
||||
@@ -194,6 +194,7 @@ void VulkanCommandBuffer::begin() noexcept {
|
||||
}
|
||||
|
||||
fvkmemory::resource_ptr<VulkanSemaphore> VulkanCommandBuffer::submit() {
|
||||
FVK_LOGD << "Submitting VulkanCommandBuffer: " << mBuffer << " (age=" << age() << ")";
|
||||
while (mMarkerCount > 0) {
|
||||
popMarker();
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
// If any VkRenderPass or VkFramebuffer is unused for more than TIME_BEFORE_EVICTION frames, it
|
||||
// is evicted from the cache.
|
||||
static constexpr uint32_t TIME_BEFORE_EVICTION = FVK_MAX_COMMAND_BUFFERS;
|
||||
static constexpr uint32_t TIME_BEFORE_EVICTION = 3;
|
||||
|
||||
using namespace bluevk;
|
||||
|
||||
@@ -120,6 +120,8 @@ fvkmemory::resource_ptr<VulkanFramebuffer> VulkanFboCache::getFramebuffer(FboKey
|
||||
VkResult error = vkCreateFramebuffer(mDevice, &info, VKALLOC, &framebuffer);
|
||||
FILAMENT_CHECK_POSTCONDITION(error == VK_SUCCESS) << "Unable to create framebuffer."
|
||||
<< " error=" << static_cast<int32_t>(error);
|
||||
FVK_LOGD << "VulkanFboCache - Created VkFramebuffer " << framebuffer << " for renderTarget " << renderTarget.get()
|
||||
<< " size=" << config.width << "x" << config.height;
|
||||
fvkmemory::resource_ptr<VulkanFramebuffer> fbh =
|
||||
fvkmemory::resource_ptr<VulkanFramebuffer>::construct(resManager, mDevice, framebuffer,
|
||||
renderTarget);
|
||||
@@ -404,6 +406,8 @@ void VulkanFboCache::gc() noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
FVK_LOGD << "VulkanFboCache sizes: framebuffers=" << mFramebufferCache.size() << " renderpasses=" << mRenderPassCache.size();
|
||||
|
||||
FVK_SYSTRACE_END();
|
||||
}
|
||||
|
||||
|
||||
@@ -403,10 +403,13 @@ VulkanRenderTarget::VulkanRenderTarget()
|
||||
mOffscreen(false),
|
||||
mProtected(false),
|
||||
mInfo(std::make_unique<Auxiliary>()) {
|
||||
FVK_LOGD << "Creating default VulkanRenderTarget: " << this;
|
||||
mInfo->rpkey.samples = mInfo->fbkey.samples = 1;
|
||||
}
|
||||
|
||||
VulkanRenderTarget::~VulkanRenderTarget() = default;
|
||||
VulkanRenderTarget::~VulkanRenderTarget() {
|
||||
FVK_LOGD << "Destroying VulkanRenderTarget: " << this << " (offscreen=" << mOffscreen << ")";
|
||||
}
|
||||
|
||||
void VulkanRenderTarget::bindSwapChain(fvkmemory::resource_ptr<VulkanSwapChain> swapchain) {
|
||||
assert_invariant(!mOffscreen);
|
||||
@@ -443,9 +446,12 @@ void VulkanRenderTarget::bindSwapChain(fvkmemory::resource_ptr<VulkanSwapChain>
|
||||
fbkey.depth = VK_NULL_HANDLE;
|
||||
}
|
||||
mInfo->colors.set(0);
|
||||
FVK_LOGD << "bindSwapChain: target=" << this << ", swapchain=" << swapchain.get()
|
||||
<< ", size=" << width << "x" << height;
|
||||
}
|
||||
|
||||
void VulkanRenderTarget::releaseSwapchain() {
|
||||
FVK_LOGD << "releaseSwapchain: target=" << this;
|
||||
mInfo->colors = {};
|
||||
mInfo->attachments.clear();
|
||||
}
|
||||
@@ -459,6 +465,7 @@ VulkanRenderTarget::VulkanRenderTarget(VkDevice device, VkPhysicalDevice physica
|
||||
mOffscreen(true),
|
||||
mProtected(false),
|
||||
mInfo(std::make_unique<Auxiliary>()) {
|
||||
FVK_LOGD << "Creating offscreen VulkanRenderTarget: " << this << ", size=" << width << "x" << height << ", samples=" << (int)samples;
|
||||
auto& depth = depthStencil[0];
|
||||
|
||||
// Constrain the sample count according to both kinds of sample count masks obtained from
|
||||
@@ -719,9 +726,13 @@ VulkanFramebuffer::VulkanFramebuffer(VkDevice device, VkFramebuffer framebuffer,
|
||||
fvkmemory::resource_ptr<VulkanRenderTarget> renderTarget)
|
||||
: mDevice(device),
|
||||
mFramebuffer(framebuffer),
|
||||
mRenderTarget(renderTarget) {}
|
||||
mRenderTarget(renderTarget) {
|
||||
FVK_LOGD << "Creating VulkanFramebuffer: " << framebuffer
|
||||
<< ", target=" << renderTarget.get();
|
||||
}
|
||||
|
||||
VulkanFramebuffer::~VulkanFramebuffer() {
|
||||
FVK_LOGD << "Destroying VulkanFramebuffer: " << mFramebuffer;
|
||||
vkDestroyFramebuffer(mDevice, mFramebuffer, VKALLOC);
|
||||
}
|
||||
|
||||
|
||||
@@ -534,6 +534,8 @@ void VulkanPipelineCache::gc() noexcept {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
FVK_LOGD << "VulkanPipelineCache sizes: pipelines=" << mPipelines.size();
|
||||
}
|
||||
|
||||
bool VulkanPipelineCache::PipelineEqual::operator()(const PipelineKey& k1,
|
||||
|
||||
@@ -271,6 +271,8 @@ void VulkanStagePool::gc() noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
FVK_LOGD << "VulkanStagePool sizes: stages=" << mStages.size() << " freeImages=" << mFreeImages.size();
|
||||
|
||||
FVK_SYSTRACE_END();
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ VulkanSwapChain::VulkanSwapChain(VulkanPlatform* platform, VulkanContext const&
|
||||
mCurrentSwapIndex(0),
|
||||
mAcquired(false),
|
||||
mIsFirstRenderPass(true) {
|
||||
FVK_LOGD << "Creating VulkanSwapChain: " << this << ", window=" << nativeWindow << ", size=" << extent.width << "x" << extent.height;
|
||||
swapChain = mPlatform->createSwapChain(nativeWindow, flags, extent);
|
||||
FILAMENT_CHECK_POSTCONDITION(swapChain) << "Unable to create swapchain";
|
||||
|
||||
@@ -53,6 +54,7 @@ VulkanSwapChain::VulkanSwapChain(VulkanPlatform* platform, VulkanContext const&
|
||||
}
|
||||
|
||||
VulkanSwapChain::~VulkanSwapChain() {
|
||||
FVK_LOGD << "Destroying VulkanSwapChain: " << this;
|
||||
// Must wait for the inflight command buffers to finish since they might contain the images
|
||||
// we're about to destroy.
|
||||
mCommands->flush();
|
||||
@@ -68,6 +70,7 @@ VulkanSwapChain::~VulkanSwapChain() {
|
||||
}
|
||||
|
||||
void VulkanSwapChain::update() {
|
||||
FVK_LOGD << "VulkanSwapChain::update: " << this;
|
||||
mColors.clear();
|
||||
|
||||
auto const bundle = mPlatform->getSwapChainBundle(swapChain);
|
||||
@@ -89,6 +92,7 @@ void VulkanSwapChain::update() {
|
||||
colorUsage |= TextureUsage::PROTECTED;
|
||||
}
|
||||
for (auto const color: bundle.colors) {
|
||||
FVK_LOGD << "VulkanSwapChain::update: Adding color image=" << color << " to swapchain " << this;
|
||||
auto colorTexture = fvkmemory::resource_ptr<VulkanTexture>::construct(mResourceManager,
|
||||
mContext, device, mAllocator, mResourceManager, mCommands, color, VK_NULL_HANDLE,
|
||||
bundle.colorFormat, VK_NULL_HANDLE /*ycrcb */, 1, bundle.extent.width,
|
||||
@@ -157,6 +161,7 @@ void VulkanSwapChain::acquire(bool& resized) {
|
||||
|
||||
// Check if the swapchain should be resized.
|
||||
if ((resized = mPlatform->hasResized(swapChain))) {
|
||||
FVK_LOGD << "VulkanSwapChain::acquire: Resizing " << this;
|
||||
if (mFlushAndWaitOnResize) {
|
||||
mCommands->flush();
|
||||
mCommands->wait();
|
||||
@@ -176,6 +181,7 @@ void VulkanSwapChain::acquire(bool& resized) {
|
||||
|
||||
mCurrentSwapIndex = imageSyncData.imageIndex;
|
||||
assert_invariant(mCurrentSwapIndex < mFinishedDrawing.size());
|
||||
FVK_LOGD << "VulkanSwapChain::acquire: " << this << ", index=" << mCurrentSwapIndex << ", image=" << mColors[mCurrentSwapIndex]->getVkImage();
|
||||
mFinishedDrawing[mCurrentSwapIndex] = {};
|
||||
FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR)
|
||||
<< "Cannot acquire in swapchain. error=" << static_cast<int32_t>(result);
|
||||
|
||||
@@ -294,9 +294,19 @@ VulkanTextureState::VulkanTextureState(VulkanStagePool& stagePool, VulkanCommand
|
||||
mYcbcr{ ycbcrConversion },
|
||||
mDefaultLayout(getDefaultLayoutImpl(usage)),
|
||||
mUsage(usage),
|
||||
mIsProtected(isProtected) {}
|
||||
mIsProtected(isProtected) {
|
||||
FVK_LOGD << "Creating VulkanTextureState: image=" << image
|
||||
<< ", memory=" << deviceMemory
|
||||
<< ", format=" << format
|
||||
<< ", viewType=" << viewType
|
||||
<< ", levels=" << (int)levels
|
||||
<< ", layers=" << (int)layerCount
|
||||
<< ", usage=" << usage;
|
||||
}
|
||||
|
||||
VulkanTextureState::~VulkanTextureState() {
|
||||
FVK_LOGD << "Destroying VulkanTextureState: image=" << mTextureImage
|
||||
<< ", memory=" << mTextureImageMemory;
|
||||
clearCachedImageViews();
|
||||
if (mTextureImageMemory != VK_NULL_HANDLE) {
|
||||
vkDestroyImage(mDevice, mTextureImage, VKALLOC);
|
||||
@@ -512,6 +522,12 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice,
|
||||
|
||||
void VulkanTexture::updateImage(const PixelBufferDescriptor& data, uint32_t width, uint32_t height,
|
||||
uint32_t depth, uint32_t xoffset, uint32_t yoffset, uint32_t zoffset, uint32_t miplevel) {
|
||||
FVK_LOGD << "updateImage: texture=" << mState->mTextureImage
|
||||
<< ", format=" << (int)data.format
|
||||
<< ", type=" << (int)data.type
|
||||
<< ", size=" << width << "x" << height << "x" << depth
|
||||
<< ", offset=" << xoffset << "," << yoffset << "," << zoffset
|
||||
<< ", mip=" << miplevel;
|
||||
assert_invariant(width <= this->width && height <= this->height);
|
||||
assert_invariant(depth <= this->depth * ((target == SamplerType::SAMPLER_CUBEMAP ||
|
||||
target == SamplerType::SAMPLER_CUBEMAP_ARRAY) ? 6 : 1));
|
||||
@@ -616,6 +632,11 @@ void VulkanTexture::updateImage(const PixelBufferDescriptor& data, uint32_t widt
|
||||
|
||||
void VulkanTexture::updateImageWithBlit(const PixelBufferDescriptor& data, uint32_t width,
|
||||
uint32_t height, uint32_t depth, uint32_t miplevel) {
|
||||
FVK_LOGD << "updateImageWithBlit: texture=" << mState->mTextureImage
|
||||
<< ", format=" << (int)data.format
|
||||
<< ", type=" << (int)data.type
|
||||
<< ", size=" << width << "x" << height << "x" << depth
|
||||
<< ", mip=" << miplevel;
|
||||
// Otherwise, use vkCmdCopyBufferToImage.
|
||||
size_t const bpp = PixelBufferDescriptor::computeDataSize(data.format, data.type, 1, 1, 1);
|
||||
// Note: if bpp = 0, we're dealing with a compressed format; we should fall
|
||||
@@ -755,10 +776,14 @@ bool VulkanTexture::transitionLayout(VkCommandBuffer cmdbuf, VkImageSubresourceR
|
||||
setLayout(range, newLayout);
|
||||
|
||||
if (hasTransitions) {
|
||||
FVK_LOGD << "transition texture=" << mState->mTextureImage << " (" << range.baseArrayLayer
|
||||
<< "," << range.baseMipLevel << ")" << " count=(" << range.layerCount << ","
|
||||
<< range.levelCount << ")" << " from=" << (int)oldLayout << " to=" << (int)newLayout
|
||||
<< " format=" << mState->mVkFormat;
|
||||
#if FVK_ENABLED(FVK_DEBUG_LAYOUT_TRANSITION)
|
||||
FVK_LOGD << "transition texture=" << mState->mTextureImage << " (" << range.baseArrayLayer
|
||||
<< "," << range.baseMipLevel << ")" << " count=(" << range.layerCount << ","
|
||||
<< range.levelCount << ")" << " from=" << oldLayout << " to=" << newLayout
|
||||
<< range.levelCount << ")" << " from=" << (int)oldLayout << " to=" << (int)newLayout
|
||||
<< " format=" << mState->mVkFormat << " depth="
|
||||
<< fvkutils::isVkDepthFormat(mState->mVkFormat)
|
||||
<< " slice-by-slice=" << transitionSliceBySlice;
|
||||
@@ -767,7 +792,7 @@ bool VulkanTexture::transitionLayout(VkCommandBuffer cmdbuf, VkImageSubresourceR
|
||||
#if FVK_ENABLED(FVK_DEBUG_LAYOUT_TRANSITION)
|
||||
FVK_LOGD << "transition texture=" << mState->mTextureImage << " (" << range.baseArrayLayer
|
||||
<< "," << range.baseMipLevel << ")" << " count=(" << range.layerCount << ","
|
||||
<< range.levelCount << ")" << " to=" << newLayout
|
||||
<< range.levelCount << ")" << " to=" << (int)newLayout
|
||||
<< " is skipped because of no change in layout";
|
||||
#endif
|
||||
}
|
||||
@@ -878,7 +903,7 @@ void VulkanTexture::print() const {
|
||||
level >= mPrimaryViewRange.baseMipLevel &&
|
||||
level < (mPrimaryViewRange.baseMipLevel + mPrimaryViewRange.levelCount);
|
||||
FVK_LOGD << "[" << mState->mTextureImage << "]: (" << layer << "," << level
|
||||
<< ")=" << getLayout(layer, level)
|
||||
<< ")=" << (int)getLayout(layer, level)
|
||||
<< " primary=" << primary;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1970,9 +1970,19 @@ void WebGPUDriver::dispatchCompute(Handle<HwProgram> program, math::uint3 workGr
|
||||
//todo
|
||||
}
|
||||
|
||||
void WebGPUDriver::scissor(
|
||||
Viewport scissor) {
|
||||
//todo
|
||||
void WebGPUDriver::scissor(Viewport scissor) {
|
||||
assert_invariant(mRenderPassEncoder);
|
||||
assert_invariant(mCurrentRenderTarget);
|
||||
|
||||
// The WebGPU scissor starts from the top-left corner
|
||||
assert_invariant(scissor.left >= 0 &&
|
||||
mCurrentRenderTarget->height >= scissor.bottom + scissor.height /*top >= 0*/ &&
|
||||
scissor.width <= mCurrentRenderTarget->width &&
|
||||
scissor.height <= mCurrentRenderTarget->height);
|
||||
|
||||
mRenderPassEncoder.SetScissorRect(scissor.left,
|
||||
mCurrentRenderTarget->height - scissor.bottom - scissor.height /*top*/, scissor.width,
|
||||
scissor.height);
|
||||
}
|
||||
|
||||
void WebGPUDriver::beginTimerQuery(Handle<HwTimerQuery> tqh) {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "PlatformRunner.h"
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@@ -30,18 +30,18 @@ TestArguments parseArguments(int argc, char* argv[]) {
|
||||
// The first colon in OPTSTR turns on silent error reporting. This is important, as the
|
||||
// arguments may also contain gtest parameters we don't know about.
|
||||
static constexpr const char* OPTSTR = ":a:kc";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ "headless_only", no_argument, nullptr, 'k' },
|
||||
{ "ci", no_argument, nullptr, 'c' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "headless_only", utils::getopt::no_argument, nullptr, 'k' },
|
||||
{ "ci", utils::getopt::no_argument, nullptr, 'c' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
|
||||
int opt;
|
||||
int optionIndex = 0;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &optionIndex)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &optionIndex)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
if (arg == "opengl") {
|
||||
|
||||
@@ -32,7 +32,6 @@ using namespace filament;
|
||||
using namespace filament::backend;
|
||||
|
||||
TEST_F(BackendTest, ScissorViewportRegion) {
|
||||
SKIP_IF(Backend::WEBGPU, "test cases fail in WebGPU, see b/424157731");
|
||||
auto& api = getDriverApi();
|
||||
|
||||
constexpr int kSrcTexWidth = 1024;
|
||||
|
||||
@@ -182,7 +182,7 @@ Program::SpecializationConstant LocalProgramCache::getConstantImpl(
|
||||
return getConstantImpl(it->second + CONFIG_MAX_RESERVED_SPEC_CONSTANTS);
|
||||
}
|
||||
|
||||
std::string name_cstring(name);
|
||||
CString name_cstring(name);
|
||||
PANIC_PRECONDITION("No such constant exists: %s", name_cstring.c_str());
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -2248,6 +2248,18 @@ PostProcessManager::BloomPassOutput PostProcessManager::bloom(FrameGraph& fg,
|
||||
float bloomHeight = float(inoutBloomOptions.resolution);
|
||||
float bloomWidth = bloomHeight * aspect;
|
||||
|
||||
// With extreme aspect ratios the major axis can exceed the GPU's maximum
|
||||
// texture dimension. Scale both axes down proportionally so that the larger
|
||||
// one stays within the hardware limit.
|
||||
const float maxDimension = float(
|
||||
FTexture::getMaxTextureSize(mEngine, SamplerType::SAMPLER_2D));
|
||||
const float bloomMajor = std::max(bloomWidth, bloomHeight);
|
||||
if (bloomMajor > maxDimension) {
|
||||
const float clampScale = maxDimension / bloomMajor;
|
||||
bloomWidth *= clampScale;
|
||||
bloomHeight *= clampScale;
|
||||
}
|
||||
|
||||
// we might need to adjust the max # of levels
|
||||
const uint32_t major = uint32_t(std::max(bloomWidth, bloomHeight));
|
||||
const uint8_t maxLevels = FTexture::maxLevelCount(major);
|
||||
|
||||
@@ -1138,6 +1138,7 @@ void FView::prepareShadowMapping() const noexcept {
|
||||
constexpr uint32_t SHADOW_SAMPLING_RUNTIME_PCSS = 3u;
|
||||
auto& s = mUniforms.edit();
|
||||
s.cascadeSplits = uniforms.cascadeSplits;
|
||||
s.shadowAtlasResolution = uniforms.atlasResolution;
|
||||
s.ssContactShadowDistance = uniforms.ssContactShadowDistance;
|
||||
s.directionalShadows = int32_t(uniforms.directionalShadows);
|
||||
s.cascades = int32_t(uniforms.cascades);
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
#include <utils/debug.h>
|
||||
#include <utils/CString.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace filament::backend;
|
||||
|
||||
namespace filament {
|
||||
|
||||
@@ -153,13 +153,17 @@ struct PerViewUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
|
||||
int32_t directionalShadows;
|
||||
float ssContactShadowDistance;
|
||||
|
||||
math::float2 shadowAtlasResolution; // dim, 1/dim
|
||||
float shadowReserved0;
|
||||
float shadowReserved1;
|
||||
|
||||
// position of cascade splits, in world space (not including the near plane)
|
||||
// -Inf stored in unused components
|
||||
math::float4 cascadeSplits;
|
||||
// bit 0-3: cascade count
|
||||
// bit 8-11: cascade has visible shadows
|
||||
int32_t cascades;
|
||||
float shadowPenumbraRatioScale; // For DPCF or PCSS, scale penumbra ratio for artistic use
|
||||
float shadowPenumbraRatioScale; // For DPCF or PCSS, scale penumbra ratio for artistic use
|
||||
math::float2 lightFarAttenuationParams; // a, a/far (a=1/pct-of-far)
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
@@ -213,7 +217,7 @@ struct PerViewUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
|
||||
float es2Reserved2;
|
||||
|
||||
// bring PerViewUib to 2 KiB
|
||||
math::float4 reserved[22];
|
||||
math::float4 reserved[21];
|
||||
};
|
||||
|
||||
// 2 KiB == 128 float4s
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#define TNT_ENUMMANAGER_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <filamat/MaterialBuilder.h>
|
||||
@@ -37,55 +37,55 @@ using OutputType = MaterialBuilder::OutputType;
|
||||
using ConstantType = MaterialBuilder::ConstantType;
|
||||
using ShaderStageType = MaterialBuilder::ShaderStageFlags;
|
||||
|
||||
// Convenience methods to convert std::string to Enum and also iterate over Enum values.
|
||||
// Convenience methods to convert std::string_view to Enum and also iterate over Enum values.
|
||||
class Enums {
|
||||
public:
|
||||
|
||||
// Returns true if string "s" is a valid string representation of an element of enum T.
|
||||
template<typename T>
|
||||
static bool isValid(const std::string& s) noexcept {
|
||||
std::unordered_map<std::string, T>& map = getMap<T>();
|
||||
static bool isValid(const std::string_view& s) noexcept {
|
||||
std::unordered_map<std::string_view, T>& map = getMap<T>();
|
||||
return map.find(s) != map.end();
|
||||
}
|
||||
|
||||
// Return enum matching its string representation. Returns undefined if s is not a valid enum T
|
||||
// value. You should always call isValid() first to validate a string before calling toEnum().
|
||||
template<typename T>
|
||||
static T toEnum(const std::string& s) noexcept {
|
||||
std::unordered_map<std::string, T>& map = getMap<T>();
|
||||
static T toEnum(const std::string_view& s) noexcept {
|
||||
std::unordered_map<std::string_view, T>& map = getMap<T>();
|
||||
return map.at(s);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static std::string toString(T t) noexcept;
|
||||
static std::string_view toString(T t) noexcept;
|
||||
|
||||
// Return a map of all values in an enum with their string representation.
|
||||
template<typename T>
|
||||
static std::unordered_map<std::string, T>& map() noexcept {
|
||||
std::unordered_map<std::string, T>& map = getMap<T>();
|
||||
static std::unordered_map<std::string_view, T>& map() noexcept {
|
||||
auto& map = getMap<T>();
|
||||
return map;
|
||||
};
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
static std::unordered_map<std::string, T>& getMap() noexcept;
|
||||
static std::unordered_map<std::string_view, T>& getMap() noexcept;
|
||||
|
||||
static std::unordered_map<std::string, Property> mStringToProperty;
|
||||
static std::unordered_map<std::string, UniformType> mStringToUniformType;
|
||||
static std::unordered_map<std::string, SamplerType> mStringToSamplerType;
|
||||
static std::unordered_map<std::string, SubpassType> mStringToSubpassType;
|
||||
static std::unordered_map<std::string, SamplerFormat> mStringToSamplerFormat;
|
||||
static std::unordered_map<std::string, ParameterPrecision> mStringToSamplerPrecision;
|
||||
static std::unordered_map<std::string, OutputTarget> mStringToOutputTarget;
|
||||
static std::unordered_map<std::string, OutputQualifier> mStringToOutputQualifier;
|
||||
static std::unordered_map<std::string, OutputType> mStringToOutputType;
|
||||
static std::unordered_map<std::string, ConstantType> mStringToConstantType;
|
||||
static std::unordered_map<std::string, ShaderStageType> mStringToShaderStageType;
|
||||
static std::unordered_map<std::string_view, Property> mStringToProperty;
|
||||
static std::unordered_map<std::string_view, UniformType> mStringToUniformType;
|
||||
static std::unordered_map<std::string_view, SamplerType> mStringToSamplerType;
|
||||
static std::unordered_map<std::string_view, SubpassType> mStringToSubpassType;
|
||||
static std::unordered_map<std::string_view, SamplerFormat> mStringToSamplerFormat;
|
||||
static std::unordered_map<std::string_view, ParameterPrecision> mStringToSamplerPrecision;
|
||||
static std::unordered_map<std::string_view, OutputTarget> mStringToOutputTarget;
|
||||
static std::unordered_map<std::string_view, OutputQualifier> mStringToOutputQualifier;
|
||||
static std::unordered_map<std::string_view, OutputType> mStringToOutputType;
|
||||
static std::unordered_map<std::string_view, ConstantType> mStringToConstantType;
|
||||
static std::unordered_map<std::string_view, ShaderStageType> mStringToShaderStageType;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
std::string Enums::toString(T t) noexcept {
|
||||
std::unordered_map<std::string, T>& map = getMap<T>();
|
||||
std::string_view Enums::toString(T t) noexcept {
|
||||
auto& map = getMap<T>();
|
||||
auto result = std::find_if(map.begin(), map.end(), [t](auto& pair) {
|
||||
return pair.second == t;
|
||||
});
|
||||
|
||||
+24
-22
@@ -18,9 +18,11 @@
|
||||
|
||||
#include "filamat/MaterialBuilder.h"
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace filamat {
|
||||
|
||||
std::unordered_map<std::string, Property> Enums::mStringToProperty = {
|
||||
std::unordered_map<std::string_view, Property> Enums::mStringToProperty = {
|
||||
{ "baseColor", Property::BASE_COLOR },
|
||||
{ "roughness", Property::ROUGHNESS },
|
||||
{ "metallic", Property::METALLIC },
|
||||
@@ -55,11 +57,11 @@ std::unordered_map<std::string, Property> Enums::mStringToProperty = {
|
||||
};
|
||||
|
||||
template <>
|
||||
std::unordered_map<std::string, Property>& Enums::getMap<Property>() noexcept {
|
||||
std::unordered_map<std::string_view, Property>& Enums::getMap<Property>() noexcept {
|
||||
return mStringToProperty;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, UniformType> Enums::mStringToUniformType = {
|
||||
std::unordered_map<std::string_view, UniformType> Enums::mStringToUniformType = {
|
||||
{ "bool", UniformType::BOOL },
|
||||
{ "bool2", UniformType::BOOL2 },
|
||||
{ "bool3", UniformType::BOOL3 },
|
||||
@@ -83,11 +85,11 @@ std::unordered_map<std::string, UniformType> Enums::mStringToUniformType = {
|
||||
};
|
||||
|
||||
template <>
|
||||
std::unordered_map<std::string, UniformType>& Enums::getMap<UniformType>() noexcept {
|
||||
std::unordered_map<std::string_view, UniformType>& Enums::getMap<UniformType>() noexcept {
|
||||
return mStringToUniformType;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, SamplerType> Enums::mStringToSamplerType = {
|
||||
std::unordered_map<std::string_view, SamplerType> Enums::mStringToSamplerType = {
|
||||
{ "sampler2d", SamplerType::SAMPLER_2D },
|
||||
{ "sampler2dArray", SamplerType::SAMPLER_2D_ARRAY },
|
||||
{ "sampler3d", SamplerType::SAMPLER_3D },
|
||||
@@ -97,20 +99,20 @@ std::unordered_map<std::string, SamplerType> Enums::mStringToSamplerType = {
|
||||
};
|
||||
|
||||
template <>
|
||||
std::unordered_map<std::string, SamplerType>& Enums::getMap<SamplerType>() noexcept {
|
||||
std::unordered_map<std::string_view, SamplerType>& Enums::getMap<SamplerType>() noexcept {
|
||||
return mStringToSamplerType;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, SubpassType> Enums::mStringToSubpassType = {
|
||||
std::unordered_map<std::string_view, SubpassType> Enums::mStringToSubpassType = {
|
||||
{ "subpassInput", SubpassType::SUBPASS_INPUT },
|
||||
};
|
||||
|
||||
template <>
|
||||
std::unordered_map<std::string, SubpassType>& Enums::getMap<SubpassType>() noexcept {
|
||||
std::unordered_map<std::string_view, SubpassType>& Enums::getMap<SubpassType>() noexcept {
|
||||
return mStringToSubpassType;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, ParameterPrecision> Enums::mStringToSamplerPrecision = {
|
||||
std::unordered_map<std::string_view, ParameterPrecision> Enums::mStringToSamplerPrecision = {
|
||||
{ "default", ParameterPrecision::DEFAULT },
|
||||
{ "low", ParameterPrecision::LOW },
|
||||
{ "medium", ParameterPrecision::MEDIUM },
|
||||
@@ -118,30 +120,30 @@ std::unordered_map<std::string, ParameterPrecision> Enums::mStringToSamplerPreci
|
||||
};
|
||||
|
||||
template <>
|
||||
std::unordered_map<std::string, ParameterPrecision>& Enums::getMap<ParameterPrecision>() noexcept {
|
||||
std::unordered_map<std::string_view, ParameterPrecision>& Enums::getMap<ParameterPrecision>() noexcept {
|
||||
return mStringToSamplerPrecision;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, OutputTarget> Enums::mStringToOutputTarget = {
|
||||
std::unordered_map<std::string_view, OutputTarget> Enums::mStringToOutputTarget = {
|
||||
{ "color", OutputTarget::COLOR },
|
||||
{ "depth", OutputTarget::DEPTH }
|
||||
};
|
||||
|
||||
template <>
|
||||
std::unordered_map<std::string, OutputTarget>& Enums::getMap<OutputTarget>() noexcept {
|
||||
std::unordered_map<std::string_view, OutputTarget>& Enums::getMap<OutputTarget>() noexcept {
|
||||
return mStringToOutputTarget;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, OutputQualifier> Enums::mStringToOutputQualifier = {
|
||||
std::unordered_map<std::string_view, OutputQualifier> Enums::mStringToOutputQualifier = {
|
||||
{ "out", OutputQualifier::OUT }
|
||||
};
|
||||
|
||||
template <>
|
||||
std::unordered_map<std::string, OutputQualifier>& Enums::getMap<OutputQualifier>() noexcept {
|
||||
std::unordered_map<std::string_view, OutputQualifier>& Enums::getMap<OutputQualifier>() noexcept {
|
||||
return mStringToOutputQualifier;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, OutputType> Enums::mStringToOutputType = {
|
||||
std::unordered_map<std::string_view, OutputType> Enums::mStringToOutputType = {
|
||||
{ "float", OutputType::FLOAT },
|
||||
{ "float2", OutputType::FLOAT2 },
|
||||
{ "float3", OutputType::FLOAT3 },
|
||||
@@ -149,11 +151,11 @@ std::unordered_map<std::string, OutputType> Enums::mStringToOutputType = {
|
||||
};
|
||||
|
||||
template <>
|
||||
std::unordered_map<std::string, OutputType>& Enums::getMap<OutputType>() noexcept {
|
||||
std::unordered_map<std::string_view, OutputType>& Enums::getMap<OutputType>() noexcept {
|
||||
return mStringToOutputType;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, SamplerFormat> Enums::mStringToSamplerFormat = {
|
||||
std::unordered_map<std::string_view, SamplerFormat> Enums::mStringToSamplerFormat = {
|
||||
{ "int", SamplerFormat::INT },
|
||||
{ "uint", SamplerFormat::UINT },
|
||||
{ "float", SamplerFormat::FLOAT },
|
||||
@@ -161,29 +163,29 @@ std::unordered_map<std::string, SamplerFormat> Enums::mStringToSamplerFormat = {
|
||||
};
|
||||
|
||||
template <>
|
||||
std::unordered_map<std::string, SamplerFormat>& Enums::getMap<SamplerFormat>() noexcept {
|
||||
std::unordered_map<std::string_view, SamplerFormat>& Enums::getMap<SamplerFormat>() noexcept {
|
||||
return mStringToSamplerFormat;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, ConstantType > Enums::mStringToConstantType = {
|
||||
std::unordered_map<std::string_view, ConstantType > Enums::mStringToConstantType = {
|
||||
{ "int", ConstantType::INT },
|
||||
{ "float", ConstantType::FLOAT },
|
||||
{ "bool", ConstantType::BOOL },
|
||||
};
|
||||
|
||||
template <>
|
||||
std::unordered_map<std::string, ConstantType>& Enums::getMap<ConstantType>() noexcept {
|
||||
std::unordered_map<std::string_view, ConstantType>& Enums::getMap<ConstantType>() noexcept {
|
||||
return mStringToConstantType;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, ShaderStageType> Enums::mStringToShaderStageType = {
|
||||
std::unordered_map<std::string_view, ShaderStageType> Enums::mStringToShaderStageType = {
|
||||
{ "fragment", ShaderStageType::FRAGMENT },
|
||||
{ "vertex", ShaderStageType::VERTEX },
|
||||
{ "compute", ShaderStageType::COMPUTE },
|
||||
};
|
||||
|
||||
template <>
|
||||
std::unordered_map<std::string, ShaderStageType>& Enums::getMap<ShaderStageType>() noexcept {
|
||||
std::unordered_map<std::string_view, ShaderStageType>& Enums::getMap<ShaderStageType>() noexcept {
|
||||
return mStringToShaderStageType;
|
||||
};
|
||||
|
||||
|
||||
@@ -849,17 +849,16 @@ static void showErrorMessage(const char* materialName, filament::Variant const v
|
||||
const char* targetApiString = "unknown";
|
||||
switch (targetApi) {
|
||||
case TargetApi::OPENGL:
|
||||
targetApiString = (featureLevel == MaterialBuilder::FeatureLevel::FEATURE_LEVEL_0)
|
||||
? "GLES 2.0.\n" : "OpenGL.\n";
|
||||
targetApiString = (featureLevel == MaterialBuilder::FeatureLevel::FEATURE_LEVEL_0) ? "GLES 2.0" : "OpenGL";
|
||||
break;
|
||||
case TargetApi::VULKAN:
|
||||
targetApiString = "Vulkan.\n";
|
||||
targetApiString = "Vulkan";
|
||||
break;
|
||||
case TargetApi::METAL:
|
||||
targetApiString = "Metal.\n";
|
||||
targetApiString = "Metal";
|
||||
break;
|
||||
case TargetApi::WEBGPU:
|
||||
targetApiString = "WebGPU.\n";
|
||||
targetApiString = "WebGPU";
|
||||
break;
|
||||
case TargetApi::ALL:
|
||||
assert_invariant(false); // Unreachable.
|
||||
@@ -869,24 +868,20 @@ static void showErrorMessage(const char* materialName, filament::Variant const v
|
||||
const char* shaderStageString = "unknown";
|
||||
switch (shaderType) {
|
||||
case ShaderStage::VERTEX:
|
||||
shaderStageString = "Vertex Shader\n";
|
||||
shaderStageString = "Vertex Shader";
|
||||
break;
|
||||
case ShaderStage::FRAGMENT:
|
||||
shaderStageString = "Fragment Shader\n";
|
||||
shaderStageString = "Fragment Shader";
|
||||
break;
|
||||
case ShaderStage::COMPUTE:
|
||||
shaderStageString = "Compute Shader\n";
|
||||
shaderStageString = "Compute Shader";
|
||||
break;
|
||||
}
|
||||
|
||||
LOG(ERROR)
|
||||
<< "Error in \"" << materialName << "\""
|
||||
<< ", Variant 0x" << io::hex << +variant.key
|
||||
<< ", " << targetApiString
|
||||
<< "=========================\n"
|
||||
<< "Generated " << shaderStageString
|
||||
<< "=========================\n"
|
||||
<< shaderCode;
|
||||
<< ", " << shaderStageString
|
||||
<< ", Variant " << io::hex << +variant.key;
|
||||
}
|
||||
|
||||
bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Variant>& variants,
|
||||
@@ -1417,7 +1412,7 @@ bool MaterialBuilder::checkMaterialLevelFeatures(MaterialInfo const& info) const
|
||||
auto const* stage = to_string(sib.getStageFlags());
|
||||
for (auto const& sampler: samplers) {
|
||||
LOG(ERROR) << "\"" << sampler.name.c_str() << "\" "
|
||||
<< Enums::toString(sampler.type).c_str() << " " << stage << '\n';
|
||||
<< Enums::toString(sampler.type) << " " << stage << '\n';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -165,6 +165,9 @@ BufferInterfaceBlock const& UibGenerator::getPerViewUib() noexcept {
|
||||
// ------------------------------------------------------------------------------------
|
||||
{ "directionalShadows", 0, Type::INT },
|
||||
{ "ssContactShadowDistance", 0, Type::FLOAT },
|
||||
{ "shadowAtlasResolution", 0, Type::FLOAT2, Precision::HIGH },
|
||||
{ "shadowReserved0", 0, Type::FLOAT },
|
||||
{ "shadowReserved1", 0, Type::FLOAT },
|
||||
|
||||
{ "cascadeSplits", 0, Type::FLOAT4, Precision::HIGH },
|
||||
{ "cascades", 0, Type::INT },
|
||||
|
||||
@@ -44,7 +44,7 @@ target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
|
||||
target_include_directories(${TARGET} PRIVATE ${filamat_SOURCE_DIR}/src)
|
||||
|
||||
set_target_properties(${TARGET} PROPERTIES FOLDER Libs)
|
||||
target_link_libraries(${TARGET} getopt filamat filabridge utils)
|
||||
target_link_libraries(${TARGET} filamat filabridge utils)
|
||||
|
||||
# ==================================================================================================
|
||||
# Installation
|
||||
|
||||
@@ -41,13 +41,13 @@ bool DirIncluder::operator()(const utils::CString& includedBy, IncludeResult& re
|
||||
const utils::Path headerPath = getHeaderPath();
|
||||
|
||||
if (!headerPath.isFile()) {
|
||||
utils::slog.e << "File " << headerPath << " does not exist." << utils::io::endl;
|
||||
utils::slog.e << "File " << headerPath.c_str() << " does not exist." << utils::io::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ifstream stream(headerPath.getPath(), std::ios::binary);
|
||||
if (!stream) {
|
||||
utils::slog.e << "Unable to open " << headerPath << "." << utils::io::endl;
|
||||
utils::slog.e << "Unable to open " << headerPath.c_str() << "." << utils::io::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,7 +52,7 @@ set(LIBS
|
||||
filament
|
||||
filament-iblprefilter
|
||||
geometry
|
||||
getopt
|
||||
|
||||
image
|
||||
imageio
|
||||
imgui
|
||||
|
||||
@@ -12,6 +12,7 @@ set(PUBLIC_HDR_DIR include)
|
||||
file(GLOB_RECURSE PUBLIC_HDRS ${PUBLIC_HDR_DIR}/${TARGET}/*.h)
|
||||
|
||||
set(DIST_HDRS
|
||||
${PUBLIC_HDR_DIR}/${TARGET}/getopt.h
|
||||
${PUBLIC_HDR_DIR}/${TARGET}/algorithm.h
|
||||
${PUBLIC_HDR_DIR}/${TARGET}/bitset.h
|
||||
${PUBLIC_HDR_DIR}/${TARGET}/CallStack.h
|
||||
@@ -122,6 +123,11 @@ endif()
|
||||
include_directories(${PUBLIC_HDR_DIR})
|
||||
|
||||
add_library(${TARGET} STATIC ${PUBLIC_HDRS} ${SRCS})
|
||||
if (HAS_SYSTEM_GETOPT)
|
||||
target_compile_definitions(${TARGET} PUBLIC HAS_SYSTEM_GETOPT)
|
||||
else()
|
||||
target_link_libraries(${TARGET} PUBLIC getopt)
|
||||
endif()
|
||||
target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
|
||||
set_target_properties(${TARGET} PROPERTIES FOLDER Libs)
|
||||
target_link_libraries(${TARGET} PUBLIC tsl)
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
|
||||
#include <utils/CallStack.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/CString.h>
|
||||
#include <utils/sstream.h>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#ifdef __EXCEPTIONS
|
||||
@@ -394,14 +394,14 @@ public:
|
||||
* @param file the file where the above function in implemented
|
||||
* @param line the line in the above file where the error was detected
|
||||
* @param literal a literal version of the error message
|
||||
* @param reason std::string describing the error
|
||||
* @param reason CString describing the error
|
||||
* @see ASSERT_PRECONDITION, ASSERT_POSTCONDITION, ASSERT_ARITHMETIC
|
||||
* @see PANIC_PRECONDITION, PANIC_POSTCONDITION, PANIC_ARITHMETIC
|
||||
* @see setMode()
|
||||
*/
|
||||
static void panic(
|
||||
char const* function, char const* file, int line, char const* literal,
|
||||
std::string reason) UTILS_NORETURN;
|
||||
CString reason) UTILS_NORETURN;
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -413,7 +413,7 @@ private:
|
||||
* @param reason a description of the cause of the error
|
||||
*/
|
||||
TPanic(char const* function, char const* file, int line, char const* literal,
|
||||
std::string reason);
|
||||
CString reason);
|
||||
|
||||
friend class PreconditionPanic;
|
||||
friend class PostconditionPanic;
|
||||
@@ -426,9 +426,9 @@ private:
|
||||
char const* const mFile = nullptr; // file where the panic happened
|
||||
char const* const mFunction = nullptr; // function where the panic happened
|
||||
int const mLine = -1; // line where the panic happened
|
||||
std::string mLiteral; // reason for the panic, built only from literals
|
||||
std::string mReason; // reason for the panic
|
||||
mutable std::string mWhat; // fully formatted reason
|
||||
CString mLiteral; // reason for the panic, built only from literals
|
||||
CString mReason; // reason for the panic
|
||||
mutable CString mWhat; // fully formatted reason
|
||||
CallStack mCallstack;
|
||||
};
|
||||
|
||||
@@ -525,7 +525,7 @@ public:
|
||||
PanicStream& operator<<(const char* value) noexcept;
|
||||
PanicStream& operator<<(const unsigned char* value) noexcept;
|
||||
|
||||
PanicStream& operator<<(std::string const& value) noexcept;
|
||||
PanicStream& operator<<(CString const& value) noexcept;
|
||||
PanicStream& operator<<(std::string_view const& value) noexcept;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2026 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 UTILS_GETOPT_H
|
||||
#define UTILS_GETOPT_H
|
||||
|
||||
// If system has getopt, we just include it
|
||||
#if defined(HAS_SYSTEM_GETOPT)
|
||||
#include <getopt.h>
|
||||
#else
|
||||
#include <getopt/getopt.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#undef no_argument
|
||||
#undef required_argument
|
||||
#undef optional_argument
|
||||
|
||||
// This is an aliasing of getopt to prevent compilation conflicts with the system getop (if
|
||||
// it exists). Please refer to third_party/getopt for API details.
|
||||
namespace utils {
|
||||
namespace getopt {
|
||||
using ::getopt;
|
||||
using ::optarg;
|
||||
using ::optind;
|
||||
using ::opterr;
|
||||
using ::optopt;
|
||||
using ::option;
|
||||
using ::getopt_long;
|
||||
using ::getopt_long_only;
|
||||
|
||||
constexpr int no_argument = 0;
|
||||
constexpr int required_argument = 1;
|
||||
constexpr int optional_argument = 2;
|
||||
}
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // UTILS_GETOPT_H
|
||||
@@ -24,8 +24,12 @@
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace utils::io {
|
||||
|
||||
struct ostream_;
|
||||
@@ -62,7 +66,6 @@ public:
|
||||
ostream& operator<<(const char* string) noexcept;
|
||||
ostream& operator<<(const unsigned char* string) noexcept;
|
||||
|
||||
ostream& operator<<(std::string const& s) noexcept;
|
||||
ostream& operator<<(std::string_view const& s) noexcept;
|
||||
|
||||
ostream& operator<<(ostream& (* f)(ostream&)) noexcept { return f(*this); }
|
||||
@@ -149,11 +152,17 @@ class ostream;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& o, bitset32 const& s) noexcept {
|
||||
return o << (void*) uintptr_t(s.getValue());
|
||||
return o << reinterpret_cast<void*>(uintptr_t(s.getValue()));
|
||||
}
|
||||
|
||||
inline io::ostream& operator<<(io::ostream& o, bitset32 const& s) noexcept {
|
||||
return o << (void*) uintptr_t(s.getValue());
|
||||
return o << reinterpret_cast<void*>(uintptr_t(s.getValue()));
|
||||
}
|
||||
|
||||
inline io::ostream& operator<<(io::ostream& o, std::string const& s) noexcept {
|
||||
return o << static_cast<std::string_view>(s);
|
||||
}
|
||||
|
||||
}// namespace utils
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
#if defined(WIN32)
|
||||
# define NOMINMAX
|
||||
# include <windows.h>
|
||||
# include <string>
|
||||
# else
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
@@ -210,14 +209,22 @@ JobSystem::JobSystem(const size_t userThreadCount, const size_t adoptableThreads
|
||||
static_assert(std::atomic<bool>::is_always_lock_free);
|
||||
static_assert(std::atomic<uint16_t>::is_always_lock_free);
|
||||
|
||||
std::random_device rd;
|
||||
const size_t hardwareThreadCount = mThreadCount;
|
||||
auto& states = mThreadStates;
|
||||
|
||||
#pragma nounroll
|
||||
for (size_t i = 0, n = states.size(); i < n; i++) {
|
||||
// don't use std::random_device because it forces the use of std::string
|
||||
constexpr uint32_t base_seed = 1337;
|
||||
uint32_t seed = base_seed + static_cast<uint32_t>(i);
|
||||
seed = (seed ^ 61) ^ (seed >> 16);
|
||||
seed = seed + (seed << 3);
|
||||
seed = seed ^ (seed >> 4);
|
||||
seed = seed * 0x27d4eb2d;
|
||||
seed = seed ^ (seed >> 15);
|
||||
|
||||
auto& state = states[i];
|
||||
state.rndGen = default_random_engine(rd());
|
||||
state.rndGen = default_random_engine(seed);
|
||||
state.js = this;
|
||||
if (i < hardwareThreadCount) {
|
||||
// don't start a thread of adoptable thread slots
|
||||
|
||||
+14
-14
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <utils/CallStack.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/CString.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/ostream.h>
|
||||
@@ -33,7 +34,6 @@
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <new>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
@@ -79,8 +79,8 @@ public:
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
UTILS_NOINLINE
|
||||
static std::string sprintfToString(const char* format, va_list args) noexcept {
|
||||
std::string s;
|
||||
static CString sprintfToString(const char* format, va_list args) noexcept {
|
||||
CString s;
|
||||
va_list tmp;
|
||||
va_copy(tmp, args);
|
||||
int n = vsnprintf(nullptr, 0, format, tmp);
|
||||
@@ -91,22 +91,22 @@ static std::string sprintfToString(const char* format, va_list args) noexcept {
|
||||
char* const buf = new(std::nothrow) char[n];
|
||||
if (buf) {
|
||||
vsnprintf(buf, size_t(n), format, args);
|
||||
s.assign(buf);
|
||||
s = CString(buf);
|
||||
delete [] buf;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static std::string sprintfToString(const char* format, ...) noexcept {
|
||||
static CString sprintfToString(const char* format, ...) noexcept {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
std::string const s{ sprintfToString(format, args) };
|
||||
CString const s{ sprintfToString(format, args) };
|
||||
va_end(args);
|
||||
return s;
|
||||
}
|
||||
|
||||
static std::string buildPanicString(
|
||||
static CString buildPanicString(
|
||||
std::string_view const& msg, const char* function, int line,
|
||||
const char* file, const char* reason) {
|
||||
#ifndef NDEBUG
|
||||
@@ -130,7 +130,7 @@ void Panic::setPanicHandler(PanicHandlerCallback const handler, void* user) noex
|
||||
|
||||
template<typename T>
|
||||
TPanic<T>::TPanic(const char* function, const char* file, int const line, char const* literal,
|
||||
std::string reason)
|
||||
CString reason)
|
||||
: mFile(file),
|
||||
mFunction(function),
|
||||
mLine(line),
|
||||
@@ -200,7 +200,7 @@ void TPanic<T>::panic(char const* function, char const* file, int const line, ch
|
||||
const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
std::string reason{ sprintfToString(format, args) };
|
||||
CString reason{ sprintfToString(format, args) };
|
||||
va_end(args);
|
||||
|
||||
panic(function, file, line, literal, std::move(reason));
|
||||
@@ -208,10 +208,10 @@ void TPanic<T>::panic(char const* function, char const* file, int const line, ch
|
||||
|
||||
template<typename T>
|
||||
void TPanic<T>::panic(char const* function, char const* file, int line, char const* literal,
|
||||
std::string reason) {
|
||||
CString reason) {
|
||||
|
||||
if (reason.empty()) {
|
||||
reason = literal;
|
||||
reason = CString(literal);
|
||||
}
|
||||
|
||||
T e(function, formatFile(file), line, literal, std::move(reason));
|
||||
@@ -238,10 +238,10 @@ namespace details {
|
||||
void panicLog(char const* function, char const* file, int const line, const char* format, ...) noexcept {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
std::string const reason{ sprintfToString(format, args) };
|
||||
CString const reason{ sprintfToString(format, args) };
|
||||
va_end(args);
|
||||
|
||||
std::string const msg = buildPanicString("PanicLog",
|
||||
CString const msg = buildPanicString("PanicLog",
|
||||
function, line, file, reason.c_str());
|
||||
|
||||
slog.e << msg << io::endl;
|
||||
@@ -343,7 +343,7 @@ PanicStream& PanicStream::operator<<(unsigned char const* value) noexcept {
|
||||
return *this;
|
||||
}
|
||||
|
||||
PanicStream& PanicStream::operator<<(std::string const& value) noexcept {
|
||||
PanicStream& PanicStream::operator<<(CString const& value) noexcept {
|
||||
mStream << value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
@@ -206,10 +205,6 @@ ostream& ostream::operator<<(const void* value) noexcept {
|
||||
return print("%p", value);
|
||||
}
|
||||
|
||||
ostream& ostream::operator<<(std::string const& s) noexcept {
|
||||
return print("%s", s.c_str());
|
||||
}
|
||||
|
||||
ostream& ostream::operator<<(std::string_view const& s) noexcept {
|
||||
return print("%.*s", s.length(), s.data());
|
||||
}
|
||||
|
||||
@@ -228,7 +228,6 @@ add_library(samples-common STATIC
|
||||
)
|
||||
|
||||
target_include_directories(samples-common PRIVATE
|
||||
${ROOT_DIR}/third_party/getopt/include
|
||||
)
|
||||
target_link_libraries(samples-common filament)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <utils/Path.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@@ -73,16 +73,16 @@ filament::Engine::Backend parseArgumentsForBackend(int argc, char* argv[]) {
|
||||
// The first colon in OPTSTR turns on silent error reporting. This is important, as the
|
||||
// arguments may also contain gtest parameters we don't know about.
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int optionIndex = 0;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &optionIndex)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &optionIndex)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
|
||||
+19
-19
@@ -68,7 +68,7 @@
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
@@ -151,7 +151,7 @@ static void printUsage(char* name) {
|
||||
" Prints this message\n\n"
|
||||
"API_USAGE"
|
||||
" --ibl=<path to cmgen IBL>, -i <path>\n"
|
||||
" Applies an IBL generated by cmgen's deploy option\n\n"
|
||||
" Applies an IBL generated by cmgen's deploy utils::getopt::option\n\n"
|
||||
" --scale=[number], -s [number]\n"
|
||||
" Applies uniform scale\n\n"
|
||||
" --material=<path>, -m <path>\n"
|
||||
@@ -186,25 +186,25 @@ static void printUsage(char* name) {
|
||||
// Parses command line arguments and populates the Config object.
|
||||
static int handleCommandLineArguments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:s:li:m:c:p:x:yb:S:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ "ibl", required_argument, nullptr, 'i' },
|
||||
{ "scale", required_argument, nullptr, 's' },
|
||||
{ "material", required_argument, nullptr, 'm' },
|
||||
{ "params", required_argument, nullptr, 'p' },
|
||||
{ "count", required_argument, nullptr, 'c' },
|
||||
{ "light-on", no_argument, nullptr, 'l' },
|
||||
{ "skybox-off", no_argument, nullptr, 'y' },
|
||||
{ "prefix", required_argument, nullptr, 'x' },
|
||||
{ "clear-color", required_argument, nullptr, 'b' },
|
||||
{ "size", required_argument, nullptr, 'S' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "ibl", utils::getopt::required_argument, nullptr, 'i' },
|
||||
{ "scale", utils::getopt::required_argument, nullptr, 's' },
|
||||
{ "material", utils::getopt::required_argument, nullptr, 'm' },
|
||||
{ "params", utils::getopt::required_argument, nullptr, 'p' },
|
||||
{ "count", utils::getopt::required_argument, nullptr, 'c' },
|
||||
{ "light-on", utils::getopt::no_argument, nullptr, 'l' },
|
||||
{ "skybox-off", utils::getopt::no_argument, nullptr, 'y' },
|
||||
{ "prefix", utils::getopt::required_argument, nullptr, 'x' },
|
||||
{ "clear-color", utils::getopt::required_argument, nullptr, 'b' },
|
||||
{ "size", utils::getopt::required_argument, nullptr, 'S' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string const arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string const arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -272,7 +272,7 @@ static int handleCommandLineArguments(int argc, char* argv[], Config* config) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
// Cleans up Filament resources (entities, materials, etc.) before exit.
|
||||
|
||||
+11
-11
@@ -36,7 +36,7 @@
|
||||
|
||||
#include <camutils/Manipulator.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <utils/NameComponentManager.h>
|
||||
|
||||
@@ -112,19 +112,19 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
static constexpr const char* OPTSTR = "ha:i:un:m:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ "ibl", required_argument, nullptr, 'i' },
|
||||
{ "num", required_argument, nullptr, 'n' },
|
||||
{ "animate", required_argument, nullptr, 'm' },
|
||||
{ "ubershader", no_argument, nullptr, 'u' },
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "ibl", utils::getopt::required_argument, nullptr, 'i' },
|
||||
{ "num", utils::getopt::required_argument, nullptr, 'n' },
|
||||
{ "animate", utils::getopt::required_argument, nullptr, 'm' },
|
||||
{ "ubershader", utils::getopt::no_argument, nullptr, 'u' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -147,7 +147,7 @@ static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
static std::ifstream::pos_type getFileSize(const char* filename) {
|
||||
|
||||
+23
-29
@@ -46,7 +46,7 @@
|
||||
|
||||
#include <private/filament/EngineEnums.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <utils/NameComponentManager.h>
|
||||
#include <utils/Log.h>
|
||||
@@ -219,29 +219,29 @@ static std::ifstream::pos_type getFileSize(const char* filename) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
static constexpr const char* OPTSTR = "ha:f:i:usc:rt:y:b:evg:dw:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ "feature-level", required_argument, nullptr, 'f' },
|
||||
{ "batch", required_argument, nullptr, 'b' },
|
||||
{ "headless", no_argument, nullptr, 'e' },
|
||||
{ "ibl", required_argument, nullptr, 'i' },
|
||||
{ "ubershader", no_argument, nullptr, 'u' },
|
||||
{ "actual-size", no_argument, nullptr, 's' },
|
||||
{ "camera", required_argument, nullptr, 'c' },
|
||||
{ "eyes", required_argument, nullptr, 'y' },
|
||||
{ "recompute-aabb", no_argument, nullptr, 'r' },
|
||||
{ "settings", required_argument, nullptr, 't' },
|
||||
{ "split-view", no_argument, nullptr, 'v' },
|
||||
{ "vulkan-gpu-hint", required_argument, nullptr, 'g' },
|
||||
{ "screenshot-as-ppm", no_argument, nullptr, 'd' },
|
||||
{ "webgpu-backend", required_argument, nullptr, 'w' },
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "feature-level", utils::getopt::required_argument, nullptr, 'f' },
|
||||
{ "batch", utils::getopt::required_argument, nullptr, 'b' },
|
||||
{ "headless", utils::getopt::no_argument, nullptr, 'e' },
|
||||
{ "ibl", utils::getopt::required_argument, nullptr, 'i' },
|
||||
{ "ubershader", utils::getopt::no_argument, nullptr, 'u' },
|
||||
{ "actual-size", utils::getopt::no_argument, nullptr, 's' },
|
||||
{ "camera", utils::getopt::required_argument, nullptr, 'c' },
|
||||
{ "eyes", utils::getopt::required_argument, nullptr, 'y' },
|
||||
{ "recompute-aabb", utils::getopt::no_argument, nullptr, 'r' },
|
||||
{ "settings", utils::getopt::required_argument, nullptr, 't' },
|
||||
{ "split-view", utils::getopt::no_argument, nullptr, 'v' },
|
||||
{ "vulkan-gpu-hint", utils::getopt::required_argument, nullptr, 'g' },
|
||||
{ "screenshot-as-ppm", utils::getopt::no_argument, nullptr, 'd' },
|
||||
{ "webgpu-backend", utils::getopt::required_argument, nullptr, 'w' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string const arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string const arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -327,7 +327,7 @@ static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
std::cerr << "--headless is allowed only when --batch is present." << std::endl;
|
||||
app->config.headless = false;
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
static bool loadSettings(const char* filename, Settings* out) {
|
||||
@@ -1017,16 +1017,10 @@ int main(int argc, char** argv) {
|
||||
#endif
|
||||
const auto overdrawVisibilityBit = (1u << App::Scene::OVERDRAW_VISIBILITY_LAYER);
|
||||
bool visualizeOverdraw = view->getVisibleLayers() & overdrawVisibilityBit;
|
||||
// TODO: enable after stencil buffer supported is added for Vulkan.
|
||||
const bool overdrawDisabled = engine->getBackend() == backend::Backend::VULKAN;
|
||||
ImGui::BeginDisabled(overdrawDisabled);
|
||||
ImGui::Checkbox(!overdrawDisabled ? "Visualize overdraw"
|
||||
: "Visualize overdraw (disabled for Vulkan)",
|
||||
&visualizeOverdraw);
|
||||
ImGui::EndDisabled();
|
||||
ImGui::Checkbox("Visualize overdraw", &visualizeOverdraw);
|
||||
view->setVisibleLayers(overdrawVisibilityBit,
|
||||
(uint8_t)visualizeOverdraw << App::Scene::OVERDRAW_VISIBILITY_LAYER);
|
||||
view->setStencilBufferEnabled(visualizeOverdraw);
|
||||
app.viewer->getSettings().view.stencilBufferEnabled = visualizeOverdraw;
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopupModal("MessageBox", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <utils/JobSystem.h>
|
||||
#include <utils/Path.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
|
||||
@@ -123,15 +123,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg != nullptr ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg != nullptr ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -143,7 +143,7 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <filamentapp/Config.h>
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <stb_image.h>
|
||||
|
||||
@@ -94,15 +94,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], Config& config) {
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -113,7 +113,7 @@ static int handleCommandLineArguments(int argc, char* argv[], Config& config) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
struct App {
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <utils/EntityManager.h>
|
||||
#include <utils/Path.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <filamentapp/Config.h>
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
@@ -113,15 +113,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg != nullptr ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg != nullptr ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -133,7 +133,7 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <filamentapp/Config.h>
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>// for printing usage/help
|
||||
@@ -80,15 +80,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -99,7 +99,7 @@ static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include "generated/resources/resources.h"
|
||||
|
||||
@@ -89,15 +89,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg != nullptr ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg != nullptr ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -109,7 +109,7 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <utils/EntityManager.h>
|
||||
#include <utils/Path.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <filamentapp/Config.h>
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
@@ -116,15 +116,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg != nullptr ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg != nullptr ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -136,7 +136,7 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <utils/EntityManager.h>
|
||||
#include <utils/Path.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <filamentapp/Config.h>
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
@@ -108,15 +108,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg != nullptr ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg != nullptr ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -128,7 +128,7 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <filamentapp/Config.h>
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
@@ -108,17 +108,17 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
static constexpr const char* OPTSTR = "ha:y:m:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ "eyes", required_argument, nullptr, 'y' },
|
||||
{ "samples", required_argument, nullptr, 'm'},
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "eyes", utils::getopt::required_argument, nullptr, 'y' },
|
||||
{ "samples", utils::getopt::required_argument, nullptr, 'm'},
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -156,7 +156,7 @@ static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <filamentapp/Config.h>
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
@@ -94,15 +94,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -113,7 +113,7 @@ static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include <utils/EntityManager.h>
|
||||
#include <utils/Path.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <filamentapp/Config.h>
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
@@ -105,13 +105,13 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
static constexpr const char* OPTSTR = "ha:p";
|
||||
static const struct option OPTIONS[] = { { "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' }, { "positions", no_argument, nullptr, 'p' },
|
||||
static const utils::getopt::option OPTIONS[] = { { "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' }, { "positions", utils::getopt::no_argument, nullptr, 'p' },
|
||||
{ nullptr, 0, nullptr, 0 } };
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -125,7 +125,7 @@ static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
#include <utils/EntityManager.h>
|
||||
#include <utils/Path.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
@@ -392,16 +392,16 @@ static void printUsage(char* name) {
|
||||
// Parses command-line arguments.
|
||||
static int handleCommandLineArguments(int const argc, char* argv[], App* app) {
|
||||
static constexpr const char* OPTSTR = "he:a:c:";
|
||||
static constexpr option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ "emitters", required_argument, nullptr, 'e' },
|
||||
{ "camera", required_argument, nullptr, 'c' },
|
||||
static constexpr utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "emitters", utils::getopt::required_argument, nullptr, 'e' },
|
||||
{ "camera", utils::getopt::required_argument, nullptr, 'c' },
|
||||
{ nullptr, 0, nullptr, 0 } };
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
const std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
const std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -427,7 +427,7 @@ static int handleCommandLineArguments(int const argc, char* argv[], App* app) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
// Resets a particle to a new random state.
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
#include <camutils/Manipulator.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <math/half.h>
|
||||
#include <math/vec3.h>
|
||||
@@ -119,16 +119,16 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
static constexpr const char* OPTSTR = "ha:c:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ "camera", required_argument, nullptr, 'c' },
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "camera", utils::getopt::required_argument, nullptr, 'c' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -148,7 +148,7 @@ static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
static constexpr float4 sFullScreenTriangleVertices[3] = {
|
||||
|
||||
+15
-15
@@ -21,7 +21,7 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <utils/EntityManager.h>
|
||||
#include <utils/Path.h>
|
||||
@@ -111,22 +111,22 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "hi:vs:mdcpa:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ "ibl", required_argument, nullptr, 'i' },
|
||||
{ "split-view", no_argument, nullptr, 'v' },
|
||||
{ "scale", required_argument, nullptr, 's' },
|
||||
{ "more-lights", no_argument, nullptr, 'm' },
|
||||
{ "disco", no_argument, nullptr, 'd' },
|
||||
{ "clear-coat", no_argument, nullptr, 'c' },
|
||||
{ "shadow-plane", no_argument, nullptr, 'p' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "ibl", utils::getopt::required_argument, nullptr, 'i' },
|
||||
{ "split-view", utils::getopt::no_argument, nullptr, 'v' },
|
||||
{ "scale", utils::getopt::required_argument, nullptr, 's' },
|
||||
{ "more-lights", utils::getopt::no_argument, nullptr, 'm' },
|
||||
{ "disco", utils::getopt::no_argument, nullptr, 'd' },
|
||||
{ "clear-coat", utils::getopt::no_argument, nullptr, 'c' },
|
||||
{ "shadow-plane", utils::getopt::no_argument, nullptr, 'p' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg != nullptr ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg != nullptr ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -162,7 +162,7 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
@@ -127,22 +127,22 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:vps:i:d:c:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ "ibl", required_argument, nullptr, 'i' },
|
||||
{ "split-view", no_argument, nullptr, 'v' },
|
||||
{ "scale", required_argument, nullptr, 's' },
|
||||
{ "shadow-plane", no_argument, nullptr, 'p' },
|
||||
{ "single", no_argument, nullptr, 'n' },
|
||||
{ "dirt", required_argument, nullptr, 'd' },
|
||||
{ "camera", required_argument, nullptr, 'c' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "ibl", utils::getopt::required_argument, nullptr, 'i' },
|
||||
{ "split-view", utils::getopt::no_argument, nullptr, 'v' },
|
||||
{ "scale", utils::getopt::required_argument, nullptr, 's' },
|
||||
{ "shadow-plane", utils::getopt::no_argument, nullptr, 'p' },
|
||||
{ "single", utils::getopt::no_argument, nullptr, 'n' },
|
||||
{ "dirt", utils::getopt::required_argument, nullptr, 'd' },
|
||||
{ "camera", utils::getopt::required_argument, nullptr, 'c' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -187,7 +187,7 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
static void cleanup(Engine* engine, View*, Scene*) {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#include <filameshio/MeshReader.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
@@ -97,15 +97,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -116,7 +116,7 @@ static int handleCommandLineArguments(int argc, char* argv[], Config* config) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
static void removeObjects(Engine* engine, Scene* scene, App& app, int count) {
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <filamentapp/Config.h>
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -149,16 +149,16 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
static constexpr const char* OPTSTR = "ha:m:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ "mode", required_argument, nullptr, 'm' },
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "mode", utils::getopt::required_argument, nullptr, 'm' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -179,7 +179,7 @@ static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
+12
-12
@@ -21,7 +21,7 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <utils/Path.h>
|
||||
|
||||
@@ -76,7 +76,7 @@ static void printUsage(char* name) {
|
||||
" Prints this message\n\n"
|
||||
"API_USAGE"
|
||||
" --ibl=<path to cmgen IBL>, -i <path>\n"
|
||||
" Applies an IBL generated by cmgen's deploy option\n\n"
|
||||
" Applies an IBL generated by cmgen's deploy utils::getopt::option\n\n"
|
||||
" --split-view, -v\n"
|
||||
" Splits the window into 4 views\n\n"
|
||||
" --scale=[number], -s [number]\n"
|
||||
@@ -95,18 +95,18 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:i:vs:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "api", required_argument, 0, 'a' },
|
||||
{ "ibl", required_argument, 0, 'i' },
|
||||
{ "split-view", no_argument, 0, 'v' },
|
||||
{ "scale", required_argument, 0, 's' },
|
||||
{ 0, 0, 0, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, 0, 'h' },
|
||||
{ "api", utils::getopt::required_argument, 0, 'a' },
|
||||
{ "ibl", utils::getopt::required_argument, 0, 'i' },
|
||||
{ "split-view", utils::getopt::no_argument, 0, 'v' },
|
||||
{ "scale", utils::getopt::required_argument, 0, 's' },
|
||||
{ 0, 0, 0, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -133,7 +133,7 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
static void cleanup(Engine* engine, View* view, Scene* scene) {
|
||||
|
||||
+15
-15
@@ -39,7 +39,7 @@
|
||||
#include <math/mat4.h>
|
||||
#include <math/vec3.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <stb_image.h>
|
||||
|
||||
@@ -106,7 +106,7 @@ static void printUsage(char* name) {
|
||||
" Prints this message\n\n"
|
||||
"API_USAGE"
|
||||
" --ibl=<path to cmgen IBL>, -i <path>\n"
|
||||
" Applies an IBL generated by cmgen's deploy option\n\n"
|
||||
" Applies an IBL generated by cmgen's deploy utils::getopt::option\n\n"
|
||||
" --split-view, -v\n"
|
||||
" Splits the window into 4 views\n\n"
|
||||
" --scale=[number], -s [number]\n"
|
||||
@@ -140,21 +140,21 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:i:vs:m:cA";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ "ibl", required_argument, nullptr, 'i' },
|
||||
{ "split-view", no_argument, nullptr, 'v' },
|
||||
{ "scale", required_argument, nullptr, 's' },
|
||||
{ "material", required_argument, nullptr, 'm' },
|
||||
{ "clear-coat", no_argument, nullptr, 'c' },
|
||||
{ "anisotropy", no_argument, nullptr, 'A' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "ibl", utils::getopt::required_argument, nullptr, 'i' },
|
||||
{ "split-view", utils::getopt::no_argument, nullptr, 'v' },
|
||||
{ "scale", utils::getopt::required_argument, nullptr, 's' },
|
||||
{ "material", utils::getopt::required_argument, nullptr, 'm' },
|
||||
{ "clear-coat", utils::getopt::no_argument, nullptr, 'c' },
|
||||
{ "anisotropy", utils::getopt::no_argument, nullptr, 'A' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string const arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string const arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -190,7 +190,7 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
static void cleanup(Engine* engine, View*, Scene*) {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <utils/Path.h>
|
||||
|
||||
@@ -82,7 +82,7 @@ static void printUsage(char* name) {
|
||||
" Prints this message\n\n"
|
||||
"API_USAGE"
|
||||
" --ibl=<path to cmgen IBL>, -i <path>\n"
|
||||
" Applies an IBL generated by cmgen's deploy option\n\n"
|
||||
" Applies an IBL generated by cmgen's deploy utils::getopt::option\n\n"
|
||||
" --split-view, -v\n"
|
||||
" Splits the window into 4 views\n\n"
|
||||
" --scale=[number], -s [number]\n"
|
||||
@@ -107,21 +107,21 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:i:vs:n:a:c:b:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ "ibl", required_argument, nullptr, 'i' },
|
||||
{ "split-view", no_argument, nullptr, 'v' },
|
||||
{ "scale", required_argument, nullptr, 's' },
|
||||
{ "normal-map", required_argument, nullptr, 'n' },
|
||||
{ "clear-coat-normal-map", required_argument, nullptr, 'c' },
|
||||
{ "basecolor-map", required_argument, nullptr, 'b' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "ibl", utils::getopt::required_argument, nullptr, 'i' },
|
||||
{ "split-view", utils::getopt::no_argument, nullptr, 'v' },
|
||||
{ "scale", utils::getopt::required_argument, nullptr, 's' },
|
||||
{ "normal-map", utils::getopt::required_argument, nullptr, 'n' },
|
||||
{ "clear-coat-normal-map", utils::getopt::required_argument, nullptr, 'c' },
|
||||
{ "basecolor-map", utils::getopt::required_argument, nullptr, 'b' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -157,7 +157,7 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
static void cleanup(Engine* engine, View*, Scene*) {
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <utils/EntityManager.h>
|
||||
#include <utils/Path.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <filamentapp/Config.h>
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
@@ -160,15 +160,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg != nullptr ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg != nullptr ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -180,7 +180,7 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
+7
-7
@@ -37,7 +37,7 @@
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
#include <filamentapp/IBL.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <utils/Path.h>
|
||||
|
||||
@@ -90,15 +90,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -109,7 +109,7 @@ static int handleCommandLineArguments(int argc, char* argv[], Config* config) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
static Texture* loadNormalMap(Engine* engine, const uint8_t* normals, size_t nbytes) {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include <filamentapp/Config.h>
|
||||
#include <filamentapp/FilamentApp.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <stb_image.h>
|
||||
|
||||
@@ -103,15 +103,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], Config& config) {
|
||||
static constexpr const char* OPTSTR = "ha:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -122,7 +122,7 @@ static int handleCommandLineArguments(int argc, char* argv[], Config& config) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include <utils/EntityManager.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@@ -72,15 +72,15 @@ static void printUsage(char* name) {
|
||||
|
||||
static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
static constexpr const char* OPTSTR = "ha:f:i:usc:rt:b:ev";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "api", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -91,7 +91,7 @@ static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
@@ -53,6 +53,12 @@ for f in $(find . -name '*.h'); do
|
||||
done
|
||||
popd >/dev/null
|
||||
|
||||
# Check if the system has getopt
|
||||
HAS_SYSTEM_GETOPT=0
|
||||
if echo "#include <getopt.h>" | clang -x c++ -std=c++17 -E - > /dev/null 2>&1; then
|
||||
HAS_SYSTEM_GETOPT=1
|
||||
fi
|
||||
|
||||
rm -rf out/check-headers
|
||||
mkdir -p out/check-headers
|
||||
|
||||
@@ -61,10 +67,17 @@ echo "Checking that public headers compile independently..."
|
||||
for include in "${includes[@]}"; do
|
||||
rm -f ${TMP_FILE}
|
||||
echo "Checking ${include}"
|
||||
if [[ "${include}" == "utils/Systrace.h" ]]; then
|
||||
# A necessary define before we can include utils/Systrace.h
|
||||
echo "#define SYSTRACE_TAG SYSTRACE_TAG_DISABLED" >> ${TMP_FILE}
|
||||
fi
|
||||
case "${include}" in
|
||||
"utils/Systrace.h")
|
||||
# A necessary define before we can include utils/Systrace.h
|
||||
echo "#define SYSTRACE_TAG SYSTRACE_TAG_DISABLED" >> ${TMP_FILE}
|
||||
;;
|
||||
"utils/getopt.h")
|
||||
if [[ $HAS_SYSTEM_GETOPT -eq 1 ]]; then
|
||||
echo "#define HAS_SYSTEM_GETOPT 1" >> ${TMP_FILE}
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
echo "#include <${include}>" >> ${TMP_FILE}
|
||||
# Filament is built internally with C++20, but we maintain C++17 compatibility (for the time
|
||||
# being) in our public headers to support projects on older toolchains.
|
||||
|
||||
Vendored
+30
-24
@@ -1,24 +1,30 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(getopt)
|
||||
|
||||
set(TARGET getopt)
|
||||
set(PUBLIC_HDR_DIR include)
|
||||
|
||||
# ==================================================================================================
|
||||
# Sources and headers
|
||||
# ==================================================================================================
|
||||
set(PUBLIC_HDRS include/getopt/getopt.h)
|
||||
set(PRIVATE_HDRS include/getopt/getopt.h)
|
||||
|
||||
set(SRCS
|
||||
src/getopt.c
|
||||
src/getopt_long.c)
|
||||
|
||||
# ==================================================================================================
|
||||
# Include and target definitions
|
||||
# ==================================================================================================
|
||||
include_directories(${PUBLIC_HDR_DIR})
|
||||
|
||||
add_library(${TARGET} STATIC ${PRIVATE_HDRS} ${PUBLIC_HDRS} ${SRCS})
|
||||
target_include_directories (${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
|
||||
set_target_properties(${TARGET} PROPERTIES FOLDER ThirdParty)
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(getopt)
|
||||
|
||||
set(TARGET getopt)
|
||||
set(PUBLIC_HDR_DIR include)
|
||||
|
||||
# ==================================================================================================
|
||||
# Sources and headers
|
||||
# ==================================================================================================
|
||||
set(PUBLIC_HDRS include/getopt/getopt.h)
|
||||
set(PRIVATE_HDRS include/getopt/getopt.h)
|
||||
|
||||
set(SRCS
|
||||
src/getopt.c
|
||||
src/getopt_long.c)
|
||||
|
||||
# ==================================================================================================
|
||||
# Include and target definitions
|
||||
# ==================================================================================================
|
||||
include_directories(${PUBLIC_HDR_DIR})
|
||||
|
||||
add_library(${TARGET} STATIC ${PRIVATE_HDRS} ${PUBLIC_HDRS} ${SRCS})
|
||||
target_include_directories (${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
|
||||
set_target_properties(${TARGET} PROPERTIES FOLDER ThirdParty)
|
||||
|
||||
# ==================================================================================================
|
||||
# Installation
|
||||
# ==================================================================================================
|
||||
install(TARGETS ${TARGET} ARCHIVE DESTINATION lib/${DIST_DIR})
|
||||
install(DIRECTORY ${PUBLIC_HDR_DIR}/getopt DESTINATION include)
|
||||
|
||||
+12
-12
@@ -7,12 +7,12 @@ set(TARGET cmgen)
|
||||
# Sources and headers
|
||||
# ==================================================================================================
|
||||
set(HDRS
|
||||
src/ProgressUpdater.h
|
||||
src/ProgressUpdater.h
|
||||
)
|
||||
|
||||
set(SRCS
|
||||
src/cmgen.cpp
|
||||
src/ProgressUpdater.cpp
|
||||
src/cmgen.cpp
|
||||
src/ProgressUpdater.cpp
|
||||
)
|
||||
|
||||
# ==================================================================================================
|
||||
@@ -20,28 +20,28 @@ set(SRCS
|
||||
# ==================================================================================================
|
||||
add_executable(${TARGET} ${HDRS} ${SRCS})
|
||||
|
||||
target_link_libraries(${TARGET} PRIVATE ibl imageio getopt)
|
||||
target_link_libraries(${TARGET} PRIVATE ibl imageio )
|
||||
set_target_properties(${TARGET} PROPERTIES FOLDER Tools)
|
||||
|
||||
# ==================================================================================================
|
||||
# Compile options and optimizations
|
||||
# ==================================================================================================
|
||||
if (MSVC)
|
||||
target_compile_options(${TARGET} PRIVATE /fp:fast)
|
||||
target_compile_options(${TARGET} PRIVATE /fp:fast)
|
||||
else()
|
||||
target_compile_options(${TARGET} PRIVATE -ffast-math -fno-finite-math-only)
|
||||
target_compile_options(${TARGET} PRIVATE -ffast-math -fno-finite-math-only)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W0 /Zc:__cplusplus")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W0 /Zc:__cplusplus")
|
||||
endif()
|
||||
|
||||
# =================================================================================================
|
||||
# Licenses
|
||||
# ==================================================================================================
|
||||
set(MODULE_LICENSES getopt libpng tinyexr libz)
|
||||
set(MODULE_LICENSES libpng tinyexr libz)
|
||||
set(GENERATION_ROOT ${CMAKE_CURRENT_BINARY_DIR}/generated)
|
||||
list_licenses(${GENERATION_ROOT}/licenses/licenses.inc ${MODULE_LICENSES})
|
||||
list_licenses(${GENERATION_ROOT}/licenses/licenses.inc "${MODULE_LICENSES}")
|
||||
target_include_directories(${TARGET} PRIVATE ${GENERATION_ROOT})
|
||||
|
||||
# ==================================================================================================
|
||||
@@ -53,7 +53,7 @@ install(TARGETS ${TARGET} RUNTIME DESTINATION bin)
|
||||
# Tests
|
||||
# ==================================================================================================
|
||||
if (FILAMENT_BUILD_TESTING AND NOT ANDROID)
|
||||
add_executable(test_${TARGET} tests/test_cmgen.cpp)
|
||||
target_link_libraries(test_${TARGET} PRIVATE imageio gtest)
|
||||
set_target_properties(test_${TARGET} PROPERTIES FOLDER Tests)
|
||||
add_executable(test_${TARGET} tests/test_cmgen.cpp)
|
||||
target_link_libraries(test_${TARGET} PRIVATE imageio gtest)
|
||||
set_target_properties(test_${TARGET} PROPERTIES FOLDER Tests)
|
||||
endif()
|
||||
|
||||
+34
-34
@@ -44,7 +44,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
|
||||
using namespace filament::math;
|
||||
@@ -245,35 +245,35 @@ static void license() {
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[]) {
|
||||
static constexpr const char* OPTSTR = "hqidt:f:c:s:x:w:S:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "license", no_argument, nullptr, 'l' },
|
||||
{ "quiet", no_argument, nullptr, 'q' },
|
||||
{ "type", required_argument, nullptr, 't' },
|
||||
{ "format", required_argument, nullptr, 'f' },
|
||||
{ "compression", required_argument, nullptr, 'c' },
|
||||
{ "size", required_argument, nullptr, 's' },
|
||||
{ "extract", required_argument, nullptr, 'e' },
|
||||
{ "extract-blur", required_argument, nullptr, 'r' },
|
||||
{ "sh", optional_argument, nullptr, 'z' },
|
||||
{ "sh-output", required_argument, nullptr, 'o' },
|
||||
{ "sh-irradiance", no_argument, nullptr, 'i' },
|
||||
{ "sh-shader", no_argument, nullptr, 'b' },
|
||||
{ "sh-window", required_argument, nullptr, 'w' },
|
||||
{ "clamp", no_argument, nullptr, 'K' },
|
||||
{ "ibl-is-mipmap", required_argument, nullptr, 'y' },
|
||||
{ "ibl-ld", required_argument, nullptr, 'p' },
|
||||
{ "ibl-irradiance", required_argument, nullptr, 'P' },
|
||||
{ "ibl-dfg", required_argument, nullptr, 'a' },
|
||||
{ "ibl-dfg-multiscatter", no_argument, nullptr, 'u' },
|
||||
{ "ibl-dfg-cloth", no_argument, nullptr, 'C' },
|
||||
{ "ibl-no-prefilter", no_argument, nullptr, 'n' },
|
||||
{ "ibl-min-lod-size", required_argument, nullptr, 'S' },
|
||||
{ "ibl-samples", required_argument, nullptr, 'k' },
|
||||
{ "deploy", required_argument, nullptr, 'x' },
|
||||
{ "no-mirror", no_argument, nullptr, 'm' },
|
||||
{ "debug", no_argument, nullptr, 'd' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "license", utils::getopt::no_argument, nullptr, 'l' },
|
||||
{ "quiet", utils::getopt::no_argument, nullptr, 'q' },
|
||||
{ "type", utils::getopt::required_argument, nullptr, 't' },
|
||||
{ "format", utils::getopt::required_argument, nullptr, 'f' },
|
||||
{ "compression", utils::getopt::required_argument, nullptr, 'c' },
|
||||
{ "size", utils::getopt::required_argument, nullptr, 's' },
|
||||
{ "extract", utils::getopt::required_argument, nullptr, 'e' },
|
||||
{ "extract-blur", utils::getopt::required_argument, nullptr, 'r' },
|
||||
{ "sh", utils::getopt::optional_argument, nullptr, 'z' },
|
||||
{ "sh-output", utils::getopt::required_argument, nullptr, 'o' },
|
||||
{ "sh-irradiance", utils::getopt::no_argument, nullptr, 'i' },
|
||||
{ "sh-shader", utils::getopt::no_argument, nullptr, 'b' },
|
||||
{ "sh-window", utils::getopt::required_argument, nullptr, 'w' },
|
||||
{ "clamp", utils::getopt::no_argument, nullptr, 'K' },
|
||||
{ "ibl-is-mipmap", utils::getopt::required_argument, nullptr, 'y' },
|
||||
{ "ibl-ld", utils::getopt::required_argument, nullptr, 'p' },
|
||||
{ "ibl-irradiance", utils::getopt::required_argument, nullptr, 'P' },
|
||||
{ "ibl-dfg", utils::getopt::required_argument, nullptr, 'a' },
|
||||
{ "ibl-dfg-multiscatter", utils::getopt::no_argument, nullptr, 'u' },
|
||||
{ "ibl-dfg-cloth", utils::getopt::no_argument, nullptr, 'C' },
|
||||
{ "ibl-no-prefilter", utils::getopt::no_argument, nullptr, 'n' },
|
||||
{ "ibl-min-lod-size", utils::getopt::required_argument, nullptr, 'S' },
|
||||
{ "ibl-samples", utils::getopt::required_argument, nullptr, 'k' },
|
||||
{ "deploy", utils::getopt::required_argument, nullptr, 'x' },
|
||||
{ "no-mirror", utils::getopt::no_argument, nullptr, 'm' },
|
||||
{ "debug", utils::getopt::no_argument, nullptr, 'd' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
@@ -281,8 +281,8 @@ static int handleCommandLineArgments(int argc, char* argv[]) {
|
||||
bool format_specified = false;
|
||||
bool type_specified = false;
|
||||
bool ktx_format_requested = false;
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -471,7 +471,7 @@ static int handleCommandLineArgments(int argc, char* argv[]) {
|
||||
if (num_sh_bands && g_sh_compute) {
|
||||
g_sh_compute = (size_t) num_sh_bands;
|
||||
}
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
@@ -617,7 +617,7 @@ int main(int argc, char* argv[]) {
|
||||
levels.push_back(std::move(cml));
|
||||
}
|
||||
|
||||
// we mirror by default -- the mirror option in fact un-mirrors.
|
||||
// we mirror by default -- the mirror utils::getopt::option in fact un-mirrors.
|
||||
g_mirror = !g_mirror;
|
||||
if (g_mirror) {
|
||||
if (!g_quiet) {
|
||||
|
||||
@@ -15,20 +15,20 @@ set(SRCS src/main.cpp)
|
||||
# ==================================================================================================
|
||||
add_executable(${TARGET} ${HDRS} ${SRCS})
|
||||
|
||||
target_link_libraries(${TARGET} PRIVATE imageio getopt)
|
||||
target_link_libraries(${TARGET} PRIVATE imageio )
|
||||
set_target_properties(${TARGET} PROPERTIES FOLDER Tools)
|
||||
|
||||
# ==================================================================================================
|
||||
# Compile options and optimizations
|
||||
# ==================================================================================================
|
||||
if (NOT LINUX)
|
||||
target_compile_options(${TARGET} PRIVATE )
|
||||
target_compile_options(${TARGET} PRIVATE )
|
||||
endif()
|
||||
|
||||
# =================================================================================================
|
||||
# Licenses
|
||||
# ==================================================================================================
|
||||
set(MODULE_LICENSES getopt libpng tinyexr libz)
|
||||
set(MODULE_LICENSES libpng tinyexr libz)
|
||||
set(GENERATION_ROOT ${CMAKE_CURRENT_BINARY_DIR}/generated)
|
||||
list_licenses(${GENERATION_ROOT}/licenses/licenses.inc ${MODULE_LICENSES})
|
||||
list_licenses(${GENERATION_ROOT}/licenses/licenses.inc "${MODULE_LICENSES}")
|
||||
target_include_directories(${TARGET} PRIVATE ${GENERATION_ROOT})
|
||||
|
||||
+11
-11
@@ -31,7 +31,7 @@
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Path.h>
|
||||
|
||||
#include <getopt/getopt.h>
|
||||
#include <utils/getopt.h>
|
||||
|
||||
using namespace filament::math;
|
||||
using namespace image;
|
||||
@@ -90,20 +90,20 @@ static void license() {
|
||||
|
||||
static int handleArguments(int argc, char* argv[]) {
|
||||
static constexpr const char* OPTSTR = "hc:f:g";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "license", no_argument, nullptr, 's' },
|
||||
{ "ground-truth", no_argument, nullptr, 'g' },
|
||||
{ "format", required_argument, nullptr, 'f' },
|
||||
{ "compression", required_argument, nullptr, 'c' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
static const utils::getopt::option OPTIONS[] = {
|
||||
{ "help", utils::getopt::no_argument, nullptr, 'h' },
|
||||
{ "license", utils::getopt::no_argument, nullptr, 's' },
|
||||
{ "ground-truth", utils::getopt::no_argument, nullptr, 'g' },
|
||||
{ "format", utils::getopt::required_argument, nullptr, 'f' },
|
||||
{ "compression", utils::getopt::required_argument, nullptr, 'c' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
|
||||
};
|
||||
|
||||
int opt;
|
||||
int optionIndex = 0;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &optionIndex)) >= 0) {
|
||||
std::string arg(optarg ? optarg : "");
|
||||
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &optionIndex)) >= 0) {
|
||||
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
|
||||
switch (opt) {
|
||||
default:
|
||||
case 'h':
|
||||
@@ -145,7 +145,7 @@ static int handleArguments(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
return utils::getopt::optind;
|
||||
}
|
||||
|
||||
static bool isIncludeFile(const Path& filename) {
|
||||
|
||||
@@ -6,12 +6,12 @@ set(TARGET diffimg)
|
||||
add_executable(${TARGET} main.cpp)
|
||||
|
||||
target_link_libraries(${TARGET} PRIVATE
|
||||
getopt
|
||||
imagediff
|
||||
imageio
|
||||
imageio-lite
|
||||
image
|
||||
utils
|
||||
|
||||
imagediff
|
||||
imageio
|
||||
imageio-lite
|
||||
image
|
||||
utils
|
||||
)
|
||||
|
||||
set_target_properties(${TARGET} PROPERTIES FOLDER Tools)
|
||||
@@ -19,9 +19,9 @@ set_target_properties(${TARGET} PROPERTIES FOLDER Tools)
|
||||
# =================================================================================================
|
||||
# Licenses
|
||||
# ==================================================================================================
|
||||
set(MODULE_LICENSES getopt)
|
||||
set(MODULE_LICENSES )
|
||||
set(GENERATION_ROOT ${CMAKE_CURRENT_BINARY_DIR}/generated)
|
||||
list_licenses(${GENERATION_ROOT}/licenses/licenses.inc ${MODULE_LICENSES})
|
||||
list_licenses(${GENERATION_ROOT}/licenses/licenses.inc "${MODULE_LICENSES}")
|
||||
target_include_directories(${TARGET} PRIVATE ${GENERATION_ROOT})
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user