EGLConfigSelector.cpp [plain text]
#include "config.h"
#include "EGLConfigSelector.h"
#if USE(EGL)
#include "EGLHelper.h"
namespace WebCore {
EGLConfigSelector::EGLConfigSelector(GLPlatformSurface::SurfaceAttributes attributes)
: m_pixmapFBConfig(0)
, m_surfaceContextFBConfig(0)
, m_attributes(attributes)
{
m_sharedDisplay = EGLHelper::eglDisplay();
}
EGLConfigSelector::~EGLConfigSelector()
{
}
EGLConfig EGLConfigSelector::pixmapContextConfig()
{
if (!m_pixmapFBConfig)
m_pixmapFBConfig = createConfig(EGL_PIXMAP_BIT);
return m_pixmapFBConfig;
}
EGLConfig EGLConfigSelector::surfaceContextConfig()
{
if (!m_surfaceContextFBConfig)
m_surfaceContextFBConfig = createConfig(EGL_WINDOW_BIT);
return m_surfaceContextFBConfig;
}
EGLint EGLConfigSelector::nativeVisualId(const EGLConfig& config) const
{
if (m_sharedDisplay == EGL_NO_DISPLAY)
return -1;
EGLint eglValue = 0;
eglGetConfigAttrib(m_sharedDisplay, config, EGL_NATIVE_VISUAL_ID, &eglValue);
return eglValue;
}
GLPlatformSurface::SurfaceAttributes EGLConfigSelector::attributes() const
{
return m_attributes;
}
void EGLConfigSelector::reset()
{
m_surfaceContextFBConfig = 0;
m_pixmapFBConfig = 0;
}
EGLConfig EGLConfigSelector::createConfig(EGLint expectedSurfaceType)
{
if (m_sharedDisplay == EGL_NO_DISPLAY)
return 0;
EGLint numConfigs;
eglGetConfigs(m_sharedDisplay, 0, 0, &numConfigs);
if (!numConfigs) {
LOG_ERROR("Failed to retrieve number of EGL configs.");
return 0;
}
EGLConfig configs[numConfigs];
eglGetConfigs(m_sharedDisplay, configs, numConfigs, &numConfigs);
if (!numConfigs) {
LOG_ERROR("Failed to retrieve any EGL configs.");
return 0;
}
EGLConfig config = 0;
EGLint alpha, surface, red, green, blue, renderType;
EGLint expectedAlpha = m_attributes & GLPlatformSurface::SupportAlpha ? 8 : 0;
EGLint expectedRed = 8;
EGLint expectedBlue = 8;
EGLint expectedGreen = 8;
#if USE(OPENGL_ES_2)
EGLint expectedRenderType = EGL_OPENGL_ES2_BIT;
#else
EGLint expectedRenderType = EGL_OPENGL_BIT;
#endif
for (int i = 0; i < numConfigs; i++) {
EGLConfig tempConfig = configs[i];
eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_RENDERABLE_TYPE, &renderType);
if (!(renderType & expectedRenderType))
continue;
eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_ALPHA_SIZE, &alpha);
if (alpha != expectedAlpha)
continue;
eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_RED_SIZE, &red);
if (red != expectedRed)
continue;
eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_GREEN_SIZE, &green);
if (green != expectedGreen)
continue;
eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_BLUE_SIZE, &blue);
if (blue != expectedBlue)
continue;
eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_SURFACE_TYPE, &surface);
if (surface & expectedSurfaceType) {
config = configs[i];
break;
}
}
if ((m_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);
}
if (!config)
LOG_ERROR("Failed to find a valid EGL Configuration.");
return config;
}
#if PLATFORM(X11)
EGLConfig EGLConfigSelector::surfaceClientConfig(NativeVisualId id)
{
EGLConfig config = findMatchingConfigWithVisualId(id);
if (!config)
config = createConfig(EGL_PIXMAP_BIT);
return config;
}
EGLConfig EGLConfigSelector::findMatchingConfigWithVisualId(NativeVisualId id)
{
if (m_sharedDisplay == EGL_NO_DISPLAY)
return 0;
EGLint numConfigs;
EGLint i;
EGLint visualId;
EGLConfig config = 0;
eglGetConfigs(m_sharedDisplay, 0, 0, &numConfigs);
if (!numConfigs) {
LOG_ERROR("Failed to retrieve any EGL configs.");
return 0;
}
EGLConfig configs[numConfigs];
eglGetConfigs(m_sharedDisplay, configs, numConfigs, &numConfigs);
if (!numConfigs) {
LOG_ERROR("Failed to retrieve any EGL configs.");
return 0;
}
int alphaChannelRequired = m_attributes & GLPlatformSurface::SupportAlpha ? 8 : 0;
for (i = 0; i < numConfigs; i++) {
EGLint alpha, surfaces;
EGLConfig tempConfig = configs[i];
eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_NATIVE_VISUAL_ID, &visualId);
if (static_cast<NativeVisualId>(visualId) != id)
continue;
eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_ALPHA_SIZE, &alpha);
if (alphaChannelRequired != alpha)
continue;
eglGetConfigAttrib(m_sharedDisplay, tempConfig, EGL_SURFACE_TYPE, &surfaces);
if (surfaces & EGL_PIXMAP_BIT) {
config = tempConfig;
break;
}
}
return config;
}
#endif
}
#endif