1685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com
2685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com/*
3685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2006 The Android Open Source Project
4685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com *
5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file.
7685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com */
8685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com
9bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
10bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkFilterProc.h"
11bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
12bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comclass BILERP_BITMAP16_SHADER_CLASS : public HasSpan16_Sampler_BitmapShader {
13bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.compublic:
14bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com    BILERP_BITMAP16_SHADER_CLASS(const SkBitmap& src)
15bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        : HasSpan16_Sampler_BitmapShader(src, true,
16bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                         SkShader::kClamp_TileMode,
17bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                         SkShader::kClamp_TileMode)
18bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com    {
19bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com    }
20bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
21bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com    virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count)
22bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com    {
23bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        SkASSERT(count > 0);
24935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
25bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        U8CPU alpha = this->getPaintAlpha();
26bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
27bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        const SkMatrix& inv = this->getTotalInverse();
28bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        const SkBitmap& srcBitmap = this->getSrcBitmap();
29bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        unsigned        srcMaxX = srcBitmap.width() - 1;
30bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        unsigned        srcMaxY = srcBitmap.height() - 1;
31bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        unsigned        srcRB = srcBitmap.rowBytes();
32bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
33bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap);
34bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
35bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        const SkFilterProc* proc_table = SkGetBilinearFilterProcTable();
36bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels();
37bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
38bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        if (this->getInverseClass() == kPerspective_MatrixClass)
39bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        {
40bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
41bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                    SkIntToScalar(y) + SK_ScalarHalf, count);
42bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            while ((count = iter.next()) != 0)
43bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            {
44bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                const SkFixed* srcXY = iter.getXY();
45bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                while (--count >= 0)
46bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                {
47bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    SkFixed fx = *srcXY++ - SK_FixedHalf;
48bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    SkFixed fy = *srcXY++ - SK_FixedHalf;
49bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    int ix = fx >> 16;
50bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    int iy = fy >> 16;
51bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    int x = SkClampMax(ix, srcMaxX);
52bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    int y = SkClampMax(iy, srcMaxY);
53bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
54bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
55bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
56bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + y * srcRB)) + x;
57bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    if ((unsigned)ix < srcMaxX)
58bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                        p01 += 1;
59bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    p10 = p00;
60bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    p11 = p01;
61bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    if ((unsigned)iy < srcMaxY)
62bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    {
63bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                        p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
64bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                        p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
65bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    }
66bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
67bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
68bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
69bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                      SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
70bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                      SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
71bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                      SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
72bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
73bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    *dstC++ = expanded_rgb16_to_8888(c, alpha);
74bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                }
75bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            }
76bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        }
77bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        else    // linear case
78bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        {
79bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            SkFixed fx, fy, dx, dy;
80bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
81bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            // now init fx, fy, dx, dy
82bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            {
83bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                SkPoint srcPt;
84bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
85bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                                 SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
86bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
87bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
88bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;
89bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
90bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                if (this->getInverseClass() == kFixedStepInX_MatrixClass)
91bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
92bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                else
93bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                {
94bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    dx = SkScalarToFixed(inv.getScaleX());
95bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    dy = SkScalarToFixed(inv.getSkewY());
96bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                }
97bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            }
98bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
99bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            do {
100bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                int ix = fx >> 16;
101bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                int iy = fy >> 16;
102bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
103bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
104bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
105bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels +
106bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                                                   SkClampMax(iy, srcMaxY) * srcRB)) +
107bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                                                   SkClampMax(ix, srcMaxX);
108bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                if ((unsigned)ix < srcMaxX)
109bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    p01 += 1;
110bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                p10 = p00;
111bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                p11 = p01;
112bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                if ((unsigned)iy < srcMaxY)
113bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                {
114bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
115bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
116bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                }
117bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
118bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
119bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
120bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                  SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
121bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                  SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
122bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                  SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
123bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                *dstC++ = expanded_rgb16_to_8888(c, alpha);
124bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
125bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                fx += dx;
126bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                fy += dy;
127bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            } while (--count != 0);
128bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        }
129bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap);
130bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com    }
131bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
132bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com    virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count)
133bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com    {
134bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        SkASSERT(count > 0);
135bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
136bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        const SkMatrix& inv = this->getTotalInverse();
137bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        const SkBitmap& srcBitmap = this->getSrcBitmap();
138bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        unsigned        srcMaxX = srcBitmap.width() - 1;
139bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        unsigned        srcMaxY = srcBitmap.height() - 1;
140bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        unsigned        srcRB = srcBitmap.rowBytes();
141bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
142bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap);
143bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
144bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        const SkFilterProc* proc_table = SkGetBilinearFilterProcTable();
145bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels();
146bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
147bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        if (this->getInverseClass() == kPerspective_MatrixClass)
148bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        {
149bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
150bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                    SkIntToScalar(y) + SK_ScalarHalf, count);
151bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            while ((count = iter.next()) != 0)
152bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            {
153bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                const SkFixed* srcXY = iter.getXY();
154bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                while (--count >= 0)
155bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                {
156bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    SkFixed fx = *srcXY++ - SK_FixedHalf;
157bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    SkFixed fy = *srcXY++ - SK_FixedHalf;
158bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    int ix = fx >> 16;
159bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    int iy = fy >> 16;
160935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
161bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
162bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
163bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels +
164bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                                                      SkClampMax(iy, srcMaxY) * srcRB)) +
165bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                                                      SkClampMax(ix, srcMaxX);
166bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    if ((unsigned)ix < srcMaxX)
167bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                        p01 += 1;
168bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    p10 = p00;
169bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    p11 = p01;
170bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    if ((unsigned)iy < srcMaxY)
171bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    {
172bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                        p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
173bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                        p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
174bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    }
175bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
176bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
177bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
178bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                      SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
179bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                      SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
180bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                      SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
181bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    *dstC++ = SkCompact_rgb_16(c);
182bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                }
183bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            }
184bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        }
185bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        else    // linear case
186bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        {
187bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            SkFixed fx, fy, dx, dy;
188bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
189bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            // now init fx, fy, dx, dy
190bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            {
191bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                SkPoint srcPt;
192bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
193bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                                 SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
194bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
195bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
196bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;
197bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
198bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                if (this->getInverseClass() == kFixedStepInX_MatrixClass)
199bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
200bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                else
201bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                {
202bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    dx = SkScalarToFixed(inv.getScaleX());
203bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    dy = SkScalarToFixed(inv.getSkewY());
204bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                }
205bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            }
206bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
207bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            do {
208bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                int ix = fx >> 16;
209bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                int iy = fy >> 16;
210935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
211bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
212bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
213bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels +
214bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                                                  SkClampMax(iy, srcMaxY) * srcRB)) +
215bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                                                  SkClampMax(ix, srcMaxX);
216bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                if ((unsigned)ix < srcMaxX)
217bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    p01 += 1;
218bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                p10 = p00;
219bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                p11 = p01;
220bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                if ((unsigned)iy < srcMaxY)
221bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                {
222bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
223bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                    p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
224bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                }
225bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
226bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
227bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
228bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                  SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
229bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                  SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
230bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                                  SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
231bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                *dstC++ = SkCompact_rgb_16(c);
232bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
233bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                fx += dx;
234bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com                fy += dy;
235bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com            } while (--count != 0);
236bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        }
237bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap);
238bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com    }
239bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com};
240bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
241bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#undef BILERP_BITMAP16_SHADER_CLASS
242bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#undef BILERP_BITMAP16_SHADER_TYPE
243bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#undef BILERP_BITMAP16_SHADER_PREAMBLE
244bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#undef BILERP_BITMAP16_SHADER_PIXEL
245bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#undef BILERP_BITMAP16_SHADER_POSTAMBLE
246