New file. Added glue code for the assembly MMX functions.

2001-11-19  Daniel Egger  <degger@fhm.edu>

	* app/paint-funcs/paint-funcs-mmx.h: New file. Added glue code
	for the assembly MMX functions.

	* app/paint-funcs/paint-funcs-generic.h: Moved MMX code from here ...
	* app/paint-funcs/paint-funcs-mmx.h: ... to here. Cleaned up a bit
	and don't check for use_mmx on every single call but ...
	* app/paint-funcs/paint-funcs.c: (paint_funcs_setup): ... here and
	register MMX functions if CPU has those capabilities.

	Code is untested for the MMX case due no available Intel-Machine
	right now but should't be to far away from a working state.
This commit is contained in:
Daniel Egger 2001-11-19 13:46:10 +00:00 committed by Daniel Egger
parent 21479d29b7
commit 0a28fa8c9c
4 changed files with 151 additions and 63 deletions

View File

@ -1,3 +1,17 @@
2001-11-19 Daniel Egger <degger@fhm.edu>
* app/paint-funcs/paint-funcs-mmx.h: New file. Added glue code
for the assembly MMX functions.
* app/paint-funcs/paint-funcs-generic.h: Moved MMX code from here ...
* app/paint-funcs/paint-funcs-mmx.h: ... to here. Cleaned up a bit
and don't check for use_mmx on every single call but ...
* app/paint-funcs/paint-funcs.c: (paint_funcs_setup): ... here and
register MMX functions if CPU has those capabilities.
Code is untested for the MMX case due no available Intel-Machine
right now but should't be to far away from a working state.
2001-11-19 Sven Neumann <sven@gimp.org>
* RELEASE-TO-CVS.patch: changes to the text tool to make it compile

View File

@ -24,42 +24,6 @@
#ifndef __PAINT_FUNCS_GENERIC_H__
#define __PAINT_FUNCS_GENERIC_H__
/* FIXME: Still ugly as butt but working and the MMX code doesn't
* belong here!! */
#ifdef HAVE_ASM_MMX
#define MMX_PIXEL_OP(x) \
void \
x( \
const unsigned char *src1, \
const unsigned char *src2, \
unsigned count, \
unsigned char *dst) __attribute((regparm(3)));
#define MMX_PIXEL_OP_3A_1A(op) \
MMX_PIXEL_OP(op##_pixels_3a_3a) \
MMX_PIXEL_OP(op##_pixels_1a_1a)
#define USE_MMX_PIXEL_OP_3A_1A(op) \
if (use_mmx && has_alpha1 && has_alpha2) \
{ \
if (bytes1==2 && bytes2==2) \
return op##_pixels_1a_1a(src1, src2, length, dest); \
if (bytes1==4 && bytes2==4) \
return op##_pixels_3a_3a(src1, src2, length, dest); \
} \
/*fprintf(stderr, "non-MMX: %s(%d, %d, %d, %d)\n", #op, \
bytes1, bytes2, has_alpha1, has_alpha2);*/
#else /* ! HAVE_ASM_MMX */
#define MMX_PIXEL_OP_3A_1A(op)
#define USE_MMX_PIXEL_OP_3A_1A(op)
#endif /* HAVE_ASM_MMX */
#define INT_MULT(a,b,t) ((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8))
@ -82,8 +46,10 @@ x( \
* aka GRAYA and RGBA and thus the macro below works. This will have
* to change if we support bigger formats. We'll do it so for now because
* masking is always cheaper than passing parameters over the stack. */
/* FIXME: Move to a global place */
#define HAS_ALPHA(bytes) (~##bytes & 1)
/* FIXME: Move to a more global place */
struct apply_layer_mode_struct
{
guchar bytes1 : 3;
@ -278,7 +244,7 @@ extract_alpha_pixels (const guchar *src,
}
}
MMX_PIXEL_OP_3A_1A(darken)
static inline void
darken_pixels (const guchar *src1,
const guchar *src2,
@ -293,8 +259,6 @@ darken_pixels (const guchar *src1,
guint b;
guchar s1, s2;
USE_MMX_PIXEL_OP_3A_1A(darken)
while (length--)
{
for (b = 0; b < alpha; b++)
@ -315,7 +279,7 @@ darken_pixels (const guchar *src1,
}
}
MMX_PIXEL_OP_3A_1A(lighten)
static inline void
lighten_pixels (const guchar *src1,
const guchar *src2,
@ -330,8 +294,6 @@ lighten_pixels (const guchar *src1,
guint b;
guchar s1, s2;
USE_MMX_PIXEL_OP_3A_1A(lighten)
while (length--)
{
for (b = 0; b < alpha; b++)
@ -392,6 +354,7 @@ hue_only_pixels (const guchar *src1,
}
}
static inline void
saturation_only_pixels (const guchar *src1,
const guchar *src2,
@ -431,6 +394,7 @@ saturation_only_pixels (const guchar *src1,
}
}
static inline void
value_only_pixels (const guchar *src1,
const guchar *src2,
@ -470,6 +434,7 @@ value_only_pixels (const guchar *src1,
}
}
static inline void
color_only_pixels (const guchar *src1,
const guchar *src2,
@ -511,7 +476,7 @@ color_only_pixels (const guchar *src1,
}
}
MMX_PIXEL_OP_3A_1A(multiply)
static inline void
multiply_pixels (const guchar *src1,
const guchar *src2,
@ -525,8 +490,6 @@ multiply_pixels (const guchar *src1,
const guint alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
guint b, tmp;
USE_MMX_PIXEL_OP_3A_1A(multiply)
if (has_alpha1 && has_alpha2)
{
while (length --)
@ -603,7 +566,6 @@ divide_pixels (const guchar *src1,
}
MMX_PIXEL_OP_3A_1A(screen)
static inline void
screen_pixels (const guchar *src1,
const guchar *src2,
@ -617,8 +579,6 @@ screen_pixels (const guchar *src1,
const guint alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
guint b, tmp;
USE_MMX_PIXEL_OP_3A_1A(screen)
while (length --)
{
for (b = 0; b < alpha; b++)
@ -636,8 +596,6 @@ screen_pixels (const guchar *src1,
}
MMX_PIXEL_OP_3A_1A(overlay)
static inline void
overlay_pixels (const guchar *src1,
const guchar *src2,
@ -672,7 +630,6 @@ overlay_pixels (const guchar *src1,
}
static inline void
dodge_pixels (const guchar *src1,
const guchar *src2,
@ -782,8 +739,6 @@ hardlight_pixels (const guchar *src1,
}
MMX_PIXEL_OP_3A_1A(add)
static inline void
add_pixels (const guchar *src1,
const guchar *src2,
@ -797,8 +752,6 @@ add_pixels (const guchar *src1,
const guint alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
guint b;
USE_MMX_PIXEL_OP_3A_1A(add)
while (length --)
{
for (b = 0; b < alpha; b++)
@ -819,8 +772,6 @@ add_pixels (const guchar *src1,
}
MMX_PIXEL_OP_3A_1A(substract)
static inline void
subtract_pixels (const guchar *src1,
const guchar *src2,
@ -835,8 +786,6 @@ subtract_pixels (const guchar *src1,
guint b;
gint diff;
USE_MMX_PIXEL_OP_3A_1A(substract)
while (length --)
{
for (b = 0; b < alpha; b++)
@ -857,8 +806,6 @@ subtract_pixels (const guchar *src1,
}
MMX_PIXEL_OP_3A_1A(difference)
static inline void
difference_pixels (const guchar *src1,
const guchar *src2,
@ -873,8 +820,6 @@ difference_pixels (const guchar *src1,
guint b;
gint diff;
USE_MMX_PIXEL_OP_3A_1A(difference)
while (length --)
{
for (b = 0; b < alpha; b++)

View File

@ -0,0 +1,114 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* This file is supposed to contain the MMX implementation of the
* pixelfiddeling paint-functions.
*/
#ifndef __PAINT_FUNCS_MMX_H__
#define __PAINT_FUNCS_MMX_H__
/* FIXME: Needs a bigger overhaul. Maybe inline assembly would be better? */
#ifdef HAVE_ASM_MMX
#define MMX_PIXEL_OP(x) \
void \
x( \
const unsigned char *src1, \
const unsigned char *src2, \
unsigned count, \
unsigned char *dst) __attribute((regparm(3)));
/* A drawable has an alphachannel if contains either 4 or 2 bytes data
* aka GRAYA and RGBA and thus the macro below works. This will have
* to change if we support bigger formats. We'll do it so for now because
* masking is always cheaper than passing parameters over the stack. */
#define HAS_ALPHA(bytes) (~##bytes & 1)
#define MMX_PIXEL_OP_3A_1A(op) \
MMX_PIXEL_OP(op##_pixels_3a_3a) \
MMX_PIXEL_OP(op##_pixels_1a_1a)
#define USE_MMX_PIXEL_OP_3A_1A(op) \
if (HAS_ALPHA (alms->bytes1) && HAS_ALPHA (bytes2)) \
{ \
if (alms->bytes1==2 && alms->bytes2==2) \
return op##_pixels_1a_1a(alms->src1, alms->src2, alms->length, alms->dest); \
if (alms->bytes1==4 && alms->bytes2==4) \
return op##_pixels_3a_3a(alms->src1, alms->src2, alms->length, alms->dest); \
}
MMX_PIXEL_OP_3A_1A(multiply);
static void
layer_multiply_mode_mmx (struct apply_layer_mode_struct *alms)
{
USE_MMX_PIXEL_OP_3A_1A(multiply);
}
MMX_PIXEL_OP_3A_1A(screen);
static void
layer_screen_mode_mmx (struct apply_layer_mode_struct *alms)
{
USE_MMX_PIXEL_OP_3A_1A(screen);
}
MMX_PIXEL_OP_3A_1A(overlay);
static void
layer_overlay_mode_mmx (struct apply_layer_mode_struct *alms)
{
USE_MMX_PIXEL_OP_3A_1A(overlay);
}
MMX_PIXEL_OP_3A_1A(difference);
static void
layer_difference_mode_mmx (struct apply_layer_mode_struct *alms)
{
USE_MMX_PIXEL_OP_3A_1A(difference);
}
MMX_PIXEL_OP_3A_1A(add);
static void
layer_addition_mode_mmx (struct apply_layer_mode_struct *alms)
{
USE_MMX_PIXEL_OP_3A_1A(add);
}
MMX_PIXEL_OP_3A_1A(substract);
static void
layer_subtract_mode_mmx (struct apply_layer_mode_struct *alms)
{
USE_MMX_PIXEL_OP_3A_1A(substract);
}
MMX_PIXEL_OP_3A_1A(darken);
static void
layer_darken_only_mode_mmx (struct apply_layer_mode_struct *alms)
{
USE_MMX_PIXEL_OP_3A_1A(darken);
}
MMX_PIXEL_OP_3A_1A(lighten);
static void
layer_lighten_only_mode_mmx (struct apply_layer_mode_struct *alms)
{
USE_MMX_PIXEL_OP_3A_1A(lighten);
}
#endif /* HAVE_ASM_MMX */
#endif /* __PAINT_FUNCS_MMX_H__ */

View File

@ -37,6 +37,7 @@
#include "paint-funcs.h"
#include "paint-funcs-generic.h"
#include "paint-funcs-mmx.h"
#define RANDOM_SEED 314159265
#define EPSILON 0.0001
@ -450,6 +451,20 @@ paint_funcs_setup (void)
add_lut[j][k] = tmp_sum;
}
}
#ifdef HAVE_ASM_MMX
if (use_mmx)
{
layer_mode_funcs[DIFFERENCE_MODE] = layer_difference_mode_mmx;
layer_mode_funcs[ADD_MODE] = layer_add_mode_mmx;
layer_mode_funcs[SUBSTRACT_MODE] = layer_substract_mode_mmx;
layer_mode_funcs[OVERLAY_MODE] = layer_overlay_mode_mmx;
layer_mode_funcs[SCREEN_MODE] = layer_screen_mode_mmx;
layer_mode_funcs[MULTIPLY_MODE] = layer_multiply_mode_mmx;
layer_mode_funcs[DARKEN_ONLY_MODE] = layer_darken_only_mode_mmx;
layer_mode_funcs[LIGHTEN_ONLY_MODE] = layer_lighten_only_mode_mmx;
}
#endif /* HAVE_ASM_MMX */
}
void