1/* 2 * Copyright (C) 2012 Intel Corporation. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 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. 12 * 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. 24 */ 25 26#ifndef GLXConfigSelector_h 27#define GLXConfigSelector_h 28 29#if USE(GLX) 30 31#include "X11Helper.h" 32#include <opengl/GLDefs.h> 33#include <opengl/GLPlatformSurface.h> 34 35namespace WebCore { 36 37static int clientAttributes[] = { 38 // The specification is a set key value pairs stored in a simple array. 39 GLX_LEVEL, 0, 40 static_cast<int>(GLX_VISUAL_ID), 0, 41 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, 42 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, 43 GLX_BIND_TO_TEXTURE_RGBA_EXT, TRUE, 44 0 45}; 46 47static int glxSurfaceAttributes[] = { 48 GLX_LEVEL, 0, 49 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, 50 GLX_RENDER_TYPE, 0, 51 GLX_RED_SIZE, 1, 52 GLX_GREEN_SIZE, 1, 53 GLX_BLUE_SIZE, 1, 54 GLX_ALPHA_SIZE, 0, 55 GLX_DOUBLEBUFFER, GL_FALSE, 56 None 57}; 58 59class GLXConfigSelector { 60 WTF_MAKE_NONCOPYABLE(GLXConfigSelector); 61 62public: 63 GLXConfigSelector(GLPlatformSurface::SurfaceAttributes attr = GLPlatformSurface::Default) 64 : m_surfaceContextFBConfig(0) 65 , m_pixmapContextFBConfig(0) 66 , m_attributes(attr) 67 { 68 } 69 70 virtual ~GLXConfigSelector() 71 { 72 } 73 74 XVisualInfo* visualInfo(const GLXFBConfig& config) 75 { 76 return glXGetVisualFromFBConfig(X11Helper::nativeDisplay(), config); 77 } 78 79 GLXFBConfig pixmapContextConfig() 80 { 81 if (!m_pixmapContextFBConfig) { 82 validateAttributes(); 83 m_pixmapContextFBConfig = findMatchingConfig(glxSurfaceAttributes, m_attributes & GLPlatformSurface::SupportAlpha ? 32 : 24); 84 } 85 86 return m_pixmapContextFBConfig; 87 } 88 89 90 GLXFBConfig surfaceContextConfig() 91 { 92 if (!m_surfaceContextFBConfig) { 93 glxSurfaceAttributes[3] = GLX_WINDOW_BIT; 94 glxSurfaceAttributes[7] = 8; 95 glxSurfaceAttributes[9] = 8; 96 glxSurfaceAttributes[11] = 8; 97 validateAttributes(); 98 m_surfaceContextFBConfig = findMatchingConfig(glxSurfaceAttributes, m_attributes & GLPlatformSurface::SupportAlpha ? 32 : 24); 99 } 100 101 return m_surfaceContextFBConfig; 102 } 103 104 GLXFBConfig surfaceClientConfig(int depth, VisualID id) 105 { 106 clientAttributes[3] = static_cast<int>(id); 107 clientAttributes[8] = depth == 32 ? GLX_BIND_TO_TEXTURE_RGBA_EXT : GLX_BIND_TO_TEXTURE_RGB_EXT; 108 // Prefer to match with Visual Id. 109 GLXFBConfig config = findMatchingConfigWithVisualId(clientAttributes, depth, id); 110 111 if (!config) 112 config = findMatchingConfig(clientAttributes, depth); 113 114 return config; 115 } 116 117 void reset() 118 { 119 m_surfaceContextFBConfig = 0; 120 m_pixmapContextFBConfig = 0; 121 } 122 123 GLPlatformSurface::SurfaceAttributes attributes() const 124 { 125 return m_attributes; 126 } 127 128private: 129 void validateAttributes() 130 { 131 if (m_attributes & GLPlatformSurface::SupportAlpha) { 132 glxSurfaceAttributes[13] = 8; 133 glxSurfaceAttributes[5] = GLX_RGBA_BIT; 134 } 135 136 if (m_attributes & GLPlatformSurface::DoubleBuffered) 137 glxSurfaceAttributes[15] = GL_TRUE; 138 } 139 140 GLXFBConfig findMatchingConfig(const int attributes[], int depth = 32) 141 { 142 int numAvailableConfigs; 143 OwnPtrX11<GLXFBConfig> temp(glXChooseFBConfig(X11Helper::nativeDisplay(), DefaultScreen(X11Helper::nativeDisplay()), attributes, &numAvailableConfigs)); 144 145 if (!numAvailableConfigs || !temp.get()) 146 return 0; 147 148 OwnPtrX11<XVisualInfo> scopedVisualInfo; 149 for (int i = 0; i < numAvailableConfigs; ++i) { 150 scopedVisualInfo = glXGetVisualFromFBConfig(X11Helper::nativeDisplay(), temp[i]); 151 if (!scopedVisualInfo.get()) 152 continue; 153 154#if USE(GRAPHICS_SURFACE) && USE(GLX) 155 if (X11Helper::isXRenderExtensionSupported()) { 156 XRenderPictFormat* format = XRenderFindVisualFormat(X11Helper::nativeDisplay(), scopedVisualInfo->visual); 157 158 if (format) { 159 if (m_attributes & GLPlatformSurface::SupportAlpha) { 160 if (scopedVisualInfo->depth == depth && format->direct.alphaMask > 0) 161 return temp[i]; 162 } else if (!format->direct.alphaMask) 163 return temp[i]; 164 } 165 } 166#endif 167 if (scopedVisualInfo->depth == depth) 168 return temp[i]; 169 } 170 171 // Did not find any visual supporting alpha, select the first available config. 172 scopedVisualInfo = glXGetVisualFromFBConfig(X11Helper::nativeDisplay(), temp[0]); 173 174 if ((m_attributes & GLPlatformSurface::SupportAlpha) && (scopedVisualInfo->depth != 32)) 175 m_attributes &= ~GLPlatformSurface::SupportAlpha; 176 177 return temp[0]; 178 } 179 180 GLXFBConfig findMatchingConfigWithVisualId(const int attributes[], int depth, VisualID id) 181 { 182 int numAvailableConfigs; 183 OwnPtrX11<GLXFBConfig> temp(glXChooseFBConfig(X11Helper::nativeDisplay(), DefaultScreen(X11Helper::nativeDisplay()), attributes, &numAvailableConfigs)); 184 185 if (!numAvailableConfigs || !temp.get()) 186 return 0; 187 188 OwnPtrX11<XVisualInfo> scopedVisualInfo; 189 for (int i = 0; i < numAvailableConfigs; ++i) { 190 scopedVisualInfo = glXGetVisualFromFBConfig(X11Helper::nativeDisplay(), temp[i]); 191 if (!scopedVisualInfo.get()) 192 continue; 193 194 if (id && scopedVisualInfo->depth == depth && scopedVisualInfo->visualid == id) 195 return temp[i]; 196 } 197 198 return 0; 199 } 200 201 GLXFBConfig m_surfaceContextFBConfig; 202 GLXFBConfig m_pixmapContextFBConfig; 203 GLPlatformSurface::SurfaceAttributes m_attributes : 3; 204}; 205 206} 207 208#endif 209 210#endif 211 212