summaryrefslogtreecommitdiff
path: root/apps/recorder
diff options
context:
space:
mode:
authorAndrew Mahone <andrew.mahone@gmail.com>2009-01-20 17:24:49 +0000
committerAndrew Mahone <andrew.mahone@gmail.com>2009-01-20 17:24:49 +0000
commit1b13299769a3f2eed3137727cdaf8fdd2f8e4791 (patch)
tree60326c970d50b115fe8a8af42b13aa0f1e43985c /apps/recorder
parent73f2d001fd3ba117e4585c25d42fb93b244518ee (diff)
scaler optimizations:
on sh, use 8.24 fixed-point C math for final division in scaler on coldfire, use 8.32 fixed-point via emac on other architectures, use 8.32 fixed-point C math use shift-and-add to divide when adjusting scale factors in pictureflow git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19802 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/recorder')
-rw-r--r--apps/recorder/resize.c21
-rw-r--r--apps/recorder/resize.h45
2 files changed, 55 insertions, 11 deletions
diff --git a/apps/recorder/resize.c b/apps/recorder/resize.c
index f9345113d6..235e071f7b 100644
--- a/apps/recorder/resize.c
+++ b/apps/recorder/resize.c
@@ -244,7 +244,7 @@ static inline bool scale_v_area(struct rowset *rset, struct scaler_context *ctx)
/* Set up rounding and scale factors */
ctx->divisor *= ctx->src->height;
ctx->round = ctx->divisor >> 1;
- ctx->divisor = ((ctx->divisor - 1 + 0x80000000U) / ctx->divisor) << 1;
+ ctx->divisor = (((ctx->divisor >> 1) + SC_NUM) / ctx->divisor) << SC_FIX;
mul = 0;
oy = rset->rowstart;
oye = 0;
@@ -442,7 +442,7 @@ static inline bool scale_v_linear(struct rowset *rset,
/* Set up scale and rounding factors, the divisor is bm->height - 1 */
ctx->divisor *= (ctx->bm->height - 1);
ctx->round = ctx->divisor >> 1;
- ctx->divisor = ((ctx->divisor - 1 + 0x80000000U) / ctx->divisor) << 1;
+ ctx->divisor = (((ctx->divisor >> 1) + SC_NUM) / ctx->divisor) << SC_FIX;
/* Set up our two temp buffers. The names are generic because they'll be
swapped each time a new input row is read
*/
@@ -531,8 +531,7 @@ void output_row_native(uint32_t row, void * row_in, struct scaler_context *ctx)
for (col = 0; col < ctx->bm->width; col++) {
if (ctx->dither)
delta = DITHERXDY(col,dy);
- bright = ((*qp++) + ctx->round) *
- (uint64_t)ctx->divisor >> 32;
+ bright = SC_MUL((*qp++) + ctx->round,ctx->divisor);
bright = (3 * bright + (bright >> 6) + delta) >> 8;
data |= (~bright & 3) << shift;
shift -= 2;
@@ -555,8 +554,7 @@ void output_row_native(uint32_t row, void * row_in, struct scaler_context *ctx)
for (col = 0; col < ctx->bm->width; col++) {
if (ctx->dither)
delta = DITHERXDY(col,dy);
- bright = ((*qp++) + ctx->round) *
- (uint64_t)ctx->divisor >> 32;
+ bright = SC_MUL((*qp++) + ctx->round, ctx->divisor);
bright = (3 * bright + (bright >> 6) + delta) >> 8;
*dest++ |= (~bright & 3) << shift;
}
@@ -571,8 +569,7 @@ void output_row_native(uint32_t row, void * row_in, struct scaler_context *ctx)
for (col = 0; col < ctx->bm->width; col++) {
if (ctx->dither)
delta = DITHERXDY(col,dy);
- bright = ((*qp++) + ctx->round) *
- (uint64_t)ctx->divisor >> 32;
+ bright = SC_MUL((*qp++) + ctx->round, ctx->divisor);
bright = (3 * bright + (bright >> 6) + delta) >> 8;
*dest++ |= vi_pattern[bright] << shift;
}
@@ -588,9 +585,9 @@ void output_row_native(uint32_t row, void * row_in, struct scaler_context *ctx)
if (ctx->dither)
delta = DITHERXDY(col,dy);
q0 = *qp++;
- r = (q0.r + ctx->round) * (uint64_t)ctx->divisor >> 32;
- g = (q0.g + ctx->round) * (uint64_t)ctx->divisor >> 32;
- b = (q0.b + ctx->round) * (uint64_t)ctx->divisor >> 32;
+ r = SC_MUL(q0.r + ctx->round, ctx->divisor);
+ g = SC_MUL(q0.g + ctx->round, ctx->divisor);
+ b = SC_MUL(q0.b + ctx->round, ctx->divisor);
r = (31 * r + (r >> 3) + delta) >> 8;
g = (63 * g + (g >> 2) + delta) >> 8;
b = (31 * b + (b >> 3) + delta) >> 8;
@@ -680,6 +677,7 @@ int resize_on_load(struct bitmap *bm, bool dither, struct dim *src,
scale_h_linear_setup(&ctx);
}
#endif
+ SC_MUL_INIT;
#ifdef HAVE_UPSCALER
if (sh > dh)
#endif
@@ -688,6 +686,7 @@ int resize_on_load(struct bitmap *bm, bool dither, struct dim *src,
else
ret = scale_v_linear(rset, &ctx);
#endif
+ SC_MUL_END;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
cpu_boost(false);
#endif
diff --git a/apps/recorder/resize.h b/apps/recorder/resize.h
index f8328e3f3d..e1237c441c 100644
--- a/apps/recorder/resize.h
+++ b/apps/recorder/resize.h
@@ -43,6 +43,51 @@
#define MAX_SC_STACK_ALLOC 0
#define HAVE_UPSCALER 1
+#if defined(CPU_COLDFIRE)
+#define SC_NUM 0x80000000U
+#define SC_MUL_INIT \
+ unsigned long macsr_st = coldfire_get_macsr(); \
+ coldfire_set_macsr(0);
+#define SC_MUL_END coldfire_set_macsr(macsr_st);
+#define SC_MUL(x, y) \
+({ \
+ unsigned long t; \
+ asm ("mac.l %[a], %[b], %%acc0\n\t" \
+ "move.l %%accext01, %[t]\n\t" \
+ "move.l #0, %%acc0\n\t" \
+ : [t] "=r" (t) : [a] "r" (x), [b] "r" (y)); \
+ t; \
+})
+#elif defined(CPU_SH)
+#define SC_SHIFT 24
+#endif
+
+#ifndef SC_SHIFT
+#define SC_SHIFT 32
+#endif
+
+#if SC_SHIFT == 24
+#define SC_NUM 0x1000000U
+#define SC_FIX 0
+
+#ifndef SC_MUL
+#define SC_MUL(x, y) ((x) * (y) >> 24)
+#define SC_MUL_INIT
+#define SC_MUL_END
+#endif
+
+#else /* SC_SHIFT == 32 */
+#define SC_NUM 0x80000000U
+#define SC_FIX 1
+
+#ifndef SC_MUL
+#define SC_MUL(x, y) ((x) * (uint64_t)(y) >> 32)
+#define SC_MUL_INIT
+#define SC_MUL_END
+#endif
+
+#endif
+
struct img_part {
int len;
#if !defined(HAVE_LCD_COLOR)