Home | History | Annotate | Line # | Download | only in cw
      1 /*
      2  * Copyright  2004 Eric Anholt
      3  *
      4  * Permission to use, copy, modify, distribute, and sell this software and its
      5  * documentation for any purpose is hereby granted without fee, provided that
      6  * the above copyright notice appear in all copies and that both that
      7  * copyright notice and this permission notice appear in supporting
      8  * documentation, and that the name of Eric Anholt not be used in
      9  * advertising or publicity pertaining to distribution of the software without
     10  * specific, written prior permission.  Eric Anholt makes no
     11  * representations about the suitability of this software for any purpose.  It
     12  * is provided "as is" without express or implied warranty.
     13  *
     14  * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     16  * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     20  * PERFORMANCE OF THIS SOFTWARE.
     21  */
     22 
     23 #ifdef HAVE_DIX_CONFIG_H
     24 #include <dix-config.h>
     25 #endif
     26 
     27 #include <string.h>
     28 
     29 #include "gcstruct.h"
     30 #include "windowstr.h"
     31 #include "cw.h"
     32 
     33 #define cwPsDecl(pScreen)	\
     34     PictureScreenPtr	ps = GetPictureScreen (pScreen);	\
     35     cwScreenPtr		pCwScreen = getCwScreen (pScreen)
     36 
     37 #define cwPicturePrivate					\
     38     cwPicturePtr    pPicturePrivate = getCwPicture(pPicture)
     39 
     40 #define cwSrcPictureDecl							\
     41     int		    src_picture_x_off, src_picture_y_off;			\
     42     PicturePtr	    pBackingSrcPicture = cwGetBackingPicture(pSrcPicture,	\
     43 							     &src_picture_x_off,\
     44 							     &src_picture_y_off)
     45 
     46 #define cwDstPictureDecl							\
     47     int		    dst_picture_x_off, dst_picture_y_off;			\
     48     PicturePtr	    pBackingDstPicture = cwGetBackingPicture(pDstPicture,	\
     49 							     &dst_picture_x_off,\
     50 							     &dst_picture_y_off)
     51 
     52 #define cwMskPictureDecl							\
     53     int		    msk_picture_x_off = 0, msk_picture_y_off = 0;		\
     54     PicturePtr	    pBackingMskPicture = (!pMskPicture ? 0 :	    		\
     55 					  cwGetBackingPicture(pMskPicture,	\
     56 							      &msk_picture_x_off,\
     57 							      &msk_picture_y_off))
     58 
     59 #define cwPsUnwrap(elt) {	\
     60     ps->elt = pCwScreen->elt;	\
     61 }
     62 
     63 #define cwPsWrap(elt,func) {	\
     64     pCwScreen->elt = ps->elt;	\
     65     ps->elt = func;		\
     66 }
     67 
     68 static cwPicturePtr
     69 cwCreatePicturePrivate (PicturePtr pPicture)
     70 {
     71     WindowPtr	    pWindow = (WindowPtr) pPicture->pDrawable;
     72     PixmapPtr	    pPixmap = getCwPixmap (pWindow);
     73     int		    error;
     74     cwPicturePtr    pPicturePrivate;
     75 
     76     pPicturePrivate = malloc(sizeof (cwPictureRec));
     77     if (!pPicturePrivate)
     78 	return NULL;
     79 
     80     pPicturePrivate->pBackingPicture = CreatePicture (0, &pPixmap->drawable,
     81 						      pPicture->pFormat,
     82 						      0, 0, serverClient,
     83 						      &error);
     84     if (!pPicturePrivate->pBackingPicture)
     85     {
     86 	free(pPicturePrivate);
     87 	return NULL;
     88     }
     89 
     90     /*
     91      * Ensure that this serial number does not match the window's
     92      */
     93     pPicturePrivate->serialNumber = pPixmap->drawable.serialNumber;
     94     pPicturePrivate->stateChanges = (1 << (CPLastBit + 1)) - 1;
     95 
     96     setCwPicture(pPicture, pPicturePrivate);
     97 
     98     return pPicturePrivate;
     99 }
    100 
    101 static void
    102 cwDestroyPicturePrivate (PicturePtr pPicture)
    103 {
    104     cwPicturePrivate;
    105 
    106     if (pPicturePrivate)
    107     {
    108 	if (pPicturePrivate->pBackingPicture)
    109 	    FreePicture (pPicturePrivate->pBackingPicture, 0);
    110 	free(pPicturePrivate);
    111 	setCwPicture(pPicture, NULL);
    112     }
    113 }
    114 
    115 static PicturePtr
    116 cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
    117 {
    118     cwPicturePrivate;
    119 
    120     if (pPicturePrivate)
    121     {
    122 	DrawablePtr pDrawable = pPicture->pDrawable;
    123 	WindowPtr   pWindow = (WindowPtr) pDrawable;
    124 	PixmapPtr   pPixmap = getCwPixmap (pWindow);
    125 
    126 	*x_off = pDrawable->x - pPixmap->screen_x;
    127 	*y_off = pDrawable->y - pPixmap->screen_y;
    128 
    129 	return pPicturePrivate->pBackingPicture;
    130     }
    131     else
    132     {
    133 	*x_off = *y_off = 0;
    134 	return pPicture;
    135     }
    136 }
    137 
    138 static void
    139 cwDestroyPicture (PicturePtr pPicture)
    140 {
    141     ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
    142     cwPsDecl(pScreen);
    143 
    144     cwPsUnwrap(DestroyPicture);
    145     cwDestroyPicturePrivate (pPicture);
    146     (*ps->DestroyPicture) (pPicture);
    147     cwPsWrap(DestroyPicture, cwDestroyPicture);
    148 }
    149 
    150 static void
    151 cwChangePicture (PicturePtr pPicture, Mask mask)
    152 {
    153     ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
    154     cwPsDecl(pScreen);
    155     cwPicturePtr	pPicturePrivate = getCwPicture(pPicture);
    156 
    157     cwPsUnwrap(ChangePicture);
    158     (*ps->ChangePicture) (pPicture, mask);
    159     if (pPicturePrivate)
    160 	pPicturePrivate->stateChanges |= mask;
    161     cwPsWrap(ChangePicture, cwChangePicture);
    162 }
    163 
    164 
    165 static void
    166 cwValidatePicture (PicturePtr pPicture,
    167 		   Mask       mask)
    168 {
    169     DrawablePtr		pDrawable = pPicture->pDrawable;
    170     ScreenPtr		pScreen = pDrawable->pScreen;
    171     cwPsDecl(pScreen);
    172     cwPicturePrivate;
    173 
    174     cwPsUnwrap(ValidatePicture);
    175 
    176     /*
    177      * Must call ValidatePicture to ensure pPicture->pCompositeClip is valid
    178      */
    179     (*ps->ValidatePicture) (pPicture, mask);
    180 
    181     if (!cwDrawableIsRedirWindow (pDrawable))
    182     {
    183 	if (pPicturePrivate)
    184 	    cwDestroyPicturePrivate (pPicture);
    185     }
    186     else
    187     {
    188 	PicturePtr  pBackingPicture;
    189 	DrawablePtr pBackingDrawable;
    190 	int	    x_off, y_off;
    191 
    192 	pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
    193 
    194 	if (pPicturePrivate &&
    195 	    pPicturePrivate->pBackingPicture->pDrawable != pBackingDrawable)
    196 	{
    197 	    cwDestroyPicturePrivate (pPicture);
    198 	    pPicturePrivate = 0;
    199 	}
    200 
    201 	if (!pPicturePrivate)
    202 	{
    203 	    pPicturePrivate = cwCreatePicturePrivate (pPicture);
    204 	    if (!pPicturePrivate)
    205 	    {
    206 		cwPsWrap(ValidatePicture, cwValidatePicture);
    207 		return;
    208 	    }
    209 	}
    210 
    211 	pBackingPicture = pPicturePrivate->pBackingPicture;
    212 
    213 	/*
    214 	 * Always copy transform and filters because there's no
    215 	 * indication of when they've changed
    216 	 */
    217 	SetPictureTransform(pBackingPicture, pPicture->transform);
    218 
    219 	if (pBackingPicture->filter != pPicture->filter ||
    220 	    pPicture->filter_nparams > 0)
    221 	{
    222 	    char    *filter = PictureGetFilterName (pPicture->filter);
    223 
    224 	    SetPictureFilter(pBackingPicture,
    225 			     filter, strlen (filter),
    226 			     pPicture->filter_params,
    227 			     pPicture->filter_nparams);
    228 	}
    229 
    230 	pPicturePrivate->stateChanges |= mask;
    231 
    232 	if (pPicturePrivate->serialNumber != pDrawable->serialNumber ||
    233 	    (pPicturePrivate->stateChanges & (CPClipXOrigin|CPClipYOrigin|CPClipMask)))
    234 	{
    235 	    SetPictureClipRegion (pBackingPicture,
    236 				  x_off - pDrawable->x,
    237 				  y_off - pDrawable->y,
    238 				  pPicture->pCompositeClip);
    239 
    240 	    pPicturePrivate->serialNumber = pDrawable->serialNumber;
    241 	    pPicturePrivate->stateChanges &= ~(CPClipXOrigin | CPClipYOrigin | CPClipMask);
    242 	}
    243 
    244 	CopyPicture(pPicture, pPicturePrivate->stateChanges, pBackingPicture);
    245 
    246 	ValidatePicture (pBackingPicture);
    247     }
    248     cwPsWrap(ValidatePicture, cwValidatePicture);
    249 }
    250 
    251 static void
    252 cwComposite (CARD8	op,
    253 	     PicturePtr pSrcPicture,
    254 	     PicturePtr pMskPicture,
    255 	     PicturePtr pDstPicture,
    256 	     INT16	xSrc,
    257 	     INT16	ySrc,
    258 	     INT16	xMsk,
    259 	     INT16	yMsk,
    260 	     INT16	xDst,
    261 	     INT16	yDst,
    262 	     CARD16	width,
    263 	     CARD16	height)
    264 {
    265     ScreenPtr	pScreen = pDstPicture->pDrawable->pScreen;
    266     cwPsDecl(pScreen);
    267     cwSrcPictureDecl;
    268     cwMskPictureDecl;
    269     cwDstPictureDecl;
    270 
    271     cwPsUnwrap(Composite);
    272     (*ps->Composite) (op, pBackingSrcPicture, pBackingMskPicture, pBackingDstPicture,
    273 		      xSrc + src_picture_x_off, ySrc + src_picture_y_off,
    274 		      xMsk + msk_picture_x_off, yMsk + msk_picture_y_off,
    275 		      xDst + dst_picture_x_off, yDst + dst_picture_y_off,
    276 		      width, height);
    277     cwPsWrap(Composite, cwComposite);
    278 }
    279 
    280 static void
    281 cwCompositeRects (CARD8		op,
    282 		  PicturePtr	pDstPicture,
    283 		  xRenderColor  *color,
    284 		  int		nRect,
    285 		  xRectangle	*rects)
    286 {
    287     ScreenPtr	pScreen = pDstPicture->pDrawable->pScreen;
    288     cwPsDecl(pScreen);
    289     cwDstPictureDecl;
    290     int i;
    291 
    292     cwPsUnwrap(CompositeRects);
    293     for (i = 0; i < nRect; i++)
    294     {
    295 	rects[i].x += dst_picture_x_off;
    296 	rects[i].y += dst_picture_y_off;
    297     }
    298     (*ps->CompositeRects) (op, pBackingDstPicture, color, nRect, rects);
    299     cwPsWrap(CompositeRects, cwCompositeRects);
    300 }
    301 
    302 static void
    303 cwTrapezoids (CARD8	    op,
    304 	      PicturePtr    pSrcPicture,
    305 	      PicturePtr    pDstPicture,
    306 	      PictFormatPtr maskFormat,
    307 	      INT16	    xSrc,
    308 	      INT16	    ySrc,
    309 	      int	    ntrap,
    310 	      xTrapezoid    *traps)
    311 {
    312     ScreenPtr	pScreen = pDstPicture->pDrawable->pScreen;
    313     cwPsDecl(pScreen);
    314     cwSrcPictureDecl;
    315     cwDstPictureDecl;
    316     int i;
    317 
    318     cwPsUnwrap(Trapezoids);
    319     if (dst_picture_x_off || dst_picture_y_off) {
    320 	for (i = 0; i < ntrap; i++)
    321 	{
    322 	    traps[i].top += dst_picture_y_off << 16;
    323 	    traps[i].bottom += dst_picture_y_off << 16;
    324 	    traps[i].left.p1.x += dst_picture_x_off << 16;
    325 	    traps[i].left.p1.y += dst_picture_y_off << 16;
    326 	    traps[i].left.p2.x += dst_picture_x_off << 16;
    327 	    traps[i].left.p2.y += dst_picture_y_off << 16;
    328 	    traps[i].right.p1.x += dst_picture_x_off << 16;
    329 	    traps[i].right.p1.y += dst_picture_y_off << 16;
    330 	    traps[i].right.p2.x += dst_picture_x_off << 16;
    331 	    traps[i].right.p2.y += dst_picture_y_off << 16;
    332 	}
    333     }
    334     (*ps->Trapezoids) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
    335 		       xSrc + src_picture_x_off, ySrc + src_picture_y_off,
    336 		       ntrap, traps);
    337     cwPsWrap(Trapezoids, cwTrapezoids);
    338 }
    339 
    340 static void
    341 cwTriangles (CARD8	    op,
    342 	     PicturePtr	    pSrcPicture,
    343 	     PicturePtr	    pDstPicture,
    344 	     PictFormatPtr  maskFormat,
    345 	     INT16	    xSrc,
    346 	     INT16	    ySrc,
    347 	     int	    ntri,
    348 	     xTriangle	   *tris)
    349 {
    350     ScreenPtr	pScreen = pDstPicture->pDrawable->pScreen;
    351     cwPsDecl(pScreen);
    352     cwSrcPictureDecl;
    353     cwDstPictureDecl;
    354     int i;
    355 
    356     cwPsUnwrap(Triangles);
    357     if (dst_picture_x_off || dst_picture_y_off) {
    358 	for (i = 0; i < ntri; i++)
    359 	{
    360 	    tris[i].p1.x += dst_picture_x_off << 16;
    361 	    tris[i].p1.y += dst_picture_y_off << 16;
    362 	    tris[i].p2.x += dst_picture_x_off << 16;
    363 	    tris[i].p2.y += dst_picture_y_off << 16;
    364 	    tris[i].p3.x += dst_picture_x_off << 16;
    365 	    tris[i].p3.y += dst_picture_y_off << 16;
    366 	}
    367     }
    368     (*ps->Triangles) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
    369 		      xSrc + src_picture_x_off, ySrc + src_picture_y_off,
    370 		      ntri, tris);
    371     cwPsWrap(Triangles, cwTriangles);
    372 }
    373 
    374 static void
    375 cwTriStrip (CARD8	    op,
    376 	    PicturePtr	    pSrcPicture,
    377 	    PicturePtr	    pDstPicture,
    378 	    PictFormatPtr   maskFormat,
    379 	    INT16	    xSrc,
    380 	    INT16	    ySrc,
    381 	    int		    npoint,
    382 	    xPointFixed    *points)
    383 {
    384     ScreenPtr	pScreen = pDstPicture->pDrawable->pScreen;
    385     cwPsDecl(pScreen);
    386     cwSrcPictureDecl;
    387     cwDstPictureDecl;
    388     int i;
    389 
    390     cwPsUnwrap(TriStrip);
    391     if (dst_picture_x_off || dst_picture_y_off) {
    392 	for (i = 0; i < npoint; i++)
    393 	{
    394 	    points[i].x += dst_picture_x_off << 16;
    395 	    points[i].y += dst_picture_y_off << 16;
    396 	}
    397     }
    398     (*ps->TriStrip) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
    399 		     xSrc + src_picture_x_off, ySrc + src_picture_y_off,
    400 		     npoint, points);
    401     cwPsWrap(TriStrip, cwTriStrip);
    402 }
    403 
    404 static void
    405 cwTriFan (CARD8		 op,
    406 	  PicturePtr	 pSrcPicture,
    407 	  PicturePtr	 pDstPicture,
    408 	  PictFormatPtr  maskFormat,
    409 	  INT16		 xSrc,
    410 	  INT16		 ySrc,
    411 	  int		 npoint,
    412 	  xPointFixed   *points)
    413 {
    414     ScreenPtr	pScreen = pDstPicture->pDrawable->pScreen;
    415     cwPsDecl(pScreen);
    416     cwSrcPictureDecl;
    417     cwDstPictureDecl;
    418     int i;
    419 
    420     cwPsUnwrap(TriFan);
    421     if (dst_picture_x_off || dst_picture_y_off) {
    422 	for (i = 0; i < npoint; i++)
    423 	{
    424 	    points[i].x += dst_picture_x_off << 16;
    425 	    points[i].y += dst_picture_y_off << 16;
    426 	}
    427     }
    428     (*ps->TriFan) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
    429 		   xSrc + src_picture_x_off, ySrc + src_picture_y_off,
    430 		   npoint, points);
    431     cwPsWrap(TriFan, cwTriFan);
    432 }
    433 
    434 void
    435 cwInitializeRender (ScreenPtr pScreen)
    436 {
    437     cwPsDecl (pScreen);
    438 
    439     cwPsWrap(DestroyPicture, cwDestroyPicture);
    440     cwPsWrap(ChangePicture, cwChangePicture);
    441     cwPsWrap(ValidatePicture, cwValidatePicture);
    442     cwPsWrap(Composite, cwComposite);
    443     cwPsWrap(CompositeRects, cwCompositeRects);
    444     cwPsWrap(Trapezoids, cwTrapezoids);
    445     cwPsWrap(Triangles, cwTriangles);
    446     cwPsWrap(TriStrip, cwTriStrip);
    447     cwPsWrap(TriFan, cwTriFan);
    448     /* There is no need to wrap AddTraps as far as we can tell.  AddTraps can
    449      * only be done on alpha-only pictures, and we won't be getting
    450      * alpha-only window pictures, so there's no need to translate.
    451      */
    452 }
    453 
    454 void
    455 cwFiniRender (ScreenPtr pScreen)
    456 {
    457     cwPsDecl (pScreen);
    458 
    459     cwPsUnwrap(DestroyPicture);
    460     cwPsUnwrap(ChangePicture);
    461     cwPsUnwrap(ValidatePicture);
    462     cwPsUnwrap(Composite);
    463     cwPsUnwrap(CompositeRects);
    464     cwPsUnwrap(Trapezoids);
    465     cwPsUnwrap(Triangles);
    466     cwPsUnwrap(TriStrip);
    467     cwPsUnwrap(TriFan);
    468 }
    469 
    470