Compare commits
112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
979d6742e0 | ||
|
|
4a7a033d04 | ||
|
|
5c2bbcb4a1 | ||
|
|
dec903a0ee | ||
|
|
e9475b322b | ||
|
|
78785a5bca | ||
|
|
662b4b5ca3 | ||
|
|
bee96d1cf1 | ||
|
|
122ebe1ccb | ||
|
|
e741e165ae | ||
|
|
d38dc24915 | ||
|
|
d12612f091 | ||
|
|
e6d73135c1 | ||
|
|
816612cf0a | ||
|
|
7ca8ba272c | ||
|
|
d337a6d019 | ||
|
|
f79c4c6080 | ||
|
|
2e7fc6229b | ||
|
|
fc724575fa | ||
|
|
84716610b8 | ||
|
|
d9aead8aac | ||
|
|
ce148ebeb1 | ||
|
|
e1315fbaa7 | ||
|
|
1690549392 | ||
|
|
c73710e343 | ||
|
|
29983772ed | ||
|
|
d100e628c2 | ||
|
|
94f121f37d | ||
|
|
d9266ba61c | ||
|
|
8389056d2d | ||
|
|
26b8cb238a | ||
|
|
f8d4690cd8 | ||
|
|
c2e2f80945 | ||
|
|
e9efcdf191 | ||
|
|
8ea159520d | ||
|
|
337e18051a | ||
|
|
3c4e094990 | ||
|
|
71e6f3d037 | ||
|
|
092a0489da | ||
|
|
1c6279366f | ||
|
|
d2690bf75a | ||
|
|
44f002a5a1 | ||
|
|
f8442c9ec0 | ||
|
|
b3513c7d1f | ||
|
|
a82e813333 | ||
|
|
dd246aeee4 | ||
|
|
1653d3615b | ||
|
|
4847b00f9e | ||
|
|
d613145c1a | ||
|
|
a788f66e18 | ||
|
|
9ca3a7456c | ||
|
|
5cec001058 | ||
|
|
2fb42f5144 | ||
|
|
02c22a668c | ||
|
|
a7bf90f5be | ||
|
|
f71e90fae0 | ||
|
|
8afb11128d | ||
|
|
2e0c238cc6 | ||
|
|
2ac85049a9 | ||
|
|
ea428a27d1 | ||
|
|
03b89b4327 | ||
|
|
a878d1f39c | ||
|
|
4a09e13e9d | ||
|
|
0b4d32bf98 | ||
|
|
b940fc9c48 | ||
|
|
2eb0dd7153 | ||
|
|
101c7db9a2 | ||
|
|
032ace2051 | ||
|
|
5754b9907d | ||
|
|
ffb8203ae7 | ||
|
|
906da033dd | ||
|
|
1077405bc1 | ||
|
|
e37df8fc89 | ||
|
|
3799e219fc | ||
|
|
eab14da30e | ||
|
|
84e999fe57 | ||
|
|
f22ff6a340 | ||
|
|
d9d0b93306 | ||
|
|
09248cd451 | ||
|
|
73880428dc | ||
|
|
2a049d1324 | ||
|
|
51cbd74235 | ||
|
|
45246b6109 | ||
|
|
d3956adca8 | ||
|
|
3bef718238 | ||
|
|
e9daaa0503 | ||
|
|
298e54c32a | ||
|
|
4c82f0259d | ||
|
|
d0c043c7ff | ||
|
|
20cbecfd7c | ||
|
|
194defdb1b | ||
|
|
6d3ea21993 | ||
|
|
5017cbe67e | ||
|
|
4c4201cb72 | ||
|
|
3ee635f8e4 | ||
|
|
4c2dabffd6 | ||
|
|
185c83dae2 | ||
|
|
15d124b225 | ||
|
|
9c474c5b08 | ||
|
|
f92f283e00 | ||
|
|
f6b94614e8 | ||
|
|
978517b057 | ||
|
|
d911640809 | ||
|
|
473e610430 | ||
|
|
3b9b725406 | ||
|
|
fa742bc6bf | ||
|
|
6a02dd0993 | ||
|
|
243d10f864 | ||
|
|
bbe46071f3 | ||
|
|
8ded184ea3 | ||
|
|
ce407ba844 | ||
|
|
ddb6a7fa93 |
2
.github/workflows/android-continuous.yml
vendored
2
.github/workflows/android-continuous.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/ios-continuous.yml
vendored
2
.github/workflows/ios-continuous.yml
vendored
@@ -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
|
||||
|
||||
4
.github/workflows/linux-continuous.yml
vendored
4
.github/workflows/linux-continuous.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/mac-continuous.yml
vendored
2
.github/workflows/mac-continuous.yml
vendored
@@ -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
|
||||
|
||||
12
.github/workflows/presubmit.yml
vendored
12
.github/workflows/presubmit.yml
vendored
@@ -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
|
||||
|
||||
12
.github/workflows/release.yml
vendored
12
.github/workflows/release.yml
vendored
@@ -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
|
||||
|
||||
1
.github/workflows/verify-release-notes.yml
vendored
1
.github/workflows/verify-release-notes.yml
vendored
@@ -24,3 +24,4 @@ jobs:
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
pull-request-number: ${{ github.event.pull_request.number }}
|
||||
release-notes-file: 'NEW_RELEASE_NOTES.md'
|
||||
|
||||
2
.github/workflows/web-continuous.yml
vendored
2
.github/workflows/web-continuous.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/windows-continuous.yml
vendored
2
.github/workflows/windows-continuous.yml
vendored
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -31,6 +31,8 @@ option(FILAMENT_SKIP_SDL2 "Skip dependencies of SDL2, and SDL2" OFF)
|
||||
|
||||
option(FILAMENT_LINUX_IS_MOBILE "Treat Linux as Mobile" OFF)
|
||||
|
||||
option(FILAMENT_ENABLE_ASAN_UBSAN "Enable Address and Undefined Behavior Sanitizers" OFF)
|
||||
|
||||
set(FILAMENT_NDK_VERSION "" CACHE STRING
|
||||
"Android NDK version or version prefix to be used when building for Android."
|
||||
)
|
||||
@@ -67,25 +69,30 @@ endif()
|
||||
# ==================================================================================================
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if (CCACHE_PROGRAM)
|
||||
set(C_LAUNCHER "${CCACHE_PROGRAM}")
|
||||
set(CXX_LAUNCHER "${CCACHE_PROGRAM}")
|
||||
|
||||
configure_file(build/launch-c.in launch-c)
|
||||
configure_file(build/launch-cxx.in launch-cxx)
|
||||
|
||||
execute_process(COMMAND chmod a+rx
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/launch-c"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/launch-cxx"
|
||||
)
|
||||
|
||||
if (CMAKE_GENERATOR STREQUAL "Xcode")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
|
||||
if (WIN32)
|
||||
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
|
||||
else()
|
||||
set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
|
||||
set(C_LAUNCHER "${CCACHE_PROGRAM}")
|
||||
set(CXX_LAUNCHER "${CCACHE_PROGRAM}")
|
||||
|
||||
configure_file(build/launch-c.in launch-c)
|
||||
configure_file(build/launch-cxx.in launch-cxx)
|
||||
|
||||
execute_process(COMMAND chmod a+rx
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/launch-c"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/launch-cxx"
|
||||
)
|
||||
|
||||
if (CMAKE_GENERATOR STREQUAL "Xcode")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
|
||||
else()
|
||||
set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -374,10 +381,10 @@ endif()
|
||||
# ==================================================================================================
|
||||
# Debug compiler flags
|
||||
# ==================================================================================================
|
||||
# ASAN is deactivated for now because:
|
||||
# -fsanitize=undefined causes extremely long link times
|
||||
# -fsanitize=address causes a crash with assimp, which we can't explain for now
|
||||
#set(EXTRA_SANITIZE_OPTIONS "-fsanitize=undefined -fsanitize=address")
|
||||
if (FILAMENT_ENABLE_ASAN_UBSAN)
|
||||
set(EXTRA_SANITIZE_OPTIONS "-fsanitize=address -fsanitize=undefined")
|
||||
endif()
|
||||
|
||||
if (NOT MSVC AND NOT WEBGL)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstack-protector")
|
||||
endif()
|
||||
@@ -497,9 +504,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})
|
||||
@@ -675,6 +687,7 @@ add_subdirectory(${EXTERNAL}/robin-map/tnt)
|
||||
add_subdirectory(${EXTERNAL}/smol-v/tnt)
|
||||
add_subdirectory(${EXTERNAL}/benchmark/tnt)
|
||||
add_subdirectory(${EXTERNAL}/meshoptimizer/tnt)
|
||||
add_subdirectory(${EXTERNAL}/mikktspace)
|
||||
add_subdirectory(${EXTERNAL}/cgltf/tnt)
|
||||
add_subdirectory(${EXTERNAL}/draco/tnt)
|
||||
add_subdirectory(${EXTERNAL}/jsmn/tnt)
|
||||
|
||||
10
NEW_RELEASE_NOTES.md
Normal file
10
NEW_RELEASE_NOTES.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Filament Release Notes log
|
||||
|
||||
**If you are merging a PR into main**: please add the release note below, under the *Release notes
|
||||
for next branch cut* header.
|
||||
|
||||
**If you are cherry-picking a commit into an rc/ branch**: add the release note under the
|
||||
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
|
||||
|
||||
## Release notes for next branch cut
|
||||
|
||||
@@ -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.7'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -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.7'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
|
||||
@@ -3,7 +3,33 @@
|
||||
This file contains one line summaries of commits that are worthy of mentioning in release notes.
|
||||
A new header is inserted each time a *tag* is created.
|
||||
|
||||
## main branch
|
||||
**Do not edit this file unless you are performing a release or cherry-picking into an rc/ branch.**
|
||||
Instead, if you are authoring a PR for the main branch, add your release note to
|
||||
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
|
||||
|
||||
## v1.31.7
|
||||
|
||||
## v1.31.6
|
||||
|
||||
- engine: the default render channel is now 2 instead of 0
|
||||
- gltfio: Fix crash when a MIME type has no texture provider
|
||||
|
||||
## 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
|
||||
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -257,23 +257,79 @@ 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.
|
||||
*
|
||||
* <p>All renderables in a given channel are rendered together, regardless of anything else.
|
||||
* They are sorted as usual within a channel.</p>
|
||||
* <p>Channels work similarly to priorities, except that they enforce the strongest
|
||||
* ordering.</p>
|
||||
*
|
||||
* <p>Channels 0 and 1 may not have render primitives using a material with `refractionType`
|
||||
* set to `screenspace`.</p>
|
||||
*
|
||||
* @param channel clamped to the range [0..3], defaults to 2.
|
||||
*
|
||||
* @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 +711,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 +941,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 +964,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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -166,6 +166,8 @@ Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv
|
||||
const jfieldID cameraAperture = env->GetFieldID(klass, "cameraAperture", "F");
|
||||
const jfieldID cameraSpeed = env->GetFieldID(klass, "cameraSpeed", "F");
|
||||
const jfieldID cameraISO = env->GetFieldID(klass, "cameraISO", "F");
|
||||
const jfieldID cameraNear = env->GetFieldID(klass, "cameraNear", "F");
|
||||
const jfieldID cameraFar = env->GetFieldID(klass, "cameraFar", "F");
|
||||
const jfieldID groundShadowStrength = env->GetFieldID(klass, "groundShadowStrength", "F");
|
||||
const jfieldID groundPlaneEnabled = env->GetFieldID(klass, "groundPlaneEnabled", "Z");
|
||||
const jfieldID skyboxEnabled = env->GetFieldID(klass, "skyboxEnabled", "Z");
|
||||
@@ -177,6 +179,8 @@ Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv
|
||||
env->SetFloatField(result, cameraAperture, options.cameraAperture);
|
||||
env->SetFloatField(result, cameraSpeed, options.cameraSpeed);
|
||||
env->SetFloatField(result, cameraISO, options.cameraISO);
|
||||
env->SetFloatField(result, cameraNear, options.cameraNear);
|
||||
env->SetFloatField(result, cameraFar, options.cameraFar);
|
||||
env->SetFloatField(result, groundShadowStrength, options.groundShadowStrength);
|
||||
env->SetBooleanField(result, groundPlaneEnabled, options.groundPlaneEnabled);
|
||||
env->SetBooleanField(result, skyboxEnabled, options.skyboxEnabled);
|
||||
|
||||
@@ -97,6 +97,8 @@ public class AutomationEngine {
|
||||
public float cameraAperture = 16.0f;
|
||||
public float cameraSpeed = 125.0f;
|
||||
public float cameraISO = 100.0f;
|
||||
public float cameraNear = 0.1f;
|
||||
public float cameraFar = 100.0f;
|
||||
public float groundShadowStrength = 0.75f;
|
||||
public boolean groundPlaneEnabled = false;
|
||||
public boolean skyboxEnabled = true;
|
||||
|
||||
@@ -27,8 +27,8 @@ import com.google.android.filament.gltfio.*
|
||||
import kotlinx.coroutines.*
|
||||
import java.nio.Buffer
|
||||
|
||||
private const val kNearPlane = 0.05 // 5 cm
|
||||
private const val kFarPlane = 1000.0 // 1 km
|
||||
private const val kNearPlane = 0.05f // 5 cm
|
||||
private const val kFarPlane = 1000.0f // 1 km
|
||||
private const val kAperture = 16f
|
||||
private const val kShutterSpeed = 1f / 125f
|
||||
private const val kSensitivity = 100f
|
||||
@@ -80,6 +80,18 @@ class ModelViewer(
|
||||
updateCameraProjection()
|
||||
}
|
||||
|
||||
var cameraNear = kNearPlane
|
||||
set(value) {
|
||||
field = value
|
||||
updateCameraProjection()
|
||||
}
|
||||
|
||||
var cameraFar = kFarPlane
|
||||
set(value) {
|
||||
field = value
|
||||
updateCameraProjection()
|
||||
}
|
||||
|
||||
val scene: Scene
|
||||
val view: View
|
||||
val camera: Camera
|
||||
@@ -368,7 +380,8 @@ class ModelViewer(
|
||||
val width = view.viewport.width
|
||||
val height = view.viewport.height
|
||||
val aspect = width.toDouble() / height.toDouble()
|
||||
camera.setLensProjection(cameraFocalLength.toDouble(), aspect, kNearPlane, kFarPlane)
|
||||
camera.setLensProjection(cameraFocalLength.toDouble(), aspect,
|
||||
cameraNear.toDouble(), cameraFar.toDouble())
|
||||
}
|
||||
|
||||
inner class SurfaceCallback : UiHelper.RendererCallback {
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.31.1
|
||||
VERSION_NAME=1.31.7
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -356,6 +356,8 @@ class MainActivity : Activity() {
|
||||
automation.applySettings(modelViewer.engine, json, viewerContent)
|
||||
modelViewer.view.colorGrading = automation.getColorGrading(modelViewer.engine)
|
||||
modelViewer.cameraFocalLength = automation.viewerOptions.cameraFocalLength
|
||||
modelViewer.cameraNear = automation.viewerOptions.cameraNear
|
||||
modelViewer.cameraFar = automation.viewerOptions.cameraFar
|
||||
updateRootTransform()
|
||||
}
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 848 KiB After Width: | Height: | Size: 848 KiB |
29
build.sh
29
build.sh
@@ -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"
|
||||
@@ -56,6 +58,9 @@ function print_help {
|
||||
echo " When building for Android, also build select sample APKs."
|
||||
echo " sampleN is an Android sample, e.g., sample-gltf-viewer."
|
||||
echo " This automatically performs a partial desktop build and install."
|
||||
echo " -b"
|
||||
echo " Enable Address and Undefined Behavior Sanitizers (asan/ubsan) for debugging."
|
||||
echo " This is only for the desktop build."
|
||||
echo ""
|
||||
echo "Build types:"
|
||||
echo " release"
|
||||
@@ -162,6 +167,11 @@ EGL_ON_LINUX_OPTION="-DFILAMENT_SUPPORTS_EGL_ON_LINUX=OFF"
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF"
|
||||
MATDBG_GRADLE_OPTION=""
|
||||
|
||||
MATOPT_OPTION=""
|
||||
MATOPT_GRADLE_OPTION=""
|
||||
|
||||
ASAN_UBSAN_OPTION=""
|
||||
|
||||
IOS_BUILD_SIMULATOR=false
|
||||
BUILD_UNIVERSAL_LIBRARIES=false
|
||||
|
||||
@@ -221,6 +231,8 @@ function build_desktop_target {
|
||||
${SWIFTSHADER_OPTION} \
|
||||
${EGL_ON_LINUX_OPTION} \
|
||||
${MATDBG_OPTION} \
|
||||
${MATOPT_OPTION} \
|
||||
${ASAN_UBSAN_OPTION} \
|
||||
${deployment_target} \
|
||||
${architectures} \
|
||||
../..
|
||||
@@ -347,6 +359,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 +476,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 +524,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 +591,7 @@ function build_ios_target {
|
||||
-DIOS=1 \
|
||||
-DCMAKE_TOOLCHAIN_FILE=../../third_party/clang/iOS.cmake \
|
||||
${MATDBG_OPTION} \
|
||||
${MATOPT_OPTION} \
|
||||
../..
|
||||
fi
|
||||
|
||||
@@ -740,7 +756,7 @@ function run_tests {
|
||||
|
||||
pushd "$(dirname "$0")" > /dev/null
|
||||
|
||||
while getopts ":hacCfijmp:q:uvslwtedk:" opt; do
|
||||
while getopts ":hacCfijmp:q:uvslwtedk:b" opt; do
|
||||
case ${opt} in
|
||||
h)
|
||||
print_help
|
||||
@@ -758,12 +774,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
|
||||
;;
|
||||
@@ -863,6 +883,9 @@ while getopts ":hacCfijmp:q:uvslwtedk:" opt; do
|
||||
BUILD_ANDROID_SAMPLES=true
|
||||
ANDROID_SAMPLES=$(echo "${OPTARG}" | tr ',' '\n')
|
||||
;;
|
||||
b) ASAN_UBSAN_OPTION="-DFILAMENT_ENABLE_ASAN_UBSAN=ON"
|
||||
echo "Enabled ASAN/UBSAN"
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -${OPTARG}" >&2
|
||||
echo ""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
@@ -50,7 +50,6 @@ set(PUBLIC_HDRS
|
||||
|
||||
set(SRCS
|
||||
src/AtlasAllocator.cpp
|
||||
src/Box.cpp
|
||||
src/BufferObject.cpp
|
||||
src/Camera.cpp
|
||||
src/Color.cpp
|
||||
@@ -589,6 +588,7 @@ else()
|
||||
-Wgnu-conditional-omitted-operand
|
||||
-Wweak-vtables -Wnon-virtual-dtor -Wclass-varargs -Wimplicit-fallthrough
|
||||
-Wover-aligned
|
||||
-Werror
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -112,7 +114,7 @@ endif()
|
||||
# ==================================================================================================
|
||||
|
||||
if (FILAMENT_SUPPORTS_METAL)
|
||||
set(METAL_SRCS
|
||||
set(METAL_OBJC_SRCS
|
||||
src/metal/MetalBlitter.mm
|
||||
src/metal/MetalBuffer.mm
|
||||
src/metal/MetalBufferPool.mm
|
||||
@@ -122,18 +124,21 @@ if (FILAMENT_SUPPORTS_METAL)
|
||||
src/metal/MetalExternalImage.mm
|
||||
src/metal/MetalHandles.mm
|
||||
src/metal/MetalPlatform.mm
|
||||
src/metal/MetalResourceTracker.cpp
|
||||
src/metal/MetalState.mm
|
||||
src/metal/MetalTimerQuery.mm
|
||||
src/metal/MetalUtils.mm
|
||||
)
|
||||
|
||||
list(APPEND SRCS ${METAL_SRCS})
|
||||
set(METAL_CPP_SRCS
|
||||
src/metal/MetalResourceTracker.cpp
|
||||
)
|
||||
|
||||
list(APPEND SRCS ${METAL_OBJC_SRCS} ${METAL_CPP_SRCS})
|
||||
|
||||
if (IOS)
|
||||
# Objective-C++ sources need an additional compiler flag on iOS to disable exceptions.
|
||||
set_property(SOURCE
|
||||
${METAL_SRCS}
|
||||
${METAL_OBJC_SRCS}
|
||||
src/opengl/platforms/PlatformCocoaTouchGL.mm
|
||||
src/opengl/platforms/CocoaTouchExternalImage.mm
|
||||
src/opengl/platforms/PlatformCocoaGL.mm
|
||||
@@ -150,6 +155,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 +179,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
|
||||
@@ -348,6 +353,7 @@ else()
|
||||
-Wgnu-conditional-omitted-operand
|
||||
-Wweak-vtables -Wnon-virtual-dtor -Wclass-varargs -Wimplicit-fallthrough
|
||||
-Wover-aligned
|
||||
-Werror
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -279,8 +279,8 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
size_t bpr = bpp * stride;
|
||||
size_t bprAligned = (bpr + (alignment - 1)) & (~alignment + 1);
|
||||
size_t const bpr = bpp * stride;
|
||||
size_t const bprAligned = (bpr + (alignment - 1)) & (~alignment + 1);
|
||||
return bprAligned * height;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
4
filament/backend/include/backend/README.md
Normal file
4
filament/backend/include/backend/README.md
Normal 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.
|
||||
261
filament/backend/include/backend/platforms/OpenGLPlatform.h
Normal file
261
filament/backend/include/backend/platforms/OpenGLPlatform.h
Normal 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
|
||||
67
filament/backend/include/backend/platforms/PlatformCocoaGL.h
Normal file
67
filament/backend/include/backend/platforms/PlatformCocoaGL.h
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
55
filament/backend/include/backend/platforms/PlatformWebGL.h
Normal file
55
filament/backend/include/backend/platforms/PlatformWebGL.h
Normal 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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
59
filament/backend/include/private/backend/PlatformFactory.h
Normal file
59
filament/backend/include/private/backend/PlatformFactory.h
Normal 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
|
||||
3
filament/backend/include/private/backend/README.md
Normal file
3
filament/backend/include/private/backend/README.md
Normal 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.
|
||||
@@ -75,6 +75,7 @@ CommandStream::CommandStream(Driver& driver, CircularBuffer& buffer) noexcept
|
||||
|
||||
void CommandStream::execute(void* buffer) {
|
||||
SYSTRACE_CALL();
|
||||
SYSTRACE_CONTEXT();
|
||||
|
||||
Profiler profiler;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
182
filament/backend/src/PlatformFactory.cpp
Normal file
182
filament/backend/src/PlatformFactory.cpp
Normal 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
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -120,7 +120,12 @@ constexpr inline GLenum getBufferBindingType(BufferObjectBinding bindingType) no
|
||||
case BufferObjectBinding::UNIFORM:
|
||||
return GL_UNIFORM_BUFFER;
|
||||
case BufferObjectBinding::SHADER_STORAGE:
|
||||
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
|
||||
return GL_SHADER_STORAGE_BUFFER;
|
||||
#else
|
||||
utils::panic(__func__, __FILE__, __LINE__, "SHADER_STORAGE not supported");
|
||||
return 0x90D2; // just to return something
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
#include "OpenGLContext.h"
|
||||
|
||||
#include <backend/platforms/OpenGLPlatform.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
// change to true to display all GL extensions in the console on start-up
|
||||
#define DEBUG_PRINT_EXTENSIONS false
|
||||
|
||||
@@ -70,7 +74,9 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
constexpr GLint MAX_FRAGMENT_SAMPLER_COUNT = caps3.MAX_FRAGMENT_SAMPLER_COUNT;
|
||||
|
||||
if constexpr (BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GLES) {
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
initExtensionsGLES();
|
||||
#endif
|
||||
if (state.major == 3) {
|
||||
assert_invariant(gets.max_texture_image_units >= 16);
|
||||
assert_invariant(gets.max_combined_texture_image_units >= 32);
|
||||
@@ -88,8 +94,9 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
}
|
||||
}
|
||||
} else if constexpr (BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GL) {
|
||||
// OpenGL version
|
||||
#if defined(GL_VERSION_4_1)
|
||||
initExtensionsGL();
|
||||
#endif
|
||||
if (state.major == 4) {
|
||||
assert_invariant(state.minor >= 1);
|
||||
mShaderModel = ShaderModel::DESKTOP;
|
||||
@@ -268,7 +275,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 *) {
|
||||
@@ -349,6 +358,8 @@ void OpenGLContext::setDefaultState() noexcept {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
|
||||
void OpenGLContext::initExtensionsGLES() noexcept {
|
||||
const char * const extensions = (const char*)glGetString(GL_EXTENSIONS);
|
||||
GLUtils::unordered_string_set const exts = GLUtils::split(extensions);
|
||||
@@ -393,6 +404,10 @@ void OpenGLContext::initExtensionsGLES() noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(GL_ES_VERSION_2_0)
|
||||
|
||||
#if defined(GL_VERSION_4_1)
|
||||
|
||||
void OpenGLContext::initExtensionsGL() noexcept {
|
||||
GLUtils::unordered_string_set exts;
|
||||
GLint n = 0;
|
||||
@@ -416,21 +431,31 @@ void OpenGLContext::initExtensionsGL() noexcept {
|
||||
ext.EXT_color_buffer_float = true; // Assumes core profile.
|
||||
ext.EXT_color_buffer_half_float = true; // Assumes core profile.
|
||||
ext.EXT_debug_marker = exts.has("GL_EXT_debug_marker"sv);
|
||||
ext.EXT_disjoint_timer_query = true;
|
||||
ext.EXT_multisampled_render_to_texture = false;
|
||||
ext.EXT_multisampled_render_to_texture2 = false;
|
||||
ext.EXT_shader_framebuffer_fetch = exts.has("GL_EXT_shader_framebuffer_fetch"sv);
|
||||
ext.EXT_texture_compression_bptc = exts.has("GL_EXT_texture_compression_bptc"sv);
|
||||
ext.EXT_texture_compression_etc2 = exts.has("GL_ARB_ES3_compatibility"sv);
|
||||
ext.EXT_texture_compression_rgtc = exts.has("GL_EXT_texture_compression_rgtc"sv);
|
||||
ext.EXT_texture_compression_s3tc = exts.has("GL_EXT_texture_compression_s3tc"sv);
|
||||
ext.EXT_texture_compression_s3tc_srgb = exts.has("GL_EXT_texture_compression_s3tc_srgb"sv);
|
||||
ext.EXT_texture_compression_rgtc = exts.has("GL_EXT_texture_compression_rgtc"sv);
|
||||
ext.EXT_texture_compression_bptc = exts.has("GL_EXT_texture_compression_bptc"sv);
|
||||
ext.EXT_texture_cube_map_array = true;
|
||||
ext.EXT_texture_filter_anisotropic = exts.has("GL_EXT_texture_filter_anisotropic"sv);
|
||||
ext.EXT_texture_sRGB = exts.has("GL_EXT_texture_sRGB"sv);
|
||||
ext.GOOGLE_cpp_style_line_directive = exts.has("GL_GOOGLE_cpp_style_line_directive"sv);
|
||||
ext.KHR_debug = major >= 4 && minor >= 3;
|
||||
ext.KHR_texture_compression_astc_hdr = exts.has("GL_KHR_texture_compression_astc_hdr"sv);
|
||||
ext.KHR_texture_compression_astc_ldr = exts.has("GL_KHR_texture_compression_astc_ldr"sv);
|
||||
ext.OES_EGL_image_external_essl3 = exts.has("GL_OES_EGL_image_external_essl3"sv);
|
||||
ext.OES_EGL_image_external_essl3 = false;
|
||||
ext.QCOM_tiled_rendering = false;
|
||||
ext.WEBGL_compressed_texture_etc = false;
|
||||
ext.WEBGL_compressed_texture_s3tc = false;
|
||||
ext.WEBGL_compressed_texture_s3tc_srgb = false;
|
||||
}
|
||||
|
||||
#endif // defined(GL_VERSION_4_1)
|
||||
|
||||
void OpenGLContext::bindBuffer(GLenum target, GLuint buffer) noexcept {
|
||||
if (target == GL_ELEMENT_ARRAY_BUFFER) {
|
||||
constexpr size_t targetIndex = getIndexForBufferTarget(GL_ELEMENT_ARRAY_BUFFER);
|
||||
@@ -463,13 +488,8 @@ void OpenGLContext::pixelStore(GLenum pname, GLint param) noexcept {
|
||||
|
||||
switch (pname) {
|
||||
case GL_PACK_ALIGNMENT: pcur = &state.pack.alignment; break;
|
||||
case GL_PACK_ROW_LENGTH: pcur = &state.pack.row_length; break;
|
||||
case GL_PACK_SKIP_PIXELS: pcur = &state.pack.skip_pixels; break; // convenience
|
||||
case GL_PACK_SKIP_ROWS: pcur = &state.pack.skip_row; break; // convenience
|
||||
case GL_UNPACK_ALIGNMENT: pcur = &state.unpack.alignment; break;
|
||||
case GL_UNPACK_ROW_LENGTH: pcur = &state.unpack.row_length; break;
|
||||
case GL_UNPACK_SKIP_PIXELS: pcur = &state.unpack.skip_pixels; break; // convenience
|
||||
case GL_UNPACK_SKIP_ROWS: pcur = &state.unpack.skip_row; break; // convenience
|
||||
default:
|
||||
goto default_case;
|
||||
}
|
||||
@@ -616,12 +636,10 @@ void OpenGLContext::resetState() noexcept {
|
||||
GLenum const bufferTargets[] = {
|
||||
GL_UNIFORM_BUFFER,
|
||||
GL_TRANSFORM_FEEDBACK_BUFFER,
|
||||
#if !defined(__EMSCRIPTEN__)
|
||||
#if !defined(__EMSCRIPTEN__) && (defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1))
|
||||
GL_SHADER_STORAGE_BUFFER,
|
||||
#endif
|
||||
GL_ARRAY_BUFFER,
|
||||
GL_COPY_READ_BUFFER,
|
||||
GL_COPY_WRITE_BUFFER,
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
GL_PIXEL_PACK_BUFFER,
|
||||
GL_PIXEL_UNPACK_BUFFER,
|
||||
@@ -644,23 +662,30 @@ void OpenGLContext::resetState() noexcept {
|
||||
// Reset state.textures to its default state to avoid the complexity and error-prone
|
||||
// nature of resetting the GL state to its existing state
|
||||
state.textures = {};
|
||||
const GLuint textureTargets[] = {
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE_2D_ARRAY,
|
||||
GL_TEXTURE_CUBE_MAP,
|
||||
GL_TEXTURE_3D,
|
||||
const std::pair<GLuint, bool> textureTargets[] = {
|
||||
{ GL_TEXTURE_2D, true },
|
||||
{ GL_TEXTURE_2D_ARRAY, true },
|
||||
{ GL_TEXTURE_CUBE_MAP, true },
|
||||
{ GL_TEXTURE_3D, true },
|
||||
#if !defined(__EMSCRIPTEN__)
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
GL_TEXTURE_EXTERNAL_OES,
|
||||
GL_TEXTURE_CUBE_MAP_ARRAY,
|
||||
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
|
||||
{ GL_TEXTURE_2D_MULTISAMPLE, true },
|
||||
#endif
|
||||
#if defined(GL_OES_EGL_image_external)
|
||||
{ GL_TEXTURE_EXTERNAL_OES, ext.OES_EGL_image_external_essl3 },
|
||||
#endif
|
||||
#if defined(GL_VERSION_4_1) || defined(GL_EXT_texture_cube_map_array)
|
||||
{ GL_TEXTURE_CUBE_MAP_ARRAY, ext.EXT_texture_cube_map_array },
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
for (GLint unit = 0; unit < gets.max_combined_texture_image_units; ++unit) {
|
||||
glActiveTexture(GL_TEXTURE0 + unit);
|
||||
glBindSampler(unit, 0);
|
||||
|
||||
for (auto const target : textureTargets) {
|
||||
glBindTexture(target, 0);
|
||||
for (auto [target, available] : textureTargets) {
|
||||
if (available) {
|
||||
glBindTexture(target, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0 + state.textures.active);
|
||||
@@ -668,14 +693,10 @@ void OpenGLContext::resetState() noexcept {
|
||||
// state.unpack
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, state.unpack.alignment);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, state.unpack.row_length);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, state.unpack.skip_pixels);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, state.unpack.skip_row);
|
||||
|
||||
// state.pack
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, state.pack.alignment);
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, state.pack.row_length);
|
||||
glPixelStorei(GL_PACK_SKIP_PIXELS, state.pack.skip_pixels);
|
||||
glPixelStorei(GL_PACK_SKIP_ROWS, state.pack.skip_row);
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0); // we rely on GL_PACK_ROW_LENGTH being zero
|
||||
|
||||
// state.window
|
||||
glScissor(
|
||||
@@ -694,4 +715,30 @@ void OpenGLContext::resetState() noexcept {
|
||||
|
||||
}
|
||||
|
||||
OpenGLContext::FenceSync OpenGLContext::createFenceSync(
|
||||
OpenGLPlatform&) noexcept {
|
||||
auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
return { .sync = sync };
|
||||
}
|
||||
|
||||
void OpenGLContext::destroyFenceSync(
|
||||
OpenGLPlatform&, FenceSync sync) noexcept {
|
||||
glDeleteSync(sync.sync);
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
OpenGLContext::FenceSync::Status OpenGLContext::clientWaitSync(
|
||||
OpenGLPlatform&, FenceSync sync) const noexcept {
|
||||
GLenum const status = glClientWaitSync(sync.sync, 0, 0u);
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
using Status = OpenGLContext::FenceSync::Status;
|
||||
switch (status) {
|
||||
case GL_ALREADY_SIGNALED: return Status::ALREADY_SIGNALED;
|
||||
case GL_TIMEOUT_EXPIRED: return Status::TIMEOUT_EXPIRED;
|
||||
case GL_CONDITION_SATISFIED: return Status::CONDITION_SATISFIED;
|
||||
default: return Status::FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
} // namesapce filament
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class OpenGLPlatform;
|
||||
|
||||
class OpenGLContext {
|
||||
public:
|
||||
static constexpr const size_t MAX_TEXTURE_UNIT_COUNT = MAX_SAMPLER_COUNT;
|
||||
@@ -110,9 +112,6 @@ public:
|
||||
GLenum sfailBack, GLenum dpfailBack, GLenum dppassBack) noexcept;
|
||||
inline void stencilMaskSeparate(GLuint maskFront, GLuint maskBack) noexcept;
|
||||
inline void polygonOffset(GLfloat factor, GLfloat units) noexcept;
|
||||
inline void beginQuery(GLenum target, GLuint query) noexcept;
|
||||
inline void endQuery(GLenum target) noexcept;
|
||||
inline GLuint getQuery(GLenum target) const noexcept;
|
||||
|
||||
inline void setScissor(GLint left, GLint bottom, GLsizei width, GLsizei height) noexcept;
|
||||
inline void viewport(GLint left, GLint bottom, GLsizei width, GLsizei height) noexcept;
|
||||
@@ -121,6 +120,26 @@ public:
|
||||
void deleteBuffers(GLsizei n, const GLuint* buffers, GLenum target) noexcept;
|
||||
void deleteVertexArrays(GLsizei n, const GLuint* arrays) noexcept;
|
||||
|
||||
// we abstract GL's sync because it's not available in ES2, but we can use EGL's sync
|
||||
// instead, if available.
|
||||
struct FenceSync {
|
||||
enum class Status {
|
||||
ALREADY_SIGNALED,
|
||||
TIMEOUT_EXPIRED,
|
||||
CONDITION_SATISFIED,
|
||||
FAILURE
|
||||
};
|
||||
union {
|
||||
void* fence;
|
||||
GLsync sync;
|
||||
};
|
||||
};
|
||||
|
||||
FenceSync createFenceSync(OpenGLPlatform& platform) noexcept;
|
||||
void destroyFenceSync(OpenGLPlatform& platform, FenceSync sync) noexcept;
|
||||
FenceSync::Status clientWaitSync(OpenGLPlatform& platform, FenceSync sync) const noexcept;
|
||||
|
||||
|
||||
// glGet*() values
|
||||
struct {
|
||||
GLfloat max_anisotropy;
|
||||
@@ -149,21 +168,21 @@ public:
|
||||
bool EXT_color_buffer_half_float;
|
||||
bool EXT_debug_marker;
|
||||
bool EXT_disjoint_timer_query;
|
||||
bool EXT_multisampled_render_to_texture;
|
||||
bool EXT_multisampled_render_to_texture2;
|
||||
bool EXT_multisampled_render_to_texture;
|
||||
bool EXT_shader_framebuffer_fetch;
|
||||
bool KHR_texture_compression_astc_hdr;
|
||||
bool KHR_texture_compression_astc_ldr;
|
||||
bool EXT_texture_compression_bptc;
|
||||
bool EXT_texture_compression_etc2;
|
||||
bool EXT_texture_compression_rgtc;
|
||||
bool EXT_texture_compression_s3tc;
|
||||
bool EXT_texture_compression_s3tc_srgb;
|
||||
bool EXT_texture_compression_rgtc;
|
||||
bool EXT_texture_compression_bptc;
|
||||
bool EXT_texture_cube_map_array;
|
||||
bool EXT_texture_filter_anisotropic;
|
||||
bool EXT_texture_sRGB;
|
||||
bool GOOGLE_cpp_style_line_directive;
|
||||
bool KHR_debug;
|
||||
bool KHR_texture_compression_astc_hdr;
|
||||
bool KHR_texture_compression_astc_ldr;
|
||||
bool OES_EGL_image_external_essl3;
|
||||
bool QCOM_tiled_rendering;
|
||||
bool WEBGL_compressed_texture_etc;
|
||||
@@ -315,8 +334,8 @@ public:
|
||||
GLintptr offset = 0;
|
||||
GLsizeiptr size = 0;
|
||||
} buffers[MAX_BUFFER_BINDINGS];
|
||||
} targets[2]; // there are only 2 indexed buffer target (uniform and transform feedback)
|
||||
GLuint genericBinding[9] = { 0 };
|
||||
} targets[3]; // there are only 3 indexed buffer targets
|
||||
GLuint genericBinding[7] = {};
|
||||
} buffers;
|
||||
|
||||
struct {
|
||||
@@ -332,15 +351,10 @@ public:
|
||||
struct {
|
||||
GLint row_length = 0;
|
||||
GLint alignment = 4;
|
||||
GLint skip_pixels = 0;
|
||||
GLint skip_row = 0;
|
||||
} unpack;
|
||||
|
||||
struct {
|
||||
GLint row_length = 0;
|
||||
GLint alignment = 4;
|
||||
GLint skip_pixels = 0;
|
||||
GLint skip_row = 0;
|
||||
} pack;
|
||||
|
||||
struct {
|
||||
@@ -348,10 +362,6 @@ public:
|
||||
vec4gli viewport { 0 };
|
||||
vec2glf depthRange { 0.0f, 1.0f };
|
||||
} window;
|
||||
|
||||
struct {
|
||||
GLuint timer = -1u;
|
||||
} queries;
|
||||
} state;
|
||||
|
||||
private:
|
||||
@@ -403,8 +413,12 @@ private:
|
||||
RenderPrimitive mDefaultVAO;
|
||||
|
||||
// this is chosen to minimize code size
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
void initExtensionsGLES() noexcept;
|
||||
#endif
|
||||
#if defined(GL_VERSION_4_1)
|
||||
void initExtensionsGL() noexcept;
|
||||
#endif
|
||||
|
||||
template <typename T, typename F>
|
||||
static inline void update_state(T& state, T const& expected, F functor, bool force = false) noexcept {
|
||||
@@ -429,7 +443,9 @@ constexpr size_t OpenGLContext::getIndexForTextureTarget(GLuint target) noexcept
|
||||
case GL_TEXTURE_2D: return 0;
|
||||
case GL_TEXTURE_2D_ARRAY: return 1;
|
||||
case GL_TEXTURE_CUBE_MAP: return 2;
|
||||
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
|
||||
case GL_TEXTURE_2D_MULTISAMPLE: return 3;
|
||||
#endif
|
||||
case GL_TEXTURE_EXTERNAL_OES: return 4;
|
||||
case GL_TEXTURE_3D: return 5;
|
||||
case GL_TEXTURE_CUBE_MAP_ARRAY: return 6;
|
||||
@@ -450,17 +466,15 @@ constexpr size_t OpenGLContext::getIndexForCap(GLenum cap) noexcept { //NOLINT
|
||||
case GL_SAMPLE_ALPHA_TO_COVERAGE: index = 6; break;
|
||||
case GL_SAMPLE_COVERAGE: index = 7; break;
|
||||
case GL_POLYGON_OFFSET_FILL: index = 8; break;
|
||||
case GL_PRIMITIVE_RESTART_FIXED_INDEX: index = 9; break;
|
||||
case GL_RASTERIZER_DISCARD: index = 10; break;
|
||||
#ifdef GL_ARB_seamless_cube_map
|
||||
case GL_TEXTURE_CUBE_MAP_SEAMLESS: index = 11; break;
|
||||
case GL_TEXTURE_CUBE_MAP_SEAMLESS: index = 9; break;
|
||||
#endif
|
||||
#if BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GL
|
||||
case GL_PROGRAM_POINT_SIZE: index = 12; break;
|
||||
case GL_PROGRAM_POINT_SIZE: index = 10; break;
|
||||
#endif
|
||||
default: index = 13; break; // should never happen
|
||||
default: break;
|
||||
}
|
||||
assert_invariant(index < 13 && index < state.enables.caps.size());
|
||||
assert_invariant(index < state.enables.caps.size());
|
||||
return index;
|
||||
}
|
||||
|
||||
@@ -470,15 +484,14 @@ constexpr size_t OpenGLContext::getIndexForBufferTarget(GLenum target) noexcept
|
||||
// The indexed buffers MUST be first in this list (those usable with bindBufferRange)
|
||||
case GL_UNIFORM_BUFFER: index = 0; break;
|
||||
case GL_TRANSFORM_FEEDBACK_BUFFER: index = 1; break;
|
||||
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
|
||||
case GL_SHADER_STORAGE_BUFFER: index = 2; break;
|
||||
|
||||
#endif
|
||||
case GL_ARRAY_BUFFER: index = 3; break;
|
||||
case GL_COPY_READ_BUFFER: index = 4; break;
|
||||
case GL_COPY_WRITE_BUFFER: index = 5; break;
|
||||
case GL_ELEMENT_ARRAY_BUFFER: index = 6; break;
|
||||
case GL_PIXEL_PACK_BUFFER: index = 7; break;
|
||||
case GL_PIXEL_UNPACK_BUFFER: index = 8; break;
|
||||
default: index = 9; break; // should never happen
|
||||
case GL_ELEMENT_ARRAY_BUFFER: index = 4; break;
|
||||
case GL_PIXEL_PACK_BUFFER: index = 5; break;
|
||||
case GL_PIXEL_UNPACK_BUFFER: index = 6; break;
|
||||
default: break;
|
||||
}
|
||||
assert_invariant(index < sizeof(state.buffers.genericBinding)/sizeof(state.buffers.genericBinding[0])); // NOLINT(misc-redundant-expression)
|
||||
return index;
|
||||
@@ -501,21 +514,21 @@ void OpenGLContext::bindSampler(GLuint unit, GLuint sampler) noexcept {
|
||||
}
|
||||
|
||||
void OpenGLContext::setScissor(GLint left, GLint bottom, GLsizei width, GLsizei height) noexcept {
|
||||
vec4gli scissor(left, bottom, width, height);
|
||||
vec4gli const scissor(left, bottom, width, height);
|
||||
update_state(state.window.scissor, scissor, [&]() {
|
||||
glScissor(left, bottom, width, height);
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLContext::viewport(GLint left, GLint bottom, GLsizei width, GLsizei height) noexcept {
|
||||
vec4gli viewport(left, bottom, width, height);
|
||||
vec4gli const viewport(left, bottom, width, height);
|
||||
update_state(state.window.viewport, viewport, [&]() {
|
||||
glViewport(left, bottom, width, height);
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLContext::depthRange(GLclampf near, GLclampf far) noexcept {
|
||||
vec2glf depthRange(near, far);
|
||||
vec2glf const depthRange(near, far);
|
||||
update_state(state.window.depthRange, depthRange, [&]() {
|
||||
glDepthRangef(near, far);
|
||||
});
|
||||
@@ -526,7 +539,7 @@ void OpenGLContext::bindVertexArray(RenderPrimitive const* p) noexcept {
|
||||
update_state(state.vao.p, vao, [&]() {
|
||||
glBindVertexArray(vao->vao);
|
||||
// update GL_ELEMENT_ARRAY_BUFFER, which is updated by glBindVertexArray
|
||||
size_t targetIndex = getIndexForBufferTarget(GL_ELEMENT_ARRAY_BUFFER);
|
||||
size_t const targetIndex = getIndexForBufferTarget(GL_ELEMENT_ARRAY_BUFFER);
|
||||
state.buffers.genericBinding[targetIndex] = vao->elementArray;
|
||||
if (UTILS_UNLIKELY(bugs.vao_doesnt_store_element_array_buffer_binding)) {
|
||||
// This shouldn't be needed, but it looks like some drivers don't do the implicit
|
||||
@@ -538,8 +551,10 @@ void OpenGLContext::bindVertexArray(RenderPrimitive const* p) noexcept {
|
||||
|
||||
void OpenGLContext::bindBufferRange(GLenum target, GLuint index, GLuint buffer,
|
||||
GLintptr offset, GLsizeiptr size) noexcept {
|
||||
size_t targetIndex = getIndexForBufferTarget(target);
|
||||
assert_invariant(targetIndex <= 2); // validity check
|
||||
size_t const targetIndex = getIndexForBufferTarget(target);
|
||||
|
||||
// validity check
|
||||
assert_invariant(targetIndex < sizeof(state.buffers.targets) / sizeof(*state.buffers.targets));
|
||||
|
||||
// this ALSO sets the generic binding
|
||||
if ( state.buffers.targets[targetIndex].buffers[index].name != buffer
|
||||
@@ -616,7 +631,7 @@ void OpenGLContext::disableVertexAttribArray(GLuint index) noexcept {
|
||||
}
|
||||
|
||||
void OpenGLContext::enable(GLenum cap) noexcept {
|
||||
size_t index = getIndexForCap(cap);
|
||||
size_t const index = getIndexForCap(cap);
|
||||
if (UTILS_UNLIKELY(!state.enables.caps[index])) {
|
||||
state.enables.caps.set(index);
|
||||
glEnable(cap);
|
||||
@@ -624,7 +639,7 @@ void OpenGLContext::enable(GLenum cap) noexcept {
|
||||
}
|
||||
|
||||
void OpenGLContext::disable(GLenum cap) noexcept {
|
||||
size_t index = getIndexForCap(cap);
|
||||
size_t const index = getIndexForCap(cap);
|
||||
if (UTILS_UNLIKELY(state.enables.caps[index])) {
|
||||
state.enables.caps.unset(index);
|
||||
glDisable(cap);
|
||||
@@ -723,41 +738,6 @@ void OpenGLContext::polygonOffset(GLfloat factor, GLfloat units) noexcept {
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLContext::beginQuery(GLenum target, GLuint query) noexcept {
|
||||
switch (target) {
|
||||
case GL_TIME_ELAPSED:
|
||||
if (state.queries.timer != -1u) {
|
||||
// this is an error
|
||||
break;
|
||||
}
|
||||
state.queries.timer = query;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
glBeginQuery(target, query);
|
||||
}
|
||||
|
||||
void OpenGLContext::endQuery(GLenum target) noexcept {
|
||||
switch (target) {
|
||||
case GL_TIME_ELAPSED:
|
||||
state.queries.timer = -1u;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
glEndQuery(target);
|
||||
}
|
||||
|
||||
GLuint OpenGLContext::getQuery(GLenum target) const noexcept {
|
||||
switch (target) {
|
||||
case GL_TIME_ELAPSED:
|
||||
return state.queries.timer;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif //TNT_FILAMENT_BACKEND_OPENGLCONTEXT_H
|
||||
|
||||
@@ -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>
|
||||
@@ -69,7 +69,9 @@ using namespace utils;
|
||||
namespace filament::backend {
|
||||
|
||||
Driver* OpenGLDriverFactory::create(
|
||||
OpenGLPlatform* const platform, void* const sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
OpenGLPlatform* const platform,
|
||||
void* const sharedGLContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept {
|
||||
return OpenGLDriver::create(platform, sharedGLContext, driverConfig);
|
||||
}
|
||||
|
||||
@@ -171,12 +173,16 @@ 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;
|
||||
#endif
|
||||
|
||||
// Timer queries are core in GL 3.3, otherwise we need EXT_disjoint_timer_query
|
||||
// iOS headers don't define GL_EXT_disjoint_timer_query, so make absolutely sure
|
||||
// we won't use it.
|
||||
#if defined(GL_VERSION_3_3) || defined(GL_EXT_disjoint_timer_query)
|
||||
if (mContext.ext.EXT_disjoint_timer_query ||
|
||||
BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GL) {
|
||||
// timer queries are available
|
||||
@@ -187,7 +193,9 @@ OpenGLDriver::OpenGLDriver(OpenGLPlatform* platform, const Platform::DriverConfi
|
||||
mTimerQueryImpl = new TimerQueryNative(mContext);
|
||||
}
|
||||
mFrameTimeSupported = true;
|
||||
} else if (mPlatform.canCreateFence()) {
|
||||
} else
|
||||
#endif
|
||||
if (mPlatform.canCreateFence()) {
|
||||
// no timer queries, but we can use fences
|
||||
mTimerQueryImpl = new OpenGLTimerQueryFence(mPlatform);
|
||||
mFrameTimeSupported = true;
|
||||
@@ -537,6 +545,7 @@ void OpenGLDriver::textureStorage(OpenGLDriver::GLTexture* t,
|
||||
GLsizei(width), GLsizei(height), GLsizei(depth) * 6);
|
||||
break;
|
||||
}
|
||||
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
|
||||
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||
if constexpr (TEXTURE_2D_MULTISAMPLE_SUPPORTED) {
|
||||
// NOTE: if there is a mix of texture and renderbuffers, "fixed_sample_locations" must be true
|
||||
@@ -554,6 +563,7 @@ void OpenGLDriver::textureStorage(OpenGLDriver::GLTexture* t,
|
||||
PANIC_LOG("GL_TEXTURE_2D_MULTISAMPLE is not supported");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default: // cannot happen
|
||||
break;
|
||||
}
|
||||
@@ -574,7 +584,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);
|
||||
|
||||
@@ -611,6 +631,7 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
|
||||
if (t->samples > 1) {
|
||||
// Note: we can't be here in practice because filament's user API doesn't
|
||||
// allow the creation of multi-sampled textures.
|
||||
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
|
||||
if (gl.features.multisample_texture) {
|
||||
// multi-sample texture on GL 3.2 / GLES 3.1 and above
|
||||
t->gl.target = GL_TEXTURE_2D_MULTISAMPLE;
|
||||
@@ -619,6 +640,7 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
|
||||
} else {
|
||||
// Turn off multi-sampling for that texture. It's just not supported.
|
||||
}
|
||||
#endif
|
||||
}
|
||||
textureStorage(t, w, h, depth);
|
||||
}
|
||||
@@ -711,6 +733,7 @@ void OpenGLDriver::importTextureR(Handle<HwTexture> th, intptr_t id,
|
||||
if (t->samples > 1) {
|
||||
// Note: we can't be here in practice because filament's user API doesn't
|
||||
// allow the creation of multi-sampled textures.
|
||||
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
|
||||
if (gl.features.multisample_texture) {
|
||||
// multi-sample texture on GL 3.2 / GLES 3.1 and above
|
||||
t->gl.target = GL_TEXTURE_2D_MULTISAMPLE;
|
||||
@@ -718,6 +741,7 @@ void OpenGLDriver::importTextureR(Handle<HwTexture> th, intptr_t id,
|
||||
} else {
|
||||
// Turn off multi-sampling for that texture. It's just not supported.
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
@@ -790,6 +814,7 @@ void OpenGLDriver::framebufferTexture(TargetBufferInfo const& binfo,
|
||||
|
||||
GLTexture* t = handle_cast<GLTexture*>(binfo.handle);
|
||||
|
||||
assert_invariant(t);
|
||||
assert_invariant(t->target != SamplerType::SAMPLER_EXTERNAL);
|
||||
assert_invariant(rt->width <= valueForLevel(binfo.level, t->width) &&
|
||||
rt->height <= valueForLevel(binfo.level, t->height));
|
||||
@@ -897,7 +922,9 @@ void OpenGLDriver::framebufferTexture(TargetBufferInfo const& binfo,
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
case GL_TEXTURE_2D:
|
||||
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
|
||||
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||
#endif
|
||||
if (any(t->usage & TextureUsage::SAMPLEABLE)) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment,
|
||||
target, t->gl.id, binfo.level);
|
||||
@@ -1063,10 +1090,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;
|
||||
@@ -1128,21 +1152,26 @@ void OpenGLDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
|
||||
rt->gl.samples = samples;
|
||||
rt->targets = targets;
|
||||
|
||||
UTILS_UNUSED_IN_RELEASE math::vec2<uint32_t> tmin = {std::numeric_limits<uint32_t>::max()};
|
||||
UTILS_UNUSED_IN_RELEASE math::vec2<uint32_t> tmax = {0};
|
||||
UTILS_UNUSED_IN_RELEASE math::vec2<uint32_t> tmin = { std::numeric_limits<uint32_t>::max() };
|
||||
UTILS_UNUSED_IN_RELEASE math::vec2<uint32_t> tmax = { 0 };
|
||||
auto checkDimensions = [&tmin, &tmax](GLTexture* t, uint8_t level) {
|
||||
const auto twidth = std::max(1u, t->width >> level);
|
||||
const auto theight = std::max(1u, t->height >> level);
|
||||
tmin = { std::min(tmin.x, twidth), std::min(tmin.y, theight) };
|
||||
tmax = { std::max(tmax.x, twidth), std::max(tmax.y, theight) };
|
||||
};
|
||||
|
||||
|
||||
if (any(targets & TargetBufferFlags::COLOR_ALL)) {
|
||||
GLenum bufs[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT] = { GL_NONE };
|
||||
const size_t maxDrawBuffers = getMaxDrawBuffers();
|
||||
for (size_t i = 0; i < maxDrawBuffers; i++) {
|
||||
if (any(targets & getTargetBufferFlagsAt(i))) {
|
||||
auto t = rt->gl.color[i] = handle_cast<GLTexture*>(color[i].handle);
|
||||
const auto twidth = std::max(1u, t->width >> color[i].level);
|
||||
const auto theight = std::max(1u, t->height >> color[i].level);
|
||||
tmin = { std::min(tmin.x, twidth), std::min(tmin.y, theight) };
|
||||
tmax = { std::max(tmax.x, twidth), std::max(tmax.y, theight) };
|
||||
assert_invariant(color[i].handle);
|
||||
rt->gl.color[i] = handle_cast<GLTexture*>(color[i].handle);
|
||||
framebufferTexture(color[i], rt, GL_COLOR_ATTACHMENT0 + i);
|
||||
bufs[i] = GL_COLOR_ATTACHMENT0 + i;
|
||||
checkDimensions(rt->gl.color[i], color[i].level);
|
||||
}
|
||||
}
|
||||
glDrawBuffers((GLsizei)maxDrawBuffers, bufs);
|
||||
@@ -1152,37 +1181,28 @@ void OpenGLDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
|
||||
// handle special cases first (where depth/stencil are packed)
|
||||
bool specialCased = false;
|
||||
if ((targets & TargetBufferFlags::DEPTH_AND_STENCIL) == TargetBufferFlags::DEPTH_AND_STENCIL) {
|
||||
assert_invariant(!stencil.handle || stencil.handle == depth.handle);
|
||||
auto t = rt->gl.depth = handle_cast<GLTexture*>(depth.handle);
|
||||
const auto twidth = std::max(1u, t->width >> depth.level);
|
||||
const auto theight = std::max(1u, t->height >> depth.level);
|
||||
tmin = { std::min(tmin.x, twidth), std::min(tmin.y, theight) };
|
||||
tmax = { std::max(tmax.x, twidth), std::max(tmax.y, theight) };
|
||||
if (any(rt->gl.depth->usage & TextureUsage::SAMPLEABLE) ||
|
||||
(!depth.handle && !stencil.handle)) {
|
||||
// special case: depth & stencil requested, and both provided as the same texture
|
||||
// special case: depth & stencil requested, but both not provided
|
||||
specialCased = true;
|
||||
assert_invariant(depth.handle);
|
||||
// either we supplied only the depth handle or both depth/stencil are identical and not null
|
||||
if (depth.handle && (stencil.handle == depth.handle || !stencil.handle)) {
|
||||
rt->gl.depth = handle_cast<GLTexture*>(depth.handle);
|
||||
framebufferTexture(depth, rt, GL_DEPTH_STENCIL_ATTACHMENT);
|
||||
specialCased = true;
|
||||
checkDimensions(rt->gl.depth, depth.level);
|
||||
}
|
||||
}
|
||||
|
||||
if (!specialCased) {
|
||||
if (any(targets & TargetBufferFlags::DEPTH)) {
|
||||
auto t = rt->gl.depth = handle_cast<GLTexture*>(depth.handle);
|
||||
const auto twidth = std::max(1u, t->width >> depth.level);
|
||||
const auto theight = std::max(1u, t->height >> depth.level);
|
||||
tmin = { std::min(tmin.x, twidth), std::min(tmin.y, theight) };
|
||||
tmax = { std::max(tmax.x, twidth), std::max(tmax.y, theight) };
|
||||
assert_invariant(depth.handle);
|
||||
rt->gl.depth = handle_cast<GLTexture*>(depth.handle);
|
||||
framebufferTexture(depth, rt, GL_DEPTH_ATTACHMENT);
|
||||
checkDimensions(rt->gl.depth, depth.level);
|
||||
}
|
||||
if (any(targets & TargetBufferFlags::STENCIL)) {
|
||||
auto t = rt->gl.stencil = handle_cast<GLTexture*>(stencil.handle);
|
||||
const auto twidth = std::max(1u, t->width >> stencil.level);
|
||||
const auto theight = std::max(1u, t->height >> stencil.level);
|
||||
tmin = { std::min(tmin.x, twidth), std::min(tmin.y, theight) };
|
||||
tmax = { std::max(tmax.x, twidth), std::max(tmax.y, theight) };
|
||||
assert_invariant(stencil.handle);
|
||||
rt->gl.stencil = handle_cast<GLTexture*>(stencil.handle);
|
||||
framebufferTexture(stencil, rt, GL_STENCIL_ATTACHMENT);
|
||||
checkDimensions(rt->gl.stencil, stencil.level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1204,19 +1224,19 @@ void OpenGLDriver::createSyncR(Handle<HwSync> fh, int) {
|
||||
DEBUG_MARKER()
|
||||
|
||||
GLSync* f = handle_cast<GLSync *>(fh);
|
||||
f->gl.sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
f->handle = mContext.createFenceSync(mPlatform);
|
||||
|
||||
// check the status of the sync once a frame, since we must do this from our thread
|
||||
std::weak_ptr<GLSync::State> const weak = f->result;
|
||||
runEveryNowAndThen([sync = f->gl.sync, weak]() -> bool {
|
||||
runEveryNowAndThen(
|
||||
[&platform = mPlatform, context = mContext, handle = f->handle, weak]() -> bool {
|
||||
auto result = weak.lock();
|
||||
if (result) {
|
||||
GLenum const status = glClientWaitSync(sync, 0, 0u);
|
||||
auto const status = context.clientWaitSync(platform, handle);
|
||||
result->status.store(status, std::memory_order_relaxed);
|
||||
return (status != GL_TIMEOUT_EXPIRED);
|
||||
return (status != OpenGLContext::FenceSync::Status::TIMEOUT_EXPIRED);
|
||||
}
|
||||
return true; // we're done
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1317,7 +1337,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);
|
||||
}
|
||||
@@ -1325,9 +1345,6 @@ void OpenGLDriver::destroyTexture(Handle<HwTexture> th) {
|
||||
assert_invariant(t->gl.target == GL_RENDERBUFFER);
|
||||
glDeleteRenderbuffers(1, &t->gl.id);
|
||||
}
|
||||
if (t->gl.fence) {
|
||||
glDeleteSync(t->gl.fence);
|
||||
}
|
||||
if (t->gl.sidecarRenderBufferMS) {
|
||||
glDeleteRenderbuffers(1, &t->gl.sidecarRenderBufferMS);
|
||||
}
|
||||
@@ -1406,10 +1423,9 @@ void OpenGLDriver::destroyTimerQuery(Handle<HwTimerQuery> tqh) {
|
||||
|
||||
void OpenGLDriver::destroySync(Handle<HwSync> sh) {
|
||||
DEBUG_MARKER()
|
||||
|
||||
if (sh) {
|
||||
GLSync* s = handle_cast<GLSync*>(sh);
|
||||
glDeleteSync(s->gl.sync);
|
||||
mContext.destroyFenceSync(mPlatform, s->handle);
|
||||
destruct(sh, s);
|
||||
}
|
||||
}
|
||||
@@ -1451,7 +1467,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 +1475,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 +1494,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 +1510,7 @@ void OpenGLDriver::updateStreams(DriverApi* driver) {
|
||||
}
|
||||
});
|
||||
}
|
||||
mStreamsWithPendingAquiredImage.clear();
|
||||
mStreamsWithPendingAcquiredImage.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1676,6 +1700,10 @@ bool OpenGLDriver::isAutoDepthResolveSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLDriver::isSRGBSwapChainSupported() {
|
||||
return mPlatform.isSRGBSwapChainSupported();
|
||||
}
|
||||
|
||||
bool OpenGLDriver::isWorkaroundNeeded(Workaround workaround) {
|
||||
switch (workaround) {
|
||||
case Workaround::SPLIT_EASU:
|
||||
@@ -1951,7 +1979,9 @@ void OpenGLDriver::generateMipmaps(Handle<HwTexture> th) {
|
||||
|
||||
auto& gl = mContext;
|
||||
GLTexture* t = handle_cast<GLTexture *>(th);
|
||||
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
|
||||
assert_invariant(t->gl.target != GL_TEXTURE_2D_MULTISAMPLE);
|
||||
#endif
|
||||
// Note: glGenerateMimap can also fail if the internal format is not both
|
||||
// color-renderable and filterable (i.e.: doesn't work for depth)
|
||||
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
|
||||
@@ -1992,8 +2022,13 @@ void OpenGLDriver::setTextureData(GLTexture* t, uint32_t level,
|
||||
|
||||
gl.pixelStore(GL_UNPACK_ROW_LENGTH, GLint(p.stride));
|
||||
gl.pixelStore(GL_UNPACK_ALIGNMENT, GLint(p.alignment));
|
||||
gl.pixelStore(GL_UNPACK_SKIP_PIXELS, GLint(p.left));
|
||||
gl.pixelStore(GL_UNPACK_SKIP_ROWS, GLint(p.top));
|
||||
|
||||
// This is equivalent to using GL_UNPACK_SKIP_PIXELS and GL_UNPACK_SKIP_ROWS
|
||||
using PBD = PixelBufferDescriptor;
|
||||
size_t const stride = p.stride ? p.stride : width;
|
||||
size_t const bpp = PBD::computeDataSize(p.format, p.type, 1, 1, 1);
|
||||
size_t const bpr = PBD::computeDataSize(p.format, p.type, stride, 1, p.alignment);
|
||||
void const* const buffer = static_cast<char const*>(p.buffer) + p.left * bpp + bpr * p.top;
|
||||
|
||||
switch (t->target) {
|
||||
case SamplerType::SAMPLER_EXTERNAL:
|
||||
@@ -2007,7 +2042,7 @@ void OpenGLDriver::setTextureData(GLTexture* t, uint32_t level,
|
||||
assert_invariant(t->gl.target == GL_TEXTURE_2D);
|
||||
glTexSubImage2D(t->gl.target, GLint(level),
|
||||
GLint(xoffset), GLint(yoffset),
|
||||
GLsizei(width), GLsizei(height), glFormat, glType, p.buffer);
|
||||
GLsizei(width), GLsizei(height), glFormat, glType, buffer);
|
||||
break;
|
||||
case SamplerType::SAMPLER_3D:
|
||||
assert_invariant(zoffset + depth <= std::max(1u, t->depth >> level));
|
||||
@@ -2016,7 +2051,7 @@ void OpenGLDriver::setTextureData(GLTexture* t, uint32_t level,
|
||||
assert_invariant(t->gl.target == GL_TEXTURE_3D);
|
||||
glTexSubImage3D(t->gl.target, GLint(level),
|
||||
GLint(xoffset), GLint(yoffset), GLint(zoffset),
|
||||
GLsizei(width), GLsizei(height), GLsizei(depth), glFormat, glType, p.buffer);
|
||||
GLsizei(width), GLsizei(height), GLsizei(depth), glFormat, glType, buffer);
|
||||
break;
|
||||
case SamplerType::SAMPLER_2D_ARRAY:
|
||||
case SamplerType::SAMPLER_CUBEMAP_ARRAY:
|
||||
@@ -2028,7 +2063,7 @@ void OpenGLDriver::setTextureData(GLTexture* t, uint32_t level,
|
||||
t->gl.target == GL_TEXTURE_CUBE_MAP_ARRAY);
|
||||
glTexSubImage3D(t->gl.target, GLint(level),
|
||||
GLint(xoffset), GLint(yoffset), GLint(zoffset),
|
||||
GLsizei(width), GLsizei(height), GLsizei(depth), glFormat, glType, p.buffer);
|
||||
GLsizei(width), GLsizei(height), GLsizei(depth), glFormat, glType, buffer);
|
||||
break;
|
||||
case SamplerType::SAMPLER_CUBEMAP: {
|
||||
assert_invariant(t->gl.target == GL_TEXTURE_CUBE_MAP);
|
||||
@@ -2044,7 +2079,7 @@ void OpenGLDriver::setTextureData(GLTexture* t, uint32_t level,
|
||||
GLenum const target = getCubemapTarget(zoffset + face);
|
||||
glTexSubImage2D(target, GLint(level), GLint(xoffset), GLint(yoffset),
|
||||
GLsizei(width), GLsizei(height), glFormat, glType,
|
||||
static_cast<uint8_t const*>(p.buffer) + faceSize * face);
|
||||
static_cast<uint8_t const*>(buffer) + faceSize * face);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2163,37 +2198,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) {
|
||||
@@ -2329,13 +2353,14 @@ SyncStatus OpenGLDriver::getSyncStatus(Handle<HwSync> sh) {
|
||||
return SyncStatus::NOT_SIGNALED;
|
||||
}
|
||||
auto status = s->result->status.load(std::memory_order_relaxed);
|
||||
using Status = OpenGLContext::FenceSync::Status;
|
||||
switch (status) {
|
||||
case GL_CONDITION_SATISFIED:
|
||||
case GL_ALREADY_SIGNALED:
|
||||
case Status::CONDITION_SATISFIED:
|
||||
case Status::ALREADY_SIGNALED:
|
||||
return SyncStatus::SIGNALED;
|
||||
case GL_TIMEOUT_EXPIRED:
|
||||
case Status::TIMEOUT_EXPIRED:
|
||||
return SyncStatus::NOT_SIGNALED;
|
||||
case GL_WAIT_FAILED:
|
||||
case Status::FAILURE:
|
||||
default:
|
||||
return SyncStatus::ERROR;
|
||||
}
|
||||
@@ -2706,10 +2731,7 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
|
||||
GLenum const glFormat = getFormat(p.format);
|
||||
GLenum const glType = getType(p.type);
|
||||
|
||||
gl.pixelStore(GL_PACK_ROW_LENGTH, (GLint)p.stride);
|
||||
gl.pixelStore(GL_PACK_ALIGNMENT, (GLint)p.alignment);
|
||||
gl.pixelStore(GL_PACK_SKIP_PIXELS, (GLint)p.left);
|
||||
gl.pixelStore(GL_PACK_SKIP_ROWS, (GLint)p.top);
|
||||
gl.pixelStore(GL_PACK_ALIGNMENT, (GLint)p.alignment);
|
||||
|
||||
/*
|
||||
* glReadPixel() operation...
|
||||
@@ -2737,44 +2759,54 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
|
||||
*/
|
||||
|
||||
GLRenderTarget const* s = handle_cast<GLRenderTarget const*>(src);
|
||||
gl.bindFramebuffer(GL_READ_FRAMEBUFFER, s->gl.fbo);
|
||||
|
||||
// glReadPixel doesn't resolve automatically, but it does with the auto-resolve extension,
|
||||
// which we're always emulating. So if we have a resolved fbo (fbo_read), use that instead.
|
||||
gl.bindFramebuffer(GL_READ_FRAMEBUFFER, s->gl.fbo_read ? s->gl.fbo_read : s->gl.fbo);
|
||||
|
||||
using PBD = PixelBufferDescriptor;
|
||||
|
||||
// The PBO only needs to accommodate the area we're reading, with alignment.
|
||||
auto const pboSize = (GLsizeiptr)PBD::computeDataSize(
|
||||
p.format, p.type, width, height, p.alignment);
|
||||
|
||||
GLuint pbo;
|
||||
glGenBuffers(1, &pbo);
|
||||
gl.bindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, (GLsizeiptr)p.size, nullptr, GL_STATIC_DRAW);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, pboSize, nullptr, GL_STATIC_DRAW);
|
||||
glReadPixels(GLint(x), GLint(y), GLint(width), GLint(height), glFormat, glType, nullptr);
|
||||
gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
// we're forced to make a copy on the heap because otherwise it deletes std::function<> copy
|
||||
// constructor.
|
||||
auto* pUserBuffer = new PixelBufferDescriptor(std::move(p));
|
||||
whenGpuCommandsComplete([this, width, height, pbo, pUserBuffer]() mutable {
|
||||
auto* const pUserBuffer = new PixelBufferDescriptor(std::move(p));
|
||||
whenGpuCommandsComplete([this, width, height, pbo, pboSize, pUserBuffer]() mutable {
|
||||
PixelBufferDescriptor& p = *pUserBuffer;
|
||||
auto& gl = mContext;
|
||||
gl.bindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
|
||||
void* vaddr = nullptr;
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
std::unique_ptr<uint8_t> clientBuffer = std::make_unique<uint8_t>(p.size);
|
||||
glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, p.size, clientBuffer.get());
|
||||
std::unique_ptr<uint8_t> clientBuffer = std::make_unique<uint8_t>(pboSize);
|
||||
glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, pboSize, clientBuffer.get());
|
||||
vaddr = clientBuffer.get();
|
||||
#else
|
||||
vaddr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, (GLsizeiptr)p.size, GL_MAP_READ_BIT);
|
||||
vaddr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, pboSize, GL_MAP_READ_BIT);
|
||||
#endif
|
||||
if (vaddr) {
|
||||
// now we need to flip the buffer vertically to match our API
|
||||
size_t const stride = p.stride ? p.stride : width;
|
||||
size_t const bpp = PixelBufferDescriptor::computeDataSize(
|
||||
p.format, p.type, 1, 1, 1);
|
||||
size_t const bpr = PixelBufferDescriptor::computeDataSize(
|
||||
p.format, p.type, stride, 1, p.alignment);
|
||||
char const* head = (char const*)vaddr + p.left * bpp + bpr * p.top;
|
||||
char* tail = (char*)p.buffer + p.left * bpp + bpr * (p.top + height - 1);
|
||||
size_t const bpp = PBD::computeDataSize(p.format, p.type, 1, 1, 1);
|
||||
size_t const dstBpr = PBD::computeDataSize(p.format, p.type, stride, 1, p.alignment);
|
||||
char* pDst = (char*)p.buffer + p.left * bpp + dstBpr * (p.top + height - 1);
|
||||
|
||||
size_t const srcBpr = PBD::computeDataSize(p.format, p.type, width, 1, p.alignment);
|
||||
char const* pSrc = (char const*)vaddr;
|
||||
|
||||
for (size_t i = 0; i < height; ++i) {
|
||||
memcpy(tail, head, bpp * width);
|
||||
head += bpr;
|
||||
tail -= bpr;
|
||||
memcpy(pDst, pSrc, bpp * width);
|
||||
pSrc += srcBpr;
|
||||
pDst -= dstBpr;
|
||||
}
|
||||
#if !defined(__EMSCRIPTEN__)
|
||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||
@@ -2841,7 +2873,7 @@ void OpenGLDriver::readBufferSubData(backend::BufferObjectHandle boh,
|
||||
}
|
||||
|
||||
void OpenGLDriver::whenGpuCommandsComplete(std::function<void()> fn) noexcept {
|
||||
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
OpenGLContext::FenceSync sync = mContext.createFenceSync(mPlatform);
|
||||
mGpuCommandCompleteOps.emplace_back(sync, std::move(fn));
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
@@ -2854,15 +2886,16 @@ void OpenGLDriver::executeGpuCommandsCompleteOps() noexcept {
|
||||
auto& v = mGpuCommandCompleteOps;
|
||||
auto it = v.begin();
|
||||
while (it != v.end()) {
|
||||
GLenum const status = glClientWaitSync(it->first, 0, 0);
|
||||
if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED) {
|
||||
using Status = OpenGLContext::FenceSync::Status;
|
||||
auto const status = mContext.clientWaitSync(mPlatform, it->first);
|
||||
if (status == Status::ALREADY_SIGNALED || status == Status::CONDITION_SATISFIED) {
|
||||
it->second();
|
||||
glDeleteSync(it->first);
|
||||
mContext.destroyFenceSync(mPlatform, it->first);
|
||||
it = v.erase(it);
|
||||
} else if (UTILS_UNLIKELY(status == GL_WAIT_FAILED)) {
|
||||
} else if (UTILS_UNLIKELY(status == Status::FAILURE)) {
|
||||
// This should never happen, but is very problematic if it does, as we might leak
|
||||
// some data depending on what the callback does. However, we clean up our own state.
|
||||
glDeleteSync(it->first);
|
||||
mContext.destroyFenceSync(mPlatform, it->first);
|
||||
it = v.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
@@ -3200,8 +3233,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
|
||||
|
||||
@@ -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>
|
||||
@@ -120,7 +122,6 @@ public:
|
||||
GLenum target = 0;
|
||||
GLenum internalFormat = 0;
|
||||
GLuint sidecarRenderBufferMS = 0; // multi-sample sidecar renderbuffer
|
||||
mutable GLsync fence = {};
|
||||
|
||||
// texture parameters go here too
|
||||
GLfloat anisotropy = 1.0;
|
||||
@@ -132,7 +133,7 @@ public:
|
||||
uint8_t reserved : 3;
|
||||
} gl;
|
||||
|
||||
void* platformPImpl = nullptr;
|
||||
OpenGLPlatform::ExternalTexture* externalTexture = nullptr;
|
||||
};
|
||||
|
||||
struct GLTimerQuery : public HwTimerQuery {
|
||||
@@ -184,11 +185,10 @@ public:
|
||||
struct GLSync : public HwSync {
|
||||
using HwSync::HwSync;
|
||||
struct State {
|
||||
std::atomic<GLenum> status{ GL_TIMEOUT_EXPIRED };
|
||||
std::atomic<OpenGLContext::FenceSync::Status> status{
|
||||
OpenGLContext::FenceSync::Status::TIMEOUT_EXPIRED };
|
||||
};
|
||||
struct {
|
||||
GLsync sync;
|
||||
} gl;
|
||||
OpenGLContext::FenceSync handle{};
|
||||
std::shared_ptr<State> result{ std::make_shared<GLSync::State>() };
|
||||
};
|
||||
|
||||
@@ -349,7 +349,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,12 +359,10 @@ 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;
|
||||
std::vector<std::pair<GLsync, std::function<void()>>> mGpuCommandCompleteOps;
|
||||
std::vector<std::pair<OpenGLContext::FenceSync, std::function<void()>>> mGpuCommandCompleteOps;
|
||||
|
||||
// tasks regularly executed on the main thread at until they return true
|
||||
void runEveryNowAndThen(std::function<bool()> fn) noexcept;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -121,11 +121,21 @@ void OpenGLProgram::compileShaders(OpenGLContext& context,
|
||||
UTILS_NOUNROLL
|
||||
for (size_t i = 0; i < Program::SHADER_TYPE_COUNT; i++) {
|
||||
const ShaderStage stage = static_cast<ShaderStage>(i);
|
||||
GLenum glShaderType;
|
||||
GLenum glShaderType{};
|
||||
switch (stage) {
|
||||
case ShaderStage::VERTEX: glShaderType = GL_VERTEX_SHADER; break;
|
||||
case ShaderStage::FRAGMENT: glShaderType = GL_FRAGMENT_SHADER; break;
|
||||
case ShaderStage::COMPUTE: glShaderType = GL_COMPUTE_SHADER; break;
|
||||
case ShaderStage::VERTEX:
|
||||
glShaderType = GL_VERTEX_SHADER;
|
||||
break;
|
||||
case ShaderStage::FRAGMENT:
|
||||
glShaderType = GL_FRAGMENT_SHADER;
|
||||
break;
|
||||
case ShaderStage::COMPUTE:
|
||||
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
|
||||
glShaderType = GL_COMPUTE_SHADER;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if (UTILS_LIKELY(!shadersSource[i].empty())) {
|
||||
@@ -406,11 +416,6 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* gld) const noexcept {
|
||||
const GLTexture* const t = sb->textureUnitEntries[j].texture;
|
||||
GLuint const s = sb->textureUnitEntries[j].sampler;
|
||||
if (t) { // program may not use all samplers of sampler group
|
||||
if (UTILS_UNLIKELY(t->gl.fence)) {
|
||||
glWaitSync(t->gl.fence, 0, GL_TIMEOUT_IGNORED);
|
||||
glDeleteSync(t->gl.fence);
|
||||
t->gl.fence = nullptr;
|
||||
}
|
||||
gld->bindTexture(tmu, t);
|
||||
gld->bindSampler(tmu, s);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -34,8 +34,9 @@ OpenGLTimerQueryInterface::~OpenGLTimerQueryInterface() = default;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
TimerQueryNative::TimerQueryNative(OpenGLContext& context)
|
||||
: gl(context) {
|
||||
#if defined(GL_VERSION_3_3) || defined(GL_EXT_disjoint_timer_query)
|
||||
|
||||
TimerQueryNative::TimerQueryNative(OpenGLContext&) {
|
||||
}
|
||||
|
||||
TimerQueryNative::~TimerQueryNative() = default;
|
||||
@@ -44,12 +45,12 @@ void TimerQueryNative::flush() {
|
||||
}
|
||||
|
||||
void TimerQueryNative::beginTimeElapsedQuery(GLTimerQuery* query) {
|
||||
gl.beginQuery(GL_TIME_ELAPSED, query->gl.query);
|
||||
glBeginQuery(GL_TIME_ELAPSED, query->gl.query);
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void TimerQueryNative::endTimeElapsedQuery(GLTimerQuery*) {
|
||||
gl.endQuery(GL_TIME_ELAPSED);
|
||||
glEndQuery(GL_TIME_ELAPSED);
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
@@ -62,14 +63,14 @@ bool TimerQueryNative::queryResultAvailable(GLTimerQuery* query) {
|
||||
|
||||
uint64_t TimerQueryNative::queryResult(GLTimerQuery* query) {
|
||||
GLuint64 elapsedTime = 0;
|
||||
// IOS doesn't have glGetQueryObjectui64v, we'll never end-up here on ios anyways
|
||||
#ifndef IOS
|
||||
// we won't end-up here if we're on ES and don't have GL_EXT_disjoint_timer_query
|
||||
glGetQueryObjectui64v(query->gl.query, GL_QUERY_RESULT, &elapsedTime);
|
||||
#endif
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
return elapsedTime;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
OpenGLTimerQueryFence::OpenGLTimerQueryFence(OpenGLPlatform& platform)
|
||||
@@ -85,7 +86,7 @@ OpenGLTimerQueryFence::OpenGLTimerQueryFence(OpenGLPlatform& platform)
|
||||
});
|
||||
exitRequested = mExitRequested;
|
||||
if (!queue.empty()) {
|
||||
Job job(queue.front());
|
||||
Job const job(queue.front());
|
||||
queue.erase(queue.begin());
|
||||
lock.unlock();
|
||||
job();
|
||||
@@ -105,7 +106,7 @@ OpenGLTimerQueryFence::~OpenGLTimerQueryFence() {
|
||||
}
|
||||
|
||||
void OpenGLTimerQueryFence::enqueue(OpenGLTimerQueryFence::Job&& job) {
|
||||
std::unique_lock<utils::Mutex> lock(mLock);
|
||||
std::unique_lock<utils::Mutex> const lock(mLock);
|
||||
mQueue.push_back(std::forward<Job>(job));
|
||||
mCondition.notify_one();
|
||||
}
|
||||
@@ -114,9 +115,9 @@ void OpenGLTimerQueryFence::flush() {
|
||||
// Use calls to flush() as a proxy for when the GPU work started.
|
||||
GLTimerQuery* query = mActiveQuery;
|
||||
if (query) {
|
||||
uint64_t elapsed = query->gl.emulation->elapsed.load(std::memory_order_relaxed);
|
||||
uint64_t const elapsed = query->gl.emulation->elapsed.load(std::memory_order_relaxed);
|
||||
if (!elapsed) {
|
||||
uint64_t now = clock::now().time_since_epoch().count();
|
||||
uint64_t const now = clock::now().time_since_epoch().count();
|
||||
query->gl.emulation->elapsed.store(now, std::memory_order_relaxed);
|
||||
//SYSTRACE_CONTEXT();
|
||||
//SYSTRACE_ASYNC_BEGIN("gpu", query->gl.query);
|
||||
@@ -139,7 +140,7 @@ void OpenGLTimerQueryFence::beginTimeElapsedQuery(GLTimerQuery* query) {
|
||||
void OpenGLTimerQueryFence::endTimeElapsedQuery(GLTimerQuery* query) {
|
||||
assert_invariant(mActiveQuery);
|
||||
Platform::Fence* fence = mPlatform.createFence();
|
||||
std::weak_ptr<GLTimerQuery::State> weak = query->gl.emulation;
|
||||
std::weak_ptr<GLTimerQuery::State> const weak = query->gl.emulation;
|
||||
mActiveQuery = nullptr;
|
||||
//uint32_t cookie = cookie = query->gl.query;
|
||||
push([&platform = mPlatform, fence, weak]() {
|
||||
|
||||
@@ -48,6 +48,8 @@ public:
|
||||
virtual uint64_t queryResult(GLTimerQuery* query) = 0;
|
||||
};
|
||||
|
||||
#if defined(GL_VERSION_3_3) || defined(GL_EXT_disjoint_timer_query)
|
||||
|
||||
class TimerQueryNative : public OpenGLTimerQueryInterface {
|
||||
public:
|
||||
explicit TimerQueryNative(OpenGLContext& context);
|
||||
@@ -58,9 +60,10 @@ private:
|
||||
void endTimeElapsedQuery(GLTimerQuery* query) override;
|
||||
bool queryResultAvailable(GLTimerQuery* query) override;
|
||||
uint64_t queryResult(GLTimerQuery* query) override;
|
||||
OpenGLContext& gl;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
class OpenGLTimerQueryFence : public OpenGLTimerQueryInterface {
|
||||
public:
|
||||
explicit OpenGLTimerQueryFence(OpenGLPlatform& platform);
|
||||
|
||||
@@ -16,11 +16,17 @@
|
||||
|
||||
#include "gl_headers.h"
|
||||
|
||||
#if defined(__ANDROID__) || defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(__EMSCRIPTEN__)
|
||||
#if defined(FILAMENT_IMPORT_ENTRY_POINTS)
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <mutex>
|
||||
|
||||
// for non EGL platforms, we'd need to implement this differently. Currently, it's not a problem.
|
||||
template<typename T>
|
||||
static void getProcAddress(T& pfn, const char* name) noexcept {
|
||||
pfn = (T)eglGetProcAddress(name);
|
||||
}
|
||||
|
||||
namespace glext {
|
||||
#ifdef GL_QCOM_tiled_rendering
|
||||
PFNGLSTARTTILINGQCOMPROC glStartTilingQCOM;
|
||||
@@ -49,68 +55,48 @@ 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() {
|
||||
std::call_once(sGlExtInitialized, []() {
|
||||
std::call_once(sGlExtInitialized, +[]() {
|
||||
#ifdef GL_QCOM_tiled_rendering
|
||||
glStartTilingQCOM =
|
||||
(PFNGLSTARTTILINGQCOMPROC)eglGetProcAddress(
|
||||
"glStartTilingQCOM");
|
||||
|
||||
glEndTilingQCOM =
|
||||
(PFNGLENDTILINGQCOMPROC)eglGetProcAddress(
|
||||
"glEndTilingQCOM");
|
||||
getProcAddress(glStartTilingQCOM, "glStartTilingQCOM");
|
||||
getProcAddress(glEndTilingQCOM, "glEndTilingQCOM");
|
||||
#endif
|
||||
|
||||
#ifdef GL_OES_EGL_image
|
||||
glEGLImageTargetTexture2DOES =
|
||||
(PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress(
|
||||
"glEGLImageTargetTexture2DOES");
|
||||
getProcAddress(glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES");
|
||||
#endif
|
||||
|
||||
#if GL_EXT_debug_marker
|
||||
glInsertEventMarkerEXT =
|
||||
(PFNGLINSERTEVENTMARKEREXTPROC)eglGetProcAddress(
|
||||
"glInsertEventMarkerEXT");
|
||||
|
||||
glPushGroupMarkerEXT =
|
||||
(PFNGLPUSHGROUPMARKEREXTPROC)eglGetProcAddress(
|
||||
"glPushGroupMarkerEXT");
|
||||
|
||||
glPopGroupMarkerEXT =
|
||||
(PFNGLPOPGROUPMARKEREXTPROC)eglGetProcAddress(
|
||||
"glPopGroupMarkerEXT");
|
||||
getProcAddress(glInsertEventMarkerEXT, "glInsertEventMarkerEXT");
|
||||
getProcAddress(glPushGroupMarkerEXT, "glPushGroupMarkerEXT");
|
||||
getProcAddress(glPopGroupMarkerEXT, "glPopGroupMarkerEXT");
|
||||
#endif
|
||||
#if GL_EXT_multisampled_render_to_texture
|
||||
glFramebufferTexture2DMultisampleEXT =
|
||||
(PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)eglGetProcAddress(
|
||||
"glFramebufferTexture2DMultisampleEXT");
|
||||
glRenderbufferStorageMultisampleEXT =
|
||||
(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)eglGetProcAddress(
|
||||
"glRenderbufferStorageMultisampleEXT");
|
||||
getProcAddress(glFramebufferTexture2DMultisampleEXT, "glFramebufferTexture2DMultisampleEXT");
|
||||
getProcAddress(glRenderbufferStorageMultisampleEXT, "glRenderbufferStorageMultisampleEXT");
|
||||
#endif
|
||||
#ifdef GL_KHR_debug
|
||||
glDebugMessageCallbackKHR =
|
||||
(PFNGLDEBUGMESSAGECALLBACKKHRPROC)eglGetProcAddress(
|
||||
"glDebugMessageCallbackKHR");
|
||||
glGetDebugMessageLogKHR =
|
||||
(PFNGLGETDEBUGMESSAGELOGKHRPROC)eglGetProcAddress(
|
||||
"glGetDebugMessageLogKHR");
|
||||
getProcAddress(glDebugMessageCallbackKHR, "glDebugMessageCallbackKHR");
|
||||
getProcAddress(glGetDebugMessageLogKHR, "glGetDebugMessageLogKHR");
|
||||
#endif
|
||||
#ifdef GL_EXT_disjoint_timer_query
|
||||
glGetQueryObjectui64v =
|
||||
(PFNGLGETQUERYOBJECTUI64VEXTPROC)eglGetProcAddress(
|
||||
"glGetQueryObjectui64vEXT");
|
||||
getProcAddress(glGetQueryObjectui64v, "glGetQueryObjectui64vEXT");
|
||||
#endif
|
||||
#ifdef GL_EXT_clip_control
|
||||
getProcAddress(glClipControl, "glClipControlEXT");
|
||||
#endif
|
||||
#if defined(__ANDROID__)
|
||||
getProcAddress(glDispatchCompute, "glDispatchCompute");
|
||||
#endif
|
||||
});
|
||||
#ifdef GL_EXT_clip_control
|
||||
glClipControl =
|
||||
(PFNGLCLIPCONTROLEXTPROC)eglGetProcAddress(
|
||||
"glClipControlEXT");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace glext
|
||||
|
||||
#endif
|
||||
#endif // defined(FILAMENT_IMPORT_ENTRY_POINTS)
|
||||
|
||||
@@ -26,42 +26,6 @@
|
||||
#endif
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
/* The Android NDK doesn't expose extensions, fake it with eglGetProcAddress */
|
||||
namespace glext {
|
||||
// importGLESExtensionsEntryPoints is thread-safe and can be called multiple times.
|
||||
// it is currently called from PlatformEGL.
|
||||
void importGLESExtensionsEntryPoints();
|
||||
|
||||
#ifdef GL_QCOM_tiled_rendering
|
||||
extern PFNGLSTARTTILINGQCOMPROC glStartTilingQCOM;
|
||||
extern PFNGLENDTILINGQCOMPROC glEndTilingQCOM;
|
||||
#endif
|
||||
#ifdef GL_OES_EGL_image
|
||||
extern PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
|
||||
#endif
|
||||
#ifdef GL_EXT_debug_marker
|
||||
extern PFNGLINSERTEVENTMARKEREXTPROC glInsertEventMarkerEXT;
|
||||
extern PFNGLPUSHGROUPMARKEREXTPROC glPushGroupMarkerEXT;
|
||||
extern PFNGLPOPGROUPMARKEREXTPROC glPopGroupMarkerEXT;
|
||||
#endif
|
||||
#ifdef GL_EXT_multisampled_render_to_texture
|
||||
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT;
|
||||
#endif
|
||||
#ifdef GL_KHR_debug
|
||||
extern PFNGLDEBUGMESSAGECALLBACKKHRPROC glDebugMessageCallbackKHR;
|
||||
extern PFNGLGETDEBUGMESSAGELOGKHRPROC glGetDebugMessageLogKHR;
|
||||
#endif
|
||||
#ifdef GL_EXT_disjoint_timer_query
|
||||
extern PFNGLGETQUERYOBJECTUI64VEXTPROC glGetQueryObjectui64v;
|
||||
#endif
|
||||
#ifdef GL_EXT_clip_control
|
||||
extern PFNGLCLIPCONTROLEXTPROC glClipControl;
|
||||
#endif
|
||||
}
|
||||
|
||||
using namespace glext;
|
||||
|
||||
#elif defined(IOS)
|
||||
|
||||
#define GLES_SILENCE_DEPRECATION
|
||||
@@ -82,111 +46,110 @@
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if (!defined(GL_ES_VERSION_2_0) && !defined(GL_VERSION_4_1))
|
||||
#error "Minimum header version must be OpenGL ES 2.0 or OpenGL 4.1"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Since we need ES3.1 headers and iOS only has ES3.0, we also define the constants we
|
||||
* need to avoid many #ifdef in the actual code.
|
||||
* GLES extensions
|
||||
*/
|
||||
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
#if defined(GL_ES_VERSION_2_0) // this basically means all versions of GLES
|
||||
|
||||
#ifdef GL_EXT_disjoint_timer_query
|
||||
# ifndef GL_TIME_ELAPSED
|
||||
# define GL_TIME_ELAPSED GL_TIME_ELAPSED_EXT
|
||||
# endif
|
||||
#if defined(IOS)
|
||||
|
||||
// iOS headers only provide prototypes, nothing to do.
|
||||
|
||||
#else
|
||||
|
||||
#define FILAMENT_IMPORT_ENTRY_POINTS
|
||||
|
||||
/* The Android NDK doesn't expose extensions, fake it with eglGetProcAddress */
|
||||
namespace glext {
|
||||
// importGLESExtensionsEntryPoints is thread-safe and can be called multiple times.
|
||||
// it is currently called from PlatformEGL.
|
||||
void importGLESExtensionsEntryPoints();
|
||||
|
||||
#ifdef GL_QCOM_tiled_rendering
|
||||
extern PFNGLSTARTTILINGQCOMPROC glStartTilingQCOM;
|
||||
extern PFNGLENDTILINGQCOMPROC glEndTilingQCOM;
|
||||
#endif
|
||||
#ifdef GL_OES_EGL_image
|
||||
extern PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
|
||||
#endif
|
||||
#ifdef GL_EXT_debug_marker
|
||||
extern PFNGLINSERTEVENTMARKEREXTPROC glInsertEventMarkerEXT;
|
||||
extern PFNGLPUSHGROUPMARKEREXTPROC glPushGroupMarkerEXT;
|
||||
extern PFNGLPOPGROUPMARKEREXTPROC glPopGroupMarkerEXT;
|
||||
#endif
|
||||
#ifdef GL_EXT_multisampled_render_to_texture
|
||||
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT;
|
||||
#endif
|
||||
#ifdef GL_KHR_debug
|
||||
extern PFNGLDEBUGMESSAGECALLBACKKHRPROC glDebugMessageCallbackKHR;
|
||||
extern PFNGLGETDEBUGMESSAGELOGKHRPROC glGetDebugMessageLogKHR;
|
||||
#endif
|
||||
|
||||
#ifdef GL_EXT_clip_control
|
||||
# ifndef GL_LOWER_LEFT
|
||||
# define GL_LOWER_LEFT GL_LOWER_LEFT_EXT
|
||||
# endif
|
||||
# ifndef GL_ZERO_TO_ONE
|
||||
# define GL_ZERO_TO_ONE GL_ZERO_TO_ONE_EXT
|
||||
# endif
|
||||
extern PFNGLCLIPCONTROLEXTPROC glClipControl;
|
||||
#endif
|
||||
#ifdef GL_EXT_disjoint_timer_query
|
||||
extern PFNGLGETQUERYOBJECTUI64VEXTPROC glGetQueryObjectui64v;
|
||||
#endif
|
||||
#if defined(__ANDROID__)
|
||||
extern PFNGLDISPATCHCOMPUTEPROC glDispatchCompute;
|
||||
#endif
|
||||
} // namespace glext
|
||||
|
||||
using namespace glext;
|
||||
|
||||
#ifndef GL_TEXTURE_CUBE_MAP_ARRAY
|
||||
# define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
|
||||
#endif
|
||||
|
||||
// Prevent lots of #ifdef's between desktop and mobile
|
||||
|
||||
#ifdef GL_EXT_disjoint_timer_query
|
||||
# define GL_TIME_ELAPSED GL_TIME_ELAPSED_EXT
|
||||
#endif
|
||||
|
||||
#ifdef GL_EXT_clip_control
|
||||
# define GL_LOWER_LEFT GL_LOWER_LEFT_EXT
|
||||
# define GL_ZERO_TO_ONE GL_ZERO_TO_ONE_EXT
|
||||
#endif
|
||||
|
||||
// we need GL_TEXTURE_CUBE_MAP_ARRAY defined, but we won't use it if the extension/feature
|
||||
// is not available.
|
||||
#if defined(GL_EXT_texture_cube_map_array)
|
||||
# define GL_TEXTURE_CUBE_MAP_ARRAY GL_TEXTURE_CUBE_MAP_ARRAY_EXT
|
||||
#else
|
||||
# define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
|
||||
#endif
|
||||
|
||||
#if defined(GL_KHR_debug)
|
||||
# ifndef GL_DEBUG_OUTPUT
|
||||
# define GL_DEBUG_OUTPUT GL_DEBUG_OUTPUT_KHR
|
||||
# endif
|
||||
# ifndef GL_DEBUG_OUTPUT_SYNCHRONOUS
|
||||
# define GL_DEBUG_OUTPUT_SYNCHRONOUS GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR
|
||||
# endif
|
||||
|
||||
# ifndef GL_DEBUG_SEVERITY_HIGH
|
||||
# define GL_DEBUG_SEVERITY_HIGH GL_DEBUG_SEVERITY_HIGH_KHR
|
||||
# endif
|
||||
# ifndef GL_DEBUG_SEVERITY_MEDIUM
|
||||
# define GL_DEBUG_SEVERITY_MEDIUM GL_DEBUG_SEVERITY_MEDIUM_KHR
|
||||
# endif
|
||||
# ifndef GL_DEBUG_SEVERITY_LOW
|
||||
# define GL_DEBUG_SEVERITY_LOW GL_DEBUG_SEVERITY_LOW_KHR
|
||||
# endif
|
||||
# ifndef GL_DEBUG_SEVERITY_NOTIFICATION
|
||||
# define GL_DEBUG_SEVERITY_NOTIFICATION GL_DEBUG_SEVERITY_NOTIFICATION_KHR
|
||||
# endif
|
||||
|
||||
# ifndef GL_DEBUG_TYPE_MARKER
|
||||
# define GL_DEBUG_TYPE_MARKER GL_DEBUG_TYPE_MARKER_KHR
|
||||
# endif
|
||||
# ifndef GL_DEBUG_TYPE_ERROR
|
||||
# define GL_DEBUG_TYPE_ERROR GL_DEBUG_TYPE_ERROR_KHR
|
||||
# endif
|
||||
# ifndef GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
|
||||
# define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR
|
||||
# endif
|
||||
# ifndef GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
|
||||
# define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR
|
||||
# endif
|
||||
# ifndef GL_DEBUG_TYPE_PORTABILITY
|
||||
# define GL_DEBUG_TYPE_PORTABILITY GL_DEBUG_TYPE_PORTABILITY_KHR
|
||||
# endif
|
||||
# ifndef GL_DEBUG_TYPE_PERFORMANCE
|
||||
# define GL_DEBUG_TYPE_PERFORMANCE GL_DEBUG_TYPE_PERFORMANCE_KHR
|
||||
# endif
|
||||
# ifndef GL_DEBUG_TYPE_OTHER
|
||||
# define GL_DEBUG_TYPE_OTHER GL_DEBUG_TYPE_OTHER_KHR
|
||||
# endif
|
||||
|
||||
# define glDebugMessageCallback glDebugMessageCallbackKHR
|
||||
# define GL_DEBUG_OUTPUT GL_DEBUG_OUTPUT_KHR
|
||||
# define GL_DEBUG_OUTPUT_SYNCHRONOUS GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR
|
||||
# define GL_DEBUG_SEVERITY_HIGH GL_DEBUG_SEVERITY_HIGH_KHR
|
||||
# define GL_DEBUG_SEVERITY_MEDIUM GL_DEBUG_SEVERITY_MEDIUM_KHR
|
||||
# define GL_DEBUG_SEVERITY_LOW GL_DEBUG_SEVERITY_LOW_KHR
|
||||
# define GL_DEBUG_SEVERITY_NOTIFICATION GL_DEBUG_SEVERITY_NOTIFICATION_KHR
|
||||
# define GL_DEBUG_TYPE_MARKER GL_DEBUG_TYPE_MARKER_KHR
|
||||
# define GL_DEBUG_TYPE_ERROR GL_DEBUG_TYPE_ERROR_KHR
|
||||
# define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR
|
||||
# define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR
|
||||
# define GL_DEBUG_TYPE_PORTABILITY GL_DEBUG_TYPE_PORTABILITY_KHR
|
||||
# define GL_DEBUG_TYPE_PERFORMANCE GL_DEBUG_TYPE_PERFORMANCE_KHR
|
||||
# define GL_DEBUG_TYPE_OTHER GL_DEBUG_TYPE_OTHER_KHR
|
||||
# define glDebugMessageCallback glDebugMessageCallbackKHR
|
||||
#endif
|
||||
|
||||
/* The iOS SDK only provides OpenGL ES headers up to 3.0. Filament works with OpenGL 3.0, but
|
||||
* requires ES3.1 headers */
|
||||
#if !defined(GL_ES_VERSION_3_1)
|
||||
#define GL_SHADER_STORAGE_BUFFER 0x90D2
|
||||
#define GL_COMPUTE_SHADER 0x91B9
|
||||
|
||||
#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
|
||||
|
||||
// FIXME: The GL_TIME_ELAPSED define is used unconditionally in Filament, but
|
||||
// requires extension support.
|
||||
#ifndef GL_TIME_ELAPSED
|
||||
#define GL_TIME_ELAPSED 0x88BF
|
||||
#endif
|
||||
|
||||
#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
|
||||
#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
|
||||
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
|
||||
#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
|
||||
#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
|
||||
#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
|
||||
#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
|
||||
#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
|
||||
|
||||
#endif
|
||||
#endif // GL_ES_VERSION_2_0
|
||||
|
||||
// This is just to simplify the implementation (i.e. so we don't have to have #ifdefs everywhere)
|
||||
#ifndef GL_OES_EGL_image_external
|
||||
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
|
||||
#endif
|
||||
|
||||
// This is an odd duck function that exists in WebGL 2.0 but not in OpenGL ES.
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
extern "C" {
|
||||
@@ -219,11 +182,6 @@ void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *d
|
||||
# define BACKEND_OPENGL_LEVEL BACKEND_OPENGL_LEVEL_GLES20
|
||||
#endif
|
||||
|
||||
// This is just to simplify the implementation (i.e. so we don't have to have #ifdefs everywhere)
|
||||
#ifndef GL_OES_EGL_image_external
|
||||
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
|
||||
#endif
|
||||
|
||||
#include "NullGLES.h"
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_OPENGL_GL_HEADERS_H
|
||||
|
||||
@@ -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:
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
@@ -87,13 +84,13 @@ Driver* PlatformCocoaTouchGL::createDriver(void* const sharedGLContext, const Pl
|
||||
pImpl->mDefaultColorbuffer = renderbuffer[0];
|
||||
pImpl->mDefaultDepthbuffer = renderbuffer[1];
|
||||
|
||||
CVReturn success = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, nullptr,
|
||||
pImpl->mGLContext, nullptr, &pImpl->mTextureCache);
|
||||
UTILS_UNUSED_IN_RELEASE CVReturn success = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault,
|
||||
nullptr, pImpl->mGLContext, nullptr, &pImpl->mTextureCache);
|
||||
assert_invariant(success == kCVReturnSuccess);
|
||||
|
||||
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
|
||||
|
||||
@@ -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,25 +78,31 @@ 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;
|
||||
}
|
||||
|
||||
#if defined(__ANDROID__) || defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(__EMSCRIPTEN__)
|
||||
// PlatofrmEGL is used with and without GLES, but this function is only
|
||||
// meaningful when GLES is used.
|
||||
#if defined(FILAMENT_IMPORT_ENTRY_POINTS)
|
||||
importGLESExtensionsEntryPoints();
|
||||
#endif
|
||||
|
||||
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 +116,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 +135,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 +143,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 +195,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 +207,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 +244,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 +385,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 +423,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 +461,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
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user