src/video/SDL_stretch.c
changeset 1895 c121d94672cb
parent 1849 b5a4ac87b98c
child 1985 8055185ae4ed
     1.1 --- a/src/video/SDL_stretch.c	Thu Jul 06 18:01:37 2006 +0000
     1.2 +++ b/src/video/SDL_stretch.c	Mon Jul 10 21:04:37 2006 +0000
     1.3 @@ -55,67 +55,68 @@
     1.4  
     1.5  static unsigned char copy_row[4096];
     1.6  
     1.7 -static int generate_rowbytes(int src_w, int dst_w, int bpp)
     1.8 +static int
     1.9 +generate_rowbytes(int src_w, int dst_w, int bpp)
    1.10  {
    1.11 -	static struct {
    1.12 -		int bpp;
    1.13 -		int src_w;
    1.14 -		int dst_w;
    1.15 -	} last;
    1.16 +    static struct
    1.17 +    {
    1.18 +        int bpp;
    1.19 +        int src_w;
    1.20 +        int dst_w;
    1.21 +    } last;
    1.22  
    1.23 -	int i;
    1.24 -	int pos, inc;
    1.25 -	unsigned char *eip;
    1.26 -	unsigned char load, store;
    1.27 +    int i;
    1.28 +    int pos, inc;
    1.29 +    unsigned char *eip;
    1.30 +    unsigned char load, store;
    1.31  
    1.32 -	/* See if we need to regenerate the copy buffer */
    1.33 -	if ( (src_w == last.src_w) &&
    1.34 -	     (dst_w == last.dst_w) && (bpp == last.bpp) ) {
    1.35 -		return(0);
    1.36 -	}
    1.37 -	last.bpp = bpp;
    1.38 -	last.src_w = src_w;
    1.39 -	last.dst_w = dst_w;
    1.40 +    /* See if we need to regenerate the copy buffer */
    1.41 +    if ((src_w == last.src_w) && (dst_w == last.dst_w) && (bpp == last.bpp)) {
    1.42 +        return (0);
    1.43 +    }
    1.44 +    last.bpp = bpp;
    1.45 +    last.src_w = src_w;
    1.46 +    last.dst_w = dst_w;
    1.47  
    1.48 -	switch (bpp) {
    1.49 -	    case 1:
    1.50 -		load = LOAD_BYTE;
    1.51 -		store = STORE_BYTE;
    1.52 -		break;
    1.53 -	    case 2:
    1.54 -	    case 4:
    1.55 -		load = LOAD_WORD;
    1.56 -		store = STORE_WORD;
    1.57 -		break;
    1.58 -	    default:
    1.59 -		SDL_SetError("ASM stretch of %d bytes isn't supported\n", bpp);
    1.60 -		return(-1);
    1.61 -	}
    1.62 -	pos = 0x10000;
    1.63 -	inc = (src_w << 16) / dst_w;
    1.64 -	eip = copy_row;
    1.65 -	for ( i=0; i<dst_w; ++i ) {
    1.66 -		while ( pos >= 0x10000L ) {
    1.67 -			if ( bpp == 2 ) {
    1.68 -				*eip++ = PREFIX16;
    1.69 -			}
    1.70 -			*eip++ = load;
    1.71 -			pos -= 0x10000L;
    1.72 -		}
    1.73 -		if ( bpp == 2 ) {
    1.74 -			*eip++ = PREFIX16;
    1.75 -		}
    1.76 -		*eip++ = store;
    1.77 -		pos += inc;
    1.78 -	}
    1.79 -	*eip++ = RETURN;
    1.80 +    switch (bpp) {
    1.81 +    case 1:
    1.82 +        load = LOAD_BYTE;
    1.83 +        store = STORE_BYTE;
    1.84 +        break;
    1.85 +    case 2:
    1.86 +    case 4:
    1.87 +        load = LOAD_WORD;
    1.88 +        store = STORE_WORD;
    1.89 +        break;
    1.90 +    default:
    1.91 +        SDL_SetError("ASM stretch of %d bytes isn't supported\n", bpp);
    1.92 +        return (-1);
    1.93 +    }
    1.94 +    pos = 0x10000;
    1.95 +    inc = (src_w << 16) / dst_w;
    1.96 +    eip = copy_row;
    1.97 +    for (i = 0; i < dst_w; ++i) {
    1.98 +        while (pos >= 0x10000L) {
    1.99 +            if (bpp == 2) {
   1.100 +                *eip++ = PREFIX16;
   1.101 +            }
   1.102 +            *eip++ = load;
   1.103 +            pos -= 0x10000L;
   1.104 +        }
   1.105 +        if (bpp == 2) {
   1.106 +            *eip++ = PREFIX16;
   1.107 +        }
   1.108 +        *eip++ = store;
   1.109 +        pos += inc;
   1.110 +    }
   1.111 +    *eip++ = RETURN;
   1.112  
   1.113 -	/* Verify that we didn't overflow (too late) */
   1.114 -	if ( eip > (copy_row+sizeof(copy_row)) ) {
   1.115 -		SDL_SetError("Copy buffer overflow");
   1.116 -		return(-1);
   1.117 -	}
   1.118 -	return(0);
   1.119 +    /* Verify that we didn't overflow (too late) */
   1.120 +    if (eip > (copy_row + sizeof(copy_row))) {
   1.121 +        SDL_SetError("Copy buffer overflow");
   1.122 +        return (-1);
   1.123 +    }
   1.124 +    return (0);
   1.125  }
   1.126  
   1.127  #else
   1.128 @@ -139,196 +140,186 @@
   1.129  	}						\
   1.130  }
   1.131  DEFINE_COPY_ROW(copy_row1, Uint8)
   1.132 -DEFINE_COPY_ROW(copy_row2, Uint16)
   1.133 -DEFINE_COPY_ROW(copy_row4, Uint32)
   1.134 +    DEFINE_COPY_ROW(copy_row2, Uint16) DEFINE_COPY_ROW(copy_row4, Uint32)
   1.135 +#endif /* USE_ASM_STRETCH */
   1.136 +/* The ASM code doesn't handle 24-bpp stretch blits */
   1.137 +     void
   1.138 +     copy_row3(Uint8 * src, int src_w, Uint8 * dst, int dst_w)
   1.139 +{
   1.140 +    int i;
   1.141 +    int pos, inc;
   1.142 +    Uint8 pixel[3];
   1.143  
   1.144 -#endif /* USE_ASM_STRETCH */
   1.145 -
   1.146 -/* The ASM code doesn't handle 24-bpp stretch blits */
   1.147 -void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w)
   1.148 -{
   1.149 -	int i;
   1.150 -	int pos, inc;
   1.151 -	Uint8 pixel[3] = { 0, 0, 0 };
   1.152 -
   1.153 -	pos = 0x10000;
   1.154 -	inc = (src_w << 16) / dst_w;
   1.155 -	for ( i=dst_w; i>0; --i ) {
   1.156 -		while ( pos >= 0x10000L ) {
   1.157 -			pixel[0] = *src++;
   1.158 -			pixel[1] = *src++;
   1.159 -			pixel[2] = *src++;
   1.160 -			pos -= 0x10000L;
   1.161 -		}
   1.162 -		*dst++ = pixel[0];
   1.163 -		*dst++ = pixel[1];
   1.164 -		*dst++ = pixel[2];
   1.165 -		pos += inc;
   1.166 -	}
   1.167 +    pos = 0x10000;
   1.168 +    inc = (src_w << 16) / dst_w;
   1.169 +    for (i = dst_w; i > 0; --i) {
   1.170 +        while (pos >= 0x10000L) {
   1.171 +            pixel[0] = *src++;
   1.172 +            pixel[1] = *src++;
   1.173 +            pixel[2] = *src++;
   1.174 +            pos -= 0x10000L;
   1.175 +        }
   1.176 +        *dst++ = pixel[0];
   1.177 +        *dst++ = pixel[1];
   1.178 +        *dst++ = pixel[2];
   1.179 +        pos += inc;
   1.180 +    }
   1.181  }
   1.182  
   1.183  /* Perform a stretch blit between two surfaces of the same format.
   1.184     NOTE:  This function is not safe to call from multiple threads!
   1.185  */
   1.186 -int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect,
   1.187 -                    SDL_Surface *dst, SDL_Rect *dstrect)
   1.188 +int
   1.189 +SDL_SoftStretch(SDL_Surface * src, SDL_Rect * srcrect,
   1.190 +                SDL_Surface * dst, SDL_Rect * dstrect)
   1.191  {
   1.192 -	int src_locked;
   1.193 -	int dst_locked;
   1.194 -	int pos, inc;
   1.195 -	int dst_width;
   1.196 -	int dst_maxrow;
   1.197 -	int src_row, dst_row;
   1.198 -	Uint8 *srcp = NULL;
   1.199 -	Uint8 *dstp;
   1.200 -	SDL_Rect full_src;
   1.201 -	SDL_Rect full_dst;
   1.202 +    int src_locked;
   1.203 +    int dst_locked;
   1.204 +    int pos, inc;
   1.205 +    int dst_width;
   1.206 +    int dst_maxrow;
   1.207 +    int src_row, dst_row;
   1.208 +    Uint8 *srcp = NULL;
   1.209 +    Uint8 *dstp;
   1.210 +    SDL_Rect full_src;
   1.211 +    SDL_Rect full_dst;
   1.212  #if defined(USE_ASM_STRETCH) && defined(__GNUC__)
   1.213 -	int u1, u2;
   1.214 +    int u1, u2;
   1.215  #endif
   1.216 -	const int bpp = dst->format->BytesPerPixel;
   1.217 +    const int bpp = dst->format->BytesPerPixel;
   1.218  
   1.219 -	if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) {
   1.220 -		SDL_SetError("Only works with same format surfaces");
   1.221 -		return(-1);
   1.222 -	}
   1.223 +    if (src->format->BitsPerPixel != dst->format->BitsPerPixel) {
   1.224 +        SDL_SetError("Only works with same format surfaces");
   1.225 +        return (-1);
   1.226 +    }
   1.227  
   1.228 -	/* Verify the blit rectangles */
   1.229 -	if ( srcrect ) {
   1.230 -		if ( (srcrect->x < 0) || (srcrect->y < 0) ||
   1.231 -		     ((srcrect->x+srcrect->w) > src->w) ||
   1.232 -		     ((srcrect->y+srcrect->h) > src->h) ) {
   1.233 -			SDL_SetError("Invalid source blit rectangle");
   1.234 -			return(-1);
   1.235 -		}
   1.236 -	} else {
   1.237 -		full_src.x = 0;
   1.238 -		full_src.y = 0;
   1.239 -		full_src.w = src->w;
   1.240 -		full_src.h = src->h;
   1.241 -		srcrect = &full_src;
   1.242 -	}
   1.243 -	if ( dstrect ) {
   1.244 -		if ( (dstrect->x < 0) || (dstrect->y < 0) ||
   1.245 -		     ((dstrect->x+dstrect->w) > dst->w) ||
   1.246 -		     ((dstrect->y+dstrect->h) > dst->h) ) {
   1.247 -			SDL_SetError("Invalid destination blit rectangle");
   1.248 -			return(-1);
   1.249 -		}
   1.250 -	} else {
   1.251 -		full_dst.x = 0;
   1.252 -		full_dst.y = 0;
   1.253 -		full_dst.w = dst->w;
   1.254 -		full_dst.h = dst->h;
   1.255 -		dstrect = &full_dst;
   1.256 -	}
   1.257 +    /* Verify the blit rectangles */
   1.258 +    if (srcrect) {
   1.259 +        if ((srcrect->x < 0) || (srcrect->y < 0) ||
   1.260 +            ((srcrect->x + srcrect->w) > src->w) ||
   1.261 +            ((srcrect->y + srcrect->h) > src->h)) {
   1.262 +            SDL_SetError("Invalid source blit rectangle");
   1.263 +            return (-1);
   1.264 +        }
   1.265 +    } else {
   1.266 +        full_src.x = 0;
   1.267 +        full_src.y = 0;
   1.268 +        full_src.w = src->w;
   1.269 +        full_src.h = src->h;
   1.270 +        srcrect = &full_src;
   1.271 +    }
   1.272 +    if (dstrect) {
   1.273 +        if ((dstrect->x < 0) || (dstrect->y < 0) ||
   1.274 +            ((dstrect->x + dstrect->w) > dst->w) ||
   1.275 +            ((dstrect->y + dstrect->h) > dst->h)) {
   1.276 +            SDL_SetError("Invalid destination blit rectangle");
   1.277 +            return (-1);
   1.278 +        }
   1.279 +    } else {
   1.280 +        full_dst.x = 0;
   1.281 +        full_dst.y = 0;
   1.282 +        full_dst.w = dst->w;
   1.283 +        full_dst.h = dst->h;
   1.284 +        dstrect = &full_dst;
   1.285 +    }
   1.286  
   1.287 -	/* Lock the destination if it's in hardware */
   1.288 -	dst_locked = 0;
   1.289 -	if ( SDL_MUSTLOCK(dst) ) {
   1.290 -		if ( SDL_LockSurface(dst) < 0 ) {
   1.291 -			SDL_SetError("Unable to lock destination surface");
   1.292 -			return(-1);
   1.293 -		}
   1.294 -		dst_locked = 1;
   1.295 -	}
   1.296 -	/* Lock the source if it's in hardware */
   1.297 -	src_locked = 0;
   1.298 -	if ( SDL_MUSTLOCK(src) ) {
   1.299 -		if ( SDL_LockSurface(src) < 0 ) {
   1.300 -			if ( dst_locked ) {
   1.301 -				SDL_UnlockSurface(dst);
   1.302 -			}
   1.303 -			SDL_SetError("Unable to lock source surface");
   1.304 -			return(-1);
   1.305 -		}
   1.306 -		src_locked = 1;
   1.307 -	}
   1.308 +    /* Lock the destination if it's in hardware */
   1.309 +    dst_locked = 0;
   1.310 +    if (SDL_MUSTLOCK(dst)) {
   1.311 +        if (SDL_LockSurface(dst) < 0) {
   1.312 +            SDL_SetError("Unable to lock destination surface");
   1.313 +            return (-1);
   1.314 +        }
   1.315 +        dst_locked = 1;
   1.316 +    }
   1.317 +    /* Lock the source if it's in hardware */
   1.318 +    src_locked = 0;
   1.319 +    if (SDL_MUSTLOCK(src)) {
   1.320 +        if (SDL_LockSurface(src) < 0) {
   1.321 +            if (dst_locked) {
   1.322 +                SDL_UnlockSurface(dst);
   1.323 +            }
   1.324 +            SDL_SetError("Unable to lock source surface");
   1.325 +            return (-1);
   1.326 +        }
   1.327 +        src_locked = 1;
   1.328 +    }
   1.329  
   1.330 -	/* Set up the data... */
   1.331 -	pos = 0x10000;
   1.332 -	inc = (srcrect->h << 16) / dstrect->h;
   1.333 -	src_row = srcrect->y;
   1.334 -	dst_row = dstrect->y;
   1.335 -	dst_width = dstrect->w*bpp;
   1.336 +    /* Set up the data... */
   1.337 +    pos = 0x10000;
   1.338 +    inc = (srcrect->h << 16) / dstrect->h;
   1.339 +    src_row = srcrect->y;
   1.340 +    dst_row = dstrect->y;
   1.341 +    dst_width = dstrect->w * bpp;
   1.342  
   1.343  #ifdef USE_ASM_STRETCH
   1.344 -	/* Write the opcodes for this stretch */
   1.345 -	if ( (bpp != 3) &&
   1.346 -	     (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0) ) {
   1.347 -		return(-1);
   1.348 -	}
   1.349 +    /* Write the opcodes for this stretch */
   1.350 +    if ((bpp != 3) && (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0)) {
   1.351 +        return (-1);
   1.352 +    }
   1.353  #endif
   1.354  
   1.355 -	/* Perform the stretch blit */
   1.356 -	for ( dst_maxrow = dst_row+dstrect->h; dst_row<dst_maxrow; ++dst_row ) {
   1.357 -		dstp = (Uint8 *)dst->pixels + (dst_row*dst->pitch)
   1.358 -		                            + (dstrect->x*bpp);
   1.359 -		while ( pos >= 0x10000L ) {
   1.360 -			srcp = (Uint8 *)src->pixels + (src_row*src->pitch)
   1.361 -			                            + (srcrect->x*bpp);
   1.362 -			++src_row;
   1.363 -			pos -= 0x10000L;
   1.364 -		}
   1.365 +    /* Perform the stretch blit */
   1.366 +    for (dst_maxrow = dst_row + dstrect->h; dst_row < dst_maxrow; ++dst_row) {
   1.367 +        dstp = (Uint8 *) dst->pixels + (dst_row * dst->pitch)
   1.368 +            + (dstrect->x * bpp);
   1.369 +        while (pos >= 0x10000L) {
   1.370 +            srcp = (Uint8 *) src->pixels + (src_row * src->pitch)
   1.371 +                + (srcrect->x * bpp);
   1.372 +            ++src_row;
   1.373 +            pos -= 0x10000L;
   1.374 +        }
   1.375  #ifdef USE_ASM_STRETCH
   1.376 -		switch (bpp) {
   1.377 -		    case 3:
   1.378 -			copy_row3(srcp, srcrect->w, dstp, dstrect->w);
   1.379 -			break;
   1.380 -		    default:
   1.381 +        switch (bpp) {
   1.382 +        case 3:
   1.383 +            copy_row3(srcp, srcrect->w, dstp, dstrect->w);
   1.384 +            break;
   1.385 +        default:
   1.386  #ifdef __GNUC__
   1.387 -			__asm__ __volatile__ (
   1.388 -			"call *%4"
   1.389 -			: "=&D" (u1), "=&S" (u2)
   1.390 -			: "0" (dstp), "1" (srcp), "r" (copy_row)
   1.391 -			: "memory" );
   1.392 +          __asm__ __volatile__("call *%4": "=&D"(u1), "=&S"(u2): "0"(dstp), "1"(srcp), "r"(copy_row):"memory");
   1.393  #elif defined(_MSC_VER) || defined(__WATCOMC__)
   1.394 -		{ void *code = copy_row;
   1.395 -			__asm {
   1.396 -				push edi
   1.397 -				push esi
   1.398 -	
   1.399 -				mov edi, dstp
   1.400 -				mov esi, srcp
   1.401 -				call dword ptr code
   1.402 -
   1.403 -				pop esi
   1.404 -				pop edi
   1.405 -			}
   1.406 -		}
   1.407 +            {
   1.408 +                void *code = copy_row;
   1.409 +                __asm {
   1.410 +                push edi
   1.411 +                        push esi
   1.412 +                        mov edi, dstp
   1.413 +                        mov esi, srcp call dword ptr code pop esi pop edi}
   1.414 +            }
   1.415  #else
   1.416  #error Need inline assembly for this compiler
   1.417  #endif
   1.418 -			break;
   1.419 -		}
   1.420 +            break;
   1.421 +        }
   1.422  #else
   1.423 -		switch (bpp) {
   1.424 -		    case 1:
   1.425 -			copy_row1(srcp, srcrect->w, dstp, dstrect->w);
   1.426 -			break;
   1.427 -		    case 2:
   1.428 -			copy_row2((Uint16 *)srcp, srcrect->w,
   1.429 -			          (Uint16 *)dstp, dstrect->w);
   1.430 -			break;
   1.431 -		    case 3:
   1.432 -			copy_row3(srcp, srcrect->w, dstp, dstrect->w);
   1.433 -			break;
   1.434 -		    case 4:
   1.435 -			copy_row4((Uint32 *)srcp, srcrect->w,
   1.436 -			          (Uint32 *)dstp, dstrect->w);
   1.437 -			break;
   1.438 -		}
   1.439 +        switch (bpp) {
   1.440 +        case 1:
   1.441 +            copy_row1(srcp, srcrect->w, dstp, dstrect->w);
   1.442 +            break;
   1.443 +        case 2:
   1.444 +            copy_row2((Uint16 *) srcp, srcrect->w,
   1.445 +                      (Uint16 *) dstp, dstrect->w);
   1.446 +            break;
   1.447 +        case 3:
   1.448 +            copy_row3(srcp, srcrect->w, dstp, dstrect->w);
   1.449 +            break;
   1.450 +        case 4:
   1.451 +            copy_row4((Uint32 *) srcp, srcrect->w,
   1.452 +                      (Uint32 *) dstp, dstrect->w);
   1.453 +            break;
   1.454 +        }
   1.455  #endif
   1.456 -		pos += inc;
   1.457 -	}
   1.458 +        pos += inc;
   1.459 +    }
   1.460  
   1.461 -	/* We need to unlock the surfaces if they're locked */
   1.462 -	if ( dst_locked ) {
   1.463 -		SDL_UnlockSurface(dst);
   1.464 -	}
   1.465 -	if ( src_locked ) {
   1.466 -		SDL_UnlockSurface(src);
   1.467 -	}
   1.468 -	return(0);
   1.469 +    /* We need to unlock the surfaces if they're locked */
   1.470 +    if (dst_locked) {
   1.471 +        SDL_UnlockSurface(dst);
   1.472 +    }
   1.473 +    if (src_locked) {
   1.474 +        SDL_UnlockSurface(src);
   1.475 +    }
   1.476 +    return (0);
   1.477  }
   1.478  
   1.479 +/* vi: set ts=4 sw=4 expandtab: */