get familiar with SkBlitMask_D32.cpp
- some refactoring - remove SK_RESTRICT - try to remove SK_SUPPORT_LEGACY_A8_MASKBLITTER Change-Id: I3a270fa2423a66f6e49e5f4f89593a27a9a26e9f Reviewed-on: https://skia-review.googlesource.com/c/170061 Reviewed-by: Mike Klein <mtklein@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
parent
919c9e77c3
commit
a3741a6152
@ -24,8 +24,8 @@ SkBlitMask::BlitLCD16RowProc SkBlitMask::BlitLCD16RowFactory(bool isOpaque) {
|
||||
}
|
||||
}
|
||||
|
||||
static void D32_LCD16_Proc(void* SK_RESTRICT dst, size_t dstRB,
|
||||
const void* SK_RESTRICT mask, size_t maskRB,
|
||||
static void D32_LCD16_Proc(void* dst, size_t dstRB,
|
||||
const void* mask, size_t maskRB,
|
||||
SkColor color, int width, int height) {
|
||||
|
||||
SkPMColor* dstRow = (SkPMColor*)dst;
|
||||
@ -50,11 +50,12 @@ static void D32_LCD16_Proc(void* SK_RESTRICT dst, size_t dstRB,
|
||||
} while (--height != 0);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SkBlitMask::BlitColor(const SkPixmap& device, const SkMask& mask,
|
||||
const SkIRect& clip, SkColor color) {
|
||||
int x = clip.fLeft, y = clip.fTop;
|
||||
bool SkBlitMask::BlitColor(const SkPixmap& device,
|
||||
const SkMask& mask,
|
||||
const SkIRect& clip,
|
||||
SkColor color) {
|
||||
int x = clip.fLeft,
|
||||
y = clip.fTop;
|
||||
|
||||
if (device.colorType() == kN32_SkColorType && mask.fFormat == SkMask::kA8_Format) {
|
||||
SkOpts::blit_mask_d32_a8(device.writable_addr32(x,y), device.rowBytes(),
|
||||
@ -64,7 +65,6 @@ bool SkBlitMask::BlitColor(const SkPixmap& device, const SkMask& mask,
|
||||
}
|
||||
|
||||
if (device.colorType() == kN32_SkColorType && mask.fFormat == SkMask::kLCD16_Format) {
|
||||
// TODO: Is this reachable code? Seems like no.
|
||||
D32_LCD16_Proc(device.writable_addr32(x,y), device.rowBytes(),
|
||||
mask.getAddr(x,y), mask.fRowBytes,
|
||||
color, clip.width(), clip.height());
|
||||
@ -74,83 +74,35 @@ bool SkBlitMask::BlitColor(const SkPixmap& device, const SkMask& mask,
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void A8_RowProc_Blend(
|
||||
SkPMColor* SK_RESTRICT dst, const void* maskIn, const SkPMColor* SK_RESTRICT src, int count) {
|
||||
const uint8_t* SK_RESTRICT mask = static_cast<const uint8_t*>(maskIn);
|
||||
static void A8_RowProc_Blend(SkPMColor* dst, const void* vmask, const SkPMColor* src, int n) {
|
||||
auto mask = (const uint8_t*)vmask;
|
||||
|
||||
#ifndef SK_SUPPORT_LEGACY_A8_MASKBLITTER
|
||||
Sk4px::MapDstSrcAlpha(count, dst, src, mask,
|
||||
[](const Sk4px& d, const Sk4px& s, const Sk4px& aa) {
|
||||
const auto s_aa = s.approxMulDiv255(aa);
|
||||
return s_aa + d.approxMulDiv255(s_aa.alphas().inv());
|
||||
});
|
||||
#else
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (mask[i]) {
|
||||
dst[i] = SkBlendARGB32(src[i], dst[i], mask[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Sk4px::MapDstSrcAlpha(n, dst, src, mask, [](const Sk4px& d, const Sk4px& s, const Sk4px& aa) {
|
||||
const auto s_aa = s.approxMulDiv255(aa);
|
||||
return s_aa + d.approxMulDiv255(s_aa.alphas().inv());
|
||||
});
|
||||
}
|
||||
|
||||
// expand the steps that SkAlphaMulQ performs, but this way we can
|
||||
// exand.. add.. combine
|
||||
// instead of
|
||||
// expand..combine add expand..combine
|
||||
//
|
||||
#define EXPAND0(v, m, s) ((v) & (m)) * (s)
|
||||
#define EXPAND1(v, m, s) (((v) >> 8) & (m)) * (s)
|
||||
#define COMBINE(e0, e1, m) ((((e0) >> 8) & (m)) | ((e1) & ~(m)))
|
||||
static void A8_RowProc_Opaque(SkPMColor* dst, const void* vmask, const SkPMColor* src, int n) {
|
||||
auto mask = (const uint8_t*)vmask;
|
||||
|
||||
static void A8_RowProc_Opaque(
|
||||
SkPMColor* SK_RESTRICT dst, const void* maskIn, const SkPMColor* SK_RESTRICT src, int count) {
|
||||
const uint8_t* SK_RESTRICT mask = static_cast<const uint8_t*>(maskIn);
|
||||
|
||||
#ifndef SK_SUPPORT_LEGACY_A8_MASKBLITTER
|
||||
Sk4px::MapDstSrcAlpha(count, dst, src, mask,
|
||||
[](const Sk4px& d, const Sk4px& s, const Sk4px& aa) {
|
||||
return (s * aa + d * aa.inv()).div255();
|
||||
});
|
||||
#else
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int m = mask[i];
|
||||
if (m) {
|
||||
m += (m >> 7);
|
||||
#if 1
|
||||
// this is slightly slower than the expand/combine version, but it
|
||||
// is much closer to the old results, so we use it for now to reduce
|
||||
// rebaselining.
|
||||
dst[i] = SkAlphaMulQ(src[i], m) + SkAlphaMulQ(dst[i], 256 - m);
|
||||
#else
|
||||
uint32_t v = src[i];
|
||||
uint32_t s0 = EXPAND0(v, rbmask, m);
|
||||
uint32_t s1 = EXPAND1(v, rbmask, m);
|
||||
v = dst[i];
|
||||
uint32_t d0 = EXPAND0(v, rbmask, m);
|
||||
uint32_t d1 = EXPAND1(v, rbmask, m);
|
||||
dst[i] = COMBINE(s0 + d0, s1 + d1, rbmask);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // SK_SUPPORT_LEGACY_A8_MASKBLITTER
|
||||
Sk4px::MapDstSrcAlpha(n, dst, src, mask, [](const Sk4px& d, const Sk4px& s, const Sk4px& aa) {
|
||||
return (s * aa + d * aa.inv()).div255();
|
||||
});
|
||||
}
|
||||
|
||||
static int upscale31To255(int value) {
|
||||
value = (value << 3) | (value >> 2);
|
||||
return value;
|
||||
}
|
||||
static void LCD16_RowProc_Blend(SkPMColor* dst, const void* maskIn, const SkPMColor* src, int n) {
|
||||
|
||||
static int src_alpha_blend(int src, int dst, int srcA, int mask) {
|
||||
auto src_alpha_blend = [](int s, int d, int sa, int m) {
|
||||
return d + SkAlphaMul(s - SkAlphaMul(sa, d), m);
|
||||
};
|
||||
|
||||
return dst + SkAlphaMul(src - SkAlphaMul(srcA, dst), mask);
|
||||
}
|
||||
auto upscale_31_to_255 = [](int v) {
|
||||
return (v << 3) | (v >> 2);
|
||||
};
|
||||
|
||||
static void LCD16_RowProc_Blend(
|
||||
SkPMColor* SK_RESTRICT dst, const void* maskIn, const SkPMColor* SK_RESTRICT src, int count) {
|
||||
const uint16_t* SK_RESTRICT mask = static_cast<const uint16_t*>(maskIn);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
auto mask = (const uint16_t*)maskIn;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
uint16_t m = mask[i];
|
||||
if (0 == m) {
|
||||
continue;
|
||||
@ -166,34 +118,28 @@ static void LCD16_RowProc_Blend(
|
||||
|
||||
srcA += srcA >> 7;
|
||||
|
||||
/* We want all of these in 5bits, hence the shifts in case one of them
|
||||
* (green) is 6bits.
|
||||
*/
|
||||
// We're ignoring the least significant bit of the green coverage channel here.
|
||||
int maskR = SkGetPackedR16(m) >> (SK_R16_BITS - 5);
|
||||
int maskG = SkGetPackedG16(m) >> (SK_G16_BITS - 5);
|
||||
int maskB = SkGetPackedB16(m) >> (SK_B16_BITS - 5);
|
||||
|
||||
maskR = upscale31To255(maskR);
|
||||
maskG = upscale31To255(maskG);
|
||||
maskB = upscale31To255(maskB);
|
||||
// Scale up to 8-bit coverage to work with SkAlphaMul() in src_alpha_blend().
|
||||
maskR = upscale_31_to_255(maskR);
|
||||
maskG = upscale_31_to_255(maskG);
|
||||
maskB = upscale_31_to_255(maskB);
|
||||
|
||||
int dstR = SkGetPackedR32(d);
|
||||
int dstG = SkGetPackedG32(d);
|
||||
int dstB = SkGetPackedB32(d);
|
||||
|
||||
// LCD blitting is only supported if the dst is known/required
|
||||
// to be opaque
|
||||
// This LCD blit routine only works if the destination is opaque.
|
||||
dst[i] = SkPackARGB32(0xFF,
|
||||
src_alpha_blend(srcR, dstR, srcA, maskR),
|
||||
src_alpha_blend(srcG, dstG, srcA, maskG),
|
||||
src_alpha_blend(srcB, dstB, srcA, maskB));
|
||||
src_alpha_blend(srcR, SkGetPackedR32(d), srcA, maskR),
|
||||
src_alpha_blend(srcG, SkGetPackedG32(d), srcA, maskG),
|
||||
src_alpha_blend(srcB, SkGetPackedB32(d), srcA, maskB));
|
||||
}
|
||||
}
|
||||
|
||||
static void LCD16_RowProc_Opaque(
|
||||
SkPMColor* SK_RESTRICT dst, const void* maskIn, const SkPMColor* SK_RESTRICT src, int count) {
|
||||
const uint16_t* SK_RESTRICT mask = static_cast<const uint16_t*>(maskIn);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
static void LCD16_RowProc_Opaque(SkPMColor* dst, const void* vmask, const SkPMColor* src, int n) {
|
||||
auto mask = (const uint16_t*)vmask;
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
uint16_t m = mask[i];
|
||||
if (0 == m) {
|
||||
continue;
|
||||
@ -206,28 +152,21 @@ static void LCD16_RowProc_Opaque(
|
||||
int srcG = SkGetPackedG32(s);
|
||||
int srcB = SkGetPackedB32(s);
|
||||
|
||||
/* We want all of these in 5bits, hence the shifts in case one of them
|
||||
* (green) is 6bits.
|
||||
*/
|
||||
// We're ignoring the least significant bit of the green coverage channel here.
|
||||
int maskR = SkGetPackedR16(m) >> (SK_R16_BITS - 5);
|
||||
int maskG = SkGetPackedG16(m) >> (SK_G16_BITS - 5);
|
||||
int maskB = SkGetPackedB16(m) >> (SK_B16_BITS - 5);
|
||||
|
||||
// Now upscale them to 0..32, so we can use blend32
|
||||
// Now upscale them to 0..32, so we can use SkBlend32.
|
||||
maskR = SkUpscale31To32(maskR);
|
||||
maskG = SkUpscale31To32(maskG);
|
||||
maskB = SkUpscale31To32(maskB);
|
||||
|
||||
int dstR = SkGetPackedR32(d);
|
||||
int dstG = SkGetPackedG32(d);
|
||||
int dstB = SkGetPackedB32(d);
|
||||
|
||||
// LCD blitting is only supported if the dst is known/required
|
||||
// to be opaque
|
||||
// This LCD blit routine only works if the destination is opaque.
|
||||
dst[i] = SkPackARGB32(0xFF,
|
||||
SkBlend32(srcR, dstR, maskR),
|
||||
SkBlend32(srcG, dstG, maskG),
|
||||
SkBlend32(srcB, dstB, maskB));
|
||||
SkBlend32(srcR, SkGetPackedR32(d), maskR),
|
||||
SkBlend32(srcG, SkGetPackedG32(d), maskG),
|
||||
SkBlend32(srcB, SkGetPackedB32(d), maskB));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user