diff options
author | 2016-04-14 09:02:14 -0700 | |
---|---|---|
committer | 2016-04-14 09:02:14 -0700 | |
commit | 3dc6aac5da2dbeb56cda025f3699cad72e1a4b4e (patch) | |
tree | d11f29b9ad16a38bcac7e4dd0814b372e7ef388b /src | |
parent | 82a455f0e9a7a50a399a58be906b48c24aeec056 (diff) |
remove U16 support, just support F16
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1889753002
Review URL: https://codereview.chromium.org/1889753002
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkBlitter.cpp | 3 | ||||
-rw-r--r-- | src/core/SkBlitter_PM4f.cpp | 37 | ||||
-rw-r--r-- | src/core/SkCoreBlitters.h | 10 | ||||
-rw-r--r-- | src/core/SkShader.cpp | 15 | ||||
-rw-r--r-- | src/core/SkSpriteBlitter4f.cpp | 8 | ||||
-rw-r--r-- | src/core/SkXfermodeF16.cpp | 178 | ||||
-rw-r--r-- | src/core/SkXfermodeU64.cpp | 239 |
7 files changed, 210 insertions, 280 deletions
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index 8f0031cd46..343160c4b4 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -938,8 +938,7 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, break; case kRGBA_F16_SkColorType: - // kU16_SkColorType: - blitter = SkBlitter_ARGB64_Create(device, *paint, shaderContext, allocator); + blitter = SkBlitter_F16_Create(device, *paint, shaderContext, allocator); break; default: diff --git a/src/core/SkBlitter_PM4f.cpp b/src/core/SkBlitter_PM4f.cpp index 820d72cc2e..bf332c5985 100644 --- a/src/core/SkBlitter_PM4f.cpp +++ b/src/core/SkBlitter_PM4f.cpp @@ -363,8 +363,8 @@ struct State32 : State4f { SkXfermode::LCD32Proc getLCDProc(uint32_t oneOrManyFlag) const { uint32_t flags = fFlags & 1; - if (!(fFlags & SkXfermode::kDstIsSRGB_D32Flag)) { - flags |= SkXfermode::kDstIsLinearInt_LCDFlag; + if (fFlags & SkXfermode::kDstIsSRGB_D32Flag) { + flags |= SkXfermode::kDstIsSRGB_LCDFlag; } return SkXfermode::GetLCD32Proc(flags | oneOrManyFlag); } @@ -374,31 +374,26 @@ struct State32 : State4f { } }; -struct State64 : State4f { +struct StateF16 : State4f { typedef uint64_t DstType; - SkXfermode::D64Proc fProc1; - SkXfermode::D64Proc fProcN; + SkXfermode::F16Proc fProc1; + SkXfermode::F16Proc fProcN; - State64(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) + StateF16(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) : State4f(info, paint, shaderContext) { if (is_opaque(paint, shaderContext)) { - fFlags |= SkXfermode::kSrcIsOpaque_D64Flag; + fFlags |= SkXfermode::kSrcIsOpaque_F16Flag; } - if (kRGBA_F16_SkColorType == info.colorType()) { - fFlags |= SkXfermode::kDstIsFloat16_D64Flag; - } - fProc1 = SkXfermode::GetD64Proc(fXfer, fFlags | SkXfermode::kSrcIsSingle_D64Flag); - fProcN = SkXfermode::GetD64Proc(fXfer, fFlags); + SkASSERT(kRGBA_F16_SkColorType == info.colorType()); + fProc1 = SkXfermode::GetF16Proc(fXfer, fFlags | SkXfermode::kSrcIsSingle_F16Flag); + fProcN = SkXfermode::GetF16Proc(fXfer, fFlags); } - SkXfermode::LCD64Proc getLCDProc(uint32_t oneOrManyFlag) const { + SkXfermode::LCDF16Proc getLCDProc(uint32_t oneOrManyFlag) const { uint32_t flags = fFlags & 1; - if (!(fFlags & SkXfermode::kDstIsFloat16_D64Flag)) { - flags |= SkXfermode::kDstIsLinearInt_LCDFlag; - } - return SkXfermode::GetLCD64Proc(flags | oneOrManyFlag); + return SkXfermode::GetLCDF16Proc(flags | oneOrManyFlag); } static DstType* WritableAddr(const SkPixmap& device, int x, int y) { @@ -434,8 +429,8 @@ SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint& paint, return create<State32>(device, paint, shaderContext, allocator); } -SkBlitter* SkBlitter_ARGB64_Create(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext, - SkTBlitterAllocator* allocator) { - return create<State64>(device, paint, shaderContext, allocator); +SkBlitter* SkBlitter_F16_Create(const SkPixmap& device, const SkPaint& paint, + SkShader::Context* shaderContext, + SkTBlitterAllocator* allocator) { + return create<StateF16>(device, paint, shaderContext, allocator); } diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h index ec9ee203ef..8fcfde6f76 100644 --- a/src/core/SkCoreBlitters.h +++ b/src/core/SkCoreBlitters.h @@ -185,13 +185,11 @@ private: typedef SkShaderBlitter INHERITED; }; -SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext, - SkTBlitterAllocator* allocator); +SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint&, SkShader::Context*, + SkTBlitterAllocator*); -SkBlitter* SkBlitter_ARGB64_Create(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext, - SkTBlitterAllocator* allocator); +SkBlitter* SkBlitter_F16_Create(const SkPixmap& device, const SkPaint&, SkShader::Context*, + SkTBlitterAllocator*); /////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp index 8032cc6e4c..0ed97b0223 100644 --- a/src/core/SkShader.cpp +++ b/src/core/SkShader.cpp @@ -375,16 +375,16 @@ static void D32_BlitAA(SkShader::Context::BlitState* state, int x, int y, const proc(state->fXfer, dst.writable_addr32(x, y), src, count, aa); } -static void D64_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst, +static void F16_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst, int count) { - SkXfermode::D64Proc proc = (SkXfermode::D64Proc)state->fStorage[0]; + SkXfermode::F16Proc proc = (SkXfermode::F16Proc)state->fStorage[0]; const SkPM4f* src = (const SkPM4f*)state->fStorage[1]; proc(state->fXfer, dst.writable_addr64(x, y), src, count, nullptr); } -static void D64_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst, +static void F16_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst, int count, const SkAlpha aa[]) { - SkXfermode::D64Proc proc = (SkXfermode::D64Proc)state->fStorage[0]; + SkXfermode::F16Proc proc = (SkXfermode::F16Proc)state->fStorage[0]; const SkPM4f* src = (const SkPM4f*)state->fStorage[1]; proc(state->fXfer, dst.writable_addr64(x, y), src, count, aa); } @@ -406,11 +406,10 @@ bool SkColorShader::ColorShaderContext::onChooseBlitProcs(const SkImageInfo& inf state->fBlitAA = D32_BlitAA; return true; case kRGBA_F16_SkColorType: - flags |= SkXfermode::kDstIsFloat16_D64Flag; - state->fStorage[0] = (void*)SkXfermode::GetD64Proc(state->fXfer, flags); + state->fStorage[0] = (void*)SkXfermode::GetF16Proc(state->fXfer, flags); state->fStorage[1] = &fPM4f; - state->fBlitBW = D64_BlitBW; - state->fBlitAA = D64_BlitAA; + state->fBlitBW = F16_BlitBW; + state->fBlitAA = F16_BlitAA; return true; default: return false; diff --git a/src/core/SkSpriteBlitter4f.cpp b/src/core/SkSpriteBlitter4f.cpp index 2561620379..a13edd9806 100644 --- a/src/core/SkSpriteBlitter4f.cpp +++ b/src/core/SkSpriteBlitter4f.cpp @@ -34,11 +34,11 @@ private: class Sprite_F16 : public Sprite_4f { public: Sprite_F16(const SkPixmap& src, const SkPaint& paint) : INHERITED(src, paint) { - uint32_t flags = SkXfermode::kDstIsFloat16_D64Flag; + uint32_t flags = 0; if (src.isOpaque()) { - flags |= SkXfermode::kSrcIsOpaque_D64Flag; + flags |= SkXfermode::kSrcIsOpaque_F16Flag; } - fWriter = SkXfermode::GetD64Proc(fXfer, flags); + fWriter = SkXfermode::GetF16Proc(fXfer, flags); } void blitRect(int x, int y, int width, int height) override { @@ -55,7 +55,7 @@ public: } private: - SkXfermode::D64Proc fWriter; + SkXfermode::F16Proc fWriter; typedef Sprite_4f INHERITED; }; diff --git a/src/core/SkXfermodeF16.cpp b/src/core/SkXfermodeF16.cpp new file mode 100644 index 0000000000..dfcefa2de5 --- /dev/null +++ b/src/core/SkXfermodeF16.cpp @@ -0,0 +1,178 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkHalf.h" +#include "SkPM4fPriv.h" +#include "SkUtils.h" +#include "SkXfermode.h" + +static Sk4f lerp_by_coverage(const Sk4f& src, const Sk4f& dst, uint8_t srcCoverage) { + return dst + (src - dst) * Sk4f(srcCoverage * (1/255.0f)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +static void xfer_1(const SkXfermode* xfer, uint64_t dst[], const SkPM4f* src, int count, + const SkAlpha aa[]) { + SkXfermodeProc4f proc = xfer->getProc4f(); + SkPM4f d; + if (aa) { + for (int i = 0; i < count; ++i) { + Sk4f d4 = SkHalfToFloat_01(dst[i]); + d4.store(d.fVec); + Sk4f r4 = Sk4f::Load(proc(*src, d).fVec); + dst[i] = SkFloatToHalf_01(lerp_by_coverage(r4, d4, aa[i])); + } + } else { + for (int i = 0; i < count; ++i) { + SkHalfToFloat_01(dst[i]).store(d.fVec); + Sk4f r4 = Sk4f::Load(proc(*src, d).fVec); + dst[i] = SkFloatToHalf_01(r4); + } + } +} + +static void xfer_n(const SkXfermode* xfer, uint64_t dst[], const SkPM4f src[], int count, + const SkAlpha aa[]) { + SkXfermodeProc4f proc = xfer->getProc4f(); + SkPM4f d; + if (aa) { + for (int i = 0; i < count; ++i) { + Sk4f d4 = SkHalfToFloat_01(dst[i]); + d4.store(d.fVec); + Sk4f r4 = Sk4f::Load(proc(src[i], d).fVec); + dst[i] = SkFloatToHalf_01(lerp_by_coverage(r4, d4, aa[i])); + } + } else { + for (int i = 0; i < count; ++i) { + SkHalfToFloat_01(dst[i]).store(d.fVec); + Sk4f r4 = Sk4f::Load(proc(src[i], d).fVec); + dst[i] = SkFloatToHalf_01(r4); + } + } +} + +const SkXfermode::F16Proc gProcs_General[] = { xfer_n, xfer_n, xfer_1, xfer_1 }; + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +static void clear(const SkXfermode*, uint64_t dst[], const SkPM4f*, int count, const SkAlpha aa[]) { + if (aa) { + for (int i = 0; i < count; ++i) { + if (aa[i]) { + const Sk4f d4 = SkHalfToFloat_01(dst[i]); + dst[i] = SkFloatToHalf_01(d4 * Sk4f((255 - aa[i]) * 1.0f/255)); + } + } + } else { + sk_memset64(dst, 0, count); + } +} + +const SkXfermode::F16Proc gProcs_Clear[] = { clear, clear, clear, clear }; + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +static void src_1(const SkXfermode*, uint64_t dst[], const SkPM4f* src, int count, + const SkAlpha aa[]) { + const Sk4f s4 = Sk4f::Load(src->fVec); + if (aa) { + for (int i = 0; i < count; ++i) { + const Sk4f d4 = SkHalfToFloat_01(dst[i]); + dst[i] = SkFloatToHalf_01(lerp_by_coverage(s4, d4, aa[i])); + } + } else { + sk_memset64(dst, SkFloatToHalf_01(s4), count); + } +} + +static void src_n(const SkXfermode*, uint64_t dst[], const SkPM4f src[], int count, + const SkAlpha aa[]) { + if (aa) { + for (int i = 0; i < count; ++i) { + const Sk4f s4 = Sk4f::Load(src[i].fVec); + const Sk4f d4 = SkHalfToFloat_01(dst[i]); + dst[i] = SkFloatToHalf_01(lerp_by_coverage(s4, d4, aa[i])); + } + } else { + for (int i = 0; i < count; ++i) { + const Sk4f s4 = Sk4f::Load(src[i].fVec); + dst[i] = SkFloatToHalf_01(s4); + } + } +} + +const SkXfermode::F16Proc gProcs_Src[] = { src_n, src_n, src_1, src_1 }; + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +static void dst(const SkXfermode*, uint64_t*, const SkPM4f*, int count, const SkAlpha[]) {} + +const SkXfermode::F16Proc gProcs_Dst[] = { dst, dst, dst, dst }; + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +static void srcover_1(const SkXfermode*, uint64_t dst[], const SkPM4f* src, int count, + const SkAlpha aa[]) { + const Sk4f s4 = Sk4f::Load(src->fVec); + const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); + for (int i = 0; i < count; ++i) { + const Sk4f d4 = SkHalfToFloat_01(dst[i]); + const Sk4f r4 = s4 + d4 * dst_scale; + if (aa) { + dst[i] = SkFloatToHalf_01(lerp_by_coverage(r4, d4, aa[i])); + } else { + dst[i] = SkFloatToHalf_01(r4); + } + } +} + +static void srcover_n(const SkXfermode*, uint64_t dst[], const SkPM4f src[], int count, + const SkAlpha aa[]) { + for (int i = 0; i < count; ++i) { + const Sk4f s4 = Sk4f::Load(src[i].fVec); + const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); + const Sk4f d4 = SkHalfToFloat_01(dst[i]); + const Sk4f r4 = s4 + d4 * dst_scale; + if (aa) { + dst[i] = SkFloatToHalf_01(lerp_by_coverage(r4, d4, aa[i])); + } else { + dst[i] = SkFloatToHalf_01(r4); + } + } +} + +const SkXfermode::F16Proc gProcs_SrcOver[] = { srcover_n, src_n, srcover_1, src_1 }; + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +static SkXfermode::F16Proc find_proc(SkXfermode::Mode mode, uint32_t flags) { + SkASSERT(0 == (flags & ~3)); + flags &= 3; + + switch (mode) { + case SkXfermode::kClear_Mode: return gProcs_Clear[flags]; + case SkXfermode::kSrc_Mode: return gProcs_Src[flags]; + case SkXfermode::kDst_Mode: return gProcs_Dst[flags]; + case SkXfermode::kSrcOver_Mode: return gProcs_SrcOver[flags]; + default: + break; + } + return gProcs_General[flags]; +} + +SkXfermode::F16Proc SkXfermode::onGetF16Proc(uint32_t flags) const { + SkASSERT(0 == (flags & ~3)); + flags &= 3; + + Mode mode; + return this->asMode(&mode) ? find_proc(mode, flags) : gProcs_General[flags]; +} + +SkXfermode::F16Proc SkXfermode::GetF16Proc(SkXfermode* xfer, uint32_t flags) { + return xfer ? xfer->onGetF16Proc(flags) : find_proc(SkXfermode::kSrcOver_Mode, flags); +} diff --git a/src/core/SkXfermodeU64.cpp b/src/core/SkXfermodeU64.cpp deleted file mode 100644 index 2cf3e1b97e..0000000000 --- a/src/core/SkXfermodeU64.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkHalf.h" -#include "SkPM4fPriv.h" -#include "SkUtils.h" -#include "SkXfermode.h" - -enum DstType { - kU16_Dst, - kF16_Dst, -}; - -static Sk4f lerp_by_coverage(const Sk4f& src, const Sk4f& dst, uint8_t srcCoverage) { - return dst + (src - dst) * Sk4f(srcCoverage * (1/255.0f)); -} - -template <DstType D> Sk4f unit_to_bias(const Sk4f& x4) { - return (D == kU16_Dst) ? x4 * Sk4f(65535) : x4; -} - -template <DstType D> Sk4f bias_to_unit(const Sk4f& x4) { - return (D == kU16_Dst) ? x4 * Sk4f(1.0f/65535) : x4; -} - -// returns value already biased by 65535 -static Sk4f load_from_u16(uint64_t value) { - return SkNx_cast<float>(Sk4h::Load(&value)); -} - -// takes floats already biased by 65535 -static uint64_t store_to_u16(const Sk4f& x4) { - uint64_t value; - SkNx_cast<uint16_t>(x4 + Sk4f(0.5f)).store(&value); - return value; -} - -// Returns dst in its "natural" bias (either unit-float or 16bit int) -// -template <DstType D> Sk4f load_from_dst(uint64_t dst) { - return (D == kU16_Dst) ? load_from_u16(dst) : SkHalfToFloat_01(dst); -} - -// Assumes x4 is already in the "natural" bias (either unit-float or 16bit int) -template <DstType D> uint64_t store_to_dst(const Sk4f& x4) { - return (D == kU16_Dst) ? store_to_u16(x4) : SkFloatToHalf_01(x4); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -template <DstType D> void xfer_u64_1(const SkXfermode* xfer, uint64_t dst[], - const SkPM4f* src, int count, const SkAlpha aa[]) { - SkXfermodeProc4f proc = xfer->getProc4f(); - SkPM4f d; - if (aa) { - for (int i = 0; i < count; ++i) { - Sk4f d4 = bias_to_unit<D>(load_from_dst<D>(dst[i])); - d4.store(d.fVec); - Sk4f r4 = unit_to_bias<D>(Sk4f::Load(proc(*src, d).fVec)); - dst[i] = store_to_dst<D>(lerp_by_coverage(r4, d4, aa[i])); - } - } else { - for (int i = 0; i < count; ++i) { - bias_to_unit<D>(load_from_dst<D>(dst[i])).store(d.fVec); - Sk4f r4 = unit_to_bias<D>(Sk4f::Load(proc(*src, d).fVec)); - dst[i] = store_to_dst<D>(r4); - } - } -} - -template <DstType D> void xfer_u64_n(const SkXfermode* xfer, uint64_t dst[], - const SkPM4f src[], int count, const SkAlpha aa[]) { - SkXfermodeProc4f proc = xfer->getProc4f(); - SkPM4f d; - if (aa) { - for (int i = 0; i < count; ++i) { - Sk4f d4 = bias_to_unit<D>(load_from_dst<D>(dst[i])); - d4.store(d.fVec); - Sk4f r4 = unit_to_bias<D>(Sk4f::Load(proc(src[i], d).fVec)); - dst[i] = store_to_dst<D>(lerp_by_coverage(r4, d4, aa[i])); - } - } else { - for (int i = 0; i < count; ++i) { - bias_to_unit<D>(load_from_dst<D>(dst[i])).store(d.fVec); - Sk4f r4 = unit_to_bias<D>(Sk4f::Load(proc(src[i], d).fVec)); - dst[i] = store_to_dst<D>(r4); - } - } -} - -const SkXfermode::D64Proc gProcs_General[] = { - xfer_u64_n<kU16_Dst>, xfer_u64_n<kU16_Dst>, - xfer_u64_1<kU16_Dst>, xfer_u64_1<kU16_Dst>, - xfer_u64_n<kF16_Dst>, xfer_u64_n<kF16_Dst>, - xfer_u64_1<kF16_Dst>, xfer_u64_1<kF16_Dst>, -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -template <DstType D> void clear(const SkXfermode*, uint64_t dst[], - const SkPM4f*, int count, const SkAlpha aa[]) { - if (aa) { - for (int i = 0; i < count; ++i) { - if (aa[i]) { - const Sk4f d4 = load_from_dst<D>(dst[i]); - dst[i] = store_to_dst<D>(d4 * Sk4f((255 - aa[i]) * 1.0f/255)); - } - } - } else { - sk_memset64(dst, 0, count); - } -} - -const SkXfermode::D64Proc gProcs_Clear[] = { - clear<kU16_Dst>, clear<kU16_Dst>, - clear<kU16_Dst>, clear<kU16_Dst>, - clear<kF16_Dst>, clear<kF16_Dst>, - clear<kF16_Dst>, clear<kF16_Dst>, -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -template <DstType D> void src_1(const SkXfermode*, uint64_t dst[], - const SkPM4f* src, int count, const SkAlpha aa[]) { - const Sk4f s4 = unit_to_bias<D>(Sk4f::Load(src->fVec)); - if (aa) { - for (int i = 0; i < count; ++i) { - const Sk4f d4 = load_from_dst<D>(dst[i]); - dst[i] = store_to_dst<D>(lerp_by_coverage(s4, d4, aa[i])); - } - } else { - sk_memset64(dst, store_to_dst<D>(s4), count); - } -} - -template <DstType D> void src_n(const SkXfermode*, uint64_t dst[], - const SkPM4f src[], int count, const SkAlpha aa[]) { - if (aa) { - for (int i = 0; i < count; ++i) { - const Sk4f s4 = unit_to_bias<D>(Sk4f::Load(src[i].fVec)); - const Sk4f d4 = load_from_dst<D>(dst[i]); - dst[i] = store_to_dst<D>(lerp_by_coverage(s4, d4, aa[i])); - } - } else { - for (int i = 0; i < count; ++i) { - const Sk4f s4 = unit_to_bias<D>(Sk4f::Load(src[i].fVec)); - dst[i] = store_to_dst<D>(s4); - } - } -} - -const SkXfermode::D64Proc gProcs_Src[] = { - src_n<kU16_Dst>, src_n<kU16_Dst>, - src_1<kU16_Dst>, src_1<kU16_Dst>, - src_n<kF16_Dst>, src_n<kF16_Dst>, - src_1<kF16_Dst>, src_1<kF16_Dst>, -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -static void dst(const SkXfermode*, uint64_t*, const SkPM4f*, int count, const SkAlpha[]) {} - -const SkXfermode::D64Proc gProcs_Dst[] = { - dst, dst, dst, dst, dst, dst, dst, dst, -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -template <DstType D> void srcover_1(const SkXfermode*, uint64_t dst[], - const SkPM4f* src, int count, const SkAlpha aa[]) { - const Sk4f s4 = Sk4f::Load(src->fVec); - const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); - const Sk4f s4bias = unit_to_bias<D>(s4); - for (int i = 0; i < count; ++i) { - const Sk4f d4bias = load_from_dst<D>(dst[i]); - const Sk4f r4bias = s4bias + d4bias * dst_scale; - if (aa) { - dst[i] = store_to_dst<D>(lerp_by_coverage(r4bias, d4bias, aa[i])); - } else { - dst[i] = store_to_dst<D>(r4bias); - } - } -} - -template <DstType D> void srcover_n(const SkXfermode*, uint64_t dst[], - const SkPM4f src[], int count, const SkAlpha aa[]) { - for (int i = 0; i < count; ++i) { - const Sk4f s4 = Sk4f::Load(src[i].fVec); - const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); - const Sk4f s4bias = unit_to_bias<D>(s4); - const Sk4f d4bias = load_from_dst<D>(dst[i]); - const Sk4f r4bias = s4bias + d4bias * dst_scale; - if (aa) { - dst[i] = store_to_dst<D>(lerp_by_coverage(r4bias, d4bias, aa[i])); - } else { - dst[i] = store_to_dst<D>(r4bias); - } - } -} - -const SkXfermode::D64Proc gProcs_SrcOver[] = { - srcover_n<kU16_Dst>, src_n<kU16_Dst>, - srcover_1<kU16_Dst>, src_1<kU16_Dst>, - srcover_n<kF16_Dst>, src_n<kF16_Dst>, - srcover_1<kF16_Dst>, src_1<kF16_Dst>, -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -static SkXfermode::D64Proc find_proc(SkXfermode::Mode mode, uint32_t flags) { - SkASSERT(0 == (flags & ~7)); - flags &= 7; - - switch (mode) { - case SkXfermode::kClear_Mode: return gProcs_Clear[flags]; - case SkXfermode::kSrc_Mode: return gProcs_Src[flags]; - case SkXfermode::kDst_Mode: return gProcs_Dst[flags]; - case SkXfermode::kSrcOver_Mode: return gProcs_SrcOver[flags]; - default: - break; - } - return gProcs_General[flags]; -} - -SkXfermode::D64Proc SkXfermode::onGetD64Proc(uint32_t flags) const { - SkASSERT(0 == (flags & ~7)); - flags &= 7; - - Mode mode; - return this->asMode(&mode) ? find_proc(mode, flags) : gProcs_General[flags]; -} - -SkXfermode::D64Proc SkXfermode::GetD64Proc(SkXfermode* xfer, uint32_t flags) { - return xfer ? xfer->onGetD64Proc(flags) : find_proc(SkXfermode::kSrcOver_Mode, flags); -} |