Compare commits
164 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c0643f122 | ||
|
|
4742693869 | ||
|
|
6c39e474ea | ||
|
|
5c8977c906 | ||
|
|
ebb62b5d55 | ||
|
|
6b3cc2e2f3 | ||
|
|
b9a5ad205a | ||
|
|
100986d8d9 | ||
|
|
b7c9a36d57 | ||
|
|
d76551ab28 | ||
|
|
92bc0752d1 | ||
|
|
657c251463 | ||
|
|
b6b8fee483 | ||
|
|
be5b60f895 | ||
|
|
681d31758f | ||
|
|
76b2edd6ea | ||
|
|
80dc2f5c9d | ||
|
|
ce7dd7a1fb | ||
|
|
85617c96a2 | ||
|
|
58760adb6a | ||
|
|
4ef0b72773 | ||
|
|
45631c3b81 | ||
|
|
6f6dde2579 | ||
|
|
e0acbe42cf | ||
|
|
4f137ccf89 | ||
|
|
04010e7dd9 | ||
|
|
f4f9f331c0 | ||
|
|
dada291f6b | ||
|
|
18f2f8b6d4 | ||
|
|
d4117ac968 | ||
|
|
eccbc8c242 | ||
|
|
3cdf24f515 | ||
|
|
d91faf9df8 | ||
|
|
d950efa6ea | ||
|
|
8ebb37d011 | ||
|
|
3366db83ef | ||
|
|
861d69ea7c | ||
|
|
5415254aac | ||
|
|
b2cc904fab | ||
|
|
3f87b520bb | ||
|
|
135a362176 | ||
|
|
391ebc3702 | ||
|
|
b4d1443720 | ||
|
|
c06737aca2 | ||
|
|
f847232296 | ||
|
|
89f06b8923 | ||
|
|
90a2b1f3c9 | ||
|
|
059f51338d | ||
|
|
d3cea5121e | ||
|
|
c37301d2dc | ||
|
|
aa16778fbd | ||
|
|
ee499ad2ca | ||
|
|
958dd5bb27 | ||
|
|
f988b75999 | ||
|
|
e3ccb4bb3c | ||
|
|
3f0dc6f7e6 | ||
|
|
c212dd5bc7 | ||
|
|
1eceab0040 | ||
|
|
ab9d1e5956 | ||
|
|
c906290416 | ||
|
|
d52a24b6e9 | ||
|
|
9aeec3a759 | ||
|
|
550fcfe2e3 | ||
|
|
b2cdf9f2b4 | ||
|
|
19a3fe3dce | ||
|
|
754abbf78e | ||
|
|
9b855e9a03 | ||
|
|
2534fdf92d | ||
|
|
dab02e915e | ||
|
|
68da1a25eb | ||
|
|
c67b363576 | ||
|
|
5c0e7d8211 | ||
|
|
caacc61602 | ||
|
|
e902df19b2 | ||
|
|
3d57c60840 | ||
|
|
8ab2725a79 | ||
|
|
ff27f8109c | ||
|
|
40b372dda7 | ||
|
|
8e09d8bd71 | ||
|
|
d6df4cd03a | ||
|
|
df03fdf3d7 | ||
|
|
6c59945395 | ||
|
|
d16cc50561 | ||
|
|
fd330a98aa | ||
|
|
e667484a94 | ||
|
|
71e5e6c6c0 | ||
|
|
c1df902593 | ||
|
|
3c3320a2ba | ||
|
|
35753bc6c2 | ||
|
|
5f7967d09c | ||
|
|
404b6e8af3 | ||
|
|
898c20e584 | ||
|
|
f278b76b04 | ||
|
|
6353f17635 | ||
|
|
9cae34babf | ||
|
|
c37cc61b30 | ||
|
|
9aced8e9b8 | ||
|
|
dde060bf4d | ||
|
|
b60518caa5 | ||
|
|
69000ef1f2 | ||
|
|
39d6106ef2 | ||
|
|
96a1cbe69f | ||
|
|
90c23a7d5d | ||
|
|
5710304114 | ||
|
|
0f684820bc | ||
|
|
09fe495384 | ||
|
|
e1d2d6ade6 | ||
|
|
e0b6f2ca71 | ||
|
|
8457d6092d | ||
|
|
72c16e07ed | ||
|
|
12b96cba04 | ||
|
|
e4d943e942 | ||
|
|
7fa66325f3 | ||
|
|
e188a7875e | ||
|
|
ac9822b8c8 | ||
|
|
edb5fddd03 | ||
|
|
35f4a97e32 | ||
|
|
487b10fdda | ||
|
|
271cda88aa | ||
|
|
25b73ddcfa | ||
|
|
35b8146a87 | ||
|
|
091e5a33ac | ||
|
|
ffe4b7390d | ||
|
|
604d3e34a4 | ||
|
|
e116dd4aec | ||
|
|
d53614fb0a | ||
|
|
c91e5df117 | ||
|
|
96574816b3 | ||
|
|
b43a609ebc | ||
|
|
2a35ee279b | ||
|
|
2c490ec799 | ||
|
|
fbb08d338a | ||
|
|
8e1718458a | ||
|
|
6bcd709320 | ||
|
|
1a6e3ec88e | ||
|
|
f5f50eca06 | ||
|
|
886fb7fb94 | ||
|
|
a82b3bedb2 | ||
|
|
d879bbc80a | ||
|
|
bf437b7933 | ||
|
|
49dff3c439 | ||
|
|
0d6c017cfb | ||
|
|
ba042db3f4 | ||
|
|
faeba6ad95 | ||
|
|
163e28ca7a | ||
|
|
3dbc168d76 | ||
|
|
fe49946852 | ||
|
|
6310ea46e3 | ||
|
|
ef8e3e5224 | ||
|
|
26cc722f74 | ||
|
|
043fdf7a51 | ||
|
|
c01105b49a | ||
|
|
f56f5a300c | ||
|
|
8b79f3683e | ||
|
|
319bd123ce | ||
|
|
e23243a65b | ||
|
|
c4261a8c10 | ||
|
|
009b58537e | ||
|
|
e51709a4e8 | ||
|
|
78813ed9b7 | ||
|
|
2e649a9f16 | ||
|
|
d36783cd1d | ||
|
|
101a59138c | ||
|
|
3809259f47 |
13
.github/workflows/release.yml
vendored
13
.github/workflows/release.yml
vendored
@@ -50,8 +50,7 @@ jobs:
|
||||
cd build/$WORKFLOW_OS && printf "y" | ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
if [ -f out/filament-release-darwin.tgz ]; then mv out/filament-release-darwin.tgz out/filament-${TAG}-mac.tgz; fi;
|
||||
if [ -f out/filament-release-linux.tgz ]; then mv out/filament-release-linux.tgz out/filament-${TAG}-linux.tgz; fi;
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
@@ -80,8 +79,7 @@ jobs:
|
||||
cd build/web && printf "y" | ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
mv out/filament-release-web.tgz out/filament-${TAG}-web.tgz
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
@@ -123,15 +121,13 @@ jobs:
|
||||
APK_KEYSTORE_PASS: ${{ secrets.APK_KEYSTORE_PASS }}
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
mv out/filament-android-release.aar out/filament-${TAG}-android.aar
|
||||
mv out/filamat-android-release.aar out/filamat-${TAG}-android.aar
|
||||
mv out/filamat-android-lite-release.aar out/filamat-${TAG}-lite-android.aar
|
||||
mv out/gltfio-android-release.aar out/gltfio-${TAG}-android.aar
|
||||
mv out/gltfio-android-lite-release.aar out/gltfio-${TAG}-lite-android.aar
|
||||
mv out/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
|
||||
mv out/filament-utils-android-lite-release.aar out/filament-utils-${TAG}-lite-android.aar
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.aar out/*.apk
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
@@ -158,8 +154,7 @@ jobs:
|
||||
cd build/ios && printf "y" | ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
mv out/filament-release-ios.tgz out/filament-${TAG}-ios.tgz
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
|
||||
@@ -647,12 +647,14 @@ add_subdirectory(${LIBRARIES}/gltfio)
|
||||
add_subdirectory(${LIBRARIES}/ibl)
|
||||
add_subdirectory(${LIBRARIES}/iblprefilter)
|
||||
add_subdirectory(${LIBRARIES}/image)
|
||||
add_subdirectory(${LIBRARIES}/ktxreader)
|
||||
add_subdirectory(${LIBRARIES}/math)
|
||||
add_subdirectory(${LIBRARIES}/mathio)
|
||||
add_subdirectory(${LIBRARIES}/utils)
|
||||
add_subdirectory(${LIBRARIES}/viewer)
|
||||
add_subdirectory(${FILAMENT}/filament)
|
||||
add_subdirectory(${FILAMENT}/shaders)
|
||||
add_subdirectory(${EXTERNAL}/basisu/tnt)
|
||||
add_subdirectory(${EXTERNAL}/civetweb/tnt)
|
||||
add_subdirectory(${EXTERNAL}/hat-trie/tnt)
|
||||
add_subdirectory(${EXTERNAL}/imgui/tnt)
|
||||
@@ -705,8 +707,6 @@ if (IS_HOST_PLATFORM)
|
||||
|
||||
add_subdirectory(${FILAMENT}/samples)
|
||||
|
||||
add_subdirectory(${EXTERNAL}/astcenc/tnt)
|
||||
add_subdirectory(${EXTERNAL}/etc2comp)
|
||||
add_subdirectory(${EXTERNAL}/libassimp/tnt)
|
||||
add_subdirectory(${EXTERNAL}/libpng/tnt)
|
||||
add_subdirectory(${EXTERNAL}/libsdl2/tnt)
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.20.5'
|
||||
implementation 'com.google.android.filament:filament-android:1.22.0'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -43,7 +43,6 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite) | Trimmed version of `gltfio` that does not support some glTF extensions. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android) | KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android-lite) | Trimmed version of `filament-utils` that does not support some glTF features. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android) | A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite) | A much smaller alternative to `filamat-android` that can only generate OpenGL shaders. It does not provide validation or optimizations. |
|
||||
|
||||
@@ -52,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:
|
||||
|
||||
```
|
||||
pod 'Filament', '~> 1.20.5'
|
||||
pod 'Filament', '~> 1.22.0'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
@@ -169,11 +168,13 @@ steps:
|
||||
- [x] KHR_draco_mesh_compression
|
||||
- [x] KHR_lights_punctual
|
||||
- [x] KHR_materials_clearcoat
|
||||
- [x] KHR_materials_emissive_strength
|
||||
- [x] KHR_materials_ior
|
||||
- [x] KHR_materials_pbrSpecularGlossiness
|
||||
- [x] KHR_materials_sheen
|
||||
- [x] KHR_materials_transmission
|
||||
- [x] KHR_materials_unlit
|
||||
- [x] KHR_materials_variants
|
||||
- [x] KHR_materials_volume
|
||||
- [x] KHR_mesh_quantization
|
||||
- [x] KHR_texture_transform
|
||||
|
||||
@@ -3,7 +3,51 @@
|
||||
This file contains one line summaries of commits that are worthy of mentioning in release notes.
|
||||
A new header is inserted each time a *tag* is created.
|
||||
|
||||
## v1.20.6 (currently main branch)
|
||||
## v1.22.1 (currently main branch)
|
||||
|
||||
## v1.22.0
|
||||
|
||||
- engine: Changed UBOs layout [⚠️ **Material breakage**].
|
||||
- engine: Improve effects relying on mipmapping
|
||||
- engine: Fix assert seen with VSM shadows.
|
||||
- WebGL: Fix `isTextureFormatSupported` for ETC2 formats.
|
||||
|
||||
## v1.21.3
|
||||
|
||||
- Java: Renamed the `KTXLoader` Kotlin class to `KTX1Loader`. [⚠️ **API Change**].
|
||||
- libs: Added `Ktx2Reader` and `BasisEncoder` to support Basis-encoded KTX2 files.
|
||||
- engine: Remove deprecated `Stream` APIs, see `Texture::import()` for an alternative [⚠️ **API Change**].
|
||||
- tools: Removed KTX1 compression support from mipgen. [⚠️ **API Change**].
|
||||
- tools: Added support for KTX2 to mipgen.
|
||||
- gltfio: Added `resetBoneMatrices()` method.
|
||||
- gltfio: Introduced `TextureProvider` interface. [⚠️ **API Change**].
|
||||
- gltfio: Fix progress indicator when error occurs.
|
||||
- samples: Desktop and Web Suzanne samples now use KTX2 instead of KTX1.
|
||||
- samples: Fix regression with sample-gltf-viewer and zip files.
|
||||
|
||||
## v1.21.2
|
||||
|
||||
- Java: Add Java binding to get skins in `FilamentAsset`.
|
||||
- libs: Add libs/ktxreader [⚠️ **API Change**].
|
||||
- mipgen: fixups / clarification regarding sRGB.
|
||||
- WebGL: fix intermittent 'detached ArrayBuffer' errors.
|
||||
|
||||
## v1.21.1
|
||||
|
||||
- engine: Allow both screen-space refraction and screen-space reflections on the same object [⚠️ **Material breakage**].
|
||||
- engine: Optimizations for screen-space reflections.
|
||||
- engine: Remove `Viewport::scale()` [⚠️ **API Change**].
|
||||
- engine: Fix 12x overallocation of memory in `MorphTargetBuffer`.
|
||||
- Metal: Fix validation error when reading from default `SwapChain`.
|
||||
|
||||
## v1.21.0
|
||||
|
||||
- engine: OpenGL performance improvements with some drivers.
|
||||
- engine: Fix incorrect shadows with some custom projection matrices.
|
||||
- engine: Fix low frame rates seen with a lot of morph targets.
|
||||
- gltfio: Add support for KHR_materials_variants.
|
||||
- gltfio: Add support for KHR_materials_emissive_strength.
|
||||
- gltfio: Java now exposes morph target names as an array for consistency [⚠️ **API Change**].
|
||||
|
||||
## v1.20.5
|
||||
|
||||
@@ -429,7 +473,7 @@ devices.
|
||||
- engine: Fix RenderTarget NPE when depth is not present.
|
||||
- engine: Improvements to Camera APIs. Move focus distance from DofOptions to Camera.
|
||||
- engine: VSM shadows now support `shadowMultiplier`.
|
||||
- java: Expose severla MaterialInstance APIs (setColorWrite, setDepthWrite, setDepthCulling) that
|
||||
- java: Expose several MaterialInstance APIs (setColorWrite, setDepthWrite, setDepthCulling) that
|
||||
should have been public.
|
||||
- java: fix bug with Texture::setImage buffer size calculation.
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
// com.google.android.filament.exclude-vulkan
|
||||
// When set, support for Vulkan will be excluded.
|
||||
//
|
||||
// com.google.android.filament.matdbg
|
||||
// When set, enables matdbg, disables shader optimizations
|
||||
//
|
||||
// com.google.android.filament.skip-samples
|
||||
// Exclude samples from the project. Useful to speed up compilation.
|
||||
//
|
||||
@@ -59,6 +62,11 @@ buildscript {
|
||||
.forUseAtConfigurationTime()
|
||||
.isPresent()
|
||||
|
||||
def matdbg = providers
|
||||
.gradleProperty("com.google.android.filament.matdbg")
|
||||
.forUseAtConfigurationTime()
|
||||
.isPresent()
|
||||
|
||||
def abis = ["arm64-v8a", "armeabi-v7a", "x86_64", "x86"]
|
||||
def newAbis = providers
|
||||
.gradleProperty("com.google.android.filament.abis")
|
||||
@@ -102,7 +110,9 @@ buildscript {
|
||||
"-DANDROID_PLATFORM=21",
|
||||
"-DANDROID_STL=c++_static",
|
||||
"-DFILAMENT_DIST_DIR=${filamentPath}".toString(),
|
||||
"-DFILAMENT_SUPPORTS_VULKAN=${excludeVulkan ? 'OFF' : 'ON'}".toString()
|
||||
"-DFILAMENT_SUPPORTS_VULKAN=${excludeVulkan ? 'OFF' : 'ON'}".toString(),
|
||||
"-DFILAMENT_ENABLE_MATDBG=${matdbg ? 'ON' : 'OFF'}".toString(),
|
||||
"-DFILAMENT_DISABLE_MATOPT=${matdbg ? 'ON' : 'OFF'}".toString()
|
||||
]
|
||||
|
||||
ext.cppFlags = [
|
||||
|
||||
@@ -133,7 +133,7 @@ public class MaterialBuilder {
|
||||
FADE, // material is transparent and color is alpha-pre-multiplied,
|
||||
// affects specular lighting
|
||||
MULTIPLY, // material darkens what's behind it
|
||||
SCREN // material brightens what's behind it
|
||||
SCREEN // material brightens what's behind it
|
||||
}
|
||||
|
||||
public enum VertexDomain {
|
||||
|
||||
@@ -98,16 +98,6 @@ Java_com_google_android_filament_Stream_nBuilderStreamSource(JNIEnv* env,
|
||||
builder->setStreamSource(env, streamSource);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Stream_nBuilderStream(JNIEnv*, jclass,
|
||||
jlong nativeStreamBuilder, jlong externalTextureId) {
|
||||
StreamBuilder* builder = (StreamBuilder*) nativeStreamBuilder;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
builder->builder()->stream(externalTextureId);
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Stream_nBuilderWidth(JNIEnv*, jclass,
|
||||
jlong nativeStreamBuilder, jint width) {
|
||||
@@ -143,41 +133,6 @@ Java_com_google_android_filament_Stream_nSetDimensions(JNIEnv*, jclass, jlong na
|
||||
stream->setDimensions((uint32_t) width, (uint32_t) height);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Stream_nReadPixels(JNIEnv *env, jclass,
|
||||
jlong nativeStream, jlong nativeEngine,
|
||||
jint xoffset, jint yoffset, jint width, jint height,
|
||||
jobject storage, jint remaining,
|
||||
jint left, jint top, jint type, jint alignment, jint stride, jint format,
|
||||
jobject handler, jobject runnable) {
|
||||
Stream *stream = (Stream *) nativeStream;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
|
||||
stride = stride ? stride : width;
|
||||
size_t sizeInBytes = PixelBufferDescriptor::computeDataSize(
|
||||
(PixelDataFormat) format, (PixelDataType) type,
|
||||
(size_t) stride, (size_t) (height + top), (size_t) alignment);
|
||||
|
||||
AutoBuffer nioBuffer(env, storage, 0);
|
||||
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
|
||||
// BufferOverflowException
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *buffer = nioBuffer.getData();
|
||||
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
|
||||
PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride,
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
stream->readPixels(uint32_t(xoffset), uint32_t(yoffset), uint32_t(width), uint32_t(height),
|
||||
std::move(desc));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Stream_nGetTimestamp(JNIEnv*, jclass, jlong nativeStream) {
|
||||
Stream *stream = (Stream *) nativeStream;
|
||||
|
||||
@@ -531,6 +531,10 @@ public class Renderer {
|
||||
* Typically, this will happen after multiple calls to {@link #beginFrame},
|
||||
* {@link #render}, {@link #endFrame}.</p>
|
||||
* <br>
|
||||
* <p>OpenGL only: if issuing a <code>readPixels</code> on a {@link RenderTarget} backed by a
|
||||
* {@link Texture} that had data uploaded to it via {@link Texture#setImage}, the data returned
|
||||
* from <code>readPixels</code> will be y-flipped with respect to the {@link Texture#setImage}
|
||||
* call.</p>
|
||||
* <p><code>readPixels</code> is intended for debugging and testing.
|
||||
* It will impact performance significantly.</p>
|
||||
*
|
||||
|
||||
@@ -103,9 +103,6 @@ public class Stream {
|
||||
/** Not synchronized but copy-free. Good for video. */
|
||||
NATIVE,
|
||||
|
||||
/** Synchronized, but GL-only and incurs copies. Good for AR on devices before API 26. */
|
||||
TEXTURE_ID,
|
||||
|
||||
/** Synchronized, copy-free, and take a release callback. Good for AR but requires API 26+. */
|
||||
ACQUIRED,
|
||||
};
|
||||
@@ -121,7 +118,7 @@ public class Stream {
|
||||
* By default, Stream objects are {@link StreamType#ACQUIRED ACQUIRED} and must have external images pushed to them via
|
||||
* {@link #setAcquiredImage}.
|
||||
*
|
||||
* To create a {@link StreamType#NATIVE NATIVE} or {@link StreamType#TEXTURE_ID TEXTURE_ID} stream, call one of the <pre>stream</pre> methods
|
||||
* To create a {@link StreamType#NATIVE NATIVE} stream, call one of the <pre>stream</pre> methods
|
||||
* on the builder.
|
||||
*/
|
||||
public static class Builder {
|
||||
@@ -156,27 +153,6 @@ public class Stream {
|
||||
throw new IllegalArgumentException("Invalid stream source: " + streamSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link StreamType#TEXTURE_ID TEXTURE_ID} stream. A copy stream will sample data from the supplied
|
||||
* external texture and copy it into an internal private texture.
|
||||
*
|
||||
* <p>Currently only OpenGL external texture ids are supported.</p>
|
||||
*
|
||||
* @param externalTextureId An opaque texture id (typically a GLuint created with
|
||||
* <code>glGenTextures()</code>) in a context shared with
|
||||
* filament -- in that case this texture's target must be
|
||||
* <code>GL_TEXTURE_EXTERNAL_OES.</code>
|
||||
* @return This Builder, for chaining calls.
|
||||
* @see Texture#setExternalStream
|
||||
* @deprecated this method existed only for ARCore which doesn't need this anymore, use {@link Texture.Builder#importTexture(long)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public Builder stream(long externalTextureId) {
|
||||
nBuilderStream(mNativeBuilder, externalTextureId);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param width initial width of the incoming stream. Whether this value is used is
|
||||
* stream dependent. On Android, it must be set when using
|
||||
@@ -276,92 +252,6 @@ public class Stream {
|
||||
nSetDimensions(getNativeObject(), width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads back the content of the last frame of a <code>Stream</code> since the last call to
|
||||
* {@link Renderer#beginFrame}.
|
||||
*
|
||||
* <p>The Stream must be a copy stream, which can be checked with {@link #getStreamType()}.
|
||||
* This function is a no-op otherwise.</p>
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* Stream buffer User buffer (PixelBufferDescriptor)
|
||||
* +--------------------+
|
||||
* | | .stride .alignment
|
||||
* | | ----------------------->-->
|
||||
* | | O----------------------+--+ low addresses
|
||||
* | | | | | |
|
||||
* | w | | | .top | |
|
||||
* | <---------> | | V | |
|
||||
* | +---------+ | | +---------+ | |
|
||||
* | | ^ | | ======> | | | | |
|
||||
* | x | h| | | |.left| | | |
|
||||
* +------>| v | | +---->| | | |
|
||||
* | +.........+ | | +.........+ | |
|
||||
* | ^ | | | |
|
||||
* | y | | +----------------------+--+ high addresses
|
||||
* O------------+-------+
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* <p>Typically readPixels() will be called after {@link Renderer#beginFrame}.</p>
|
||||
*
|
||||
* <p>After calling this method, the callback associated with <code>buffer</code>
|
||||
* will be invoked on the main thread, indicating that the read-back has completed.
|
||||
* Typically, this will happen after multiple calls to {@link Renderer#beginFrame},
|
||||
* {@link Renderer#render}, {@link Renderer#endFrame}.</p>
|
||||
*
|
||||
* <p><code>readPixels</code> is intended for debugging and testing.
|
||||
* It will impact performance significantly.</p>
|
||||
*
|
||||
* @param xoffset left offset of the sub-region to read back
|
||||
* @param yoffset bottom offset of the sub-region to read back
|
||||
* @param width width of the sub-region to read back
|
||||
* @param height height of the sub-region to read back
|
||||
* @param buffer client-side buffer where the read-back will be written
|
||||
*
|
||||
* <p>
|
||||
* The following format are always supported:
|
||||
* <li>{@link Texture.Format#RGBA}</li>
|
||||
* <li>{@link Texture.Format#RGBA_INTEGER}</li>
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The following types are always supported:
|
||||
* <li>{@link Texture.Type#UBYTE}</li>
|
||||
* <li>{@link Texture.Type#UINT}</li>
|
||||
* <li>{@link Texture.Type#INT}</li>
|
||||
* <li>{@link Texture.Type#FLOAT}</li>
|
||||
* </p>
|
||||
*
|
||||
* <p>Other combination of format/type may be supported. If a combination is
|
||||
* not supported, this operation may fail silently. Use a DEBUG build
|
||||
* to get some logs about the failure.</p>
|
||||
*
|
||||
* @exception BufferOverflowException if the specified parameters would result in reading
|
||||
* outside of <code>buffer</code>.
|
||||
*/
|
||||
public void readPixels(
|
||||
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset,
|
||||
@IntRange(from = 0) int width, @IntRange(from = 0) int height,
|
||||
@NonNull Texture.PixelBufferDescriptor buffer) {
|
||||
|
||||
if (buffer.storage.isReadOnly()) {
|
||||
throw new ReadOnlyBufferException();
|
||||
}
|
||||
|
||||
int result = nReadPixels(getNativeObject(), mNativeEngine,
|
||||
xoffset, yoffset, width, height,
|
||||
buffer.storage, buffer.storage.remaining(),
|
||||
buffer.left, buffer.top, buffer.type.ordinal(), buffer.alignment,
|
||||
buffer.stride, buffer.format.ordinal(),
|
||||
buffer.handler, buffer.callback);
|
||||
|
||||
if (result < 0) {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the presentation time of the currently displayed frame in nanosecond.
|
||||
*
|
||||
@@ -387,7 +277,6 @@ public class Stream {
|
||||
private static native long nCreateBuilder();
|
||||
private static native void nDestroyBuilder(long nativeStreamBuilder);
|
||||
private static native void nBuilderStreamSource(long nativeStreamBuilder, Object streamSource);
|
||||
private static native void nBuilderStream(long nativeStreamBuilder, long externalTextureId);
|
||||
private static native void nBuilderWidth(long nativeStreamBuilder, int width);
|
||||
private static native void nBuilderHeight(long nativeStreamBuilder, int height);
|
||||
private static native long nBuilderBuild(long nativeStreamBuilder, long nativeEngine);
|
||||
|
||||
@@ -14,6 +14,10 @@ add_library(image STATIC IMPORTED)
|
||||
set_target_properties(image PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimage.a)
|
||||
|
||||
add_library(ktxreader STATIC IMPORTED)
|
||||
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
|
||||
|
||||
add_library(viewer STATIC IMPORTED)
|
||||
set_target_properties(viewer PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libviewer.a)
|
||||
@@ -64,5 +68,6 @@ target_link_libraries(filament-utils-jni
|
||||
camutils
|
||||
iblprefilter
|
||||
image
|
||||
ktxreader
|
||||
viewer
|
||||
)
|
||||
|
||||
@@ -1,30 +1,16 @@
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
flavorDimensions "functionality"
|
||||
productFlavors {
|
||||
full {
|
||||
dimension "functionality"
|
||||
}
|
||||
|
||||
lite {
|
||||
dimension "functionality"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
// hack: this is needed because filament-utils-android/CMakeLists.txt builds
|
||||
// gltfio from source, which needs this defined
|
||||
arguments.add("-DGLTFIO_LITE=ON")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
kotlin.srcDirs += "src/main/java"
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
missingDimensionStrategy 'functionality', 'full'
|
||||
}
|
||||
|
||||
// No need to package up the following shared libs, which arise as a side effect of our
|
||||
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle
|
||||
// dependencies, these shared libs already get pulled in, so we need to avoid the error:
|
||||
@@ -55,9 +41,7 @@ dependencies {
|
||||
implementation deps.coroutines.android
|
||||
|
||||
api project(':filament-android')
|
||||
|
||||
fullApi module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
|
||||
liteApi module("com.google.android.filament:gltfio-android-lite:${VERSION_NAME}")
|
||||
api module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
|
||||
}
|
||||
|
||||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
@@ -65,14 +49,9 @@ apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
afterEvaluate {
|
||||
publishing {
|
||||
publications {
|
||||
fullRelease(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID_FULL
|
||||
from components.fullRelease
|
||||
}
|
||||
|
||||
liteRelease(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID_LITE
|
||||
from components.liteRelease
|
||||
release(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID
|
||||
from components.release
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
POM_NAME=Filament Android Utilities
|
||||
POM_ARTIFACT_ID_FULL=filament-utils-android
|
||||
POM_ARTIFACT_ID_LITE=filament-utils-android-lite
|
||||
POM_ARTIFACT_ID=filament-utils-android
|
||||
POM_PACKAGING=aar
|
||||
|
||||
@@ -20,13 +20,14 @@
|
||||
#include <filament/IndirectLight.h>
|
||||
#include <filament/Skybox.h>
|
||||
|
||||
#include <image/KtxUtility.h>
|
||||
#include <ktxreader/Ktx1Reader.h>
|
||||
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace filament::math;
|
||||
using namespace image;
|
||||
using namespace ktxreader;
|
||||
|
||||
jlong nCreateHDRTexture(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jint internalFormat);
|
||||
@@ -35,9 +36,9 @@ static jlong nCreateKTXTexture(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
return (jlong) ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
||||
KtxBundle* bundle = (KtxBundle*) userdata;
|
||||
Ktx1Bundle* bundle = new Ktx1Bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
return (jlong) Ktx1Reader::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
||||
Ktx1Bundle* bundle = (Ktx1Bundle*) userdata;
|
||||
delete bundle;
|
||||
}, bundle);
|
||||
}
|
||||
@@ -46,9 +47,9 @@ static jlong nCreateIndirectLight(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
Texture* cubemap = ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
||||
KtxBundle* bundle = (KtxBundle*) userdata;
|
||||
Ktx1Bundle* bundle = new Ktx1Bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
Texture* cubemap = Ktx1Reader::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
||||
Ktx1Bundle* bundle = (Ktx1Bundle*) userdata;
|
||||
delete bundle;
|
||||
}, bundle);
|
||||
|
||||
@@ -68,9 +69,9 @@ static jlong nCreateSkybox(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
Texture* cubemap = ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
||||
KtxBundle* bundle = (KtxBundle*) userdata;
|
||||
Ktx1Bundle* bundle = new Ktx1Bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
Texture* cubemap = Ktx1Reader::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
||||
Ktx1Bundle* bundle = (Ktx1Bundle*) userdata;
|
||||
delete bundle;
|
||||
}, bundle);
|
||||
return (jlong) Skybox::Builder().environment(cubemap).showSun(true).build(*engine);
|
||||
@@ -79,7 +80,7 @@ static jlong nCreateSkybox(JNIEnv* env, jclass,
|
||||
static jboolean nGetSphericalHarmonics(JNIEnv* env, jclass, jobject javaBuffer, jint remaining,
|
||||
jfloatArray outSphericalHarmonics_) {
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
KtxBundle bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
Ktx1Bundle bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
|
||||
jfloat* outSphericalHarmonics = env->GetFloatArrayElements(outSphericalHarmonics_, nullptr);
|
||||
const auto success = bundle.getSphericalHarmonics(
|
||||
@@ -98,8 +99,8 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
|
||||
|
||||
int rc;
|
||||
|
||||
// KTXLoader
|
||||
jclass ktxloaderClass = env->FindClass("com/google/android/filament/utils/KTXLoader");
|
||||
// KTX1Loader
|
||||
jclass ktxloaderClass = env->FindClass("com/google/android/filament/utils/KTX1Loader");
|
||||
if (ktxloaderClass == nullptr) return JNI_ERR;
|
||||
static const JNINativeMethod ktxMethods[] = {
|
||||
{(char*)"nCreateKTXTexture", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateKTXTexture)},
|
||||
|
||||
@@ -40,7 +40,7 @@ import com.google.android.filament.Renderer;
|
||||
*
|
||||
* When executing a test, clients should call tick() after each frame is rendered, which provides an
|
||||
* opportunity to push settings to Filament, increment the current test index (if enough time has
|
||||
* elapsed), and request an asychronous screenshot.
|
||||
* elapsed), and request an asynchronous screenshot.
|
||||
*
|
||||
* The time to sleep between tests is configurable and can be set to zero. Automation also waits a
|
||||
* specified minimum number of frames between tests.
|
||||
|
||||
@@ -24,12 +24,12 @@ import com.google.android.filament.Texture
|
||||
import java.nio.Buffer
|
||||
|
||||
/**
|
||||
* Utilities for consuming KTX files and producing Filament textures, IBLs, and sky boxes.
|
||||
* Utilities for consuming KTX1 files and producing Filament textures, IBLs, and sky boxes.
|
||||
*
|
||||
* KTX is a simple container format that makes it easy to bundle miplevels and cubemap faces
|
||||
* into a single file.
|
||||
*/
|
||||
object KTXLoader {
|
||||
object KTX1Loader {
|
||||
class Options {
|
||||
var srgb = false
|
||||
}
|
||||
@@ -11,6 +11,18 @@ add_library(dracodec STATIC IMPORTED)
|
||||
set_target_properties(dracodec PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libdracodec.a)
|
||||
|
||||
add_library(ktxreader STATIC IMPORTED)
|
||||
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
|
||||
|
||||
add_library(stb STATIC IMPORTED)
|
||||
set_target_properties(stb PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libstb.a)
|
||||
|
||||
add_library(basis_transcoder STATIC IMPORTED)
|
||||
set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a)
|
||||
|
||||
add_library(utils STATIC IMPORTED)
|
||||
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
|
||||
@@ -32,6 +44,7 @@ set(GLTFIO_SRCS
|
||||
${GLTFIO_DIR}/include/gltfio/ResourceLoader.h
|
||||
${GLTFIO_DIR}/include/gltfio/FilamentAsset.h
|
||||
${GLTFIO_DIR}/include/gltfio/FilamentInstance.h
|
||||
${GLTFIO_DIR}/include/gltfio/TextureProvider.h
|
||||
${GLTFIO_DIR}/include/gltfio/math.h
|
||||
|
||||
${GLTFIO_DIR}/src/Animator.cpp
|
||||
@@ -47,13 +60,13 @@ set(GLTFIO_SRCS
|
||||
${GLTFIO_DIR}/src/GltfEnums.h
|
||||
${GLTFIO_DIR}/src/MaterialProvider.cpp
|
||||
${GLTFIO_DIR}/src/ResourceLoader.cpp
|
||||
${GLTFIO_DIR}/src/StbProvider.cpp
|
||||
${GLTFIO_DIR}/src/TangentsJob.h
|
||||
${GLTFIO_DIR}/src/TangentsJob.cpp
|
||||
${GLTFIO_DIR}/src/UbershaderLoader.cpp
|
||||
${GLTFIO_DIR}/src/Wireframe.cpp
|
||||
${GLTFIO_DIR}/src/Wireframe.h
|
||||
${GLTFIO_DIR}/src/upcast.h
|
||||
${GLTFIO_DIR}/src/Image.cpp
|
||||
|
||||
src/main/cpp/Animator.cpp
|
||||
src/main/cpp/AssetLoader.cpp
|
||||
@@ -81,6 +94,7 @@ set(GLTFIO_INCLUDE_DIRS
|
||||
../../third_party/hat-trie
|
||||
../../third_party/stb
|
||||
../../libs/utils/include
|
||||
../../libs/ktxreader/include
|
||||
)
|
||||
|
||||
add_library(gltfio-jni SHARED ${GLTFIO_SRCS})
|
||||
@@ -90,9 +104,9 @@ set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_
|
||||
|
||||
if(GLTFIO_LITE)
|
||||
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_LITE=1)
|
||||
target_link_libraries(gltfio-jni filament-jni utils log gltfio_resources_lite)
|
||||
target_link_libraries(gltfio-jni filament-jni utils log stb ktxreader basis_transcoder gltfio_resources_lite)
|
||||
else()
|
||||
target_link_libraries(gltfio-jni filament-jni utils log gltfio_resources)
|
||||
target_link_libraries(gltfio-jni filament-jni utils log stb ktxreader basis_transcoder gltfio_resources)
|
||||
|
||||
# Enable Draco in the non-lite variant of gltfio.
|
||||
target_link_libraries(gltfio-jni dracodec)
|
||||
|
||||
@@ -36,6 +36,12 @@ Java_com_google_android_filament_gltfio_Animator_nUpdateBoneMatrices(JNIEnv*, jc
|
||||
animator->updateBoneMatrices();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_Animator_nResetBoneMatrices(JNIEnv*, jclass, jlong nativeAnimator) {
|
||||
Animator* animator = (Animator*) nativeAnimator;
|
||||
animator->resetBoneMatrices();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_gltfio_Animator_nGetAnimationCount(JNIEnv*, jclass, jlong nativeAnimator) {
|
||||
Animator* animator = (Animator*) nativeAnimator;
|
||||
|
||||
@@ -201,6 +201,44 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetExtras(JNIEnv* env, jc
|
||||
return val ? env->NewStringUTF(val) : nullptr;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetSkinCount(JNIEnv* , jclass,
|
||||
jlong nativeAsset) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
return (jint) asset->getSkinCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetSkinNames(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jobjectArray result) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
jsize available = env->GetArrayLength(result);
|
||||
for (int i = 0; i < available; ++i) {
|
||||
const char* name = asset->getSkinNameAt(i);
|
||||
if (name) {
|
||||
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetJointCountAt(JNIEnv* , jclass,
|
||||
jlong nativeAsset, jint skinIndex) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
return (jint) asset->getJointCountAt(skinIndex);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetJointsAt(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint skinIndex, jintArray result) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
jsize available = env->GetArrayLength(result);
|
||||
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
|
||||
std::copy_n(asset->getJointsAt(skinIndex),
|
||||
std::min(available, (jsize) asset->getJointCountAt(skinIndex)), entities);
|
||||
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetAnimator(JNIEnv* , jclass,
|
||||
jlong nativeAsset) {
|
||||
@@ -215,15 +253,6 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetResourceUriCount(JNIEn
|
||||
return (jint) asset->getResourceUriCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jstring JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMorphTargetNameAt(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint entityId, jint targetIndex) {
|
||||
Entity entity = Entity::import(entityId);
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
const char* val = asset->getMorphTargetNameAt(entity, (size_t) targetIndex);
|
||||
return val ? env->NewStringUTF(val) : nullptr;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetResourceUris(JNIEnv* env, jclass,
|
||||
jlong nativeAsset,
|
||||
@@ -235,6 +264,49 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetResourceUris(JNIEnv* e
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMorphTargetCount(JNIEnv*, jclass,
|
||||
jlong nativeAsset, jint entityId) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
Entity entity = Entity::import(entityId);
|
||||
return (jint) asset->getMorphTargetCountAt(entity);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMorphTargetNames(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint entityId, jobjectArray result) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
Entity entity = Entity::import(entityId);
|
||||
for (int i = 0, n = asset->getMorphTargetCountAt(entity); i < n; ++i) {
|
||||
const char* name = asset->getMorphTargetNameAt(entity, i);
|
||||
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialVariantCount(JNIEnv*, jclass,
|
||||
jlong nativeAsset) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
return (jint) asset->getMaterialVariantCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialVariantNames(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jobjectArray result) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
for (int i = 0; i < asset->getMaterialVariantCount(); ++i) {
|
||||
const char* name = asset->getMaterialVariantName(i);
|
||||
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nApplyMaterialVariant(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint variantIndex) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
asset->applyMaterialVariant(variantIndex);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nReleaseSourceData(JNIEnv* env, jclass,
|
||||
jlong nativeAsset) {
|
||||
|
||||
@@ -54,3 +54,10 @@ Java_com_google_android_filament_gltfio_FilamentInstance_nGetAnimator(JNIEnv* ,
|
||||
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
|
||||
return (jlong) instance->getAnimator();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentInstance_nApplyMaterialVariant(JNIEnv* env, jclass,
|
||||
jlong nativeInstance, jint variantIndex) {
|
||||
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
|
||||
instance->applyMaterialVariant(variantIndex);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <filament/Engine.h>
|
||||
|
||||
#include <gltfio/ResourceLoader.h>
|
||||
#include <gltfio/TextureProvider.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
|
||||
@@ -114,3 +115,27 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nAsyncCancelLoad(JNIEnv*,
|
||||
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
|
||||
loader->asyncCancelLoad();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateTextureProvider(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) createStbProvider(engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nDestroyTextureProvider(JNIEnv*, jclass,
|
||||
jlong nativeProvider) {
|
||||
TextureProvider* provider = (TextureProvider*) nativeProvider;
|
||||
delete provider;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nAddTextureProvider(JNIEnv* env, jclass,
|
||||
jlong nativeLoader, jstring url, jlong nativeProvider) {
|
||||
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
|
||||
TextureProvider* provider = (TextureProvider*) nativeProvider;
|
||||
const char* cstring = env->GetStringUTFChars(url, nullptr);
|
||||
loader->addTextureProvider(cstring, provider);
|
||||
env->ReleaseStringUTFChars(url, cstring);
|
||||
}
|
||||
|
||||
@@ -66,6 +66,15 @@ public class Animator {
|
||||
nUpdateBoneMatrices(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass the identity matrix into all bone nodes, useful for returning to the T pose.
|
||||
*
|
||||
* <p>NOTE: this operation is independent of <code>animation</code>.</p>
|
||||
*/
|
||||
public void resetBoneMatrices() {
|
||||
nResetBoneMatrices(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of <code>animation</code> definitions in the glTF asset.
|
||||
*/
|
||||
@@ -109,6 +118,7 @@ public class Animator {
|
||||
|
||||
private static native void nApplyAnimation(long nativeAnimator, int index, float time);
|
||||
private static native void nUpdateBoneMatrices(long nativeAnimator);
|
||||
private static native void nResetBoneMatrices(long nativeAnimator);
|
||||
private static native int nGetAnimationCount(long nativeAnimator);
|
||||
private static native float nGetAnimationDuration(long nativeAnimator, int index);
|
||||
private static native String nGetAnimationName(long nativeAnimator, int index);
|
||||
|
||||
@@ -217,10 +217,44 @@ public class FilamentAsset {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the target name at target index in the given entity.
|
||||
* Gets the skin count of this asset.
|
||||
*/
|
||||
public String getMorphTargetNameAt(@Entity int entity, int targetIndex) {
|
||||
return nGetMorphTargetNameAt(getNativeObject(), entity, targetIndex);
|
||||
public int getSkinCount() {
|
||||
return nGetSkinCount(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the skin name at skin index in this asset.
|
||||
*/
|
||||
public @NonNull String[] getSkinNames() {
|
||||
String[] result = new String[getSkinCount()];
|
||||
nGetSkinNames(getNativeObject(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the joint count at skin index in this asset.
|
||||
*/
|
||||
public int getJointCountAt(int skinIndex) {
|
||||
return nGetJointCountAt(getNativeObject(), skinIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets joints at skin index in this asset.
|
||||
*/
|
||||
public @NonNull @Entity int[] getJointsAt(int skinIndex) {
|
||||
int[] result = new int[getJointCountAt(skinIndex)];
|
||||
nGetJointsAt(getNativeObject(), skinIndex, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of all morph targets in the given entity.
|
||||
*/
|
||||
public @NonNull String[] getMorphTargetNames(@Entity int entity) {
|
||||
String[] names = new String[nGetMorphTargetCount(mNativeObject, entity)];
|
||||
nGetMorphTargetNames(mNativeObject, entity, names);
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,6 +266,31 @@ public class FilamentAsset {
|
||||
return uris;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of all material variants.
|
||||
*/
|
||||
public @NonNull String[] getMaterialVariantNames() {
|
||||
String[] names = new String[nGetMaterialVariantCount(mNativeObject)];
|
||||
nGetMaterialVariantNames(mNativeObject, names);
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given material variant to all primitives that it affects.
|
||||
*
|
||||
* This is efficient because it merely swaps around persistent MaterialInstances. If you change
|
||||
* a material parameter while a certain variant is active, the updated value will be remembered
|
||||
* after you re-apply that variant.
|
||||
*
|
||||
* If the asset is instanced, this affects all instances in the same way.
|
||||
* To set the variant on an individual instance, use FilamentInstance#applyMaterialVariant.
|
||||
*
|
||||
* Ignored if variantIndex is out of bounds.
|
||||
*/
|
||||
public void applyMaterialVariant(@IntRange(from = 0) int variantIndex) {
|
||||
nApplyMaterialVariant(getNativeObject(), variantIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reclaims CPU-side memory for URI strings, binding lists, and raw animation data.
|
||||
*
|
||||
@@ -268,11 +327,21 @@ public class FilamentAsset {
|
||||
private static native int nGetMaterialInstanceCount(long nativeAsset);
|
||||
private static native void nGetMaterialInstances(long nativeAsset, long[] nativeResults);
|
||||
|
||||
private static native int nGetMaterialVariantCount(long nativeAsset);
|
||||
private static native void nGetMaterialVariantNames(long nativeAsset, String[] result);
|
||||
|
||||
private static native int nGetMorphTargetCount(long nativeAsset, int entity);
|
||||
private static native void nGetMorphTargetNames(long nativeAsset, int entity, String[] result);
|
||||
|
||||
private static native void nGetBoundingBox(long nativeAsset, float[] box);
|
||||
private static native String nGetName(long nativeAsset, int entity);
|
||||
private static native String nGetExtras(long nativeAsset, int entity);
|
||||
private static native long nGetAnimator(long nativeAsset);
|
||||
private static native String nGetMorphTargetNameAt(long nativeAsset, int entity, int targetIndex);
|
||||
private static native void nApplyMaterialVariant(long nativeAsset, int variantIndex);
|
||||
private static native int nGetSkinCount(long nativeAsset);
|
||||
private static native void nGetSkinNames(long nativeAsset, String[] result);
|
||||
private static native int nGetJointCountAt(long nativeAsset, int skinIndex);
|
||||
private static native void nGetJointsAt(long nativeAsset, int skinIndex, int[] result);
|
||||
private static native int nGetResourceUriCount(long nativeAsset);
|
||||
private static native void nGetResourceUris(long nativeAsset, String[] result);
|
||||
private static native void nReleaseSourceData(long nativeAsset);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.google.android.filament.gltfio;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.filament.Entity;
|
||||
@@ -84,8 +85,18 @@ public class FilamentInstance {
|
||||
return mAnimator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given material variant to all primitives in this instance.
|
||||
*
|
||||
* Ignored if variantIndex is out of bounds.
|
||||
*/
|
||||
void applyMaterialVariant(@IntRange(from = 0) int variantIndex) {
|
||||
nApplyMaterialVariant(mNativeObject, variantIndex);
|
||||
}
|
||||
|
||||
private static native int nGetRoot(long nativeAsset);
|
||||
private static native int nGetEntityCount(long nativeAsset);
|
||||
private static native void nGetEntities(long nativeAsset, int[] result);
|
||||
private static native long nGetAnimator(long nativeAsset);
|
||||
private static native void nApplyMaterialVariant(long nativeAsset, int variantIndex);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import java.nio.Buffer;
|
||||
*/
|
||||
public class ResourceLoader {
|
||||
private final long mNativeObject;
|
||||
private final long mNativeProvider;
|
||||
|
||||
/**
|
||||
* Constructs a resource loader tied to the given Filament engine.
|
||||
@@ -46,6 +47,9 @@ public class ResourceLoader {
|
||||
public ResourceLoader(@NonNull Engine engine) {
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
mNativeObject = nCreateResourceLoader(nativeEngine, false, false, false);
|
||||
mNativeProvider = nCreateTextureProvider(nativeEngine);
|
||||
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeProvider);
|
||||
nAddTextureProvider(mNativeObject, "image/png", mNativeProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,6 +67,9 @@ public class ResourceLoader {
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights,
|
||||
recomputeBoundingBoxes, ignoreBindTransform);
|
||||
mNativeProvider = nCreateTextureProvider(nativeEngine);
|
||||
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeProvider);
|
||||
nAddTextureProvider(mNativeObject, "image/png", mNativeProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,6 +77,7 @@ public class ResourceLoader {
|
||||
*/
|
||||
public void destroy() {
|
||||
nDestroyResourceLoader(mNativeObject);
|
||||
nDestroyTextureProvider(mNativeProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,4 +186,8 @@ public class ResourceLoader {
|
||||
private static native float nAsyncGetLoadProgress(long nativeLoader);
|
||||
private static native void nAsyncUpdateLoad(long nativeLoader);
|
||||
private static native void nAsyncCancelLoad(long nativeLoader);
|
||||
|
||||
private static native long nCreateTextureProvider(long nativeEngine);
|
||||
private static native void nAddTextureProvider(long nativeLoader, String url, long nativeProvider);
|
||||
private static native void nDestroyTextureProvider(long nativeProvider);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.20.5
|
||||
VERSION_NAME=1.22.0
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
@@ -150,12 +150,12 @@ class MainActivity : Activity() {
|
||||
val scene = modelViewer.scene
|
||||
val ibl = "default_env"
|
||||
readCompressedAsset("envs/$ibl/${ibl}_ibl.ktx").let {
|
||||
scene.indirectLight = KTXLoader.createIndirectLight(engine, it)
|
||||
scene.indirectLight = KTX1Loader.createIndirectLight(engine, it)
|
||||
scene.indirectLight!!.intensity = 30_000.0f
|
||||
viewerContent.indirectLight = modelViewer.scene.indirectLight
|
||||
}
|
||||
readCompressedAsset("envs/$ibl/${ibl}_skybox.ktx").let {
|
||||
scene.skybox = KTXLoader.createSkybox(engine, it)
|
||||
scene.skybox = KTX1Loader.createSkybox(engine, it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,9 +297,10 @@ class MainActivity : Activity() {
|
||||
|
||||
val gltfBuffer = pathToBufferMapping[gltfPath]!!
|
||||
|
||||
// The gltf is often not at the root level (e.g. if a folder is zipped) so
|
||||
// we need to extract its path in order to resolve the embedded uri strings.
|
||||
var prefix = URI(gltfPath!!).resolve("..")
|
||||
// In a zip file, the gltf file might be in the same folder as resources, or in a different
|
||||
// folder. It is crucial to test against both of these cases. In any case, the resource
|
||||
// paths are all specified relative to the location of the gltf file.
|
||||
var prefix = URI(gltfPath!!).resolve(".")
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
if (gltfPath!!.endsWith(".glb")) {
|
||||
@@ -308,7 +309,7 @@ class MainActivity : Activity() {
|
||||
modelViewer.loadModelGltf(gltfBuffer) { uri ->
|
||||
val path = prefix.resolve(uri).toString()
|
||||
if (!pathToBufferMapping.contains(path)) {
|
||||
Log.e(TAG, "Could not find '$uri' in zip using prefix '$prefix'")
|
||||
Log.e(TAG, "Could not find '$uri' in zip using prefix '$prefix' and base path '${gltfPath!!}'")
|
||||
setStatusText("Zip is missing $path")
|
||||
}
|
||||
pathToBufferMapping[path]
|
||||
|
||||
@@ -79,8 +79,6 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
// Performs the rendering and schedules new frames
|
||||
private val frameScheduler = FrameCallback()
|
||||
|
||||
private var externalTextureID: Int = 0
|
||||
|
||||
@RequiresApi(30)
|
||||
class Api30Impl {
|
||||
companion object {
|
||||
@@ -103,8 +101,6 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
setupView()
|
||||
setupScene()
|
||||
|
||||
externalTextureID = createExternalTexture()
|
||||
|
||||
@Suppress("deprecation")
|
||||
val display = if (Build.VERSION.SDK_INT >= 30) {
|
||||
Api30Impl.getDisplay(this)
|
||||
@@ -112,7 +108,7 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
windowManager.defaultDisplay!!
|
||||
}
|
||||
|
||||
streamHelper = StreamHelper(engine, materialInstance, display, externalTextureID)
|
||||
streamHelper = StreamHelper(engine, materialInstance, display)
|
||||
this.title = streamHelper.getTestName()
|
||||
}
|
||||
|
||||
@@ -445,31 +441,4 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
check(EGL14.eglMakeCurrent(display, surface, surface, context)) { "Error making GL context." }
|
||||
return context
|
||||
}
|
||||
|
||||
private fun createExternalTexture(): Int {
|
||||
val textures = IntArray(1)
|
||||
GLES30.glGenTextures(1, textures, 0)
|
||||
val result = textures[0]
|
||||
|
||||
val textureTarget = GLES11Ext.GL_TEXTURE_EXTERNAL_OES
|
||||
GLES30.glBindTexture(textureTarget, result)
|
||||
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE)
|
||||
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE)
|
||||
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST)
|
||||
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST)
|
||||
|
||||
if (!GLES30.glIsTexture(result)) {
|
||||
throw RuntimeException("OpenGL error: $result is an invalid texture.")
|
||||
}
|
||||
|
||||
val error = GLES30.glGetError()
|
||||
if (error != GLES30.GL_NO_ERROR) {
|
||||
val errorString = GLU.gluErrorString(error)
|
||||
throw RuntimeException("OpenGL error: $errorString!")
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ class StreamHelper(
|
||||
private val filamentEngine: Engine,
|
||||
private val filamentMaterial: MaterialInstance,
|
||||
private val display: Display,
|
||||
private val externalTextureId: Int
|
||||
) {
|
||||
/**
|
||||
* The StreamSource configures the source data for the texture.
|
||||
@@ -51,7 +50,6 @@ class StreamHelper(
|
||||
*/
|
||||
enum class StreamSource {
|
||||
CANVAS_STREAM_NATIVE, // copy-free but does not guarantee synchronization
|
||||
CANVAS_STREAM_TEXID, // synchronized but incurs a copy
|
||||
CANVAS_STREAM_ACQUIRED, // synchronized and copy-free
|
||||
}
|
||||
|
||||
@@ -127,10 +125,6 @@ class StreamHelper(
|
||||
|
||||
surface.unlockCanvasAndPost(canvas)
|
||||
|
||||
if (streamSource == StreamSource.CANVAS_STREAM_TEXID) {
|
||||
surfaceTexture!!.updateTexImage()
|
||||
}
|
||||
|
||||
if (streamSource == StreamSource.CANVAS_STREAM_ACQUIRED) {
|
||||
val image = imageReader!!.acquireLatestImage()
|
||||
filamentStream!!.setAcquiredImage(
|
||||
@@ -146,7 +140,7 @@ class StreamHelper(
|
||||
|
||||
fun nextTest() {
|
||||
stopTest()
|
||||
streamSource = StreamSource.values()[(streamSource.ordinal + 1) % 3]
|
||||
streamSource = StreamSource.values()[(streamSource.ordinal + 1) % StreamSource.values().size]
|
||||
startTest()
|
||||
}
|
||||
|
||||
@@ -213,23 +207,6 @@ class StreamHelper(
|
||||
filamentTexture.setExternalStream(filamentEngine, filamentStream!!)
|
||||
}
|
||||
|
||||
if (streamSource == StreamSource.CANVAS_STREAM_TEXID) {
|
||||
|
||||
// Create the Android surface that will hold the canvas image.
|
||||
surfaceTexture = SurfaceTexture(externalTextureId)
|
||||
surfaceTexture!!.setDefaultBufferSize(resolution.width, resolution.height)
|
||||
canvasSurface = Surface(surfaceTexture)
|
||||
|
||||
// Create the Filament Stream object that gets bound to the Texture.
|
||||
filamentStream = Stream.Builder()
|
||||
.stream(externalTextureId.toLong())
|
||||
.width(resolution.width)
|
||||
.height(resolution.height)
|
||||
.build(filamentEngine)
|
||||
|
||||
filamentTexture.setExternalStream(filamentEngine, filamentStream!!)
|
||||
}
|
||||
|
||||
if (streamSource == StreamSource.CANVAS_STREAM_ACQUIRED) {
|
||||
filamentStream = Stream.Builder()
|
||||
.width(resolution.width)
|
||||
|
||||
BIN
art/diagrams/ImageUploadReadPixels.png
Normal file
BIN
art/diagrams/ImageUploadReadPixels.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
BIN
art/diagrams/NDC.png
Normal file
BIN
art/diagrams/NDC.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
BIN
art/diagrams/RenderingReadPixels.png
Normal file
BIN
art/diagrams/RenderingReadPixels.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
22
build.sh
22
build.sh
@@ -98,9 +98,9 @@ function print_matdbg_help {
|
||||
echo ""
|
||||
echo "FOR ANDROID BUILDS:"
|
||||
echo ""
|
||||
echo "1) The most reliable way to enable matdbg is to bypass Gradle and"
|
||||
echo " directly modify the appropriate two lines in the following file:"
|
||||
echo " ./android/filament-android/CMakeLists.txt"
|
||||
echo "1) For Android Studio builds, make sure to set:"
|
||||
echo " -Pcom.google.android.filament.matdbg"
|
||||
echo " option in Preferences > Build > Compiler > Command line options."
|
||||
echo ""
|
||||
echo "2) The port number is hardcoded to 8081 so you will need to do:"
|
||||
echo " adb forward tcp:8081 tcp:8081"
|
||||
@@ -156,6 +156,7 @@ VULKAN_ANDROID_GRADLE_OPTION=""
|
||||
SWIFTSHADER_OPTION="-DFILAMENT_USE_SWIFTSHADER=OFF"
|
||||
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF"
|
||||
MATDBG_GRADLE_OPTION=""
|
||||
|
||||
IOS_BUILD_SIMULATOR=false
|
||||
BUILD_UNIVERSAL_LIBRARIES=false
|
||||
@@ -303,7 +304,7 @@ function build_webgl_with_target {
|
||||
}
|
||||
|
||||
function build_webgl {
|
||||
# For the host tools, supress install and always use Release.
|
||||
# For the host tools, suppress install and always use Release.
|
||||
local old_install_command=${INSTALL_COMMAND}; INSTALL_COMMAND=
|
||||
local old_issue_debug_build=${ISSUE_DEBUG_BUILD}; ISSUE_DEBUG_BUILD=false
|
||||
local old_issue_release_build=${ISSUE_RELEASE_BUILD}; ISSUE_RELEASE_BUILD=true
|
||||
@@ -402,7 +403,7 @@ function ensure_android_build {
|
||||
function build_android {
|
||||
ensure_android_build
|
||||
|
||||
# Supress intermediate desktop tools install
|
||||
# Suppress intermediate desktop tools install
|
||||
local old_install_command=${INSTALL_COMMAND}
|
||||
INSTALL_COMMAND=
|
||||
|
||||
@@ -456,6 +457,7 @@ function build_android {
|
||||
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
|
||||
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
|
||||
${VULKAN_ANDROID_GRADLE_OPTION} \
|
||||
${MATDBG_GRADLE_OPTION} \
|
||||
:filament-android:assembleDebug \
|
||||
:gltfio-android:assembleDebug \
|
||||
:filament-utils-android:assembleDebug
|
||||
@@ -487,8 +489,7 @@ function build_android {
|
||||
cp gltfio-android/build/outputs/aar/gltfio-android-full-debug.aar ../out/gltfio-android-debug.aar
|
||||
|
||||
echo "Installing out/filament-utils-android-debug.aar..."
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-lite-debug.aar ../out/
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-full-debug.aar ../out/filament-utils-android-debug.aar
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-debug.aar ../out/filament-utils-android-debug.aar
|
||||
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
for sample in ${ANDROID_SAMPLES}; do
|
||||
@@ -505,6 +506,7 @@ function build_android {
|
||||
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
|
||||
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
|
||||
${VULKAN_ANDROID_GRADLE_OPTION} \
|
||||
${MATDBG_GRADLE_OPTION} \
|
||||
:filament-android:assembleRelease \
|
||||
:gltfio-android:assembleRelease \
|
||||
:filament-utils-android:assembleRelease
|
||||
@@ -536,8 +538,7 @@ function build_android {
|
||||
cp gltfio-android/build/outputs/aar/gltfio-android-full-release.aar ../out/gltfio-android-release.aar
|
||||
|
||||
echo "Installing out/filament-utils-android-release.aar..."
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-lite-release.aar ../out/
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-full-release.aar ../out/filament-utils-android-release.aar
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-release.aar ../out/filament-utils-android-release.aar
|
||||
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
for sample in ${ANDROID_SAMPLES}; do
|
||||
@@ -600,7 +601,7 @@ function archive_ios {
|
||||
}
|
||||
|
||||
function build_ios {
|
||||
# Supress intermediate desktop tools install
|
||||
# Suppress intermediate desktop tools install
|
||||
local old_install_command=${INSTALL_COMMAND}
|
||||
INSTALL_COMMAND=
|
||||
|
||||
@@ -756,6 +757,7 @@ while getopts ":hacCfijmp:q:uvslwtdk:" opt; do
|
||||
d)
|
||||
PRINT_MATDBG_HELP=true
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON, -DFILAMENT_BUILD_FILAMAT=ON"
|
||||
MATDBG_GRADLE_OPTION="-Pcom.google.android.filament.matdbg"
|
||||
;;
|
||||
f)
|
||||
ISSUE_CMAKE_ALWAYS=true
|
||||
|
||||
14
build/common/requirements.txt
Normal file
14
build/common/requirements.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
setuptools==40.6.2
|
||||
wheel==0.37.1
|
||||
certifi==2021.10.8
|
||||
cffi==1.15.0
|
||||
charset-normalizer==2.0.12
|
||||
Deprecated==1.2.13
|
||||
idna==3.3
|
||||
pycparser==2.21
|
||||
PyGithub==1.55
|
||||
PyJWT==2.3.0
|
||||
PyNaCl==1.5.0
|
||||
requests==2.27.1
|
||||
urllib3==1.26.9
|
||||
wrapt==1.14.0
|
||||
@@ -11,3 +11,4 @@ tools/cmgen/test_cmgen compare
|
||||
tools/glslminifier/test_glslminifier
|
||||
libs/filameshio/test_filameshio
|
||||
libs/camutils/test_camutils
|
||||
libs/ktxreader/test_ktxreader
|
||||
|
||||
@@ -12,6 +12,25 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
# requirements.txt created via:
|
||||
#
|
||||
# pip3 install virtualenv
|
||||
# python3 -m venv env
|
||||
# pip3 install PyGithub
|
||||
# pip3 install wheel
|
||||
# --all includes wheel and setuputils, which is needed for GitHub Actions
|
||||
# pip3 freeze --all > requirements.txt
|
||||
# Manually move 'setuptools' and 'wheel' lines to the beginning of the file.
|
||||
# Manually remove the 'pip' line.
|
||||
#
|
||||
# Requirements are installed in GitHub Actions via:
|
||||
# xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
# xargs must be used because the ordering of the dependencies matters (namely, setuptools).
|
||||
# sudo must be used to uninstall non-matching versions of packages.
|
||||
# pip is removed to avoid conflicts with the pre-installed pip version on Actions.
|
||||
# This technique does not work with Windows, unfortunately.
|
||||
|
||||
from github import Github
|
||||
import os, sys
|
||||
|
||||
|
||||
@@ -2169,7 +2169,7 @@ type aliases:
|
||||
|
||||
Name | Type | Description
|
||||
:-----------------------------------|:--------:|:------------------------------------
|
||||
**getResolution()** | float4 | Resolution of the view in pixels: `width`, `height`, `1 / width`, `1 / height`
|
||||
**getResolution()** | float4 | Dimensions of the view's effective viewport in pixels: `width`, `height`, `1 / width`, `1 / height`. This might be different from `View::getViewport()` for instance because of added rendering guard-bands. This can be used in conjunction with `getNormalizedViewportCoord()` to generate pixel coordinates.
|
||||
**getWorldCameraPosition()** | float3 | Position of the camera/eye in world space
|
||||
**getWorldOffset()** | float3 | The shift required to obtain API-level world space
|
||||
**getTime()** | float | Current time as a remainder of 1 second. Yields a value between 0 and 1
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<canvas></canvas>
|
||||
<script src="//unpkg.com/filament@1.15.0/filament.js"></script>
|
||||
<script src="filament.js"></script>
|
||||
<script src="//unpkg.com/gl-matrix@2.8.1"></script>
|
||||
<script src="//unpkg.com/gltumble"></script>
|
||||
<script src="tutorial_redball.js"></script>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<canvas></canvas>
|
||||
<script src="//unpkg.com/filament@1.15.0/filament.js"></script>
|
||||
<script src="filament.js"></script>
|
||||
<script src="//unpkg.com/gl-matrix@2.8.1"></script>
|
||||
<script src="//unpkg.com/gltumble"></script>
|
||||
<script src="tutorial_suzanne.js"></script>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<canvas></canvas>
|
||||
<script src="//unpkg.com/filament@1.15.0/filament.js"></script>
|
||||
<script src="filament.js"></script>
|
||||
<script src="//unpkg.com/gl-matrix@2.8.1"></script>
|
||||
<script src="//unpkg.com/gltumble"></script>
|
||||
<script src="tutorial_triangle.js"></script>
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -113,7 +113,7 @@ class App {
|
||||
this.view = engine.createView();
|
||||
this.view.setVignetteOptions({ midPoint: 0.8, enabled: true });
|
||||
|
||||
this.view.setBloomOptions({ stength: 0.2, enabled: true });
|
||||
this.view.setBloomOptions({ strength: 0.2, enabled: true });
|
||||
|
||||
this.view.setCamera(this.camera);
|
||||
this.view.setScene(this.scene);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -64,7 +64,7 @@
|
||||
<td align="left">Array of 16-bit or 32-bit unsigned integers consumed by the GPU.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#KtxBundle">KtxBundle</a></td>
|
||||
<td align="left"><a href="#Ktx1Bundle">Ktx1Bundle</a></td>
|
||||
<td align="left">In-memory representation of a KTX file.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -583,6 +583,11 @@
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: enabled, sampleCount, customResolve.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setScreenSpaceReflectionsOptions(overrides)</strong>
|
||||
<ul>
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: thickness, bias, maxDistance, stride, enabled.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setShadowOptions(instance, overrides)</strong>
|
||||
<ul>
|
||||
<li><em>instance</em> Instance of a light component obtained from <code>getInstance</code>.</li>
|
||||
@@ -662,63 +667,63 @@ as quaternions.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='classdoc'>
|
||||
<h2>class <a id='KtxBundle' href='#KtxBundle'>KtxBundle</a></h2>
|
||||
<h2>class <a id='Ktx1Bundle' href='#Ktx1Bundle'>Ktx1Bundle</a></h2>
|
||||
<p>In-memory representation of a KTX file.</p>
|
||||
<ul>
|
||||
<li><strong>ktxBundle.getArrayLength()</strong>
|
||||
<li><strong>ktx1Bundle.getArrayLength()</strong>
|
||||
<ul>
|
||||
<li>Obtains length of the texture array.</li>
|
||||
<li><em>returns</em> The number of elements in the texture array</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.getCompressedPixelDataType()</strong>
|
||||
<li><strong>ktx1Bundle.getCompressedPixelDataType()</strong>
|
||||
<ul>
|
||||
<li><em>returns</em> <a href="#CompressedPixelDataType">CompressedPixelDataType</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.getInternalFormat(srgb)</strong>
|
||||
<li><strong>ktx1Bundle.getInternalFormat(srgb)</strong>
|
||||
<ul>
|
||||
<li><em>srgb</em> boolean that forces the resulting format to SRGB if possible.</li>
|
||||
<li><em>returns</em> <a href="#Texture%24InternalFormat">Texture$InternalFormat</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.getMetadata(key)</strong>
|
||||
<li><strong>ktx1Bundle.getMetadata(key)</strong>
|
||||
<ul>
|
||||
<li>Obtains arbitrary metadata from the KTX file.</li>
|
||||
<li><em>key</em> string</li>
|
||||
<li><em>returns</em> string</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.getPixelDataFormat()</strong>
|
||||
<li><strong>ktx1Bundle.getPixelDataFormat()</strong>
|
||||
<ul>
|
||||
<li><em>returns</em> <a href="#PixelDataFormat">PixelDataFormat</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.getPixelDataType()</strong>
|
||||
<li><strong>ktx1Bundle.getPixelDataType()</strong>
|
||||
<ul>
|
||||
<li><em>returns</em> <a href="#PixelDataType">PixelDataType</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.info()</strong>
|
||||
<li><strong>ktx1Bundle.info()</strong>
|
||||
<ul>
|
||||
<li>Obtains properties of the KTX header.</li>
|
||||
<li><em>returns</em> The <a href="#KtxInfo">KtxInfo</a> property accessor object.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.info()</strong>
|
||||
<li><strong>ktx1Bundle.info()</strong>
|
||||
<ul>
|
||||
<li>Obtains properties of the KTX header.</li>
|
||||
<li><em>returns</em> The <a href="#KtxInfo">KtxInfo</a> property accessor object.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.isCompressed()</strong>
|
||||
<li><strong>ktx1Bundle.isCompressed()</strong>
|
||||
<ul>
|
||||
<li><em>returns</em> boolean</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Most clients should use one of the <code>create*FromKtx</code> utility methods in the JavaScript <a href="#Engine">Engine</a>
|
||||
wrapper rather than interacting with <code>KtxBundle</code> directly.</p>
|
||||
wrapper rather than interacting with <code>Ktx1Bundle</code> directly.</p>
|
||||
</div>
|
||||
<div class='classdoc'>
|
||||
<h2>class <a id='KtxInfo' href='#KtxInfo'>KtxInfo</a></h2>
|
||||
@@ -743,7 +748,7 @@ wrapper rather than interacting with <code>KtxBundle</code> directly.</p>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>For example, <code>ktxbundle.info().pixelWidth</code>. See the
|
||||
<p>For example, <code>Ktx1Bundle.info().pixelWidth</code>. See the
|
||||
<a href="https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/">KTX spec</a> for the list of
|
||||
properties.</p>
|
||||
</div>
|
||||
@@ -1267,7 +1272,9 @@ This defines the following functions:</p>
|
||||
<ul>
|
||||
<li>POINTS</li>
|
||||
<li>LINES</li>
|
||||
<li>LINE_STRIP</li>
|
||||
<li>TRIANGLES</li>
|
||||
<li>TRIANGLE_STRIP</li>
|
||||
<li>NONE</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -12,7 +12,9 @@ textures.</p>
|
||||
<a href="tutorial_triangle.html">previous tutorial</a>. Change the last script tag from <code>triangle.js</code> to <code>redball.js</code>.</p>
|
||||
<p>Next you'll need to get a couple command-line tools: <code>matc</code> and <code>cmgen</code>. You can find these in the
|
||||
appropriate <a href="//github.com/google/filament/releases">Filament release</a>. You should choose the
|
||||
archive that corresponds to your development machine rather than the one for web.</p>
|
||||
archive that corresponds to your development machine rather than the one for web, and the version
|
||||
that matches the <code>unpkg.com/filament@x.x.x</code> url in the script tag of <code>redball.html</code> (you may check
|
||||
out the last available release of <a href="https://www.npmjs.com/package/filament">filament on npm</a>).</p>
|
||||
<h2>Define plastic material</h2>
|
||||
<p>The <code>matc</code> tool consumes a text file containing a high-level description of a PBR material, and
|
||||
produces a binary material package that contains shader code and associated metadata. For more
|
||||
@@ -60,12 +62,12 @@ IBL KTX contains these coefficients in its metadata.</p>
|
||||
<h2>Create JavaScript</h2>
|
||||
<p>Next, create <code>redball.js</code> with the following content.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> environ <span style="color: #666666">=</span> <span style="color: #BA2121">'pillars_2k'</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> filamat_url <span style="color: #666666">=</span> <span style="color: #BA2121">'plastic.filamat'</span>
|
||||
|
||||
Filament.init([ filamat_url, ibl_url, sky_url ], () => {
|
||||
<span style="color: #408080; font-style: italic">// Create some global aliases to enums for convenience.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Create some global aliases to enums for convenience.</span>
|
||||
<span style="color: #008000">window</span>.VertexAttribute <span style="color: #666666">=</span> Filament.VertexAttribute;
|
||||
<span style="color: #008000">window</span>.AttributeType <span style="color: #666666">=</span> Filament.VertexBuffer$AttributeType;
|
||||
<span style="color: #008000">window</span>.PrimitiveType <span style="color: #666666">=</span> Filament.RenderableManager$PrimitiveType;
|
||||
@@ -73,7 +75,7 @@ Filament.init([ filamat_url, ibl_url, sky_url ], () => {
|
||||
<span style="color: #008000">window</span>.Fov <span style="color: #666666">=</span> Filament.Camera$Fov;
|
||||
<span style="color: #008000">window</span>.LightType <span style="color: #666666">=</span> Filament.LightManager$Type;
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Obtain the canvas DOM object and pass it to the App.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Obtain the canvas DOM object and pass it to the App.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> canvas <span style="color: #666666">=</span> <span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">'canvas'</span>)[<span style="color: #666666">0</span>];
|
||||
<span style="color: #008000">window</span>.app <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> App(canvas);
|
||||
} );
|
||||
@@ -84,11 +86,11 @@ Filament.init([ filamat_url, ibl_url, sky_url ], () => {
|
||||
<span style="color: #008000; font-weight: bold">const</span> engine <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine <span style="color: #666666">=</span> Filament.Engine.create(canvas);
|
||||
<span style="color: #008000; font-weight: bold">const</span> scene <span style="color: #666666">=</span> engine.createScene();
|
||||
|
||||
<span style="color: #408080; font-style: italic">// TODO: create material</span>
|
||||
<span style="color: #408080; font-style: italic">// TODO: create sphere</span>
|
||||
<span style="color: #408080; font-style: italic">// TODO: create lights</span>
|
||||
<span style="color: #408080; font-style: italic">// TODO: create IBL</span>
|
||||
<span style="color: #408080; font-style: italic">// TODO: create skybox</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create material</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create sphere</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create lights</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create IBL</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create skybox</span>
|
||||
|
||||
<span style="color: #008000; font-weight: bold">this</span>.swapChain <span style="color: #666666">=</span> engine.createSwapChain();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer <span style="color: #666666">=</span> engine.createRenderer();
|
||||
@@ -209,9 +211,9 @@ following (don't type this out, there's an easier way).</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> format <span style="color: #666666">=</span> Filament.PixelDataFormat.RGB;
|
||||
<span style="color: #008000; font-weight: bold">const</span> datatype <span style="color: #666666">=</span> Filament.PixelDataType.UINT_10F_11F_11F_REV;
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Create a Texture object for the mipmapped cubemap.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Create a Texture object for the mipmapped cubemap.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_package <span style="color: #666666">=</span> Filament.Buffer(Filament.assets[ibl_url]);
|
||||
<span style="color: #008000; font-weight: bold">const</span> iblktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.KtxBundle(ibl_package);
|
||||
<span style="color: #008000; font-weight: bold">const</span> iblktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.Ktx1Bundle(ibl_package);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibltex <span style="color: #666666">=</span> Filament.Texture.Builder()
|
||||
.width(iblktx.info().pixelWidth)
|
||||
@@ -227,11 +229,11 @@ following (don't type this out, there's an easier way).</p>
|
||||
ibltex.setImageCube(engine, level, pixelbuffer);
|
||||
}
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Parse the spherical harmonics metadata.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Parse the spherical harmonics metadata.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> shstring <span style="color: #666666">=</span> iblktx.getMetadata(<span style="color: #BA2121">'sh'</span>);
|
||||
<span style="color: #008000; font-weight: bold">const</span> shfloats <span style="color: #666666">=</span> shstring.split(<span style="color: #BB6688">/\s/</span>, <span style="color: #666666">9</span> <span style="color: #666666">*</span> <span style="color: #666666">3</span>).map(<span style="color: #008000">parseFloat</span>);
|
||||
<span style="color: #008000; font-weight: bold">const</span> shfloats <span style="color: #666666">=</span> shstring.split(<span style="color: #A45A77">/\s/</span>, <span style="color: #666666">9</span> <span style="color: #666666">*</span> <span style="color: #666666">3</span>).map(<span style="color: #008000">parseFloat</span>);
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Build the IBL object and insert it into the scene.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Build the IBL object and insert it into the scene.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> indirectLight <span style="color: #666666">=</span> Filament.IndirectLight.Builder()
|
||||
.reflections(ibltex)
|
||||
.irradianceSh(<span style="color: #666666">3</span>, shfloats)
|
||||
@@ -253,7 +255,7 @@ scene.setIndirectLight(indirectLight);
|
||||
Without a skybox, the reflections on the ball are not representative of its surroundings.
|
||||
Here's one way to create a texture for the skybox:</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> sky_package <span style="color: #666666">=</span> Filament.Buffer(Filament.assets[sky_url]);
|
||||
<span style="color: #008000; font-weight: bold">const</span> skyktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.KtxBundle(sky_package);
|
||||
<span style="color: #008000; font-weight: bold">const</span> skyktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.Ktx1Bundle(sky_package);
|
||||
<span style="color: #008000; font-weight: bold">const</span> skytex <span style="color: #666666">=</span> Filament.Texture.Builder()
|
||||
.width(skyktx.info().pixelWidth)
|
||||
.height(skyktx.info().pixelHeight)
|
||||
|
||||
@@ -22,25 +22,25 @@ converting <a href="https://github.com/google/filament/blob/main/assets/models/m
|
||||
<p>Next, let's create mipmapped KTX files using filament's <code>mipgen</code> tool. We'll create compressed and
|
||||
non-compressed variants for each texture, since not all platforms support the same compression
|
||||
formats. First copy over the PNG files from the <a href="https://github.com/google/filament/blob/main/assets/models/monkey">monkey folder</a>, then do:</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #408080; font-style: italic"># Create mipmaps for base color and two compressed variants.</span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic"># Create mipmaps for base color and two compressed variants.</span>
|
||||
mipgen albedo.png albedo.ktx
|
||||
mipgen --compression<span style="color: #666666">=</span>astc_fast_ldr_4x4 albedo.png albedo_astc.ktx
|
||||
mipgen --compression<span style="color: #666666">=</span>s3tc_rgb_dxt1 albedo.png albedo_s3tc_srgb.ktx
|
||||
|
||||
<span style="color: #408080; font-style: italic"># Create mipmaps for the normal map and a compressed variant.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the normal map and a compressed variant.</span>
|
||||
mipgen --strip-alpha --kernel<span style="color: #666666">=</span>NORMALS --linear normal.png normal.ktx
|
||||
mipgen --strip-alpha --kernel<span style="color: #666666">=</span>NORMALS --linear --compression<span style="color: #666666">=</span>etc_rgb8_normalxyz_40 <span style="color: #BB6622; font-weight: bold">\</span>
|
||||
mipgen --strip-alpha --kernel<span style="color: #666666">=</span>NORMALS --linear --compression<span style="color: #666666">=</span>etc_rgb8_normalxyz_40 <span style="color: #AA5D1F; font-weight: bold">\</span>
|
||||
normal.png normal_etc.ktx
|
||||
|
||||
<span style="color: #408080; font-style: italic"># Create mipmaps for the single-component roughness map and a compressed variant.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the single-component roughness map and a compressed variant.</span>
|
||||
mipgen --grayscale roughness.png roughness.ktx
|
||||
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 roughness.png roughness_etc.ktx
|
||||
|
||||
<span style="color: #408080; font-style: italic"># Create mipmaps for the single-component metallic map and a compressed variant.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the single-component metallic map and a compressed variant.</span>
|
||||
mipgen --grayscale metallic.png metallic.ktx
|
||||
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 metallic.png metallic_etc.ktx
|
||||
|
||||
<span style="color: #408080; font-style: italic"># Create mipmaps for the single-component occlusion map and a compressed variant.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the single-component occlusion map and a compressed variant.</span>
|
||||
mipgen --grayscale ao.png ao.ktx
|
||||
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 ao.png ao_etc.ktx
|
||||
</pre></div>
|
||||
@@ -101,7 +101,7 @@ materials, consult the official document describing the <a href="https://google.
|
||||
<p>Create a text file called <code>suzanne.html</code> and copy over the HTML that we used in the <a href="tutorial_redball.html">previous
|
||||
tutorial</a>. Change the last script tag from <code>redball.js</code> to <code>suzanne.js</code>. Next, create <code>suzanne.js</code>
|
||||
with the following content.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #408080; font-style: italic">// TODO: declare asset URLs</span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// TODO: declare asset URLs</span>
|
||||
|
||||
Filament.init([ filamat_url, filamesh_url, sky_small_url, ibl_url ], () => {
|
||||
<span style="color: #008000">window</span>.app <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> App(<span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">'canvas'</span>)[<span style="color: #666666">0</span>]);
|
||||
@@ -119,9 +119,9 @@ Filament.init([ filamat_url, filamesh_url, sky_small_url, ibl_url ], () => {
|
||||
<span style="color: #008000; font-weight: bold">const</span> filamesh <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.loadFilamesh(filamesh_url, <span style="color: #008000; font-weight: bold">this</span>.matinstance);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.suzanne <span style="color: #666666">=</span> filamesh.renderable;
|
||||
|
||||
<span style="color: #408080; font-style: italic">// TODO: create sky box and IBL</span>
|
||||
<span style="color: #408080; font-style: italic">// TODO: initialize gltumble</span>
|
||||
<span style="color: #408080; font-style: italic">// TODO: fetch larger assets</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create sky box and IBL</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: initialize gltumble</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: fetch larger assets</span>
|
||||
|
||||
<span style="color: #008000; font-weight: bold">this</span>.swapChain <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createSwapChain();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createRenderer();
|
||||
@@ -141,7 +141,7 @@ Filament.init([ filamat_url, filamesh_url, sky_small_url, ibl_url ], () => {
|
||||
}
|
||||
|
||||
render() {
|
||||
<span style="color: #408080; font-style: italic">// TODO: apply gltumble matrix</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: apply gltumble matrix</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain, <span style="color: #008000; font-weight: bold">this</span>.view);
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
@@ -176,14 +176,14 @@ last resort. Go ahead and replace the <strong>declare asset URLs</strong> commen
|
||||
<span style="color: #008000; font-weight: bold">const</span> texture_suffix <span style="color: #666666">=</span> Filament.getSupportedFormatSuffix(<span style="color: #BA2121">'etc'</span>);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span> environ <span style="color: #666666">=</span> <span style="color: #BA2121">'venetian_crossroads_2k'</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_small_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_skybox_tiny.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_large_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> albedo_url <span style="color: #666666">=</span> <span style="color: #BA2121">`albedo</span><span style="color: #BB6688; font-weight: bold">${</span>albedo_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> ao_url <span style="color: #666666">=</span> <span style="color: #BA2121">`ao</span><span style="color: #BB6688; font-weight: bold">${</span>texture_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> metallic_url <span style="color: #666666">=</span> <span style="color: #BA2121">`metallic</span><span style="color: #BB6688; font-weight: bold">${</span>texture_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> normal_url <span style="color: #666666">=</span> <span style="color: #BA2121">`normal</span><span style="color: #BB6688; font-weight: bold">${</span>texture_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> roughness_url <span style="color: #666666">=</span> <span style="color: #BA2121">`roughness</span><span style="color: #BB6688; font-weight: bold">${</span>texture_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_small_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox_tiny.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_large_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> albedo_url <span style="color: #666666">=</span> <span style="color: #BA2121">`albedo</span><span style="color: #A45A77; font-weight: bold">${</span>albedo_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> ao_url <span style="color: #666666">=</span> <span style="color: #BA2121">`ao</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> metallic_url <span style="color: #666666">=</span> <span style="color: #BA2121">`metallic</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> normal_url <span style="color: #666666">=</span> <span style="color: #BA2121">`normal</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> roughness_url <span style="color: #666666">=</span> <span style="color: #BA2121">`roughness</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> filamat_url <span style="color: #666666">=</span> <span style="color: #BA2121">'textured.filamat'</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> filamesh_url <span style="color: #666666">=</span> <span style="color: #BA2121">'suzanne.filamesh'</span>;
|
||||
</pre></div>
|
||||
@@ -224,7 +224,7 @@ was created in the app constructor.</p>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'normal'</span>, normal, sampler);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'ao'</span>, ao, sampler);
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Replace low-res skybox with high-res skybox.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Replace low-res skybox with high-res skybox.</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.engine.destroySkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.skybox <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx(sky_large_url);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.scene.setSkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);
|
||||
@@ -236,7 +236,7 @@ was created in the app constructor.</p>
|
||||
<h2>Introduce trackball rotation</h2>
|
||||
<p>Add the following script tag to your HTML file. This imports a small third-party library that
|
||||
listens for drag events and computes a rotation matrix.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><<span style="color: #008000; font-weight: bold">script</span> <span style="color: #7D9029">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"//unpkg.com/gltumble"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><<span style="color: #008000; font-weight: bold">script</span> <span style="color: #687822">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"//unpkg.com/gltumble"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
</pre></div>
|
||||
|
||||
<p>Next, replace the <strong>initialize gltumble</strong> and <strong>apply gltumble matrix</strong> comments with the following
|
||||
|
||||
@@ -16,22 +16,22 @@ subsequent code blocks.</p>
|
||||
<h2>Start your project</h2>
|
||||
<p>First, create a text file called <code>triangle.html</code> and fill it with the following HTML. This creates
|
||||
a mobile-friendly page with a full-screen canvas.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #BC7A00"><!DOCTYPE html></span>
|
||||
<<span style="color: #008000; font-weight: bold">html</span> <span style="color: #7D9029">lang</span><span style="color: #666666">=</span><span style="color: #BA2121">"en"</span>>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #9C6500"><!DOCTYPE html></span>
|
||||
<<span style="color: #008000; font-weight: bold">html</span> <span style="color: #687822">lang</span><span style="color: #666666">=</span><span style="color: #BA2121">"en"</span>>
|
||||
<<span style="color: #008000; font-weight: bold">head</span>>
|
||||
<<span style="color: #008000; font-weight: bold">title</span>>Filament Tutorial</<span style="color: #008000; font-weight: bold">title</span>>
|
||||
<<span style="color: #008000; font-weight: bold">meta</span> <span style="color: #7D9029">charset</span><span style="color: #666666">=</span><span style="color: #BA2121">"utf-8"</span>>
|
||||
<<span style="color: #008000; font-weight: bold">meta</span> <span style="color: #7D9029">name</span><span style="color: #666666">=</span><span style="color: #BA2121">"viewport"</span> <span style="color: #7D9029">content</span><span style="color: #666666">=</span><span style="color: #BA2121">"width=device-width,user-scalable=no,initial-scale=1"</span>>
|
||||
<<span style="color: #008000; font-weight: bold">style</span>>
|
||||
<span style="color: #008000; font-weight: bold">body</span> { <span style="color: #008000; font-weight: bold">margin</span>: <span style="color: #666666">0</span>; <span style="color: #008000; font-weight: bold">overflow</span>: <span style="color: #008000; font-weight: bold">hidden</span>; }
|
||||
<span style="color: #008000; font-weight: bold">canvas</span> { touch-action: <span style="color: #008000; font-weight: bold">none</span>; <span style="color: #008000; font-weight: bold">width</span>: <span style="color: #666666">100</span><span style="color: #B00040">%</span>; <span style="color: #008000; font-weight: bold">height</span>: <span style="color: #666666">100</span><span style="color: #B00040">%</span>; }
|
||||
</<span style="color: #008000; font-weight: bold">style</span>>
|
||||
<<span style="color: #008000; font-weight: bold">meta</span> <span style="color: #687822">charset</span><span style="color: #666666">=</span><span style="color: #BA2121">"utf-8"</span>>
|
||||
<<span style="color: #008000; font-weight: bold">meta</span> <span style="color: #687822">name</span><span style="color: #666666">=</span><span style="color: #BA2121">"viewport"</span> <span style="color: #687822">content</span><span style="color: #666666">=</span><span style="color: #BA2121">"width=device-width,user-scalable=no,initial-scale=1"</span>>
|
||||
<<span style="color: #008000; font-weight: bold">style</span>><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">body</span><span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">margin</span>:<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>;<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">overflow</span>:<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">hidden</span>;<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">canvas</span><span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"> </span>touch-action:<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">none</span>;<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">width</span>:<span style="color: #bbbbbb"> </span><span style="color: #666666">100</span><span style="color: #B00040">%</span>;<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">height</span>:<span style="color: #bbbbbb"> </span><span style="color: #666666">100</span><span style="color: #B00040">%</span>;<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span></<span style="color: #008000; font-weight: bold">style</span>>
|
||||
</<span style="color: #008000; font-weight: bold">head</span>>
|
||||
<<span style="color: #008000; font-weight: bold">body</span>>
|
||||
<<span style="color: #008000; font-weight: bold">canvas</span>></<span style="color: #008000; font-weight: bold">canvas</span>>
|
||||
<<span style="color: #008000; font-weight: bold">script</span> <span style="color: #7D9029">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"//unpkg.com/filament@1.15.0/filament.js"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
<<span style="color: #008000; font-weight: bold">script</span> <span style="color: #7D9029">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"//unpkg.com/gl-matrix@2.8.1"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
<<span style="color: #008000; font-weight: bold">script</span> <span style="color: #7D9029">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"triangle.js"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
<<span style="color: #008000; font-weight: bold">script</span> <span style="color: #687822">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"filament.js"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
<<span style="color: #008000; font-weight: bold">script</span> <span style="color: #687822">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"//unpkg.com/gl-matrix@2.8.1"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
<<span style="color: #008000; font-weight: bold">script</span> <span style="color: #687822">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"triangle.js"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
</<span style="color: #008000; font-weight: bold">body</span>>
|
||||
</<span style="color: #008000; font-weight: bold">html</span>>
|
||||
</pre></div>
|
||||
@@ -50,18 +50,18 @@ a mobile-friendly page with a full-screen canvas.</p>
|
||||
<p>Go ahead and create <code>triangle.js</code> with the following content.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">class</span> App {
|
||||
<span style="color: #008000; font-weight: bold">constructor</span>() {
|
||||
<span style="color: #408080; font-style: italic">// TODO: create entities</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create entities</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.render <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.resize <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);
|
||||
<span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">'resize'</span>, <span style="color: #008000; font-weight: bold">this</span>.resize);
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
render() {
|
||||
<span style="color: #408080; font-style: italic">// TODO: render scene</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span>
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
resize() {
|
||||
<span style="color: #408080; font-style: italic">// TODO: adjust viewport and canvas</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: adjust viewport and canvas</span>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,9 +81,9 @@ that define a PBR material. We'll learn more about material packages in the next
|
||||
<h2>Spawn a local server</h2>
|
||||
<p>Because of CORS restrictions, your web app cannot fetch the material package directly from the
|
||||
file system. One way around this is to create a temporary server using Python or node:</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>python3 -m http.server <span style="color: #408080; font-style: italic"># Python 3</span>
|
||||
python -m SimpleHTTPServer <span style="color: #408080; font-style: italic"># Python 2.7</span>
|
||||
npx http-server -p <span style="color: #666666">8000</span> <span style="color: #408080; font-style: italic"># nodejs</span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>python3 -m http.server <span style="color: #3D7B7B; font-style: italic"># Python 3</span>
|
||||
python -m SimpleHTTPServer <span style="color: #3D7B7B; font-style: italic"># Python 2.7</span>
|
||||
npx http-server -p <span style="color: #666666">8000</span> <span style="color: #3D7B7B; font-style: italic"># nodejs</span>
|
||||
</pre></div>
|
||||
|
||||
<p>To see if this works, navigate to <a href="http://localhost:8000">http://localhost:8000</a> and check if you
|
||||
@@ -185,10 +185,10 @@ view.</p>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setScene(<span style="color: #008000; font-weight: bold">this</span>.scene);
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Set up a blue-green background:</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Set up a blue-green background:</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer.setClearOptions({clearColor<span style="color: #666666">:</span> [<span style="color: #666666">0.0</span>, <span style="color: #666666">0.1</span>, <span style="color: #666666">0.2</span>, <span style="color: #666666">1.0</span>], clear<span style="color: #666666">:</span> <span style="color: #008000; font-weight: bold">true</span>});
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Adjust the initial viewport:</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Adjust the initial viewport:</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.resize();
|
||||
</pre></div>
|
||||
|
||||
@@ -198,14 +198,14 @@ However the canvas is still blank!</p>
|
||||
<p>Recall that our App class has a skeletal render method, which the browser calls every time it needs
|
||||
to repaint. Often this is 60 times a second.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>render() {
|
||||
<span style="color: #408080; font-style: italic">// TODO: render scene</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span>
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
<p>Let's flesh this out by rotating the triangle and invoking the Filament renderer. Add the following
|
||||
code to the top of the render method.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #408080; font-style: italic">// Rotate the triangle.</span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// Rotate the triangle.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> radians <span style="color: #666666">=</span> <span style="color: #008000">Date</span>.now() <span style="color: #666666">/</span> <span style="color: #666666">1000</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> transform <span style="color: #666666">=</span> mat4.fromRotation(mat4.create(), radians, [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">1</span>]);
|
||||
<span style="color: #008000; font-weight: bold">const</span> tcm <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.getTransformManager();
|
||||
@@ -213,7 +213,7 @@ code to the top of the render method.</p>
|
||||
tcm.setTransform(inst, transform);
|
||||
inst.<span style="color: #AA22FF; font-weight: bold">delete</span>();
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Render the frame.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Render the frame.</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain, <span style="color: #008000; font-weight: bold">this</span>.view);
|
||||
</pre></div>
|
||||
|
||||
|
||||
@@ -92,7 +92,6 @@ set(SRCS
|
||||
src/UniformBuffer.cpp
|
||||
src/VertexBuffer.cpp
|
||||
src/View.cpp
|
||||
src/Viewport.cpp
|
||||
src/components/CameraManager.cpp
|
||||
src/components/LightManager.cpp
|
||||
src/components/RenderableManager.cpp
|
||||
@@ -118,14 +117,14 @@ set(SRCS
|
||||
src/details/Texture.cpp
|
||||
src/details/VertexBuffer.cpp
|
||||
src/details/View.cpp
|
||||
src/fg2/Blackboard.cpp
|
||||
src/fg2/DependencyGraph.cpp
|
||||
src/fg2/FrameGraph.cpp
|
||||
src/fg2/FrameGraphPass.cpp
|
||||
src/fg2/FrameGraphResources.cpp
|
||||
src/fg2/FrameGraphTexture.cpp
|
||||
src/fg2/PassNode.cpp
|
||||
src/fg2/ResourceNode.cpp
|
||||
src/fg/Blackboard.cpp
|
||||
src/fg/DependencyGraph.cpp
|
||||
src/fg/FrameGraph.cpp
|
||||
src/fg/FrameGraphPass.cpp
|
||||
src/fg/FrameGraphResources.cpp
|
||||
src/fg/FrameGraphTexture.cpp
|
||||
src/fg/PassNode.cpp
|
||||
src/fg/ResourceNode.cpp
|
||||
src/fsr.cpp
|
||||
)
|
||||
|
||||
@@ -177,19 +176,19 @@ set(PRIVATE_HDRS
|
||||
src/details/Texture.h
|
||||
src/details/VertexBuffer.h
|
||||
src/details/View.h
|
||||
src/fg2/Blackboard.h
|
||||
src/fg2/FrameGraph.h
|
||||
src/fg2/FrameGraphId.h
|
||||
src/fg2/FrameGraphPass.h
|
||||
src/fg2/FrameGraphRenderPass.h
|
||||
src/fg2/FrameGraphResources.h
|
||||
src/fg2/FrameGraphTexture.h
|
||||
src/fg2/Resource.cpp
|
||||
src/fg2/details/DependencyGraph.h
|
||||
src/fg2/details/PassNode.h
|
||||
src/fg2/details/Resource.h
|
||||
src/fg2/details/ResourceNode.h
|
||||
src/fg2/details/Utilities.h
|
||||
src/fg/Blackboard.h
|
||||
src/fg/FrameGraph.h
|
||||
src/fg/FrameGraphId.h
|
||||
src/fg/FrameGraphPass.h
|
||||
src/fg/FrameGraphRenderPass.h
|
||||
src/fg/FrameGraphResources.h
|
||||
src/fg/FrameGraphTexture.h
|
||||
src/fg/Resource.cpp
|
||||
src/fg/details/DependencyGraph.h
|
||||
src/fg/details/PassNode.h
|
||||
src/fg/details/Resource.h
|
||||
src/fg/details/ResourceNode.h
|
||||
src/fg/details/Utilities.h
|
||||
src/fsr.h
|
||||
src/materials/fsr/ffx_a.h
|
||||
src/materials/fsr/ffx_fsr1.h
|
||||
|
||||
@@ -13,7 +13,6 @@ set(PUBLIC_HDRS
|
||||
include/backend/CallbackHandler.h
|
||||
include/backend/DriverEnums.h
|
||||
include/backend/Handle.h
|
||||
include/backend/ShaderStageFlags.h
|
||||
include/backend/PipelineState.h
|
||||
include/backend/PixelBufferDescriptor.h
|
||||
include/backend/Platform.h
|
||||
@@ -43,6 +42,7 @@ set(PRIVATE_HDRS
|
||||
include/private/backend/CircularBuffer.h
|
||||
include/private/backend/CommandBufferQueue.h
|
||||
include/private/backend/CommandStream.h
|
||||
include/private/backend/Dispatcher.h
|
||||
include/private/backend/Driver.h
|
||||
include/private/backend/DriverApi.h
|
||||
include/private/backend/DriverAPI.inc
|
||||
@@ -65,8 +65,6 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
|
||||
src/opengl/gl_headers.h
|
||||
src/opengl/GLUtils.cpp
|
||||
src/opengl/GLUtils.h
|
||||
src/opengl/OpenGLBlitter.cpp
|
||||
src/opengl/OpenGLBlitter.h
|
||||
src/opengl/OpenGLContext.cpp
|
||||
src/opengl/OpenGLContext.h
|
||||
src/opengl/OpenGLDriver.cpp
|
||||
@@ -75,8 +73,8 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
|
||||
src/opengl/OpenGLProgram.cpp
|
||||
src/opengl/OpenGLProgram.h
|
||||
src/opengl/OpenGLPlatform.cpp
|
||||
src/opengl/TimerQuery.cpp
|
||||
src/opengl/TimerQuery.h
|
||||
src/opengl/OpenGLTimerQuery.cpp
|
||||
src/opengl/OpenGLTimerQuery.h
|
||||
include/private/backend/OpenGLPlatform.h
|
||||
)
|
||||
if (EGL)
|
||||
@@ -89,7 +87,6 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
|
||||
endif ()
|
||||
if (ANDROID)
|
||||
list(APPEND SRCS src/opengl/platforms/ExternalStreamManagerAndroid.cpp)
|
||||
list(APPEND SRCS src/android/ExternalTextureManagerAndroid.cpp)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformEGLAndroid.cpp)
|
||||
elseif (IOS)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformCocoaTouchGL.mm)
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace filament {
|
||||
/**
|
||||
* Types and enums used by filament's driver.
|
||||
*
|
||||
@@ -41,24 +40,24 @@ namespace filament {
|
||||
* internal redeclaration of these types.
|
||||
* For e.g. Use Texture::Sampler instead of filament::SamplerType.
|
||||
*/
|
||||
namespace backend {
|
||||
namespace filament::backend {
|
||||
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_TRANSPARENT = 0x1;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_READABLE = 0x2;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_TRANSPARENT = 0x1;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_READABLE = 0x2;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER = 0x8;
|
||||
|
||||
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_VERTEX_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_FRAGMENT_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_SAMPLER_COUNT = 32; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
|
||||
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_VERTEX_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_FRAGMENT_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_SAMPLER_COUNT = 32; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
|
||||
|
||||
static_assert(MAX_VERTEX_BUFFER_COUNT <= MAX_VERTEX_ATTRIBUTE_COUNT,
|
||||
"The number of buffer objects that can be attached to a VertexBuffer must be "
|
||||
"less than or equal to the maximum number of vertex attributes.");
|
||||
|
||||
static constexpr size_t CONFIG_BINDING_COUNT = 8;
|
||||
static constexpr size_t CONFIG_BINDING_COUNT = 12; // This is guaranteed by OpenGL ES.
|
||||
|
||||
/**
|
||||
* Selects which driver a particular Engine should use.
|
||||
@@ -142,9 +141,9 @@ struct Viewport {
|
||||
uint32_t width; //!< width in pixels
|
||||
uint32_t height; //!< height in pixels
|
||||
//! get the right coordinate in window space of the viewport
|
||||
int32_t right() const noexcept { return left + width; }
|
||||
int32_t right() const noexcept { return left + int32_t(width); }
|
||||
//! get the top coordinate in window space of the viewport
|
||||
int32_t top() const noexcept { return bottom + height; }
|
||||
int32_t top() const noexcept { return bottom + int32_t(height); }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -160,7 +159,7 @@ struct DepthRange {
|
||||
* @see Fence, Fence::wait()
|
||||
*/
|
||||
enum class FenceStatus : int8_t {
|
||||
ERROR = -1, //!< An error occured. The Fence condition is not satisfied.
|
||||
ERROR = -1, //!< An error occurred. The Fence condition is not satisfied.
|
||||
CONDITION_SATISFIED = 0, //!< The Fence condition is satisfied.
|
||||
TIMEOUT_EXPIRED = 1, //!< wait()'s timeout expired. The Fence condition is not satisfied.
|
||||
};
|
||||
@@ -169,7 +168,7 @@ enum class FenceStatus : int8_t {
|
||||
* Status codes for sync objects
|
||||
*/
|
||||
enum class SyncStatus : int8_t {
|
||||
ERROR = -1, //!< An error occured. The Sync is not signaled.
|
||||
ERROR = -1, //!< An error occurred. The Sync is not signaled.
|
||||
SIGNALED = 0, //!< The Sync is signaled.
|
||||
NOT_SIGNALED = 1, //!< The Sync is not signaled yet
|
||||
};
|
||||
@@ -789,7 +788,6 @@ enum class BlendFunction : uint8_t {
|
||||
//! Stream for external textures
|
||||
enum class StreamType {
|
||||
NATIVE, //!< Not synchronized but copy-free. Good for video.
|
||||
TEXTURE_ID, //!< Synchronized, but GL-only and incurs copies. Good for AR on devices before API 26.
|
||||
ACQUIRED, //!< Synchronized, copy-free, and take a release callback. Good for AR but requires API 26+.
|
||||
};
|
||||
|
||||
@@ -906,6 +904,16 @@ enum ShaderType : uint8_t {
|
||||
};
|
||||
static constexpr size_t PIPELINE_STAGE_COUNT = 2;
|
||||
|
||||
struct ShaderStageFlags {
|
||||
bool vertex : 1;
|
||||
bool fragment : 1;
|
||||
bool hasShaderType(ShaderType type) const {
|
||||
return (vertex && type == ShaderType::VERTEX) ||
|
||||
(fragment && type == ShaderType::FRAGMENT);
|
||||
}
|
||||
};
|
||||
static constexpr ShaderStageFlags ALL_SHADER_STAGE_FLAGS = { true, true };
|
||||
|
||||
/**
|
||||
* Selects which buffers to clear at the beginning of the render pass, as well as which buffers
|
||||
* can be discarded at the beginning and end of the render pass.
|
||||
@@ -988,8 +996,7 @@ enum class Workaround : uint16_t {
|
||||
ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
template<> struct utils::EnableBitMaskOperators<filament::backend::TargetBufferFlags>
|
||||
: public std::true_type {};
|
||||
@@ -1026,6 +1033,7 @@ utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend:
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::RasterState& rs);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::RenderPassParams& b);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::Viewport& v);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::ShaderStageFlags stageFlags);
|
||||
#endif
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_DRIVERENUMS_H
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
* underlying platform is returned and \p backendHint is updated
|
||||
* accordingly. Can't be nullptr.
|
||||
*
|
||||
* @return A pointer to the Plaform object.
|
||||
* @return A pointer to the Platform object.
|
||||
*
|
||||
* @see destroy
|
||||
*/
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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_SHADERSTAGEFLAGS_H
|
||||
#define TNT_FILAMENT_BACKEND_SHADERSTAGEFLAGS_H
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
struct ShaderStageFlags {
|
||||
bool vertex : 1;
|
||||
bool fragment : 1;
|
||||
|
||||
inline bool hasShaderType(ShaderType type) const {
|
||||
return (vertex && type == ShaderType::VERTEX) ||
|
||||
(fragment && type == ShaderType::FRAGMENT);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr ShaderStageFlags ALL_SHADER_STAGE_FLAGS = { .vertex = true, .fragment = true };
|
||||
|
||||
inline utils::io::ostream& operator<<(utils::io::ostream& stream, ShaderStageFlags stageFlags) {
|
||||
stream << "{ ";
|
||||
if (stageFlags.vertex) {
|
||||
stream << "vertex";
|
||||
}
|
||||
if (stageFlags.fragment) {
|
||||
if (stageFlags.vertex)
|
||||
stream << " | ";
|
||||
stream << "fragment";
|
||||
}
|
||||
stream << " }";
|
||||
return stream;
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_SHADERSTAGEFLAGS_H
|
||||
@@ -1,5 +1,3 @@
|
||||
#include <utility>
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
@@ -20,23 +18,19 @@
|
||||
#define TNT_FILAMENT_BACKEND_PRIVATE_COMMANDSTREAM_H
|
||||
|
||||
#include "private/backend/CircularBuffer.h"
|
||||
#include "private/backend/Dispatcher.h"
|
||||
#include "private/backend/Program.h"
|
||||
#include "private/backend/SamplerGroup.h"
|
||||
#include "private/backend/Driver.h"
|
||||
|
||||
#include <backend/BufferDescriptor.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
#include <backend/PipelineState.h>
|
||||
#include <backend/PixelBufferDescriptor.h>
|
||||
#include <backend/PresentCallable.h>
|
||||
#include <backend/TargetBufferInfo.h>
|
||||
|
||||
#include "private/backend/Program.h"
|
||||
#include "private/backend/SamplerGroup.h"
|
||||
|
||||
// FIXME: we'd like to not need this header here.
|
||||
#include "private/backend/Driver.h"
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/ThreadUtils.h>
|
||||
|
||||
@@ -45,40 +39,14 @@
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Set to true to print every commands out on log.d. This requires RTTI and DEBUG
|
||||
// Set to true to print every command out on log.d. This requires RTTI and DEBUG
|
||||
#define DEBUG_COMMAND_STREAM false
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
|
||||
class Driver;
|
||||
class CommandBase;
|
||||
|
||||
/*
|
||||
* Dispatcher is a data structure containing only function pointers.
|
||||
* Each function pointer targets code that unpacks the arguments to the driver's method and
|
||||
* calls it.
|
||||
*
|
||||
* Dispatcher's function pointers are populated during initialization and no CommandStream calls
|
||||
* can be made before that.
|
||||
*
|
||||
* When a command is inserted into the stream, the corresponding function pointer is copied
|
||||
* directly into CommandBase from Dispatcher.
|
||||
*/
|
||||
class Dispatcher {
|
||||
public:
|
||||
using Execute = void (*)(Driver& driver, CommandBase* self, intptr_t* next);
|
||||
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params)
|
||||
#define DECL_DRIVER_API(methodName, paramsDecl, params) Execute methodName##_;
|
||||
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) Execute methodName##_;
|
||||
#include "DriverAPI.inc"
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace filament::backend {
|
||||
|
||||
class CommandBase {
|
||||
static constexpr size_t FILAMENT_OBJECT_ALIGNMENT = alignof(std::max_align_t);
|
||||
@@ -96,8 +64,10 @@ public:
|
||||
|
||||
// executes this command and returns the next one
|
||||
inline CommandBase* execute(Driver& driver) {
|
||||
// it is important to return the next command offset by output parameter instead
|
||||
// of return value -- it allows the compiler to perform the tail call optimization.
|
||||
// returning the next command by output parameter allows the compiler to perform the
|
||||
// tail-call optimization in the function called by mExecute, however that comes at
|
||||
// a cost here (writing and reading the stack at each iteration), in the end it's
|
||||
// probably better to pay the cost at just one location.
|
||||
intptr_t next;
|
||||
mExecute(driver, this, &next);
|
||||
return reinterpret_cast<CommandBase*>(reinterpret_cast<intptr_t>(this) + next);
|
||||
@@ -132,7 +102,7 @@ constexpr decltype(auto) apply(M&& m, D&& d, T&& t) {
|
||||
/*
|
||||
* CommandType<> is just a wrapper class to specialize on a pointer-to-member of Driver
|
||||
* (i.e. a method pointer to a method of Driver of a particular type -- but not the
|
||||
* method itself). We only do that so we can identify the parameters of that method.
|
||||
* method itself). We only do that, so we can identify the parameters of that method.
|
||||
* We won't call through that pointer though.
|
||||
*/
|
||||
template<typename... ARGS>
|
||||
@@ -208,7 +178,7 @@ class NoopCommand : public CommandBase {
|
||||
}
|
||||
public:
|
||||
inline constexpr explicit NoopCommand(void* next) noexcept
|
||||
: CommandBase(execute), mNext(size_t((char *)next - (char *)this)) { }
|
||||
: CommandBase(execute), mNext(intptr_t((char *)next - (char *)this)) { }
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -216,41 +186,34 @@ public:
|
||||
#if !defined(NDEBUG) || (FILAMENT_DEBUG_COMMANDS >= FILAMENT_DEBUG_COMMANDS_ENABLE)
|
||||
// For now, simply pass the method name down as a string and throw away the parameters.
|
||||
// This is good enough for certain debugging needs and we can improve this later.
|
||||
#define DEBUG_COMMAND_BEGIN(methodName, sync, ...) mDriver->debugCommandBegin(this, sync, #methodName)
|
||||
#define DEBUG_COMMAND_END(methodName, sync) mDriver->debugCommandEnd(this, sync, #methodName)
|
||||
#define DEBUG_COMMAND_BEGIN(methodName, sync, ...) mDriver.debugCommandBegin(this, sync, #methodName)
|
||||
#define DEBUG_COMMAND_END(methodName, sync) mDriver.debugCommandEnd(this, sync, #methodName)
|
||||
#else
|
||||
#define DEBUG_COMMAND_BEGIN(methodName, sync, ...)
|
||||
#define DEBUG_COMMAND_END(methodName, sync)
|
||||
#endif
|
||||
|
||||
class CommandStream {
|
||||
// Dispatcher could be a value (instead of pointer), which saves a load when writing commands
|
||||
// at the expense of a larger CommandStream object (about ~400 bytes)
|
||||
Dispatcher* mDispatcher = nullptr;
|
||||
Driver* mDriver = nullptr;
|
||||
CircularBuffer* UTILS_RESTRICT mCurrentBuffer = nullptr;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// just for debugging...
|
||||
std::thread::id mThreadId{};
|
||||
#endif
|
||||
|
||||
bool mUsePerformanceCounter = false;
|
||||
|
||||
template<typename T>
|
||||
struct AutoExecute {
|
||||
T closure;
|
||||
inline AutoExecute(T&& closure) : closure(std::forward<T>(closure)) {}
|
||||
inline explicit AutoExecute(T&& closure) : closure(std::forward<T>(closure)) {}
|
||||
inline ~AutoExecute() { closure(); }
|
||||
};
|
||||
|
||||
public:
|
||||
CommandStream(Driver& driver, CircularBuffer& buffer) noexcept;
|
||||
|
||||
CommandStream(CommandStream const& rhs) noexcept = delete;
|
||||
CommandStream& operator=(CommandStream const& rhs) noexcept = delete;
|
||||
|
||||
public:
|
||||
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
|
||||
inline void methodName(paramsDecl) { \
|
||||
DEBUG_COMMAND_BEGIN(methodName, false, params); \
|
||||
using Cmd = COMMAND_TYPE(methodName); \
|
||||
void* const p = allocateCommand(CommandBase::align(sizeof(Cmd))); \
|
||||
new(p) Cmd(mDispatcher->methodName##_, APPLY(std::move, params)); \
|
||||
new(p) Cmd(mDispatcher.methodName##_, APPLY(std::move, params)); \
|
||||
DEBUG_COMMAND_END(methodName, false); \
|
||||
}
|
||||
|
||||
@@ -260,16 +223,16 @@ public:
|
||||
AutoExecute callOnExit([=](){ \
|
||||
DEBUG_COMMAND_END(methodName, true); \
|
||||
}); \
|
||||
return apply(&Driver::methodName, *mDriver, std::forward_as_tuple(params)); \
|
||||
return apply(&Driver::methodName, mDriver, std::forward_as_tuple(params)); \
|
||||
}
|
||||
|
||||
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) \
|
||||
inline RetType methodName(paramsDecl) { \
|
||||
DEBUG_COMMAND_BEGIN(methodName, false, params); \
|
||||
RetType result = mDriver->methodName##S(); \
|
||||
RetType result = mDriver.methodName##S(); \
|
||||
using Cmd = COMMAND_TYPE(methodName##R); \
|
||||
void* const p = allocateCommand(CommandBase::align(sizeof(Cmd))); \
|
||||
new(p) Cmd(mDispatcher->methodName##_, RetType(result), APPLY(std::move, params)); \
|
||||
new(p) Cmd(mDispatcher.methodName##_, RetType(result), APPLY(std::move, params)); \
|
||||
DEBUG_COMMAND_END(methodName, false); \
|
||||
return result; \
|
||||
}
|
||||
@@ -277,10 +240,7 @@ public:
|
||||
#include "DriverAPI.inc"
|
||||
|
||||
public:
|
||||
CommandStream() noexcept = default;
|
||||
CommandStream(Driver& driver, CircularBuffer& buffer) noexcept;
|
||||
|
||||
// This is for debugging only. Currently CircularBuffer can only be written from a
|
||||
// This is for debugging only. Currently, CircularBuffer can only be written from a
|
||||
// single thread. In debug builds we assert this condition.
|
||||
// Call this first in the render loop.
|
||||
inline void debugThreading() noexcept {
|
||||
@@ -315,8 +275,21 @@ public:
|
||||
private:
|
||||
inline void* allocateCommand(size_t size) {
|
||||
assert_invariant(utils::ThreadUtils::isThisThread(mThreadId));
|
||||
return mCurrentBuffer->allocate(size);
|
||||
return mCurrentBuffer.allocate(size);
|
||||
}
|
||||
|
||||
// We use a copy of Dispatcher (instead of a pointer) because this removes one dereference
|
||||
// when executing driver commands.
|
||||
Driver& UTILS_RESTRICT mDriver;
|
||||
CircularBuffer& UTILS_RESTRICT mCurrentBuffer;
|
||||
Dispatcher mDispatcher;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// just for debugging...
|
||||
std::thread::id mThreadId{};
|
||||
#endif
|
||||
|
||||
bool mUsePerformanceCounter = false;
|
||||
};
|
||||
|
||||
void* CommandStream::allocate(size_t size, size_t alignment) noexcept {
|
||||
@@ -341,7 +314,6 @@ PodType* CommandStream::allocatePod(size_t count, size_t alignment) noexcept {
|
||||
return static_cast<PodType*>(allocate(count * sizeof(PodType), alignment));
|
||||
}
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PRIVATE_COMMANDSTREAM_H
|
||||
|
||||
50
filament/backend/include/private/backend/Dispatcher.h
Normal file
50
filament/backend/include/private/backend/Dispatcher.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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_PRIVATE_DISPATCHER_H
|
||||
#define TNT_FILAMENT_BACKEND_PRIVATE_DISPATCHER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class Driver;
|
||||
class CommandBase;
|
||||
|
||||
/*
|
||||
* Dispatcher is a data structure containing only function pointers.
|
||||
* Each function pointer targets code that unpacks the arguments to the driver's method and
|
||||
* calls it.
|
||||
*
|
||||
* Dispatcher's function pointers are populated during initialization and no CommandStream calls
|
||||
* can be made before that.
|
||||
*
|
||||
* When a command is inserted into the stream, the corresponding function pointer is copied
|
||||
* directly into CommandBase from Dispatcher.
|
||||
*/
|
||||
class Dispatcher {
|
||||
public:
|
||||
using Execute = void (*)(Driver& driver, CommandBase* self, intptr_t* next);
|
||||
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params)
|
||||
#define DECL_DRIVER_API(methodName, paramsDecl, params) Execute methodName##_;
|
||||
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) Execute methodName##_;
|
||||
|
||||
#include "DriverAPI.inc"
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif //TNT_FILAMENT_BACKEND_PRIVATE_DISPATCHER_H
|
||||
@@ -17,23 +17,14 @@
|
||||
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_DRIVER_H
|
||||
#define TNT_FILAMENT_BACKEND_PRIVATE_DRIVER_H
|
||||
|
||||
#include <backend/BufferDescriptor.h>
|
||||
#include <backend/CallbackHandler.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
#include <backend/PipelineState.h>
|
||||
#include <backend/PixelBufferDescriptor.h>
|
||||
#include <backend/PresentCallable.h>
|
||||
#include <backend/TargetBufferInfo.h>
|
||||
|
||||
#include "private/backend/DriverApiForward.h"
|
||||
#include "private/backend/Program.h"
|
||||
#include "private/backend/SamplerGroup.h"
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -49,8 +40,13 @@
|
||||
|
||||
#define FILAMENT_DEBUG_COMMANDS FILAMENT_DEBUG_COMMANDS_NONE
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace filament::backend {
|
||||
|
||||
class BufferDescriptor;
|
||||
class CallbackHandler;
|
||||
class PixelBufferDescriptor;
|
||||
class Program;
|
||||
class SamplerGroup;
|
||||
|
||||
template<typename T>
|
||||
class ConcreteDispatcher;
|
||||
@@ -59,27 +55,32 @@ class CommandStream;
|
||||
|
||||
class Driver {
|
||||
public:
|
||||
static size_t getElementTypeSize(ElementType type) noexcept;
|
||||
|
||||
virtual ~Driver() noexcept;
|
||||
|
||||
static size_t getElementTypeSize(ElementType type) noexcept;
|
||||
|
||||
// called from the main thread (NOT the render-thread) at various intervals, this
|
||||
// is where the driver can execute user callbacks.
|
||||
virtual void purge() noexcept = 0;
|
||||
|
||||
virtual ShaderModel getShaderModel() const noexcept = 0;
|
||||
|
||||
virtual Dispatcher& getDispatcher() noexcept = 0;
|
||||
// Returns the dispatcher. This is only called once during initialization of the CommandStream,
|
||||
// so it doesn't matter that it's virtual.
|
||||
virtual Dispatcher getDispatcher() const noexcept = 0;
|
||||
|
||||
// called from CommandStream::execute on the render-thread
|
||||
// the fn function will execute a batch of driver commands
|
||||
// this gives the driver a chance to wrap their execution in a meaningful manner
|
||||
// the default implementation simply calls fn
|
||||
virtual void execute(std::function<void(void)> fn) noexcept;
|
||||
virtual void execute(std::function<void(void)> const& fn) noexcept;
|
||||
|
||||
// This is called on debug build, or when enabled manually on the backend thread side.
|
||||
virtual void debugCommandBegin(CommandStream* cmds, bool synchronous, const char* methodName) noexcept = 0;
|
||||
virtual void debugCommandEnd(CommandStream* cmds, bool synchronous, const char* methodName) noexcept = 0;
|
||||
virtual void debugCommandBegin(CommandStream* cmds,
|
||||
bool synchronous, const char* methodName) noexcept = 0;
|
||||
|
||||
virtual void debugCommandEnd(CommandStream* cmds,
|
||||
bool synchronous, const char* methodName) noexcept = 0;
|
||||
|
||||
/*
|
||||
* Asynchronous calls here only to provide a type to CommandStream. They must be non-virtual
|
||||
@@ -101,7 +102,6 @@ public:
|
||||
#include "private/backend/DriverAPI.inc"
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PRIVATE_DRIVER_H
|
||||
|
||||
@@ -246,11 +246,6 @@ DECL_DRIVER_API_R_N(backend::SwapChainHandle, createSwapChainHeadless,
|
||||
uint32_t, height,
|
||||
uint64_t, flags)
|
||||
|
||||
DECL_DRIVER_API_R_N(backend::StreamHandle, createStreamFromTextureId,
|
||||
intptr_t, externalTextureId,
|
||||
uint32_t, width,
|
||||
uint32_t, height)
|
||||
|
||||
DECL_DRIVER_API_R_0(backend::TimerQueryHandle, createTimerQuery)
|
||||
|
||||
|
||||
@@ -461,14 +456,6 @@ DECL_DRIVER_API_N(readPixels,
|
||||
uint32_t, height,
|
||||
backend::PixelBufferDescriptor&&, data)
|
||||
|
||||
DECL_DRIVER_API_N(readStreamPixels,
|
||||
backend::StreamHandle, sh,
|
||||
uint32_t, x,
|
||||
uint32_t, y,
|
||||
uint32_t, width,
|
||||
uint32_t, height,
|
||||
backend::PixelBufferDescriptor&&, data)
|
||||
|
||||
/*
|
||||
* Rendering operations
|
||||
* --------------------
|
||||
|
||||
@@ -17,15 +17,12 @@
|
||||
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_DRIVERAPIFORWARD_H
|
||||
#define TNT_FILAMENT_BACKEND_PRIVATE_DRIVERAPIFORWARD_H
|
||||
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace filament::backend {
|
||||
|
||||
class CommandStream;
|
||||
|
||||
using DriverApi = CommandStream;
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PRIVATE_DRIVERAPIFORWARD_H
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
*/
|
||||
template<typename D, typename ... ARGS>
|
||||
Handle<D> allocateAndConstruct(ARGS&& ... args) noexcept {
|
||||
Handle<D> h{ allocateHandle(sizeof(D)) };
|
||||
Handle<D> h{ allocateHandle<sizeof(D)>() };
|
||||
D* addr = handle_cast<D*>(h);
|
||||
new(addr) D(std::forward<ARGS>(args)...);
|
||||
#if HANDLE_TYPE_SAFETY
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
*/
|
||||
template<typename D>
|
||||
Handle<D> allocate() noexcept {
|
||||
Handle<D> h{ allocateHandle(sizeof(D)) };
|
||||
Handle<D> h{ allocateHandle<sizeof(D)>() };
|
||||
#if HANDLE_TYPE_SAFETY
|
||||
D* addr = handle_cast<D*>(h);
|
||||
mLock.lock();
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
}
|
||||
#endif
|
||||
p->~D();
|
||||
deallocateHandle(handle.getId(), sizeof(D));
|
||||
deallocateHandle<sizeof(D)>(handle.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,23 +249,49 @@ private:
|
||||
utils::LockingPolicy::SpinLock>;
|
||||
#endif
|
||||
|
||||
// this is inlined because we're always called with a constexpr size
|
||||
HandleBase::HandleId allocateHandle(size_t size) noexcept {
|
||||
void* p = mHandleArena.alloc(size);
|
||||
if (UTILS_LIKELY(p)) {
|
||||
return pointerToHandle(p);
|
||||
// allocateHandle()/deallocateHandle() selects the pool to use at compile-time based on the
|
||||
// allocation size this is always inlined, because all these do is to call
|
||||
// allocateHandleInPool()/deallocateHandleFromPool() with the right pool size.
|
||||
template<size_t SIZE>
|
||||
HandleBase::HandleId allocateHandle() noexcept {
|
||||
if constexpr (SIZE <= P0) { return allocateHandleInPool<P0>(); }
|
||||
if constexpr (SIZE <= P1) { return allocateHandleInPool<P1>(); }
|
||||
return allocateHandleInPool<P2>();
|
||||
}
|
||||
|
||||
template<size_t SIZE>
|
||||
void deallocateHandle(HandleBase::HandleId id) noexcept {
|
||||
if constexpr (SIZE <= P0) {
|
||||
deallocateHandleFromPool<P0>(id);
|
||||
} else if constexpr (SIZE <= P1) {
|
||||
deallocateHandleFromPool<P1>(id);
|
||||
} else {
|
||||
return allocateHandleSlow(size);
|
||||
deallocateHandleFromPool<P2>(id);
|
||||
}
|
||||
}
|
||||
|
||||
// this is inlined because we're always called with a constexpr size
|
||||
void deallocateHandle(HandleBase::HandleId id, size_t size) noexcept {
|
||||
// allocateHandleInPool()/deallocateHandleFromPool() is NOT inlined, which will cause three
|
||||
// versions to be generated, one for each pool. Because the arena is synchronized,
|
||||
// the code generated is not trivial (even if it's not insane either).
|
||||
template<size_t SIZE>
|
||||
UTILS_NOINLINE
|
||||
HandleBase::HandleId allocateHandleInPool() noexcept {
|
||||
void* p = mHandleArena.alloc(SIZE);
|
||||
if (UTILS_LIKELY(p)) {
|
||||
return pointerToHandle(p);
|
||||
} else {
|
||||
return allocateHandleSlow(SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
template<size_t SIZE>
|
||||
UTILS_NOINLINE
|
||||
void deallocateHandleFromPool(HandleBase::HandleId id) noexcept {
|
||||
if (UTILS_LIKELY(isPoolHandle(id))) {
|
||||
void* p = handleToPointer(id);
|
||||
mHandleArena.free(p, size);
|
||||
mHandleArena.free(p, SIZE);
|
||||
} else {
|
||||
deallocateHandleSlow(id, size);
|
||||
deallocateHandleSlow(id, SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,15 +82,6 @@ public:
|
||||
virtual void detach(Stream* stream) noexcept = 0;
|
||||
virtual void updateTexImage(Stream* stream, int64_t* timestamp) noexcept = 0;
|
||||
|
||||
// external texture storage
|
||||
virtual ExternalTexture* createExternalTextureStorage() noexcept = 0;
|
||||
|
||||
// this is called synchronously in the application thread (NOT the Driver thread)
|
||||
virtual void reallocateExternalStorage(ExternalTexture* ets,
|
||||
uint32_t w, uint32_t h, TextureFormat format) noexcept = 0;
|
||||
|
||||
virtual void destroyExternalTextureStorage(ExternalTexture* ets) noexcept = 0;
|
||||
|
||||
// The method allows platforms to convert a user-supplied external image object into a new type
|
||||
// (e.g. HardwareBuffer => EGLImage). It makes sense for the default implementation to do nothing.
|
||||
virtual AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept { return source; }
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/ShaderStageFlags.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
@@ -94,13 +93,15 @@ public:
|
||||
}
|
||||
|
||||
using ShaderBlob = utils::FixedCapacityVector<uint8_t>;
|
||||
std::array<ShaderBlob, SHADER_TYPE_COUNT> const& getShadersSource() const noexcept {
|
||||
return mShadersSource;
|
||||
}
|
||||
using ShaderSource = std::array<ShaderBlob, SHADER_TYPE_COUNT>;
|
||||
ShaderSource const& getShadersSource() const noexcept { return mShadersSource; }
|
||||
ShaderSource& getShadersSource() noexcept { return mShadersSource; }
|
||||
|
||||
UniformBlockInfo const& getUniformBlockInfo() const noexcept { return mUniformBlocks; }
|
||||
UniformBlockInfo& getUniformBlockInfo() noexcept { return mUniformBlocks; }
|
||||
|
||||
SamplerGroupInfo const& getSamplerGroupInfo() const { return mSamplerGroups; }
|
||||
SamplerGroupInfo& getSamplerGroupInfo() { return mSamplerGroups; }
|
||||
|
||||
const utils::CString& getName() const noexcept { return mName; }
|
||||
|
||||
@@ -111,7 +112,7 @@ private:
|
||||
|
||||
UniformBlockInfo mUniformBlocks = {};
|
||||
SamplerGroupInfo mSamplerGroups = {};
|
||||
std::array<ShaderBlob, SHADER_TYPE_COUNT> mShadersSource;
|
||||
ShaderSource mShadersSource;
|
||||
bool mHasSamplers = false;
|
||||
utils::CString mName;
|
||||
utils::Invocable<utils::io::ostream&(utils::io::ostream& out)> mLogger;
|
||||
|
||||
@@ -33,8 +33,7 @@
|
||||
|
||||
using namespace utils;
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace filament::backend {
|
||||
|
||||
CircularBuffer::CircularBuffer(size_t size) {
|
||||
mData = alloc(size);
|
||||
@@ -56,6 +55,7 @@ CircularBuffer::~CircularBuffer() noexcept {
|
||||
// If the system does not support mmap, emulate soft circular buffer with two buffers next
|
||||
// to each others and a special case in circularize()
|
||||
|
||||
UTILS_NOINLINE
|
||||
void* CircularBuffer::alloc(size_t size) noexcept {
|
||||
#if HAS_MMAP
|
||||
void* data = nullptr;
|
||||
@@ -127,6 +127,7 @@ void* CircularBuffer::alloc(size_t size) noexcept {
|
||||
#endif
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
void CircularBuffer::dealloc() noexcept {
|
||||
#if HAS_MMAP
|
||||
if (mData) {
|
||||
@@ -162,5 +163,4 @@ void CircularBuffer::circularize() noexcept {
|
||||
mTail = mHead;
|
||||
}
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -29,8 +29,7 @@
|
||||
|
||||
using namespace utils;
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace filament::backend {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// A few utility functions for debugging...
|
||||
@@ -57,9 +56,9 @@ static UTILS_NOINLINE UTILS_UNUSED std::string extractMethodName(std::string& co
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
CommandStream::CommandStream(Driver& driver, CircularBuffer& buffer) noexcept
|
||||
: mDispatcher(&driver.getDispatcher()),
|
||||
mDriver(&driver),
|
||||
mCurrentBuffer(&buffer)
|
||||
: mDriver(driver),
|
||||
mCurrentBuffer(buffer),
|
||||
mDispatcher(driver.getDispatcher())
|
||||
#ifndef NDEBUG
|
||||
, mThreadId(ThreadUtils::getThreadId())
|
||||
#endif
|
||||
@@ -84,8 +83,8 @@ void CommandStream::execute(void* buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
mDriver->execute([this, buffer]() {
|
||||
Driver& UTILS_RESTRICT driver = *mDriver;
|
||||
mDriver.execute([this, buffer]() {
|
||||
Driver& UTILS_RESTRICT driver = mDriver;
|
||||
CommandBase* UTILS_RESTRICT base = static_cast<CommandBase*>(buffer);
|
||||
while (UTILS_LIKELY(base)) {
|
||||
base = base->execute(driver);
|
||||
@@ -152,5 +151,4 @@ void CustomCommand::execute(Driver&, CommandBase* base, intptr_t* next) noexcept
|
||||
static_cast<CustomCommand*>(base)->~CustomCommand();
|
||||
}
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Systrace.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define DEBUG_LEVEL_NONE 0
|
||||
@@ -46,10 +46,10 @@
|
||||
namespace filament::backend {
|
||||
|
||||
template<typename ConcreteDriver>
|
||||
class ConcreteDispatcher final : public Dispatcher {
|
||||
class ConcreteDispatcher {
|
||||
public:
|
||||
// initialize the dispatch table
|
||||
ConcreteDispatcher() noexcept;
|
||||
|
||||
static Dispatcher make() noexcept;
|
||||
|
||||
private:
|
||||
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params)
|
||||
@@ -72,13 +72,19 @@ private:
|
||||
|
||||
template<typename ConcreteDriver>
|
||||
UTILS_NOINLINE
|
||||
ConcreteDispatcher<ConcreteDriver>::ConcreteDispatcher() noexcept : Dispatcher() {
|
||||
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params)
|
||||
#define DECL_DRIVER_API(methodName, paramsDecl, params) methodName##_ = &ConcreteDispatcher::methodName;
|
||||
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) methodName##_ = &ConcreteDispatcher::methodName;
|
||||
#include "private/backend/DriverAPI.inc"
|
||||
}
|
||||
Dispatcher ConcreteDispatcher<ConcreteDriver>::make() noexcept {
|
||||
Dispatcher dispatcher;
|
||||
|
||||
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params)
|
||||
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
|
||||
dispatcher.methodName##_ = &ConcreteDispatcher::methodName;
|
||||
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) \
|
||||
dispatcher.methodName##_ = &ConcreteDispatcher::methodName;
|
||||
|
||||
#include "private/backend/DriverAPI.inc"
|
||||
|
||||
return dispatcher;
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
|
||||
#include "private/backend/Driver.h"
|
||||
|
||||
#include "private/backend/AcquiredImage.h"
|
||||
#include "private/backend/CommandStream.h"
|
||||
|
||||
#include "DriverBase.h"
|
||||
@@ -25,20 +27,15 @@
|
||||
#include <math/vec4.h>
|
||||
|
||||
#include <backend/BufferDescriptor.h>
|
||||
#include <backend/PixelBufferDescriptor.h>
|
||||
|
||||
#include <utils/Systrace.h>
|
||||
|
||||
using namespace utils;
|
||||
using namespace filament::math;
|
||||
|
||||
namespace filament {
|
||||
namespace filament::backend {
|
||||
|
||||
using namespace math;
|
||||
|
||||
namespace backend {
|
||||
|
||||
DriverBase::DriverBase(Dispatcher* dispatcher) noexcept
|
||||
: mDispatcher(dispatcher) {
|
||||
DriverBase::DriverBase() noexcept {
|
||||
if constexpr (UTILS_HAS_THREADING) {
|
||||
// This thread services user callbacks
|
||||
mServiceThread = std::thread([this]() {
|
||||
@@ -75,7 +72,6 @@ DriverBase::~DriverBase() noexcept {
|
||||
lock.unlock();
|
||||
mServiceThread.join();
|
||||
}
|
||||
delete mDispatcher;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -169,14 +165,6 @@ void DriverBase::debugCommandEnd(CommandStream* cmds, bool synchronous, const ch
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
Driver::~Driver() noexcept = default;
|
||||
|
||||
void Driver::execute(std::function<void(void)> fn) noexcept {
|
||||
fn();
|
||||
}
|
||||
|
||||
size_t Driver::getElementTypeSize(ElementType type) noexcept {
|
||||
switch (type) {
|
||||
case ElementType::BYTE: return sizeof(int8_t);
|
||||
@@ -208,5 +196,12 @@ size_t Driver::getElementTypeSize(ElementType type) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
Driver::~Driver() noexcept = default;
|
||||
|
||||
void Driver::execute(std::function<void(void)> const& fn) noexcept {
|
||||
fn();
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -22,14 +22,14 @@
|
||||
|
||||
#include <backend/Platform.h>
|
||||
|
||||
#include <backend/BufferDescriptor.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/CallbackHandler.h>
|
||||
|
||||
#include "private/backend/AcquiredImage.h"
|
||||
#include "private/backend/Dispatcher.h"
|
||||
#include "private/backend/Driver.h"
|
||||
#include "private/backend/SamplerGroup.h"
|
||||
|
||||
#include <array>
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class Dispatcher;
|
||||
struct AcquiredImage;
|
||||
|
||||
/*
|
||||
* Hardware handles
|
||||
@@ -72,7 +72,7 @@ struct HwBufferObject : public HwBase {
|
||||
uint32_t byteCount{};
|
||||
|
||||
HwBufferObject() noexcept = default;
|
||||
HwBufferObject(uint32_t byteCount) noexcept : byteCount(byteCount) {}
|
||||
explicit HwBufferObject(uint32_t byteCount) noexcept : byteCount(byteCount) {}
|
||||
};
|
||||
|
||||
struct HwIndexBuffer : public HwBase {
|
||||
@@ -98,12 +98,8 @@ struct HwRenderPrimitive : public HwBase {
|
||||
};
|
||||
|
||||
struct HwProgram : public HwBase {
|
||||
#ifndef NDEBUG
|
||||
utils::CString name;
|
||||
explicit HwProgram(utils::CString name) noexcept : name(std::move(name)) { }
|
||||
#else
|
||||
explicit HwProgram(const utils::CString&) noexcept { }
|
||||
#endif
|
||||
HwProgram() noexcept = default;
|
||||
};
|
||||
|
||||
@@ -171,21 +167,16 @@ struct HwTimerQuery : public HwBase {
|
||||
|
||||
class DriverBase : public Driver {
|
||||
public:
|
||||
DriverBase() = delete;
|
||||
explicit DriverBase(Dispatcher* dispatcher) noexcept;
|
||||
DriverBase() noexcept;
|
||||
~DriverBase() noexcept override;
|
||||
|
||||
void purge() noexcept final;
|
||||
|
||||
Dispatcher& getDispatcher() noexcept final { return *mDispatcher; }
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Privates
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
protected:
|
||||
Dispatcher* mDispatcher;
|
||||
|
||||
class CallbackDataDetails;
|
||||
|
||||
// Helpers...
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace filament::backend {
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
static char const * const kOurNamespace = "filament::";
|
||||
static char const * const kOurNamespace = "filament::backend";
|
||||
|
||||
// removes all occurrences of "what" from "str"
|
||||
UTILS_NOINLINE
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 "ExternalTextureManagerAndroid.h"
|
||||
|
||||
#include <utils/api_level.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
using namespace utils;
|
||||
|
||||
namespace filament {
|
||||
using namespace backend;
|
||||
|
||||
template <typename T>
|
||||
static void loadSymbol(T*& pfn, const char *symbol) noexcept {
|
||||
pfn = (T*)dlsym(RTLD_DEFAULT, symbol);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ndk {
|
||||
/*
|
||||
* This mimics the GraphicBuffer class for pre-API 26
|
||||
*/
|
||||
template<typename NATIVE_TYPE, typename REF>
|
||||
struct ANativeObjectBase : public NATIVE_TYPE, public REF {
|
||||
};
|
||||
|
||||
struct android_native_base_t {
|
||||
unsigned int magic;
|
||||
unsigned int version;
|
||||
void* reserved[4];
|
||||
void (* incRef)(struct android_native_base_t* base);
|
||||
void (* decRef)(struct android_native_base_t* base);
|
||||
};
|
||||
|
||||
struct ANativeWindowBuffer {
|
||||
struct android_native_base_t common;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int stride;
|
||||
unsigned int format;
|
||||
unsigned int usage_deprecated;
|
||||
uintptr_t layerCount;
|
||||
void* reserved[1];
|
||||
const void* handle;
|
||||
uint64_t usage;
|
||||
void* reserved_proc[8 - (sizeof(uint64_t) / sizeof(void*))];
|
||||
};
|
||||
|
||||
struct RefBase {
|
||||
virtual ~RefBase() = default;
|
||||
void* ref;
|
||||
};
|
||||
|
||||
struct GraphicBuffer : public ANativeObjectBase<ANativeWindowBuffer, RefBase> {
|
||||
};
|
||||
struct GraphicBufferWrapper {
|
||||
GraphicBuffer* graphicBuffer;
|
||||
};
|
||||
} // namespace ndk
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
using namespace ndk;
|
||||
|
||||
struct EGLExternalTexture : public ExternalTextureManagerAndroid::ExternalTexture {
|
||||
GraphicBufferWrapper* graphicBufferWrapper = nullptr;
|
||||
};
|
||||
|
||||
ExternalTextureManagerAndroid& ExternalTextureManagerAndroid::create() noexcept {
|
||||
return *(new ExternalTextureManagerAndroid{});
|
||||
}
|
||||
|
||||
void ExternalTextureManagerAndroid::destroy(ExternalTextureManagerAndroid* pExternalTextureManager) noexcept {
|
||||
delete pExternalTextureManager;
|
||||
}
|
||||
|
||||
// called on gl thread
|
||||
ExternalTextureManagerAndroid::ExternalTextureManagerAndroid() noexcept
|
||||
: mVm(VirtualMachineEnv::get()) {
|
||||
}
|
||||
|
||||
// not quite sure on which thread this is going to be called
|
||||
ExternalTextureManagerAndroid::~ExternalTextureManagerAndroid() noexcept {
|
||||
if (__builtin_available(android 26, *)) {
|
||||
} else {
|
||||
if (mGraphicBufferClass) {
|
||||
JNIEnv* env = VirtualMachineEnv::getThreadEnvironment();
|
||||
if (env) {
|
||||
env->DeleteGlobalRef(mGraphicBufferClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// called on gl thread
|
||||
backend::Platform::ExternalTexture* ExternalTextureManagerAndroid::createExternalTexture() noexcept {
|
||||
if (__builtin_available(android 26, *)) {
|
||||
} else {
|
||||
// initialize java stuff on-demand
|
||||
if (!mGraphicBufferClass) {
|
||||
JNIEnv* env = mVm.getEnvironment();
|
||||
mGraphicBufferClass = env->FindClass("android/view/GraphicBuffer");
|
||||
mGraphicBuffer_nCreateGraphicBuffer = env->GetStaticMethodID(
|
||||
mGraphicBufferClass, "nCreateGraphicBuffer", "(IIII)J");
|
||||
mGraphicBuffer_nDestroyGraphicBuffer = env->GetStaticMethodID(
|
||||
mGraphicBufferClass, "nDestroyGraphicBuffer", "(J)V");
|
||||
|
||||
mGraphicBufferClass = static_cast<jclass>(env->NewGlobalRef(mGraphicBufferClass));
|
||||
}
|
||||
}
|
||||
EGLExternalTexture* ets = new EGLExternalTexture;
|
||||
return ets;
|
||||
}
|
||||
|
||||
// called on app thread
|
||||
void ExternalTextureManagerAndroid::reallocate(
|
||||
backend::Platform::ExternalTexture* ets, uint32_t w, uint32_t h,
|
||||
backend::TextureFormat format, uint64_t usage) noexcept {
|
||||
destroyStorage(ets);
|
||||
alloc(ets, w, h, format, usage);
|
||||
}
|
||||
|
||||
// called on gl thread
|
||||
void ExternalTextureManagerAndroid::destroy(backend::Platform::ExternalTexture* ets) noexcept {
|
||||
destroyStorage(ets);
|
||||
delete static_cast<EGLExternalTexture*>(ets);
|
||||
}
|
||||
|
||||
// called on app thread
|
||||
void ExternalTextureManagerAndroid::alloc(
|
||||
backend::Platform::ExternalTexture* t,
|
||||
uint32_t w, uint32_t h, TextureFormat format, uint64_t usage) noexcept {
|
||||
|
||||
EGLExternalTexture* ets = static_cast<EGLExternalTexture*>(t);
|
||||
|
||||
AHardwareBuffer_Desc desc = { w, h, 1, 0, usage, 0, 0, 0 };
|
||||
switch (format) {
|
||||
case TextureFormat::RGB8:
|
||||
// don't use R8G8B8 here because some drivers produce garbled images
|
||||
desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
|
||||
break;
|
||||
case TextureFormat::RGBA8:
|
||||
desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
|
||||
break;
|
||||
case TextureFormat::RGB565:
|
||||
desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
|
||||
break;
|
||||
case TextureFormat::RGB10_A2:
|
||||
desc.format = AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
|
||||
break;
|
||||
default:
|
||||
slog.e << "Unsupported format " << (int)format << ", use RGBA8 or RGB8 only."
|
||||
<< io::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (__builtin_available(android 26, *)) {
|
||||
// allocate new storage...
|
||||
AHardwareBuffer* buffer = nullptr;
|
||||
if (AHardwareBuffer_allocate(&desc, &buffer) < 0) {
|
||||
slog.e << "AHardwareBuffer_allocate() failed" << io::endl;
|
||||
return;
|
||||
}
|
||||
ets->hardwareBuffer = buffer;
|
||||
} else {
|
||||
// note: This is called on the application thread (not the GL thread)
|
||||
JNIEnv* env = VirtualMachineEnv::getThreadEnvironment();
|
||||
if (!env) {
|
||||
return; // this should not happen
|
||||
}
|
||||
|
||||
jlong graphicBufferWrapperJni = env->CallStaticLongMethod(mGraphicBufferClass,
|
||||
mGraphicBuffer_nCreateGraphicBuffer, w, h, desc.format, usage);
|
||||
VirtualMachineEnv::handleException(env);
|
||||
|
||||
if (graphicBufferWrapperJni) {
|
||||
GraphicBuffer* const gb = ((GraphicBufferWrapper*)graphicBufferWrapperJni)->graphicBuffer;
|
||||
ets->graphicBufferWrapper = (GraphicBufferWrapper*)graphicBufferWrapperJni;
|
||||
ets->clientBuffer = static_cast<ANativeWindowBuffer*>(gb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// called on gl thread
|
||||
void ExternalTextureManagerAndroid::destroyStorage(backend::Platform::ExternalTexture* t) noexcept {
|
||||
EGLExternalTexture* ets = static_cast<EGLExternalTexture*>(t);
|
||||
if (__builtin_available(android 26, *)) {
|
||||
// destroy the current storage if any
|
||||
if (ets->hardwareBuffer) {
|
||||
AHardwareBuffer_release(ets->hardwareBuffer);
|
||||
ets->hardwareBuffer = nullptr;
|
||||
}
|
||||
} else {
|
||||
if (ets->graphicBufferWrapper) {
|
||||
JNIEnv* env = VirtualMachineEnv::get().getEnvironment();
|
||||
env->CallStaticVoidMethod(mGraphicBufferClass,
|
||||
mGraphicBuffer_nDestroyGraphicBuffer, (jlong)ets->graphicBufferWrapper);
|
||||
VirtualMachineEnv::handleException(env);
|
||||
ets->graphicBufferWrapper = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_TEXTURE_MANAGER_ANDROID_H
|
||||
#define TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_TEXTURE_MANAGER_ANDROID_H
|
||||
|
||||
#include "private/backend/VirtualMachineEnv.h"
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Platform.h>
|
||||
|
||||
#include <android/api-level.h>
|
||||
#include <android/hardware_buffer.h>
|
||||
|
||||
namespace filament {
|
||||
|
||||
/*
|
||||
* ExternalTextureManagerAndroid::ExternalTexture is basically a wrapper for AHardwareBuffer.
|
||||
*
|
||||
* This class doesn't rely on GL or EGL, and could be used for other Android platform if needed
|
||||
* (e.g. Vulkan).
|
||||
*
|
||||
* ExternalTextureManagerAndroid handle allocation/destruction using either Java or the NDK,
|
||||
* whichever is available.
|
||||
*/
|
||||
class ExternalTextureManagerAndroid {
|
||||
public:
|
||||
|
||||
struct ExternalTexture : public backend::Platform::ExternalTexture {
|
||||
void* clientBuffer = nullptr;
|
||||
AHardwareBuffer* hardwareBuffer = nullptr;
|
||||
};
|
||||
|
||||
// must be called on backend thread
|
||||
static ExternalTextureManagerAndroid& create() noexcept;
|
||||
|
||||
// must be called on backend thread
|
||||
static void destroy(ExternalTextureManagerAndroid* pExternalTextureManager) noexcept;
|
||||
|
||||
// must be called on backend thread (only because we don't synchronize
|
||||
backend::Platform::ExternalTexture* createExternalTexture() noexcept;
|
||||
|
||||
// called on app thread
|
||||
void reallocate(
|
||||
backend::Platform::ExternalTexture* ets, uint32_t w, uint32_t h,
|
||||
backend::TextureFormat format, uint64_t usage) noexcept;
|
||||
|
||||
// must be called on backend thread
|
||||
void destroy(backend::Platform::ExternalTexture* ets) noexcept;
|
||||
|
||||
private:
|
||||
ExternalTextureManagerAndroid() noexcept;
|
||||
~ExternalTextureManagerAndroid() noexcept;
|
||||
|
||||
// called on app thread
|
||||
void alloc(backend::Platform::ExternalTexture* ets,
|
||||
uint32_t w, uint32_t h, backend::TextureFormat format, uint64_t usage) noexcept;
|
||||
|
||||
// called on gl thread
|
||||
void destroyStorage(backend::Platform::ExternalTexture* ets) noexcept;
|
||||
|
||||
VirtualMachineEnv& mVm;
|
||||
|
||||
jclass mGraphicBufferClass = nullptr;
|
||||
jmethodID mGraphicBuffer_nCreateGraphicBuffer = nullptr;
|
||||
jmethodID mGraphicBuffer_nDestroyGraphicBuffer = nullptr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_TEXTURE_MANAGER_ANDROID_H
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
struct MetalContext;
|
||||
|
||||
@@ -45,7 +44,7 @@ public:
|
||||
uint32_t slice = 0; // must be 0 on source attachment
|
||||
};
|
||||
|
||||
// Valid source formats: 2D, 2DMultisample, 3D
|
||||
// Valid source formats: 2D, 2DArray, 2DMultisample, 3D
|
||||
// Valid destination formats: 2D, 2DArray, 3D, Cube
|
||||
Attachment source, destination;
|
||||
SamplerMagFilter filter;
|
||||
@@ -133,7 +132,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
#include "MetalBlitter.h"
|
||||
|
||||
#include "MetalContext.h"
|
||||
#include "MetalUtils.h"
|
||||
|
||||
#include <utils/Panic.h>
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
static const char* functionLibrary = R"(
|
||||
#include <metal_stdlib>
|
||||
@@ -145,8 +145,6 @@ void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args) {
|
||||
bool blitColor = args.blitColor();
|
||||
bool blitDepth = args.blitDepth();
|
||||
|
||||
ASSERT_PRECONDITION(args.source.slice == 0u, "Source attachment must have slice of 0.");
|
||||
|
||||
ASSERT_PRECONDITION(args.source.region.size.depth == args.destination.region.size.depth,
|
||||
"Blitting requires the source and destination regions to have the same depth.");
|
||||
|
||||
@@ -223,7 +221,7 @@ void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
|
||||
|
||||
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
|
||||
[blitEncoder copyFromTexture:args.source.color
|
||||
sourceSlice:0
|
||||
sourceSlice:args.source.slice
|
||||
sourceLevel:args.source.level
|
||||
sourceOrigin:args.source.region.origin
|
||||
sourceSize:args.source.region.size
|
||||
@@ -244,7 +242,7 @@ void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
|
||||
|
||||
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
|
||||
[blitEncoder copyFromTexture:args.source.depth
|
||||
sourceSlice:0
|
||||
sourceSlice:args.source.slice
|
||||
sourceLevel:args.source.level
|
||||
sourceOrigin:args.source.region.origin
|
||||
sourceSize:args.source.region.size
|
||||
@@ -301,7 +299,7 @@ void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor
|
||||
}
|
||||
id<MTLFunction> fragmentFunction = getBlitFragmentFunction(key);
|
||||
|
||||
PipelineState pipelineState {
|
||||
MetalPipelineState pipelineState {
|
||||
.vertexFunction = getBlitVertexFunction(),
|
||||
.fragmentFunction = fragmentFunction,
|
||||
.vertexDescription = {},
|
||||
@@ -323,12 +321,22 @@ void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor
|
||||
id<MTLRenderPipelineState> pipeline = mContext.pipelineStateCache.getOrCreateState(pipelineState);
|
||||
[encoder setRenderPipelineState:pipeline];
|
||||
|
||||
// For texture arrays, create a view of the texture at the given slice (layer).
|
||||
id<MTLTexture> srcTextureColor = args.source.color;
|
||||
if (srcTextureColor && srcTextureColor.textureType == MTLTextureType2DArray) {
|
||||
srcTextureColor = createTextureViewWithSingleSlice(srcTextureColor, args.source.slice);
|
||||
}
|
||||
id<MTLTexture> srcTextureDepth = args.source.depth;
|
||||
if (srcTextureDepth && srcTextureDepth.textureType == MTLTextureType2DArray) {
|
||||
srcTextureDepth = createTextureViewWithSingleSlice(srcTextureDepth, args.source.slice);
|
||||
}
|
||||
|
||||
if (blitColor) {
|
||||
[encoder setFragmentTexture:args.source.color atIndex:0];
|
||||
[encoder setFragmentTexture:srcTextureColor atIndex:0];
|
||||
}
|
||||
|
||||
if (blitDepth) {
|
||||
[encoder setFragmentTexture:args.source.depth atIndex:1];
|
||||
[encoder setFragmentTexture:srcTextureDepth atIndex:1];
|
||||
}
|
||||
|
||||
SamplerMinFilter filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST;
|
||||
@@ -521,6 +529,5 @@ id<MTLFunction> MetalBlitter::getBlitFragmentFunction(BlitFunctionKey key) {
|
||||
return function;
|
||||
}
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
class MetalBuffer {
|
||||
public:
|
||||
@@ -94,7 +93,6 @@ private:
|
||||
void copyIntoStreamBuffer(void* src, size_t size);
|
||||
};
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
MetalBuffer::MetalBuffer(MetalContext& context, BufferUsage usage, size_t size, bool forceGpuBuffer)
|
||||
: mBufferSize(size), mContext(context) {
|
||||
@@ -206,6 +205,5 @@ void MetalBuffer::bindBuffers(id<MTLCommandBuffer> cmdBuffer, id<MTLRenderComman
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
struct MetalContext;
|
||||
|
||||
@@ -78,7 +77,6 @@ private:
|
||||
static constexpr uint32_t TIME_BEFORE_EVICTION = 10;
|
||||
};
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
MetalBufferPoolEntry const* MetalBufferPool::acquireBuffer(size_t numBytes) {
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
@@ -110,6 +109,5 @@ void MetalBufferPool::reset() noexcept {
|
||||
mFreeStages.clear();
|
||||
}
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -36,14 +36,13 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
class MetalDriver;
|
||||
class MetalBlitter;
|
||||
class MetalBufferPool;
|
||||
class MetalRenderTarget;
|
||||
class MetalSwapChain;
|
||||
class TimerQueryInterface;
|
||||
class MetalTimerQueryInterface;
|
||||
struct MetalUniformBuffer;
|
||||
struct MetalIndexBuffer;
|
||||
struct MetalSamplerGroup;
|
||||
@@ -113,7 +112,7 @@ struct MetalContext {
|
||||
MTLSharedEventListener* eventListener = nil;
|
||||
uint64_t signalId = 1;
|
||||
|
||||
TimerQueryInterface* timerQueryImpl;
|
||||
MetalTimerQueryInterface* timerQueryImpl;
|
||||
|
||||
std::stack<const char*> groupMarkers;
|
||||
|
||||
@@ -134,7 +133,6 @@ id<MTLTexture> getOrCreateEmptyTexture(MetalContext* context);
|
||||
|
||||
bool isInRenderPass(MetalContext* context);
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
void initializeSupportedGpuFamilies(MetalContext* context) {
|
||||
auto& highestSupportedFamily = context->highestSupportedGpuFamily;
|
||||
@@ -145,6 +144,5 @@ bool isInRenderPass(MetalContext* context) {
|
||||
return context->currentRenderPassEncoder != nil;
|
||||
}
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -31,8 +31,6 @@ namespace backend {
|
||||
|
||||
class MetalPlatform;
|
||||
|
||||
namespace metal {
|
||||
|
||||
class MetalBuffer;
|
||||
struct MetalUniformBuffer;
|
||||
struct MetalContext;
|
||||
@@ -44,31 +42,32 @@ struct UniformBufferState;
|
||||
#endif
|
||||
|
||||
class MetalDriver final : public DriverBase {
|
||||
explicit MetalDriver(backend::MetalPlatform* platform) noexcept;
|
||||
explicit MetalDriver(MetalPlatform* platform) noexcept;
|
||||
~MetalDriver() noexcept override;
|
||||
Dispatcher getDispatcher() const noexcept final;
|
||||
|
||||
public:
|
||||
static Driver* create(backend::MetalPlatform* platform);
|
||||
static Driver* create(MetalPlatform* platform);
|
||||
|
||||
private:
|
||||
|
||||
friend class MetalSwapChain;
|
||||
|
||||
backend::MetalPlatform& mPlatform;
|
||||
MetalPlatform& mPlatform;
|
||||
|
||||
MetalContext* mContext;
|
||||
|
||||
ShaderModel getShaderModel() const noexcept final;
|
||||
|
||||
// Overrides the default implementation by wrapping the call to fn in an @autoreleasepool block.
|
||||
void execute(std::function<void(void)> fn) noexcept final;
|
||||
void execute(std::function<void(void)> const& fn) noexcept final;
|
||||
|
||||
/*
|
||||
* Driver interface
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
friend class backend::ConcreteDispatcher;
|
||||
friend class ConcreteDispatcher;
|
||||
|
||||
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
|
||||
UTILS_ALWAYS_INLINE inline void methodName(paramsDecl);
|
||||
@@ -86,7 +85,7 @@ private:
|
||||
* Memory management
|
||||
*/
|
||||
|
||||
backend::HandleAllocatorMTL mHandleAllocator;
|
||||
HandleAllocatorMTL mHandleAllocator;
|
||||
|
||||
template<typename D>
|
||||
Handle<D> alloc_handle() {
|
||||
@@ -126,7 +125,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -41,22 +41,23 @@ namespace filament {
|
||||
namespace backend {
|
||||
|
||||
Driver* MetalDriverFactory::create(MetalPlatform* const platform) {
|
||||
return metal::MetalDriver::create(platform);
|
||||
return MetalDriver::create(platform);
|
||||
}
|
||||
|
||||
namespace metal {
|
||||
|
||||
UTILS_NOINLINE
|
||||
Driver* MetalDriver::create(MetalPlatform* const platform) {
|
||||
assert_invariant(platform);
|
||||
return new MetalDriver(platform);
|
||||
}
|
||||
|
||||
MetalDriver::MetalDriver(backend::MetalPlatform* platform) noexcept
|
||||
: DriverBase(new ConcreteDispatcher<MetalDriver>()),
|
||||
mPlatform(*platform),
|
||||
mContext(new MetalContext),
|
||||
mHandleAllocator("Handles", FILAMENT_METAL_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U) {
|
||||
Dispatcher MetalDriver::getDispatcher() const noexcept {
|
||||
return ConcreteDispatcher<MetalDriver>::make();
|
||||
}
|
||||
|
||||
MetalDriver::MetalDriver(MetalPlatform* platform) noexcept
|
||||
: mPlatform(*platform),
|
||||
mContext(new MetalContext),
|
||||
mHandleAllocator("Handles", FILAMENT_METAL_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U) {
|
||||
mContext->driver = this;
|
||||
|
||||
mContext->device = mPlatform.createDevice();
|
||||
@@ -108,7 +109,7 @@ MetalDriver::MetalDriver(backend::MetalPlatform* platform) noexcept
|
||||
mContext->blitter = new MetalBlitter(*mContext);
|
||||
|
||||
if (@available(iOS 12, *)) {
|
||||
mContext->timerQueryImpl = new TimerQueryFence(*mContext);
|
||||
mContext->timerQueryImpl = new MetalTimerQueryFence(*mContext);
|
||||
} else {
|
||||
mContext->timerQueryImpl = new TimerQueryNoop();
|
||||
}
|
||||
@@ -149,18 +150,18 @@ void MetalDriver::beginFrame(int64_t monotonic_clock_ns, uint32_t frameId) {
|
||||
}
|
||||
|
||||
void MetalDriver::setFrameScheduledCallback(Handle<HwSwapChain> sch,
|
||||
backend::FrameScheduledCallback callback, void* user) {
|
||||
FrameScheduledCallback callback, void* user) {
|
||||
auto* swapChain = handle_cast<MetalSwapChain>(sch);
|
||||
swapChain->setFrameScheduledCallback(callback, user);
|
||||
}
|
||||
|
||||
void MetalDriver::setFrameCompletedCallback(Handle<HwSwapChain> sch,
|
||||
backend::FrameCompletedCallback callback, void* user) {
|
||||
FrameCompletedCallback callback, void* user) {
|
||||
auto* swapChain = handle_cast<MetalSwapChain>(sch);
|
||||
swapChain->setFrameCompletedCallback(callback, user);
|
||||
}
|
||||
|
||||
void MetalDriver::execute(std::function<void(void)> fn) noexcept {
|
||||
void MetalDriver::execute(std::function<void(void)> const& fn) noexcept {
|
||||
@autoreleasepool {
|
||||
fn();
|
||||
}
|
||||
@@ -291,7 +292,7 @@ void MetalDriver::createDefaultRenderTargetR(Handle<HwRenderTarget> rth, int dum
|
||||
|
||||
void MetalDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
|
||||
TargetBufferFlags targetBufferFlags, uint32_t width, uint32_t height,
|
||||
uint8_t samples, backend::MRT color,
|
||||
uint8_t samples, MRT color,
|
||||
TargetBufferInfo depth, TargetBufferInfo stencil) {
|
||||
// Clamp sample count to what the device supports.
|
||||
auto& sc = mContext->sampleCountLookup;
|
||||
@@ -344,7 +345,7 @@ void MetalDriver::createSyncR(Handle<HwSync> sh, int) {
|
||||
}
|
||||
|
||||
void MetalDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow, uint64_t flags) {
|
||||
if (UTILS_UNLIKELY(flags & backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER)) {
|
||||
if (UTILS_UNLIKELY(flags & SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER)) {
|
||||
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef) nativeWindow;
|
||||
construct_handle<MetalSwapChain>(sch, *mContext, pixelBuffer, flags);
|
||||
} else {
|
||||
@@ -358,10 +359,6 @@ void MetalDriver::createSwapChainHeadlessR(Handle<HwSwapChain> sch,
|
||||
construct_handle<MetalSwapChain>(sch, *mContext, width, height, flags);
|
||||
}
|
||||
|
||||
void MetalDriver::createStreamFromTextureIdR(Handle<HwStream>, intptr_t externalTextureId,
|
||||
uint32_t width, uint32_t height) {
|
||||
}
|
||||
|
||||
void MetalDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, int) {
|
||||
// nothing to do, timer query was constructed in createTimerQueryS
|
||||
}
|
||||
@@ -430,10 +427,6 @@ Handle<HwSwapChain> MetalDriver::createSwapChainHeadlessS() noexcept {
|
||||
return alloc_handle<MetalSwapChain>();
|
||||
}
|
||||
|
||||
Handle<HwStream> MetalDriver::createStreamFromTextureIdS() noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
Handle<HwTimerQuery> MetalDriver::createTimerQueryS() noexcept {
|
||||
// The handle must be constructed here, as a synchronous call to getTimerQueryValue might happen
|
||||
// before createTimerQueryR is executed.
|
||||
@@ -569,7 +562,7 @@ Handle<HwStream> MetalDriver::createStreamAcquired() {
|
||||
}
|
||||
|
||||
void MetalDriver::setAcquiredImage(Handle<HwStream> sh, void* image,
|
||||
backend::CallbackHandler* handler, backend::StreamCallback cb, void* userData) {
|
||||
CallbackHandler* handler, StreamCallback cb, void* userData) {
|
||||
}
|
||||
|
||||
void MetalDriver::setStreamDimensions(Handle<HwStream> stream, uint32_t width,
|
||||
@@ -581,7 +574,7 @@ int64_t MetalDriver::getStreamTimestamp(Handle<HwStream> stream) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MetalDriver::updateStreams(backend::DriverApi* driver) {
|
||||
void MetalDriver::updateStreams(DriverApi* driver) {
|
||||
|
||||
}
|
||||
|
||||
@@ -1052,14 +1045,9 @@ void MetalDriver::readPixels(Handle<HwRenderTarget> src, uint32_t x, uint32_t y,
|
||||
}];
|
||||
}
|
||||
|
||||
void MetalDriver::readStreamPixels(Handle<HwStream> sh, uint32_t x, uint32_t y, uint32_t width,
|
||||
uint32_t height, PixelBufferDescriptor&& data) {
|
||||
|
||||
}
|
||||
|
||||
void MetalDriver::blit(TargetBufferFlags buffers,
|
||||
Handle<HwRenderTarget> dst, backend::Viewport dstRect,
|
||||
Handle<HwRenderTarget> src, backend::Viewport srcRect,
|
||||
Handle<HwRenderTarget> dst, Viewport dstRect,
|
||||
Handle<HwRenderTarget> src, Viewport srcRect,
|
||||
SamplerMagFilter filter) {
|
||||
// If we're the in middle of a render pass, finish it.
|
||||
// This condition should only occur during copyFrame. It's okay to end the render pass because
|
||||
@@ -1099,7 +1087,8 @@ void MetalDriver::blit(TargetBufferFlags buffers,
|
||||
dstRect.width, dstRect.height);
|
||||
|
||||
auto isBlitableTextureType = [](MTLTextureType t) {
|
||||
return t == MTLTextureType2D || t == MTLTextureType2DMultisample;
|
||||
return t == MTLTextureType2D || t == MTLTextureType2DMultisample ||
|
||||
t == MTLTextureType2DArray;
|
||||
};
|
||||
|
||||
MetalBlitter::BlitArgs args;
|
||||
@@ -1121,6 +1110,8 @@ void MetalDriver::blit(TargetBufferFlags buffers,
|
||||
args.destination.color = dstColorAttachment.getTexture();
|
||||
args.source.level = srcColorAttachment.level;
|
||||
args.destination.level = dstColorAttachment.level;
|
||||
args.source.slice = srcColorAttachment.layer;
|
||||
args.destination.slice = dstColorAttachment.layer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1137,25 +1128,33 @@ void MetalDriver::blit(TargetBufferFlags buffers,
|
||||
args.destination.depth = dstDepthAttachment.getTexture();
|
||||
|
||||
if (args.blitColor()) {
|
||||
// If blitting color, we've already set the source and destination levels.
|
||||
// Check that they match the requested depth levels.
|
||||
// If blitting color, we've already set the source and destination levels and slices.
|
||||
// Check that they match the requested depth levels/slices.
|
||||
ASSERT_PRECONDITION(args.source.level == srcDepthAttachment.level,
|
||||
"Color and depth source LOD must match. (%d != %d)",
|
||||
args.source.level, srcDepthAttachment.level);
|
||||
ASSERT_PRECONDITION(args.destination.level == dstDepthAttachment.level,
|
||||
"Color and depth destination LOD must match. (%d != %d)",
|
||||
args.destination.level, dstDepthAttachment.level);
|
||||
ASSERT_PRECONDITION(args.source.slice == srcDepthAttachment.layer,
|
||||
"Color and depth source layer must match. (%d != %d)",
|
||||
args.source.slice, srcDepthAttachment.layer);
|
||||
ASSERT_PRECONDITION(args.destination.slice == dstDepthAttachment.layer,
|
||||
"Color and depth destination layer must match. (%d != %d)",
|
||||
args.destination.slice, dstDepthAttachment.layer);
|
||||
}
|
||||
|
||||
args.source.level = srcDepthAttachment.level;
|
||||
args.destination.level = dstDepthAttachment.level;
|
||||
args.source.slice = srcDepthAttachment.layer;
|
||||
args.destination.slice = dstDepthAttachment.layer;
|
||||
}
|
||||
}
|
||||
|
||||
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
|
||||
}
|
||||
|
||||
void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t instanceCount) {
|
||||
void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t instanceCount) {
|
||||
ASSERT_PRECONDITION(mContext->currentRenderPassEncoder != nullptr,
|
||||
"Attempted to draw without a valid command encoder.");
|
||||
auto primitive = handle_cast<MetalRenderPrimitive>(rph);
|
||||
@@ -1185,7 +1184,7 @@ void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph,
|
||||
if (depthAttachment) {
|
||||
depthPixelFormat = depthAttachment.getPixelFormat();
|
||||
}
|
||||
metal::PipelineState pipelineState {
|
||||
MetalPipelineState pipelineState {
|
||||
.vertexFunction = program->vertexFunction,
|
||||
.fragmentFunction = program->fragmentFunction,
|
||||
.vertexDescription = primitive->vertexDescription,
|
||||
@@ -1293,15 +1292,15 @@ void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph,
|
||||
return mContext->samplerStateCache.getOrCreateState(s);
|
||||
};
|
||||
|
||||
id<MTLTexture> texturesToBindVertex[backend::MAX_VERTEX_SAMPLER_COUNT] = {};
|
||||
id<MTLSamplerState> samplersToBindVertex[backend::MAX_VERTEX_SAMPLER_COUNT] = {};
|
||||
id<MTLTexture> texturesToBindVertex[MAX_VERTEX_SAMPLER_COUNT] = {};
|
||||
id<MTLSamplerState> samplersToBindVertex[MAX_VERTEX_SAMPLER_COUNT] = {};
|
||||
|
||||
enumerateSamplerGroups(program, ShaderType::VERTEX,
|
||||
[this, &getTextureToBind, &getSamplerToBind, &texturesToBindVertex, &samplersToBindVertex](
|
||||
const SamplerGroup::Sampler* sampler, uint8_t binding) {
|
||||
// We currently only support a max of MAX_VERTEX_SAMPLER_COUNT samplers. Ignore any additional
|
||||
// samplers that may be bound.
|
||||
if (binding >= backend::MAX_VERTEX_SAMPLER_COUNT) {
|
||||
if (binding >= MAX_VERTEX_SAMPLER_COUNT) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1325,21 +1324,21 @@ void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph,
|
||||
}
|
||||
}
|
||||
|
||||
NSRange vertexSamplerRange = NSMakeRange(0, backend::MAX_VERTEX_SAMPLER_COUNT);
|
||||
NSRange vertexSamplerRange = NSMakeRange(0, MAX_VERTEX_SAMPLER_COUNT);
|
||||
[mContext->currentRenderPassEncoder setVertexTextures:texturesToBindVertex
|
||||
withRange:vertexSamplerRange];
|
||||
[mContext->currentRenderPassEncoder setVertexSamplerStates:samplersToBindVertex
|
||||
withRange:vertexSamplerRange];
|
||||
|
||||
id<MTLTexture> texturesToBindFragment[backend::MAX_FRAGMENT_SAMPLER_COUNT] = {};
|
||||
id<MTLSamplerState> samplersToBindFragment[backend::MAX_FRAGMENT_SAMPLER_COUNT] = {};
|
||||
id<MTLTexture> texturesToBindFragment[MAX_FRAGMENT_SAMPLER_COUNT] = {};
|
||||
id<MTLSamplerState> samplersToBindFragment[MAX_FRAGMENT_SAMPLER_COUNT] = {};
|
||||
|
||||
enumerateSamplerGroups(program, ShaderType::FRAGMENT,
|
||||
[this, &getTextureToBind, &getSamplerToBind, &texturesToBindFragment, &samplersToBindFragment](
|
||||
const SamplerGroup::Sampler* sampler, uint8_t binding) {
|
||||
// We currently only support a max of MAX_FRAGMENT_SAMPLER_COUNT samplers. Ignore any additional
|
||||
// samplers that may be bound.
|
||||
if (binding >= backend::MAX_FRAGMENT_SAMPLER_COUNT) {
|
||||
if (binding >= MAX_FRAGMENT_SAMPLER_COUNT) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1363,7 +1362,7 @@ void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph,
|
||||
}
|
||||
}
|
||||
|
||||
NSRange fragmentSamplerRange = NSMakeRange(0, backend::MAX_FRAGMENT_SAMPLER_COUNT);
|
||||
NSRange fragmentSamplerRange = NSMakeRange(0, MAX_FRAGMENT_SAMPLER_COUNT);
|
||||
[mContext->currentRenderPassEncoder setFragmentTextures:texturesToBindFragment
|
||||
withRange:fragmentSamplerRange];
|
||||
[mContext->currentRenderPassEncoder setFragmentSamplerStates:samplersToBindFragment
|
||||
@@ -1468,10 +1467,8 @@ void MetalDriver::enumerateBoundUniformBuffers(
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace metal
|
||||
|
||||
// explicit instantiation of the Dispatcher
|
||||
template class ConcreteDispatcher<metal::MetalDriver>;
|
||||
template class ConcreteDispatcher<MetalDriver>;
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -24,7 +24,7 @@ class Driver;
|
||||
|
||||
class MetalDriverFactory {
|
||||
public:
|
||||
static Driver* create(backend::MetalPlatform* platform);
|
||||
static Driver* create(MetalPlatform* platform);
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
struct MetalContext;
|
||||
|
||||
@@ -405,7 +404,6 @@ inline MTLTextureSwizzleChannels getSwizzleChannels(TextureSwizzle r, TextureSwi
|
||||
getSwizzle(a));
|
||||
}
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
MTLPixelFormat getMetalFormat(MetalContext* context, TextureFormat format) noexcept {
|
||||
switch (format) {
|
||||
@@ -207,6 +206,5 @@ MTLPixelFormat getMetalFormat(MetalContext* context, TextureFormat format) noexc
|
||||
return MTLPixelFormatInvalid;
|
||||
}
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
struct MetalContext;
|
||||
|
||||
@@ -129,7 +128,6 @@ private:
|
||||
} mSwizzle;
|
||||
};
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
static const auto cvBufferDeleter = [](const void* buffer) {
|
||||
CVBufferRelease((CVMetalTextureRef) buffer);
|
||||
@@ -300,6 +299,5 @@ id<MTLCommandBuffer> MetalExternalImage::encodeColorConversionPass(id<MTLTexture
|
||||
return commandBuffer;
|
||||
}
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
class MetalSwapChain : public HwSwapChain {
|
||||
public:
|
||||
@@ -357,7 +356,6 @@ struct MetalTimerQuery : public HwTimerQuery {
|
||||
std::shared_ptr<Status> status;
|
||||
};
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
static inline MTLTextureUsage getMetalTextureUsage(TextureUsage usage) {
|
||||
NSUInteger u = 0;
|
||||
@@ -68,9 +67,8 @@ MetalSwapChain::MetalSwapChain(MetalContext& context, CAMetalLayer* nativeWindow
|
||||
}
|
||||
|
||||
// Needed so we can use the SwapChain as a blit source.
|
||||
if (flags & SwapChain::CONFIG_READABLE) {
|
||||
nativeWindow.framebufferOnly = NO;
|
||||
}
|
||||
// Also needed for rendering directly into the SwapChain during refraction.
|
||||
nativeWindow.framebufferOnly = NO;
|
||||
|
||||
layer.device = context.device;
|
||||
}
|
||||
@@ -81,7 +79,7 @@ MetalSwapChain::MetalSwapChain(MetalContext& context, int32_t width, int32_t hei
|
||||
|
||||
MetalSwapChain::MetalSwapChain(MetalContext& context, CVPixelBufferRef pixelBuffer, uint64_t flags)
|
||||
: context(context), externalImage(context), type(SwapChainType::CVPIXELBUFFERREF) {
|
||||
assert_invariant(flags & backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER);
|
||||
assert_invariant(flags & SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER);
|
||||
MetalExternalImage::assertWritableImage(pixelBuffer);
|
||||
externalImage.set(pixelBuffer);
|
||||
assert_invariant(externalImage.isValid());
|
||||
@@ -224,7 +222,7 @@ void MetalSwapChain::scheduleFrameScheduledCallback() {
|
||||
}
|
||||
|
||||
assert_invariant(drawable);
|
||||
backend::FrameScheduledCallback callback = frameScheduledCallback;
|
||||
FrameScheduledCallback callback = frameScheduledCallback;
|
||||
// This block strongly captures drawable to keep it alive until the handler executes.
|
||||
// We cannot simply reference this->drawable inside the block because the block would then only
|
||||
// capture the _this_ pointer (MetalSwapChain*) instead of the drawable.
|
||||
@@ -245,12 +243,12 @@ void MetalSwapChain::scheduleFrameCompletedCallback() {
|
||||
return;
|
||||
}
|
||||
|
||||
backend::FrameCompletedCallback callback = frameCompletedCallback;
|
||||
FrameCompletedCallback callback = frameCompletedCallback;
|
||||
void* userData = frameCompletedUserData;
|
||||
[getPendingCommandBuffer(&context) addCompletedHandler:^(id<MTLCommandBuffer> cb) {
|
||||
struct CallbackData {
|
||||
void* userData;
|
||||
backend::FrameCompletedCallback callback;
|
||||
FrameCompletedCallback callback;
|
||||
};
|
||||
CallbackData* data = new CallbackData();
|
||||
data->userData = userData;
|
||||
@@ -369,7 +367,7 @@ MetalProgram::MetalProgram(id<MTLDevice> device, const Program& program) noexcep
|
||||
*shaderFunctions[i] = [library newFunctionWithName:@"main0"];
|
||||
}
|
||||
|
||||
// All stages of the program have compiled successfuly, this is a valid program.
|
||||
// All stages of the program have compiled successfully, this is a valid program.
|
||||
isValid = true;
|
||||
|
||||
// This calculates Metal resource binding indices. Filament's sampler bindings range from 0-31
|
||||
@@ -1024,6 +1022,5 @@ FenceStatus MetalFence::wait(uint64_t timeoutNs) {
|
||||
return FenceStatus::ERROR;
|
||||
}
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
bool MetalResourceTracker::trackResource(CommandBuffer buffer, Resource resource,
|
||||
ResourceDeleter deleter) {
|
||||
@@ -53,6 +52,5 @@ void MetalResourceTracker::clearResources(CommandBuffer buffer) {
|
||||
mResources.erase(found);
|
||||
}
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
/**
|
||||
* MetalResourceTracker is a simple utility that maps individual command buffers to a set of
|
||||
@@ -76,7 +75,6 @@ private:
|
||||
std::mutex mMutex;
|
||||
};
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -31,24 +31,21 @@
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
|
||||
inline bool operator==(const backend::SamplerParams& lhs, const backend::SamplerParams& rhs) {
|
||||
inline bool operator==(const SamplerParams& lhs, const SamplerParams& rhs) {
|
||||
return lhs.u == rhs.u;
|
||||
}
|
||||
|
||||
namespace metal {
|
||||
|
||||
static constexpr uint32_t MAX_VERTEX_ATTRIBUTE_COUNT = backend::MAX_VERTEX_ATTRIBUTE_COUNT;
|
||||
static constexpr uint32_t SAMPLER_GROUP_COUNT = Program::BINDING_COUNT;
|
||||
static constexpr uint32_t SAMPLER_BINDING_COUNT = backend::MAX_SAMPLER_COUNT;
|
||||
static constexpr uint32_t SAMPLER_BINDING_COUNT = MAX_SAMPLER_COUNT;
|
||||
static constexpr uint32_t VERTEX_BUFFER_START = Program::BINDING_COUNT;
|
||||
|
||||
// The "zero" buffer is a small buffer for missing attributes that resides in the vertex slot
|
||||
// immediately following any user-provided vertex buffers.
|
||||
static constexpr uint32_t ZERO_VERTEX_BUFFER = backend::MAX_VERTEX_BUFFER_COUNT;
|
||||
static constexpr uint32_t ZERO_VERTEX_BUFFER = MAX_VERTEX_BUFFER_COUNT;
|
||||
|
||||
// The total number of vertex buffer "slots" that the Metal backend can bind.
|
||||
// + 1 to account for the zero buffer.
|
||||
static constexpr uint32_t VERTEX_BUFFER_COUNT = backend::MAX_VERTEX_BUFFER_COUNT + 1;
|
||||
static constexpr uint32_t VERTEX_BUFFER_COUNT = MAX_VERTEX_BUFFER_COUNT + 1;
|
||||
|
||||
// Forward declarations necessary here, definitions at end of file.
|
||||
inline bool operator==(const MTLViewport& lhs, const MTLViewport& rhs);
|
||||
@@ -173,7 +170,7 @@ private:
|
||||
};
|
||||
|
||||
// StateTracker keeps track of state changes made to a Metal command encoder.
|
||||
// Different kinds of state, like pipeline state, uniform buffer state, etc, are passed to the
|
||||
// Different kinds of state, like pipeline state, uniform buffer state, etc., are passed to the
|
||||
// current Metal command encoder and persist throughout the lifetime of the encoder (a frame).
|
||||
// StateTracker is used to prevent calling redundant state change methods.
|
||||
template<typename StateType>
|
||||
@@ -212,7 +209,7 @@ private:
|
||||
|
||||
// Pipeline state
|
||||
|
||||
struct PipelineState {
|
||||
struct MetalPipelineState {
|
||||
id<MTLFunction> vertexFunction = nil; // 8 bytes
|
||||
id<MTLFunction> fragmentFunction = nil; // 8 bytes
|
||||
VertexDescription vertexDescription; // 528 bytes
|
||||
@@ -223,7 +220,7 @@ struct PipelineState {
|
||||
bool colorWrite = true; // 1 byte
|
||||
char padding[7] = { 0 }; // 7 bytes
|
||||
|
||||
bool operator==(const PipelineState& rhs) const noexcept {
|
||||
bool operator==(const MetalPipelineState& rhs) const noexcept {
|
||||
return (
|
||||
this->vertexFunction == rhs.vertexFunction &&
|
||||
this->fragmentFunction == rhs.fragmentFunction &&
|
||||
@@ -237,23 +234,23 @@ struct PipelineState {
|
||||
);
|
||||
}
|
||||
|
||||
bool operator!=(const PipelineState& rhs) const noexcept {
|
||||
bool operator!=(const MetalPipelineState& rhs) const noexcept {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
};
|
||||
|
||||
// This assert checks that the struct is the size we expect without any "hidden" padding bytes
|
||||
// inserted by the compiler.
|
||||
static_assert(sizeof(PipelineState) == 688, "PipelineState unexpected size.");
|
||||
static_assert(sizeof(MetalPipelineState) == 688, "MetalPipelineState unexpected size.");
|
||||
|
||||
struct PipelineStateCreator {
|
||||
id<MTLRenderPipelineState> operator()(id<MTLDevice> device, const PipelineState& state)
|
||||
id<MTLRenderPipelineState> operator()(id<MTLDevice> device, const MetalPipelineState& state)
|
||||
noexcept;
|
||||
};
|
||||
|
||||
using PipelineStateTracker = StateTracker<PipelineState>;
|
||||
using PipelineStateTracker = StateTracker<MetalPipelineState>;
|
||||
|
||||
using PipelineStateCache = StateCache<PipelineState, id<MTLRenderPipelineState>,
|
||||
using PipelineStateCache = StateCache<MetalPipelineState, id<MTLRenderPipelineState>,
|
||||
PipelineStateCreator>;
|
||||
|
||||
// Depth-stencil State
|
||||
@@ -315,7 +312,7 @@ using UniformBufferStateTracker = StateTracker<UniformBufferState>;
|
||||
// Sampler states
|
||||
|
||||
struct SamplerState {
|
||||
backend::SamplerParams samplerParams;
|
||||
SamplerParams samplerParams;
|
||||
uint32_t minLod = 0;
|
||||
uint32_t maxLod = UINT_MAX;
|
||||
|
||||
@@ -343,7 +340,6 @@ using SamplerStateCache = StateCache<SamplerState, id<MTLSamplerState>, SamplerS
|
||||
using CullModeStateTracker = StateTracker<MTLCullMode>;
|
||||
using WindingStateTracker = StateTracker<MTLWinding>;
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -20,10 +20,9 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
id<MTLRenderPipelineState> PipelineStateCreator::operator()(id<MTLDevice> device,
|
||||
const PipelineState& state) noexcept {
|
||||
const MetalPipelineState& state) noexcept {
|
||||
MTLRenderPipelineDescriptor* descriptor = [MTLRenderPipelineDescriptor new];
|
||||
|
||||
// Shader Functions
|
||||
@@ -105,7 +104,7 @@ id<MTLDepthStencilState> DepthStateCreator::operator()(id<MTLDevice> device,
|
||||
|
||||
id<MTLSamplerState> SamplerStateCreator::operator()(id<MTLDevice> device,
|
||||
const SamplerState& state) noexcept {
|
||||
backend::SamplerParams params = state.samplerParams;
|
||||
SamplerParams params = state.samplerParams;
|
||||
MTLSamplerDescriptor* samplerDescriptor = [MTLSamplerDescriptor new];
|
||||
samplerDescriptor.minFilter = getFilter(params.filterMin);
|
||||
samplerDescriptor.magFilter = getFilter(params.filterMag);
|
||||
@@ -133,6 +132,5 @@ id<MTLSamplerState> SamplerStateCreator::operator()(id<MTLDevice> device,
|
||||
return [device newSamplerStateWithDescriptor:samplerDescriptor];
|
||||
}
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -23,14 +23,13 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
struct MetalTimerQuery;
|
||||
struct MetalContext;
|
||||
|
||||
class TimerQueryInterface {
|
||||
class MetalTimerQueryInterface {
|
||||
public:
|
||||
virtual ~TimerQueryInterface();
|
||||
virtual ~MetalTimerQueryInterface();
|
||||
virtual void beginTimeElapsedQuery(MetalTimerQuery* query) = 0;
|
||||
virtual void endTimeElapsedQuery(MetalTimerQuery* query) = 0;
|
||||
virtual bool getQueryResult(MetalTimerQuery* query, uint64_t* outElapsedTime) = 0;
|
||||
@@ -41,9 +40,9 @@ protected:
|
||||
|
||||
// Uses MTLSharedEvents to implement timer queries.
|
||||
// Only available on >= iOS 12.0.
|
||||
class API_AVAILABLE(ios(12.0)) TimerQueryFence : public TimerQueryInterface {
|
||||
class API_AVAILABLE(ios(12.0)) MetalTimerQueryFence : public MetalTimerQueryInterface {
|
||||
public:
|
||||
explicit TimerQueryFence(MetalContext& context) : mContext(context) {}
|
||||
explicit MetalTimerQueryFence(MetalContext& context) : mContext(context) {}
|
||||
|
||||
void beginTimeElapsedQuery(MetalTimerQuery* query) override;
|
||||
void endTimeElapsedQuery(MetalTimerQuery* query) override;
|
||||
@@ -53,14 +52,13 @@ private:
|
||||
MetalContext& mContext;
|
||||
};
|
||||
|
||||
class TimerQueryNoop : public TimerQueryInterface {
|
||||
class TimerQueryNoop : public MetalTimerQueryInterface {
|
||||
public:
|
||||
void beginTimeElapsedQuery(MetalTimerQuery* query) override {}
|
||||
void endTimeElapsedQuery(MetalTimerQuery* query) override {}
|
||||
bool getQueryResult(MetalTimerQuery* query, uint64_t* outElapsedTime) override;
|
||||
};
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -20,11 +20,10 @@
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace metal {
|
||||
|
||||
TimerQueryInterface::~TimerQueryInterface() = default;
|
||||
MetalTimerQueryInterface::~MetalTimerQueryInterface() = default;
|
||||
|
||||
void TimerQueryFence::beginTimeElapsedQuery(MetalTimerQuery* query) {
|
||||
void MetalTimerQueryFence::beginTimeElapsedQuery(MetalTimerQuery* query) {
|
||||
auto* fence = new MetalFence(mContext);
|
||||
fence->encode();
|
||||
query->status->elapsed = 0;
|
||||
@@ -41,7 +40,7 @@ void TimerQueryFence::beginTimeElapsedQuery(MetalTimerQuery* query) {
|
||||
});
|
||||
}
|
||||
|
||||
void TimerQueryFence::endTimeElapsedQuery(MetalTimerQuery* query) {
|
||||
void MetalTimerQueryFence::endTimeElapsedQuery(MetalTimerQuery* query) {
|
||||
auto* fence = new MetalFence(mContext);
|
||||
fence->encode();
|
||||
|
||||
@@ -57,7 +56,7 @@ void TimerQueryFence::endTimeElapsedQuery(MetalTimerQuery* query) {
|
||||
});
|
||||
}
|
||||
|
||||
bool TimerQueryFence::getQueryResult(MetalTimerQuery* query, uint64_t* outElapsedTime) {
|
||||
bool MetalTimerQueryFence::getQueryResult(MetalTimerQuery* query, uint64_t* outElapsedTime) {
|
||||
if (!query->status->available.load()) {
|
||||
return false;
|
||||
}
|
||||
@@ -71,6 +70,5 @@ bool TimerQueryNoop::getQueryResult(MetalTimerQuery* query, uint64_t* outElapsed
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace metal
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
namespace filament::backend::metal {
|
||||
namespace filament::backend {
|
||||
|
||||
/**
|
||||
* Creates a texture view of the passed-in texture with the given swizzle. If swizzle is the default
|
||||
@@ -29,6 +29,19 @@ API_AVAILABLE(ios(13.0))
|
||||
id<MTLTexture> createTextureViewWithSwizzle(id<MTLTexture> texture,
|
||||
MTLTextureSwizzleChannels swizzle);
|
||||
|
||||
} // namespace filament::backend::metal
|
||||
/**
|
||||
* Creates a texture view of the passed-in texture with the given layer.
|
||||
*
|
||||
* The returned MTLTexture will have a type of MTLTextureType2D.
|
||||
* The following MTLTextureTypes are supported:
|
||||
* - MTLTextureType2D (this is a no-op)
|
||||
* - MTLTextureType2DArray
|
||||
* - MTLTextureTypeCube
|
||||
*
|
||||
* All other MTLTextureTypes are unsupported.
|
||||
*/
|
||||
id<MTLTexture> createTextureViewWithSingleSlice(id<MTLTexture> texture, NSUInteger slice);
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif //TNT_FILAMENT_DRIVER_METALUTILS_H
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "MetalUtils.h"
|
||||
|
||||
namespace filament::backend::metal {
|
||||
namespace filament::backend {
|
||||
|
||||
id<MTLTexture> createTextureViewWithSwizzle(id<MTLTexture> texture,
|
||||
MTLTextureSwizzleChannels swizzle) {
|
||||
@@ -37,4 +37,15 @@ id<MTLTexture> createTextureViewWithSwizzle(id<MTLTexture> texture,
|
||||
swizzle:swizzle];
|
||||
}
|
||||
|
||||
id<MTLTexture> createTextureViewWithSingleSlice(id<MTLTexture> texture, NSUInteger slice) {
|
||||
if (texture.textureType == MTLTextureType2D) {
|
||||
return texture;
|
||||
}
|
||||
NSUInteger mips = texture.mipmapLevelCount;
|
||||
return [texture newTextureViewWithPixelFormat:texture.pixelFormat
|
||||
textureType:MTLTextureType2D
|
||||
levels:NSMakeRange(0, mips)
|
||||
slices:NSMakeRange(slice, 1)];
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -17,20 +17,21 @@
|
||||
#include "noop/NoopDriver.h"
|
||||
#include "CommandStreamDispatcher.h"
|
||||
|
||||
namespace filament {
|
||||
|
||||
using namespace backend;
|
||||
namespace filament::backend {
|
||||
|
||||
Driver* NoopDriver::create() {
|
||||
return new NoopDriver();
|
||||
}
|
||||
|
||||
NoopDriver::NoopDriver() noexcept : DriverBase(new ConcreteDispatcher<NoopDriver>()) {
|
||||
}
|
||||
NoopDriver::NoopDriver() noexcept = default;
|
||||
|
||||
NoopDriver::~NoopDriver() noexcept = default;
|
||||
|
||||
backend::ShaderModel NoopDriver::getShaderModel() const noexcept {
|
||||
Dispatcher NoopDriver::getDispatcher() const noexcept {
|
||||
return ConcreteDispatcher<NoopDriver>::make();
|
||||
}
|
||||
|
||||
ShaderModel NoopDriver::getShaderModel() const noexcept {
|
||||
#if defined(__ANDROID__) || defined(IOS) || defined(__EMSCRIPTEN__)
|
||||
return ShaderModel::GL_ES_30;
|
||||
#else
|
||||
@@ -39,7 +40,7 @@ backend::ShaderModel NoopDriver::getShaderModel() const noexcept {
|
||||
}
|
||||
|
||||
// explicit instantiation of the Dispatcher
|
||||
template class backend::ConcreteDispatcher<NoopDriver>;
|
||||
template class ConcreteDispatcher<NoopDriver>;
|
||||
|
||||
|
||||
void NoopDriver::terminate() {
|
||||
@@ -52,12 +53,12 @@ void NoopDriver::beginFrame(int64_t monotonic_clock_ns, uint32_t frameId) {
|
||||
}
|
||||
|
||||
void NoopDriver::setFrameScheduledCallback(Handle<HwSwapChain> sch,
|
||||
backend::FrameScheduledCallback callback, void* user) {
|
||||
FrameScheduledCallback callback, void* user) {
|
||||
|
||||
}
|
||||
|
||||
void NoopDriver::setFrameCompletedCallback(Handle<HwSwapChain> sch,
|
||||
backend::FrameCompletedCallback callback, void* user) {
|
||||
FrameCompletedCallback callback, void* user) {
|
||||
|
||||
}
|
||||
|
||||
@@ -118,7 +119,7 @@ Handle<HwStream> NoopDriver::createStreamAcquired() {
|
||||
}
|
||||
|
||||
void NoopDriver::setAcquiredImage(Handle<HwStream> sh, void* image,
|
||||
backend::CallbackHandler* handler, backend::StreamCallback cb, void* userData) {
|
||||
CallbackHandler* handler, StreamCallback cb, void* userData) {
|
||||
}
|
||||
|
||||
void NoopDriver::setStreamDimensions(Handle<HwStream> sh, uint32_t width, uint32_t height) {
|
||||
@@ -148,7 +149,7 @@ bool NoopDriver::isTextureSwizzleSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NoopDriver::isTextureFormatMipmappable(backend::TextureFormat format) {
|
||||
bool NoopDriver::isTextureFormatMipmappable(TextureFormat format) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -181,7 +182,7 @@ math::float2 NoopDriver::getClipSpaceParams() {
|
||||
}
|
||||
|
||||
uint8_t NoopDriver::getMaxDrawBuffers() {
|
||||
return backend::MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT;
|
||||
return MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT;
|
||||
}
|
||||
|
||||
void NoopDriver::updateIndexBuffer(Handle<HwIndexBuffer> ibh, BufferDescriptor&& p,
|
||||
@@ -307,14 +308,9 @@ void NoopDriver::readPixels(Handle<HwRenderTarget> src,
|
||||
scheduleDestroy(std::move(p));
|
||||
}
|
||||
|
||||
void NoopDriver::readStreamPixels(Handle<HwStream> sh, uint32_t x, uint32_t y, uint32_t width,
|
||||
uint32_t height, PixelBufferDescriptor&& p) {
|
||||
scheduleDestroy(std::move(p));
|
||||
}
|
||||
|
||||
void NoopDriver::blit(TargetBufferFlags buffers,
|
||||
Handle<HwRenderTarget> dst, backend::Viewport dstRect,
|
||||
Handle<HwRenderTarget> src, backend::Viewport srcRect,
|
||||
Handle<HwRenderTarget> dst, Viewport dstRect,
|
||||
Handle<HwRenderTarget> src, Viewport srcRect,
|
||||
SamplerMagFilter filter) {
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user