123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- /*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "include/core/SkShader.h"
- #include "include/private/SkColorData.h"
- #include "include/private/SkColorData.h"
- #include "src/core/SkCoreBlitters.h"
- #include "src/core/SkXfermodePriv.h"
- #include "src/utils/SkUTF.h"
- #include "include/private/SkNx.h"
- static void D16_S32X_src(uint16_t dst[], const SkPMColor src[], int count, uint8_t coverage) {
- SkASSERT(coverage == 0xFF);
- for (int i = 0; i < count; ++i) {
- dst[i] = SkPixel32ToPixel16(src[i]);
- }
- }
- static void D16_S32X_src_coverage(uint16_t dst[], const SkPMColor src[], int count,
- uint8_t coverage) {
- switch (coverage) {
- case 0: break;
- case 0xFF:
- for (int i = 0; i < count; ++i) {
- dst[i] = SkPixel32ToPixel16(src[i]);
- }
- break;
- default:
- unsigned scale = coverage + (coverage >> 7);
- for (int i = 0; i < count; ++i) {
- dst[i] = SkSrcOver32To16(SkAlphaMulQ(src[i], scale), dst[i]);
- }
- break;
- }
- }
- static void D16_S32A_srcover(uint16_t dst[], const SkPMColor src[], int count, uint8_t coverage) {
- SkASSERT(coverage == 0xFF);
- for (int i = 0; i < count; ++i) {
- dst[i] = SkSrcOver32To16(src[i], dst[i]);
- }
- }
- static void D16_S32A_srcover_coverage(uint16_t dst[], const SkPMColor src[], int count,
- uint8_t coverage) {
- switch (coverage) {
- case 0: break;
- case 0xFF:
- for (int i = 0; i < count; ++i) {
- dst[i] = SkSrcOver32To16(src[i], dst[i]);
- }
- break;
- default:
- unsigned scale = coverage + (coverage >> 7);
- for (int i = 0; i < count; ++i) {
- dst[i] = SkSrcOver32To16(SkAlphaMulQ(src[i], scale), dst[i]);
- }
- break;
- }
- }
- bool SkRGB565_Shader_Blitter::Supports(const SkPixmap& device, const SkPaint& paint) {
- if (device.colorType() != kRGB_565_SkColorType) {
- return false;
- }
- if (device.colorSpace()) {
- return false;
- }
- if (paint.getBlendMode() != SkBlendMode::kSrcOver &&
- paint.getBlendMode() != SkBlendMode::kSrc) {
- return false;
- }
- if (paint.isDither()) {
- return false;
- }
- return true;
- }
- SkRGB565_Shader_Blitter::SkRGB565_Shader_Blitter(const SkPixmap& device,
- const SkPaint& paint, SkShaderBase::Context* shaderContext)
- : INHERITED(device, paint, shaderContext)
- {
- SkASSERT(shaderContext);
- SkASSERT(Supports(device, paint));
- fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor)));
- bool isOpaque = SkToBool(shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag);
- if (paint.getBlendMode() == SkBlendMode::kSrc || isOpaque) {
- fBlend = D16_S32X_src;
- fBlendCoverage = D16_S32X_src_coverage;
- } else { // srcover
- fBlend = isOpaque ? D16_S32X_src : D16_S32A_srcover;
- fBlendCoverage = isOpaque ? D16_S32X_src_coverage : D16_S32A_srcover_coverage;
- }
- }
- SkRGB565_Shader_Blitter::~SkRGB565_Shader_Blitter() {
- sk_free(fBuffer);
- }
- void SkRGB565_Shader_Blitter::blitH(int x, int y, int width) {
- SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
- uint16_t* device = fDevice.writable_addr16(x, y);
- SkPMColor* span = fBuffer;
- fShaderContext->shadeSpan(x, y, span, width);
- fBlend(device, span, width, 0xFF);
- }
- void SkRGB565_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha coverage[],
- const int16_t runs[]) {
- SkPMColor* span = fBuffer;
- uint16_t* device = fDevice.writable_addr16(x, y);
- auto* shaderContext = fShaderContext;
- for (;;) {
- int count = *runs;
- if (count <= 0) {
- break;
- }
- int aa = *coverage;
- if (aa) {
- shaderContext->shadeSpan(x, y, span, count);
- fBlendCoverage(device, span, count, aa);
- }
- device += count;
- runs += count;
- coverage += count;
- x += count;
- }
- }
|