gfx/skia/trunk/src/core/SkBlitRow_D16.cpp

changeset 0
6474c204b198
     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 +}

mercurial