1 #include "SkBlitRow.h" 2 #include "SkColorPriv.h" 3 #include "SkDither.h" 4 5 /////////////////////////////////////////////////////////////////////////////// 6 7 static void S32_D565_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++ = SkPixel32ToPixel16_ToU16(c); 18 } while (--count != 0); 19 } 20 } 21 22 static void S32_D565_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 int scale = SkAlpha255To256(alpha); 29 do { 30 SkPMColor c = *src++; 31 SkPMColorAssert(c); 32 SkASSERT(SkGetPackedA32(c) == 255); 33 uint16_t d = *dst; 34 *dst++ = SkPackRGB16( 35 SkAlphaBlend(SkPacked32ToR16(c), SkGetPackedR16(d), scale), 36 SkAlphaBlend(SkPacked32ToG16(c), SkGetPackedG16(d), scale), 37 SkAlphaBlend(SkPacked32ToB16(c), SkGetPackedB16(d), scale)); 38 } while (--count != 0); 39 } 40 } 41 42 static void S32A_D565_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 *dst = SkSrcOver32To16(c, *dst); 54 } 55 dst += 1; 56 } while (--count != 0); 57 } 58 } 59 60 static void S32A_D565_Blend(uint16_t* SK_RESTRICT dst, 61 const SkPMColor* SK_RESTRICT src, int count, 62 U8CPU alpha, int /*x*/, int /*y*/) { 63 SkASSERT(255 > alpha); 64 65 if (count > 0) { 66 do { 67 SkPMColor sc = *src++; 68 SkPMColorAssert(sc); 69 if (sc) { 70 uint16_t dc = *dst; 71 unsigned dst_scale = 255 - SkMulDiv255Round(SkGetPackedA32(sc), alpha); 72 unsigned dr = SkMulS16(SkPacked32ToR16(sc), alpha) + SkMulS16(SkGetPackedR16(dc), dst_scale); 73 unsigned dg = SkMulS16(SkPacked32ToG16(sc), alpha) + SkMulS16(SkGetPackedG16(dc), dst_scale); 74 unsigned db = SkMulS16(SkPacked32ToB16(sc), alpha) + SkMulS16(SkGetPackedB16(dc), dst_scale); 75 *dst = SkPackRGB16(SkDiv255Round(dr), SkDiv255Round(dg), SkDiv255Round(db)); 76 } 77 dst += 1; 78 } while (--count != 0); 79 } 80 } 81 82 ///////////////////////////////////////////////////////////////////////////// 83 84 static void S32_D565_Opaque_Dither(uint16_t* SK_RESTRICT dst, 85 const SkPMColor* SK_RESTRICT src, 86 int count, U8CPU alpha, int x, int y) { 87 SkASSERT(255 == alpha); 88 89 if (count > 0) { 90 DITHER_565_SCAN(y); 91 do { 92 SkPMColor c = *src++; 93 SkPMColorAssert(c); 94 SkASSERT(SkGetPackedA32(c) == 255); 95 96 unsigned dither = DITHER_VALUE(x); 97 *dst++ = SkDitherRGB32To565(c, dither); 98 DITHER_INC_X(x); 99 } while (--count != 0); 100 } 101 } 102 103 static void S32_D565_Blend_Dither(uint16_t* SK_RESTRICT dst, 104 const SkPMColor* SK_RESTRICT src, 105 int count, U8CPU alpha, int x, int y) { 106 SkASSERT(255 > alpha); 107 108 if (count > 0) { 109 int scale = SkAlpha255To256(alpha); 110 DITHER_565_SCAN(y); 111 do { 112 SkPMColor c = *src++; 113 SkPMColorAssert(c); 114 SkASSERT(SkGetPackedA32(c) == 255); 115 116 int dither = DITHER_VALUE(x); 117 int sr = SkGetPackedR32(c); 118 int sg = SkGetPackedG32(c); 119 int sb = SkGetPackedB32(c); 120 sr = SkDITHER_R32To565(sr, dither); 121 sg = SkDITHER_G32To565(sg, dither); 122 sb = SkDITHER_B32To565(sb, dither); 123 124 uint16_t d = *dst; 125 *dst++ = SkPackRGB16(SkAlphaBlend(sr, SkGetPackedR16(d), scale), 126 SkAlphaBlend(sg, SkGetPackedG16(d), scale), 127 SkAlphaBlend(sb, SkGetPackedB16(d), scale)); 128 DITHER_INC_X(x); 129 } while (--count != 0); 130 } 131 } 132 133 static void S32A_D565_Opaque_Dither(uint16_t* SK_RESTRICT dst, 134 const SkPMColor* SK_RESTRICT src, 135 int count, U8CPU alpha, int x, int y) { 136 SkASSERT(255 == alpha); 137 138 if (count > 0) { 139 DITHER_565_SCAN(y); 140 do { 141 SkPMColor c = *src++; 142 SkPMColorAssert(c); 143 if (c) { 144 unsigned a = SkGetPackedA32(c); 145 146 int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a)); 147 148 unsigned sr = SkGetPackedR32(c); 149 unsigned sg = SkGetPackedG32(c); 150 unsigned sb = SkGetPackedB32(c); 151 sr = SkDITHER_R32_FOR_565(sr, d); 152 sg = SkDITHER_G32_FOR_565(sg, d); 153 sb = SkDITHER_B32_FOR_565(sb, d); 154 155 uint32_t src_expanded = (sg << 24) | (sr << 13) | (sb << 2); 156 uint32_t dst_expanded = SkExpand_rgb_16(*dst); 157 dst_expanded = dst_expanded * (SkAlpha255To256(255 - a) >> 3); 158 // now src and dst expanded are in g:11 r:10 x:1 b:10 159 *dst = SkCompact_rgb_16((src_expanded + dst_expanded) >> 5); 160 } 161 dst += 1; 162 DITHER_INC_X(x); 163 } while (--count != 0); 164 } 165 } 166 167 static void S32A_D565_Blend_Dither(uint16_t* SK_RESTRICT dst, 168 const SkPMColor* SK_RESTRICT src, 169 int count, U8CPU alpha, int x, int y) { 170 SkASSERT(255 > alpha); 171 172 if (count > 0) { 173 int src_scale = SkAlpha255To256(alpha); 174 DITHER_565_SCAN(y); 175 do { 176 SkPMColor c = *src++; 177 SkPMColorAssert(c); 178 if (c) 179 { 180 unsigned d = *dst; 181 int sa = SkGetPackedA32(c); 182 int dst_scale = SkAlpha255To256(255 - SkAlphaMul(sa, src_scale)); 183 int dither = DITHER_VALUE(x); 184 185 int sr = SkGetPackedR32(c); 186 int sg = SkGetPackedG32(c); 187 int sb = SkGetPackedB32(c); 188 sr = SkDITHER_R32To565(sr, dither); 189 sg = SkDITHER_G32To565(sg, dither); 190 sb = SkDITHER_B32To565(sb, dither); 191 192 int dr = (sr * src_scale + SkGetPackedR16(d) * dst_scale) >> 8; 193 int dg = (sg * src_scale + SkGetPackedG16(d) * dst_scale) >> 8; 194 int db = (sb * src_scale + SkGetPackedB16(d) * dst_scale) >> 8; 195 196 *dst = SkPackRGB16(dr, dg, db); 197 } 198 dst += 1; 199 DITHER_INC_X(x); 200 } while (--count != 0); 201 } 202 } 203 204 /////////////////////////////////////////////////////////////////////////////// 205 /////////////////////////////////////////////////////////////////////////////// 206 207 static const SkBlitRow::Proc gDefault_565_Procs[] = { 208 // no dither 209 S32_D565_Opaque, 210 S32_D565_Blend, 211 212 S32A_D565_Opaque, 213 S32A_D565_Blend, 214 215 // dither 216 S32_D565_Opaque_Dither, 217 S32_D565_Blend_Dither, 218 219 S32A_D565_Opaque_Dither, 220 S32A_D565_Blend_Dither 221 }; 222 223 extern SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags); 224 225 SkBlitRow::Proc SkBlitRow::Factory(unsigned flags, SkBitmap::Config config) { 226 SkASSERT(flags < SK_ARRAY_COUNT(gDefault_565_Procs)); 227 // just so we don't crash 228 flags &= kFlags16_Mask; 229 230 SkBlitRow::Proc proc = NULL; 231 232 switch (config) { 233 case SkBitmap::kRGB_565_Config: 234 proc = PlatformProcs565(flags); 235 if (NULL == proc) { 236 proc = gDefault_565_Procs[flags]; 237 } 238 break; 239 case SkBitmap::kARGB_4444_Config: 240 proc = PlatformProcs4444(flags); 241 if (NULL == proc) { 242 proc = SkBlitRow_Factory_4444(flags); 243 } 244 break; 245 default: 246 break; 247 } 248 return proc; 249 } 250 251