Ticket #8656: diff

File diff, 7.8 KB (added by SF/robinwatts, 17 years ago)

ARM version of rotation functions, plus C changes to call it

  • src/video/wingapi/SDL_gapivideo.

    old new  
    707707        return;
    708708}
    709709
     710#ifdef ARM
     711extern void ARM_rotate(unsigned char *dstptr,
     712                       unsigned char *srcPtr,
     713                       int            w,
     714                       int            h,
     715                       int            dstLineStep,
     716                       int            srcPixStep,
     717                       int            srcLineStep);
     718#endif
     719
    710720static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
    711721{
    712722        static int height=0, width=0, w4=0, w4loop=0, w2=0, w1=0, x1=0, h4=0, h4loop=0, h2=0, h1=0, dstPixelstep2=0, dstLinestep2=0, aligned=0, srcPixelstep2=0, dstLinestep2c=0;
     
    722732        dstLinestep2c = dstLinestep2 - dstPixelstep;
    723733
    724734        while (numrects--) {
     735#ifdef ARM
     736                /* In practise, if we are rotating, we should always fall into one of these two cases... */
     737                if ((rotation == SDL_ROTATE_RIGHT) && (!convertPalette))
     738                {
     739                    /* Typical values: sps=2 sls=480 dps=480 dls=-2
     740                     * We are going to rotate that to be:
     741                     * sps = -480 sls=2 dps=2 dls=480
     742                     *
     743                     * so sps = -OLDsls
     744                     *    sls =  OLDsps
     745                     *    dps = -OLDdls
     746                     *    dls =  OLDdps
     747                     */
     748                    /* Could do: assert(dstLinestep == -2); */
     749                    ARM_rotate(screenBuffer + startOffset - 2 + (rects->x * dstPixelstep) + ((rects->y+rects->h-1) * dstLinestep),
     750                               (unsigned char*)gapiBuffer     + (rects->x * srcPixelstep) + ((rects->y+rects->h-1) * srcLinestep),
     751                               rects->h, rects->w,
     752                               dstPixelstep,  /*  480 */
     753                               -srcLinestep,  /* -480 */
     754                               srcPixelstep); /*    2 */
     755                    rects++;
     756                    continue;
     757                }
     758                else if ((rotation == SDL_ROTATE_LEFT) && (!convertPalette))
     759                {
     760                    /* Typical values: sps=2 sls=640 dps=-480 dls=2
     761                     * We are going to rotate that to be:
     762                     * sps=640 sls=-2 dps=2 dls=480
     763                     *
     764                     * so sps =  OLDsls
     765                     *    sls = -OLDsps
     766                     *    dps =  OLDdls
     767                     *    dls = -OLDdps
     768                     */
     769                    /* Could do: assert(dstLinestep == 2); */
     770                    ARM_rotate(screenBuffer + startOffset + ((rects->x+rects->w-1) * dstPixelstep) + (rects->y * dstLinestep),
     771                               (unsigned char*)gapiBuffer + ((rects->x+rects->w-1) * srcPixelstep) + (rects->y * srcLinestep),
     772                               rects->h, rects->w,
     773                               -dstPixelstep,  /* 480 */
     774                               srcLinestep,    /* 640 */
     775                               -srcPixelstep); /*  -2 */
     776                    rects++;
     777                    continue;
     778                }
     779#endif /* ARM */
    725780                destPointer = screenBuffer + startOffset + (rects->x * dstPixelstep) + (rects->y * dstLinestep);
    726781                srcPointer = (unsigned char*)gapiBuffer + (rects->x * srcPixelstep) + (rects->y * srcLinestep);
    727782                width = rects->w;
  • src/video/wingapi/ARM_rot.

    old new  
     1@ ARM code version of rotation routines.
     2@
     3@ @author Robin Watts (robin@wss.co.uk)
     4@
     5@ When rotating a block of memory to the screen, the key facts to bear in
     6@ mind are:
     7@  * Screen memory is uncached - therefore to get best performance we want
     8@    to write runs of horizontal pixels so the write buffer can kick in and
     9@    merge the buffered writes.
     10@  * Reading large numbers of pixels to be written out horizontally, pulls
     11@    in lots of cache lines. We need to be careful not to cache bust here.
     12@  * The 16 or 32 way set associativity for screens can hurt us here too.
     13@
     14@ A good compromise is therefore to write out in bursts of 4 horizontal
     15@ pixels at once.
     16
     17        .text
     18
     19        .global ARM_rotate
     20
     21        @ Reads block of w*h pixels from srcPtr (addressed by srcPixStep,
     22        @ srcLineStep) and stores them at dst (addressed by dstPixStep,
     23        @ dstLineStep), converting palette by table lookup in convertPalette.
     24ARM_rotate:
     25        @ r0 = destPtr
     26        @ r1 = srcPtr
     27        @ r2 = w
     28        @ r3 = h
     29        @ r4 = dstLineStep
     30        @ r5 = srcPixStep  - e.g. 480
     31        @ r6 = srcLineStep - e.g. 2 or -2
     32        MOV     r12,r13
     33        STMFD   r13!,{r4-r11,r14}
     34        LDMFD   r12,{r4-r6}
     35
     36        @ For simplicity, we will think about width/height in terms of
     37        @ destination.
     38
     39        AND     r7,r0,#6
     40        MOV     r7,r7,LSR #1
     41        AND     r7,r7,#3        @ r7 = Numbr over a multiple of 4 we start on
     42        RSB     r7,r7,#4        @ r7 = Number to do first time.
     43rotate_loop:
     44        CMP     r7,r2
     45        MOVGT   r7,r2           @ r7 = width to do this time
     46
     47        SUBS    r7,r7,#4        @ r7 = width-4
     48        BLT     thin            @ less than 4 pixels wide
     49        SUB     r8,r4,#6        @ r8 = dstLineStep-6
     50x_loop_4:
     51        @ In this routine we will to copy a 4 pixel wide stripe
     52        ADD     r9,r5,r5,LSL #1 @ r9 = 3*srcPixStep
     53        SUB     r9,r6,r9        @ r9 = srcLineStep-3*srcPixStep
     54        MOV     r7,r3           @ r7 = h
     55y_loop_4:
     56        @ r9 >= 0, so at least 4 to do.
     57        LDRH    r10,[r1],r5     @ r10 = *(src)
     58        LDRH    r11,[r1],r5     @ r11 = *(src+srcPixStep)
     59        LDRH    r12,[r1],r5     @ r12 = *(src+srcPixStep*2)
     60        LDRH    r14,[r1],r9     @ r14 = *(src+srcPixStep*3)  src+=srcLineStep
     61        STRH    r10,[r0],#2     @ *(ptr) = r10
     62        STRH    r11,[r0],#2     @ *(ptr+2) = r11
     63        STRH    r12,[r0],#2     @ *(ptr+4) = r12
     64        STRH    r14,[r0],r8     @ *(ptr+6) = r14    ptr += dstLineStep
     65        SUBS    r7,r7,#1        @ h--
     66        BGT     y_loop_4
     67
     68        MUL     r10,r3,r6
     69        ADD     r1,r1,r5,LSL #2
     70        SUB     r1,r1,r10
     71        MUL     r10,r3,r4
     72        ADD     r0,r0,#8
     73        SUB     r0,r0,r10
     74
     75        SUBS    r2,r2,#4        @ r2 = w -= 4
     76        BEQ     rotate_end      @ if w = 0, none left.
     77        SUBS    r7,r2,#4        @ r7 = w - 4
     78        BGE     x_loop_4        @ if 4 or more left, go back.
     79thin:
     80        MOV     r14,r3          @ r14 = h
     81thin_lp:
     82        ADDS    r7,r7,#2        @ Always do 1. GE => do 2. GT => do 3
     83        BGE     just_2
     84        BGT     just_3
     85
     86        @ Just do a 1 pixel wide stripe. Either the last pixel stripe, or
     87        @ the first pixel stripe to align us.
     88y_loop_1:
     89        LDRH    r10,[r1],r6
     90        SUBS    r14,r14,#1
     91        STRH    r10,[r0],r4
     92        BGT     y_loop_1
     93
     94        MUL     r10,r3,r6       @ How much to step r1 back to undo this line?
     95        ADD     r1,r1,r5        @ Move r1 on by srcPixStep
     96        SUB     r1,r1,r10       @ Move r1 back by amount just added on
     97        MUL     r10,r3,r4       @ How much to step r0 back to undo this line?
     98        ADD     r0,r0,#2        @ Move r0 on by dstPixStep
     99        SUB     r0,r0,r10       @ Move r0 back by amount just added on
     100
     101        SUBS    r2,r2,#1        @ If we havent finished (i.e. we were doing
     102        MOV     r7,r2           @ the first pixel rather than the last one)
     103        BGT     rotate_loop     @ then jump back to do some more
     104rotate_end:
     105        LDMFD   r13!,{r4-r11,PC}
     106
     107just_2:
     108        @ Just do a 2 pixel wide stripe. Either the last stripe, or
     109        @ the first stripe to align us.
     110        SUB     r9,r6,r5        @ r9 = srcLineStep - srcPixStep
     111        SUB     r8,r4,#2        @ r8 = dstLineStep - 2
     112y_loop_2:
     113        LDRH    r10,[r1],r5
     114        LDRH    r11,[r1],r9
     115        SUBS    r14,r14,#1
     116        STRH    r10,[r0],#2
     117        STRH    r11,[r0],r8
     118        BGT     y_loop_2
     119
     120        MUL     r10,r3,r6       @ How much to step r1 back to undo this line?
     121        ADD     r1,r1,r5,LSL #1 @ Move r1 on by srcPixStep*2
     122        SUB     r1,r1,r10       @ Move r1 back by amount just added on
     123        MUL     r10,r3,r4       @ How much to step r0 back to undo this line?
     124        ADD     r0,r0,#4        @ Move r0 on by dstPixStep*2
     125        SUB     r0,r0,r10       @ Move r0 back by amount just added on
     126
     127        SUBS    r2,r2,#2        @ If we havent finished (i.e. we were doing
     128        MOV     r7,r2           @ the first stripe rather than the last one)
     129        BGT     rotate_loop     @ then jump back to do some more
     130
     131        LDMFD   r13!,{r4-r11,PC}
     132just_3:
     133        SUB     r9,r6,r5,LSL #1 @ r9 = srcLineStep - srcPixStep
     134        SUB     r8,r4,#4        @ r8 = dstLineStep - 2
     135y_loop_3:
     136        LDRH    r10,[r1],r5
     137        LDRH    r11,[r1],r5
     138        LDRH    r12,[r1],r9
     139        STRH    r10,[r0],#2
     140        STRH    r11,[r0],#2
     141        STRH    r12,[r0],r8
     142        SUBS    r14,r14,#1
     143        BGT     y_loop_3
     144
     145        MUL     r10,r3,r6       @ How much to step r1 back to undo this line?
     146        ADD     r1,r1,r5        @ Move r1 on by srcPixStep*3
     147        ADD     r1,r1,r5,LSL #1
     148        SUB     r1,r1,r10       @ Move r1 back by amount just added on
     149        MUL     r10,r3,r4       @ How much to step r0 back to undo this line?
     150        ADD     r0,r0,#6        @ Move r0 on by dstPixStep*3
     151        SUB     r0,r0,r10       @ Move r0 back by amount just added on
     152
     153        SUBS    r2,r2,#3        @ If we havent finished (i.e. we were doing
     154        MOV     r7,r2           @ the first stripe rather than the last one)
     155        BGT     rotate_loop     @ then jump back to do some more
     156
     157        LDMFD   r13!,{r4-r11,PC}