1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitRow.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCoreBlitters.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDither.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 14e552dc82be1512df0a8a7f24310d27d2740d7601djsollen@google.com#include "SkUtilsArm.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17f62833d9c9075dd1028ef4395e3370d2597d9115mtklein#if defined(__mips_dsp) 186336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesutextern void blitmask_d565_opaque_mips(int width, int height, uint16_t* device, 196336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut unsigned deviceRB, const uint8_t* alpha, 206336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut uint32_t expanded32, unsigned maskRB); 216336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut#endif 226336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut 2389351ec35a05eaf59edb7431d23a754cd084a363commit-bot@chromium.org#if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN) 24867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com #include <arm_neon.h> 25dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhangextern void SkRGB16BlitterBlitV_neon(uint16_t* device, 26dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhang int height, 27dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhang size_t deviceRB, 28dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhang unsigned scale, 29dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhang uint32_t src32); 30867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#else 31867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com // if we don't have neon, then our black blitter is worth the extra code 32867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com #define USE_BLACK_BLITTER 33867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#endif 34867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count) { 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0) { 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // see if we need to write one short before we can cast to an 4byte ptr 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // (we do this subtract rather than (unsigned)dst so we don't get warnings 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // on 64bit machines) 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (((char*)dst - (char*)0) & 2) { 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst++ = value; 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count -= 1; 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTSwap(value, other); 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 46fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // fast way to set [value,other] pairs 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_CPU_BENDIAN 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32((uint32_t*)dst, (value << 16) | other, count >> 1); 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32((uint32_t*)dst, (other << 16) | value, count >> 1); 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 53fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count & 1) { 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dst[count - 1] = value; 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 621fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comclass SkRGB16_Blitter : public SkRasterBlitter { 631fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.compublic: 6441e010cb901c0da9066c4df562030808c9ccd7f8reed SkRGB16_Blitter(const SkPixmap& device, const SkPaint& paint); 6536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitH(int x, int y, int width) override; 66a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 6736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const int16_t* runs) override; 6836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitV(int x, int y, int height, SkAlpha alpha) override; 6936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitRect(int x, int y, int width, int height) override; 7041e010cb901c0da9066c4df562030808c9ccd7f8reed void blitMask(const SkMask&, const SkIRect&) override; 7141e010cb901c0da9066c4df562030808c9ccd7f8reed const SkPixmap* justAnOpaqueColor(uint32_t*) override; 72fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 731fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprotected: 741fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkPMColor fSrcColor32; 75ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t fExpandedRaw16; 761fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com unsigned fScale; 771fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com uint16_t fColor16; // already scaled by fScale 781fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com uint16_t fRawColor16; // unscaled 791fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com uint16_t fRawDither16; // unscaled 801fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkBool8 fDoDither; 81fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 82402448d6818cab9d7b7633a0c18fcf574c915357mlee SkBlitRow::ColorProc16 fColorProc16; 83402448d6818cab9d7b7633a0c18fcf574c915357mlee 841fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com // illegal 851fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkRGB16_Blitter& operator=(const SkRGB16_Blitter&); 86fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 871fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com typedef SkRasterBlitter INHERITED; 881fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com}; 891fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 901fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comclass SkRGB16_Opaque_Blitter : public SkRGB16_Blitter { 911fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.compublic: 9241e010cb901c0da9066c4df562030808c9ccd7f8reed SkRGB16_Opaque_Blitter(const SkPixmap& device, const SkPaint& paint); 9336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitH(int x, int y, int width) override; 9441e010cb901c0da9066c4df562030808c9ccd7f8reed void blitAntiH(int x, int y, const SkAlpha* antialias, const int16_t* runs) override; 9536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitV(int x, int y, int height, SkAlpha alpha) override; 9636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitRect(int x, int y, int width, int height) override; 9741e010cb901c0da9066c4df562030808c9ccd7f8reed void blitMask(const SkMask&, const SkIRect&) override; 98fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 991fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprivate: 1001fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com typedef SkRGB16_Blitter INHERITED; 1011fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com}; 1021fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 103867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#ifdef USE_BLACK_BLITTER 1041fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comclass SkRGB16_Black_Blitter : public SkRGB16_Opaque_Blitter { 1051fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.compublic: 10641e010cb901c0da9066c4df562030808c9ccd7f8reed SkRGB16_Black_Blitter(const SkPixmap& device, const SkPaint& paint); 10736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitMask(const SkMask&, const SkIRect&) override; 10841e010cb901c0da9066c4df562030808c9ccd7f8reed void blitAntiH(int x, int y, const SkAlpha* antialias, const int16_t* runs) override; 109fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1101fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprivate: 1111fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com typedef SkRGB16_Opaque_Blitter INHERITED; 1121fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com}; 113867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#endif 1141fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 1151fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comclass SkRGB16_Shader_Blitter : public SkShaderBlitter { 1161fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.compublic: 11741e010cb901c0da9066c4df562030808c9ccd7f8reed SkRGB16_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, 11887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext); 1191fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual ~SkRGB16_Shader_Blitter(); 12036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitH(int x, int y, int width) override; 121a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 12236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const int16_t* runs) override; 12336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitRect(int x, int y, int width, int height) override; 124fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1251fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprotected: 126a7f11918d92621507f35b228a290f05dcaf0f4b6reed SkPMColor* fBuffer; 127a7f11918d92621507f35b228a290f05dcaf0f4b6reed SkBlitRow::Proc16 fOpaqueProc; 128a7f11918d92621507f35b228a290f05dcaf0f4b6reed SkBlitRow::Proc16 fAlphaProc; 129fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1301fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprivate: 1311fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com // illegal 1321fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkRGB16_Shader_Blitter& operator=(const SkRGB16_Shader_Blitter&); 133fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1341fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com typedef SkShaderBlitter INHERITED; 1351fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com}; 1361fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 1371fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comclass SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter { 1381fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.compublic: 13941e010cb901c0da9066c4df562030808c9ccd7f8reed SkRGB16_Shader_Xfermode_Blitter(const SkPixmap& device, const SkPaint& paint, 14087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext); 1411fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual ~SkRGB16_Shader_Xfermode_Blitter(); 14236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitH(int x, int y, int width) override; 143a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 14436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const int16_t* runs) override; 145fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1461fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprivate: 1471fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkXfermode* fXfermode; 1481fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkPMColor* fBuffer; 1491fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com uint8_t* fAAExpand; 150fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1511fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com // illegal 1521fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkRGB16_Shader_Xfermode_Blitter& operator=(const SkRGB16_Shader_Xfermode_Blitter&); 153fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1541fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com typedef SkShaderBlitter INHERITED; 1551fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com}; 1561fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 1571fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com/////////////////////////////////////////////////////////////////////////////// 158867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#ifdef USE_BLACK_BLITTER 15941e010cb901c0da9066c4df562030808c9ccd7f8reedSkRGB16_Black_Blitter::SkRGB16_Black_Blitter(const SkPixmap& device, const SkPaint& paint) 160dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com : INHERITED(device, paint) { 16196fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(paint.getShader() == nullptr); 16296fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(paint.getColorFilter() == nullptr); 16396fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(paint.getXfermode() == nullptr); 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(paint.getColor() == SK_ColorBLACK); 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 1 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define black_8_pixels(mask, dst) \ 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { \ 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x80) dst[0] = 0; \ 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x40) dst[1] = 0; \ 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x20) dst[2] = 0; \ 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x10) dst[3] = 0; \ 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x08) dst[4] = 0; \ 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x04) dst[5] = 0; \ 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x02) dst[6] = 0; \ 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x01) dst[7] = 0; \ 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (0) 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline black_8_pixels(U8CPU mask, uint16_t dst[]) 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x80) dst[0] = 0; 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x40) dst[1] = 0; 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x20) dst[2] = 0; 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x10) dst[3] = 0; 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x08) dst[4] = 0; 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x04) dst[5] = 0; 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x02) dst[6] = 0; 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x01) dst[7] = 0; 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_NAME SkRGB16_Black_BlitBW 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_ARGS 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst) black_8_pixels(mask, dst) 19641e010cb901c0da9066c4df562030808c9ccd7f8reed#define SK_BLITBWMASK_GETADDR writable_addr16 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_DEVTYPE uint16_t 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitBWMaskTemplate.h" 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 200333d6cb2448d0febcbeb7c8c7310c0ff2d1a6104tomhudson@google.comvoid SkRGB16_Black_Blitter::blitMask(const SkMask& mask, 201333d6cb2448d0febcbeb7c8c7310c0ff2d1a6104tomhudson@google.com const SkIRect& clip) { 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask.fFormat == SkMask::kBW_Format) { 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRGB16_Black_BlitBW(fDevice, mask, clip); 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 20541e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(clip.fLeft, clip.fTop); 2067989186dab6bc2f1c1927daf91bddd32b7fd8d0creed@google.com const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop); 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned width = clip.width(); 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned height = clip.height(); 209e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes() - (width << 1); 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned maskRB = mask.fRowBytes - width; 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((int)height > 0); 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((int)width > 0); 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((int)deviceRB >= 0); 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((int)maskRB >= 0); 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned w = width; 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned aa = *alpha++; 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *device = SkAlphaMulRGB16(*device, SkAlpha255To256(255 - aa)); 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += 1; 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--w != 0); 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device = (uint16_t*)((char*)device + deviceRB); 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha += maskRB; 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--height != 0); 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Black_Blitter::blitAntiH(int x, int y, 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkAlpha* SK_RESTRICT antialias, 232a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* SK_RESTRICT runs) { 23341e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = runs[0]; 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count >= 0); 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned aa = antialias[0]; 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa) { 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa == 255) { 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(device, 0, count << 1); 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com aa = SkAlpha255To256(255 - aa); 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *device = SkAlphaMulRGB16(*device, aa); 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += 1; 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--count != 0); 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com continue; 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 260867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#endif 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2629a74d313452f30629e2615eb8cbfe902433582c0reed@android.com/////////////////////////////////////////////////////////////////////////////// 2639a74d313452f30629e2615eb8cbfe902433582c0reed@android.com/////////////////////////////////////////////////////////////////////////////// 2649a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 26541e010cb901c0da9066c4df562030808c9ccd7f8reedSkRGB16_Opaque_Blitter::SkRGB16_Opaque_Blitter(const SkPixmap& device, const SkPaint& paint) 26641e010cb901c0da9066c4df562030808c9ccd7f8reed : INHERITED(device, paint) {} 2679a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 268a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comvoid SkRGB16_Opaque_Blitter::blitH(int x, int y, int width) { 2699a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkASSERT(width > 0); 2709a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkASSERT(x + width <= fDevice.width()); 27141e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); 2729a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t srcColor = fColor16; 27331d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com 2749a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkASSERT(fRawColor16 == srcColor); 2759a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (fDoDither) { 2769a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t ditherColor = fRawDither16; 2779a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if ((x ^ y) & 1) { 2789a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkTSwap(ditherColor, srcColor); 2799a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 2809a74d313452f30629e2615eb8cbfe902433582c0reed@android.com sk_dither_memset16(device, srcColor, ditherColor, width); 2819a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } else { 2829a74d313452f30629e2615eb8cbfe902433582c0reed@android.com sk_memset16(device, srcColor, width); 2839a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 2849a74d313452f30629e2615eb8cbfe902433582c0reed@android.com} 2859a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 2869a74d313452f30629e2615eb8cbfe902433582c0reed@android.com// return 1 or 0 from a bool 28763debae4c1020fa1e0ccd92ef3cbfdc8735acf8ereed@android.comstatic inline int Bool2Int(int value) { 288fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com return !!value; 2899a74d313452f30629e2615eb8cbfe902433582c0reed@android.com} 2909a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 2919a74d313452f30629e2615eb8cbfe902433582c0reed@android.comvoid SkRGB16_Opaque_Blitter::blitAntiH(int x, int y, 2929a74d313452f30629e2615eb8cbfe902433582c0reed@android.com const SkAlpha* SK_RESTRICT antialias, 293a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* SK_RESTRICT runs) { 29441e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); 2959a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t srcColor = fRawColor16; 296ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t srcExpanded = fExpandedRaw16; 2979a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int ditherInt = Bool2Int(fDoDither); 2989a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t ditherColor = fRawDither16; 2999a74d313452f30629e2615eb8cbfe902433582c0reed@android.com // if we have no dithering, this will always fail 3009a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if ((x ^ y) & ditherInt) { 3019a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkTSwap(ditherColor, srcColor); 3029a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3039a74d313452f30629e2615eb8cbfe902433582c0reed@android.com for (;;) { 3049a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int count = runs[0]; 3059a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkASSERT(count >= 0); 3069a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (count <= 0) { 3079a74d313452f30629e2615eb8cbfe902433582c0reed@android.com return; 3089a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3099a74d313452f30629e2615eb8cbfe902433582c0reed@android.com runs += count; 31031d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com 3119a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned aa = antialias[0]; 3129a74d313452f30629e2615eb8cbfe902433582c0reed@android.com antialias += count; 3139a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (aa) { 3149a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (aa == 255) { 3159a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (ditherInt) { 3169a74d313452f30629e2615eb8cbfe902433582c0reed@android.com sk_dither_memset16(device, srcColor, 3179a74d313452f30629e2615eb8cbfe902433582c0reed@android.com ditherColor, count); 3189a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } else { 3199a74d313452f30629e2615eb8cbfe902433582c0reed@android.com sk_memset16(device, srcColor, count); 3209a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3219a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } else { 3229a74d313452f30629e2615eb8cbfe902433582c0reed@android.com // TODO: respect fDoDither 3239a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned scale5 = SkAlpha255To256(aa) >> 3; 324ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t src32 = srcExpanded * scale5; 3259a74d313452f30629e2615eb8cbfe902433582c0reed@android.com scale5 = 32 - scale5; // now we can use it on the device 3269a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int n = count; 3279a74d313452f30629e2615eb8cbfe902433582c0reed@android.com do { 3289a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 3299a74d313452f30629e2615eb8cbfe902433582c0reed@android.com *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); 3309a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (--n != 0); 3319a74d313452f30629e2615eb8cbfe902433582c0reed@android.com goto DONE; 3329a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3339a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3349a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device += count; 33531d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com 3369a74d313452f30629e2615eb8cbfe902433582c0reed@android.com DONE: 3379a74d313452f30629e2615eb8cbfe902433582c0reed@android.com // if we have no dithering, this will always fail 3389a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (count & ditherInt) { 3399a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkTSwap(ditherColor, srcColor); 3409a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3419a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3429a74d313452f30629e2615eb8cbfe902433582c0reed@android.com} 3439a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 3449a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#define solid_8_pixels(mask, dst, color) \ 3459a74d313452f30629e2615eb8cbfe902433582c0reed@android.com do { \ 3469a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x80) dst[0] = color; \ 3479a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x40) dst[1] = color; \ 3489a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x20) dst[2] = color; \ 3499a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x10) dst[3] = color; \ 3509a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x08) dst[4] = color; \ 3519a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x04) dst[5] = color; \ 3529a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x02) dst[6] = color; \ 3539a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x01) dst[7] = color; \ 3549a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (0) 3559a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 3569a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#define SK_BLITBWMASK_NAME SkRGB16_BlitBW 3579a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#define SK_BLITBWMASK_ARGS , uint16_t color 3589a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst) solid_8_pixels(mask, dst, color) 35941e010cb901c0da9066c4df562030808c9ccd7f8reed#define SK_BLITBWMASK_GETADDR writable_addr16 3609a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#define SK_BLITBWMASK_DEVTYPE uint16_t 3619a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#include "SkBlitBWMaskTemplate.h" 3629a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 363f62833d9c9075dd1028ef4395e3370d2597d9115mtklein#if !defined(__mips_dsp) 3649a74d313452f30629e2615eb8cbfe902433582c0reed@android.comstatic U16CPU blend_compact(uint32_t src32, uint32_t dst32, unsigned scale5) { 3659a74d313452f30629e2615eb8cbfe902433582c0reed@android.com return SkCompact_rgb_16(dst32 + ((src32 - dst32) * scale5 >> 5)); 3669a74d313452f30629e2615eb8cbfe902433582c0reed@android.com} 3676336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut#endif 3689a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 369333d6cb2448d0febcbeb7c8c7310c0ff2d1a6104tomhudson@google.comvoid SkRGB16_Opaque_Blitter::blitMask(const SkMask& mask, 370333d6cb2448d0febcbeb7c8c7310c0ff2d1a6104tomhudson@google.com const SkIRect& clip) { 3719a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask.fFormat == SkMask::kBW_Format) { 3729a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkRGB16_BlitBW(fDevice, mask, clip, fColor16); 3739a74d313452f30629e2615eb8cbfe902433582c0reed@android.com return; 3749a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 37531d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com 37641e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(clip.fLeft, clip.fTop); 3777989186dab6bc2f1c1927daf91bddd32b7fd8d0creed@google.com const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop); 3789a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int width = clip.width(); 3799a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int height = clip.height(); 380e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes() - (width << 1); 3819a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned maskRB = mask.fRowBytes - width; 382ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t expanded32 = fExpandedRaw16; 38331d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com 38489351ec35a05eaf59edb7431d23a754cd084a363commit-bot@chromium.org#if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN) 385fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#define UNROLL 8 386867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com do { 387867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com int w = width; 388867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com if (w >= UNROLL) { 389641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org uint32x4_t color, dev_lo, dev_hi; 390641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org uint32x4_t wn1, wn2, tmp; 391641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org uint32x4_t vmask_g16, vmask_ng16; 392641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org uint16x8_t valpha, vdev; 393641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org uint16x4_t odev_lo, odev_hi, valpha_lo, valpha_hi; 394641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 395641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // prepare constants 396641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org vmask_g16 = vdupq_n_u32(SK_G16_MASK_IN_PLACE); 397641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org vmask_ng16 = vdupq_n_u32(~SK_G16_MASK_IN_PLACE); 398867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com color = vdupq_n_u32(expanded32); 399fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 400867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com do { 401641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // alpha is 8x8, widen and split to get a pair of 16x4 402641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org valpha = vaddw_u8(vdupq_n_u16(1), vld1_u8(alpha)); 403641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org valpha = vshrq_n_u16(valpha, 3); 404641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org valpha_lo = vget_low_u16(valpha); 405641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org valpha_hi = vget_high_u16(valpha); 406641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 407641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // load pixels 408641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org vdev = vld1q_u16(device); 409641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org dev_lo = vmovl_u16(vget_low_u16(vdev)); 410641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org dev_hi = vmovl_u16(vget_high_u16(vdev)); 411641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 412641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // unpack them in 32 bits 413641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org dev_lo = (dev_lo & vmask_ng16) | vshlq_n_u32(dev_lo & vmask_g16, 16); 414641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org dev_hi = (dev_hi & vmask_ng16) | vshlq_n_u32(dev_hi & vmask_g16, 16); 415641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 416641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // blend with color 417641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org tmp = (color - dev_lo) * vmovl_u16(valpha_lo); 418641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org tmp = vshrq_n_u32(tmp, 5); 419641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org dev_lo += tmp; 420641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 421641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org tmp = vmulq_u32(color - dev_hi, vmovl_u16(valpha_hi)); 422641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org tmp = vshrq_n_u32(tmp, 5); 423641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org dev_hi += tmp; 424641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 425641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // re-compact 426641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org wn1 = dev_lo & vmask_ng16; 427641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org wn2 = vshrq_n_u32(dev_lo, 16) & vmask_g16; 428641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org odev_lo = vmovn_u32(wn1 | wn2); 429641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 430641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org wn1 = dev_hi & vmask_ng16; 431641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org wn2 = vshrq_n_u32(dev_hi, 16) & vmask_g16; 432641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org odev_hi = vmovn_u32(wn1 | wn2); 433641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 434641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // store 435641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org vst1q_u16(device, vcombine_u16(odev_lo, odev_hi)); 436fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 437867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com device += UNROLL; 438867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com alpha += UNROLL; 439867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com w -= UNROLL; 440867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com } while (w >= UNROLL); 441867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com } 442fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 443641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // residuals 444867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com while (w > 0) { 445867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com *device = blend_compact(expanded32, SkExpand_rgb_16(*device), 446867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com SkAlpha255To256(*alpha++) >> 3); 447867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com device += 1; 448867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com --w; 449867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com } 450867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com device = (uint16_t*)((char*)device + deviceRB); 451867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com alpha += maskRB; 452867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com } while (--height != 0); 453fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#undef UNROLL 454f62833d9c9075dd1028ef4395e3370d2597d9115mtklein#elif defined(__mips_dsp) 4556336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut blitmask_d565_opaque_mips(width, height, device, deviceRB, alpha, expanded32, maskRB); 456867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#else // non-neon code 4579a74d313452f30629e2615eb8cbfe902433582c0reed@android.com do { 4589a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int w = width; 4599a74d313452f30629e2615eb8cbfe902433582c0reed@android.com do { 460ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com *device = blend_compact(expanded32, SkExpand_rgb_16(*device), 4619a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkAlpha255To256(*alpha++) >> 3); 4629a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device += 1; 4639a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (--w != 0); 4649a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device = (uint16_t*)((char*)device + deviceRB); 4659a74d313452f30629e2615eb8cbfe902433582c0reed@android.com alpha += maskRB; 4669a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (--height != 0); 467867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#endif 4689a74d313452f30629e2615eb8cbfe902433582c0reed@android.com} 4699a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 470ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.comvoid SkRGB16_Opaque_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { 47141e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); 472e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes(); 473fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 474ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com // TODO: respect fDoDither 475ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com unsigned scale5 = SkAlpha255To256(alpha) >> 3; 476ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t src32 = fExpandedRaw16 * scale5; 477ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com scale5 = 32 - scale5; 478dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhang#if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN) 479dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhang SkRGB16BlitterBlitV_neon(device, height, deviceRB, scale5, src32); 480dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhang#else 481ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com do { 482ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 483ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com *device = SkCompact_rgb_16((src32 + dst32) >> 5); 484ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com device = (uint16_t*)((char*)device + deviceRB); 485ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com } while (--height != 0); 486dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhang#endif 487ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com} 488ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com 4899a74d313452f30629e2615eb8cbfe902433582c0reed@android.comvoid SkRGB16_Opaque_Blitter::blitRect(int x, int y, int width, int height) { 4909a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); 49141e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); 492e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes(); 4939a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t color16 = fColor16; 49431d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com 4959a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (fDoDither) { 4969a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t ditherColor = fRawDither16; 4979a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if ((x ^ y) & 1) { 4989a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkTSwap(ditherColor, color16); 4999a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 5009a74d313452f30629e2615eb8cbfe902433582c0reed@android.com while (--height >= 0) { 5019a74d313452f30629e2615eb8cbfe902433582c0reed@android.com sk_dither_memset16(device, color16, ditherColor, width); 5029a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkTSwap(ditherColor, color16); 5039a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device = (uint16_t*)((char*)device + deviceRB); 5049a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 5059a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } else { // no dither 5069a74d313452f30629e2615eb8cbfe902433582c0reed@android.com while (--height >= 0) { 5079a74d313452f30629e2615eb8cbfe902433582c0reed@android.com sk_memset16(device, color16, width); 5089a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device = (uint16_t*)((char*)device + deviceRB); 5099a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 5109a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 5119a74d313452f30629e2615eb8cbfe902433582c0reed@android.com} 5129a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 5139a74d313452f30629e2615eb8cbfe902433582c0reed@android.com/////////////////////////////////////////////////////////////////////////////// 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 51541e010cb901c0da9066c4df562030808c9ccd7f8reedSkRGB16_Blitter::SkRGB16_Blitter(const SkPixmap& device, const SkPaint& paint) 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(device) { 5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkColor color = paint.getColor(); 5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fSrcColor32 = SkPreMultiplyColor(color); 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fScale = SkAlpha255To256(SkColorGetA(color)); 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int r = SkColorGetR(color); 5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int g = SkColorGetG(color); 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int b = SkColorGetB(color); 5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRawColor16 = fRawDither16 = SkPack888ToRGB16(r, g, b); 5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we're dithered, use fRawDither16 to hold that. 5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((fDoDither = paint.isDither()) != false) { 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRawDither16 = SkDitherPack888ToRGB16(r, g, b); 5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 531ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com 532ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com fExpandedRaw16 = SkExpand_rgb_16(fRawColor16); 533ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor16 = SkPackRGB16( SkAlphaMul(r, fScale) >> (8 - SK_R16_BITS), 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAlphaMul(g, fScale) >> (8 - SK_G16_BITS), 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAlphaMul(b, fScale) >> (8 - SK_B16_BITS)); 537402448d6818cab9d7b7633a0c18fcf574c915357mlee 538402448d6818cab9d7b7633a0c18fcf574c915357mlee // compute SkBlitRow::Procs 539402448d6818cab9d7b7633a0c18fcf574c915357mlee unsigned flags = 0; 540402448d6818cab9d7b7633a0c18fcf574c915357mlee 541402448d6818cab9d7b7633a0c18fcf574c915357mlee if (SkGetPackedA32(fSrcColor32) < 0xFF) { 542402448d6818cab9d7b7633a0c18fcf574c915357mlee flags |= SkBlitRow::kSrcPixelAlpha_Flag; 543402448d6818cab9d7b7633a0c18fcf574c915357mlee } 544402448d6818cab9d7b7633a0c18fcf574c915357mlee 545402448d6818cab9d7b7633a0c18fcf574c915357mlee if (fDoDither) { 546402448d6818cab9d7b7633a0c18fcf574c915357mlee flags |= SkBlitRow::kDither_Flag; 547402448d6818cab9d7b7633a0c18fcf574c915357mlee } 548402448d6818cab9d7b7633a0c18fcf574c915357mlee 549402448d6818cab9d7b7633a0c18fcf574c915357mlee fColorProc16 = SkBlitRow::ColorFactory16(flags); 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 55241e010cb901c0da9066c4df562030808c9ccd7f8reedconst SkPixmap* SkRGB16_Blitter::justAnOpaqueColor(uint32_t* value) { 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fDoDither && 256 == fScale) { 5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *value = fRawColor16; 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return &fDevice; 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 55796fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 560a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comvoid SkRGB16_Blitter::blitH(int x, int y, int width) { 5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(width > 0); 5628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x + width <= fDevice.width()); 56341e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); 5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 565402448d6818cab9d7b7633a0c18fcf574c915357mlee fColorProc16(device, fSrcColor32, width, x, y); 5668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Blitter::blitAntiH(int x, int y, 5698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkAlpha* SK_RESTRICT antialias, 570a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* SK_RESTRICT runs) { 57141e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); 572ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t srcExpanded = fExpandedRaw16; 5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned scale = fScale; 5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5759a74d313452f30629e2615eb8cbfe902433582c0reed@android.com // TODO: respect fDoDither 5769a74d313452f30629e2615eb8cbfe902433582c0reed@android.com for (;;) { 5779a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int count = runs[0]; 5789a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkASSERT(count >= 0); 5799a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (count <= 0) { 5809a74d313452f30629e2615eb8cbfe902433582c0reed@android.com return; 5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5829a74d313452f30629e2615eb8cbfe902433582c0reed@android.com runs += count; 5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5849a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned aa = antialias[0]; 5859a74d313452f30629e2615eb8cbfe902433582c0reed@android.com antialias += count; 5869a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (aa) { 5879a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned scale5 = SkAlpha255To256(aa) * scale >> (8 + 3); 588ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t src32 = srcExpanded * scale5; 5899a74d313452f30629e2615eb8cbfe902433582c0reed@android.com scale5 = 32 - scale5; 5909a74d313452f30629e2615eb8cbfe902433582c0reed@android.com do { 5919a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 5929a74d313452f30629e2615eb8cbfe902433582c0reed@android.com *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); 5939a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (--count != 0); 5949a74d313452f30629e2615eb8cbfe902433582c0reed@android.com continue; 5958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5969a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device += count; 5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline void blend_8_pixels(U8CPU bw, uint16_t dst[], unsigned dst_scale, 6018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U16CPU srcColor) { 6028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x80) dst[0] = srcColor + SkAlphaMulRGB16(dst[0], dst_scale); 6038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x40) dst[1] = srcColor + SkAlphaMulRGB16(dst[1], dst_scale); 6048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x20) dst[2] = srcColor + SkAlphaMulRGB16(dst[2], dst_scale); 6058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x10) dst[3] = srcColor + SkAlphaMulRGB16(dst[3], dst_scale); 6068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x08) dst[4] = srcColor + SkAlphaMulRGB16(dst[4], dst_scale); 6078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x04) dst[5] = srcColor + SkAlphaMulRGB16(dst[5], dst_scale); 6088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x02) dst[6] = srcColor + SkAlphaMulRGB16(dst[6], dst_scale); 6098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x01) dst[7] = srcColor + SkAlphaMulRGB16(dst[7], dst_scale); 6108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_NAME SkRGB16_BlendBW 6138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_ARGS , unsigned dst_scale, U16CPU src_color 6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst) blend_8_pixels(mask, dst, dst_scale, src_color) 61541e010cb901c0da9066c4df562030808c9ccd7f8reed#define SK_BLITBWMASK_GETADDR writable_addr16 6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_DEVTYPE uint16_t 6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitBWMaskTemplate.h" 6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 619333d6cb2448d0febcbeb7c8c7310c0ff2d1a6104tomhudson@google.comvoid SkRGB16_Blitter::blitMask(const SkMask& mask, 620333d6cb2448d0febcbeb7c8c7310c0ff2d1a6104tomhudson@google.com const SkIRect& clip) { 6218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask.fFormat == SkMask::kBW_Format) { 6229a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkRGB16_BlendBW(fDevice, mask, clip, 256 - fScale, fColor16); 6238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 6248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 62641e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(clip.fLeft, clip.fTop); 6277989186dab6bc2f1c1927daf91bddd32b7fd8d0creed@google.com const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop); 6288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = clip.width(); 6298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = clip.height(); 630e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes() - (width << 1); 6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned maskRB = mask.fRowBytes - width; 632ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t color32 = fExpandedRaw16; 6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6349a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned scale256 = fScale; 6359a74d313452f30629e2615eb8cbfe902433582c0reed@android.com do { 6369a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int w = width; 6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 6389a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned aa = *alpha++; 6399a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned scale = SkAlpha255To256(aa) * scale256 >> (8 + 3); 6409a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint32_t src32 = color32 * scale; 6419a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint32_t dst32 = SkExpand_rgb_16(*device) * (32 - scale); 6429a74d313452f30629e2615eb8cbfe902433582c0reed@android.com *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); 6439a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (--w != 0); 6449a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device = (uint16_t*)((char*)device + deviceRB); 6459a74d313452f30629e2615eb8cbfe902433582c0reed@android.com alpha += maskRB; 6469a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (--height != 0); 6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { 65041e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); 651e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes(); 6528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 653ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com // TODO: respect fDoDither 654ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com unsigned scale5 = SkAlpha255To256(alpha) * fScale >> (8 + 3); 655ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t src32 = fExpandedRaw16 * scale5; 656ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com scale5 = 32 - scale5; 657dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhang#if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN) 658dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhang SkRGB16BlitterBlitV_neon(device, height, deviceRB, scale5, src32); 659dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhang#else 660ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com do { 661ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 662ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com *device = SkCompact_rgb_16((src32 + dst32) >> 5); 663ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com device = (uint16_t*)((char*)device + deviceRB); 664ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com } while (--height != 0); 665dc77b3591841bf1e70ed45455490d688e5d4e6f9yang.zhang#endif 6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Blitter::blitRect(int x, int y, int width, int height) { 6698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); 67041e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); 671e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes(); 6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6739a74d313452f30629e2615eb8cbfe902433582c0reed@android.com while (--height >= 0) { 674402448d6818cab9d7b7633a0c18fcf574c915357mlee fColorProc16(device, fSrcColor32, width, x, y); 6759a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device = (uint16_t*)((char*)device + deviceRB); 6768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 68141e010cb901c0da9066c4df562030808c9ccd7f8reedSkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkPixmap& device, 68287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkPaint& paint, 68387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext) 68441e010cb901c0da9066c4df562030808c9ccd7f8reed : INHERITED(device, paint, shaderContext) 68541e010cb901c0da9066c4df562030808c9ccd7f8reed{ 68696fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(paint.getXfermode() == nullptr); 6878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor)); 6898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // compute SkBlitRow::Procs 6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned flags = 0; 692fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 6935119bdb952025a30f115b9c6a187173956e55097reed@android.com uint32_t shaderFlags = fShaderFlags; 6948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // shaders take care of global alpha, so we never set it in SkBlitRow 6958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!(shaderFlags & SkShader::kOpaqueAlpha_Flag)) { 6968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkBlitRow::kSrcPixelAlpha_Flag; 697c2050e3a3ecfb8738b36e2add15c526e8e0f21fecommit-bot@chromium.org } 6984e5a758f3832594cf1828d367496b5a80bcab8eereed if (paint.isDither()) { 6998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkBlitRow::kDither_Flag; 7008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // used when we know our global alpha is 0xFF 702a7f11918d92621507f35b228a290f05dcaf0f4b6reed fOpaqueProc = SkBlitRow::Factory16(flags); 7038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // used when we know our global alpha is < 0xFF 704a7f11918d92621507f35b228a290f05dcaf0f4b6reed fAlphaProc = SkBlitRow::Factory16(flags | SkBlitRow::kGlobalAlpha_Flag); 7058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRGB16_Shader_Blitter::~SkRGB16_Shader_Blitter() { 7088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fBuffer); 7098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Shader_Blitter::blitH(int x, int y, int width) { 7128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x + width <= fDevice.width()); 7138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 71487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderContext->shadeSpan(x, y, fBuffer, width); 7158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // shaders take care of global alpha, so we pass 0xFF (should be ignored) 71641e010cb901c0da9066c4df562030808c9ccd7f8reed fOpaqueProc(fDevice.writable_addr16(x, y), fBuffer, width, 0xFF, x, y); 7178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7195119bdb952025a30f115b9c6a187173956e55097reed@android.comvoid SkRGB16_Shader_Blitter::blitRect(int x, int y, int width, int height) { 72087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext = fShaderContext; 721a7f11918d92621507f35b228a290f05dcaf0f4b6reed SkBlitRow::Proc16 proc = fOpaqueProc; 72287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkPMColor* buffer = fBuffer; 72341e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* dst = fDevice.writable_addr16(x, y); 72487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org size_t dstRB = fDevice.rowBytes(); 7255119bdb952025a30f115b9c6a187173956e55097reed@android.com 7263c9b2a4a0e4f57db23640e85959ee78b86634628reed@android.com if (fShaderFlags & SkShader::kConstInY32_Flag) { 72787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, buffer, width); 7285119bdb952025a30f115b9c6a187173956e55097reed@android.com do { 7295119bdb952025a30f115b9c6a187173956e55097reed@android.com proc(dst, buffer, width, 0xFF, x, y); 7305119bdb952025a30f115b9c6a187173956e55097reed@android.com y += 1; 7315119bdb952025a30f115b9c6a187173956e55097reed@android.com dst = (uint16_t*)((char*)dst + dstRB); 7325119bdb952025a30f115b9c6a187173956e55097reed@android.com } while (--height); 7335119bdb952025a30f115b9c6a187173956e55097reed@android.com } else { 7345119bdb952025a30f115b9c6a187173956e55097reed@android.com do { 73587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, buffer, width); 7365119bdb952025a30f115b9c6a187173956e55097reed@android.com proc(dst, buffer, width, 0xFF, x, y); 7375119bdb952025a30f115b9c6a187173956e55097reed@android.com y += 1; 7385119bdb952025a30f115b9c6a187173956e55097reed@android.com dst = (uint16_t*)((char*)dst + dstRB); 7395119bdb952025a30f115b9c6a187173956e55097reed@android.com } while (--height); 7405119bdb952025a30f115b9c6a187173956e55097reed@android.com } 7415119bdb952025a30f115b9c6a187173956e55097reed@android.com} 7425119bdb952025a30f115b9c6a187173956e55097reed@android.com 7438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int count_nonzero_span(const int16_t runs[], const SkAlpha aa[]) { 7448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = 0; 7458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 7468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = *runs; 7478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (n == 0 || *aa == 0) { 7488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += n; 7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com aa += n; 7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count += n; 7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 7558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Shader_Blitter::blitAntiH(int x, int y, 7588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkAlpha* SK_RESTRICT antialias, 759a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* SK_RESTRICT runs) { 76087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext = fShaderContext; 7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor* SK_RESTRICT span = fBuffer; 76241e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); 7638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = *runs; 7668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 7678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int aa = *antialias; 7708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0 == aa) { 7718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += count; 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com continue; 7768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int nonZeroCount = count + count_nonzero_span(runs + count, antialias + count); 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer 78187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, nonZeroCount); 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor* localSpan = span; 7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 785a7f11918d92621507f35b228a290f05dcaf0f4b6reed SkBlitRow::Proc16 proc = (aa == 0xFF) ? fOpaqueProc : fAlphaProc; 7868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com proc(device, localSpan, count, aa, x, y); 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += count; 7898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com nonZeroCount -= count; 7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (nonZeroCount == 0) { 7948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 7958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com localSpan += count; 7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(nonZeroCount > 0); 7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count = *runs; 7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com aa = *antialias; 8018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////// 8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter( 80841e010cb901c0da9066c4df562030808c9ccd7f8reed const SkPixmap& device, const SkPaint& paint, 80987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext) 81041e010cb901c0da9066c4df562030808c9ccd7f8reed : INHERITED(device, paint, shaderContext) 81141e010cb901c0da9066c4df562030808c9ccd7f8reed{ 8128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXfermode = paint.getXfermode(); 8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fXfermode); 8148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXfermode->ref(); 8158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = device.width(); 8178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBuffer = (SkPMColor*)sk_malloc_throw((width + (SkAlign4(width) >> 2)) * sizeof(SkPMColor)); 8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fAAExpand = (uint8_t*)(fBuffer + width); 8198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRGB16_Shader_Xfermode_Blitter::~SkRGB16_Shader_Xfermode_Blitter() { 8228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXfermode->unref(); 8238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fBuffer); 8248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Shader_Xfermode_Blitter::blitH(int x, int y, int width) { 8278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x + width <= fDevice.width()); 8288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 82941e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* device = fDevice.writable_addr16(x, y); 8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor* span = fBuffer; 8318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 83287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderContext->shadeSpan(x, y, span, width); 83396fcdcc219d2a0d3579719b84b28bede76efba64halcanary fXfermode->xfer16(device, span, width, nullptr); 8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y, 8378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkAlpha* SK_RESTRICT antialias, 838a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* SK_RESTRICT runs) { 83987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext = fShaderContext; 84087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkXfermode* mode = fXfermode; 8418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor* SK_RESTRICT span = fBuffer; 84287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org uint8_t* SK_RESTRICT aaExpand = fAAExpand; 84341e010cb901c0da9066c4df562030808c9ccd7f8reed uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); 8448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = *runs; 8478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 8488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 8498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int aa = *antialias; 8518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0 == aa) { 8528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 8538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 8548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 8558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += count; 8568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com continue; 8578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int nonZeroCount = count + count_nonzero_span(runs + count, 8608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias + count); 8618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer 86387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, nonZeroCount); 8648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += nonZeroCount; 8668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor* localSpan = span; 8678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 8688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa == 0xFF) { 86996fcdcc219d2a0d3579719b84b28bede76efba64halcanary mode->xfer16(device, localSpan, count, nullptr); 8708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 8718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(aa); 8728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(aaExpand, aa, count); 8738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mode->xfer16(device, localSpan, count, aaExpand); 8748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 8768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 8778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 8788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com nonZeroCount -= count; 8798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (nonZeroCount == 0) { 8808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 8818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com localSpan += count; 8838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(nonZeroCount > 0); 8848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count = *runs; 8858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 8868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com aa = *antialias; 8878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 888fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 8898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8911fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com/////////////////////////////////////////////////////////////////////////////// 8928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 89341e010cb901c0da9066c4df562030808c9ccd7f8reedSkBlitter* SkBlitter_ChooseD565(const SkPixmap& device, const SkPaint& paint, 89487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext, 895a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org SkTBlitterAllocator* allocator) { 89696fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(allocator != nullptr); 897a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org 8981fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkBlitter* blitter; 8991fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkShader* shader = paint.getShader(); 9001fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkXfermode* mode = paint.getXfermode(); 9011fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 9021fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com // we require a shader if there is an xfermode, handled by our caller 90396fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(nullptr == mode || shader); 9041fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 9051fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com if (shader) { 90696fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(shaderContext != nullptr); 9071fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com if (mode) { 90887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org blitter = allocator->createT<SkRGB16_Shader_Xfermode_Blitter>(device, paint, 90987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext); 9101fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } else { 91187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org blitter = allocator->createT<SkRGB16_Shader_Blitter>(device, paint, shaderContext); 9121fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } 9131fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } else { 9141fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com // no shader, no xfermode, (and we always ignore colorfilter) 9151fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkColor color = paint.getColor(); 9161fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com if (0 == SkColorGetA(color)) { 917a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<SkNullBlitter>(); 918867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#ifdef USE_BLACK_BLITTER 9191fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } else if (SK_ColorBLACK == color) { 920a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<SkRGB16_Black_Blitter>(device, paint); 921867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#endif 9221fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } else if (0xFF == SkColorGetA(color)) { 923a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<SkRGB16_Opaque_Blitter>(device, paint); 9241fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } else { 925a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<SkRGB16_Blitter>(device, paint); 9261fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } 9271fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } 928fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 9291fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com return blitter; 9308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 931