• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "include/core/SkShader.h"
9 #include "include/private/SkColorData.h"
10 #include "include/private/SkColorData.h"
11 #include "src/core/SkCoreBlitters.h"
12 #include "src/core/SkXfermodePriv.h"
13 #include "src/utils/SkUTF.h"
14 
15 #include "include/private/SkNx.h"
16 
D16_S32X_src(uint16_t dst[],const SkPMColor src[],int count,uint8_t coverage)17 static void D16_S32X_src(uint16_t dst[], const SkPMColor src[], int count, uint8_t coverage) {
18     SkASSERT(coverage == 0xFF);
19     for (int i = 0; i < count; ++i) {
20         dst[i] = SkPixel32ToPixel16(src[i]);
21     }
22 }
23 
D16_S32X_src_coverage(uint16_t dst[],const SkPMColor src[],int count,uint8_t coverage)24 static void D16_S32X_src_coverage(uint16_t dst[], const SkPMColor src[], int count,
25                                   uint8_t coverage) {
26     switch (coverage) {
27         case 0: break;
28         case 0xFF:
29             for (int i = 0; i < count; ++i) {
30                 dst[i] = SkPixel32ToPixel16(src[i]);
31             }
32             break;
33         default:
34             unsigned scale = coverage + (coverage >> 7);
35             for (int i = 0; i < count; ++i) {
36                 dst[i] = SkSrcOver32To16(SkAlphaMulQ(src[i], scale), dst[i]);
37             }
38             break;
39     }
40 }
41 
D16_S32A_srcover(uint16_t dst[],const SkPMColor src[],int count,uint8_t coverage)42 static void D16_S32A_srcover(uint16_t dst[], const SkPMColor src[], int count, uint8_t coverage) {
43     SkASSERT(coverage == 0xFF);
44     for (int i = 0; i < count; ++i) {
45         dst[i] = SkSrcOver32To16(src[i], dst[i]);
46     }
47 }
48 
D16_S32A_srcover_coverage(uint16_t dst[],const SkPMColor src[],int count,uint8_t coverage)49 static void D16_S32A_srcover_coverage(uint16_t dst[], const SkPMColor src[], int count,
50                                       uint8_t coverage) {
51     switch (coverage) {
52         case 0: break;
53         case 0xFF:
54             for (int i = 0; i < count; ++i) {
55                 dst[i] = SkSrcOver32To16(src[i], dst[i]);
56             }
57             break;
58         default:
59             unsigned scale = coverage + (coverage >> 7);
60             for (int i = 0; i < count; ++i) {
61                 dst[i] = SkSrcOver32To16(SkAlphaMulQ(src[i], scale), dst[i]);
62             }
63             break;
64     }
65 }
66 
Supports(const SkPixmap & device,const SkPaint & paint)67 bool SkRGB565_Shader_Blitter::Supports(const SkPixmap& device, const SkPaint& paint) {
68     if (device.colorType() != kRGB_565_SkColorType) {
69         return false;
70     }
71     if (device.colorSpace()) {
72         return false;
73     }
74     if (paint.getBlendMode() != SkBlendMode::kSrcOver &&
75         paint.getBlendMode() != SkBlendMode::kSrc) {
76         return false;
77     }
78     if (paint.isDither()) {
79         return false;
80     }
81     return true;
82 }
83 
SkRGB565_Shader_Blitter(const SkPixmap & device,const SkPaint & paint,SkShaderBase::Context * shaderContext)84 SkRGB565_Shader_Blitter::SkRGB565_Shader_Blitter(const SkPixmap& device,
85         const SkPaint& paint, SkShaderBase::Context* shaderContext)
86     : INHERITED(device, paint, shaderContext)
87 {
88     SkASSERT(shaderContext);
89     SkASSERT(Supports(device, paint));
90 
91     fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor)));
92 
93     bool isOpaque = SkToBool(shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag);
94 
95     if (paint.getBlendMode() == SkBlendMode::kSrc || isOpaque) {
96         fBlend = D16_S32X_src;
97         fBlendCoverage = D16_S32X_src_coverage;
98     } else {    // srcover
99         fBlend = isOpaque ? D16_S32X_src : D16_S32A_srcover;
100         fBlendCoverage = isOpaque ? D16_S32X_src_coverage : D16_S32A_srcover_coverage;
101     }
102 }
103 
~SkRGB565_Shader_Blitter()104 SkRGB565_Shader_Blitter::~SkRGB565_Shader_Blitter() {
105     sk_free(fBuffer);
106 }
107 
blitH(int x,int y,int width)108 void SkRGB565_Shader_Blitter::blitH(int x, int y, int width) {
109     SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
110 
111     uint16_t* device = fDevice.writable_addr16(x, y);
112 
113     SkPMColor*  span = fBuffer;
114     fShaderContext->shadeSpan(x, y, span, width);
115     fBlend(device, span, width, 0xFF);
116 }
117 
blitAntiH(int x,int y,const SkAlpha coverage[],const int16_t runs[])118 void SkRGB565_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha coverage[],
119                                         const int16_t runs[]) {
120     SkPMColor* span = fBuffer;
121     uint16_t*  device = fDevice.writable_addr16(x, y);
122     auto*      shaderContext = fShaderContext;
123 
124     for (;;) {
125         int count = *runs;
126         if (count <= 0) {
127             break;
128         }
129         int aa = *coverage;
130         if (aa) {
131             shaderContext->shadeSpan(x, y, span, count);
132             fBlendCoverage(device, span, count, aa);
133         }
134         device += count;
135         runs += count;
136         coverage += count;
137         x += count;
138     }
139 }
140