diff options
Diffstat (limited to 'Source/WebCore/platform/graphics/surfaces/egl/EGLConfigSelector.cpp')
-rw-r--r-- | Source/WebCore/platform/graphics/surfaces/egl/EGLConfigSelector.cpp | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/Source/WebCore/platform/graphics/surfaces/egl/EGLConfigSelector.cpp b/Source/WebCore/platform/graphics/surfaces/egl/EGLConfigSelector.cpp new file mode 100644 index 000000000..8d6033014 --- /dev/null +++ b/Source/WebCore/platform/graphics/surfaces/egl/EGLConfigSelector.cpp @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#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 |