~ubuntu-branches/ubuntu/karmic/libsdl1.2/karmic

« back to all changes in this revision

Viewing changes to src/video/SDL_stretch.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2008-01-05 14:10:45 UTC
  • mto: (2.1.3 lenny)
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20080105141045-mjdg2rp09mamme4a
Tags: upstream-1.2.13
ImportĀ upstreamĀ versionĀ 1.2.13

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
 
43
43
#ifdef USE_ASM_STRETCH
44
44
 
 
45
#ifdef HAVE_MPROTECT
 
46
#include <sys/types.h>
 
47
#include <sys/mman.h>
 
48
#endif
 
49
#ifdef __GNUC__
 
50
#define PAGE_ALIGNED __attribute__((__aligned__(4096)))
 
51
#else
 
52
#define PAGE_ALIGNED
 
53
#endif
 
54
 
45
55
#if defined(_M_IX86) || defined(i386)
46
56
#define PREFIX16        0x66
47
57
#define STORE_BYTE      0xAA
53
63
#error Need assembly opcodes for this architecture
54
64
#endif
55
65
 
56
 
static unsigned char copy_row[4096];
 
66
static unsigned char copy_row[4096] PAGE_ALIGNED;
57
67
 
58
68
static int generate_rowbytes(int src_w, int dst_w, int bpp)
59
69
{
61
71
                int bpp;
62
72
                int src_w;
63
73
                int dst_w;
 
74
                int status;
64
75
        } last;
65
76
 
66
77
        int i;
71
82
        /* See if we need to regenerate the copy buffer */
72
83
        if ( (src_w == last.src_w) &&
73
84
             (dst_w == last.dst_w) && (bpp == last.bpp) ) {
74
 
                return(0);
 
85
                return(last.status);
75
86
        }
76
87
        last.bpp = bpp;
77
88
        last.src_w = src_w;
78
89
        last.dst_w = dst_w;
 
90
        last.status = -1;
79
91
 
80
92
        switch (bpp) {
81
93
            case 1:
110
122
        }
111
123
        *eip++ = RETURN;
112
124
 
113
 
        /* Verify that we didn't overflow (too late) */
 
125
        /* Verify that we didn't overflow (too late!!!) */
114
126
        if ( eip > (copy_row+sizeof(copy_row)) ) {
115
127
                SDL_SetError("Copy buffer overflow");
116
128
                return(-1);
117
129
        }
 
130
#ifdef HAVE_MPROTECT
 
131
        /* Make the code executable */
 
132
        if ( mprotect(copy_row, sizeof(copy_row), PROT_READ|PROT_WRITE|PROT_EXEC) < 0 ) {
 
133
                SDL_SetError("Couldn't make copy buffer executable");
 
134
                return(-1);
 
135
        }
 
136
#endif
 
137
        last.status = 0;
118
138
        return(0);
119
139
}
120
140
 
121
 
#else
 
141
#endif /* USE_ASM_STRETCH */
122
142
 
123
143
#define DEFINE_COPY_ROW(name, type)                     \
124
144
void name(type *src, int src_w, type *dst, int dst_w)   \
142
162
DEFINE_COPY_ROW(copy_row2, Uint16)
143
163
DEFINE_COPY_ROW(copy_row4, Uint32)
144
164
 
145
 
#endif /* USE_ASM_STRETCH */
146
 
 
147
165
/* The ASM code doesn't handle 24-bpp stretch blits */
148
166
void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w)
149
167
{
183
201
        Uint8 *dstp;
184
202
        SDL_Rect full_src;
185
203
        SDL_Rect full_dst;
186
 
#if defined(USE_ASM_STRETCH) && defined(__GNUC__)
 
204
#ifdef USE_ASM_STRETCH
 
205
        SDL_bool use_asm = SDL_TRUE;
 
206
#ifdef __GNUC__
187
207
        int u1, u2;
188
208
#endif
 
209
#endif /* USE_ASM_STRETCH */
189
210
        const int bpp = dst->format->BytesPerPixel;
190
211
 
191
212
        if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) {
254
275
 
255
276
#ifdef USE_ASM_STRETCH
256
277
        /* Write the opcodes for this stretch */
257
 
        if ( (bpp != 3) &&
 
278
        if ( (bpp == 3) ||
258
279
             (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0) ) {
259
 
                return(-1);
 
280
                use_asm = SDL_FALSE;
260
281
        }
261
282
#endif
262
283
 
271
292
                        pos -= 0x10000L;
272
293
                }
273
294
#ifdef USE_ASM_STRETCH
274
 
                switch (bpp) {
275
 
                    case 3:
276
 
                        copy_row3(srcp, srcrect->w, dstp, dstrect->w);
277
 
                        break;
278
 
                    default:
 
295
                if (use_asm) {
279
296
#ifdef __GNUC__
280
297
                        __asm__ __volatile__ (
281
298
                        "call *%4"
299
316
#else
300
317
#error Need inline assembly for this compiler
301
318
#endif
302
 
                        break;
303
 
                }
304
 
#else
 
319
                } else
 
320
#endif
305
321
                switch (bpp) {
306
322
                    case 1:
307
323
                        copy_row1(srcp, srcrect->w, dstp, dstrect->w);
318
334
                                  (Uint32 *)dstp, dstrect->w);
319
335
                        break;
320
336
                }
321
 
#endif
322
337
                pos += inc;
323
338
        }
324
339