Expose some GPU Information
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Oct 2012 00:01:57 +0000 (00:01 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Oct 2012 00:01:57 +0000 (00:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=97813

Reviewed by Sam Weinig and Ken Russell and Tim Horton.

Currently there are a few places in the WebGL code (and elsewhere, like CSS filters)
where we do some feature detection by examining the GPU vendor and its capabilities.
This patch puts this detection into our shared Extensions3D object.

* platform/graphics/Extensions3D.h: Adds the new methods for detecting vendor and features.
* platform/graphics/GraphicsContext3D.h:
(GraphicsContext3D): No longer needs function to detect multisampling on ATI.
* platform/graphics/chromium/Extensions3DChromium.h: Stub implementations of all
the new methods. Chromium does its detection elsewhere.
(WebCore::Extensions3DChromium::isNVIDIA):
(WebCore::Extensions3DChromium::isAMD):
(WebCore::Extensions3DChromium::isIntel):
(WebCore::Extensions3DChromium::vendor):
(Extensions3DChromium):
(WebCore::Extensions3DChromium::maySupportMultisampling):
(WebCore::Extensions3DChromium::requiresBuiltInFunctionEmulation):
* platform/graphics/filters/FECustomFilter.cpp:
(WebCore::FECustomFilter::createMultisampleBuffer): Add test for system multisampling to
custom filter code.
* platform/graphics/gpu/DrawingBuffer.cpp:
(WebCore::DrawingBuffer::create): Add test for system multisampling to drawing buffer's
creation code.
* platform/graphics/opengl/Extensions3DOpenGLCommon.cpp:
(WebCore::Extensions3DOpenGLCommon::Extensions3DOpenGLCommon): Detects all the features
as the object is created.
(WebCore::Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE): Can now simply ask
itself if it needs to turn on built-in function translation.
* platform/graphics/opengl/Extensions3DOpenGLCommon.h:
(Extensions3DOpenGLCommon):
(WebCore::Extensions3DOpenGLCommon::isNVIDIA):
(WebCore::Extensions3DOpenGLCommon::isAMD):
(WebCore::Extensions3DOpenGLCommon::isIntel):
(WebCore::Extensions3DOpenGLCommon::vendor):
(WebCore::Extensions3DOpenGLCommon::maySupportMultisampling):
(WebCore::Extensions3DOpenGLCommon::requiresBuiltInFunctionEmulation):
* platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
(WebCore::GraphicsContext3D::validateAttributes): Ask the extension object instead of
testing directly.
* platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:
(WebCore::GraphicsContext3D::validateDepthStencil): Ask the extension object instead
of testing directly.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@130235 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/Extensions3D.h
Source/WebCore/platform/graphics/GraphicsContext3D.h
Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h
Source/WebCore/platform/graphics/filters/FECustomFilter.cpp
Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h
Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp

index 67ebec7..9a9747d 100644 (file)
@@ -1,3 +1,54 @@
+2012-10-02  Dean Jackson  <dino@apple.com>
+
+        Expose some GPU Information
+        https://bugs.webkit.org/show_bug.cgi?id=97813
+
+        Reviewed by Sam Weinig, Ken Russell and Tim Horton.
+
+        Currently there are a few places in the WebGL code (and elsewhere, like CSS filters)
+        where we do some feature detection by examining the GPU vendor and its capabilities.
+        This patch puts this detection into our shared Extensions3D object.
+
+        Covered by existing tests. No new functionality.
+
+        * platform/graphics/Extensions3D.h: Adds the new methods for detecting vendor and features.
+        * platform/graphics/GraphicsContext3D.h:
+        (GraphicsContext3D): No longer needs function to detect multisampling on ATI.
+        * platform/graphics/chromium/Extensions3DChromium.h: Stub implementations of all
+        the new methods. Chromium does its detection elsewhere.
+        (WebCore::Extensions3DChromium::isNVIDIA):
+        (WebCore::Extensions3DChromium::isAMD):
+        (WebCore::Extensions3DChromium::isIntel):
+        (WebCore::Extensions3DChromium::vendor):
+        (Extensions3DChromium):
+        (WebCore::Extensions3DChromium::maySupportMultisampling):
+        (WebCore::Extensions3DChromium::requiresBuiltInFunctionEmulation):
+        * platform/graphics/filters/FECustomFilter.cpp:
+        (WebCore::FECustomFilter::createMultisampleBuffer): Add test for system multisampling to
+        custom filter code.
+        * platform/graphics/gpu/DrawingBuffer.cpp:
+        (WebCore::DrawingBuffer::create): Add test for system multisampling to drawing buffer's
+        creation code.
+        * platform/graphics/opengl/Extensions3DOpenGLCommon.cpp:
+        (WebCore::Extensions3DOpenGLCommon::Extensions3DOpenGLCommon): Detects all the features
+        as the object is created.
+        (WebCore::Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE): Can now simply ask
+        itself if it needs to turn on built-in function translation.
+        * platform/graphics/opengl/Extensions3DOpenGLCommon.h:
+        (Extensions3DOpenGLCommon):
+        (WebCore::Extensions3DOpenGLCommon::isNVidia):
+        (WebCore::Extensions3DOpenGLCommon::isAMD):
+        (WebCore::Extensions3DOpenGLCommon::isIntel):
+        (WebCore::Extensions3DOpenGLCommon::vendor):
+        (WebCore::Extensions3DOpenGLCommon::maySupportMultisampling):
+        (WebCore::Extensions3DOpenGLCommon::requiresBuiltInFunctionEmulation):
+        * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
+        (WebCore::GraphicsContext3D::validateAttributes): Ask the extension object instead of
+        testing directly.
+        * platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:
+        (WebCore::GraphicsContext3D::validateDepthStencil): Ask the extension object instead
+        of testing directly.
+
 2012-10-02  Kenichi Ishibashi  <bashi@chromium.org>
 
         [Chromium] Introduce caches for HarfBuzzShaper
index 5f28afb..48b26ce 100644 (file)
@@ -188,6 +188,22 @@ public:
     virtual void insertEventMarkerEXT(const String&) = 0;
     virtual void pushGroupMarkerEXT(const String&) = 0;
     virtual void popGroupMarkerEXT(void) = 0;
+
+    virtual bool isNVIDIA() = 0;
+    virtual bool isAMD() = 0;
+    virtual bool isIntel() = 0;
+    virtual String vendor() = 0;
+
+    // If this method returns false then the system *definitely* does not support multisampling.
+    // It does not necessarily say the system does support it - callers must attempt to construct
+    // multisampled renderbuffers and check framebuffer completeness.
+    // Ports should implement this to return false on configurations where it is known
+    // that multisampling is not available.
+    virtual bool maySupportMultisampling() = 0;
+
+    // Some configurations have bugs regarding built-in functions in their OpenGL drivers
+    // that must be avoided. Ports should implement this flag such configurations.
+    virtual bool requiresBuiltInFunctionEmulation() = 0;
 };
 
 } // namespace WebCore
index 42076ff..5327f3a 100644 (file)
@@ -1027,7 +1027,6 @@ public:
     friend class GraphicsContext3DPrivate;
     OwnPtr<GraphicsContext3DPrivate> m_private;
 #endif
-    bool systemAllowsMultisamplingOnATICards() const;
 };
 
 } // namespace WebCore
index edd6c13..0ae6551 100644 (file)
@@ -137,6 +137,15 @@ public:
     virtual void pushGroupMarkerEXT(const String&);
     virtual void popGroupMarkerEXT(void);
 
+    // Some helper methods to detect GPU functionality
+    virtual bool isNVidia() { return false; }
+    virtual bool isAMD() { return false; }
+    virtual bool isIntel() { return false; }
+    virtual String vendor() { return ""; }
+
+    virtual bool maySupportMultisampling() { return true; }
+    virtual bool requiresBuiltInFunctionEmulation() { return false; }
+
 private:
     // Instances of this class are strictly owned by the GraphicsContext3D implementation and do not
     // need to be instantiated by any other code.
index fb5760f..3ceb7fa 100644 (file)
@@ -299,7 +299,8 @@ bool FECustomFilter::createMultisampleBuffer()
     m_triedMultisampleBuffer = true;
 
     Extensions3D* extensions = m_context->getExtensions();
-    if (!extensions 
+    if (!extensions
+        || !extensions->maySupportMultisampling()
         || !extensions->supports("GL_ANGLE_framebuffer_multisample")
         || !extensions->supports("GL_ANGLE_framebuffer_blit")
         || !extensions->supports("GL_OES_rgb8_rgba8"))
index fe51104..282bde0 100644 (file)
@@ -54,7 +54,10 @@ static const float s_resourceAdjustedRatio = 0.5;
 PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, const IntSize& size, PreserveDrawingBuffer preserve, AlphaRequirement alpha)
 {
     Extensions3D* extensions = context->getExtensions();
-    bool multisampleSupported = extensions->supports("GL_ANGLE_framebuffer_blit") && extensions->supports("GL_ANGLE_framebuffer_multisample") && extensions->supports("GL_OES_rgb8_rgba8");
+    bool multisampleSupported = extensions->maySupportMultisampling()
+        && extensions->supports("GL_ANGLE_framebuffer_blit")
+        && extensions->supports("GL_ANGLE_framebuffer_multisample")
+        && extensions->supports("GL_OES_rgb8_rgba8");
     if (multisampleSupported) {
         extensions->ensureEnabled("GL_ANGLE_framebuffer_blit");
         extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample");
index 60f6bfa..cf7fa2f 100644 (file)
@@ -53,7 +53,46 @@ namespace WebCore {
 Extensions3DOpenGLCommon::Extensions3DOpenGLCommon(GraphicsContext3D* context)
     : m_initializedAvailableExtensions(false)
     , m_context(context)
+    , m_isNVIDIA(false)
+    , m_isAMD(false)
+    , m_isIntel(false)
+    , m_maySupportMultisampling(true)
+    , m_requiresBuiltInFunctionEmulation(false)
 {
+    m_vendor = String(reinterpret_cast<const char*>(::glGetString(GL_VENDOR)));
+
+    Vector<String> vendorComponents;
+    m_vendor.lower().split(' ', vendorComponents);
+    if (vendorComponents.contains("nvidia"))
+        m_isNVIDIA = true;
+    if (vendorComponents.contains("ati") || vendorComponents.contains("amd"))
+        m_isAMD = true;
+    if (vendorComponents.contains("intel"))
+        m_isIntel = true;
+
+#if PLATFORM(MAC)
+    if (m_isAMD || m_isIntel)
+        m_requiresBuiltInFunctionEmulation = true;
+
+    // Currently in Mac we only allow multisampling if the vendor is NVIDIA,
+    // or if the vendor is AMD/ATI and the system is 10.7.2 and above.
+
+    bool systemSupportsMultisampling = true;
+#if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1080
+    ASSERT(isMainThread());
+    static SInt32 version;
+    if (!version) {
+        if (Gestalt(gestaltSystemVersion, &version) != noErr)
+            systemSupportsMultisampling = false;
+    }
+    // See https://bugs.webkit.org/show_bug.cgi?id=77922 for more details
+    if (systemSupportsMultisampling)
+        systemSupportsMultisampling = version >= 0x1072;
+#endif // SNOW_LEOPARD and LION
+
+    if (m_isNVIDIA || (m_isAMD && systemSupportsMultisampling))
+        m_maySupportMultisampling = true;
+#endif
 }
 
 Extensions3DOpenGLCommon::~Extensions3DOpenGLCommon()
@@ -123,11 +162,8 @@ String Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE(Platform3DObject
     String shaderInfoLog;
     int extraCompileOptions = 0;
 
-#if PLATFORM(MAC)
-    const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR));
-    if (vendor && (std::strstr(vendor, "ATI") || std::strstr(vendor, "AMD") || std::strstr(vendor, "Intel")))
+    if (m_requiresBuiltInFunctionEmulation)
         extraCompileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS;
-#endif
 
     bool isValid = compiler.validateShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog, extraCompileOptions);
 
index 75869de..7092cfa 100644 (file)
@@ -57,6 +57,14 @@ public:
     virtual void getnUniformfvEXT(GC3Duint program, int location, GC3Dsizei bufSize, float *params);
     virtual void getnUniformivEXT(GC3Duint program, int location, GC3Dsizei bufSize, int *params);
 
+    virtual bool isNVIDIA() { return m_isNVIDIA; }
+    virtual bool isAMD() { return m_isAMD; }
+    virtual bool isIntel() { return m_isIntel; }
+    virtual String vendor() { return m_vendor; }
+
+    virtual bool maySupportMultisampling() { return m_maySupportMultisampling; }
+    virtual bool requiresBuiltInFunctionEmulation() { return m_requiresBuiltInFunctionEmulation; }
+
 protected:
     friend class Extensions3DOpenGLES;
     Extensions3DOpenGLCommon(GraphicsContext3D*);
@@ -70,6 +78,14 @@ protected:
 
     // Weak pointer back to GraphicsContext3D
     GraphicsContext3D* m_context;
+
+    bool m_isNVIDIA;
+    bool m_isAMD;
+    bool m_isIntel;
+    bool m_maySupportMultisampling;
+    bool m_requiresBuiltInFunctionEmulation;
+
+    String m_vendor;
 };
 
 } // namespace WebCore
index 98e1145..54af7ca 100644 (file)
@@ -59,13 +59,7 @@ void GraphicsContext3D::validateAttributes()
     Extensions3D* extensions = getExtensions();
     validateDepthStencil("GL_EXT_packed_depth_stencil");
     if (m_attrs.antialias) {
-        bool isValidVendor = true;
-        // Currently in Mac we only turn on antialias if vendor is NVIDIA,
-        // or if ATI and on 10.7.2 and above.
-        const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR));
-        if (!vendor || (!std::strstr(vendor, "NVIDIA") && !(std::strstr(vendor, "ATI") && systemAllowsMultisamplingOnATICards())))
-            isValidVendor = false;
-        if (!isValidVendor || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
+        if (!extensions->maySupportMultisampling() || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
             m_attrs.antialias = false;
         else
             extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample");
@@ -281,26 +275,6 @@ void GraphicsContext3D::clearDepth(GC3Dclampf depth)
     ::glClearDepth(depth);
 }
 
-bool GraphicsContext3D::systemAllowsMultisamplingOnATICards() const
-{
-#if PLATFORM(MAC)
-#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
-    return true;
-#else
-    ASSERT(isMainThread());
-    static SInt32 version;
-    if (!version) {
-        if (Gestalt(gestaltSystemVersion, &version) != noErr)
-            return false;
-    }
-    // See https://bugs.webkit.org/show_bug.cgi?id=77922 for more details
-    return version >= 0x1072;
-#endif // SNOW_LEOPARD and LION
-#else
-    return false;
-#endif // PLATFORM(MAC)
-}
-
 Extensions3D* GraphicsContext3D::getExtensions()
 {
     if (!m_extensions)
index 4fffee4..8a2ac81 100644 (file)
@@ -88,13 +88,7 @@ void GraphicsContext3D::validateDepthStencil(const char* packedDepthStencilExten
             m_attrs.stencil = false;
     }
     if (m_attrs.antialias) {
-        bool isValidVendor = true;
-        // Currently in Mac we only turn on antialias if vendor is NVIDIA,
-        // or if ATI and on 10.7.2 and above.
-        const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR));
-        if (!vendor || (!std::strstr(vendor, "NVIDIA") && !(std::strstr(vendor, "ATI") && systemAllowsMultisamplingOnATICards())))
-            isValidVendor = false;
-        if (!isValidVendor || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
+        if (!extensions->maySupportMultisampling() || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
             m_attrs.antialias = false;
         else
             extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample");