[EFL][Qt][WebGL] Share the common code between GraphicsSurfaceGLX and X11WindowResources.
[WebKit-https.git] / Source / WebCore / platform / graphics / surfaces / glx / GLXConfigSelector.h
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(ACCELERATED_COMPOSITING) && USE(GLX)
30
31 #include "X11Helper.h"
32 #include <opengl/GLDefs.h>
33
34 namespace WebCore {
35
36 static int clientAttributes[] = {
37     // The specification is a set key value pairs stored in a simple array.
38     GLX_LEVEL,                          0,
39     static_cast<int>(GLX_VISUAL_ID),    0,
40     GLX_DRAWABLE_TYPE,                  GLX_PIXMAP_BIT,
41     GLX_BIND_TO_TEXTURE_TARGETS_EXT,    GLX_TEXTURE_2D_BIT_EXT,
42     GLX_BIND_TO_TEXTURE_RGBA_EXT,       TRUE,
43     0
44 };
45
46 class GLXConfigSelector {
47     WTF_MAKE_NONCOPYABLE(GLXConfigSelector);
48
49 public:
50     GLXConfigSelector()
51         : m_pbufferFBConfig(0)
52         , m_surfaceContextFBConfig(0)
53     {
54     }
55
56     virtual ~GLXConfigSelector()
57     {
58     }
59
60     XVisualInfo* visualInfo()
61     {
62         if (!surfaceContextConfig())
63             return 0;
64
65         return glXGetVisualFromFBConfig(X11Helper::nativeDisplay(), m_surfaceContextFBConfig);
66     }
67
68     GLXFBConfig pBufferContextConfig()
69     {
70         if (!m_pbufferFBConfig) {
71             static const int attributes[] = {
72                 GLX_LEVEL, 0,
73                 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
74                 GLX_RENDER_TYPE,   GLX_RGBA_BIT,
75                 GLX_RED_SIZE,      1,
76                 GLX_GREEN_SIZE,    1,
77                 GLX_BLUE_SIZE,     1,
78                 GLX_DOUBLEBUFFER,  GL_FALSE,
79                 None
80             };
81
82             m_pbufferFBConfig = findMatchingConfig(attributes);
83         }
84
85         return m_pbufferFBConfig;
86     }
87
88     GLXFBConfig surfaceContextConfig()
89     {
90         if (!m_surfaceContextFBConfig)
91             createSurfaceConfig();
92
93         return m_surfaceContextFBConfig;
94     }
95
96     GLXFBConfig surfaceClientConfig(int depth, VisualID id)
97     {
98         clientAttributes[3] = static_cast<int>(id);
99         clientAttributes[8] = depth == 32 ? GLX_BIND_TO_TEXTURE_RGBA_EXT : GLX_BIND_TO_TEXTURE_RGB_EXT;
100
101         return findMatchingConfig(clientAttributes, depth, id);
102     }
103
104     void reset()
105     {
106         m_pbufferFBConfig = 0;
107         m_surfaceContextFBConfig = 0;
108     }
109
110 private:
111     void createSurfaceConfig()
112     {
113         static int attributes[] = {
114             GLX_LEVEL, 0,
115             GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
116             GLX_RENDER_TYPE,   GLX_RGBA_BIT,
117             GLX_RED_SIZE,      1,
118             GLX_GREEN_SIZE,    1,
119             GLX_BLUE_SIZE,     1,
120             GLX_ALPHA_SIZE,    1,
121             GLX_DEPTH_SIZE,    1,
122             GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
123             GLX_DOUBLEBUFFER,  True,
124             None
125         };
126
127         m_surfaceContextFBConfig = findMatchingConfig(attributes);
128     }
129
130     GLXFBConfig findMatchingConfig(const int attributes[], int depth = 32, VisualID id = 0)
131     {
132         int numAvailableConfigs;
133         OwnPtrX11<GLXFBConfig> temp(glXChooseFBConfig(X11Helper::nativeDisplay(), DefaultScreen(X11Helper::nativeDisplay()), attributes, &numAvailableConfigs));
134
135         if (!numAvailableConfigs || !temp.get())
136             return 0;
137
138         OwnPtrX11<XVisualInfo> scopedVisualInfo;
139         for (int i = 0; i < numAvailableConfigs; ++i) {
140             scopedVisualInfo = glXGetVisualFromFBConfig(X11Helper::nativeDisplay(), temp[i]);
141             if (!scopedVisualInfo.get())
142                 continue;
143
144             if (id && scopedVisualInfo->depth == depth && scopedVisualInfo->visualid == id)
145                 return temp[i];
146
147 #if USE(GRAPHICS_SURFACE)
148             if (X11Helper::isXRenderExtensionSupported()) {
149                 XRenderPictFormat* format = XRenderFindVisualFormat(X11Helper::nativeDisplay(), scopedVisualInfo->visual);
150                 if (format && depth == 32 && format->direct.alphaMask > 0)
151                     return temp[i];
152             }
153 #endif
154             if (scopedVisualInfo->depth == depth)
155                 return temp[i];
156         }
157
158         // Did not find any visual supporting alpha, select the first available config.
159         return temp[0];
160     }
161
162     GLXFBConfig m_pbufferFBConfig;
163     GLXFBConfig m_surfaceContextFBConfig;
164 };
165
166 }
167
168 #endif
169
170 #endif