Compare commits

..
Author SHA1 Message Date
Run Yu 5f14ebba87 Use MapAsync and AllowProcessEvents for callback 2025-11-19 11:19:27 -05:00
716 changed files with 21804 additions and 64886 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ runs:
uses: actions/cache@v4 # Use a specific version uses: actions/cache@v4 # Use a specific version
with: with:
path: ~/Library/Caches/Homebrew path: ~/Library/Caches/Homebrew
key: ${{ runner.os }}-brew-20251211 key: ${{ runner.os }}-brew-20250424
- name: Install Mac Prerequisites - name: Install Mac Prerequisites
shell: bash shell: bash
run: | run: |
+1 -2
View File
@@ -21,9 +21,8 @@ jobs:
- name: Run update script - name: Run update script
env: env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }} GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
run: | run: |
GOLDEN_BRANCH=$(echo "${COMMIT_MESSAGE}" | python3 test/renderdiff/src/commit_msg.py) GOLDEN_BRANCH=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | python3 test/renderdiff/src/commit_msg.py)
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}" COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
if [[ "${GOLDEN_BRANCH}" != "main" ]]; then if [[ "${GOLDEN_BRANCH}" != "main" ]]; then
git config --global user.email "filament.bot@gmail.com" git config --global user.email "filament.bot@gmail.com"
+6 -6
View File
@@ -134,17 +134,18 @@ jobs:
env: env:
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }} COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
run: | run: |
ls ./gltf/Models
TEST_DIR=test/renderdiff TEST_DIR=test/renderdiff
source ${TEST_DIR}/src/preamble.sh source ${TEST_DIR}/src/preamble.sh
set -eux start_
GOLDEN_BRANCH=$(echo "${COMMIT_MESSAGE}" | python3 ${TEST_DIR}/src/commit_msg.py) GOLDEN_BRANCH=$(echo "${COMMIT_MESSAGE}" | python3 ${TEST_DIR}/src/commit_msg.py)
bash ${TEST_DIR}/generate.sh bash ${TEST_DIR}/generate.sh && \
python3 ${TEST_DIR}/src/golden_manager.py \ python3 ${TEST_DIR}/src/golden_manager.py \
--branch=${GOLDEN_BRANCH} \ --branch=${GOLDEN_BRANCH} \
--output=${GOLDEN_OUTPUT_DIR} --output=${GOLDEN_OUTPUT_DIR}
# Note that we need to upload the output even if comparison fails, so we undo `set -eux` # Note that we need to upload the output even if comparison fails, so we undo `set -ex`
set +eux end_
python3 ${TEST_DIR}/src/compare.py \ python3 ${TEST_DIR}/src/compare.py \
--src=${GOLDEN_OUTPUT_DIR} \ --src=${GOLDEN_OUTPUT_DIR} \
@@ -157,7 +158,6 @@ jobs:
cat compare_output.txt >> "$GITHUB_OUTPUT" cat compare_output.txt >> "$GITHUB_OUTPUT"
echo "$DELIMITER" >> "$GITHUB_OUTPUT" echo "$DELIMITER" >> "$GITHUB_OUTPUT"
fi fi
shell: bash
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:
name: presubmit-renderdiff-result name: presubmit-renderdiff-result
-43
View File
@@ -242,12 +242,6 @@ foremost for `arm64-v8a`.
To build Android on Windows machines, see [android/Windows.md](android/Windows.md). To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
#### Important: SDK location
Either ensure your `ANDROID_HOME` environment variable is set or make sure the root project
contains a `local.properties` file with the `sdk.dir` property pointing to your installation of
the Android SDK.
#### Easy Android build #### Easy Android build
The easiest way to build Filament for Android is to use `build.sh` and the The easiest way to build Filament for Android is to use `build.sh` and the
@@ -257,45 +251,8 @@ The easiest way to build Filament for Android is to use `build.sh` and the
./build.sh -p android release ./build.sh -p android release
``` ```
To build a sample (such as `android/samples/sample-hello-triangle`) for an ARM 64-bit phone, you would run
```shell
./build.sh -p android -q arm64-v8a -k sample-hello-triangle release
```
The output APK can be found in `android/samples/sample-hello-triangle/build/outputs/apk/release/sample-hello-triangle-release-unsigned.apk`
Run `build.sh -h` for more information. Run `build.sh -h` for more information.
#### Android Studio
You must use the latest stable release of Android Studio.
The Android build of filament is separated into java/kotlin client APIs, a layer of jni bindings
that bridges java/kotlin with native code, and Filament and other component code that have been compiled
into architecture-specific libraries. Our default Android Studio gradle setup can compile java/kotlin and
the jni bindings for you, but it will treat the filament libraries as already compiled and present on
the system.
Therefore, before compiling the sample app or any other targets, you must
make sure that the native filament libraries have been compiled and are located at a prescribed location
so that the jni bindings can link against them. You can do so by using the easy build script
```shell
./build.sh -p android release -q arm64-v8a
```
Note that the above step will also install host machine tools into prescribed locations. These tools are
required for compiling Filament assets such as materials and environment maps.
Now we are ready to compile the apps. To open the project, point Studio to the `android` folder.
After opening the project and syncing with Gradle, select the sample of your choice
using the drop-down widget in the toolbar. Additionally, you will need to select a deployment target.
By doing so, Android Studio will automatically try to compile the app only for that specific
device's architecture. So if you are targeting a new Pixel phone, make sure that the step above
(compiling the library) is targeting ARM 64-bit (`-q arm64-v8a` ), and if you are running the app on
an emulator on a Linux machine with an x86 64-bit chipset, you would indicate (`-q x86_64`) in the above step.
#### Manual builds #### Manual builds
Invoke CMake in a build directory of your choice, inside of filament's directory. The commands Invoke CMake in a build directory of your choice, inside of filament's directory. The commands
+4 -10
View File
@@ -473,7 +473,7 @@ endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}")
if (FILAMENT_ENABLE_COVERAGE) if (FILAMENT_ENABLE_COVERAGE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping -Wno-pass-failed") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping")
endif() endif()
# Disable the stack check for macOS to workaround a known issue in clang 11.0.0. # Disable the stack check for macOS to workaround a known issue in clang 11.0.0.
@@ -563,10 +563,6 @@ if (FILAMENT_SUPPORTS_WEBGPU)
add_definitions(-DFILAMENT_SUPPORTS_WEBGPU) add_definitions(-DFILAMENT_SUPPORTS_WEBGPU)
endif() endif()
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_definitions(-DFILAMENT_SUPPORTS_WEBP_TEXTURES)
endif()
# Build with Metal support on non-WebGL Apple platforms. # Build with Metal support on non-WebGL Apple platforms.
if (APPLE AND NOT WEBGL) if (APPLE AND NOT WEBGL)
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" ON) option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" ON)
@@ -876,9 +872,7 @@ add_subdirectory(${LIBRARIES}/utils)
add_subdirectory(${LIBRARIES}/viewer) add_subdirectory(${LIBRARIES}/viewer)
add_subdirectory(${FILAMENT}/shaders) add_subdirectory(${FILAMENT}/shaders)
add_subdirectory(${EXTERNAL}/abseil/tnt) add_subdirectory(${EXTERNAL}/abseil/tnt)
# Add zstd before basisu to force it to use the external zstd target, add_subdirectory(${EXTERNAL}/basisu/tnt)
# preventing a duplicate symbol conflict with its bundled version.
add_subdirectory(${EXTERNAL}/zstd/tnt)
add_subdirectory(${EXTERNAL}/civetweb/tnt) add_subdirectory(${EXTERNAL}/civetweb/tnt)
add_subdirectory(${EXTERNAL}/imgui/tnt) add_subdirectory(${EXTERNAL}/imgui/tnt)
add_subdirectory(${EXTERNAL}/robin-map/tnt) add_subdirectory(${EXTERNAL}/robin-map/tnt)
@@ -892,7 +886,7 @@ add_subdirectory(${EXTERNAL}/jsmn/tnt)
add_subdirectory(${EXTERNAL}/stb/tnt) add_subdirectory(${EXTERNAL}/stb/tnt)
add_subdirectory(${EXTERNAL}/getopt) add_subdirectory(${EXTERNAL}/getopt)
add_subdirectory(${EXTERNAL}/perfetto/tnt) add_subdirectory(${EXTERNAL}/perfetto/tnt)
add_subdirectory(${EXTERNAL}/basisu/tnt) add_subdirectory(${EXTERNAL}/zstd/tnt)
# Note that this has to be placed after mikktspace in order for combine_static_libs to work. # Note that this has to be placed after mikktspace in order for combine_static_libs to work.
@@ -919,6 +913,7 @@ endif()
if (FILAMENT_SUPPORTS_WEBP_TEXTURES) if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_subdirectory(${EXTERNAL}/libwebp/tnt) add_subdirectory(${EXTERNAL}/libwebp/tnt)
add_definitions(-DFILAMENT_SUPPORTS_WEBP_TEXTURES)
endif() endif()
if (FILAMENT_SUPPORTS_VULKAN) if (FILAMENT_SUPPORTS_VULKAN)
@@ -976,7 +971,6 @@ if (IS_HOST_PLATFORM)
add_subdirectory(${TOOLS}/roughness-prefilter) add_subdirectory(${TOOLS}/roughness-prefilter)
add_subdirectory(${TOOLS}/specular-color) add_subdirectory(${TOOLS}/specular-color)
add_subdirectory(${TOOLS}/uberz) add_subdirectory(${TOOLS}/uberz)
add_subdirectory(${TOOLS}/specgen)
endif() endif()
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS) # Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)
+4
View File
@@ -6,3 +6,7 @@
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md). appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut ## Release notes for next branch cut
- engine: add `View::getLastDynamicResolutionScale()` (b/457753622)
- materials: Make Material Instances' UBO descriptor use dynamic offsets. [⚠️ **Recompile Materials**]
+2 -2
View File
@@ -31,7 +31,7 @@ repositories {
} }
dependencies { dependencies {
implementation 'com.google.android.filament:filament-android:1.68.4' implementation 'com.google.android.filament:filament-android:1.67.0'
} }
``` ```
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release: iOS projects can use CocoaPods to install the latest release:
```shell ```shell
pod 'Filament', '~> 1.68.4' pod 'Filament', '~> 1.67.0'
``` ```
## Documentation ## Documentation
-21
View File
@@ -7,27 +7,6 @@ A new header is inserted each time a *tag* is created.
Instead, if you are authoring a PR for the main branch, add your release note to Instead, if you are authoring a PR for the main branch, add your release note to
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md). [NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
## v1.68.4
- gltfio: Add optional support for webp textures (EXT_texture_webp), controlled via FILAMENT_SUPPORTS_WEBP_TEXTURES cmake option
## v1.68.3
- materials: added support for the glTF `KHR_materials_dispersion` extension, which adds dispersion for refractive objects
## v1.68.2
- Support `setPresentationTime` with the Metal backend.
## v1.68.1
## v1.68.0
- engine: add `View::getLastDynamicResolutionScale()` (b/457753622)
- Metal: report GPU errors to the platform via `debugUpdateStat` (b/431665753).
- materials: Make Material Instances' UBO descriptor use dynamic offsets. [⚠️ **Recompile Materials**]
## v1.67.1 ## v1.67.1
- Metal: Add support for the `SwapChain::CONFIG_MSAA_4_SAMPLES` flag. - Metal: Add support for the `SwapChain::CONFIG_MSAA_4_SAMPLES` flag.
+1 -2
View File
@@ -100,7 +100,7 @@ buildscript {
'kotlin': '2.0.21', 'kotlin': '2.0.21',
'kotlin_coroutines': '1.9.0', 'kotlin_coroutines': '1.9.0',
'buildTools': '35.0.0', 'buildTools': '35.0.0',
'ndk': '29.0.14206865', 'ndk': '27.0.11718014',
'androidx_core': '1.13.1', 'androidx_core': '1.13.1',
'androidx_annotations': '1.9.0' 'androidx_annotations': '1.9.0'
] ]
@@ -124,7 +124,6 @@ buildscript {
ext.cmakeArgs = [ ext.cmakeArgs = [
"--no-warn-unused-cli", "--no-warn-unused-cli",
"-DANDROID_WEAK_API_DEFS=ON",
"-DANDROID_PIE=ON", "-DANDROID_PIE=ON",
"-DANDROID_PLATFORM=21", "-DANDROID_PLATFORM=21",
"-DANDROID_STL=c++_static", "-DANDROID_STL=c++_static",
@@ -335,13 +335,6 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefract
builder->refractionMode((MaterialBuilder::RefractionMode) mode); builder->refractionMode((MaterialBuilder::RefractionMode) mode);
} }
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderReflectionMode(JNIEnv* env,
jclass, jlong nativeBuilder, jint mode) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->reflectionMode((MaterialBuilder::ReflectionMode) mode);
}
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefractionType(JNIEnv* env, Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefractionType(JNIEnv* env,
jclass, jlong nativeBuilder, jint type) { jclass, jlong nativeBuilder, jint type) {
@@ -177,11 +177,6 @@ public class MaterialBuilder {
SCREEN_SPACE SCREEN_SPACE
} }
public enum ReflectionMode {
DEFAULT,
SCREEN_SPACE
}
public enum RefractionType { public enum RefractionType {
SOLID, SOLID,
THIN THIN
@@ -408,12 +403,6 @@ public class MaterialBuilder {
return this; return this;
} }
@NonNull
public MaterialBuilder reflectionMode(ReflectionMode mode) {
nMaterialBuilderReflectionMode(mNativeObject, mode.ordinal());
return this;
}
@NonNull @NonNull
public MaterialBuilder refractionType(RefractionType type) { public MaterialBuilder refractionType(RefractionType type) {
nMaterialBuilderRefractionType(mNativeObject, type.ordinal()); nMaterialBuilderRefractionType(mNativeObject, type.ordinal());
@@ -615,7 +604,6 @@ public class MaterialBuilder {
private static native void nMaterialBuilderSpecularAntiAliasingThreshold(long mNativeObject, private static native void nMaterialBuilderSpecularAntiAliasingThreshold(long mNativeObject,
float threshold); float threshold);
private static native void nMaterialBuilderRefractionMode(long nativeBuilder, int mode); private static native void nMaterialBuilderRefractionMode(long nativeBuilder, int mode);
private static native void nMaterialBuilderReflectionMode(long nativeBuilder, int mode);
private static native void nMaterialBuilderRefractionType(long nativeBuilder, int type); private static native void nMaterialBuilderRefractionType(long nativeBuilder, int type);
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject, private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
boolean clearCoatIorChange); boolean clearCoatIorChange);
-7
View File
@@ -134,7 +134,6 @@ target_include_directories(filament-jni PRIVATE
../../filament/backend/include ../../filament/backend/include
../../third_party/robin-map ../../third_party/robin-map
../../third_party/perfetto ../../third_party/perfetto
../../libs/bluevk/include
../../libs/utils/include) ../../libs/utils/include)
# Ordering is significant in the following list. The PRIVATE qualifier prevents transitive deps. # Ordering is significant in the following list. The PRIVATE qualifier prevents transitive deps.
@@ -168,9 +167,3 @@ target_link_libraries(filament-jni
# Force a relink when the version script is changed: # Force a relink when the version script is changed:
set_target_properties(filament-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT}) set_target_properties(filament-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
if (FILAMENT_SUPPORTS_VULKAN)
add_definitions(-DFILAMENT_SUPPORTS_VULKAN=1)
else()
add_definitions(-DFILAMENT_SUPPORTS_VULKAN=0)
endif()
@@ -25,7 +25,7 @@ using namespace filament;
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass, Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
jlong nativeEngine, jobject buffer_, jint size, jint shBandCount, jint shadowQuality, jint uboBatchingMode) { jlong nativeEngine, jobject buffer_, jint size, jint shBandCount, jint shadowQuality) {
Engine* engine = (Engine*) nativeEngine; Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, buffer_, size); AutoBuffer buffer(env, buffer_, size);
auto builder = Material::Builder(); auto builder = Material::Builder();
@@ -33,7 +33,6 @@ Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
builder.sphericalHarmonicsBandCount(shBandCount); builder.sphericalHarmonicsBandCount(shBandCount);
} }
builder.shadowSamplingQuality((Material::Builder::ShadowSamplingQuality)shadowQuality); builder.shadowSamplingQuality((Material::Builder::ShadowSamplingQuality)shadowQuality);
builder.uboBatching((Material::UboBatchingMode)uboBatchingMode);
Material* material = builder Material* material = builder
.package(buffer.getData(), buffer.getSize()) .package(buffer.getData(), buffer.getSize())
.build(*engine); .build(*engine);
@@ -63,14 +63,6 @@ Java_com_google_android_filament_Skybox_nBuilderColor(JNIEnv *, jclass,
builder->color({r, g, b, a}); builder->color({r, g, b, a});
} }
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_Skybox_nBuilderPriority(JNIEnv *, jclass,
jlong nativeSkyBoxBuilder, jint priority) {
Skybox::Builder *builder = (Skybox::Builder *) nativeSkyBoxBuilder;
builder->priority(uint8_t(priority));
}
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Skybox_nBuilderBuild(JNIEnv *env, jclass type, Java_com_google_android_filament_Skybox_nBuilderBuild(JNIEnv *env, jclass type,
jlong nativeSkyBoxBuilder, jlong nativeEngine) { jlong nativeSkyBoxBuilder, jlong nativeEngine) {
@@ -21,11 +21,6 @@
#ifdef __ANDROID__ #ifdef __ANDROID__
#include <android/bitmap.h> #include <android/bitmap.h>
#include <android/hardware_buffer_jni.h>
#include <backend/platforms/PlatformEGLAndroid.h>
# if FILAMENT_SUPPORTS_VULKAN
# include <backend/platforms/VulkanPlatformAndroid.h>
# endif
#endif #endif
#include <filament/Engine.h> #include <filament/Engine.h>
@@ -393,57 +388,6 @@ Java_com_google_android_filament_Texture_nSetExternalImage(JNIEnv*, jclass, jlon
texture->setExternalImage(*engine, (void*)eglImage); texture->setExternalImage(*engine, (void*)eglImage);
} }
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Texture_nSetExternalImageByAHB(JNIEnv *env, jclass clazz,
jlong nativeTexture, jlong nativeEngine, jobject ahb) {
Texture *texture = (Texture *) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
#ifdef __ANDROID__
Platform* platform = engine->getPlatform();
AHardwareBuffer* nativeBuffer = nullptr;
if (__builtin_available(android 26, *)) {
nativeBuffer = AHardwareBuffer_fromHardwareBuffer(env, ahb);
}
if (!nativeBuffer) {
// either we're not on Android 26, or ahb wasn't a AHardwareBuffer
return JNI_FALSE;
}
if (engine->getBackend() == Backend::OPENGL) {
// CAVEAT: we assume that Backend::OPENGL on Android implies PlatformEGLAndroid.
#if UTILS_HAS_RTTI
if (!dynamic_cast<PlatformEGLAndroid*>(platform)) {
return JNI_FALSE;
}
#endif
auto* eglPlatform = (PlatformEGLAndroid*) platform;
auto ref = eglPlatform->createExternalImage(nativeBuffer, false);
texture->setExternalImage(*engine, ref);
}
#if FILAMENT_SUPPORTS_VULKAN
else if (engine->getBackend() == Backend::VULKAN) {
// CAVEAT: we assume that Backend::VULKAN on Android implies VulkanPlatformAndroid.
#if UTILS_HAS_RTTI
if (!dynamic_cast<VulkanPlatformAndroid*>(platform)) {
return JNI_FALSE;
}
#endif
auto* vulkanPlatform = (VulkanPlatformAndroid*) platform;
auto ref = vulkanPlatform->createExternalImage(nativeBuffer, false);
texture->setExternalImage(*engine, ref);
}
#endif // FILAMENT_SUPPORTS_VULKAN
// success!
return JNI_TRUE;
#else
// other platforms could come here
return JNI_FALSE;
#endif // __ANDROID__
}
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Texture_nSetExternalStream(JNIEnv*, jclass, Java_com_google_android_filament_Texture_nSetExternalStream(JNIEnv*, jclass,
jlong nativeTexture, jlong nativeEngine, jlong nativeStream) { jlong nativeTexture, jlong nativeEngine, jlong nativeStream) {
@@ -663,4 +607,3 @@ Java_com_google_android_filament_android_TextureHelper_nSetBitmapWithCallback(JN
} }
#endif #endif
@@ -261,20 +261,6 @@ public class Material {
LOW LOW
} }
/**
* Defines whether a material instance should use UBO batching or not.
*/
public enum UboBatchingMode {
/**
* For default, it follows the engine settings.
* If UBO batching is enabled on the engine and the material domain is SURFACE, it
* turns on the UBO batching. Otherwise, it turns off the UBO batching.
*/
DEFAULT,
/** Disable the Ubo Batching for this material */
DISABLED
}
public static class UserVariantFilterBit { public static class UserVariantFilterBit {
/** Directional lighting */ /** Directional lighting */
public static int DIRECTIONAL_LIGHTING = 0x01; public static int DIRECTIONAL_LIGHTING = 0x01;
@@ -386,7 +372,6 @@ public class Material {
private int mSize; private int mSize;
private int mShBandCount = 0; private int mShBandCount = 0;
private ShadowSamplingQuality mShadowSamplingQuality = ShadowSamplingQuality.LOW; private ShadowSamplingQuality mShadowSamplingQuality = ShadowSamplingQuality.LOW;
private UboBatchingMode mUboBatchingMode = UboBatchingMode.DEFAULT;
/** /**
@@ -431,17 +416,6 @@ public class Material {
return this; return this;
} }
/**
* Set the batching mode of the instances created from this material.
* @param uboBatchingMode
* @return Reference to this Builder for chaining calls.
*/
@NonNull
public Builder uboBatching(UboBatchingMode mode) {
mUboBatchingMode = mode;
return this;
}
/** /**
* Creates and returns the Material object. * Creates and returns the Material object.
* *
@@ -454,7 +428,7 @@ public class Material {
@NonNull @NonNull
public Material build(@NonNull Engine engine) { public Material build(@NonNull Engine engine) {
long nativeMaterial = nBuilderBuild(engine.getNativeObject(), long nativeMaterial = nBuilderBuild(engine.getNativeObject(),
mBuffer, mSize, mShBandCount, mShadowSamplingQuality.ordinal(), mUboBatchingMode.ordinal()); mBuffer, mSize, mShBandCount, mShadowSamplingQuality.ordinal());
if (nativeMaterial == 0) throw new IllegalStateException("Couldn't create Material"); if (nativeMaterial == 0) throw new IllegalStateException("Couldn't create Material");
return new Material(nativeMaterial); return new Material(nativeMaterial);
} }
@@ -1120,7 +1094,7 @@ public class Material {
mNativeObject = 0; mNativeObject = 0;
} }
private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size, int shBandCount, int shadowQuality, int uboBatchingMode); private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size, int shBandCount, int shadowQuality);
private static native long nCreateInstance(long nativeMaterial); private static native long nCreateInstance(long nativeMaterial);
private static native long nCreateInstanceWithName(long nativeMaterial, @NonNull String name); private static native long nCreateInstanceWithName(long nativeMaterial, @NonNull String name);
private static native long nGetDefaultInstance(long nativeMaterial); private static native long nGetDefaultInstance(long nativeMaterial);
@@ -155,24 +155,6 @@ public class Skybox {
return this; return this;
} }
/**
* Set the rendering priority of the Skybox. By default, it is set to the lowest
* priority (7) such that the Skybox is always rendered after the opaque objects,
* to reduce overdraw when depth culling is enabled.
*
* @param priority clamped to the range [0..7], defaults to 4; 7 is lowest priority
* (rendered last).
*
* @return Builder reference for chaining calls.
*
* @see RenderableManager.Builder#priority
*/
@NonNull
public Builder priority(@IntRange(from = 0, to = 7) int priority) {
nBuilderPriority(mNativeBuilder, priority);
return this;
}
/** /**
* Creates a <code>Skybox</code> object * Creates a <code>Skybox</code> object
* *
@@ -280,7 +262,6 @@ public class Skybox {
private static native void nBuilderShowSun(long nativeSkyboxBuilder, boolean show); private static native void nBuilderShowSun(long nativeSkyboxBuilder, boolean show);
private static native void nBuilderIntensity(long nativeSkyboxBuilder, float intensity); private static native void nBuilderIntensity(long nativeSkyboxBuilder, float intensity);
private static native void nBuilderColor(long nativeSkyboxBuilder, float r, float g, float b, float a); private static native void nBuilderColor(long nativeSkyboxBuilder, float r, float g, float b, float a);
private static native void nBuilderPriority(long nativeSkyboxBuilder, int priority);
private static native long nBuilderBuild(long nativeSkyboxBuilder, long nativeEngine); private static native long nBuilderBuild(long nativeSkyboxBuilder, long nativeEngine);
private static native void nSetLayerMask(long nativeSkybox, int select, int value); private static native void nSetLayerMask(long nativeSkybox, int select, int value);
private static native int nGetLayerMask(long nativeSkybox); private static native int nGetLayerMask(long nativeSkybox);
@@ -71,16 +71,6 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
* @see MaterialInstance#setParameter(String, Texture, TextureSampler) * @see MaterialInstance#setParameter(String, Texture, TextureSampler)
*/ */
public class Texture { public class Texture {
private static Class<?> HardwareBufferClass = null;
static {
try {
HardwareBufferClass = Class.forName("android.hardware.HardwareBuffer");
} catch (ClassNotFoundException ignored) {
}
}
private static final Sampler[] sSamplerValues = Sampler.values(); private static final Sampler[] sSamplerValues = Sampler.values();
private static final InternalFormat[] sInternalFormatValues = InternalFormat.values(); private static final InternalFormat[] sInternalFormatValues = InternalFormat.values();
@@ -1182,38 +1172,6 @@ public class Texture {
nSetExternalImage(getNativeObject(), engine.getNativeObject(), eglImage); nSetExternalImage(getNativeObject(), engine.getNativeObject(), eglImage);
} }
/**
* Specifies the external image to associate with this <code>Texture</code>.
*
* <p>Typically, the external image is OS specific, and can be a video or camera frame.
* There are many restrictions when using an external image as a texture, such as:</p>
* <ul>
* <li> only the level of detail (lod) 0 can be specified</li>
* <li> only nearest or linear filtering is supported</li>
* <li> the size and format of the texture is defined by the external image</li>
* <li> only the CLAMP_TO_EDGE wrap mode is supported</li>
* </ul>
*
* @param engine {@link Engine} this texture is associated to. Must be the
* instance passed to {@link Builder#build Builder.build()}.
* @param externalImageRef An OS specific Object. On Android it must be a
* <code>android.hardware.HardwareBuffer</code>
*/
public void setExternalImage(@NonNull Engine engine, Object externalImageRef) {
if (HardwareBufferClass != null) {
if (!HardwareBufferClass.isInstance(externalImageRef)) {
throw new IllegalArgumentException("externalImageRef must be a AHardwareBuffer");
}
if (!nSetExternalImageByAHB(getNativeObject(), engine.getNativeObject(), externalImageRef)) {
throw new IllegalStateException("Error setting AHardwareBuffer as external image");
}
} else {
throw new UnsupportedOperationException(
"setExternalImage(Engine, Object) not supported on this platform");
}
}
/** /**
* Specifies the external stream to associate with this <code>Texture</code>. * Specifies the external stream to associate with this <code>Texture</code>.
* *
@@ -1406,8 +1364,6 @@ public class Texture {
private static native void nSetExternalImage( private static native void nSetExternalImage(
long nativeObject, long nativeEngine, long eglImage); long nativeObject, long nativeEngine, long eglImage);
private static native boolean nSetExternalImageByAHB(long nativeTexture, long nativeObject, Object ahb);
private static native void nSetExternalStream(long nativeTexture, private static native void nSetExternalStream(long nativeTexture,
long nativeEngine, long nativeStream); long nativeEngine, long nativeStream);
@@ -2041,6 +2041,10 @@ public class View {
* use an AABB neighborhood * use an AABB neighborhood
*/ */
AABB, AABB,
/**
* use the variance of the neighborhood (not recommended)
*/
VARIANCE,
/** /**
* use both AABB and variance * use both AABB and variance
*/ */
@@ -2071,7 +2075,7 @@ public class View {
} }
/** /**
* @deprecated has no effect. * reconstruction filter width typically between 1 (sharper) and 2 (smoother)
*/ */
public float filterWidth = 1.0f; public float filterWidth = 1.0f;
/** /**
@@ -2091,9 +2095,9 @@ public class View {
*/ */
public boolean enabled = false; public boolean enabled = false;
/** /**
* Upscaling factor. Disables Dynamic Resolution. [BETA] * 4x TAA upscaling. Disables Dynamic Resolution. [BETA]
*/ */
public float upscaling = 1.0f; public boolean upscaling = false;
/** /**
* whether to filter the history buffer * whether to filter the history buffer
*/ */
@@ -2106,10 +2110,6 @@ public class View {
* whether to use the YcoCg color-space for history rejection * whether to use the YcoCg color-space for history rejection
*/ */
public boolean useYCoCg = false; public boolean useYCoCg = false;
/**
* set to true for HDR content
*/
public boolean hdr = true;
/** /**
* type of color gamut box * type of color gamut box
*/ */
@@ -16,9 +16,6 @@
package com.google.android.filament.utils package com.google.android.filament.utils
import android.graphics.Bitmap
import android.os.Handler
import android.os.Looper
import android.view.MotionEvent import android.view.MotionEvent
import android.view.Surface import android.view.Surface
import android.view.SurfaceView import android.view.SurfaceView
@@ -29,7 +26,6 @@ import com.google.android.filament.android.UiHelper
import com.google.android.filament.gltfio.* import com.google.android.filament.gltfio.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.nio.Buffer import java.nio.Buffer
import java.nio.ByteBuffer
private const val kNearPlane = 0.05f // 5 cm private const val kNearPlane = 0.05f // 5 cm
private const val kFarPlane = 1000.0f // 1 km private const val kFarPlane = 1000.0f // 1 km
@@ -123,8 +119,6 @@ class ModelViewer(
private val target = DoubleArray(3) private val target = DoubleArray(3)
private val upward = DoubleArray(3) private val upward = DoubleArray(3)
private var debugFrameCallback: ((Bitmap) -> Unit)? = null
init { init {
renderer = engine.createRenderer() renderer = engine.createRenderer()
scene = engine.createScene() scene = engine.createScene()
@@ -311,39 +305,10 @@ class ModelViewer(
// Render the scene, unless the renderer wants to skip the frame. // Render the scene, unless the renderer wants to skip the frame.
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) { if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
renderer.render(view) renderer.render(view)
debugFrameCallback?.let {
val viewport = view.viewport
val bitmap = Bitmap.createBitmap(viewport.width, viewport.height,
Bitmap.Config.ARGB_8888)
val buffer = ByteBuffer.allocateDirect(viewport.width * viewport.height * 4)
val handler = Handler(Looper.getMainLooper())
val pixelBufferDescriptor = Texture.PixelBufferDescriptor(buffer,
Texture.Format.RGBA, Texture.Type.UBYTE, 1, 0, 0, 0, handler) {
buffer.rewind()
bitmap.copyPixelsFromBuffer(buffer)
it(bitmap)
}
renderer.readPixels(viewport.left, viewport.bottom, viewport.width,
viewport.height, pixelBufferDescriptor)
debugFrameCallback = null
}
renderer.endFrame() renderer.endFrame()
} }
} }
/*
* Sets a callback that will be invoked with the next rendered frame as a Bitmap. Note that this
* is a one-time callback.
*
* @param callback callback to be invoked with a rendered frame as [Bitmap]
*/
fun debugGetNextFrameCallback(callback: (Bitmap) -> Unit) {
debugFrameCallback = callback
}
private fun populateScene(asset: FilamentAsset) { private fun populateScene(asset: FilamentAsset) {
val rcm = engine.renderableManager val rcm = engine.renderableManager
var count = 0 var count = 0
-14
View File
@@ -6,7 +6,6 @@ option(FILAMENT_ENABLE_FGVIEWER "Enables Frame Graph Viewer" OFF)
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF) option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF) option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF)
option(FILAMENT_SUPPORTS_WEBGPU "Enables WebGPU on Android" OFF) option(FILAMENT_SUPPORTS_WEBGPU "Enables WebGPU on Android" OFF)
option(FILAMENT_SUPPORTS_WEBP_TEXTURES "Enable webp texture support on Android" OFF)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
@@ -31,12 +30,6 @@ add_library(stb STATIC IMPORTED)
set_target_properties(stb PROPERTIES IMPORTED_LOCATION set_target_properties(stb PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libstb.a) ${FILAMENT_DIR}/lib/${ANDROID_ABI}/libstb.a)
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_library(webpdecoder STATIC IMPORTED)
set_target_properties(webpdecoder PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libwebpdecoder.a)
endif()
add_library(basis_transcoder STATIC IMPORTED) add_library(basis_transcoder STATIC IMPORTED)
set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a) ${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a)
@@ -88,10 +81,6 @@ set(GLTFIO_INCLUDE_DIRS
../../libs/ktxreader/include ../../libs/ktxreader/include
) )
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
list(APPEND GLTFIO_INCLUDE_DIRS ../../third_party/libwebp/src)
endif()
add_library(gltfio-jni SHARED ${GLTFIO_SRCS}) add_library(gltfio-jni SHARED ${GLTFIO_SRCS})
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1) target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1)
@@ -118,6 +107,3 @@ target_link_libraries(gltfio-jni
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
PRIVATE log # needed only when perfetto above is used PRIVATE log # needed only when perfetto above is used
) )
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
target_link_libraries(gltfio-jni PRIVATE webpdecoder)
endif()
@@ -128,18 +128,6 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nCreateKtx2Provider(JNIEn
return (jlong) createKtx2Provider(engine); return (jlong) createKtx2Provider(engine);
} }
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nIsWebpSupported(JNIEnv*, jclass) {
return (jboolean) isWebpSupported();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateWebpProvider(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) createWebpProvider(engine);
}
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nDestroyTextureProvider(JNIEnv*, jclass, Java_com_google_android_filament_gltfio_ResourceLoader_nDestroyTextureProvider(JNIEnv*, jclass,
jlong nativeProvider) { jlong nativeProvider) {
@@ -37,7 +37,6 @@ public class ResourceLoader {
private final long mNativeObject; private final long mNativeObject;
private final long mNativeStbProvider; private final long mNativeStbProvider;
private final long mNativeKtx2Provider; private final long mNativeKtx2Provider;
private final long mNativeWebpProvider;
/** /**
* Constructs a resource loader tied to the given Filament engine. * Constructs a resource loader tied to the given Filament engine.
@@ -51,17 +50,9 @@ public class ResourceLoader {
mNativeObject = nCreateResourceLoader(nativeEngine, false); mNativeObject = nCreateResourceLoader(nativeEngine, false);
mNativeStbProvider = nCreateStbProvider(nativeEngine); mNativeStbProvider = nCreateStbProvider(nativeEngine);
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine); mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider); nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider); nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider); nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
if (nIsWebpSupported()) {
mNativeWebpProvider = nCreateWebpProvider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/webp", mNativeWebpProvider);
}
else {
mNativeWebpProvider = 0;
}
} }
/** /**
@@ -77,17 +68,9 @@ public class ResourceLoader {
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights); mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights);
mNativeStbProvider = nCreateStbProvider(nativeEngine); mNativeStbProvider = nCreateStbProvider(nativeEngine);
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine); mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider); nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider); nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider); nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
if (nIsWebpSupported()) {
mNativeWebpProvider = nCreateWebpProvider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/webp", mNativeWebpProvider);
}
else {
mNativeWebpProvider = 0;
}
} }
/** /**
@@ -97,9 +80,6 @@ public class ResourceLoader {
nDestroyResourceLoader(mNativeObject); nDestroyResourceLoader(mNativeObject);
nDestroyTextureProvider(mNativeStbProvider); nDestroyTextureProvider(mNativeStbProvider);
nDestroyTextureProvider(mNativeKtx2Provider); nDestroyTextureProvider(mNativeKtx2Provider);
if (nIsWebpSupported()) {
nDestroyTextureProvider(mNativeWebpProvider);
}
} }
/** /**
@@ -211,9 +191,6 @@ public class ResourceLoader {
private static native long nCreateStbProvider(long nativeEngine); private static native long nCreateStbProvider(long nativeEngine);
private static native long nCreateKtx2Provider(long nativeEngine); private static native long nCreateKtx2Provider(long nativeEngine);
private static native boolean nIsWebpSupported();
private static native long nCreateWebpProvider(long nativeEngine);
private static native void nAddTextureProvider(long nativeLoader, String url, long nativeProvider); private static native void nAddTextureProvider(long nativeLoader, String url, long nativeProvider);
private static native void nDestroyTextureProvider(long nativeProvider); private static native void nDestroyTextureProvider(long nativeProvider);
} }
+1 -1
View File
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament GROUP=com.google.android.filament
VERSION_NAME=1.68.4 VERSION_NAME=1.67.0
POM_DESCRIPTION=Real-time physically based rendering engine for Android. POM_DESCRIPTION=Real-time physically based rendering engine for Android.
+45 -3
View File
@@ -80,12 +80,54 @@ frame and the external texture are perfectly synchronized.
![Stream Test](../../docs/images/samples/sample_stream_test.jpg) ![Stream Test](../../docs/images/samples/sample_stream_test.jpg)
## Building Samples ## Prerequisites
Before you start, make sure to read [Filament's README](../../README.md). You need to be able to Before you start, make sure to read [Filament's README](../../README.md). You need to be able to
compile Filament's native library and Filament's AAR for this project. The easiest way to proceed compile Filament's native library and Filament's AAR for this project. The easiest way to proceed
is to install all the required dependencies and to run the following commands at the root of the is to install all the required dependencies and to run the following commands at the root of the
source tree. source tree:
To build the samples, please follow the steps described in [BUILDING.md](../../BUILDING.md#android) ```shell
./build.sh -p desktop -i release
./build.sh -p android release
```
This will build all the native components and the AAR required by this sample application.
If you do not use the build script, you must set the `filament_tools_dir` property when invoking
Gradle, either from the command line or from `local.properties`. This property must point to the
distribution/install directory for desktop (produced by make/ninja install). This directory must
contain `bin/matc` and `bin/cmgen`.
Example:
```shell
./gradlew -Pfilament_tools_dir=../../dist-release assembleDebug
```
## Important: SDK location
Either ensure your `ANDROID_HOME` environment variable is set or make sure the root project
contains a `local.properties` file with the `sdk.dir` property pointing to your installation of
the Android SDK.
## Compiling
### Android Studio
You must use the latest stable release of Android Studio. To open the project, point Studio to the
`android` folder. After opening the project and syncing to gradle, select the sample of your choice
using the drop-down widget in the toolbar.
To compile and run each sample make sure you have selected the appropriate build variant
(arm7, arm8, x86 or x86_64). If you are not sure you can simply select the "universal"
variant which includes all the other ones.
### Command Line
From the `android` directory in the project root:
```shell
./gradlew :samples:sample-hello-triangle:installDebug
```
Replace `sample-hello-triangle` with your preferred project.
@@ -1,12 +0,0 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
/.idea/caches
/.idea/gradle.xml
.DS_Store
/build
/captures
/src/main/assets
.externalNativeBuild
@@ -1,53 +0,0 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
}
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
}
clean.doFirst {
delete "src/main/assets"
}
android {
namespace 'com.google.android.filament.texturetarget'
compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.google.android.filament.texturetarget"
minSdkVersion 26
targetSdkVersion versions.targetSdk
}
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
// is not configuration-cache friendly yet; this is only useful for Play publication
dependenciesInfo {
includeInApk = false
}
// We use the .filamat extension for materials compiled with matc
// Telling aapt to not compress them allows to load them efficiently
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
implementation deps.kotlin
implementation project(':filament-android')
}
@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:exported="true"
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
@@ -1,449 +0,0 @@
/*
* Copyright (C) 2024 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.
*/
package com.google.android.filament.texturetarget
import android.animation.ValueAnimator
import android.app.Activity
import android.hardware.HardwareBuffer
import android.opengl.Matrix
import android.os.Bundle
import android.view.Choreographer
import android.view.Surface
import android.view.SurfaceView
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.RenderableManager.PrimitiveType
import com.google.android.filament.VertexBuffer.AttributeType
import com.google.android.filament.VertexBuffer.VertexAttribute
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.channels.Channels
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
class MainActivity : Activity() {
companion object {
init {
Filament.init()
}
}
private lateinit var surfaceView: SurfaceView
private lateinit var uiHelper: UiHelper
private lateinit var displayHelper: DisplayHelper
private lateinit var choreographer: Choreographer
private lateinit var engine: Engine
private lateinit var renderer: Renderer
private lateinit var scene: Scene
private lateinit var view: View
private lateinit var camera: Camera
private lateinit var triangleMaterial: Material
private lateinit var texturedMaterial: Material
private lateinit var triangleVertexBuffer: VertexBuffer
private lateinit var triangleIndexBuffer: IndexBuffer
private lateinit var quadVertexBuffer: VertexBuffer
private lateinit var quadIndexBuffer: IndexBuffer
@Entity private var triangleRenderable = 0
@Entity private var quadRenderable = 0
private var swapChain: SwapChain? = null
private val frameScheduler = FrameCallback()
private val animator = ValueAnimator.ofFloat(0.0f, 360.0f)
private var hardwareBuffer: HardwareBuffer? = null
private var texture: Texture? = null
private var renderTarget: RenderTarget? = null
private var useExternalTexture = true
private lateinit var offscreenView: View
private lateinit var offscreenCamera: Camera
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// To use set this flag with adb, run
// adb shell am start -n com.google.android.filament.texturetarget/.MainActivity --ez useExternalTexture false
useExternalTexture = intent.getBooleanExtra("useExternalTexture", true)
surfaceView = SurfaceView(this)
setContentView(surfaceView)
choreographer = Choreographer.getInstance()
displayHelper = DisplayHelper(this)
setupSurfaceView()
setupFilament()
setupView()
setupScene()
}
private fun setupSurfaceView() {
uiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
uiHelper.renderCallback = SurfaceCallback()
uiHelper.attachTo(surfaceView)
}
private fun setupFilament() {
engine = Engine.create()
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera(engine.entityManager.create())
offscreenView = engine.createView()
offscreenCamera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
scene.skybox = Skybox.Builder()
.priority(0)
.color(0.0f, 0.0f, 1.0f, 1.0f).build(engine)
// This is the view that will be drawn on screen.
view.camera = camera
view.scene = scene
view.isPostProcessingEnabled = false
// This is the view that will be rendered off-screen.
offscreenView.camera = offscreenCamera
offscreenView.scene = scene
offscreenView.isPostProcessingEnabled = false
}
private fun setupScene() {
loadMaterials()
createTriangleMesh()
createQuadMesh()
// layer 1: skybox
// layer 2: triangle
// layer 3: quad
triangleMaterial.defaultInstance.cullingMode = Material.CullingMode.NONE;
texturedMaterial.defaultInstance.cullingMode = Material.CullingMode.NONE;
// The triangle is a regular renderable.
triangleRenderable = EntityManager.get().create()
RenderableManager.Builder(1)
.geometry(0, PrimitiveType.TRIANGLES, triangleVertexBuffer, triangleIndexBuffer, 0, 3)
.material(0, triangleMaterial.defaultInstance)
.culling(false)
.castShadows(false)
.receiveShadows(false)
.layerMask(7, 2)
.build(engine, triangleRenderable)
// The quad is a regular renderable.
quadRenderable = EntityManager.get().create()
RenderableManager.Builder(1)
.geometry(0, PrimitiveType.TRIANGLES, quadVertexBuffer, quadIndexBuffer, 0, 6)
.material(0, texturedMaterial.defaultInstance)
.culling(false)
.castShadows(false)
.receiveShadows(false)
.layerMask(7, 4)
.build(engine, quadRenderable)
// We only want to render the triangle in the offscreen view.
offscreenView.setVisibleLayers(7, 3) // render skybox + triangle
// We only want to render the quad in the on-screen view.
view.setVisibleLayers(7, 4) // render quad only
scene.addEntity(triangleRenderable)
scene.addEntity(quadRenderable)
startAnimation()
}
private fun loadMaterials() {
readUncompressedAsset("materials/baked_color.filamat").let {
triangleMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
if (useExternalTexture) {
readUncompressedAsset("materials/texturedExternal.filamat").let {
texturedMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
} else {
readUncompressedAsset("materials/textured.filamat").let {
texturedMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
}
}
private fun createTriangleMesh() {
val intSize = 4
val floatSize = 4
val shortSize = 2
val vertexSize = 3 * floatSize + intSize
data class Vertex(val x: Float, val y: Float, val z: Float, val color: Int)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.z)
putInt(v.color)
return this
}
val vertexCount = 3
val a1 = PI * 2.0 / 3.0
val a2 = PI * 4.0 / 3.0
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
.order(ByteOrder.nativeOrder())
.put(Vertex(1.0f, 0.0f, 0.0f, 0xffff0000.toInt()))
.put(Vertex(cos(a1).toFloat(), sin(a1).toFloat(), 0.0f, 0xff00ff00.toInt()))
.put(Vertex(cos(a2).toFloat(), sin(a2).toFloat(), 0.0f, 0xff0000ff.toInt()))
.flip()
triangleVertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT3, 0, vertexSize)
.attribute(VertexAttribute.COLOR, 0, AttributeType.UBYTE4, 3 * floatSize, vertexSize)
.normalized(VertexAttribute.COLOR)
.build(engine)
triangleVertexBuffer.setBufferAt(engine, 0, vertexData)
val indexData = ByteBuffer.allocate(vertexCount * shortSize)
.order(ByteOrder.nativeOrder())
.putShort(0)
.putShort(1)
.putShort(2)
.flip()
triangleIndexBuffer = IndexBuffer.Builder()
.indexCount(3)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
triangleIndexBuffer.setBuffer(engine, indexData)
}
private fun createQuadMesh() {
val floatSize = 4
val shortSize = 2
val vertexSize = (2 * floatSize) + (2 * floatSize) // position + UV
data class Vertex(val x: Float, val y: Float, val u: Float, val v: Float)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.u)
putFloat(v.v)
return this
}
val vertexCount = 4
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
.order(ByteOrder.nativeOrder())
.put(Vertex(-1.0f, -1.0f, 0.0f, 0.0f))
.put(Vertex( 1.0f, -1.0f, 1.0f, 0.0f))
.put(Vertex( 1.0f, 1.0f, 1.0f, 1.0f))
.put(Vertex(-1.0f, 1.0f, 0.0f, 1.0f))
.flip()
quadVertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT2, 0, vertexSize)
.attribute(VertexAttribute.UV0, 0, AttributeType.FLOAT2, 2 * floatSize, vertexSize)
.build(engine)
quadVertexBuffer.setBufferAt(engine, 0, vertexData)
val indexData = ByteBuffer.allocate(6 * shortSize)
.order(ByteOrder.nativeOrder())
.putShort(0).putShort(1).putShort(2)
.putShort(0).putShort(2).putShort(3)
.flip()
quadIndexBuffer = IndexBuffer.Builder()
.indexCount(6)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
quadIndexBuffer.setBuffer(engine, indexData)
}
private fun startAnimation() {
animator.interpolator = LinearInterpolator()
animator.duration = 4000
animator.repeatMode = ValueAnimator.RESTART
animator.repeatCount = ValueAnimator.INFINITE
animator.addUpdateListener { a ->
val transformMatrix = FloatArray(16)
Matrix.setRotateM(transformMatrix, 0, -(a.animatedValue as Float), 0.0f, 0.0f, 1.0f)
val tcm = engine.transformManager
tcm.setTransform(tcm.getInstance(triangleRenderable), transformMatrix)
}
animator.start()
}
override fun onResume() {
super.onResume()
choreographer.postFrameCallback(frameScheduler)
animator.start()
}
override fun onPause() {
super.onPause()
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
}
override fun onDestroy() {
super.onDestroy()
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
uiHelper.detach()
// Destroy all renderables.
scene.remove(triangleRenderable)
scene.remove(quadRenderable)
// Destroy all resources.
engine.destroyEntity(triangleRenderable)
engine.destroyEntity(quadRenderable)
engine.destroyRenderer(renderer)
engine.destroyVertexBuffer(triangleVertexBuffer)
engine.destroyIndexBuffer(triangleIndexBuffer)
engine.destroyVertexBuffer(quadVertexBuffer)
engine.destroyIndexBuffer(quadIndexBuffer)
engine.destroyMaterial(triangleMaterial)
engine.destroyMaterial(texturedMaterial)
engine.destroyView(view)
engine.destroyView(offscreenView)
engine.destroyScene(scene)
engine.destroyCameraComponent(camera.entity)
engine.destroyCameraComponent(offscreenCamera.entity)
renderTarget?.let { engine.destroyRenderTarget(it) }
texture?.let { engine.destroyTexture(it) }
hardwareBuffer?.close()
val entityManager = EntityManager.get()
entityManager.destroy(triangleRenderable)
entityManager.destroy(quadRenderable)
entityManager.destroy(camera.entity)
entityManager.destroy(offscreenCamera.entity)
engine.destroy()
}
inner class FrameCallback : Choreographer.FrameCallback {
override fun doFrame(frameTimeNanos: Long) {
choreographer.postFrameCallback(this)
if (uiHelper.isReadyToRender) {
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
// Render the triangle to the texture.
renderer.render(offscreenView)
// Render the quad to the screen.
renderer.render(view)
renderer.endFrame()
}
}
}
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
displayHelper.attach(renderer, surfaceView.display)
}
override fun onDetachedFromSurface() {
displayHelper.detach()
swapChain?.let {
engine.destroySwapChain(it)
engine.flushAndWait()
swapChain = null
}
}
override fun onResized(width: Int, height: Int) {
// On-screen camera
val zoom = 1.0
val aspect = width.toDouble() / height.toDouble()
camera.setProjection(Camera.Projection.ORTHO, -aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
view.viewport = Viewport(0, 0, width, height)
// Off-screen camera
val offscreenZoom = 1.5
offscreenCamera.setProjection(Camera.Projection.ORTHO,
-aspect * offscreenZoom, aspect * offscreenZoom,
-offscreenZoom, offscreenZoom, 0.0, 10.0)
offscreenView.viewport = Viewport(0, 0, width, height)
// If we have a render target, destroy it.
renderTarget?.let { engine.destroyRenderTarget(it) }
texture?.let { engine.destroyTexture(it) }
hardwareBuffer?.close()
if (useExternalTexture) {
// Create a new render target.
hardwareBuffer = HardwareBuffer.create(width, height,
HardwareBuffer.RGBA_8888, 1,
HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE or HardwareBuffer.USAGE_GPU_COLOR_OUTPUT)
texture = Texture.Builder()
.width(width)
.height(height)
.usage(Texture.Usage.COLOR_ATTACHMENT or Texture.Usage.SAMPLEABLE)
.sampler(Texture.Sampler.SAMPLER_EXTERNAL)
.format(Texture.InternalFormat.RGBA8)
.external()
.build(engine)
texture!!.setExternalImage(engine, hardwareBuffer!!)
} else {
texture = Texture.Builder()
.width(width)
.height(height)
.levels(1)
.usage(Texture.Usage.COLOR_ATTACHMENT or Texture.Usage.SAMPLEABLE)
.format(Texture.InternalFormat.RGBA8)
.build(engine)
}
renderTarget = RenderTarget.Builder()
.texture(RenderTarget.AttachmentPoint.COLOR, texture!!)
.build(engine)
offscreenView.renderTarget = renderTarget
// Set the texture on the quad material.
texturedMaterial.defaultInstance.setParameter("texture", texture!!,
TextureSampler(TextureSampler.MinFilter.LINEAR, TextureSampler.MagFilter.LINEAR,
TextureSampler.WrapMode.CLAMP_TO_EDGE))
FilamentHelper.synchronizePendingFrames(engine)
}
}
private fun readUncompressedAsset(assetName: String): ByteBuffer {
assets.openFd(assetName).use { fd ->
val input = fd.createInputStream()
val dst = ByteBuffer.allocate(fd.length.toInt())
val src = Channels.newChannel(input)
src.read(dst)
src.close()
return dst.apply { rewind() }
}
}
}
@@ -1,18 +0,0 @@
material {
name : baked_color,
shadingModel : unlit,
requires : [
color
]
}
fragment {
void material(inout MaterialInputs material) {
// You must always call the prepareMaterial() function
prepareMaterial(material);
// We set the material's color to the color interpolated from
// the model's vertices
material.baseColor = getColor();
}
}
@@ -1,20 +0,0 @@
material {
name : textured,
shadingModel : unlit,
parameters : [
{
type : sampler2d,
name : texture
}
],
requires: [
uv0
]
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, uvToRenderTargetUV(getUV0()));
}
}
@@ -1,20 +0,0 @@
material {
name : textured,
shadingModel : unlit,
parameters : [
{
type : samplerExternal,
name : texture
}
],
requires: [
uv0
]
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, uvToRenderTargetUV(getUV0()));
}
}
@@ -1,34 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0"/>
<item
android:color="#00000000"
android:offset="1.0"/>
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1"/>
</vector>
@@ -1,171 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z"/>
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
</vector>
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>
@@ -1,3 +0,0 @@
<resources>
<string name="app_name">Texture Target</string>
</resources>
@@ -1,8 +0,0 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
-1
View File
@@ -17,7 +17,6 @@ include ':samples:sample-multi-view'
include ':samples:sample-page-curl' include ':samples:sample-page-curl'
include ':samples:sample-stream-test' include ':samples:sample-stream-test'
include ':samples:sample-texture-view' include ':samples:sample-texture-view'
include ':samples:sample-texture-target'
include ':samples:sample-textured-object' include ':samples:sample-textured-object'
include ':samples:sample-transparent-view' include ':samples:sample-transparent-view'
+1 -9
View File
@@ -158,7 +158,7 @@ function print_fgviewer_help {
} }
# Unless explicitly specified, NDK version will be selected as highest available version within same major release chain # Unless explicitly specified, NDK version will be selected as highest available version within same major release chain
FILAMENT_NDK_VERSION=$(cat `dirname $0`/build/common/versions | grep GITHUB_NDK_VERSION | sed s/GITHUB_NDK_VERSION=//g | cut -f 1 -d ".") FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/build/common/versions | grep GITHUB_NDK_VERSION | sed s/GITHUB_NDK_VERSION=//g | cut -f 1 -d ".")}
# Internal variables # Internal variables
ISSUE_CLEAN=false ISSUE_CLEAN=false
@@ -556,14 +556,11 @@ function build_android {
archive_android "Release" archive_android "Release"
fi fi
local root_dir=$(pwd)
pushd android > /dev/null pushd android > /dev/null
if [[ "${ISSUE_DEBUG_BUILD}" == "true" ]]; then if [[ "${ISSUE_DEBUG_BUILD}" == "true" ]]; then
./gradlew \ ./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \ -Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/debug/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \ -Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${VULKAN_ANDROID_GRADLE_OPTION} \ ${VULKAN_ANDROID_GRADLE_OPTION} \
${WEBGPU_ANDROID_GRADLE_OPTION} \ ${WEBGPU_ANDROID_GRADLE_OPTION} \
@@ -576,7 +573,6 @@ function build_android {
./gradlew \ ./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \ -Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/debug/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \ -Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${WEBGPU_ANDROID_GRADLE_OPTION} \ ${WEBGPU_ANDROID_GRADLE_OPTION} \
:filamat-android:assembleDebug :filamat-android:assembleDebug
@@ -585,7 +581,6 @@ function build_android {
for sample in ${ANDROID_SAMPLES}; do for sample in ${ANDROID_SAMPLES}; do
./gradlew \ ./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \ -Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/debug/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \ -Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${MATOPT_GRADLE_OPTION} \ ${MATOPT_GRADLE_OPTION} \
:samples:${sample}:assembleDebug :samples:${sample}:assembleDebug
@@ -618,7 +613,6 @@ function build_android {
if [[ "${ISSUE_RELEASE_BUILD}" == "true" ]]; then if [[ "${ISSUE_RELEASE_BUILD}" == "true" ]]; then
./gradlew \ ./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \ -Pcom.google.android.filament.dist-dir=../out/android-release/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/release/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \ -Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${VULKAN_ANDROID_GRADLE_OPTION} \ ${VULKAN_ANDROID_GRADLE_OPTION} \
${WEBGPU_ANDROID_GRADLE_OPTION} \ ${WEBGPU_ANDROID_GRADLE_OPTION} \
@@ -631,7 +625,6 @@ function build_android {
./gradlew \ ./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \ -Pcom.google.android.filament.dist-dir=../out/android-release/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/release/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \ -Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${WEBGPU_ANDROID_GRADLE_OPTION} \ ${WEBGPU_ANDROID_GRADLE_OPTION} \
:filamat-android:assembleRelease :filamat-android:assembleRelease
@@ -640,7 +633,6 @@ function build_android {
for sample in ${ANDROID_SAMPLES}; do for sample in ${ANDROID_SAMPLES}; do
./gradlew \ ./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \ -Pcom.google.android.filament.dist-dir=../out/android-release/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/release/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \ -Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${MATOPT_GRADLE_OPTION} \ ${MATOPT_GRADLE_OPTION} \
:samples:${sample}:assembleRelease :samples:${sample}:assembleRelease
+2 -2
View File
@@ -18,8 +18,8 @@ if [[ "$GITHUB_WORKFLOW" ]]; then
fi fi
fi fi
# Unless explicitly specified, NDK version will be selected as highest available version within same major release chain # Unless explicitly specified, NDK version will be set to match exactly the required one
FILAMENT_NDK_VERSION=$(cat `dirname $0`/../common/versions | grep GITHUB_NDK_VERSION | sed s/GITHUB_NDK_VERSION=//g) FILAMENT_NDK_VERSION=${GITHUB_NDK_VERSION:-27.0.11718014}
(! grep "${FILAMENT_NDK_VERSION}" `dirname $0`/../../android/build.gradle > /dev/null) && (! grep "${FILAMENT_NDK_VERSION}" `dirname $0`/../../android/build.gradle > /dev/null) &&
echo "Mismatch of NDK versions: want ${FILAMENT_NDK_VERSION} and not found in android/build.gradle" && echo "Mismatch of NDK versions: want ${FILAMENT_NDK_VERSION} and not found in android/build.gradle" &&
+1
View File
@@ -1,5 +1,6 @@
libs/viewer/test_settings libs/viewer/test_settings
filament/test/test_filament --gtest_filter=-FilamentTest.FroxelData:FilamentExposureWithEngineTest.SetExposure:FilamentExposureWithEngineTest.ComputeEV100:RenderingTest.* filament/test/test_filament --gtest_filter=-FilamentTest.FroxelData:FilamentExposureWithEngineTest.SetExposure:FilamentExposureWithEngineTest.ComputeEV100:RenderingTest.*
filament/test/test_material_parser
libs/math/test_math libs/math/test_math
libs/image/test_image compare libs/image/tests/reference/ libs/image/test_image compare libs/image/tests/reference/
libs/utils/test_utils libs/utils/test_utils
+2 -2
View File
@@ -3,7 +3,7 @@ GITHUB_CMAKE_VERSION=3.22.1
GITHUB_NINJA_VERSION=1.10.2 GITHUB_NINJA_VERSION=1.10.2
GITHUB_MESA_VERSION=24.2.1 GITHUB_MESA_VERSION=24.2.1
GITHUB_LLVM_VERSION=16 GITHUB_LLVM_VERSION=16
GITHUB_NDK_VERSION=29.0.14206865 GITHUB_NDK_VERSION=27.0.11718014
GITHUB_EMSDK_VERSION=3.1.60 GITHUB_EMSDK_VERSION=3.1.60
GITHUB_VULKANSDK_VERSION=1.4.321.0 GITHUB_VULKANSDK_VERSION=1.4.321.0
GITHUB_GLTF_SAMPLE_ASSETS_COMMIT=d441dfdb87413ff412c620849a649d61789a470f GITHUB_GLTF_SAMPLE_ASSETS_COMMIT=d441dfdb87413ff412c620849a649d61789a470f
+1 -1
View File
@@ -75,7 +75,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# C_FLAGS += -Wl,-pie # C_FLAGS += -Wl,-pie
# CXX_FLAGS += -lstdc++ # CXX_FLAGS += -lstdc++
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE -march=armv8-a -mtune=cortex-a78" CACHE STRING "Toolchain CFLAGS") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE -mcpu=cortex-a57" CACHE STRING "Toolchain CFLAGS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}" CACHE STRING "Toolchain CXXFLAGS") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}" CACHE STRING "Toolchain CXXFLAGS")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie -static-libstdc++" CACHE STRING "Toolchain LDFLAGS") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie -static-libstdc++" CACHE STRING "Toolchain LDFLAGS")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++" CACHE STRING "Toolchain LDFLAGS") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++" CACHE STRING "Toolchain LDFLAGS")
+1 -1
View File
@@ -87,7 +87,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# for hardfp: CFLAGS must have -mhard-float # for hardfp: CFLAGS must have -mhard-float
# LDFLAGS must have -Wl,--no-warn-mismatch # LDFLAGS must have -Wl,--no-warn-mismatch
# #
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=neon-vfpv4 -fPIE" CACHE STRING "Toolchain CFLAGS") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb -march=armv7-a -mcpu=cortex-a15 -mfloat-abi=softfp -mfpu=neon-vfpv4 -fPIE" CACHE STRING "Toolchain CFLAGS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}" CACHE STRING "Toolchain CXXFLAGS") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}" CACHE STRING "Toolchain CXXFLAGS")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -march=armv7-a -Wl,--no-warn-mismatch -L${TOOLCHAIN}/arm-linux-androideabi/lib/armv7-a -static-libstdc++ -fPIE -pie" CACHE STRING "Toolchain LDFLAGS") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -march=armv7-a -Wl,--no-warn-mismatch -L${TOOLCHAIN}/arm-linux-androideabi/lib/armv7-a -static-libstdc++ -fPIE -pie" CACHE STRING "Toolchain LDFLAGS")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -march=armv7-a -Wl,--no-warn-mismatch -L${TOOLCHAIN}/arm-linux-androideabi/lib/armv7-a -static-libstdc++" CACHE STRING "Toolchain LDFLAGS") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -march=armv7-a -Wl,--no-warn-mismatch -L${TOOLCHAIN}/arm-linux-androideabi/lib/armv7-a -static-libstdc++" CACHE STRING "Toolchain LDFLAGS")
+6 -30
View File
@@ -97,7 +97,6 @@ in table [standardProperties].
**transmission** | Defines how much of the diffuse light of a dielectric is transmitted through the object, in other words this defines how transparent an object is **transmission** | Defines how much of the diffuse light of a dielectric is transmitted through the object, in other words this defines how transparent an object is
**ior** | Index of refraction, either for refractive objects or as an alternative to reflectance **ior** | Index of refraction, either for refractive objects or as an alternative to reflectance
**microThickness** | Thickness of the thin layer of refractive objects **microThickness** | Thickness of the thin layer of refractive objects
**dispersion** | Strength of the dispersion effect for refractive objects, specified as 20/Abbe number
**bentNormal** | A normal pointing in the average unoccluded direction. Can be used to improve indirect lighting quality **bentNormal** | A normal pointing in the average unoccluded direction. Can be used to improve indirect lighting quality
**shadowStrength** | Strength factor between 0 and 1 for all shadows received by this material **shadowStrength** | Strength factor between 0 and 1 for all shadows received by this material
[Table [standardProperties]: Properties of the standard model] [Table [standardProperties]: Properties of the standard model]
@@ -127,7 +126,6 @@ The type and range of each property is described in table [standardPropertiesTyp
**absorption** | float3 | [0..n] | **absorption** | float3 | [0..n] |
**microThickness** | float | [0..n] | **microThickness** | float | [0..n] |
**thickness** | float | [0..n] | **thickness** | float | [0..n] |
**dispersion** | float | [0..n] | Realistic values are between [0, 1], with the exception of Rutile, which has a value of 2.04
[Table [standardPropertiesTypes]: Range and type of the standard model's properties] [Table [standardPropertiesTypes]: Range and type of the standard model's properties]
@@ -155,14 +153,13 @@ The type and range of each property is described in table [standardPropertiesTyp
as-is, which can lead to physically impossible materials, however, this might be desirable as-is, which can lead to physically impossible materials, however, this might be desirable
for artistic reasons. for artistic reasons.
!!! Note: About `thickness`, `microThickness` and `dispersion` for refraction !!! Note: About `thickness` and `microThickness` for refraction
`thickness` represents the thickness of solid objects in the direction of the normal, for `thickness` represents the thickness of solid objects in the direction of the normal, for
satisfactory results, this should be provided per fragment (e.g.: as a texture) or at least per satisfactory results, this should be provided per fragment (e.g.: as a texture) or at least per
vertex. `microThickness` represent the thickness of the thin layer of an object, and can vertex. `microThickness` represent the thickness of the thin layer of an object, and can
generally be provided as a constant value. For example, a 1mm thin hollow sphere of radius 1m, generally be provided as a constant value. For example, a 1mm thin hollow sphere of radius 1m,
would have a `thickness` of 1 and a `microThickness` of 0.001. Dispersion controls the angular would have a `thickness` of 1 and a `microThickness` of 0.001. Currently `thickness` is not
separation of colors transmitting through a volume, and can be set by a constant value. used when `refractionType` is set to `thin`.
Currently `thickness` and `dispersion` are not used when `refractionType` is set to `thin`.
### Base color ### Base color
@@ -654,26 +651,6 @@ the `refractionType` is set to `solid` and `absorption` coefficients are set.
![Figure [varyingThickness]: `thickness` varying from 0.0 at the top of the prism to 3.0 at the ![Figure [varyingThickness]: `thickness` varying from 0.0 at the top of the prism to 3.0 at the
bottom of the prism](images/material_thickness.png) bottom of the prism](images/material_thickness.png)
### Dispersion
The dispersion property controls the angular separation of colors transmitting through a relatively
clear volume. It can only be used when `refractionType` is set to `volume`.
Its value is specified as 20/Abbe number. When the value is zero, no dispersion is used.
Table [commonMatDispersion] describes acceptable dispersion values for various types of materials.
Material | Abbe Number (V) | Dispersion (20/V)
--------------------------:|:------------------:|:-----------------
Rutile | 9.8 | 2.04
Polycarbonate | 32 | 0.625
Diamond | 55 | 0.36
Water | 55 | 0.36
Crown Glass | 59 | 0.33
[Table [commonMatDispersion]: Dispersion of common materials]
![Figure [dispersionProperty]: `dispersion` varying from 0.0
(left) to 5.0 (right)](images/materials/dispersion.png)
## Subsurface model ## Subsurface model
### Thickness ### Thickness
@@ -2299,7 +2276,6 @@ struct MaterialInputs {
float3 absorption; // default float3(0.0, 0.0, 0.0) float3 absorption; // default float3(0.0, 0.0, 0.0)
float ior; // default: 1.5 float ior; // default: 1.5
float microThickness; // default: 0.0, not available with refractionType "solid" float microThickness; // default: 0.0, not available with refractionType "solid"
float dispersion; // default: 0.0, not available with refractionType "thin"
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2480,9 +2456,9 @@ type aliases:
**uint2** | uvec2 | A vector of 2 unsigned integers **uint2** | uvec2 | A vector of 2 unsigned integers
**uint3** | uvec3 | A vector of 3 unsigned integers **uint3** | uvec3 | A vector of 3 unsigned integers
**uint4** | uvec4 | A vector of 4 unsigned integers **uint4** | uvec4 | A vector of 4 unsigned integers
**float2** | vec2 | A vector of 2 floats **float2** | float2 | A vector of 2 floats
**float3** | vec3 | A vector of 3 floats **float3** | float3 | A vector of 3 floats
**float4** | vec4 | A vector of 4 floats **float4** | float4 | A vector of 4 floats
**float4x4** | mat4 | A 4x4 float matrix **float4x4** | mat4 | A 4x4 float matrix
**float3x3** | mat3 | A 3x3 float matrix **float3x3** | mat3 | A 3x3 float matrix
-29
View File
@@ -327,41 +327,12 @@ host tools are required to successfully build for Android.</p>
<p>Note that the main target is the ARM 64-bit target. Our implementation is optimized first and <p>Note that the main target is the ARM 64-bit target. Our implementation is optimized first and
foremost for <code>arm64-v8a</code>.</p> foremost for <code>arm64-v8a</code>.</p>
<p>To build Android on Windows machines, see <a href="android/Windows.html">android/Windows.md</a>.</p> <p>To build Android on Windows machines, see <a href="android/Windows.html">android/Windows.md</a>.</p>
<h4 id="important-sdk-location"><a class="header" href="#important-sdk-location">Important: SDK location</a></h4>
<p>Either ensure your <code>ANDROID_HOME</code> environment variable is set or make sure the root project
contains a <code>local.properties</code> file with the <code>sdk.dir</code> property pointing to your installation of
the Android SDK.</p>
<h4 id="easy-android-build"><a class="header" href="#easy-android-build">Easy Android build</a></h4> <h4 id="easy-android-build"><a class="header" href="#easy-android-build">Easy Android build</a></h4>
<p>The easiest way to build Filament for Android is to use <code>build.sh</code> and the <p>The easiest way to build Filament for Android is to use <code>build.sh</code> and the
<code>-p android</code> flag. For instance to build the release target:</p> <code>-p android</code> flag. For instance to build the release target:</p>
<pre><code class="language-shell">./build.sh -p android release <pre><code class="language-shell">./build.sh -p android release
</code></pre> </code></pre>
<p>To build a sample (such as <code>android/samples/sample-hello-triangle</code>) for an ARM 64-bit phone, you would run</p>
<pre><code class="language-shell">./build.sh -p android -q arm64-v8a -k sample-hello-triangle release
</code></pre>
<p>The output APK can be found in <code>android/samples/sample-hello-triangle/build/outputs/apk/release/sample-hello-triangle-release-unsigned.apk</code></p>
<p>Run <code>build.sh -h</code> for more information.</p> <p>Run <code>build.sh -h</code> for more information.</p>
<h4 id="android-studio"><a class="header" href="#android-studio">Android Studio</a></h4>
<p>You must use the latest stable release of Android Studio.</p>
<p>The Android build of filament is separated into java/kotlin client APIs, a layer of jni bindings
that bridges java/kotlin with native code, and Filament and other component code that have been compiled
into architecture-specific libraries. Our default Android Studio gradle setup can compile java/kotlin and
the jni bindings for you, but it will treat the filament libraries as already compiled and present on
the system.</p>
<p>Therefore, before compiling the sample app or any other targets, you must
make sure that the native filament libraries have been compiled and are located at a prescribed location
so that the jni bindings can link against them. You can do so by using the easy build script</p>
<pre><code class="language-shell">./build.sh -p android release -q arm64-v8a
</code></pre>
<p>Note that the above step will also install host machine tools into prescribed locations. These tools are
required for compiling Filament assets such as materials and environment maps.</p>
<p>Now we are ready to compile the apps. To open the project, point Studio to the <code>android</code> folder.
After opening the project and syncing with Gradle, select the sample of your choice
using the drop-down widget in the toolbar. Additionally, you will need to select a deployment target.
By doing so, Android Studio will automatically try to compile the app only for that specific
device's architecture. So if you are targeting a new Pixel phone, make sure that the step above
(compiling the library) is targeting ARM 64-bit (<code>-q arm64-v8a</code> ), and if you are running the app on
an emulator on a Linux machine with an x86 64-bit chipset, you would indicate (<code>-q x86_64</code>) in the above step.</p>
<h4 id="manual-builds"><a class="header" href="#manual-builds">Manual builds</a></h4> <h4 id="manual-builds"><a class="header" href="#manual-builds">Manual builds</a></h4>
<p>Invoke CMake in a build directory of your choice, inside of filament's directory. The commands <p>Invoke CMake in a build directory of your choice, inside of filament's directory. The commands
below show how to build Filament for ARM 64-bit (<code>aarch64</code>).</p> below show how to build Filament for ARM 64-bit (<code>aarch64</code>).</p>
+1 -1
View File
@@ -203,7 +203,7 @@ tree into <code>docs_src/src_mdbook/src/dup</code>. Moreover, to restore valid l
to perform a number of URL replacements in addition to the copy. These replacements are to perform a number of URL replacements in addition to the copy. These replacements are
described in <a href="https://github.com/google/filament/blob/main/docs_src/build/duplicates.json"><code>docs_src/build/duplicates.json</code></a>.</p> described in <a href="https://github.com/google/filament/blob/main/docs_src/build/duplicates.json"><code>docs_src/build/duplicates.json</code></a>.</p>
<h3 id="core-concept-docs"><a class="header" href="#core-concept-docs">Core concept docs</a></h3> <h3 id="core-concept-docs"><a class="header" href="#core-concept-docs">Core concept docs</a></h3>
<p>The primary design of Filament as a physically-based renderer and details of its materials <p>The primary design of Filament as a phyiscally-based renderer and details of its materials
system are described in <code>Filament.md.html</code> and <code>Materials.md.html</code>, respectively. These two system are described in <code>Filament.md.html</code> and <code>Materials.md.html</code>, respectively. These two
documents are written in <a href="https://casual-effects.com/markdeep/"><code>markdeep</code></a>. To embed them into our book, we</p> documents are written in <a href="https://casual-effects.com/markdeep/"><code>markdeep</code></a>. To embed them into our book, we</p>
<ol> <ol>
+2 -2
View File
@@ -181,7 +181,7 @@ important for <code>matc</code> (material compiler).</p>
} }
dependencies { dependencies {
implementation 'com.google.android.filament:filament-android:1.68.2' implementation 'com.google.android.filament:filament-android:1.66.2'
} }
</code></pre> </code></pre>
<p>Here are all the libraries available in the group <code>com.google.android.filament</code>:</p> <p>Here are all the libraries available in the group <code>com.google.android.filament</code>:</p>
@@ -196,7 +196,7 @@ dependencies {
</div> </div>
<h3 id="ios"><a class="header" href="#ios">iOS</a></h3> <h3 id="ios"><a class="header" href="#ios">iOS</a></h3>
<p>iOS projects can use CocoaPods to install the latest release:</p> <p>iOS projects can use CocoaPods to install the latest release:</p>
<pre><code class="language-shell">pod 'Filament', '~&gt; 1.68.2' <pre><code class="language-shell">pod 'Filament', '~&gt; 1.66.2'
</code></pre> </code></pre>
<h2 id="documentation"><a class="header" href="#documentation">Documentation</a></h2> <h2 id="documentation"><a class="header" href="#documentation">Documentation</a></h2>
<ul> <ul>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 MiB

+1474 -1462
View File
File diff suppressed because one or more lines are too long
+1047 -1073
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -12
View File
@@ -307,7 +307,7 @@ class FilamentViewer extends LitElement {
asyncInterval: 30 asyncInterval: 30
}; };
const doneAddingResources = (resourceLoader, stbProvider, ktx2Provider, webpProvider) => { const doneAddingResources = (resourceLoader, stbProvider, ktx2Provider) => {
this.srcBlobResources = {}; this.srcBlobResources = {};
resourceLoader.asyncBeginLoad(this.asset); resourceLoader.asyncBeginLoad(this.asset);
const timer = setInterval(() => { const timer = setInterval(() => {
@@ -318,9 +318,6 @@ class FilamentViewer extends LitElement {
resourceLoader.delete(); resourceLoader.delete();
stbProvider.delete(); stbProvider.delete();
ktx2Provider.delete(); ktx2Provider.delete();
if (webpProvider) {
webpProvider.delete();
}
this.animator = this.asset.getInstance().getAnimator(); this.animator = this.asset.getInstance().getAnimator();
this.animationStartTime = Date.now(); this.animationStartTime = Date.now();
} }
@@ -338,25 +335,18 @@ class FilamentViewer extends LitElement {
const stbProvider = new Filament.gltfio$StbProvider(this.engine); const stbProvider = new Filament.gltfio$StbProvider(this.engine);
const ktx2Provider = new Filament.gltfio$Ktx2Provider(this.engine); const ktx2Provider = new Filament.gltfio$Ktx2Provider(this.engine);
let webpProvider = null;
resourceLoader.addStbProvider("image/jpeg", stbProvider); resourceLoader.addStbProvider("image/jpeg", stbProvider);
resourceLoader.addStbProvider("image/png", stbProvider); resourceLoader.addStbProvider("image/png", stbProvider);
resourceLoader.addKtx2Provider("image/ktx2", ktx2Provider); resourceLoader.addKtx2Provider("image/ktx2", ktx2Provider);
if (Filament.gltfio$WebpProvider.isWebpSupported()) {
webpProvider = new Filament.gltfio$WebpProvider(this.engine);
resourceLoader.addWebpProvider("image/webp", webpProvider);
}
let remaining = Object.keys(this.srcBlobResources).length; let remaining = Object.keys(this.srcBlobResources).length;
for (const name in this.srcBlobResources) { for (const name in this.srcBlobResources) {
this.srcBlobResources[name].arrayBuffer().then(buffer => { this.srcBlobResources[name].arrayBuffer().then(buffer => {
const desc = getBufferDescriptor(new Uint8Array(buffer)); const desc = getBufferDescriptor(new Uint8Array(buffer));
resourceLoader.addResourceData(name, getBufferDescriptor(desc)); resourceLoader.addResourceData(name, getBufferDescriptor(desc));
if (--remaining === 0) { if (--remaining === 0) {
doneAddingResources(resourceLoader, stbProvider, ktx2Provider, webpProvider); doneAddingResources(resourceLoader, stbProvider, ktx2Provider);
} }
}); });
} }
+1 -1
View File
@@ -49,7 +49,7 @@ to perform a number of URL replacements in addition to the copy. These replaceme
described in [`docs_src/build/duplicates.json`]. described in [`docs_src/build/duplicates.json`].
### Core concept docs ### Core concept docs
The primary design of Filament as a physically-based renderer and details of its materials The primary design of Filament as a phyiscally-based renderer and details of its materials
system are described in `Filament.md.html` and `Materials.md.html`, respectively. These two system are described in `Filament.md.html` and `Materials.md.html`, respectively. These two
documents are written in [`markdeep`]. To embed them into our book, we documents are written in [`markdeep`]. To embed them into our book, we
1. Convert the markdeep into html 1. Convert the markdeep into html
-4
View File
@@ -16,8 +16,6 @@
FILAMENT_BOT_TOKEN=$2 FILAMENT_BOT_TOKEN=$2
set -ex
function update_to_main() { function update_to_main() {
python3 docs_src/build/run.py python3 docs_src/build/run.py
mkdir -p tmp mkdir -p tmp
@@ -51,5 +49,3 @@ else
echo "has edits (to /docs_src): ${HAS_EDITS}" echo "has edits (to /docs_src): ${HAS_EDITS}"
echo "bypass: ${DO_BYPASS}" echo "bypass: ${DO_BYPASS}"
fi fi
set +ex
+1 -1
View File
@@ -10,6 +10,6 @@ sortedcontainers==2.4.0
trio==0.31.0 trio==0.31.0
trio-websocket==0.12.2 trio-websocket==0.12.2
typing_extensions==4.15.0 typing_extensions==4.15.0
urllib3==2.6.3 urllib3==2.5.0
websocket-client==1.9.0 websocket-client==1.9.0
wsproto==1.2.0 wsproto==1.2.0
+1 -27
View File
@@ -81,28 +81,6 @@ def pull_markdeep_docs():
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, directory=MARKDEEP_DIR, **kwargs) super().__init__(*args, directory=MARKDEEP_DIR, **kwargs)
def do_GET(self):
print(f'================ {self.path}')
# Use the checked-in markdeep since its locked to a version
if self.path == '/third_party/markdeep/markdeep.min.js':
file_path = f'{ROOT_DIR}/third_party/markdeep/markdeep.min.js'
try:
with open(file_path, 'rb') as f:
content = f.read()
self.send_response(200)
self.send_header('Content-type', 'application/javascript')
self.send_header('Content-Length', len(content))
self.end_headers()
# Send the file content
self.wfile.write(content)
except FileNotFoundError:
self.send_error(404, 'File not found')
else:
# For all other paths, use the default behavior (serve from MARKDEEP_DIR)
super().do_GET()
def start_server(port): def start_server(port):
"""Starts the web server in a separate thread.""" """Starts the web server in a separate thread."""
httpd = Server(("", port), Handler) httpd = Server(("", port), Handler)
@@ -115,9 +93,6 @@ def pull_markdeep_docs():
PORT = 12345 PORT = 12345
httpd = start_server(PORT) httpd = start_server(PORT)
# Workaround for unknown dead-lock when the selenium tries to make request to the local server above.
time.sleep(3)
# Set up Chrome options for headless mode # Set up Chrome options for headless mode
chrome_options = Options() chrome_options = Options()
chrome_options.add_argument("--headless") chrome_options.add_argument("--headless")
@@ -132,8 +107,7 @@ def pull_markdeep_docs():
# Open the URL with ?export, which markdeep will export the resulting html. # Open the URL with ?export, which markdeep will export the resulting html.
driver.get(f"http://localhost:{PORT}/{doc}.md.html?export") driver.get(f"http://localhost:{PORT}/{doc}.md.html?export")
time.sleep(1.5) time.sleep(3)
# We extract the html from the resulting "page" (an html output itself). # We extract the html from the resulting "page" (an html output itself).
text = driver.find_elements(By.TAG_NAME, "pre")[0].text text = driver.find_elements(By.TAG_NAME, "pre")[0].text
+6 -30
View File
@@ -97,7 +97,6 @@ in table [standardProperties].
**transmission** | Defines how much of the diffuse light of a dielectric is transmitted through the object, in other words this defines how transparent an object is **transmission** | Defines how much of the diffuse light of a dielectric is transmitted through the object, in other words this defines how transparent an object is
**ior** | Index of refraction, either for refractive objects or as an alternative to reflectance **ior** | Index of refraction, either for refractive objects or as an alternative to reflectance
**microThickness** | Thickness of the thin layer of refractive objects **microThickness** | Thickness of the thin layer of refractive objects
**dispersion** | Strength of the dispersion effect for refractive objects, specified as 20/Abbe number
**bentNormal** | A normal pointing in the average unoccluded direction. Can be used to improve indirect lighting quality **bentNormal** | A normal pointing in the average unoccluded direction. Can be used to improve indirect lighting quality
**shadowStrength** | Strength factor between 0 and 1 for all shadows received by this material **shadowStrength** | Strength factor between 0 and 1 for all shadows received by this material
[Table [standardProperties]: Properties of the standard model] [Table [standardProperties]: Properties of the standard model]
@@ -127,7 +126,6 @@ The type and range of each property is described in table [standardPropertiesTyp
**absorption** | float3 | [0..n] | **absorption** | float3 | [0..n] |
**microThickness** | float | [0..n] | **microThickness** | float | [0..n] |
**thickness** | float | [0..n] | **thickness** | float | [0..n] |
**dispersion** | float | [0..n] | Realistic values are between [0, 1], with the exception of Rutile, which has a value of 2.04
[Table [standardPropertiesTypes]: Range and type of the standard model's properties] [Table [standardPropertiesTypes]: Range and type of the standard model's properties]
@@ -155,14 +153,13 @@ The type and range of each property is described in table [standardPropertiesTyp
as-is, which can lead to physically impossible materials, however, this might be desirable as-is, which can lead to physically impossible materials, however, this might be desirable
for artistic reasons. for artistic reasons.
!!! Note: About `thickness`, `microThickness` and `dispersion` for refraction !!! Note: About `thickness` and `microThickness` for refraction
`thickness` represents the thickness of solid objects in the direction of the normal, for `thickness` represents the thickness of solid objects in the direction of the normal, for
satisfactory results, this should be provided per fragment (e.g.: as a texture) or at least per satisfactory results, this should be provided per fragment (e.g.: as a texture) or at least per
vertex. `microThickness` represent the thickness of the thin layer of an object, and can vertex. `microThickness` represent the thickness of the thin layer of an object, and can
generally be provided as a constant value. For example, a 1mm thin hollow sphere of radius 1m, generally be provided as a constant value. For example, a 1mm thin hollow sphere of radius 1m,
would have a `thickness` of 1 and a `microThickness` of 0.001. Dispersion controls the angular would have a `thickness` of 1 and a `microThickness` of 0.001. Currently `thickness` is not
separation of colors transmitting through a volume, and can be set by a constant value. used when `refractionType` is set to `thin`.
Currently `thickness` and `dispersion` are not used when `refractionType` is set to `thin`.
### Base color ### Base color
@@ -654,26 +651,6 @@ the `refractionType` is set to `solid` and `absorption` coefficients are set.
![Figure [varyingThickness]: `thickness` varying from 0.0 at the top of the prism to 3.0 at the ![Figure [varyingThickness]: `thickness` varying from 0.0 at the top of the prism to 3.0 at the
bottom of the prism](images/material_thickness.png) bottom of the prism](images/material_thickness.png)
### Dispersion
The dispersion property controls the angular separation of colors transmitting through a relatively
clear volume. It can only be used when `refractionType` is set to `volume`.
Its value is specified as 20/Abbe number. When the value is zero, no dispersion is used.
Table [commonMatDispersion] describes acceptable dispersion values for various types of materials.
Material | Abbe Number (V) | Dispersion (20/V)
--------------------------:|:------------------:|:-----------------
Rutile | 9.8 | 2.04
Polycarbonate | 32 | 0.625
Diamond | 55 | 0.36
Water | 55 | 0.36
Crown Glass | 59 | 0.33
[Table [commonMatDispersion]: Dispersion of common materials]
![Figure [dispersionProperty]: `dispersion` varying from 0.0
(left) to 5.0 (right)](images/materials/dispersion.png)
## Subsurface model ## Subsurface model
### Thickness ### Thickness
@@ -2299,7 +2276,6 @@ struct MaterialInputs {
float3 absorption; // default float3(0.0, 0.0, 0.0) float3 absorption; // default float3(0.0, 0.0, 0.0)
float ior; // default: 1.5 float ior; // default: 1.5
float microThickness; // default: 0.0, not available with refractionType "solid" float microThickness; // default: 0.0, not available with refractionType "solid"
float dispersion; // default: 0.0, not available with refractionType "thin"
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2480,9 +2456,9 @@ type aliases:
**uint2** | uvec2 | A vector of 2 unsigned integers **uint2** | uvec2 | A vector of 2 unsigned integers
**uint3** | uvec3 | A vector of 3 unsigned integers **uint3** | uvec3 | A vector of 3 unsigned integers
**uint4** | uvec4 | A vector of 4 unsigned integers **uint4** | uvec4 | A vector of 4 unsigned integers
**float2** | vec2 | A vector of 2 floats **float2** | float2 | A vector of 2 floats
**float3** | vec3 | A vector of 3 floats **float3** | float3 | A vector of 3 floats
**float4** | vec4 | A vector of 4 floats **float4** | float4 | A vector of 4 floats
**float4x4** | mat4 | A 4x4 float matrix **float4x4** | mat4 | A 4x4 float matrix
**float3x3** | mat3 | A 3x3 float matrix **float3x3** | mat3 | A 3x3 float matrix
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 MiB

+2 -12
View File
@@ -307,7 +307,7 @@ class FilamentViewer extends LitElement {
asyncInterval: 30 asyncInterval: 30
}; };
const doneAddingResources = (resourceLoader, stbProvider, ktx2Provider, webpProvider) => { const doneAddingResources = (resourceLoader, stbProvider, ktx2Provider) => {
this.srcBlobResources = {}; this.srcBlobResources = {};
resourceLoader.asyncBeginLoad(this.asset); resourceLoader.asyncBeginLoad(this.asset);
const timer = setInterval(() => { const timer = setInterval(() => {
@@ -318,9 +318,6 @@ class FilamentViewer extends LitElement {
resourceLoader.delete(); resourceLoader.delete();
stbProvider.delete(); stbProvider.delete();
ktx2Provider.delete(); ktx2Provider.delete();
if (webpProvider) {
webpProvider.delete();
}
this.animator = this.asset.getInstance().getAnimator(); this.animator = this.asset.getInstance().getAnimator();
this.animationStartTime = Date.now(); this.animationStartTime = Date.now();
} }
@@ -338,25 +335,18 @@ class FilamentViewer extends LitElement {
const stbProvider = new Filament.gltfio$StbProvider(this.engine); const stbProvider = new Filament.gltfio$StbProvider(this.engine);
const ktx2Provider = new Filament.gltfio$Ktx2Provider(this.engine); const ktx2Provider = new Filament.gltfio$Ktx2Provider(this.engine);
let webpProvider = null;
resourceLoader.addStbProvider("image/jpeg", stbProvider); resourceLoader.addStbProvider("image/jpeg", stbProvider);
resourceLoader.addStbProvider("image/png", stbProvider); resourceLoader.addStbProvider("image/png", stbProvider);
resourceLoader.addKtx2Provider("image/ktx2", ktx2Provider); resourceLoader.addKtx2Provider("image/ktx2", ktx2Provider);
if (Filament.gltfio$WebpProvider.isWebpSupported()) {
webpProvider = new Filament.gltfio$WebpProvider(this.engine);
resourceLoader.addWebpProvider("image/webp", webpProvider);
}
let remaining = Object.keys(this.srcBlobResources).length; let remaining = Object.keys(this.srcBlobResources).length;
for (const name in this.srcBlobResources) { for (const name in this.srcBlobResources) {
this.srcBlobResources[name].arrayBuffer().then(buffer => { this.srcBlobResources[name].arrayBuffer().then(buffer => {
const desc = getBufferDescriptor(new Uint8Array(buffer)); const desc = getBufferDescriptor(new Uint8Array(buffer));
resourceLoader.addResourceData(name, getBufferDescriptor(desc)); resourceLoader.addResourceData(name, getBufferDescriptor(desc));
if (--remaining === 0) { if (--remaining === 0) {
doneAddingResources(resourceLoader, stbProvider, ktx2Provider, webpProvider); doneAddingResources(resourceLoader, stbProvider, ktx2Provider);
} }
}); });
} }
+2 -7
View File
@@ -97,6 +97,7 @@ set(SRCS
src/RenderableManager.cpp src/RenderableManager.cpp
src/Renderer.cpp src/Renderer.cpp
src/RendererUtils.cpp src/RendererUtils.cpp
src/ResourceAllocator.cpp
src/ResourceList.cpp src/ResourceList.cpp
src/Scene.cpp src/Scene.cpp
src/ShadowMap.cpp src/ShadowMap.cpp
@@ -107,7 +108,6 @@ set(SRCS
src/SwapChain.cpp src/SwapChain.cpp
src/Sync.cpp src/Sync.cpp
src/Texture.cpp src/Texture.cpp
src/TextureCache.cpp
src/ToneMapper.cpp src/ToneMapper.cpp
src/TransformManager.cpp src/TransformManager.cpp
src/UniformBuffer.cpp src/UniformBuffer.cpp
@@ -158,7 +158,6 @@ set(SRCS
src/fg/FrameGraphTexture.cpp src/fg/FrameGraphTexture.cpp
src/fg/PassNode.cpp src/fg/PassNode.cpp
src/fg/ResourceNode.cpp src/fg/ResourceNode.cpp
src/fg/ResourceCreationContext.cpp
src/fsr.cpp src/fsr.cpp
src/ZstdHelper.cpp src/ZstdHelper.cpp
) )
@@ -169,7 +168,6 @@ set(PRIVATE_HDRS
src/Bimap.h src/Bimap.h
src/BufferPoolAllocator.h src/BufferPoolAllocator.h
src/ColorSpaceUtils.h src/ColorSpaceUtils.h
src/compact.h
src/Culler.h src/Culler.h
src/DFG.h src/DFG.h
src/FilamentAPI-impl.h src/FilamentAPI-impl.h
@@ -190,17 +188,16 @@ set(PRIVATE_HDRS
src/RenderPass.h src/RenderPass.h
src/RenderPrimitive.h src/RenderPrimitive.h
src/RendererUtils.h src/RendererUtils.h
src/ResourceAllocator.h
src/ResourceList.h src/ResourceList.h
src/ShadowMap.h src/ShadowMap.h
src/ShadowMapManager.h src/ShadowMapManager.h
src/SharedHandle.h src/SharedHandle.h
src/TextureCache.h
src/UniformBuffer.h src/UniformBuffer.h
src/components/CameraManager.h src/components/CameraManager.h
src/components/LightManager.h src/components/LightManager.h
src/components/RenderableManager.h src/components/RenderableManager.h
src/components/TransformManager.h src/components/TransformManager.h
src/details/AsyncHelpers.h
src/details/BufferAllocator.h src/details/BufferAllocator.h
src/details/BufferObject.h src/details/BufferObject.h
src/details/Camera.h src/details/Camera.h
@@ -235,7 +232,6 @@ set(PRIVATE_HDRS
src/ds/TypedUniformBuffer.h src/ds/TypedUniformBuffer.h
src/fg/Blackboard.h src/fg/Blackboard.h
src/fg/FrameGraph.h src/fg/FrameGraph.h
src/fg/FrameGraphDummyLink.h
src/fg/FrameGraphId.h src/fg/FrameGraphId.h
src/fg/FrameGraphPass.h src/fg/FrameGraphPass.h
src/fg/FrameGraphRenderPass.h src/fg/FrameGraphRenderPass.h
@@ -245,7 +241,6 @@ set(PRIVATE_HDRS
src/fg/details/DependencyGraph.h src/fg/details/DependencyGraph.h
src/fg/details/PassNode.h src/fg/details/PassNode.h
src/fg/details/Resource.h src/fg/details/Resource.h
src/fg/details/ResourceAllocator.h
src/fg/details/ResourceNode.h src/fg/details/ResourceNode.h
src/fg/details/Utilities.h src/fg/details/Utilities.h
src/fsr.h src/fsr.h
+4 -24
View File
@@ -28,7 +28,6 @@ set(SRCS
src/BackendUtils.cpp src/BackendUtils.cpp
src/BlobCacheKey.cpp src/BlobCacheKey.cpp
src/Callable.cpp src/Callable.cpp
src/CallbackHandler.cpp
src/CallbackManager.cpp src/CallbackManager.cpp
src/CircularBuffer.cpp src/CircularBuffer.cpp
src/CommandBufferQueue.cpp src/CommandBufferQueue.cpp
@@ -37,7 +36,6 @@ set(SRCS
src/Driver.cpp src/Driver.cpp
src/Handle.cpp src/Handle.cpp
src/HandleAllocator.cpp src/HandleAllocator.cpp
src/JobQueue.cpp
src/ostream.cpp src/ostream.cpp
src/noop/NoopDriver.cpp src/noop/NoopDriver.cpp
src/noop/PlatformNoop.cpp src/noop/PlatformNoop.cpp
@@ -61,7 +59,6 @@ set(PRIVATE_HDRS
src/CompilerThreadPool.h src/CompilerThreadPool.h
src/DataReshaper.h src/DataReshaper.h
src/DriverBase.h src/DriverBase.h
src/JobQueue.h
) )
# ================================================================================================== # ==================================================================================================
@@ -209,8 +206,6 @@ if (FILAMENT_SUPPORTS_VULKAN)
src/vulkan/VulkanDriverFactory.h src/vulkan/VulkanDriverFactory.h
src/vulkan/VulkanExternalImageManager.cpp src/vulkan/VulkanExternalImageManager.cpp
src/vulkan/VulkanExternalImageManager.h src/vulkan/VulkanExternalImageManager.h
src/vulkan/VulkanStreamedImageManager.cpp
src/vulkan/VulkanStreamedImageManager.h
src/vulkan/VulkanFboCache.cpp src/vulkan/VulkanFboCache.cpp
src/vulkan/VulkanFboCache.h src/vulkan/VulkanFboCache.h
src/vulkan/VulkanHandles.cpp src/vulkan/VulkanHandles.cpp
@@ -321,8 +316,6 @@ if (FILAMENT_SUPPORTS_WEBGPU)
src/webgpu/WebGPURenderPrimitive.h src/webgpu/WebGPURenderPrimitive.h
src/webgpu/WebGPURenderTarget.cpp src/webgpu/WebGPURenderTarget.cpp
src/webgpu/WebGPURenderTarget.h src/webgpu/WebGPURenderTarget.h
src/webgpu/WebGPUStagePool.cpp
src/webgpu/WebGPUStagePool.h
src/webgpu/WebGPUStrings.h src/webgpu/WebGPUStrings.h
src/webgpu/WebGPUSwapChain.cpp src/webgpu/WebGPUSwapChain.cpp
src/webgpu/WebGPUSwapChain.h src/webgpu/WebGPUSwapChain.h
@@ -336,25 +329,13 @@ if (FILAMENT_SUPPORTS_WEBGPU)
src/webgpu/WebGPUVertexBufferInfo.h src/webgpu/WebGPUVertexBufferInfo.h
) )
if (WIN32) if (WIN32)
list(APPEND SRCS list(APPEND SRCS src/webgpu/platform/WebGPUPlatformWindows.cpp)
include/backend/platforms/WebGPUPlatformWindows.h
src/webgpu/platform/WebGPUPlatformWindows.cpp
)
elseif (LINUX) elseif (LINUX)
list(APPEND SRCS list(APPEND SRCS src/webgpu/platform/WebGPUPlatformLinux.cpp)
include/backend/platforms/WebGPUPlatformLinux.h
src/webgpu/platform/WebGPUPlatformLinux.cpp
)
elseif (APPLE OR IOS) elseif (APPLE OR IOS)
list(APPEND SRCS list(APPEND SRCS src/webgpu/platform/WebGPUPlatformApple.mm)
include/backend/platforms/WebGPUPlatformApple.h
src/webgpu/platform/WebGPUPlatformApple.mm
)
elseif (ANDROID) elseif (ANDROID)
list(APPEND SRCS list(APPEND SRCS src/webgpu/platform/WebGPUPlatformAndroid.cpp)
include/backend/platforms/WebGPUPlatformAndroid.h
src/webgpu/platform/WebGPUPlatformAndroid.cpp
)
endif() endif()
if (TNT_DEV) if (TNT_DEV)
@@ -583,7 +564,6 @@ if (APPLE OR LINUX)
test/test_ReadPixels.cpp test/test_ReadPixels.cpp
test/test_BufferUpdates.cpp test/test_BufferUpdates.cpp
test/test_Callbacks.cpp test/test_Callbacks.cpp
test/test_JobQueue.cpp
test/test_MemoryMappedBuffer.cpp test/test_MemoryMappedBuffer.cpp
test/test_MsaaSwapChain.cpp test/test_MsaaSwapChain.cpp
test/test_MRT.cpp test/test_MRT.cpp
@@ -0,0 +1,63 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_BUFFEROBJECTSTREAMDESCRIPTOR_H
#define TNT_FILAMENT_BACKEND_BUFFEROBJECTSTREAMDESCRIPTOR_H
#include <backend/Handle.h>
#include <vector>
namespace filament::backend {
/**
* The type of association between a buffer object and a stream.
*/
enum class BufferObjectStreamAssociationType { TRANSFORM_MATRIX };
/**
* A descriptor for a buffer object to stream association.
*/
class UTILS_PUBLIC BufferObjectStreamDescriptor {
public:
//! creates an empty descriptor
BufferObjectStreamDescriptor() noexcept = default;
BufferObjectStreamDescriptor(const BufferObjectStreamDescriptor& rhs) = delete;
BufferObjectStreamDescriptor& operator=(const BufferObjectStreamDescriptor& rhs) = delete;
BufferObjectStreamDescriptor(BufferObjectStreamDescriptor&& rhs) = default;
BufferObjectStreamDescriptor& operator=(BufferObjectStreamDescriptor&& rhs) = default;
// --------------------------------------------------------------------------------------------
struct StreamDataDescriptor {
uint32_t offset;
Handle<HwStream> stream;
BufferObjectStreamAssociationType associationType;
};
std::vector<StreamDataDescriptor> mStreams;
};
} // namespace filament::backend
#if !defined(NDEBUG)
utils::io::ostream& operator<<(utils::io::ostream& out,
const filament::backend::BufferObjectStreamDescriptor& b);
#endif
#endif // TNT_FILAMENT_BACKEND_BUFFEROBJECTSTREAMDESCRIPTOR_H
@@ -64,7 +64,7 @@ public:
virtual void post(void* user, Callback callback) = 0; virtual void post(void* user, Callback callback) = 0;
protected: protected:
virtual ~CallbackHandler(); virtual ~CallbackHandler() = default;
}; };
} // namespace filament::backend } // namespace filament::backend
+4 -12
View File
@@ -499,7 +499,7 @@ using descriptor_set_t = uint8_t;
using descriptor_binding_t = uint8_t; using descriptor_binding_t = uint8_t;
struct DescriptorSetLayoutDescriptor { struct DescriptorSetLayoutBinding {
static bool isSampler(DescriptorType type) noexcept { static bool isSampler(DescriptorType type) noexcept {
return int(type) <= int(DescriptorType::SAMPLER_EXTERNAL); return int(type) <= int(DescriptorType::SAMPLER_EXTERNAL);
} }
@@ -513,8 +513,8 @@ struct DescriptorSetLayoutDescriptor {
DescriptorFlags flags = DescriptorFlags::NONE; DescriptorFlags flags = DescriptorFlags::NONE;
uint16_t count = 0; uint16_t count = 0;
friend bool operator==(DescriptorSetLayoutDescriptor const& lhs, friend bool operator==(DescriptorSetLayoutBinding const& lhs,
DescriptorSetLayoutDescriptor const& rhs) noexcept { DescriptorSetLayoutBinding const& rhs) noexcept {
return lhs.type == rhs.type && return lhs.type == rhs.type &&
lhs.flags == rhs.flags && lhs.flags == rhs.flags &&
lhs.count == rhs.count && lhs.count == rhs.count &&
@@ -1385,7 +1385,7 @@ static_assert(sizeof(SamplerParams) <= sizeof(uint64_t),
struct DescriptorSetLayout { struct DescriptorSetLayout {
std::variant<utils::StaticString, utils::CString, std::monostate> label; std::variant<utils::StaticString, utils::CString, std::monostate> label;
utils::FixedCapacityVector<DescriptorSetLayoutDescriptor> descriptors; utils::FixedCapacityVector<DescriptorSetLayoutBinding> bindings;
}; };
//! blending equation function //! blending equation function
@@ -1713,14 +1713,6 @@ using FrameTimestamps = Platform::FrameTimestamps;
using CompositorTiming = Platform::CompositorTiming; using CompositorTiming = Platform::CompositorTiming;
using AsynchronousMode = Platform::AsynchronousMode;
using AsyncCallId = uint32_t;
static constexpr AsyncCallId InvalidAsyncCallId = std::numeric_limits<AsyncCallId>::max();
using AsynchronousMode = Platform::AsynchronousMode;
} // namespace filament::backend } // namespace filament::backend
template<> struct utils::EnableBitMaskOperators<filament::backend::ShaderStageFlags> template<> struct utils::EnableBitMaskOperators<filament::backend::ShaderStageFlags>
+8 -86
View File
@@ -19,17 +19,13 @@
#ifndef TNT_FILAMENT_BACKEND_PLATFORM_H #ifndef TNT_FILAMENT_BACKEND_PLATFORM_H
#define TNT_FILAMENT_BACKEND_PLATFORM_H #define TNT_FILAMENT_BACKEND_PLATFORM_H
#include <utils/CString.h>
#include <utils/compiler.h> #include <utils/compiler.h>
#include <utils/Invocable.h> #include <utils/Invocable.h>
#include <utils/Mutex.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <atomic> #include <atomic>
#include <memory>
#include <mutex>
namespace filament::backend { namespace filament::backend {
@@ -74,9 +70,6 @@ public:
ExternalImageHandle& operator=(ExternalImageHandle const& rhs) noexcept; ExternalImageHandle& operator=(ExternalImageHandle const& rhs) noexcept;
ExternalImageHandle& operator=(ExternalImageHandle&& rhs) noexcept; ExternalImageHandle& operator=(ExternalImageHandle&& rhs) noexcept;
bool operator==(const ExternalImageHandle& rhs) const noexcept {
return mTarget == rhs.mTarget;
}
explicit operator bool() const noexcept { return mTarget != nullptr; } explicit operator bool() const noexcept { return mTarget != nullptr; }
ExternalImage* UTILS_NULLABLE get() noexcept { return mTarget; } ExternalImage* UTILS_NULLABLE get() noexcept { return mTarget; }
@@ -255,28 +248,6 @@ public:
REALTIME, REALTIME,
}; };
/**
* Defines how asynchronous operations are handled by the engine.
*/
enum class AsynchronousMode : uint8_t {
/**
* Asynchronous operations are disabled. This is the default.
*/
NONE,
/**
* Attempts to use a dedicated worker thread for asynchronous tasks. If threading is not
* supported by the platform, it automatically falls back to using an amortization strategy.
*/
THREAD_PREFERRED,
/**
* Uses an amortization strategy, processing a small number of asynchronous tasks during
* each engine update cycle.
*/
AMORTIZATION,
};
struct DriverConfig { struct DriverConfig {
/** /**
* Size of handle arena in bytes. Setting to 0 indicates default value is to be used. * Size of handle arena in bytes. Setting to 0 indicates default value is to be used.
@@ -288,8 +259,7 @@ public:
/** /**
* Set to `true` to forcibly disable parallel shader compilation in the backend. * Set to `true` to forcibly disable parallel shader compilation in the backend.
* Currently only honored by the GL and Metal backends, and the Vulkan backend * Currently only honored by the GL and Metal backends.
* when some experimental features are enabled.
*/ */
bool disableParallelShaderCompile = false; bool disableParallelShaderCompile = false;
@@ -320,12 +290,6 @@ public:
*/ */
StereoscopicType stereoscopicType = StereoscopicType::NONE; StereoscopicType stereoscopicType = StereoscopicType::NONE;
/*
* The number of eyes to render when stereoscopic rendering is enabled. Supported values are
* between 1 and Engine::getMaxStereoscopicEyes() (inclusive).
*/
uint8_t stereoscopicEyeCount = 2;
/** /**
* Assert the native window associated to a SwapChain is valid when calling makeCurrent(). * Assert the native window associated to a SwapChain is valid when calling makeCurrent().
* This is only supported for: * This is only supported for:
@@ -347,28 +311,12 @@ public:
*/ */
GpuContextPriority gpuContextPriority = GpuContextPriority::DEFAULT; GpuContextPriority gpuContextPriority = GpuContextPriority::DEFAULT;
/**
* Enables asynchronous pipeline cache preloading, if supported on this device.
* This is only supported for:
* - VulkanPlatform
* When the following device extensions are available:
* - VK_KHR_dynamic_rendering
* - VK_EXT_vertex_input_dynamic_state
* Should be enabled only for devices where it has been shown this is effective.
*/
bool vulkanEnableAsyncPipelineCachePrewarming = false;
/** /**
* Bypass the staging buffer because the device is of Unified Memory Architecture. * Bypass the staging buffer because the device is of Unified Memory Architecture.
* This is only supported for: * This is only supported for:
* - VulkanPlatform * - VulkanPlatform
*/ */
bool vulkanEnableStagingBufferBypass = false; bool vulkanEnableStagingBufferBypass = false;
/**
* Asynchronous mode for the engine. Defines how asynchronous operations are handled.
*/
AsynchronousMode asynchronousMode = AsynchronousMode::NONE;
}; };
Platform() noexcept; Platform() noexcept;
@@ -560,22 +508,13 @@ public:
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
// Debugging APIs // Debugging APIs
using DebugUpdateStatFunc = utils::Invocable<void(const char* UTILS_NONNULL key, using DebugUpdateStatFunc = utils::Invocable<void(const char* UTILS_NONNULL key, uint64_t value)>;
uint64_t intValue, utils::CString stringValue)>;
/** /**
* Sets the callback function that the backend can use to update backend-specific statistics * Sets the callback function that the backend can use to update backend-specific statistics
* to aid with debugging. This callback is guaranteed to be called on the Filament driver * to aid with debugging. This callback is guaranteed to be called on the Filament driver
* thread. * thread.
* *
* The callback signature is (key, intValue, stringValue). Note that for any given call,
* only one of the value parameters (intValue or stringValue) will be meaningful, depending on
* the specific key.
*
* IMPORTANT_NOTE: because the callback is called on the driver thread, only quick, non-blocking
* work should be done inside it. Furthermore, no graphics API calls (such as GL calls) should
* be made, which could interfere with Filament's driver state.
*
* @param debugUpdateStat an Invocable that updates debug statistics * @param debugUpdateStat an Invocable that updates debug statistics
*/ */
void setDebugUpdateStatFunc(DebugUpdateStatFunc&& debugUpdateStat) noexcept; void setDebugUpdateStatFunc(DebugUpdateStatFunc&& debugUpdateStat) noexcept;
@@ -594,32 +533,15 @@ public:
* This function is guaranteed to be called only on a single thread, the Filament driver * This function is guaranteed to be called only on a single thread, the Filament driver
* thread. * thread.
* *
* @param key a null-terminated C-string with the key of the debug statistic * @param key a null-terminated C-string with the key of the debug statistic
* @param intValue the updated integer value of key (the string value passed to the * @param value the updated value of key
* callback will be empty)
*/ */
void debugUpdateStat(const char* UTILS_NONNULL key, uint64_t intValue); void debugUpdateStat(const char* UTILS_NONNULL key, uint64_t value);
/**
* To track backend-specific statistics, the backend implementation can call the
* application-provided callback function debugUpdateStatFunc to associate or update a value
* with a given key. It is possible for this function to be called multiple times with the
* same key, in which case newer values should overwrite older values.
*
* This function is guaranteed to be called only on a single thread, the Filament driver
* thread.
*
* @param key a null-terminated C-string with the key of the debug statistic
* @param stringValue the updated string value of key (the integer value passed to the
* callback will be 0)
*/
void debugUpdateStat(const char* UTILS_NONNULL key, utils::CString stringValue);
private: private:
std::shared_ptr<InsertBlobFunc> mInsertBlob; InsertBlobFunc mInsertBlob;
std::shared_ptr<RetrieveBlobFunc> mRetrieveBlob; RetrieveBlobFunc mRetrieveBlob;
std::shared_ptr<DebugUpdateStatFunc> mDebugUpdateStat; DebugUpdateStatFunc mDebugUpdateStat;
mutable utils::Mutex mMutex;
}; };
} // namespace filament } // namespace filament
@@ -50,13 +50,7 @@ public:
descriptor_binding_t binding; descriptor_binding_t binding;
}; };
struct DescriptorSetLayoutBinding {
descriptor_set_t set;
DescriptorSetLayout layout;
};
using SpecializationConstant = std::variant<int32_t, float, bool>; using SpecializationConstant = std::variant<int32_t, float, bool>;
using DescriptorSetLayoutArray = utils::FixedCapacityVector<DescriptorSetLayoutBinding>;
struct Uniform { // For ES2 support struct Uniform { // For ES2 support
utils::CString name; // full qualified name of the uniform field utils::CString name; // full qualified name of the uniform field
@@ -153,19 +147,6 @@ public:
return mDescriptorBindings; return mDescriptorBindings;
} }
inline Program& descriptorLayout(backend::descriptor_set_t set,
DescriptorSetLayout descriptorLayout) noexcept {
mDescriptorLayouts.push_back({
.set = set,
.layout = std::move(descriptorLayout),
});
return *this;
}
const DescriptorSetLayoutArray& getDescriptorSetLayouts() const noexcept {
return mDescriptorLayouts;
}
utils::FixedCapacityVector<PushConstant> const& getPushConstants( utils::FixedCapacityVector<PushConstant> const& getPushConstants(
ShaderStage stage) const noexcept { ShaderStage stage) const noexcept {
return mPushConstants[static_cast<uint8_t>(stage)]; return mPushConstants[static_cast<uint8_t>(stage)];
@@ -195,11 +176,6 @@ private:
std::array<utils::FixedCapacityVector<PushConstant>, SHADER_TYPE_COUNT> mPushConstants; std::array<utils::FixedCapacityVector<PushConstant>, SHADER_TYPE_COUNT> mPushConstants;
DescriptorSetInfo mDescriptorBindings; DescriptorSetInfo mDescriptorBindings;
// Descriptions for descriptor set layouts that may be used for this Program, which
// can be useful for attempting to compile the pipeline ahead of time.
DescriptorSetLayoutArray mDescriptorLayouts =
DescriptorSetLayoutArray::with_capacity(MAX_DESCRIPTOR_SET_COUNT);
// For ES2 support only // For ES2 support only
AttributesInfo mAttributes; AttributesInfo mAttributes;
BindingUniformsInfo mBindingUniformsInfo; BindingUniformsInfo mBindingUniformsInfo;
@@ -17,6 +17,8 @@
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H #ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H #define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#include "AndroidSwapChainHelper.h"
#include "AndroidFrameCallback.h"
#include "AndroidNdk.h" #include "AndroidNdk.h"
#include <backend/AcquiredImage.h> #include <backend/AcquiredImage.h>
@@ -30,6 +32,8 @@
#include <math/mat3.h> #include <math/mat3.h>
#include "AndroidNativeWindow.h"
#include <chrono> #include <chrono>
#include <stddef.h> #include <stddef.h>
@@ -167,10 +171,19 @@ protected:
SwapChain* drawSwapChain, SwapChain* drawSwapChain,
SwapChain* readSwapChain) override; SwapChain* readSwapChain) override;
private: struct SwapChainEGLAndroid : public SwapChainEGL {
struct SwapChainEGLAndroid; SwapChainEGLAndroid(PlatformEGLAndroid const& platform,
struct AndroidDetails; void* nativeWindow, uint64_t flags);
SwapChainEGLAndroid(PlatformEGLAndroid const& platform,
uint32_t width, uint32_t height, uint64_t flags);
void terminate(PlatformEGLAndroid& platform);
bool setPresentFrameId(uint64_t frameId) const noexcept;
uint64_t getFrameId(uint64_t frameId) const noexcept;
private:
AndroidSwapChainHelper mImpl{};
};
private:
// prevent derived classes' implementations to call through // prevent derived classes' implementations to call through
[[nodiscard]] SwapChain* createSwapChain(void* nativeWindow, uint64_t flags) override; [[nodiscard]] SwapChain* createSwapChain(void* nativeWindow, uint64_t flags) override;
[[nodiscard]] SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) override; [[nodiscard]] SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) override;
@@ -190,14 +203,17 @@ private:
int mOSVersion; int mOSVersion;
ExternalStreamManagerAndroid& mExternalStreamManager; ExternalStreamManagerAndroid& mExternalStreamManager;
AndroidDetails& mAndroidDetails;
InitializeJvmForPerformanceManagerIfNeeded const mInitializeJvmForPerformanceManagerIfNeeded; InitializeJvmForPerformanceManagerIfNeeded const mInitializeJvmForPerformanceManagerIfNeeded;
utils::PerformanceHintManager mPerformanceHintManager; utils::PerformanceHintManager mPerformanceHintManager;
utils::PerformanceHintManager::Session mPerformanceHintSession; utils::PerformanceHintManager::Session mPerformanceHintSession;
SwapChainEGLAndroid* mCurrentDrawSwapChain{};
using clock = std::chrono::high_resolution_clock; using clock = std::chrono::high_resolution_clock;
clock::time_point mStartTimeOfActualWork; clock::time_point mStartTimeOfActualWork;
SwapChainEGLAndroid* mCurrentDrawSwapChain{}; AndroidProducerThrottling mProducerThrottling;
bool mAssertNativeWindowIsValid = false; bool mAssertNativeWindowIsValid = false;
AndroidFrameCallback mAndroidFrameCallback;
}; };
} // namespace filament::backend } // namespace filament::backend
@@ -64,7 +64,7 @@ protected:
std::vector<int> mAttribs; std::vector<int> mAttribs;
// For shared contexts // For shared contexts
static constexpr int SHARED_CONTEXT_NUM = 2; static constexpr int SHARED_CONTEXT_NUM = 1;
std::vector<HGLRC> mAdditionalContexts; std::vector<HGLRC> mAdditionalContexts;
std::atomic<int> mNextFreeSharedContextIndex{0}; std::atomic<int> mNextFreeSharedContextIndex{0};
}; };
@@ -33,7 +33,8 @@ protected:
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
// Platform Interface // Platform Interface
Driver* createDriver(void* sharedGLContext, const DriverConfig& driverConfig) override; Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) override;
int getOSVersion() const noexcept override; int getOSVersion() const noexcept override;
@@ -42,7 +43,7 @@ protected:
void terminate() noexcept override; void terminate() noexcept override;
SwapChain* createSwapChain(void* nativeWindow, uint64_t flags) noexcept override; SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override; SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override; void destroySwapChain(SwapChain* swapChain) noexcept override;
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) override; bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) override;
@@ -28,7 +28,6 @@
#include <utils/Hash.h> #include <utils/Hash.h>
#include <utils/PrivateImplementation.h> #include <utils/PrivateImplementation.h>
#include <cstring>
#include <cstddef> #include <cstddef>
#include <functional> #include <functional>
#include <string> #include <string>
@@ -56,31 +55,14 @@ struct VulkanCmdFence;
*/ */
class VulkanPlatform : public Platform, utils::PrivateImplementation<VulkanPlatformPrivate> { class VulkanPlatform : public Platform, utils::PrivateImplementation<VulkanPlatformPrivate> {
public: public:
/**
* Encapsulates information required to instantiate a known external format,
* typically for the purpose of preloading a pipeline cache for materials using
* external formats for samplers.
*/
struct ExternalYcbcrFormat {
uint64_t externalFormat;
VkSamplerYcbcrModelConversion ycbcrModelConversion;
VkSamplerYcbcrRange ycbcrRange;
};
struct ExtensionHashFn { struct ExtensionHashFn {
std::size_t operator()(utils::CString const& s) const noexcept { std::size_t operator()(utils::CString const& s) const noexcept {
return std::hash<std::string>{}(s.data()); return std::hash<std::string>{}(s.data());
} }
}; };
// Note: utils::CString::operator== has an edge case that breaks for the extension set.
// Instead, we'll provide our own comparator.
struct ExtensionEqualFn {
bool operator()(utils::CString const& a, utils::CString const& b) const noexcept {
return strcmp(a.c_str(), b.c_str()) == 0;
}
};
// Utility for managing device or instance extensions during initialization. // Utility for managing device or instance extensions during initialization.
using ExtensionSet = std::unordered_set<utils::CString, ExtensionHashFn, ExtensionEqualFn>; using ExtensionSet = std::unordered_set<utils::CString, ExtensionHashFn>;
/** /**
* A collection of handles to objects and metadata that comprises a Vulkan context. The client * A collection of handles to objects and metadata that comprises a Vulkan context. The client
@@ -455,50 +437,6 @@ protected:
std::shared_ptr<VulkanCmdFence> fenceStatus; std::shared_ptr<VulkanCmdFence> fenceStatus;
}; };
/**
* Creates the VkInstance used by Filament's Vulkan backend.
*
* This method can be overridden in subclasses to customize VkInstance creation, such as
* adding application-specific layers or extensions.
*
* The provided `createInfo` contains layers and extensions required by Filament.
* If you override this method and need to modify the `createInfo` struct, you must first
* make a copy of it and modify the copy.
*
* @param createInfo The VkInstanceCreateInfo prepared by Filament.
* @return The created VkInstance, or VK_NULL_HANDLE on failure.
*/
virtual VkInstance createVkInstance(VkInstanceCreateInfo const& createInfo) noexcept;
/**
* Selects a VkPhysicalDevice (GPU) for Filament's Vulkan backend to use.
*
* This method can be overridden in subclasses to implement custom GPU selection logic.
* For example, an application might override this to prefer a discrete GPU over an
* integrated one based on device properties.
*
* The default implementation selects the first device that meets Filament's requirements.
*
* @param instance The VkInstance to enumerate devices from.
* @return The selected VkPhysicalDevice, or VK_NULL_HANDLE if no suitable device is found.
*/
virtual VkPhysicalDevice selectVkPhysicalDevice(VkInstance instance) noexcept;
/**
* Creates the VkDevice used by Filament's Vulkan backend.
*
* This method can be overridden in subclasses to customize VkDevice creation, such as
* adding application-specific extensions or enabling features.
*
* The provided `createInfo` contains extensions and features required by Filament.
* If you override this method and need to modify the `createInfo` struct, you must first
* make a copy of it and modify the copy.
*
* @param createInfo The VkDeviceCreateInfo prepared by Filament.
* @return The created VkDevice, or VK_NULL_HANDLE on failure.
*/
virtual VkDevice createVkDevice(VkDeviceCreateInfo const& createInfo) noexcept;
using SurfaceBundle = std::tuple<VkSurfaceKHR, VkExtent2D>; using SurfaceBundle = std::tuple<VkSurfaceKHR, VkExtent2D>;
virtual ExtensionSet getSwapchainInstanceExtensions() const = 0; virtual ExtensionSet getSwapchainInstanceExtensions() const = 0;
virtual SurfaceBundle createVkSurfaceKHR(void* nativeWindow, VkInstance instance, virtual SurfaceBundle createVkSurfaceKHR(void* nativeWindow, VkInstance instance,
@@ -511,48 +449,7 @@ protected:
*/ */
bool isTransientAttachmentSupported() const noexcept; bool isTransientAttachmentSupported() const noexcept;
/**
* For pipeline cache prewarming, if external samplers are present, we need to build
* the fake pipeline using the proper formats specified. Since there's no way to
* get these at material build time, we allow the app to register them before
* creating materials.
*
* @param format The format, containing the external format value which should be
* extracted from an AHardwareBuffer.
*/
void registerPipelineCachePrewarmExternalFormat(const ExternalYcbcrFormat& format) noexcept;
private: private:
/**
* Contains information about features that should be requested
* when calling vkCreateDevice, based on feature support from
* vkGetPhysicalDeviceFeatures2.
*/
struct MiscDeviceFeatures {
/**
* This allows creation of a VkGraphicsPipeline without a
* render pass specified.
*/
bool dynamicRendering;
/**
* Allows creation of a 2d image view, or 2d image view array,
* to be created from a 3d VkImage.
*/
bool imageView2Don3DImage;
};
void createInstance(ExtensionSet const& requiredExts) noexcept;
void queryAndSetDeviceFeatures(Platform::DriverConfig const& driverConfig,
ExtensionSet const& instExts, ExtensionSet const& deviceExts,
void* sharedContext) noexcept;
void createLogicalDeviceAndQueues(ExtensionSet const& deviceExtensions,
VkPhysicalDeviceFeatures const& features,
VkPhysicalDeviceVulkan11Features const& vk11Features, bool createProtectedQueue,
MiscDeviceFeatures const& requestedFeatures) noexcept;
friend struct VulkanPlatformPrivate; friend struct VulkanPlatformPrivate;
}; };
@@ -17,13 +17,12 @@
#ifndef TNT_FILAMENT_BACKEND_PLATFORMS_VULKAN_PLATFORM_ANDROID_H #ifndef TNT_FILAMENT_BACKEND_PLATFORMS_VULKAN_PLATFORM_ANDROID_H
#define TNT_FILAMENT_BACKEND_PLATFORMS_VULKAN_PLATFORM_ANDROID_H #define TNT_FILAMENT_BACKEND_PLATFORMS_VULKAN_PLATFORM_ANDROID_H
#include "AndroidFrameCallback.h"
#include "AndroidNdk.h" #include "AndroidNdk.h"
#include <backend/DriverEnums.h> #include <backend/DriverEnums.h>
#include <backend/platforms/VulkanPlatform.h> #include <backend/platforms/VulkanPlatform.h>
#include <utils/compiler.h>
#include <android/hardware_buffer.h> #include <android/hardware_buffer.h>
namespace filament::backend { namespace filament::backend {
@@ -81,6 +80,7 @@ public:
bool queryFrameTimestamps(SwapChain const* swapchain, uint64_t frameId, bool queryFrameTimestamps(SwapChain const* swapchain, uint64_t frameId,
FrameTimestamps* outFrameTimestamps) const noexcept override; FrameTimestamps* outFrameTimestamps) const noexcept override;
protected: protected:
ExtensionSet getSwapchainInstanceExtensions() const override; ExtensionSet getSwapchainInstanceExtensions() const override;
@@ -91,8 +91,6 @@ protected:
VkExternalFenceHandleTypeFlagBits getFenceExportFlags() const noexcept override; VkExternalFenceHandleTypeFlagBits getFenceExportFlags() const noexcept override;
private: private:
struct AndroidDetails;
struct ExternalImageVulkanAndroid : public ExternalImage { struct ExternalImageVulkanAndroid : public ExternalImage {
AHardwareBuffer* aHardwareBuffer = nullptr; AHardwareBuffer* aHardwareBuffer = nullptr;
bool sRGB = false; bool sRGB = false;
@@ -101,7 +99,7 @@ private:
~ExternalImageVulkanAndroid() override; ~ExternalImageVulkanAndroid() override;
}; };
AndroidDetails& mAndroidDetails; AndroidFrameCallback mAndroidFrameCallback;
int mOSVersion{}; int mOSVersion{};
}; };
@@ -54,9 +54,9 @@ public:
// a 3rd party library could be considered. However, this was a simple and // a 3rd party library could be considered. However, this was a simple and
// quick change and works for now. // quick change and works for now.
// gets the size (height and width) of the surface/window // gets the size (height and width) of the surface/window
[[nodiscard]] virtual wgpu::Extent2D getSurfaceExtent(void* nativeWindow) const = 0; [[nodiscard]] wgpu::Extent2D getSurfaceExtent(void* nativeWindow) const;
// either returns a valid surface or panics // either returns a valid surface or panics
[[nodiscard]] virtual wgpu::Surface createSurface(void* nativeWindow, uint64_t flags) = 0; [[nodiscard]] wgpu::Surface createSurface(void* nativeWindow, uint64_t flags);
// either returns a valid adapter or panics // either returns a valid adapter or panics
[[nodiscard]] wgpu::Adapter requestAdapter(wgpu::Surface const& surface); [[nodiscard]] wgpu::Adapter requestAdapter(wgpu::Surface const& surface);
// either returns a valid device or panics // either returns a valid device or panics
@@ -74,9 +74,10 @@ protected:
[[nodiscard]] Driver* createDriver(void* sharedContext, [[nodiscard]] Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) override; const Platform::DriverConfig& driverConfig) override;
private:
// returns adapter request option variations applicable for the particular // returns adapter request option variations applicable for the particular
// platform // platform
[[nodiscard]] virtual std::vector<wgpu::RequestAdapterOptions> getAdapterOptions() = 0; [[nodiscard]] static std::vector<wgpu::RequestAdapterOptions> getAdapterOptions();
// we may consider having the driver own this in the future // we may consider having the driver own this in the future
wgpu::Instance mInstance; wgpu::Instance mInstance;
@@ -1,35 +0,0 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_PLATFORMS_WEBGPUPLATFORMANDROID_H
#define TNT_FILAMENT_BACKEND_PLATFORMS_WEBGPUPLATFORMANDROID_H
#include <backend/platforms/WebGPUPlatform.h>
namespace filament::backend {
class WebGPUPlatformAndroid : public WebGPUPlatform {
public:
wgpu::Extent2D getSurfaceExtent(void* nativeWindow) const override;
wgpu::Surface createSurface(void* nativeWindow, uint64_t /*flags*/) override;
protected:
std::vector<wgpu::RequestAdapterOptions> getAdapterOptions() override;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PLATFORMS_WEBGPUPLATFORMANDROID_H
@@ -1,35 +0,0 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_PLATFORMS_WEBGPUPLATFORMAPPLE_H
#define TNT_FILAMENT_BACKEND_PLATFORMS_WEBGPUPLATFORMAPPLE_H
#include <backend/platforms/WebGPUPlatform.h>
namespace filament::backend {
class WebGPUPlatformApple : public WebGPUPlatform {
public:
wgpu::Extent2D getSurfaceExtent(void* nativeWindow) const override;
wgpu::Surface createSurface(void* nativeWindow, uint64_t /*flags*/) override;
protected:
std::vector<wgpu::RequestAdapterOptions> getAdapterOptions() override;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PLATFORMS_WEBGPUPLATFORMAPPLE_H
@@ -1,35 +0,0 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_PLATFORMS_WEBGPUPLATFORMLINUX_H
#define TNT_FILAMENT_BACKEND_PLATFORMS_WEBGPUPLATFORMLINUX_H
#include <backend/platforms/WebGPUPlatform.h>
namespace filament::backend {
class WebGPUPlatformLinux : public WebGPUPlatform {
public:
wgpu::Extent2D getSurfaceExtent(void* nativeWindow) const override;
wgpu::Surface createSurface(void* nativeWindow, uint64_t /*flags*/) override;
protected:
std::vector<wgpu::RequestAdapterOptions> getAdapterOptions() override;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PLATFORMS_WEBGPUPLATFORMLINUX_H
@@ -1,35 +0,0 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_PLATFORMS_WEBGPUPLATFORMWINDOWS_H
#define TNT_FILAMENT_BACKEND_PLATFORMS_WEBGPUPLATFORMWINDOWS_H
#include <backend/platforms/WebGPUPlatform.h>
namespace filament::backend {
class WebGPUPlatformWindows : public WebGPUPlatform {
public:
wgpu::Extent2D getSurfaceExtent(void* nativeWindow) const override;
wgpu::Surface createSurface(void* nativeWindow, uint64_t /*flags*/) override;
protected:
std::vector<wgpu::RequestAdapterOptions> getAdapterOptions() override;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PLATFORMS_WEBGPUPLATFORMWINDOWS_H
@@ -22,6 +22,7 @@
#include "private/backend/Driver.h" #include "private/backend/Driver.h"
#include <backend/BufferDescriptor.h> #include <backend/BufferDescriptor.h>
#include <backend/BufferObjectStreamDescriptor.h>
#include <backend/CallbackHandler.h> #include <backend/CallbackHandler.h>
#include <backend/DriverEnums.h> #include <backend/DriverEnums.h>
#include <backend/Handle.h> #include <backend/Handle.h>
@@ -51,6 +51,7 @@
namespace filament::backend { namespace filament::backend {
class BufferDescriptor; class BufferDescriptor;
class BufferObjectStreamDescriptor;
class CallbackHandler; class CallbackHandler;
class PixelBufferDescriptor; class PixelBufferDescriptor;
class Program; class Program;
@@ -70,11 +71,6 @@ public:
// is where the driver can execute user callbacks. // is where the driver can execute user callbacks.
virtual void purge() noexcept = 0; virtual void purge() noexcept = 0;
// Called from the engine thread (render-thread) to execute the `callback` via the `handler` if
// it is available. Otherwise, if `handler` is null, the `callback` is executed on the main
// thread via `purge()`.
virtual void scheduleCallback(CallbackHandler* handler, void* user, CallbackHandler::Callback callback) = 0;
virtual ShaderModel getShaderModel() const noexcept = 0; virtual ShaderModel getShaderModel() const noexcept = 0;
// The shader languages used for shaders for this driver in order of preference, used to inform // The shader languages used for shaders for this driver in order of preference, used to inform
@@ -74,9 +74,8 @@
#define APPLY10(M, A, ...) EXPAND(M(A)), EXPAND(APPLY9(M, __VA_ARGS__)) #define APPLY10(M, A, ...) EXPAND(M(A)), EXPAND(APPLY9(M, __VA_ARGS__))
#define APPLY11(M, A, ...) EXPAND(M(A)), EXPAND(APPLY10(M, __VA_ARGS__)) #define APPLY11(M, A, ...) EXPAND(M(A)), EXPAND(APPLY10(M, __VA_ARGS__))
#define APPLY12(M, A, ...) EXPAND(M(A)), EXPAND(APPLY11(M, __VA_ARGS__)) #define APPLY12(M, A, ...) EXPAND(M(A)), EXPAND(APPLY11(M, __VA_ARGS__))
#define APPLY13(M, A, ...) EXPAND(M(A)), EXPAND(APPLY12(M, __VA_ARGS__)) #define APPLY_N__(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, X, ...) APPLY##X
#define APPLY_N__(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, X, ...) APPLY##X #define APPLY(M, ...) EXPAND(EXPAND(APPLY_N__(M, __VA_ARGS__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))(M, __VA_ARGS__))
#define APPLY(M, ...) EXPAND(EXPAND(APPLY_N__(M, __VA_ARGS__, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))(M, __VA_ARGS__))
#define PAIR_ARGS_0(M, ...) #define PAIR_ARGS_0(M, ...)
@@ -92,12 +91,11 @@
#define PAIR_ARGS_10(M, X, Y, ...) M(X, Y), EXPAND(PAIR_ARGS_9(M, __VA_ARGS__)) #define PAIR_ARGS_10(M, X, Y, ...) M(X, Y), EXPAND(PAIR_ARGS_9(M, __VA_ARGS__))
#define PAIR_ARGS_11(M, X, Y, ...) M(X, Y), EXPAND(PAIR_ARGS_10(M, __VA_ARGS__)) #define PAIR_ARGS_11(M, X, Y, ...) M(X, Y), EXPAND(PAIR_ARGS_10(M, __VA_ARGS__))
#define PAIR_ARGS_12(M, X, Y, ...) M(X, Y), EXPAND(PAIR_ARGS_11(M, __VA_ARGS__)) #define PAIR_ARGS_12(M, X, Y, ...) M(X, Y), EXPAND(PAIR_ARGS_11(M, __VA_ARGS__))
#define PAIR_ARGS_13(M, X, Y, ...) M(X, Y), EXPAND(PAIR_ARGS_12(M, __VA_ARGS__))
#define PAIR_ARGS_N__(_0, E1, _1, E2, _2, E3, _3, E4, _4, E5, _5, E6, _6, E7, _7, E8, _8, E9, _9, E10, _10, E11, _11, E12, _12, E13, _13, X, ...) PAIR_ARGS_##X #define PAIR_ARGS_N__(_0, E1, _1, E2, _2, E3, _3, E4, _4, E5, _5, E6, _6, E7, _7, E8, _8, E9, _9, E10, _10, E11, _11, E12, _12, X, ...) PAIR_ARGS_##X
#define PAIR_ARGS_N(M, ...) \ #define PAIR_ARGS_N(M, ...) \
EXPAND(EXPAND(PAIR_ARGS_N__(0, ##__VA_ARGS__, 13, E, 12, E, 11, E, 10, E, 9, E, 8, E, 7, E, 6, E, 5, E, 4, E, 3, E, 2, E, 1, E, 0))(M, __VA_ARGS__)) EXPAND(EXPAND(PAIR_ARGS_N__(0, ##__VA_ARGS__, 12, E, 11, E, 10, E, 9, E, 8, E, 7, E, 6, E, 5, E, 4, E, 3, E, 2, E, 1, E, 0))(M, __VA_ARGS__))
#define ARG(T, P) T P #define ARG(T, P) T P
@@ -194,27 +192,11 @@ DECL_DRIVER_API_TAGGED_R_N(backend::IndexBufferHandle, createIndexBuffer,
uint32_t, indexCount, uint32_t, indexCount,
backend::BufferUsage, usage) backend::BufferUsage, usage)
DECL_DRIVER_API_TAGGED_R_N(backend::IndexBufferHandle, createIndexBufferAsync,
backend::ElementType, elementType,
uint32_t, indexCount,
backend::BufferUsage, usage,
backend::CallbackHandler*, handler,
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_TAGGED_R_N(backend::BufferObjectHandle, createBufferObject, DECL_DRIVER_API_TAGGED_R_N(backend::BufferObjectHandle, createBufferObject,
uint32_t, byteCount, uint32_t, byteCount,
backend::BufferObjectBinding, bindingType, backend::BufferObjectBinding, bindingType,
backend::BufferUsage, usage) backend::BufferUsage, usage)
DECL_DRIVER_API_TAGGED_R_N(backend::BufferObjectHandle, createBufferObjectAsync,
uint32_t, byteCount,
backend::BufferObjectBinding, bindingType,
backend::BufferUsage, usage,
backend::CallbackHandler*, handler,
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTexture, DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTexture,
backend::SamplerType, target, backend::SamplerType, target,
uint8_t, levels, uint8_t, levels,
@@ -225,19 +207,6 @@ DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTexture,
uint32_t, depth, uint32_t, depth,
backend::TextureUsage, usage) backend::TextureUsage, usage)
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureAsync,
backend::SamplerType, target,
uint8_t, levels,
backend::TextureFormat, format,
uint8_t, samples,
uint32_t, width,
uint32_t, height,
uint32_t, depth,
backend::TextureUsage, usage,
backend::CallbackHandler*, handler,
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureView, DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureView,
backend::TextureHandle, texture, backend::TextureHandle, texture,
uint8_t, baseLevel, uint8_t, baseLevel,
@@ -250,16 +219,6 @@ DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureViewSwizzle,
backend::TextureSwizzle, b, backend::TextureSwizzle, b,
backend::TextureSwizzle, a) backend::TextureSwizzle, a)
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureViewSwizzleAsync,
backend::TextureHandle, texture,
backend::TextureSwizzle, r,
backend::TextureSwizzle, g,
backend::TextureSwizzle, b,
backend::TextureSwizzle, a,
backend::CallbackHandler*, handler,
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureExternalImage2, DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureExternalImage2,
backend::SamplerType, target, backend::SamplerType, target,
backend::TextureFormat, format, backend::TextureFormat, format,
@@ -295,20 +254,6 @@ DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, importTexture,
uint32_t, depth, uint32_t, depth,
backend::TextureUsage, usage) backend::TextureUsage, usage)
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, importTextureAsync,
intptr_t, id,
backend::SamplerType, target,
uint8_t, levels,
backend::TextureFormat, format,
uint8_t, samples,
uint32_t, width,
uint32_t, height,
uint32_t, depth,
backend::TextureUsage, usage,
backend::CallbackHandler*, handler,
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_TAGGED_R_N(backend::RenderPrimitiveHandle, createRenderPrimitive, DECL_DRIVER_API_TAGGED_R_N(backend::RenderPrimitiveHandle, createRenderPrimitive,
backend::VertexBufferHandle, vbh, backend::VertexBufferHandle, vbh,
backend::IndexBufferHandle, ibh, backend::IndexBufferHandle, ibh,
@@ -412,7 +357,6 @@ DECL_DRIVER_API_SYNCHRONOUS_0(bool, isDepthStencilResolveSupported)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isDepthStencilBlitSupported, backend::TextureFormat, format) DECL_DRIVER_API_SYNCHRONOUS_N(bool, isDepthStencilBlitSupported, backend::TextureFormat, format)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isProtectedTexturesSupported) DECL_DRIVER_API_SYNCHRONOUS_0(bool, isProtectedTexturesSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isDepthClampSupported) DECL_DRIVER_API_SYNCHRONOUS_0(bool, isDepthClampSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isAsynchronousModeEnabled)
DECL_DRIVER_API_SYNCHRONOUS_0(uint8_t, getMaxDrawBuffers) DECL_DRIVER_API_SYNCHRONOUS_0(uint8_t, getMaxDrawBuffers)
DECL_DRIVER_API_SYNCHRONOUS_0(size_t, getMaxUniformBufferSize) DECL_DRIVER_API_SYNCHRONOUS_0(size_t, getMaxUniformBufferSize)
DECL_DRIVER_API_SYNCHRONOUS_N(size_t, getMaxTextureSize, backend::SamplerType, target) DECL_DRIVER_API_SYNCHRONOUS_N(size_t, getMaxTextureSize, backend::SamplerType, target)
@@ -438,39 +382,19 @@ DECL_DRIVER_API_N(setVertexBufferObject,
uint32_t, index, uint32_t, index,
backend::BufferObjectHandle, bufferObject) backend::BufferObjectHandle, bufferObject)
DECL_DRIVER_API_R_N(backend::AsyncCallId, setVertexBufferObjectAsync,
backend::VertexBufferHandle, vbh,
uint32_t, index,
backend::BufferObjectHandle, bufferObject,
backend::CallbackHandler*, handler,
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_N(updateIndexBuffer, DECL_DRIVER_API_N(updateIndexBuffer,
backend::IndexBufferHandle, ibh, backend::IndexBufferHandle, ibh,
backend::BufferDescriptor&&, data, backend::BufferDescriptor&&, data,
uint32_t, byteOffset) uint32_t, byteOffset)
DECL_DRIVER_API_R_N(backend::AsyncCallId, updateIndexBufferAsync,
backend::IndexBufferHandle, ibh,
backend::BufferDescriptor&&, data,
uint32_t, byteOffset,
backend::CallbackHandler*, handler,
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_N(updateBufferObject, DECL_DRIVER_API_N(updateBufferObject,
backend::BufferObjectHandle, ibh, backend::BufferObjectHandle, ibh,
backend::BufferDescriptor&&, data, backend::BufferDescriptor&&, data,
uint32_t, byteOffset) uint32_t, byteOffset)
DECL_DRIVER_API_R_N(backend::AsyncCallId, updateBufferObjectAsync, DECL_DRIVER_API_N(registerBufferObjectStreams,
backend::BufferObjectHandle, ibh, backend::BufferObjectHandle, boh,
backend::BufferDescriptor&&, data, backend::BufferObjectStreamDescriptor&&, streams)
uint32_t, byteOffset,
backend::CallbackHandler*, handler,
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_N(updateBufferObjectUnsynchronized, DECL_DRIVER_API_N(updateBufferObjectUnsynchronized,
backend::BufferObjectHandle, boh, backend::BufferObjectHandle, boh,
@@ -491,20 +415,6 @@ DECL_DRIVER_API_N(update3DImage,
uint32_t, depth, uint32_t, depth,
backend::PixelBufferDescriptor&&, data) backend::PixelBufferDescriptor&&, data)
DECL_DRIVER_API_R_N(backend::AsyncCallId, update3DImageAsync,
backend::TextureHandle, th,
uint32_t, level,
uint32_t, xoffset,
uint32_t, yoffset,
uint32_t, zoffset,
uint32_t, width,
uint32_t, height,
uint32_t, depth,
backend::PixelBufferDescriptor&&, data,
backend::CallbackHandler*, handler,
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_N(generateMipmaps, DECL_DRIVER_API_N(generateMipmaps,
backend::TextureHandle, th) backend::TextureHandle, th)
@@ -671,19 +581,6 @@ DECL_DRIVER_API_N(dispatchCompute,
DECL_DRIVER_API_N(scissor, DECL_DRIVER_API_N(scissor,
Viewport, scissor) Viewport, scissor)
/*
* Asyncronous operation helpers
* --------------------
*/
DECL_DRIVER_API_R_N(backend::AsyncCallId, queueCommandAsync,
utils::Invocable<void(void)>&&, command,
backend::CallbackHandler*, handler,
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, cancelAsyncJob, backend::AsyncCallId, jobId)
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
@@ -61,16 +61,6 @@ int NativeWindow::enableFrameTimestamps(ANativeWindow* anw, bool enable) {
return pWindow->perform(anw, ENABLE_FRAME_TIMESTAMPS, enable); return pWindow->perform(anw, ENABLE_FRAME_TIMESTAMPS, enable);
} }
int NativeWindow::frameTimestampsSupportsPresent(ANativeWindow* anw, bool* outSupportsPresent) {
NativeWindow const* pWindow = reinterpret_cast<NativeWindow const*>(anw);
int value = 0;
bool const success = pWindow->perform(anw, FRAME_TIMESTAMPS_SUPPORTS_PRESENT, &value);
if (success) {
*outSupportsPresent = bool(value);
}
return success;
}
int NativeWindow::getCompositorTiming(ANativeWindow* anw, int NativeWindow::getCompositorTiming(ANativeWindow* anw,
int64_t* compositeDeadline, int64_t* compositeInterval, int64_t* compositeDeadline, int64_t* compositeInterval,
int64_t* compositeToPresentLatency) { int64_t* compositeToPresentLatency) {
@@ -32,7 +32,6 @@ struct NativeWindow {
// is valid query enum value // is valid query enum value
enum { enum {
IS_VALID = 17, IS_VALID = 17,
FRAME_TIMESTAMPS_SUPPORTS_PRESENT = 18,
GET_NEXT_FRAME_ID = 24, GET_NEXT_FRAME_ID = 24,
ENABLE_FRAME_TIMESTAMPS = 25, ENABLE_FRAME_TIMESTAMPS = 25,
GET_COMPOSITOR_TIMING = 26, GET_COMPOSITOR_TIMING = 26,
@@ -52,7 +51,6 @@ struct NativeWindow {
static int getNextFrameId(ANativeWindow* anw, uint64_t* frameId); static int getNextFrameId(ANativeWindow* anw, uint64_t* frameId);
static int enableFrameTimestamps(ANativeWindow* anw, bool enable); static int enableFrameTimestamps(ANativeWindow* anw, bool enable);
static int frameTimestampsSupportsPresent(ANativeWindow* anw, bool* outSupportsPresent);
static int getCompositorTiming(ANativeWindow* anw, static int getCompositorTiming(ANativeWindow* anw,
int64_t* compositeDeadline, int64_t* compositeInterval, int64_t* compositeDeadline, int64_t* compositeInterval,
int64_t* compositeToPresentLatency); int64_t* compositeToPresentLatency);
+1 -1
View File
@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include <backend/platforms/AndroidNdk.h> #include "AndroidNdk.h"
#include <android/hardware_buffer.h> #include <android/hardware_buffer.h>
@@ -19,9 +19,6 @@
#include <android/native_window.h> #include <android/native_window.h>
#include <utils/compiler.h>
#include <utils/Logger.h>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
@@ -39,23 +36,11 @@ bool AndroidSwapChainHelper::setPresentFrameId(
int const status = NativeWindow::getNextFrameId(anw, &sysFrameId); int const status = NativeWindow::getNextFrameId(anw, &sysFrameId);
if (status == 0) { if (status == 0) {
std::lock_guard const lock(mLock); std::lock_guard const lock(mLock);
// frameIds must be strictly monotonic, if that's not the case (i.e. the new frameId is auto const pos = mFrameIdToSystemFrameId.find(frameId);
// less or equal to the last one in the map), we have to clear the map, because the if (pos && *pos != sysFrameId) {
// map's find() assume sorted keys. // we're trying to associate the same frame id to a different frame!
// This case can happen if two different filament::Renderer are used with the same return false;
// ANativeWindow (the Renderer would have different frameIds). This is expected to
// be a rare case.
if (UTILS_UNLIKELY(!mFrameIdToSystemFrameId.empty() &&
frameId <= mFrameIdToSystemFrameId.back().first)) {
// this log is expected to happen very rarely
DLOG(INFO) << "clearing frame history anw=" << anw
<< ", frameId=" << frameId
<< ", previous=" << mFrameIdToSystemFrameId.back().first
<< ", sysFrameId=" << sysFrameId;
// clear the frame history
mFrameIdToSystemFrameId.clear();
} }
// oldest entry is removed // oldest entry is removed
mFrameIdToSystemFrameId.insert(frameId, sysFrameId); mFrameIdToSystemFrameId.insert(frameId, sysFrameId);
return true; return true;
-26
View File
@@ -1,26 +0,0 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <backend/CallbackHandler.h>
namespace filament::backend {
// Define the virtual destructor here to avoid a compiler warning that we treat as an error.
// "'CallbackHandler' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit"
// The warning occurs when a class inherits from CallbackHandler.
CallbackHandler::~CallbackHandler() = default;
} // namespace filament::backend
+1 -5
View File
@@ -28,9 +28,7 @@
#include <utils/Logger.h> #include <utils/Logger.h>
#include <utils/compiler.h> #include <utils/compiler.h>
#include <utils/debug.h> #include <utils/debug.h>
#include <utils/JobSystem.h>
#include <utils/ostream.h> #include <utils/ostream.h>
#include <utils/Panic.h>
#include <math/half.h> #include <math/half.h>
#include <math/vec2.h> #include <math/vec2.h>
@@ -49,12 +47,10 @@ using namespace filament::math;
namespace filament::backend { namespace filament::backend {
DriverBase::DriverBase(const Platform::DriverConfig& driverConfig) noexcept DriverBase::DriverBase() noexcept {
: mDriverConfig(driverConfig) {
if constexpr (UTILS_HAS_THREADING) { if constexpr (UTILS_HAS_THREADING) {
// This thread services user callbacks // This thread services user callbacks
mServiceThread = std::thread([this]() { mServiceThread = std::thread([this]() {
JobSystem::setThreadName("ServiceThread");
do { do {
auto& serviceThreadCondition = mServiceThreadCondition; auto& serviceThreadCondition = mServiceThreadCondition;
auto& serviceThreadCallbackQueue = mServiceThreadCallbackQueue; auto& serviceThreadCallbackQueue = mServiceThreadCallbackQueue;

Some files were not shown because too many files have changed in this diff Show More