GLXConfigSelector.h [plain text]
#ifndef GLXConfigSelector_h
#define GLXConfigSelector_h
#if USE(GLX)
#include "X11Helper.h"
#include "XUniquePtr.h"
#include <opengl/GLDefs.h>
#include <opengl/GLPlatformSurface.h>
namespace WebCore {
static int clientAttributes[] = {
GLX_LEVEL, 0,
static_cast<int>(GLX_VISUAL_ID), 0,
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
GLX_BIND_TO_TEXTURE_RGBA_EXT, TRUE,
0
};
static int glxSurfaceAttributes[] = {
GLX_LEVEL, 0,
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
GLX_RENDER_TYPE, 0,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 0,
GLX_DOUBLEBUFFER, GL_FALSE,
None
};
class GLXConfigSelector {
WTF_MAKE_NONCOPYABLE(GLXConfigSelector);
public:
GLXConfigSelector(GLPlatformSurface::SurfaceAttributes attr = GLPlatformSurface::Default)
: m_surfaceContextFBConfig(0)
, m_pixmapContextFBConfig(0)
, m_attributes(attr)
{
}
virtual ~GLXConfigSelector()
{
}
XVisualInfo* visualInfo(const GLXFBConfig& config)
{
return glXGetVisualFromFBConfig(X11Helper::nativeDisplay(), config);
}
GLXFBConfig pixmapContextConfig()
{
if (!m_pixmapContextFBConfig) {
validateAttributes();
m_pixmapContextFBConfig = findMatchingConfig(glxSurfaceAttributes, m_attributes & GLPlatformSurface::SupportAlpha ? 32 : 24);
}
return m_pixmapContextFBConfig;
}
GLXFBConfig surfaceContextConfig()
{
if (!m_surfaceContextFBConfig) {
glxSurfaceAttributes[3] = GLX_WINDOW_BIT;
glxSurfaceAttributes[7] = 8;
glxSurfaceAttributes[9] = 8;
glxSurfaceAttributes[11] = 8;
validateAttributes();
m_surfaceContextFBConfig = findMatchingConfig(glxSurfaceAttributes, m_attributes & GLPlatformSurface::SupportAlpha ? 32 : 24);
}
return m_surfaceContextFBConfig;
}
GLXFBConfig surfaceClientConfig(int depth, VisualID id)
{
clientAttributes[3] = static_cast<int>(id);
clientAttributes[8] = depth == 32 ? GLX_BIND_TO_TEXTURE_RGBA_EXT : GLX_BIND_TO_TEXTURE_RGB_EXT;
GLXFBConfig config = findMatchingConfigWithVisualId(clientAttributes, depth, id);
if (!config)
config = findMatchingConfig(clientAttributes, depth);
return config;
}
void reset()
{
m_surfaceContextFBConfig = 0;
m_pixmapContextFBConfig = 0;
}
GLPlatformSurface::SurfaceAttributes attributes() const
{
return m_attributes;
}
private:
void validateAttributes()
{
if (m_attributes & GLPlatformSurface::SupportAlpha) {
glxSurfaceAttributes[13] = 8;
glxSurfaceAttributes[5] = GLX_RGBA_BIT;
}
if (m_attributes & GLPlatformSurface::DoubleBuffered)
glxSurfaceAttributes[15] = GL_TRUE;
}
GLXFBConfig findMatchingConfig(const int attributes[], int depth = 32)
{
int numAvailableConfigs;
XUniquePtr<GLXFBConfig> temp(glXChooseFBConfig(X11Helper::nativeDisplay(), DefaultScreen(X11Helper::nativeDisplay()), attributes, &numAvailableConfigs));
if (!numAvailableConfigs || !temp.get())
return 0;
for (int i = 0; i < numAvailableConfigs; ++i) {
XUniquePtr<XVisualInfo> scopedVisualInfo { glXGetVisualFromFBConfig(X11Helper::nativeDisplay(), temp.get()[i]) };
if (!scopedVisualInfo.get())
continue;
#if USE(GRAPHICS_SURFACE) && USE(GLX)
if (X11Helper::isXRenderExtensionSupported()) {
XRenderPictFormat* format = XRenderFindVisualFormat(X11Helper::nativeDisplay(), scopedVisualInfo->visual);
if (format) {
if (m_attributes & GLPlatformSurface::SupportAlpha) {
if (scopedVisualInfo->depth == depth && format->direct.alphaMask > 0)
return temp.get()[i];
} else if (!format->direct.alphaMask)
return temp.get()[i];
}
}
#endif
if (scopedVisualInfo->depth == depth)
return temp.get()[i];
}
XUniquePtr<XVisualInfo> scopedVisualInfo { glXGetVisualFromFBConfig(X11Helper::nativeDisplay(), temp.get()[0]) };
if ((m_attributes & GLPlatformSurface::SupportAlpha) && (scopedVisualInfo->depth != 32))
m_attributes &= ~GLPlatformSurface::SupportAlpha;
return temp.get()[0];
}
GLXFBConfig findMatchingConfigWithVisualId(const int attributes[], int depth, VisualID id)
{
int numAvailableConfigs;
XUniquePtr<GLXFBConfig> temp(glXChooseFBConfig(X11Helper::nativeDisplay(), DefaultScreen(X11Helper::nativeDisplay()), attributes, &numAvailableConfigs));
if (!numAvailableConfigs || !temp.get())
return 0;
for (int i = 0; i < numAvailableConfigs; ++i) {
XUniquePtr<XVisualInfo> scopedVisualInfo { glXGetVisualFromFBConfig(X11Helper::nativeDisplay(), temp.get()[i]) };
if (!scopedVisualInfo.get())
continue;
if (id && scopedVisualInfo->depth == depth && scopedVisualInfo->visualid == id)
return temp.get()[i];
}
return 0;
}
GLXFBConfig m_surfaceContextFBConfig;
GLXFBConfig m_pixmapContextFBConfig;
GLPlatformSurface::SurfaceAttributes m_attributes : 3;
};
}
#endif
#endif