36 #if ((defined(_MFC_VER) && defined(_M_IX86)) || \
37 defined(__WATCOMC__) || \
38 (defined(__GNUC__) && defined(__i386__))) && SDL_ASSEMBLY_ROUTINES
44 #ifdef USE_ASM_STRETCH
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;
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\n", 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,
A collection of pixels used in software blitting.
GLuint GLdouble GLdouble u2
static void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w)
#define DEFINE_COPY_ROW(name, type)
uint32_t Uint32
An unsigned 32-bit integer type.
DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface *surface)
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
uint8_t Uint8
An unsigned 8-bit integer type.
uint16_t Uint16
An unsigned 16-bit integer type.
DECLSPEC int SDLCALL SDL_LockSurface(SDL_Surface *surface)
Sets up a surface for directly accessing the pixels.
A rectangle, with the origin at the upper left.
DECLSPEC int SDLCALL 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.