void SkRasterPipelineBlitter::blitH(int x, int y, int w) { fDstPtr = fDst.writable_addr(0,y); if (fCanMemsetInBlitH) { switch (fDst.shiftPerPixel()) { case 0: memset ((uint8_t *)fDstPtr + x, fMemsetColor, w); return; case 1: sk_memset16((uint16_t*)fDstPtr + x, fMemsetColor, w); return; case 2: sk_memset32((uint32_t*)fDstPtr + x, fMemsetColor, w); return; case 3: sk_memset64((uint64_t*)fDstPtr + x, fMemsetColor, w); return; default: break; } } if (!fBlitH) { SkRasterPipeline p(fAlloc); p.extend(fColorPipeline); if (fBlend == SkBlendMode::kSrcOver && fDst.info().colorType() == kRGBA_8888_SkColorType && !fDst.colorSpace() && fDst.info().alphaType() != kUnpremul_SkAlphaType && fDitherRate == 0.0f) { p.append(SkRasterPipeline::srcover_rgba_8888, &fDstPtr); } else { if (fBlend != SkBlendMode::kSrc) { this->append_load_d(&p); this->append_blend(&p); this->maybe_clamp(&p); } this->append_store(&p); } fBlitH = p.compile(); } this->maybe_shade(x,y,w); fBlitH(x,y,w); }
bool SkPixmap::erase(const SkColor4f& origColor, const SkIRect* subset) const { SkPixmap pm; if (subset) { if (!this->extractSubset(&pm, *subset)) { return false; } } else { pm = *this; } const SkColor4f color = origColor.pin(); if (kRGBA_F16_SkColorType != pm.colorType()) { Sk4f c4 = Sk4f::Load(color.vec()); SkColor c; (c4 * Sk4f(255) + Sk4f(0.5f)).store(&c); return pm.erase(c); } const uint64_t half4 = color.premul().toF16(); for (int y = 0; y < pm.height(); ++y) { sk_memset64(pm.writable_addr64(0, y), half4, pm.width()); } return true; }
void SkRasterPipelineBlitter::blitH(int x, int y, int w) { fDstPtr = fDst.writable_addr(0,y); fCurrentY = y; if (fCanMemsetInBlitH) { switch (fDst.shiftPerPixel()) { case 0: memset ((uint8_t *)fDstPtr + x, fMemsetColor, w); return; case 1: sk_memset16((uint16_t*)fDstPtr + x, fMemsetColor, w); return; case 2: sk_memset32((uint32_t*)fDstPtr + x, fMemsetColor, w); return; case 3: sk_memset64((uint64_t*)fDstPtr + x, fMemsetColor, w); return; default: break; } } auto& p = fBlitH; if (p.empty()) { p.extend(fShader); if (fBlend != SkBlendMode::kSrc) { this->append_load_d(&p); this->append_blend(&p); this->maybe_clamp(&p); } this->append_store(&p); } p.run(x,w); }
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_finite_ftz(dst[i]); SkFloatToHalf_finite_ftz(d4 * Sk4f((255 - aa[i]) * 1.0f/255)).store(&dst[i]); } } } else { sk_memset64(dst, 0, count); } }
template <DstType D> void src_1(const SkXfermode::U64State& state, uint64_t dst[], const SkPM4f& src, int count, const SkAlpha aa[]) { const Sk4f s4 = pm_to_rgba_order(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); } }
void SkSampler::Fill(const SkImageInfo& info, void* dst, size_t rowBytes, SkCodec::ZeroInitialized zeroInit) { SkASSERT(dst != nullptr); if (SkCodec::kYes_ZeroInitialized == zeroInit) { return; } const int width = info.width(); const int numRows = info.height(); // Use the proper memset routine to fill the remaining bytes switch (info.colorType()) { case kRGBA_8888_SkColorType: case kBGRA_8888_SkColorType: { uint32_t* dstRow = (uint32_t*) dst; for (int row = 0; row < numRows; row++) { sk_memset32(dstRow, 0, width); dstRow = SkTAddOffset<uint32_t>(dstRow, rowBytes); } break; } case kRGB_565_SkColorType: { uint16_t* dstRow = (uint16_t*) dst; for (int row = 0; row < numRows; row++) { sk_memset16(dstRow, 0, width); dstRow = SkTAddOffset<uint16_t>(dstRow, rowBytes); } break; } case kGray_8_SkColorType: { uint8_t* dstRow = (uint8_t*) dst; for (int row = 0; row < numRows; row++) { memset(dstRow, 0, width); dstRow = SkTAddOffset<uint8_t>(dstRow, rowBytes); } break; } case kRGBA_F16_SkColorType: { uint64_t* dstRow = (uint64_t*) dst; for (int row = 0; row < numRows; row++) { sk_memset64(dstRow, 0, width); dstRow = SkTAddOffset<uint64_t>(dstRow, rowBytes); } break; } default: SkCodecPrintf("Error: Unsupported dst color type for fill(). Doing nothing.\n"); SkASSERT(false); break; } }
static void src_1(SkBlendMode, 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_finite_ftz(dst[i]); SkFloatToHalf_finite_ftz(lerp_by_coverage(s4, d4, aa[i])).store(&dst[i]); } } else { uint64_t s4h; SkFloatToHalf_finite_ftz(s4).store(&s4h); sk_memset64(dst, s4h, count); } }
void SkSampler::Fill(const SkImageInfo& info, void* dst, size_t rowBytes, uint64_t colorOrIndex, SkCodec::ZeroInitialized zeroInit) { SkASSERT(dst != nullptr); // Calculate bytes to fill. const size_t bytesToFill = info.computeByteSize(rowBytes); const int width = info.width(); const int numRows = info.height(); // Use the proper memset routine to fill the remaining bytes switch (info.colorType()) { case kRGBA_8888_SkColorType: case kBGRA_8888_SkColorType: { // If memory is zero initialized, we may not need to fill uint32_t color = (uint32_t) colorOrIndex; if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) { return; } uint32_t* dstRow = (uint32_t*) dst; for (int row = 0; row < numRows; row++) { sk_memset32((uint32_t*) dstRow, color, width); dstRow = SkTAddOffset<uint32_t>(dstRow, rowBytes); } break; } case kRGB_565_SkColorType: { // If the destination is k565, the caller passes in a 16-bit color. // We will not assert that the high bits of colorOrIndex must be zeroed. // This allows us to take advantage of the fact that the low 16 bits of an // SKPMColor may be a valid a 565 color. For example, the low 16 // bits of SK_ColorBLACK are identical to the 565 representation // for black. // If memory is zero initialized, we may not need to fill uint16_t color = (uint16_t) colorOrIndex; if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) { return; } uint16_t* dstRow = (uint16_t*) dst; for (int row = 0; row < numRows; row++) { sk_memset16((uint16_t*) dstRow, color, width); dstRow = SkTAddOffset<uint16_t>(dstRow, rowBytes); } break; } case kGray_8_SkColorType: // If the destination is kGray, the caller passes in an 8-bit color. // We will not assert that the high bits of colorOrIndex must be zeroed. // This allows us to take advantage of the fact that the low 8 bits of an // SKPMColor may be a valid a grayscale color. For example, the low 8 // bits of SK_ColorBLACK are identical to the grayscale representation // for black. // If memory is zero initialized, we may not need to fill if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == (uint8_t) colorOrIndex) { return; } memset(dst, (uint8_t) colorOrIndex, bytesToFill); break; case kRGBA_F16_SkColorType: { uint64_t color = colorOrIndex; if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) { return; } uint64_t* dstRow = (uint64_t*) dst; for (int row = 0; row < numRows; row++) { sk_memset64((uint64_t*) dstRow, color, width); dstRow = SkTAddOffset<uint64_t>(dstRow, rowBytes); } break; } default: SkCodecPrintf("Error: Unsupported dst color type for fill(). Doing nothing.\n"); SkASSERT(false); break; } }