Lower limit from API 21 to API 19 (#1701)
* Lower limit from API 21 to API 19 This was requested by an internal application. API 19 is when OpenGL ES 3.0 support was added so there is no good reason for us to not support this API level. The only trick is to avoid referring to the glTexStorage2DMultisample symbol directly as it only exists in 3.1. * Compile out code we never use * Use reflection to handle shared EGL contexts pre-API 21. * Remove comment * More fixes required to run on API level 19 - dlym() fails for ashmem on API 19, so we only try on API 26+ instead. - Older emulation for OpenGL ES 3.0 returns error states for valid API calls so we need to clear the GL error bit before we create the GL driver. - Activity lifecycle changes since API 19 would cause animations to keep running and to reference destroyed objects. - EGLContext.getNativeHandle() is new in API 21, we need to use reflection on API 19. The new code path uses the class loading trick to avoid a bytecode verification error on API 19. * Filament now runs properly on API level 19 This commit adds a new api_level() API to libutils which can be used to query the platform's API level. On Android it works as expected, other platforms currently return 0.
This commit is contained in:
@@ -5,6 +5,7 @@ A new header is inserted each time a *tag* is created.
|
||||
|
||||
## Next release
|
||||
|
||||
- Minimum API level on Android is now API 19 instead of API 21.
|
||||
- Added missing API documentation.
|
||||
- Improved existing API documentation.
|
||||
- Added `Camera::setExposure(float)` to directly control the camera's exposure.
|
||||
|
||||
@@ -47,7 +47,7 @@ android {
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments.add("-DANDROID_PIE=ON")
|
||||
arguments.add("-DANDROID_PLATFORM=android-21")
|
||||
arguments.add("-DANDROID_PLATFORM=android-19")
|
||||
arguments.add("-DANDROID_STL=c++_static")
|
||||
arguments.add("-DFILAMENT_DIST_DIR=${filament_path}".toString())
|
||||
cppFlags.add("-std=c++14")
|
||||
|
||||
134
android/filament-android/.idea/codeStyles/Project.xml
generated
134
android/filament-android/.idea/codeStyles/Project.xml
generated
@@ -1,29 +1,113 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<Objective-C-extensions>
|
||||
<file>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||
</file>
|
||||
<class>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||
</class>
|
||||
<extensions>
|
||||
<pair source="cpp" header="h" fileNamingConvention="NONE" />
|
||||
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||
</extensions>
|
||||
</Objective-C-extensions>
|
||||
<codeStyleSettings language="XML">
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
@@ -37,9 +37,9 @@ if (project.hasProperty("filament_dist_dir")) {
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
// Our minSdkVersion is actually 21, we lie and say 14 here so apps don't have
|
||||
// Our minSdkVersion is actually 19, we lie and say 14 here so apps don't have
|
||||
// to increase their minSdkVersion unnecessarily. It is however up to them to
|
||||
// ensure they do not initialize Filament on API levels < 21.
|
||||
// ensure they do not initialize Filament on API levels < 19.
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
@@ -50,7 +50,7 @@ android {
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments.add("-DANDROID_PIE=ON")
|
||||
arguments.add("-DANDROID_PLATFORM=android-21")
|
||||
arguments.add("-DANDROID_PLATFORM=android-19")
|
||||
arguments.add("-DANDROID_STL=c++_static")
|
||||
arguments.add("-DFILAMENT_DIST_DIR=${filament_path}".toString())
|
||||
cppFlags.add("-std=c++14")
|
||||
|
||||
@@ -19,8 +19,10 @@ package com.google.android.filament;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.opengl.EGL14;
|
||||
import android.opengl.EGLContext;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
final class AndroidPlatform extends Platform {
|
||||
private static final String LOG_TAG = "Filament";
|
||||
@@ -59,6 +61,20 @@ final class AndroidPlatform extends Platform {
|
||||
|
||||
@Override
|
||||
long getSharedContextNativeHandle(Object sharedContext) {
|
||||
return ((EGLContext) sharedContext).getNativeHandle();
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
return AndroidPlatform21.getSharedContextNativeHandle(sharedContext);
|
||||
} else {
|
||||
try {
|
||||
//noinspection JavaReflectionMemberAccess
|
||||
Method method = EGLContext.class.getDeclaredMethod("getHandle");
|
||||
Integer handle = (Integer) method.invoke(sharedContext);
|
||||
//noinspection ConstantConditions
|
||||
return handle.longValue();
|
||||
} catch (Exception e) {
|
||||
Log.d(LOG_TAG, "Could not access shared context's native handle", e);
|
||||
}
|
||||
// Should not happen
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.opengl.EGLContext;
|
||||
|
||||
final class AndroidPlatform21 {
|
||||
static long getSharedContextNativeHandle(Object sharedContext) {
|
||||
return ((EGLContext) sharedContext).getNativeHandle();
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ android {
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments.add("-DANDROID_PIE=ON")
|
||||
arguments.add("-DANDROID_PLATFORM=android-21")
|
||||
arguments.add("-DANDROID_PLATFORM=android-19")
|
||||
arguments.add("-DANDROID_STL=c++_static")
|
||||
arguments.add("-DFILAMENT_DIST_DIR=${filament_path}".toString())
|
||||
cppFlags.add("-std=c++14")
|
||||
|
||||
@@ -38,7 +38,7 @@ android {
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.gltf"
|
||||
minSdkVersion 26
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@@ -426,6 +426,11 @@ class MainActivity : Activity() {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
// Stop the animation and any pending frame
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
animator.cancel();
|
||||
|
||||
// Always detach the surface before destroying the engine
|
||||
uiHelper.detach()
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ android {
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.hellotriangle"
|
||||
minSdkVersion 21
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@@ -253,6 +253,11 @@ class MainActivity : Activity() {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
// Stop the animation and any pending frame
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
animator.cancel();
|
||||
|
||||
// Always detach the surface before destroying the engine
|
||||
uiHelper.detach()
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ android {
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.ibl"
|
||||
minSdkVersion 21
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@@ -230,6 +230,11 @@ class MainActivity : Activity() {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
// Stop the animation and any pending frame
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
animator.cancel();
|
||||
|
||||
// Always detach the surface before destroying the engine
|
||||
uiHelper.detach()
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ android {
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.litcube"
|
||||
minSdkVersion 21
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@@ -338,6 +338,11 @@ class MainActivity : Activity() {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
// Stop the animation and any pending frame
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
animator.cancel();
|
||||
|
||||
// Always detach the surface before destroying the engine
|
||||
uiHelper.detach()
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ android {
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.material_builder"
|
||||
minSdkVersion 21
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@@ -266,6 +266,11 @@ class MainActivity : Activity() {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
// Stop the animation and any pending frame
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
animator.cancel();
|
||||
|
||||
// Always detach the surface before destroying the engine
|
||||
uiHelper.detach()
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ android {
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.textureview"
|
||||
minSdkVersion 21
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@@ -253,6 +253,11 @@ class MainActivity : Activity() {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
// Stop the animation and any pending frame
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
animator.cancel();
|
||||
|
||||
// Always detach the surface before destroying the engine
|
||||
uiHelper.detach()
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ android {
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.textured"
|
||||
minSdkVersion 26
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@@ -249,6 +249,11 @@ class MainActivity : Activity() {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
// Stop the animation and any pending frame
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
animator.cancel();
|
||||
|
||||
// Always detach the surface before destroying the engine
|
||||
uiHelper.detach()
|
||||
|
||||
|
||||
@@ -79,19 +79,20 @@ private fun internalFormat(type: TextureType) = when (type) {
|
||||
}
|
||||
|
||||
// Not required when SKIP_BITMAP_COPY is true
|
||||
private fun format(bitmap: Bitmap) = when (bitmap.config) {
|
||||
Bitmap.Config.ALPHA_8 -> Texture.Format.ALPHA
|
||||
Bitmap.Config.RGB_565 -> Texture.Format.RGB
|
||||
Bitmap.Config.ARGB_8888 -> Texture.Format.RGBA
|
||||
Bitmap.Config.RGBA_F16 -> Texture.Format.RGBA
|
||||
// Use String representation for compatibility across API levels
|
||||
private fun format(bitmap: Bitmap) = when (bitmap.config.name) {
|
||||
"ALPHA_8" -> Texture.Format.ALPHA
|
||||
"RGB_565" -> Texture.Format.RGB
|
||||
"ARGB_8888" -> Texture.Format.RGBA
|
||||
"RGBA_F16" -> Texture.Format.RGBA
|
||||
else -> throw IllegalArgumentException("Unknown bitmap configuration")
|
||||
}
|
||||
|
||||
// Not required when SKIP_BITMAP_COPY is true
|
||||
private fun type(bitmap: Bitmap) = when (bitmap.config) {
|
||||
Bitmap.Config.ALPHA_8 -> Texture.Type.UBYTE
|
||||
Bitmap.Config.RGB_565 -> Texture.Type.UBYTE
|
||||
Bitmap.Config.ARGB_8888 -> Texture.Type.UBYTE
|
||||
Bitmap.Config.RGBA_F16 -> Texture.Type.HALF
|
||||
private fun type(bitmap: Bitmap) = when (bitmap.config.name) {
|
||||
"ALPHA_8" -> Texture.Type.UBYTE
|
||||
"RGB_565" -> Texture.Type.UBYTE
|
||||
"ARGB_8888" -> Texture.Type.UBYTE
|
||||
"RGBA_F16" -> Texture.Type.HALF
|
||||
else -> throw IllegalArgumentException("Unsupported bitmap configuration")
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ android {
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.hellotriangle"
|
||||
minSdkVersion 21
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@@ -271,6 +271,11 @@ class MainActivity : Activity() {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
// Stop the animation and any pending frame
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
animator.cancel();
|
||||
|
||||
// Always detach the surface before destroying the engine
|
||||
uiHelper.detach()
|
||||
|
||||
|
||||
3
build.sh
3
build.sh
@@ -121,8 +121,11 @@ function build_clean {
|
||||
echo "Cleaning build directories..."
|
||||
rm -Rf out
|
||||
rm -Rf android/filament-android/build android/filament-android/.externalNativeBuild
|
||||
rm -Rf android/filament-android/build android/filament-android/.cxx
|
||||
rm -Rf android/filamat-android/build android/filamat-android/.externalNativeBuild
|
||||
rm -Rf android/filamat-android/build android/filamat-android/.cxx
|
||||
rm -Rf android/gltfio-android/build android/gltfio-android/.externalNativeBuild
|
||||
rm -Rf android/gltfio-android/build android/gltfio-android/.cxx
|
||||
}
|
||||
|
||||
function build_desktop_target {
|
||||
|
||||
@@ -21,7 +21,7 @@ set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
|
||||
# android
|
||||
set(API_LEVEL 21)
|
||||
set(API_LEVEL 19)
|
||||
|
||||
# architecture
|
||||
set(ARCH armv7a-linux-androideabi)
|
||||
|
||||
@@ -21,7 +21,7 @@ set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
|
||||
# android
|
||||
set(API_LEVEL 21)
|
||||
set(API_LEVEL 19)
|
||||
|
||||
# architecture
|
||||
set(ARCH i686-linux-android)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "ExternalStreamManagerAndroid.h"
|
||||
|
||||
#include <utils/api_level.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
@@ -42,22 +43,22 @@ ExternalStreamManagerAndroid& ExternalStreamManagerAndroid::get() noexcept {
|
||||
|
||||
ExternalStreamManagerAndroid::ExternalStreamManagerAndroid() noexcept
|
||||
: mVm(VirtualMachineEnv::get()) {
|
||||
// We're not initializing the JVM here -- but we could -- because most of the time
|
||||
// we don't need the jvm. Instead we do the initialization on first use. This means we could get
|
||||
// a nasty slow down the very first time, but we'll live with it for now.
|
||||
|
||||
loadSymbol(ASurfaceTexture_fromSurfaceTexture, "ASurfaceTexture_fromSurfaceTexture");
|
||||
loadSymbol(ASurfaceTexture_release, "ASurfaceTexture_release");
|
||||
loadSymbol(ASurfaceTexture_attachToGLContext, "ASurfaceTexture_attachToGLContext");
|
||||
loadSymbol(ASurfaceTexture_detachFromGLContext, "ASurfaceTexture_detachFromGLContext");
|
||||
loadSymbol(ASurfaceTexture_updateTexImage, "ASurfaceTexture_updateTexImage");
|
||||
loadSymbol(ASurfaceTexture_getTimestamp, "ASurfaceTexture_getTimestamp");
|
||||
// the following dlsym() calls don't work on API 19
|
||||
if (api_level() >= 21) {
|
||||
loadSymbol(ASurfaceTexture_fromSurfaceTexture, "ASurfaceTexture_fromSurfaceTexture");
|
||||
loadSymbol(ASurfaceTexture_release, "ASurfaceTexture_release");
|
||||
loadSymbol(ASurfaceTexture_attachToGLContext, "ASurfaceTexture_attachToGLContext");
|
||||
loadSymbol(ASurfaceTexture_detachFromGLContext, "ASurfaceTexture_detachFromGLContext");
|
||||
loadSymbol(ASurfaceTexture_updateTexImage, "ASurfaceTexture_updateTexImage");
|
||||
loadSymbol(ASurfaceTexture_getTimestamp, "ASurfaceTexture_getTimestamp");
|
||||
}
|
||||
|
||||
if (ASurfaceTexture_fromSurfaceTexture) {
|
||||
slog.d << "Using ASurfaceTexture" << io::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UTILS_NOINLINE
|
||||
JNIEnv* ExternalStreamManagerAndroid::getEnvironmentSlow() noexcept {
|
||||
JNIEnv * env = mVm.getEnvironment();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "ExternalTextureManagerAndroid.h"
|
||||
|
||||
#include <utils/api_level.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
@@ -94,8 +95,11 @@ ExternalTextureManagerAndroid::ExternalTextureManagerAndroid() noexcept
|
||||
// if we compile for API 26 (Oreo) and above, we're guaranteed to have AHardwareBuffer
|
||||
// in all other cases, we need to get them at runtime.
|
||||
#ifndef PLATFORM_HAS_HARDWAREBUFFER
|
||||
loadSymbol(AHardwareBuffer_allocate, "AHardwareBuffer_allocate");
|
||||
loadSymbol(AHardwareBuffer_release, "AHardwareBuffer_release");
|
||||
// the following dlsym() calls don't work on API 19
|
||||
if (api_level() >= 21) {
|
||||
loadSymbol(AHardwareBuffer_allocate, "AHardwareBuffer_allocate");
|
||||
loadSymbol(AHardwareBuffer_release, "AHardwareBuffer_release");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
// we don't want to rely on it.
|
||||
#define ALLOW_REVERSE_MULTISAMPLE_RESOLVE false
|
||||
|
||||
// We can only support this feature on OpenGL ES 3.1+
|
||||
// Support is currently disabled as we don't need it
|
||||
#define TEXTURE_2D_MULTISAMPLE_SUPPORTED false
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#define HAS_MAPBUFFERS 0
|
||||
#else
|
||||
@@ -65,7 +69,7 @@ Driver* OpenGLDriverFactory::create(
|
||||
return OpenGLDriver::create(platform, sharedGLContext);
|
||||
}
|
||||
|
||||
} // namesapce backend
|
||||
} // namespace backend
|
||||
|
||||
using namespace backend;
|
||||
using namespace GLUtils;
|
||||
@@ -76,7 +80,8 @@ Driver* OpenGLDriver::create(
|
||||
assert(platform);
|
||||
OpenGLPlatform* const ec = platform;
|
||||
|
||||
{ // here we check we're on a supported version of GL before initializing the driver
|
||||
{
|
||||
// here we check we're on a supported version of GL before initializing the driver
|
||||
GLint major = 0, minor = 0;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &minor);
|
||||
@@ -93,7 +98,6 @@ Driver* OpenGLDriver::create(
|
||||
if (UTILS_UNLIKELY(!(major >= 3 && minor >= 0))) {
|
||||
PANIC_LOG("OpenGL ES 3.0 minimum needed (current %d.%d)", major, minor);
|
||||
goto cleanup;
|
||||
|
||||
}
|
||||
} else if (GL41_HEADERS) {
|
||||
// we require GL 4.1 headers and minimum version
|
||||
@@ -573,20 +577,24 @@ void OpenGLDriver::textureStorage(OpenGLDriver::GLTexture* t,
|
||||
break;
|
||||
}
|
||||
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||
// NOTE: if there is a mix of texture and renderbuffers, "fixed_sample_locations" must be true
|
||||
// NOTE: what's the benefit of setting "fixed_sample_locations" to false?
|
||||
if (TEXTURE_2D_MULTISAMPLE_SUPPORTED) {
|
||||
// NOTE: if there is a mix of texture and renderbuffers, "fixed_sample_locations" must be true
|
||||
// NOTE: what's the benefit of setting "fixed_sample_locations" to false?
|
||||
#if GLES31_HEADERS
|
||||
// only supported from GL 4.3 and GLES 3.1
|
||||
glTexStorage2DMultisample(t->gl.target, t->samples, t->gl.internalFormat,
|
||||
GLsizei(width), GLsizei(height), GL_TRUE);
|
||||
// only supported from GL 4.3 and GLES 3.1
|
||||
glTexStorage2DMultisample(t->gl.target, t->samples, t->gl.internalFormat,
|
||||
GLsizei(width), GLsizei(height), GL_TRUE);
|
||||
#elif GL41_HEADERS
|
||||
// only supported in GL (never in GLES)
|
||||
// TODO: use glTexStorage2DMultisample() on GL 4.3 and above
|
||||
glTexImage2DMultisample(t->gl.target, t->samples, t->gl.internalFormat,
|
||||
GLsizei(width), GLsizei(height), GL_TRUE);
|
||||
// only supported in GL (never in GLES)
|
||||
// TODO: use glTexStorage2DMultisample() on GL 4.3 and above
|
||||
glTexImage2DMultisample(t->gl.target, t->samples, t->gl.internalFormat,
|
||||
GLsizei(width), GLsizei(height), GL_TRUE);
|
||||
#else
|
||||
# error "GL/GLES header version not supported"
|
||||
#endif
|
||||
} else {
|
||||
PANIC_LOG("GL_TEXTURE_2D_MULTISAMPLE is not supported");
|
||||
}
|
||||
break;
|
||||
default: // cannot happen
|
||||
break;
|
||||
|
||||
@@ -41,9 +41,11 @@
|
||||
#include <android/api-level.h>
|
||||
#include <sys/system_properties.h>
|
||||
|
||||
// We require filament to be built with a API 21 toolchain, before that, OpenGLES 3.0 didn't exist
|
||||
#if __ANDROID_API__ < 21
|
||||
# error "__ANDROID_API__ must be at least 21"
|
||||
// We require filament to be built with a 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
|
||||
# error "__ANDROID_API__ must be at least 19"
|
||||
#endif
|
||||
|
||||
using namespace utils;
|
||||
@@ -96,6 +98,14 @@ static void logEglError(const char* name) noexcept {
|
||||
slog.e << name << " failed with " << err << io::endl;
|
||||
}
|
||||
|
||||
static void clearGlError() noexcept {
|
||||
// clear GL error that may have been set by previous calls
|
||||
GLenum error = glGetError();
|
||||
if (error != GL_NO_ERROR) {
|
||||
slog.w << "Ignoring pending GL error " << io::hex << error << io::endl;
|
||||
}
|
||||
}
|
||||
|
||||
class unordered_string_set : public std::unordered_set<std::string> {
|
||||
public:
|
||||
bool has(const char* str) {
|
||||
@@ -251,7 +261,6 @@ Driver* PlatformEGL::createDriver(void* sharedContext) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
@@ -290,6 +299,9 @@ Driver* PlatformEGL::createDriver(void* sharedContext) noexcept {
|
||||
|
||||
initializeGlExtensions();
|
||||
|
||||
// this is needed with older emulators/API levels on Android
|
||||
clearGlError();
|
||||
|
||||
// success!!
|
||||
return OpenGLDriverFactory::create(this, sharedContext);
|
||||
|
||||
@@ -513,7 +525,7 @@ void PlatformEGL::initializeGlExtensions() noexcept {
|
||||
GLint n;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &n);
|
||||
for (GLint i = 0; i < n; ++i) {
|
||||
const char * const extension = (const char*)glGetStringi(GL_EXTENSIONS, (GLuint)i);
|
||||
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");
|
||||
|
||||
@@ -23,6 +23,7 @@ set(DIST_HDRS
|
||||
)
|
||||
|
||||
set(SRCS
|
||||
src/api_level.cpp
|
||||
src/ashmem.cpp
|
||||
src/Allocator.cpp
|
||||
src/CallStack.cpp
|
||||
|
||||
34
libs/utils/include/utils/api_level.h
Normal file
34
libs/utils/include/utils/api_level.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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_UTILS_API_H
|
||||
#define TNT_UTILS_API_H
|
||||
|
||||
#include <utils/compiler.h>
|
||||
|
||||
namespace utils {
|
||||
|
||||
/**
|
||||
* Returns this platform's API level. On Android this function will return
|
||||
* the API level as defined by the SDK API level version. If a platform does
|
||||
* not have an API level, this function returns 0.
|
||||
*/
|
||||
UTILS_PUBLIC
|
||||
int api_level();
|
||||
|
||||
} // namespace utils
|
||||
|
||||
#endif // TNT_UTILS_ARCHITECTURE_H
|
||||
53
libs/utils/src/api_level.cpp
Normal file
53
libs/utils/src/api_level.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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_UTILS_API_H
|
||||
#define TNT_UTILS_API_H
|
||||
|
||||
#include <utils/api_level.h>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <mutex>
|
||||
#include <sys/system_properties.h>
|
||||
#endif
|
||||
|
||||
namespace utils {
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
uint32_t sApiLevel = 0;
|
||||
std::once_flag sApiLevelOnceFlag;
|
||||
|
||||
int api_level() {
|
||||
std::call_once(sApiLevelOnceFlag, []() {
|
||||
char sdkVersion[PROP_VALUE_MAX];
|
||||
__system_property_get("ro.build.version.sdk", sdkVersion);
|
||||
sApiLevel = atoi(sdkVersion);
|
||||
});
|
||||
return sApiLevel;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int api_level() {
|
||||
return 0; // API level is only supported on Android currently
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace utils
|
||||
|
||||
#endif // TNT_UTILS_ARCHITECTURE_H
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <utils/ashmem.h>
|
||||
#include <utils/api_level.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
@@ -85,13 +86,15 @@ static int __ashmem_open() {
|
||||
}
|
||||
|
||||
int ashmem_create_region(const char *name, size_t size) {
|
||||
|
||||
// dynamically check if we have "ASharedMemory_create" (should be the case since 26 (Oreo))
|
||||
using TASharedMemory_create = int(*)(const char *name, size_t size);
|
||||
TASharedMemory_create pfnASharedMemory_create =
|
||||
(TASharedMemory_create)dlsym(RTLD_DEFAULT, "ASharedMemory_create");
|
||||
if (pfnASharedMemory_create) {
|
||||
return pfnASharedMemory_create(name, size);
|
||||
// Fetch the API level to avoid dlsym() on API 19
|
||||
if (api_level() >= 26) {
|
||||
// dynamically check if we have "ASharedMemory_create" (should be the case since 26 (Oreo))
|
||||
using TASharedMemory_create = int(*)(const char *name, size_t size);
|
||||
TASharedMemory_create pfnASharedMemory_create =
|
||||
(TASharedMemory_create)dlsym(RTLD_DEFAULT, "ASharedMemory_create");
|
||||
if (pfnASharedMemory_create) {
|
||||
return pfnASharedMemory_create(name, size);
|
||||
}
|
||||
}
|
||||
|
||||
int ret, save_errno;
|
||||
|
||||
Reference in New Issue
Block a user