1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkBlitRow_D16.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,245 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkBlitRow.h" 1.12 +#include "SkColorPriv.h" 1.13 +#include "SkDither.h" 1.14 +#include "SkMathPriv.h" 1.15 + 1.16 +/////////////////////////////////////////////////////////////////////////////// 1.17 + 1.18 +static void S32_D565_Opaque(uint16_t* SK_RESTRICT dst, 1.19 + const SkPMColor* SK_RESTRICT src, int count, 1.20 + U8CPU alpha, int /*x*/, int /*y*/) { 1.21 + SkASSERT(255 == alpha); 1.22 + 1.23 + if (count > 0) { 1.24 + do { 1.25 + SkPMColor c = *src++; 1.26 + SkPMColorAssert(c); 1.27 + *dst++ = SkPixel32ToPixel16_ToU16(c); 1.28 + } while (--count != 0); 1.29 + } 1.30 +} 1.31 + 1.32 +static void S32_D565_Blend(uint16_t* SK_RESTRICT dst, 1.33 + const SkPMColor* SK_RESTRICT src, int count, 1.34 + U8CPU alpha, int /*x*/, int /*y*/) { 1.35 + SkASSERT(255 > alpha); 1.36 + 1.37 + if (count > 0) { 1.38 + int scale = SkAlpha255To256(alpha); 1.39 + do { 1.40 + SkPMColor c = *src++; 1.41 + SkPMColorAssert(c); 1.42 + uint16_t d = *dst; 1.43 + *dst++ = SkPackRGB16( 1.44 + SkAlphaBlend(SkPacked32ToR16(c), SkGetPackedR16(d), scale), 1.45 + SkAlphaBlend(SkPacked32ToG16(c), SkGetPackedG16(d), scale), 1.46 + SkAlphaBlend(SkPacked32ToB16(c), SkGetPackedB16(d), scale)); 1.47 + } while (--count != 0); 1.48 + } 1.49 +} 1.50 + 1.51 +static void S32A_D565_Opaque(uint16_t* SK_RESTRICT dst, 1.52 + const SkPMColor* SK_RESTRICT src, int count, 1.53 + U8CPU alpha, int /*x*/, int /*y*/) { 1.54 + SkASSERT(255 == alpha); 1.55 + 1.56 + if (count > 0) { 1.57 + do { 1.58 + SkPMColor c = *src++; 1.59 + SkPMColorAssert(c); 1.60 +// if (__builtin_expect(c!=0, 1)) 1.61 + if (c) { 1.62 + *dst = SkSrcOver32To16(c, *dst); 1.63 + } 1.64 + dst += 1; 1.65 + } while (--count != 0); 1.66 + } 1.67 +} 1.68 + 1.69 +static void S32A_D565_Blend(uint16_t* SK_RESTRICT dst, 1.70 + const SkPMColor* SK_RESTRICT src, int count, 1.71 + U8CPU alpha, int /*x*/, int /*y*/) { 1.72 + SkASSERT(255 > alpha); 1.73 + 1.74 + if (count > 0) { 1.75 + do { 1.76 + SkPMColor sc = *src++; 1.77 + SkPMColorAssert(sc); 1.78 + if (sc) { 1.79 + uint16_t dc = *dst; 1.80 + unsigned dst_scale = 255 - SkMulDiv255Round(SkGetPackedA32(sc), alpha); 1.81 + unsigned dr = SkMulS16(SkPacked32ToR16(sc), alpha) + SkMulS16(SkGetPackedR16(dc), dst_scale); 1.82 + unsigned dg = SkMulS16(SkPacked32ToG16(sc), alpha) + SkMulS16(SkGetPackedG16(dc), dst_scale); 1.83 + unsigned db = SkMulS16(SkPacked32ToB16(sc), alpha) + SkMulS16(SkGetPackedB16(dc), dst_scale); 1.84 + *dst = SkPackRGB16(SkDiv255Round(dr), SkDiv255Round(dg), SkDiv255Round(db)); 1.85 + } 1.86 + dst += 1; 1.87 + } while (--count != 0); 1.88 + } 1.89 +} 1.90 + 1.91 +///////////////////////////////////////////////////////////////////////////// 1.92 + 1.93 +static void S32_D565_Opaque_Dither(uint16_t* SK_RESTRICT dst, 1.94 + const SkPMColor* SK_RESTRICT src, 1.95 + int count, U8CPU alpha, int x, int y) { 1.96 + SkASSERT(255 == alpha); 1.97 + 1.98 + if (count > 0) { 1.99 + DITHER_565_SCAN(y); 1.100 + do { 1.101 + SkPMColor c = *src++; 1.102 + SkPMColorAssert(c); 1.103 + 1.104 + unsigned dither = DITHER_VALUE(x); 1.105 + *dst++ = SkDitherRGB32To565(c, dither); 1.106 + DITHER_INC_X(x); 1.107 + } while (--count != 0); 1.108 + } 1.109 +} 1.110 + 1.111 +static void S32_D565_Blend_Dither(uint16_t* SK_RESTRICT dst, 1.112 + const SkPMColor* SK_RESTRICT src, 1.113 + int count, U8CPU alpha, int x, int y) { 1.114 + SkASSERT(255 > alpha); 1.115 + 1.116 + if (count > 0) { 1.117 + int scale = SkAlpha255To256(alpha); 1.118 + DITHER_565_SCAN(y); 1.119 + do { 1.120 + SkPMColor c = *src++; 1.121 + SkPMColorAssert(c); 1.122 + 1.123 + int dither = DITHER_VALUE(x); 1.124 + int sr = SkGetPackedR32(c); 1.125 + int sg = SkGetPackedG32(c); 1.126 + int sb = SkGetPackedB32(c); 1.127 + sr = SkDITHER_R32To565(sr, dither); 1.128 + sg = SkDITHER_G32To565(sg, dither); 1.129 + sb = SkDITHER_B32To565(sb, dither); 1.130 + 1.131 + uint16_t d = *dst; 1.132 + *dst++ = SkPackRGB16(SkAlphaBlend(sr, SkGetPackedR16(d), scale), 1.133 + SkAlphaBlend(sg, SkGetPackedG16(d), scale), 1.134 + SkAlphaBlend(sb, SkGetPackedB16(d), scale)); 1.135 + DITHER_INC_X(x); 1.136 + } while (--count != 0); 1.137 + } 1.138 +} 1.139 + 1.140 +static void S32A_D565_Opaque_Dither(uint16_t* SK_RESTRICT dst, 1.141 + const SkPMColor* SK_RESTRICT src, 1.142 + int count, U8CPU alpha, int x, int y) { 1.143 + SkASSERT(255 == alpha); 1.144 + 1.145 + if (count > 0) { 1.146 + DITHER_565_SCAN(y); 1.147 + do { 1.148 + SkPMColor c = *src++; 1.149 + SkPMColorAssert(c); 1.150 + if (c) { 1.151 + unsigned a = SkGetPackedA32(c); 1.152 + 1.153 + int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a)); 1.154 + 1.155 + unsigned sr = SkGetPackedR32(c); 1.156 + unsigned sg = SkGetPackedG32(c); 1.157 + unsigned sb = SkGetPackedB32(c); 1.158 + sr = SkDITHER_R32_FOR_565(sr, d); 1.159 + sg = SkDITHER_G32_FOR_565(sg, d); 1.160 + sb = SkDITHER_B32_FOR_565(sb, d); 1.161 + 1.162 + uint32_t src_expanded = (sg << 24) | (sr << 13) | (sb << 2); 1.163 + uint32_t dst_expanded = SkExpand_rgb_16(*dst); 1.164 + dst_expanded = dst_expanded * (SkAlpha255To256(255 - a) >> 3); 1.165 + // now src and dst expanded are in g:11 r:10 x:1 b:10 1.166 + *dst = SkCompact_rgb_16((src_expanded + dst_expanded) >> 5); 1.167 + } 1.168 + dst += 1; 1.169 + DITHER_INC_X(x); 1.170 + } while (--count != 0); 1.171 + } 1.172 +} 1.173 + 1.174 +static void S32A_D565_Blend_Dither(uint16_t* SK_RESTRICT dst, 1.175 + const SkPMColor* SK_RESTRICT src, 1.176 + int count, U8CPU alpha, int x, int y) { 1.177 + SkASSERT(255 > alpha); 1.178 + 1.179 + if (count > 0) { 1.180 + int src_scale = SkAlpha255To256(alpha); 1.181 + DITHER_565_SCAN(y); 1.182 + do { 1.183 + SkPMColor c = *src++; 1.184 + SkPMColorAssert(c); 1.185 + if (c) 1.186 + { 1.187 + unsigned d = *dst; 1.188 + int sa = SkGetPackedA32(c); 1.189 + int dst_scale = SkAlpha255To256(255 - SkAlphaMul(sa, src_scale)); 1.190 + int dither = DITHER_VALUE(x); 1.191 + 1.192 + int sr = SkGetPackedR32(c); 1.193 + int sg = SkGetPackedG32(c); 1.194 + int sb = SkGetPackedB32(c); 1.195 + sr = SkDITHER_R32To565(sr, dither); 1.196 + sg = SkDITHER_G32To565(sg, dither); 1.197 + sb = SkDITHER_B32To565(sb, dither); 1.198 + 1.199 + int dr = (sr * src_scale + SkGetPackedR16(d) * dst_scale) >> 8; 1.200 + int dg = (sg * src_scale + SkGetPackedG16(d) * dst_scale) >> 8; 1.201 + int db = (sb * src_scale + SkGetPackedB16(d) * dst_scale) >> 8; 1.202 + 1.203 + *dst = SkPackRGB16(dr, dg, db); 1.204 + } 1.205 + dst += 1; 1.206 + DITHER_INC_X(x); 1.207 + } while (--count != 0); 1.208 + } 1.209 +} 1.210 + 1.211 +/////////////////////////////////////////////////////////////////////////////// 1.212 +/////////////////////////////////////////////////////////////////////////////// 1.213 + 1.214 +static const SkBlitRow::Proc gDefault_565_Procs[] = { 1.215 + // no dither 1.216 + S32_D565_Opaque, 1.217 + S32_D565_Blend, 1.218 + 1.219 + S32A_D565_Opaque, 1.220 + S32A_D565_Blend, 1.221 + 1.222 + // dither 1.223 + S32_D565_Opaque_Dither, 1.224 + S32_D565_Blend_Dither, 1.225 + 1.226 + S32A_D565_Opaque_Dither, 1.227 + S32A_D565_Blend_Dither 1.228 +}; 1.229 + 1.230 +SkBlitRow::Proc SkBlitRow::Factory(unsigned flags, SkBitmap::Config config) { 1.231 + SkASSERT(flags < SK_ARRAY_COUNT(gDefault_565_Procs)); 1.232 + // just so we don't crash 1.233 + flags &= kFlags16_Mask; 1.234 + 1.235 + SkBlitRow::Proc proc = NULL; 1.236 + 1.237 + switch (config) { 1.238 + case SkBitmap::kRGB_565_Config: 1.239 + proc = PlatformProcs565(flags); 1.240 + if (NULL == proc) { 1.241 + proc = gDefault_565_Procs[flags]; 1.242 + } 1.243 + break; 1.244 + default: 1.245 + break; 1.246 + } 1.247 + return proc; 1.248 +}