2 * Copyright (C) 2012 Intel Corporation. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
27 #include "EGLConfigSelector.h"
29 #if USE(EGL) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
31 #include "EGLHelper.h"
32 #include <wtf/HashMap.h>
36 #if !defined(EGL_FORMAT_RGBA_8888_EXACT_KHR)
37 #define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2
40 #if !defined(EGL_FORMAT_RGBA_8888_KHR)
41 #define EGL_FORMAT_RGBA_8888_KHR 0x30C3
46 static inline EGLConfigPool& getInstance()
48 static EGLConfigPool eglConfigPool;
51 virtual ~EGLConfigPool();
52 EGLConfig pixmapContextConfig(GLPlatformSurface::SurfaceAttributes);
53 EGLConfig surfaceContextConfig(GLPlatformSurface::SurfaceAttributes);
56 EGLConfig createConfig(EGLint expectedSurfaceType, GLPlatformSurface::SurfaceAttributes);
57 typedef HashMap<GLPlatformSurface::SurfaceAttributes, EGLConfig> PixmapConfigMap;
58 PixmapConfigMap m_pixmapConfigs;
59 typedef HashMap<GLPlatformSurface::SurfaceAttributes, EGLConfig> WindowConfigMap;
60 WindowConfigMap m_windowConfigs;
63 EGLConfigPool::EGLConfigPool()
67 EGLConfigPool::~EGLConfigPool()
69 m_windowConfigs.clear();
70 m_pixmapConfigs.clear();
73 EGLConfig EGLConfigPool::pixmapContextConfig(GLPlatformSurface::SurfaceAttributes attributes)
76 PixmapConfigMap::iterator it = m_pixmapConfigs.find(attributes);
77 if (it != m_pixmapConfigs.end()) {
82 config = createConfig(attributes & GLPlatformSurface::Lockable ? EGL_PIXMAP_BIT | EGL_LOCK_SURFACE_BIT_KHR : EGL_PIXMAP_BIT, attributes);
84 m_pixmapConfigs.add(attributes, config);
89 EGLConfig EGLConfigPool::surfaceContextConfig(GLPlatformSurface::SurfaceAttributes attributes)
92 WindowConfigMap::iterator it = m_windowConfigs.find(attributes);
93 if (it != m_windowConfigs.end()) {
98 config = createConfig(attributes & GLPlatformSurface::Lockable ? EGL_WINDOW_BIT | EGL_LOCK_SURFACE_BIT_KHR : EGL_WINDOW_BIT, attributes);
100 m_windowConfigs.add(attributes, config);
105 EGLConfig EGLConfigPool::createConfig(EGLint expectedSurfaceType, GLPlatformSurface::SurfaceAttributes attributes)
107 EGLDisplay display = EGLHelper::eglDisplay();
108 if (display == EGL_NO_DISPLAY)
112 eglGetConfigs(display, 0, 0, &numConfigs);
115 LOG_ERROR("Failed to retrieve number of EGL configs.");
119 EGLConfig configs[numConfigs];
120 eglGetConfigs(display, configs, numConfigs, &numConfigs);
123 LOG_ERROR("Failed to retrieve any EGL configs.");
127 EGLConfig config = 0;
128 EGLint alpha, surface, red, green, blue, renderType, stencil, depth, configAttribute, matchFormat, samples;
129 EGLint expectedAlpha = attributes & GLPlatformSurface::SupportAlpha ? 8 : 0;
130 EGLint expectedRed = 8;
131 EGLint expectedBlue = 8;
132 EGLint expectedGreen = 8;
133 EGLint expectedStencilSize = attributes & GLPlatformSurface::SupportStencil ? 8 : 0;
134 EGLint expectedDepthSize = attributes & GLPlatformSurface::SupportDepth ? 16 : 0;
135 EGLint expectedConfigAttribute = EGL_NONE;
136 EGLint expectedMatchFormat = EGL_NONE;
137 EGLint expectedSamples = attributes & GLPlatformSurface::SupportSamples ? 4 : 0;
139 EGLint expectedRenderType = EGL_OPENGL_ES2_BIT;
141 EGLint expectedRenderType = EGL_OPENGL_BIT;
143 static bool isVendorImagination = EGLHelper::isVendor("imagination");
144 static bool isVendorMesa = EGLHelper::isVendor("mesa");
145 static bool isVendorArm = EGLHelper::isVendor("arm");
148 expectedDepthSize = attributes & GLPlatformSurface::SupportDepth ? 24 : 0;
149 expectedStencilSize = attributes & GLPlatformSurface::SupportStencil ? 8 : 0;
152 if (!expectedAlpha && isVendorImagination)
153 expectedConfigAttribute = EGL_NON_CONFORMANT_CONFIG;
155 if (attributes & GLPlatformSurface::Lockable) {
156 if (isVendorImagination || isVendorArm)
157 matchFormat = EGL_FORMAT_RGBA_8888_EXACT_KHR;
159 matchFormat = EGL_FORMAT_RGBA_8888_KHR;
162 for (int i = 0; i < numConfigs; i++) {
163 EGLConfig tempConfig = configs[i];
164 eglGetConfigAttrib(display, tempConfig, EGL_RENDERABLE_TYPE, &renderType);
165 if (!(renderType & expectedRenderType))
168 if (expectedConfigAttribute != EGL_NONE) {
169 eglGetConfigAttrib(display, tempConfig, EGL_CONFIG_CAVEAT, &configAttribute);
171 if (expectedConfigAttribute != configAttribute) {
172 LOG_ERROR("Expected config attribute didnt match. Checking next EGLConfig.");
177 if (expectedMatchFormat != EGL_NONE) {
178 eglGetConfigAttrib(display, tempConfig, EGL_MATCH_FORMAT_KHR, &matchFormat);
180 if (expectedMatchFormat != matchFormat) {
181 LOG_ERROR("ExpectedMatchFormat didnt match. Checking next EGLConfig.");
186 eglGetConfigAttrib(display, tempConfig, EGL_ALPHA_SIZE, &alpha);
188 if (alpha != expectedAlpha) {
189 LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "alpha", alpha, expectedAlpha);
193 eglGetConfigAttrib(display, tempConfig, EGL_RED_SIZE, &red);
195 if (red != expectedRed) {
196 LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "red", red, expectedRed);
200 eglGetConfigAttrib(display, tempConfig, EGL_GREEN_SIZE, &green);
202 if (green != expectedGreen) {
203 LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Green", green, expectedGreen);
207 eglGetConfigAttrib(display, tempConfig, EGL_BLUE_SIZE, &blue);
209 if (blue != expectedBlue) {
210 LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Blue", blue, expectedBlue);
214 eglGetConfigAttrib(display, tempConfig, EGL_STENCIL_SIZE, &stencil);
216 if (stencil != expectedStencilSize) {
217 LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Stencil", stencil, expectedStencilSize);
221 eglGetConfigAttrib(display, tempConfig, EGL_DEPTH_SIZE, &depth);
223 if (depth != expectedDepthSize) {
224 LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Depth", depth, expectedDepthSize);
228 eglGetConfigAttrib(display, tempConfig, EGL_SAMPLES, &samples);
230 if (samples != expectedSamples) {
231 LOG_ERROR("Failed to match %s Attribute Value. Retrieved %d, Expected: %d. Checking next EGLConfig.", "Samples", samples, expectedSamples);
235 eglGetConfigAttrib(display, tempConfig, EGL_SURFACE_TYPE, &surface);
237 if (surface & expectedSurfaceType) {
243 if ((attributes & GLPlatformSurface::SupportAlpha) && !config) {
244 LOG_ERROR("Failed to retrieve EGL Configuration with alpha. Trying to find one without alpha support.");
245 attributes &= ~GLPlatformSurface::SupportAlpha;
246 config = createConfig(expectedSurfaceType, attributes);
250 LOG_ERROR("Failed to find a valid EGL Configuration.");
255 EGLConfigSelector::EGLConfigSelector(GLPlatformSurface::SurfaceAttributes attributes)
256 : m_attributes(attributes)
258 static bool isVendorMesa = EGLHelper::isVendor("mesa");
260 if ((m_attributes & GLPlatformSurface::SupportStencil) || (m_attributes & GLPlatformSurface::SupportDepth)) {
261 m_attributes |= GLPlatformSurface::SupportStencil;
262 m_attributes |= GLPlatformSurface::SupportDepth;
265 m_attributes |= GLPlatformSurface::SupportAlpha;
269 EGLConfigSelector::~EGLConfigSelector()
273 EGLConfig EGLConfigSelector::pixmapContextConfig()
275 return EGLConfigPool::getInstance().pixmapContextConfig(m_attributes);
278 EGLConfig EGLConfigSelector::surfaceContextConfig()
280 return EGLConfigPool::getInstance().surfaceContextConfig(m_attributes);
283 EGLint EGLConfigSelector::nativeVisualId(const EGLConfig& config) const
285 EGLDisplay display = EGLHelper::eglDisplay();
286 if (display == EGL_NO_DISPLAY)
290 eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &eglValue);
295 GLPlatformSurface::SurfaceAttributes EGLConfigSelector::attributes() const
300 void EGLConfigSelector::reset()
305 EGLConfig EGLConfigSelector::surfaceClientConfig(NativeVisualId id)
307 EGLConfig config = findMatchingConfigWithVisualId(id);
310 config = pixmapContextConfig();
315 EGLConfig EGLConfigSelector::findMatchingConfigWithVisualId(NativeVisualId id)
317 EGLDisplay display = EGLHelper::eglDisplay();
318 if (display == EGL_NO_DISPLAY)
324 EGLConfig config = 0;
326 eglGetConfigs(display, 0, 0, &numConfigs);
329 LOG_ERROR("Failed to retrieve any EGL configs.");
333 EGLConfig configs[numConfigs];
334 eglGetConfigs(display, configs, numConfigs, &numConfigs);
337 LOG_ERROR("Failed to retrieve any EGL configs.");
341 int alphaChannelRequired = m_attributes & GLPlatformSurface::SupportAlpha ? 8 : 0;
342 for (i = 0; i < numConfigs; i++) {
343 EGLint alpha, surfaces;
344 EGLConfig tempConfig = configs[i];
345 eglGetConfigAttrib(display, tempConfig, EGL_NATIVE_VISUAL_ID, &visualId);
347 if (static_cast<NativeVisualId>(visualId) != id)
350 eglGetConfigAttrib(display, tempConfig, EGL_ALPHA_SIZE, &alpha);
352 if (alphaChannelRequired != alpha)
355 eglGetConfigAttrib(display, tempConfig, EGL_SURFACE_TYPE, &surfaces);
357 if (surfaces & EGL_PIXMAP_BIT) {