diff --git a/doc/changelog.dox b/doc/changelog.dox index 198a0a507..7d217fcb3 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -88,7 +88,8 @@ See also: - Implemented @webgl_extension{WEBGL,debug_renderer_info} as @ref GL::Context::rendererStringUnmasked() and @relativeref{GL::Context,vendorStringUnmasked()} together with printing - those in the engine startup log if the extension is available. It also + those in the engine startup log if the extension is available and expanding + the capabilities of @ref GL::Context::detectedDriver() on WebGL. It also resulted in a new @cpp "firefox-deprecated-debug-renderer-info" @ce workaround being added, see @ref opengl-workarounds for more info. - Recognizing @webgl_extension{EXT,float_blend} and diff --git a/src/Magnum/GL/Context.cpp b/src/Magnum/GL/Context.cpp index 059bc8a70..8ad04aa99 100644 --- a/src/Magnum/GL/Context.cpp +++ b/src/Magnum/GL/Context.cpp @@ -1317,13 +1317,10 @@ Debug& operator<<(Debug& debug, const Context::DetectedDriver value) { switch(value) { /* LCOV_EXCL_START */ #define _c(value) case Context::DetectedDriver::value: return debug << "::" #value; - #ifndef MAGNUM_TARGET_WEBGL _c(Amd) - #endif #ifdef MAGNUM_TARGET_GLES _c(Angle) #endif - #ifndef MAGNUM_TARGET_WEBGL _c(IntelWindows) _c(Mesa) _c(NVidia) @@ -1331,7 +1328,6 @@ Debug& operator<<(Debug& debug, const Context::DetectedDriver value) { #ifdef MAGNUM_TARGET_GLES _c(SwiftShader) #endif - #endif #ifdef CORRADE_TARGET_ANDROID _c(ArmMali) #endif diff --git a/src/Magnum/GL/Context.h b/src/Magnum/GL/Context.h index 43246b7f8..3893f8230 100644 --- a/src/Magnum/GL/Context.h +++ b/src/Magnum/GL/Context.h @@ -409,54 +409,45 @@ class MAGNUM_GL_EXPORT Context { /** * @brief Detected driver * - * @see @ref DetectedDriver, @ref detectedDriver() + * On WebGL, if @webgl_extension{WEBGL,debug_renderer_info} is not + * available and the browser doesn't report the real values through + * @ref vendorString() and @ref rendererString(), driver detection can + * be performed only for limited cases --- see documentation of + * particular values for more information. + * @see @ref DetectedDrivers, @ref detectedDriver() */ enum class DetectedDriver: UnsignedShort { - #ifndef MAGNUM_TARGET_WEBGL /** * Proprietary AMD desktop drivers on Windows and Linux. In * contrast, AMDGPU Mesa drivers report as * @ref DetectedDriver::Mesa instead. - * @requires_gles Not detectable on WebGL, as browsers - * intentionally hide most of the driver information. */ Amd = 1 << 0, - #endif #if defined(MAGNUM_TARGET_GLES) || defined(DOXYGEN_GENERATING_OUTPUT) /** * OpenGL ES implementation by ANGLE (translated to D3D), used by - * browsers on Windows for WebGL. As the WebGL specification - * explicitly disallows exposing driver information to the - * application, this check cannot be done reliably. See also - * @ref DetectedDriver::SwiftShader. + * browsers on Windows for WebGL. See also + * @ref DetectedDriver::SwiftShader. On WebGL, if + * @webgl_extension{WEBGL,debug_renderer_info} is not available, + * the detection is done by checking if the line size range is just + * 1, which is always the case on D3D but not always on GL. * @requires_gles ANGLE doesn't support desktop OpenGL contexts. */ Angle = 1 << 1, #endif - #ifndef MAGNUM_TARGET_WEBGL - /** - * Intel desktop drivers on Windows - * @requires_gles Not detectable on WebGL, as browsers - * intentionally hide most of the driver information. - */ + /** Intel desktop drivers on Windows */ IntelWindows = 1 << 2, /** * Mesa drivers on Windows and Linux. In particular, Intel, AMD * and NVidia Mesa drivers match as this. See also * @ref DetectedDriver::Svga3D. - * @requires_gles Not detectable on WebGL, as browsers - * intentionally hide most of the driver information. */ Mesa = 1 << 3, - /** - * Proprietary NVidia drivers on Windows and Linux - * @requires_gles Not detectable on WebGL, as browsers - * intentionally hide most of the driver information. - */ + /** Proprietary NVidia drivers on Windows and Linux */ NVidia = 1 << 4, /** @@ -464,8 +455,6 @@ class MAGNUM_GL_EXPORT Context { * Windows and Linux guests. See https://www.mesa3d.org/vmware-guest.html * for more information. Detected in combination with * @ref DetectedDriver::Mesa. - * @requires_gles Not detectable on WebGL, as browsers - * intentionally hide most of the driver information. */ Svga3D = 1 << 5, @@ -475,13 +464,11 @@ class MAGNUM_GL_EXPORT Context { * renderer for OpenGL ES. Usually used by browsers in cases where * a GPU isn't available. See also @ref DetectedDriver::Angle. * @requires_gles SwiftShader doesn't support desktop OpenGL - * contexts. Not detectable on WebGL, as browsers - * intentionally hide most of the driver information. + * contexts. * @m_since{2019,10} */ SwiftShader = 1 << 6, #endif - #endif #if defined(CORRADE_TARGET_ANDROID) || defined(DOXYGEN_GENERATING_OUTPUT) /** diff --git a/src/Magnum/GL/Implementation/driverSpecific.cpp b/src/Magnum/GL/Implementation/driverSpecific.cpp index e32704756..d0abeab2a 100644 --- a/src/Magnum/GL/Implementation/driverSpecific.cpp +++ b/src/Magnum/GL/Implementation/driverSpecific.cpp @@ -429,68 +429,90 @@ auto Context::detectedDriver() -> DetectedDrivers { _detectedDrivers = DetectedDrivers{}; - #if !defined(MAGNUM_TARGET_WEBGL) && !defined(CORRADE_TARGET_APPLE) - const Containers::StringView renderer = rendererString(); + #ifndef CORRADE_TARGET_APPLE + const Containers::StringView renderer = + #ifndef MAGNUM_TARGET_WEBGL + rendererString() + #else + rendererStringUnmasked() + #endif + ; #endif #if !defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_WEBGL) const Containers::StringView version = versionString(); #endif - #if (!defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_WEBGL)) || defined(MAGNUM_TARGET_GLES) - const Containers::StringView vendor = vendorString(); + #if !defined(CORRADE_TARGET_APPLE) || defined(MAGNUM_TARGET_GLES) + const Containers::StringView vendor = + #ifndef MAGNUM_TARGET_WEBGL + vendorString() + #else + vendorStringUnmasked() + #endif + ; #endif + /* In some cases we can have a combination of drivers (e.g. ANGLE running + on top of Mesa, Mesa Zink running on top of NVidia drivers...) so the + detection has no early returns. */ + /* Apple has its own drivers */ - #if !defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_WEBGL) + /** @todo when Zink on Apple is a thing, this needs an update */ + #ifndef CORRADE_TARGET_APPLE /* AMD binary desktop drivers */ if(vendor.contains("ATI Technologies Inc."_s)) - return *_detectedDrivers |= DetectedDriver::Amd; + *_detectedDrivers |= DetectedDriver::Amd; #ifdef CORRADE_TARGET_WINDOWS /* Intel Windows drivers */ if(vendor.contains("Intel"_s)) - return *_detectedDrivers |= DetectedDriver::IntelWindows; + *_detectedDrivers |= DetectedDriver::IntelWindows; #endif /* Mesa drivers */ - if(version.contains("Mesa"_s)) { + #ifndef MAGNUM_TARGET_WEBGL + if(version.contains("Mesa"_s)) + #else + if(renderer.contains("Mesa"_s)) + #endif + { *_detectedDrivers |= DetectedDriver::Mesa; if(renderer.contains("SVGA3D"_s)) *_detectedDrivers |= DetectedDriver::Svga3D; - return *_detectedDrivers; + *_detectedDrivers; } if(vendor.contains("NVIDIA Corporation"_s)) - return *_detectedDrivers |= DetectedDriver::NVidia; + *_detectedDrivers |= DetectedDriver::NVidia; #endif - /** @todo there is also D3D9/D3D11 distinction on webglreport.com, is it useful? */ #ifdef MAGNUM_TARGET_GLES - /* ANGLE. Can detect easily on ES, have to resort to hacks on WebGL. - Sources: http://stackoverflow.com/a/20149090 + http://webglreport.com */ - #ifndef MAGNUM_TARGET_WEBGL + /* ANGLE. On WebGL only if we are so lucky and have access to the unmasked + renderer string. */ if(renderer.contains("ANGLE"_s)) - return *_detectedDrivers |= DetectedDriver::Angle; - #else - { + *_detectedDrivers |= DetectedDriver::Angle; + #ifdef MAGNUM_TARGET_WEBGL + /* Otherwise try to detect a D3D ANGLE backend by querying line width. It's + always exactly just 1 on D3D, usually more on GL, not sure about Metal. + so this is not a 100% match. Sources: http://stackoverflow.com/a/20149090 + and http://webglreport.com */ + else { Range1Di range; glGetIntegerv(GL_ALIASED_LINE_WIDTH_RANGE, range.data()); if(range.min() == 1 && range.max() == 1 && vendor != "Internet Explorer"_s) - return *_detectedDrivers |= DetectedDriver::Angle; + *_detectedDrivers |= DetectedDriver::Angle; } #endif - #ifndef MAGNUM_TARGET_WEBGL /* SwiftShader */ if(renderer.contains("SwiftShader"_s)) - return *_detectedDrivers |= DetectedDriver::SwiftShader; - #endif + *_detectedDrivers |= DetectedDriver::SwiftShader; #endif #ifdef CORRADE_TARGET_ANDROID if(vendor.contains("ARM"_s) && renderer.contains("Mali"_s)) - return *_detectedDrivers |= DetectedDriver::ArmMali; + *_detectedDrivers |= DetectedDriver::ArmMali; #endif return *_detectedDrivers;