Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Work in progress: merging new texture features into SDL blit system

  • Loading branch information
slouken committed Aug 17, 2007
1 parent f49163b commit ac8654a27fae43838e8718ffc9d583e406ab26d4
@@ -906,7 +906,7 @@ SDL_RLEBlit(SDL_Surface * src, SDL_Rect * srcrect,
}

alpha = (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA
? (src->map->cmod >> 24) : 255;
? src->map->info.a : 255;
/* if left or right edge clipping needed, call clip blit */
if (srcrect->x || srcrect->w != src->w) {
RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha);
@@ -1715,7 +1715,7 @@ RLEColorkeySurface(SDL_Surface * surface)
skip = run = 0;
dst = rlebuf;
rgbmask = ~surface->format->Amask;
ckey = surface->map->ckey & rgbmask;
ckey = surface->map->info.colorkey & rgbmask;
lastline = dst;
getpix = getpixes[bpp - 1];
w = surface->w;
@@ -1948,7 +1948,7 @@ SDL_UnRLESurface(SDL_Surface * surface, int recode)
}

/* fill it with the background colour */
SDL_FillRect(surface, NULL, surface->map->ckey);
SDL_FillRect(surface, NULL, surface->map->info.colorkey);

/* now render the encoded surface */
full.x = full.y = 0;
@@ -61,31 +61,23 @@ SDL_SoftBlit(SDL_Surface * src, SDL_Rect * srcrect,

/* Set up source and destination buffer pointers, and BLIT! */
if (okay && srcrect->w && srcrect->h) {
SDL_BlitInfo info;
SDL_loblit RunBlit;
SDL_BlitInfo *info = &src->map->info;

/* Set up the blit information */
info.s_pixels = (Uint8 *) src->pixels +
info->src = (Uint8 *) src->pixels +
(Uint16) srcrect->y * src->pitch +
(Uint16) srcrect->x * src->format->BytesPerPixel;
info.s_width = srcrect->w;
info.s_height = srcrect->h;
info.s_skip = src->pitch - info.s_width * src->format->BytesPerPixel;
info.d_pixels = (Uint8 *) dst->pixels +
(Uint16) srcrect->x * info->src_fmt->BytesPerPixel;
info.src_w = srcrect->w;
info.src_h = srcrect->h;
info.dst = (Uint8 *) dst->pixels +
(Uint16) dstrect->y * dst->pitch +
(Uint16) dstrect->x * dst->format->BytesPerPixel;
info.d_width = dstrect->w;
info.d_height = dstrect->h;
info.d_skip = dst->pitch - info.d_width * dst->format->BytesPerPixel;
info.src = src->format;
info.table = src->map->table;
info.dst = dst->format;
info.ckey = src->map->ckey;
info.cmod = src->map->cmod;
RunBlit = (SDL_loblit) src->map->data;
(Uint16) dstrect->x * info->dst_fmt->BytesPerPixel;
info.dst_w = dstrect->w;
info.dst_h = dstrect->h;
RunBlit = (SDL_BlitFunc) src->map->data;

/* Run the actual software blit */
RunBlit(&info);
RunBlit(info);
}

/* We need to unlock the surfaces if they're locked */
@@ -124,50 +116,67 @@ SDL_UseAltivecPrefetch()
}
#endif /* __MACOSX__ */

static SDL_loblit
SDL_ChooseBlitFunc(SDL_BlitEntry * entries, int count)
static SDL_BlitFunc
SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags, SDL_BlitEntry * entries)
{
int i;
static Uint32 features = 0xffffffff;

/* Get the available CPU features */
if (features == 0xffffffff) {
const char *override = SDL_getenv("SDL_BLIT_FEATURES");
const char *override = SDL_getenv("SDL_BLIT_CPU_FEATURES");

features = SDL_BLIT_ANY;
features = SDL_CPU_ANY;

/* Allow an override for testing .. */
if (override) {
SDL_sscanf(override, "%u", &features);
} else {
if (SDL_HasMMX()) {
features |= SDL_BLIT_MMX;
features |= SDL_CPU_MMX;
}
if (SDL_Has3DNow()) {
features |= SDL_CPU_3DNOW;
}
if (SDL_HasSSE()) {
features |= SDL_BLIT_SSE;
features |= SDL_CPU_SSE;
}
if (SDL_HasSSE2()) {
features |= SDL_CPU_SSE2;
}
if (SDL_HasAltiVec()) {
if (SDL_UseAltivecPrefetch()) {
features |= SDL_BLIT_ALTIVEC_PREFETCH;
features |= SDL_CPU_ALTIVEC_PREFETCH;
} else {
features |= SDL_BLIT_ALTIVEC_NOPREFETCH;
features |= SDL_CPU_ALTIVEC_NOPREFETCH;
}
}
}
}

for (i = count; i > 0; --i) {
if (features & entries[i].features) {
return entries[i].blit;
for (i = 0; entries[i].blit; ++i) {
if (src_format != entries[i].src_format) {
continue;
}
if (dst_format != entries[i].dst_format) {
continue;
}
if ((flags & entries[i].flags) != flags) {
continue;
}
if (!(features & entries[i].cpu)) {
continue;
}
return entries[i].func;
}
return entries[0].blit;
return NULL;
}

/* Figure out which of many blit routines to set up on a surface */
int
SDL_CalculateBlit(SDL_Surface * surface)
{
SDL_loblit blit = NULL;
SDL_BlitFunc blit = NULL;
int blit_index;

/* Clean everything out to start */
@@ -210,6 +219,10 @@ SDL_CalculateBlit(SDL_Surface * surface)
}
}
}
if (blit == NULL) {
blit = SDL_ChooseBlitFunc(src_format, dst_format, surface->map->info.flags, SDL_GeneratedBlitFuncTable);
}

/* Make sure we have a blit function */
if (blit == NULL) {
SDL_InvalidateMap(surface->map);
@@ -33,67 +33,74 @@
#ifdef __SSE__
#include <xmmintrin.h>
#endif
#ifdef __SSE2__
#include <emmintrin.h>
#endif

#include "SDL_cpuinfo.h"
#include "SDL_endian.h"

/* The structure passed to the low level blit functions */
typedef struct
{
Uint8 *s_pixels;
int s_width;
int s_height;
int s_skip;
Uint8 *d_pixels;
int d_width;
int d_height;
int d_skip;
SDL_PixelFormat *src;
/* SDL blit copy flags */
#define SDL_COPY_MODULATE_COLOR 0x0001
#define SDL_COPY_MODULATE_ALPHA 0x0002
#define SDL_COPY_MASK 0x0010
#define SDL_COPY_BLEND 0x0020
#define SDL_COPY_ADD 0x0040
#define SDL_COPY_MOD 0x0080
#define SDL_COPY_COLORKEY 0x0100
#define SDL_COPY_NEAREST 0x0200

/* SDL blit CPU flags */
#define SDL_CPU_ANY 0x0000
#define SDL_CPU_MMX 0x0001
#define SDL_CPU_3DNOW 0x0002
#define SDL_CPU_SSE 0x0004
#define SDL_CPU_SSE2 0x0008
#define SDL_CPU_ALTIVEC_PREFETCH 0x0010
#define SDL_CPU_ALTIVEC_NOPREFETCH 0x0020

typedef struct {
Uint8 *src;
int src_w, src_h;
int src_pitch;
Uint8 *dst;
int dst_w, dst_h;
int dst_pitch;
SDL_PixelFormat *src_fmt;
SDL_PixelFormat *dst_fmt;
Uint8 *table;
SDL_PixelFormat *dst;
Uint32 ckey, cmod;
int flags;
Uint32 colorkey;
Uint8 r, g, b, a;
} SDL_BlitInfo;

/* The type definition for the low level blit functions */
typedef void (*SDL_loblit) (SDL_BlitInfo * info);
typedef void (SDLCALL * SDL_BlitFunc)(SDL_BlitInfo *info);

typedef struct {
Uint32 src_format;
Uint32 dst_format;
int flags;
int cpu;
SDL_BlitFunc func;
} SDL_BlitFuncEntry;

/* Blit mapping definition */
typedef struct SDL_BlitMap
{
SDL_Surface *dst;
int identity;
Uint8 *table;
SDL_blit blit;
void *data;
Uint32 ckey; /* colorkey */
Uint32 cmod; /* ARGB modulation */
SDL_BlitInfo info;

/* the version count matches the destination; mismatch indicates
an invalid mapping */
unsigned int format_version;
} SDL_BlitMap;

#define SDL_BLIT_ANY 0x00000000
#define SDL_BLIT_MMX 0x00000001
#define SDL_BLIT_SSE 0x00000002
#define SDL_BLIT_ALTIVEC_PREFETCH 0x00000004
#define SDL_BLIT_ALTIVEC_NOPREFETCH 0x00000008

typedef struct SDL_BlitEntry
{
Uint32 features;
SDL_loblit blit;
} SDL_BlitEntry;

/* Functions found in SDL_blit.c */
extern int SDL_CalculateBlit(SDL_Surface * surface);

/* Functions found in SDL_blit_{0,1,N,A}.c */
extern SDL_loblit SDL_CalculateBlit0(SDL_Surface * surface, int complex);
extern SDL_loblit SDL_CalculateBlit1(SDL_Surface * surface, int complex);
extern SDL_loblit SDL_CalculateBlitN(SDL_Surface * surface, int complex);
extern SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface * surface, int complex);

/*
* Useful macros for blitting routines
*/

0 comments on commit ac8654a

Please sign in to comment.