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
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>
31 #define XGL_GC_OP_FALLBACK_PROLOGUE(pDrawable) \
32 xglSyncDamageBoxBits (pDrawable); \
33 XGL_GC_UNWRAP (funcs); \
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) { \
46 case FillOpaqueStippled: \
47 if (!xglSyncBits (&pGC->stipple->drawable, NullBox)) \
48 FatalError (XGL_SW_FAILURE_STRING); \
51 if (!xglSyncBits (&pGC->tile.pixmap->drawable, NullBox)) \
52 FatalError (XGL_SW_FAILURE_STRING); \
55 XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable)
57 static const GCFuncs xglGCFuncs
= {
67 static const GCOps xglGCOps
= {
91 xglFillSpans (DrawablePtr pDrawable
,
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
);
108 /* xglFillSpan handles fall-back */
109 xglFillSpan (pDrawable
, pGC
, nspans
, ppt
, pwidth
);
114 xglSetSpans (DrawablePtr pDrawable
,
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
);
130 xglPutImage (DrawablePtr pDrawable
,
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
);
152 RegionPtr pClip
= pGC
->pCompositeClip
;
156 XGL_DRAWABLE_PIXMAP (pDrawable
);
158 if (!xglMapPixmapBits (pPixmap
))
159 FatalError (XGL_SW_FAILURE_STRING
);
161 XGL_GC_UNWRAP (funcs
);
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
;
175 REGION_INIT (pDrawable
->pScreen
, ®ion
, &box
, 1);
176 REGION_INTERSECT (pDrawable
->pScreen
, ®ion
, pClip
, ®ion
);
178 xglAddSurfaceDamage (pDrawable
, ®ion
);
180 REGION_UNINIT (pDrawable
->pScreen
, ®ion
);
185 xglCopyArea (DrawablePtr pSrc
,
200 box
.x1
= pSrc
->x
+ srcX
;
201 box
.y1
= pSrc
->y
+ srcY
;
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
);
217 /* xglCopyProc handles fall-back */
218 pRegion
= fbDoCopy (pSrc
, pDst
, pGC
,
230 xglCopyPlane (DrawablePtr pSrc
,
239 unsigned long bitPlane
)
246 box
.x1
= pSrc
->x
+ srcX
;
247 box
.y1
= pSrc
->y
+ srcY
;
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
,
258 XGL_GC_OP_FALLBACK_EPILOGUE (pDst
);
264 xglPolyPoint (DrawablePtr pDrawable
,
272 XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable
);
273 (*pGC
->ops
->PolyPoint
) (pDrawable
, pGC
, mode
, npt
, pptInit
);
274 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable
);
278 xglPolylines (DrawablePtr pDrawable
,
284 if (pGC
->lineWidth
== 0)
290 if (pGC
->lineStyle
== LineSolid
)
292 if (xglFillLine (pDrawable
, pGC
, mode
, npt
, ppt
))
297 XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable
);
298 (*pGC
->ops
->Polylines
) (pDrawable
, pGC
, mode
, npt
, ppt
);
299 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable
);
303 if (pGC
->lineStyle
!= LineSolid
)
304 miWideDash (pDrawable
, pGC
, mode
, npt
, ppt
);
306 miWideLine (pDrawable
, pGC
, mode
, npt
, ppt
);
311 xglPolySegment (DrawablePtr pDrawable
,
316 if (pGC
->lineWidth
== 0)
322 if (pGC
->lineStyle
== LineSolid
)
324 if (xglFillSegment (pDrawable
, pGC
, nsegInit
, pSegInit
))
329 XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable
);
330 (*pGC
->ops
->PolySegment
) (pDrawable
, pGC
, nsegInit
, pSegInit
);
331 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable
);
333 miPolySegment (pDrawable
, pGC
, nsegInit
, pSegInit
);
337 xglPolyArc (DrawablePtr pDrawable
,
342 if (pGC
->lineWidth
== 0)
346 XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable
);
347 (*pGC
->ops
->PolyArc
) (pDrawable
, pGC
, narcs
, pArcs
);
348 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable
);
350 miPolyArc (pDrawable
, pGC
, narcs
, pArcs
);
354 xglPolyFillRect (DrawablePtr pDrawable
,
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
);
369 /* xglFillRect handles fall-back */
370 xglFillRect (pDrawable
, pGC
, nrect
, prect
);
375 xglPolyFillArc (DrawablePtr pDrawable
,
382 XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable
);
383 (*pGC
->ops
->PolyFillArc
) (pDrawable
, pGC
, narcs
, pArcs
);
384 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable
);
388 xglImageGlyphBlt (DrawablePtr pDrawable
,
400 if (xglSolidGlyph (pDrawable
,
410 XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable
);
411 (*pGC
->ops
->ImageGlyphBlt
) (pDrawable
, pGC
, x
, y
, nglyph
, ppci
,
413 XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable
);
417 xglPolyGlyphBlt (DrawablePtr pDrawable
,
429 if (xglFillGlyph (pDrawable
,
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
);
445 xglPushPixels (GCPtr pGC
,
447 DrawablePtr pDrawable
,
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
);
464 xglCreateGC (GCPtr pGC
)
466 ScreenPtr pScreen
= pGC
->pScreen
;
469 XGL_SCREEN_PRIV (pScreen
);
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
);
480 pGCPriv
->op
= GLITZ_OPERATOR_SRC
;
490 xglDestroyGC (GCPtr pGC
)
495 glitz_surface_destroy (pGCPriv
->fg
);
498 glitz_surface_destroy (pGCPriv
->bg
);
500 XGL_GC_UNWRAP (funcs
);
502 (*pGC
->funcs
->DestroyGC
) (pGC
);
503 XGL_GC_WRAP (funcs
, (GCFuncs
*) &xglGCFuncs
);
504 XGL_GC_WRAP (ops
, (GCOps
*) &xglGCOps
);
508 xglValidateGC (GCPtr pGC
,
509 unsigned long changes
,
510 DrawablePtr pDrawable
)
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
)
525 xglSyncBits (&pGC
->stipple
->drawable
, NULL
);
528 XGL_GC_UNWRAP (funcs
);
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
;
550 glitz_surface_destroy (pGCPriv
->fg
);
552 pGCPriv
->fg
= glitz_surface_create (pScreenPriv
->drawable
,
553 format
, 1, 1, 0, NULL
);
555 glitz_surface_set_fill (pGCPriv
->fg
, GLITZ_FILL_REPEAT
);
558 glitz_surface_destroy (pGCPriv
->bg
);
560 pGCPriv
->bg
= glitz_surface_create (pScreenPriv
->drawable
,
561 format
, 1, 1, 0, NULL
);
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
;
575 pGCPriv
->flags
|= xglGCSoftwareDrawableFlag
;
578 if (changes
& GCFunction
)
582 pGCPriv
->op
= GLITZ_OPERATOR_CLEAR
;
583 pGCPriv
->flags
&= ~xglGCBadFunctionFlag
;
586 pGCPriv
->op
= GLITZ_OPERATOR_SRC
;
587 pGCPriv
->flags
&= ~xglGCBadFunctionFlag
;
590 pGCPriv
->op
= GLITZ_OPERATOR_DST
;
591 pGCPriv
->flags
&= ~xglGCBadFunctionFlag
;
594 pGCPriv
->flags
|= xglGCBadFunctionFlag
;
599 if (changes
& GCPlaneMask
)
603 mask
= FbFullMask (pDrawable
->depth
);
605 if ((pGC
->planemask
& mask
) != mask
)
606 pGCPriv
->flags
|= xglGCPlaneMaskFlag
;
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
;
619 XGL_DRAWABLE_PIXMAP_PRIV (pDrawable
);
621 format
.fourcc
= GLITZ_FOURCC_RGB
;
622 format
.masks
= pPixmapPriv
->pVisual
->pPixel
->masks
;
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
);