From b056c126fee9835d881ce75a8f2e7c6387e13276 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 7 May 2024 09:53:31 -0700 Subject: [PATCH] Add an Engine debug setting to force GLES 2.0 (#7829) * Add an Engine debug setting to force GLES 2.0 This setting is only meaningful on GLES backends, it's otherwise ignored. When set to true, the backend will try to force a ES2 context if supported. If not supported by the platform, the backend will pretend it's a ES2 context. This setting is currently only taken into account by the EGL platform. * Update filament/backend/include/backend/Platform.h Co-authored-by: Powei Feng --------- Co-authored-by: Powei Feng --- android/filament-android/src/main/cpp/Engine.cpp | 4 +++- .../java/com/google/android/filament/Engine.java | 13 +++++++++++-- filament/backend/include/backend/Platform.h | 6 ++++++ filament/backend/src/opengl/OpenGLContext.cpp | 10 +++++++++- filament/backend/src/opengl/OpenGLContext.h | 3 ++- filament/backend/src/opengl/OpenGLDriver.cpp | 6 +++++- .../backend/src/opengl/platforms/PlatformEGL.cpp | 2 +- filament/include/filament/Engine.h | 7 +++++++ filament/src/details/Engine.cpp | 6 ++++-- 9 files changed, 48 insertions(+), 9 deletions(-) diff --git a/android/filament-android/src/main/cpp/Engine.cpp b/android/filament-android/src/main/cpp/Engine.cpp index ef67358079d..482d54834b3 100644 --- a/android/filament-android/src/main/cpp/Engine.cpp +++ b/android/filament-android/src/main/cpp/Engine.cpp @@ -517,7 +517,8 @@ extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBu jlong textureUseAfterFreePoolSize, jboolean disableParallelShaderCompile, jint stereoscopicType, jlong stereoscopicEyeCount, jlong resourceAllocatorCacheSizeMB, jlong resourceAllocatorCacheMaxAge, - jboolean disableHandleUseAfterFreeCheck) { + jboolean disableHandleUseAfterFreeCheck, + jboolean forceGLES2Context) { Engine::Builder* builder = (Engine::Builder*) nativeBuilder; Engine::Config config = { .commandBufferSizeMB = (uint32_t) commandBufferSizeMB, @@ -533,6 +534,7 @@ extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBu .resourceAllocatorCacheSizeMB = (uint32_t) resourceAllocatorCacheSizeMB, .resourceAllocatorCacheMaxAge = (uint8_t) resourceAllocatorCacheMaxAge, .disableHandleUseAfterFreeCheck = (bool) disableHandleUseAfterFreeCheck, + .forceGLES2Context = (bool) forceGLES2Context }; builder->config(&config); } diff --git a/android/filament-android/src/main/java/com/google/android/filament/Engine.java b/android/filament-android/src/main/java/com/google/android/filament/Engine.java index 9f8f478009e..bfb17aa5ae4 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/Engine.java +++ b/android/filament-android/src/main/java/com/google/android/filament/Engine.java @@ -225,7 +225,8 @@ public Builder config(Config config) { config.textureUseAfterFreePoolSize, config.disableParallelShaderCompile, config.stereoscopicType.ordinal(), config.stereoscopicEyeCount, config.resourceAllocatorCacheSizeMB, config.resourceAllocatorCacheMaxAge, - config.disableHandleUseAfterFreeCheck); + config.disableHandleUseAfterFreeCheck, + config.forceGLES2Context); return this; } @@ -428,6 +429,13 @@ public static class Config { * Disable backend handles use-after-free checks. */ public boolean disableHandleUseAfterFreeCheck = false; + + /* + * When the OpenGL ES backend is used, setting this value to true will force a GLES2.0 + * context if supported by the Platform, or if not, will have the backend pretend + * it's a GLES2 context. Ignored on other backends. + */ + public boolean forceGLES2Context = false; } private Engine(long nativeEngine, Config config) { @@ -1353,7 +1361,8 @@ private static native void nSetBuilderConfig(long nativeBuilder, long commandBuf long textureUseAfterFreePoolSize, boolean disableParallelShaderCompile, int stereoscopicType, long stereoscopicEyeCount, long resourceAllocatorCacheSizeMB, long resourceAllocatorCacheMaxAge, - boolean disableHandleUseAfterFreeCheck); + boolean disableHandleUseAfterFreeCheck, + boolean forceGLES2Context); private static native void nSetBuilderFeatureLevel(long nativeBuilder, int ordinal); private static native void nSetBuilderSharedContext(long nativeBuilder, long sharedContext); private static native void nSetBuilderPaused(long nativeBuilder, boolean paused); diff --git a/filament/backend/include/backend/Platform.h b/filament/backend/include/backend/Platform.h index 03026dffe6e..45b0bb82683 100644 --- a/filament/backend/include/backend/Platform.h +++ b/filament/backend/include/backend/Platform.h @@ -65,6 +65,12 @@ class UTILS_PUBLIC Platform { * Disable backend handles use-after-free checks. */ bool disableHandleUseAfterFreeCheck = false; + + /** + * Force GLES2 context if supported, or pretend the context is ES2. Only meaningful on + * GLES 3.x backends. + */ + bool forceGLES2Context = false; }; Platform() noexcept; diff --git a/filament/backend/src/opengl/OpenGLContext.cpp b/filament/backend/src/opengl/OpenGLContext.cpp index f87c5004061..eea3d87fa61 100644 --- a/filament/backend/src/opengl/OpenGLContext.cpp +++ b/filament/backend/src/opengl/OpenGLContext.cpp @@ -63,7 +63,8 @@ bool OpenGLContext::queryOpenGLVersion(GLint* major, GLint* minor) noexcept { #endif } -OpenGLContext::OpenGLContext(OpenGLPlatform& platform) noexcept +OpenGLContext::OpenGLContext(OpenGLPlatform& platform, + Platform::DriverConfig const& driverConfig) noexcept : mPlatform(platform), mSamplerMap(32) { @@ -85,6 +86,13 @@ OpenGLContext::OpenGLContext(OpenGLPlatform& platform) noexcept queryOpenGLVersion(&state.major, &state.minor); + #if defined(BACKEND_OPENGL_VERSION_GLES) + if (UTILS_UNLIKELY(driverConfig.forceGLES2Context)) { + state.major = 2; + state.minor = 0; + } + #endif + OpenGLContext::initExtensions(&ext, state.major, state.minor); OpenGLContext::initProcs(&procs, ext, state.major, state.minor); diff --git a/filament/backend/src/opengl/OpenGLContext.h b/filament/backend/src/opengl/OpenGLContext.h index ff01b76d648..2465c9f82d4 100644 --- a/filament/backend/src/opengl/OpenGLContext.h +++ b/filament/backend/src/opengl/OpenGLContext.h @@ -91,7 +91,8 @@ class OpenGLContext final : public TimerQueryFactoryInterface { static bool queryOpenGLVersion(GLint* major, GLint* minor) noexcept; - explicit OpenGLContext(OpenGLPlatform& platform) noexcept; + explicit OpenGLContext(OpenGLPlatform& platform, + Platform::DriverConfig const& driverConfig) noexcept; ~OpenGLContext() noexcept final; diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index 93037fe051a..52b75fcf166 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -173,6 +173,10 @@ Driver* OpenGLDriver::create(OpenGLPlatform* const platform, PANIC_LOG("OpenGL ES 2.0 minimum needed (current %d.%d)", major, minor); goto cleanup; } + if (UTILS_UNLIKELY(driverConfig.forceGLES2Context)) { + major = 2; + minor = 0; + } #else // we require GL 4.1 headers and minimum version if (UTILS_UNLIKELY(!((major == 4 && minor >= 1) || major > 4))) { @@ -203,7 +207,7 @@ OpenGLDriver::DebugMarker::~DebugMarker() noexcept { OpenGLDriver::OpenGLDriver(OpenGLPlatform* platform, const Platform::DriverConfig& driverConfig) noexcept : mPlatform(*platform), - mContext(mPlatform), + mContext(mPlatform, driverConfig), mShaderCompilerService(*this), mHandleAllocator("Handles", driverConfig.handleArenaSize, diff --git a/filament/backend/src/opengl/platforms/PlatformEGL.cpp b/filament/backend/src/opengl/platforms/PlatformEGL.cpp index b041473839f..dcbec00ec15 100644 --- a/filament/backend/src/opengl/platforms/PlatformEGL.cpp +++ b/filament/backend/src/opengl/platforms/PlatformEGL.cpp @@ -174,7 +174,7 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon }; #ifdef __ANDROID__ - bool requestES2Context = false; + bool requestES2Context = driverConfig.forceGLES2Context; char property[PROP_VALUE_MAX]; int const length = __system_property_get("debug.filament.es2", property); if (length > 0) { diff --git a/filament/include/filament/Engine.h b/filament/include/filament/Engine.h index a737469b768..e77fc5f45f1 100644 --- a/filament/include/filament/Engine.h +++ b/filament/include/filament/Engine.h @@ -362,6 +362,13 @@ class UTILS_PUBLIC Engine { METAL_LIBRARY = 2, }; ShaderLanguage preferredShaderLanguage = ShaderLanguage::DEFAULT; + + /* + * When the OpenGL ES backend is used, setting this value to true will force a GLES2.0 + * context if supported by the Platform, or if not, will have the backend pretend + * it's a GLES2 context. Ignored on other backends. + */ + bool forceGLES2Context = false; }; diff --git a/filament/src/details/Engine.cpp b/filament/src/details/Engine.cpp index d57df19550a..0f8077bb092 100644 --- a/filament/src/details/Engine.cpp +++ b/filament/src/details/Engine.cpp @@ -102,7 +102,8 @@ Engine* FEngine::create(Engine::Builder const& builder) { .handleArenaSize = instance->getRequestedDriverHandleArenaSize(), .textureUseAfterFreePoolSize = instance->getConfig().textureUseAfterFreePoolSize, .disableParallelShaderCompile = instance->getConfig().disableParallelShaderCompile, - .disableHandleUseAfterFreeCheck = instance->getConfig().disableHandleUseAfterFreeCheck + .disableHandleUseAfterFreeCheck = instance->getConfig().disableHandleUseAfterFreeCheck, + .forceGLES2Context = instance->getConfig().forceGLES2Context }; instance->mDriver = platform->createDriver(sharedContext, driverConfig); @@ -673,7 +674,8 @@ int FEngine::loop() { .handleArenaSize = getRequestedDriverHandleArenaSize(), .textureUseAfterFreePoolSize = mConfig.textureUseAfterFreePoolSize, .disableParallelShaderCompile = mConfig.disableParallelShaderCompile, - .disableHandleUseAfterFreeCheck = mConfig.disableHandleUseAfterFreeCheck + .disableHandleUseAfterFreeCheck = mConfig.disableHandleUseAfterFreeCheck, + .forceGLES2Context = mConfig.forceGLES2Context }; mDriver = mPlatform->createDriver(mSharedGLContext, driverConfig);