1 : /*
2 : * Copyright 2011 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 "SkBlitRow.h"
9 : #include "SkBlitMask.h"
10 : #include "SkColorPriv.h"
11 : #include "SkUtils.h"
12 :
13 : #define UNROLL
14 :
15 0 : static void S32_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
16 : const SkPMColor* SK_RESTRICT src,
17 : int count, U8CPU alpha) {
18 0 : SkASSERT(255 == alpha);
19 0 : memcpy(dst, src, count * sizeof(SkPMColor));
20 0 : }
21 :
22 0 : static void S32_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
23 : const SkPMColor* SK_RESTRICT src,
24 : int count, U8CPU alpha) {
25 0 : SkASSERT(alpha <= 255);
26 0 : if (count > 0) {
27 0 : unsigned src_scale = SkAlpha255To256(alpha);
28 0 : unsigned dst_scale = 256 - src_scale;
29 :
30 : #ifdef UNROLL
31 0 : if (count & 1) {
32 0 : *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
33 0 : dst += 1;
34 0 : count -= 1;
35 : }
36 :
37 0 : const SkPMColor* SK_RESTRICT srcEnd = src + count;
38 0 : while (src != srcEnd) {
39 0 : *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
40 0 : dst += 1;
41 0 : *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
42 0 : dst += 1;
43 : }
44 : #else
45 : do {
46 : *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale);
47 : src += 1;
48 : dst += 1;
49 : } while (--count > 0);
50 : #endif
51 : }
52 0 : }
53 :
54 : //#define TEST_SRC_ALPHA
55 :
56 0 : static void S32A_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
57 : const SkPMColor* SK_RESTRICT src,
58 : int count, U8CPU alpha) {
59 0 : SkASSERT(255 == alpha);
60 0 : if (count > 0) {
61 : #ifdef UNROLL
62 0 : if (count & 1) {
63 0 : *dst = SkPMSrcOver(*(src++), *dst);
64 0 : dst += 1;
65 0 : count -= 1;
66 : }
67 :
68 0 : const SkPMColor* SK_RESTRICT srcEnd = src + count;
69 0 : while (src != srcEnd) {
70 0 : *dst = SkPMSrcOver(*(src++), *dst);
71 0 : dst += 1;
72 0 : *dst = SkPMSrcOver(*(src++), *dst);
73 0 : dst += 1;
74 : }
75 : #else
76 : do {
77 : #ifdef TEST_SRC_ALPHA
78 : SkPMColor sc = *src;
79 : if (sc) {
80 : unsigned srcA = SkGetPackedA32(sc);
81 : SkPMColor result = sc;
82 : if (srcA != 255) {
83 : result = SkPMSrcOver(sc, *dst);
84 : }
85 : *dst = result;
86 : }
87 : #else
88 : *dst = SkPMSrcOver(*src, *dst);
89 : #endif
90 : src += 1;
91 : dst += 1;
92 : } while (--count > 0);
93 : #endif
94 : }
95 0 : }
96 :
97 0 : static void S32A_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
98 : const SkPMColor* SK_RESTRICT src,
99 : int count, U8CPU alpha) {
100 0 : SkASSERT(alpha <= 255);
101 0 : if (count > 0) {
102 : #ifdef UNROLL
103 0 : if (count & 1) {
104 0 : *dst = SkBlendARGB32(*(src++), *dst, alpha);
105 0 : dst += 1;
106 0 : count -= 1;
107 : }
108 :
109 0 : const SkPMColor* SK_RESTRICT srcEnd = src + count;
110 0 : while (src != srcEnd) {
111 0 : *dst = SkBlendARGB32(*(src++), *dst, alpha);
112 0 : dst += 1;
113 0 : *dst = SkBlendARGB32(*(src++), *dst, alpha);
114 0 : dst += 1;
115 : }
116 : #else
117 : do {
118 : *dst = SkBlendARGB32(*src, *dst, alpha);
119 : src += 1;
120 : dst += 1;
121 : } while (--count > 0);
122 : #endif
123 : }
124 0 : }
125 :
126 : ///////////////////////////////////////////////////////////////////////////////
127 :
128 : static const SkBlitRow::Proc32 gDefault_Procs32[] = {
129 : S32_Opaque_BlitRow32,
130 : S32_Blend_BlitRow32,
131 : S32A_Opaque_BlitRow32,
132 : S32A_Blend_BlitRow32
133 : };
134 :
135 0 : SkBlitRow::Proc32 SkBlitRow::Factory32(unsigned flags) {
136 0 : SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32));
137 : // just so we don't crash
138 0 : flags &= kFlags32_Mask;
139 :
140 0 : SkBlitRow::Proc32 proc = PlatformProcs32(flags);
141 0 : if (NULL == proc) {
142 0 : proc = gDefault_Procs32[flags];
143 : }
144 0 : SkASSERT(proc);
145 0 : return proc;
146 : }
147 :
148 0 : SkBlitRow::Proc32 SkBlitRow::ColorProcFactory() {
149 0 : SkBlitRow::ColorProc proc = PlatformColorProc();
150 0 : if (NULL == proc) {
151 0 : proc = Color32;
152 : }
153 0 : SkASSERT(proc);
154 0 : return proc;
155 : }
156 :
157 0 : void SkBlitRow::Color32(SkPMColor* SK_RESTRICT dst,
158 : const SkPMColor* SK_RESTRICT src,
159 : int count, SkPMColor color) {
160 0 : if (count > 0) {
161 0 : if (0 == color) {
162 0 : if (src != dst) {
163 0 : memcpy(dst, src, count * sizeof(SkPMColor));
164 : }
165 0 : return;
166 : }
167 0 : unsigned colorA = SkGetPackedA32(color);
168 0 : if (255 == colorA) {
169 0 : sk_memset32(dst, color, count);
170 : } else {
171 0 : unsigned scale = 256 - SkAlpha255To256(colorA);
172 0 : do {
173 0 : *dst = color + SkAlphaMulQ(*src, scale);
174 0 : src += 1;
175 0 : dst += 1;
176 : } while (--count);
177 : }
178 : }
179 : }
180 :
|