summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2013-09-05 18:15:07 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2013-09-05 18:15:07 -0400
commitddf2aa26a7fbe94f0c9403af7546c756db1a80e4 (patch)
tree89685a9c9e1ffdb8966e9fd723dd67628771b13c
parent813545b4d2bf2b62ed12f9ee345248c80b850305 (diff)
src/dest iters
-rw-r--r--iterjit.c416
1 files changed, 397 insertions, 19 deletions
diff --git a/iterjit.c b/iterjit.c
index c63fbaa..b188f92 100644
--- a/iterjit.c
+++ b/iterjit.c
@@ -101,11 +101,192 @@
*/
#include <stdio.h>
+#include <stddef.h>
+#include <pixman.h>
#include "simplex86.h"
#include "simple-reg.h"
#include "stack-man.h"
#include "crc32.h"
+typedef struct
+{
+ pixman_op_t op;
+ pixman_image_t * src_image;
+ pixman_image_t * mask_image;
+ pixman_image_t * dest_image;
+ int32_t src_x;
+ int32_t src_y;
+ int32_t mask_x;
+ int32_t mask_y;
+ int32_t dest_x;
+ int32_t dest_y;
+ int32_t width;
+ int32_t height;
+
+ uint32_t src_flags;
+ uint32_t mask_flags;
+ uint32_t dest_flags;
+} pixman_composite_info_t;
+typedef struct image_common image_common_t;
+typedef struct solid_fill solid_fill_t;
+typedef struct gradient gradient_t;
+typedef struct linear_gradient linear_gradient_t;
+typedef struct horizontal_gradient horizontal_gradient_t;
+typedef struct vertical_gradient vertical_gradient_t;
+typedef struct conical_gradient conical_gradient_t;
+typedef struct radial_gradient radial_gradient_t;
+typedef struct bits_image bits_image_t;
+typedef struct circle circle_t;
+
+typedef struct argb_t argb_t;
+
+struct argb_t
+{
+ float a;
+ float r;
+ float g;
+ float b;
+};
+
+typedef void (*fetch_scanline_t) (bits_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t *buffer,
+ const uint32_t *mask);
+
+typedef void (*store_scanline_t) (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values);
+
+typedef enum
+{
+ BITS,
+ LINEAR,
+ CONICAL,
+ RADIAL,
+ SOLID
+} image_type_t;
+
+typedef void (*property_changed_func_t) (pixman_image_t *image);
+
+struct image_common
+{
+ image_type_t type;
+ int32_t ref_count;
+ pixman_region32_t clip_region;
+ int32_t alpha_count; /* How many times this image is being used as an alpha map */
+ pixman_bool_t have_clip_region; /* FALSE if there is no clip */
+ pixman_bool_t client_clip; /* Whether the source clip was
+ set by a client */
+ pixman_bool_t clip_sources; /* Whether the clip applies when
+ * the image is used as a source
+ */
+ pixman_bool_t dirty;
+ pixman_transform_t * transform;
+ pixman_repeat_t repeat;
+ pixman_filter_t filter;
+ pixman_fixed_t * filter_params;
+ int n_filter_params;
+ bits_image_t * alpha_map;
+ int alpha_origin_x;
+ int alpha_origin_y;
+ pixman_bool_t component_alpha;
+ property_changed_func_t property_changed;
+
+ pixman_image_destroy_func_t destroy_func;
+ void * destroy_data;
+
+ uint32_t flags;
+ pixman_format_code_t extended_format_code;
+};
+
+struct solid_fill
+{
+ image_common_t common;
+ pixman_color_t color;
+
+ uint32_t color_32;
+ argb_t color_float;
+};
+
+struct gradient
+{
+ image_common_t common;
+ int n_stops;
+ pixman_gradient_stop_t *stops;
+};
+
+struct linear_gradient
+{
+ gradient_t common;
+ pixman_point_fixed_t p1;
+ pixman_point_fixed_t p2;
+};
+
+struct circle
+{
+ pixman_fixed_t x;
+ pixman_fixed_t y;
+ pixman_fixed_t radius;
+};
+
+struct radial_gradient
+{
+ gradient_t common;
+
+ circle_t c1;
+ circle_t c2;
+
+ circle_t delta;
+ double a;
+ double inva;
+ double mindr;
+};
+
+struct conical_gradient
+{
+ gradient_t common;
+ pixman_point_fixed_t center;
+ double angle;
+};
+
+struct bits_image
+{
+ image_common_t common;
+ pixman_format_code_t format;
+ const pixman_indexed_t * indexed;
+ int width;
+ int height;
+ uint32_t * bits;
+ uint32_t * free_me;
+ int rowstride; /* in number of uint32_t's */
+
+ fetch_scanline_t fetch_scanline_32;
+ store_scanline_t store_scanline_32;
+
+ fetch_scanline_t fetch_scanline_float;
+ store_scanline_t store_scanline_float;
+
+ /* Used for indirect access to the bits */
+ pixman_read_memory_func_t read_func;
+ pixman_write_memory_func_t write_func;
+};
+
+union pixman_image
+{
+ image_type_t type;
+ image_common_t common;
+ bits_image_t bits;
+ gradient_t gradient;
+ linear_gradient_t linear;
+ conical_gradient_t conical;
+ radial_gradient_t radial;
+ solid_fill_t solid;
+};
+
typedef struct jit_dest_iter_t jit_dest_iter_t;
typedef struct jit_src_iter_t jit_src_iter_t;
typedef struct jit_combiner_t jit_combiner_t;
@@ -121,25 +302,29 @@ struct jit_t
struct jit_src_iter_t
{
- void (* begin) (jit_src_iter_t *src, jit_t *jit);
+ void (* begin) (jit_src_iter_t *src, jit_t *jit, reg_t info);
void (* begin_line) (jit_src_iter_t *src, jit_t *jit);
- op_t (* load_pixels) (jit_src_iter_t *src, jit_t *jit, int n_pixels);
+ reg_t (* load_pixels) (jit_src_iter_t *src, jit_t *jit, int n_pixels);
void (* advance_pixels) (jit_src_iter_t *src, jit_t *jit, int n_pixels);
void (* end_line) (jit_src_iter_t *src, jit_t *jit);
void (* end) (jit_src_iter_t *src, jit_t *jit);
+
+ reg_t line;
+ reg_t stride;
+ reg_t s;
};
struct jit_combiner_t
{
- op_t (* combine) (jit_combiner_t *combiner, jit_t *jit,
- jit_src_iter_t *src,
- jit_src_iter_t *mask,
- jit_dest_iter_t *dest);
+ reg_t (* combine) (jit_combiner_t *combiner, jit_t *jit,
+ jit_src_iter_t *src,
+ jit_src_iter_t *mask,
+ jit_dest_iter_t *dest);
};
struct jit_dest_iter_t
{
- void (* begin) (jit_dest_iter_t *dest, jit_t *jit);
+ void (* begin) (jit_dest_iter_t *dest, jit_t *jit, reg_t info);
op_t (* load_pixels) (jit_dest_iter_t *dest, jit_t *jit, int n_pixels);
void (* advance_pixels) (jit_dest_iter_t *dest, jit_t *jit, int n_pixels);
void (* process_line) (jit_dest_iter_t *dest_iter,
@@ -148,14 +333,185 @@ struct jit_dest_iter_t
jit_src_iter_t *mask_iter,
jit_combiner_t *combiner);
void (* end) (jit_dest_iter_t *dest, jit_t *jit);
+
+ reg_t line;
+ reg_t stride;
};
+#define MEMBER(variable, type, member) \
+ BASE((variable), offsetof (type, member))
+
+void jit_switch_group (jit_t *jit, const char *group);
+reg_t jit_alloc_gp (jit_t *jit);
+reg_t jit_alloc_xmm (jit_t *jit);
+void jit_preserve_gp (jit_t *jit, reg_t reg);
+void jit_free_gp (jit_t *jit, reg_t reg);
+void jit_reload_gp (jit_t *jit, reg_t reg);
+void jit_free_gp (jit_t *jit, reg_t reg);
+void jit_free_xmm (jit_t *jit, reg_t reg);
+
+static void
+src_a8r8g8b8_begin (jit_src_iter_t *src,
+ jit_t *jit,
+ reg_t info)
+{
+ reg_t image, tmp;
+
+ jit_switch_group (jit, "src");
+ jit_preserve_gp (jit, info);
+ src->line = jit_alloc_gp (jit);
+ src->stride = jit_alloc_gp (jit);
+ image = jit_alloc_gp (jit);
+ tmp = jit_alloc_gp (jit);
+
+ BEGIN_ASM (jit->fragment)
+ I_mov, image, MEMBER (info, pixman_composite_info_t, src_image),
+
+ /* Stride */
+ I_mov, src->stride, MEMBER (image, pixman_image_t, bits.rowstride),
+ I_shl, src->stride, IMM (2),
+
+ /* Line */
+ I_mov, src->line, MEMBER(image, pixman_image_t, bits.bits),
+ I_mov, tmp, src->stride,
+ I_imul2, tmp, MEMBER (info, pixman_composite_info_t, src_y),
+ I_add, src->line, tmp,
+ I_mov, tmp, MEMBER (info, pixman_composite_info_t, src_x),
+ I_shl, tmp, IMM (2),
+ I_add, src->line, tmp,
+ END_ASM ();
+
+ jit_free_gp (jit, info);
+ jit_free_gp (jit, image);
+ jit_free_gp (jit, tmp);
+}
+
+static void
+src_a8r8g8b8_begin_line (jit_src_iter_t *src, jit_t *jit)
+{
+ jit_switch_group (jit, "src");
+ src->s = jit_alloc_gp (jit);
+
+ jit_reload_gp (jit, src->line);
+ jit_reload_gp (jit, src->stride);
+ BEGIN_ASM (jit->fragment)
+ I_mov, src->s, src->line,
+ I_add, src->line, src->stride,
+ END_ASM ();
+}
+
+static reg_t
+src_a8r8g8b8_load_pixels (jit_src_iter_t *src, jit_t *jit, int n_pixels)
+{
+ instruction_t move;
+ reg_t r;
+
+ jit_switch_group (jit, "src");
+
+ r = jit_alloc_xmm (jit);
+
+ switch (n_pixels)
+ {
+ case 1:
+ move = I_movd;
+ break;
+
+ case 2:
+ move = I_movq;
+ break;
+
+ case 4:
+ move = I_movdqu;
+ break;
+ }
+
+ BEGIN_ASM (jit->fragment)
+ move, r, PTR (src->s),
+ END_ASM ();
+
+ jit_free_xmm (jit, r);
+
+ return r;
+}
+
+static void
+src_a8r8g8b8_advance_pixels (jit_src_iter_t *src, jit_t *jit, int n_pixels)
+{
+ int n_bytes = n_pixels * 4;
+
+ jit_switch_group (jit, "src");
+ jit_reload_gp (jit, src->s);
+
+ BEGIN_ASM (jit->fragment)
+ I_add, src->s, IMM (n_bytes),
+ END_ASM ();
+}
+
+static void
+src_a8r8g8b8_end_line (jit_src_iter_t *src, jit_t *jit)
+{
+ jit_switch_group (jit, "src");
+ jit_free_gp (jit, src->s);
+}
+
+static void
+src_a8r8g8b8_end (jit_src_iter_t *src, jit_t *jit)
+{
+ jit_switch_group (jit, "src");
+ jit_free_gp (jit, src->stride);
+ jit_free_gp (jit, src->line);
+}
+
+jit_src_iter_t *
+src_iter_create_a8r8g8b8 (jit_dest_iter_t *dest)
+{
+ jit_src_iter_t *iter = malloc (sizeof *iter); /* FIXME OOM */
+
+ iter->begin = src_a8r8g8b8_begin;
+ iter->begin_line = src_a8r8g8b8_begin_line;
+ iter->load_pixels = src_a8r8g8b8_load_pixels;
+ iter->advance_pixels = src_a8r8g8b8_advance_pixels;
+ iter->end_line = src_a8r8g8b8_end_line;
+ iter->end = src_a8r8g8b8_end;
+
+ return iter;
+}
+
+/* Dest iter */
static void
dest_a8r8g8b8_begin (jit_dest_iter_t * dest,
- jit_t * jit)
+ jit_t * jit,
+ reg_t info)
{
+ reg_t image, tmp;
+
+ jit_switch_group (jit, "dest");
+ jit_preserve_gp (jit, info);
+ dest->line = jit_alloc_gp (jit);
+ dest->stride = jit_alloc_gp (jit);
+ image = jit_alloc_gp (jit);
+ tmp = jit_alloc_gp (jit);
+
BEGIN_ASM (jit->fragment)
+ I_mov, image, MEMBER (info, pixman_composite_info_t, dest_image),
+
+ /* Stride */
+ I_mov, dest->stride, MEMBER (image, pixman_image_t, bits.rowstride),
+ I_shl, dest->stride, IMM (2),
+
+ /* Line */
+ I_mov, dest->line, MEMBER(image, pixman_image_t, bits.bits),
+ I_mov, tmp, dest->stride,
+ I_imul2, tmp, MEMBER (info, pixman_composite_info_t, dest_y),
+ I_add, dest->line, tmp,
+ I_mov, tmp, MEMBER (info, pixman_composite_info_t, dest_x),
+ I_shl, tmp, IMM (2),
+ I_add, dest->line, tmp,
END_ASM ();
+
+ jit_free_gp (jit, info);
+ jit_free_gp (jit, image);
+ jit_free_gp (jit, tmp);
}
static void
@@ -166,6 +522,7 @@ dest_a8r8g8b8_process_line (jit_dest_iter_t *dest,
jit_combiner_t *combiner)
{
src->begin_line (src, jit);
+ mask->begin_line (mask, jit);
BEGIN_ASM (jit->fragment)
@@ -198,33 +555,54 @@ generate_kernel (jit_t *jit,
jit_dest_iter_t *dest_iter,
jit_combiner_t *combiner)
{
- reg_context_t context;
- op_t h = reg_context_alloc (&context, jit->fragment);
+ reg_t h, composite_info;
- src_iter->begin (src_iter, jit);
- if (mask_iter)
- mask_iter->begin (mask_iter, jit);
- dest_iter->begin (dest_iter, jit);
+ jit_switch_group (jit, "outer");
+ jit_preserve_gp (jit, rsi);
+ composite_info = rsi;
+
+ h = jit_alloc_gp (jit);
BEGIN_ASM (jit->fragment)
+ I_mov, h, MEMBER (composite_info, pixman_composite_info_t, height),
I_test, h, h,
I_jz, LABEL ("done"),
- DEFINE_LABEL ("outer_loop"),
END_ASM ();
- dest_iter->process_line (dest_iter, jit,
- src_iter, mask_iter, combiner);
+ jit_free_gp (jit, composite_info);
+ /* begin */
+ src_iter->begin (src_iter, jit, composite_info);
+ if (mask_iter)
+ mask_iter->begin (mask_iter, jit, composite_info);
+ dest_iter->begin (dest_iter, jit, composite_info);
+
+ /* loop */
+ BEGIN_ASM (jit->fragment)
+ DEFINE_LABEL ("vertical_loop"),
+ END_ASM ();
+
+ dest_iter->process_line (
+ dest_iter, jit, src_iter, mask_iter, combiner);
+
+ jit_switch_group (jit, "outer");
+ jit_reload_gp (jit, h);
BEGIN_ASM (jit->fragment)
I_sub, h, IMM (1),
- I_jnz, LABEL ("outer_loop"),
- DEFINE_LABEL ("done"),
+ I_jnz, LABEL ("vertical_loop"),
END_ASM ();
+
+ jit_free_gp (jit, h);
+ /* end */
dest_iter->end (dest_iter, jit);
if (mask_iter)
mask_iter->end (mask_iter, jit);
src_iter->end (src_iter, jit);
+
+ BEGIN_ASM (jit->fragment)
+ DEFINE_LABEL ("done"),
+ END_ASM();
}
int