gfx/skia/trunk/src/core/SkBitmapProcState_matrix.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/core/SkBitmapProcState_matrix.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,303 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2011 Google Inc.
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +#include "SkMath.h"
    1.13 +#include "SkMathPriv.h"
    1.14 +
    1.15 +#define SCALE_NOFILTER_NAME     MAKENAME(_nofilter_scale)
    1.16 +#define SCALE_FILTER_NAME       MAKENAME(_filter_scale)
    1.17 +#define AFFINE_NOFILTER_NAME    MAKENAME(_nofilter_affine)
    1.18 +#define AFFINE_FILTER_NAME      MAKENAME(_filter_affine)
    1.19 +#define PERSP_NOFILTER_NAME     MAKENAME(_nofilter_persp)
    1.20 +#define PERSP_FILTER_NAME       MAKENAME(_filter_persp)
    1.21 +
    1.22 +#define PACK_FILTER_X_NAME  MAKENAME(_pack_filter_x)
    1.23 +#define PACK_FILTER_Y_NAME  MAKENAME(_pack_filter_y)
    1.24 +
    1.25 +#ifndef PREAMBLE
    1.26 +    #define PREAMBLE(state)
    1.27 +    #define PREAMBLE_PARAM_X
    1.28 +    #define PREAMBLE_PARAM_Y
    1.29 +    #define PREAMBLE_ARG_X
    1.30 +    #define PREAMBLE_ARG_Y
    1.31 +#endif
    1.32 +
    1.33 +// declare functions externally to suppress warnings.
    1.34 +void SCALE_NOFILTER_NAME(const SkBitmapProcState& s,
    1.35 +                                uint32_t xy[], int count, int x, int y);
    1.36 +void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s,
    1.37 +                                 uint32_t xy[], int count, int x, int y);
    1.38 +void PERSP_NOFILTER_NAME(const SkBitmapProcState& s,
    1.39 +                                uint32_t* SK_RESTRICT xy,
    1.40 +                                int count, int x, int y);
    1.41 +void SCALE_FILTER_NAME(const SkBitmapProcState& s,
    1.42 +                              uint32_t xy[], int count, int x, int y);
    1.43 +void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
    1.44 +                               uint32_t xy[], int count, int x, int y);
    1.45 +void PERSP_FILTER_NAME(const SkBitmapProcState& s,
    1.46 +                              uint32_t* SK_RESTRICT xy, int count,
    1.47 +                              int x, int y);
    1.48 +
    1.49 +void SCALE_NOFILTER_NAME(const SkBitmapProcState& s,
    1.50 +                                uint32_t xy[], int count, int x, int y) {
    1.51 +    SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
    1.52 +                             SkMatrix::kScale_Mask)) == 0);
    1.53 +
    1.54 +    PREAMBLE(s);
    1.55 +    // we store y, x, x, x, x, x
    1.56 +
    1.57 +    const unsigned maxX = s.fBitmap->width() - 1;
    1.58 +    SkFractionalInt fx;
    1.59 +    {
    1.60 +        SkPoint pt;
    1.61 +        s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
    1.62 +                                  SkIntToScalar(y) + SK_ScalarHalf, &pt);
    1.63 +        fx = SkScalarToFractionalInt(pt.fY);
    1.64 +        const unsigned maxY = s.fBitmap->height() - 1;
    1.65 +        *xy++ = TILEY_PROCF(SkFractionalIntToFixed(fx), maxY);
    1.66 +        fx = SkScalarToFractionalInt(pt.fX);
    1.67 +    }
    1.68 +
    1.69 +    if (0 == maxX) {
    1.70 +        // all of the following X values must be 0
    1.71 +        memset(xy, 0, count * sizeof(uint16_t));
    1.72 +        return;
    1.73 +    }
    1.74 +
    1.75 +    const SkFractionalInt dx = s.fInvSxFractionalInt;
    1.76 +
    1.77 +#ifdef CHECK_FOR_DECAL
    1.78 +    if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) {
    1.79 +        decal_nofilter_scale(xy, SkFractionalIntToFixed(fx),
    1.80 +                             SkFractionalIntToFixed(dx), count);
    1.81 +    } else
    1.82 +#endif
    1.83 +    {
    1.84 +        int i;
    1.85 +        for (i = (count >> 2); i > 0; --i) {
    1.86 +            unsigned a, b;
    1.87 +            a = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx;
    1.88 +            b = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx;
    1.89 +#ifdef SK_CPU_BENDIAN
    1.90 +            *xy++ = (a << 16) | b;
    1.91 +#else
    1.92 +            *xy++ = (b << 16) | a;
    1.93 +#endif
    1.94 +            a = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx;
    1.95 +            b = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx;
    1.96 +#ifdef SK_CPU_BENDIAN
    1.97 +            *xy++ = (a << 16) | b;
    1.98 +#else
    1.99 +            *xy++ = (b << 16) | a;
   1.100 +#endif
   1.101 +        }
   1.102 +        uint16_t* xx = (uint16_t*)xy;
   1.103 +        for (i = (count & 3); i > 0; --i) {
   1.104 +            *xx++ = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx;
   1.105 +        }
   1.106 +    }
   1.107 +}
   1.108 +
   1.109 +// note: we could special-case on a matrix which is skewed in X but not Y.
   1.110 +// this would require a more general setup thatn SCALE does, but could use
   1.111 +// SCALE's inner loop that only looks at dx
   1.112 +
   1.113 +void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s,
   1.114 +                                 uint32_t xy[], int count, int x, int y) {
   1.115 +    SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
   1.116 +    SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
   1.117 +                             SkMatrix::kScale_Mask |
   1.118 +                             SkMatrix::kAffine_Mask)) == 0);
   1.119 +
   1.120 +    PREAMBLE(s);
   1.121 +    SkPoint srcPt;
   1.122 +    s.fInvProc(s.fInvMatrix,
   1.123 +               SkIntToScalar(x) + SK_ScalarHalf,
   1.124 +               SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
   1.125 +
   1.126 +    SkFractionalInt fx = SkScalarToFractionalInt(srcPt.fX);
   1.127 +    SkFractionalInt fy = SkScalarToFractionalInt(srcPt.fY);
   1.128 +    SkFractionalInt dx = s.fInvSxFractionalInt;
   1.129 +    SkFractionalInt dy = s.fInvKyFractionalInt;
   1.130 +    int maxX = s.fBitmap->width() - 1;
   1.131 +    int maxY = s.fBitmap->height() - 1;
   1.132 +
   1.133 +    for (int i = count; i > 0; --i) {
   1.134 +        *xy++ = (TILEY_PROCF(SkFractionalIntToFixed(fy), maxY) << 16) |
   1.135 +                 TILEX_PROCF(SkFractionalIntToFixed(fx), maxX);
   1.136 +        fx += dx; fy += dy;
   1.137 +    }
   1.138 +}
   1.139 +
   1.140 +void PERSP_NOFILTER_NAME(const SkBitmapProcState& s,
   1.141 +                                uint32_t* SK_RESTRICT xy,
   1.142 +                                int count, int x, int y) {
   1.143 +    SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask);
   1.144 +
   1.145 +    PREAMBLE(s);
   1.146 +    int maxX = s.fBitmap->width() - 1;
   1.147 +    int maxY = s.fBitmap->height() - 1;
   1.148 +
   1.149 +    SkPerspIter   iter(s.fInvMatrix,
   1.150 +                       SkIntToScalar(x) + SK_ScalarHalf,
   1.151 +                       SkIntToScalar(y) + SK_ScalarHalf, count);
   1.152 +
   1.153 +    while ((count = iter.next()) != 0) {
   1.154 +        const SkFixed* SK_RESTRICT srcXY = iter.getXY();
   1.155 +        while (--count >= 0) {
   1.156 +            *xy++ = (TILEY_PROCF(srcXY[1], maxY) << 16) |
   1.157 +                     TILEX_PROCF(srcXY[0], maxX);
   1.158 +            srcXY += 2;
   1.159 +        }
   1.160 +    }
   1.161 +}
   1.162 +
   1.163 +//////////////////////////////////////////////////////////////////////////////
   1.164 +
   1.165 +static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max,
   1.166 +                                          SkFixed one PREAMBLE_PARAM_Y) {
   1.167 +    unsigned i = TILEY_PROCF(f, max);
   1.168 +    i = (i << 4) | TILEY_LOW_BITS(f, max);
   1.169 +    return (i << 14) | (TILEY_PROCF((f + one), max));
   1.170 +}
   1.171 +
   1.172 +static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max,
   1.173 +                                          SkFixed one PREAMBLE_PARAM_X) {
   1.174 +    unsigned i = TILEX_PROCF(f, max);
   1.175 +    i = (i << 4) | TILEX_LOW_BITS(f, max);
   1.176 +    return (i << 14) | (TILEX_PROCF((f + one), max));
   1.177 +}
   1.178 +
   1.179 +void SCALE_FILTER_NAME(const SkBitmapProcState& s,
   1.180 +                              uint32_t xy[], int count, int x, int y) {
   1.181 +    SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
   1.182 +                             SkMatrix::kScale_Mask)) == 0);
   1.183 +    SkASSERT(s.fInvKy == 0);
   1.184 +
   1.185 +    PREAMBLE(s);
   1.186 +
   1.187 +    const unsigned maxX = s.fBitmap->width() - 1;
   1.188 +    const SkFixed one = s.fFilterOneX;
   1.189 +    const SkFractionalInt dx = s.fInvSxFractionalInt;
   1.190 +    SkFractionalInt fx;
   1.191 +
   1.192 +    {
   1.193 +        SkPoint pt;
   1.194 +        s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
   1.195 +                                  SkIntToScalar(y) + SK_ScalarHalf, &pt);
   1.196 +        const SkFixed fy = SkScalarToFixed(pt.fY) - (s.fFilterOneY >> 1);
   1.197 +        const unsigned maxY = s.fBitmap->height() - 1;
   1.198 +        // compute our two Y values up front
   1.199 +        *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y);
   1.200 +        // now initialize fx
   1.201 +        fx = SkScalarToFractionalInt(pt.fX) - (SkFixedToFractionalInt(one) >> 1);
   1.202 +    }
   1.203 +
   1.204 +#ifdef CHECK_FOR_DECAL
   1.205 +    if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) {
   1.206 +        decal_filter_scale(xy, SkFractionalIntToFixed(fx),
   1.207 +                           SkFractionalIntToFixed(dx), count);
   1.208 +    } else
   1.209 +#endif
   1.210 +    {
   1.211 +        do {
   1.212 +            SkFixed fixedFx = SkFractionalIntToFixed(fx);
   1.213 +            *xy++ = PACK_FILTER_X_NAME(fixedFx, maxX, one PREAMBLE_ARG_X);
   1.214 +            fx += dx;
   1.215 +        } while (--count != 0);
   1.216 +    }
   1.217 +}
   1.218 +
   1.219 +void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
   1.220 +                               uint32_t xy[], int count, int x, int y) {
   1.221 +    SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
   1.222 +    SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
   1.223 +                             SkMatrix::kScale_Mask |
   1.224 +                             SkMatrix::kAffine_Mask)) == 0);
   1.225 +
   1.226 +    PREAMBLE(s);
   1.227 +    SkPoint srcPt;
   1.228 +    s.fInvProc(s.fInvMatrix,
   1.229 +               SkIntToScalar(x) + SK_ScalarHalf,
   1.230 +               SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
   1.231 +
   1.232 +    SkFixed oneX = s.fFilterOneX;
   1.233 +    SkFixed oneY = s.fFilterOneY;
   1.234 +    SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1);
   1.235 +    SkFixed fy = SkScalarToFixed(srcPt.fY) - (oneY >> 1);
   1.236 +    SkFixed dx = s.fInvSx;
   1.237 +    SkFixed dy = s.fInvKy;
   1.238 +    unsigned maxX = s.fBitmap->width() - 1;
   1.239 +    unsigned maxY = s.fBitmap->height() - 1;
   1.240 +
   1.241 +    do {
   1.242 +        *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y);
   1.243 +        fy += dy;
   1.244 +        *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X);
   1.245 +        fx += dx;
   1.246 +    } while (--count != 0);
   1.247 +}
   1.248 +
   1.249 +void PERSP_FILTER_NAME(const SkBitmapProcState& s,
   1.250 +                              uint32_t* SK_RESTRICT xy, int count,
   1.251 +                              int x, int y) {
   1.252 +    SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask);
   1.253 +
   1.254 +    PREAMBLE(s);
   1.255 +    unsigned maxX = s.fBitmap->width() - 1;
   1.256 +    unsigned maxY = s.fBitmap->height() - 1;
   1.257 +    SkFixed oneX = s.fFilterOneX;
   1.258 +    SkFixed oneY = s.fFilterOneY;
   1.259 +
   1.260 +    SkPerspIter   iter(s.fInvMatrix,
   1.261 +                       SkIntToScalar(x) + SK_ScalarHalf,
   1.262 +                       SkIntToScalar(y) + SK_ScalarHalf, count);
   1.263 +
   1.264 +    while ((count = iter.next()) != 0) {
   1.265 +        const SkFixed* SK_RESTRICT srcXY = iter.getXY();
   1.266 +        do {
   1.267 +            *xy++ = PACK_FILTER_Y_NAME(srcXY[1] - (oneY >> 1), maxY,
   1.268 +                                       oneY PREAMBLE_ARG_Y);
   1.269 +            *xy++ = PACK_FILTER_X_NAME(srcXY[0] - (oneX >> 1), maxX,
   1.270 +                                       oneX PREAMBLE_ARG_X);
   1.271 +            srcXY += 2;
   1.272 +        } while (--count != 0);
   1.273 +    }
   1.274 +}
   1.275 +
   1.276 +static SkBitmapProcState::MatrixProc MAKENAME(_Procs)[] = {
   1.277 +    SCALE_NOFILTER_NAME,
   1.278 +    SCALE_FILTER_NAME,
   1.279 +    AFFINE_NOFILTER_NAME,
   1.280 +    AFFINE_FILTER_NAME,
   1.281 +    PERSP_NOFILTER_NAME,
   1.282 +    PERSP_FILTER_NAME
   1.283 +};
   1.284 +
   1.285 +#undef MAKENAME
   1.286 +#undef TILEX_PROCF
   1.287 +#undef TILEY_PROCF
   1.288 +#ifdef CHECK_FOR_DECAL
   1.289 +    #undef CHECK_FOR_DECAL
   1.290 +#endif
   1.291 +
   1.292 +#undef SCALE_NOFILTER_NAME
   1.293 +#undef SCALE_FILTER_NAME
   1.294 +#undef AFFINE_NOFILTER_NAME
   1.295 +#undef AFFINE_FILTER_NAME
   1.296 +#undef PERSP_NOFILTER_NAME
   1.297 +#undef PERSP_FILTER_NAME
   1.298 +
   1.299 +#undef PREAMBLE
   1.300 +#undef PREAMBLE_PARAM_X
   1.301 +#undef PREAMBLE_PARAM_Y
   1.302 +#undef PREAMBLE_ARG_X
   1.303 +#undef PREAMBLE_ARG_Y
   1.304 +
   1.305 +#undef TILEX_LOW_BITS
   1.306 +#undef TILEY_LOW_BITS

mercurial