~gma500/+junk/gma500-maverick

« back to all changes in this revision

Viewing changes to xserver-xorg-video-psb/src/psb_composite.c

  • Committer: Luca Forina
  • Date: 2011-02-14 09:55:00 UTC
  • Revision ID: luca.forina@gmail.com-20110214095500-kq7o333fbjuoquqs
new commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 *
 
3
 * Copyright (c) Intel Corp. 2007.
 
4
 * All Rights Reserved.
 
5
 *
 
6
 * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
 
7
 * develop this driver.
 
8
 *
 
9
 * Permission is hereby granted, free of charge, to any person obtaining a
 
10
 * copy of this software and associated documentation files (the
 
11
 * "Software"), to deal in the Software without restriction, including
 
12
 * without limitation the rights to use, copy, modify, merge, publish,
 
13
 * distribute, sub license, and/or sell copies of the Software, and to
 
14
 * permit persons to whom the Software is furnished to do so, subject to
 
15
 * the following conditions:
 
16
 *
 
17
 * The above copyright notice and this permission notice (including the
 
18
 * next paragraph) shall be included in all copies or substantial portions
 
19
 * of the Software.
 
20
 *
 
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
22
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 
24
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
 
25
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
26
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 
27
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 
28
 *
 
29
 **************************************************************************/
 
30
/*
 
31
 * Authors:
 
32
 *   Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
 
33
 */
 
34
 
 
35
#ifdef HAVE_CONFIG_H
 
36
#include "config.h"
 
37
#endif
 
38
 
 
39
#include <sys/time.h>
 
40
#include <picturestr.h>
 
41
#include <psb_reg.h>
 
42
#include "psb_accel.h"
 
43
#include "psb_driver.h"
 
44
 
 
45
static Bool psbSupportDstA0[] =
 
46
    { TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE,
 
47
    FALSE, FALSE, FALSE, TRUE, FALSE
 
48
};
 
49
 
 
50
static Bool
 
51
psbIsPot(unsigned int val)
 
52
{
 
53
    unsigned int test = 0x1;
 
54
 
 
55
    if (!val)
 
56
        return FALSE;
 
57
 
 
58
    while ((val & test) == 0)
 
59
        test <<= 1;
 
60
 
 
61
    return val == test;
 
62
}
 
63
 
 
64
static Bool
 
65
psbExaSrfInfo(ScrnInfoPtr pScrn, XpsbSurfacePtr srf,
 
66
              PixmapPtr pPix, PicturePtr pPict)
 
67
{
 
68
    DrawablePtr pDraw;
 
69
    struct _MMBuffer *mmBuffer;
 
70
    unsigned long offset;
 
71
    unsigned int needed_pitch;
 
72
 
 
73
    pDraw = (pPict->repeat) ? pPict->pDrawable : &pPix->drawable;
 
74
    srf->w = pDraw->width;
 
75
    srf->h = pDraw->height;
 
76
    srf->stride = exaGetPixmapPitch(pPix);
 
77
    if (!psbExaGetSuperOffset(pPix, &offset, &mmBuffer))
 
78
        return FALSE;
 
79
 
 
80
    if (!pPict->repeat) {
 
81
 
 
82
        needed_pitch =
 
83
            ALIGN_TO(pDraw->width, 32) * (pDraw->bitsPerPixel >> 3);
 
84
 
 
85
        if (srf->stride != needed_pitch) {
 
86
            unsigned int tmp = srf->stride / (pDraw->bitsPerPixel >> 3);
 
87
 
 
88
            if ((tmp & 31) == 0)
 
89
                srf->w = tmp;
 
90
        }
 
91
        srf->offset = offset;
 
92
 
 
93
    } else {
 
94
 
 
95
        /*
 
96
         * Poulsbo can only do repeat on power-of-two textures.
 
97
         */
 
98
 
 
99
        needed_pitch =
 
100
            ALIGN_TO(pDraw->width, 32) * (pDraw->bitsPerPixel >> 3);
 
101
        if (srf->stride != needed_pitch || !psbIsPot(pDraw->width)
 
102
            || !psbIsPot(pDraw->height))
 
103
            return FALSE;
 
104
 
 
105
        /*
 
106
         * FIXME: Need to check whether we should add the drawable start offset from
 
107
         * the pixmap base here...
 
108
         */
 
109
 
 
110
        srf->offset = offset;
 
111
 
 
112
    }
 
113
    srf->buffer = mmKernelBuf(mmBuffer);
 
114
    srf->x = 0;
 
115
    srf->y = 0;
 
116
    srf->pictFormat = pPict->format;
 
117
    srf->minFilter = Xpsb_nearest;
 
118
    srf->magFilter = Xpsb_nearest;
 
119
    srf->uMode = (pPict->repeat) ? Xpsb_repeat : Xpsb_clamp;
 
120
    srf->vMode = srf->uMode;
 
121
 
 
122
    return TRUE;
 
123
}
 
124
 
 
125
static inline Bool
 
126
psbIsScalar(PicturePtr pPict)
 
127
{
 
128
    return (pPict->repeat && pPict->pDrawable->width == 1 &&
 
129
            pPict->pDrawable->height == 1 &&
 
130
            psbExpandablePixel(pPict->format));
 
131
}
 
132
 
 
133
Bool
 
134
psbExaPrepareComposite3D(int op, PicturePtr pSrcPicture,
 
135
                         PicturePtr pMaskPicture, PicturePtr pDstPicture,
 
136
                         PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
 
137
{
 
138
    ScreenPtr pScreen = pDst->drawable.pScreen;
 
139
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 
140
    PsbPtr pPsb = psbPTR(pScrn);
 
141
    PsbExaPtr pPsbExa = pPsb->pPsbExa;
 
142
    XpsbSurfacePtr opTex[2];
 
143
    CARD32 scalarPixel;
 
144
    unsigned int numTex = 0;
 
145
 
 
146
    if (PICT_FORMAT_A(pDstPicture->format) == 0 && !psbSupportDstA0[op])
 
147
        return FALSE;
 
148
 
 
149
    pPsbExa->scalarSrc = psbIsScalar(pSrcPicture);
 
150
    pPsbExa->scalarMask = (pMaskPicture == NULL) ||
 
151
        PICT_FORMAT_A(pMaskPicture->format) == 0 || psbIsScalar(pMaskPicture);
 
152
 
 
153
    if (pPsbExa->scalarSrc && pPsbExa->scalarMask) {
 
154
 
 
155
        /*
 
156
         * Ouch. EXA should've optimized this away.
 
157
         */
 
158
 
 
159
        pPsbExa->scalarSrc = FALSE;
 
160
    }
 
161
 
 
162
    if ((pPsbExa->scalarSrc || pPsbExa->scalarMask) &&
 
163
        !(pPsbExa->scalarSrc && pPsbExa->scalarMask)) {
 
164
 
 
165
        /*
 
166
         * Get the scalar pixel value.
 
167
         */
 
168
 
 
169
        if (pPsbExa->scalarSrc)
 
170
            psbPixelARGB8888(pSrcPicture->format, pSrc->devPrivate.ptr,
 
171
                             &scalarPixel);
 
172
        else if (pMaskPicture != NULL &&
 
173
                 PICT_FORMAT_A(pMaskPicture->format) > 0)
 
174
            psbPixelARGB8888(pMaskPicture->format, pMask->devPrivate.ptr,
 
175
                             &scalarPixel);
 
176
        else
 
177
            scalarPixel = 0xFF000000;
 
178
    }
 
179
 
 
180
    if (!pPsbExa->scalarSrc) {
 
181
        if (!psbExaSrfInfo(pScrn, &pPsbExa->src, pSrc, pSrcPicture))
 
182
            return FALSE;
 
183
 
 
184
        opTex[numTex] = &pPsbExa->src;
 
185
        pPsbExa->src.texCoordIndex = numTex++;
 
186
    }
 
187
    if (!pPsbExa->scalarMask) {
 
188
        if (!psbExaSrfInfo(pScrn, &pPsbExa->mask, pMask, pMaskPicture))
 
189
            return FALSE;
 
190
 
 
191
        opTex[numTex] = &pPsbExa->mask;
 
192
        pPsbExa->mask.texCoordIndex = numTex++;
 
193
    }
 
194
    if (!psbExaSrfInfo(pScrn, &pPsbExa->dst, pDst, pDstPicture)) {
 
195
        return FALSE;
 
196
    }
 
197
 
 
198
    pPsbExa->dst.texCoordIndex = 0;
 
199
 
 
200
    if (!psb3DPrepareComposite(pScrn, &pPsbExa->dst,
 
201
                               opTex, numTex, op,
 
202
                               (unsigned int)scalarPixel,
 
203
                               pPsbExa->scalarSrc, pPsbExa->scalarMask))
 
204
        return FALSE;
 
205
 
 
206
    return TRUE;
 
207
}
 
208
 
 
209
void
 
210
psbExaComposite3D(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 
211
                  int dstX, int dstY, int width, int height)
 
212
{
 
213
    ScreenPtr pScreen = pDst->drawable.pScreen;
 
214
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 
215
    PsbPtr pPsb = psbPTR(pScrn);
 
216
    PsbExaPtr pPsbExa = pPsb->pPsbExa;
 
217
    float vertices[4 * XPSB_VOFFSET_COUNT];
 
218
    XpsbSurface *src = &pPsbExa->src;
 
219
    XpsbSurface *mask = &pPsbExa->mask;
 
220
    Bool scalar = pPsbExa->scalarSrc || pPsbExa->scalarMask;
 
221
    unsigned int used_coords = ((scalar) ? 4 : 6);
 
222
 
 
223
    int coord;
 
224
 
 
225
    float *vertex0 = &vertices[0 * used_coords];
 
226
    float *vertex3 = &vertices[3 * used_coords];
 
227
    float *vertex;
 
228
 
 
229
    /*
 
230
     * Top left corner.
 
231
     */
 
232
 
 
233
    coord = XPSB_VOFFSET_UT0;
 
234
    vertex0[XPSB_VOFFSET_X] = dstX;
 
235
    vertex0[XPSB_VOFFSET_Y] = dstY;
 
236
    if (!pPsbExa->scalarSrc) {
 
237
        vertex0[coord++] = (float)srcX / (float)src->w;
 
238
        vertex0[coord++] = (float)srcY / (float)src->h;
 
239
    }
 
240
    if (!pPsbExa->scalarMask) {
 
241
        vertex0[coord++] = (float)maskX / (float)mask->w;
 
242
        vertex0[coord++] = (float)maskY / (float)mask->h;
 
243
    }
 
244
 
 
245
    /*
 
246
     * Bottom right.
 
247
     */
 
248
 
 
249
    coord = XPSB_VOFFSET_UT0;
 
250
    vertex3[XPSB_VOFFSET_X] = dstX + width;
 
251
    vertex3[XPSB_VOFFSET_Y] = dstY + height;
 
252
    if (!pPsbExa->scalarSrc) {
 
253
        vertex3[coord++] = (float)(srcX + width) / (float)src->w;
 
254
        vertex3[coord++] = (float)(srcY + height) / (float)src->h;
 
255
    }
 
256
    if (!pPsbExa->scalarMask) {
 
257
        vertex3[coord++] = (float)(maskX + width) / (float)mask->w;
 
258
        vertex3[coord++] = (float)(maskY + height) / (float)mask->h;
 
259
    }
 
260
 
 
261
    /*
 
262
     * Top right.
 
263
     */
 
264
 
 
265
    vertex = &vertices[1 * used_coords];
 
266
    vertex[XPSB_VOFFSET_X] = vertex3[XPSB_VOFFSET_X];
 
267
    vertex[XPSB_VOFFSET_Y] = vertex0[XPSB_VOFFSET_Y];
 
268
    vertex[XPSB_VOFFSET_UT0] = vertex3[XPSB_VOFFSET_UT0];
 
269
    vertex[XPSB_VOFFSET_VT0] = vertex0[XPSB_VOFFSET_VT0];
 
270
    if (!scalar) {
 
271
        vertex[XPSB_VOFFSET_UT1] = vertex3[XPSB_VOFFSET_UT1];
 
272
        vertex[XPSB_VOFFSET_VT1] = vertex0[XPSB_VOFFSET_VT1];
 
273
    }
 
274
 
 
275
    /*
 
276
     * Bottom left.
 
277
     */
 
278
 
 
279
    vertex = &vertices[2 * used_coords];
 
280
    vertex[XPSB_VOFFSET_X] = vertex0[XPSB_VOFFSET_X];
 
281
    vertex[XPSB_VOFFSET_Y] = vertex3[XPSB_VOFFSET_Y];
 
282
    vertex[XPSB_VOFFSET_UT0] = vertex0[XPSB_VOFFSET_UT0];
 
283
    vertex[XPSB_VOFFSET_VT0] = vertex3[XPSB_VOFFSET_VT0];
 
284
    if (!scalar) {
 
285
        vertex[XPSB_VOFFSET_UT1] = vertex0[XPSB_VOFFSET_UT1];
 
286
        vertex[XPSB_VOFFSET_VT1] = vertex3[XPSB_VOFFSET_VT1];
 
287
    }
 
288
 
 
289
    psb3DCompositeQuad(pScrn, vertices);
 
290
}
 
291
 
 
292
void
 
293
psbExaDoneComposite3D(PixmapPtr pPixmap)
 
294
{
 
295
    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
 
296
 
 
297
    psb3DCompositeFinish(pScrn);
 
298
}