| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkTwoPointConicalGradient.h" | 8 #include "SkTwoPointConicalGradient.h" |
| 9 #include "SkTwoPointConicalGradient_gpu.h" | 9 #include "SkTwoPointConicalGradient_gpu.h" |
| 10 | 10 |
| 11 struct TwoPtRadialContext { | 11 struct TwoPtRadialContext { |
| 12 const TwoPtRadial& fRec; | 12 const TwoPtRadial& fRec; |
| 13 float fRelX, fRelY; | 13 float fRelX, fRelY; |
| 14 const float fIncX, fIncY; | 14 const float fIncX, fIncY; |
| 15 float fB; | 15 float fB; |
| 16 const float fDB; | 16 const float fDB; |
| 17 | 17 |
| 18 TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkScalar fy, | 18 TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkScalar fy, |
| 19 SkScalar dfx, SkScalar dfy); | 19 SkScalar dfx, SkScalar dfy); |
| 20 SkFixed nextT(); | 20 float nextT(); |
| 21 }; | 21 }; |
| 22 | 22 |
| 23 static int valid_divide(float numer, float denom, float* ratio) { | 23 static int valid_divide(float numer, float denom, float* ratio) { |
| 24 SkASSERT(ratio); | 24 SkASSERT(ratio); |
| 25 if (0 == denom) { | 25 if (0 == denom) { |
| 26 return 0; | 26 return 0; |
| 27 } | 27 } |
| 28 *ratio = numer / denom; | 28 *ratio = numer / denom; |
| 29 return 1; | 29 return 1; |
| 30 } | 30 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 } | 70 } |
| 71 return 2; | 71 return 2; |
| 72 } | 72 } |
| 73 | 73 |
| 74 static float lerp(float x, float dx, float t) { | 74 static float lerp(float x, float dx, float t) { |
| 75 return x + t * dx; | 75 return x + t * dx; |
| 76 } | 76 } |
| 77 | 77 |
| 78 static float sqr(float x) { return x * x; } | 78 static float sqr(float x) { return x * x; } |
| 79 | 79 |
| 80 const float TwoPtRadial::kDontDrawT = NAN; |
| 81 |
| 80 void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0, | 82 void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0, |
| 81 const SkPoint& center1, SkScalar rad1, | 83 const SkPoint& center1, SkScalar rad1, |
| 82 bool flipped) { | 84 bool flipped) { |
| 83 fCenterX = SkScalarToFloat(center0.fX); | 85 fCenterX = SkScalarToFloat(center0.fX); |
| 84 fCenterY = SkScalarToFloat(center0.fY); | 86 fCenterY = SkScalarToFloat(center0.fY); |
| 85 fDCenterX = SkScalarToFloat(center1.fX) - fCenterX; | 87 fDCenterX = SkScalarToFloat(center1.fX) - fCenterX; |
| 86 fDCenterY = SkScalarToFloat(center1.fY) - fCenterY; | 88 fDCenterY = SkScalarToFloat(center1.fY) - fCenterY; |
| 87 fRadius = SkScalarToFloat(rad0); | 89 fRadius = SkScalarToFloat(rad0); |
| 88 fDRadius = SkScalarToFloat(rad1) - fRadius; | 90 fDRadius = SkScalarToFloat(rad1) - fRadius; |
| 89 | 91 |
| 90 fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius); | 92 fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius); |
| 91 fRadius2 = sqr(fRadius); | 93 fRadius2 = sqr(fRadius); |
| 92 fRDR = fRadius * fDRadius; | 94 fRDR = fRadius * fDRadius; |
| 93 | 95 |
| 94 fFlipped = flipped; | 96 fFlipped = flipped; |
| 95 } | 97 } |
| 96 | 98 |
| 97 TwoPtRadialContext::TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkSc
alar fy, | 99 TwoPtRadialContext::TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkSc
alar fy, |
| 98 SkScalar dfx, SkScalar dfy) | 100 SkScalar dfx, SkScalar dfy) |
| 99 : fRec(rec) | 101 : fRec(rec) |
| 100 , fRelX(SkScalarToFloat(fx) - rec.fCenterX) | 102 , fRelX(SkScalarToFloat(fx) - rec.fCenterX) |
| 101 , fRelY(SkScalarToFloat(fy) - rec.fCenterY) | 103 , fRelY(SkScalarToFloat(fy) - rec.fCenterY) |
| 102 , fIncX(SkScalarToFloat(dfx)) | 104 , fIncX(SkScalarToFloat(dfx)) |
| 103 , fIncY(SkScalarToFloat(dfy)) | 105 , fIncY(SkScalarToFloat(dfy)) |
| 104 , fB(-2 * (rec.fDCenterX * fRelX + rec.fDCenterY * fRelY + rec.fRDR)) | 106 , fB(-2 * (rec.fDCenterX * fRelX + rec.fDCenterY * fRelY + rec.fRDR)) |
| 105 , fDB(-2 * (rec.fDCenterX * fIncX + rec.fDCenterY * fIncY)) {} | 107 , fDB(-2 * (rec.fDCenterX * fIncX + rec.fDCenterY * fIncY)) {} |
| 106 | 108 |
| 107 SkFixed TwoPtRadialContext::nextT() { | 109 float TwoPtRadialContext::nextT() { |
| 108 float roots[2]; | 110 float roots[2]; |
| 109 | 111 |
| 110 float C = sqr(fRelX) + sqr(fRelY) - fRec.fRadius2; | 112 float C = sqr(fRelX) + sqr(fRelY) - fRec.fRadius2; |
| 111 int countRoots = find_quad_roots(fRec.fA, fB, C, roots, fRec.fFlipped); | 113 int countRoots = find_quad_roots(fRec.fA, fB, C, roots, fRec.fFlipped); |
| 112 | 114 |
| 113 fRelX += fIncX; | 115 fRelX += fIncX; |
| 114 fRelY += fIncY; | 116 fRelY += fIncY; |
| 115 fB += fDB; | 117 fB += fDB; |
| 116 | 118 |
| 117 if (0 == countRoots) { | 119 if (0 == countRoots) { |
| 118 return TwoPtRadial::kDontDrawT; | 120 return TwoPtRadial::kDontDrawT; |
| 119 } | 121 } |
| 120 | 122 |
| 121 // Prefer the bigger t value if both give a radius(t) > 0 | 123 // Prefer the bigger t value if both give a radius(t) > 0 |
| 122 // find_quad_roots returns the values sorted, so we start with the last | 124 // find_quad_roots returns the values sorted, so we start with the last |
| 123 float t = roots[countRoots - 1]; | 125 float t = roots[countRoots - 1]; |
| 124 float r = lerp(fRec.fRadius, fRec.fDRadius, t); | 126 float r = lerp(fRec.fRadius, fRec.fDRadius, t); |
| 125 if (r < 0) { | 127 if (r < 0) { |
| 126 t = roots[0]; // might be the same as roots[countRoots-1] | 128 t = roots[0]; // might be the same as roots[countRoots-1] |
| 127 r = lerp(fRec.fRadius, fRec.fDRadius, t); | 129 r = lerp(fRec.fRadius, fRec.fDRadius, t); |
| 128 if (r < 0) { | 130 if (r < 0) { |
| 129 return TwoPtRadial::kDontDrawT; | 131 return TwoPtRadial::kDontDrawT; |
| 130 } | 132 } |
| 131 } | 133 } |
| 132 return SkFloatToFixed(t); | 134 return t; |
| 133 } | 135 } |
| 134 | 136 |
| 135 typedef void (*TwoPointConicalProc)(TwoPtRadialContext* rec, SkPMColor* dstC, | 137 typedef void (*TwoPointConicalProc)(TwoPtRadialContext* rec, SkPMColor* dstC, |
| 136 const SkPMColor* cache, int toggle, int coun
t); | 138 const SkPMColor* cache, int toggle, int coun
t); |
| 137 | 139 |
| 138 static void twopoint_clamp(TwoPtRadialContext* rec, SkPMColor* SK_RESTRICT dstC, | 140 static void twopoint_clamp(TwoPtRadialContext* rec, SkPMColor* SK_RESTRICT dstC, |
| 139 const SkPMColor* SK_RESTRICT cache, int toggle, | 141 const SkPMColor* SK_RESTRICT cache, int toggle, |
| 140 int count) { | 142 int count) { |
| 141 for (; count > 0; --count) { | 143 for (; count > 0; --count) { |
| 142 SkFixed t = rec->nextT(); | 144 float t = rec->nextT(); |
| 143 if (TwoPtRadial::DontDrawT(t)) { | 145 if (TwoPtRadial::DontDrawT(t)) { |
| 144 *dstC++ = 0; | 146 *dstC++ = 0; |
| 145 } else { | 147 } else { |
| 146 SkFixed index = SkClampMax(t, 0xFFFF); | 148 const unsigned index = clamp_tileproc(t); |
| 147 SkASSERT(index <= 0xFFFF); | 149 SkASSERT(index <= 0xFFFF); |
| 148 *dstC++ = cache[toggle + | 150 *dstC++ = cache[toggle + |
| 149 (index >> SkGradientShaderBase::kCache32Shift)]; | 151 (index >> SkGradientShaderBase::kCache32Shift)]; |
| 150 } | 152 } |
| 151 toggle = next_dither_toggle(toggle); | 153 toggle = next_dither_toggle(toggle); |
| 152 } | 154 } |
| 153 } | 155 } |
| 154 | 156 |
| 155 static void twopoint_repeat(TwoPtRadialContext* rec, SkPMColor* SK_RESTRICT dstC
, | 157 static void twopoint_repeat(TwoPtRadialContext* rec, SkPMColor* SK_RESTRICT dstC
, |
| 156 const SkPMColor* SK_RESTRICT cache, int toggle, | 158 const SkPMColor* SK_RESTRICT cache, int toggle, |
| 157 int count) { | 159 int count) { |
| 158 for (; count > 0; --count) { | 160 for (; count > 0; --count) { |
| 159 SkFixed t = rec->nextT(); | 161 float t = rec->nextT(); |
| 160 if (TwoPtRadial::DontDrawT(t)) { | 162 if (TwoPtRadial::DontDrawT(t)) { |
| 161 *dstC++ = 0; | 163 *dstC++ = 0; |
| 162 } else { | 164 } else { |
| 163 SkFixed index = repeat_tileproc(t); | 165 const unsigned index = repeat_tileproc(t); |
| 164 SkASSERT(index <= 0xFFFF); | 166 SkASSERT(index <= 0xFFFF); |
| 165 *dstC++ = cache[toggle + | 167 *dstC++ = cache[toggle + |
| 166 (index >> SkGradientShaderBase::kCache32Shift)]; | 168 (index >> SkGradientShaderBase::kCache32Shift)]; |
| 167 } | 169 } |
| 168 toggle = next_dither_toggle(toggle); | 170 toggle = next_dither_toggle(toggle); |
| 169 } | 171 } |
| 170 } | 172 } |
| 171 | 173 |
| 172 static void twopoint_mirror(TwoPtRadialContext* rec, SkPMColor* SK_RESTRICT dstC
, | 174 static void twopoint_mirror(TwoPtRadialContext* rec, SkPMColor* SK_RESTRICT dstC
, |
| 173 const SkPMColor* SK_RESTRICT cache, int toggle, | 175 const SkPMColor* SK_RESTRICT cache, int toggle, |
| 174 int count) { | 176 int count) { |
| 175 for (; count > 0; --count) { | 177 for (; count > 0; --count) { |
| 176 SkFixed t = rec->nextT(); | 178 float t = rec->nextT(); |
| 177 if (TwoPtRadial::DontDrawT(t)) { | 179 if (TwoPtRadial::DontDrawT(t)) { |
| 178 *dstC++ = 0; | 180 *dstC++ = 0; |
| 179 } else { | 181 } else { |
| 180 SkFixed index = mirror_tileproc(t); | 182 const unsigned index = mirror_tileproc(t); |
| 181 SkASSERT(index <= 0xFFFF); | 183 SkASSERT(index <= 0xFFFF); |
| 182 *dstC++ = cache[toggle + | 184 *dstC++ = cache[toggle + |
| 183 (index >> SkGradientShaderBase::kCache32Shift)]; | 185 (index >> SkGradientShaderBase::kCache32Shift)]; |
| 184 } | 186 } |
| 185 toggle = next_dither_toggle(toggle); | 187 toggle = next_dither_toggle(toggle); |
| 186 } | 188 } |
| 187 } | 189 } |
| 188 | 190 |
| 189 ///////////////////////////////////////////////////////////////////// | 191 ///////////////////////////////////////////////////////////////////// |
| 190 | 192 |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 str->appendScalar(fCenter2.fY); | 390 str->appendScalar(fCenter2.fY); |
| 389 str->append(") radius2: "); | 391 str->append(") radius2: "); |
| 390 str->appendScalar(fRadius2); | 392 str->appendScalar(fRadius2); |
| 391 str->append(" "); | 393 str->append(" "); |
| 392 | 394 |
| 393 this->INHERITED::toString(str); | 395 this->INHERITED::toString(str); |
| 394 | 396 |
| 395 str->append(")"); | 397 str->append(")"); |
| 396 } | 398 } |
| 397 #endif | 399 #endif |
| OLD | NEW |