SkBlitRow_opts_arm_neon.cpp revision dfff2737f8ad3e945a4dcbe175380d4b2a91a260
1a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com/* 2a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com * Copyright 2012 The Android Open Source Project 3a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com * 4a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com * Use of this source code is governed by a BSD-style license that can be 5a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com * found in the LICENSE file. 6a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com */ 7a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 8a111e492b84c312a6bd5d5d9ef100dca48f4941ddjsollen@google.com#include "SkBlitRow_opts_arm_neon.h" 9a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 10a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#include "SkBlitMask.h" 11a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#include "SkBlitRow.h" 12a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#include "SkColorPriv.h" 13a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#include "SkDither.h" 14a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#include "SkMathPriv.h" 15a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#include "SkUtils.h" 16a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 17a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#include "SkCachePreload_arm.h" 180060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org#include "SkColor_opts_neon.h" 19a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#include <arm_neon.h> 20a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 210060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.orgvoid S32_D565_Opaque_neon(uint16_t* SK_RESTRICT dst, 220060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org const SkPMColor* SK_RESTRICT src, int count, 230060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org U8CPU alpha, int /*x*/, int /*y*/) { 240060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org SkASSERT(255 == alpha); 250060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org 260060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org while (count >= 8) { 270060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org uint8x8x4_t vsrc; 280060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org uint16x8_t vdst; 290060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org 300060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org // Load 310060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org vsrc = vld4_u8((uint8_t*)src); 320060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org 330060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org // Convert src to 565 34bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org vdst = SkPixel32ToPixel16_neon8(vsrc); 350060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org 360060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org // Store 370060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org vst1q_u16(dst, vdst); 380060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org 390060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org // Prepare next iteration 400060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org dst += 8; 410060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org src += 8; 420060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org count -= 8; 430060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org }; 440060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org 450060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org // Leftovers 460060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org while (count > 0) { 470060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org SkPMColor c = *src++; 480060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org SkPMColorAssert(c); 490060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org *dst = SkPixel32ToPixel16_ToU16(c); 500060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org dst++; 510060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org count--; 520060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org }; 530060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org} 540060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org 55a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comvoid S32A_D565_Opaque_neon(uint16_t* SK_RESTRICT dst, 56a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com const SkPMColor* SK_RESTRICT src, int count, 57a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com U8CPU alpha, int /*x*/, int /*y*/) { 58a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkASSERT(255 == alpha); 59a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 60a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (count >= 8) { 61efbe8e9bedda21a3e061ebf3d96431a0f250a654djsollen@google.com uint16_t* SK_RESTRICT keep_dst = 0; 62fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 63a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com asm volatile ( 64a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "ands ip, %[count], #7 \n\t" 65a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmov.u8 d31, #1<<7 \n\t" 66a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vld1.16 {q12}, [%[dst]] \n\t" 67a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vld4.8 {d0-d3}, [%[src]] \n\t" 68a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // Thumb does not support the standard ARM conditional 69a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // instructions but instead requires the 'it' instruction 70a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // to signal conditional execution 71a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "it eq \n\t" 72a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "moveq ip, #8 \n\t" 73a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "mov %[keep_dst], %[dst] \n\t" 74fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 75a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "add %[src], %[src], ip, LSL#2 \n\t" 76a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "add %[dst], %[dst], ip, LSL#1 \n\t" 77a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "subs %[count], %[count], ip \n\t" 78a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "b 9f \n\t" 79a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // LOOP 80a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "2: \n\t" 81fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 82a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vld1.16 {q12}, [%[dst]]! \n\t" 83a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vld4.8 {d0-d3}, [%[src]]! \n\t" 84a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vst1.16 {q10}, [%[keep_dst]] \n\t" 85a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "sub %[keep_dst], %[dst], #8*2 \n\t" 86a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "subs %[count], %[count], #8 \n\t" 87a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "9: \n\t" 88a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "pld [%[dst],#32] \n\t" 89a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // expand 0565 q12 to 8888 {d4-d7} 90a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmovn.u16 d4, q12 \n\t" 91a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshr.u16 q11, q12, #5 \n\t" 92a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshr.u16 q10, q12, #6+5 \n\t" 93a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmovn.u16 d5, q11 \n\t" 94a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmovn.u16 d6, q10 \n\t" 95a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshl.u8 d4, d4, #3 \n\t" 96a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshl.u8 d5, d5, #2 \n\t" 97a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshl.u8 d6, d6, #3 \n\t" 98fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 99a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmovl.u8 q14, d31 \n\t" 100a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmovl.u8 q13, d31 \n\t" 101a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmovl.u8 q12, d31 \n\t" 102fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 103a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // duplicate in 4/2/1 & 8pix vsns 104a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmvn.8 d30, d3 \n\t" 105a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmlal.u8 q14, d30, d6 \n\t" 106a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmlal.u8 q13, d30, d5 \n\t" 107a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmlal.u8 q12, d30, d4 \n\t" 108a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshr.u16 q8, q14, #5 \n\t" 109a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshr.u16 q9, q13, #6 \n\t" 110a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vaddhn.u16 d6, q14, q8 \n\t" 111a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshr.u16 q8, q12, #5 \n\t" 112a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vaddhn.u16 d5, q13, q9 \n\t" 113a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vqadd.u8 d6, d6, d0 \n\t" // moved up 114a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vaddhn.u16 d4, q12, q8 \n\t" 115a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // intentionally don't calculate alpha 116a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // result in d4-d6 117fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 118a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vqadd.u8 d5, d5, d1 \n\t" 119a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vqadd.u8 d4, d4, d2 \n\t" 120fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 121a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // pack 8888 {d4-d6} to 0565 q10 122a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshll.u8 q10, d6, #8 \n\t" 123a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshll.u8 q3, d5, #8 \n\t" 124a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshll.u8 q2, d4, #8 \n\t" 125a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vsri.u16 q10, q3, #5 \n\t" 126a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vsri.u16 q10, q2, #11 \n\t" 127fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 128a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "bne 2b \n\t" 129fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 130a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "1: \n\t" 131a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vst1.16 {q10}, [%[keep_dst]] \n\t" 132a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com : [count] "+r" (count) 133fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com : [dst] "r" (dst), [keep_dst] "r" (keep_dst), [src] "r" (src) 134a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com : "ip", "cc", "memory", "d0","d1","d2","d3","d4","d5","d6","d7", 135a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "d16","d17","d18","d19","d20","d21","d22","d23","d24","d25","d26","d27","d28","d29", 136a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "d30","d31" 137a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com ); 138a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 139fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com else 140a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com { // handle count < 8 141efbe8e9bedda21a3e061ebf3d96431a0f250a654djsollen@google.com uint16_t* SK_RESTRICT keep_dst = 0; 142fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 143a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com asm volatile ( 144a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmov.u8 d31, #1<<7 \n\t" 145a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "mov %[keep_dst], %[dst] \n\t" 146fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 147a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "tst %[count], #4 \n\t" 148a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "beq 14f \n\t" 149a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vld1.16 {d25}, [%[dst]]! \n\t" 150a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vld1.32 {q1}, [%[src]]! \n\t" 151fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 152a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "14: \n\t" 153a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "tst %[count], #2 \n\t" 154a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "beq 12f \n\t" 155a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vld1.32 {d24[1]}, [%[dst]]! \n\t" 156a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vld1.32 {d1}, [%[src]]! \n\t" 157fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 158a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "12: \n\t" 159a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "tst %[count], #1 \n\t" 160a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "beq 11f \n\t" 161a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vld1.16 {d24[1]}, [%[dst]]! \n\t" 162a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vld1.32 {d0[1]}, [%[src]]! \n\t" 163fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 164a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "11: \n\t" 165a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // unzips achieve the same as a vld4 operation 166a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vuzpq.u16 q0, q1 \n\t" 167a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vuzp.u8 d0, d1 \n\t" 168a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vuzp.u8 d2, d3 \n\t" 169a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // expand 0565 q12 to 8888 {d4-d7} 170a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmovn.u16 d4, q12 \n\t" 171a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshr.u16 q11, q12, #5 \n\t" 172a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshr.u16 q10, q12, #6+5 \n\t" 173a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmovn.u16 d5, q11 \n\t" 174a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmovn.u16 d6, q10 \n\t" 175a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshl.u8 d4, d4, #3 \n\t" 176a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshl.u8 d5, d5, #2 \n\t" 177a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshl.u8 d6, d6, #3 \n\t" 178fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 179a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmovl.u8 q14, d31 \n\t" 180a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmovl.u8 q13, d31 \n\t" 181a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmovl.u8 q12, d31 \n\t" 182fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 183a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // duplicate in 4/2/1 & 8pix vsns 184a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmvn.8 d30, d3 \n\t" 185a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmlal.u8 q14, d30, d6 \n\t" 186a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmlal.u8 q13, d30, d5 \n\t" 187a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmlal.u8 q12, d30, d4 \n\t" 188a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshr.u16 q8, q14, #5 \n\t" 189a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshr.u16 q9, q13, #6 \n\t" 190a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vaddhn.u16 d6, q14, q8 \n\t" 191a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshr.u16 q8, q12, #5 \n\t" 192a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vaddhn.u16 d5, q13, q9 \n\t" 193a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vqadd.u8 d6, d6, d0 \n\t" // moved up 194a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vaddhn.u16 d4, q12, q8 \n\t" 195a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // intentionally don't calculate alpha 196a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // result in d4-d6 197fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 198a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vqadd.u8 d5, d5, d1 \n\t" 199a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vqadd.u8 d4, d4, d2 \n\t" 200fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 201a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // pack 8888 {d4-d6} to 0565 q10 202a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshll.u8 q10, d6, #8 \n\t" 203a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshll.u8 q3, d5, #8 \n\t" 204a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshll.u8 q2, d4, #8 \n\t" 205a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vsri.u16 q10, q3, #5 \n\t" 206a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vsri.u16 q10, q2, #11 \n\t" 207fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 208a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // store 209a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "tst %[count], #4 \n\t" 210a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "beq 24f \n\t" 211a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vst1.16 {d21}, [%[keep_dst]]! \n\t" 212fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 213a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "24: \n\t" 214a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "tst %[count], #2 \n\t" 215a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "beq 22f \n\t" 216a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vst1.32 {d20[1]}, [%[keep_dst]]! \n\t" 217fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 218a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "22: \n\t" 219a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "tst %[count], #1 \n\t" 220a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "beq 21f \n\t" 221a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vst1.16 {d20[1]}, [%[keep_dst]]! \n\t" 222fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 223a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "21: \n\t" 224a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com : [count] "+r" (count) 225a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com : [dst] "r" (dst), [keep_dst] "r" (keep_dst), [src] "r" (src) 226a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com : "ip", "cc", "memory", "d0","d1","d2","d3","d4","d5","d6","d7", 227a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "d16","d17","d18","d19","d20","d21","d22","d23","d24","d25","d26","d27","d28","d29", 228a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "d30","d31" 229a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com ); 230a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 231a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com} 232a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 233be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.orgstatic inline uint16x8_t SkDiv255Round_neon8(uint16x8_t prod) { 234be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org prod += vdupq_n_u16(128); 235be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org prod += vshrq_n_u16(prod, 8); 236be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org return vshrq_n_u16(prod, 8); 237be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org} 238be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org 239a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comvoid S32A_D565_Blend_neon(uint16_t* SK_RESTRICT dst, 240a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com const SkPMColor* SK_RESTRICT src, int count, 241a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com U8CPU alpha, int /*x*/, int /*y*/) { 242be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org SkASSERT(255 > alpha); 243a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 244be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org /* This code implements a Neon version of S32A_D565_Blend. The results have 245be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org * a few mismatches compared to the original code. These mismatches never 246be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org * exceed 1. 247a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com */ 248fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 249be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org if (count >= 8) { 250be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org uint16x8_t valpha_max, vmask_blue; 251be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org uint8x8_t valpha; 252be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org 253be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org // prepare constants 254be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org valpha_max = vmovq_n_u16(255); 255be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org valpha = vdup_n_u8(alpha); 256be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vmask_blue = vmovq_n_u16(SK_B16_MASK); 257be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org 258be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org do { 259be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org uint16x8_t vdst, vdst_r, vdst_g, vdst_b; 260be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org uint16x8_t vres_a, vres_r, vres_g, vres_b; 261be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org uint8x8x4_t vsrc; 262be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org 263be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org // load pixels 264be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vdst = vld1q_u16(dst); 265be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6)) 266be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org asm ( 267be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org "vld4.u8 %h[vsrc], [%[src]]!" 268be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org : [vsrc] "=w" (vsrc), [src] "+&r" (src) 269be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org : : 270be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org ); 271a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#else 272be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org register uint8x8_t d0 asm("d0"); 273be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org register uint8x8_t d1 asm("d1"); 274be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org register uint8x8_t d2 asm("d2"); 275be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org register uint8x8_t d3 asm("d3"); 276be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org 277be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org asm volatile ( 278be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org "vld4.u8 {d0-d3},[%[src]]!;" 279be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org : "=w" (d0), "=w" (d1), "=w" (d2), "=w" (d3), 280be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org [src] "+&r" (src) 281be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org : : 282be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org ); 283be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vsrc.val[0] = d0; 284be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vsrc.val[1] = d1; 285be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vsrc.val[2] = d2; 286be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vsrc.val[3] = d3; 287a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 288fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 289fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 290be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org // deinterleave dst 291be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vdst_g = vshlq_n_u16(vdst, SK_R16_BITS); // shift green to top of lanes 292be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vdst_b = vdst & vmask_blue; // extract blue 293be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vdst_r = vshrq_n_u16(vdst, SK_R16_SHIFT); // extract red 294be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vdst_g = vshrq_n_u16(vdst_g, SK_R16_BITS + SK_B16_BITS); // extract green 295be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org 296be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org // shift src to 565 297be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vsrc.val[NEON_R] = vshr_n_u8(vsrc.val[NEON_R], 8 - SK_R16_BITS); 298be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vsrc.val[NEON_G] = vshr_n_u8(vsrc.val[NEON_G], 8 - SK_G16_BITS); 299be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vsrc.val[NEON_B] = vshr_n_u8(vsrc.val[NEON_B], 8 - SK_B16_BITS); 300be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org 301be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org // calc src * src_scale 302be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_a = vmull_u8(vsrc.val[NEON_A], valpha); 303be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_r = vmull_u8(vsrc.val[NEON_R], valpha); 304be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_g = vmull_u8(vsrc.val[NEON_G], valpha); 305be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_b = vmull_u8(vsrc.val[NEON_B], valpha); 306be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org 307be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org // prepare dst_scale 308be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_a = SkDiv255Round_neon8(vres_a); 309be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_a = valpha_max - vres_a; // 255 - (sa * src_scale) / 255 310be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org 311be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org // add dst * dst_scale to previous result 312be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_r = vmlaq_u16(vres_r, vdst_r, vres_a); 313be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_g = vmlaq_u16(vres_g, vdst_g, vres_a); 314be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_b = vmlaq_u16(vres_b, vdst_b, vres_a); 315be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org 316be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org#ifdef S32A_D565_BLEND_EXACT 317be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org // It is possible to get exact results with this but it is slow, 318be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org // even slower than C code in some cases 319be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_r = SkDiv255Round_neon8(vres_r); 320be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_g = SkDiv255Round_neon8(vres_g); 321be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_b = SkDiv255Round_neon8(vres_b); 322be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org#else 323be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_r = vrshrq_n_u16(vres_r, 8); 324be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_g = vrshrq_n_u16(vres_g, 8); 325be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_b = vrshrq_n_u16(vres_b, 8); 326be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org#endif 327be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org // pack result 328be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_b = vsliq_n_u16(vres_b, vres_g, SK_G16_SHIFT); // insert green into blue 329be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vres_b = vsliq_n_u16(vres_b, vres_r, SK_R16_SHIFT); // insert red into green/blue 330be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org 331be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org // store 332be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org vst1q_u16(dst, vres_b); 333be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org dst += 8; 334be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org count -= 8; 335be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org } while (count >= 8); 336be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org } 337a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 338be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org // leftovers 339be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org while (count-- > 0) { 340be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org SkPMColor sc = *src++; 341be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org if (sc) { 342be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org uint16_t dc = *dst; 343be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org unsigned dst_scale = 255 - SkMulDiv255Round(SkGetPackedA32(sc), alpha); 344be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org unsigned dr = SkMulS16(SkPacked32ToR16(sc), alpha) + SkMulS16(SkGetPackedR16(dc), dst_scale); 345be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org unsigned dg = SkMulS16(SkPacked32ToG16(sc), alpha) + SkMulS16(SkGetPackedG16(dc), dst_scale); 346be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org unsigned db = SkMulS16(SkPacked32ToB16(sc), alpha) + SkMulS16(SkGetPackedB16(dc), dst_scale); 347be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org *dst = SkPackRGB16(SkDiv255Round(dr), SkDiv255Round(dg), SkDiv255Round(db)); 348be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org } 349be233d63ca015c2991f4fe0802e4a31a71642062commit-bot@chromium.org dst += 1; 350a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 351a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com} 352a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 353a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com/* dither matrix for Neon, derived from gDitherMatrix_3Bit_16. 354a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com * each dither value is spaced out into byte lanes, and repeated 355a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com * to allow an 8-byte load from offsets 0, 1, 2 or 3 from the 356a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com * start of each row. 357a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com */ 358a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comstatic const uint8_t gDitherMatrix_Neon[48] = { 359a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 0, 4, 1, 5, 0, 4, 1, 5, 0, 4, 1, 5, 360a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 6, 2, 7, 3, 6, 2, 7, 3, 6, 2, 7, 3, 361a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1, 5, 0, 4, 1, 5, 0, 4, 1, 5, 0, 4, 362a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 7, 3, 6, 2, 7, 3, 6, 2, 7, 3, 6, 2, 363fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 364a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com}; 365a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 366a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comvoid S32_D565_Blend_Dither_neon(uint16_t *dst, const SkPMColor *src, 367a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com int count, U8CPU alpha, int x, int y) 368a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com{ 369fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3704cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org SkASSERT(255 > alpha); 3714cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 3724cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org // rescale alpha to range 1 - 256 373a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com int scale = SkAlpha255To256(alpha); 374fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3754cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org if (count >= 8) { 3764cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org /* select row and offset for dither array */ 3774cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org const uint8_t *dstart = &gDitherMatrix_Neon[(y&3)*12 + (x&3)]; 378fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3794cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org uint8x8_t vdither = vld1_u8(dstart); // load dither values 3804cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org uint8x8_t vdither_g = vshr_n_u8(vdither, 1); // calc. green dither values 381fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3824cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org int16x8_t vscale = vdupq_n_s16(scale); // duplicate scale into neon reg 3834cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org uint16x8_t vmask_b = vdupq_n_u16(0x1F); // set up blue mask 384fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3854cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org do { 3864cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 3874cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org uint8x8_t vsrc_r, vsrc_g, vsrc_b; 3884cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org uint8x8_t vsrc565_r, vsrc565_g, vsrc565_b; 3894cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org uint16x8_t vsrc_dit_r, vsrc_dit_g, vsrc_dit_b; 3904cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org uint16x8_t vsrc_res_r, vsrc_res_g, vsrc_res_b; 3914cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org uint16x8_t vdst; 3924cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org uint16x8_t vdst_r, vdst_g, vdst_b; 3934cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org int16x8_t vres_r, vres_g, vres_b; 3944cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org int8x8_t vres8_r, vres8_g, vres8_b; 3954cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 3964cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org // Load source and add dither 3974cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org { 3984cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org register uint8x8_t d0 asm("d0"); 3994cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org register uint8x8_t d1 asm("d1"); 4004cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org register uint8x8_t d2 asm("d2"); 4014cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org register uint8x8_t d3 asm("d3"); 4024cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4034cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org asm ( 4044cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org "vld4.8 {d0-d3},[%[src]]! /* r=%P0 g=%P1 b=%P2 a=%P3 */" 4054cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org : "=w" (d0), "=w" (d1), "=w" (d2), "=w" (d3), [src] "+&r" (src) 4064cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org : 4074cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org ); 4084cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc_g = d1; 4094cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) 4104cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc_r = d2; vsrc_b = d0; 4114cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) 4124cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc_r = d0; vsrc_b = d2; 4134cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org#endif 4144cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org } 4154cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4164cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc565_g = vshr_n_u8(vsrc_g, 6); // calc. green >> 6 4174cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc565_r = vshr_n_u8(vsrc_r, 5); // calc. red >> 5 4184cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc565_b = vshr_n_u8(vsrc_b, 5); // calc. blue >> 5 4194cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4204cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc_dit_g = vaddl_u8(vsrc_g, vdither_g); // add in dither to green and widen 4214cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc_dit_r = vaddl_u8(vsrc_r, vdither); // add in dither to red and widen 4224cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc_dit_b = vaddl_u8(vsrc_b, vdither); // add in dither to blue and widen 4234cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4244cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc_dit_r = vsubw_u8(vsrc_dit_r, vsrc565_r); // sub shifted red from result 4254cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc_dit_g = vsubw_u8(vsrc_dit_g, vsrc565_g); // sub shifted green from result 4264cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc_dit_b = vsubw_u8(vsrc_dit_b, vsrc565_b); // sub shifted blue from result 4274cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4284cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc_res_r = vshrq_n_u16(vsrc_dit_r, 3); 4294cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc_res_g = vshrq_n_u16(vsrc_dit_g, 2); 4304cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vsrc_res_b = vshrq_n_u16(vsrc_dit_b, 3); 4314cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4324cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org // Load dst and unpack 4334cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vdst = vld1q_u16(dst); 4344cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vdst_g = vshrq_n_u16(vdst, 5); // shift down to get green 4354cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vdst_r = vshrq_n_u16(vshlq_n_u16(vdst, 5), 5+5); // double shift to extract red 4364cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vdst_b = vandq_u16(vdst, vmask_b); // mask to get blue 4374cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4384cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org // subtract dst from src and widen 4394cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres_r = vsubq_s16(vreinterpretq_s16_u16(vsrc_res_r), vreinterpretq_s16_u16(vdst_r)); 4404cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres_g = vsubq_s16(vreinterpretq_s16_u16(vsrc_res_g), vreinterpretq_s16_u16(vdst_g)); 4414cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres_b = vsubq_s16(vreinterpretq_s16_u16(vsrc_res_b), vreinterpretq_s16_u16(vdst_b)); 4424cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4434cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org // multiply diffs by scale and shift 4444cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres_r = vmulq_s16(vres_r, vscale); 4454cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres_g = vmulq_s16(vres_g, vscale); 4464cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres_b = vmulq_s16(vres_b, vscale); 4474cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4484cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres8_r = vshrn_n_s16(vres_r, 8); 4494cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres8_g = vshrn_n_s16(vres_g, 8); 4504cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres8_b = vshrn_n_s16(vres_b, 8); 4514cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4524cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org // add dst to result 4534cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres_r = vaddw_s8(vreinterpretq_s16_u16(vdst_r), vres8_r); 4544cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres_g = vaddw_s8(vreinterpretq_s16_u16(vdst_g), vres8_g); 4554cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres_b = vaddw_s8(vreinterpretq_s16_u16(vdst_b), vres8_b); 4564cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4574cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org // put result into 565 format 4584cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres_b = vsliq_n_s16(vres_b, vres_g, 5); // shift up green and insert into blue 4594cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vres_b = vsliq_n_s16(vres_b, vres_r, 6+5); // shift up red and insert into blue 4604cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4614cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org // Store result 4624cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org vst1q_u16(dst, vreinterpretq_u16_s16(vres_b)); 4634cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4644cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org // Next iteration 4654cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org dst += 8; 4664cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org count -= 8; 4674cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4684cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org } while (count >= 8); 4694cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org } 4704cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4714cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org // Leftovers 4724cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org if (count > 0) { 4734cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org int scale = SkAlpha255To256(alpha); 4744cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org DITHER_565_SCAN(y); 4754cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org do { 4764cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org SkPMColor c = *src++; 4774cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org SkPMColorAssert(c); 4784cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4794cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org int dither = DITHER_VALUE(x); 4804cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org int sr = SkGetPackedR32(c); 4814cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org int sg = SkGetPackedG32(c); 4824cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org int sb = SkGetPackedB32(c); 4834cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org sr = SkDITHER_R32To565(sr, dither); 4844cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org sg = SkDITHER_G32To565(sg, dither); 4854cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org sb = SkDITHER_B32To565(sb, dither); 4864cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org 4874cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org uint16_t d = *dst; 4884cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org *dst++ = SkPackRGB16(SkAlphaBlend(sr, SkGetPackedR16(d), scale), 4894cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org SkAlphaBlend(sg, SkGetPackedG16(d), scale), 4904cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org SkAlphaBlend(sb, SkGetPackedB16(d), scale)); 4914cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org DITHER_INC_X(x); 4924cc26324e3be5258fae9dc102aa6a3af7d1c96eacommit-bot@chromium.org } while (--count != 0); 493a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 494a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com} 495a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 496a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comvoid S32A_Opaque_BlitRow32_neon(SkPMColor* SK_RESTRICT dst, 497a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com const SkPMColor* SK_RESTRICT src, 498a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com int count, U8CPU alpha) { 499a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 500a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkASSERT(255 == alpha); 501a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (count > 0) { 502a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 503a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 504fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint8x8_t alpha_mask; 505a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 506fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com static const uint8_t alpha_mask_setup[] = {3,3,3,3,7,7,7,7}; 507fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com alpha_mask = vld1_u8(alpha_mask_setup); 508a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 509fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* do the NEON unrolled code */ 510fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#define UNROLL 4 511fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com while (count >= UNROLL) { 512fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint8x8_t src_raw, dst_raw, dst_final; 513fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint8x8_t src_raw_2, dst_raw_2, dst_final_2; 514a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 5150a5699ee482c3b5ef1e857de8a2de06c6a1fa298commit-bot@chromium.org /* The two prefetches below may make the code slighlty 5160a5699ee482c3b5ef1e857de8a2de06c6a1fa298commit-bot@chromium.org * slower for small values of count but are worth having 5170a5699ee482c3b5ef1e857de8a2de06c6a1fa298commit-bot@chromium.org * in the general case. 5180a5699ee482c3b5ef1e857de8a2de06c6a1fa298commit-bot@chromium.org */ 5190a5699ee482c3b5ef1e857de8a2de06c6a1fa298commit-bot@chromium.org __builtin_prefetch(src+32); 5200a5699ee482c3b5ef1e857de8a2de06c6a1fa298commit-bot@chromium.org __builtin_prefetch(dst+32); 5210a5699ee482c3b5ef1e857de8a2de06c6a1fa298commit-bot@chromium.org 522fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* get the source */ 523fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com src_raw = vreinterpret_u8_u32(vld1_u32(src)); 524fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#if UNROLL > 2 525fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com src_raw_2 = vreinterpret_u8_u32(vld1_u32(src+2)); 526a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 527a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 528fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* get and hold the dst too */ 529fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_raw = vreinterpret_u8_u32(vld1_u32(dst)); 530fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#if UNROLL > 2 531fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_raw_2 = vreinterpret_u8_u32(vld1_u32(dst+2)); 532a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 533a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 534fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* 1st and 2nd bits of the unrolling */ 535fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com { 536fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint8x8_t dst_cooked; 537fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint16x8_t dst_wide; 538fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint8x8_t alpha_narrow; 539fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint16x8_t alpha_wide; 540a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 541fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* get the alphas spread out properly */ 542fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com alpha_narrow = vtbl1_u8(src_raw, alpha_mask); 543fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com alpha_wide = vsubw_u8(vdupq_n_u16(256), alpha_narrow); 544a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 545fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* spread the dest */ 546fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_wide = vmovl_u8(dst_raw); 547a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 548fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* alpha mul the dest */ 549fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_wide = vmulq_u16 (dst_wide, alpha_wide); 550fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_cooked = vshrn_n_u16(dst_wide, 8); 551a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 552fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* sum -- ignoring any byte lane overflows */ 553fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_final = vadd_u8(src_raw, dst_cooked); 554fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 555a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 556fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#if UNROLL > 2 557fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* the 3rd and 4th bits of our unrolling */ 558fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com { 559fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint8x8_t dst_cooked; 560fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint16x8_t dst_wide; 561fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint8x8_t alpha_narrow; 562fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint16x8_t alpha_wide; 563a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 564fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com alpha_narrow = vtbl1_u8(src_raw_2, alpha_mask); 565fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com alpha_wide = vsubw_u8(vdupq_n_u16(256), alpha_narrow); 566a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 567fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* spread the dest */ 568fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_wide = vmovl_u8(dst_raw_2); 569a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 570fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* alpha mul the dest */ 571fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_wide = vmulq_u16 (dst_wide, alpha_wide); 572fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_cooked = vshrn_n_u16(dst_wide, 8); 573a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 574fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* sum -- ignoring any byte lane overflows */ 575fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_final_2 = vadd_u8(src_raw_2, dst_cooked); 576fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 577a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 578a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 579fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com vst1_u32(dst, vreinterpret_u32_u8(dst_final)); 580fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#if UNROLL > 2 581fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com vst1_u32(dst+2, vreinterpret_u32_u8(dst_final_2)); 582a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 583a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 584fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com src += UNROLL; 585fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst += UNROLL; 586fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com count -= UNROLL; 587fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 588fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#undef UNROLL 589a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 590fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* do any residual iterations */ 591a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com while (--count >= 0) { 592a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com *dst = SkPMSrcOver(*src, *dst); 593a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com src += 1; 594a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com dst += 1; 595a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 596a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 597a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com} 598a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 599c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.comvoid S32A_Opaque_BlitRow32_neon_src_alpha(SkPMColor* SK_RESTRICT dst, 600c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com const SkPMColor* SK_RESTRICT src, 601c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com int count, U8CPU alpha) { 602c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com SkASSERT(255 == alpha); 603c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 604c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if (count <= 0) 605c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com return; 606c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 607c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* Use these to check if src is transparent or opaque */ 608c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com const unsigned int ALPHA_OPAQ = 0xFF000000; 609c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com const unsigned int ALPHA_TRANS = 0x00FFFFFF; 610c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 611c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com#define UNROLL 4 612c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com const SkPMColor* SK_RESTRICT src_end = src + count - (UNROLL + 1); 613c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com const SkPMColor* SK_RESTRICT src_temp = src; 614c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 615c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* set up the NEON variables */ 616c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com uint8x8_t alpha_mask; 617c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com static const uint8_t alpha_mask_setup[] = {3,3,3,3,7,7,7,7}; 618c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com alpha_mask = vld1_u8(alpha_mask_setup); 619c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 620c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com uint8x8_t src_raw, dst_raw, dst_final; 621c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com uint8x8_t src_raw_2, dst_raw_2, dst_final_2; 622c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com uint8x8_t dst_cooked; 623c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com uint16x8_t dst_wide; 624c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com uint8x8_t alpha_narrow; 625c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com uint16x8_t alpha_wide; 626c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 627c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* choose the first processing type */ 628c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if( src >= src_end) 629c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com goto TAIL; 630c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(*src <= ALPHA_TRANS) 631c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com goto ALPHA_0; 632c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(*src >= ALPHA_OPAQ) 633c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com goto ALPHA_255; 634c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* fall-thru */ 635c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 636c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.comALPHA_1_TO_254: 637c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com do { 638c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 639c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* get the source */ 640c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com src_raw = vreinterpret_u8_u32(vld1_u32(src)); 641c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com src_raw_2 = vreinterpret_u8_u32(vld1_u32(src+2)); 642c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 643c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* get and hold the dst too */ 644c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst_raw = vreinterpret_u8_u32(vld1_u32(dst)); 645c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst_raw_2 = vreinterpret_u8_u32(vld1_u32(dst+2)); 646c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 647c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 648c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* get the alphas spread out properly */ 649c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com alpha_narrow = vtbl1_u8(src_raw, alpha_mask); 650c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* reflect SkAlpha255To256() semantics a+1 vs a+a>>7 */ 651c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* we collapsed (255-a)+1 ... */ 652c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com alpha_wide = vsubw_u8(vdupq_n_u16(256), alpha_narrow); 653c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 654c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* spread the dest */ 655c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst_wide = vmovl_u8(dst_raw); 656c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 657c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* alpha mul the dest */ 658c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst_wide = vmulq_u16 (dst_wide, alpha_wide); 659c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst_cooked = vshrn_n_u16(dst_wide, 8); 660c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 661c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* sum -- ignoring any byte lane overflows */ 662c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst_final = vadd_u8(src_raw, dst_cooked); 663c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 664c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com alpha_narrow = vtbl1_u8(src_raw_2, alpha_mask); 665c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* reflect SkAlpha255To256() semantics a+1 vs a+a>>7 */ 666c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* we collapsed (255-a)+1 ... */ 667c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com alpha_wide = vsubw_u8(vdupq_n_u16(256), alpha_narrow); 668c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 669c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* spread the dest */ 670c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst_wide = vmovl_u8(dst_raw_2); 671c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 672c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* alpha mul the dest */ 673c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst_wide = vmulq_u16 (dst_wide, alpha_wide); 674c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst_cooked = vshrn_n_u16(dst_wide, 8); 675c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 676c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* sum -- ignoring any byte lane overflows */ 677c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst_final_2 = vadd_u8(src_raw_2, dst_cooked); 678c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 679c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com vst1_u32(dst, vreinterpret_u32_u8(dst_final)); 680c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com vst1_u32(dst+2, vreinterpret_u32_u8(dst_final_2)); 681c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 682c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com src += UNROLL; 683c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst += UNROLL; 684c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 685c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* if 2 of the next pixels aren't between 1 and 254 686c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com it might make sense to go to the optimized loops */ 687c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if((src[0] <= ALPHA_TRANS && src[1] <= ALPHA_TRANS) || (src[0] >= ALPHA_OPAQ && src[1] >= ALPHA_OPAQ)) 688c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com break; 689c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 690c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com } while(src < src_end); 691c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 692c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if (src >= src_end) 693c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com goto TAIL; 694c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 695c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(src[0] >= ALPHA_OPAQ && src[1] >= ALPHA_OPAQ) 696c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com goto ALPHA_255; 697c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 698c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /*fall-thru*/ 699c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 700c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.comALPHA_0: 701c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 702c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /*In this state, we know the current alpha is 0 and 703c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com we optimize for the next alpha also being zero. */ 704c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com src_temp = src; //so we don't have to increment dst every time 705c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com do { 706c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(*(++src) > ALPHA_TRANS) 707c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com break; 708c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(*(++src) > ALPHA_TRANS) 709c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com break; 710c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(*(++src) > ALPHA_TRANS) 711c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com break; 712c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(*(++src) > ALPHA_TRANS) 713c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com break; 714c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com } while(src < src_end); 715c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 716c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst += (src - src_temp); 717c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 718c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* no longer alpha 0, so determine where to go next. */ 719c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if( src >= src_end) 720c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com goto TAIL; 721c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(*src >= ALPHA_OPAQ) 722c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com goto ALPHA_255; 723c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com else 724c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com goto ALPHA_1_TO_254; 725c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 726c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.comALPHA_255: 727c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com while((src[0] & src[1] & src[2] & src[3]) >= ALPHA_OPAQ) { 728c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst[0]=src[0]; 729c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst[1]=src[1]; 730c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst[2]=src[2]; 731c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst[3]=src[3]; 732c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com src+=UNROLL; 733c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst+=UNROLL; 734c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(src >= src_end) 735c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com goto TAIL; 736c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com } 737c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 738c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com //Handle remainder. 739c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(*src >= ALPHA_OPAQ) { *dst++ = *src++; 740c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(*src >= ALPHA_OPAQ) { *dst++ = *src++; 741c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(*src >= ALPHA_OPAQ) { *dst++ = *src++; } 742c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com } 743c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com } 744c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 745c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if( src >= src_end) 746c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com goto TAIL; 747c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if(*src <= ALPHA_TRANS) 748c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com goto ALPHA_0; 749c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com else 750c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com goto ALPHA_1_TO_254; 751c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 752c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.comTAIL: 753c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* do any residual iterations */ 754c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com src_end += UNROLL + 1; //goto the real end 755c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com while(src != src_end) { 756c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if( *src != 0 ) { 757c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com if( *src >= ALPHA_OPAQ ) { 758c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com *dst = *src; 759c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com } 760c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com else { 761c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com *dst = SkPMSrcOver(*src, *dst); 762c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com } 763c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com } 764c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com src++; 765c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com dst++; 766c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com } 767c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com 768c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com#undef UNROLL 769c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com return; 770c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com} 771a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 772a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com/* Neon version of S32_Blend_BlitRow32() 773a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com * portable version is in src/core/SkBlitRow_D32.cpp 774a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com */ 775a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comvoid S32_Blend_BlitRow32_neon(SkPMColor* SK_RESTRICT dst, 776a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com const SkPMColor* SK_RESTRICT src, 777a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com int count, U8CPU alpha) { 778a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkASSERT(alpha <= 255); 779fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 780dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org if (count <= 0) { 781dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org return; 782dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org } 783fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 784dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org uint16_t src_scale = SkAlpha255To256(alpha); 785dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org uint16_t dst_scale = 256 - src_scale; 786fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 787dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org while (count >= 2) { 788dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org uint8x8_t vsrc, vdst, vres; 789dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org uint16x8_t vsrc_wide, vdst_wide; 790fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 791dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org /* These commented prefetches are a big win for count 792dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org * values > 64 on an A9 (Pandaboard) but hurt by 10% for count = 4. 793dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org * They also hurt a little (<5%) on an A15 794dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org */ 795dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org //__builtin_prefetch(src+32); 796dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org //__builtin_prefetch(dst+32); 797fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 798dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org // Load 799dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vsrc = vreinterpret_u8_u32(vld1_u32(src)); 800dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vdst = vreinterpret_u8_u32(vld1_u32(dst)); 801dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org 802dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org // Process src 803dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vsrc_wide = vmovl_u8(vsrc); 804dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vsrc_wide = vmulq_u16(vsrc_wide, vdupq_n_u16(src_scale)); 805dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org 806dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org // Process dst 807dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vdst_wide = vmull_u8(vdst, vdup_n_u8(dst_scale)); 808dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org 809dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org // Combine 810dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vres = vshrn_n_u16(vdst_wide, 8) + vshrn_n_u16(vsrc_wide, 8); 811dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org 812dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org // Store 813dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vst1_u32(dst, vreinterpret_u32_u8(vres)); 814dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org 815dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org src += 2; 816dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org dst += 2; 817dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org count -= 2; 818fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 819fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 820fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com if (count == 1) { 821dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org uint8x8_t vsrc, vdst, vres; 822dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org uint16x8_t vsrc_wide, vdst_wide; 823a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 824dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org // Load 825dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vsrc = vreinterpret_u8_u32(vld1_lane_u32(src, vreinterpret_u32_u8(vsrc), 0)); 826dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vdst = vreinterpret_u8_u32(vld1_lane_u32(dst, vreinterpret_u32_u8(vdst), 0)); 827dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org 828dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org // Process 829dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vsrc_wide = vmovl_u8(vsrc); 830dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vsrc_wide = vmulq_u16(vsrc_wide, vdupq_n_u16(src_scale)); 831dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vdst_wide = vmull_u8(vdst, vdup_n_u8(dst_scale)); 832dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vres = vshrn_n_u16(vdst_wide, 8) + vshrn_n_u16(vsrc_wide, 8); 833dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org 834dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org // Store 835dfff2737f8ad3e945a4dcbe175380d4b2a91a260commit-bot@chromium.org vst1_lane_u32(dst, vreinterpret_u32_u8(vres), 0); 836a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 837a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com} 838a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 8391fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.orgvoid S32A_Blend_BlitRow32_neon(SkPMColor* SK_RESTRICT dst, 8401fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org const SkPMColor* SK_RESTRICT src, 8411fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org int count, U8CPU alpha) { 8421fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8431fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org SkASSERT(255 >= alpha); 8441fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8451fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org if (count <= 0) { 8461fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org return; 8471fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org } 8481fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8491fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org unsigned alpha256 = SkAlpha255To256(alpha); 8501fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8511fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org // First deal with odd counts 8521fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org if (count & 1) { 8531fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org uint8x8_t vsrc = vdup_n_u8(0), vdst = vdup_n_u8(0), vres; 8541fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org uint16x8_t vdst_wide, vsrc_wide; 8551fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org unsigned dst_scale; 8561fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8571fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org // Load 8581fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vsrc = vreinterpret_u8_u32(vld1_lane_u32(src, vreinterpret_u32_u8(vsrc), 0)); 8591fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vdst = vreinterpret_u8_u32(vld1_lane_u32(dst, vreinterpret_u32_u8(vdst), 0)); 8601fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8611fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org // Calc dst_scale 8621fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org dst_scale = vget_lane_u8(vsrc, 3); 8631fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org dst_scale *= alpha256; 8641fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org dst_scale >>= 8; 8651fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org dst_scale = 256 - dst_scale; 8661fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8671fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org // Process src 8681fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vsrc_wide = vmovl_u8(vsrc); 8691fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vsrc_wide = vmulq_n_u16(vsrc_wide, alpha256); 8701fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8711fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org // Process dst 8721fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vdst_wide = vmovl_u8(vdst); 8731fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vdst_wide = vmulq_n_u16(vdst_wide, dst_scale); 8741fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8751fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org // Combine 8761fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vres = vshrn_n_u16(vdst_wide, 8) + vshrn_n_u16(vsrc_wide, 8); 8771fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8781fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vst1_lane_u32(dst, vreinterpret_u32_u8(vres), 0); 8791fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org dst++; 8801fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org src++; 8811fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org count--; 8821fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org } 8831fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8841fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org if (count) { 8851fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org uint8x8_t alpha_mask; 8861fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org static const uint8_t alpha_mask_setup[] = {3,3,3,3,7,7,7,7}; 8871fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org alpha_mask = vld1_u8(alpha_mask_setup); 8881fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8891fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org do { 8901fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8911fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org uint8x8_t vsrc, vdst, vres, vsrc_alphas; 8921fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org uint16x8_t vdst_wide, vsrc_wide, vsrc_scale, vdst_scale; 8931fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8941fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org __builtin_prefetch(src+32); 8951fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org __builtin_prefetch(dst+32); 8961fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 8971fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org // Load 8981fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vsrc = vreinterpret_u8_u32(vld1_u32(src)); 8991fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vdst = vreinterpret_u8_u32(vld1_u32(dst)); 9001fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 9011fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org // Prepare src_scale 9021fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vsrc_scale = vdupq_n_u16(alpha256); 9031fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 9041fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org // Calc dst_scale 9051fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vsrc_alphas = vtbl1_u8(vsrc, alpha_mask); 9061fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vdst_scale = vmovl_u8(vsrc_alphas); 9071fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vdst_scale *= vsrc_scale; 9081fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vdst_scale = vshrq_n_u16(vdst_scale, 8); 9091fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vdst_scale = vsubq_u16(vdupq_n_u16(256), vdst_scale); 9101fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 9111fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org // Process src 9121fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vsrc_wide = vmovl_u8(vsrc); 9131fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vsrc_wide *= vsrc_scale; 9141fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 9151fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org // Process dst 9161fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vdst_wide = vmovl_u8(vdst); 9171fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vdst_wide *= vdst_scale; 9181fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 9191fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org // Combine 9201fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vres = vshrn_n_u16(vdst_wide, 8) + vshrn_n_u16(vsrc_wide, 8); 9211fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 9221fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org vst1_u32(dst, vreinterpret_u32_u8(vres)); 9231fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 9241fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org src += 2; 9251fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org dst += 2; 9261fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org count -= 2; 9271fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org } while(count); 9281fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org } 9291fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org} 9301fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org 931a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com/////////////////////////////////////////////////////////////////////////////// 932a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 933fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#undef DEBUG_OPAQUE_DITHER 934a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 935fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#if defined(DEBUG_OPAQUE_DITHER) 936a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comstatic void showme8(char *str, void *p, int len) 937a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com{ 938fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com static char buf[256]; 939fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com char tbuf[32]; 940fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int i; 941fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com char *pc = (char*) p; 942fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sprintf(buf,"%8s:", str); 943fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com for(i=0;i<len;i++) { 944fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sprintf(tbuf, " %02x", pc[i]); 945fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com strcat(buf, tbuf); 946fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 947fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com SkDebugf("%s\n", buf); 948a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com} 949a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comstatic void showme16(char *str, void *p, int len) 950a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com{ 951fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com static char buf[256]; 952fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com char tbuf[32]; 953fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int i; 954fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint16_t *pc = (uint16_t*) p; 955fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sprintf(buf,"%8s:", str); 956fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com len = (len / sizeof(uint16_t)); /* passed as bytes */ 957fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com for(i=0;i<len;i++) { 958fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sprintf(tbuf, " %04x", pc[i]); 959fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com strcat(buf, tbuf); 960fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 961fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com SkDebugf("%s\n", buf); 962a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com} 963a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 964a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 965a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comvoid S32A_D565_Opaque_Dither_neon (uint16_t * SK_RESTRICT dst, 966a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com const SkPMColor* SK_RESTRICT src, 967a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com int count, U8CPU alpha, int x, int y) { 968a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkASSERT(255 == alpha); 969a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 970fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#define UNROLL 8 971a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 972a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (count >= UNROLL) { 973fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint8x8_t dbase; 974fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 975fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#if defined(DEBUG_OPAQUE_DITHER) 976fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint16_t tmpbuf[UNROLL]; 977fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int td[UNROLL]; 978fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int tdv[UNROLL]; 979fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int ta[UNROLL]; 980fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int tap[UNROLL]; 981fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint16_t in_dst[UNROLL]; 982fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int offset = 0; 983fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int noisy = 0; 984a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 985a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 986fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com const uint8_t *dstart = &gDitherMatrix_Neon[(y&3)*12 + (x&3)]; 987fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dbase = vld1_u8(dstart); 988a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 989a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com do { 990fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint8x8_t sr, sg, sb, sa, d; 991fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint16x8_t dst8, scale8, alpha8; 992fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint16x8_t dst_r, dst_g, dst_b; 993fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 994fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#if defined(DEBUG_OPAQUE_DITHER) 995fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* calculate 8 elements worth into a temp buffer */ 996fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com { 997fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int my_y = y; 998fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int my_x = x; 999fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com SkPMColor* my_src = (SkPMColor*)src; 1000fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint16_t* my_dst = dst; 1001fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int i; 1002a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1003a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com DITHER_565_SCAN(my_y); 1004a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com for(i=0;i<UNROLL;i++) { 1005a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkPMColor c = *my_src++; 1006a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkPMColorAssert(c); 1007a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (c) { 1008a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned a = SkGetPackedA32(c); 1009fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1010a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com int d = SkAlphaMul(DITHER_VALUE(my_x), SkAlpha255To256(a)); 1011fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com tdv[i] = DITHER_VALUE(my_x); 1012fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com ta[i] = a; 1013fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com tap[i] = SkAlpha255To256(a); 1014fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com td[i] = d; 1015fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1016a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned sr = SkGetPackedR32(c); 1017a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned sg = SkGetPackedG32(c); 1018a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned sb = SkGetPackedB32(c); 1019a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com sr = SkDITHER_R32_FOR_565(sr, d); 1020a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com sg = SkDITHER_G32_FOR_565(sg, d); 1021a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com sb = SkDITHER_B32_FOR_565(sb, d); 1022fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1023a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com uint32_t src_expanded = (sg << 24) | (sr << 13) | (sb << 2); 1024a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com uint32_t dst_expanded = SkExpand_rgb_16(*my_dst); 1025a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com dst_expanded = dst_expanded * (SkAlpha255To256(255 - a) >> 3); 1026a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // now src and dst expanded are in g:11 r:10 x:1 b:10 1027a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com tmpbuf[i] = SkCompact_rgb_16((src_expanded + dst_expanded) >> 5); 1028fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com td[i] = d; 1029a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1030a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } else { 1031fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com tmpbuf[i] = *my_dst; 1032fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com ta[i] = tdv[i] = td[i] = 0xbeef; 1033fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1034fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com in_dst[i] = *my_dst; 1035a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com my_dst += 1; 1036a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com DITHER_INC_X(my_x); 1037a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 1038fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1039a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 1040a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1041fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* source is in ABGR */ 1042fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com { 1043fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com register uint8x8_t d0 asm("d0"); 1044fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com register uint8x8_t d1 asm("d1"); 1045fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com register uint8x8_t d2 asm("d2"); 1046fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com register uint8x8_t d3 asm("d3"); 1047a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1048fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com asm ("vld4.8 {d0-d3},[%4] /* r=%P0 g=%P1 b=%P2 a=%P3 */" 1049fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com : "=w" (d0), "=w" (d1), "=w" (d2), "=w" (d3) 1050fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com : "r" (src) 1051a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com ); 1052fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sr = d0; sg = d1; sb = d2; sa = d3; 1053fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1054a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1055fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* calculate 'd', which will be 0..7 */ 1056fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* dbase[] is 0..7; alpha is 0..256; 16 bits suffice */ 1057a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#if defined(SK_BUILD_FOR_ANDROID) 1058fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* SkAlpha255To256() semantic a+1 vs a+a>>7 */ 1059fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com alpha8 = vaddw_u8(vmovl_u8(sa), vdup_n_u8(1)); 1060a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#else 1061fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com alpha8 = vaddw_u8(vmovl_u8(sa), vshr_n_u8(sa, 7)); 1062a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 1063fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com alpha8 = vmulq_u16(alpha8, vmovl_u8(dbase)); 1064fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com d = vshrn_n_u16(alpha8, 8); /* narrowing too */ 1065fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1066fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* sr = sr - (sr>>5) + d */ 1067fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* watching for 8-bit overflow. d is 0..7; risky range of 1068fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * sr is >248; and then (sr>>5) is 7 so it offsets 'd'; 1069fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * safe as long as we do ((sr-sr>>5) + d) */ 1070fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sr = vsub_u8(sr, vshr_n_u8(sr, 5)); 1071fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sr = vadd_u8(sr, d); 1072fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1073fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* sb = sb - (sb>>5) + d */ 1074fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sb = vsub_u8(sb, vshr_n_u8(sb, 5)); 1075fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sb = vadd_u8(sb, d); 1076fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1077fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* sg = sg - (sg>>6) + d>>1; similar logic for overflows */ 1078fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sg = vsub_u8(sg, vshr_n_u8(sg, 6)); 1079fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sg = vadd_u8(sg, vshr_n_u8(d,1)); 1080fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1081fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* need to pick up 8 dst's -- at 16 bits each, 128 bits */ 1082fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst8 = vld1q_u16(dst); 1083fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_b = vandq_u16(dst8, vdupq_n_u16(0x001F)); 1084fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_g = vandq_u16(vshrq_n_u16(dst8,5), vdupq_n_u16(0x003F)); 1085fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_r = vshrq_n_u16(dst8,11); /* clearing hi bits */ 1086fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1087fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* blend */ 1088a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#if 1 1089fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* SkAlpha255To256() semantic a+1 vs a+a>>7 */ 1090fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* originally 255-sa + 1 */ 1091fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com scale8 = vsubw_u8(vdupq_n_u16(256), sa); 1092a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#else 1093fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com scale8 = vsubw_u8(vdupq_n_u16(255), sa); 1094fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com scale8 = vaddq_u16(scale8, vshrq_n_u16(scale8, 7)); 1095a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 1096a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1097a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#if 1 1098fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* combine the addq and mul, save 3 insns */ 1099fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com scale8 = vshrq_n_u16(scale8, 3); 1100fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_b = vmlaq_u16(vshll_n_u8(sb,2), dst_b, scale8); 1101fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_g = vmlaq_u16(vshll_n_u8(sg,3), dst_g, scale8); 1102fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_r = vmlaq_u16(vshll_n_u8(sr,2), dst_r, scale8); 1103a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#else 1104fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* known correct, but +3 insns over above */ 1105fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com scale8 = vshrq_n_u16(scale8, 3); 1106fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_b = vmulq_u16(dst_b, scale8); 1107fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_g = vmulq_u16(dst_g, scale8); 1108fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_r = vmulq_u16(dst_r, scale8); 1109fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1110fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* combine */ 1111fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* NB: vshll widens, need to preserve those bits */ 1112fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_b = vaddq_u16(dst_b, vshll_n_u8(sb,2)); 1113fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_g = vaddq_u16(dst_g, vshll_n_u8(sg,3)); 1114fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst_r = vaddq_u16(dst_r, vshll_n_u8(sr,2)); 1115a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 1116a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1117fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* repack to store */ 1118fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst8 = vandq_u16(vshrq_n_u16(dst_b, 5), vdupq_n_u16(0x001F)); 1119fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst8 = vsliq_n_u16(dst8, vshrq_n_u16(dst_g, 5), 5); 1120fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst8 = vsliq_n_u16(dst8, vshrq_n_u16(dst_r,5), 11); 1121fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1122fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com vst1q_u16(dst, dst8); 1123fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1124fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#if defined(DEBUG_OPAQUE_DITHER) 1125fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* verify my 8 elements match the temp buffer */ 1126fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com { 1127fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int i, bad=0; 1128fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com static int invocation; 1129fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1130fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com for (i=0;i<UNROLL;i++) 1131fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com if (tmpbuf[i] != dst[i]) bad=1; 1132fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com if (bad) { 1133fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com SkDebugf("BAD S32A_D565_Opaque_Dither_neon(); invocation %d offset %d\n", 1134fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com invocation, offset); 1135fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com SkDebugf(" alpha 0x%x\n", alpha); 1136fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com for (i=0;i<UNROLL;i++) 1137fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com SkDebugf("%2d: %s %04x w %04x id %04x s %08x d %04x %04x %04x %04x\n", 1138fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com i, ((tmpbuf[i] != dst[i])?"BAD":"got"), 1139fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst[i], tmpbuf[i], in_dst[i], src[i], td[i], tdv[i], tap[i], ta[i]); 1140fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1141fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com showme16("alpha8", &alpha8, sizeof(alpha8)); 1142fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com showme16("scale8", &scale8, sizeof(scale8)); 1143fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com showme8("d", &d, sizeof(d)); 1144fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com showme16("dst8", &dst8, sizeof(dst8)); 1145fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com showme16("dst_b", &dst_b, sizeof(dst_b)); 1146fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com showme16("dst_g", &dst_g, sizeof(dst_g)); 1147fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com showme16("dst_r", &dst_r, sizeof(dst_r)); 1148fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com showme8("sb", &sb, sizeof(sb)); 1149fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com showme8("sg", &sg, sizeof(sg)); 1150fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com showme8("sr", &sr, sizeof(sr)); 1151fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1152fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* cop out */ 1153fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com return; 1154fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1155fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com offset += UNROLL; 1156fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com invocation++; 1157fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1158a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 1159a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1160a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com dst += UNROLL; 1161fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com src += UNROLL; 1162fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com count -= UNROLL; 1163fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* skip x += UNROLL, since it's unchanged mod-4 */ 1164a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } while (count >= UNROLL); 1165a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 1166fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#undef UNROLL 1167a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1168a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com /* residuals */ 1169a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (count > 0) { 1170a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com DITHER_565_SCAN(y); 1171a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com do { 1172a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkPMColor c = *src++; 1173a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkPMColorAssert(c); 1174a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (c) { 1175a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned a = SkGetPackedA32(c); 1176fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1177a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // dither and alpha are just temporary variables to work-around 1178a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // an ICE in debug. 1179a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned dither = DITHER_VALUE(x); 1180a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned alpha = SkAlpha255To256(a); 1181a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com int d = SkAlphaMul(dither, alpha); 1182fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1183a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned sr = SkGetPackedR32(c); 1184a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned sg = SkGetPackedG32(c); 1185a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned sb = SkGetPackedB32(c); 1186a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com sr = SkDITHER_R32_FOR_565(sr, d); 1187a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com sg = SkDITHER_G32_FOR_565(sg, d); 1188a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com sb = SkDITHER_B32_FOR_565(sb, d); 1189fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1190a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com uint32_t src_expanded = (sg << 24) | (sr << 13) | (sb << 2); 1191a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com uint32_t dst_expanded = SkExpand_rgb_16(*dst); 1192a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com dst_expanded = dst_expanded * (SkAlpha255To256(255 - a) >> 3); 1193a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // now src and dst expanded are in g:11 r:10 x:1 b:10 1194a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com *dst = SkCompact_rgb_16((src_expanded + dst_expanded) >> 5); 1195a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 1196a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com dst += 1; 1197a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com DITHER_INC_X(x); 1198a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } while (--count != 0); 1199a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 1200a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com} 1201a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1202a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com/////////////////////////////////////////////////////////////////////////////// 1203a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1204fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#undef DEBUG_S32_OPAQUE_DITHER 1205a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1206a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comvoid S32_D565_Opaque_Dither_neon(uint16_t* SK_RESTRICT dst, 1207a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com const SkPMColor* SK_RESTRICT src, 1208a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com int count, U8CPU alpha, int x, int y) { 1209a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkASSERT(255 == alpha); 1210a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1211fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#define UNROLL 8 1212a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (count >= UNROLL) { 1213fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint8x8_t d; 1214fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com const uint8_t *dstart = &gDitherMatrix_Neon[(y&3)*12 + (x&3)]; 1215fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com d = vld1_u8(dstart); 1216fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1217fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com while (count >= UNROLL) { 1218efbe8e9bedda21a3e061ebf3d96431a0f250a654djsollen@google.com uint8x8_t sr, sg, sb; 1219efbe8e9bedda21a3e061ebf3d96431a0f250a654djsollen@google.com uint16x8_t dr, dg, db; 1220fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint16x8_t dst8; 1221fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1222fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com { 1223fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com register uint8x8_t d0 asm("d0"); 1224fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com register uint8x8_t d1 asm("d1"); 1225fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com register uint8x8_t d2 asm("d2"); 1226fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com register uint8x8_t d3 asm("d3"); 1227fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1228688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org asm ( 1229688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org "vld4.8 {d0-d3},[%[src]]! /* r=%P0 g=%P1 b=%P2 a=%P3 */" 1230688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org : "=w" (d0), "=w" (d1), "=w" (d2), "=w" (d3), [src] "+&r" (src) 1231688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org : 1232688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org ); 1233688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org sg = d1; 1234688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) 1235688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org sr = d2; sb = d0; 1236688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) 1237688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org sr = d0; sb = d2; 1238688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org#endif 1239fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1240fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /* XXX: if we want to prefetch, hide it in the above asm() 1241fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * using the gcc __builtin_prefetch(), the prefetch will 1242fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * fall to the bottom of the loop -- it won't stick up 1243fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * at the top of the loop, just after the vld4. 1244fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com */ 1245fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1246688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org // sr = sr - (sr>>5) + d 1247fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sr = vsub_u8(sr, vshr_n_u8(sr, 5)); 1248fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dr = vaddl_u8(sr, d); 1249fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1250688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org // sb = sb - (sb>>5) + d 1251fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sb = vsub_u8(sb, vshr_n_u8(sb, 5)); 1252fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com db = vaddl_u8(sb, d); 1253fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1254688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org // sg = sg - (sg>>6) + d>>1; similar logic for overflows 1255fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com sg = vsub_u8(sg, vshr_n_u8(sg, 6)); 1256688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org dg = vaddl_u8(sg, vshr_n_u8(d, 1)); 1257fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1258688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org // pack high bits of each into 565 format (rgb, b is lsb) 1259fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst8 = vshrq_n_u16(db, 3); 1260fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst8 = vsliq_n_u16(dst8, vshrq_n_u16(dg, 2), 5); 1261688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org dst8 = vsliq_n_u16(dst8, vshrq_n_u16(dr, 3), 11); 1262fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1263688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org // store it 1264fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com vst1q_u16(dst, dst8); 1265fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1266fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#if defined(DEBUG_S32_OPAQUE_DITHER) 1267688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org // always good to know if we generated good results 1268fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com { 1269fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com int i, myx = x, myy = y; 1270fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com DITHER_565_SCAN(myy); 1271fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com for (i=0;i<UNROLL;i++) { 1272688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org // the '!' in the asm block above post-incremented src by the 8 pixels it reads. 1273688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org SkPMColor c = src[i-8]; 1274fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com unsigned dither = DITHER_VALUE(myx); 1275fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com uint16_t val = SkDitherRGB32To565(c, dither); 1276fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com if (val != dst[i]) { 1277fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com SkDebugf("RBE: src %08x dither %02x, want %04x got %04x dbas[i] %02x\n", 1278fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com c, dither, val, dst[i], dstart[i]); 1279fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1280fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com DITHER_INC_X(myx); 1281fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1282fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1283a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com#endif 1284a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1285fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com dst += UNROLL; 1286688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org // we don't need to increment src as the asm above has already done it 1287fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com count -= UNROLL; 1288688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org x += UNROLL; // probably superfluous 1289fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1290a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 1291fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#undef UNROLL 1292a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1293688d362b4545e1beadebb7ba5886813d7038883ccommit-bot@chromium.org // residuals 1294a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (count > 0) { 1295a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com DITHER_565_SCAN(y); 1296a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com do { 1297a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkPMColor c = *src++; 1298a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkPMColorAssert(c); 1299a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkASSERT(SkGetPackedA32(c) == 255); 1300a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1301a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned dither = DITHER_VALUE(x); 1302a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com *dst++ = SkDitherRGB32To565(c, dither); 1303a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com DITHER_INC_X(x); 1304a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } while (--count != 0); 1305a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 1306a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com} 1307a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1308a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comvoid Color32_arm_neon(SkPMColor* dst, const SkPMColor* src, int count, 1309a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com SkPMColor color) { 1310a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (count <= 0) { 1311a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com return; 1312a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 1313a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1314a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (0 == color) { 1315a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (src != dst) { 1316a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com memcpy(dst, src, count * sizeof(SkPMColor)); 1317a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 1318a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com return; 1319a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 1320a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1321a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned colorA = SkGetPackedA32(color); 1322a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (255 == colorA) { 1323a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com sk_memset32(dst, color, count); 1324a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } else { 1325a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com unsigned scale = 256 - SkAlpha255To256(colorA); 1326a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1327a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com if (count >= 8) { 1328a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // at the end of this assembly, count will have been decremented 1329a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // to a negative value. That is, if count mod 8 = x, it will be 1330a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // -8 +x coming out. 1331a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com asm volatile ( 1332a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com PLD128(src, 0) 1333a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1334a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vdup.32 q0, %[color] \n\t" 1335a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1336a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com PLD128(src, 128) 1337a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1338a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // scale numerical interval [0-255], so load as 8 bits 1339a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vdup.8 d2, %[scale] \n\t" 1340a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1341a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com PLD128(src, 256) 1342a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1343a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "subs %[count], %[count], #8 \n\t" 1344a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1345a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com PLD128(src, 384) 1346a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1347a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "Loop_Color32: \n\t" 1348a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1349a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // load src color, 8 pixels, 4 64 bit registers 1350a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // (and increment src). 1351a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vld1.32 {d4-d7}, [%[src]]! \n\t" 1352a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1353a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com PLD128(src, 384) 1354a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1355a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // multiply long by scale, 64 bits at a time, 1356a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // destination into a 128 bit register. 1357a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmull.u8 q4, d4, d2 \n\t" 1358a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmull.u8 q5, d5, d2 \n\t" 1359a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmull.u8 q6, d6, d2 \n\t" 1360a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vmull.u8 q7, d7, d2 \n\t" 1361a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1362a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // shift the 128 bit registers, containing the 16 1363a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // bit scaled values back to 8 bits, narrowing the 1364a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // results to 64 bit registers. 1365a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshrn.i16 d8, q4, #8 \n\t" 1366a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshrn.i16 d9, q5, #8 \n\t" 1367a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshrn.i16 d10, q6, #8 \n\t" 1368a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vshrn.i16 d11, q7, #8 \n\t" 1369a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1370a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // adding back the color, using 128 bit registers. 1371a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vadd.i8 q6, q4, q0 \n\t" 1372a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vadd.i8 q7, q5, q0 \n\t" 1373a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1374a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // store back the 8 calculated pixels (2 128 bit 1375a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // registers), and increment dst. 1376a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "vst1.32 {d12-d15}, [%[dst]]! \n\t" 1377a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1378a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "subs %[count], %[count], #8 \n\t" 1379a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "bge Loop_Color32 \n\t" 1380a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com : [src] "+r" (src), [dst] "+r" (dst), [count] "+r" (count) 1381a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com : [color] "r" (color), [scale] "r" (scale) 1382a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com : "cc", "memory", 1383a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", 1384a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15" 1385a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com ); 1386a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // At this point, if we went through the inline assembly, count is 1387a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // a negative value: 1388a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // if the value is -8, there is no pixel left to process. 1389a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // if the value is -7, there is one pixel left to process 1390a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // ... 1391a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // And'ing it with 7 will give us the number of pixels 1392a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // left to process. 1393a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com count = count & 0x7; 1394a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 1395a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1396a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com while (count > 0) { 1397a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com *dst = color + SkAlphaMulQ(*src, scale); 1398a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com src += 1; 1399a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com dst += 1; 1400a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com count--; 1401a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 1402a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com } 1403a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com} 1404a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1405a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com/////////////////////////////////////////////////////////////////////////////// 1406a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1407a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comconst SkBlitRow::Proc sk_blitrow_platform_565_procs_arm_neon[] = { 1408a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // no dither 14090060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org // NOTE: For the S32_D565_Blend function below, we don't have a special 14100060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org // version that assumes that each source pixel is opaque. But our 14110060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org // S32A is still faster than the default, so use it. 14120060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org S32_D565_Opaque_neon, 1413a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com S32A_D565_Blend_neon, // really S32_D565_Blend 1414a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com S32A_D565_Opaque_neon, 1415a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com S32A_D565_Blend_neon, 1416a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1417a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com // dither 1418a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com S32_D565_Opaque_Dither_neon, 1419a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com S32_D565_Blend_Dither_neon, 1420a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com S32A_D565_Opaque_Dither_neon, 1421a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com NULL, // S32A_D565_Blend_Dither 1422a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com}; 1423a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com 1424a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.comconst SkBlitRow::Proc32 sk_blitrow_platform_32_procs_arm_neon[] = { 1425a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com NULL, // S32_Opaque, 1426fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com S32_Blend_BlitRow32_neon, // S32_Blend, 1427c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com /* 1428c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com * We have two choices for S32A_Opaque procs. The one reads the src alpha 1429c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com * value and attempts to optimize accordingly. The optimization is 1430c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com * sensitive to the source content and is not a win in all cases. For 1431c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com * example, if there are a lot of transitions between the alpha states, 1432c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com * the performance will almost certainly be worse. However, for many 1433c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com * common cases the performance is equivalent or better than the standard 1434c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com * case where we do not inspect the src alpha. 1435c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com */ 1436c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com#if SK_A32_SHIFT == 24 1437c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com // This proc assumes the alpha value occupies bits 24-32 of each SkPMColor 1438c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com S32A_Opaque_BlitRow32_neon_src_alpha, // S32A_Opaque, 1439c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com#else 1440c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com S32A_Opaque_BlitRow32_neon, // S32A_Opaque, 1441c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com#endif 14421fdc6774280ffc18dd7e1247e430931aa2f58790commit-bot@chromium.org S32A_Blend_BlitRow32_neon // S32A_Blend 1443a8dd1ce930811a51cc841f583424d507d95e7e78digit@google.com}; 1444