Compare commits

...
4 changed files with 824 additions and 158 deletions

View file

@ -10,6 +10,11 @@
#include "gdkpixelops.h"
#include "gdkimage.h"
#include "gdkrgb.h"
typedef struct _GdkRgbInfo GdkRgbInfo;
#ifndef __i386__
#error "gdkpixelops-x86-mmx.c requires a 32-bit x86 target"
#endif
@ -299,3 +304,347 @@ DEFINE_RGB16_MMX_COMPOSITOR (
pack_565)
#undef DEFINE_RGB16_MMX_COMPOSITOR
/*
* GdkRGB Gray conversion MMX kernels.
*/
static __m64
gdk_rgb_gray_mmx_load4 (const guchar *p)
{
guint32 v;
memcpy (&v, p, sizeof (v));
return _mm_cvtsi32_si64 ((gint) v);
}
static __m64
gdk_rgb_gray_mmx_load2 (const guchar *p)
{
guint16 v;
memcpy (&v, p, sizeof (v));
return _mm_cvtsi32_si64 ((gint) v);
}
static void
gdk_rgb_gray_mmx_store8 (guchar *p,
__m64 v)
{
memcpy (p, &v, sizeof (v));
}
static __m64
gdk_rgb_gray_mmx_555 (__m64 b)
{
const __m64 zero = _mm_setzero_si64 ();
__m64 g = _mm_unpacklo_pi8 (b, zero);
__m64 v = _mm_srli_pi16 (g, 3);
return _mm_or_si64 (
_mm_or_si64 (
_mm_slli_pi16 (v, 10),
_mm_slli_pi16 (v, 5)),
v);
}
static __m64
gdk_rgb_gray_mmx_565 (__m64 b)
{
const __m64 zero = _mm_setzero_si64 ();
__m64 g = _mm_unpacklo_pi8 (b, zero);
__m64 v5 = _mm_srli_pi16 (g, 3);
__m64 v6 = _mm_srli_pi16 (g, 2);
return _mm_or_si64 (
_mm_or_si64 (
_mm_slli_pi16 (v5, 11),
_mm_slli_pi16 (v6, 5)),
v5);
}
static __m64
gdk_rgb_gray_mmx_swap16 (__m64 v)
{
return _mm_or_si64 (
_mm_slli_pi16 (v, 8),
_mm_srli_pi16 (v, 8));
}
static guint16
gdk_rgb_gray_tail_555 (guint g)
{
return (guint16)
(((g & 0xf8) << 7) |
((g & 0xf8) << 2) |
(g >> 3));
}
static guint16
gdk_rgb_gray_tail_565 (guint g)
{
return (guint16)
(((g & 0xf8) << 8) |
((g & 0xfc) << 3) |
(g >> 3));
}
static guint16
gdk_rgb_gray_tail_swap16 (guint16 v)
{
return (guint16) ((v << 8) | (v >> 8));
}
#define DEFINE_GDK_RGB_GRAY16_MMX(name, vector_value, tail_value) \
G_GNUC_INTERNAL void \
name (GdkRgbInfo *image_info, \
GdkImage *image, \
gint x0, \
gint y0, \
gint width, \
gint height, \
const guchar *buf, \
gint rowstride, \
gint x_align, \
gint y_align, \
GdkRgbCmap *cmap) \
{ \
const guchar *src = buf; \
guchar *dst = ((guchar *) image->mem) + \
y0 * image->bpl + x0 * 2; \
gint y; \
\
(void) image_info; \
(void) x_align; \
(void) y_align; \
(void) cmap; \
\
for (y = 0; y < height; y++) \
{ \
const guchar *p = src; \
guchar *q = dst; \
gint x = 0; \
\
for (; x + 4 <= width; x += 4) \
{ \
__m64 out = (vector_value); \
\
gdk_rgb_gray_mmx_store8 (q, out); \
\
p += 4; \
q += 8; \
} \
\
for (; x < width; x++) \
{ \
guint16 out = (tail_value); \
\
memcpy (q, &out, sizeof (out)); \
\
p++; \
q += 2; \
} \
\
src += rowstride; \
dst += image->bpl; \
} \
\
if (width >= 4 && height > 0) \
_mm_empty (); \
}
DEFINE_GDK_RGB_GRAY16_MMX (
_gdk_rgb_convert_gray_555_mmx,
gdk_rgb_gray_mmx_555 (
gdk_rgb_gray_mmx_load4 (p)),
gdk_rgb_gray_tail_555 (*p))
DEFINE_GDK_RGB_GRAY16_MMX (
_gdk_rgb_convert_gray_555_br_mmx,
gdk_rgb_gray_mmx_swap16 (
gdk_rgb_gray_mmx_555 (
gdk_rgb_gray_mmx_load4 (p))),
gdk_rgb_gray_tail_swap16 (
gdk_rgb_gray_tail_555 (*p)))
DEFINE_GDK_RGB_GRAY16_MMX (
_gdk_rgb_convert_gray_565_mmx,
gdk_rgb_gray_mmx_565 (
gdk_rgb_gray_mmx_load4 (p)),
gdk_rgb_gray_tail_565 (*p))
DEFINE_GDK_RGB_GRAY16_MMX (
_gdk_rgb_convert_gray_565_br_mmx,
gdk_rgb_gray_mmx_swap16 (
gdk_rgb_gray_mmx_565 (
gdk_rgb_gray_mmx_load4 (p))),
gdk_rgb_gray_tail_swap16 (
gdk_rgb_gray_tail_565 (*p)))
#undef DEFINE_GDK_RGB_GRAY16_MMX
/*
* One shared 101010 implementation.
* The two GdkRgbConvFunc wrappers differ only in the alpha mask.
*/
static __m64
gdk_rgb_gray_mmx_dwords2 (const guchar *p)
{
const __m64 zero = _mm_setzero_si64 ();
__m64 b = gdk_rgb_gray_mmx_load2 (p);
__m64 w = _mm_unpacklo_pi8 (b, zero);
return _mm_unpacklo_pi16 (w, zero);
}
static void
gdk_rgb_gray_101010_lsb_mmx_impl (GdkImage *image,
gint x0,
gint y0,
gint width,
gint height,
const guchar *buf,
gint rowstride,
guint32 alpha)
{
if (width < 4)
{
const guchar *tiny_src = buf;
guchar *tiny_dst =
((guchar *) image->mem) +
y0 * image->bpl +
x0 * 4;
gint tiny_y;
for (tiny_y = 0; tiny_y < height; tiny_y++)
{
const guchar *p = tiny_src;
guchar *q = tiny_dst;
gint x;
for (x = 0; x < width; x++)
{
guint32 g = *p++;
guint32 g10 =
(g << 2) | (g >> 6);
guint32 out =
alpha |
(g10 << 20) |
(g10 << 10) |
g10;
memcpy (q, &out, sizeof (out));
q += 4;
}
tiny_src += rowstride;
tiny_dst += image->bpl;
}
return;
}
const __m64 alpha2 =
_mm_set_pi32 ((gint) alpha, (gint) alpha);
const guchar *src = buf;
guchar *dst =
((guchar *) image->mem) +
y0 * image->bpl +
x0 * 4;
gint y;
for (y = 0; y < height; y++)
{
const guchar *p = src;
guchar *q = dst;
gint x = 0;
for (; x + 2 <= width; x += 2)
{
__m64 g =
gdk_rgb_gray_mmx_dwords2 (p);
__m64 g10 =
_mm_or_si64 (
_mm_slli_pi32 (g, 2),
_mm_srli_pi32 (g, 6));
__m64 out =
_mm_or_si64 (
alpha2,
_mm_or_si64 (
g10,
_mm_or_si64 (
_mm_slli_pi32 (g10, 10),
_mm_slli_pi32 (g10, 20))));
gdk_rgb_gray_mmx_store8 (q, out);
p += 2;
q += 8;
}
for (; x < width; x++)
{
guint32 g = *p++;
guint32 g10 =
(g << 2) | (g >> 6);
guint32 out =
alpha |
(g10 << 20) |
(g10 << 10) |
g10;
memcpy (q, &out, sizeof (out));
q += 4;
}
src += rowstride;
dst += image->bpl;
}
if (width >= 2 && height > 0)
_mm_empty ();
}
#define DEFINE_GDK_RGB_GRAY101010_MMX(name, alpha) \
G_GNUC_INTERNAL void \
name (GdkRgbInfo *image_info, \
GdkImage *image, \
gint x0, \
gint y0, \
gint width, \
gint height, \
const guchar *buf, \
gint rowstride, \
gint x_align, \
gint y_align, \
GdkRgbCmap *cmap) \
{ \
(void) image_info; \
(void) x_align; \
(void) y_align; \
(void) cmap; \
\
gdk_rgb_gray_101010_lsb_mmx_impl ( \
image, x0, y0, \
width, height, \
buf, rowstride, \
alpha); \
}
DEFINE_GDK_RGB_GRAY101010_MMX (
_gdk_rgb_convert_gray_101010_lsb_30_mmx,
0)
DEFINE_GDK_RGB_GRAY101010_MMX (
_gdk_rgb_convert_gray_101010_lsb_32_mmx,
0xc0000000U)
#undef DEFINE_GDK_RGB_GRAY101010_MMX

View file

@ -40,6 +40,14 @@ _gdk_pixel_ops_composite_565_mmx (guchar *src_buf,
gint width,
gint height);
static gboolean gdk_pixel_ops_mmx_available;
G_GNUC_INTERNAL gboolean
_gdk_pixel_ops_have_mmx (void)
{
return gdk_pixel_ops_mmx_available;
}
G_GNUC_INTERNAL void
_gdk_pixel_ops_init (void)
{
@ -51,6 +59,7 @@ _gdk_pixel_ops_init (void)
if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) &&
(edx & bit_MMX) != 0)
{
gdk_pixel_ops_mmx_available = TRUE;
_gdk_pixel_ops.composite_0888 =
_gdk_pixel_ops_composite_0888_mmx;
_gdk_pixel_ops.composite_555 =

View file

@ -29,8 +29,10 @@ extern G_GNUC_INTERNAL GdkPixelOps _gdk_pixel_ops;
#ifdef HAVE_GDK_PIXELOPS_INIT
G_GNUC_INTERNAL void _gdk_pixel_ops_init (void);
G_GNUC_INTERNAL gboolean _gdk_pixel_ops_have_mmx (void);
#else
#define _gdk_pixel_ops_init() ((void) 0)
#define _gdk_pixel_ops_have_mmx() FALSE
#endif
G_END_DECLS

View file

@ -39,6 +39,7 @@
#include "gdkinternals.h" /* _gdk_windowing_get_bits_for_depth() */
#include "gdkrgb.h"
#include "gdkpixelops.h"
#include "gdkscreen.h"
#include "gdkalias.h"
#include <glib/gprintf.h>
@ -57,11 +58,11 @@ typedef enum
GDK_RGB_FORMAT_888_MSB,
GDK_RGB_FORMAT_0888,
GDK_RGB_FORMAT_0888_BR,
GDK_RGB_FORMAT_RGB0_NATIVE,
GDK_RGB_FORMAT_101010_R_LOW_LE,
GDK_RGB_FORMAT_101010_B_LOW_LE,
GDK_RGB_FORMAT_101010_R_LOW_BE,
GDK_RGB_FORMAT_101010_B_LOW_BE
GDK_RGB_FORMAT_8880_BR,
GDK_RGB_FORMAT_101010_R_LOW_LSB,
GDK_RGB_FORMAT_101010_B_LOW_LSB,
GDK_RGB_FORMAT_101010_R_LOW_MSB,
GDK_RGB_FORMAT_101010_B_LOW_MSB
} GdkRgbFormat;
typedef void (*GdkRgbConvFunc) (GdkRgbInfo *image_info, GdkImage *image,
@ -71,6 +72,25 @@ typedef void (*GdkRgbConvFunc) (GdkRgbInfo *image_info, GdkImage *image,
gint x_align, gint y_align,
GdkRgbCmap *cmap);
#ifdef HAVE_GDK_PIXELOPS_INIT
#define DECLARE_GDK_RGB_GRAY_MMX(name) \
G_GNUC_INTERNAL void \
name (GdkRgbInfo *, GdkImage *, \
gint, gint, gint, gint, \
const guchar *, gint, \
gint, gint, GdkRgbCmap *);
DECLARE_GDK_RGB_GRAY_MMX (_gdk_rgb_convert_gray_555_mmx)
DECLARE_GDK_RGB_GRAY_MMX (_gdk_rgb_convert_gray_555_br_mmx)
DECLARE_GDK_RGB_GRAY_MMX (_gdk_rgb_convert_gray_565_mmx)
DECLARE_GDK_RGB_GRAY_MMX (_gdk_rgb_convert_gray_565_br_mmx)
DECLARE_GDK_RGB_GRAY_MMX (_gdk_rgb_convert_gray_101010_lsb_30_mmx)
DECLARE_GDK_RGB_GRAY_MMX (_gdk_rgb_convert_gray_101010_lsb_32_mmx)
#undef DECLARE_GDK_RGB_GRAY_MMX
#endif
#define STAGE_ROWSTRIDE (GDK_SCRATCH_IMAGE_WIDTH * 3)
#define GDK_RGB_STAGE_ROWS 4
@ -117,7 +137,7 @@ struct _GdkRgbCmapInfo
GdkRgbInfo *image_info;
GdkRgbCmap *cmap;
guchar lut[256]; /* For 8-bit modes */
guchar lut[1]; /* variable-sized private LUT */
};
static GdkRgbCmapInfo *gdk_rgb_cmap_get_info (GdkRgbCmap *cmap, GdkRgbInfo *image_info);
@ -2279,24 +2299,13 @@ gdk_rgb_convert_888_lsb (GdkRgbInfo *image_info, GdkImage *image,
/* convert 24-bit packed to 32-bit unpacked */
/* todo: optimize this */
#if G_BYTE_ORDER == G_LITTLE_ENDIAN && GLIB_SIZEOF_VOID_P == 8 && \
(defined(__x86_64__) || defined(__amd64__))
#define GDK_RGB_STORE_0888(p, bp) G_STMT_START { \
guint32 pixel; \
pixel = 0xff000000U | \
((guint32) (bp)[0] << 16) | \
((guint32) (bp)[1] << 8) | \
(guint32) (bp)[2]; \
guint32 pixel = GUINT32_TO_LE (0xff000000U | \
((guint32) (bp)[0] << 16) | \
((guint32) (bp)[1] << 8) | \
(guint32) (bp)[2]); \
memcpy ((p), &pixel, sizeof (pixel)); \
} G_STMT_END
#else
#define GDK_RGB_STORE_0888(p, bp) G_STMT_START { \
(p)[0] = (bp)[2]; \
(p)[1] = (bp)[1]; \
(p)[2] = (bp)[0]; \
(p)[3] = 0xff; \
} G_STMT_END
#endif
#define GDK_RGB_STORE_0888_BR(p, bp) G_STMT_START { \
(p)[0] = 0xff; \
@ -3456,29 +3465,22 @@ gdk_rgb_convert_indexed_lut (GdkRgbInfo *image_info, GdkImage *image,
const guchar *buf, gint rowstride,
gint x_align, gint y_align, GdkRgbCmap *cmap)
{
union {
guint16 u16[256];
guint32 u32[256];
} lut;
gint i, y;
GdkRgbCmapInfo *cmap_info;
gint y;
gint bpl = image->bpl;
const guchar *src = buf;
guchar *dst = ((guchar *) image->mem) + y0 * bpl + x0 * image_info->bpp;
guchar *dst = ((guchar *) image->mem) +
y0 * bpl + x0 * image_info->bpp;
(void) x_align;
(void) y_align;
cmap_info = gdk_rgb_cmap_get_info (cmap, image_info);
g_assert (cmap_info != NULL);
if (image_info->bpp == 2)
{
guint is_565 = image_info->format == GDK_RGB_FORMAT_565;
guint red_shift = 9 - is_565;
guint green_shift = 6 - is_565;
guint32 green_mask = 0x00f800 | (is_565 << 10);
for (i = 0; i < cmap->n_colors; i++)
{
guint32 rgb = cmap->colors[i];
lut.u16[i] = ((rgb & 0xf80000) >> red_shift) |
((rgb & green_mask) >> green_shift) |
((rgb & 0x0000f8) >> 3);
}
const guint16 *lut = (const guint16 *) cmap_info->lut;
for (y = 0; y < height; y++)
{
@ -3487,7 +3489,7 @@ gdk_rgb_convert_indexed_lut (GdkRgbInfo *image_info, GdkImage *image,
gint x;
for (x = 0; x < width; x++)
q[x] = lut.u16[p[x]];
q[x] = lut[p[x]];
src += rowstride;
dst += bpl;
@ -3495,13 +3497,7 @@ gdk_rgb_convert_indexed_lut (GdkRgbInfo *image_info, GdkImage *image,
}
else
{
gboolean little = image_info->format == GDK_RGB_FORMAT_0888;
for (i = 0; i < cmap->n_colors; i++)
{
guint32 pixel = 0xff000000U | cmap->colors[i];
lut.u32[i] = little ? GUINT32_TO_LE (pixel) : GUINT32_TO_BE (pixel);
}
const guint32 *lut = (const guint32 *) cmap_info->lut;
for (y = 0; y < height; y++)
{
@ -3510,7 +3506,7 @@ gdk_rgb_convert_indexed_lut (GdkRgbInfo *image_info, GdkImage *image,
gint x;
for (x = 0; x < width; x++)
q[x] = lut.u32[p[x]];
q[x] = lut[p[x]];
src += rowstride;
dst += bpl;
@ -3519,6 +3515,61 @@ gdk_rgb_convert_indexed_lut (GdkRgbInfo *image_info, GdkImage *image,
}
#define DEFINE_GDK_RGB_INDEXED_888_CONVERTER(name, shift0, shift2) \
static void \
name (GdkRgbInfo *image_info, \
GdkImage *image, \
gint x0, \
gint y0, \
gint width, \
gint height, \
const guchar *buf, \
int rowstride, \
gint x_align, \
gint y_align, \
GdkRgbCmap *cmap) \
{ \
const guchar *src = buf; \
guchar *dst = ((guchar *) image->mem) + \
y0 * image->bpl + x0 * 3; \
gint x, y; \
\
(void) image_info; \
(void) x_align; \
(void) y_align; \
\
for (y = 0; y < height; y++) \
{ \
const guchar *p = src; \
guchar *q = dst; \
\
for (x = 0; x < width; x++) \
{ \
guint32 rgb = cmap->colors[p[x]]; \
\
q[0] = rgb >> (shift0); \
q[1] = rgb >> 8; \
q[2] = rgb >> (shift2); \
q += 3; \
} \
\
src += rowstride; \
dst += image->bpl; \
} \
}
DEFINE_GDK_RGB_INDEXED_888_CONVERTER (
gdk_rgb_convert_indexed_888_lsb,
0,
16)
DEFINE_GDK_RGB_INDEXED_888_CONVERTER (
gdk_rgb_convert_indexed_888_msb,
16,
0)
#undef DEFINE_GDK_RGB_INDEXED_888_CONVERTER
static void
gdk_rgb_gray_to_stage (guchar *stage,
const guchar *buf, gint rowstride, gint width, gint height,
@ -3553,50 +3604,145 @@ gdk_rgb_gray_to_stage (guchar *stage,
/* Generic gray conversion function - convert to 24bit packed, then go
from there. */
static void
gdk_rgb_convert_gray_0888_native (GdkRgbInfo *image_info, GdkImage *image,
gint x0, gint y0, gint width, gint height,
const guchar *buf, gint rowstride,
gint x_align, gint y_align, GdkRgbCmap *cmap)
{
gint y, w;
gint bpl = image->bpl;
guchar *obuf = ((guchar *) image->mem) + y0 * bpl + x0 * 4;
for (y = 0; y < height; y++)
{
const guchar *p = buf;
guchar *q = obuf;
w = width;
while (w--)
{
guchar g = *p++;
/*
* Store bytes explicitly here. Word-store performance varies by
* microarchitecture even within one ISA, so keep this generic path
* free of CPU-specific runtime dispatch.
*/
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
q[0] = g;
q[1] = g;
q[2] = g;
q[3] = 0xff;
#else
q[0] = 0xff;
q[1] = g;
q[2] = g;
q[3] = g;
#endif
q += 4;
}
buf += rowstride;
obuf += bpl;
}
#define DEFINE_GDK_RGB_GRAY_DIRECT(name, qtype, pixel_bytes, setup, store) \
static void \
name (GdkRgbInfo *image_info, \
GdkImage *image, \
gint x0, \
gint y0, \
gint width, \
gint height, \
const guchar *buf, \
gint rowstride, \
gint x_align, \
gint y_align, \
GdkRgbCmap *cmap) \
{ \
const guchar *src = buf; \
guchar *dst = ((guchar *) image->mem) + \
y0 * image->bpl + x0 * (pixel_bytes); \
gint x, y; \
\
setup \
\
(void) x_align; \
(void) y_align; \
(void) cmap; \
\
for (y = 0; y < height; y++) \
{ \
const guchar *p = src; \
qtype *q = (qtype *) dst; \
\
for (x = 0; x < width; x++) \
{ \
guint32 g = *p++; \
store \
} \
\
src += rowstride; \
dst += image->bpl; \
} \
}
DEFINE_GDK_RGB_GRAY_DIRECT (
gdk_rgb_convert_gray_555_br,
guint16,
2,
(void) image_info;,
guint16 pixel =
((g & 0xf8) << 7) |
((g & 0xf8) << 2) |
(g >> 3);
*q++ = (guint16) ((pixel << 8) | (pixel >> 8));)
DEFINE_GDK_RGB_GRAY_DIRECT (
gdk_rgb_convert_gray_565_br,
guint16,
2,
(void) image_info;,
guint16 pixel =
((g & 0xf8) << 8) |
((g & 0xfc) << 3) |
(g >> 3);
*q++ = (guint16) ((pixel << 8) | (pixel >> 8));)
DEFINE_GDK_RGB_GRAY_DIRECT (
gdk_rgb_convert_gray_888,
guchar,
3,
(void) image_info;,
q[0] = g;
q[1] = g;
q[2] = g;
q += 3;)
DEFINE_GDK_RGB_GRAY_DIRECT (
gdk_rgb_convert_gray_0888,
guchar,
4,
(void) image_info;,
q[0] = g;
q[1] = g;
q[2] = g;
q[3] = 0xff;
q += 4;)
DEFINE_GDK_RGB_GRAY_DIRECT (
gdk_rgb_convert_gray_0888_br,
guchar,
4,
(void) image_info;,
q[0] = 0xff;
q[1] = g;
q[2] = g;
q[3] = g;
q += 4;)
DEFINE_GDK_RGB_GRAY_DIRECT (
gdk_rgb_convert_gray_8880_br,
guint32,
4,
(void) image_info;,
*q++ =
(g << 16) |
(g << 8) |
g;)
DEFINE_GDK_RGB_GRAY_DIRECT (
gdk_rgb_convert_gray_101010_lsb,
guint32,
4,
guint32 alpha_mask =
image_info->visual->depth == 32
? 0xc0000000U
: 0;,
guint32 g10 =
(g << 2) | (g >> 6);
*q++ = GUINT32_TO_LE (
alpha_mask |
(g10 << 20) |
(g10 << 10) |
g10);)
DEFINE_GDK_RGB_GRAY_DIRECT (
gdk_rgb_convert_gray_101010_msb,
guint32,
4,
guint32 alpha_mask =
image_info->visual->depth == 32
? 0xc0000000U
: 0;,
guint32 g10 =
(g << 2) | (g >> 6);
*q++ = GUINT32_TO_BE (
alpha_mask |
(g10 << 20) |
(g10 << 10) |
g10);)
#undef DEFINE_GDK_RGB_GRAY_DIRECT
DEFINE_STAGED_CONVERTER (gdk_rgb_convert_gray_generic,
conv, gdk_rgb_gray_to_stage)
@ -3724,7 +3870,8 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
if (image_info->bitmap)
conv = gdk_rgb_convert_1;
else if (bpp == 16 && depth == 16 && !byterev &&
else if (bpp == 16 && depth == 16 &&
vtype == GDK_VISUAL_TRUE_COLOR && !byterev &&
red_mask == 0xf800 && green_mask == 0x7e0 && blue_mask == 0x1f)
{
SET_CONV (gdk_rgb_convert_565, GDK_RGB_FORMAT_565);
@ -3779,11 +3926,11 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
#if G_BYTE_ORDER == G_BIG_ENDIAN
else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
(mask_bgr && byte_order == GDK_MSB_FIRST))
SET_CONV (gdk_rgb_convert_8880_br, GDK_RGB_FORMAT_RGB0_NATIVE);
SET_CONV (gdk_rgb_convert_8880_br, GDK_RGB_FORMAT_8880_BR);
#else
else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
(mask_bgr && byte_order == GDK_LSB_FIRST))
SET_CONV (gdk_rgb_convert_8880_br, GDK_RGB_FORMAT_RGB0_NATIVE);
SET_CONV (gdk_rgb_convert_8880_br, GDK_RGB_FORMAT_8880_BR);
#endif
else if (bpp == 32 && (depth == 30 || depth == 32) &&
vtype == GDK_VISUAL_TRUE_COLOR &&
@ -3798,15 +3945,15 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
? gdk_rgb_convert_101010_r_low_lsb
: gdk_rgb_convert_101010_r_low_msb),
(byte_order == GDK_LSB_FIRST
? GDK_RGB_FORMAT_101010_R_LOW_LE
: GDK_RGB_FORMAT_101010_R_LOW_BE));
? GDK_RGB_FORMAT_101010_R_LOW_LSB
: GDK_RGB_FORMAT_101010_R_LOW_MSB));
else
SET_CONV ((byte_order == GDK_LSB_FIRST
? gdk_rgb_convert_101010_b_low_lsb
: gdk_rgb_convert_101010_b_low_msb),
(byte_order == GDK_LSB_FIRST
? GDK_RGB_FORMAT_101010_B_LOW_LE
: GDK_RGB_FORMAT_101010_B_LOW_BE));
? GDK_RGB_FORMAT_101010_B_LOW_LSB
: GDK_RGB_FORMAT_101010_B_LOW_MSB));
}
else if (vtype == GDK_VISUAL_TRUE_COLOR && byte_order == GDK_LSB_FIRST)
@ -3914,6 +4061,12 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
conv_indexed = gdk_rgb_convert_indexed_lut;
break;
case GDK_RGB_FORMAT_555_BR:
conv_gray = gdk_rgb_convert_gray_555_br;
conv_gray_d = gdk_rgb_convert_gray_555_br;
conv_indexed = gdk_rgb_convert_indexed_lut;
break;
case GDK_RGB_FORMAT_565:
conv_32 = gdk_rgb_convert_32_565;
conv_32_d = gdk_rgb_convert_32_565_d;
@ -3921,23 +4074,57 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
conv_indexed = gdk_rgb_convert_indexed_lut;
break;
case GDK_RGB_FORMAT_565_BR:
conv_gray = gdk_rgb_convert_gray_565_br;
conv_gray_d = gdk_rgb_convert_gray_565_br;
conv_indexed = gdk_rgb_convert_indexed_lut;
break;
case GDK_RGB_FORMAT_0888:
conv_32 = gdk_rgb_convert_32_0888;
conv_32_d = gdk_rgb_convert_32_0888;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
conv_gray = gdk_rgb_convert_gray_0888_native;
conv_gray_d = gdk_rgb_convert_gray_0888_native;
#endif
conv_gray = gdk_rgb_convert_gray_0888;
conv_gray_d = gdk_rgb_convert_gray_0888;
conv_indexed = gdk_rgb_convert_indexed_lut;
break;
case GDK_RGB_FORMAT_0888_BR:
conv_32 = gdk_rgb_convert_32_0888_br;
conv_32_d = gdk_rgb_convert_32_0888_br;
#if G_BYTE_ORDER == G_BIG_ENDIAN
conv_gray = gdk_rgb_convert_gray_0888_native;
conv_gray_d = gdk_rgb_convert_gray_0888_native;
#endif
conv_gray = gdk_rgb_convert_gray_0888_br;
conv_gray_d = gdk_rgb_convert_gray_0888_br;
conv_indexed = gdk_rgb_convert_indexed_lut;
break;
case GDK_RGB_FORMAT_888_LSB:
conv_gray = gdk_rgb_convert_gray_888;
conv_gray_d = gdk_rgb_convert_gray_888;
conv_indexed = gdk_rgb_convert_indexed_888_lsb;
break;
case GDK_RGB_FORMAT_888_MSB:
conv_gray = gdk_rgb_convert_gray_888;
conv_gray_d = gdk_rgb_convert_gray_888;
conv_indexed = gdk_rgb_convert_indexed_888_msb;
break;
case GDK_RGB_FORMAT_8880_BR:
conv_gray = gdk_rgb_convert_gray_8880_br;
conv_gray_d = gdk_rgb_convert_gray_8880_br;
conv_indexed = gdk_rgb_convert_indexed_lut;
break;
case GDK_RGB_FORMAT_101010_R_LOW_LSB:
case GDK_RGB_FORMAT_101010_B_LOW_LSB:
conv_gray = gdk_rgb_convert_gray_101010_lsb;
conv_gray_d = gdk_rgb_convert_gray_101010_lsb;
conv_indexed = gdk_rgb_convert_indexed_lut;
break;
case GDK_RGB_FORMAT_101010_R_LOW_MSB:
case GDK_RGB_FORMAT_101010_B_LOW_MSB:
conv_gray = gdk_rgb_convert_gray_101010_msb;
conv_gray_d = gdk_rgb_convert_gray_101010_msb;
conv_indexed = gdk_rgb_convert_indexed_lut;
break;
@ -3945,6 +4132,50 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
break;
}
#ifdef HAVE_GDK_PIXELOPS_INIT
if (_gdk_pixel_ops_have_mmx ())
{
switch (format)
{
case GDK_RGB_FORMAT_555:
conv_gray =
_gdk_rgb_convert_gray_555_mmx;
conv_gray_d = conv_gray;
break;
case GDK_RGB_FORMAT_555_BR:
conv_gray =
_gdk_rgb_convert_gray_555_br_mmx;
conv_gray_d = conv_gray;
break;
case GDK_RGB_FORMAT_565:
conv_gray =
_gdk_rgb_convert_gray_565_mmx;
break;
case GDK_RGB_FORMAT_565_BR:
conv_gray =
_gdk_rgb_convert_gray_565_br_mmx;
conv_gray_d = conv_gray;
break;
case GDK_RGB_FORMAT_101010_R_LOW_LSB:
case GDK_RGB_FORMAT_101010_B_LOW_LSB:
conv_gray =
depth == 32
? _gdk_rgb_convert_gray_101010_lsb_32_mmx
: _gdk_rgb_convert_gray_101010_lsb_30_mmx;
conv_gray_d = conv_gray;
break;
default:
break;
}
}
#endif
image_info->format = format;
image_info->conv = conv;
@ -4073,7 +4304,7 @@ gdk_rgb_get_info_from_drawable (GdkDrawable *drawable)
(p) += 4; \
} G_STMT_END
#define GDK_RGB16_STORE_RGB0_NATIVE(p, r, g, b, a) G_STMT_START { \
#define GDK_RGB16_STORE_8880_BR(p, r, g, b, a) G_STMT_START { \
guint32 pixel__ = (((b) >> 8) << 16) | \
(((g) >> 8) << 8) | \
((r) >> 8); \
@ -4115,7 +4346,7 @@ gdk_rgb_get_info_from_drawable (GdkDrawable *drawable)
(p) += 2; \
} G_STMT_END
#define GDK_RGB16_STORE_101010_R_LOW_LE(p, r, g, b, a) \
#define GDK_RGB16_STORE_101010_R_LOW_LSB(p, r, g, b, a) \
G_STMT_START { \
guint32 pixel__ = (a) | \
(((b) >> 6) << 20) | \
@ -4126,7 +4357,7 @@ G_STMT_START { \
(p) += 4; \
} G_STMT_END
#define GDK_RGB16_STORE_101010_B_LOW_LE(p, r, g, b, a) \
#define GDK_RGB16_STORE_101010_B_LOW_LSB(p, r, g, b, a) \
G_STMT_START { \
guint32 pixel__ = (a) | \
(((r) >> 6) << 20) | \
@ -4137,7 +4368,7 @@ G_STMT_START { \
(p) += 4; \
} G_STMT_END
#define GDK_RGB16_STORE_101010_R_LOW_BE(p, r, g, b, a) \
#define GDK_RGB16_STORE_101010_R_LOW_MSB(p, r, g, b, a) \
G_STMT_START { \
guint32 pixel__ = (a) | \
(((b) >> 6) << 20) | \
@ -4148,7 +4379,7 @@ G_STMT_START { \
(p) += 4; \
} G_STMT_END
#define GDK_RGB16_STORE_101010_B_LOW_BE(p, r, g, b, a) \
#define GDK_RGB16_STORE_101010_B_LOW_MSB(p, r, g, b, a) \
G_STMT_START { \
guint32 pixel__ = (a) | \
(((r) >> 6) << 20) | \
@ -4220,19 +4451,19 @@ DEFINE_GDK_RGB16_PAIR (rgb, 3, GDK_RGB16_STORE_RGB)
DEFINE_GDK_RGB16_PAIR (bgr, 3, GDK_RGB16_STORE_BGR)
DEFINE_GDK_RGB16_PAIR (bgra, 4, GDK_RGB16_STORE_BGRA)
DEFINE_GDK_RGB16_PAIR (argb, 4, GDK_RGB16_STORE_ARGB)
DEFINE_GDK_RGB16_PAIR (rgb0_native, 4, GDK_RGB16_STORE_RGB0_NATIVE)
DEFINE_GDK_RGB16_PAIR (8880_br, 4, GDK_RGB16_STORE_8880_BR)
DEFINE_GDK_RGB16_PAIR (565, 2, GDK_RGB16_STORE_565)
DEFINE_GDK_RGB16_PAIR (565_br, 2, GDK_RGB16_STORE_565_BR)
DEFINE_GDK_RGB16_PAIR (555, 2, GDK_RGB16_STORE_555)
DEFINE_GDK_RGB16_PAIR (555_br, 2, GDK_RGB16_STORE_555_BR)
DEFINE_GDK_RGB16_PAIR (101010_r_low_le, 4,
GDK_RGB16_STORE_101010_R_LOW_LE)
DEFINE_GDK_RGB16_PAIR (101010_b_low_le, 4,
GDK_RGB16_STORE_101010_B_LOW_LE)
DEFINE_GDK_RGB16_PAIR (101010_r_low_be, 4,
GDK_RGB16_STORE_101010_R_LOW_BE)
DEFINE_GDK_RGB16_PAIR (101010_b_low_be, 4,
GDK_RGB16_STORE_101010_B_LOW_BE)
DEFINE_GDK_RGB16_PAIR (101010_r_low_lsb, 4,
GDK_RGB16_STORE_101010_R_LOW_LSB)
DEFINE_GDK_RGB16_PAIR (101010_b_low_lsb, 4,
GDK_RGB16_STORE_101010_B_LOW_LSB)
DEFINE_GDK_RGB16_PAIR (101010_r_low_msb, 4,
GDK_RGB16_STORE_101010_R_LOW_MSB)
DEFINE_GDK_RGB16_PAIR (101010_b_low_msb, 4,
GDK_RGB16_STORE_101010_B_LOW_MSB)
#undef DEFINE_GDK_RGB16_PAIR
#undef DEFINE_GDK_RGB16_CONVERTER
@ -4241,15 +4472,15 @@ DEFINE_GDK_RGB16_PAIR (101010_b_low_be, 4,
#undef GDK_RGB16_STORE_BGR
#undef GDK_RGB16_STORE_BGRA
#undef GDK_RGB16_STORE_ARGB
#undef GDK_RGB16_STORE_RGB0_NATIVE
#undef GDK_RGB16_STORE_8880_BR
#undef GDK_RGB16_STORE_565
#undef GDK_RGB16_STORE_565_BR
#undef GDK_RGB16_STORE_555
#undef GDK_RGB16_STORE_555_BR
#undef GDK_RGB16_STORE_101010_R_LOW_LE
#undef GDK_RGB16_STORE_101010_B_LOW_LE
#undef GDK_RGB16_STORE_101010_R_LOW_BE
#undef GDK_RGB16_STORE_101010_B_LOW_BE
#undef GDK_RGB16_STORE_101010_R_LOW_LSB
#undef GDK_RGB16_STORE_101010_B_LOW_LSB
#undef GDK_RGB16_STORE_101010_R_LOW_MSB
#undef GDK_RGB16_STORE_101010_B_LOW_MSB
static void
@ -4416,20 +4647,20 @@ gdk_rgb16_select_converter (GdkRgbInfo *image_info,
case GDK_RGB_FORMAT_0888_BR:
SELECT_PAIR (argb);
case GDK_RGB_FORMAT_RGB0_NATIVE:
SELECT_PAIR (rgb0_native);
case GDK_RGB_FORMAT_8880_BR:
SELECT_PAIR (8880_br);
case GDK_RGB_FORMAT_101010_R_LOW_LE:
SELECT_PAIR (101010_r_low_le);
case GDK_RGB_FORMAT_101010_R_LOW_LSB:
SELECT_PAIR (101010_r_low_lsb);
case GDK_RGB_FORMAT_101010_B_LOW_LE:
SELECT_PAIR (101010_b_low_le);
case GDK_RGB_FORMAT_101010_B_LOW_LSB:
SELECT_PAIR (101010_b_low_lsb);
case GDK_RGB_FORMAT_101010_R_LOW_BE:
SELECT_PAIR (101010_r_low_be);
case GDK_RGB_FORMAT_101010_R_LOW_MSB:
SELECT_PAIR (101010_r_low_msb);
case GDK_RGB_FORMAT_101010_B_LOW_BE:
SELECT_PAIR (101010_b_low_be);
case GDK_RGB_FORMAT_101010_B_LOW_MSB:
SELECT_PAIR (101010_b_low_msb);
default:
break;
@ -4854,48 +5085,123 @@ gdk_draw_gray_image (GdkDrawable *drawable,
static GdkRgbCmapInfo *
gdk_rgb_cmap_get_info (GdkRgbCmap *cmap,
GdkRgbInfo *image_info)
GdkRgbInfo *image_info)
{
GSList *tmp_list;
GdkRgbCmapInfo *cmap_info;
int i, j;
guint32 rgb;
gsize lut_bytes;
gboolean lut8;
gint i;
/* We don't need a LUT for TrueColor or DirectColor visuals */
if (image_info->bpp != 1 ||
!(image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR ||
image_info->visual->type == GDK_VISUAL_STATIC_COLOR ||
image_info->visual->type == GDK_VISUAL_GRAYSCALE))
return NULL;
lut8 =
image_info->bpp == 1 &&
(image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR ||
image_info->visual->type == GDK_VISUAL_STATIC_COLOR ||
image_info->visual->type == GDK_VISUAL_GRAYSCALE);
tmp_list = cmap->info_list;
while (tmp_list)
if (lut8)
lut_bytes = 256;
else
{
cmap_info = tmp_list->data;
if (cmap_info->image_info == image_info)
return cmap_info;
tmp_list = tmp_list->next;
switch (image_info->format)
{
case GDK_RGB_FORMAT_565:
case GDK_RGB_FORMAT_565_BR:
case GDK_RGB_FORMAT_555:
case GDK_RGB_FORMAT_555_BR:
lut_bytes = 256 * sizeof (guint16);
break;
case GDK_RGB_FORMAT_0888:
case GDK_RGB_FORMAT_0888_BR:
case GDK_RGB_FORMAT_8880_BR:
case GDK_RGB_FORMAT_101010_R_LOW_LSB:
case GDK_RGB_FORMAT_101010_B_LOW_LSB:
case GDK_RGB_FORMAT_101010_R_LOW_MSB:
case GDK_RGB_FORMAT_101010_B_LOW_MSB:
lut_bytes = 256 * sizeof (guint32);
break;
default:
return NULL;
}
}
cmap_info = g_new (GdkRgbCmapInfo, 1);
for (tmp_list = cmap->info_list;
tmp_list;
tmp_list = tmp_list->next)
{
cmap_info = tmp_list->data;
if (cmap_info->image_info == image_info)
return cmap_info;
}
cmap_info =
g_malloc (G_STRUCT_OFFSET (GdkRgbCmapInfo, lut) +
lut_bytes);
cmap_info->image_info = image_info;
cmap_info->cmap = cmap;
for (i = 0; i < cmap->n_colors; i++)
if (lut8)
{
rgb = cmap->colors[i];
j = ((rgb & 0xf00000) >> 12) |
((rgb & 0xf000) >> 8) |
((rgb & 0xf0) >> 4);
for (i = 0; i < cmap->n_colors; i++)
{
guint32 rgb = cmap->colors[i];
gint j;
j = ((rgb & 0xf00000) >> 12) |
((rgb & 0x00f000) >> 8) |
((rgb & 0x0000f0) >> 4);
#ifdef VERBOSE
g_print ("%d %x %x\n", i, j, image_info->colorcube[j]);
g_print ("%d %x %x\n",
i, j, image_info->colorcube[j]);
#endif
cmap_info->lut[i] = image_info->colorcube[j];
cmap_info->lut[i] =
image_info->colorcube[j];
}
}
else
{
GdkImage image;
guchar stage[256 * 3];
for (i = 0; i < cmap->n_colors; i++)
{
guint32 rgb = cmap->colors[i];
stage[i * 3 + 0] = rgb >> 16;
stage[i * 3 + 1] = rgb >> 8;
stage[i * 3 + 2] = rgb;
}
memset (&image, 0, sizeof (image));
image.mem = cmap_info->lut;
image.bpl = cmap->n_colors * image_info->bpp;
g_assert (image_info->conv != NULL);
image_info->conv (image_info,
&image,
0, 0,
cmap->n_colors, 1,
stage,
cmap->n_colors * 3,
0, 0,
NULL);
}
cmap->info_list = g_slist_prepend (cmap->info_list, cmap_info);
image_info->cmap_info_list = g_slist_prepend (image_info->cmap_info_list, cmap_info);
cmap->info_list =
g_slist_prepend (cmap->info_list,
cmap_info);
image_info->cmap_info_list =
g_slist_prepend (image_info->cmap_info_list,
cmap_info);
return cmap_info;
}