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

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/core/SkBitmapShader16BilerpTemplate.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,245 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2006 The Android Open Source Project
     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 +
    1.13 +#include "SkFilterProc.h"
    1.14 +
    1.15 +class BILERP_BITMAP16_SHADER_CLASS : public HasSpan16_Sampler_BitmapShader {
    1.16 +public:
    1.17 +    BILERP_BITMAP16_SHADER_CLASS(const SkBitmap& src)
    1.18 +        : HasSpan16_Sampler_BitmapShader(src, true,
    1.19 +                                         SkShader::kClamp_TileMode,
    1.20 +                                         SkShader::kClamp_TileMode)
    1.21 +    {
    1.22 +    }
    1.23 +
    1.24 +    virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count)
    1.25 +    {
    1.26 +        SkASSERT(count > 0);
    1.27 +
    1.28 +        U8CPU alpha = this->getPaintAlpha();
    1.29 +
    1.30 +        const SkMatrix& inv = this->getTotalInverse();
    1.31 +        const SkBitmap& srcBitmap = this->getSrcBitmap();
    1.32 +        unsigned        srcMaxX = srcBitmap.width() - 1;
    1.33 +        unsigned        srcMaxY = srcBitmap.height() - 1;
    1.34 +        unsigned        srcRB = srcBitmap.rowBytes();
    1.35 +
    1.36 +        BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap);
    1.37 +
    1.38 +        const SkFilterProc* proc_table = SkGetBilinearFilterProcTable();
    1.39 +        const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels();
    1.40 +
    1.41 +        if (this->getInverseClass() == kPerspective_MatrixClass)
    1.42 +        {
    1.43 +            SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
    1.44 +                                    SkIntToScalar(y) + SK_ScalarHalf, count);
    1.45 +            while ((count = iter.next()) != 0)
    1.46 +            {
    1.47 +                const SkFixed* srcXY = iter.getXY();
    1.48 +                while (--count >= 0)
    1.49 +                {
    1.50 +                    SkFixed fx = *srcXY++ - SK_FixedHalf;
    1.51 +                    SkFixed fy = *srcXY++ - SK_FixedHalf;
    1.52 +                    int ix = fx >> 16;
    1.53 +                    int iy = fy >> 16;
    1.54 +                    int x = SkClampMax(ix, srcMaxX);
    1.55 +                    int y = SkClampMax(iy, srcMaxY);
    1.56 +
    1.57 +                    const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
    1.58 +
    1.59 +                    p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + y * srcRB)) + x;
    1.60 +                    if ((unsigned)ix < srcMaxX)
    1.61 +                        p01 += 1;
    1.62 +                    p10 = p00;
    1.63 +                    p11 = p01;
    1.64 +                    if ((unsigned)iy < srcMaxY)
    1.65 +                    {
    1.66 +                        p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
    1.67 +                        p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
    1.68 +                    }
    1.69 +
    1.70 +                    SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
    1.71 +                    uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
    1.72 +                                      SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
    1.73 +                                      SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
    1.74 +                                      SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
    1.75 +
    1.76 +                    *dstC++ = expanded_rgb16_to_8888(c, alpha);
    1.77 +                }
    1.78 +            }
    1.79 +        }
    1.80 +        else    // linear case
    1.81 +        {
    1.82 +            SkFixed fx, fy, dx, dy;
    1.83 +
    1.84 +            // now init fx, fy, dx, dy
    1.85 +            {
    1.86 +                SkPoint srcPt;
    1.87 +                this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
    1.88 +                                                 SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
    1.89 +
    1.90 +                fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
    1.91 +                fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;
    1.92 +
    1.93 +                if (this->getInverseClass() == kFixedStepInX_MatrixClass)
    1.94 +                    (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
    1.95 +                else
    1.96 +                {
    1.97 +                    dx = SkScalarToFixed(inv.getScaleX());
    1.98 +                    dy = SkScalarToFixed(inv.getSkewY());
    1.99 +                }
   1.100 +            }
   1.101 +
   1.102 +            do {
   1.103 +                int ix = fx >> 16;
   1.104 +                int iy = fy >> 16;
   1.105 +
   1.106 +                const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
   1.107 +
   1.108 +                p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels +
   1.109 +                                                                   SkClampMax(iy, srcMaxY) * srcRB)) +
   1.110 +                                                                   SkClampMax(ix, srcMaxX);
   1.111 +                if ((unsigned)ix < srcMaxX)
   1.112 +                    p01 += 1;
   1.113 +                p10 = p00;
   1.114 +                p11 = p01;
   1.115 +                if ((unsigned)iy < srcMaxY)
   1.116 +                {
   1.117 +                    p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
   1.118 +                    p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
   1.119 +                }
   1.120 +
   1.121 +                SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
   1.122 +                uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
   1.123 +                                  SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
   1.124 +                                  SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
   1.125 +                                  SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
   1.126 +                *dstC++ = expanded_rgb16_to_8888(c, alpha);
   1.127 +
   1.128 +                fx += dx;
   1.129 +                fy += dy;
   1.130 +            } while (--count != 0);
   1.131 +        }
   1.132 +        BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap);
   1.133 +    }
   1.134 +
   1.135 +    virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count)
   1.136 +    {
   1.137 +        SkASSERT(count > 0);
   1.138 +
   1.139 +        const SkMatrix& inv = this->getTotalInverse();
   1.140 +        const SkBitmap& srcBitmap = this->getSrcBitmap();
   1.141 +        unsigned        srcMaxX = srcBitmap.width() - 1;
   1.142 +        unsigned        srcMaxY = srcBitmap.height() - 1;
   1.143 +        unsigned        srcRB = srcBitmap.rowBytes();
   1.144 +
   1.145 +        BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap);
   1.146 +
   1.147 +        const SkFilterProc* proc_table = SkGetBilinearFilterProcTable();
   1.148 +        const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels();
   1.149 +
   1.150 +        if (this->getInverseClass() == kPerspective_MatrixClass)
   1.151 +        {
   1.152 +            SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
   1.153 +                                    SkIntToScalar(y) + SK_ScalarHalf, count);
   1.154 +            while ((count = iter.next()) != 0)
   1.155 +            {
   1.156 +                const SkFixed* srcXY = iter.getXY();
   1.157 +                while (--count >= 0)
   1.158 +                {
   1.159 +                    SkFixed fx = *srcXY++ - SK_FixedHalf;
   1.160 +                    SkFixed fy = *srcXY++ - SK_FixedHalf;
   1.161 +                    int ix = fx >> 16;
   1.162 +                    int iy = fy >> 16;
   1.163 +
   1.164 +                    const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
   1.165 +
   1.166 +                    p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels +
   1.167 +                                                                      SkClampMax(iy, srcMaxY) * srcRB)) +
   1.168 +                                                                      SkClampMax(ix, srcMaxX);
   1.169 +                    if ((unsigned)ix < srcMaxX)
   1.170 +                        p01 += 1;
   1.171 +                    p10 = p00;
   1.172 +                    p11 = p01;
   1.173 +                    if ((unsigned)iy < srcMaxY)
   1.174 +                    {
   1.175 +                        p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
   1.176 +                        p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
   1.177 +                    }
   1.178 +
   1.179 +                    SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
   1.180 +                    uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
   1.181 +                                      SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
   1.182 +                                      SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
   1.183 +                                      SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
   1.184 +                    *dstC++ = SkCompact_rgb_16(c);
   1.185 +                }
   1.186 +            }
   1.187 +        }
   1.188 +        else    // linear case
   1.189 +        {
   1.190 +            SkFixed fx, fy, dx, dy;
   1.191 +
   1.192 +            // now init fx, fy, dx, dy
   1.193 +            {
   1.194 +                SkPoint srcPt;
   1.195 +                this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
   1.196 +                                                 SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
   1.197 +
   1.198 +                fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
   1.199 +                fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;
   1.200 +
   1.201 +                if (this->getInverseClass() == kFixedStepInX_MatrixClass)
   1.202 +                    (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
   1.203 +                else
   1.204 +                {
   1.205 +                    dx = SkScalarToFixed(inv.getScaleX());
   1.206 +                    dy = SkScalarToFixed(inv.getSkewY());
   1.207 +                }
   1.208 +            }
   1.209 +
   1.210 +            do {
   1.211 +                int ix = fx >> 16;
   1.212 +                int iy = fy >> 16;
   1.213 +
   1.214 +                const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
   1.215 +
   1.216 +                p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels +
   1.217 +                                                                  SkClampMax(iy, srcMaxY) * srcRB)) +
   1.218 +                                                                  SkClampMax(ix, srcMaxX);
   1.219 +                if ((unsigned)ix < srcMaxX)
   1.220 +                    p01 += 1;
   1.221 +                p10 = p00;
   1.222 +                p11 = p01;
   1.223 +                if ((unsigned)iy < srcMaxY)
   1.224 +                {
   1.225 +                    p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
   1.226 +                    p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
   1.227 +                }
   1.228 +
   1.229 +                SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
   1.230 +                uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
   1.231 +                                  SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
   1.232 +                                  SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
   1.233 +                                  SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
   1.234 +                *dstC++ = SkCompact_rgb_16(c);
   1.235 +
   1.236 +                fx += dx;
   1.237 +                fy += dy;
   1.238 +            } while (--count != 0);
   1.239 +        }
   1.240 +        BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap);
   1.241 +    }
   1.242 +};
   1.243 +
   1.244 +#undef BILERP_BITMAP16_SHADER_CLASS
   1.245 +#undef BILERP_BITMAP16_SHADER_TYPE
   1.246 +#undef BILERP_BITMAP16_SHADER_PREAMBLE
   1.247 +#undef BILERP_BITMAP16_SHADER_PIXEL
   1.248 +#undef BILERP_BITMAP16_SHADER_POSTAMBLE

mercurial