Share EGLConfig between surfaces. 40/5040/4
authorKondapally Kalyan <kalyan.kondapally@intel.com>
Sun, 30 Jun 2013 19:25:04 +0000 (22:25 +0300)
committerKondapally Kalyan <kalyan.kondapally@intel.com>
Sun, 30 Jun 2013 19:25:04 +0000 (22:25 +0300)
We create surfaces with attributes which don't vary much in the
most common cases. It would be good to share EGLConfig between surfaces
using same attributes. This patch refactors EGLConfigSelector to be able to
share configs between different surfaces without having to query for it
all the time.
Change-Id: I10fa6188a1ae4692e47b9be8932eab39e8458373

Source/WebCore/platform/graphics/surfaces/egl/EGLConfigSelector.cpp
Source/WebCore/platform/graphics/surfaces/egl/EGLConfigSelector.h

index 8dcfe7e..4ecba7c 100644 (file)
@@ -29,6 +29,7 @@
 #if USE(EGL) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
 
 #include "EGLHelper.h"
+#include <wtf/HashMap.h>
 
 namespace WebCore {
 
@@ -40,63 +41,75 @@ namespace WebCore {
 #define EGL_FORMAT_RGBA_8888_KHR 0x30C3
 #endif
 
-EGLConfigSelector::EGLConfigSelector(GLPlatformSurface::SurfaceAttributes attributes)
-    : m_pixmapFBConfig(0)
-    , m_surfaceContextFBConfig(0)
-    , m_attributes(attributes)
+class EGLConfigPool {
+public:
+    static inline EGLConfigPool& getInstance()
+    {
+        static EGLConfigPool eglConfigPool;
+        return eglConfigPool;
+    }
+    virtual ~EGLConfigPool();
+    EGLConfig pixmapContextConfig(GLPlatformSurface::SurfaceAttributes);
+    EGLConfig surfaceContextConfig(GLPlatformSurface::SurfaceAttributes);
+private:
+    EGLConfigPool(void);
+    EGLConfig createConfig(EGLint expectedSurfaceType, GLPlatformSurface::SurfaceAttributes);
+    typedef HashMap<GLPlatformSurface::SurfaceAttributes, EGLConfig> PixmapConfigMap;
+    PixmapConfigMap m_pixmapConfigs;
+    typedef HashMap<GLPlatformSurface::SurfaceAttributes, EGLConfig> WindowConfigMap;
+    WindowConfigMap m_windowConfigs;
+};
+
+EGLConfigPool::EGLConfigPool()
 {
-    m_sharedDisplay = EGLHelper::eglDisplay();
 }
 
-EGLConfigSelector::~EGLConfigSelector()
+EGLConfigPool::~EGLConfigPool()
 {
+    m_windowConfigs.clear();
+    m_pixmapConfigs.clear();
 }
 
-EGLConfig EGLConfigSelector::pixmapContextConfig()
+EGLConfig EGLConfigPool::pixmapContextConfig(GLPlatformSurface::SurfaceAttributes attributes)
 {
-    if (!m_pixmapFBConfig)
-        m_pixmapFBConfig = createConfig( m_attributes & GLPlatformSurface::Lockable ? EGL_PIXMAP_BIT | EGL_LOCK_SURFACE_BIT_KHR : EGL_PIXMAP_BIT);
-
-    return m_pixmapFBConfig;
-}
+    EGLConfig config = 0;
+    PixmapConfigMap::iterator it = m_pixmapConfigs.find(attributes);
+    if (it != m_pixmapConfigs.end()) {
+        config = it->second;
+        return config;
+    }
 
-EGLConfig EGLConfigSelector::surfaceContextConfig()
-{
-    if (!m_surfaceContextFBConfig)
-        m_surfaceContextFBConfig = createConfig(EGL_WINDOW_BIT);
+    config = createConfig(attributes & GLPlatformSurface::Lockable ? EGL_PIXMAP_BIT | EGL_LOCK_SURFACE_BIT_KHR : EGL_PIXMAP_BIT, attributes);
+    if (config)
+        m_pixmapConfigs.add(attributes, config);
 
-    return m_surfaceContextFBConfig;
+    return config;
 }
 
-EGLint EGLConfigSelector::nativeVisualId(const EGLConfig& config) const
+EGLConfig EGLConfigPool::surfaceContextConfig(GLPlatformSurface::SurfaceAttributes attributes)
 {
-    if (m_sharedDisplay == EGL_NO_DISPLAY)
-        return -1;
-
-    EGLint eglValue = 0;
-    eglGetConfigAttrib(m_sharedDisplay, config, EGL_NATIVE_VISUAL_ID, &eglValue);
-
-    return eglValue;
-}
+    EGLConfig config = 0;
+    WindowConfigMap::iterator it = m_windowConfigs.find(attributes);
+    if (it != m_windowConfigs.end()) {
+        config = it->second;
+        return config;
+    }
 
-GLPlatformSurface::SurfaceAttributes EGLConfigSelector::attributes() const
-{
-    return m_attributes;
-}
+    config = createConfig(attributes & GLPlatformSurface::Lockable ? EGL_WINDOW_BIT | EGL_LOCK_SURFACE_BIT_KHR : EGL_WINDOW_BIT, attributes);
+    if (config)
+        m_windowConfigs.add(attributes, config);
 
-void EGLConfigSelector::reset()
-{
-    m_surfaceContextFBConfig = 0;
-    m_pixmapFBConfig = 0;
+    return config;
 }
 
-EGLConfig EGLConfigSelector::createConfig(EGLint expectedSurfaceType)
+EGLConfig EGLConfigPool::createConfig(EGLint expectedSurfaceType, GLPlatformSurface::SurfaceAttributes attributes)
 {
-    if (m_sharedDisplay == EGL_NO_DISPLAY)
+    EGLDisplay display = EGLHelper::eglDisplay();
+    if (display == EGL_NO_DISPLAY)
         return 0;
 
     EGLint numConfigs;
-    eglGetConfigs(m_sharedDisplay, 0, 0, &numConfigs);
+    eglGetConfigs(display, 0, 0, &numConfigs);
 
     if (!numConfigs) {
         LOG_ERROR("Failed to retrieve number of EGL configs.");
@@ -104,7 +117,7 @@ EGLConfig EGLConfigSelector::createConfig(EGLint expectedSurfaceType)
     }
 
     EGLConfig configs[numConfigs];
-    eglGetConfigs(m_sharedDisplay, configs, numConfigs, &numConfigs);
+    eglGetConfigs(display, configs, numConfigs, &numConfigs);
 
     if (!numConfigs) {
         LOG_ERROR("Failed to retrieve any EGL configs.");
@@ -113,15 +126,15 @@ EGLConfig EGLConfigSelector::createConfig(EGLint expectedSurfaceType)
 
     EGLConfig config = 0;
     EGLint alpha, surface, red, green, blue, renderType, stencil, depth, configAttribute, matchFormat, samples;
-    EGLint expectedAlpha = m_attributes & GLPlatformSurface::SupportAlpha ? 8 : 0;
+    EGLint expectedAlpha = attributes & GLPlatformSurface::SupportAlpha ? 8 : 0;
     EGLint expectedRed = 8;
     EGLint expectedBlue = 8;
     EGLint expectedGreen = 8;
-    EGLint expectedStencilSize = m_attributes & GLPlatformSurface::SupportStencil ? 8 : 0;
-    EGLint expectedDepthSize = m_attributes & GLPlatformSurface::SupportDepth ? 16 : 0;
+    EGLint expectedStencilSize = attributes & GLPlatformSurface::SupportStencil ? 8 : 0;
+    EGLint expectedDepthSize = attributes & GLPlatformSurface::SupportDepth ? 16 : 0;
     EGLint expectedConfigAttribute = EGL_NONE;
     EGLint expectedMatchFormat = EGL_NONE;
-    EGLint expectedSamples = m_attributes & GLPlatformSurface::SupportSamples ? 4 : 0;
+    EGLint expectedSamples = attributes & GLPlatformSurface::SupportSamples ? 4 : 0;
 #if USE(OPENGL_ES_2)
     EGLint expectedRenderType = EGL_OPENGL_ES2_BIT;
 #else
@@ -132,22 +145,14 @@ EGLConfig EGLConfigSelector::createConfig(EGLint expectedSurfaceType)
     static bool isVendorArm = EGLHelper::isVendor("arm");
 
     if (isVendorMesa) {
-        // Force depth if stencil is true or depth if stencil is true.
-        if ((m_attributes & GLPlatformSurface::SupportStencil) || (m_attributes & GLPlatformSurface::SupportDepth)) {
-            m_attributes &= GLPlatformSurface::SupportStencil;
-            m_attributes &= GLPlatformSurface::SupportDepth;
-        }
-
-        expectedDepthSize = m_attributes & GLPlatformSurface::SupportDepth ? 24 : 0;
-        expectedStencilSize = m_attributes & GLPlatformSurface::SupportStencil ? 8 : 0;
-        // Doesn't support EGLConfig with no alpha.
-        expectedAlpha = 8;
+        expectedDepthSize = attributes & GLPlatformSurface::SupportDepth ? 24 : 0;
+        expectedStencilSize = attributes & GLPlatformSurface::SupportStencil ? 8 : 0;
     }
 
     if (!expectedAlpha && isVendorImagination)
         expectedConfigAttribute = EGL_NON_CONFORMANT_CONFIG;
 
-    if (m_attributes & GLPlatformSurface::Lockable) {
+    if (attributes & GLPlatformSurface::Lockable) {
         if (isVendorImagination || isVendorArm)
             matchFormat = EGL_FORMAT_RGBA_8888_EXACT_KHR;
         else
@@ -156,12 +161,12 @@ EGLConfig EGLConfigSelector::createConfig(EGLint expectedSurfaceType)
 
     for (int i = 0; i < numConfigs; i++) {
         EGLConfig tempConfig = configs[i];
-        eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_RENDERABLE_TYPE, &renderType);
+        eglGetConfigAttrib(display, tempConfig, EGL_RENDERABLE_TYPE, &renderType);
         if (!(renderType & expectedRenderType))
             continue;
 
         if (expectedConfigAttribute != EGL_NONE) {
-            eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_CONFIG_CAVEAT, &configAttribute);
+            eglGetConfigAttrib(display, tempConfig, EGL_CONFIG_CAVEAT, &configAttribute);
 
             if (expectedConfigAttribute != configAttribute) {
                 LOG_ERROR("Expected config attribute didnt match. Checking next EGLConfig.");
@@ -170,7 +175,7 @@ EGLConfig EGLConfigSelector::createConfig(EGLint expectedSurfaceType)
         }
 
         if (expectedMatchFormat != EGL_NONE) {
-            eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_MATCH_FORMAT_KHR, &matchFormat);
+            eglGetConfigAttrib(display, tempConfig, EGL_MATCH_FORMAT_KHR, &matchFormat);
 
             if (expectedMatchFormat != matchFormat) {
                 LOG_ERROR("ExpectedMatchFormat didnt match. Checking next EGLConfig.");
@@ -178,56 +183,56 @@ EGLConfig EGLConfigSelector::createConfig(EGLint expectedSurfaceType)
             }
         }
 
-        eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_ALPHA_SIZE, &alpha);
+        eglGetConfigAttrib(display, tempConfig, EGL_ALPHA_SIZE, &alpha);
 
         if (alpha != expectedAlpha) {
             LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "alpha", alpha, expectedAlpha);
             continue;
         }
 
-        eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_RED_SIZE, &red);
+        eglGetConfigAttrib(display, tempConfig, EGL_RED_SIZE, &red);
 
         if (red != expectedRed) {
             LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "red", red, expectedRed);
             continue;
         }
 
-        eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_GREEN_SIZE, &green);
+        eglGetConfigAttrib(display, tempConfig, EGL_GREEN_SIZE, &green);
 
         if (green != expectedGreen) {
             LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Green", green, expectedGreen);
             continue;
         }
 
-        eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_BLUE_SIZE, &blue);
+        eglGetConfigAttrib(display, tempConfig, EGL_BLUE_SIZE, &blue);
 
         if (blue != expectedBlue) {
             LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Blue", blue, expectedBlue);
             continue;
         }
 
-        eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_STENCIL_SIZE, &stencil);
+        eglGetConfigAttrib(display, tempConfig, EGL_STENCIL_SIZE, &stencil);
 
         if (stencil != expectedStencilSize) {
             LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Stencil", stencil, expectedStencilSize);
             continue;
         }
 
-        eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_DEPTH_SIZE, &depth);
+        eglGetConfigAttrib(display, tempConfig, EGL_DEPTH_SIZE, &depth);
 
         if (depth != expectedDepthSize) {
             LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Depth", depth, expectedDepthSize);
             continue;
         }
 
-        eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_SAMPLES, &samples);
+        eglGetConfigAttrib(display, tempConfig, EGL_SAMPLES, &samples);
 
         if (samples != expectedSamples) {
             LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Samples", samples, expectedSamples);
             continue;
         }
 
-        eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_SURFACE_TYPE, &surface);
+        eglGetConfigAttrib(display, tempConfig, EGL_SURFACE_TYPE, &surface);
 
         if (surface & expectedSurfaceType) {
             config = configs[i];
@@ -235,10 +240,10 @@ EGLConfig EGLConfigSelector::createConfig(EGLint expectedSurfaceType)
         }
     }
 
-    if ((m_attributes & GLPlatformSurface::SupportAlpha) && !config) {
+    if ((attributes & GLPlatformSurface::SupportAlpha) && !config) {
         LOG_ERROR("Failed to retrieve EGL Configuration with alpha. Trying to find one without alpha support.");
-        m_attributes &= ~GLPlatformSurface::SupportAlpha;
-        config = createConfig(expectedSurfaceType);
+        attributes &= ~GLPlatformSurface::SupportAlpha;
+        config = createConfig(expectedSurfaceType, attributes);
     }
 
     if (!config)
@@ -247,20 +252,70 @@ EGLConfig EGLConfigSelector::createConfig(EGLint expectedSurfaceType)
     return config;
 }
 
+EGLConfigSelector::EGLConfigSelector(GLPlatformSurface::SurfaceAttributes attributes)
+    : m_attributes(attributes)
+{
+    static bool isVendorMesa = EGLHelper::isVendor("mesa");
+    if (isVendorMesa) {
+        if ((m_attributes & GLPlatformSurface::SupportStencil) || (m_attributes & GLPlatformSurface::SupportDepth)) {
+            m_attributes |= GLPlatformSurface::SupportStencil;
+            m_attributes |= GLPlatformSurface::SupportDepth;
+        }
+
+        m_attributes |= GLPlatformSurface::SupportAlpha;
+    }
+}
+
+EGLConfigSelector::~EGLConfigSelector()
+{
+}
+
+EGLConfig EGLConfigSelector::pixmapContextConfig()
+{
+    return EGLConfigPool::getInstance().pixmapContextConfig(m_attributes);
+}
+
+EGLConfig EGLConfigSelector::surfaceContextConfig()
+{
+    return EGLConfigPool::getInstance().surfaceContextConfig(m_attributes);
+}
+
+EGLint EGLConfigSelector::nativeVisualId(const EGLConfig& config) const
+{
+    EGLDisplay display = EGLHelper::eglDisplay();
+    if (display == EGL_NO_DISPLAY)
+        return -1;
+
+    EGLint eglValue = 0;
+    eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &eglValue);
+
+    return eglValue;
+}
+
+GLPlatformSurface::SurfaceAttributes EGLConfigSelector::attributes() const
+{
+    return m_attributes;
+}
+
+void EGLConfigSelector::reset()
+{
+}
+
 #if PLATFORM(X11)
 EGLConfig EGLConfigSelector::surfaceClientConfig(NativeVisualId id)
 {
     EGLConfig config = findMatchingConfigWithVisualId(id);
 
     if (!config)
-        config = createConfig(EGL_PIXMAP_BIT);
+        config = pixmapContextConfig();
 
     return config;
 }
 
 EGLConfig EGLConfigSelector::findMatchingConfigWithVisualId(NativeVisualId id)
 {
-    if (m_sharedDisplay == EGL_NO_DISPLAY)
+    EGLDisplay display = EGLHelper::eglDisplay();
+    if (display == EGL_NO_DISPLAY)
         return 0;
 
     EGLint numConfigs;
@@ -268,7 +323,7 @@ EGLConfig EGLConfigSelector::findMatchingConfigWithVisualId(NativeVisualId id)
     EGLint visualId;
     EGLConfig config = 0;
 
-    eglGetConfigs(m_sharedDisplay, 0, 0, &numConfigs);
+    eglGetConfigs(display, 0, 0, &numConfigs);
 
     if (!numConfigs) {
         LOG_ERROR("Failed to retrieve any EGL configs.");
@@ -276,7 +331,7 @@ EGLConfig EGLConfigSelector::findMatchingConfigWithVisualId(NativeVisualId id)
     }
 
     EGLConfig configs[numConfigs];
-    eglGetConfigs(m_sharedDisplay, configs, numConfigs, &numConfigs);
+    eglGetConfigs(display, configs, numConfigs, &numConfigs);
 
     if (!numConfigs) {
         LOG_ERROR("Failed to retrieve any EGL configs.");
@@ -287,17 +342,17 @@ EGLConfig EGLConfigSelector::findMatchingConfigWithVisualId(NativeVisualId id)
     for (i = 0; i < numConfigs; i++) {
         EGLint alpha, surfaces;
         EGLConfig tempConfig = configs[i];
-        eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_NATIVE_VISUAL_ID, &visualId);
+        eglGetConfigAttrib(display, tempConfig, EGL_NATIVE_VISUAL_ID, &visualId);
 
         if (static_cast<NativeVisualId>(visualId) != id)
             continue;
 
-        eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_ALPHA_SIZE, &alpha);
+        eglGetConfigAttrib(display, tempConfig, EGL_ALPHA_SIZE, &alpha);
 
         if (alphaChannelRequired != alpha)
             continue;
 
-        eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_SURFACE_TYPE, &surfaces);
+        eglGetConfigAttrib(display, tempConfig, EGL_SURFACE_TYPE, &surfaces);
 
         if (surfaces & EGL_PIXMAP_BIT) {
             config = tempConfig;
index b8f665d..392f813 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef EGLConfigSelector_h
 #define EGLConfigSelector_h
 
-#if USE(EGL)
+#if USE(EGL) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
 
 #include "EGLSurface.h"
 #include <wtf/Noncopyable.h>
@@ -54,13 +54,9 @@ private:
 #if PLATFORM(X11)
     EGLConfig findMatchingConfigWithVisualId(NativeVisualId);
 #endif
-    EGLConfig createConfig(EGLint expectedSurfaceType);
 
 protected:
-    EGLConfig m_pixmapFBConfig;
-    EGLConfig m_surfaceContextFBConfig;
-    unsigned m_attributes : 3;
-    PlatformDisplay m_sharedDisplay;
+    GLPlatformSurface::SurfaceAttributes m_attributes;
 };
 
 }