cw_render.c revision 706f2543
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 68static cwPicturePtr 69cwCreatePicturePrivate (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 101static void 102cwDestroyPicturePrivate (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 115static PicturePtr 116cwGetBackingPicture (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 138static void 139cwDestroyPicture (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 150static void 151cwChangePicture (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 165static void 166cwValidatePicture (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 251static void 252cwComposite (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 280static void 281cwCompositeRects (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 302static void 303cwTrapezoids (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 340static void 341cwTriangles (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 374static void 375cwTriStrip (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 404static void 405cwTriFan (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 434void 435cwInitializeRender (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 454void 455cwFiniRender (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