diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2013-09-05 18:15:07 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2013-09-05 18:15:07 -0400 |
commit | ddf2aa26a7fbe94f0c9403af7546c756db1a80e4 (patch) | |
tree | 89685a9c9e1ffdb8966e9fd723dd67628771b13c | |
parent | 813545b4d2bf2b62ed12f9ee345248c80b850305 (diff) |
src/dest iters
-rw-r--r-- | iterjit.c | 416 |
1 files changed, 397 insertions, 19 deletions
@@ -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 |