summaryrefslogtreecommitdiffstats
path: root/libass/ass_render.c
diff options
context:
space:
mode:
authorDr.Smile <vabnick@gmail.com>2015-06-26 02:14:21 +0300
committerDr.Smile <vabnick@gmail.com>2015-06-26 02:14:21 +0300
commit38a175cad5a894467cb7187ad0187db1ae3f89ff (patch)
treea7262be6620f31c2f0d8df26218c6160c5354f56 /libass/ass_render.c
parent88f1fd37fe5785851f069e3dc6939f1ab905f4bc (diff)
downloadlibass-38a175cad5a894467cb7187ad0187db1ae3f89ff.tar.bz2
libass-38a175cad5a894467cb7187ad0187db1ae3f89ff.tar.xz
Switch to virtual function table
Use one pointer to table of functions instead of scattered bunch of function pointers. Different versions of these tables can be constructed in compile time. Also, bitmap memory alignment now depends only on SSE2/AVX2 support and is constant for every width. That simplifies code without noticeable performance penalty.
Diffstat (limited to 'libass/ass_render.c')
-rw-r--r--libass/ass_render.c110
1 files changed, 35 insertions, 75 deletions
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 357e1cc..0995b96 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -34,12 +34,6 @@
#define SUBPIXEL_MASK 63
#define SUBPIXEL_ACCURACY 7
-#if (defined(__i386__) || defined(__x86_64__)) && CONFIG_ASM
-
-#include "x86/blend_bitmaps.h"
-#include "x86/rasterizer.h"
-
-#endif // ASM
ASS_Renderer *ass_renderer_init(ASS_Library *library)
{
@@ -70,56 +64,19 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library)
priv->ftlibrary = ft;
// images_root and related stuff is zero-filled in calloc
- #if (defined(__i386__) || defined(__x86_64__)) && CONFIG_ASM
- int sse2 = has_sse2();
- int avx2 = has_avx2();
- priv->add_bitmaps_func = avx2 ? ass_add_bitmaps_avx2 :
- (sse2 ? ass_add_bitmaps_sse2 : ass_add_bitmaps_x86);
- #ifdef __x86_64__
- priv->mul_bitmaps_func = avx2 ? ass_mul_bitmaps_avx2 : ass_mul_bitmaps_sse2;
- priv->sub_bitmaps_func = avx2 ? ass_sub_bitmaps_avx2 : ass_sub_bitmaps_sse2;
- #else
- priv->mul_bitmaps_func = mul_bitmaps_c;
- priv->sub_bitmaps_func = ass_sub_bitmaps_x86;
- #endif
- #else
- priv->add_bitmaps_func = add_bitmaps_c;
- priv->sub_bitmaps_func = sub_bitmaps_c;
- priv->mul_bitmaps_func = mul_bitmaps_c;
- #endif
-
-#if CONFIG_RASTERIZER
-#if CONFIG_LARGE_TILES
- priv->rasterizer.tile_order = 5;
- #if (defined(__i386__) || defined(__x86_64__)) && CONFIG_ASM
- priv->rasterizer.fill_solid = avx2 ? ass_fill_solid_tile32_avx2 :
- (sse2 ? ass_fill_solid_tile32_sse2 : ass_fill_solid_tile32_c);
- priv->rasterizer.fill_halfplane = avx2 ? ass_fill_halfplane_tile32_avx2 :
- (sse2 ? ass_fill_halfplane_tile32_sse2 : ass_fill_halfplane_tile32_c);
- priv->rasterizer.fill_generic = avx2 ? ass_fill_generic_tile32_avx2 :
- (sse2 ? ass_fill_generic_tile32_sse2 : ass_fill_generic_tile32_c);
- #else
- priv->rasterizer.fill_solid = ass_fill_solid_tile32_c;
- priv->rasterizer.fill_halfplane = ass_fill_halfplane_tile32_c;
- priv->rasterizer.fill_generic = ass_fill_generic_tile32_c;
- #endif
+#if (defined(__i386__) || defined(__x86_64__)) && CONFIG_ASM
+ if (has_avx2())
+ priv->engine = &ass_bitmap_engine_avx2;
+ else if (has_sse2())
+ priv->engine = &ass_bitmap_engine_sse2;
+ else
+ priv->engine = &ass_bitmap_engine_c;
#else
- priv->rasterizer.tile_order = 4;
- #if (defined(__i386__) || defined(__x86_64__)) && CONFIG_ASM
- priv->rasterizer.fill_solid = avx2 ? ass_fill_solid_tile16_avx2 :
- (sse2 ? ass_fill_solid_tile16_sse2 : ass_fill_solid_tile16_c);
- priv->rasterizer.fill_halfplane = avx2 ? ass_fill_halfplane_tile16_avx2 :
- (sse2 ? ass_fill_halfplane_tile16_sse2 : ass_fill_halfplane_tile16_c);
- priv->rasterizer.fill_generic = avx2 ? ass_fill_generic_tile16_avx2 :
- (sse2 ? ass_fill_generic_tile16_sse2 : ass_fill_generic_tile16_c);
- #else
- priv->rasterizer.fill_solid = ass_fill_solid_tile16_c;
- priv->rasterizer.fill_halfplane = ass_fill_halfplane_tile16_c;
- priv->rasterizer.fill_generic = ass_fill_generic_tile16_c;
- #endif
+ priv->engine = &ass_bitmap_engine_c;
#endif
- priv->rasterizer.outline_error = 16;
- rasterizer_init(&priv->rasterizer);
+
+#if CONFIG_RASTERIZER
+ rasterizer_init(&priv->rasterizer, 16);
#endif
priv->cache.font_cache = ass_font_cache_create();
@@ -633,9 +590,9 @@ static void blend_vector_clip(ASS_Renderer *render_priv,
// Blend together
memcpy(nbuffer, abuffer, ((ah - 1) * as) + aw);
- render_priv->sub_bitmaps_func(nbuffer + atop * as + aleft, as,
- bbuffer + btop * bs + bleft, bs,
- h, w);
+ render_priv->engine->sub_bitmaps(nbuffer + atop * as + aleft, as,
+ bbuffer + btop * bs + bleft, bs,
+ h, w);
} else {
// Regular clip
if (ax + aw < bx || ay + ah < by || ax > bx + bw ||
@@ -654,10 +611,10 @@ static void blend_vector_clip(ASS_Renderer *render_priv,
}
// Blend together
- render_priv->mul_bitmaps_func(nbuffer, ns,
- abuffer + atop * as + aleft, as,
- bbuffer + btop * bs + bleft, bs,
- w, h);
+ render_priv->engine->mul_bitmaps(nbuffer, ns,
+ abuffer + atop * as + aleft, as,
+ bbuffer + btop * bs + bleft, bs,
+ w, h);
cur->dst_x += aleft;
cur->dst_y += atop;
cur->w = w;
@@ -1843,15 +1800,15 @@ static void make_shadow_bitmap(CombinedBitmapInfo *info, ASS_Renderer *render_pr
// Create shadow and fix outline as needed
if (info->bm_o && !(info->filter.flags & FILTER_BORDER_STYLE_3)) {
- info->bm_s = copy_bitmap(info->bm_o);
+ info->bm_s = copy_bitmap(render_priv->engine, info->bm_o);
fix_outline(info->bm, info->bm_o);
} else if (info->bm_o && (info->filter.flags & FILTER_NONZERO_BORDER)) {
- info->bm_s = copy_bitmap(info->bm_o);
+ info->bm_s = copy_bitmap(render_priv->engine, info->bm_o);
} else if (info->bm_o) {
info->bm_s = info->bm_o;
info->bm_o = 0;
} else
- info->bm_s = copy_bitmap(info->bm);
+ info->bm_s = copy_bitmap(render_priv->engine, info->bm);
if (!info->bm_s)
return;
@@ -2328,7 +2285,7 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv,
for (int j = 0; j < info->bitmap_count; ++j) {
if (!info->bitmaps[j].image->bm)
continue;
- info->bm = copy_bitmap(info->bitmaps[j].image->bm);
+ info->bm = copy_bitmap(render_priv->engine, info->bitmaps[j].image->bm);
if (info->bm) {
info->bm->left += info->bitmaps[j].x;
info->bm->top += info->bitmaps[j].y;
@@ -2336,7 +2293,8 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv,
break;
}
} else if (info->n_bm) {
- info->bm = alloc_bitmap(info->rect.x_max - info->rect.x_min + 2 * bord,
+ info->bm = alloc_bitmap(render_priv->engine,
+ info->rect.x_max - info->rect.x_min + 2 * bord,
info->rect.y_max - info->rect.y_min + 2 * bord);
Bitmap *dst = info->bm;
if (dst) {
@@ -2351,9 +2309,9 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv,
assert(x >= 0 && x + src->w <= dst->w);
assert(y >= 0 && y + src->h <= dst->h);
unsigned char *buf = dst->buffer + y * dst->stride + x;
- render_priv->add_bitmaps_func(buf, dst->stride,
- src->buffer, src->stride,
- src->h, src->w);
+ render_priv->engine->add_bitmaps(buf, dst->stride,
+ src->buffer, src->stride,
+ src->h, src->w);
}
}
}
@@ -2361,7 +2319,7 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv,
for (int j = 0; j < info->bitmap_count; ++j) {
if (!info->bitmaps[j].image->bm_o)
continue;
- info->bm_o = copy_bitmap(info->bitmaps[j].image->bm_o);
+ info->bm_o = copy_bitmap(render_priv->engine, info->bitmaps[j].image->bm_o);
if (info->bm_o) {
info->bm_o->left += info->bitmaps[j].x;
info->bm_o->top += info->bitmaps[j].y;
@@ -2369,7 +2327,8 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv,
break;
}
} else if (info->n_bm_o) {
- info->bm_o = alloc_bitmap(info->rect_o.x_max - info->rect_o.x_min + 2 * bord,
+ info->bm_o = alloc_bitmap(render_priv->engine,
+ info->rect_o.x_max - info->rect_o.x_min + 2 * bord,
info->rect_o.y_max - info->rect_o.y_min + 2 * bord);
Bitmap *dst = info->bm_o;
if (dst) {
@@ -2384,15 +2343,16 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv,
assert(x >= 0 && x + src->w <= dst->w);
assert(y >= 0 && y + src->h <= dst->h);
unsigned char *buf = dst->buffer + y * dst->stride + x;
- render_priv->add_bitmaps_func(buf, dst->stride,
- src->buffer, src->stride,
- src->h, src->w);
+ render_priv->engine->add_bitmaps(buf, dst->stride,
+ src->buffer, src->stride,
+ src->h, src->w);
}
}
}
if(info->bm || info->bm_o){
- ass_synth_blur(render_priv->synth_priv, info->filter.flags & FILTER_BORDER_STYLE_3,
+ ass_synth_blur(render_priv->engine,
+ render_priv->synth_priv, info->filter.flags & FILTER_BORDER_STYLE_3,
info->filter.be, info->filter.blur, info->bm, info->bm_o);
if (info->filter.flags & FILTER_DRAW_SHADOW)
make_shadow_bitmap(info, render_priv);