| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 "Sk4fLinearGradient.h" | 8 #include "Sk4fLinearGradient.h" |
| 9 #include "SkUtils.h" | |
| 10 #include "SkXfermode.h" | 9 #include "SkXfermode.h" |
| 11 | 10 |
| 12 namespace { | 11 namespace { |
| 13 | 12 |
| 14 template<typename DstType, SkColorProfileType, ApplyPremul> | 13 template<DstType dstType, ApplyPremul premul> |
| 15 void fill(const Sk4f& c, DstType* dst, int n); | 14 void ramp(const Sk4f& c, const Sk4f& dc, typename DstTraits<dstType, premul>::Ty
pe dst[], int n) { |
| 16 | |
| 17 template<> | |
| 18 void fill<SkPM4f, kLinear_SkColorProfileType, ApplyPremul::False> | |
| 19 (const Sk4f& c, SkPM4f* dst, int n) { | |
| 20 while (n > 0) { | |
| 21 c.store(dst++); | |
| 22 n--; | |
| 23 } | |
| 24 } | |
| 25 | |
| 26 template<> | |
| 27 void fill<SkPM4f, kLinear_SkColorProfileType, ApplyPremul::True> | |
| 28 (const Sk4f& c, SkPM4f* dst, int n) { | |
| 29 fill<SkPM4f, kLinear_SkColorProfileType, ApplyPremul::False>(premul_4f(c), d
st, n); | |
| 30 } | |
| 31 | |
| 32 template<> | |
| 33 void fill<SkPMColor, kLinear_SkColorProfileType, ApplyPremul::False> | |
| 34 (const Sk4f& c, SkPMColor* dst, int n) { | |
| 35 sk_memset32(dst, trunc_from_4f_255<ApplyPremul::False>(c), n); | |
| 36 } | |
| 37 | |
| 38 template<> | |
| 39 void fill<SkPMColor, kLinear_SkColorProfileType, ApplyPremul::True> | |
| 40 (const Sk4f& c, SkPMColor* dst, int n) { | |
| 41 sk_memset32(dst, trunc_from_4f_255<ApplyPremul::True>(c), n); | |
| 42 } | |
| 43 | |
| 44 template<> | |
| 45 void fill<SkPMColor, kSRGB_SkColorProfileType, ApplyPremul::False> | |
| 46 (const Sk4f& c, SkPMColor* dst, int n) { | |
| 47 // FIXME: this assumes opaque colors. Handle unpremultiplication. | |
| 48 sk_memset32(dst, Sk4f_toS32(c), n); | |
| 49 } | |
| 50 | |
| 51 template<> | |
| 52 void fill<SkPMColor, kSRGB_SkColorProfileType, ApplyPremul::True> | |
| 53 (const Sk4f& c, SkPMColor* dst, int n) { | |
| 54 sk_memset32(dst, Sk4f_toS32(premul_4f(c)), n); | |
| 55 } | |
| 56 | |
| 57 template<> | |
| 58 void fill<uint64_t, kLinear_SkColorProfileType, ApplyPremul::False> | |
| 59 (const Sk4f& c, uint64_t* dst, int n) { | |
| 60 sk_memset64(dst, SkFloatToHalf_01(c), n); | |
| 61 } | |
| 62 | |
| 63 template<> | |
| 64 void fill<uint64_t, kLinear_SkColorProfileType, ApplyPremul::True> | |
| 65 (const Sk4f& c, uint64_t* dst, int n) { | |
| 66 sk_memset64(dst, SkFloatToHalf_01(premul_4f(c)), n); | |
| 67 } | |
| 68 | |
| 69 template<typename DstType, SkColorProfileType profile, ApplyPremul premul> | |
| 70 void ramp(const Sk4f& c, const Sk4f& dc, DstType* dst, int n) { | |
| 71 SkASSERT(n > 0); | 15 SkASSERT(n > 0); |
| 72 | 16 |
| 73 const Sk4f dc2 = dc + dc; | 17 const Sk4f dc2 = dc + dc; |
| 74 const Sk4f dc4 = dc2 + dc2; | 18 const Sk4f dc4 = dc2 + dc2; |
| 75 | 19 |
| 76 Sk4f c0 = c ; | 20 Sk4f c0 = c ; |
| 77 Sk4f c1 = c + dc; | 21 Sk4f c1 = c + dc; |
| 78 Sk4f c2 = c0 + dc2; | 22 Sk4f c2 = c0 + dc2; |
| 79 Sk4f c3 = c1 + dc2; | 23 Sk4f c3 = c1 + dc2; |
| 80 | 24 |
| 81 while (n >= 4) { | 25 while (n >= 4) { |
| 82 store4x<DstType, profile, premul>(c0, c1, c2, c3, dst); | 26 DstTraits<dstType, premul>::store4x(c0, c1, c2, c3, dst); |
| 83 dst += 4; | 27 dst += 4; |
| 84 | 28 |
| 85 c0 = c0 + dc4; | 29 c0 = c0 + dc4; |
| 86 c1 = c1 + dc4; | 30 c1 = c1 + dc4; |
| 87 c2 = c2 + dc4; | 31 c2 = c2 + dc4; |
| 88 c3 = c3 + dc4; | 32 c3 = c3 + dc4; |
| 89 n -= 4; | 33 n -= 4; |
| 90 } | 34 } |
| 91 if (n & 2) { | 35 if (n & 2) { |
| 92 store<DstType, profile, premul>(c0, dst++); | 36 DstTraits<dstType, premul>::store(c0, dst++); |
| 93 store<DstType, profile, premul>(c1, dst++); | 37 DstTraits<dstType, premul>::store(c1, dst++); |
| 94 c0 = c0 + dc2; | 38 c0 = c0 + dc2; |
| 95 } | 39 } |
| 96 if (n & 1) { | 40 if (n & 1) { |
| 97 store<DstType, profile, premul>(c0, dst); | 41 DstTraits<dstType, premul>::store(c0, dst); |
| 98 } | 42 } |
| 99 } | 43 } |
| 100 | 44 |
| 101 template<SkShader::TileMode> | 45 template<SkShader::TileMode> |
| 102 SkScalar pinFx(SkScalar); | 46 SkScalar pinFx(SkScalar); |
| 103 | 47 |
| 104 template<> | 48 template<> |
| 105 SkScalar pinFx<SkShader::kClamp_TileMode>(SkScalar fx) { | 49 SkScalar pinFx<SkShader::kClamp_TileMode>(SkScalar fx) { |
| 106 return fx; | 50 return fx; |
| 107 } | 51 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 void SkLinearGradient:: | 130 void SkLinearGradient:: |
| 187 LinearGradient4fContext::shadeSpan(int x, int y, SkPMColor dst[], int count) { | 131 LinearGradient4fContext::shadeSpan(int x, int y, SkPMColor dst[], int count) { |
| 188 if (!this->isFast()) { | 132 if (!this->isFast()) { |
| 189 this->INHERITED::shadeSpan(x, y, dst, count); | 133 this->INHERITED::shadeSpan(x, y, dst, count); |
| 190 return; | 134 return; |
| 191 } | 135 } |
| 192 | 136 |
| 193 // TODO: plumb dithering | 137 // TODO: plumb dithering |
| 194 SkASSERT(count > 0); | 138 SkASSERT(count > 0); |
| 195 if (fColorsArePremul) { | 139 if (fColorsArePremul) { |
| 196 this->shadePremulSpan<SkPMColor, | 140 this->shadePremulSpan<DstType::L32, |
| 197 kLinear_SkColorProfileType, | |
| 198 ApplyPremul::False>(x, y, dst, count); | 141 ApplyPremul::False>(x, y, dst, count); |
| 199 } else { | 142 } else { |
| 200 this->shadePremulSpan<SkPMColor, | 143 this->shadePremulSpan<DstType::L32, |
| 201 kLinear_SkColorProfileType, | |
| 202 ApplyPremul::True>(x, y, dst, count); | 144 ApplyPremul::True>(x, y, dst, count); |
| 203 } | 145 } |
| 204 } | 146 } |
| 205 | 147 |
| 206 void SkLinearGradient:: | 148 void SkLinearGradient:: |
| 207 LinearGradient4fContext::shadeSpan4f(int x, int y, SkPM4f dst[], int count) { | 149 LinearGradient4fContext::shadeSpan4f(int x, int y, SkPM4f dst[], int count) { |
| 208 if (!this->isFast()) { | 150 if (!this->isFast()) { |
| 209 this->INHERITED::shadeSpan4f(x, y, dst, count); | 151 this->INHERITED::shadeSpan4f(x, y, dst, count); |
| 210 return; | 152 return; |
| 211 } | 153 } |
| 212 | 154 |
| 213 // TONOTDO: plumb dithering | 155 // TONOTDO: plumb dithering |
| 214 SkASSERT(count > 0); | 156 SkASSERT(count > 0); |
| 215 if (fColorsArePremul) { | 157 if (fColorsArePremul) { |
| 216 this->shadePremulSpan<SkPM4f, | 158 this->shadePremulSpan<DstType::F32, |
| 217 kLinear_SkColorProfileType, | |
| 218 ApplyPremul::False>(x, y, dst, count); | 159 ApplyPremul::False>(x, y, dst, count); |
| 219 } else { | 160 } else { |
| 220 this->shadePremulSpan<SkPM4f, | 161 this->shadePremulSpan<DstType::F32, |
| 221 kLinear_SkColorProfileType, | |
| 222 ApplyPremul::True>(x, y, dst, count); | 162 ApplyPremul::True>(x, y, dst, count); |
| 223 } | 163 } |
| 224 } | 164 } |
| 225 | 165 |
| 226 template<typename DstType, SkColorProfileType profile, ApplyPremul premul> | 166 template<DstType dstType, ApplyPremul premul> |
| 227 void SkLinearGradient:: | 167 void SkLinearGradient:: |
| 228 LinearGradient4fContext::shadePremulSpan(int x, int y, | 168 LinearGradient4fContext::shadePremulSpan(int x, int y, |
| 229 DstType dst[], | 169 typename DstTraits<dstType, premul>::Ty
pe dst[], |
| 230 int count) const { | 170 int count) const { |
| 231 const SkLinearGradient& shader = | 171 const SkLinearGradient& shader = |
| 232 static_cast<const SkLinearGradient&>(fShader); | 172 static_cast<const SkLinearGradient&>(fShader); |
| 233 switch (shader.fTileMode) { | 173 switch (shader.fTileMode) { |
| 234 case kClamp_TileMode: | 174 case kClamp_TileMode: |
| 235 this->shadeSpanInternal<DstType, | 175 this->shadeSpanInternal<dstType, |
| 236 profile, | |
| 237 premul, | 176 premul, |
| 238 kClamp_TileMode>(x, y, dst, count); | 177 kClamp_TileMode>(x, y, dst, count); |
| 239 break; | 178 break; |
| 240 case kRepeat_TileMode: | 179 case kRepeat_TileMode: |
| 241 this->shadeSpanInternal<DstType, | 180 this->shadeSpanInternal<dstType, |
| 242 profile, | |
| 243 premul, | 181 premul, |
| 244 kRepeat_TileMode>(x, y, dst, count); | 182 kRepeat_TileMode>(x, y, dst, count); |
| 245 break; | 183 break; |
| 246 case kMirror_TileMode: | 184 case kMirror_TileMode: |
| 247 this->shadeSpanInternal<DstType, | 185 this->shadeSpanInternal<dstType, |
| 248 profile, | |
| 249 premul, | 186 premul, |
| 250 kMirror_TileMode>(x, y, dst, count); | 187 kMirror_TileMode>(x, y, dst, count); |
| 251 break; | 188 break; |
| 252 } | 189 } |
| 253 } | 190 } |
| 254 | 191 |
| 255 template<typename DstType, SkColorProfileType profile, ApplyPremul premul, | 192 template<DstType dstType, ApplyPremul premul, SkShader::TileMode tileMode> |
| 256 SkShader::TileMode tileMode> | |
| 257 void SkLinearGradient:: | 193 void SkLinearGradient:: |
| 258 LinearGradient4fContext::shadeSpanInternal(int x, int y, | 194 LinearGradient4fContext::shadeSpanInternal(int x, int y, |
| 259 DstType dst[], | 195 typename DstTraits<dstType, premul>::
Type dst[], |
| 260 int count) const { | 196 int count) const { |
| 261 SkPoint pt; | 197 SkPoint pt; |
| 262 fDstToPosProc(fDstToPos, | 198 fDstToPosProc(fDstToPos, |
| 263 x + SK_ScalarHalf, | 199 x + SK_ScalarHalf, |
| 264 y + SK_ScalarHalf, | 200 y + SK_ScalarHalf, |
| 265 &pt); | 201 &pt); |
| 266 const SkScalar fx = pinFx<tileMode>(pt.x()); | 202 const SkScalar fx = pinFx<tileMode>(pt.x()); |
| 267 const SkScalar dx = fDstToPos.getScaleX(); | 203 const SkScalar dx = fDstToPos.getScaleX(); |
| 268 LinearIntervalProcessor<DstType, profile, tileMode> proc(fIntervals.begin(), | 204 LinearIntervalProcessor<dstType, tileMode> proc(fIntervals.begin(), |
| 269 fIntervals.end() -
1, | 205 fIntervals.end() - 1, |
| 270 this->findInterval(
fx), | 206 this->findInterval(fx), |
| 271 fx, | 207 fx, |
| 272 dx, | 208 dx, |
| 273 SkScalarNearlyZero(
dx * count)); | 209 SkScalarNearlyZero(dx * coun
t)); |
| 274 while (count > 0) { | 210 while (count > 0) { |
| 275 // What we really want here is SkTPin(advance, 1, count) | 211 // What we really want here is SkTPin(advance, 1, count) |
| 276 // but that's a significant perf hit for >> stops; investigate. | 212 // but that's a significant perf hit for >> stops; investigate. |
| 277 const int n = SkScalarTruncToInt( | 213 const int n = SkScalarTruncToInt( |
| 278 SkTMin<SkScalar>(proc.currentAdvance() + 1, SkIntToScalar(count))); | 214 SkTMin<SkScalar>(proc.currentAdvance() + 1, SkIntToScalar(count))); |
| 279 | 215 |
| 280 // The current interval advance can be +inf (e.g. when reaching | 216 // The current interval advance can be +inf (e.g. when reaching |
| 281 // the clamp mode end intervals) - when that happens, we expect to | 217 // the clamp mode end intervals) - when that happens, we expect to |
| 282 // a) consume all remaining count in one swoop | 218 // a) consume all remaining count in one swoop |
| 283 // b) return a zero color gradient | 219 // b) return a zero color gradient |
| 284 SkASSERT(SkScalarIsFinite(proc.currentAdvance()) | 220 SkASSERT(SkScalarIsFinite(proc.currentAdvance()) |
| 285 || (n == count && proc.currentRampIsZero())); | 221 || (n == count && proc.currentRampIsZero())); |
| 286 | 222 |
| 287 if (proc.currentRampIsZero()) { | 223 if (proc.currentRampIsZero()) { |
| 288 fill<DstType, profile, premul>(proc.currentColor(), | 224 DstTraits<dstType, premul>::store(proc.currentColor(), |
| 289 dst, n); | 225 dst, n); |
| 290 } else { | 226 } else { |
| 291 ramp<DstType, profile, premul>(proc.currentColor(), | 227 ramp<dstType, premul>(proc.currentColor(), |
| 292 proc.currentColorGrad(), | 228 proc.currentColorGrad(), |
| 293 dst, n); | 229 dst, n); |
| 294 } | 230 } |
| 295 | 231 |
| 296 proc.advance(SkIntToScalar(n)); | 232 proc.advance(SkIntToScalar(n)); |
| 297 count -= n; | 233 count -= n; |
| 298 dst += n; | 234 dst += n; |
| 299 } | 235 } |
| 300 } | 236 } |
| 301 | 237 |
| 302 template<typename DstType, SkColorProfileType profile, SkShader::TileMode tileMo
de> | 238 template<DstType dstType, SkShader::TileMode tileMode> |
| 303 class SkLinearGradient:: | 239 class SkLinearGradient:: |
| 304 LinearGradient4fContext::LinearIntervalProcessor { | 240 LinearGradient4fContext::LinearIntervalProcessor { |
| 305 public: | 241 public: |
| 306 LinearIntervalProcessor(const Interval* firstInterval, | 242 LinearIntervalProcessor(const Interval* firstInterval, |
| 307 const Interval* lastInterval, | 243 const Interval* lastInterval, |
| 308 const Interval* i, | 244 const Interval* i, |
| 309 SkScalar fx, | 245 SkScalar fx, |
| 310 SkScalar dx, | 246 SkScalar dx, |
| 311 bool is_vertical) | 247 bool is_vertical) |
| 312 : fAdvX((i->fP1 - fx) / dx) | 248 : fAdvX((i->fP1 - fx) / dx) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 339 advX = this->advance_interval(advX); | 275 advX = this->advance_interval(advX); |
| 340 } | 276 } |
| 341 SkASSERT(advX < fAdvX); | 277 SkASSERT(advX < fAdvX); |
| 342 | 278 |
| 343 fCc = fCc + fDcDx * Sk4f(advX); | 279 fCc = fCc + fDcDx * Sk4f(advX); |
| 344 fAdvX -= advX; | 280 fAdvX -= advX; |
| 345 } | 281 } |
| 346 | 282 |
| 347 private: | 283 private: |
| 348 void compute_interval_props(SkScalar t) { | 284 void compute_interval_props(SkScalar t) { |
| 349 fDc = dst_swizzle<DstType>(fInterval->fDc); | 285 const Sk4f dC = DstTraits<dstType>::load(fInterval->fDc); |
| 350 fCc = dst_swizzle<DstType>(fInterval->fC0); | 286 fCc = DstTraits<dstType>::load(fInterval->fC0); |
| 351 fCc = fCc + fDc * Sk4f(t); | 287 fCc = fCc + dC * Sk4f(t); |
| 352 fCc = scale_for_dest<DstType, profile>(fCc); | 288 fDcDx = dC * fDx; |
| 353 fDcDx = scale_for_dest<DstType, profile>(fDc * Sk4f(fDx)); | 289 fZeroRamp = fIsVertical || fInterval->isZeroRamp(); |
| 354 fZeroRamp = fIsVertical || fInterval->isZeroRamp(); | |
| 355 } | 290 } |
| 356 | 291 |
| 357 const Interval* next_interval(const Interval* i) const { | 292 const Interval* next_interval(const Interval* i) const { |
| 358 SkASSERT(i >= fFirstInterval); | 293 SkASSERT(i >= fFirstInterval); |
| 359 SkASSERT(i <= fLastInterval); | 294 SkASSERT(i <= fLastInterval); |
| 360 i++; | 295 i++; |
| 361 | 296 |
| 362 if (tileMode == kClamp_TileMode) { | 297 if (tileMode == kClamp_TileMode) { |
| 363 SkASSERT(i <= fLastInterval); | 298 SkASSERT(i <= fLastInterval); |
| 364 return i; | 299 return i; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 377 SkASSERT(fAdvX > 0); | 312 SkASSERT(fAdvX > 0); |
| 378 } while (advX >= fAdvX); | 313 } while (advX >= fAdvX); |
| 379 | 314 |
| 380 compute_interval_props(0); | 315 compute_interval_props(0); |
| 381 | 316 |
| 382 SkASSERT(advX >= 0); | 317 SkASSERT(advX >= 0); |
| 383 return advX; | 318 return advX; |
| 384 } | 319 } |
| 385 | 320 |
| 386 // Current interval properties. | 321 // Current interval properties. |
| 387 Sk4f fDc; // local color gradient (dc/dt) | |
| 388 Sk4f fDcDx; // dst color gradient (dc/dx) | 322 Sk4f fDcDx; // dst color gradient (dc/dx) |
| 389 Sk4f fCc; // current color, interpolated in dst | 323 Sk4f fCc; // current color, interpolated in dst |
| 390 SkScalar fAdvX; // remaining interval advance in dst | 324 SkScalar fAdvX; // remaining interval advance in dst |
| 391 bool fZeroRamp; // current interval color grad is 0 | 325 bool fZeroRamp; // current interval color grad is 0 |
| 392 | 326 |
| 393 const Interval* fFirstInterval; | 327 const Interval* fFirstInterval; |
| 394 const Interval* fLastInterval; | 328 const Interval* fLastInterval; |
| 395 const Interval* fInterval; // current interval | 329 const Interval* fInterval; // current interval |
| 396 const SkScalar fDx; // 'dx' for consistency with other impls; actual
ly dt/dx | 330 const SkScalar fDx; // 'dx' for consistency with other impls; actual
ly dt/dx |
| 397 const bool fIsVertical; | 331 const bool fIsVertical; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 | 403 |
| 470 void SkLinearGradient:: | 404 void SkLinearGradient:: |
| 471 LinearGradient4fContext::D32_BlitBW(BlitState* state, int x, int y, const SkPixm
ap& dst, | 405 LinearGradient4fContext::D32_BlitBW(BlitState* state, int x, int y, const SkPixm
ap& dst, |
| 472 int count) { | 406 int count) { |
| 473 // FIXME: ignoring coverage for now | 407 // FIXME: ignoring coverage for now |
| 474 const LinearGradient4fContext* ctx = | 408 const LinearGradient4fContext* ctx = |
| 475 static_cast<const LinearGradient4fContext*>(state->fCtx); | 409 static_cast<const LinearGradient4fContext*>(state->fCtx); |
| 476 | 410 |
| 477 if (dst.info().isLinear()) { | 411 if (dst.info().isLinear()) { |
| 478 if (ctx->fColorsArePremul) { | 412 if (ctx->fColorsArePremul) { |
| 479 ctx->shadePremulSpan<SkPMColor, kLinear_SkColorProfileType, ApplyPre
mul::False>( | 413 ctx->shadePremulSpan<DstType::L32, ApplyPremul::False>( |
| 480 x, y, dst.writable_addr32(x, y), count); | 414 x, y, dst.writable_addr32(x, y), count); |
| 481 } else { | 415 } else { |
| 482 ctx->shadePremulSpan<SkPMColor, kLinear_SkColorProfileType, ApplyPre
mul::True>( | 416 ctx->shadePremulSpan<DstType::L32, ApplyPremul::True>( |
| 483 x, y, dst.writable_addr32(x, y), count); | 417 x, y, dst.writable_addr32(x, y), count); |
| 484 } | 418 } |
| 485 } else { | 419 } else { |
| 486 if (ctx->fColorsArePremul) { | 420 if (ctx->fColorsArePremul) { |
| 487 ctx->shadePremulSpan<SkPMColor, kSRGB_SkColorProfileType, ApplyPremu
l::False>( | 421 ctx->shadePremulSpan<DstType::S32, ApplyPremul::False>( |
| 488 x, y, dst.writable_addr32(x, y), count); | 422 x, y, dst.writable_addr32(x, y), count); |
| 489 } else { | 423 } else { |
| 490 ctx->shadePremulSpan<SkPMColor, kSRGB_SkColorProfileType, ApplyPremu
l::True>( | 424 ctx->shadePremulSpan<DstType::S32, ApplyPremul::True>( |
| 491 x, y, dst.writable_addr32(x, y), count); | 425 x, y, dst.writable_addr32(x, y), count); |
| 492 } | 426 } |
| 493 } | 427 } |
| 494 } | 428 } |
| 495 | 429 |
| 496 void SkLinearGradient:: | 430 void SkLinearGradient:: |
| 497 LinearGradient4fContext::D64_BlitBW(BlitState* state, int x, int y, const SkPixm
ap& dst, | 431 LinearGradient4fContext::D64_BlitBW(BlitState* state, int x, int y, const SkPixm
ap& dst, |
| 498 int count) { | 432 int count) { |
| 499 // FIXME: ignoring coverage for now | 433 // FIXME: ignoring coverage for now |
| 500 const LinearGradient4fContext* ctx = | 434 const LinearGradient4fContext* ctx = |
| 501 static_cast<const LinearGradient4fContext*>(state->fCtx); | 435 static_cast<const LinearGradient4fContext*>(state->fCtx); |
| 502 | 436 |
| 503 if (ctx->fColorsArePremul) { | 437 if (ctx->fColorsArePremul) { |
| 504 ctx->shadePremulSpan<uint64_t, kLinear_SkColorProfileType, ApplyPremul::
False>( | 438 ctx->shadePremulSpan<DstType::F16, ApplyPremul::False>( |
| 505 x, y, dst.writable_addr64(x, y), count); | 439 x, y, dst.writable_addr64(x, y), count); |
| 506 } else { | 440 } else { |
| 507 ctx->shadePremulSpan<uint64_t, kLinear_SkColorProfileType, ApplyPremul::
True>( | 441 ctx->shadePremulSpan<DstType::F16, ApplyPremul::True>( |
| 508 x, y, dst.writable_addr64(x, y), count); | 442 x, y, dst.writable_addr64(x, y), count); |
| 509 } | 443 } |
| 510 } | 444 } |
| OLD | NEW |