1 #include "SkBlitRow.h" 2 #include "SkColorPriv.h" 3 #include "SkDither.h" 4 5 /////////////////////////////////////////////////////////////////////////////// 6 7 static void S32_D4444_Opaque(uint16_t* SK_RESTRICT dst, 8 const SkPMColor* SK_RESTRICT src, int count, 9 U8CPU alpha, int /*x*/, int /*y*/) { 10 SkASSERT(255 == alpha); 11 12 if (count > 0) { 13 do { 14 SkPMColor c = *src++; 15 SkPMColorAssert(c); 16 SkASSERT(SkGetPackedA32(c) == 255); 17 *dst++ = SkPixel32ToPixel4444(c); 18 } while (--count != 0); 19 } 20 } 21 22 static void S32_D4444_Blend(uint16_t* SK_RESTRICT dst, 23 const SkPMColor* SK_RESTRICT src, int count, 24 U8CPU alpha, int /*x*/, int /*y*/) { 25 SkASSERT(255 > alpha); 26 27 if (count > 0) { 28 unsigned scale16 = SkAlpha255To256(alpha) >> 4; 29 do { 30 SkPMColor c = *src++; 31 SkPMColorAssert(c); 32 SkASSERT(SkGetPackedA32(c) == 255); 33 34 uint32_t src_expand = SkExpand32_4444(c); 35 uint32_t dst_expand = SkExpand_4444(*dst); 36 dst_expand += (src_expand - dst_expand) * scale16 >> 4; 37 *dst++ = SkCompact_4444(dst_expand); 38 } while (--count != 0); 39 } 40 } 41 42 static void S32A_D4444_Opaque(uint16_t* SK_RESTRICT dst, 43 const SkPMColor* SK_RESTRICT src, int count, 44 U8CPU alpha, int /*x*/, int /*y*/) { 45 SkASSERT(255 == alpha); 46 47 if (count > 0) { 48 do { 49 SkPMColor c = *src++; 50 SkPMColorAssert(c); 51 // if (__builtin_expect(c!=0, 1)) 52 if (c) 53 { 54 unsigned scale16 = SkAlpha255To256(255 - SkGetPackedA32(c)) >> 4; 55 uint32_t src_expand = SkExpand_8888(c); 56 uint32_t dst_expand = SkExpand_4444(*dst) * scale16; 57 *dst = SkCompact_4444((src_expand + dst_expand) >> 4); 58 } 59 dst += 1; 60 } while (--count != 0); 61 } 62 } 63 64 static void S32A_D4444_Blend(uint16_t* SK_RESTRICT dst, 65 const SkPMColor* SK_RESTRICT src, int count, 66 U8CPU alpha, int /*x*/, int /*y*/) { 67 SkASSERT(255 > alpha); 68 69 if (count > 0) { 70 int src_scale = SkAlpha255To256(alpha) >> 4; 71 do { 72 SkPMColor sc = *src++; 73 SkPMColorAssert(sc); 74 75 if (sc) { 76 unsigned dst_scale = 16 - (SkGetPackedA32(sc) * src_scale >> 8); 77 uint32_t src_expand = SkExpand32_4444(sc) * src_scale; 78 uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale; 79 *dst = SkCompact_4444((src_expand + dst_expand) >> 4); 80 } 81 dst += 1; 82 } while (--count != 0); 83 } 84 } 85 86 ///////////////////////////////////////////////////////////////////////////// 87 88 static void S32_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst, 89 const SkPMColor* SK_RESTRICT src, 90 int count, U8CPU alpha, int x, int y) { 91 SkASSERT(255 == alpha); 92 93 if (count > 0) { 94 DITHER_4444_SCAN(y); 95 do { 96 SkPMColor c = *src++; 97 SkPMColorAssert(c); 98 SkASSERT(SkGetPackedA32(c) == 255); 99 100 unsigned dither = DITHER_VALUE(x); 101 *dst++ = SkDitherARGB32To4444(c, dither); 102 DITHER_INC_X(x); 103 } while (--count != 0); 104 } 105 } 106 107 static void S32_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst, 108 const SkPMColor* SK_RESTRICT src, 109 int count, U8CPU alpha, int x, int y) { 110 SkASSERT(255 > alpha); 111 112 if (count > 0) { 113 int scale16 = SkAlpha255To256(alpha) >> 4; 114 DITHER_4444_SCAN(y); 115 do { 116 SkPMColor c = *src++; 117 SkPMColorAssert(c); 118 SkASSERT(SkGetPackedA32(c) == 255); 119 120 uint32_t src_expand = SkExpand32_4444(c) * scale16; 121 uint32_t dst_expand = SkExpand_4444(*dst) * (16 - scale16); 122 123 c = SkCompact_8888(src_expand + dst_expand); // convert back to SkPMColor 124 *dst++ = SkDitherARGB32To4444(c, DITHER_VALUE(x)); 125 DITHER_INC_X(x); 126 } while (--count != 0); 127 } 128 } 129 130 static void S32A_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst, 131 const SkPMColor* SK_RESTRICT src, 132 int count, U8CPU alpha, int x, int y) { 133 SkASSERT(255 == alpha); 134 135 if (count > 0) { 136 DITHER_4444_SCAN(y); 137 do { 138 SkPMColor c = *src++; 139 SkPMColorAssert(c); 140 if (c) { 141 unsigned a = SkGetPackedA32(c); 142 int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a)); 143 144 unsigned scale16 = SkAlpha255To256(255 - a) >> 4; 145 uint32_t src_expand = SkExpand_8888(c); 146 uint32_t dst_expand = SkExpand_4444(*dst) * scale16; 147 // convert back to SkPMColor 148 c = SkCompact_8888(src_expand + dst_expand); 149 *dst = SkDitherARGB32To4444(c, d); 150 } 151 dst += 1; 152 DITHER_INC_X(x); 153 } while (--count != 0); 154 } 155 } 156 157 // need DitherExpand888To4444(expand, dither) 158 159 static void S32A_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst, 160 const SkPMColor* SK_RESTRICT src, 161 int count, U8CPU alpha, int x, int y) { 162 SkASSERT(255 > alpha); 163 164 if (count > 0) { 165 int src_scale = SkAlpha255To256(alpha) >> 4; 166 DITHER_4444_SCAN(y); 167 do { 168 SkPMColor c = *src++; 169 SkPMColorAssert(c); 170 if (c) { 171 unsigned a = SkAlpha255To256(SkGetPackedA32(c)); 172 int d = SkAlphaMul(DITHER_VALUE(x), a); 173 174 unsigned dst_scale = 16 - SkAlphaMul(src_scale, a); 175 uint32_t src_expand = SkExpand32_4444(c) * src_scale; 176 uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale; 177 // convert back to SkPMColor 178 c = SkCompact_8888(src_expand + dst_expand); 179 *dst = SkDitherARGB32To4444(c, d); 180 } 181 dst += 1; 182 DITHER_INC_X(x); 183 } while (--count != 0); 184 } 185 } 186 187 /////////////////////////////////////////////////////////////////////////////// 188 /////////////////////////////////////////////////////////////////////////////// 189 190 static const SkBlitRow::Proc gProcs4444[] = { 191 // no dither 192 S32_D4444_Opaque, 193 S32_D4444_Blend, 194 195 S32A_D4444_Opaque, 196 S32A_D4444_Blend, 197 198 // dither 199 S32_D4444_Opaque_Dither, 200 S32_D4444_Blend_Dither, 201 202 S32A_D4444_Opaque_Dither, 203 S32A_D4444_Blend_Dither 204 }; 205 206 SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags); 207 SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags) 208 { 209 SkASSERT(flags < SK_ARRAY_COUNT(gProcs4444)); 210 211 return gProcs4444[flags]; 212 } 213 214 215