blob: 75330ae33761a5ba8d8a81e7e3359de9b9c64254 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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 */
reed@google.com58af9a62011-10-12 13:43:52 +00007
reed@android.comc4cae852009-09-23 15:06:10 +00008#include "SkBlitRow.h"
reed@google.com58af9a62011-10-12 13:43:52 +00009#include "SkBlitMask.h"
reed@android.comc4cae852009-09-23 15:06:10 +000010#include "SkColorPriv.h"
mtklein4a37d082015-09-10 10:38:02 -070011#include "SkOpts.h"
reed@android.comc4cae852009-09-23 15:06:10 +000012#include "SkUtils.h"
13
djsollen@google.com57f49692011-02-23 20:46:31 +000014#define UNROLL
15
reed@android.comc4cae852009-09-23 15:06:10 +000016static void S32_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
17 const SkPMColor* SK_RESTRICT src,
18 int count, U8CPU alpha) {
19 SkASSERT(255 == alpha);
mtklein58fd2c82015-07-27 11:08:28 -070020 memcpy(dst, src, count * 4);
reed@android.comc4cae852009-09-23 15:06:10 +000021}
22
23static 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;
djsollen@google.com57f49692011-02-23 20:46:31 +000030
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
reed@android.comc4cae852009-09-23 15:06:10 +000046 do {
47 *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale);
48 src += 1;
49 dst += 1;
50 } while (--count > 0);
djsollen@google.com57f49692011-02-23 20:46:31 +000051#endif
reed@android.comc4cae852009-09-23 15:06:10 +000052 }
53}
54
reed@android.comc4cae852009-09-23 15:06:10 +000055static 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) {
djsollen@google.com57f49692011-02-23 20:46:31 +000060#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
reed@android.comc4cae852009-09-23 15:06:10 +000075 do {
reed@android.comc4cae852009-09-23 15:06:10 +000076 *dst = SkPMSrcOver(*src, *dst);
reed@android.comc4cae852009-09-23 15:06:10 +000077 src += 1;
78 dst += 1;
79 } while (--count > 0);
djsollen@google.com57f49692011-02-23 20:46:31 +000080#endif
reed@android.comc4cae852009-09-23 15:06:10 +000081 }
82}
83
84static 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) {
djsollen@google.com57f49692011-02-23 20:46:31 +000089#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
reed@android.comc4cae852009-09-23 15:06:10 +0000104 do {
105 *dst = SkBlendARGB32(*src, *dst, alpha);
106 src += 1;
107 dst += 1;
108 } while (--count > 0);
djsollen@google.com57f49692011-02-23 20:46:31 +0000109#endif
reed@android.comc4cae852009-09-23 15:06:10 +0000110 }
111}
112
113///////////////////////////////////////////////////////////////////////////////
114
115static const SkBlitRow::Proc32 gDefault_Procs32[] = {
116 S32_Opaque_BlitRow32,
117 S32_Blend_BlitRow32,
118 S32A_Opaque_BlitRow32,
119 S32A_Blend_BlitRow32
120};
121
122SkBlitRow::Proc32 SkBlitRow::Factory32(unsigned flags) {
123 SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32));
124 // just so we don't crash
125 flags &= kFlags32_Mask;
reed@google.com981d4792011-03-09 12:55:47 +0000126
senorblanco@chromium.org92727612009-11-04 20:51:06 +0000127 SkBlitRow::Proc32 proc = PlatformProcs32(flags);
halcanary96fcdcc2015-08-27 07:41:13 -0700128 if (nullptr == proc) {
reed@android.comc4cae852009-09-23 15:06:10 +0000129 proc = gDefault_Procs32[flags];
130 }
131 SkASSERT(proc);
132 return proc;
133}
134
mtklein95cc0122015-04-27 15:11:01 -0700135void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[], int count, SkPMColor color) {
mtkleinafe2ffb2015-04-17 11:00:54 -0700136 switch (SkGetPackedA32(color)) {
137 case 0: memmove(dst, src, count * sizeof(SkPMColor)); return;
138 case 255: sk_memset32(dst, color, count); return;
139 }
mtklein4a37d082015-09-10 10:38:02 -0700140 return SkOpts::blit_row_color32(dst, src, count, color);
reed@android.comc4cae852009-09-23 15:06:10 +0000141}