diff options
author | Andrew Mahone <andrew.mahone@gmail.com> | 2009-05-26 20:00:47 +0000 |
---|---|---|
committer | Andrew Mahone <andrew.mahone@gmail.com> | 2009-05-26 20:00:47 +0000 |
commit | 92785b8f2f20b0fc16de7e771e5eb55fd8497ff8 (patch) | |
tree | 3af2399c1e1be8e56cb1b5e6787efd738dad6d52 /apps/plugins/pictureflow | |
parent | c4ed88f59302882749023268ac456c415a4b1243 (diff) | |
download | rockbox-92785b8f2f20b0fc16de7e771e5eb55fd8497ff8.tar.gz rockbox-92785b8f2f20b0fc16de7e771e5eb55fd8497ff8.zip |
Use pre-multiplication in scaler to save one multiply per color component on ARM and Coldfire, at the cost of an extra add/shift in the horizontal scaler to reduce values to a workable range. SH-1 retains the same basic math, as
the use of 16x16->32 hardware multiplication in the earlier scaler stages saves more than removing the 32x32->40 multiply to descale output.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21091 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pictureflow')
-rw-r--r-- | apps/plugins/pictureflow/pictureflow.c | 49 |
1 files changed, 16 insertions, 33 deletions
diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c index a1ad3d2776..bbe2541681 100644 --- a/apps/plugins/pictureflow/pictureflow.c +++ b/apps/plugins/pictureflow/pictureflow.c | |||
@@ -592,25 +592,12 @@ static inline PFreal fcos(int iangle) | |||
592 | return fsin(iangle + (IANGLE_MAX >> 2)); | 592 | return fsin(iangle + (IANGLE_MAX >> 2)); |
593 | } | 593 | } |
594 | 594 | ||
595 | static inline uint32_t div255(uint32_t val) | 595 | static inline unsigned scale_val(unsigned val, unsigned bits) |
596 | { | 596 | { |
597 | return ((((val >> 8) + val) >> 8) + val) >> 8; | 597 | val = val * ((1 << bits) - 1); |
598 | return ((val >> 8) + val + 128) >> 8; | ||
598 | } | 599 | } |
599 | 600 | ||
600 | #define SCALE_VAL(val,out) div255((val) * (out) + 127) | ||
601 | #define SCALE_VAL32(val, out) \ | ||
602 | ({ \ | ||
603 | uint32_t val__ = (val) * (out); \ | ||
604 | val__ = ((((val__ >> 8) + val__) >> 8) + val__ + 128) >> 8; \ | ||
605 | val__; \ | ||
606 | }) | ||
607 | #define SCALE_VAL8(val, out) \ | ||
608 | ({ \ | ||
609 | unsigned val__ = (val) * (out); \ | ||
610 | val__ = ((val__ >> 8) + val__ + 128) >> 8; \ | ||
611 | val__; \ | ||
612 | }) | ||
613 | |||
614 | static void output_row_8_transposed(uint32_t row, void * row_in, | 601 | static void output_row_8_transposed(uint32_t row, void * row_in, |
615 | struct scaler_context *ctx) | 602 | struct scaler_context *ctx) |
616 | { | 603 | { |
@@ -625,9 +612,9 @@ static void output_row_8_transposed(uint32_t row, void * row_in, | |||
625 | unsigned r, g, b; | 612 | unsigned r, g, b; |
626 | for (; dest < end; dest += ctx->bm->height) | 613 | for (; dest < end; dest += ctx->bm->height) |
627 | { | 614 | { |
628 | r = SCALE_VAL8(qp->red, 31); | 615 | r = scale_val(qp->red, 5); |
629 | g = SCALE_VAL8(qp->green, 63); | 616 | g = scale_val(qp->green, 6); |
630 | b = SCALE_VAL8((qp++)->blue, 31); | 617 | b = scale_val((qp++)->blue, 5); |
631 | *dest = LCD_RGBPACK_LCD(r,g,b); | 618 | *dest = LCD_RGBPACK_LCD(r,g,b); |
632 | } | 619 | } |
633 | #endif | 620 | #endif |
@@ -641,19 +628,15 @@ static void output_row_32_transposed(uint32_t row, void * row_in, | |||
641 | #ifdef USEGSLIB | 628 | #ifdef USEGSLIB |
642 | uint32_t *qp = (uint32_t*)row_in; | 629 | uint32_t *qp = (uint32_t*)row_in; |
643 | for (; dest < end; dest += ctx->bm->height) | 630 | for (; dest < end; dest += ctx->bm->height) |
644 | *dest = SC_MUL((*qp++) + ctx->round, ctx->divisor); | 631 | *dest = SC_OUT(*qp++, ctx); |
645 | #else | 632 | #else |
646 | struct uint32_rgb *qp = (struct uint32_rgb*)row_in; | 633 | struct uint32_rgb *qp = (struct uint32_rgb*)row_in; |
647 | uint32_t rb_mul = SCALE_VAL32(ctx->divisor, 31), | ||
648 | rb_rnd = SCALE_VAL32(ctx->round, 31), | ||
649 | g_mul = SCALE_VAL32(ctx->divisor, 63), | ||
650 | g_rnd = SCALE_VAL32(ctx->round, 63); | ||
651 | int r, g, b; | 634 | int r, g, b; |
652 | for (; dest < end; dest += ctx->bm->height) | 635 | for (; dest < end; dest += ctx->bm->height) |
653 | { | 636 | { |
654 | r = SC_MUL(qp->r + rb_rnd, rb_mul); | 637 | r = scale_val(SC_OUT(qp->r, ctx), 5); |
655 | g = SC_MUL(qp->g + g_rnd, g_mul); | 638 | g = scale_val(SC_OUT(qp->g, ctx), 6); |
656 | b = SC_MUL(qp->b + rb_rnd, rb_mul); | 639 | b = scale_val(SC_OUT(qp->b, ctx), 5); |
657 | qp++; | 640 | qp++; |
658 | *dest = LCD_RGBPACK_LCD(r,g,b); | 641 | *dest = LCD_RGBPACK_LCD(r,g,b); |
659 | } | 642 | } |
@@ -670,14 +653,14 @@ static void output_row_32_transposed_fromyuv(uint32_t row, void * row_in, | |||
670 | for (; dest < end; dest += ctx->bm->height) | 653 | for (; dest < end; dest += ctx->bm->height) |
671 | { | 654 | { |
672 | unsigned r, g, b, y, u, v; | 655 | unsigned r, g, b, y, u, v; |
673 | y = SC_MUL(qp->b + ctx->round, ctx->divisor); | 656 | y = SC_OUT(qp->b, ctx); |
674 | u = SC_MUL(qp->g + ctx->round, ctx->divisor); | 657 | u = SC_OUT(qp->g, ctx); |
675 | v = SC_MUL(qp->r + ctx->round, ctx->divisor); | 658 | v = SC_OUT(qp->r, ctx); |
676 | qp++; | 659 | qp++; |
677 | yuv_to_rgb(y, u, v, &r, &g, &b); | 660 | yuv_to_rgb(y, u, v, &r, &g, &b); |
678 | r = (31 * r + (r >> 3) + 127) >> 8; | 661 | r = scale_val(r, 5); |
679 | g = (63 * g + (g >> 2) + 127) >> 8; | 662 | g = scale_val(g, 6); |
680 | b = (31 * b + (b >> 3) + 127) >> 8; | 663 | b = scale_val(b, 5); |
681 | *dest = LCD_RGBPACK_LCD(r, g, b); | 664 | *dest = LCD_RGBPACK_LCD(r, g, b); |
682 | } | 665 | } |
683 | } | 666 | } |