gfx/skia/trunk/src/core/SkBlitRow_D32.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_D32.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,249 @@
     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 "SkBlitMask.h"
    1.13 +#include "SkColorPriv.h"
    1.14 +#include "SkUtils.h"
    1.15 +
    1.16 +#define UNROLL
    1.17 +
    1.18 +SkBlitRow::ColorRectProc PlatformColorRectProcFactory();
    1.19 +
    1.20 +static void S32_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
    1.21 +                                 const SkPMColor* SK_RESTRICT src,
    1.22 +                                 int count, U8CPU alpha) {
    1.23 +    SkASSERT(255 == alpha);
    1.24 +    memcpy(dst, src, count * sizeof(SkPMColor));
    1.25 +}
    1.26 +
    1.27 +static void S32_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
    1.28 +                                const SkPMColor* SK_RESTRICT src,
    1.29 +                                int count, U8CPU alpha) {
    1.30 +    SkASSERT(alpha <= 255);
    1.31 +    if (count > 0) {
    1.32 +        unsigned src_scale = SkAlpha255To256(alpha);
    1.33 +        unsigned dst_scale = 256 - src_scale;
    1.34 +
    1.35 +#ifdef UNROLL
    1.36 +        if (count & 1) {
    1.37 +            *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
    1.38 +            dst += 1;
    1.39 +            count -= 1;
    1.40 +        }
    1.41 +
    1.42 +        const SkPMColor* SK_RESTRICT srcEnd = src + count;
    1.43 +        while (src != srcEnd) {
    1.44 +            *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
    1.45 +            dst += 1;
    1.46 +            *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
    1.47 +            dst += 1;
    1.48 +        }
    1.49 +#else
    1.50 +        do {
    1.51 +            *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale);
    1.52 +            src += 1;
    1.53 +            dst += 1;
    1.54 +        } while (--count > 0);
    1.55 +#endif
    1.56 +    }
    1.57 +}
    1.58 +
    1.59 +static void S32A_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
    1.60 +                                  const SkPMColor* SK_RESTRICT src,
    1.61 +                                  int count, U8CPU alpha) {
    1.62 +    SkASSERT(255 == alpha);
    1.63 +    if (count > 0) {
    1.64 +#ifdef UNROLL
    1.65 +        if (count & 1) {
    1.66 +            *dst = SkPMSrcOver(*(src++), *dst);
    1.67 +            dst += 1;
    1.68 +            count -= 1;
    1.69 +        }
    1.70 +
    1.71 +        const SkPMColor* SK_RESTRICT srcEnd = src + count;
    1.72 +        while (src != srcEnd) {
    1.73 +            *dst = SkPMSrcOver(*(src++), *dst);
    1.74 +            dst += 1;
    1.75 +            *dst = SkPMSrcOver(*(src++), *dst);
    1.76 +            dst += 1;
    1.77 +        }
    1.78 +#else
    1.79 +        do {
    1.80 +            *dst = SkPMSrcOver(*src, *dst);
    1.81 +            src += 1;
    1.82 +            dst += 1;
    1.83 +        } while (--count > 0);
    1.84 +#endif
    1.85 +    }
    1.86 +}
    1.87 +
    1.88 +static void S32A_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
    1.89 +                                 const SkPMColor* SK_RESTRICT src,
    1.90 +                                 int count, U8CPU alpha) {
    1.91 +    SkASSERT(alpha <= 255);
    1.92 +    if (count > 0) {
    1.93 +#ifdef UNROLL
    1.94 +        if (count & 1) {
    1.95 +            *dst = SkBlendARGB32(*(src++), *dst, alpha);
    1.96 +            dst += 1;
    1.97 +            count -= 1;
    1.98 +        }
    1.99 +
   1.100 +        const SkPMColor* SK_RESTRICT srcEnd = src + count;
   1.101 +        while (src != srcEnd) {
   1.102 +            *dst = SkBlendARGB32(*(src++), *dst, alpha);
   1.103 +            dst += 1;
   1.104 +            *dst = SkBlendARGB32(*(src++), *dst, alpha);
   1.105 +            dst += 1;
   1.106 +        }
   1.107 +#else
   1.108 +        do {
   1.109 +            *dst = SkBlendARGB32(*src, *dst, alpha);
   1.110 +            src += 1;
   1.111 +            dst += 1;
   1.112 +        } while (--count > 0);
   1.113 +#endif
   1.114 +    }
   1.115 +}
   1.116 +
   1.117 +///////////////////////////////////////////////////////////////////////////////
   1.118 +
   1.119 +static const SkBlitRow::Proc32 gDefault_Procs32[] = {
   1.120 +    S32_Opaque_BlitRow32,
   1.121 +    S32_Blend_BlitRow32,
   1.122 +    S32A_Opaque_BlitRow32,
   1.123 +    S32A_Blend_BlitRow32
   1.124 +};
   1.125 +
   1.126 +SkBlitRow::Proc32 SkBlitRow::Factory32(unsigned flags) {
   1.127 +    SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32));
   1.128 +    // just so we don't crash
   1.129 +    flags &= kFlags32_Mask;
   1.130 +
   1.131 +    SkBlitRow::Proc32 proc = PlatformProcs32(flags);
   1.132 +    if (NULL == proc) {
   1.133 +        proc = gDefault_Procs32[flags];
   1.134 +    }
   1.135 +    SkASSERT(proc);
   1.136 +    return proc;
   1.137 +}
   1.138 +
   1.139 +SkBlitRow::Proc32 SkBlitRow::ColorProcFactory() {
   1.140 +    SkBlitRow::ColorProc proc = PlatformColorProc();
   1.141 +    if (NULL == proc) {
   1.142 +        proc = Color32;
   1.143 +    }
   1.144 +    SkASSERT(proc);
   1.145 +    return proc;
   1.146 +}
   1.147 +
   1.148 +void SkBlitRow::Color32(SkPMColor* SK_RESTRICT dst,
   1.149 +                        const SkPMColor* SK_RESTRICT src,
   1.150 +                        int count, SkPMColor color) {
   1.151 +    if (count > 0) {
   1.152 +        if (0 == color) {
   1.153 +            if (src != dst) {
   1.154 +                memcpy(dst, src, count * sizeof(SkPMColor));
   1.155 +            }
   1.156 +            return;
   1.157 +        }
   1.158 +        unsigned colorA = SkGetPackedA32(color);
   1.159 +        if (255 == colorA) {
   1.160 +            sk_memset32(dst, color, count);
   1.161 +        } else {
   1.162 +            unsigned scale = 256 - SkAlpha255To256(colorA);
   1.163 +            do {
   1.164 +                *dst = color + SkAlphaMulQ(*src, scale);
   1.165 +                src += 1;
   1.166 +                dst += 1;
   1.167 +            } while (--count);
   1.168 +        }
   1.169 +    }
   1.170 +}
   1.171 +
   1.172 +template <size_t N> void assignLoop(SkPMColor* dst, SkPMColor color) {
   1.173 +    for (size_t i = 0; i < N; ++i) {
   1.174 +        *dst++ = color;
   1.175 +    }
   1.176 +}
   1.177 +
   1.178 +static inline void assignLoop(SkPMColor dst[], SkPMColor color, int count) {
   1.179 +    while (count >= 4) {
   1.180 +        *dst++ = color;
   1.181 +        *dst++ = color;
   1.182 +        *dst++ = color;
   1.183 +        *dst++ = color;
   1.184 +        count -= 4;
   1.185 +    }
   1.186 +    if (count >= 2) {
   1.187 +        *dst++ = color;
   1.188 +        *dst++ = color;
   1.189 +        count -= 2;
   1.190 +    }
   1.191 +    if (count > 0) {
   1.192 +        *dst++ = color;
   1.193 +    }
   1.194 +}
   1.195 +
   1.196 +void SkBlitRow::ColorRect32(SkPMColor* dst, int width, int height,
   1.197 +                            size_t rowBytes, SkPMColor color) {
   1.198 +    if (width <= 0 || height <= 0 || 0 == color) {
   1.199 +        return;
   1.200 +    }
   1.201 +
   1.202 +    // Just made up this value, since I saw it once in a SSE2 file.
   1.203 +    // We should consider writing some tests to find the optimimal break-point
   1.204 +    // (or query the Platform proc?)
   1.205 +    static const int MIN_WIDTH_FOR_SCANLINE_PROC = 32;
   1.206 +
   1.207 +    bool isOpaque = (0xFF == SkGetPackedA32(color));
   1.208 +
   1.209 +    if (!isOpaque || width >= MIN_WIDTH_FOR_SCANLINE_PROC) {
   1.210 +        SkBlitRow::ColorProc proc = SkBlitRow::ColorProcFactory();
   1.211 +        while (--height >= 0) {
   1.212 +            (*proc)(dst, dst, width, color);
   1.213 +            dst = (SkPMColor*) ((char*)dst + rowBytes);
   1.214 +        }
   1.215 +    } else {
   1.216 +        switch (width) {
   1.217 +            case 1:
   1.218 +                while (--height >= 0) {
   1.219 +                    assignLoop<1>(dst, color);
   1.220 +                    dst = (SkPMColor*) ((char*)dst + rowBytes);
   1.221 +                }
   1.222 +                break;
   1.223 +            case 2:
   1.224 +                while (--height >= 0) {
   1.225 +                    assignLoop<2>(dst, color);
   1.226 +                    dst = (SkPMColor*) ((char*)dst + rowBytes);
   1.227 +                }
   1.228 +                break;
   1.229 +            case 3:
   1.230 +                while (--height >= 0) {
   1.231 +                    assignLoop<3>(dst, color);
   1.232 +                    dst = (SkPMColor*) ((char*)dst + rowBytes);
   1.233 +                }
   1.234 +                break;
   1.235 +            default:
   1.236 +                while (--height >= 0) {
   1.237 +                    assignLoop(dst, color, width);
   1.238 +                    dst = (SkPMColor*) ((char*)dst + rowBytes);
   1.239 +                }
   1.240 +                break;
   1.241 +        }
   1.242 +    }
   1.243 +}
   1.244 +
   1.245 +SkBlitRow::ColorRectProc SkBlitRow::ColorRectProcFactory() {
   1.246 +    SkBlitRow::ColorRectProc proc = PlatformColorRectProcFactory();
   1.247 +    if (NULL == proc) {
   1.248 +        proc = ColorRect32;
   1.249 +    }
   1.250 +    SkASSERT(proc);
   1.251 +    return proc;
   1.252 +}

mercurial