#if USE(EGL) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
#include "EGLHelper.h"
+
+#include <stdlib.h>
+#include <string.h>
+
#include <wtf/HashMap.h>
namespace WebCore {
#define EGL_FORMAT_RGBA_8888_KHR 0x30C3
#endif
+static bool printDebugMessage = false;
+
+struct SupportedEGLConfig {
+ EGLConfig config;
+ GLPlatformSurface::SurfaceAttributes supportedAttributes;
+};
+
class EGLConfigPool {
public:
static inline EGLConfigPool& getInstance()
return eglConfigPool;
}
virtual ~EGLConfigPool();
- EGLConfig pixmapContextConfig(GLPlatformSurface::SurfaceAttributes);
- EGLConfig surfaceContextConfig(GLPlatformSurface::SurfaceAttributes);
+ SupportedEGLConfig* pixmapContextConfig(GLPlatformSurface::SurfaceAttributes);
+ SupportedEGLConfig* surfaceContextConfig(GLPlatformSurface::SurfaceAttributes);
private:
EGLConfigPool(void);
- EGLConfig createConfig(EGLint expectedSurfaceType, GLPlatformSurface::SurfaceAttributes);
- typedef HashMap<GLPlatformSurface::SurfaceAttributes, EGLConfig> PixmapConfigMap;
+ void createConfig(EGLint expectedSurfaceType, GLPlatformSurface::SurfaceAttributes, SupportedEGLConfig*);
+ SupportedEGLConfig* config(EGLint, GLPlatformSurface::SurfaceAttributes);
+ SupportedEGLConfig* retrieveConfig(EGLint, GLPlatformSurface::SurfaceAttributes);
+ typedef HashMap<GLPlatformSurface::SurfaceAttributes, SupportedEGLConfig*> PixmapConfigMap;
PixmapConfigMap m_pixmapConfigs;
- typedef HashMap<GLPlatformSurface::SurfaceAttributes, EGLConfig> WindowConfigMap;
+ typedef HashMap<GLPlatformSurface::SurfaceAttributes, SupportedEGLConfig*> WindowConfigMap;
WindowConfigMap m_windowConfigs;
};
EGLConfigPool::EGLConfigPool()
{
+ const char* debug = getenv("EGL_LOG_LEVEL");
+ if (debug && (strstr(debug, "debug")))
+ printDebugMessage = true;
}
EGLConfigPool::~EGLConfigPool()
{
- m_windowConfigs.clear();
- m_pixmapConfigs.clear();
+ if (!m_windowConfigs.isEmpty()) {
+ deleteAllValues(m_windowConfigs);
+ m_windowConfigs.clear();
+ }
+
+ if (!m_pixmapConfigs.isEmpty()) {
+ deleteAllValues(m_pixmapConfigs);
+ m_pixmapConfigs.clear();
+ }
}
-EGLConfig EGLConfigPool::pixmapContextConfig(GLPlatformSurface::SurfaceAttributes attributes)
+SupportedEGLConfig* EGLConfigPool::pixmapContextConfig(GLPlatformSurface::SurfaceAttributes attributes)
{
- EGLConfig config = 0;
- PixmapConfigMap::iterator it = m_pixmapConfigs.find(attributes);
- if (it != m_pixmapConfigs.end()) {
- config = it->second;
- return config;
- }
+ return config(attributes & GLPlatformSurface::Lockable ? EGL_PIXMAP_BIT | EGL_LOCK_SURFACE_BIT_KHR : EGL_PIXMAP_BIT, attributes);
+}
+
+SupportedEGLConfig* EGLConfigPool::surfaceContextConfig(GLPlatformSurface::SurfaceAttributes attributes)
+{
+ return config(attributes & GLPlatformSurface::Lockable ? EGL_WINDOW_BIT | EGL_LOCK_SURFACE_BIT_KHR : EGL_WINDOW_BIT, attributes);
+}
- config = createConfig(attributes & GLPlatformSurface::Lockable ? EGL_PIXMAP_BIT | EGL_LOCK_SURFACE_BIT_KHR : EGL_PIXMAP_BIT, attributes);
- if (config)
- m_pixmapConfigs.add(attributes, config);
+SupportedEGLConfig* EGLConfigPool::retrieveConfig(EGLint expectedSurfaceType, GLPlatformSurface::SurfaceAttributes attributes)
+{
+ if (expectedSurfaceType & EGL_WINDOW_BIT) {
+ WindowConfigMap::const_iterator end = m_windowConfigs.end();
+ WindowConfigMap::iterator it;
- return config;
+ for (it = m_windowConfigs.begin(); it != end; ++it) {
+ if (it->first == attributes || it->second->supportedAttributes == attributes)
+ return it->second;
+ }
+ } else {
+ PixmapConfigMap::const_iterator end = m_pixmapConfigs.end();
+ PixmapConfigMap::iterator it;
+
+ for (it = m_pixmapConfigs.begin(); it != end; ++it) {
+ if (it->first == attributes || it->second->supportedAttributes == attributes)
+ return it->second;
+ }
+ }
+
+ return 0;
}
-EGLConfig EGLConfigPool::surfaceContextConfig(GLPlatformSurface::SurfaceAttributes attributes)
+SupportedEGLConfig* EGLConfigPool::config(EGLint expectedSurfaceType, GLPlatformSurface::SurfaceAttributes attributes)
{
- EGLConfig config = 0;
- WindowConfigMap::iterator it = m_windowConfigs.find(attributes);
- if (it != m_windowConfigs.end()) {
- config = it->second;
- return config;
+ SupportedEGLConfig* eglConfig = retrieveConfig(expectedSurfaceType, attributes);
+ if (eglConfig)
+ return eglConfig;
+
+ eglConfig = new SupportedEGLConfig();
+ if (!eglConfig) {
+ LOG_ERROR("Failed to allocate memory for EGL config.");
+ return 0;
}
- config = createConfig(attributes & GLPlatformSurface::Lockable ? EGL_WINDOW_BIT | EGL_LOCK_SURFACE_BIT_KHR : EGL_WINDOW_BIT, attributes);
- if (config)
- m_windowConfigs.add(attributes, config);
+ eglConfig->supportedAttributes = attributes;
+ eglConfig->config = 0;
+ createConfig(expectedSurfaceType, eglConfig->supportedAttributes, eglConfig);
+
+ if (!eglConfig->config) {
+ if (eglConfig->supportedAttributes & GLPlatformSurface::SupportAlpha) {
+ if (printDebugMessage)
+ LOG_ERROR("Failed to retrieve EGL Configuration with alpha. Trying to find one without alpha support.");
+ eglConfig->supportedAttributes &= ~GLPlatformSurface::SupportAlpha;
+ } else {
+ if (printDebugMessage)
+ LOG_ERROR("Failed to retrieve EGL Configuration without alpha. Trying to find one with alpha support.");
+ eglConfig->supportedAttributes |= GLPlatformSurface::SupportAlpha;
+ }
- return config;
+ createConfig(expectedSurfaceType, eglConfig->supportedAttributes, eglConfig);
+
+ if (!eglConfig->config) {
+ delete eglConfig;
+ LOG_ERROR("Failed to retrieve valid EGL Configuration.");
+ return 0;
+ }
+ }
+
+ if (expectedSurfaceType & EGL_WINDOW_BIT)
+ m_windowConfigs.add(attributes, eglConfig);
+ else
+ m_pixmapConfigs.add(attributes, eglConfig);
+
+ return eglConfig;
}
-EGLConfig EGLConfigPool::createConfig(EGLint expectedSurfaceType, GLPlatformSurface::SurfaceAttributes attributes)
+void EGLConfigPool::createConfig(EGLint expectedSurfaceType, GLPlatformSurface::SurfaceAttributes attributes, SupportedEGLConfig* supportedConfig)
{
EGLDisplay display = EGLHelper::eglDisplay();
- if (display == EGL_NO_DISPLAY)
- return 0;
+ if (display == EGL_NO_DISPLAY) {
+ supportedConfig->config = 0;
+ return;
+ }
EGLint numConfigs;
eglGetConfigs(display, 0, 0, &numConfigs);
if (!numConfigs) {
- LOG_ERROR("Failed to retrieve number of EGL configs.");
- return 0;
+ LOG_ERROR("Failed to retrieve total number of supported EGL configs.");
+ supportedConfig->config = 0;
+ return;
}
EGLConfig configs[numConfigs];
if (!numConfigs) {
LOG_ERROR("Failed to retrieve any EGL configs.");
- return 0;
+ supportedConfig->config = 0;
+ return;
}
- EGLConfig config = 0;
EGLint alpha, surface, red, green, blue, renderType, stencil, depth, configAttribute, matchFormat, samples;
EGLint expectedAlpha = attributes & GLPlatformSurface::SupportAlpha ? 8 : 0;
EGLint expectedRed = 8;
static bool isVendorMesa = EGLHelper::isVendor("mesa");
static bool isVendorArm = EGLHelper::isVendor("arm");
- if (isVendorMesa) {
+ if (isVendorMesa)
expectedDepthSize = attributes & GLPlatformSurface::SupportDepth ? 24 : 0;
- expectedStencilSize = attributes & GLPlatformSurface::SupportStencil ? 8 : 0;
- }
if (!expectedAlpha && isVendorImagination)
expectedConfigAttribute = EGL_NON_CONFORMANT_CONFIG;
eglGetConfigAttrib(display, tempConfig, EGL_CONFIG_CAVEAT, &configAttribute);
if (expectedConfigAttribute != configAttribute) {
- LOG_ERROR("Expected config attribute didnt match. Checking next EGLConfig.");
+ if (printDebugMessage)
+ LOG_ERROR("Expected config attribute didnt match. Checking next EGLConfig.");
continue;
}
}
eglGetConfigAttrib(display, tempConfig, EGL_MATCH_FORMAT_KHR, &matchFormat);
if (expectedMatchFormat != matchFormat) {
- LOG_ERROR("ExpectedMatchFormat didnt match. Checking next EGLConfig.");
+ if (printDebugMessage)
+ LOG_ERROR("ExpectedMatchFormat didnt match. Checking next EGLConfig.");
continue;
}
}
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);
+ if (printDebugMessage)
+ LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "alpha", alpha, expectedAlpha);
continue;
}
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);
+ if (printDebugMessage)
+ LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "red", red, expectedRed);
continue;
}
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);
+ if (printDebugMessage)
+ LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Green", green, expectedGreen);
continue;
}
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);
+ if (printDebugMessage)
+ LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Blue", blue, expectedBlue);
continue;
}
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);
+ if (printDebugMessage)
+ LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Stencil", stencil, expectedStencilSize);
continue;
}
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);
+ if (printDebugMessage)
+ LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Depth", depth, expectedDepthSize);
continue;
}
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);
+ if (printDebugMessage)
+ LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Samples", samples, expectedSamples);
continue;
}
eglGetConfigAttrib(display, tempConfig, EGL_SURFACE_TYPE, &surface);
if (surface & expectedSurfaceType) {
- config = configs[i];
+ supportedConfig->config = configs[i];
break;
}
}
-
- if ((attributes & GLPlatformSurface::SupportAlpha) && !config) {
- LOG_ERROR("Failed to retrieve EGL Configuration with alpha. Trying to find one without alpha support.");
- attributes &= ~GLPlatformSurface::SupportAlpha;
- config = createConfig(expectedSurfaceType, attributes);
- }
-
- if (!config)
- LOG_ERROR("Failed to find a valid EGL Configuration.");
-
- return config;
}
EGLConfigSelector::EGLConfigSelector(GLPlatformSurface::SurfaceAttributes attributes)
m_attributes |= GLPlatformSurface::SupportStencil;
m_attributes |= GLPlatformSurface::SupportDepth;
}
-
- m_attributes |= GLPlatformSurface::SupportAlpha;
}
}
EGLConfig EGLConfigSelector::pixmapContextConfig()
{
- return EGLConfigPool::getInstance().pixmapContextConfig(m_attributes);
+ SupportedEGLConfig* eglConfig = EGLConfigPool::getInstance().pixmapContextConfig(m_attributes);
+ if (!eglConfig)
+ return 0;
+
+ m_attributes = eglConfig->supportedAttributes;
+ return eglConfig->config;
}
EGLConfig EGLConfigSelector::surfaceContextConfig()
{
- return EGLConfigPool::getInstance().surfaceContextConfig(m_attributes);
+ SupportedEGLConfig* eglConfig = EGLConfigPool::getInstance().surfaceContextConfig(m_attributes);
+ if (!eglConfig)
+ return 0;
+
+ m_attributes = eglConfig->supportedAttributes;
+ return eglConfig->config;
}
EGLint EGLConfigSelector::nativeVisualId(const EGLConfig& config) const
eglGetConfigs(display, 0, 0, &numConfigs);
if (!numConfigs) {
- LOG_ERROR("Failed to retrieve any EGL configs.");
+ LOG_ERROR("Failed to retrieve total number of supported EGL configs.");
return 0;
}