Merge commit 'origin/gallium-master-merge'
[mesa.git] / src / gallium / state_trackers / wgl / shared / stw_pixelformat.c
1 /**************************************************************************
2 *
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "pipe/p_debug.h"
29 #include "stw_pixelformat.h"
30 #include "stw_public.h"
31
32 #define MAX_PIXELFORMATS 16
33
34 static struct pixelformat_info pixelformats[MAX_PIXELFORMATS];
35 static uint pixelformat_count = 0;
36 static uint pixelformat_extended_count = 0;
37
38 static uint currentpixelformat = 0;
39
40
41 static void
42 add_standard_pixelformats(
43 struct pixelformat_info **ppf,
44 uint flags )
45 {
46 struct pixelformat_info *pf = *ppf;
47 struct pixelformat_color_info color24 = { 8, 0, 8, 8, 8, 16 };
48 struct pixelformat_alpha_info alpha8 = { 8, 24 };
49 struct pixelformat_alpha_info noalpha = { 0, 0 };
50 struct pixelformat_depth_info depth24s8 = { 24, 8 };
51 struct pixelformat_depth_info depth16 = { 16, 0 };
52
53 pf->flags = PF_FLAG_DOUBLEBUFFER | flags;
54 pf->color = color24;
55 pf->alpha = alpha8;
56 pf->depth = depth16;
57 pf++;
58
59 pf->flags = PF_FLAG_DOUBLEBUFFER | flags;
60 pf->color = color24;
61 pf->alpha = alpha8;
62 pf->depth = depth24s8;
63 pf++;
64
65 pf->flags = PF_FLAG_DOUBLEBUFFER | flags;
66 pf->color = color24;
67 pf->alpha = noalpha;
68 pf->depth = depth16;
69 pf++;
70
71 pf->flags = PF_FLAG_DOUBLEBUFFER | flags;
72 pf->color = color24;
73 pf->alpha = noalpha;
74 pf->depth = depth24s8;
75 pf++;
76
77 pf->flags = flags;
78 pf->color = color24;
79 pf->alpha = noalpha;
80 pf->depth = depth16;
81 pf++;
82
83 pf->flags = flags;
84 pf->color = color24;
85 pf->alpha = noalpha;
86 pf->depth = depth24s8;
87 pf++;
88
89 *ppf = pf;
90 }
91
92 void
93 pixelformat_init( void )
94 {
95 struct pixelformat_info *pf = pixelformats;
96
97 add_standard_pixelformats( &pf, 0 );
98 pixelformat_count = pf - pixelformats;
99
100 add_standard_pixelformats( &pf, PF_FLAG_MULTISAMPLED );
101 pixelformat_extended_count = pf - pixelformats;
102
103 assert( pixelformat_extended_count <= MAX_PIXELFORMATS );
104 }
105
106 uint
107 pixelformat_get_count( void )
108 {
109 return pixelformat_count;
110 }
111
112 uint
113 pixelformat_get_extended_count( void )
114 {
115 return pixelformat_extended_count;
116 }
117
118 const struct pixelformat_info *
119 pixelformat_get_info( uint index )
120 {
121 assert( index < pixelformat_extended_count );
122
123 return &pixelformats[index];
124 }
125
126
127 int
128 stw_pixelformat_describe(
129 HDC hdc,
130 int iPixelFormat,
131 UINT nBytes,
132 LPPIXELFORMATDESCRIPTOR ppfd )
133 {
134 uint count;
135 uint index;
136 const struct pixelformat_info *pf;
137
138 (void) hdc;
139
140 count = pixelformat_get_extended_count();
141 index = (uint) iPixelFormat - 1;
142
143 if (ppfd == NULL)
144 return count;
145 if (index >= count || nBytes != sizeof( PIXELFORMATDESCRIPTOR ))
146 return 0;
147
148 pf = pixelformat_get_info( index );
149
150 ppfd->nSize = sizeof( PIXELFORMATDESCRIPTOR );
151 ppfd->nVersion = 1;
152 ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
153 if (pf->flags & PF_FLAG_DOUBLEBUFFER)
154 ppfd->dwFlags |= PFD_DOUBLEBUFFER | PFD_SWAP_COPY;
155 ppfd->iPixelType = PFD_TYPE_RGBA;
156 ppfd->cColorBits = pf->color.redbits + pf->color.greenbits + pf->color.bluebits;
157 ppfd->cRedBits = pf->color.redbits;
158 ppfd->cRedShift = pf->color.redshift;
159 ppfd->cGreenBits = pf->color.greenbits;
160 ppfd->cGreenShift = pf->color.greenshift;
161 ppfd->cBlueBits = pf->color.bluebits;
162 ppfd->cBlueShift = pf->color.blueshift;
163 ppfd->cAlphaBits = pf->alpha.alphabits;
164 ppfd->cAlphaShift = pf->alpha.alphashift;
165 ppfd->cAccumBits = 0;
166 ppfd->cAccumRedBits = 0;
167 ppfd->cAccumGreenBits = 0;
168 ppfd->cAccumBlueBits = 0;
169 ppfd->cAccumAlphaBits = 0;
170 ppfd->cDepthBits = pf->depth.depthbits;
171 ppfd->cStencilBits = pf->depth.stencilbits;
172 ppfd->cAuxBuffers = 0;
173 ppfd->iLayerType = 0;
174 ppfd->bReserved = 0;
175 ppfd->dwLayerMask = 0;
176 ppfd->dwVisibleMask = 0;
177 ppfd->dwDamageMask = 0;
178
179 return count;
180 }
181
182 /* Only used by the wgl code, but have it here to avoid exporting the
183 * pixelformat.h functionality.
184 */
185 int stw_pixelformat_choose( HDC hdc,
186 CONST PIXELFORMATDESCRIPTOR *ppfd )
187 {
188 uint count;
189 uint index;
190 uint bestindex;
191 uint bestdelta;
192
193 (void) hdc;
194
195 count = pixelformat_get_count();
196 bestindex = count;
197 bestdelta = 0xffffffff;
198
199 for (index = 0; index < count; index++) {
200 uint delta = 0;
201 const struct pixelformat_info *pf = pixelformat_get_info( index );
202
203 if (!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
204 !!(ppfd->dwFlags & PFD_DOUBLEBUFFER) !=
205 !!(pf->flags & PF_FLAG_DOUBLEBUFFER))
206 continue;
207
208 if (ppfd->cColorBits != pf->color.redbits + pf->color.greenbits + pf->color.bluebits)
209 delta += 8;
210
211 if (ppfd->cDepthBits != pf->depth.depthbits)
212 delta += 4;
213
214 if (ppfd->cStencilBits != pf->depth.stencilbits)
215 delta += 2;
216
217 if (ppfd->cAlphaBits != pf->alpha.alphabits)
218 delta++;
219
220 if (delta < bestdelta) {
221 bestindex = index;
222 bestdelta = delta;
223 if (bestdelta == 0)
224 break;
225 }
226 }
227
228 if (bestindex == count)
229 return 0;
230
231 return bestindex + 1;
232 }
233
234
235 int
236 stw_pixelformat_get(
237 HDC hdc )
238 {
239 return currentpixelformat;
240 }
241
242
243 BOOL
244 stw_pixelformat_set(
245 HDC hdc,
246 int iPixelFormat )
247 {
248 uint count;
249 uint index;
250
251 (void) hdc;
252
253 index = (uint) iPixelFormat - 1;
254 count = pixelformat_get_extended_count();
255 if (index >= count)
256 return FALSE;
257
258 currentpixelformat = iPixelFormat;
259
260 /* Some applications mistakenly use the undocumented wglSetPixelFormat
261 * function instead of SetPixelFormat, so we call SetPixelFormat here to
262 * avoid opengl32.dll's wglCreateContext to fail */
263 if (GetPixelFormat(hdc) == 0) {
264 SetPixelFormat(hdc, iPixelFormat, NULL);
265 }
266
267 return TRUE;
268 }
269
270
271
272 /* XXX: this needs to be turned into queries on pipe_screen or
273 * stw_winsys.
274 */
275 int
276 stw_query_sample_buffers( void )
277 {
278 return 1;
279 }
280
281 int
282 stw_query_samples( void )
283 {
284 return 4;
285 }
286