1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 758af9a64701540c7f8083bc22a42d0bae3a5583creed@google.com 8c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com#include "SkBlitRow.h" 958af9a64701540c7f8083bc22a42d0bae3a5583creed@google.com#include "SkBlitMask.h" 10c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com#include "SkColorPriv.h" 112880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#include "SkOpts.h" 12c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com#include "SkUtils.h" 13c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com 1457f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com#define UNROLL 1557f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com 16c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.comstatic void S32_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst, 17c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com const SkPMColor* SK_RESTRICT src, 18c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com int count, U8CPU alpha) { 19c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com SkASSERT(255 == alpha); 202880df2609eba09b555ca37be04b6ad89290c765Tom Hudson memcpy(dst, src, count * 4); 21c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com} 22c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com 23c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.comstatic void S32_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst, 24c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com const SkPMColor* SK_RESTRICT src, 25c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com int count, U8CPU alpha) { 26c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com SkASSERT(alpha <= 255); 27c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com if (count > 0) { 28c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com unsigned src_scale = SkAlpha255To256(alpha); 29c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com unsigned dst_scale = 256 - src_scale; 3057f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com 3157f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com#ifdef UNROLL 3257f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com if (count & 1) { 3357f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale); 3457f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com dst += 1; 3557f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com count -= 1; 3657f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com } 3757f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com 3857f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com const SkPMColor* SK_RESTRICT srcEnd = src + count; 3957f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com while (src != srcEnd) { 4057f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale); 4157f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com dst += 1; 4257f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale); 4357f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com dst += 1; 4457f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com } 4557f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com#else 46c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com do { 47c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale); 48c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com src += 1; 49c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com dst += 1; 50c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com } while (--count > 0); 5157f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com#endif 52c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com } 53c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com} 54c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com 55c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.comstatic void S32A_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst, 56c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com const SkPMColor* SK_RESTRICT src, 57c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com int count, U8CPU alpha) { 58c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com SkASSERT(255 == alpha); 59c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com if (count > 0) { 6057f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com#ifdef UNROLL 6157f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com if (count & 1) { 6257f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com *dst = SkPMSrcOver(*(src++), *dst); 6357f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com dst += 1; 6457f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com count -= 1; 6557f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com } 6657f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com 6757f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com const SkPMColor* SK_RESTRICT srcEnd = src + count; 6857f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com while (src != srcEnd) { 6957f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com *dst = SkPMSrcOver(*(src++), *dst); 7057f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com dst += 1; 7157f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com *dst = SkPMSrcOver(*(src++), *dst); 7257f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com dst += 1; 7357f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com } 7457f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com#else 75c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com do { 76c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com *dst = SkPMSrcOver(*src, *dst); 77c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com src += 1; 78c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com dst += 1; 79c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com } while (--count > 0); 8057f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com#endif 81c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com } 82c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com} 83c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com 84c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.comstatic void S32A_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst, 85c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com const SkPMColor* SK_RESTRICT src, 86c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com int count, U8CPU alpha) { 87c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com SkASSERT(alpha <= 255); 88c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com if (count > 0) { 8957f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com#ifdef UNROLL 9057f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com if (count & 1) { 9157f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com *dst = SkBlendARGB32(*(src++), *dst, alpha); 9257f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com dst += 1; 9357f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com count -= 1; 9457f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com } 9557f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com 9657f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com const SkPMColor* SK_RESTRICT srcEnd = src + count; 9757f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com while (src != srcEnd) { 9857f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com *dst = SkBlendARGB32(*(src++), *dst, alpha); 9957f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com dst += 1; 10057f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com *dst = SkBlendARGB32(*(src++), *dst, alpha); 10157f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com dst += 1; 10257f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com } 10357f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com#else 104c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com do { 105c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com *dst = SkBlendARGB32(*src, *dst, alpha); 106c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com src += 1; 107c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com dst += 1; 108c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com } while (--count > 0); 10957f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com#endif 110c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com } 111c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com} 112c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com 113c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com/////////////////////////////////////////////////////////////////////////////// 114c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com 115c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.comstatic const SkBlitRow::Proc32 gDefault_Procs32[] = { 116c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com S32_Opaque_BlitRow32, 117c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com S32_Blend_BlitRow32, 118c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com S32A_Opaque_BlitRow32, 119c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com S32A_Blend_BlitRow32 120c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com}; 121c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com 122c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.comSkBlitRow::Proc32 SkBlitRow::Factory32(unsigned flags) { 123c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32)); 124c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com // just so we don't crash 125c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com flags &= kFlags32_Mask; 126981d4798007b91e2e19c13b171583927a56df63breed@google.com 1279272761b22746d2d22439c26f5555028f8e824dasenorblanco@chromium.org SkBlitRow::Proc32 proc = PlatformProcs32(flags); 1282880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (nullptr == proc) { 129c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com proc = gDefault_Procs32[flags]; 130c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com } 131c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com SkASSERT(proc); 132c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com return proc; 133c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com} 134c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com 13595cc012ccaea20f372893ae277ea0a8a6339d094mtkleinvoid SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[], int count, SkPMColor color) { 136afe2ffb8ba5e7362a2ee6f4e1540c9ab22df2c1emtklein switch (SkGetPackedA32(color)) { 137afe2ffb8ba5e7362a2ee6f4e1540c9ab22df2c1emtklein case 0: memmove(dst, src, count * sizeof(SkPMColor)); return; 138afe2ffb8ba5e7362a2ee6f4e1540c9ab22df2c1emtklein case 255: sk_memset32(dst, color, count); return; 139afe2ffb8ba5e7362a2ee6f4e1540c9ab22df2c1emtklein } 1402880df2609eba09b555ca37be04b6ad89290c765Tom Hudson return SkOpts::blit_row_color32(dst, src, count, color); 141c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com} 142