1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23#define RBMASK  0xF0F0          /* Short, or 16 bit format */
24#define GAMASK  0x0F0F          /* Short, or 16 bit format */
25#define AMASK   0x000F          /* Short, or 16 bit format */
26
27#if 1
28#define short34to35WithGamma(x)         \
29        (  (((x) & 0xf000) >> 1)        \
30         | (((x) & 0x0f00) >> 2)        \
31         | (((x) & 0x00f0) >> 3)        \
32         | (((x) & 0x8000) >> 5)        \
33         | (((x) & 0x0800) >> 6)        \
34         | (((x) & 0x0080) >> 7) )
35
36#define short35to34WithGamma(x)         \
37        (  0x000F                       \
38         | (((x) & 0x001e) << 3)        \
39         | (((x) & 0x03c0) << 2)        \
40         | (((x) & 0x7800) << 1) )
41#else
42#define short34to35WithGamma(x) \
43        (  (_bm34To35SampleTable[((x) & 0x00F0) >> 4])          \
44         | (_bm34To35SampleTable[((x) & 0x0F00) >> 8] << 5)     \
45         | (_bm34To35SampleTable[(x) >> 12] << 10) )
46
47#define short35to34WithGamma(x) \
48        (  0x000F                                               \
49         | (_bm35To34SampleTable[x & 0x001F] << 4)              \
50         | (_bm35To34SampleTable[(x & 0x03E0) >> 5] << 8)       \
51         | (_bm35To34SampleTable[(x & 0x7C00) >> 10] << 12) )
52#endif
53
54void IOFramebuffer::StdFBDisplayCursor555(
55                IOFramebuffer * inst,
56                StdFBShmem_t *shmem,
57                volatile unsigned short *vramPtr,
58                unsigned int cursStart,
59                unsigned int vramRow,
60                unsigned int cursRow,
61                int width,
62                int height )
63{
64    int i, j;
65    volatile unsigned short *cursPtr;
66    volatile unsigned short *savePtr;
67    unsigned short s, d, f;
68    unsigned char *_bm34To35SampleTable;
69    unsigned char *_bm35To34SampleTable;
70
71    savePtr = (volatile unsigned short *) inst->cursorSave;
72    cursPtr = (volatile unsigned short *) inst->__private->cursorImages[ shmem->frame ];
73    cursPtr += cursStart;
74
75    _bm34To35SampleTable = inst->colorConvert.t._bm34To35SampleTable;
76    _bm35To34SampleTable = inst->colorConvert.t._bm35To34SampleTable;
77
78    for (i = height; --i >= 0; ) {
79        for (j = width; --j >= 0; ) {
80            d = *savePtr++ = *vramPtr;
81            if ( (s = *cursPtr++) == 0 )
82            {   /* Transparent black area.  Leave dst as is. */
83                ++vramPtr;
84                continue;
85            }
86            if ( (f = (~s) & (unsigned int)AMASK) == 0 )
87            {   /* Opaque cursor pixel.  Mark it. */
88                *vramPtr++ = short34to35WithGamma(s);
89                continue;
90            }
91            if (f == AMASK)
92            {   /* Transparent non black cursor pixel.  xor it. */
93                *vramPtr++ = d ^ short34to35WithGamma(s);
94                continue;
95            }
96            /* Alpha is not 0 or 1.0.  Sover the cursor. */
97            d = short35to34WithGamma(d);
98            d = s + (((((d & RBMASK)>>4)*f + GAMASK) & RBMASK)
99                | ((((d & GAMASK)*f+GAMASK)>>4) & GAMASK));
100            *vramPtr++ = short34to35WithGamma(d);
101        }
102        cursPtr += cursRow; /* starting point of next cursor line */
103        vramPtr += vramRow; /* starting point of next screen line */
104    }
105}
106
107static inline unsigned int MUL32(unsigned int a, unsigned int b)
108{
109    unsigned int v, w;
110
111    v  = ((a & 0xFF00FF00) >> 8) * b;
112    v += ((v & 0xFF00FF00) >> 8) + 0x00010001;
113    w  = (a & 0x00FF00FF) * b;
114    w += ((w & 0xFF00FF00) >> 8) + 0x00010001;
115
116    return (v & 0xFF00FF00) | ((w >> 8) & 0x00FF00FF);
117}
118
119static inline unsigned char map32to256( unsigned char *directToLogical, unsigned int s)
120{
121    unsigned char logicalValue;
122
123    if ((s ^ (s>>8)) & 0x00FFFF00) {
124        logicalValue =  directToLogical[(s>>24)        + 0] +
125                        directToLogical[((s>>16)&0xFF) + 256] +
126                        directToLogical[((s>>8)&0xFF)  + 512];
127    } else {
128        logicalValue =  directToLogical[(s>>24)        + 768];
129    }
130    // final conversion to actual palette
131    return( directToLogical[ logicalValue + 1024 ]);
132}
133
134void IOFramebuffer::StdFBDisplayCursor8P(
135                IOFramebuffer * inst,
136                StdFBShmem_t *shmem,
137                volatile unsigned char *vramPtr,
138                unsigned int cursStart,
139                unsigned int vramRow,
140                unsigned int cursRow,
141                int width,
142                int height )
143{
144    int i, j;
145    volatile unsigned char *savePtr;    /* saved screen data pointer */
146    volatile unsigned char *cursPtr;
147    unsigned char dst, src, alpha, white;
148    unsigned int rgb32val;
149    volatile unsigned char *maskPtr;            /* cursor mask pointer */
150    unsigned int *_bm256To38SampleTable
151        = inst->colorConvert.t._bm256To38SampleTable;
152    unsigned char *_bm38To256SampleTable
153        = inst->colorConvert.t._bm38To256SampleTable;
154
155    savePtr = (volatile unsigned char *) inst->cursorSave;
156    cursPtr = (volatile unsigned char *) inst->__private->cursorImages[ shmem->frame ];
157    maskPtr = (volatile unsigned char *) inst->__private->cursorMasks[ shmem->frame ];
158    cursPtr += cursStart;
159    maskPtr += cursStart;
160
161    white = inst->white;
162    for (i = height; --i >= 0; ) {
163        for (j = width; --j >= 0; savePtr++,maskPtr++,cursPtr++,vramPtr++) {
164            dst = *savePtr = *vramPtr;
165            src = *cursPtr;
166            if ((alpha = *maskPtr)) {
167                if ((alpha = ~alpha)) {
168                    rgb32val = _bm256To38SampleTable[dst];
169                    rgb32val = (_bm256To38SampleTable[src] & ~0xFF) +
170                                      MUL32(rgb32val, alpha);
171                    *vramPtr = map32to256(_bm38To256SampleTable, rgb32val);
172                } else
173                    *vramPtr = src;
174            } else if (src == white)
175                *vramPtr = dst ^ 0xFF;
176        }
177        cursPtr += cursRow; /* starting point of next cursor line */
178        maskPtr += cursRow;
179        vramPtr += vramRow; /* starting point of next screen line */
180    }
181}
182
183
184void IOFramebuffer::StdFBDisplayCursor8G(
185                                 IOFramebuffer * inst,
186                                 StdFBShmem_t *shmem,
187                                 volatile unsigned char *vramPtr,
188                                 unsigned int cursStart,
189                                 unsigned int vramRow,
190                                 unsigned int cursRow,
191                                 int width,
192                                 int height )
193{
194    int i, j;
195    volatile unsigned char *savePtr;    /* saved screen data pointer */
196    unsigned short s, d, a;
197    volatile unsigned char *cursPtr;
198    volatile unsigned char *maskPtr;            /* cursor mask pointer */
199
200    savePtr = (volatile unsigned char *) inst->cursorSave;
201    cursPtr = (volatile unsigned char *) inst->__private->cursorImages[ shmem->frame ];
202    maskPtr = (volatile unsigned char *) inst->__private->cursorMasks[ shmem->frame ];
203    cursPtr += cursStart;
204    maskPtr += cursStart;
205
206    for (i = height; --i >= 0; ) {
207        for (j = width; --j >= 0; ) {
208            int t;
209            d = *savePtr++ = *vramPtr;
210            s = *cursPtr++;
211            a = *maskPtr++;
212            if (a) {
213                t = d * (255 - *maskPtr++);
214                *vramPtr = s + ((t + (t >> 8) + 1) >> 8);
215            } else if (s)
216                *vramPtr = d ^ s;
217            vramPtr++;
218        }
219        cursPtr += cursRow; /* starting point of next cursor line */
220        maskPtr += cursRow;
221        vramPtr += vramRow; /* starting point of next screen line */
222    }
223}
224
225void IOFramebuffer::StdFBDisplayCursor30Axxx(
226                                 IOFramebuffer * inst,
227                                 StdFBShmem_t *shmem,
228                                 volatile unsigned int *vramPtr,
229                                 unsigned int cursStart,
230                                 unsigned int vramRow,
231                                 unsigned int cursRow,
232                                 int width,
233                                 int height )
234{
235    int i, j;
236    volatile unsigned int *savePtr;     /* saved screen data pointer */
237    unsigned long long s, d;
238    unsigned int f;
239    volatile unsigned int *cursPtr;
240
241    savePtr = (volatile unsigned int *) inst->cursorSave;
242    cursPtr = (volatile unsigned int *) inst->__private->cursorImages[ shmem->frame ];
243    cursPtr += cursStart;
244
245    /* Pixel format is Axxx */
246    for (i = height; --i >= 0; ) {
247        for (j = width; --j >= 0; ) {
248            d = *savePtr++ = *vramPtr;
249            s = *cursPtr++;
250            f = s >> 24;
251            s = ((s&0x000000FF)<<2)|((s&0x0000FF00)<<4)|((s&0x00FF0000)<<6);
252            if (f) {
253                if (f == 0xFF)          // Opaque pixel
254                    *vramPtr++ = s;
255                else {                  // SOVER the cursor pixel
256                    s <<= 10;  d <<= 10;   /* Now pixels are xxxA */
257                    f ^= 0xFF;
258                    d = s+(((((d&0xFFC00FFC00ULL)>>8)*f+0x0FF000FF) & 0xFFC00FFC00ULL)
259                        | ((((d & 0x3FF003FF)*f+0x0FF000FF)>>8) & 0x3FF003FF));
260                    *vramPtr++ = (d>>10) | 0xC0000000;
261                }
262            } else if (s) {
263                // Transparent non black cursor pixel.  xor it.
264                *vramPtr++ = d ^ s;
265                continue;
266            } else                      // Transparent cursor pixel
267                vramPtr++;
268        }
269        cursPtr += cursRow; /* starting point of next cursor line */
270        vramPtr += vramRow; /* starting point of next screen line */
271    }
272}
273
274void IOFramebuffer::StdFBDisplayCursor32Axxx(
275                                 IOFramebuffer * inst,
276                                 StdFBShmem_t *shmem,
277                                 volatile unsigned int *vramPtr,
278                                 unsigned int cursStart,
279                                 unsigned int vramRow,
280                                 unsigned int cursRow,
281                                 int width,
282                                 int height )
283{
284    int i, j;
285    volatile unsigned int *savePtr;     /* saved screen data pointer */
286    unsigned int s, d, f;
287    volatile unsigned int *cursPtr;
288
289    savePtr = (volatile unsigned int *) inst->cursorSave;
290    cursPtr = (volatile unsigned int *) inst->__private->cursorImages[ shmem->frame ];
291    cursPtr += cursStart;
292
293    /* Pixel format is Axxx */
294    for (i = height; --i >= 0; ) {
295        for (j = width; --j >= 0; ) {
296            d = *savePtr++ = *vramPtr;
297            s = *cursPtr++;
298            f = s >> 24;
299            if (f) {
300                if (f == 0xFF)          // Opaque pixel
301                    *vramPtr++ = s;
302                else {                  // SOVER the cursor pixel
303                    s <<= 8;  d <<= 8;   /* Now pixels are xxxA */
304                    f ^= 0xFF;
305                    d = s+(((((d&0xFF00FF00)>>8)*f+0x00FF00FF)&0xFF00FF00)
306                        | ((((d & 0x00FF00FF)*f+0x00FF00FF)>>8) &
307                            0x00FF00FF));
308                    *vramPtr++ = (d>>8) | 0xFF000000;
309                }
310            } else if (s) {
311                // Transparent non black cursor pixel.  xor it.
312                *vramPtr++ = d ^ s;
313                continue;
314            } else                      // Transparent cursor pixel
315                vramPtr++;
316        }
317        cursPtr += cursRow; /* starting point of next cursor line */
318        vramPtr += vramRow; /* starting point of next screen line */
319    }
320}
321
322void IOFramebuffer::StdFBRemoveCursor16(
323                                IOFramebuffer * inst,
324                                StdFBShmem_t *shmem,
325                                volatile unsigned short *vramPtr,
326                                unsigned int vramRow,
327                                int width,
328                                int height )
329{
330    int i, j;
331    volatile unsigned short *savePtr;
332
333    savePtr = (volatile unsigned short *) inst->cursorSave;
334
335    for (i = height; --i >= 0; ) {
336        for (j = width; --j >= 0; )
337            *vramPtr++ = *savePtr++;
338        vramPtr += vramRow;
339    }
340}
341
342void IOFramebuffer::StdFBRemoveCursor8(
343                               IOFramebuffer * inst,
344                               StdFBShmem_t *shmem,
345                               volatile unsigned char *vramPtr,
346                               unsigned int vramRow,
347                               int width,
348                               int height )
349{
350    int i, j;
351    volatile unsigned char *savePtr;
352
353    savePtr = (volatile unsigned char *) inst->cursorSave;
354
355    for (i = height; --i >= 0; ) {
356        for (j = width; --j >= 0; )
357            *vramPtr++ = *savePtr++;
358        vramPtr += vramRow;
359    }
360}
361
362void IOFramebuffer::StdFBRemoveCursor32(
363                                IOFramebuffer * inst,
364                                StdFBShmem_t *shmem,
365                                volatile unsigned int *vramPtr,
366                                unsigned int vramRow,
367                                int width,
368                                int height )
369{
370    int i, j;
371    volatile unsigned int *savePtr;
372
373    savePtr = (volatile unsigned int *) inst->cursorSave;
374
375    for (i = height; --i >= 0; ) {
376        for (j = width; --j >= 0; )
377            *vramPtr++ = *savePtr++;
378        vramPtr += vramRow;
379    }
380}
381