Removed some unused variables that gcc 4.6.1 complains about.
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
21 #include "SDL_config.h"
23 /* This a stretch blit implementation based on ideas given to me by
24 Tomasz Cejner - thanks! :)
26 April 27, 2000 - Sam Lantinga
29 #include "SDL_video.h"
32 /* This isn't ready for general consumption yet - it should be folded
33 into the general blitting mechanism.
36 #if ((defined(_MFC_VER) && defined(_M_IX86)/* && !defined(_WIN32_WCE) still needed? */) || \
37 defined(__WATCOMC__) || \
38 (defined(__GNUC__) && defined(__i386__))) && SDL_ASSEMBLY_ROUTINES
39 /* There's a bug with gcc 4.4.1 and -O2 where srcp doesn't get the correct
40 * value after the first scanline. FIXME? */
41 /*#define USE_ASM_STRETCH*/
44 #ifdef USE_ASM_STRETCH
47 #include <sys/types.h>
51 #define PAGE_ALIGNED __attribute__((__aligned__(4096)))
56 #if defined(_M_IX86) || defined(i386)
58 #define STORE_BYTE 0xAA
59 #define STORE_WORD 0xAB
60 #define LOAD_BYTE 0xAC
61 #define LOAD_WORD 0xAD
64 #error Need assembly opcodes for this architecture
67 static unsigned char copy_row[4096] PAGE_ALIGNED;
70 generate_rowbytes(int src_w, int dst_w, int bpp)
82 unsigned char *eip, *fence;
83 unsigned char load, store;
85 /* See if we need to regenerate the copy buffer */
86 if ((src_w == last.src_w) && (dst_w == last.dst_w) && (bpp == last.bpp)) {
105 SDL_SetError("ASM stretch of %d bytes isn't supported\n", bpp);
109 /* Make the code writeable */
110 if (mprotect(copy_row, sizeof(copy_row), PROT_READ | PROT_WRITE) < 0) {
111 SDL_SetError("Couldn't make copy buffer writeable");
116 inc = (src_w << 16) / dst_w;
118 fence = copy_row + sizeof(copy_row)-2;
119 for (i = 0; i < dst_w; ++i) {
120 while (pos >= 0x10000L) {
142 /* Make the code executable but not writeable */
143 if (mprotect(copy_row, sizeof(copy_row), PROT_READ | PROT_EXEC) < 0) {
144 SDL_SetError("Couldn't make copy buffer executable");
152 #endif /* USE_ASM_STRETCH */
154 #define DEFINE_COPY_ROW(name, type) \
155 static void name(type *src, int src_w, type *dst, int dst_w) \
162 inc = (src_w << 16) / dst_w; \
163 for ( i=dst_w; i>0; --i ) { \
164 while ( pos >= 0x10000L ) { \
173 DEFINE_COPY_ROW(copy_row1, Uint8)
174 DEFINE_COPY_ROW(copy_row2, Uint16)
175 DEFINE_COPY_ROW(copy_row4, Uint32)
178 /* The ASM code doesn't handle 24-bpp stretch blits */
180 copy_row3(Uint8 * src, int src_w, Uint8 * dst, int dst_w)
184 Uint8 pixel[3] = { 0, 0, 0 };
187 inc = (src_w << 16) / dst_w;
188 for (i = dst_w; i > 0; --i) {
189 while (pos >= 0x10000L) {
202 /* Perform a stretch blit between two surfaces of the same format.
203 NOTE: This function is not safe to call from multiple threads!
206 SDL_SoftStretch(SDL_Surface * src, const SDL_Rect * srcrect,
207 SDL_Surface * dst, const SDL_Rect * dstrect)
213 int src_row, dst_row;
218 #ifdef USE_ASM_STRETCH
219 SDL_bool use_asm = SDL_TRUE;
223 #endif /* USE_ASM_STRETCH */
224 const int bpp = dst->format->BytesPerPixel;
226 if (src->format->BitsPerPixel != dst->format->BitsPerPixel) {
227 SDL_SetError("Only works with same format surfaces");
231 /* Verify the blit rectangles */
233 if ((srcrect->x < 0) || (srcrect->y < 0) ||
234 ((srcrect->x + srcrect->w) > src->w) ||
235 ((srcrect->y + srcrect->h) > src->h)) {
236 SDL_SetError("Invalid source blit rectangle");
247 if ((dstrect->x < 0) || (dstrect->y < 0) ||
248 ((dstrect->x + dstrect->w) > dst->w) ||
249 ((dstrect->y + dstrect->h) > dst->h)) {
250 SDL_SetError("Invalid destination blit rectangle");
261 /* Lock the destination if it's in hardware */
263 if (SDL_MUSTLOCK(dst)) {
264 if (SDL_LockSurface(dst) < 0) {
265 SDL_SetError("Unable to lock destination surface");
270 /* Lock the source if it's in hardware */
272 if (SDL_MUSTLOCK(src)) {
273 if (SDL_LockSurface(src) < 0) {
275 SDL_UnlockSurface(dst);
277 SDL_SetError("Unable to lock source surface");
283 /* Set up the data... */
285 inc = (srcrect->h << 16) / dstrect->h;
286 src_row = srcrect->y;
287 dst_row = dstrect->y;
289 #ifdef USE_ASM_STRETCH
290 /* Write the opcodes for this stretch */
291 if ((bpp == 3) || (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0)) {
296 /* Perform the stretch blit */
297 for (dst_maxrow = dst_row + dstrect->h; dst_row < dst_maxrow; ++dst_row) {
298 dstp = (Uint8 *) dst->pixels + (dst_row * dst->pitch)
299 + (dstrect->x * bpp);
300 while (pos >= 0x10000L) {
301 srcp = (Uint8 *) src->pixels + (src_row * src->pitch)
302 + (srcrect->x * bpp);
306 #ifdef USE_ASM_STRETCH
309 __asm__ __volatile__("call *%4":"=&D"(u1), "=&S"(u2)
310 :"0"(dstp), "1"(srcp), "r"(copy_row)
312 #elif defined(_MSC_VER) || defined(__WATCOMC__)
315 void *code = copy_row;
328 #error Need inline assembly for this compiler
334 copy_row1(srcp, srcrect->w, dstp, dstrect->w);
337 copy_row2((Uint16 *) srcp, srcrect->w,
338 (Uint16 *) dstp, dstrect->w);
341 copy_row3(srcp, srcrect->w, dstp, dstrect->w);
344 copy_row4((Uint32 *) srcp, srcrect->w,
345 (Uint32 *) dstp, dstrect->w);
351 /* We need to unlock the surfaces if they're locked */
353 SDL_UnlockSurface(dst);
356 SDL_UnlockSurface(src);
361 /* vi: set ts=4 sw=4 expandtab: */