Compare commits

..

78 Commits

Author SHA1 Message Date
Benjamin Doherty
d9aead8aac Linux CI: use clang 14 2023-02-21 16:06:48 -08:00
Powei Feng
ce148ebeb1 Update linux clang to version 10 (#6556) 2023-02-21 16:00:07 -08:00
Powei Feng
e1315fbaa7 Update CI Ubuntu version 2023-02-21 15:57:00 -08:00
Benjamin Doherty
c73710e343 Merge branch 'rc/1.31.5' into release 2023-02-21 13:16:47 -08:00
Benjamin Doherty
092a0489da Bump version to 1.31.5 2023-02-13 11:53:24 -08:00
Benjamin Doherty
1c6279366f Merge branch 'rc/1.31.4' into release 2023-02-13 11:51:37 -08:00
Benjamin Doherty
d2690bf75a Release Filament 1.31.4 2023-02-13 11:51:06 -08:00
Ben Doherty
44f002a5a1 gltfio: Fix race condition affecting mobile and web (#6548)
When loading a glTF file on platforms without a filesystem, a client
calls `addResourceData` to populate `ResourceLoader`'s cache with data.
For example, a web client might make HTTP fetch requests to fill in
buffer data. This internal cache of data is stored in
`ResourceLoader::Impl::mUriDataCache`.

This works well, except the cache must persist until after it has been
uploaded to the GPU.

There was already a mechanism (see `uploadUserdata`) in place to ensure
that glTF data persisted until after it had been uploaded to the GPU.
However, this mechanism did not extend to client-provided data. Thus, a
race occured between Filament's driver consuming the buffer and it
getting freed.
2023-02-13 10:44:22 -08:00
Powei Feng
f8442c9ec0 vulkan: Remove unused presentQueueFamilyIndex (#6545) 2023-02-10 12:41:00 -08:00
Powei Feng
b3513c7d1f geometry: Add TangentSpaceMesh implementations (#6530)
geometry: Add TangentSpaceMesh implementations

Added:
 - Hughes-Moller
 - Frisvad's method
 - Flat shading
2023-02-10 09:34:49 -08:00
Mathias Agopian
a82e813333 fix libmath streaming operators 2023-02-09 16:11:30 -08:00
Powei Feng
dd246aeee4 vulkan: Assert that graphics-QF is present-QF (#6540) 2023-02-09 13:31:29 -08:00
Ben Doherty
1653d3615b Fix Metal crash due to empty program names (#6537) 2023-02-09 12:11:04 -08:00
Mathias Agopian
4847b00f9e improve SoA a bit
Instead of storing the arrays into an array of void*, we use a 
tuple<> instead. This improves debugging because now the tuple<>
has pointer with the correct types.

It also improves most of the code except `push_back` which now
relies on a hack -- this is the only place where I'm not able to 
resolve the array strictly at compile time, even if in practice it is.
2023-02-08 16:22:00 -08:00
Igor Korobka
d613145c1a Fix JNI after minification is applied
UbershaderProvider.getNativeObject() is accessed from AssetLoader.cpp,
so it must be annotated with @UsedByNative("AssetLoader.cpp") to
avoid runtime crashes when minification is applied.

Fixes #5944
2023-02-08 15:29:55 -08:00
ritik619
a788f66e18 Fixed typographic error 2023-02-08 12:01:50 -08:00
Romain Guy
9ca3a7456c Fix JNI 2023-02-08 09:07:59 -08:00
Mathias Agopian
5cec001058 matdbg: direct SPIRV edit now supported 2023-02-03 13:57:44 -08:00
Mathias Agopian
2fb42f5144 matdbg: refresh spirv properly
we now refresh the spirv code properly after it's rebuilt from the
glsl tab.
2023-02-02 11:10:21 -08:00
Mathias Agopian
02c22a668c matdbg: make sure we use the same spirv parameters everywhere 2023-02-02 11:10:02 -08:00
Mathias Agopian
a7bf90f5be build.sh -d is now split in two options
`-d` now enables matdbg and adds debugging data, but doesn't affect 
 material optimization

`-g` disables material optimizations


A similar change is done with gradle options. The new proprety
`com.google.android.filament.matnopt` is used to disable material
optimizations.

These options mimic `matc` options.
2023-02-01 23:59:00 -08:00
Mathias Agopian
f71e90fae0 deduplicate spirv disassembly code 2023-02-01 21:12:53 -08:00
Mathias Agopian
8afb11128d move UibGenerator and SibGenerator to the shader folder
The shader folder is where we generate the glsl, so this is more
appropriate.
2023-02-01 21:12:53 -08:00
Mathias Agopian
2e0c238cc6 We now require Vulkan 1.1 for the vulkan backend 2023-02-01 21:10:26 -08:00
Benjamin Doherty
2ac85049a9 Bump version to 1.31.4 2023-02-01 11:55:09 -08:00
Benjamin Doherty
ea428a27d1 Merge branch 'rc/1.31.3' into release 2023-02-01 11:54:04 -08:00
Benjamin Doherty
03b89b4327 Release Filament 1.31.3 2023-02-01 11:53:41 -08:00
Mathias Agopian
a878d1f39c improve sample_full_pbr
- -m option now works with "directory_*.png" or just "*.png"
- "color" replaced by "albedo" to mach other places in the source tree
- fixed warnings
- clear the background when IBL is not used
2023-02-01 10:04:02 -08:00
Mathias Agopian
4a09e13e9d fix a couple typos and consts.
make it easier to activate matdbg on android builds, by adding, but
commenting out the appropriate property.
2023-02-01 10:03:20 -08:00
Mathias Agopian
0b4d32bf98 matdbg: use GLSL 4.5 on desktop when debugging spirv
GLSL 4.5 is closer to spriv than 4.1 and since this is just to 
"interpret" the spirv, 4.5 is fine.

Set the default precision for GLES though.
2023-02-01 10:03:20 -08:00
Mathias Agopian
b940fc9c48 update remote ui 2023-01-31 20:55:23 -08:00
Koncz Levente
2eb0dd7153 Sample Full PBR fixes (#6490)
* Calculate view vector without using camera eye position

* Fix compilation error (during parsing the material when a height map is passed in)

* Add SUN light to the scene
2023-01-31 12:28:25 -08:00
Mathias Agopian
101c7db9a2 update remote ui 2023-01-31 09:52:37 -08:00
Mathias Agopian
032ace2051 Add output color space to ColorGrading settings 2023-01-31 09:46:22 -08:00
Mathias Agopian
5754b9907d Add support for sRGB swapchains
This change adds a 'SRGB' config flag when creating a SwapChain that
enables linear to sRGB conversion on write.

When using this flag, the linear->srgb conversion in the color grading
post processing should be disabled (or, the whole post-processing
stage should be disabled).

There is also a new query to determine if this flag is supported by
the underlaying platform.

On Metal, this happens automatically when the underlaying layer is sRGB.

This reverts commit 3799e219fc.
2023-01-31 09:29:02 -08:00
Mathias Agopian
ffb8203ae7 Fix typo in ColorSpace operator= 2023-01-30 21:35:51 -08:00
Powei Feng
906da033dd vulkan: Add fallback extent for swap chain sizing (#6495)
vulkan: Add fallback extent for swap chain sizing
2023-01-30 19:29:10 -08:00
daemyung danny jang
1077405bc1 Support Windows32 on bluegl as C backend (#6499) 2023-01-30 15:56:15 -08:00
daemyung danny jang
e37df8fc89 Include a header in alphabetical order (#6507) 2023-01-30 14:58:56 -08:00
Mathias Agopian
3799e219fc Revert "Add support for sRGB swapchains"
This reverts commit eab14da30e.

This broke macOS desktop (and maybe other GL platforms).
2023-01-30 11:20:18 -08:00
Mathias Agopian
eab14da30e Add support for sRGB swapchains
This change adds a 'SRGB' config flag when creating a SwapChain that
enables linear to sRGB conversion on write.

When using this flag, the linear->srgb conversion in the color grading
post processing should be disabled (or, the whole post-processing
stage should be disabled).

There is also a new query to determine if this flag is supported by
the underlaying platform.


On Metal, this happens automatically when the underlaying layer is sRGB.
2023-01-30 10:49:38 -08:00
Mathias Agopian
84e999fe57 cleanup PlatformEGL config selection code
We now structure the code to assume we have EGL_KHR_no_config_context,
which is the common case. This allows use to decouple context creation
from swapchain creation.

We still handle the case where the extension is not present by always
selecting a transparent config.
2023-01-30 10:49:38 -08:00
Mathias Agopian
f22ff6a340 the createSwapChain flag shouldn't be a reference 2023-01-30 10:49:38 -08:00
daemyung danny jang
d9d0b93306 Fix a build error (#6502) 2023-01-30 10:38:36 -08:00
Powei Feng
09248cd451 Destroy FilamentInstance's mRoot in EntityManager (#6500) 2023-01-27 16:05:42 -08:00
Koncz Levente
73880428dc Ortho shading fixes (#6453) 2023-01-27 09:36:56 -08:00
Ben Doherty
2a049d1324 Initialize object_uniforms in depth shader (#6492) 2023-01-26 16:23:14 -08:00
Powei Feng
51cbd74235 Add missing STL includes (#6496) 2023-01-26 16:07:58 -08:00
Powei Feng
45246b6109 geometry: Add TangentSpaceMesh class outline (#6476)
- Defined class with documentation in comments
 - Implemented algorithm selection
 - No actual algorithms written yet

Part of google/filament#6358
2023-01-26 14:39:48 -08:00
Ben Doherty
d3956adca8 matdbg: take desktop/mobile into account for SPIR-V to GLSL translation (#6488) 2023-01-26 11:30:51 -08:00
Benjamin Doherty
3bef718238 Bump version to 1.31.3 2023-01-24 14:28:21 -08:00
Benjamin Doherty
e9daaa0503 Merge branch 'rc/1.31.2' into release 2023-01-24 14:27:02 -08:00
Benjamin Doherty
298e54c32a Release Filament 1.31.2 2023-01-24 14:26:22 -08:00
Ben Doherty
4c82f0259d Add systrace support on Apple platforms (#6480) 2023-01-23 14:11:47 -08:00
Mathias Agopian
d0c043c7ff implement draw command channels
There can be up to 4 channels drawing commands can be associated to. 
Channels work like "priorities" except it's the strongest command ordering 
key, in particular it takes precedence over the object's blending mode.
2023-01-23 13:47:41 -08:00
Powei Feng
20cbecfd7c vulkan: put getEnabledLayers behind VK_ENABLE_VALIDATION (#6474) 2023-01-18 18:38:53 -08:00
Powei Feng
194defdb1b vulkan: Fix readPixels memory leak (#6473) 2023-01-18 16:35:58 -08:00
Benjamin Doherty
6d3ea21993 Bump version to 1.31.2 2023-01-18 14:25:45 -08:00
Benjamin Doherty
5017cbe67e Release Filament 1.31.1 2023-01-18 14:23:21 -08:00
Ben Doherty
4c4201cb72 Update check-headers script to ignore platform headers (#6472) 2023-01-18 13:53:45 -08:00
Powei Feng
3ee635f8e4 Fix enabledLayers (#6467)
instanceCreateInfo should not take stack-allocated data
2023-01-18 13:50:10 -08:00
Ben Doherty
4c2dabffd6 Vulkan: fix stack-use-after-scope ASAN error in VulkanContext.cpp (#6463) 2023-01-18 12:00:08 -08:00
Mathias Agopian
185c83dae2 Fix a crash on Vulkan with some Adreno drivers
We were using a specialization constant to size an array inside an
UBO interface block, which caused the crash in the Vulkan driver.

However, this specialization constant was only used to workaround a
Chrome bug on WebGL. Additionally, specialized array size inside blocks
are not fully supported in spirv.

This workaround simply replaces the specialization constant by a 
constant on Vulkan.

Fix #6444
2023-01-18 10:36:43 -08:00
Mathias Agopian
15d124b225 disable KHR_debug messages
there were never useful and in fact harmful, because confusing to our
users.
2023-01-18 10:35:48 -08:00
Mathias Agopian
9c474c5b08 remove too verbose log when auto-instancing 2023-01-18 10:35:31 -08:00
Mathias Agopian
f92f283e00 Fix a typo with auto instancing
fixes b/265831206
2023-01-17 16:42:26 -08:00
Mathias Agopian
f6b94614e8 Make all OpenGLPlatform related interfaces public
- Remove DefaultPlatform from public headers
DefaultPlatform is now PlatormFactory and is just an implementation
detail.

- VulkanPlatform is now public
- Improvements to the OpenGLPlatform interface
- Cleanup PlatformEGL and PlatformEGLAndroid

Also:

- reworked how external image worked so that all the implementation
  is contained in the Platform and no dependency to the backend is
  needed.

- MetalPlatform is now entirely private and final

This is because MetalPlatform wasn't an interface. We probably need one
so it could be customized in the future. But as it stands now it's
better to be private.
2023-01-17 16:39:44 -08:00
Ben Doherty
978517b057 Update actions/checkout version (#6454) 2023-01-17 09:59:19 -08:00
Levente Koncz
d911640809 Attempt to fix skybox shader in ORTHO view 2023-01-13 16:29:08 -08:00
Mathias Agopian
473e610430 reenable compute in the GL backend
We do some shenanigans so it works with API < 21 on android.
2023-01-13 16:00:56 -08:00
Mathias Agopian
3b9b725406 fix dynamic lighting with custom projections
Forxelization made many assumptions about the shape of the projection
matrix, the gist of these fixes is to remove those assumptions.

Fix #6390
2023-01-13 11:36:44 -08:00
Mathias Agopian
fa742bc6bf fix typos 2023-01-13 11:36:44 -08:00
Romain Guy
6a02dd0993 Update to Android Studio Electric Eel and AGP 7.4.0 (#6456) 2023-01-13 08:21:03 -08:00
Powei Feng
243d10f864 [vulkan] enumerate: Returning size = 0 is ok (#6450) 2023-01-12 12:56:34 -08:00
Romain Guy
bbe46071f3 Update Android dependencies (#6452) 2023-01-12 10:02:18 -08:00
Ben Doherty
8ded184ea3 Metal: add labels to aid debugging (#6451) 2023-01-12 09:55:43 -08:00
Romain Guy
ce407ba844 Fix typo 2023-01-11 08:48:04 -08:00
Powei Feng
ddb6a7fa93 Update Linux build instructions (#6438) 2023-01-10 16:42:44 -08:00
188 changed files with 116918 additions and 98944 deletions

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/android && printf "y" | ./build.sh continuous

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/ios && printf "y" | ./build.sh continuous

View File

@@ -10,10 +10,10 @@ on:
jobs:
build-linux:
name: build-linux
runs-on: ubuntu-18.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/linux && printf "y" | ./build.sh continuous

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/mac && printf "y" | ./build.sh continuous

View File

@@ -15,10 +15,10 @@ jobs:
strategy:
matrix:
os: [macos-latest, ubuntu-18.04]
os: [macos-latest, ubuntu-22.04]
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
WORKFLOW_OS=`echo \`uname\` | sed "s/Darwin/mac/" | tr [:upper:] [:lower:]`
@@ -32,7 +32,7 @@ jobs:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
build\windows\build-github.bat presubmit
@@ -43,7 +43,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/android && printf "y" | ./build.sh presubmit
@@ -53,7 +53,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/ios && printf "y" | ./build.sh presubmit
@@ -66,7 +66,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/web && printf "y" | ./build.sh presubmit

View File

@@ -31,7 +31,7 @@ jobs:
strategy:
matrix:
os: [macos-latest, ubuntu-18.04]
os: [macos-latest, ubuntu-22.04]
steps:
- name: Decide Git ref
@@ -41,7 +41,7 @@ jobs:
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
@@ -76,7 +76,7 @@ jobs:
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
@@ -109,7 +109,7 @@ jobs:
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
@@ -160,7 +160,7 @@ jobs:
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
@@ -194,7 +194,7 @@ jobs:
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
shell: bash
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/web && printf "y" | ./build.sh continuous

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
build\windows\build-github.bat continuous

View File

@@ -92,6 +92,8 @@ Make sure you've installed the following dependencies:
- `libc++abi-7-dev` (`libcxxabi-static` on Fedora) or higher
- `ninja-build`
- `libxi-dev`
- `libxcomposite-dev` (`libXcomposite-devel` on Fedora)
- `libxxf86vm-dev` (`libXxf86vm-devel` on Fedora)
After dependencies have been installed, we highly recommend using the [easy build](#easy-build)
script.

View File

@@ -497,9 +497,14 @@ if (FILAMENT_SUPPORTS_METAL)
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a metal)
endif()
# Disable optimizations and enable debug info (preserves names in SPIR-V)
# Enable debug info (preserves names in SPIR-V)
if (FILAMENT_ENABLE_MATDBG)
set(MATC_OPT_FLAGS ${MATC_OPT_FLAGS} -d)
endif()
# Disable optimizations
if (FILAMENT_DISABLE_MATOPT)
set(MATC_OPT_FLAGS -gd)
set(MATC_OPT_FLAGS ${MATC_OPT_FLAGS} -g)
endif()
set(MATC_BASE_FLAGS ${MATC_API_FLAGS} -p ${MATC_TARGET} ${MATC_OPT_FLAGS})

View File

@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.31.1'
implementation 'com.google.android.filament:filament-android:1.31.5'
}
```
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release:
```
pod 'Filament', '~> 1.31.1'
pod 'Filament', '~> 1.31.5'
```
### Snapshots

View File

@@ -5,6 +5,23 @@ A new header is inserted each time a *tag* is created.
## main branch
## v1.31.5
- gltfio: fix potential early freeing of data provided with `ResourceLoader::addResourceData`.
## v1.31.4
- engine: fix broken picking [⚠️ **Recompile Materials to get the fix**]
- engine: added support for sRGB swapchains. See `SwapChain.h`
- bluegl: support Windows32
## v1.31.3
- vulkan: fix memory leak in readPixels
- engine: added support for draw-commands channels (stronger ordering of commands/renderables)
## v1.31.2
## v1.31.1
- gltfio: expose joint inverse bind matrices via method on FilamentInstance

View File

@@ -12,7 +12,10 @@
// When set, support for Vulkan will be excluded.
//
// com.google.android.filament.matdbg
// When set, enables matdbg, disables shader optimizations
// When set, enables matdbg
//
// com.google.android.filament.matnopt
// When set, disable shader optimizations.
//
// com.google.android.filament.skip-samples
// Exclude samples from the project. Useful to speed up compilation.
@@ -62,6 +65,10 @@ buildscript {
.gradleProperty("com.google.android.filament.matdbg")
.isPresent()
def matnopt = providers
.gradleProperty("com.google.android.filament.matnopt")
.isPresent()
def abis = ["arm64-v8a", "armeabi-v7a", "x86_64", "x86"]
def newAbis = providers
.gradleProperty("com.google.android.filament.abis")
@@ -75,9 +82,9 @@ buildscript {
'minSdk': 19,
'targetSdk': 33,
'compileSdk': 33,
'kotlin': '1.7.10',
'kotlin_coroutines': '1.6.1',
'buildTools': '33.0.0',
'kotlin': '1.8.0',
'kotlin_coroutines': '1.6.4',
'buildTools': '33.0.1',
'ndk': '25.1.8937393',
'androidx_core': '1.9.0',
'androidx_annotations': '1.3.0'
@@ -96,8 +103,7 @@ buildscript {
]
dependencies {
// NOTE: See TODO in gradle.properties once we move to Gradle 7.4
classpath 'com.android.tools.build:gradle:7.3.0'
classpath 'com.android.tools.build:gradle:7.4.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
}
@@ -109,7 +115,7 @@ buildscript {
"-DFILAMENT_DIST_DIR=${filamentPath}".toString(),
"-DFILAMENT_SUPPORTS_VULKAN=${excludeVulkan ? 'OFF' : 'ON'}".toString(),
"-DFILAMENT_ENABLE_MATDBG=${matdbg ? 'ON' : 'OFF'}".toString(),
"-DFILAMENT_DISABLE_MATOPT=${matdbg ? 'ON' : 'OFF'}".toString()
"-DFILAMENT_DISABLE_MATOPT=${matnopt ? 'ON' : 'OFF'}".toString()
]
ext.cppFlags = [

View File

@@ -150,6 +150,13 @@ Java_com_google_android_filament_RenderableManager_nBuilderPriority(JNIEnv*, jcl
builder->priority((uint8_t) priority);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderChannel(JNIEnv*, jclass,
jlong nativeBuilder, jint channel) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
builder->channel((uint8_t) channel);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderCulling(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
@@ -339,6 +346,13 @@ Java_com_google_android_filament_RenderableManager_nSetPriority(JNIEnv*, jclass,
rm->setPriority((RenderableManager::Instance) i, (uint8_t) priority);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetChannel(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint channel) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
rm->setChannel((RenderableManager::Instance) i, (uint8_t) channel);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetCulling(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jboolean enabled) {

View File

@@ -16,6 +16,7 @@
#include <jni.h>
#include <filament/Engine.h>
#include <filament/SwapChain.h>
#include "common/CallbackUtils.h"
@@ -32,3 +33,9 @@ Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* en
JniCallback::postToJavaAndDestroy(callback);
}, callback);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_SwapChain_nIsSRGBSwapChainSupported(JNIEnv *, jclass, jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (bool)SwapChain::isSRGBSwapChainSupported(*engine);
}

View File

@@ -257,23 +257,74 @@ public class RenderableManager {
* Provides coarse-grained control over draw order.
*
* <p>In general Filament reserves the right to re-order renderables to allow for efficient
* rendering. However clients can control ordering at a coarse level using <em>priority</em>.</p>
* rendering. However clients can control ordering at a coarse level using \em priority.
* The priority is applied separately for opaque and translucent objects, that is, opaque
* objects are always drawn before translucent objects regardless of the priority.</p>
*
* <p>For example, this could be used to draw a semitransparent HUD, if a client wishes to
* avoid using a separate View for the HUD. Note that priority is completely orthogonal to
* {@link Builder#layerMask}, which merely controls visibility.</p>
* <p>The Skybox always using the lowest priority, so it's drawn last, which may improve
* performance.</p>
*
* <p>The priority is clamped to the range [0..7], defaults to 4; 7 is lowest priority
* (rendered last).</p>
*
* @see Builder#blendOrder
*/
/**
* Provides coarse-grained control over draw order.
*
* <p>In general Filament reserves the right to re-order renderables to allow for efficient
* rendering. However clients can control ordering at a coarse level using priority.
* The priority is applied separately for opaque and translucent objects, that is, opaque
* objects are always drawn before translucent objects regardless of the priority.</p>
*
* <p>For example, this could be used to draw a semitransparent HUD, if a client wishes to
* avoid using a separate View for the HUD. Note that priority is completely orthogonal to
* {@link Builder#layerMask}, which merely controls visibility.</p>
* <p>The Skybox always using the lowest priority, so it's drawn last, which may improve
* performance.</p>
*
* @param priority clamped to the range [0..7], defaults to 4; 7 is lowest priority
* (rendered last).
*
* @return Builder reference for chaining calls.
*
* @see Builder#channel
* @see Builder#blendOrder
* @see #setPriority
* @see #setBlendOrderAt
*/
@NonNull
public Builder priority(@IntRange(from = 0, to = 7) int priority) {
nBuilderPriority(mNativeBuilder, priority);
return this;
}
/**
* Set the channel this renderable is associated to. There can be 4 channels.
* All renderables in a given channel are rendered together, regardless of anything else.
* They are sorted as usual withing a channel.
* Channels work similarly to priorities, except that they enforce the strongest ordering.
*
* @param channel clamped to the range [0..3], defaults to 0.
*
* @return Builder reference for chaining calls.
*
* @see Builder::blendOrder()
* @see Builder::priority()
* @see RenderableManager::setBlendOrderAt()
*/
@NonNull
public Builder channel(@IntRange(from = 0, to = 3) int channel) {
nBuilderChannel(mNativeBuilder, channel);
return this;
}
/**
* Controls frustum culling, true by default.
*
@@ -655,6 +706,15 @@ public class RenderableManager {
nSetPriority(mNativeObject, i, priority);
}
/**
* Changes the channel of a renderable
*
* @see Builder#channel
*/
public void setChannel(@EntityInstance int i, @IntRange(from = 0, to = 3) int channel) {
nSetChannel(mNativeObject, i, channel);
}
/**
* Changes whether or not frustum culling is on.
*
@@ -876,6 +936,7 @@ public class RenderableManager {
private static native void nBuilderBoundingBox(long nativeBuilder, float cx, float cy, float cz, float ex, float ey, float ez);
private static native void nBuilderLayerMask(long nativeBuilder, int select, int value);
private static native void nBuilderPriority(long nativeBuilder, int priority);
private static native void nBuilderChannel(long nativeBuilder, int channel);
private static native void nBuilderCulling(long nativeBuilder, boolean enabled);
private static native void nBuilderCastShadows(long nativeBuilder, boolean enabled);
private static native void nBuilderReceiveShadows(long nativeBuilder, boolean enabled);
@@ -898,6 +959,7 @@ public class RenderableManager {
private static native void nSetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float cx, float cy, float cz, float ex, float ey, float ez);
private static native void nSetLayerMask(long nativeRenderableManager, int i, int select, int value);
private static native void nSetPriority(long nativeRenderableManager, int i, int priority);
private static native void nSetChannel(long nativeRenderableManager, int i, int channel);
private static native void nSetCulling(long nativeRenderableManager, int i, boolean enabled);
private static native void nSetLightChannel(long nativeRenderableManager, int i, int channel, boolean enable);
private static native boolean nGetLightChannel(long nativeRenderableManager, int i, int channel);

View File

@@ -91,11 +91,34 @@ public class SwapChain {
*/
public static final long CONFIG_ENABLE_XCB = 0x4;
/**
* Indicates that the SwapChain must automatically perform linear to sRGB encoding.
*
* This flag is ignored if isSRGBSwapChainSupported() is false.
*
* When using this flag, post-processing should be disabled.
*
* @see SwapChain#isSRGBSwapChainSupported
* @see View#setPostProcessingEnabled
*/
public static final long CONFIG_SRGB_COLORSPACE = 0x10;
SwapChain(long nativeSwapChain, Object surface) {
mNativeObject = nativeSwapChain;
mSurface = surface;
}
/**
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag.
* The default implementation returns false.
*
* @param engine A reference to the filament Engine
* @return true if SWAP_CHAIN_CONFIG_SRGB_COLORSPACE is supported, false otherwise.
*/
public static boolean isSRGBSwapChainSupported(@NonNull Engine engine) {
return nIsSRGBSwapChainSupported(engine.getNativeObject());
}
/**
* @return the native <code>Object</code> this <code>SwapChain</code> was created from or null
* for a headless SwapChain.
@@ -141,4 +164,5 @@ public class SwapChain {
}
private static native void nSetFrameCompletedCallback(long nativeSwapChain, Object handler, Runnable callback);
private static native boolean nIsSRGBSwapChainSupported(long nativeEngine);
}

View File

@@ -276,7 +276,7 @@ public class TextureSampler {
}
/**
* Sets the wrapping mode in the t (depth) direction.
* Sets the wrapping mode in the r (depth) direction.
* @param mode wrapping mode
*/
public void setWrapModeR(WrapMode mode) {

View File

@@ -28,47 +28,81 @@ import com.google.android.filament.proguard.UsedByNative;
@UsedByNative("AssetLoader.cpp")
public interface MaterialProvider {
/**
* MaterialKey specifies the requirements for a requested glTF material.
* The provider creates Filament materials that fulfill these requirements.
*/
@UsedByNative("MaterialKey.cpp")
public static class MaterialKey {
@UsedByNative("MaterialKey.cpp")
public boolean doubleSided;
@UsedByNative("MaterialKey.cpp")
public boolean unlit;
@UsedByNative("MaterialKey.cpp")
public boolean hasVertexColors;
@UsedByNative("MaterialKey.cpp")
public boolean hasBaseColorTexture;
@UsedByNative("MaterialKey.cpp")
public boolean hasNormalTexture;
@UsedByNative("MaterialKey.cpp")
public boolean hasOcclusionTexture;
@UsedByNative("MaterialKey.cpp")
public boolean hasEmissiveTexture;
@UsedByNative("MaterialKey.cpp")
public boolean useSpecularGlossiness;
@UsedByNative("MaterialKey.cpp")
public int alphaMode; // 0 = OPAQUE, 1 = MASK, 2 = BLEND
@UsedByNative("MaterialKey.cpp")
public boolean enableDiagnostics;
@UsedByNative("MaterialKey.cpp")
public boolean hasMetallicRoughnessTexture; // piggybacks with specularRoughness
@UsedByNative("MaterialKey.cpp")
public int metallicRoughnessUV; // piggybacks with specularRoughness
@UsedByNative("MaterialKey.cpp")
public int baseColorUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasClearCoatTexture;
@UsedByNative("MaterialKey.cpp")
public int clearCoatUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasClearCoatRoughnessTexture;
@UsedByNative("MaterialKey.cpp")
public int clearCoatRoughnessUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasClearCoatNormalTexture;
@UsedByNative("MaterialKey.cpp")
public int clearCoatNormalUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasClearCoat;
@UsedByNative("MaterialKey.cpp")
public boolean hasTransmission;
@UsedByNative("MaterialKey.cpp")
public boolean hasTextureTransforms;
@UsedByNative("MaterialKey.cpp")
public int emissiveUV;
@UsedByNative("MaterialKey.cpp")
public int aoUV;
@UsedByNative("MaterialKey.cpp")
public int normalUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasTransmissionTexture;
@UsedByNative("MaterialKey.cpp")
public int transmissionUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasSheenColorTexture;
@UsedByNative("MaterialKey.cpp")
public int sheenColorUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasSheenRoughnessTexture;
@UsedByNative("MaterialKey.cpp")
public int sheenRoughnessUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasVolumeThicknessTexture;
@UsedByNative("MaterialKey.cpp")
public int volumeThicknessUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasSheen;
@UsedByNative("MaterialKey.cpp")
public boolean hasIOR;
public MaterialKey() {}

View File

@@ -20,6 +20,7 @@ import com.google.android.filament.Engine;
import com.google.android.filament.MaterialInstance;
import com.google.android.filament.Material;
import com.google.android.filament.VertexBuffer;
import com.google.android.filament.proguard.UsedByNative;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -94,6 +95,7 @@ public class UbershaderProvider implements MaterialProvider {
nDestroyMaterials(mNativeObject);
}
@UsedByNative("AssetLoader.cpp")
public long getNativeObject() {
return mNativeObject;
}

View File

@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.31.1
VERSION_NAME=1.31.5
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
@@ -22,3 +22,5 @@ android.useAndroidX=true
com.google.android.filament.tools-dir=../../../out/release/filament
com.google.android.filament.dist-dir=../out/android-release/filament
com.google.android.filament.abis=all
#com.google.android.filament.matdbg
#com.google.android.filament.matnopt

View File

@@ -1,6 +1,6 @@
#Wed Nov 17 10:40:18 PST 2021
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

Before

Width:  |  Height:  |  Size: 848 KiB

After

Width:  |  Height:  |  Size: 848 KiB

View File

@@ -22,9 +22,11 @@ function print_help {
echo " All (and only) git-ignored files under android/ are deleted."
echo " This is sometimes needed instead of -c (which still misses some clean steps)."
echo " -d"
echo " Enable matdbg and disable material optimization."
echo " Enable matdbg."
echo " -f"
echo " Always invoke CMake before incremental builds."
echo " -g"
echo " Disable material optimization."
echo " -i"
echo " Install build output"
echo " -m"
@@ -162,6 +164,9 @@ EGL_ON_LINUX_OPTION="-DFILAMENT_SUPPORTS_EGL_ON_LINUX=OFF"
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF"
MATDBG_GRADLE_OPTION=""
MATOPT_OPTION=""
MATOPT_GRADLE_OPTION=""
IOS_BUILD_SIMULATOR=false
BUILD_UNIVERSAL_LIBRARIES=false
@@ -221,6 +226,7 @@ function build_desktop_target {
${SWIFTSHADER_OPTION} \
${EGL_ON_LINUX_OPTION} \
${MATDBG_OPTION} \
${MATOPT_OPTION} \
${deployment_target} \
${architectures} \
../..
@@ -347,6 +353,7 @@ function build_android_target {
-DCMAKE_INSTALL_PREFIX="../android-${lc_target}/filament" \
-DCMAKE_TOOLCHAIN_FILE="../../build/toolchain-${arch}-linux-android.cmake" \
${MATDBG_OPTION} \
${MATOPT_OPTION} \
${VULKAN_ANDROID_OPTION} \
../..
fi
@@ -463,6 +470,7 @@ function build_android {
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${VULKAN_ANDROID_GRADLE_OPTION} \
${MATDBG_GRADLE_OPTION} \
${MATOPT_GRADLE_OPTION} \
:filament-android:assembleDebug \
:gltfio-android:assembleDebug \
:filament-utils-android:assembleDebug
@@ -510,6 +518,7 @@ function build_android {
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${VULKAN_ANDROID_GRADLE_OPTION} \
${MATDBG_GRADLE_OPTION} \
${MATOPT_GRADLE_OPTION} \
:filament-android:assembleRelease \
:gltfio-android:assembleRelease \
:filament-utils-android:assembleRelease
@@ -576,6 +585,7 @@ function build_ios_target {
-DIOS=1 \
-DCMAKE_TOOLCHAIN_FILE=../../third_party/clang/iOS.cmake \
${MATDBG_OPTION} \
${MATOPT_OPTION} \
../..
fi
@@ -758,12 +768,16 @@ while getopts ":hacCfijmp:q:uvslwtedk:" opt; do
;;
d)
PRINT_MATDBG_HELP=true
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON, -DFILAMENT_BUILD_FILAMAT=ON"
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_BUILD_FILAMAT=ON"
MATDBG_GRADLE_OPTION="-Pcom.google.android.filament.matdbg"
;;
f)
ISSUE_CMAKE_ALWAYS=true
;;
g)
MATOPT_OPTION="-DFILAMENT_DISABLE_MATOPT=ON"
MATOPT_GRADLE_OPTION="-Pcom.google.android.filament.matnopt"
;;
i)
INSTALL_COMMAND=install
;;

View File

@@ -44,6 +44,10 @@ FILAMENT_HEADERS="$1"
includes=()
pushd "$FILAMENT_HEADERS" >/dev/null
for f in $(find . -name '*.h'); do
# Ignore platform headers. These may contain platform-specific includes.
if [[ "$f" == *backend/platforms/* ]]; then
continue
fi
include_path="${f#./}" # strip leading ./
includes+=("${include_path}")
done

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# version of clang we want to use
GITHUB_CLANG_VERSION=8
GITHUB_CLANG_VERSION=14
# version of CMake to use instead of the default one
CMAKE_VERSION=3.19.5
# version of ninja to use

View File

@@ -3821,7 +3821,7 @@ Since $\left< cos \theta \right>$ does not depend on $\phi$ (azimuthal independe
$$\begin{align*}
C^0_l &= 2\pi \int_0^{\pi} \left< cos \theta \right> y^0_l(\theta) sin \theta d\theta \\
C^0_l &= 2\pi K^)_l \int_0^{\frac{\pi}{2}} P^0_l(cos \theta) cos \theta sin \theta d\theta \\
C^0_l &= 2\pi K^m_l \int_0^{\frac{\pi}{2}} P^0_l(cos \theta) cos \theta sin \theta d\theta \\
C^m_l &= 0, m != 0
\end{align*}$$

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -9,6 +9,7 @@ set(GENERATION_ROOT ${CMAKE_CURRENT_BINARY_DIR})
# Sources and headers
# ==================================================================================================
set(PUBLIC_HDRS
include/backend/AcquiredImage.h
include/backend/BufferDescriptor.h
include/backend/CallbackHandler.h
include/backend/DriverApiForward.h
@@ -36,12 +37,12 @@ set(SRCS
src/noop/NoopDriver.cpp
src/noop/PlatformNoop.cpp
src/Platform.cpp
src/PlatformFactory.cpp
src/Program.cpp
src/SamplerGroup.cpp
)
set(PRIVATE_HDRS
include/private/backend/AcquiredImage.h
include/private/backend/CircularBuffer.h
include/private/backend/CommandBufferQueue.h
include/private/backend/CommandStream.h
@@ -50,6 +51,7 @@ set(PRIVATE_HDRS
include/private/backend/DriverApi.h
include/private/backend/DriverAPI.inc
include/private/backend/HandleAllocator.h
include/private/backend/PlatformFactory.h
include/private/backend/SamplerGroup.h
src/CommandStreamDispatcher.h
src/DataReshaper.h
@@ -62,6 +64,7 @@ set(PRIVATE_HDRS
if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMENT_USE_SWIFTSHADER)
list(APPEND SRCS
include/backend/platforms/OpenGLPlatform.h
src/opengl/gl_headers.cpp
src/opengl/gl_headers.h
src/opengl/GLUtils.cpp
@@ -76,7 +79,6 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
src/opengl/OpenGLPlatform.cpp
src/opengl/OpenGLTimerQuery.cpp
src/opengl/OpenGLTimerQuery.h
include/private/backend/OpenGLPlatform.h
)
if (EGL)
list(APPEND SRCS src/opengl/platforms/PlatformEGL.cpp)
@@ -150,6 +152,7 @@ endif()
# See root CMakeLists.txt for platforms that support Vulkan
if (FILAMENT_SUPPORTS_VULKAN)
list(APPEND SRCS
include/backend/platforms/VulkanPlatform.h
src/vulkan/VulkanBlitter.cpp
src/vulkan/VulkanBlitter.h
src/vulkan/VulkanBuffer.cpp
@@ -173,7 +176,6 @@ if (FILAMENT_SUPPORTS_VULKAN)
src/vulkan/VulkanPipelineCache.cpp
src/vulkan/VulkanPipelineCache.h
src/vulkan/VulkanPlatform.cpp
src/vulkan/VulkanPlatform.h
src/vulkan/VulkanSamplerCache.cpp
src/vulkan/VulkanSamplerCache.h
src/vulkan/VulkanStagePool.cpp

View File

@@ -42,11 +42,42 @@
*/
namespace filament::backend {
/**
* Requests a SwapChain with an alpha channel.
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_TRANSPARENT = 0x1;
/**
* This flag indicates that the swap chain may be used as a source surface
* for reading back render results. This config flag must be set when creating
* any SwapChain that will be used as the source for a blit operation.
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_READABLE = 0x2;
/**
* Indicates that the native X11 window is an XCB window rather than an XLIB window.
* This is ignored on non-Linux platforms and in builds that support only one X11 API.
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
/**
* Indicates that the native window is a CVPixelBufferRef.
*
* This is only supported by the Metal backend. The CVPixelBuffer must be in the
* kCVPixelFormatType_32BGRA format.
*
* It is not necessary to add an additional retain call before passing the pixel buffer to
* Filament. Filament will call CVPixelBufferRetain during Engine::createSwapChain, and
* CVPixelBufferRelease when the swap chain is destroyed.
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER = 0x8;
/**
* Indicates that the SwapChain must automatically perform linear to srgb encoding.
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_SRGB_COLORSPACE = 0x10;
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_SAMPLER_COUNT = 62; // Maximum needed at feature level 3.
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.

View File

@@ -23,22 +23,28 @@
#include <utils/compiler.h>
namespace filament {
namespace backend {
namespace filament::backend {
class Driver;
/**
* Platform is an interface that abstracts how the backend (also referred to as Driver) is
* created. The backend provides several common Platform concrete implementations, which are
* selected automatically. It is possible however to provide a custom Platform when creating
* the filament Engine.
*/
class UTILS_PUBLIC Platform {
public:
struct SwapChain {};
struct Fence {};
struct Stream {};
struct ExternalTexture {
uintptr_t image = 0;
};
struct DriverConfig {
size_t handleArenaSize = 0; // size of handle arena in bytes. Setting to 0 indicates default value is to be used. Driver clamps to valid values.
/*
* size of handle arena in bytes. Setting to 0 indicates default value is to be used.
* Driver clamps to valid values.
*/
size_t handleArenaSize = 0;
};
virtual ~Platform() noexcept;
@@ -62,7 +68,8 @@ public:
*
* @return nullptr on failure, or a pointer to the newly created driver.
*/
virtual backend::Driver* createDriver(void* sharedContext, const DriverConfig& driverConfig) noexcept = 0;
virtual backend::Driver* createDriver(void* sharedContext,
const DriverConfig& driverConfig) noexcept = 0;
/**
* Processes the platform's event queue when called from its primary event-handling thread.
@@ -71,39 +78,9 @@ public:
* on platforms that need it, such as macOS + OpenGL. Returns false if this is not the main
* thread, or if the platform does not need to perform any special processing.
*/
virtual bool pumpEvents() noexcept { return false; }
virtual bool pumpEvents() noexcept;
};
class UTILS_PUBLIC DefaultPlatform : public Platform {
public:
~DefaultPlatform() noexcept override;
/**
* Creates a Platform configured for the requested backend if available
*
* @param backendHint Preferred backend, if not available the backend most suitable for the
* underlying platform is returned and \p backendHint is updated
* accordingly. Can't be nullptr.
*
* @return A pointer to the Platform object.
*
* @see destroy
*/
static DefaultPlatform* create(backend::Backend* backendHint) noexcept;
/**
* Destroys a Platform object returned by create()
*
* @param platform a reference (as a pointer) to the DefaultPlatform pointer to destroy.
* \p platform is cleared upon return.
*
* @see create
*/
static void destroy(DefaultPlatform** platform) noexcept;
};
} // namespace backend
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PLATFORM_H

View File

@@ -0,0 +1,4 @@
# include/backend Headers
Headers in `include/backend/` are fully public, in particular they can be included in filament's
public headers.

View File

@@ -0,0 +1,261 @@
/*
* Copyright (C) 2015 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_OPENGLPLATFORM_H
#define TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
#include <backend/AcquiredImage.h>
#include <backend/Platform.h>
namespace filament::backend {
class Driver;
/**
* A Platform interface that creates an OpenGL backend.
*
* WARNING: None of the methods below are allowed to change the GL state and must restore it
* upon return.
*
*/
class OpenGLPlatform : public Platform {
protected:
/*
* Derived classes can use this to instantiate the default OpenGLDriver backend.
* This is typically called from your implementation of createDriver()
*/
static Driver* createDefaultDriver(OpenGLPlatform* platform,
void* sharedContext, const DriverConfig& driverConfig);
~OpenGLPlatform() noexcept override;
public:
struct ExternalTexture {
unsigned int target; // GLenum target
unsigned int id; // GLuint id
};
/**
* Called by the driver to destroy the OpenGL context. This should clean up any windows
* or buffers from initialization. This is for instance where `eglDestroyContext` would be
* called.
*/
virtual void terminate() noexcept = 0;
/**
* Called by the driver to create a SwapChain for this driver.
*
* @param nativeWindow a token representing the native window. See concrete implementation
* for details.
* @param flags extra flags used by the implementation, see filament::SwapChain
* @return The driver's SwapChain object.
*
*/
virtual SwapChain* createSwapChain(void* nativeWindow, uint64_t flags) noexcept = 0;
/**
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag.
* The default implementation returns false.
*
* @return true if SWAP_CHAIN_CONFIG_SRGB_COLORSPACE is supported, false otherwise.
*/
virtual bool isSRGBSwapChainSupported() const noexcept;
/**
* Called by the driver create a headless SwapChain.
*
* @param width width of the buffer
* @param height height of the buffer
* @param flags extra flags used by the implementation, see filament::SwapChain
* @return The driver's SwapChain object.
*
* TODO: we need a more generic way of passing construction parameters
* A void* might be enough.
*/
virtual SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept = 0;
/**
* Called by the driver to destroys the SwapChain
* @param swapChain SwapChain to be destroyed.
*/
virtual void destroySwapChain(SwapChain* swapChain) noexcept = 0;
/**
* Called by the driver to establish the default FBO. The default implementation returns 0.
* @return a GLuint casted to a uint32_t that is an OpenGL framebuffer object.
*/
virtual uint32_t createDefaultRenderTarget() noexcept;
/**
* Called by the driver to make the OpenGL context active on the calling thread and bind
* the drawSwapChain to the default render target (FBO) created with createDefaultRenderTarget.
* @param drawSwapChain SwapChain to draw to. It must be bound to the default FBO.
* @param readSwapChain SwapChain to read from (for operation like `glBlitFramebuffer`)
*/
virtual void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept = 0;
/**
* Called by the driver once the current frame finishes drawing. Typically, this should present
* the drawSwapChain. This is for example where `eglMakeCurrent()` would be called.
* @param swapChain the SwapChain to present.
*/
virtual void commit(SwapChain* swapChain) noexcept = 0;
/**
* Set the time the next committed buffer should be presented to the user at.
*
* @param presentationTimeInNanosecond time in the future in nanosecond. The clock used depends
* on the concrete platform implementation.
*/
virtual void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept;
// --------------------------------------------------------------------------------------------
// Fence support
/**
* Can this implementation create a Fence.
* @return true if supported, false otherwise. The default implementation returns false.
*/
virtual bool canCreateFence() noexcept;
/**
* Creates a Fence (e.g. eglCreateSyncKHR). This must be implemented if `canCreateFence`
* returns true. Fences are used for frame pacing.
*
* @return A Fence object. The default implementation returns nullptr.
*/
virtual Fence* createFence() noexcept;
/**
* Destroys a Fence object. The default implementation does nothing.
*
* @param fence Fence to destroy.
*/
virtual void destroyFence(Fence* fence) noexcept;
/**
* Waits on a Fence.
*
* @param fence Fence to wait on.
* @param timeout Timeout.
* @return Whether the fence signaled or timed out. See backend::FenceStatus.
* The default implementation always return backend::FenceStatus::ERROR.
*/
virtual backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept;
// --------------------------------------------------------------------------------------------
// Streaming support
/**
* Creates a Stream from a native Stream.
*
* WARNING: This is called synchronously from the application thread (NOT the Driver thread)
*
* @param nativeStream The native stream, this parameter depends on the concrete implementation.
* @return A new Stream object.
*/
virtual Stream* createStream(void* nativeStream) noexcept;
/**
* Destroys a Stream.
* @param stream Stream to destroy.
*/
virtual void destroyStream(Stream* stream) noexcept;
/**
* The specified stream takes ownership of the texture (tname) object
* Once attached, the texture is automatically updated with the Stream's content, which
* could be a video stream for instance.
*
* @param stream Stream to take ownership of the texture
* @param tname GL texture id to "bind" to the Stream.
*/
virtual void attach(Stream* stream, intptr_t tname) noexcept;
/**
* Destroys the texture associated to the stream
* @param stream Stream to detach from its texture
*/
virtual void detach(Stream* stream) noexcept;
/**
* Updates the content of the texture attached to the stream.
* @param stream Stream to update
* @param timestamp Output parameter: Timestamp of the image bound to the texture.
*/
virtual void updateTexImage(Stream* stream, int64_t* timestamp) noexcept;
// --------------------------------------------------------------------------------------------
// External Image support
/**
* Creates an external texture handle. External textures don't have any parameters because
* these are undefined until setExternalImage() is called.
* @return a pointer to an ExternalTexture structure filled with valid token. However, the
* implementation could just return { 0, GL_TEXTURE_2D } at this point. The actual
* values can be delayed until setExternalImage.
*/
virtual ExternalTexture *createExternalImageTexture() noexcept;
/**
* Destroys an external texture handle and associated data.
* @param texture a pointer to the handle to destroy.
*/
virtual void destroyExternalImage(ExternalTexture* texture) noexcept;
// called on the application thread to allow Filament to take ownership of the image
/**
* Takes ownership of the externalImage. The externalImage parameter depends on the Platform's
* concrete implementation. Ownership is released when destroyExternalImage() is called.
*
* WARNING: This is called synchronously from the application thread (NOT the Driver thread)
*
* @param externalImage A token representing the platform's external image.
* @see destroyExternalImage
*/
virtual void retainExternalImage(void* externalImage) noexcept;
/**
* Called to bind the platform-specific externalImage to an ExternalTexture.
* ExternalTexture::id is guaranteed to be bound when this method is called and ExternalTexture
* is updated with new values for id/target if necessary.
*
* WARNING: this method is not allowed to change the bound texture, or must restore the previous
* binding upon return. This is to avoid problem with a backend doing state caching.
*
* @param externalImage The platform-specific external image.
* @param texture an in/out pointer to ExternalTexture, id and target can be updated if necessary.
* @return true on success, false on error.
*/
virtual bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept;
/**
* The method allows platforms to convert a user-supplied external image object into a new type
* (e.g. HardwareBuffer => EGLImage). The default implementation returns source.
* @param source Image to transform.
* @return Transformed image.
*/
virtual AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2017 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_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#include <stdint.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
namespace filament::backend {
struct PlatformCocoaGLImpl;
/**
* A concrete implementation of OpenGLPlatform that supports macOS's Cocoa.
*/
class PlatformCocoaGL : public OpenGLPlatform {
public:
PlatformCocoaGL();
~PlatformCocoaGL() noexcept override;
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
// Currently returns 0
int getOSVersion() const noexcept override;
bool pumpEvents() noexcept override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
private:
PlatformCocoaGLImpl* pImpl = nullptr;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2017 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_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#include <stdint.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
namespace filament::backend {
struct PlatformCocoaTouchGLImpl;
class PlatformCocoaTouchGL : public OpenGLPlatform {
public:
PlatformCocoaTouchGL();
~PlatformCocoaTouchGL() noexcept;
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept final { return 0; }
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
uint32_t createDefaultRenderTarget() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImage(ExternalTexture* texture) noexcept override;
void retainExternalImage(void* externalImage) noexcept override;
bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept override;
private:
PlatformCocoaTouchGLImpl* pImpl = nullptr;
};
using ContextManager = PlatformCocoaTouchGL;
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H

View File

@@ -22,65 +22,97 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <backend/DriverEnums.h>
#include <backend/platforms/OpenGLPlatform.h>
#include "private/backend/OpenGLPlatform.h"
#include <backend/DriverEnums.h>
namespace filament::backend {
/**
* A concrete implementation of OpenGLPlatform that supports EGL.
*/
class PlatformEGL : public OpenGLPlatform {
public:
PlatformEGL() noexcept;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
/**
* Initializes EGL, creates the OpenGL context and returns a concrete Driver implementation
* that supports OpenGL/OpenGL ES.
*/
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
/**
* This returns zero. This method can be overridden to return something more useful.
* @return zero
*/
int getOSVersion() const noexcept override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept override;
bool isSRGBSwapChainSupported() const noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
bool canCreateFence() noexcept override { return true; }
bool canCreateFence() noexcept override;
Fence* createFence() noexcept override;
void destroyFence(Fence* fence) noexcept override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
void createExternalImageTexture(void* texture) noexcept override;
void destroyExternalImage(void* texture) noexcept override;
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImage(ExternalTexture* texture) noexcept override;
bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept override;
/* default no-op implementations... */
int getOSVersion() const noexcept override { return 0; }
void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept override {}
Stream* createStream(void* nativeStream) noexcept override { return nullptr; }
void destroyStream(Stream* stream) noexcept override {}
void attach(Stream* stream, intptr_t tname) noexcept override {}
void detach(Stream* stream) noexcept override {}
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept override {}
protected:
/**
* Logs glGetError() to slog.e
* @param name a string giving some context on the error. Typically __func__.
*/
static void logEglError(const char* name) noexcept;
/**
* Calls glGetError() to clear the current error flags. logs a warning to log.w if
* an error was pending.
*/
static void clearGlError() noexcept;
/**
* Always use this instead of eglMakeCurrent().
*/
EGLBoolean makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) noexcept;
void initializeGlExtensions() noexcept;
// TODO: this should probably use getters instead.
EGLDisplay mEGLDisplay = EGL_NO_DISPLAY;
EGLContext mEGLContext = EGL_NO_CONTEXT;
EGLSurface mCurrentDrawSurface = EGL_NO_SURFACE;
EGLSurface mCurrentReadSurface = EGL_NO_SURFACE;
EGLSurface mEGLDummySurface = EGL_NO_SURFACE;
EGLConfig mEGLConfig = EGL_NO_CONFIG_KHR;
EGLConfig mEGLTransparentConfig = EGL_NO_CONFIG_KHR;
// supported extensions detected at runtime
struct {
bool OES_EGL_image_external_essl3 = false;
struct {
bool OES_EGL_image_external_essl3 = false;
} gl;
struct {
bool KHR_no_config_context = false;
bool KHR_gl_colorspace = false;
} egl;
} ext;
private:
void initializeGlExtensions() noexcept;
EGLConfig findSwapChainConfig(uint64_t flags) const;
};
} // namespace filament::backend

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2017 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_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#include <backend/platforms/PlatformEGL.h>
namespace filament::backend {
class ExternalStreamManagerAndroid;
/**
* A concrete implementation of OpenGLPlatform and subclass of PlatformEGL that supports
* EGL on Android. It adds Android streaming functionality to PlatformEGL.
*/
class PlatformEGLAndroid : public PlatformEGL {
public:
PlatformEGLAndroid() noexcept;
~PlatformEGLAndroid() noexcept override;
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
/**
* Returns the Android SDK version.
* @return Android SDK version.
*/
int getOSVersion() const noexcept override;
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
/**
* Set the presentation time using `eglPresentationTimeANDROID`
* @param presentationTimeInNanosecond
*/
void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept override;
Stream* createStream(void* nativeStream) noexcept override;
void destroyStream(Stream* stream) noexcept override;
void attach(Stream* stream, intptr_t tname) noexcept override;
void detach(Stream* stream) noexcept override;
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept override;
/**
* Converts a AHardwareBuffer to EGLImage
* @param source source.image is a AHardwareBuffer
* @return source.image contains an EGLImage
*/
AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept override;
private:
int mOSVersion;
ExternalStreamManagerAndroid& mExternalStreamManager;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H

View File

@@ -21,16 +21,15 @@
namespace filament::backend {
class PlatformEGLHeadless final : public PlatformEGL {
/**
* A concrete implementation of OpenGLPlatform that supports EGL with only headless swapchains.
*/
class PlatformEGLHeadless : public PlatformEGL {
public:
PlatformEGLHeadless() noexcept;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept final;
void createExternalImageTexture(void* texture) noexcept final {}
void destroyExternalImage(void* texture) noexcept final {}
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
};
} // namespace filament

View File

@@ -19,44 +19,41 @@
#include <stdint.h>
#include <bluegl/BlueGL.h>
#include "bluegl/BlueGL.h"
#include <GL/glx.h>
#include <backend/DriverEnums.h>
#include <backend/platforms/OpenGLPlatform.h>
#include "private/backend/OpenGLPlatform.h"
#include <backend/DriverEnums.h>
#include <vector>
namespace filament::backend {
class PlatformGLX final : public OpenGLPlatform {
public:
/**
* A concrete implementation of OpenGLPlatform that supports GLX.
*/
class PlatformGLX : public OpenGLPlatform {
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* const sharedGLContext, const DriverConfig& driverConfig) noexcept override;
Driver* createDriver(void* sharedGLContext,
const DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept final override { return 0; }
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
Fence* createFence() noexcept override;
void destroyFence(Fence* fence) noexcept override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
void setPresentationTime(int64_t time) noexcept final override {}
Stream* createStream(void* nativeStream) noexcept final override { return nullptr; }
void destroyStream(Stream* stream) noexcept final override {}
void attach(Stream* stream, intptr_t tname) noexcept final override {}
void detach(Stream* stream) noexcept final override {}
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept final override {}
int getOSVersion() const noexcept final override { return 0; }
private:
Display *mGLXDisplay;
GLXContext mGLXContext;

View File

@@ -20,40 +20,39 @@
#include <stdint.h>
#include <windows.h>
#include <utils/unwindows.h>
#include "utils/unwindows.h"
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include "private/backend/OpenGLPlatform.h"
namespace filament::backend {
class PlatformWGL final : public OpenGLPlatform {
public:
Driver* createDriver(void* const sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept override;
/**
* A concrete implementation of OpenGLPlatform that supports WGL.
*/
class PlatformWGL : public OpenGLPlatform {
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept final override { return 0; }
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
Fence* createFence() noexcept override;
void destroyFence(Fence* fence) noexcept override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
void setPresentationTime(int64_t time) noexcept final override {}
Stream* createStream(void* nativeStream) noexcept final override { return nullptr; }
void destroyStream(Stream* stream) noexcept final override {}
void attach(Stream* stream, intptr_t tname) noexcept final override {}
void detach(Stream* stream) noexcept final override {}
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept final override {}
int getOSVersion() const noexcept final override { return 0; }
private:
protected:
HGLRC mContext = NULL;
HWND mHWnd = NULL;
HDC mWhdc = NULL;

View File

@@ -0,0 +1,55 @@
/*
* 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_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
#include <stdint.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
namespace filament::backend {
/**
* A concrete implementation of OpenGLPlatform that supports WebGL.
*/
class PlatformWebGL : public OpenGLPlatform {
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H

View File

@@ -14,21 +14,36 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_VULKANPLATFORM_H
#define TNT_FILAMENT_BACKEND_VULKANPLATFORM_H
#ifndef TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H
#define TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H
#include <backend/Platform.h>
namespace filament::backend {
class VulkanPlatform : public DefaultPlatform {
/**
* A Platform interface that creates a Vulkan backend.
*/
class VulkanPlatform : public Platform {
public:
struct SurfaceBundle {
void* surface;
// On certain platforms, the extent of the surface cannot be queried from Vulkan. In those
// situations, we allow the frontend to pass in the extent to use in creating the swap
// chains. Platform implementation should set extent to 0 if they do not expect to set the
// swap chain extent.
uint32_t width;
uint32_t height;
};
// Given a Vulkan instance and native window handle, creates the platform-specific surface.
virtual void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept = 0;
virtual SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept = 0;
~VulkanPlatform() override;
};
} // namespace filament::backend
#endif //TNT_FILAMENT_BACKEND_VULKANPLATFORM_H
#endif //TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H

View File

@@ -299,11 +299,11 @@ DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchMultiSampleSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameTimeSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isAutoDepthResolveSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isSRGBSwapChainSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(uint8_t, getMaxDrawBuffers)
DECL_DRIVER_API_SYNCHRONOUS_0(math::float2, getClipSpaceParams)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, canGenerateMipmaps)
DECL_DRIVER_API_SYNCHRONOUS_N(void, setupExternalImage, void*, image)
DECL_DRIVER_API_SYNCHRONOUS_N(void, cancelExternalImage, void*, image)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, getTimerQueryValue, backend::TimerQueryHandle, query, uint64_t*, elapsedTime)
DECL_DRIVER_API_SYNCHRONOUS_N(backend::SyncStatus, getSyncStatus, backend::SyncHandle, sh)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isWorkaroundNeeded, backend::Workaround, workaround)

View File

@@ -1,111 +0,0 @@
/*
* Copyright (C) 2015 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_OPENGLPLATFORM_H
#define TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
#include <backend/Platform.h>
#include "private/backend/AcquiredImage.h"
namespace filament {
namespace backend {
class Driver;
class OpenGLPlatform : public DefaultPlatform {
protected:
/*
* Derived classes can use this to instantiate the default OpenGLDriver backend.
* This is typically called from your implementation of createDriver()
*/
static Driver* createDefaultDriver(OpenGLPlatform* platform, void* sharedContext, const DriverConfig& driverConfig);
public:
~OpenGLPlatform() noexcept override;
// Called to destroy the OpenGL context. This should clean up any windows
// or buffers from initialization.
virtual void terminate() noexcept = 0;
virtual SwapChain* createSwapChain(void* nativeWindow, uint64_t& flags) noexcept = 0;
// headless swapchain
virtual SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept = 0;
virtual void destroySwapChain(SwapChain* swapChain) noexcept = 0;
virtual void createDefaultRenderTarget(uint32_t& framebuffer, uint32_t& colorbuffer,
uint32_t& depthbuffer) noexcept {
framebuffer = 0;
colorbuffer = 0;
depthbuffer = 0;
}
// Called to make the OpenGL context active on the calling thread.
virtual void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept = 0;
// Called once the current frame finishes drawing. Typically this should
// swap draw buffers (i.e. for double-buffered rendering).
virtual void commit(SwapChain* swapChain) noexcept = 0;
virtual void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept = 0;
virtual bool canCreateFence() noexcept { return false; }
virtual Fence* createFence() noexcept = 0;
virtual void destroyFence(Fence* fence) noexcept = 0;
virtual backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept = 0;
// this is called synchronously in the application thread (NOT the Driver thread)
virtual Stream* createStream(void* nativeStream) noexcept = 0;
virtual void destroyStream(Stream* stream) noexcept = 0;
// attach takes ownership of the texture (tname) object
virtual void attach(Stream* stream, intptr_t tname) noexcept = 0;
// detach destroys the texture associated to the stream
virtual void detach(Stream* stream) noexcept = 0;
virtual void updateTexImage(Stream* stream, int64_t* timestamp) 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; }
// called to bind the platform-specific externalImage to a texture
// texture points to a OpenGLDriver::GLTexture
virtual bool setExternalImage(void* externalImage, void* texture) noexcept {
return false;
}
// called on the application thread to allow Filament to take ownership of the image
virtual void retainExternalImage(void* externalImage) noexcept {}
// called to release ownership of the image
virtual void releaseExternalImage(void* externalImage) noexcept {}
// called once when a new SAMPLER_EXTERNAL texture is created.
virtual void createExternalImageTexture(void* texture) noexcept {}
// called once before a SAMPLER_EXTERNAL texture is destroyed.
virtual void destroyExternalImage(void* texture) noexcept {}
};
} // namespace backend
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H

View File

@@ -0,0 +1,59 @@
/*
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
#define TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
#include "backend/DriverEnums.h"
#include "utils/compiler.h"
namespace filament::backend {
class Platform;
class UTILS_PUBLIC PlatformFactory {
public:
/**
* Creates a Platform configured for the requested backend if available
*
* @param backendHint Preferred backend, if not available the backend most suitable for the
* underlying platform is returned and \p backendHint is updated
* accordingly. Can't be nullptr.
*
* @return A pointer to the Platform object.
*
* @see destroy
*/
static Platform* create(backend::Backend* backendHint) noexcept;
/**
* Destroys a Platform object returned by create()
*
* @param platform a reference (as a pointer) to the Platform pointer to destroy.
* \p platform is cleared upon return.
*
* @see create
*/
static void destroy(Platform** platform) noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H

View File

@@ -0,0 +1,3 @@
# include/private/backend Headers
Headers in `include/private/backend/` are only public to filament and cannot be used by end-users.

View File

@@ -14,22 +14,21 @@
* limitations under the License.
*/
#include "private/backend/Driver.h"
#include "DriverBase.h"
#include "private/backend/AcquiredImage.h"
#include "private/backend/Driver.h"
#include "private/backend/CommandStream.h"
#include "DriverBase.h"
#include <backend/AcquiredImage.h>
#include <backend/BufferDescriptor.h>
#include <utils/Systrace.h>
#include <math/half.h>
#include <math/vec2.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <backend/BufferDescriptor.h>
#include <utils/Systrace.h>
using namespace utils;
using namespace filament::math;

View File

@@ -16,172 +16,13 @@
#include <backend/Platform.h>
#include <utils/Systrace.h>
#include <utils/debug.h>
#if defined(__ANDROID__)
#include <sys/system_properties.h>
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#include "opengl/platforms/PlatformEGLAndroid.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkAndroid.h"
#endif
#elif defined(IOS)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#include "opengl/platforms/PlatformCocoaTouchGL.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkCocoaTouch.h"
#endif
#elif defined(__APPLE__)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "opengl/platforms/PlatformCocoaGL.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkCocoa.h"
#endif
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_GGP)
#include "vulkan/PlatformVkLinuxGGP.h"
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkLinuxWayland.h"
#endif
#elif defined(FILAMENT_SUPPORTS_X11)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "opengl/platforms/PlatformGLX.h"
#endif
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkLinuxX11.h"
#endif
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "opengl/platforms/PlatformEGLHeadless.h"
#endif
#endif
#elif defined(WIN32)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "opengl/platforms/PlatformWGL.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkWindows.h"
#endif
#elif defined(__EMSCRIPTEN__)
#include "opengl/platforms/PlatformWebGL.h"
#endif
#if defined (FILAMENT_SUPPORTS_METAL)
namespace filament::backend {
filament::backend::DefaultPlatform* createDefaultMetalPlatform();
}
#endif
#include "noop/PlatformNoop.h"
namespace filament::backend {
// this generates the vtable in this translation unit
Platform::~Platform() noexcept = default;
// Creates the platform-specific Platform object. The caller takes ownership and is
// responsible for destroying it. Initialization of the backend API is deferred until
// createDriver(). The passed-in backend hint is replaced with the resolved backend.
DefaultPlatform* DefaultPlatform::create(Backend* backend) noexcept {
SYSTRACE_CALL();
assert_invariant(backend);
#if defined(__ANDROID__)
char scratch[PROP_VALUE_MAX + 1];
int length = __system_property_get("debug.filament.backend", scratch);
if (length > 0) {
*backend = Backend(atoi(scratch));
}
#endif
if (*backend == Backend::DEFAULT) {
#if defined(__EMSCRIPTEN__)
*backend = Backend::OPENGL;
#elif defined(__ANDROID__)
*backend = Backend::OPENGL;
#elif defined(IOS) || defined(__APPLE__)
*backend = Backend::METAL;
#elif defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
*backend = Backend::VULKAN;
#else
* backend = Backend::OPENGL;
#endif
}
if (*backend == Backend::NOOP) {
return new PlatformNoop();
}
if (*backend == Backend::VULKAN) {
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#if defined(__ANDROID__)
return new PlatformVkAndroid();
#elif defined(IOS)
return new PlatformVkCocoaTouch();
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_GGP)
return new PlatformVkLinuxGGP();
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
return new PlatformVkLinuxWayland();
#elif defined(FILAMENT_SUPPORTS_X11)
return new PlatformVkLinuxX11();
#endif
#elif defined(__APPLE__)
return new PlatformVkCocoa();
#elif defined(WIN32)
return new PlatformVkWindows();
#else
return nullptr;
#endif
#else
return nullptr;
#endif
}
if (*backend == Backend::METAL) {
#if defined(FILAMENT_SUPPORTS_METAL)
return createDefaultMetalPlatform();
#else
return nullptr;
#endif
}
assert_invariant(*backend == Backend::OPENGL);
#if defined(FILAMENT_SUPPORTS_OPENGL)
#if defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(FILAMENT_USE_SWIFTSHADER)
// Swiftshader OpenGLES support is deprecated and incomplete
return nullptr;
#elif defined(__ANDROID__)
return new PlatformEGLAndroid();
#elif defined(IOS)
return new PlatformCocoaTouchGL();
#elif defined(__APPLE__)
return new PlatformCocoaGL();
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_X11)
return new PlatformGLX();
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
return new PlatformEGLHeadless();
#endif
#elif defined(WIN32)
return new PlatformWGL();
#elif defined(__EMSCRIPTEN__)
return new PlatformWebGL();
#else
return nullptr;
#endif
#else
return nullptr;
#endif
bool Platform::pumpEvents() noexcept {
return false;
}
// destroys a Platform created by create()
void DefaultPlatform::destroy(DefaultPlatform** platform) noexcept {
delete *platform;
*platform = nullptr;
}
DefaultPlatform::~DefaultPlatform() noexcept = default;
} // namespace filament::backend

View File

@@ -0,0 +1,182 @@
/*
* 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 <private/backend/PlatformFactory.h>
#include <utils/Systrace.h>
#include <utils/debug.h>
#if defined(__ANDROID__)
#include <sys/system_properties.h>
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#include "backend/platforms/PlatformEGLAndroid.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkAndroid.h"
#endif
#elif defined(IOS)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#include "backend/platforms/PlatformCocoaTouchGL.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkCocoaTouch.h"
#endif
#elif defined(__APPLE__)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include <backend/platforms/PlatformCocoaGL.h>
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkCocoa.h"
#endif
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_GGP)
#include "vulkan/PlatformVkLinuxGGP.h"
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkLinuxWayland.h"
#endif
#elif defined(FILAMENT_SUPPORTS_X11)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "backend/platforms/PlatformGLX.h"
#endif
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkLinuxX11.h"
#endif
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "backend/platforms/PlatformEGLHeadless.h"
#endif
#endif
#elif defined(WIN32)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "backend/platforms/PlatformWGL.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkWindows.h"
#endif
#elif defined(__EMSCRIPTEN__)
#include "backend/platforms/PlatformWebGL.h"
#endif
#if defined (FILAMENT_SUPPORTS_METAL)
namespace filament::backend {
filament::backend::Platform* createDefaultMetalPlatform();
}
#endif
#include "noop/PlatformNoop.h"
namespace filament::backend {
// Creates the platform-specific Platform object. The caller takes ownership and is
// responsible for destroying it. Initialization of the backend API is deferred until
// createDriver(). The passed-in backend hint is replaced with the resolved backend.
Platform* PlatformFactory::create(Backend* backend) noexcept {
SYSTRACE_CALL();
assert_invariant(backend);
#if defined(__ANDROID__)
char scratch[PROP_VALUE_MAX + 1];
int length = __system_property_get("debug.filament.backend", scratch);
if (length > 0) {
*backend = Backend(atoi(scratch));
}
#endif
if (*backend == Backend::DEFAULT) {
#if defined(__EMSCRIPTEN__)
*backend = Backend::OPENGL;
#elif defined(__ANDROID__)
*backend = Backend::OPENGL;
#elif defined(IOS) || defined(__APPLE__)
*backend = Backend::METAL;
#elif defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
*backend = Backend::VULKAN;
#else
* backend = Backend::OPENGL;
#endif
}
if (*backend == Backend::NOOP) {
return new PlatformNoop();
}
if (*backend == Backend::VULKAN) {
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#if defined(__ANDROID__)
return new PlatformVkAndroid();
#elif defined(IOS)
return new PlatformVkCocoaTouch();
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_GGP)
return new PlatformVkLinuxGGP();
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
return new PlatformVkLinuxWayland();
#elif defined(FILAMENT_SUPPORTS_X11)
return new PlatformVkLinuxX11();
#endif
#elif defined(__APPLE__)
return new PlatformVkCocoa();
#elif defined(WIN32)
return new PlatformVkWindows();
#else
return nullptr;
#endif
#else
return nullptr;
#endif
}
if (*backend == Backend::METAL) {
#if defined(FILAMENT_SUPPORTS_METAL)
return createDefaultMetalPlatform();
#else
return nullptr;
#endif
}
assert_invariant(*backend == Backend::OPENGL);
#if defined(FILAMENT_SUPPORTS_OPENGL)
#if defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(FILAMENT_USE_SWIFTSHADER)
// Swiftshader OpenGLES support is deprecated and incomplete
return nullptr;
#elif defined(__ANDROID__)
return new PlatformEGLAndroid();
#elif defined(IOS)
return new PlatformCocoaTouchGL();
#elif defined(__APPLE__)
return new PlatformCocoaGL();
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_X11)
return new PlatformGLX();
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
return new PlatformEGLHeadless();
#endif
#elif defined(WIN32)
return new PlatformWGL();
#elif defined(__EMSCRIPTEN__)
return new PlatformWebGL();
#else
return nullptr;
#endif
#else
return nullptr;
#endif
}
// destroys a Platform created by create()
void PlatformFactory::destroy(Platform** platform) noexcept {
delete *platform;
*platform = nullptr;
}
} // namespace filament::backend

View File

@@ -68,7 +68,7 @@ public:
}
};
void blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args);
void blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args, const char* label);
/**
* Free resources. Should be called at least once per process when no further calls to blit will
@@ -112,11 +112,12 @@ private:
};
void blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor, bool& blitDepth,
const BlitArgs& args);
const BlitArgs& args, const char* label);
void blitSlowPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor, bool& blitDepth,
const BlitArgs& args);
const BlitArgs& args, const char* label);
void blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor, bool blitDepth,
const BlitArgs& args, uint32_t depthPlaneSource, uint32_t depthPlaneDest);
const BlitArgs& args, uint32_t depthPlaneSource, uint32_t depthPlaneDest,
const char* label);
id<MTLTexture> createIntermediateTexture(id<MTLTexture> t, MTLSize size);
id<MTLFunction> compileFragmentFunction(BlitFunctionKey key);
id<MTLFunction> getBlitVertexFunction();

View File

@@ -143,7 +143,7 @@ MetalBlitter::MetalBlitter(MetalContext& context) noexcept : mContext(context) {
#define MTLSizeEqual(a, b) (a.width == b.width && a.height == b.height && a.depth == b.depth)
void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args) {
void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args, const char* label) {
bool blitColor = args.blitColor();
bool blitDepth = args.blitDepth();
@@ -164,7 +164,7 @@ void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args) {
// Determine if the blit for color or depth are eligible to use a MTLBlitCommandEncoder.
// blitColor and / or blitDepth are set to false upon success, to indicate that no more work is
// necessary for that attachment.
blitFastPath(cmdBuffer, blitColor, blitDepth, args);
blitFastPath(cmdBuffer, blitColor, blitDepth, args, label);
if (!blitColor && !blitDepth) {
return;
@@ -207,21 +207,22 @@ void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args) {
slowBlit.destination.region = finalBlit.source.region = sourceRegionNoOffset;
}
blitSlowPath(cmdBuffer, blitColor, blitDepth, slowBlit);
blitSlowPath(cmdBuffer, blitColor, blitDepth, slowBlit, label);
bool finalBlitColor = intermediateColor != nil;
bool finalBlitDepth = intermediateDepth != nil;
blitFastPath(cmdBuffer, finalBlitColor, finalBlitDepth, finalBlit);
blitFastPath(cmdBuffer, finalBlitColor, finalBlitDepth, finalBlit, label);
}
void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor, bool& blitDepth,
const BlitArgs& args) {
const BlitArgs& args, const char* label) {
if (blitColor) {
if (args.source.color.sampleCount == args.destination.color.sampleCount &&
args.source.color.pixelFormat == args.destination.color.pixelFormat &&
MTLSizeEqual(args.source.region.size, args.destination.region.size)) {
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
blitEncoder.label = @(label);
[blitEncoder copyFromTexture:args.source.color
sourceSlice:args.source.slice
sourceLevel:args.source.level
@@ -243,6 +244,7 @@ void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
MTLSizeEqual(args.source.region.size, args.destination.region.size)) {
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
blitEncoder.label = @(label);
[blitEncoder copyFromTexture:args.source.depth
sourceSlice:args.source.slice
sourceLevel:args.source.level
@@ -260,7 +262,7 @@ void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
}
void MetalBlitter::blitSlowPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor, bool& blitDepth,
const BlitArgs& args) {
const BlitArgs& args, const char* label) {
uint32_t depthPlaneSource = args.source.region.origin.z;
uint32_t depthPlaneDest = args.destination.region.origin.z;
@@ -268,7 +270,8 @@ void MetalBlitter::blitSlowPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
assert_invariant(args.source.region.size.depth == args.destination.region.size.depth);
uint32_t depthPlaneCount = args.source.region.size.depth;
for (NSUInteger d = 0; d < depthPlaneCount; d++) {
blitDepthPlane(cmdBuffer, blitColor, blitDepth, args, depthPlaneSource++, depthPlaneDest++);
blitDepthPlane(cmdBuffer, blitColor, blitDepth, args, depthPlaneSource++, depthPlaneDest++,
label);
}
blitColor = false;
@@ -276,7 +279,8 @@ void MetalBlitter::blitSlowPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
}
void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor, bool blitDepth,
const BlitArgs& args, uint32_t depthPlaneSource, uint32_t depthPlaneDest) {
const BlitArgs& args, uint32_t depthPlaneSource, uint32_t depthPlaneDest,
const char* label) {
MTLRenderPassDescriptor* descriptor = [MTLRenderPassDescriptor renderPassDescriptor];
if (blitColor) {
@@ -288,7 +292,7 @@ void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor
}
id<MTLRenderCommandEncoder> encoder = [cmdBuffer renderCommandEncoderWithDescriptor:descriptor];
encoder.label = @"Blit";
encoder.label = @(label);
BlitFunctionKey key;
key.blitColor = blitColor;

View File

@@ -69,6 +69,7 @@ void MetalBuffer::copyIntoBuffer(void* src, size_t size, size_t byteOffset) {
// Encode a blit from the staging buffer into the private GPU buffer.
id<MTLCommandBuffer> cmdBuffer = getPendingCommandBuffer(&mContext);
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
blitEncoder.label = @"Buffer upload blit";
[blitEncoder copyFromBuffer:staging->buffer
sourceOffset:0
toBuffer:mBuffer

View File

@@ -27,7 +27,7 @@
#include "MetalState.h"
#include "MetalTimerQuery.h"
#include "private/backend/MetalPlatform.h"
#include "MetalPlatform.h"
#include <CoreVideo/CVMetalTexture.h>
#include <CoreVideo/CVPixelBuffer.h>
@@ -706,6 +706,11 @@ bool MetalDriver::isAutoDepthResolveSupported() {
return mContext->supportsAutoDepthResolve;
}
bool MetalDriver::isSRGBSwapChainSupported() {
// the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag is not supported
return false;
}
bool MetalDriver::isWorkaroundNeeded(Workaround workaround) {
switch (workaround) {
case Workaround::SPLIT_EASU:
@@ -803,11 +808,6 @@ void MetalDriver::setupExternalImage(void* image) {
CVPixelBufferRetain(pixelBuffer);
}
void MetalDriver::cancelExternalImage(void* image) {
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef) image;
CVPixelBufferRelease(pixelBuffer);
}
void MetalDriver::setExternalImage(Handle<HwTexture> th, void* image) {
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"setExternalImage must be called outside of a render pass.");
@@ -1263,7 +1263,7 @@ void MetalDriver::readPixels(Handle<HwRenderTarget> src, uint32_t x, uint32_t y,
args.source.color = srcTexture;
args.destination.color = readPixelsTexture;
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
mContext->blitter->blit(getPendingCommandBuffer(mContext), args, "readPixels blit");
#if !defined(IOS)
// Managed textures on macOS require explicit synchronization between GPU / CPU.
@@ -1347,7 +1347,7 @@ void MetalDriver::blit(TargetBufferFlags buffers,
args.destination.level = dstColorAttachment.level;
args.source.slice = srcColorAttachment.layer;
args.destination.slice = dstColorAttachment.layer;
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
mContext->blitter->blit(getPendingCommandBuffer(mContext), args, "Color blit");
}
}
@@ -1370,7 +1370,7 @@ void MetalDriver::blit(TargetBufferFlags buffers,
args.destination.level = dstDepthAttachment.level;
args.source.slice = srcDepthAttachment.layer;
args.destination.slice = dstDepthAttachment.layer;
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
mContext->blitter->blit(getPendingCommandBuffer(mContext), args, "Depth blit");
}
}
}

View File

@@ -391,6 +391,9 @@ MetalProgram::MetalProgram(id<MTLDevice> device, const Program& program) noexcep
id<MTLFunction> function = [library newFunctionWithName:@"main0"
constantValues:constants
error:&error];
if (!program.getName().empty()) {
function.label = @(program.getName().c_str());
}
assert_invariant(function);
*shaderFunctions[i] = function;
}
@@ -720,6 +723,7 @@ void MetalTexture::loadWithCopyBuffer(uint32_t level, uint32_t slice, MTLRegion
stagingBufferSize);
id<MTLCommandBuffer> blitCommandBuffer = getPendingCommandBuffer(&context);
id<MTLBlitCommandEncoder> blitCommandEncoder = [blitCommandBuffer blitCommandEncoder];
blitCommandEncoder.label = @"Texture upload buffer blit";
[blitCommandEncoder copyFromBuffer:entry->buffer
sourceOffset:0
sourceBytesPerRow:shape.bytesPerRow
@@ -792,7 +796,7 @@ void MetalTexture::loadWithBlit(uint32_t level, uint32_t slice, MTLRegion region
args.destination.region = region;
args.source.color = stagingTexture;
args.destination.color = destinationTexture;
context.blitter->blit(getPendingCommandBuffer(&context), args);
context.blitter->blit(getPendingCommandBuffer(&context), args, "Texture upload blit");
}
void MetalTexture::updateLodRange(uint32_t level) {

View File

@@ -22,10 +22,9 @@
#import <Metal/Metal.h>
namespace filament {
namespace backend {
namespace filament::backend {
class MetalPlatform : public DefaultPlatform {
class MetalPlatform final : public Platform {
public:
~MetalPlatform() override;
@@ -60,7 +59,6 @@ private:
};
} // namespace backend
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRIVATE_METALPLATFORM_H

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "private/backend/MetalPlatform.h"
#include "MetalPlatform.h"
#include "MetalDriverFactory.h"
@@ -22,16 +22,15 @@
#import <Foundation/Foundation.h>
namespace filament {
namespace backend {
namespace filament::backend {
DefaultPlatform* createDefaultMetalPlatform() {
Platform* createDefaultMetalPlatform() {
return new MetalPlatform();
}
MetalPlatform::~MetalPlatform() = default;
Driver* MetalPlatform::createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
Driver* MetalPlatform::createDriver(void* /*sharedContext*/, const Platform::DriverConfig& driverConfig) noexcept {
return MetalDriverFactory::create(this, driverConfig);
}
@@ -75,5 +74,4 @@ id<MTLCommandBuffer> MetalPlatform::createAndEnqueueCommandBuffer() noexcept {
return commandBuffer;
}
} // namespace backend
} // namespace filament

View File

@@ -173,7 +173,11 @@ bool NoopDriver::isAutoDepthResolveSupported() {
return true;
}
bool NoopDriver::isWorkaroundNeeded(Workaround workaround) {
bool NoopDriver::isSRGBSwapChainSupported() {
return false;
}
bool NoopDriver::isWorkaroundNeeded(Workaround) {
return false;
}
@@ -224,9 +228,6 @@ void NoopDriver::update3DImage(Handle<HwTexture> th,
void NoopDriver::setupExternalImage(void* image) {
}
void NoopDriver::cancelExternalImage(void* image) {
}
bool NoopDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint64_t* elapsedTime) {
return false;
}

View File

@@ -22,7 +22,7 @@
namespace filament::backend {
class PlatformNoop final : public DefaultPlatform {
class PlatformNoop final : public Platform {
public:
int getOSVersion() const noexcept final { return 0; }

View File

@@ -268,7 +268,9 @@ OpenGLContext::OpenGLContext() noexcept {
}
#endif
#if !defined(NDEBUG) && defined(GL_KHR_debug)
// in practice KHR_Debug has never been useful, and actually is confusing. We keep this
// only for our own debugging, in case we need it some day.
#if false && !defined(NDEBUG) && defined(GL_KHR_debug)
if (ext.KHR_debug) {
auto cb = +[](GLenum, GLenum type, GLuint, GLenum severity, GLsizei length,
const GLchar* message, const void *) {

View File

@@ -17,14 +17,14 @@
#include "OpenGLDriver.h"
#include "private/backend/DriverApi.h"
#include "private/backend/OpenGLPlatform.h"
#include "CommandStreamDispatcher.h"
#include "OpenGLContext.h"
#include "OpenGLDriverFactory.h"
#include "OpenGLProgram.h"
#include "OpenGLTimerQuery.h"
#include "OpenGLContext.h"
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/SamplerDescriptor.h>
#include <utils/compiler.h>
@@ -171,7 +171,7 @@ OpenGLDriver::OpenGLDriver(OpenGLPlatform* platform, const Platform::DriverConfi
// set a reasonable default value for our stream array
mTexturesWithStreamsAttached.reserve(8);
mStreamsWithPendingAquiredImage.reserve(8);
mStreamsWithPendingAcquiredImage.reserve(8);
#ifndef NDEBUG
slog.i << "OS version: " << mPlatform.getOSVersion() << io::endl;
@@ -574,7 +574,17 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
GLTexture* t = construct<GLTexture>(th, target, levels, samples, w, h, depth, format, usage);
if (UTILS_LIKELY(usage & TextureUsage::SAMPLEABLE)) {
if (UTILS_UNLIKELY(t->target == SamplerType::SAMPLER_EXTERNAL)) {
mPlatform.createExternalImageTexture(t);
t->externalTexture = mPlatform.createExternalImageTexture();
if (t->externalTexture) {
t->gl.target = t->externalTexture->target;
t->gl.id = t->externalTexture->id;
t->gl.targetIndex = (uint8_t)OpenGLContext::getIndexForTextureTarget(t->gl.target);
// internalFormat actually depends on the external image, but it doesn't matter
// because it's not used anywhere for anything important.
t->gl.internalFormat = getInternalFormat(format);
t->gl.baseLevel = 0;
t->gl.maxLevel = 0;
}
} else {
glGenTextures(1, &t->gl.id);
@@ -1063,10 +1073,7 @@ void OpenGLDriver::createDefaultRenderTargetR(
construct<GLRenderTarget>(rth, 0, 0); // FIXME: we don't know the width/height
uint32_t framebuffer = 0;
uint32_t colorbuffer = 0;
uint32_t depthbuffer = 0;
mPlatform.createDefaultRenderTarget(framebuffer, colorbuffer, depthbuffer);
uint32_t framebuffer = mPlatform.createDefaultRenderTarget();
GLRenderTarget* rt = handle_cast<GLRenderTarget*>(rth);
rt->gl.fbo = framebuffer;
@@ -1317,7 +1324,7 @@ void OpenGLDriver::destroyTexture(Handle<HwTexture> th) {
detachStream(t);
}
if (UTILS_UNLIKELY(t->target == SamplerType::SAMPLER_EXTERNAL)) {
mPlatform.destroyExternalImage(t);
mPlatform.destroyExternalImage(t->externalTexture);
} else {
glDeleteTextures(1, &t->gl.id);
}
@@ -1451,7 +1458,7 @@ void OpenGLDriver::setAcquiredImage(Handle<HwStream> sh, void* hwbuffer,
// If there's no pending image, do nothing. Note that GL_OES_EGL_image does not let you pass
// NULL to glEGLImageTargetTexture2DOES, and there is no concept of "detaching" an
// EGLimage from a texture.
mStreamsWithPendingAquiredImage.push_back(glstream);
mStreamsWithPendingAcquiredImage.push_back(glstream);
}
}
@@ -1459,8 +1466,8 @@ void OpenGLDriver::setAcquiredImage(Handle<HwStream> sh, void* hwbuffer,
// and therefore do not require synchronization. The former is always called immediately before
// beginFrame, the latter is called by the user from anywhere outside beginFrame / endFrame.
void OpenGLDriver::updateStreams(DriverApi* driver) {
if (UTILS_UNLIKELY(!mStreamsWithPendingAquiredImage.empty())) {
for (GLStream* s : mStreamsWithPendingAquiredImage) {
if (UTILS_UNLIKELY(!mStreamsWithPendingAcquiredImage.empty())) {
for (GLStream* s : mStreamsWithPendingAcquiredImage) {
assert_invariant(s);
assert_invariant(s->streamType == StreamType::ACQUIRED);
@@ -1478,7 +1485,15 @@ void OpenGLDriver::updateStreams(DriverApi* driver) {
return t->hwStream == s;
});
if (pos != streams.end()) {
setExternalTexture(*pos, image);
GLTexture* t = *pos;
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
if (mPlatform.setExternalImage(image, t->externalTexture)) {
// the target and id can be reset each time
t->gl.target = t->externalTexture->target;
t->gl.id = t->externalTexture->id;
t->gl.targetIndex = (uint8_t)OpenGLContext::getIndexForTextureTarget(t->gl.target);
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
}
}
if (previousImage.image) {
@@ -1486,7 +1501,7 @@ void OpenGLDriver::updateStreams(DriverApi* driver) {
}
});
}
mStreamsWithPendingAquiredImage.clear();
mStreamsWithPendingAcquiredImage.clear();
}
}
@@ -1676,6 +1691,10 @@ bool OpenGLDriver::isAutoDepthResolveSupported() {
return true;
}
bool OpenGLDriver::isSRGBSwapChainSupported() {
return mPlatform.isSRGBSwapChainSupported();
}
bool OpenGLDriver::isWorkaroundNeeded(Workaround workaround) {
switch (workaround) {
case Workaround::SPLIT_EASU:
@@ -2163,37 +2182,26 @@ void OpenGLDriver::setupExternalImage(void* image) {
mPlatform.retainExternalImage(image);
}
void OpenGLDriver::cancelExternalImage(void* image) {
mPlatform.releaseExternalImage(image);
}
void OpenGLDriver::setExternalImage(Handle<HwTexture> th, void* image) {
DEBUG_MARKER()
mPlatform.setExternalImage(image, handle_cast<GLTexture*>(th));
setExternalTexture(handle_cast<GLTexture*>(th), image);
GLTexture* t = handle_cast<GLTexture*>(th);
assert_invariant(t);
assert_invariant(t->target == SamplerType::SAMPLER_EXTERNAL);
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
if (mPlatform.setExternalImage(image, t->externalTexture)) {
// the target and id can be reset each time
t->gl.target = t->externalTexture->target;
t->gl.id = t->externalTexture->id;
t->gl.targetIndex = (uint8_t)OpenGLContext::getIndexForTextureTarget(t->gl.target);
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
}
}
void OpenGLDriver::setExternalImagePlane(Handle<HwTexture> th, void* image, uint32_t plane) {
DEBUG_MARKER()
}
void OpenGLDriver::setExternalTexture(GLTexture* t, void* image) {
auto& gl = mContext;
// TODO: move this logic to PlatformEGL.
if (gl.ext.OES_EGL_image_external_essl3) {
assert_invariant(t->target == SamplerType::SAMPLER_EXTERNAL);
assert_invariant(t->gl.target == GL_TEXTURE_EXTERNAL_OES);
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
gl.activeTexture(OpenGLContext::DUMMY_TEXTURE_BINDING);
#ifdef GL_OES_EGL_image
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, static_cast<GLeglImageOES>(image));
#endif
}
}
void OpenGLDriver::setExternalStream(Handle<HwTexture> th, Handle<HwStream> sh) {
auto& gl = mContext;
if (gl.ext.OES_EGL_image_external_essl3) {
@@ -3200,8 +3208,14 @@ void OpenGLDriver::dispatchCompute(Handle<HwProgram> program, math::uint3 workGr
useProgram(p);
#if defined(GL_ES_VERSION_3_1) || defined(GL_VERSION_4_3)
// FIXME: this line is commented-out for now due to issues switching G3 clients to API 21.
// glDispatchCompute(workGroupCount.x, workGroupCount.y, workGroupCount.z);
#if defined(__ANDROID__)
// on Android, GLES3.1 and above entry-points are defined in glext
// (this is temporary, until we phase-out API < 21)
using glext::glDispatchCompute;
#endif
glDispatchCompute(workGroupCount.x, workGroupCount.y, workGroupCount.z);
#endif
#ifdef FILAMENT_ENABLE_MATDBG

View File

@@ -21,12 +21,14 @@
#include "GLUtils.h"
#include "OpenGLContext.h"
#include "private/backend/AcquiredImage.h"
#include "private/backend/Driver.h"
#include "private/backend/HandleAllocator.h"
#include "backend/Program.h"
#include "backend/TargetBufferInfo.h"
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/AcquiredImage.h>
#include <backend/Program.h>
#include <backend/TargetBufferInfo.h>
#include <utils/compiler.h>
#include <utils/Allocator.h>
@@ -132,7 +134,7 @@ public:
uint8_t reserved : 3;
} gl;
void* platformPImpl = nullptr;
OpenGLPlatform::ExternalTexture* externalTexture = nullptr;
};
struct GLTimerQuery : public HwTimerQuery {
@@ -349,7 +351,7 @@ private:
std::vector<GLTexture*> mTexturesWithStreamsAttached;
// the must be accessed from the user thread only
std::vector<GLStream*> mStreamsWithPendingAquiredImage;
std::vector<GLStream*> mStreamsWithPendingAcquiredImage;
void attachStream(GLTexture* t, GLStream* stream) noexcept;
void detachStream(GLTexture* t) noexcept;
@@ -359,8 +361,6 @@ private:
void updateTextureLodRange(GLTexture* texture, int8_t targetLevel) noexcept;
void setExternalTexture(GLTexture* t, void* image);
// tasks executed on the main thread after the fence signaled
void whenGpuCommandsComplete(std::function<void()> fn) noexcept;
void executeGpuCommandsCompleteOps() noexcept;

View File

@@ -14,16 +14,96 @@
* limitations under the License.
*/
#include "private/backend/OpenGLPlatform.h"
#include <backend/platforms/OpenGLPlatform.h>
#include "OpenGLDriverFactory.h"
namespace filament::backend {
OpenGLPlatform::~OpenGLPlatform() noexcept = default;
Driver* OpenGLPlatform::createDefaultDriver(OpenGLPlatform* platform, void* sharedContext, const Platform::DriverConfig& driverConfig) {
Driver* OpenGLPlatform::createDefaultDriver(OpenGLPlatform* platform,
void* sharedContext, const Platform::DriverConfig& driverConfig) {
return OpenGLDriverFactory::create(platform, sharedContext, driverConfig);
}
OpenGLPlatform::~OpenGLPlatform() noexcept = default;
bool OpenGLPlatform::isSRGBSwapChainSupported() const noexcept {
return false;
}
uint32_t OpenGLPlatform::createDefaultRenderTarget() noexcept {
return 0;
}
void OpenGLPlatform::setPresentationTime(
UTILS_UNUSED int64_t presentationTimeInNanosecond) noexcept {
}
bool OpenGLPlatform::canCreateFence() noexcept {
return false;
}
Platform::Fence* OpenGLPlatform::createFence() noexcept {
return nullptr;
}
void OpenGLPlatform::destroyFence(
UTILS_UNUSED Fence* fence) noexcept {
}
FenceStatus OpenGLPlatform::waitFence(
UTILS_UNUSED Fence* fence,
UTILS_UNUSED uint64_t timeout) noexcept {
return FenceStatus::ERROR;
}
Platform::Stream* OpenGLPlatform::createStream(
UTILS_UNUSED void* nativeStream) noexcept {
return nullptr;
}
void OpenGLPlatform::destroyStream(
UTILS_UNUSED Stream* stream) noexcept {
}
void OpenGLPlatform::attach(
UTILS_UNUSED Stream* stream,
UTILS_UNUSED intptr_t tname) noexcept {
}
void OpenGLPlatform::detach(
UTILS_UNUSED Stream* stream) noexcept {
}
void OpenGLPlatform::updateTexImage(
UTILS_UNUSED Stream* stream,
UTILS_UNUSED int64_t* timestamp) noexcept {
}
OpenGLPlatform::ExternalTexture* OpenGLPlatform::createExternalImageTexture() noexcept {
return nullptr;
}
void OpenGLPlatform::destroyExternalImage(
UTILS_UNUSED ExternalTexture* texture) noexcept {
}
void OpenGLPlatform::retainExternalImage(
UTILS_UNUSED void* externalImage) noexcept {
}
bool OpenGLPlatform::setExternalImage(
UTILS_UNUSED void* externalImage,
UTILS_UNUSED ExternalTexture* texture) noexcept {
return false;
}
AcquiredImage OpenGLPlatform::transformAcquiredImage(AcquiredImage source) noexcept {
return source;
}
} // namespace filament::backend

View File

@@ -16,7 +16,7 @@
#include "OpenGLTimerQuery.h"
#include "private/backend/OpenGLPlatform.h"
#include <backend/platforms/OpenGLPlatform.h>
#include <utils/compiler.h>
#include <utils/Log.h>

View File

@@ -49,6 +49,12 @@ PFNGLGETQUERYOBJECTUI64VEXTPROC glGetQueryObjectui64v;
PFNGLCLIPCONTROLEXTPROC glClipControl;
#endif
#if defined(__ANDROID__)
// On Android, If we want to support a build system less than ANDROID_API 21, we need to
// use getProcAddress for ES3.1 and above entry points.
PFNGLDISPATCHCOMPUTEPROC glDispatchCompute;
#endif
static std::once_flag sGlExtInitialized;
void importGLESExtensionsEntryPoints() {
@@ -109,6 +115,12 @@ void importGLESExtensionsEntryPoints() {
(PFNGLCLIPCONTROLEXTPROC)eglGetProcAddress(
"glClipControlEXT");
#endif
#if defined(__ANDROID__)
glDispatchCompute =
(PFNGLDISPATCHCOMPUTEPROC)eglGetProcAddress(
"glDispatchCompute");
#endif
}
} // namespace glext

View File

@@ -57,6 +57,9 @@
#endif
#ifdef GL_EXT_clip_control
extern PFNGLCLIPCONTROLEXTPROC glClipControl;
#endif
#if defined(__ANDROID__)
extern PFNGLDISPATCHCOMPUTEPROC glDispatchCompute;
#endif
}

View File

@@ -19,11 +19,13 @@
#include "../gl_headers.h"
#include <backend/platforms/OpenGLPlatform.h>
#include <CoreVideo/CoreVideo.h>
namespace filament::backend {
class CocoaTouchExternalImage final {
class CocoaTouchExternalImage final : public OpenGLPlatform::ExternalTexture {
public:
/**

View File

@@ -1,68 +0,0 @@
/*
* Copyright (C) 2017 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_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#include <stdint.h>
#include <backend/DriverEnums.h>
#include "private/backend/OpenGLPlatform.h"
namespace filament::backend {
struct PlatformCocoaGLImpl;
class PlatformCocoaGL final : public OpenGLPlatform {
public:
PlatformCocoaGL();
~PlatformCocoaGL() noexcept final;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
void terminate() noexcept final;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept final;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept final;
void destroySwapChain(SwapChain* swapChain) noexcept final;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept final;
void commit(SwapChain* swapChain) noexcept final;
Fence* createFence() noexcept final { return nullptr; }
void destroyFence(Fence* fence) noexcept final {}
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept final {
return FenceStatus::ERROR;
}
void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept final {}
Stream* createStream(void* nativeStream) noexcept final { return nullptr; }
void destroyStream(Stream* stream) noexcept final {}
void attach(Stream* stream, intptr_t tname) noexcept final {}
void detach(Stream* stream) noexcept final {}
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept final {}
int getOSVersion() const noexcept final { return 0; }
bool pumpEvents() noexcept override;
private:
PlatformCocoaGLImpl* pImpl = nullptr;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H

View File

@@ -17,9 +17,8 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#include "PlatformCocoaGL.h"
#include <backend/platforms/PlatformCocoaGL.h>
#include "opengl/OpenGLDriverFactory.h"
#include "opengl/gl_headers.h"
#include <utils/compiler.h>
@@ -35,7 +34,7 @@ namespace filament::backend {
using namespace backend;
struct CocoaGLSwapChain : public Platform::SwapChain {
CocoaGLSwapChain(NSView* inView);
explicit CocoaGLSwapChain(NSView* inView);
~CocoaGLSwapChain() noexcept;
NSView* view;
@@ -160,7 +159,11 @@ Driver* PlatformCocoaGL::createDriver(void* sharedContext, const Platform::Drive
int result = bluegl::bind();
ASSERT_POSTCONDITION(!result, "Unable to load OpenGL entry points.");
return OpenGLDriverFactory::create(this, sharedContext, driverConfig);
return OpenGLPlatform::createDefaultDriver(this, sharedContext, driverConfig);
}
int PlatformCocoaGL::getOSVersion() const noexcept {
return 0;
}
void PlatformCocoaGL::terminate() noexcept {
@@ -168,9 +171,7 @@ void PlatformCocoaGL::terminate() noexcept {
bluegl::unbind();
}
Platform::SwapChain* PlatformCocoaGL::createSwapChain(void* nativewindow, uint64_t& flags) noexcept {
// Transparent SwapChain is not supported
flags &= ~SWAP_CHAIN_CONFIG_TRANSPARENT;
Platform::SwapChain* PlatformCocoaGL::createSwapChain(void* nativewindow, uint64_t flags) noexcept {
NSView* nsView = (__bridge NSView*)nativewindow;
CocoaGLSwapChain* swapChain = new CocoaGLSwapChain( nsView );
@@ -185,7 +186,7 @@ Platform::SwapChain* PlatformCocoaGL::createSwapChain(void* nativewindow, uint64
return swapChain;
}
Platform::SwapChain* PlatformCocoaGL::createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept {
Platform::SwapChain* PlatformCocoaGL::createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept {
NSView* nsView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, width, height)];
// adding the pointer to the array retains the NSView

View File

@@ -1,75 +0,0 @@
/*
* Copyright (C) 2017 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_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#include <stdint.h>
#include <backend/DriverEnums.h>
#include "private/backend/OpenGLPlatform.h"
namespace filament::backend {
struct PlatformCocoaTouchGLImpl;
class PlatformCocoaTouchGL final : public OpenGLPlatform {
public:
PlatformCocoaTouchGL();
~PlatformCocoaTouchGL() noexcept final;
Driver* createDriver(void* sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept override;
void terminate() noexcept final;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept final;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept final;
void destroySwapChain(SwapChain* swapChain) noexcept final;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept final;
void commit(SwapChain* swapChain) noexcept final;
void createDefaultRenderTarget(uint32_t& framebuffer, uint32_t& colorbuffer,
uint32_t& depthbuffer) noexcept final;
Fence* createFence() noexcept final { return nullptr; }
void destroyFence(Fence* fence) noexcept final {}
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept final {
return FenceStatus::ERROR;
}
void setPresentationTime(int64_t time) noexcept final override {}
Stream* createStream(void* nativeStream) noexcept final { return nullptr; }
void destroyStream(Stream* stream) noexcept final {}
void attach(Stream* stream, intptr_t tname) noexcept final {}
void detach(Stream* stream) noexcept final {}
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept final {}
int getOSVersion() const noexcept final { return 0; }
bool setExternalImage(void* externalImage, void* texture) noexcept final;
void retainExternalImage(void* externalImage) noexcept final;
void releaseExternalImage(void* externalImage) noexcept final;
void createExternalImageTexture(void* texture) noexcept final;
void destroyExternalImage(void* texture) noexcept final;
private:
PlatformCocoaTouchGLImpl* pImpl = nullptr;
};
using ContextManager = PlatformCocoaTouchGL;
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "PlatformCocoaTouchGL.h"
#include <backend/platforms/PlatformCocoaTouchGL.h>
#define GLES_SILENCE_DEPRECATION
#include <OpenGLES/EAGL.h>
@@ -30,9 +30,6 @@
#include <utils/Panic.h>
#include "../OpenGLDriverFactory.h"
#include "../OpenGLDriver.h"
#include "CocoaTouchExternalImage.h"
namespace filament::backend {
@@ -93,7 +90,7 @@ Driver* PlatformCocoaTouchGL::createDriver(void* const sharedGLContext, const Pl
pImpl->mExternalImageSharedGl = new CocoaTouchExternalImage::SharedGl();
return OpenGLDriverFactory::create(this, sharedGLContext, driverConfig);
return OpenGLPlatform::createDefaultDriver(this, sharedGLContext, driverConfig);
}
void PlatformCocoaTouchGL::terminate() noexcept {
@@ -102,13 +99,11 @@ void PlatformCocoaTouchGL::terminate() noexcept {
delete pImpl->mExternalImageSharedGl;
}
Platform::SwapChain* PlatformCocoaTouchGL::createSwapChain(void* nativewindow, uint64_t& flags) noexcept {
// Transparent swap chain is not supported
flags &= ~SWAP_CHAIN_CONFIG_TRANSPARENT;
Platform::SwapChain* PlatformCocoaTouchGL::createSwapChain(void* nativewindow, uint64_t flags) noexcept {
return (SwapChain*) nativewindow;
}
Platform::SwapChain* PlatformCocoaTouchGL::createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept {
Platform::SwapChain* PlatformCocoaTouchGL::createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept {
CAEAGLLayer* glLayer = [CAEAGLLayer layer];
glLayer.frame = CGRectMake(0, 0, width, height);
@@ -133,11 +128,8 @@ void PlatformCocoaTouchGL::destroySwapChain(Platform::SwapChain* swapChain) noex
}
}
void PlatformCocoaTouchGL::createDefaultRenderTarget(uint32_t& framebuffer, uint32_t& colorbuffer,
uint32_t& depthbuffer) noexcept {
framebuffer = pImpl->mDefaultFramebuffer;
colorbuffer = pImpl->mDefaultColorbuffer;
depthbuffer = pImpl->mDefaultDepthbuffer;
uint32_t PlatformCocoaTouchGL::createDefaultRenderTarget() noexcept {
return pImpl->mDefaultFramebuffer;
}
void PlatformCocoaTouchGL::makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept {
@@ -180,23 +172,18 @@ void PlatformCocoaTouchGL::commit(Platform::SwapChain* swapChain) noexcept {
CVOpenGLESTextureCacheFlush(pImpl->mTextureCache, 0);
}
bool PlatformCocoaTouchGL::setExternalImage(void* externalImage, void* texture) noexcept {
CVPixelBufferRef cvPixelBuffer = (CVPixelBufferRef) externalImage;
auto* driverTexture = (OpenGLDriver::GLTexture*) texture;
OpenGLPlatform::ExternalTexture* PlatformCocoaTouchGL::createExternalImageTexture() noexcept {
ExternalTexture* outTexture = new CocoaTouchExternalImage(pImpl->mTextureCache,
*pImpl->mExternalImageSharedGl);
// the actual id/target will be set in setExternalImage*(
outTexture->id = 0;
outTexture->target = GL_TEXTURE_2D;
return outTexture;
}
CocoaTouchExternalImage* cocoaExternalImage = (CocoaTouchExternalImage*) driverTexture->platformPImpl;
if (!cocoaExternalImage->set(cvPixelBuffer)) {
return false;
}
driverTexture->gl.id = cocoaExternalImage->getGlTexture();
driverTexture->gl.internalFormat = cocoaExternalImage->getInternalFormat();
driverTexture->gl.target = cocoaExternalImage->getTarget();
driverTexture->gl.baseLevel = 0;
driverTexture->gl.maxLevel = 0;
return true;
void PlatformCocoaTouchGL::destroyExternalImage(ExternalTexture* texture) noexcept {
auto* p = static_cast<CocoaTouchExternalImage*>(texture);
delete p;
}
void PlatformCocoaTouchGL::retainExternalImage(void* externalImage) noexcept {
@@ -206,22 +193,17 @@ void PlatformCocoaTouchGL::retainExternalImage(void* externalImage) noexcept {
CVPixelBufferRetain(pixelBuffer);
}
void PlatformCocoaTouchGL::releaseExternalImage(void* externalImage) noexcept {
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef) externalImage;
CVPixelBufferRelease(pixelBuffer);
}
void PlatformCocoaTouchGL::createExternalImageTexture(void* texture) noexcept {
auto* driverTexture = (OpenGLDriver::GLTexture*) texture;
driverTexture->platformPImpl = new CocoaTouchExternalImage(pImpl->mTextureCache,
*pImpl->mExternalImageSharedGl);
}
void PlatformCocoaTouchGL::destroyExternalImage(void* texture) noexcept {
auto* driverTexture = (OpenGLDriver::GLTexture*) texture;
auto* p = (CocoaTouchExternalImage*) driverTexture->platformPImpl;
delete p;
bool PlatformCocoaTouchGL::setExternalImage(void* externalImage, ExternalTexture* texture) noexcept {
CVPixelBufferRef cvPixelBuffer = (CVPixelBufferRef) externalImage;
CocoaTouchExternalImage* cocoaExternalImage = static_cast<CocoaTouchExternalImage*>(texture);
if (!cocoaExternalImage->set(cvPixelBuffer)) {
return false;
}
texture->target = cocoaExternalImage->getTarget();
texture->id = cocoaExternalImage->getGlTexture();
// we used to set the internalFormat, but it's not used anywhere on the gl backend side
// cocoaExternalImage->getInternalFormat();
return true;
}
} // namespace filament::backend

View File

@@ -14,11 +14,9 @@
* limitations under the License.
*/
#include "PlatformEGL.h"
#include <backend/platforms/PlatformEGL.h>
#include "opengl/OpenGLDriver.h"
#include "opengl/OpenGLContext.h"
#include "opengl/OpenGLDriverFactory.h"
#include "opengl/GLUtils.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -31,7 +29,7 @@ using namespace utils;
namespace filament::backend {
using namespace backend;
// The Android NDK doesn't exposes extensions, fake it with eglGetProcAddress
// The Android NDK doesn't expose extensions, fake it with eglGetProcAddress
namespace glext {
UTILS_PRIVATE PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR = {};
UTILS_PRIVATE PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR = {};
@@ -70,7 +68,7 @@ void PlatformEGL::logEglError(const char* name) noexcept {
void PlatformEGL::clearGlError() noexcept {
// clear GL error that may have been set by previous calls
GLenum error = glGetError();
GLenum const error = glGetError();
if (error != GL_NO_ERROR) {
slog.w << "Ignoring pending GL error " << io::hex << error << io::endl;
}
@@ -80,12 +78,17 @@ void PlatformEGL::clearGlError() noexcept {
PlatformEGL::PlatformEGL() noexcept = default;
int PlatformEGL::getOSVersion() const noexcept {
return 0;
}
Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert_invariant(mEGLDisplay != EGL_NO_DISPLAY);
EGLint major, minor;
EGLBoolean initialized = eglInitialize(mEGLDisplay, &major, &minor);
EGLBoolean const initialized = eglInitialize(mEGLDisplay, &major, &minor);
if (UTILS_UNLIKELY(!initialized)) {
slog.e << "eglInitialize failed" << io::endl;
return nullptr;
@@ -99,6 +102,9 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon
auto extensions = GLUtils::split(eglQueryString(mEGLDisplay, EGL_EXTENSIONS));
ext.egl.KHR_no_config_context = extensions.has("EGL_KHR_no_config_context");
ext.egl.KHR_gl_colorspace = extensions.has("EGL_KHR_gl_colorspace");
eglCreateSyncKHR = (PFNEGLCREATESYNCKHRPROC) eglGetProcAddress("eglCreateSyncKHR");
eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC) eglGetProcAddress("eglDestroySyncKHR");
eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC) eglGetProcAddress("eglClientWaitSyncKHR");
@@ -112,7 +118,7 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon
EGL_RED_SIZE, 8, // 2
EGL_GREEN_SIZE, 8, // 4
EGL_BLUE_SIZE, 8, // 6
EGL_ALPHA_SIZE, 0, // 8 : reserved to set ALPHA_SIZE below
EGL_ALPHA_SIZE, 8, // 8
EGL_DEPTH_SIZE, 24, // 10
EGL_RECORDABLE_ANDROID, 1, // 12
EGL_NONE // 14
@@ -131,7 +137,7 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon
};
#ifdef NDEBUG
// When we don't have a shared context and we're in release mode, we always activate the
// When we don't have a shared context, and we're in release mode, we always activate the
// EGL_KHR_create_context_no_error extension.
if (!sharedContext && extensions.has("EGL_KHR_create_context_no_error")) {
contextAttribs[2] = EGL_CONTEXT_OPENGL_NO_ERROR_KHR;
@@ -139,66 +145,46 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon
}
#endif
EGLConfig eglConfig = nullptr;
// config use for creating the context
EGLConfig eglConfig = EGL_NO_CONFIG_KHR;
// find an opaque config
// find a config we can use if we don't have "EGL_KHR_no_config_context" and that we can use
// for the dummy pbuffer surface.
if (!eglChooseConfig(mEGLDisplay, configAttribs, &mEGLConfig, 1, &configsCount)) {
logEglError("eglChooseConfig");
goto error;
}
if (configsCount == 0) {
// warn and retry without EGL_RECORDABLE_ANDROID
logEglError("eglChooseConfig(..., EGL_RECORDABLE_ANDROID) failed. Continuing without it.");
configAttribs[12] = EGL_RECORDABLE_ANDROID;
configAttribs[13] = EGL_DONT_CARE;
if (!eglChooseConfig(mEGLDisplay, configAttribs, &mEGLConfig, 1, &configsCount) ||
configsCount == 0) {
logEglError("eglChooseConfig");
goto error;
}
}
// find a transparent config
configAttribs[8] = EGL_ALPHA_SIZE;
configAttribs[9] = 8;
if (!eglChooseConfig(mEGLDisplay, configAttribs, &mEGLTransparentConfig, 1, &configsCount) ||
(configAttribs[13] == EGL_DONT_CARE && configsCount == 0)) {
logEglError("eglChooseConfig");
goto error;
}
if (configsCount == 0) {
// warn and retry without EGL_RECORDABLE_ANDROID
// warn and retry without EGL_RECORDABLE_ANDROID
logEglError("eglChooseConfig(..., EGL_RECORDABLE_ANDROID) failed. Continuing without it.");
// this is not fatal
configAttribs[12] = EGL_RECORDABLE_ANDROID;
configAttribs[13] = EGL_DONT_CARE;
if (!eglChooseConfig(mEGLDisplay, configAttribs, &mEGLTransparentConfig, 1, &configsCount) ||
configsCount == 0) {
logEglError("eglChooseConfig");
goto error;
}
// this is not fatal
configAttribs[12] = EGL_RECORDABLE_ANDROID;
configAttribs[13] = EGL_DONT_CARE;
if (!eglChooseConfig(mEGLDisplay, configAttribs, &mEGLConfig, 1, &configsCount) ||
configsCount == 0) {
logEglError("eglChooseConfig");
goto error;
}
}
if (!extensions.has("EGL_KHR_no_config_context")) {
// if we have the EGL_KHR_no_config_context, we don't need to worry about the config
// when creating the context, otherwise, we must always pick a transparent config.
eglConfig = mEGLConfig = mEGLTransparentConfig;
if (UTILS_UNLIKELY(!ext.egl.KHR_no_config_context)) {
// if we don't have the EGL_KHR_no_config_context the context must be created with
// the same config as the swapchain, so we have no choice but to create a
// transparent config.
eglConfig = mEGLConfig;
}
// the pbuffer dummy surface is always created with a transparent surface because
// either we have EGL_KHR_no_config_context and it doesn't matter, or we don't and
// we must use a transparent surface
mEGLDummySurface = eglCreatePbufferSurface(mEGLDisplay, mEGLTransparentConfig, pbufferAttribs);
if (mEGLDummySurface == EGL_NO_SURFACE) {
// create the dummy surface, just for being able to make the context current.
mEGLDummySurface = eglCreatePbufferSurface(mEGLDisplay, mEGLConfig, pbufferAttribs);
if (UTILS_UNLIKELY(mEGLDummySurface == EGL_NO_SURFACE)) {
logEglError("eglCreatePbufferSurface");
goto error;
}
mEGLContext = eglCreateContext(mEGLDisplay, eglConfig, (EGLContext)sharedContext, contextAttribs);
if (mEGLContext == EGL_NO_CONTEXT && sharedContext &&
extensions.has("EGL_KHR_create_context_no_error")) {
if (UTILS_UNLIKELY(mEGLContext == EGL_NO_CONTEXT && sharedContext &&
extensions.has("EGL_KHR_create_context_no_error"))) {
// context creation could fail because of EGL_CONTEXT_OPENGL_NO_ERROR_KHR
// not matching the sharedContext. Try with it.
contextAttribs[2] = EGL_CONTEXT_OPENGL_NO_ERROR_KHR;
@@ -211,7 +197,7 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon
goto error;
}
if (!makeCurrent(mEGLDummySurface, mEGLDummySurface)) {
if (UTILS_UNLIKELY(!makeCurrent(mEGLDummySurface, mEGLDummySurface))) {
// eglMakeCurrent failed
logEglError("eglMakeCurrent");
goto error;
@@ -223,7 +209,7 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon
clearGlError();
// success!!
return OpenGLDriverFactory::create(this, sharedContext, driverConfig);
return OpenGLPlatform::createDefaultDriver(this, sharedContext, driverConfig);
error:
// if we're here, we've failed
@@ -260,36 +246,115 @@ void PlatformEGL::terminate() noexcept {
eglReleaseThread();
}
EGLConfig PlatformEGL::findSwapChainConfig(uint64_t flags) const {
EGLConfig config = EGL_NO_CONFIG_KHR;
EGLint configsCount;
EGLint configAttribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, (flags & SWAP_CHAIN_CONFIG_TRANSPARENT) ? 8 : 0,
EGL_DEPTH_SIZE, 24,
EGL_RECORDABLE_ANDROID, 1,
EGL_NONE
};
if (UTILS_UNLIKELY(
!eglChooseConfig(mEGLDisplay, configAttribs, &config, 1, &configsCount))) {
logEglError("eglChooseConfig");
return EGL_NO_CONFIG_KHR;
}
if (UTILS_UNLIKELY(configsCount == 0)) {
// warn and retry without EGL_RECORDABLE_ANDROID
logEglError(
"eglChooseConfig(..., EGL_RECORDABLE_ANDROID) failed. Continuing without it.");
configAttribs[12] = EGL_RECORDABLE_ANDROID;
configAttribs[13] = EGL_DONT_CARE;
if (UTILS_UNLIKELY(
!eglChooseConfig(mEGLDisplay, configAttribs, &config, 1, &configsCount) ||
configsCount == 0)) {
logEglError("eglChooseConfig");
return EGL_NO_CONFIG_KHR;
}
}
return config;
}
bool PlatformEGL::isSRGBSwapChainSupported() const noexcept {
return ext.egl.KHR_gl_colorspace;
}
Platform::SwapChain* PlatformEGL::createSwapChain(
void* nativeWindow, uint64_t& flags) noexcept {
EGLSurface sur = eglCreateWindowSurface(mEGLDisplay,
(flags & SWAP_CHAIN_CONFIG_TRANSPARENT) ?
mEGLTransparentConfig : mEGLConfig,
(EGLNativeWindowType)nativeWindow, nullptr);
void* nativeWindow, uint64_t flags) noexcept {
EGLConfig config = EGL_NO_CONFIG_KHR;
if (UTILS_LIKELY(ext.egl.KHR_no_config_context)) {
config = findSwapChainConfig(flags);
} else {
config = mEGLConfig;
}
if (UTILS_UNLIKELY(config == EGL_NO_CONFIG_KHR)) {
return nullptr;
}
EGLint attribs[] = {
EGL_NONE, EGL_NONE,
EGL_NONE
};
if (ext.egl.KHR_gl_colorspace) {
if (flags & SWAP_CHAIN_CONFIG_SRGB_COLORSPACE) {
attribs[0] = EGL_GL_COLORSPACE_KHR;
attribs[1] = EGL_GL_COLORSPACE_SRGB_KHR;
}
}
EGLSurface sur = eglCreateWindowSurface(mEGLDisplay, config,
(EGLNativeWindowType)nativeWindow, attribs);
if (UTILS_UNLIKELY(sur == EGL_NO_SURFACE)) {
logEglError("eglCreateWindowSurface");
return nullptr;
}
if (!eglSurfaceAttrib(mEGLDisplay, sur, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED)) {
logEglError("eglSurfaceAttrib(..., EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED)");
// this is not fatal
}
// this is not fatal
eglSurfaceAttrib(mEGLDisplay, sur, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
return (SwapChain*)sur;
}
Platform::SwapChain* PlatformEGL::createSwapChain(
uint32_t width, uint32_t height, uint64_t& flags) noexcept {
uint32_t width, uint32_t height, uint64_t flags) noexcept {
EGLConfig config = EGL_NO_CONFIG_KHR;
if (UTILS_LIKELY(ext.egl.KHR_no_config_context)) {
config = findSwapChainConfig(flags);
} else {
config = mEGLConfig;
}
if (UTILS_UNLIKELY(config == EGL_NO_CONFIG_KHR)) {
return nullptr;
}
EGLint attribs[] = {
EGL_WIDTH, EGLint(width),
EGL_HEIGHT, EGLint(height),
EGL_NONE, EGL_NONE,
EGL_NONE
};
EGLSurface sur = eglCreatePbufferSurface(mEGLDisplay,
(flags & SWAP_CHAIN_CONFIG_TRANSPARENT) ?
mEGLTransparentConfig : mEGLConfig, attribs);
if (ext.egl.KHR_gl_colorspace) {
if (flags & SWAP_CHAIN_CONFIG_SRGB_COLORSPACE) {
attribs[4] = EGL_GL_COLORSPACE_KHR;
attribs[5] = EGL_GL_COLORSPACE_SRGB_KHR;
}
}
EGLSurface sur = eglCreatePbufferSurface(mEGLDisplay, config, attribs);
if (UTILS_UNLIKELY(sur == EGL_NO_SURFACE)) {
logEglError("eglCreatePbufferSurface");
@@ -322,6 +387,10 @@ void PlatformEGL::commit(Platform::SwapChain* swapChain) noexcept {
}
}
bool PlatformEGL::canCreateFence() noexcept {
return true;
}
Platform::Fence* PlatformEGL::createFence() noexcept {
Fence* f = nullptr;
#ifdef EGL_KHR_reusable_sync
@@ -356,24 +425,34 @@ FenceStatus PlatformEGL::waitFence(
return FenceStatus::ERROR;
}
void PlatformEGL::createExternalImageTexture(void* texture) noexcept {
auto* t = (OpenGLDriver::GLTexture*) texture;
glGenTextures(1, &t->gl.id);
if (UTILS_LIKELY(ext.OES_EGL_image_external_essl3)) {
t->gl.target = GL_TEXTURE_EXTERNAL_OES;
t->gl.targetIndex = (uint8_t)
OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_EXTERNAL_OES);
OpenGLPlatform::ExternalTexture* PlatformEGL::createExternalImageTexture() noexcept {
ExternalTexture* outTexture = new ExternalTexture{};
glGenTextures(1, &outTexture->id);
if (UTILS_LIKELY(ext.gl.OES_EGL_image_external_essl3)) {
outTexture->target = GL_TEXTURE_EXTERNAL_OES;
} else {
// if texture external is not supported, revert to texture 2d
t->gl.target = GL_TEXTURE_2D;
t->gl.targetIndex = (uint8_t)
OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_2D);
outTexture->target = GL_TEXTURE_2D;
}
return outTexture;
}
void PlatformEGL::destroyExternalImage(void* texture) noexcept {
auto* t = (OpenGLDriver::GLTexture*) texture;
glDeleteTextures(1, &t->gl.id);
void PlatformEGL::destroyExternalImage(ExternalTexture* texture) noexcept {
glDeleteTextures(1, &texture->id);
delete texture;
}
bool PlatformEGL::setExternalImage(void* externalImage,
UTILS_UNUSED_IN_RELEASE ExternalTexture* texture) noexcept {
if (UTILS_LIKELY(ext.gl.OES_EGL_image_external_essl3)) {
assert_invariant(texture->target == GL_TEXTURE_EXTERNAL_OES);
// the texture is guaranteed to be bound here.
#ifdef GL_OES_EGL_image
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
static_cast<GLeglImageOES>(externalImage));
#endif
}
return true;
}
void PlatformEGL::initializeGlExtensions() noexcept {
@@ -384,7 +463,7 @@ void PlatformEGL::initializeGlExtensions() noexcept {
const char * const extension = (const char*) glGetStringi(GL_EXTENSIONS, (GLuint)i);
glExtensions.insert(extension);
}
ext.OES_EGL_image_external_essl3 = glExtensions.has("GL_OES_EGL_image_external_essl3");
ext.gl.OES_EGL_image_external_essl3 = glExtensions.has("GL_OES_EGL_image_external_essl3");
}
} // namespace filament::backend

View File

@@ -14,13 +14,10 @@
* limitations under the License.
*/
#include "PlatformEGLAndroid.h"
#include "opengl/OpenGLDriver.h"
#include "opengl/OpenGLContext.h"
#include <backend/platforms/PlatformEGLAndroid.h>
#include "opengl/GLUtils.h"
#include "ExternalStreamManagerAndroid.h"
#include "private/backend/VirtualMachineEnv.h"
#include <android/api-level.h>
@@ -32,10 +29,7 @@
#include <sys/system_properties.h>
#include <jni.h>
// We require filament to be built with a API 19 toolchain, before that, OpenGLES 3.0 didn't exist
// We require filament to be built with an API 19 toolchain, before that, OpenGLES 3.0 didn't exist
// Actually, OpenGL ES 3.0 was added to API 18, but API 19 is the better target and
// the minimum for Jetpack at the time of this comment.
#if __ANDROID_API__ < 19
@@ -47,7 +41,7 @@ using namespace utils;
namespace filament::backend {
using namespace backend;
// The Android NDK doesn't exposes extensions, fake it with eglGetProcAddress
// The Android NDK doesn't expose extensions, fake it with eglGetProcAddress
namespace glext {
extern PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR;
@@ -76,7 +70,7 @@ PlatformEGLAndroid::PlatformEGLAndroid() noexcept
char scratch[PROP_VALUE_MAX + 1];
int length = __system_property_get("ro.build.version.release", scratch);
int androidVersion = length >= 0 ? atoi(scratch) : 1;
int const androidVersion = length >= 0 ? atoi(scratch) : 1;
if (!androidVersion) {
mOSVersion = 1000; // if androidVersion is 0, it means "future"
} else {
@@ -105,7 +99,8 @@ void PlatformEGLAndroid::terminate() noexcept {
PlatformEGL::terminate();
}
Driver* PlatformEGLAndroid::createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
Driver* PlatformEGLAndroid::createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept {
Driver* driver = PlatformEGL::createDriver(sharedContext, driverConfig);
auto extensions = GLUtils::split(eglQueryString(mEGLDisplay, EGL_EXTENSIONS));

View File

@@ -1,55 +0,0 @@
/*
* Copyright (C) 2017 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_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#include "PlatformEGL.h"
namespace filament::backend {
class ExternalStreamManagerAndroid;
class PlatformEGLAndroid final : public PlatformEGL {
public:
PlatformEGLAndroid() noexcept;
~PlatformEGLAndroid() noexcept override;
void terminate() noexcept override;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept final;
int getOSVersion() const noexcept final;
void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept final;
Stream* createStream(void* nativeStream) noexcept final;
void destroyStream(Stream* stream) noexcept final;
void attach(Stream* stream, intptr_t tname) noexcept final;
void detach(Stream* stream) noexcept final;
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept final;
AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept final;
private:
int mOSVersion;
ExternalStreamManagerAndroid& mExternalStreamManager;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H

View File

@@ -14,11 +14,9 @@
* limitations under the License.
*/
#include "PlatformEGLHeadless.h"
#include <backend/platforms/PlatformEGLHeadless.h>
#include "opengl/OpenGLDriver.h"
#include "opengl/OpenGLContext.h"
#include "opengl/OpenGLDriverFactory.h"
#include "opengl/GLUtils.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -47,7 +45,8 @@ PlatformEGLHeadless::PlatformEGLHeadless() noexcept
: PlatformEGL() {
}
backend::Driver* PlatformEGLHeadless::createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
backend::Driver* PlatformEGLHeadless::createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept {
EGLBoolean bindAPI = eglBindAPI(EGL_OPENGL_API);
if (UTILS_UNLIKELY(!bindAPI)) {
slog.e << "eglBindAPI EGL_OPENGL_API failed" << io::endl;
@@ -199,7 +198,7 @@ backend::Driver* PlatformEGLHeadless::createDriver(void* sharedContext, const Pl
clearGlError();
// success!!
return OpenGLDriverFactory::create(this, sharedContext, driverConfig);
return OpenGLPlatform::createDefaultDriver(this, sharedContext, driverConfig);
error:
// if we're here, we've failed

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "PlatformGLX.h"
#include <backend/platforms/PlatformGLX.h>
#include <utils/Log.h>
#include <utils/Panic.h>
@@ -23,8 +23,6 @@
#include <GL/glx.h>
#include <GL/glxext.h>
#include "../OpenGLDriverFactory.h"
#include <dlfcn.h>
#define LIBRARY_GLX "libGL.so.1"
@@ -130,7 +128,8 @@ namespace filament::backend {
using namespace backend;
Driver* PlatformGLX::createDriver(void* const sharedGLContext, const DriverConfig& driverConfig) noexcept {
Driver* PlatformGLX::createDriver(void* const sharedGLContext,
const DriverConfig& driverConfig) noexcept {
loadLibraries();
// Get the display device
mGLXDisplay = g_x11.openDisplay(NULL);
@@ -229,7 +228,7 @@ Driver* PlatformGLX::createDriver(void* const sharedGLContext, const DriverConfi
int result = bluegl::bind();
ASSERT_POSTCONDITION(!result, "Unable to load OpenGL entry points.");
return OpenGLDriverFactory::create(this, sharedGLContext, driverConfig);
return OpenGLPlatform::createDefaultDriver(this, sharedGLContext, driverConfig);
}
void PlatformGLX::terminate() noexcept {
@@ -240,16 +239,12 @@ void PlatformGLX::terminate() noexcept {
bluegl::unbind();
}
Platform::SwapChain* PlatformGLX::createSwapChain(void* nativeWindow, uint64_t& flags) noexcept {
// Transparent swap chain is not supported
flags &= ~SWAP_CHAIN_CONFIG_TRANSPARENT;
Platform::SwapChain* PlatformGLX::createSwapChain(void* nativeWindow, uint64_t flags) noexcept {
return (SwapChain*)nativeWindow;
}
Platform::SwapChain* PlatformGLX::createSwapChain(
uint32_t width, uint32_t height, uint64_t& flags) noexcept {
// Transparent swap chain is not supported
flags &= ~SWAP_CHAIN_CONFIG_TRANSPARENT;
uint32_t width, uint32_t height, uint64_t flags) noexcept {
int pbufferAttribs[] = {
GLX_PBUFFER_WIDTH, int(width),
GLX_PBUFFER_HEIGHT, int(height),
@@ -280,18 +275,4 @@ void PlatformGLX::commit(Platform::SwapChain* swapChain) noexcept {
g_glx.swapBuffers(mGLXDisplay, (GLXDrawable)swapChain);
}
// TODO Implement GLX fences
Platform::Fence* PlatformGLX::createFence() noexcept {
Fence* f = new Fence();
return f;
}
void PlatformGLX::destroyFence(Fence* fence) noexcept {
delete fence;
}
FenceStatus PlatformGLX::waitFence(Fence* fence, uint64_t timeout) noexcept {
return FenceStatus::CONDITION_SATISFIED;
}
} // namespace filament::backend

View File

@@ -14,12 +14,10 @@
* limitations under the License.
*/
#include "PlatformWGL.h"
#include <backend/platforms/PlatformWGL.h>
#include <Wingdi.h>
#include "../OpenGLDriverFactory.h"
#ifdef _MSC_VER
// this variable is checked in BlueGL.h (included from "gl_headers.h" right after this),
// and prevents duplicate definition of OpenGL apis when building this file.
@@ -76,7 +74,8 @@ struct WGLSwapChain {
bool isHeadless = false;
};
Driver* PlatformWGL::createDriver(void* const sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept {
Driver* PlatformWGL::createDriver(void* const sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept {
int result = 0;
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = nullptr;
int pixelFormat = 0;
@@ -146,7 +145,8 @@ Driver* PlatformWGL::createDriver(void* const sharedGLContext, const Platform::D
result = bluegl::bind();
ASSERT_POSTCONDITION(!result, "Unable to load OpenGL entry points.");
return OpenGLDriverFactory::create(this, sharedGLContext, driverConfig);
return OpenGLPlatform::createDefaultDriver(this, sharedGLContext, driverConfig);
error:
if (tempContext) {
@@ -175,7 +175,7 @@ void PlatformWGL::terminate() noexcept {
bluegl::unbind();
}
Platform::SwapChain* PlatformWGL::createSwapChain(void* nativeWindow, uint64_t& flags) noexcept {
Platform::SwapChain* PlatformWGL::createSwapChain(void* nativeWindow, uint64_t flags) noexcept {
auto* swapChain = new WGLSwapChain();
swapChain->isHeadless = false;
@@ -194,7 +194,7 @@ Platform::SwapChain* PlatformWGL::createSwapChain(void* nativeWindow, uint64_t&
return (Platform::SwapChain*) swapChain;
}
Platform::SwapChain* PlatformWGL::createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept {
Platform::SwapChain* PlatformWGL::createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept {
auto* swapChain = new WGLSwapChain();
swapChain->isHeadless = true;
@@ -256,16 +256,4 @@ void PlatformWGL::commit(Platform::SwapChain* swapChain) noexcept {
}
}
//TODO Implement WGL fences
Platform::Fence* PlatformWGL::createFence() noexcept {
return nullptr;
}
void PlatformWGL::destroyFence(Fence* fence) noexcept {
}
FenceStatus PlatformWGL::waitFence(Fence* fence, uint64_t timeout) noexcept {
return FenceStatus::ERROR;
}
} // namespace filament::backend

View File

@@ -14,27 +14,31 @@
* limitations under the License.
*/
#include "PlatformWebGL.h"
#include "../OpenGLDriverFactory.h"
#include <backend/platforms/PlatformWebGL.h>
namespace filament::backend {
using namespace backend;
Driver* PlatformWebGL::createDriver(void* const sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept {
return OpenGLDriverFactory::create(this, sharedGLContext, driverConfig);
Driver* PlatformWebGL::createDriver(void* const sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept {
return OpenGLPlatform::createDefaultDriver(this, sharedGLContext, driverConfig);
}
int PlatformWebGL::getOSVersion() const noexcept {
return 0;
}
void PlatformWebGL::terminate() noexcept {
}
Platform::SwapChain* PlatformWebGL::createSwapChain(
void* nativeWindow, uint64_t& flags) noexcept {
void* nativeWindow, uint64_t flags) noexcept {
return (SwapChain*)nativeWindow;
}
Platform::SwapChain* PlatformWebGL::createSwapChain(
uint32_t width, uint32_t height, uint64_t& flags) noexcept {
uint32_t width, uint32_t height, uint64_t flags) noexcept {
// TODO: implement headless SwapChain
return nullptr;
}
@@ -49,17 +53,4 @@ void PlatformWebGL::makeCurrent(Platform::SwapChain* drawSwapChain,
void PlatformWebGL::commit(Platform::SwapChain* swapChain) noexcept {
}
Platform::Fence* PlatformWebGL::createFence() noexcept {
Fence* f = new Fence();
return f;
}
void PlatformWebGL::destroyFence(Fence* fence) noexcept {
delete fence;
}
FenceStatus PlatformWebGL::waitFence(Fence* fence, uint64_t timeout) noexcept {
return FenceStatus::CONDITION_SATISFIED;
}
} // namespace filament::backend

View File

@@ -1,60 +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_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
#include <stdint.h>
#include <backend/DriverEnums.h>
#include "private/backend/OpenGLPlatform.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
namespace filament::backend {
class PlatformWebGL final : public OpenGLPlatform {
public:
Driver* createDriver(void* const sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept override;
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept final override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept final override;
void destroySwapChain(SwapChain* swapChain) noexcept final override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept final override;
void commit(SwapChain* swapChain) noexcept final override;
Fence* createFence() noexcept final override;
void destroyFence(Fence* fence) noexcept final override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept final override;
void setPresentationTime(int64_t time) noexcept final override {}
Stream* createStream(void* nativeStream) noexcept final override { return nullptr; }
void destroyStream(Stream* stream) noexcept final override {}
void attach(Stream* stream, intptr_t tname) noexcept final override {}
void detach(Stream* stream) noexcept final override {}
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept final override {}
int getOSVersion() const noexcept final override { return 0; }
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H

View File

@@ -29,23 +29,32 @@ using namespace bluevk;
namespace filament::backend {
Driver* PlatformVkAndroid::createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
Driver* PlatformVkAndroid::createDriver(void* const sharedContext,
const Platform::DriverConfig& driverConfig) noexcept {
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
static const char* requiredInstanceExtensions[] = { "VK_KHR_android_surface" };
return VulkanDriverFactory::create(this, requiredInstanceExtensions, 1, driverConfig);
}
void* PlatformVkAndroid::createVkSurfaceKHR(void* nativeWindow, void* vkinstance, uint64_t flags) noexcept {
SurfaceBundle PlatformVkAndroid::createVkSurfaceKHR(void* nativeWindow, void* vkinstance,
uint64_t flags) noexcept {
const VkInstance instance = (VkInstance) vkinstance;
ANativeWindow* aNativeWindow = (ANativeWindow*) nativeWindow;
VkAndroidSurfaceCreateInfoKHR createInfo {
.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
.window = aNativeWindow
};
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkResult result = vkCreateAndroidSurfaceKHR(instance, &createInfo, VKALLOC, &surface);
SurfaceBundle bundle {
.surface = VK_NULL_HANDLE,
.width = 0,
.height = 0
};
VkResult result = vkCreateAndroidSurfaceKHR(instance, &createInfo, VKALLOC,
(VkSurfaceKHR*) &bundle.surface);
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateAndroidSurfaceKHR error.");
return (void*) surface;
return bundle;
}
} // namespace filament::backend

View File

@@ -20,7 +20,7 @@
#include <stdint.h>
#include <backend/DriverEnums.h>
#include "VulkanPlatform.h"
#include <backend/platforms/VulkanPlatform.h>
namespace filament::backend {
@@ -29,7 +29,8 @@ public:
Driver* createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept override;
int getOSVersion() const noexcept override { return 0; }
};

View File

@@ -20,14 +20,15 @@
#include <stdint.h>
#include <backend/DriverEnums.h>
#include "VulkanPlatform.h"
#include <backend/platforms/VulkanPlatform.h>
namespace filament::backend {
class PlatformVkCocoa final : public VulkanPlatform {
public:
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept override;
int getOSVersion() const noexcept override { return 0; }
};

View File

@@ -34,6 +34,8 @@ using namespace bluevk;
namespace filament::backend {
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
Driver* PlatformVkCocoa::createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
static const char* requiredInstanceExtensions[] = {
@@ -42,21 +44,28 @@ Driver* PlatformVkCocoa::createDriver(void* sharedContext, const Platform::Drive
return VulkanDriverFactory::create(this, requiredInstanceExtensions, 1, driverConfig);
}
void* PlatformVkCocoa::createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept {
SurfaceBundle PlatformVkCocoa::createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept {
// Obtain the CAMetalLayer-backed view.
NSView* nsview = (__bridge NSView*) nativeWindow;
ASSERT_POSTCONDITION(nsview, "Unable to obtain Metal-backed NSView.");
// Create the VkSurface.
ASSERT_POSTCONDITION(vkCreateMacOSSurfaceMVK, "Unable to load vkCreateMacOSSurfaceMVK.");
VkSurfaceKHR surface = nullptr;
VkMacOSSurfaceCreateInfoMVK createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
createInfo.pView = (__bridge void*) nsview;
VkResult result = vkCreateMacOSSurfaceMVK((VkInstance) instance, &createInfo, VKALLOC, &surface);
SurfaceBundle bundle {
.surface = nullptr,
.width = 0,
.height = 0
};
VkResult result = vkCreateMacOSSurfaceMVK((VkInstance) instance, &createInfo, VKALLOC,
(VkSurfaceKHR*) &bundle.surface);
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateMacOSSurfaceMVK error.");
return surface;
return bundle;
}
} // namespace filament::backend

View File

@@ -20,14 +20,15 @@
#include <stdint.h>
#include <backend/DriverEnums.h>
#include "VulkanPlatform.h"
#include <backend/platforms/VulkanPlatform.h>
namespace filament::backend {
class PlatformVkCocoaTouch final : public VulkanPlatform {
public:
Driver* createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept override;
int getOSVersion() const noexcept override { return 0; }
};

View File

@@ -39,31 +39,37 @@ using namespace bluevk;
namespace filament::backend {
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
Driver* PlatformVkCocoaTouch::createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
static const char* requestedExtensions[] = {"VK_MVK_ios_surface"};
return VulkanDriverFactory::create(this, requestedExtensions, 1, driverConfig);
}
void* PlatformVkCocoaTouch::createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept {
SurfaceBundle PlatformVkCocoaTouch::createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept {
SurfaceBundle bundle {
.surface = nullptr,
.width = 0,
.height = 0
};
#if METAL_AVAILABLE
CAMetalLayer* metalLayer = (CAMetalLayer*) nativeWindow;
// Create the VkSurface.
ASSERT_POSTCONDITION(vkCreateIOSSurfaceMVK, "Unable to load vkCreateIOSSurfaceMVK function.");
VkSurfaceKHR surface = nullptr;
VkIOSSurfaceCreateInfoMVK createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.pView = metalLayer;
VkResult result = vkCreateIOSSurfaceMVK((VkInstance) instance, &createInfo, VKALLOC, &surface);
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateIOSSurfaceMVK error.");
return surface;
#else
return nullptr;
VkResult result = vkCreateIOSSurfaceMVK((VkInstance) instance, &createInfo, VKALLOC,
(VkSurfaceKHR*) &bundle.surface);
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateIOSSurfaceMVK error.");
#endif
return bundle;
}
} // namespace filament::backend

View File

@@ -28,6 +28,8 @@ using namespace bluevk;
namespace filament::backend {
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
Driver* PlatformVkLinuxGGP::createDriver(
void* const sharedContext,
const Platform::DriverConfig& driverConfig) noexcept {
@@ -46,8 +48,13 @@ Driver* PlatformVkLinuxGGP::createDriver(
#endif
}
void* PlatformVkLinuxGGP::createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept {
SurfaceBundle PlatformVkLinuxGGP::createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept {
SurfaceBundle bundle {
.surface = nullptr,
.width = 0,
.height = 0
};
#if defined(FILAMENT_SUPPORTS_GGP)
VkStreamDescriptorSurfaceCreateInfoGGP surface_create_info = {
VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP};
@@ -59,16 +66,14 @@ void* PlatformVkLinuxGGP::createVkSurfaceKHR(void* nativeWindow, void* instance,
ASSERT_PRECONDITION(fpCreateStreamDescriptorSurfaceGGP != nullptr,
"Error getting VkInstance "
"function vkCreateStreamDescriptorSurfaceGGP");
VkSurfaceKHR surface = nullptr;
VkResult res = fpCreateStreamDescriptorSurfaceGGP(
static_cast<VkInstance>(instance), &surface_create_info, nullptr,
&surface);
(VkSurfaceKHR*) &bundle.surface);
ASSERT_PRECONDITION(res == VK_SUCCESS, "Error in vulkan: %d", res);
return surface;
#else
PANIC_PRECONDITION("Filament does not support GGP.");
return nullptr;
#endif
return bundle;
}
} // namespace filament::backend

View File

@@ -20,7 +20,7 @@
#include <backend/DriverEnums.h>
#include <stdint.h>
#include "VulkanPlatform.h"
#include <backend/platforms/VulkanPlatform.h>
namespace filament::backend {
@@ -30,8 +30,8 @@ class PlatformVkLinuxGGP final : public VulkanPlatform {
void* const sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
void* createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept override;
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept override;
int getOSVersion() const noexcept override { return 0; }
};

View File

@@ -27,8 +27,19 @@
using namespace bluevk;
namespace {
typedef struct _wl {
struct wl_display *display;
struct wl_surface *surface;
uint32_t width;
uint32_t height;
} wl;
} // anonymous namespace
namespace filament::backend {
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
Driver* PlatformVkLinuxWayland::createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
const char* requiredInstanceExtensions[] = {
@@ -38,15 +49,8 @@ Driver* PlatformVkLinuxWayland::createDriver(void* const sharedContext, const Pl
sizeof(requiredInstanceExtensions) / sizeof(requiredInstanceExtensions[0]), driverConfig);
}
void* PlatformVkLinuxWayland::createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept {
typedef struct _wl {
struct wl_display *display;
struct wl_surface *surface;
} wl;
VkSurfaceKHR surface = nullptr;
SurfaceBundle PlatformVkLinuxWayland::createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept {
wl* ptrval = reinterpret_cast<wl*>(nativeWindow);
VkWaylandSurfaceCreateInfoKHR createInfo = {
@@ -56,11 +60,15 @@ void* PlatformVkLinuxWayland::createVkSurfaceKHR(void* nativeWindow, void* insta
.display = ptrval->display,
.surface = ptrval->surface
};
VkResult result = vkCreateWaylandSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC, &surface);
SurfaceBundle bundle {
.surface = VK_NULL_HANDLE,
.width = ptrval->width,
.height = ptrval->height
};
VkResult result = vkCreateWaylandSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC,
(VkSurfaceKHR*) &bundle.surface);
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateWaylandSurfaceKHR error.");
return surface;
return bundle;
}
} // namespace filament::backend

View File

@@ -21,7 +21,7 @@
#include <wayland-client-core.h>
#include <backend/DriverEnums.h>
#include "VulkanPlatform.h"
#include <backend/platforms/VulkanPlatform.h>
namespace filament::backend {
@@ -30,7 +30,8 @@ public:
Driver* createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept override;
int getOSVersion() const noexcept override { return 0; }
};

View File

@@ -29,6 +29,8 @@ using namespace bluevk;
namespace filament::backend {
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
static constexpr const char* LIBRARY_X11 = "libX11.so.6";
#ifdef FILAMENT_SUPPORTS_XCB
@@ -50,7 +52,8 @@ struct X11Functions {
void* library = nullptr;
} g_x11;
Driver* PlatformVkLinuxX11::createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
Driver* PlatformVkLinuxX11::createDriver(void* const sharedContext,
const Platform::DriverConfig& driverConfig) noexcept {
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
const char* requiredInstanceExtensions[] = {
#ifdef FILAMENT_SUPPORTS_XCB
@@ -64,7 +67,8 @@ Driver* PlatformVkLinuxX11::createDriver(void* const sharedContext, const Platfo
sizeof(requiredInstanceExtensions) / sizeof(requiredInstanceExtensions[0]), driverConfig);
}
void* PlatformVkLinuxX11::createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept {
SurfaceBundle PlatformVkLinuxX11::createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept {
if (g_x11.library == nullptr) {
g_x11.library = dlopen(LIBRARY_X11, RTLD_LOCAL | RTLD_NOW);
ASSERT_PRECONDITION(g_x11.library, "Unable to open X11 library.");
@@ -85,7 +89,11 @@ void* PlatformVkLinuxX11::createVkSurfaceKHR(void* nativeWindow, void* instance,
}
VkSurfaceKHR surface = nullptr;
SurfaceBundle bundle {
.surface = nullptr,
.width = 0,
.height = 0
};
#ifdef FILAMENT_SUPPORTS_XCB
#ifdef FILAMENT_SUPPORTS_XLIB
@@ -101,8 +109,9 @@ const bool windowIsXCB = true;
.connection = mConnection,
.window = (xcb_window_t) ptrval,
};
vkCreateXcbSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC, &surface);
return surface;
vkCreateXcbSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC,
(VkSurfaceKHR*) &bundle.surface);
return bundle;
}
#endif
@@ -112,10 +121,11 @@ const bool windowIsXCB = true;
.dpy = mDisplay,
.window = (Window) nativeWindow,
};
vkCreateXlibSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC, &surface);
vkCreateXlibSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC,
(VkSurfaceKHR*) &bundle.surface);
#endif
return surface;
return bundle;
}
} // namespace filament::backend

View File

@@ -20,7 +20,7 @@
#include <stdint.h>
#include <backend/DriverEnums.h>
#include "VulkanPlatform.h"
#include <backend/platforms/VulkanPlatform.h>
#ifdef FILAMENT_SUPPORTS_XCB
#include <xcb/xcb.h>
@@ -37,7 +37,8 @@ public:
Driver* createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept override;
int getOSVersion() const noexcept override { return 0; }

View File

@@ -27,15 +27,22 @@ using namespace bluevk;
namespace filament::backend {
Driver* PlatformVkWindows::createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
Driver* PlatformVkWindows::createDriver(void* const sharedContext,
const Platform::DriverConfig& driverConfig) noexcept {
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
const char* requiredInstanceExtensions[] = { "VK_KHR_win32_surface" };
return VulkanDriverFactory::create(this, requiredInstanceExtensions, 1, driverConfig);
}
void* PlatformVkWindows::createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept {
VkSurfaceKHR surface = nullptr;
SurfaceBundle PlatformVkWindows::createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept {
SurfaceBundle bundle {
.surface = nullptr,
.width = 0,
.height = 0
};
HWND window = (HWND) nativeWindow;
VkWin32SurfaceCreateInfoKHR createInfo = {};
@@ -43,10 +50,11 @@ void* PlatformVkWindows::createVkSurfaceKHR(void* nativeWindow, void* instance,
createInfo.hwnd = window;
createInfo.hinstance = GetModuleHandle(nullptr);
VkResult result = vkCreateWin32SurfaceKHR((VkInstance) instance, &createInfo, nullptr, &surface);
VkResult result = vkCreateWin32SurfaceKHR((VkInstance) instance, &createInfo, nullptr,
(VkSurfaceKHR*) &bundle.surface);
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateWin32SurfaceKHR error.");
return surface;
return bundle;
}
} // namespace filament::backend

View File

@@ -20,7 +20,7 @@
#include <stdint.h>
#include <backend/DriverEnums.h>
#include "VulkanPlatform.h"
#include <backend/platforms/VulkanPlatform.h>
namespace filament::backend {
@@ -29,7 +29,8 @@ public:
Driver* createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept override;
int getOSVersion() const noexcept override { return 0; }

View File

@@ -57,7 +57,7 @@
constexpr struct VkAllocationCallbacks* VKALLOC = nullptr;
constexpr static const int VK_REQUIRED_VERSION_MAJOR = 1;
constexpr static const int VK_REQUIRED_VERSION_MINOR = 0;
constexpr static const int VK_REQUIRED_VERSION_MINOR = 1;
// Maximum number of VkCommandBuffer handles managed simultaneously by VulkanCommands.
//

View File

@@ -65,7 +65,38 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debugUtilsCallback(VkDebugUtilsMessageSeverityFla
utils::slog.e << utils::io::endl;
return VK_FALSE;
}
// These strings need to be allocated outside a function stack
const std::string_view DESIRED_LAYERS[] = {
"VK_LAYER_KHRONOS_validation",
#if FILAMENT_VULKAN_DUMP_API
"VK_LAYER_LUNARG_api_dump",
#endif
#if defined(ENABLE_RENDERDOC)
"VK_LAYER_RENDERDOC_Capture",
#endif
};
FixedCapacityVector<const char*> getEnabledLayers() {
constexpr size_t kMaxEnabledLayersCount = sizeof(DESIRED_LAYERS) / sizeof(DESIRED_LAYERS[0]);
const FixedCapacityVector<VkLayerProperties> availableLayers = filament::backend::enumerate(
vkEnumerateInstanceLayerProperties);
auto enabledLayers = FixedCapacityVector<const char*>::with_capacity(kMaxEnabledLayersCount);
for (const auto& desired : DESIRED_LAYERS) {
for (const VkLayerProperties& layer : availableLayers) {
const std::string_view availableLayer(layer.layerName);
if (availableLayer == desired) {
enabledLayers.push_back(desired.data());
break;
}
}
}
return enabledLayers;
}
#endif // VK_ENABLE_VALIDATION
void printDeviceInfo(VkInstance instance, VkPhysicalDevice device) {
// Print some driver or MoltenVK information if it is available.
@@ -144,49 +175,6 @@ void printDepthFormats(VkPhysicalDevice device) {
}
}
bool enableLayers(VkInstanceCreateInfo* instanceCreateInfo) {
const std::string_view DESIRED_LAYERS[] = {
"VK_LAYER_KHRONOS_validation",
#if FILAMENT_VULKAN_DUMP_API
"VK_LAYER_LUNARG_api_dump",
#endif
#if defined(ENABLE_RENDERDOC)
"VK_LAYER_RENDERDOC_Capture",
#endif
};
constexpr size_t kMaxEnabledLayersCount = sizeof(DESIRED_LAYERS) / sizeof(DESIRED_LAYERS[0]);
const FixedCapacityVector<VkLayerProperties> availableLayers = filament::backend::enumerate(
vkEnumerateInstanceLayerProperties);
auto enabledLayers = FixedCapacityVector<const char*>::with_capacity(kMaxEnabledLayersCount);
for (const auto& desired : DESIRED_LAYERS) {
for (const VkLayerProperties& layer : availableLayers) {
const std::string_view availableLayer(layer.layerName);
if (availableLayer == desired) {
enabledLayers.push_back(desired.data());
break;
}
}
}
if (!enabledLayers.empty()) {
instanceCreateInfo->enabledLayerCount = (uint32_t) enabledLayers.size();
instanceCreateInfo->ppEnabledLayerNames = enabledLayers.data();
return true;
}
#if defined(__ANDROID__)
utils::slog.d << "Validation layers are not available; did you set jniLibs in your "
<< "gradle file?" << utils::io::endl;
#else
utils::slog.d << "Validation layer not available; did you install the Vulkan SDK?\n"
<< "Please ensure that VK_LAYER_PATH is set correctly." << utils::io::endl;
#endif
return false;
}
struct InstanceExtensions {
bool debugUtilsSupported = false;
bool portabilityEnumerationSupported = false;
@@ -244,16 +232,28 @@ VkInstance createInstance(const char* const* ppRequiredExtensions, uint32_t requ
bool validationFeaturesSupported = false;
#if VK_ENABLE_VALIDATION
if (enableLayers(&instanceCreateInfo)) {
const auto enabledLayers = getEnabledLayers();
if (!enabledLayers.empty()) {
// If layers are supported, Check if VK_EXT_validation_features is supported.
const FixedCapacityVector<VkExtensionProperties> availableExts = filament::backend::enumerate(
vkEnumerateInstanceExtensionProperties, "VK_LAYER_KHRONOS_validation");
const FixedCapacityVector<VkExtensionProperties> availableExts =
filament::backend::enumerate(vkEnumerateInstanceExtensionProperties,
"VK_LAYER_KHRONOS_validation");
for (const auto& extProps : availableExts) {
if (!strcmp(extProps.extensionName, VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME)) {
validationFeaturesSupported = true;
break;
}
}
instanceCreateInfo.enabledLayerCount = (uint32_t) enabledLayers.size();
instanceCreateInfo.ppEnabledLayerNames = enabledLayers.data();
} else {
#if defined(__ANDROID__)
utils::slog.d << "Validation layers are not available; did you set jniLibs in your "
<< "gradle file?" << utils::io::endl;
#else
utils::slog.d << "Validation layer not available; did you install the Vulkan SDK?\n"
<< "Please ensure that VK_LAYER_PATH is set correctly." << utils::io::endl;
#endif
}
#endif // VK_ENABLE_VALIDATION

View File

@@ -23,7 +23,8 @@
#include "VulkanDriverFactory.h"
#include "VulkanHandles.h"
#include "VulkanMemory.h"
#include "VulkanPlatform.h"
#include <backend/platforms/VulkanPlatform.h>
#include <utils/CString.h>
#include <utils/FixedCapacityVector.h>
@@ -394,9 +395,14 @@ void VulkanDriver::createSyncR(Handle<HwSync> sh, int) {
void VulkanDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow, uint64_t flags) {
const VkInstance instance = mContext.instance;
auto vksurface = (VkSurfaceKHR) mContextManager.createVkSurfaceKHR(nativeWindow, instance,
flags);
construct<VulkanSwapChain>(sch, mContext, mStagePool, vksurface);
auto bundle = mContextManager.createVkSurfaceKHR(nativeWindow, instance, flags);
VkSurfaceKHR surface = (VkSurfaceKHR) bundle.surface;
VkExtent2D fallback{bundle.width, bundle.height};
if (fallback.width > 0 && fallback.height > 0) {
construct<VulkanSwapChain>(sch, mContext, mStagePool, surface, fallback);
} else {
construct<VulkanSwapChain>(sch, mContext, mStagePool, surface);
}
}
void VulkanDriver::createSwapChainHeadlessR(Handle<HwSwapChain> sch,
@@ -634,6 +640,11 @@ bool VulkanDriver::isAutoDepthResolveSupported() {
return false;
}
bool VulkanDriver::isSRGBSwapChainSupported() {
// TODO: implement SWAP_CHAIN_CONFIG_SRGB_COLORSPACE
return false;
}
bool VulkanDriver::isWorkaroundNeeded(Workaround workaround) {
VkPhysicalDeviceProperties const& deviceProperties = mContext.physicalDeviceProperties;
switch (workaround) {
@@ -743,9 +754,6 @@ void VulkanDriver::update3DImage(
void VulkanDriver::setupExternalImage(void* image) {
}
void VulkanDriver::cancelExternalImage(void* image) {
}
bool VulkanDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint64_t* elapsedTime) {
VulkanTimerQuery* vtq = handle_cast<VulkanTimerQuery*>(tqh);
@@ -1455,11 +1463,8 @@ void VulkanDriver::readPixels(Handle<HwRenderTarget> src, uint32_t x, uint32_t y
}
vkUnmapMemory(device, stagingMemory);
mDisposer.createDisposable((void*)stagingImage, [=] () {
vkDestroyImage(device, stagingImage, nullptr);
vkFreeMemory(device, stagingMemory, nullptr);
});
vkDestroyImage(device, stagingImage, nullptr);
vkFreeMemory(device, stagingMemory, nullptr);
scheduleDestroy(std::move(pbd));
}

View File

@@ -18,7 +18,8 @@
#include "VulkanConstants.h"
#include "VulkanMemory.h"
#include "VulkanPlatform.h"
#include <backend/platforms/VulkanPlatform.h>
#include <utils/Panic.h>

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "VulkanPlatform.h"
#include <backend/platforms/VulkanPlatform.h>
namespace filament::backend {

View File

@@ -23,6 +23,10 @@
using namespace bluevk;
using namespace utils;
namespace {
constexpr uint32_t VULKAN_UNDEFINED_EXTENT = 0xFFFFFFFF;
} // anonymous namespace
namespace filament::backend {
bool VulkanSwapChain::acquire() {
@@ -127,8 +131,12 @@ void VulkanSwapChain::create(VulkanStagePool& stagePool) {
ASSERT_POSTCONDITION(foundSuitablePresentMode, "Desired present mode is not supported by this device.");
// Create the low-level swap chain.
clientSize = caps.currentExtent;
if (caps.currentExtent.width == VULKAN_UNDEFINED_EXTENT ||
caps.currentExtent.height == VULKAN_UNDEFINED_EXTENT) {
clientSize = mFallbackExtent;
} else {
clientSize = caps.currentExtent;
}
const VkCompositeAlphaFlagBitsKHR compositeAlpha = (caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) ?
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR : VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
@@ -251,54 +259,26 @@ static void getPresentationQueue(VulkanContext& mContext, VulkanSwapChain& sc) {
FixedCapacityVector<VkQueueFamilyProperties> queueFamiliesProperties(queueFamiliesCount);
vkGetPhysicalDeviceQueueFamilyProperties(mContext.physicalDevice, &queueFamiliesCount,
queueFamiliesProperties.data());
uint32_t presentQueueFamilyIndex = 0xffff;
// We prefer the graphics and presentation queues to be the same, so first check if that works.
// On most platforms they must be the same anyway, and this avoids issues with MoltenVK.
VkBool32 supported = VK_FALSE;
vkGetPhysicalDeviceSurfaceSupportKHR(mContext.physicalDevice, mContext.graphicsQueueFamilyIndex,
sc.surface, &supported);
if (supported) {
presentQueueFamilyIndex = mContext.graphicsQueueFamilyIndex;
}
// Otherwise fall back to separate graphics and presentation queues.
if (presentQueueFamilyIndex == 0xffff) {
for (uint32_t j = 0; j < queueFamiliesCount; ++j) {
vkGetPhysicalDeviceSurfaceSupportKHR(mContext.physicalDevice, j, sc.surface, &supported);
if (supported) {
presentQueueFamilyIndex = j;
break;
}
}
}
ASSERT_POSTCONDITION(presentQueueFamilyIndex != 0xffff,
"This physical device does not support the presentation queue.");
if (mContext.graphicsQueueFamilyIndex != presentQueueFamilyIndex) {
// We assume that the chosen graphics queues are able to present. See also
// https://github.com/google/filament/issues/1532
ASSERT_POSTCONDITION(supported, "Graphics queues do not support presentation.");
// TODO: Strictly speaking, this code path is incorrect. However it is not triggered on any
// Android devices that we've tested with, nor with MoltenVK.
//
// This is incorrect because we created the logical device early on, before we had a handle
// to the rendering surface. Therefore the device was not created with the presentation
// queue family index included in VkDeviceQueueCreateInfo.
//
// This is non-trivial to fix because the driver API allows clients to do certain things
// (e.g. upload a vertex buffer) before the swap chain is created.
//
// https://github.com/google/filament/issues/1532
vkGetDeviceQueue(mContext.device, presentQueueFamilyIndex, 0, &sc.presentQueue);
} else {
sc.presentQueue = mContext.graphicsQueue;
}
ASSERT_POSTCONDITION(sc.presentQueue, "Unable to obtain presentation queue.");
sc.presentQueue = mContext.graphicsQueue;
sc.headlessQueue = VK_NULL_HANDLE;
}
// Primary SwapChain constructor. (not headless)
VulkanSwapChain::VulkanSwapChain(VulkanContext& context, VulkanStagePool& stagePool, VkSurfaceKHR vksurface) :
mContext(context) {
VulkanSwapChain::VulkanSwapChain(VulkanContext& context, VulkanStagePool& stagePool, VkSurfaceKHR vksurface,
VkExtent2D fallbackExtent) :
mContext(context),
mFallbackExtent(fallbackExtent) {
suboptimal = false;
surface = vksurface;
firstRenderPass = true;
@@ -341,9 +321,15 @@ bool VulkanSwapChain::hasResized() const {
if (surface == VK_NULL_HANDLE) {
return false;
}
VkSurfaceCapabilitiesKHR surfaceCapabilities;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mContext.physicalDevice, surface, &surfaceCapabilities);
return !equivalent(clientSize, surfaceCapabilities.currentExtent);
VkSurfaceCapabilitiesKHR caps;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mContext.physicalDevice, surface, &caps);
VkExtent2D perceivedExtent = caps.currentExtent;
// Create the low-level swap chain.
if (caps.currentExtent.width == VULKAN_UNDEFINED_EXTENT ||
caps.currentExtent.height == VULKAN_UNDEFINED_EXTENT) {
perceivedExtent = mFallbackExtent;
}
return !equivalent(clientSize, perceivedExtent);
}
VulkanTexture& VulkanSwapChain::getColorTexture() {

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