~ubuntu-branches/ubuntu/utopic/xserver-xorg-video-nouveau/utopic

« back to all changes in this revision

Viewing changes to src/nv_cursor.c

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2009-12-04 12:31:58 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20091204123158-oc7ytykkz8anvr6i
Tags: 1:0.0.15+git20100128+2630a15-0ubuntu1
* New upstream snapshot
  + Too many commits to usefully list in the changelog.
  + User modesetting code is now removed.  Nouveau will now only work with 
    KMS.
* debian/control:
  + Bump versioned Build-Dep on libdrm-dev to >= 2.4.17-1ubuntu1~ to pick 
    up nouveau #define updates.
  + Bump build-dep on xserver-xorg-dev to >= 2:1.7.  Nouveau now requires 
    xorg-server >= 1.7.
  + Drop duplicate build-dep on xserver-xorg-dev
  + List the Build-Depends one-to-a-line for clarity
  + Drop the Depends: on linux-nouveau-modules.  Replace with temporary 
    Depends against apw's linux-backports-modules-nouveau* packages.
  + Bump Standards version to 3.8.3.
* debian/README.source
  + Quilt patchsys README for standards version 3.8.3 compliance
* Change versioning to match Sarvatt's snapshot versioning.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2003 NVIDIA, Corporation
3
 
 * Copyright 2007 Maarten Maathuis
4
 
 * Copyright 2009 Stuart Bennett
5
 
 *
6
 
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 
 * copy of this software and associated documentation files (the "Software"),
8
 
 * to deal in the Software without restriction, including without limitation
9
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 
 * and/or sell copies of the Software, and to permit persons to whom the
11
 
 * Software is furnished to do so, subject to the following conditions:
12
 
 *
13
 
 * The above copyright notice and this permission notice shall be included in
14
 
 * all copies or substantial portions of the Software.
15
 
 *
16
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 
 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
 
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
21
 
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
 
 * SOFTWARE.
23
 
 */
24
 
 
25
 
#include "nv_include.h"
26
 
 
27
 
#define TO_ARGB1555(c) (0x8000                  |       /* Mask bit */  \
28
 
                        ((c & 0xf80000) >> 9 )  |       /* Red      */  \
29
 
                        ((c & 0xf800) >> 6 )    |       /* Green    */  \
30
 
                        ((c & 0xf8) >> 3 ))             /* Blue     */
31
 
#define TO_ARGB8888(c) (0xff000000 | c)
32
 
 
33
 
#define SOURCE_MASK_INTERLEAVE 32
34
 
#define TRANSPARENT_PIXEL   0
35
 
 
36
 
/*
37
 
 * Convert a source/mask bitmap cursor to an ARGB cursor, clipping or
38
 
 * padding as necessary. source/mask are assumed to be alternated each
39
 
 * SOURCE_MASK_INTERLEAVE bits.
40
 
 */
41
 
void
42
 
nv_cursor_convert_cursor(uint32_t *src, void *dst, int src_stride, int dst_stride,
43
 
                         int bpp, uint32_t fg, uint32_t bg)
44
 
{
45
 
        int width = min(src_stride, dst_stride);
46
 
        uint32_t b, m, pxval;
47
 
        int i, j, k;
48
 
 
49
 
        for (i = 0; i < width; i++) {
50
 
                for (j = 0; j < width / SOURCE_MASK_INTERLEAVE; j++) {
51
 
                        int src_off = i*src_stride/SOURCE_MASK_INTERLEAVE + j;
52
 
                        int dst_off = i*dst_stride + j*SOURCE_MASK_INTERLEAVE;
53
 
 
54
 
                        b = src[2*src_off];
55
 
                        m = src[2*src_off + 1];
56
 
 
57
 
                        for (k = 0; k < SOURCE_MASK_INTERLEAVE; k++) {
58
 
                                pxval = TRANSPARENT_PIXEL;
59
 
#if X_BYTE_ORDER == X_BIG_ENDIAN
60
 
                                if (m & 0x80000000)
61
 
                                        pxval = (b & 0x80000000) ? fg : bg;
62
 
                                b <<= 1;
63
 
                                m <<= 1;
64
 
#else
65
 
                                if (m & 1)
66
 
                                        pxval = (b & 1) ? fg : bg;
67
 
                                b >>= 1;
68
 
                                m >>= 1;
69
 
#endif
70
 
                                if (bpp == 32)
71
 
                                        ((uint32_t *)dst)[dst_off + k] = pxval;
72
 
                                else
73
 
                                        ((uint16_t *)dst)[dst_off + k] = pxval;
74
 
                        }
75
 
                }
76
 
        }
77
 
}
78
 
 
79
 
static void nv_cursor_transform_cursor(NVPtr pNv, struct nouveau_crtc *nv_crtc)
80
 
{
81
 
        uint16_t *tmp;
82
 
        struct nouveau_bo *cursor = NULL;
83
 
        int px = nv_cursor_pixels(pNv);
84
 
        int width = nv_cursor_width(pNv);
85
 
 
86
 
        if (!(tmp = xcalloc(px, 4)))
87
 
                return;
88
 
 
89
 
        /* convert to colour cursor */
90
 
        nv_cursor_convert_cursor(pNv->curImage, tmp, width, width,
91
 
                                 pNv->alphaCursor ? 32 : 16, nv_crtc->cursor_fg,
92
 
                                 nv_crtc->cursor_bg);
93
 
 
94
 
        nouveau_bo_ref(nv_crtc->head ? pNv->Cursor2 : pNv->Cursor, &cursor);
95
 
        nouveau_bo_map(cursor, NOUVEAU_BO_WR);
96
 
 
97
 
        memcpy(cursor->map, tmp, px * 4);
98
 
 
99
 
        nouveau_bo_unmap(cursor);
100
 
        nouveau_bo_ref(NULL, &cursor);
101
 
 
102
 
        xfree(tmp);
103
 
}
104
 
 
105
 
void nv_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
106
 
{
107
 
        NVPtr pNv = NVPTR(crtc->scrn);
108
 
        struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
109
 
        uint32_t fore, back;
110
 
 
111
 
        if (pNv->alphaCursor) {
112
 
                fore = TO_ARGB8888(fg);
113
 
                back = TO_ARGB8888(bg);
114
 
#if X_BYTE_ORDER == X_BIG_ENDIAN
115
 
                if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
116
 
                        fore = lswapl(fore);
117
 
                        back = lswapl(back);
118
 
                }
119
 
#endif
120
 
        } else {
121
 
                fore = TO_ARGB1555(fg);
122
 
                back = TO_ARGB1555(bg);
123
 
        }
124
 
 
125
 
        if (nv_crtc->cursor_fg != fore || nv_crtc->cursor_bg != back) {
126
 
                nv_crtc->cursor_fg = fore;
127
 
                nv_crtc->cursor_bg = back;
128
 
                nv_cursor_transform_cursor(pNv, nv_crtc);
129
 
        }
130
 
}
131
 
 
132
 
void nv_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *image)
133
 
{
134
 
        NVPtr pNv = NVPTR(crtc->scrn);
135
 
 
136
 
        /* save copy of image for colour changes */
137
 
        memcpy(pNv->curImage, image, nv_cursor_pixels(pNv) / 4);
138
 
 
139
 
        nv_cursor_transform_cursor(pNv, to_nouveau_crtc(crtc));
140
 
}
141
 
 
142
 
void nv_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
143
 
{
144
 
        NVPtr pNv = NVPTR(crtc->scrn);
145
 
        int head = to_nouveau_crtc(crtc)->head, i, alpha;
146
 
        struct nouveau_bo *cursor = NULL;
147
 
        uint32_t *dst, *src = (uint32_t *)image, tmp;
148
 
 
149
 
        nouveau_bo_ref(head ? pNv->Cursor2 : pNv->Cursor, &cursor);
150
 
        nouveau_bo_map(cursor, NOUVEAU_BO_WR);
151
 
        dst = cursor->map;
152
 
 
153
 
        /* nv11+ supports premultiplied (PM), or non-premultiplied (NPM) alpha
154
 
         * cursors (though NPM in combination with fp dithering may not work on
155
 
         * nv11, from "nv" driver history)
156
 
         * NPM mode needs NV_PCRTC_CURSOR_CONFIG_ALPHA_BLEND set and is what the
157
 
         * blob uses, however we get given PM cursors so we use PM mode
158
 
         */
159
 
        for (i = 0; i < nv_cursor_pixels(pNv); i++) {
160
 
                /* hw gets unhappy if alpha <= rgb values.  for a PM image "less
161
 
                 * than" shouldn't happen; fix "equal to" case by adding one to
162
 
                 * alpha channel (slightly inaccurate, but so is attempting to
163
 
                 * get back to NPM images, due to limits of integer precision)
164
 
                 */
165
 
                alpha = (*src >> 24);
166
 
                if (!alpha || alpha == 0xff)
167
 
                        /* alpha == max(r,g,b) works ok for 0x0 and 0xff */
168
 
                        tmp = *src;
169
 
                else
170
 
                        tmp = ((alpha + 1) << 24) | (*src & 0xffffff);
171
 
#if X_BYTE_ORDER == X_BIG_ENDIAN
172
 
                if (pNv->NVArch == 0x11)
173
 
                        tmp = lswapl(tmp);
174
 
#endif
175
 
                *dst++ = tmp;
176
 
                src++;
177
 
        }
178
 
 
179
 
        nouveau_bo_unmap(cursor);
180
 
        nouveau_bo_ref(NULL, &cursor);
181
 
}
182
 
 
183
 
void nv_crtc_show_cursor(xf86CrtcPtr crtc)
184
 
{
185
 
        struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
186
 
 
187
 
        nv_show_cursor(NVPTR(crtc->scrn), nv_crtc->head, true);
188
 
}
189
 
 
190
 
void nv_crtc_hide_cursor(xf86CrtcPtr crtc)
191
 
{
192
 
        struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
193
 
 
194
 
        nv_show_cursor(NVPTR(crtc->scrn), nv_crtc->head, false);
195
 
}
196
 
 
197
 
void nv_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
198
 
{
199
 
        struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
200
 
        NVPtr pNv = NVPTR(crtc->scrn);
201
 
 
202
 
        NVWriteRAMDAC(pNv, nv_crtc->head, NV_PRAMDAC_CU_START_POS,
203
 
                      XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) |
204
 
                      XLATE(x, 0, NV_PRAMDAC_CU_START_POS_X));
205
 
}
206
 
 
207
 
Bool NVCursorInitRandr12(ScreenPtr pScreen)
208
 
{
209
 
        NVPtr pNv = NVPTR(xf86Screens[pScreen->myNum]);
210
 
        int width = nv_cursor_width(pNv);
211
 
        int flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
212
 
                    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
213
 
                    (pNv->alphaCursor ? HARDWARE_CURSOR_ARGB : 0);
214
 
 
215
 
        return xf86_cursors_init(pScreen, width, width, flags);
216
 
}