~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to miext/cw/cw_render.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
/* $Header: /cvs/xorg/xserver/xorg/miext/cw/cw_render.c,v 1.14 2005/07/03 07:02:01 daniels Exp $ */
 
23
 
 
24
#ifdef HAVE_DIX_CONFIG_H
 
25
#include <dix-config.h>
 
26
#endif
 
27
 
 
28
#include "gcstruct.h"
 
29
#include "windowstr.h"
 
30
#include "cw.h"
 
31
 
 
32
#ifdef RENDER
 
33
 
 
34
#define cwPsDecl(pScreen)       \
 
35
    PictureScreenPtr    ps = GetPictureScreen (pScreen);        \
 
36
    cwScreenPtr         pCwScreen = getCwScreen (pScreen)
 
37
 
 
38
#define cwPicturePrivate                                        \
 
39
    cwPicturePtr    pPicturePrivate = getCwPicture(pPicture)
 
40
 
 
41
#define cwSrcPictureDecl                                                        \
 
42
    int             src_picture_x_off, src_picture_y_off;                       \
 
43
    PicturePtr      pBackingSrcPicture = cwGetBackingPicture(pSrcPicture,       \
 
44
                                                             &src_picture_x_off,\
 
45
                                                             &src_picture_y_off)
 
46
 
 
47
#define cwDstPictureDecl                                                        \
 
48
    int             dst_picture_x_off, dst_picture_y_off;                       \
 
49
    PicturePtr      pBackingDstPicture = cwGetBackingPicture(pDstPicture,       \
 
50
                                                             &dst_picture_x_off,\
 
51
                                                             &dst_picture_y_off)
 
52
 
 
53
#define cwMskPictureDecl                                                        \
 
54
    int             msk_picture_x_off = 0, msk_picture_y_off = 0;               \
 
55
    PicturePtr      pBackingMskPicture = (!pMskPicture ? 0 :                    \
 
56
                                          cwGetBackingPicture(pMskPicture,      \
 
57
                                                              &msk_picture_x_off,\
 
58
                                                              &msk_picture_y_off))
 
59
 
 
60
#define cwPsUnwrap(elt) {       \
 
61
    ps->elt = pCwScreen->elt;   \
 
62
}
 
63
 
 
64
#define cwPsWrap(elt,func) {    \
 
65
    pCwScreen->elt = ps->elt;   \
 
66
    ps->elt = func;             \
 
67
}
 
68
 
 
69
static cwPicturePtr
 
70
cwCreatePicturePrivate (PicturePtr pPicture)
 
71
{
 
72
    WindowPtr       pWindow = (WindowPtr) pPicture->pDrawable;
 
73
    PixmapPtr       pPixmap = getCwPixmap (pWindow);
 
74
    int             error;
 
75
    cwPicturePtr    pPicturePrivate;
 
76
 
 
77
    pPicturePrivate = xalloc (sizeof (cwPictureRec));
 
78
    if (!pPicturePrivate)
 
79
        return NULL;
 
80
    
 
81
    pPicturePrivate->pBackingPicture = CreatePicture (0, &pPixmap->drawable, 
 
82
                                                      pPicture->pFormat,
 
83
                                                      0, 0, serverClient,
 
84
                                                      &error);
 
85
    if (!pPicturePrivate->pBackingPicture)
 
86
    {
 
87
        xfree (pPicturePrivate);
 
88
        return NULL;
 
89
    }
 
90
 
 
91
    /*
 
92
     * Ensure that this serial number does not match the window's
 
93
     */
 
94
    pPicturePrivate->serialNumber = pPixmap->drawable.serialNumber;
 
95
    pPicturePrivate->stateChanges = (1 << (CPLastBit + 1)) - 1;
 
96
    
 
97
    setCwPicture(pPicture, pPicturePrivate);
 
98
 
 
99
    return pPicturePrivate;
 
100
}
 
101
 
 
102
static void
 
103
cwDestroyPicturePrivate (PicturePtr pPicture)
 
104
{
 
105
    cwPicturePrivate;
 
106
 
 
107
    if (pPicturePrivate)
 
108
    {
 
109
        if (pPicturePrivate->pBackingPicture)
 
110
            FreePicture (pPicturePrivate->pBackingPicture, 0);
 
111
        xfree (pPicturePrivate);
 
112
        setCwPicture(pPicture, NULL);
 
113
    }
 
114
}
 
115
 
 
116
static PicturePtr
 
117
cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
 
118
{
 
119
    cwPicturePrivate;
 
120
 
 
121
    if (pPicturePrivate)
 
122
    {
 
123
        DrawablePtr pDrawable = pPicture->pDrawable;
 
124
        WindowPtr   pWindow = (WindowPtr) pDrawable;
 
125
        PixmapPtr   pPixmap = getCwPixmap (pWindow);
 
126
 
 
127
        *x_off = pDrawable->x - pPixmap->screen_x;
 
128
        *y_off = pDrawable->y - pPixmap->screen_y;
 
129
 
 
130
        return pPicturePrivate->pBackingPicture;
 
131
    }
 
132
    else
 
133
    {
 
134
        *x_off = *y_off = 0;
 
135
        return pPicture;
 
136
    }
 
137
}
 
138
    
 
139
static void
 
140
cwDestroyPicture (PicturePtr pPicture)
 
141
{
 
142
    ScreenPtr           pScreen = pPicture->pDrawable->pScreen;
 
143
    cwPsDecl(pScreen);
 
144
    
 
145
    cwPsUnwrap(DestroyPicture);
 
146
    cwDestroyPicturePrivate (pPicture);
 
147
    (*ps->DestroyPicture) (pPicture);
 
148
    cwPsWrap(DestroyPicture, cwDestroyPicture);
 
149
}
 
150
 
 
151
static void
 
152
cwChangePicture (PicturePtr pPicture, Mask mask)
 
153
{
 
154
    ScreenPtr           pScreen = pPicture->pDrawable->pScreen;
 
155
    cwPsDecl(pScreen);
 
156
    cwPicturePtr        pPicturePrivate = getCwPicture(pPicture);
 
157
    
 
158
    cwPsUnwrap(ChangePicture);
 
159
    (*ps->ChangePicture) (pPicture, mask);
 
160
    if (pPicturePrivate)
 
161
        pPicturePrivate->stateChanges |= mask;
 
162
    cwPsWrap(ChangePicture, cwChangePicture);
 
163
}
 
164
 
 
165
 
 
166
static void
 
167
cwValidatePicture (PicturePtr pPicture,
 
168
                   Mask       mask)
 
169
{
 
170
    DrawablePtr         pDrawable = pPicture->pDrawable;
 
171
    ScreenPtr           pScreen = pDrawable->pScreen;
 
172
    cwPsDecl(pScreen);
 
173
    cwPicturePrivate;
 
174
    
 
175
    cwPsUnwrap(ValidatePicture);
 
176
 
 
177
    /*
 
178
     * Must call ValidatePicture to ensure pPicture->pCompositeClip is valid
 
179
     */
 
180
    (*ps->ValidatePicture) (pPicture, mask);
 
181
    
 
182
    if (!cwDrawableIsRedirWindow (pDrawable))
 
183
    {
 
184
        if (pPicturePrivate)
 
185
            cwDestroyPicturePrivate (pPicture);
 
186
    }
 
187
    else
 
188
    {
 
189
        PicturePtr  pBackingPicture;
 
190
        DrawablePtr pBackingDrawable;
 
191
        int         x_off, y_off;
 
192
        
 
193
        pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
 
194
 
 
195
        if (pPicturePrivate && 
 
196
            pPicturePrivate->pBackingPicture->pDrawable != pBackingDrawable)
 
197
        {
 
198
            cwDestroyPicturePrivate (pPicture);
 
199
            pPicturePrivate = 0;
 
200
        }
 
201
 
 
202
        if (!pPicturePrivate)
 
203
        {
 
204
            pPicturePrivate = cwCreatePicturePrivate (pPicture);
 
205
            if (!pPicturePrivate)
 
206
            {
 
207
                cwPsWrap(ValidatePicture, cwValidatePicture);
 
208
                return;
 
209
            }
 
210
        }
 
211
 
 
212
        pBackingPicture = pPicturePrivate->pBackingPicture;
 
213
 
 
214
        /*
 
215
         * Always copy transform and filters because there's no
 
216
         * indication of when they've changed
 
217
         */
 
218
        SetPictureTransform(pBackingPicture, pPicture->transform);
 
219
        
 
220
        if (pBackingPicture->filter != pPicture->filter ||
 
221
            pPicture->filter_nparams > 0)
 
222
        {
 
223
            char    *filter = PictureGetFilterName (pPicture->filter);
 
224
            
 
225
            SetPictureFilter(pBackingPicture,
 
226
                             filter, strlen (filter),
 
227
                             pPicture->filter_params,
 
228
                             pPicture->filter_nparams);
 
229
        }
 
230
 
 
231
        pPicturePrivate->stateChanges |= mask;
 
232
 
 
233
        if (pPicturePrivate->serialNumber != pDrawable->serialNumber ||
 
234
            (pPicturePrivate->stateChanges & (CPClipXOrigin|CPClipYOrigin|CPClipMask)))
 
235
        {
 
236
            SetPictureClipRegion (pBackingPicture, 
 
237
                                  x_off - pDrawable->x,
 
238
                                  y_off - pDrawable->y,
 
239
                                  pPicture->pCompositeClip);
 
240
    
 
241
            pPicturePrivate->serialNumber = pDrawable->serialNumber;
 
242
            pPicturePrivate->stateChanges &= ~(CPClipXOrigin | CPClipYOrigin | CPClipMask);
 
243
        }
 
244
 
 
245
        CopyPicture(pPicture, pPicturePrivate->stateChanges, pBackingPicture);
 
246
 
 
247
        ValidatePicture (pBackingPicture);
 
248
    }
 
249
    cwPsWrap(ValidatePicture, cwValidatePicture);
 
250
}
 
251
 
 
252
static void
 
253
cwComposite (CARD8      op,
 
254
             PicturePtr pSrcPicture,
 
255
             PicturePtr pMskPicture,
 
256
             PicturePtr pDstPicture,
 
257
             INT16      xSrc,
 
258
             INT16      ySrc,
 
259
             INT16      xMsk,
 
260
             INT16      yMsk,
 
261
             INT16      xDst,
 
262
             INT16      yDst,
 
263
             CARD16     width,
 
264
             CARD16     height)
 
265
{
 
266
    ScreenPtr   pScreen = pDstPicture->pDrawable->pScreen;
 
267
    cwPsDecl(pScreen);
 
268
    cwSrcPictureDecl;
 
269
    cwMskPictureDecl;
 
270
    cwDstPictureDecl;
 
271
    
 
272
    cwPsUnwrap(Composite);
 
273
    (*ps->Composite) (op, pBackingSrcPicture, pBackingMskPicture, pBackingDstPicture,
 
274
                      xSrc + src_picture_x_off, ySrc + src_picture_y_off,
 
275
                      xMsk + msk_picture_x_off, yMsk + msk_picture_y_off,
 
276
                      xDst + dst_picture_x_off, yDst + dst_picture_y_off,
 
277
                      width, height);
 
278
    cwPsWrap(Composite, cwComposite);
 
279
}
 
280
 
 
281
static void
 
282
cwGlyphs (CARD8      op,
 
283
          PicturePtr pSrcPicture,
 
284
          PicturePtr pDstPicture,
 
285
          PictFormatPtr  maskFormat,
 
286
          INT16      xSrc,
 
287
          INT16      ySrc,
 
288
          int   nlists,
 
289
          GlyphListPtr   lists,
 
290
          GlyphPtr      *glyphs)
 
291
{
 
292
    ScreenPtr   pScreen = pDstPicture->pDrawable->pScreen;
 
293
    cwPsDecl(pScreen);
 
294
    cwSrcPictureDecl;
 
295
    cwDstPictureDecl;
 
296
    
 
297
    cwPsUnwrap(Glyphs);
 
298
    if (nlists)
 
299
    {
 
300
        lists->xOff += dst_picture_x_off;
 
301
        lists->yOff += dst_picture_y_off;
 
302
    }
 
303
    (*ps->Glyphs) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
 
304
                   xSrc + src_picture_x_off, ySrc + src_picture_y_off,
 
305
                   nlists, lists, glyphs);
 
306
    cwPsWrap(Glyphs, cwGlyphs);
 
307
}
 
308
 
 
309
static void
 
310
cwCompositeRects (CARD8         op,
 
311
                  PicturePtr    pDstPicture,
 
312
                  xRenderColor  *color,
 
313
                  int           nRect,
 
314
                  xRectangle    *rects)
 
315
{
 
316
    ScreenPtr   pScreen = pDstPicture->pDrawable->pScreen;
 
317
    cwPsDecl(pScreen);
 
318
    cwDstPictureDecl;
 
319
    int i;
 
320
    
 
321
    cwPsUnwrap(CompositeRects);
 
322
    for (i = 0; i < nRect; i++)
 
323
    {
 
324
        rects[i].x += dst_picture_x_off;
 
325
        rects[i].y += dst_picture_y_off;
 
326
    }
 
327
    (*ps->CompositeRects) (op, pBackingDstPicture, color, nRect, rects);
 
328
    cwPsWrap(CompositeRects, cwCompositeRects);
 
329
}
 
330
 
 
331
static void
 
332
cwTrapezoids (CARD8         op,
 
333
              PicturePtr    pSrcPicture,
 
334
              PicturePtr    pDstPicture,
 
335
              PictFormatPtr maskFormat,
 
336
              INT16         xSrc,
 
337
              INT16         ySrc,
 
338
              int           ntrap,
 
339
              xTrapezoid    *traps)
 
340
{
 
341
    ScreenPtr   pScreen = pDstPicture->pDrawable->pScreen;
 
342
    cwPsDecl(pScreen);
 
343
    cwSrcPictureDecl;
 
344
    cwDstPictureDecl;
 
345
    int i;
 
346
    
 
347
    cwPsUnwrap(Trapezoids);
 
348
    if (dst_picture_x_off || dst_picture_y_off) {
 
349
        for (i = 0; i < ntrap; i++)
 
350
        {
 
351
            traps[i].top += dst_picture_y_off << 16;
 
352
            traps[i].bottom += dst_picture_y_off << 16;
 
353
            traps[i].left.p1.x += dst_picture_x_off << 16;
 
354
            traps[i].left.p1.y += dst_picture_y_off << 16;
 
355
            traps[i].left.p2.x += dst_picture_x_off << 16;
 
356
            traps[i].left.p2.y += dst_picture_y_off << 16;
 
357
            traps[i].right.p1.x += dst_picture_x_off << 16;
 
358
            traps[i].right.p1.y += dst_picture_y_off << 16;
 
359
            traps[i].right.p2.x += dst_picture_x_off << 16;
 
360
            traps[i].right.p2.y += dst_picture_y_off << 16;
 
361
        }
 
362
    }
 
363
    (*ps->Trapezoids) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
 
364
                       xSrc + src_picture_x_off, ySrc + src_picture_y_off,
 
365
                       ntrap, traps);
 
366
    cwPsWrap(Trapezoids, cwTrapezoids);
 
367
}
 
368
 
 
369
static void
 
370
cwTriangles (CARD8          op,
 
371
             PicturePtr     pSrcPicture,
 
372
             PicturePtr     pDstPicture,
 
373
             PictFormatPtr  maskFormat,
 
374
             INT16          xSrc,
 
375
             INT16          ySrc,
 
376
             int            ntri,
 
377
             xTriangle     *tris)
 
378
{
 
379
    ScreenPtr   pScreen = pDstPicture->pDrawable->pScreen;
 
380
    cwPsDecl(pScreen);
 
381
    cwSrcPictureDecl;
 
382
    cwDstPictureDecl;
 
383
    int i;
 
384
    
 
385
    cwPsUnwrap(Triangles);
 
386
    if (dst_picture_x_off || dst_picture_y_off) {
 
387
        for (i = 0; i < ntri; i++)
 
388
        {
 
389
            tris[i].p1.x += dst_picture_x_off << 16;
 
390
            tris[i].p1.y += dst_picture_y_off << 16;
 
391
            tris[i].p2.x += dst_picture_x_off << 16;
 
392
            tris[i].p2.y += dst_picture_y_off << 16;
 
393
            tris[i].p3.x += dst_picture_x_off << 16;
 
394
            tris[i].p3.y += dst_picture_y_off << 16;
 
395
        }
 
396
    }
 
397
    (*ps->Triangles) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
 
398
                      xSrc + src_picture_x_off, ySrc + src_picture_y_off,
 
399
                      ntri, tris);
 
400
    cwPsWrap(Triangles, cwTriangles);
 
401
}
 
402
 
 
403
static void
 
404
cwTriStrip (CARD8           op,
 
405
            PicturePtr      pSrcPicture,
 
406
            PicturePtr      pDstPicture,
 
407
            PictFormatPtr   maskFormat,
 
408
            INT16           xSrc,
 
409
            INT16           ySrc,
 
410
            int             npoint,
 
411
            xPointFixed    *points)
 
412
{
 
413
    ScreenPtr   pScreen = pDstPicture->pDrawable->pScreen;
 
414
    cwPsDecl(pScreen);
 
415
    cwSrcPictureDecl;
 
416
    cwDstPictureDecl;
 
417
    int i;
 
418
 
 
419
    cwPsUnwrap(TriStrip);
 
420
    if (dst_picture_x_off || dst_picture_y_off) {
 
421
        for (i = 0; i < npoint; i++)
 
422
        {
 
423
            points[i].x += dst_picture_x_off << 16;
 
424
            points[i].y += dst_picture_y_off << 16;
 
425
        }
 
426
    }
 
427
    (*ps->TriStrip) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
 
428
                     xSrc + src_picture_x_off, ySrc + src_picture_y_off,
 
429
                     npoint, points);
 
430
    cwPsWrap(TriStrip, cwTriStrip);
 
431
}
 
432
 
 
433
static void
 
434
cwTriFan (CARD8          op,
 
435
          PicturePtr     pSrcPicture,
 
436
          PicturePtr     pDstPicture,
 
437
          PictFormatPtr  maskFormat,
 
438
          INT16          xSrc,
 
439
          INT16          ySrc,
 
440
          int            npoint,
 
441
          xPointFixed   *points)
 
442
{
 
443
    ScreenPtr   pScreen = pDstPicture->pDrawable->pScreen;
 
444
    cwPsDecl(pScreen);
 
445
    cwSrcPictureDecl;
 
446
    cwDstPictureDecl;
 
447
    int i;
 
448
 
 
449
    cwPsUnwrap(TriFan);
 
450
    if (dst_picture_x_off || dst_picture_y_off) {
 
451
        for (i = 0; i < npoint; i++)
 
452
        {
 
453
            points[i].x += dst_picture_x_off << 16;
 
454
            points[i].y += dst_picture_y_off << 16;
 
455
        }
 
456
    }
 
457
    (*ps->TriFan) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
 
458
                   xSrc + src_picture_x_off, ySrc + src_picture_y_off,
 
459
                   npoint, points);
 
460
    cwPsWrap(TriFan, cwTriFan);
 
461
}
 
462
 
 
463
void
 
464
cwInitializeRender (ScreenPtr pScreen)
 
465
{
 
466
    cwPsDecl (pScreen);
 
467
 
 
468
    cwPsWrap(DestroyPicture, cwDestroyPicture);
 
469
    cwPsWrap(ChangePicture, cwChangePicture);
 
470
    cwPsWrap(ValidatePicture, cwValidatePicture);
 
471
    cwPsWrap(Composite, cwComposite);
 
472
    cwPsWrap(Glyphs, cwGlyphs);
 
473
    cwPsWrap(CompositeRects, cwCompositeRects);
 
474
    cwPsWrap(Trapezoids, cwTrapezoids);
 
475
    cwPsWrap(Triangles, cwTriangles);
 
476
    cwPsWrap(TriStrip, cwTriStrip);
 
477
    cwPsWrap(TriFan, cwTriFan);
 
478
    /* There is no need to wrap AddTraps as far as we can tell.  AddTraps can
 
479
     * only be done on alpha-only pictures, and we won't be getting
 
480
     * alpha-only window pictures, so there's no need to translate.
 
481
     */
 
482
}
 
483
 
 
484
void
 
485
cwFiniRender (ScreenPtr pScreen)
 
486
{
 
487
    cwPsDecl (pScreen);
 
488
 
 
489
    cwPsUnwrap(DestroyPicture);
 
490
    cwPsUnwrap(ChangePicture);
 
491
    cwPsUnwrap(ValidatePicture);
 
492
    cwPsUnwrap(Composite);
 
493
    cwPsUnwrap(Glyphs);
 
494
    cwPsUnwrap(CompositeRects);
 
495
    cwPsUnwrap(Trapezoids);
 
496
    cwPsUnwrap(Triangles);
 
497
    cwPsUnwrap(TriStrip);
 
498
    cwPsUnwrap(TriFan);
 
499
}
 
500
 
 
501
#endif /* RENDER */