First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xgl / xglcmap.c
blobb96308ddfa671dd372168b1c8903b6f79ca127ff
1 /*
2 * Copyright © 2004 David Reveman
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of
9 * David Reveman not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior permission.
11 * David Reveman makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
13 * implied warranty.
15 * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: David Reveman <davidr@novell.com>
26 #include "xgl.h"
27 #include "colormapst.h"
28 #include "micmap.h"
29 #include "fb.h"
31 static xglPixelFormatRec xglPixelFormats[] = {
33 8, 8,
36 0x000000ff,
37 0x00000000,
38 0x00000000,
39 0x00000000
41 }, {
42 15, 5,
44 16,
45 0x00000000,
46 0x00007c00,
47 0x000003e0,
48 0x0000001f
50 }, {
51 16, 6,
53 16,
54 0x00000000,
55 0x0000f800,
56 0x000007e0,
57 0x0000001f
59 }, {
60 24, 8,
62 32,
63 0x00000000,
64 0x00ff0000,
65 0x0000ff00,
66 0x000000ff
68 }, {
69 32, 8,
71 32,
72 0xff000000,
73 0x00ff0000,
74 0x0000ff00,
75 0x000000ff
80 #define NUM_XGL_PIXEL_FORMATS \
81 (sizeof (xglPixelFormats) / sizeof (xglPixelFormats[0]))
83 xglVisualPtr xglVisuals = NULL;
85 void
86 xglSetVisualTypes (int depth,
87 int visuals,
88 int redSize,
89 int greenSize,
90 int blueSize)
92 xglPixelFormatPtr pBestFormat = 0;
93 int i, rs, gs, bs, diff, bestDiff = 0;
95 for (i = 0; i < NUM_XGL_PIXEL_FORMATS; i++)
97 if (xglPixelFormats[i].depth == depth)
99 if (visuals)
101 rs = Ones (xglPixelFormats[i].masks.red_mask);
102 gs = Ones (xglPixelFormats[i].masks.green_mask);
103 bs = Ones (xglPixelFormats[i].masks.blue_mask);
105 if (redSize >= rs &&
106 greenSize >= gs &&
107 blueSize >= bs)
109 diff = (redSize - rs) + (greenSize - gs) + (blueSize - bs);
110 if (pBestFormat)
112 if (diff < bestDiff)
114 pBestFormat = &xglPixelFormats[i];
115 bestDiff = diff;
118 else
120 pBestFormat = &xglPixelFormats[i];
121 bestDiff = diff;
125 else
127 pBestFormat = &xglPixelFormats[i];
128 break;
133 if (pBestFormat)
135 xglVisualPtr new, *prev, v;
136 unsigned int bitsPerRGB;
137 Pixel rm, gm, bm;
139 new = xalloc (sizeof (xglVisualRec));
140 if (!new)
141 return;
143 new->next = 0;
145 new->format.surface = 0;
146 new->format.drawable = 0;
147 new->pPixel = pBestFormat;
148 new->vid = 0;
150 bitsPerRGB = pBestFormat->bitsPerRGB;
152 rm = pBestFormat->masks.red_mask;
153 gm = pBestFormat->masks.green_mask;
154 bm = pBestFormat->masks.blue_mask;
156 fbSetVisualTypesAndMasks (depth, visuals, bitsPerRGB, rm, gm, bm);
158 for (prev = &xglVisuals; (v = *prev); prev = &v->next);
159 *prev = new;
161 else
163 fbSetVisualTypesAndMasks (depth, 0, 0, 0, 0, 0);
167 Bool
168 xglHasVisualTypes (xglVisualPtr pVisual,
169 int depth)
171 xglVisualPtr v;
173 for (v = pVisual; v; v = v->next)
174 if (v->pPixel->depth == depth)
175 return TRUE;
177 return FALSE;
180 glitz_format_t *
181 xglFindBestSurfaceFormat (ScreenPtr pScreen,
182 xglPixelFormatPtr pPixel)
184 glitz_format_t templ, *format, *best = 0;
185 unsigned int mask;
186 unsigned short rs, gs, bs, as;
187 int i = 0;
189 XGL_SCREEN_PRIV (pScreen);
191 rs = Ones (pPixel->masks.red_mask);
192 gs = Ones (pPixel->masks.green_mask);
193 bs = Ones (pPixel->masks.blue_mask);
194 as = Ones (pPixel->masks.alpha_mask);
196 templ.color.fourcc = GLITZ_FOURCC_RGB;
197 mask = GLITZ_FORMAT_FOURCC_MASK;
199 do {
200 format = glitz_find_format (pScreenPriv->drawable, mask, &templ, i++);
201 if (format)
203 if (format->color.red_size >= rs &&
204 format->color.green_size >= gs &&
205 format->color.blue_size >= bs &&
206 format->color.alpha_size >= as)
208 if (best)
210 if (((format->color.red_size - rs) +
211 (format->color.green_size - gs) +
212 (format->color.blue_size - bs)) <
213 ((best->color.red_size - rs) +
214 (best->color.green_size - gs) +
215 (best->color.blue_size - bs)))
216 best = format;
218 else
220 best = format;
224 } while (format);
226 return best;
229 static Bool
230 xglInitVisual (ScreenPtr pScreen,
231 xglVisualPtr pVisual,
232 xglPixelFormatPtr pPixel,
233 VisualID vid)
235 glitz_format_t *format;
237 XGL_SCREEN_PRIV (pScreen);
239 format = xglFindBestSurfaceFormat (pScreen, pPixel);
240 if (format)
242 glitz_drawable_format_t templ;
243 unsigned long mask;
245 templ.color = format->color;
246 templ.depth_size = 0;
247 templ.stencil_size = 0;
248 templ.doublebuffer = 0;
249 templ.samples = 1;
251 mask =
252 GLITZ_FORMAT_FOURCC_MASK |
253 GLITZ_FORMAT_RED_SIZE_MASK |
254 GLITZ_FORMAT_GREEN_SIZE_MASK |
255 GLITZ_FORMAT_BLUE_SIZE_MASK |
256 GLITZ_FORMAT_ALPHA_SIZE_MASK |
257 GLITZ_FORMAT_DEPTH_SIZE_MASK |
258 GLITZ_FORMAT_STENCIL_SIZE_MASK |
259 GLITZ_FORMAT_DOUBLEBUFFER_MASK |
260 GLITZ_FORMAT_SAMPLES_MASK;
262 pVisual->next = 0;
263 pVisual->vid = vid;
264 pVisual->pPixel = pPixel;
265 pVisual->pbuffer = FALSE;
267 pVisual->format.surface = format;
268 pVisual->format.drawable =
269 glitz_find_drawable_format (pScreenPriv->drawable,
270 mask, &templ, 0);
272 return TRUE;
275 return FALSE;
278 static Bool
279 xglInitPbufferVisual (ScreenPtr pScreen,
280 xglVisualPtr pVisual,
281 xglPixelFormatPtr pPixel,
282 VisualID vid)
284 glitz_format_t *format;
286 XGL_SCREEN_PRIV (pScreen);
288 format = xglFindBestSurfaceFormat (pScreen, pPixel);
289 if (format)
291 glitz_drawable_format_t templ, *screenFormat;
292 unsigned long mask;
294 /* use same drawable format as screen for pbuffers */
295 screenFormat = glitz_drawable_get_format (pScreenPriv->drawable);
296 templ.id = screenFormat->id;
298 templ.color = format->color;
299 templ.samples = 1;
301 mask =
302 GLITZ_FORMAT_ID_MASK |
303 GLITZ_FORMAT_FOURCC_MASK |
304 GLITZ_FORMAT_RED_SIZE_MASK |
305 GLITZ_FORMAT_GREEN_SIZE_MASK |
306 GLITZ_FORMAT_BLUE_SIZE_MASK |
307 GLITZ_FORMAT_SAMPLES_MASK;
309 pVisual->next = 0;
310 pVisual->vid = vid;
311 pVisual->pPixel = pPixel;
312 pVisual->pbuffer = TRUE;
314 pVisual->format.surface = format;
315 pVisual->format.drawable =
316 glitz_find_pbuffer_format (pScreenPriv->drawable,
317 mask, &templ, 0);
319 if (pVisual->format.drawable)
320 return TRUE;
323 return FALSE;
326 void
327 xglInitVisuals (ScreenPtr pScreen)
329 xglVisualPtr pVisual, v, new, *prev;
330 int i;
332 XGL_SCREEN_PRIV (pScreen);
334 for (i = 0; i < pScreen->numVisuals; i++)
336 for (pVisual = xglVisuals; pVisual; pVisual = pVisual->next)
337 if (pVisual->pPixel->depth == pScreen->visuals[i].nplanes)
338 break;
340 if (pVisual)
342 new = xalloc (sizeof (xglVisualRec));
343 if (new)
345 if (xglInitVisual (pScreen, new, pVisual->pPixel,
346 pScreen->visuals[i].vid))
348 new->next = 0;
350 prev = &pScreenPriv->pVisual;
351 while ((v = *prev))
352 prev = &v->next;
354 *prev = new;
356 else
358 xfree (new);
362 new = xalloc (sizeof (xglVisualRec));
363 if (new)
365 if (xglInitPbufferVisual (pScreen, new, pVisual->pPixel,
366 pScreen->visuals[i].vid))
368 new->next = 0;
370 prev = &pScreenPriv->pVisual;
371 while ((v = *prev))
372 prev = &v->next;
374 *prev = new;
376 else
378 xfree (new);
384 /* Add additional Xgl visuals for pixmap formats */
385 for (i = 0; i < screenInfo.numPixmapFormats; i++)
387 if (!xglHasVisualTypes (pScreenPriv->pVisual,
388 screenInfo.formats[i].depth))
390 for (v = xglVisuals; v; v = v->next)
391 if (v->pPixel->depth == screenInfo.formats[i].depth)
392 break;
394 if (v)
396 new = xalloc (sizeof (xglVisualRec));
397 if (new)
399 if (xglInitVisual (pScreen, new, v->pPixel, 0))
401 new->next = 0;
403 prev = &pScreenPriv->pVisual;
404 while ((v = *prev))
405 prev = &v->next;
407 *prev = new;
409 else
411 xfree (new);
419 xglVisualPtr
420 xglFindVisualWithDepth (ScreenPtr pScreen,
421 int depth)
423 xglVisualPtr v;
425 XGL_SCREEN_PRIV (pScreen);
427 for (v = pScreenPriv->pVisual; v; v = v->next)
429 if (v->pPixel->depth == depth)
430 return v;
433 return 0;
436 xglVisualPtr
437 xglFindVisualWithId (ScreenPtr pScreen,
438 int vid)
440 xglVisualPtr v;
442 XGL_SCREEN_PRIV (pScreen);
444 for (v = pScreenPriv->pVisual; v; v = v->next)
446 if (v->vid == vid)
447 return v;
450 return 0;
453 void
454 xglClearVisualTypes (void)
456 xglVisualPtr v;
458 while (xglVisuals)
460 v = xglVisuals;
461 xglVisuals = v->next;
462 xfree (v);
465 miClearVisualTypes ();