Added source color and alpha modulation support.
Added perl script to generate optimized render copy functions. --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402032
This commit is contained in:
parent
aebbf8cb6e
commit
fdafca64b3
25 changed files with 6938 additions and 288 deletions
521
src/video/sdlgenblit.pl
Executable file
521
src/video/sdlgenblit.pl
Executable file
|
@ -0,0 +1,521 @@
|
|||
#!/usr/bin/perl -w
|
||||
#
|
||||
# A script to generate optimized C blitters for Simple DirectMedia Layer
|
||||
# http://www.libsdl.org/
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
my %file;
|
||||
|
||||
# The formats potentially supported by this script:
|
||||
# SDL_PIXELFORMAT_INDEX8
|
||||
# SDL_PIXELFORMAT_RGB332
|
||||
# SDL_PIXELFORMAT_RGB444
|
||||
# SDL_PIXELFORMAT_RGB555
|
||||
# SDL_PIXELFORMAT_ARGB4444
|
||||
# SDL_PIXELFORMAT_ARGB1555
|
||||
# SDL_PIXELFORMAT_RGB565
|
||||
# SDL_PIXELFORMAT_RGB24
|
||||
# SDL_PIXELFORMAT_BGR24
|
||||
# SDL_PIXELFORMAT_RGB888
|
||||
# SDL_PIXELFORMAT_BGR888
|
||||
# SDL_PIXELFORMAT_ARGB8888
|
||||
# SDL_PIXELFORMAT_RGBA8888
|
||||
# SDL_PIXELFORMAT_ABGR8888
|
||||
# SDL_PIXELFORMAT_BGRA8888
|
||||
# SDL_PIXELFORMAT_ARGB2101010
|
||||
|
||||
# The formats we're actually creating blitters for:
|
||||
my @src_formats = (
|
||||
"RGB888",
|
||||
"BGR888",
|
||||
"ARGB8888",
|
||||
"RGBA8888",
|
||||
"ABGR8888",
|
||||
"BGRA8888",
|
||||
);
|
||||
my @dst_formats = (
|
||||
"RGB888",
|
||||
"BGR888",
|
||||
);
|
||||
|
||||
my %format_size = (
|
||||
"RGB888" => 4,
|
||||
"BGR888" => 4,
|
||||
"ARGB8888" => 4,
|
||||
"RGBA8888" => 4,
|
||||
"ABGR8888" => 4,
|
||||
"BGRA8888" => 4,
|
||||
);
|
||||
|
||||
my %format_type = (
|
||||
"RGB888" => "Uint32",
|
||||
"BGR888" => "Uint32",
|
||||
"ARGB8888" => "Uint32",
|
||||
"RGBA8888" => "Uint32",
|
||||
"ABGR8888" => "Uint32",
|
||||
"BGRA8888" => "Uint32",
|
||||
);
|
||||
|
||||
my %get_rgba_string = (
|
||||
"RGB888" => "_R = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _B = (Uint8)_pixel; _A = 0xFF;",
|
||||
"BGR888" => "_B = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _R = (Uint8)_pixel; _A = 0xFF;",
|
||||
"ARGB8888" => "_A = (Uint8)(_pixel >> 24); _R = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _B = (Uint8)_pixel;",
|
||||
"RGBA8888" => "_R = (Uint8)(_pixel >> 24); _G = (Uint8)(_pixel >> 16); _B = (Uint8)(_pixel >> 8); _A = (Uint8)_pixel;",
|
||||
"ABGR8888" => "_A = (Uint8)(_pixel >> 24); _B = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _R = (Uint8)_pixel;",
|
||||
"BGRA8888" => "_B = (Uint8)(_pixel >> 24); _G = (Uint8)(_pixel >> 16); _R = (Uint8)(_pixel >> 8); _A = (Uint8)_pixel;",
|
||||
);
|
||||
|
||||
my %set_rgba_string = (
|
||||
"RGB888" => "_pixel = ((Uint32)_R << 16) | ((Uint32)_G << 8) | _B;",
|
||||
"BGR888" => "_pixel = ((Uint32)_B << 16) | ((Uint32)_G << 8) | _R;",
|
||||
);
|
||||
|
||||
sub open_file {
|
||||
my $name = shift;
|
||||
open(FILE, ">$name.new") || die "Cant' open $name.new: $!";
|
||||
print FILE <<__EOF__;
|
||||
/* DO NOT EDIT! This file is generated by sdlgenblit.pl */
|
||||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken\@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
__EOF__
|
||||
}
|
||||
|
||||
sub close_file {
|
||||
my $name = shift;
|
||||
print FILE <<__EOF__;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
__EOF__
|
||||
close FILE;
|
||||
if ( ! -f $name || system("cmp -s $name $name.new") != 0 ) {
|
||||
rename("$name.new", "$name");
|
||||
} else {
|
||||
unlink("$name.new");
|
||||
}
|
||||
}
|
||||
|
||||
sub output_copydefs
|
||||
{
|
||||
print FILE <<__EOF__;
|
||||
#define SDL_RENDERCOPY_MODULATE_COLOR 0x0001
|
||||
#define SDL_RENDERCOPY_MODULATE_ALPHA 0x0002
|
||||
#define SDL_RENDERCOPY_BLEND 0x0010
|
||||
#define SDL_RENDERCOPY_ADD 0x0020
|
||||
#define SDL_RENDERCOPY_MOD 0x0040
|
||||
#define SDL_RENDERCOPY_NEAREST 0x0100
|
||||
|
||||
typedef struct {
|
||||
void *src;
|
||||
int src_w, src_h;
|
||||
int src_pitch;
|
||||
void *dst;
|
||||
int dst_w, dst_h;
|
||||
int dst_pitch;
|
||||
void *aux_data;
|
||||
int flags;
|
||||
Uint8 r, g, b, a;
|
||||
} SDL_RenderCopyData;
|
||||
|
||||
typedef int (*SDL_RenderCopyFunc)(SDL_RenderCopyData *data);
|
||||
|
||||
extern SDL_RenderCopyFunc SDLCALL SDL_GetRenderCopyFunc(Uint32 src_format, Uint32 dst_format, int modMode, int blendMode, int scaleMode);
|
||||
|
||||
__EOF__
|
||||
}
|
||||
|
||||
sub output_copyfuncname
|
||||
{
|
||||
my $prefix = shift;
|
||||
my $src = shift;
|
||||
my $dst = shift;
|
||||
my $modulate = shift;
|
||||
my $blend = shift;
|
||||
my $scale = shift;
|
||||
my $args = shift;
|
||||
my $suffix = shift;
|
||||
|
||||
print FILE "$prefix SDL_RenderCopy_${src}_${dst}";
|
||||
if ( $modulate ) {
|
||||
print FILE "_Modulate";
|
||||
}
|
||||
if ( $blend ) {
|
||||
print FILE "_Blend";
|
||||
}
|
||||
if ( $scale ) {
|
||||
print FILE "_Scale";
|
||||
}
|
||||
if ( $args ) {
|
||||
print FILE "(SDL_RenderCopyData *data)";
|
||||
}
|
||||
print FILE "$suffix";
|
||||
}
|
||||
|
||||
sub get_rgba
|
||||
{
|
||||
my $prefix = shift;
|
||||
my $format = shift;
|
||||
my $string = $get_rgba_string{$format};
|
||||
$string =~ s/_/$prefix/g;
|
||||
if ( $prefix ne "" ) {
|
||||
print FILE <<__EOF__;
|
||||
${prefix}pixel = *$prefix;
|
||||
__EOF__
|
||||
} else {
|
||||
print FILE <<__EOF__;
|
||||
pixel = *src;
|
||||
__EOF__
|
||||
}
|
||||
print FILE <<__EOF__;
|
||||
$string
|
||||
__EOF__
|
||||
}
|
||||
|
||||
sub set_rgba
|
||||
{
|
||||
my $prefix = shift;
|
||||
my $format = shift;
|
||||
my $string = $set_rgba_string{$format};
|
||||
$string =~ s/_/$prefix/g;
|
||||
print FILE <<__EOF__;
|
||||
$string
|
||||
*dst = ${prefix}pixel;
|
||||
__EOF__
|
||||
}
|
||||
|
||||
sub output_copycore
|
||||
{
|
||||
my $src = shift;
|
||||
my $dst = shift;
|
||||
my $modulate = shift;
|
||||
my $blend = shift;
|
||||
if ( $modulate ) {
|
||||
print FILE <<__EOF__;
|
||||
if (flags & SDL_RENDERCOPY_MODULATE_COLOR) {
|
||||
${src}R = (${src}R * modulateR) / 255;
|
||||
${src}G = (${src}G * modulateG) / 255;
|
||||
${src}B = (${src}B * modulateB) / 255;
|
||||
}
|
||||
__EOF__
|
||||
}
|
||||
if ( $modulate && $blend ) {
|
||||
print FILE <<__EOF__;
|
||||
if (flags & SDL_RENDERCOPY_MODULATE_ALPHA) {
|
||||
${src}A = (${src}A * modulateA) / 255;
|
||||
}
|
||||
__EOF__
|
||||
}
|
||||
if ( $blend ) {
|
||||
print FILE <<__EOF__;
|
||||
if (flags & (SDL_RENDERCOPY_BLEND|SDL_RENDERCOPY_ADD)) {
|
||||
/* This goes away if we ever use premultiplied alpha */
|
||||
${src}R = (${src}R * ${src}A) / 255;
|
||||
${src}G = (${src}G * ${src}A) / 255;
|
||||
${src}B = (${src}B * ${src}A) / 255;
|
||||
}
|
||||
switch (flags & (SDL_RENDERCOPY_BLEND|SDL_RENDERCOPY_ADD|SDL_RENDERCOPY_MOD)) {
|
||||
case SDL_RENDERCOPY_BLEND:
|
||||
${dst}R = ${src}R + ((255 - ${src}A) * ${dst}R) / 255;
|
||||
${dst}G = ${src}G + ((255 - ${src}A) * ${dst}G) / 255;
|
||||
${dst}B = ${src}B + ((255 - ${src}A) * ${dst}B) / 255;
|
||||
break;
|
||||
case SDL_RENDERCOPY_ADD:
|
||||
${dst}R = ${src}R + ${dst}R; if (${dst}R > 255) ${dst}R = 255;
|
||||
${dst}G = ${src}G + ${dst}G; if (${dst}G > 255) ${dst}G = 255;
|
||||
${dst}B = ${src}B + ${dst}B; if (${dst}B > 255) ${dst}B = 255;
|
||||
break;
|
||||
case SDL_RENDERCOPY_MOD:
|
||||
${dst}R = (${src}R * ${dst}R) / 255;
|
||||
${dst}G = (${src}G * ${dst}G) / 255;
|
||||
${dst}B = (${src}B * ${dst}B) / 255;
|
||||
break;
|
||||
}
|
||||
__EOF__
|
||||
}
|
||||
}
|
||||
|
||||
sub output_copyfunc
|
||||
{
|
||||
my $src = shift;
|
||||
my $dst = shift;
|
||||
my $modulate = shift;
|
||||
my $blend = shift;
|
||||
my $scale = shift;
|
||||
|
||||
output_copyfuncname("int", $src, $dst, $modulate, $blend, $scale, 1, "\n");
|
||||
print FILE <<__EOF__;
|
||||
{
|
||||
const int flags = data->flags;
|
||||
__EOF__
|
||||
if ( $modulate ) {
|
||||
print FILE <<__EOF__;
|
||||
const Uint32 modulateR = data->r;
|
||||
const Uint32 modulateG = data->g;
|
||||
const Uint32 modulateB = data->b;
|
||||
const Uint32 modulateA = data->a;
|
||||
__EOF__
|
||||
}
|
||||
if ( $blend ) {
|
||||
print FILE <<__EOF__;
|
||||
Uint32 srcpixel;
|
||||
Uint32 srcR, srcG, srcB, srcA;
|
||||
Uint32 dstpixel;
|
||||
Uint32 dstR, dstG, dstB, dstA;
|
||||
__EOF__
|
||||
} elsif ( $modulate || $src ne $dst ) {
|
||||
print FILE <<__EOF__;
|
||||
Uint32 pixel;
|
||||
Uint32 R, G, B, A;
|
||||
__EOF__
|
||||
}
|
||||
if ( $scale ) {
|
||||
print FILE <<__EOF__;
|
||||
int srcy, srcx;
|
||||
int posy, posx;
|
||||
int incy, incx;
|
||||
|
||||
srcy = 0;
|
||||
posy = 0;
|
||||
incy = (data->src_h << 16) / data->dst_h;
|
||||
incx = (data->src_w << 16) / data->dst_w;
|
||||
|
||||
while (data->dst_h--) {
|
||||
$format_type{$src} *src;
|
||||
$format_type{$dst} *dst = ($format_type{$dst} *)data->dst;
|
||||
int n = data->dst_w;
|
||||
srcx = -1;
|
||||
posx = 0x10000L;
|
||||
while (posy >= 0x10000L) {
|
||||
++srcy;
|
||||
posy -= 0x10000L;
|
||||
}
|
||||
while (n--) {
|
||||
if (posx >= 0x10000L) {
|
||||
while (posx >= 0x10000L) {
|
||||
++srcx;
|
||||
posx -= 0x10000L;
|
||||
}
|
||||
src = ($format_type{$src} *)(data->src + (srcy * data->src_pitch) + (srcx * $format_size{$src}));
|
||||
__EOF__
|
||||
print FILE <<__EOF__;
|
||||
}
|
||||
__EOF__
|
||||
if ( $blend ) {
|
||||
get_rgba("src", $src);
|
||||
get_rgba("dst", $dst);
|
||||
output_copycore("src", "dst", $modulate, $blend);
|
||||
set_rgba("dst", $dst);
|
||||
} elsif ( $modulate || $src ne $dst ) {
|
||||
get_rgba("", $src);
|
||||
output_copycore("", "", $modulate, $blend);
|
||||
set_rgba("", $dst);
|
||||
} else {
|
||||
print FILE <<__EOF__;
|
||||
*dst = *src;
|
||||
__EOF__
|
||||
}
|
||||
print FILE <<__EOF__;
|
||||
posx += incx;
|
||||
++dst;
|
||||
}
|
||||
posy += incy;
|
||||
data->dst += data->dst_pitch;
|
||||
}
|
||||
__EOF__
|
||||
} else {
|
||||
print FILE <<__EOF__;
|
||||
|
||||
while (data->dst_h--) {
|
||||
$format_type{$src} *src = ($format_type{$src} *)data->src;
|
||||
$format_type{$dst} *dst = ($format_type{$dst} *)data->dst;
|
||||
int n = data->dst_w;
|
||||
while (n--) {
|
||||
__EOF__
|
||||
if ( $blend ) {
|
||||
get_rgba("src", $src);
|
||||
get_rgba("dst", $dst);
|
||||
output_copycore("src", "dst", $modulate, $blend);
|
||||
set_rgba("dst", $dst);
|
||||
} elsif ( $modulate || $src ne $dst ) {
|
||||
get_rgba("", $src);
|
||||
output_copycore("", "", $modulate, $blend);
|
||||
set_rgba("", $dst);
|
||||
} else {
|
||||
print FILE <<__EOF__;
|
||||
*dst = *src;
|
||||
__EOF__
|
||||
}
|
||||
print FILE <<__EOF__;
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
data->src += data->src_pitch;
|
||||
data->dst += data->dst_pitch;
|
||||
}
|
||||
__EOF__
|
||||
}
|
||||
print FILE <<__EOF__;
|
||||
return 0;
|
||||
}
|
||||
|
||||
__EOF__
|
||||
}
|
||||
|
||||
sub output_copyfunc_h
|
||||
{
|
||||
my $src = shift;
|
||||
my $dst = shift;
|
||||
for (my $modulate = 0; $modulate <= 1; ++$modulate) {
|
||||
for (my $blend = 0; $blend <= 1; ++$blend) {
|
||||
for (my $scale = 0; $scale <= 1; ++$scale) {
|
||||
if ( $modulate != 0 || $blend != 0 || $scale != 0 || $src ne $dst ) {
|
||||
output_copyfuncname("extern int SDLCALL", $src, $dst, $modulate, $blend, $scale, 1, ";\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub output_copyinc
|
||||
{
|
||||
print FILE <<__EOF__;
|
||||
#include "SDL_video.h"
|
||||
#include "SDL_rendercopy.h"
|
||||
|
||||
__EOF__
|
||||
}
|
||||
|
||||
sub output_copyfunctable
|
||||
{
|
||||
print FILE <<__EOF__;
|
||||
static struct {
|
||||
Uint32 src_format;
|
||||
Uint32 dst_format;
|
||||
int modMode;
|
||||
int blendMode;
|
||||
int scaleMode;
|
||||
SDL_RenderCopyFunc func;
|
||||
} SDL_RenderCopyFuncTable[] = {
|
||||
__EOF__
|
||||
for (my $i = 0; $i <= $#src_formats; ++$i) {
|
||||
my $src = $src_formats[$i];
|
||||
for (my $j = 0; $j <= $#dst_formats; ++$j) {
|
||||
my $dst = $dst_formats[$j];
|
||||
for (my $modulate = 0; $modulate <= 1; ++$modulate) {
|
||||
for (my $blend = 0; $blend <= 1; ++$blend) {
|
||||
for (my $scale = 0; $scale <= 1; ++$scale) {
|
||||
if ( $modulate != 0 || $blend != 0 || $scale != 0 || $src ne $dst ) {
|
||||
print FILE " { SDL_PIXELFORMAT_$src, SDL_PIXELFORMAT_$dst, ";
|
||||
if ( $modulate ) {
|
||||
print FILE "(SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA), ";
|
||||
} else {
|
||||
print FILE "0, ";
|
||||
}
|
||||
if ( $blend ) {
|
||||
print FILE "(SDL_TEXTUREBLENDMODE_MASK | SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_ADD | SDL_TEXTUREBLENDMODE_MOD), ";
|
||||
} else {
|
||||
print FILE "0, ";
|
||||
}
|
||||
if ( $scale ) {
|
||||
print FILE "SDL_TEXTURESCALEMODE_FAST, ";
|
||||
} else {
|
||||
print FILE "0, ";
|
||||
}
|
||||
output_copyfuncname("", $src_formats[$i], $dst_formats[$j], $modulate, $blend, $scale, 0, " },\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print FILE <<__EOF__;
|
||||
};
|
||||
|
||||
SDL_RenderCopyFunc SDL_GetRenderCopyFunc(Uint32 src_format, Uint32 dst_format, int modMode, int blendMode, int scaleMode)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SDL_arraysize(SDL_RenderCopyFuncTable); ++i) {
|
||||
if (src_format != SDL_RenderCopyFuncTable[i].src_format) {
|
||||
continue;
|
||||
}
|
||||
if (dst_format != SDL_RenderCopyFuncTable[i].dst_format) {
|
||||
continue;
|
||||
}
|
||||
if ((modMode & SDL_RenderCopyFuncTable[i].modMode) != modMode) {
|
||||
continue;
|
||||
}
|
||||
if ((blendMode & SDL_RenderCopyFuncTable[i].blendMode) != blendMode) {
|
||||
continue;
|
||||
}
|
||||
if ((scaleMode & SDL_RenderCopyFuncTable[i].scaleMode) != scaleMode) {
|
||||
continue;
|
||||
}
|
||||
return SDL_RenderCopyFuncTable[i].func;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__EOF__
|
||||
}
|
||||
|
||||
sub output_copyfunc_c
|
||||
{
|
||||
my $src = shift;
|
||||
my $dst = shift;
|
||||
|
||||
for (my $modulate = 0; $modulate <= 1; ++$modulate) {
|
||||
for (my $blend = 0; $blend <= 1; ++$blend) {
|
||||
for (my $scale = 0; $scale <= 1; ++$scale) {
|
||||
if ( $modulate != 0 || $blend != 0 || $scale != 0 || $src ne $dst ) {
|
||||
output_copyfunc($src, $dst, $modulate, $blend, $scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open_file("SDL_rendercopy.h");
|
||||
output_copydefs();
|
||||
for (my $i = 0; $i <= $#src_formats; ++$i) {
|
||||
for (my $j = 0; $j <= $#dst_formats; ++$j) {
|
||||
output_copyfunc_h($src_formats[$i], $dst_formats[$j]);
|
||||
}
|
||||
}
|
||||
print FILE "\n";
|
||||
close_file("SDL_rendercopy.h");
|
||||
|
||||
open_file("SDL_rendercopy.c");
|
||||
output_copyinc();
|
||||
output_copyfunctable();
|
||||
for (my $i = 0; $i <= $#src_formats; ++$i) {
|
||||
for (my $j = 0; $j <= $#dst_formats; ++$j) {
|
||||
output_copyfunc_c($src_formats[$i], $dst_formats[$j]);
|
||||
}
|
||||
}
|
||||
close_file("SDL_rendercopy.c");
|
Loading…
Add table
Add a link
Reference in a new issue