Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 #include "SkMath.h"
     10 #include "SkMathPriv.h"
     11 
     12 #define SCALE_FILTER_NAME       MAKENAME(_filter_scale)
     13 #define AFFINE_FILTER_NAME      MAKENAME(_filter_affine)
     14 #define PERSP_FILTER_NAME       MAKENAME(_filter_persp)
     15 
     16 #define PACK_FILTER_X_NAME  MAKENAME(_pack_filter_x)
     17 #define PACK_FILTER_Y_NAME  MAKENAME(_pack_filter_y)
     18 
     19 #ifndef PREAMBLE
     20     #define PREAMBLE(state)
     21     #define PREAMBLE_PARAM_X
     22     #define PREAMBLE_PARAM_Y
     23     #define PREAMBLE_ARG_X
     24     #define PREAMBLE_ARG_Y
     25 #endif
     26 
     27 // declare functions externally to suppress warnings.
     28 void SCALE_FILTER_NAME(const SkBitmapProcState& s,
     29                               uint32_t xy[], int count, int x, int y);
     30 void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
     31                                uint32_t xy[], int count, int x, int y);
     32 void PERSP_FILTER_NAME(const SkBitmapProcState& s,
     33                               uint32_t* SK_RESTRICT xy, int count,
     34                               int x, int y);
     35 
     36 static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max,
     37                                           SkFixed one PREAMBLE_PARAM_Y) {
     38     unsigned i = TILEY_PROCF(f, max);
     39     i = (i << 4) | TILEY_LOW_BITS(f, max);
     40     return (i << 14) | (TILEY_PROCF((f + one), max));
     41 }
     42 
     43 static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max,
     44                                           SkFixed one PREAMBLE_PARAM_X) {
     45     unsigned i = TILEX_PROCF(f, max);
     46     i = (i << 4) | TILEX_LOW_BITS(f, max);
     47     return (i << 14) | (TILEX_PROCF((f + one), max));
     48 }
     49 
     50 void SCALE_FILTER_NAME(const SkBitmapProcState& s,
     51                               uint32_t xy[], int count, int x, int y) {
     52     SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
     53                              SkMatrix::kScale_Mask)) == 0);
     54     SkASSERT(s.fInvKy == 0);
     55 
     56     PREAMBLE(s);
     57 
     58     const unsigned maxX = s.fPixmap.width() - 1;
     59     const SkFixed one = s.fFilterOneX;
     60     const SkFractionalInt dx = s.fInvSxFractionalInt;
     61     SkFractionalInt fx;
     62 
     63     {
     64         const SkBitmapProcStateAutoMapper mapper(s, x, y);
     65         const SkFixed fy = mapper.fixedY();
     66         const unsigned maxY = s.fPixmap.height() - 1;
     67         // compute our two Y values up front
     68         *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y);
     69         // now initialize fx
     70         fx = mapper.fractionalIntX();
     71     }
     72 
     73 #ifdef CHECK_FOR_DECAL
     74     if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) {
     75         decal_filter_scale(xy, SkFractionalIntToFixed(fx),
     76                            SkFractionalIntToFixed(dx), count);
     77     } else
     78 #endif
     79     {
     80         do {
     81             SkFixed fixedFx = SkFractionalIntToFixed(fx);
     82             *xy++ = PACK_FILTER_X_NAME(fixedFx, maxX, one PREAMBLE_ARG_X);
     83             fx += dx;
     84         } while (--count != 0);
     85     }
     86 }
     87 
     88 void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
     89                                uint32_t xy[], int count, int x, int y) {
     90     SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
     91     SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
     92                              SkMatrix::kScale_Mask |
     93                              SkMatrix::kAffine_Mask)) == 0);
     94 
     95     PREAMBLE(s);
     96     const SkBitmapProcStateAutoMapper mapper(s, x, y);
     97 
     98     SkFixed oneX = s.fFilterOneX;
     99     SkFixed oneY = s.fFilterOneY;
    100     SkFixed fx = mapper.fixedX();
    101     SkFixed fy = mapper.fixedY();
    102     SkFixed dx = s.fInvSx;
    103     SkFixed dy = s.fInvKy;
    104     unsigned maxX = s.fPixmap.width() - 1;
    105     unsigned maxY = s.fPixmap.height() - 1;
    106 
    107     do {
    108         *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y);
    109         fy += dy;
    110         *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X);
    111         fx += dx;
    112     } while (--count != 0);
    113 }
    114 
    115 void PERSP_FILTER_NAME(const SkBitmapProcState& s,
    116                               uint32_t* SK_RESTRICT xy, int count,
    117                               int x, int y) {
    118     SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask);
    119 
    120     PREAMBLE(s);
    121     unsigned maxX = s.fPixmap.width() - 1;
    122     unsigned maxY = s.fPixmap.height() - 1;
    123     SkFixed oneX = s.fFilterOneX;
    124     SkFixed oneY = s.fFilterOneY;
    125 
    126     SkPerspIter   iter(s.fInvMatrix,
    127                        SkIntToScalar(x) + SK_ScalarHalf,
    128                        SkIntToScalar(y) + SK_ScalarHalf, count);
    129 
    130     while ((count = iter.next()) != 0) {
    131         const SkFixed* SK_RESTRICT srcXY = iter.getXY();
    132         do {
    133             *xy++ = PACK_FILTER_Y_NAME(srcXY[1] - (oneY >> 1), maxY,
    134                                        oneY PREAMBLE_ARG_Y);
    135             *xy++ = PACK_FILTER_X_NAME(srcXY[0] - (oneX >> 1), maxX,
    136                                        oneX PREAMBLE_ARG_X);
    137             srcXY += 2;
    138         } while (--count != 0);
    139     }
    140 }
    141 
    142 #undef MAKENAME
    143 #undef TILEX_PROCF
    144 #undef TILEY_PROCF
    145 #ifdef CHECK_FOR_DECAL
    146     #undef CHECK_FOR_DECAL
    147 #endif
    148 
    149 #undef SCALE_FILTER_NAME
    150 #undef AFFINE_FILTER_NAME
    151 #undef PERSP_FILTER_NAME
    152 
    153 #undef PREAMBLE
    154 #undef PREAMBLE_PARAM_X
    155 #undef PREAMBLE_PARAM_Y
    156 #undef PREAMBLE_ARG_X
    157 #undef PREAMBLE_ARG_Y
    158 
    159 #undef TILEX_LOW_BITS
    160 #undef TILEY_LOW_BITS
    161