First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xgl / xglgc.c
blob7e7e75134c446304afeaa9b05557401d4f276e49
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 "fb.h"
28 #include "gcstruct.h"
29 #include "migc.h"
31 #define XGL_GC_OP_FALLBACK_PROLOGUE(pDrawable) \
32 xglSyncDamageBoxBits (pDrawable); \
33 XGL_GC_UNWRAP (funcs); \
34 XGL_GC_UNWRAP (ops)
36 #define XGL_GC_OP_FALLBACK_EPILOGUE(pDrawable) \
37 XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs); \
38 XGL_GC_WRAP (ops, (GCOps *) &xglGCOps); \
39 xglAddCurrentSurfaceDamage (pDrawable)
41 #define XGL_GC_FILL_OP_FALLBACK_PROLOGUE(pDrawable) \
42 switch (pGC->fillStyle) { \
43 case FillSolid: \
44 break; \
45 case FillStippled: \
46 case FillOpaqueStippled: \
47 if (!xglSyncBits (&pGC->stipple->drawable, NullBox)) \
48 FatalError (XGL_SW_FAILURE_STRING); \
49 break; \
50 case FillTiled: \
51 if (!xglSyncBits (&pGC->tile.pixmap->drawable, NullBox)) \
52 FatalError (XGL_SW_FAILURE_STRING); \
53 break; \
54 } \
55 XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable)
57 static const GCFuncs xglGCFuncs = {
58 xglValidateGC,
59 miChangeGC,
60 miCopyGC,
61 xglDestroyGC,
62 miChangeClip,
63 miDestroyClip,
64 miCopyClip
67 static const GCOps xglGCOps = {
68 xglFillSpans,
69 xglSetSpans,
70 xglPutImage,
71 xglCopyArea,
72 xglCopyPlane,
73 xglPolyPoint,
74 xglPolylines,
75 xglPolySegment,
76 miPolyRectangle,
77 xglPolyArc,
78 miFillPolygon,
79 xglPolyFillRect,
80 xglPolyFillArc,
81 miPolyText8,
82 miPolyText16,
83 miImageText8,
84 miImageText16,
85 xglImageGlyphBlt,
86 xglPolyGlyphBlt,
87 xglPushPixels
90 void
91 xglFillSpans (DrawablePtr pDrawable,
92 GCPtr pGC,
93 int nspans,
94 DDXPointPtr ppt,
95 int *pwidth,
96 int fSorted)
98 XGL_GC_PRIV (pGC);
100 if (pGCPriv->flags || pGC->fillStyle == FillStippled)
102 XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
103 (*pGC->ops->FillSpans) (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
104 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
106 else
108 /* xglFillSpan handles fall-back */
109 xglFillSpan (pDrawable, pGC, nspans, ppt, pwidth);
113 void
114 xglSetSpans (DrawablePtr pDrawable,
115 GCPtr pGC,
116 char *psrc,
117 DDXPointPtr ppt,
118 int *pwidth,
119 int nspans,
120 int fSorted)
122 XGL_GC_PRIV (pGC);
124 XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
125 (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
126 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
129 void
130 xglPutImage (DrawablePtr pDrawable,
131 GCPtr pGC,
132 int depth,
133 int x,
134 int y,
135 int w,
136 int h,
137 int leftPad,
138 int format,
139 char *bits)
141 XGL_GC_PRIV (pGC);
143 if (pGC->alu != GXcopy || (pGCPriv->flags & xglGCPlaneMaskFlag))
145 XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
146 (*pGC->ops->PutImage) (pDrawable, pGC, depth,
147 x, y, w, h, leftPad, format, bits);
148 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
150 else
152 RegionPtr pClip = pGC->pCompositeClip;
153 RegionRec region;
154 BoxRec box;
156 XGL_DRAWABLE_PIXMAP (pDrawable);
158 if (!xglMapPixmapBits (pPixmap))
159 FatalError (XGL_SW_FAILURE_STRING);
161 XGL_GC_UNWRAP (funcs);
162 XGL_GC_UNWRAP (ops);
164 (*pGC->ops->PutImage) (pDrawable, pGC, depth,
165 x, y, w, h, leftPad, format, bits);
167 XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs);
168 XGL_GC_WRAP (ops, (GCOps *) &xglGCOps);
170 box.x1 = pDrawable->x + x;
171 box.y1 = pDrawable->y + y;
172 box.x2 = box.x1 + w;
173 box.y2 = box.y1 + h;
175 REGION_INIT (pDrawable->pScreen, &region, &box, 1);
176 REGION_INTERSECT (pDrawable->pScreen, &region, pClip, &region);
178 xglAddSurfaceDamage (pDrawable, &region);
180 REGION_UNINIT (pDrawable->pScreen, &region);
184 RegionPtr
185 xglCopyArea (DrawablePtr pSrc,
186 DrawablePtr pDst,
187 GCPtr pGC,
188 int srcX,
189 int srcY,
190 int w,
191 int h,
192 int dstX,
193 int dstY)
195 RegionPtr pRegion;
196 BoxRec box;
198 XGL_GC_PRIV (pGC);
200 box.x1 = pSrc->x + srcX;
201 box.y1 = pSrc->y + srcY;
202 box.x2 = box.x1 + w;
203 box.y2 = box.y1 + h;
205 if (pGC->alu != GXcopy || pGCPriv->flags)
207 if (!xglSyncBits (pSrc, &box))
208 FatalError (XGL_SW_FAILURE_STRING);
210 XGL_GC_OP_FALLBACK_PROLOGUE (pDst);
211 pRegion = (*pGC->ops->CopyArea) (pSrc, pDst, pGC,
212 srcX, srcY, w, h, dstX, dstY);
213 XGL_GC_OP_FALLBACK_EPILOGUE (pDst);
215 else
217 /* xglCopyProc handles fall-back */
218 pRegion = fbDoCopy (pSrc, pDst, pGC,
219 srcX, srcY,
220 w, h,
221 dstX, dstY,
222 xglCopyProc, 0,
223 (void *) &box);
226 return pRegion;
229 RegionPtr
230 xglCopyPlane (DrawablePtr pSrc,
231 DrawablePtr pDst,
232 GCPtr pGC,
233 int srcX,
234 int srcY,
235 int w,
236 int h,
237 int dstX,
238 int dstY,
239 unsigned long bitPlane)
241 RegionPtr pRegion;
242 BoxRec box;
244 XGL_GC_PRIV (pGC);
246 box.x1 = pSrc->x + srcX;
247 box.y1 = pSrc->y + srcY;
248 box.x2 = box.x1 + w;
249 box.y2 = box.y1 + h;
251 if (!xglSyncBits (pSrc, &box))
252 FatalError (XGL_SW_FAILURE_STRING);
254 XGL_GC_OP_FALLBACK_PROLOGUE (pDst);
255 pRegion = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC,
256 srcX, srcY, w, h, dstX, dstY,
257 bitPlane);
258 XGL_GC_OP_FALLBACK_EPILOGUE (pDst);
260 return pRegion;
263 void
264 xglPolyPoint (DrawablePtr pDrawable,
265 GCPtr pGC,
266 int mode,
267 int npt,
268 DDXPointPtr pptInit)
270 XGL_GC_PRIV (pGC);
272 XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
273 (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pptInit);
274 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
277 void
278 xglPolylines (DrawablePtr pDrawable,
279 GCPtr pGC,
280 int mode,
281 int npt,
282 DDXPointPtr ppt)
284 if (pGC->lineWidth == 0)
286 XGL_GC_PRIV (pGC);
288 if (!pGCPriv->flags)
290 if (pGC->lineStyle == LineSolid)
292 if (xglFillLine (pDrawable, pGC, mode, npt, ppt))
293 return;
297 XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
298 (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppt);
299 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
301 else
303 if (pGC->lineStyle != LineSolid)
304 miWideDash (pDrawable, pGC, mode, npt, ppt);
305 else
306 miWideLine (pDrawable, pGC, mode, npt, ppt);
310 void
311 xglPolySegment (DrawablePtr pDrawable,
312 GCPtr pGC,
313 int nsegInit,
314 xSegment *pSegInit)
316 if (pGC->lineWidth == 0)
318 XGL_GC_PRIV (pGC);
320 if (!pGCPriv->flags)
322 if (pGC->lineStyle == LineSolid)
324 if (xglFillSegment (pDrawable, pGC, nsegInit, pSegInit))
325 return;
329 XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
330 (*pGC->ops->PolySegment) (pDrawable, pGC, nsegInit, pSegInit);
331 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
332 } else
333 miPolySegment (pDrawable, pGC, nsegInit, pSegInit);
336 void
337 xglPolyArc (DrawablePtr pDrawable,
338 GCPtr pGC,
339 int narcs,
340 xArc *pArcs)
342 if (pGC->lineWidth == 0)
344 XGL_GC_PRIV (pGC);
346 XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
347 (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, pArcs);
348 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
349 } else
350 miPolyArc (pDrawable, pGC, narcs, pArcs);
353 void
354 xglPolyFillRect (DrawablePtr pDrawable,
355 GCPtr pGC,
356 int nrect,
357 xRectangle *prect)
359 XGL_GC_PRIV (pGC);
361 if (pGC->fillStyle == FillStippled || pGCPriv->flags)
363 XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
364 (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrect, prect);
365 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
367 else
369 /* xglFillRect handles fall-back */
370 xglFillRect (pDrawable, pGC, nrect, prect);
374 void
375 xglPolyFillArc (DrawablePtr pDrawable,
376 GCPtr pGC,
377 int narcs,
378 xArc *pArcs)
380 XGL_GC_PRIV (pGC);
382 XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
383 (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, pArcs);
384 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
387 void
388 xglImageGlyphBlt (DrawablePtr pDrawable,
389 GCPtr pGC,
390 int x,
391 int y,
392 unsigned int nglyph,
393 CharInfoPtr *ppci,
394 pointer pglyphBase)
396 XGL_GC_PRIV (pGC);
398 if (!pGCPriv->flags)
400 if (xglSolidGlyph (pDrawable,
401 pGC,
404 nglyph,
405 ppci,
406 pglyphBase))
407 return;
410 XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
411 (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci,
412 pglyphBase);
413 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
416 void
417 xglPolyGlyphBlt (DrawablePtr pDrawable,
418 GCPtr pGC,
419 int x,
420 int y,
421 unsigned int nglyph,
422 CharInfoPtr *ppci,
423 pointer pglyphBase)
425 XGL_GC_PRIV (pGC);
427 if (!pGCPriv->flags)
429 if (xglFillGlyph (pDrawable,
430 pGC,
433 nglyph,
434 ppci,
435 pglyphBase))
436 return;
439 XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
440 (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
441 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
444 void
445 xglPushPixels (GCPtr pGC,
446 PixmapPtr pBitmap,
447 DrawablePtr pDrawable,
448 int w,
449 int h,
450 int x,
451 int y)
453 XGL_GC_PRIV (pGC);
455 if (!xglSyncBits (&pBitmap->drawable, NullBox))
456 FatalError (XGL_SW_FAILURE_STRING);
458 XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
459 (*pGC->ops->PushPixels) (pGC, pBitmap, pDrawable, w, h, x, y);
460 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
463 Bool
464 xglCreateGC (GCPtr pGC)
466 ScreenPtr pScreen = pGC->pScreen;
467 Bool ret;
469 XGL_SCREEN_PRIV (pScreen);
470 XGL_GC_PRIV (pGC);
472 XGL_SCREEN_UNWRAP (CreateGC);
473 ret = (*pScreen->CreateGC) (pGC);
474 XGL_SCREEN_WRAP (CreateGC, xglCreateGC);
476 XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs);
477 XGL_GC_WRAP (ops, (GCOps *) &xglGCOps);
479 pGCPriv->flags = 0;
480 pGCPriv->op = GLITZ_OPERATOR_SRC;
482 pGCPriv->fg = NULL;
483 pGCPriv->bg = NULL;
484 pGCPriv->id = ~0;
486 return ret;
489 void
490 xglDestroyGC (GCPtr pGC)
492 XGL_GC_PRIV (pGC);
494 if (pGCPriv->fg)
495 glitz_surface_destroy (pGCPriv->fg);
497 if (pGCPriv->bg)
498 glitz_surface_destroy (pGCPriv->bg);
500 XGL_GC_UNWRAP (funcs);
501 XGL_GC_UNWRAP (ops);
502 (*pGC->funcs->DestroyGC) (pGC);
503 XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs);
504 XGL_GC_WRAP (ops, (GCOps *) &xglGCOps);
507 void
508 xglValidateGC (GCPtr pGC,
509 unsigned long changes,
510 DrawablePtr pDrawable)
512 XGL_GC_PRIV (pGC);
514 if (changes & GCTile)
516 if (!pGC->tileIsPixel &&
517 FbEvenTile (pGC->tile.pixmap->drawable.width *
518 pDrawable->bitsPerPixel))
519 xglSyncBits (&pGC->tile.pixmap->drawable, NULL);
522 if (changes & GCStipple)
524 if (pGC->stipple)
525 xglSyncBits (&pGC->stipple->drawable, NULL);
528 XGL_GC_UNWRAP (funcs);
529 XGL_GC_UNWRAP (ops);
530 (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
531 XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs);
532 XGL_GC_WRAP (ops, (GCOps *) &xglGCOps);
534 if (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
536 XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
538 if (pPixmapPriv->pVisual && pPixmapPriv->pVisual->format.surface)
540 glitz_format_t *format;
542 format = pPixmapPriv->pVisual->format.surface;
543 if (format->id != pGCPriv->id)
545 XGL_SCREEN_PRIV (pDrawable->pScreen);
547 pGCPriv->flags |= xglGCSoftwareDrawableFlag;
549 if (pGCPriv->fg)
550 glitz_surface_destroy (pGCPriv->fg);
552 pGCPriv->fg = glitz_surface_create (pScreenPriv->drawable,
553 format, 1, 1, 0, NULL);
554 if (pGCPriv->fg)
555 glitz_surface_set_fill (pGCPriv->fg, GLITZ_FILL_REPEAT);
557 if (pGCPriv->bg)
558 glitz_surface_destroy (pGCPriv->bg);
560 pGCPriv->bg = glitz_surface_create (pScreenPriv->drawable,
561 format, 1, 1, 0, NULL);
562 if (pGCPriv->bg)
563 glitz_surface_set_fill (pGCPriv->bg, GLITZ_FILL_REPEAT);
565 pGCPriv->id = format->id;
567 if (pGCPriv->fg && pGCPriv->bg)
569 changes |= (GCForeground | GCBackground);
570 pGCPriv->flags &= ~xglGCSoftwareDrawableFlag;
574 else
575 pGCPriv->flags |= xglGCSoftwareDrawableFlag;
578 if (changes & GCFunction)
580 switch (pGC->alu) {
581 case GXclear:
582 pGCPriv->op = GLITZ_OPERATOR_CLEAR;
583 pGCPriv->flags &= ~xglGCBadFunctionFlag;
584 break;
585 case GXcopy:
586 pGCPriv->op = GLITZ_OPERATOR_SRC;
587 pGCPriv->flags &= ~xglGCBadFunctionFlag;
588 break;
589 case GXnoop:
590 pGCPriv->op = GLITZ_OPERATOR_DST;
591 pGCPriv->flags &= ~xglGCBadFunctionFlag;
592 break;
593 default:
594 pGCPriv->flags |= xglGCBadFunctionFlag;
595 break;
599 if (changes & GCPlaneMask)
601 FbBits mask;
603 mask = FbFullMask (pDrawable->depth);
605 if ((pGC->planemask & mask) != mask)
606 pGCPriv->flags |= xglGCPlaneMaskFlag;
607 else
608 pGCPriv->flags &= ~xglGCPlaneMaskFlag;
611 if (!(pGCPriv->flags & xglGCSoftwareDrawableFlag))
613 if (changes & (GCForeground | GCBackground))
615 glitz_pixel_format_t format;
616 glitz_buffer_t *buffer;
617 CARD32 pixel;
619 XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
621 format.fourcc = GLITZ_FOURCC_RGB;
622 format.masks = pPixmapPriv->pVisual->pPixel->masks;
623 format.xoffset = 0;
624 format.skip_lines = 0;
625 format.bytes_per_line = sizeof (CARD32);
626 format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
628 buffer = glitz_buffer_create_for_data (&pixel);
630 if (changes & GCForeground)
632 pixel = pGC->fgPixel;
633 glitz_set_pixels (pGCPriv->fg, 0, 0, 1, 1, &format, buffer);
636 if (changes & GCBackground)
638 pixel = pGC->bgPixel;
639 glitz_set_pixels (pGCPriv->bg, 0, 0, 1, 1, &format, buffer);
642 glitz_buffer_destroy (buffer);