Home | History | Annotate | Download | only in skia
      1 Index: sgl/SkBitmapProcState.h
      2 ===================================================================
      3 --- sgl/SkBitmapProcState.h	(revision 42716)
      4 +++ sgl/SkBitmapProcState.h	(working copy)
      5 @@ -39,8 +39,9 @@
      6                                   int count,
      7                                   uint16_t colors[]);
      8      
      9 -    typedef U16CPU (*FixedTileProc)(SkFixed);   // returns 0..0xFFFF
     10 -    
     11 +    typedef SkFixed (*FixedTileProc)(SkFixed, int);
     12 +    typedef int (*IntTileProc)(int, int);
     13 +
     14      MatrixProc          fMatrixProc;        // chooseProcs
     15      SampleProc32        fSampleProc32;      // chooseProcs
     16      SampleProc16        fSampleProc16;      // chooseProcs
     17 @@ -48,6 +49,8 @@
     18      SkMatrix            fUnitInvMatrix;     // chooseProcs
     19      FixedTileProc       fTileProcX;         // chooseProcs
     20      FixedTileProc       fTileProcY;         // chooseProcs
     21 +    IntTileProc         iTileProcX;         // chooseProcs
     22 +    IntTileProc         iTileProcY;         // chooseProcs
     23      SkFixed             fFilterOneX;
     24      SkFixed             fFilterOneY;
     25  
     26 Index: sgl/SkBitmapProcState.cpp
     27 ===================================================================
     28 --- sgl/SkBitmapProcState.cpp	(revision 42716)
     29 +++ sgl/SkBitmapProcState.cpp	(working copy)
     30 @@ -296,8 +296,9 @@
     31      }
     32      const SkMatrix* m;
     33      
     34 -    if (SkShader::kClamp_TileMode == fTileModeX &&
     35 -            SkShader::kClamp_TileMode == fTileModeY) {
     36 +    if (inv.getType() <= SkMatrix::kTranslate_Mask ||
     37 +        (SkShader::kClamp_TileMode == fTileModeX &&
     38 +         SkShader::kClamp_TileMode == fTileModeY)) {
     39          m = &inv;
     40      } else {
     41          fUnitInvMatrix = inv;
     42 @@ -330,6 +331,16 @@
     43      fInvMatrix      = m;
     44      fInvProc        = m->getMapXYProc();
     45      fInvType        = m->getType();
     46 +    if (fInvType <= SkMatrix::kTranslate_Mask &&
     47 +        inv.getType() > SkMatrix::kTranslate_Mask) {
     48 +      SkASSERT(inv.getType() <=
     49 +               (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask));
     50 +      // It is possible that by the calculation of fUnitInvMatrix, we have
     51 +      // eliminated the scale transformation of the matrix (e.g., if inv^(-1)
     52 +      // scales fOrigBitmap into an 1X1 rect). We add the scale flag back so
     53 +      // that we don't make wrong choice in chooseMatrixProc().
     54 +      fInvType |= SkMatrix::kScale_Mask;
     55 +    }
     56      fInvSx          = SkScalarToFixed(m->getScaleX());
     57      fInvSy          = SkScalarToFixed(m->getScaleY());
     58      fInvKy          = SkScalarToFixed(m->getSkewY());
     59 Index: sgl/SkBitmapProcState_matrix.h
     60 ===================================================================
     61 --- sgl/SkBitmapProcState_matrix.h	(revision 42716)
     62 +++ sgl/SkBitmapProcState_matrix.h	(working copy)
     63 @@ -1,4 +1,5 @@
     64  
     65 +#define TRANSLATE_NOFILTER_NAME MAKENAME(_nofilter_translate)
     66  #define SCALE_NOFILTER_NAME     MAKENAME(_nofilter_scale)
     67  #define SCALE_FILTER_NAME       MAKENAME(_filter_scale)
     68  #define AFFINE_NOFILTER_NAME    MAKENAME(_nofilter_affine)
     69 @@ -17,6 +18,38 @@
     70      #define PREAMBLE_ARG_Y
     71  #endif
     72  
     73 +#ifndef PREAMBLE_TRANS
     74 +    #define PREAMBLE_TRANS(state)
     75 +#endif
     76 +
     77 +static void TRANSLATE_NOFILTER_NAME(const SkBitmapProcState& s,
     78 +                                    uint32_t xy[], int count, int x, int y)
     79 +{
     80 +    SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0);
     81 +
     82 +    PREAMBLE_TRANS(s);
     83 +
     84 +    x += SkScalarFloor(s.fInvMatrix->getTranslateX());
     85 +    y += SkScalarFloor(s.fInvMatrix->getTranslateY());
     86 +
     87 +    *xy++ = (uint32_t)TILEY_TRANS(y, (s.fBitmap->height() - 1));
     88 +    
     89 +    int maxX = s.fBitmap->width() - 1;
     90 +    int i;
     91 +    uint16_t* xx = (uint16_t*)xy;
     92 +    for (i = (count >> 2); i > 0; --i)
     93 +    {
     94 +        *xx++ = (uint16_t)TILEX_TRANS(x, maxX); x++;
     95 +        *xx++ = (uint16_t)TILEX_TRANS(x, maxX); x++;
     96 +        *xx++ = (uint16_t)TILEX_TRANS(x, maxX); x++;
     97 +        *xx++ = (uint16_t)TILEX_TRANS(x, maxX); x++;
     98 +    }
     99 +    for (i = (count & 3); i > 0; --i)
    100 +    {
    101 +        *xx++ = (uint16_t)TILEX_TRANS(x, maxX); x++;
    102 +    }
    103 +}
    104 +
    105  static void SCALE_NOFILTER_NAME(const SkBitmapProcState& s,
    106                                  uint32_t xy[], int count, int x, int y) {
    107      SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
    108 @@ -206,9 +239,9 @@
    109      unsigned maxY = s.fBitmap->height() - 1;
    110      
    111      do {
    112 -        *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneX PREAMBLE_ARG_Y);
    113 +        *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y);
    114          fy += dy;
    115 -        *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneY PREAMBLE_ARG_X);
    116 +        *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X);
    117          fx += dx;
    118      } while (--count != 0);
    119  }
    120 @@ -241,6 +274,9 @@
    121  }
    122  
    123  static SkBitmapProcState::MatrixProc MAKENAME(_Procs)[] = {
    124 +    TRANSLATE_NOFILTER_NAME,
    125 +    TRANSLATE_NOFILTER_NAME,    // No need to do filtering if the matrix is no
    126 +                                // more complex than identity/translate.
    127      SCALE_NOFILTER_NAME,
    128      SCALE_FILTER_NAME,
    129      AFFINE_NOFILTER_NAME,
    130 @@ -255,7 +291,10 @@
    131  #ifdef CHECK_FOR_DECAL
    132      #undef CHECK_FOR_DECAL
    133  #endif
    134 -
    135 +#undef TILEX_TRANS
    136 +#undef TILEY_TRANS
    137 + 
    138 +#undef TRANSLATE_NOFILTER_NAME
    139  #undef SCALE_NOFILTER_NAME
    140  #undef SCALE_FILTER_NAME
    141  #undef AFFINE_NOFILTER_NAME
    142 @@ -268,6 +307,7 @@
    143  #undef PREAMBLE_PARAM_Y
    144  #undef PREAMBLE_ARG_X
    145  #undef PREAMBLE_ARG_Y
    146 +#undef PREAMBLE_TRANS
    147  
    148  #undef TILEX_LOW_BITS
    149  #undef TILEY_LOW_BITS
    150 Index: sgl/SkBitmapProcState_matrixProcs.cpp
    151 ===================================================================
    152 --- sgl/SkBitmapProcState_matrixProcs.cpp	(revision 42716)
    153 +++ sgl/SkBitmapProcState_matrixProcs.cpp	(working copy)
    154 @@ -28,6 +28,8 @@
    155  #define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF)
    156  #define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF)
    157  #define CHECK_FOR_DECAL
    158 +#define TILEX_TRANS(x, max)     SkClampMax(x, max)
    159 +#define TILEY_TRANS(y, max)     SkClampMax(y, max)
    160  #include "SkBitmapProcState_matrix.h"
    161  
    162  #define MAKENAME(suffix)        RepeatX_RepeatY ## suffix
    163 @@ -35,6 +37,9 @@
    164  #define TILEY_PROCF(fy, max)    (((fy) & 0xFFFF) * ((max) + 1) >> 16)
    165  #define TILEX_LOW_BITS(fx, max) ((((fx) & 0xFFFF) * ((max) + 1) >> 12) & 0xF)
    166  #define TILEY_LOW_BITS(fy, max) ((((fy) & 0xFFFF) * ((max) + 1) >> 12) & 0xF)
    167 +#define REAL_MOD(val, modulus)  (((val)%(modulus)) + (modulus)*( (val)<0 ))
    168 +#define TILEX_TRANS(x, max)     (REAL_MOD((x), ((max) + 1)))
    169 +#define TILEY_TRANS(y, max)     (REAL_MOD((y), ((max) + 1)))
    170  #include "SkBitmapProcState_matrix.h"
    171  
    172  #define MAKENAME(suffix)        GeneralXY ## suffix
    173 @@ -44,13 +49,17 @@
    174  #define PREAMBLE_PARAM_Y        , SkBitmapProcState::FixedTileProc tileProcY
    175  #define PREAMBLE_ARG_X          , tileProcX
    176  #define PREAMBLE_ARG_Y          , tileProcY
    177 -#define TILEX_PROCF(fx, max)    (tileProcX(fx) * ((max) + 1) >> 16)
    178 -#define TILEY_PROCF(fy, max)    (tileProcY(fy) * ((max) + 1) >> 16)
    179 -#define TILEX_LOW_BITS(fx, max) ((tileProcX(fx) * ((max) + 1) >> 12) & 0xF)
    180 -#define TILEY_LOW_BITS(fy, max) ((tileProcY(fy) * ((max) + 1) >> 12) & 0xF)
    181 +#define TILEX_PROCF(fx, max)    (tileProcX(fx, max) >> 16)
    182 +#define TILEY_PROCF(fy, max)    (tileProcY(fy, max) >> 16)
    183 +#define TILEX_LOW_BITS(fx, max) ((tileProcX(fx, max) >> 14) & 0x3)
    184 +#define TILEY_LOW_BITS(fy, max) ((tileProcY(fy, max) >> 14) & 0x3)
    185 +#define PREAMBLE_TRANS(state)   SkBitmapProcState::IntTileProc tileProcX = (state).iTileProcX; \
    186 +                                SkBitmapProcState::IntTileProc tileProcY = (state).iTileProcY
    187 +#define TILEX_TRANS(x, max)     tileProcX(x, max)
    188 +#define TILEY_TRANS(y, max)     tileProcY(y, max)
    189  #include "SkBitmapProcState_matrix.h"
    190  
    191 -static inline U16CPU fixed_clamp(SkFixed x)
    192 +static inline SkFixed fixed_clamp(SkFixed x, int max)
    193  {
    194  #ifdef SK_CPU_HAS_CONDITIONAL_INSTR
    195      if (x >> 16)
    196 @@ -66,19 +75,20 @@
    197              x = 0xFFFF;
    198      }
    199  #endif
    200 -    return x;
    201 +    return x * (max + 1);
    202  }
    203  
    204 -static inline U16CPU fixed_repeat(SkFixed x)
    205 +static inline SkFixed fixed_repeat(SkFixed x, int max)
    206  {
    207 -    return x & 0xFFFF;
    208 +    return (x & 0xFFFF) * (max + 1);
    209  }
    210  
    211 -static inline U16CPU fixed_mirror(SkFixed x)
    212 +static inline SkFixed fixed_mirror(SkFixed x, int max)
    213  {
    214      SkFixed s = x << 15 >> 31;
    215      // s is FFFFFFFF if we're on an odd interval, or 0 if an even interval
    216 -    return (x ^ s) & 0xFFFF;
    217 +    x = ((x ^ s) & 0xFFFF) * (max + 1);
    218 +    return s ? (x ^ 0xFFFF) : x;
    219  }
    220  
    221  static SkBitmapProcState::FixedTileProc choose_tile_proc(unsigned m)
    222 @@ -90,15 +100,52 @@
    223      SkASSERT(SkShader::kMirror_TileMode == m);
    224      return fixed_mirror;
    225  }
    226 + 
    227 +static inline int int_clamp(int x, int max)
    228 +{
    229 +    SkASSERT(max >= 0);
    230 +    
    231 +    return SkClampMax(x, max);
    232 +}
    233  
    234 +static inline int int_repeat(int x, int max)
    235 +{
    236 +    SkASSERT(max >= 0);
    237 +
    238 +    return x % (max + 1);
    239 +}
    240 +
    241 +static inline int int_mirror(int x, int max)
    242 +{
    243 +    SkASSERT(max >= 0);
    244 +
    245 +    int dx = x % (max + 1);
    246 +    if (dx < 0)
    247 +        dx = -dx - 1;
    248 +    
    249 +    return (x / (max + 1) % 2) ? max - dx : dx;
    250 +}
    251 +
    252 +static SkBitmapProcState::IntTileProc choose_int_tile_proc(unsigned m)
    253 +{
    254 +    if (SkShader::kClamp_TileMode == m)
    255 +        return int_clamp;
    256 +    if (SkShader::kRepeat_TileMode == m)
    257 +        return int_repeat;
    258 +    SkASSERT(SkShader::kMirror_TileMode == m);
    259 +    return int_mirror;
    260 +}
    261 +
    262  SkBitmapProcState::MatrixProc SkBitmapProcState::chooseMatrixProc()
    263  {
    264      int index = 0;
    265      if (fDoFilter)
    266          index = 1;
    267      if (fInvType & SkMatrix::kPerspective_Mask)
    268 +        index |= 6;
    269 +    else if (fInvType & SkMatrix::kAffine_Mask)
    270          index |= 4;
    271 -    else if (fInvType & SkMatrix::kAffine_Mask)
    272 +    else if (fInvType & SkMatrix::kScale_Mask)
    273          index |= 2;
    274  
    275      if (SkShader::kClamp_TileMode == fTileModeX &&
    276 @@ -123,6 +170,8 @@
    277      // only general needs these procs
    278      fTileProcX = choose_tile_proc(fTileModeX);
    279      fTileProcY = choose_tile_proc(fTileModeY);
    280 +    iTileProcX = choose_int_tile_proc(fTileModeX);
    281 +    iTileProcY = choose_int_tile_proc(fTileModeY);
    282      return GeneralXY_Procs[index];
    283  }
    284  
    285