21 #include "../SDL_internal.h" 36 #if ((defined(_MSC_VER) && defined(_M_IX86)) || \ 37 (defined(__WATCOMC__) && defined(__386__)) || \ 38 (defined(__GNUC__) && defined(__i386__))) && SDL_ASSEMBLY_ROUTINES 44 #ifdef USE_ASM_STRETCH 47 #include <sys/types.h> 51 #define PAGE_ALIGNED __attribute__((__aligned__(4096))) 56 #if defined(_M_IX86) || defined(__i386__) || defined(__386__) 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;
86 if ((src_w == last.src_w) && (dst_w == last.dst_w) && (bpp == last.bpp)) {
105 return SDL_SetError(
"ASM stretch of %d bytes isn't supported", bpp);
109 if (mprotect(copy_row,
sizeof(copy_row), PROT_READ | PROT_WRITE) < 0) {
110 return SDL_SetError(
"Couldn't make copy buffer writeable");
114 inc = (src_w << 16) / dst_w;
116 fence = copy_row +
sizeof(copy_row)-2;
117 for (i = 0; i < dst_w; ++
i) {
118 while (pos >= 0x10000L) {
141 if (mprotect(copy_row,
sizeof(copy_row), PROT_READ | PROT_EXEC) < 0) {
142 return SDL_SetError(
"Couldn't make copy buffer executable");
151 #define DEFINE_COPY_ROW(name, type) \ 152 static void name(type *src, int src_w, type *dst, int dst_w) \ 159 inc = (src_w << 16) / dst_w; \ 160 for ( i=dst_w; i>0; --i ) { \ 161 while ( pos >= 0x10000L ) { \ 181 Uint8 pixel[3] = { 0, 0, 0 };
184 inc = (src_w << 16) / dst_w;
185 for (i = dst_w; i > 0; --
i) {
186 while (pos >= 0x10000L) {
210 int src_row, dst_row;
215 #ifdef USE_ASM_STRETCH 224 return SDL_SetError(
"Only works with same format surfaces");
229 if ((srcrect->
x < 0) || (srcrect->
y < 0) ||
230 ((srcrect->
x + srcrect->
w) > src->
w) ||
231 ((srcrect->
y + srcrect->
h) > src->
h)) {
242 if ((dstrect->
x < 0) || (dstrect->
y < 0) ||
243 ((dstrect->
x + dstrect->
w) > dst->
w) ||
244 ((dstrect->
y + dstrect->
h) > dst->
h)) {
245 return SDL_SetError(
"Invalid destination blit rectangle");
259 return SDL_SetError(
"Unable to lock destination surface");
277 inc = (srcrect->
h << 16) / dstrect->
h;
278 src_row = srcrect->
y;
279 dst_row = dstrect->
y;
281 #ifdef USE_ASM_STRETCH
283 if ((bpp == 3) || (generate_rowbytes(srcrect->
w, dstrect->
w, bpp) < 0)) {
289 for (dst_maxrow = dst_row + dstrect->
h; dst_row < dst_maxrow; ++dst_row) {
291 + (dstrect->
x * bpp);
292 while (pos >= 0x10000L) {
294 + (srcrect->
x * bpp);
298 #ifdef USE_ASM_STRETCH 301 __asm__ __volatile__(
"call *%4":
"=&D"(u1),
"=&S"(u2)
302 :
"0"(dstp),
"1"(srcp),
"r"(copy_row)
304 #elif defined(_MSC_VER) || defined(__WATCOMC__) 307 void *code = copy_row;
320 #error Need inline assembly for this compiler 326 copy_row1(srcp, srcrect->
w, dstp, dstrect->
w);
329 copy_row2((
Uint16 *) srcp, srcrect->
w,
336 copy_row4((
Uint32 *) srcp, srcrect->
w,
#define SDL_UnlockSurface
A collection of pixels used in software blitting.
static void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w)
#define DEFINE_COPY_ROW(name, type)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
int SDL_SoftStretch(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect)
Perform a fast, low quality, stretch blit between two surfaces of the same pixel format.
A rectangle, with the origin at the upper left.