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 "SkOpts.h"
12 #include "SkUtils.h"
13
14 #define UNROLL
15
S32_Opaque_BlitRow32(SkPMColor * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha)16 static void S32_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
17 const SkPMColor* SK_RESTRICT src,
18 int count, U8CPU alpha) {
19 SkASSERT(255 == alpha);
20 memcpy(dst, src, count * 4);
21 }
22
S32_Blend_BlitRow32(SkPMColor * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha)23 static void S32_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
24 const SkPMColor* SK_RESTRICT src,
25 int count, U8CPU alpha) {
26 SkASSERT(alpha <= 255);
27 if (count > 0) {
28 unsigned src_scale = SkAlpha255To256(alpha);
29 unsigned dst_scale = 256 - src_scale;
30
31 #ifdef UNROLL
32 if (count & 1) {
33 *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
34 dst += 1;
35 count -= 1;
36 }
37
38 const SkPMColor* SK_RESTRICT srcEnd = src + count;
39 while (src != srcEnd) {
40 *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
41 dst += 1;
42 *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
43 dst += 1;
44 }
45 #else
46 do {
47 *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale);
48 src += 1;
49 dst += 1;
50 } while (--count > 0);
51 #endif
52 }
53 }
54
S32A_Opaque_BlitRow32(SkPMColor * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha)55 static void S32A_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
56 const SkPMColor* SK_RESTRICT src,
57 int count, U8CPU alpha) {
58 SkASSERT(255 == alpha);
59 if (count > 0) {
60 #ifdef UNROLL
61 if (count & 1) {
62 *dst = SkPMSrcOver(*(src++), *dst);
63 dst += 1;
64 count -= 1;
65 }
66
67 const SkPMColor* SK_RESTRICT srcEnd = src + count;
68 while (src != srcEnd) {
69 *dst = SkPMSrcOver(*(src++), *dst);
70 dst += 1;
71 *dst = SkPMSrcOver(*(src++), *dst);
72 dst += 1;
73 }
74 #else
75 do {
76 *dst = SkPMSrcOver(*src, *dst);
77 src += 1;
78 dst += 1;
79 } while (--count > 0);
80 #endif
81 }
82 }
83
S32A_Blend_BlitRow32(SkPMColor * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha)84 static void S32A_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
85 const SkPMColor* SK_RESTRICT src,
86 int count, U8CPU alpha) {
87 SkASSERT(alpha <= 255);
88 if (count > 0) {
89 #ifdef UNROLL
90 if (count & 1) {
91 *dst = SkBlendARGB32(*(src++), *dst, alpha);
92 dst += 1;
93 count -= 1;
94 }
95
96 const SkPMColor* SK_RESTRICT srcEnd = src + count;
97 while (src != srcEnd) {
98 *dst = SkBlendARGB32(*(src++), *dst, alpha);
99 dst += 1;
100 *dst = SkBlendARGB32(*(src++), *dst, alpha);
101 dst += 1;
102 }
103 #else
104 do {
105 *dst = SkBlendARGB32(*src, *dst, alpha);
106 src += 1;
107 dst += 1;
108 } while (--count > 0);
109 #endif
110 }
111 }
112
113 ///////////////////////////////////////////////////////////////////////////////
114
115 static const SkBlitRow::Proc32 gDefault_Procs32[] = {
116 S32_Opaque_BlitRow32,
117 S32_Blend_BlitRow32,
118 S32A_Opaque_BlitRow32,
119 S32A_Blend_BlitRow32
120 };
121
Factory32(unsigned flags)122 SkBlitRow::Proc32 SkBlitRow::Factory32(unsigned flags) {
123 SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32));
124 // just so we don't crash
125 flags &= kFlags32_Mask;
126
127 SkBlitRow::Proc32 proc = PlatformProcs32(flags);
128 if (nullptr == proc) {
129 proc = gDefault_Procs32[flags];
130 }
131 SkASSERT(proc);
132 return proc;
133 }
134
Color32(SkPMColor dst[],const SkPMColor src[],int count,SkPMColor color)135 void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[], int count, SkPMColor color) {
136 switch (SkGetPackedA32(color)) {
137 case 0: memmove(dst, src, count * sizeof(SkPMColor)); return;
138 case 255: sk_memset32(dst, color, count); return;
139 }
140 return SkOpts::blit_row_color32(dst, src, count, color);
141 }
142