diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 7f6e8f8866..494fd45c23 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -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. diff --git a/android/filamat-android/build.gradle b/android/filamat-android/build.gradle index ba1faf9895..9e04bc2d86 100644 --- a/android/filamat-android/build.gradle +++ b/android/filamat-android/build.gradle @@ -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") diff --git a/android/filament-android/.idea/codeStyles/Project.xml b/android/filament-android/.idea/codeStyles/Project.xml index 30aa626c23..ae78c113ff 100644 --- a/android/filament-android/.idea/codeStyles/Project.xml +++ b/android/filament-android/.idea/codeStyles/Project.xml @@ -1,29 +1,113 @@ - - - - - - - - - - + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
\ No newline at end of file diff --git a/android/filament-android/build.gradle b/android/filament-android/build.gradle index 7aece47a7a..97bd4c621e 100644 --- a/android/filament-android/build.gradle +++ b/android/filament-android/build.gradle @@ -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") diff --git a/android/filament-android/src/main/java/com/google/android/filament/AndroidPlatform.java b/android/filament-android/src/main/java/com/google/android/filament/AndroidPlatform.java index 6570a623c4..cb6add9e04 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/AndroidPlatform.java +++ b/android/filament-android/src/main/java/com/google/android/filament/AndroidPlatform.java @@ -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; + } } } diff --git a/android/filament-android/src/main/java/com/google/android/filament/AndroidPlatform21.java b/android/filament-android/src/main/java/com/google/android/filament/AndroidPlatform21.java new file mode 100644 index 0000000000..c50c00a167 --- /dev/null +++ b/android/filament-android/src/main/java/com/google/android/filament/AndroidPlatform21.java @@ -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(); + } +} diff --git a/android/gltfio-android/build.gradle b/android/gltfio-android/build.gradle index 5024fd04a8..2f904336a6 100644 --- a/android/gltfio-android/build.gradle +++ b/android/gltfio-android/build.gradle @@ -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") diff --git a/android/samples/gltf-bloom/app/build.gradle b/android/samples/gltf-bloom/app/build.gradle index a373781fd3..707374599a 100644 --- a/android/samples/gltf-bloom/app/build.gradle +++ b/android/samples/gltf-bloom/app/build.gradle @@ -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" diff --git a/android/samples/gltf-bloom/app/src/main/java/com/google/android/filament/gltf/MainActivity.kt b/android/samples/gltf-bloom/app/src/main/java/com/google/android/filament/gltf/MainActivity.kt index 0e59412946..013c007a04 100644 --- a/android/samples/gltf-bloom/app/src/main/java/com/google/android/filament/gltf/MainActivity.kt +++ b/android/samples/gltf-bloom/app/src/main/java/com/google/android/filament/gltf/MainActivity.kt @@ -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() diff --git a/android/samples/hello-triangle/app/build.gradle b/android/samples/hello-triangle/app/build.gradle index 9523759200..bb12e8c252 100644 --- a/android/samples/hello-triangle/app/build.gradle +++ b/android/samples/hello-triangle/app/build.gradle @@ -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" diff --git a/android/samples/hello-triangle/app/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt b/android/samples/hello-triangle/app/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt index fdc9e497a8..f19c1abbac 100644 --- a/android/samples/hello-triangle/app/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt +++ b/android/samples/hello-triangle/app/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt @@ -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() diff --git a/android/samples/image-based-lighting/app/build.gradle b/android/samples/image-based-lighting/app/build.gradle index 75622921a7..ddeff1f5e0 100644 --- a/android/samples/image-based-lighting/app/build.gradle +++ b/android/samples/image-based-lighting/app/build.gradle @@ -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" diff --git a/android/samples/image-based-lighting/app/src/main/java/com/google/android/filament/ibl/MainActivity.kt b/android/samples/image-based-lighting/app/src/main/java/com/google/android/filament/ibl/MainActivity.kt index 14b02175bd..0d9f94416a 100644 --- a/android/samples/image-based-lighting/app/src/main/java/com/google/android/filament/ibl/MainActivity.kt +++ b/android/samples/image-based-lighting/app/src/main/java/com/google/android/filament/ibl/MainActivity.kt @@ -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() diff --git a/android/samples/lit-cube/app/build.gradle b/android/samples/lit-cube/app/build.gradle index 8d78fa8713..daa0ce1a11 100644 --- a/android/samples/lit-cube/app/build.gradle +++ b/android/samples/lit-cube/app/build.gradle @@ -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" diff --git a/android/samples/lit-cube/app/src/main/java/com/google/android/filament/litcube/MainActivity.kt b/android/samples/lit-cube/app/src/main/java/com/google/android/filament/litcube/MainActivity.kt index 95839956a8..defa60a5f1 100644 --- a/android/samples/lit-cube/app/src/main/java/com/google/android/filament/litcube/MainActivity.kt +++ b/android/samples/lit-cube/app/src/main/java/com/google/android/filament/litcube/MainActivity.kt @@ -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() diff --git a/android/samples/material-builder/app/build.gradle b/android/samples/material-builder/app/build.gradle index 874dbaf013..1d634c0ec0 100644 --- a/android/samples/material-builder/app/build.gradle +++ b/android/samples/material-builder/app/build.gradle @@ -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" diff --git a/android/samples/material-builder/app/src/main/java/com/google/android/filament/material_builder/MainActivity.kt b/android/samples/material-builder/app/src/main/java/com/google/android/filament/material_builder/MainActivity.kt index a0f308b001..5c8b96be41 100644 --- a/android/samples/material-builder/app/src/main/java/com/google/android/filament/material_builder/MainActivity.kt +++ b/android/samples/material-builder/app/src/main/java/com/google/android/filament/material_builder/MainActivity.kt @@ -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() diff --git a/android/samples/texture-view/app/build.gradle b/android/samples/texture-view/app/build.gradle index 70afbb965e..0559e057a9 100644 --- a/android/samples/texture-view/app/build.gradle +++ b/android/samples/texture-view/app/build.gradle @@ -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" diff --git a/android/samples/texture-view/app/src/main/java/com/google/android/filament/textureview/MainActivity.kt b/android/samples/texture-view/app/src/main/java/com/google/android/filament/textureview/MainActivity.kt index 436ad9dc97..550d399d03 100644 --- a/android/samples/texture-view/app/src/main/java/com/google/android/filament/textureview/MainActivity.kt +++ b/android/samples/texture-view/app/src/main/java/com/google/android/filament/textureview/MainActivity.kt @@ -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() diff --git a/android/samples/textured-object/app/build.gradle b/android/samples/textured-object/app/build.gradle index 87b6a9dd81..4db15b8247 100644 --- a/android/samples/textured-object/app/build.gradle +++ b/android/samples/textured-object/app/build.gradle @@ -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" diff --git a/android/samples/textured-object/app/src/main/java/com/google/android/filament/textured/MainActivity.kt b/android/samples/textured-object/app/src/main/java/com/google/android/filament/textured/MainActivity.kt index 181a2898f9..161a495eb9 100644 --- a/android/samples/textured-object/app/src/main/java/com/google/android/filament/textured/MainActivity.kt +++ b/android/samples/textured-object/app/src/main/java/com/google/android/filament/textured/MainActivity.kt @@ -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() diff --git a/android/samples/textured-object/app/src/main/java/com/google/android/filament/textured/TextureLoader.kt b/android/samples/textured-object/app/src/main/java/com/google/android/filament/textured/TextureLoader.kt index 784a914e2a..1306e6fb1b 100644 --- a/android/samples/textured-object/app/src/main/java/com/google/android/filament/textured/TextureLoader.kt +++ b/android/samples/textured-object/app/src/main/java/com/google/android/filament/textured/TextureLoader.kt @@ -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") } diff --git a/android/samples/transparent-view/app/build.gradle b/android/samples/transparent-view/app/build.gradle index 9523759200..bb12e8c252 100644 --- a/android/samples/transparent-view/app/build.gradle +++ b/android/samples/transparent-view/app/build.gradle @@ -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" diff --git a/android/samples/transparent-view/app/src/main/java/com/google/android/filament/transparentrendering/MainActivity.kt b/android/samples/transparent-view/app/src/main/java/com/google/android/filament/transparentrendering/MainActivity.kt index e3d7097c7e..7d81786a00 100644 --- a/android/samples/transparent-view/app/src/main/java/com/google/android/filament/transparentrendering/MainActivity.kt +++ b/android/samples/transparent-view/app/src/main/java/com/google/android/filament/transparentrendering/MainActivity.kt @@ -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() diff --git a/build.sh b/build.sh index a4efc3142d..6bcf929f8c 100755 --- a/build.sh +++ b/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 { diff --git a/build/toolchain-arm7-linux-android.cmake b/build/toolchain-arm7-linux-android.cmake index 3e37fd35db..aa3cbb1ce8 100644 --- a/build/toolchain-arm7-linux-android.cmake +++ b/build/toolchain-arm7-linux-android.cmake @@ -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) diff --git a/build/toolchain-x86-linux-android.cmake b/build/toolchain-x86-linux-android.cmake index e5d68d2a0c..d1d9f1ab75 100644 --- a/build/toolchain-x86-linux-android.cmake +++ b/build/toolchain-x86-linux-android.cmake @@ -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) diff --git a/filament/backend/src/android/ExternalStreamManagerAndroid.cpp b/filament/backend/src/android/ExternalStreamManagerAndroid.cpp index 26b9e0eff0..da2941f545 100644 --- a/filament/backend/src/android/ExternalStreamManagerAndroid.cpp +++ b/filament/backend/src/android/ExternalStreamManagerAndroid.cpp @@ -16,6 +16,7 @@ #include "ExternalStreamManagerAndroid.h" +#include #include #include @@ -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(); diff --git a/filament/backend/src/android/ExternalTextureManagerAndroid.cpp b/filament/backend/src/android/ExternalTextureManagerAndroid.cpp index a52fb71ebd..d667db2bcc 100644 --- a/filament/backend/src/android/ExternalTextureManagerAndroid.cpp +++ b/filament/backend/src/android/ExternalTextureManagerAndroid.cpp @@ -17,6 +17,7 @@ #include "ExternalTextureManagerAndroid.h" +#include #include #include @@ -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 } diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index ebe1c962f8..db391ce4c2 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -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; diff --git a/filament/backend/src/opengl/PlatformEGL.cpp b/filament/backend/src/opengl/PlatformEGL.cpp index 099adba4fd..4a2bf9336d 100644 --- a/filament/backend/src/opengl/PlatformEGL.cpp +++ b/filament/backend/src/opengl/PlatformEGL.cpp @@ -41,9 +41,11 @@ #include #include -// 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 { 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"); diff --git a/libs/utils/CMakeLists.txt b/libs/utils/CMakeLists.txt index 8cf133bfd5..0b4e7b7253 100644 --- a/libs/utils/CMakeLists.txt +++ b/libs/utils/CMakeLists.txt @@ -23,6 +23,7 @@ set(DIST_HDRS ) set(SRCS + src/api_level.cpp src/ashmem.cpp src/Allocator.cpp src/CallStack.cpp diff --git a/libs/utils/include/utils/api_level.h b/libs/utils/include/utils/api_level.h new file mode 100644 index 0000000000..bf347fd2ff --- /dev/null +++ b/libs/utils/include/utils/api_level.h @@ -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 + +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 diff --git a/libs/utils/src/api_level.cpp b/libs/utils/src/api_level.cpp new file mode 100644 index 0000000000..0e74770bd4 --- /dev/null +++ b/libs/utils/src/api_level.cpp @@ -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 + +#ifdef ANDROID +#include +#include +#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 diff --git a/libs/utils/src/ashmem.cpp b/libs/utils/src/ashmem.cpp index 08e01e5867..ef3595ead6 100644 --- a/libs/utils/src/ashmem.cpp +++ b/libs/utils/src/ashmem.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include @@ -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;