From 82ba9ec5643e1295c5322b4d081a4ec5d2fe7781 Mon Sep 17 00:00:00 2001 From: Sungun Park Date: Fri, 19 Sep 2025 11:54:51 -0700 Subject: [PATCH 1/3] Cache isMSAASwapChainSupported() result for EGL This change introduces a caching mechanism to store the results of MSAA support queries. The results are stored in a vector, indexed by the power-of-two of the sample count. --- .../include/backend/platforms/PlatformEGL.h | 4 +++ .../src/opengl/platforms/PlatformEGL.cpp | 33 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/filament/backend/include/backend/platforms/PlatformEGL.h b/filament/backend/include/backend/platforms/PlatformEGL.h index 1eb661af4e73..4acd3245f07d 100644 --- a/filament/backend/include/backend/platforms/PlatformEGL.h +++ b/filament/backend/include/backend/platforms/PlatformEGL.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -168,6 +169,9 @@ class PlatformEGL : public OpenGLPlatform { EGLConfig mEGLConfig = EGL_NO_CONFIG_KHR; Config mContextAttribs; std::vector mAdditionalContexts; + // A cache for MSAA support queries. The index of the vector corresponds to the power of 2 of + // the sample count. For example, index 0 is for 2 samples, 1 is for 4 samples, etc. + mutable std::vector> mMSAASupport{4}; // caches for 2x, 4x, 8x, 16x // supported extensions detected at runtime struct { diff --git a/filament/backend/src/opengl/platforms/PlatformEGL.cpp b/filament/backend/src/opengl/platforms/PlatformEGL.cpp index 4029586f386f..402746ae1469 100644 --- a/filament/backend/src/opengl/platforms/PlatformEGL.cpp +++ b/filament/backend/src/opengl/platforms/PlatformEGL.cpp @@ -32,6 +32,7 @@ #endif #include +#include #include #include #include @@ -491,6 +492,27 @@ bool PlatformEGL::isMSAASwapChainSupported(uint32_t samples) const noexcept { return true; } + // The number of samples must be a power-of-two > 1. + if ((samples & (samples - 1)) != 0) { + LOG(INFO) << "The number of samples for MSAA is not a power of two: " << samples; + return false; + } + + // `samples` is a power-of-two that is greater than 1 (e.g., 2, 4, 8, ...). + // We use this to compute an index into our cache. + const uint32_t power = utils::ctz(samples); // `power` is 3 if the number of samples is 8x. + const uint32_t index = power - 1; // The index 0 originally means 1x, which we don't count. + // So make the index 0 to indicate 2x. + if (mMSAASupport.size() <= index) { + mMSAASupport.resize(index + 1); + } + + // Return the cached value if we have one. + if (mMSAASupport[index]) { + return *mMSAASupport[index]; + } + + // Retrieve the config to see if the given number of samples is supported. The result is cached. Config configAttribs = { { EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT }, { EGL_RED_SIZE, 8 }, @@ -498,7 +520,7 @@ bool PlatformEGL::isMSAASwapChainSupported(uint32_t samples) const noexcept { { EGL_BLUE_SIZE, 8 }, { EGL_DEPTH_SIZE, 24 }, { EGL_SAMPLE_BUFFERS, 1 }, - { EGL_SAMPLES, samples }, + { EGL_SAMPLES, (EGLint)samples }, }; if (!ext.egl.KHR_no_config_context) { @@ -514,11 +536,16 @@ bool PlatformEGL::isMSAASwapChainSupported(uint32_t samples) const noexcept { EGLConfig config = EGL_NO_CONFIG_KHR; EGLint configsCount; + bool supported = false; if (!eglChooseConfig(mEGLDisplay, configAttribs.data(), &config, 1, &configsCount)) { - return false; + supported = false; + } else { + supported = configsCount > 0; } - return configsCount > 0; + mMSAASupport[index] = supported; + + return supported; } Platform::SwapChain* PlatformEGL::createSwapChain( From 653f786bbae73dd542efd0e27712637c37cafc45 Mon Sep 17 00:00:00 2001 From: Sungun Park Date: Fri, 19 Sep 2025 16:17:31 -0700 Subject: [PATCH 2/3] feedback --- .../include/backend/platforms/PlatformEGL.h | 7 +- .../src/opengl/platforms/PlatformEGL.cpp | 94 ++++++++----------- 2 files changed, 43 insertions(+), 58 deletions(-) diff --git a/filament/backend/include/backend/platforms/PlatformEGL.h b/filament/backend/include/backend/platforms/PlatformEGL.h index 4acd3245f07d..65f2a111a9ef 100644 --- a/filament/backend/include/backend/platforms/PlatformEGL.h +++ b/filament/backend/include/backend/platforms/PlatformEGL.h @@ -28,7 +28,6 @@ #include #include -#include #include #include @@ -169,9 +168,7 @@ class PlatformEGL : public OpenGLPlatform { EGLConfig mEGLConfig = EGL_NO_CONFIG_KHR; Config mContextAttribs; std::vector mAdditionalContexts; - // A cache for MSAA support queries. The index of the vector corresponds to the power of 2 of - // the sample count. For example, index 0 is for 2 samples, 1 is for 4 samples, etc. - mutable std::vector> mMSAASupport{4}; // caches for 2x, 4x, 8x, 16x + bool mMSAA4XSupport; // supported extensions detected at runtime struct { @@ -222,6 +219,8 @@ class PlatformEGL : public OpenGLPlatform { return makeCurrent(mCurrentContext, drawSurface, readSurface); } } egl{ mEGLDisplay }; + + bool checkIfMSAASwapChainSupported(uint32_t samples) const noexcept; }; } // namespace filament::backend diff --git a/filament/backend/src/opengl/platforms/PlatformEGL.cpp b/filament/backend/src/opengl/platforms/PlatformEGL.cpp index 402746ae1469..512ee43025ce 100644 --- a/filament/backend/src/opengl/platforms/PlatformEGL.cpp +++ b/filament/backend/src/opengl/platforms/PlatformEGL.cpp @@ -32,7 +32,6 @@ #endif #include -#include #include #include #include @@ -108,7 +107,9 @@ void PlatformEGL::clearGlError() noexcept { // --------------------------------------------------------------------------------------------- -PlatformEGL::PlatformEGL() noexcept = default; +PlatformEGL::PlatformEGL() noexcept : OpenGLPlatform() { + mMSAA4XSupport = checkIfMSAASwapChainSupported(4); +} int PlatformEGL::getOSVersion() const noexcept { return 0; @@ -492,60 +493,13 @@ bool PlatformEGL::isMSAASwapChainSupported(uint32_t samples) const noexcept { return true; } - // The number of samples must be a power-of-two > 1. - if ((samples & (samples - 1)) != 0) { - LOG(INFO) << "The number of samples for MSAA is not a power of two: " << samples; - return false; + if (samples == 4) { + return mMSAA4XSupport; } - // `samples` is a power-of-two that is greater than 1 (e.g., 2, 4, 8, ...). - // We use this to compute an index into our cache. - const uint32_t power = utils::ctz(samples); // `power` is 3 if the number of samples is 8x. - const uint32_t index = power - 1; // The index 0 originally means 1x, which we don't count. - // So make the index 0 to indicate 2x. - if (mMSAASupport.size() <= index) { - mMSAASupport.resize(index + 1); - } - - // Return the cached value if we have one. - if (mMSAASupport[index]) { - return *mMSAASupport[index]; - } - - // Retrieve the config to see if the given number of samples is supported. The result is cached. - Config configAttribs = { - { EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT }, - { EGL_RED_SIZE, 8 }, - { EGL_GREEN_SIZE, 8 }, - { EGL_BLUE_SIZE, 8 }, - { EGL_DEPTH_SIZE, 24 }, - { EGL_SAMPLE_BUFFERS, 1 }, - { EGL_SAMPLES, (EGLint)samples }, - }; - - if (!ext.egl.KHR_no_config_context) { - if (isOpenGL()) { - configAttribs[EGL_RENDERABLE_TYPE] = EGL_OPENGL_BIT; - } else { - configAttribs[EGL_RENDERABLE_TYPE] = EGL_OPENGL_ES2_BIT; - if (ext.egl.KHR_create_context) { - configAttribs[EGL_RENDERABLE_TYPE] |= EGL_OPENGL_ES3_BIT_KHR; - } - } - } - - EGLConfig config = EGL_NO_CONFIG_KHR; - EGLint configsCount; - bool supported = false; - if (!eglChooseConfig(mEGLDisplay, configAttribs.data(), &config, 1, &configsCount)) { - supported = false; - } else { - supported = configsCount > 0; - } - - mMSAASupport[index] = supported; - - return supported; + // Other sample counts are not cached, retrieve it. + LOG(INFO) << "MSAA sample count " << samples << " is queried, consider caching it."; + return checkIfMSAASwapChainSupported(samples); } Platform::SwapChain* PlatformEGL::createSwapChain( @@ -865,6 +819,38 @@ EGLContext PlatformEGL::getContextForType(ContextType type) const noexcept { } } +bool PlatformEGL::checkIfMSAASwapChainSupported(uint32_t samples) const noexcept { + // Retrieve the config to see if the given number of samples is supported. The result is cached. + Config configAttribs = { + { EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT }, + { EGL_RED_SIZE, 8 }, + { EGL_GREEN_SIZE, 8 }, + { EGL_BLUE_SIZE, 8 }, + { EGL_DEPTH_SIZE, 24 }, + { EGL_SAMPLE_BUFFERS, 1 }, + { EGL_SAMPLES, (EGLint)samples }, + }; + + if (!ext.egl.KHR_no_config_context) { + if (isOpenGL()) { + configAttribs[EGL_RENDERABLE_TYPE] = EGL_OPENGL_BIT; + } else { + configAttribs[EGL_RENDERABLE_TYPE] = EGL_OPENGL_ES2_BIT; + if (ext.egl.KHR_create_context) { + configAttribs[EGL_RENDERABLE_TYPE] |= EGL_OPENGL_ES3_BIT_KHR; + } + } + } + + EGLConfig config = EGL_NO_CONFIG_KHR; + EGLint configsCount; + if (!eglChooseConfig(mEGLDisplay, configAttribs.data(), &config, 1, &configsCount)) { + return false; + } + + return configsCount > 0; +} + // --------------------------------------------------------------------------------------------- PlatformEGL::Config::Config() = default; From 8fe8f82052c4fa3a9b883f50b352ab48b701a758 Mon Sep 17 00:00:00 2001 From: Sungun Park Date: Fri, 19 Sep 2025 16:43:42 -0700 Subject: [PATCH 3/3] feedback --- filament/backend/include/backend/platforms/PlatformEGL.h | 2 +- filament/backend/src/opengl/platforms/PlatformEGL.cpp | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/filament/backend/include/backend/platforms/PlatformEGL.h b/filament/backend/include/backend/platforms/PlatformEGL.h index 65f2a111a9ef..f3dafda73f2f 100644 --- a/filament/backend/include/backend/platforms/PlatformEGL.h +++ b/filament/backend/include/backend/platforms/PlatformEGL.h @@ -168,7 +168,7 @@ class PlatformEGL : public OpenGLPlatform { EGLConfig mEGLConfig = EGL_NO_CONFIG_KHR; Config mContextAttribs; std::vector mAdditionalContexts; - bool mMSAA4XSupport; + bool mMSAA4XSupport = false; // supported extensions detected at runtime struct { diff --git a/filament/backend/src/opengl/platforms/PlatformEGL.cpp b/filament/backend/src/opengl/platforms/PlatformEGL.cpp index 512ee43025ce..0b676b6697e0 100644 --- a/filament/backend/src/opengl/platforms/PlatformEGL.cpp +++ b/filament/backend/src/opengl/platforms/PlatformEGL.cpp @@ -107,9 +107,7 @@ void PlatformEGL::clearGlError() noexcept { // --------------------------------------------------------------------------------------------- -PlatformEGL::PlatformEGL() noexcept : OpenGLPlatform() { - mMSAA4XSupport = checkIfMSAASwapChainSupported(4); -} +PlatformEGL::PlatformEGL() noexcept = default; int PlatformEGL::getOSVersion() const noexcept { return 0; @@ -324,6 +322,7 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const DriverConfig& drive mCurrentContextType = ContextType::UNPROTECTED; mContextAttribs = std::move(contextAttribs); + mMSAA4XSupport = checkIfMSAASwapChainSupported(4); initializeGlExtensions(); @@ -497,9 +496,7 @@ bool PlatformEGL::isMSAASwapChainSupported(uint32_t samples) const noexcept { return mMSAA4XSupport; } - // Other sample counts are not cached, retrieve it. - LOG(INFO) << "MSAA sample count " << samples << " is queried, consider caching it."; - return checkIfMSAASwapChainSupported(samples); + return false; } Platform::SwapChain* PlatformEGL::createSwapChain(