b216ca5c823f1d4736b0b5b4dd345325cfd10e07
[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 "util/u_debug.h"
29 #include "stw_pixelformat.h"
30 #include "stw_public.h"
31 #include "stw_tls.h"
32
33 #define MAX_PIXELFORMATS 16
34
35 static struct pixelformat_info pixelformats[MAX_PIXELFORMATS];
36 static uint pixelformat_count = 0;
37 static uint pixelformat_extended_count = 0;
38
39
40 static void
41 add_standard_pixelformats(
42 struct pixelformat_info **ppf,
43 uint flags )
44 {
45 struct pixelformat_info *pf = *ppf;
46 struct pixelformat_color_info color24 = { 8, 0, 8, 8, 8, 16 };
47 struct pixelformat_alpha_info alpha8 = { 8, 24 };
48 struct pixelformat_alpha_info noalpha = { 0, 0 };
49 struct pixelformat_depth_info depth24s8 = { 24, 8 };
50 struct pixelformat_depth_info depth16 = { 16, 0 };
51
52 pf->flags = PF_FLAG_DOUBLEBUFFER | flags;
53 pf->color = color24;
54 pf->alpha = alpha8;
55 pf->depth = depth16;
56 pf++;
57
58 pf->flags = PF_FLAG_DOUBLEBUFFER | flags;
59 pf->color = color24;
60 pf->alpha = alpha8;
61 pf->depth = depth24s8;
62 pf++;
63
64 pf->flags = PF_FLAG_DOUBLEBUFFER | flags;
65 pf->color = color24;
66 pf->alpha = noalpha;
67 pf->depth = depth16;
68 pf++;
69
70 pf->flags = PF_FLAG_DOUBLEBUFFER | flags;
71 pf->color = color24;
72 pf->alpha = noalpha;
73 pf->depth = depth24s8;
74 pf++;
75
76 pf->flags = flags;
77 pf->color = color24;
78 pf->alpha = alpha8;
79 pf->depth = depth16;
80 pf++;
81
82 pf->flags = flags;
83 pf->color = color24;
84 pf->alpha = alpha8;
85 pf->depth = depth24s8;
86 pf++;
87
88 pf->flags = flags;
89 pf->color = color24;
90 pf->alpha = noalpha;
91 pf->depth = depth16;
92 pf++;
93
94 pf->flags = flags;
95 pf->color = color24;
96 pf->alpha = noalpha;
97 pf->depth = depth24s8;
98 pf++;
99
100 *ppf = pf;
101 }
102
103 void
104 pixelformat_init( void )
105 {
106 struct pixelformat_info *pf = pixelformats;
107
108 add_standard_pixelformats( &pf, 0 );
109 pixelformat_count = pf - pixelformats;
110
111 add_standard_pixelformats( &pf, PF_FLAG_MULTISAMPLED );
112 pixelformat_extended_count = pf - pixelformats;
113
114 assert( pixelformat_extended_count <= MAX_PIXELFORMATS );
115 }
116
117 uint
118 pixelformat_get_count( void )
119 {
120 return pixelformat_count;
121 }
122
123 uint
124 pixelformat_get_extended_count( void )
125 {
126 return pixelformat_extended_count;
127 }
128
129 const struct pixelformat_info *
130 pixelformat_get_info( uint index )
131 {
132 assert( index < pixelformat_extended_count );
133
134 return &pixelformats[index];
135 }
136
137
138 int
139 stw_pixelformat_describe(
140 HDC hdc,
141 int iPixelFormat,
142 UINT nBytes,
143 LPPIXELFORMATDESCRIPTOR ppfd )
144 {
145 uint count;
146 uint index;
147 const struct pixelformat_info *pf;
148
149 (void) hdc;
150
151 count = pixelformat_get_extended_count();
152 index = (uint) iPixelFormat - 1;
153
154 if (ppfd == NULL)
155 return count;
156 if (index >= count || nBytes != sizeof( PIXELFORMATDESCRIPTOR ))
157 return 0;
158
159 pf = pixelformat_get_info( index );
160
161 ppfd->nSize = sizeof( PIXELFORMATDESCRIPTOR );
162 ppfd->nVersion = 1;
163 ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
164 if (pf->flags & PF_FLAG_DOUBLEBUFFER)
165 ppfd->dwFlags |= PFD_DOUBLEBUFFER | PFD_SWAP_COPY;
166 ppfd->iPixelType = PFD_TYPE_RGBA;
167 ppfd->cColorBits = pf->color.redbits + pf->color.greenbits + pf->color.bluebits;
168 ppfd->cRedBits = pf->color.redbits;
169 ppfd->cRedShift = pf->color.redshift;
170 ppfd->cGreenBits = pf->color.greenbits;
171 ppfd->cGreenShift = pf->color.greenshift;
172 ppfd->cBlueBits = pf->color.bluebits;
173 ppfd->cBlueShift = pf->color.blueshift;
174 ppfd->cAlphaBits = pf->alpha.alphabits;
175 ppfd->cAlphaShift = pf->alpha.alphashift;
176 ppfd->cAccumBits = 0;
177 ppfd->cAccumRedBits = 0;
178 ppfd->cAccumGreenBits = 0;
179 ppfd->cAccumBlueBits = 0;
180 ppfd->cAccumAlphaBits = 0;
181 ppfd->cDepthBits = pf->depth.depthbits;
182 ppfd->cStencilBits = pf->depth.stencilbits;
183 ppfd->cAuxBuffers = 0;
184 ppfd->iLayerType = 0;
185 ppfd->bReserved = 0;
186 ppfd->dwLayerMask = 0;
187 ppfd->dwVisibleMask = 0;
188 ppfd->dwDamageMask = 0;
189
190 return count;
191 }
192
193 /* Only used by the wgl code, but have it here to avoid exporting the
194 * pixelformat.h functionality.
195 */
196 int stw_pixelformat_choose( HDC hdc,
197 CONST PIXELFORMATDESCRIPTOR *ppfd )
198 {
199 uint count;
200 uint index;
201 uint bestindex;
202 uint bestdelta;
203
204 (void) hdc;
205
206 count = pixelformat_get_count();
207 bestindex = count;
208 bestdelta = 0xffffffff;
209
210 for (index = 0; index < count; index++) {
211 uint delta = 0;
212 const struct pixelformat_info *pf = pixelformat_get_info( index );
213
214 if (!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
215 !!(ppfd->dwFlags & PFD_DOUBLEBUFFER) !=
216 !!(pf->flags & PF_FLAG_DOUBLEBUFFER))
217 continue;
218
219 if (ppfd->cColorBits != pf->color.redbits + pf->color.greenbits + pf->color.bluebits)
220 delta += 8;
221
222 if (ppfd->cDepthBits != pf->depth.depthbits)
223 delta += 4;
224
225 if (ppfd->cStencilBits != pf->depth.stencilbits)
226 delta += 2;
227
228 if (ppfd->cAlphaBits != pf->alpha.alphabits)
229 delta++;
230
231 if (delta < bestdelta) {
232 bestindex = index;
233 bestdelta = delta;
234 if (bestdelta == 0)
235 break;
236 }
237 }
238
239 if (bestindex == count)
240 return 0;
241
242 return bestindex + 1;
243 }
244
245
246 int
247 stw_pixelformat_get(
248 HDC hdc )
249 {
250 return stw_tls_get_data()->currentPixelFormat;
251 }
252
253
254 BOOL
255 stw_pixelformat_set(
256 HDC hdc,
257 int iPixelFormat )
258 {
259 uint count;
260 uint index;
261
262 (void) hdc;
263
264 index = (uint) iPixelFormat - 1;
265 count = pixelformat_get_extended_count();
266 if (index >= count)
267 return FALSE;
268
269 stw_tls_get_data()->currentPixelFormat = iPixelFormat;
270
271 /* Some applications mistakenly use the undocumented wglSetPixelFormat
272 * function instead of SetPixelFormat, so we call SetPixelFormat here to
273 * avoid opengl32.dll's wglCreateContext to fail */
274 if (GetPixelFormat(hdc) == 0) {
275 SetPixelFormat(hdc, iPixelFormat, NULL);
276 }
277
278 return TRUE;
279 }
280
281
282
283 /* XXX: this needs to be turned into queries on pipe_screen or
284 * stw_winsys.
285 */
286 int
287 stw_query_sample_buffers( void )
288 {
289 return 1;
290 }
291
292 int
293 stw_query_samples( void )
294 {
295 return 4;
296 }
297