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