Home | History | Annotate | Download | only in opts
      1 /*
      2  * Copyright 2014 The Android Open Source Project
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 
      9 #include "SkBitmapProcState.h"
     10 #include "SkBitmapScaler.h"
     11 #include "SkColorPriv.h"
     12 #include "SkPaint.h"
     13 #include "SkUtils.h"
     14 
     15 static void SI8_D16_nofilter_DX_mips_dsp(const SkBitmapProcState& s,
     16                                          const uint32_t* SK_RESTRICT xy,
     17                                          int count, uint16_t* SK_RESTRICT colors) {
     18     SkASSERT(count > 0 && colors != NULL);
     19     SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask));
     20     SkASSERT(SkPaint::kNone_FilterLevel == s.fFilterLevel);
     21     const uint16_t* SK_RESTRICT table = s.fBitmap->getColorTable()->lock16BitCache();
     22     const uint8_t* SK_RESTRICT srcAddr = (const uint8_t*)s.fBitmap->getPixels();
     23     SkASSERT((unsigned)xy[0] < (unsigned)s.fBitmap->height());
     24     srcAddr = (const uint8_t*)((const char*)srcAddr + xy[0] * s.fBitmap->rowBytes());
     25     uint8_t src;
     26 
     27     if (1 == s.fBitmap->width()) {
     28         src = srcAddr[0];
     29         uint16_t dstValue = table[src];
     30         sk_memset16(colors, dstValue, count);
     31     } else {
     32         int count8;
     33         const uint16_t* SK_RESTRICT xx = (const uint16_t*)(xy + 1);
     34 
     35         __asm__ volatile (
     36             ".set    push                                \n\t"
     37             ".set    noreorder                           \n\t"
     38             ".set    noat                                \n\t"
     39             "sra     %[count8], %[count],      3         \n\t"
     40             "beqz    %[count8], 3f                       \n\t"
     41             " addiu  %[count8], %[count8],     -1        \n\t"
     42         "1:                                              \n\t"
     43             "beqz    %[count8], 2f                       \n\t"
     44             " addiu  %[count8], %[count8],     -1        \n\t"
     45             "pref    0,         16(%[xx])                \n\t"
     46             "lhu     $t0,       0(%[xx])                 \n\t"
     47             "lhu     $t1,       2(%[xx])                 \n\t"
     48             "lhu     $t2,       4(%[xx])                 \n\t"
     49             "lhu     $t3,       6(%[xx])                 \n\t"
     50             "lhu     $t4,       8(%[xx])                 \n\t"
     51             "lhu     $t5,       10(%[xx])                \n\t"
     52             "lhu     $t6,       12(%[xx])                \n\t"
     53             "lhu     $t7,       14(%[xx])                \n\t"
     54             "pref    0,         8(%[srcAddr])            \n\t"
     55             "lbux    $t0,       $t0(%[srcAddr])          \n\t"
     56             "lbux    $t1,       $t1(%[srcAddr])          \n\t"
     57             "lbux    $t2,       $t2(%[srcAddr])          \n\t"
     58             "lbux    $t3,       $t3(%[srcAddr])          \n\t"
     59             "lbux    $t4,       $t4(%[srcAddr])          \n\t"
     60             "lbux    $t5,       $t5(%[srcAddr])          \n\t"
     61             "lbux    $t6,       $t6(%[srcAddr])          \n\t"
     62             "lbux    $t7,       $t7(%[srcAddr])          \n\t"
     63             "addu    $t0,       $t0,           $t0       \n\t"
     64             "addu    $t1,       $t1,           $t1       \n\t"
     65             "addu    $t2,       $t2,           $t2       \n\t"
     66             "addu    $t3,       $t3,           $t3       \n\t"
     67             "addu    $t4,       $t4,           $t4       \n\t"
     68             "addu    $t5,       $t5,           $t5       \n\t"
     69             "addu    $t6,       $t6,           $t6       \n\t"
     70             "addu    $t7,       $t7,           $t7       \n\t"
     71             "pref    0,         16(%[table])             \n\t"
     72             "lhx     $t0,       $t0(%[table])            \n\t"
     73             "lhx     $t1,       $t1(%[table])            \n\t"
     74             "lhx     $t2,       $t2(%[table])            \n\t"
     75             "lhx     $t3,       $t3(%[table])            \n\t"
     76             "lhx     $t4,       $t4(%[table])            \n\t"
     77             "lhx     $t5,       $t5(%[table])            \n\t"
     78             "lhx     $t6,       $t6(%[table])            \n\t"
     79             "lhx     $t7,       $t7(%[table])            \n\t"
     80             "sh      $t0,       0(%[colors])             \n\t"
     81             "sh      $t1,       2(%[colors])             \n\t"
     82             "sh      $t2,       4(%[colors])             \n\t"
     83             "sh      $t3,       6(%[colors])             \n\t"
     84             "sh      $t4,       8(%[colors])             \n\t"
     85             "sh      $t5,       10(%[colors])            \n\t"
     86             "sh      $t6,       12(%[colors])            \n\t"
     87             "sh      $t7,       14(%[colors])            \n\t"
     88             "addiu   %[xx],     %[xx],         16        \n\t"
     89             "bgtz    %[count8], 1b                       \n\t"
     90             " addiu  %[colors], %[colors],     16        \n\t"
     91         "2:                                              \n\t"
     92             "lhu     $t0,       0(%[xx])                 \n\t"
     93             "lhu     $t1,       2(%[xx])                 \n\t"
     94             "lhu     $t2,       4(%[xx])                 \n\t"
     95             "lhu     $t3,       6(%[xx])                 \n\t"
     96             "lhu     $t4,       8(%[xx])                 \n\t"
     97             "lhu     $t5,       10(%[xx])                \n\t"
     98             "lhu     $t6,       12(%[xx])                \n\t"
     99             "lhu     $t7,       14(%[xx])                \n\t"
    100             "lbux    $t0,       $t0(%[srcAddr])          \n\t"
    101             "lbux    $t1,       $t1(%[srcAddr])          \n\t"
    102             "lbux    $t2,       $t2(%[srcAddr])          \n\t"
    103             "lbux    $t3,       $t3(%[srcAddr])          \n\t"
    104             "lbux    $t4,       $t4(%[srcAddr])          \n\t"
    105             "lbux    $t5,       $t5(%[srcAddr])          \n\t"
    106             "lbux    $t6,       $t6(%[srcAddr])          \n\t"
    107             "lbux    $t7,       $t7(%[srcAddr])          \n\t"
    108             "addu    $t0,       $t0,           $t0       \n\t"
    109             "addu    $t1,       $t1,           $t1       \n\t"
    110             "addu    $t2,       $t2,           $t2       \n\t"
    111             "addu    $t3,       $t3,           $t3       \n\t"
    112             "addu    $t4,       $t4,           $t4       \n\t"
    113             "addu    $t5,       $t5,           $t5       \n\t"
    114             "addu    $t6,       $t6,           $t6       \n\t"
    115             "addu    $t7,       $t7,           $t7       \n\t"
    116             "lhx     $t0,       $t0(%[table])            \n\t"
    117             "lhx     $t1,       $t1(%[table])            \n\t"
    118             "lhx     $t2,       $t2(%[table])            \n\t"
    119             "lhx     $t3,       $t3(%[table])            \n\t"
    120             "lhx     $t4,       $t4(%[table])            \n\t"
    121             "lhx     $t5,       $t5(%[table])            \n\t"
    122             "lhx     $t6,       $t6(%[table])            \n\t"
    123             "lhx     $t7,       $t7(%[table])            \n\t"
    124             "sh      $t0,       0(%[colors])             \n\t"
    125             "sh      $t1,       2(%[colors])             \n\t"
    126             "sh      $t2,       4(%[colors])             \n\t"
    127             "sh      $t3,       6(%[colors])             \n\t"
    128             "sh      $t4,       8(%[colors])             \n\t"
    129             "sh      $t5,       10(%[colors])            \n\t"
    130             "sh      $t6,       12(%[colors])            \n\t"
    131             "sh      $t7,       14(%[colors])            \n\t"
    132             "addiu   %[xx],     %[xx],         16        \n\t"
    133             "addiu   %[colors], %[colors],     16        \n\t"
    134         "3:                                              \n\t"
    135             ".set    pop                                 \n\t"
    136             : [xx]"+r"(xx), [count8]"=&r"(count8), [colors]"+r"(colors)
    137             : [table]"r"(table), [srcAddr]"r"(srcAddr), [count]"r"(count)
    138             : "memory","t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"
    139         );
    140 
    141         for (int i = (count & 7); i > 0; --i) {
    142             src = srcAddr[*xx++]; *colors++ = table[src];
    143         }
    144     }
    145     s.fBitmap->getColorTable()->unlock16BitCache();
    146 }
    147 
    148 static void SI8_opaque_D32_nofilter_DX_mips_dsp(const SkBitmapProcState& s,
    149                                                 const uint32_t* SK_RESTRICT xy,
    150                                                 int count, SkPMColor* SK_RESTRICT colors) {
    151     SkASSERT(count > 0 && colors != NULL);
    152     SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask));
    153     SkASSERT(SkPaint::kNone_FilterLevel == s.fFilterLevel);
    154     const SkPMColor* SK_RESTRICT table = s.fBitmap->getColorTable()->lockColors();
    155     const uint8_t* SK_RESTRICT srcAddr = (const uint8_t*)s.fBitmap->getPixels();
    156     srcAddr = (const uint8_t*)((const char*)srcAddr + xy[0] * s.fBitmap->rowBytes());
    157 
    158     if (1 == s.fBitmap->width()) {
    159         uint8_t src = srcAddr[0];
    160         SkPMColor dstValue = table[src];
    161         sk_memset32(colors, dstValue, count);
    162     } else {
    163         const uint16_t* xx = (const uint16_t*)(xy + 1);
    164         int s0, s1, s2, s3, s4, s5, s6, s7;
    165         __asm__ volatile (
    166             ".set    push                                \n\t"
    167             ".set    noreorder                           \n\t"
    168             ".set    noat                                \n\t"
    169             "srl     $t8,       %[count],    4           \n\t"
    170             "beqz    $t8,       3f                       \n\t"
    171             " nop                                        \n\t"
    172         "1:                                              \n\t"
    173             "addiu   $t8,       $t8,         -1          \n\t"
    174             "beqz    $t8,       2f                       \n\t"
    175             " addiu  %[count],  %[count],    -16         \n\t"
    176             "pref    0,         32(%[xx])                \n\t"
    177             "lhu     $t0,       0(%[xx])                 \n\t"
    178             "lhu     $t1,       2(%[xx])                 \n\t"
    179             "lhu     $t2,       4(%[xx])                 \n\t"
    180             "lhu     $t3,       6(%[xx])                 \n\t"
    181             "lhu     $t4,       8(%[xx])                 \n\t"
    182             "lhu     $t5,       10(%[xx])                \n\t"
    183             "lhu     $t6,       12(%[xx])                \n\t"
    184             "lhu     $t7,       14(%[xx])                \n\t"
    185             "lhu     %[s0],     16(%[xx])                \n\t"
    186             "lhu     %[s1],     18(%[xx])                \n\t"
    187             "lhu     %[s2],     20(%[xx])                \n\t"
    188             "lhu     %[s3],     22(%[xx])                \n\t"
    189             "lhu     %[s4],     24(%[xx])                \n\t"
    190             "lhu     %[s5],     26(%[xx])                \n\t"
    191             "lhu     %[s6],     28(%[xx])                \n\t"
    192             "lhu     %[s7],     30(%[xx])                \n\t"
    193             "lbux    $t0,       $t0(%[srcAddr])          \n\t"
    194             "lbux    $t1,       $t1(%[srcAddr])          \n\t"
    195             "lbux    $t2,       $t2(%[srcAddr])          \n\t"
    196             "lbux    $t3,       $t3(%[srcAddr])          \n\t"
    197             "lbux    $t4,       $t4(%[srcAddr])          \n\t"
    198             "lbux    $t5,       $t5(%[srcAddr])          \n\t"
    199             "lbux    $t6,       $t6(%[srcAddr])          \n\t"
    200             "lbux    $t7,       $t7(%[srcAddr])          \n\t"
    201             "lbux    %[s0],     %[s0](%[srcAddr])        \n\t"
    202             "lbux    %[s1],     %[s1](%[srcAddr])        \n\t"
    203             "lbux    %[s2],     %[s2](%[srcAddr])        \n\t"
    204             "lbux    %[s3],     %[s3](%[srcAddr])        \n\t"
    205             "lbux    %[s4],     %[s4](%[srcAddr])        \n\t"
    206             "lbux    %[s5],     %[s5](%[srcAddr])        \n\t"
    207             "lbux    %[s6],     %[s6](%[srcAddr])        \n\t"
    208             "lbux    %[s7],     %[s7](%[srcAddr])        \n\t"
    209             "sll     $t0,       $t0,         2           \n\t"
    210             "sll     $t1,       $t1,         2           \n\t"
    211             "sll     $t2,       $t2,         2           \n\t"
    212             "sll     $t3,       $t3,         2           \n\t"
    213             "sll     $t4,       $t4,         2           \n\t"
    214             "sll     $t5,       $t5,         2           \n\t"
    215             "sll     $t6,       $t6,         2           \n\t"
    216             "sll     $t7,       $t7,         2           \n\t"
    217             "sll     %[s0],     %[s0],       2           \n\t"
    218             "sll     %[s1],     %[s1],       2           \n\t"
    219             "sll     %[s2],     %[s2],       2           \n\t"
    220             "sll     %[s3],     %[s3],       2           \n\t"
    221             "sll     %[s4],     %[s4],       2           \n\t"
    222             "sll     %[s5],     %[s5],       2           \n\t"
    223             "sll     %[s6],     %[s6],       2           \n\t"
    224             "sll     %[s7],     %[s7],       2           \n\t"
    225             "pref    0,         64(%[table])             \n\t"
    226             "lwx     $t0,       $t0(%[table])            \n\t"
    227             "lwx     $t1,       $t1(%[table])            \n\t"
    228             "lwx     $t2,       $t2(%[table])            \n\t"
    229             "lwx     $t3,       $t3(%[table])            \n\t"
    230             "lwx     $t4,       $t4(%[table])            \n\t"
    231             "lwx     $t5,       $t5(%[table])            \n\t"
    232             "lwx     $t6,       $t6(%[table])            \n\t"
    233             "lwx     $t7,       $t7(%[table])            \n\t"
    234             "lwx     %[s0],     %[s0](%[table])          \n\t"
    235             "lwx     %[s1],     %[s1](%[table])          \n\t"
    236             "lwx     %[s2],     %[s2](%[table])          \n\t"
    237             "lwx     %[s3],     %[s3](%[table])          \n\t"
    238             "lwx     %[s4],     %[s4](%[table])          \n\t"
    239             "lwx     %[s5],     %[s5](%[table])          \n\t"
    240             "lwx     %[s6],     %[s6](%[table])          \n\t"
    241             "lwx     %[s7],     %[s7](%[table])          \n\t"
    242             "pref    30,        64(%[colors])            \n\t"
    243             "sw      $t0,       0(%[colors])             \n\t"
    244             "sw      $t1,       4(%[colors])             \n\t"
    245             "sw      $t2,       8(%[colors])             \n\t"
    246             "sw      $t3,       12(%[colors])            \n\t"
    247             "sw      $t4,       16(%[colors])            \n\t"
    248             "sw      $t5,       20(%[colors])            \n\t"
    249             "sw      $t6,       24(%[colors])            \n\t"
    250             "sw      $t7,       28(%[colors])            \n\t"
    251             "sw      %[s0],     32(%[colors])            \n\t"
    252             "sw      %[s1],     36(%[colors])            \n\t"
    253             "sw      %[s2],     40(%[colors])            \n\t"
    254             "sw      %[s3],     44(%[colors])            \n\t"
    255             "sw      %[s4],     48(%[colors])            \n\t"
    256             "sw      %[s5],     52(%[colors])            \n\t"
    257             "sw      %[s6],     56(%[colors])            \n\t"
    258             "sw      %[s7],     60(%[colors])            \n\t"
    259             "addiu   %[xx],     %[xx],       32          \n\t"
    260             "b       1b                                  \n\t"
    261             " addiu  %[colors], %[colors],   64          \n\t"
    262         "2:                                              \n\t"
    263             "lhu     $t0,       0(%[xx])                 \n\t"
    264             "lhu     $t1,       2(%[xx])                 \n\t"
    265             "lhu     $t2,       4(%[xx])                 \n\t"
    266             "lhu     $t3,       6(%[xx])                 \n\t"
    267             "lhu     $t4,       8(%[xx])                 \n\t"
    268             "lhu     $t5,       10(%[xx])                \n\t"
    269             "lhu     $t6,       12(%[xx])                \n\t"
    270             "lhu     $t7,       14(%[xx])                \n\t"
    271             "lhu     %[s0],     16(%[xx])                \n\t"
    272             "lhu     %[s1],     18(%[xx])                \n\t"
    273             "lhu     %[s2],     20(%[xx])                \n\t"
    274             "lhu     %[s3],     22(%[xx])                \n\t"
    275             "lhu     %[s4],     24(%[xx])                \n\t"
    276             "lhu     %[s5],     26(%[xx])                \n\t"
    277             "lhu     %[s6],     28(%[xx])                \n\t"
    278             "lhu     %[s7],     30(%[xx])                \n\t"
    279             "lbux    $t0,       $t0(%[srcAddr])          \n\t"
    280             "lbux    $t1,       $t1(%[srcAddr])          \n\t"
    281             "lbux    $t2,       $t2(%[srcAddr])          \n\t"
    282             "lbux    $t3,       $t3(%[srcAddr])          \n\t"
    283             "lbux    $t4,       $t4(%[srcAddr])          \n\t"
    284             "lbux    $t5,       $t5(%[srcAddr])          \n\t"
    285             "lbux    $t6,       $t6(%[srcAddr])          \n\t"
    286             "lbux    $t7,       $t7(%[srcAddr])          \n\t"
    287             "lbux    %[s0],     %[s0](%[srcAddr])        \n\t"
    288             "lbux    %[s1],     %[s1](%[srcAddr])        \n\t"
    289             "lbux    %[s2],     %[s2](%[srcAddr])        \n\t"
    290             "lbux    %[s3],     %[s3](%[srcAddr])        \n\t"
    291             "lbux    %[s4],     %[s4](%[srcAddr])        \n\t"
    292             "lbux    %[s5],     %[s5](%[srcAddr])        \n\t"
    293             "lbux    %[s6],     %[s6](%[srcAddr])        \n\t"
    294             "lbux    %[s7],     %[s7](%[srcAddr])        \n\t"
    295             "sll     $t0,       $t0,         2           \n\t"
    296             "sll     $t1,       $t1,         2           \n\t"
    297             "sll     $t2,       $t2,         2           \n\t"
    298             "sll     $t3,       $t3,         2           \n\t"
    299             "sll     $t4,       $t4,         2           \n\t"
    300             "sll     $t5,       $t5,         2           \n\t"
    301             "sll     $t6,       $t6,         2           \n\t"
    302             "sll     $t7,       $t7,         2           \n\t"
    303             "sll     %[s0],     %[s0],       2           \n\t"
    304             "sll     %[s1],     %[s1],       2           \n\t"
    305             "sll     %[s2],     %[s2],       2           \n\t"
    306             "sll     %[s3],     %[s3],       2           \n\t"
    307             "sll     %[s4],     %[s4],       2           \n\t"
    308             "sll     %[s5],     %[s5],       2           \n\t"
    309             "sll     %[s6],     %[s6],       2           \n\t"
    310             "sll     %[s7],     %[s7],       2           \n\t"
    311             "lwx     $t0,       $t0(%[table])            \n\t"
    312             "lwx     $t1,       $t1(%[table])            \n\t"
    313             "lwx     $t2,       $t2(%[table])            \n\t"
    314             "lwx     $t3,       $t3(%[table])            \n\t"
    315             "lwx     $t4,       $t4(%[table])            \n\t"
    316             "lwx     $t5,       $t5(%[table])            \n\t"
    317             "lwx     $t6,       $t6(%[table])            \n\t"
    318             "lwx     $t7,       $t7(%[table])            \n\t"
    319             "lwx     %[s0],     %[s0](%[table])          \n\t"
    320             "lwx     %[s1],     %[s1](%[table])          \n\t"
    321             "lwx     %[s2],     %[s2](%[table])          \n\t"
    322             "lwx     %[s3],     %[s3](%[table])          \n\t"
    323             "lwx     %[s4],     %[s4](%[table])          \n\t"
    324             "lwx     %[s5],     %[s5](%[table])          \n\t"
    325             "lwx     %[s6],     %[s6](%[table])          \n\t"
    326             "lwx     %[s7],     %[s7](%[table])          \n\t"
    327             "sw      $t0,       0(%[colors])             \n\t"
    328             "sw      $t1,       4(%[colors])             \n\t"
    329             "sw      $t2,       8(%[colors])             \n\t"
    330             "sw      $t3,       12(%[colors])            \n\t"
    331             "sw      $t4,       16(%[colors])            \n\t"
    332             "sw      $t5,       20(%[colors])            \n\t"
    333             "sw      $t6,       24(%[colors])            \n\t"
    334             "sw      $t7,       28(%[colors])            \n\t"
    335             "sw      %[s0],     32(%[colors])            \n\t"
    336             "sw      %[s1],     36(%[colors])            \n\t"
    337             "sw      %[s2],     40(%[colors])            \n\t"
    338             "sw      %[s3],     44(%[colors])            \n\t"
    339             "sw      %[s4],     48(%[colors])            \n\t"
    340             "sw      %[s5],     52(%[colors])            \n\t"
    341             "sw      %[s6],     56(%[colors])            \n\t"
    342             "sw      %[s7],     60(%[colors])            \n\t"
    343             "addiu   %[xx],     %[xx],       32          \n\t"
    344             "beqz    %[count],  4f                       \n\t"
    345             " addiu  %[colors], %[colors],   64          \n\t"
    346         "3:                                              \n\t"
    347             "addiu   %[count],  %[count],    -1          \n\t"
    348             "lhu     $t0,       0(%[xx])                 \n\t"
    349             "lbux    $t1,       $t0(%[srcAddr])          \n\t"
    350             "sll     $t1,       $t1,         2           \n\t"
    351             "lwx     $t2,       $t1(%[table])            \n\t"
    352             "sw      $t2,       0(%[colors])             \n\t"
    353             "addiu   %[xx],     %[xx],       2           \n\t"
    354             "bnez    %[count],  3b                       \n\t"
    355             " addiu  %[colors], %[colors],   4           \n\t"
    356         "4:                                              \n\t"
    357             ".set    pop                                 \n\t"
    358             : [xx]"+r"(xx), [count]"+r"(count), [colors]"+r"(colors),
    359               [s0]"=&r"(s0), [s1]"=&r"(s1), [s2]"=&r"(s2), [s3]"=&r"(s3),
    360               [s4]"=&r"(s4), [s5]"=&r"(s5), [s6]"=&r"(s6), [s7]"=&r"(s7)
    361             : [table]"r"(table), [srcAddr]"r"(srcAddr)
    362             : "memory", "t0", "t1", "t2", "t3",
    363               "t4", "t5", "t6", "t7", "t8"
    364         );
    365     }
    366     s.fBitmap->getColorTable()->unlockColors();
    367 }
    368 
    369 /*  If we replace a sampleproc, then we null-out the associated shaderproc,
    370     otherwise the shader won't even look at the matrix/sampler
    371  */
    372 
    373 void SkBitmapProcState::platformProcs() {
    374     bool isOpaque = 256 == fAlphaScale;
    375     bool justDx = false;
    376 
    377     if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
    378         justDx = true;
    379     }
    380 
    381     switch (fBitmap->colorType()) {
    382         case kIndex_8_SkColorType:
    383             if (justDx && SkPaint::kNone_FilterLevel == fFilterLevel) {
    384                 fSampleProc16 = SI8_D16_nofilter_DX_mips_dsp;
    385                 fShaderProc16 = NULL;
    386                 if (isOpaque) {
    387                     fSampleProc32 = SI8_opaque_D32_nofilter_DX_mips_dsp;
    388                     fShaderProc32 = NULL;
    389                 }
    390             }
    391             break;
    392         default:
    393             break;
    394     }
    395 }
    396 
    397 void SkBitmapScaler::PlatformConvolutionProcs(SkConvolutionProcs*) {}
    398