1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitRow.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCoreBlitters.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDither.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 16e552dc82be1512df0a8a7f24310d27d2740d7601djsollen@google.com#include "SkUtilsArm.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 196336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut#if SK_MIPS_HAS_DSP 206336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesutextern void blitmask_d565_opaque_mips(int width, int height, uint16_t* device, 216336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut unsigned deviceRB, const uint8_t* alpha, 226336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut uint32_t expanded32, unsigned maskRB); 236336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut#endif 246336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut 2589351ec35a05eaf59edb7431d23a754cd084a363commit-bot@chromium.org#if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN) 26867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com #include <arm_neon.h> 27867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#else 28867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com // if we don't have neon, then our black blitter is worth the extra code 29867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com #define USE_BLACK_BLITTER 30867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#endif 31867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count) { 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0) { 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // see if we need to write one short before we can cast to an 4byte ptr 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // (we do this subtract rather than (unsigned)dst so we don't get warnings 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // on 64bit machines) 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (((char*)dst - (char*)0) & 2) { 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst++ = value; 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count -= 1; 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTSwap(value, other); 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 43fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // fast way to set [value,other] pairs 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_CPU_BENDIAN 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32((uint32_t*)dst, (value << 16) | other, count >> 1); 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32((uint32_t*)dst, (other << 16) | value, count >> 1); 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 50fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count & 1) { 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dst[count - 1] = value; 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 591fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comclass SkRGB16_Blitter : public SkRasterBlitter { 601fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.compublic: 611fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint); 621fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual void blitH(int x, int y, int width); 63a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 64a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* runs); 651fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual void blitV(int x, int y, int height, SkAlpha alpha); 661fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual void blitRect(int x, int y, int width, int height); 67a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com virtual void blitMask(const SkMask&, 68a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const SkIRect&); 691fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual const SkBitmap* justAnOpaqueColor(uint32_t*); 70fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 711fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprotected: 721fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkPMColor fSrcColor32; 73ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t fExpandedRaw16; 741fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com unsigned fScale; 751fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com uint16_t fColor16; // already scaled by fScale 761fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com uint16_t fRawColor16; // unscaled 771fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com uint16_t fRawDither16; // unscaled 781fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkBool8 fDoDither; 79fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 801fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com // illegal 811fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkRGB16_Blitter& operator=(const SkRGB16_Blitter&); 82fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 831fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com typedef SkRasterBlitter INHERITED; 841fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com}; 851fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 861fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comclass SkRGB16_Opaque_Blitter : public SkRGB16_Blitter { 871fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.compublic: 881fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkRGB16_Opaque_Blitter(const SkBitmap& device, const SkPaint& paint); 891fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual void blitH(int x, int y, int width); 90a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 91a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* runs); 92ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com virtual void blitV(int x, int y, int height, SkAlpha alpha); 931fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual void blitRect(int x, int y, int width, int height); 94a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com virtual void blitMask(const SkMask&, 95a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const SkIRect&); 96fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 971fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprivate: 981fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com typedef SkRGB16_Blitter INHERITED; 991fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com}; 1001fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 101867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#ifdef USE_BLACK_BLITTER 1021fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comclass SkRGB16_Black_Blitter : public SkRGB16_Opaque_Blitter { 1031fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.compublic: 1041fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkRGB16_Black_Blitter(const SkBitmap& device, const SkPaint& paint); 1051fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual void blitMask(const SkMask&, const SkIRect&); 106a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 107a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* runs); 108fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1091fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprivate: 1101fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com typedef SkRGB16_Opaque_Blitter INHERITED; 1111fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com}; 112867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#endif 1131fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 1141fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comclass SkRGB16_Shader_Blitter : public SkShaderBlitter { 1151fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.compublic: 11687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkRGB16_Shader_Blitter(const SkBitmap& device, const SkPaint& paint, 11787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext); 1181fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual ~SkRGB16_Shader_Blitter(); 1191fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual void blitH(int x, int y, int width); 120a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 121a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* runs); 1221fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual void blitRect(int x, int y, int width, int height); 123fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1241fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprotected: 1251fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkPMColor* fBuffer; 1261fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkBlitRow::Proc fOpaqueProc; 1271fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkBlitRow::Proc fAlphaProc; 128fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1291fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprivate: 1301fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com // illegal 1311fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkRGB16_Shader_Blitter& operator=(const SkRGB16_Shader_Blitter&); 132fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1331fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com typedef SkShaderBlitter INHERITED; 1341fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com}; 1351fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 1361fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com// used only if the shader can perform shadSpan16 1371fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comclass SkRGB16_Shader16_Blitter : public SkRGB16_Shader_Blitter { 1381fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.compublic: 13987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkRGB16_Shader16_Blitter(const SkBitmap& device, const SkPaint& paint, 14087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext); 1411fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual void blitH(int x, int y, int width); 142a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 143a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* runs); 1441fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual void blitRect(int x, int y, int width, int height); 145fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1461fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprivate: 1471fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com typedef SkRGB16_Shader_Blitter INHERITED; 1481fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com}; 1491fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 1501fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comclass SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter { 1511fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.compublic: 15287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkRGB16_Shader_Xfermode_Blitter(const SkBitmap& device, const SkPaint& paint, 15387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext); 1541fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual ~SkRGB16_Shader_Xfermode_Blitter(); 1551fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com virtual void blitH(int x, int y, int width); 156a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 157a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* runs); 158fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1591fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comprivate: 1601fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkXfermode* fXfermode; 1611fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkPMColor* fBuffer; 1621fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com uint8_t* fAAExpand; 163fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1641fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com // illegal 1651fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkRGB16_Shader_Xfermode_Blitter& operator=(const SkRGB16_Shader_Xfermode_Blitter&); 166fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1671fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com typedef SkShaderBlitter INHERITED; 1681fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com}; 1691fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 1701fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com/////////////////////////////////////////////////////////////////////////////// 171867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#ifdef USE_BLACK_BLITTER 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRGB16_Black_Blitter::SkRGB16_Black_Blitter(const SkBitmap& device, const SkPaint& paint) 173dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com : INHERITED(device, paint) { 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(paint.getShader() == NULL); 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(paint.getColorFilter() == NULL); 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(paint.getXfermode() == NULL); 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(paint.getColor() == SK_ColorBLACK); 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 1 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define black_8_pixels(mask, dst) \ 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { \ 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x80) dst[0] = 0; \ 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x40) dst[1] = 0; \ 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x20) dst[2] = 0; \ 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x10) dst[3] = 0; \ 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x08) dst[4] = 0; \ 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x04) dst[5] = 0; \ 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x02) dst[6] = 0; \ 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x01) dst[7] = 0; \ 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (0) 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline black_8_pixels(U8CPU mask, uint16_t dst[]) 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x80) dst[0] = 0; 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x40) dst[1] = 0; 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x20) dst[2] = 0; 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x10) dst[3] = 0; 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x08) dst[4] = 0; 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x04) dst[5] = 0; 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x02) dst[6] = 0; 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x01) dst[7] = 0; 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_NAME SkRGB16_Black_BlitBW 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_ARGS 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst) black_8_pixels(mask, dst) 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_GETADDR getAddr16 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_DEVTYPE uint16_t 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitBWMaskTemplate.h" 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 213333d6cb2448d0febcbeb7c8c7310c0ff2d1a6104tomhudson@google.comvoid SkRGB16_Black_Blitter::blitMask(const SkMask& mask, 214333d6cb2448d0febcbeb7c8c7310c0ff2d1a6104tomhudson@google.com const SkIRect& clip) { 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask.fFormat == SkMask::kBW_Format) { 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRGB16_Black_BlitBW(fDevice, mask, clip); 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop); 2197989186dab6bc2f1c1927daf91bddd32b7fd8d0creed@google.com const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop); 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned width = clip.width(); 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned height = clip.height(); 222e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes() - (width << 1); 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned maskRB = mask.fRowBytes - width; 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((int)height > 0); 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((int)width > 0); 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((int)deviceRB >= 0); 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((int)maskRB >= 0); 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned w = width; 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned aa = *alpha++; 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *device = SkAlphaMulRGB16(*device, SkAlpha255To256(255 - aa)); 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += 1; 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--w != 0); 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device = (uint16_t*)((char*)device + deviceRB); 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha += maskRB; 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--height != 0); 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Black_Blitter::blitAntiH(int x, int y, 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkAlpha* SK_RESTRICT antialias, 245a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* SK_RESTRICT runs) { 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = runs[0]; 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count >= 0); 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned aa = antialias[0]; 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa) { 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa == 255) { 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(device, 0, count << 1); 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com aa = SkAlpha255To256(255 - aa); 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *device = SkAlphaMulRGB16(*device, aa); 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += 1; 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--count != 0); 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com continue; 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 273867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#endif 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2759a74d313452f30629e2615eb8cbfe902433582c0reed@android.com/////////////////////////////////////////////////////////////////////////////// 2769a74d313452f30629e2615eb8cbfe902433582c0reed@android.com/////////////////////////////////////////////////////////////////////////////// 2779a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 2789a74d313452f30629e2615eb8cbfe902433582c0reed@android.comSkRGB16_Opaque_Blitter::SkRGB16_Opaque_Blitter(const SkBitmap& device, 2799a74d313452f30629e2615eb8cbfe902433582c0reed@android.com const SkPaint& paint) 2809a74d313452f30629e2615eb8cbfe902433582c0reed@android.com: INHERITED(device, paint) {} 2819a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 282a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comvoid SkRGB16_Opaque_Blitter::blitH(int x, int y, int width) { 2839a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkASSERT(width > 0); 2849a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkASSERT(x + width <= fDevice.width()); 2859a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 2869a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t srcColor = fColor16; 28731d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com 2889a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkASSERT(fRawColor16 == srcColor); 2899a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (fDoDither) { 2909a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t ditherColor = fRawDither16; 2919a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if ((x ^ y) & 1) { 2929a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkTSwap(ditherColor, srcColor); 2939a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 2949a74d313452f30629e2615eb8cbfe902433582c0reed@android.com sk_dither_memset16(device, srcColor, ditherColor, width); 2959a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } else { 2969a74d313452f30629e2615eb8cbfe902433582c0reed@android.com sk_memset16(device, srcColor, width); 2979a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 2989a74d313452f30629e2615eb8cbfe902433582c0reed@android.com} 2999a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 3009a74d313452f30629e2615eb8cbfe902433582c0reed@android.com// return 1 or 0 from a bool 30163debae4c1020fa1e0ccd92ef3cbfdc8735acf8ereed@android.comstatic inline int Bool2Int(int value) { 302fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com return !!value; 3039a74d313452f30629e2615eb8cbfe902433582c0reed@android.com} 3049a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 3059a74d313452f30629e2615eb8cbfe902433582c0reed@android.comvoid SkRGB16_Opaque_Blitter::blitAntiH(int x, int y, 3069a74d313452f30629e2615eb8cbfe902433582c0reed@android.com const SkAlpha* SK_RESTRICT antialias, 307a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* SK_RESTRICT runs) { 3089a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 3099a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t srcColor = fRawColor16; 310ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t srcExpanded = fExpandedRaw16; 3119a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int ditherInt = Bool2Int(fDoDither); 3129a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t ditherColor = fRawDither16; 3139a74d313452f30629e2615eb8cbfe902433582c0reed@android.com // if we have no dithering, this will always fail 3149a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if ((x ^ y) & ditherInt) { 3159a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkTSwap(ditherColor, srcColor); 3169a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3179a74d313452f30629e2615eb8cbfe902433582c0reed@android.com for (;;) { 3189a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int count = runs[0]; 3199a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkASSERT(count >= 0); 3209a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (count <= 0) { 3219a74d313452f30629e2615eb8cbfe902433582c0reed@android.com return; 3229a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3239a74d313452f30629e2615eb8cbfe902433582c0reed@android.com runs += count; 32431d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com 3259a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned aa = antialias[0]; 3269a74d313452f30629e2615eb8cbfe902433582c0reed@android.com antialias += count; 3279a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (aa) { 3289a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (aa == 255) { 3299a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (ditherInt) { 3309a74d313452f30629e2615eb8cbfe902433582c0reed@android.com sk_dither_memset16(device, srcColor, 3319a74d313452f30629e2615eb8cbfe902433582c0reed@android.com ditherColor, count); 3329a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } else { 3339a74d313452f30629e2615eb8cbfe902433582c0reed@android.com sk_memset16(device, srcColor, count); 3349a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3359a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } else { 3369a74d313452f30629e2615eb8cbfe902433582c0reed@android.com // TODO: respect fDoDither 3379a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned scale5 = SkAlpha255To256(aa) >> 3; 338ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t src32 = srcExpanded * scale5; 3399a74d313452f30629e2615eb8cbfe902433582c0reed@android.com scale5 = 32 - scale5; // now we can use it on the device 3409a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int n = count; 3419a74d313452f30629e2615eb8cbfe902433582c0reed@android.com do { 3429a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 3439a74d313452f30629e2615eb8cbfe902433582c0reed@android.com *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); 3449a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (--n != 0); 3459a74d313452f30629e2615eb8cbfe902433582c0reed@android.com goto DONE; 3469a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3479a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3489a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device += count; 34931d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com 3509a74d313452f30629e2615eb8cbfe902433582c0reed@android.com DONE: 3519a74d313452f30629e2615eb8cbfe902433582c0reed@android.com // if we have no dithering, this will always fail 3529a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (count & ditherInt) { 3539a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkTSwap(ditherColor, srcColor); 3549a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3559a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 3569a74d313452f30629e2615eb8cbfe902433582c0reed@android.com} 3579a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 3589a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#define solid_8_pixels(mask, dst, color) \ 3599a74d313452f30629e2615eb8cbfe902433582c0reed@android.com do { \ 3609a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x80) dst[0] = color; \ 3619a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x40) dst[1] = color; \ 3629a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x20) dst[2] = color; \ 3639a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x10) dst[3] = color; \ 3649a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x08) dst[4] = color; \ 3659a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x04) dst[5] = color; \ 3669a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x02) dst[6] = color; \ 3679a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask & 0x01) dst[7] = color; \ 3689a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (0) 3699a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 3709a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#define SK_BLITBWMASK_NAME SkRGB16_BlitBW 3719a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#define SK_BLITBWMASK_ARGS , uint16_t color 3729a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst) solid_8_pixels(mask, dst, color) 3739a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#define SK_BLITBWMASK_GETADDR getAddr16 3749a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#define SK_BLITBWMASK_DEVTYPE uint16_t 3759a74d313452f30629e2615eb8cbfe902433582c0reed@android.com#include "SkBlitBWMaskTemplate.h" 3769a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 3776336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut#if !defined(SK_MIPS_HAS_DSP) 3789a74d313452f30629e2615eb8cbfe902433582c0reed@android.comstatic U16CPU blend_compact(uint32_t src32, uint32_t dst32, unsigned scale5) { 3799a74d313452f30629e2615eb8cbfe902433582c0reed@android.com return SkCompact_rgb_16(dst32 + ((src32 - dst32) * scale5 >> 5)); 3809a74d313452f30629e2615eb8cbfe902433582c0reed@android.com} 3816336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut#endif 3829a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 383333d6cb2448d0febcbeb7c8c7310c0ff2d1a6104tomhudson@google.comvoid SkRGB16_Opaque_Blitter::blitMask(const SkMask& mask, 384333d6cb2448d0febcbeb7c8c7310c0ff2d1a6104tomhudson@google.com const SkIRect& clip) { 3859a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (mask.fFormat == SkMask::kBW_Format) { 3869a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkRGB16_BlitBW(fDevice, mask, clip, fColor16); 3879a74d313452f30629e2615eb8cbfe902433582c0reed@android.com return; 3889a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 38931d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com 3909a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop); 3917989186dab6bc2f1c1927daf91bddd32b7fd8d0creed@google.com const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop); 3929a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int width = clip.width(); 3939a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int height = clip.height(); 394e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes() - (width << 1); 3959a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned maskRB = mask.fRowBytes - width; 396ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t expanded32 = fExpandedRaw16; 39731d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com 39889351ec35a05eaf59edb7431d23a754cd084a363commit-bot@chromium.org#if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN) 399fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#define UNROLL 8 400867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com do { 401867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com int w = width; 402867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com if (w >= UNROLL) { 403641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org uint32x4_t color, dev_lo, dev_hi; 404641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org uint32x4_t wn1, wn2, tmp; 405641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org uint32x4_t vmask_g16, vmask_ng16; 406641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org uint16x8_t valpha, vdev; 407641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org uint16x4_t odev_lo, odev_hi, valpha_lo, valpha_hi; 408641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 409641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // prepare constants 410641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org vmask_g16 = vdupq_n_u32(SK_G16_MASK_IN_PLACE); 411641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org vmask_ng16 = vdupq_n_u32(~SK_G16_MASK_IN_PLACE); 412867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com color = vdupq_n_u32(expanded32); 413fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 414867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com do { 415641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // alpha is 8x8, widen and split to get a pair of 16x4 416641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org valpha = vaddw_u8(vdupq_n_u16(1), vld1_u8(alpha)); 417641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org valpha = vshrq_n_u16(valpha, 3); 418641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org valpha_lo = vget_low_u16(valpha); 419641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org valpha_hi = vget_high_u16(valpha); 420641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 421641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // load pixels 422641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org vdev = vld1q_u16(device); 423641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org dev_lo = vmovl_u16(vget_low_u16(vdev)); 424641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org dev_hi = vmovl_u16(vget_high_u16(vdev)); 425641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 426641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // unpack them in 32 bits 427641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org dev_lo = (dev_lo & vmask_ng16) | vshlq_n_u32(dev_lo & vmask_g16, 16); 428641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org dev_hi = (dev_hi & vmask_ng16) | vshlq_n_u32(dev_hi & vmask_g16, 16); 429641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 430641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // blend with color 431641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org tmp = (color - dev_lo) * vmovl_u16(valpha_lo); 432641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org tmp = vshrq_n_u32(tmp, 5); 433641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org dev_lo += tmp; 434641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 435641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org tmp = vmulq_u32(color - dev_hi, vmovl_u16(valpha_hi)); 436641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org tmp = vshrq_n_u32(tmp, 5); 437641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org dev_hi += tmp; 438641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 439641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // re-compact 440641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org wn1 = dev_lo & vmask_ng16; 441641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org wn2 = vshrq_n_u32(dev_lo, 16) & vmask_g16; 442641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org odev_lo = vmovn_u32(wn1 | wn2); 443641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 444641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org wn1 = dev_hi & vmask_ng16; 445641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org wn2 = vshrq_n_u32(dev_hi, 16) & vmask_g16; 446641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org odev_hi = vmovn_u32(wn1 | wn2); 447641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org 448641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // store 449641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org vst1q_u16(device, vcombine_u16(odev_lo, odev_hi)); 450fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 451867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com device += UNROLL; 452867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com alpha += UNROLL; 453867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com w -= UNROLL; 454867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com } while (w >= UNROLL); 455867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com } 456fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 457641a2491964f7e5921fad6649be08175e03b0434commit-bot@chromium.org // residuals 458867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com while (w > 0) { 459867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com *device = blend_compact(expanded32, SkExpand_rgb_16(*device), 460867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com SkAlpha255To256(*alpha++) >> 3); 461867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com device += 1; 462867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com --w; 463867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com } 464867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com device = (uint16_t*)((char*)device + deviceRB); 465867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com alpha += maskRB; 466867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com } while (--height != 0); 467fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#undef UNROLL 4686336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut#elif SK_MIPS_HAS_DSP 4696336f7c225f7806f5bbccea90ba6d2c881e8a470djordje.pesut blitmask_d565_opaque_mips(width, height, device, deviceRB, alpha, expanded32, maskRB); 470867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#else // non-neon code 4719a74d313452f30629e2615eb8cbfe902433582c0reed@android.com do { 4729a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int w = width; 4739a74d313452f30629e2615eb8cbfe902433582c0reed@android.com do { 474ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com *device = blend_compact(expanded32, SkExpand_rgb_16(*device), 4759a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkAlpha255To256(*alpha++) >> 3); 4769a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device += 1; 4779a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (--w != 0); 4789a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device = (uint16_t*)((char*)device + deviceRB); 4799a74d313452f30629e2615eb8cbfe902433582c0reed@android.com alpha += maskRB; 4809a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (--height != 0); 481867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#endif 4829a74d313452f30629e2615eb8cbfe902433582c0reed@android.com} 4839a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 484ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.comvoid SkRGB16_Opaque_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { 485ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 486e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes(); 487fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 488ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com // TODO: respect fDoDither 489ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com unsigned scale5 = SkAlpha255To256(alpha) >> 3; 490ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t src32 = fExpandedRaw16 * scale5; 491ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com scale5 = 32 - scale5; 492ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com do { 493ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 494ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com *device = SkCompact_rgb_16((src32 + dst32) >> 5); 495ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com device = (uint16_t*)((char*)device + deviceRB); 496ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com } while (--height != 0); 497ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com} 498ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com 4999a74d313452f30629e2615eb8cbfe902433582c0reed@android.comvoid SkRGB16_Opaque_Blitter::blitRect(int x, int y, int width, int height) { 5009a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); 5019a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 502e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes(); 5039a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t color16 = fColor16; 50431d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com 5059a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (fDoDither) { 5069a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint16_t ditherColor = fRawDither16; 5079a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if ((x ^ y) & 1) { 5089a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkTSwap(ditherColor, color16); 5099a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 5109a74d313452f30629e2615eb8cbfe902433582c0reed@android.com while (--height >= 0) { 5119a74d313452f30629e2615eb8cbfe902433582c0reed@android.com sk_dither_memset16(device, color16, ditherColor, width); 5129a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkTSwap(ditherColor, color16); 5139a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device = (uint16_t*)((char*)device + deviceRB); 5149a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 5159a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } else { // no dither 5169a74d313452f30629e2615eb8cbfe902433582c0reed@android.com while (--height >= 0) { 5179a74d313452f30629e2615eb8cbfe902433582c0reed@android.com sk_memset16(device, color16, width); 5189a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device = (uint16_t*)((char*)device + deviceRB); 5199a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 5209a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } 5219a74d313452f30629e2615eb8cbfe902433582c0reed@android.com} 5229a74d313452f30629e2615eb8cbfe902433582c0reed@android.com 5239a74d313452f30629e2615eb8cbfe902433582c0reed@android.com/////////////////////////////////////////////////////////////////////////////// 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRGB16_Blitter::SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint) 5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(device) { 5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkColor color = paint.getColor(); 5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fSrcColor32 = SkPreMultiplyColor(color); 5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fScale = SkAlpha255To256(SkColorGetA(color)); 5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int r = SkColorGetR(color); 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int g = SkColorGetG(color); 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int b = SkColorGetB(color); 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRawColor16 = fRawDither16 = SkPack888ToRGB16(r, g, b); 5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we're dithered, use fRawDither16 to hold that. 5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((fDoDither = paint.isDither()) != false) { 5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRawDither16 = SkDitherPack888ToRGB16(r, g, b); 5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 541ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com 542ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com fExpandedRaw16 = SkExpand_rgb_16(fRawColor16); 543ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com 5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor16 = SkPackRGB16( SkAlphaMul(r, fScale) >> (8 - SK_R16_BITS), 5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAlphaMul(g, fScale) >> (8 - SK_G16_BITS), 5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAlphaMul(b, fScale) >> (8 - SK_B16_BITS)); 5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkBitmap* SkRGB16_Blitter::justAnOpaqueColor(uint32_t* value) { 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fDoDither && 256 == fScale) { 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *value = fRawColor16; 5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return &fDevice; 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 557dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.comstatic uint32_t pmcolor_to_expand16(SkPMColor c) { 558dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com unsigned r = SkGetPackedR32(c); 559dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com unsigned g = SkGetPackedG32(c); 560dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com unsigned b = SkGetPackedB32(c); 561dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com return (g << 24) | (r << 13) | (b << 2); 562dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com} 563dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com 564dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.comstatic inline void blend32_16_row(SkPMColor src, uint16_t dst[], int count) { 565dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com SkASSERT(count > 0); 566dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com uint32_t src_expand = pmcolor_to_expand16(src); 567b602b8e5334edc0bfcdf086c2ea58e2b5d5f1f3breed@android.com unsigned scale = SkAlpha255To256(0xFF - SkGetPackedA32(src)) >> 3; 568dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com do { 569dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com uint32_t dst_expand = SkExpand_rgb_16(*dst) * scale; 570dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com *dst = SkCompact_rgb_16((src_expand + dst_expand) >> 5); 571dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com dst += 1; 572dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com } while (--count != 0); 573dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com} 574dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com 575a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comvoid SkRGB16_Blitter::blitH(int x, int y, int width) { 5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(width > 0); 5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x + width <= fDevice.width()); 5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5809a74d313452f30629e2615eb8cbfe902433582c0reed@android.com // TODO: respect fDoDither 581dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com blend32_16_row(fSrcColor32, device, width); 5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Blitter::blitAntiH(int x, int y, 5858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkAlpha* SK_RESTRICT antialias, 586a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* SK_RESTRICT runs) { 5878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 588ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t srcExpanded = fExpandedRaw16; 5898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned scale = fScale; 5908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5919a74d313452f30629e2615eb8cbfe902433582c0reed@android.com // TODO: respect fDoDither 5929a74d313452f30629e2615eb8cbfe902433582c0reed@android.com for (;;) { 5939a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int count = runs[0]; 5949a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkASSERT(count >= 0); 5959a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (count <= 0) { 5969a74d313452f30629e2615eb8cbfe902433582c0reed@android.com return; 5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5989a74d313452f30629e2615eb8cbfe902433582c0reed@android.com runs += count; 5998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6009a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned aa = antialias[0]; 6019a74d313452f30629e2615eb8cbfe902433582c0reed@android.com antialias += count; 6029a74d313452f30629e2615eb8cbfe902433582c0reed@android.com if (aa) { 6039a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned scale5 = SkAlpha255To256(aa) * scale >> (8 + 3); 604ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t src32 = srcExpanded * scale5; 6059a74d313452f30629e2615eb8cbfe902433582c0reed@android.com scale5 = 32 - scale5; 6069a74d313452f30629e2615eb8cbfe902433582c0reed@android.com do { 6079a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 6089a74d313452f30629e2615eb8cbfe902433582c0reed@android.com *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); 6099a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (--count != 0); 6109a74d313452f30629e2615eb8cbfe902433582c0reed@android.com continue; 6118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6129a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device += count; 6138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline void blend_8_pixels(U8CPU bw, uint16_t dst[], unsigned dst_scale, 6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U16CPU srcColor) { 6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x80) dst[0] = srcColor + SkAlphaMulRGB16(dst[0], dst_scale); 6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x40) dst[1] = srcColor + SkAlphaMulRGB16(dst[1], dst_scale); 6208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x20) dst[2] = srcColor + SkAlphaMulRGB16(dst[2], dst_scale); 6218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x10) dst[3] = srcColor + SkAlphaMulRGB16(dst[3], dst_scale); 6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x08) dst[4] = srcColor + SkAlphaMulRGB16(dst[4], dst_scale); 6238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x04) dst[5] = srcColor + SkAlphaMulRGB16(dst[5], dst_scale); 6248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x02) dst[6] = srcColor + SkAlphaMulRGB16(dst[6], dst_scale); 6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bw & 0x01) dst[7] = srcColor + SkAlphaMulRGB16(dst[7], dst_scale); 6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_NAME SkRGB16_BlendBW 6298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_ARGS , unsigned dst_scale, U16CPU src_color 6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst) blend_8_pixels(mask, dst, dst_scale, src_color) 6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_GETADDR getAddr16 6328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_DEVTYPE uint16_t 6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitBWMaskTemplate.h" 6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 635333d6cb2448d0febcbeb7c8c7310c0ff2d1a6104tomhudson@google.comvoid SkRGB16_Blitter::blitMask(const SkMask& mask, 636333d6cb2448d0febcbeb7c8c7310c0ff2d1a6104tomhudson@google.com const SkIRect& clip) { 6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask.fFormat == SkMask::kBW_Format) { 6389a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkRGB16_BlendBW(fDevice, mask, clip, 256 - fScale, fColor16); 6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 6408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop); 6437989186dab6bc2f1c1927daf91bddd32b7fd8d0creed@google.com const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop); 6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = clip.width(); 6458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = clip.height(); 646e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes() - (width << 1); 6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned maskRB = mask.fRowBytes - width; 648ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t color32 = fExpandedRaw16; 6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6509a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned scale256 = fScale; 6519a74d313452f30629e2615eb8cbfe902433582c0reed@android.com do { 6529a74d313452f30629e2615eb8cbfe902433582c0reed@android.com int w = width; 6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 6549a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned aa = *alpha++; 6559a74d313452f30629e2615eb8cbfe902433582c0reed@android.com unsigned scale = SkAlpha255To256(aa) * scale256 >> (8 + 3); 6569a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint32_t src32 = color32 * scale; 6579a74d313452f30629e2615eb8cbfe902433582c0reed@android.com uint32_t dst32 = SkExpand_rgb_16(*device) * (32 - scale); 6589a74d313452f30629e2615eb8cbfe902433582c0reed@android.com *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); 6599a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (--w != 0); 6609a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device = (uint16_t*)((char*)device + deviceRB); 6619a74d313452f30629e2615eb8cbfe902433582c0reed@android.com alpha += maskRB; 6629a74d313452f30629e2615eb8cbfe902433582c0reed@android.com } while (--height != 0); 6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { 6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 667e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes(); 6688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 669ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com // TODO: respect fDoDither 670ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com unsigned scale5 = SkAlpha255To256(alpha) * fScale >> (8 + 3); 671ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t src32 = fExpandedRaw16 * scale5; 672ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com scale5 = 32 - scale5; 673ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com do { 674ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 675ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com *device = SkCompact_rgb_16((src32 + dst32) >> 5); 676ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com device = (uint16_t*)((char*)device + deviceRB); 677ea16cfa037bca933f6930a487b42f3c0faab9fe4reed@android.com } while (--height != 0); 6788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Blitter::blitRect(int x, int y, int width, int height) { 6818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); 6828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 683e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t deviceRB = fDevice.rowBytes(); 6849a74d313452f30629e2615eb8cbfe902433582c0reed@android.com SkPMColor src32 = fSrcColor32; 6858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6869a74d313452f30629e2615eb8cbfe902433582c0reed@android.com while (--height >= 0) { 687dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com blend32_16_row(src32, device, width); 6889a74d313452f30629e2615eb8cbfe902433582c0reed@android.com device = (uint16_t*)((char*)device + deviceRB); 6898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 6938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRGB16_Shader16_Blitter::SkRGB16_Shader16_Blitter(const SkBitmap& device, 69587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkPaint& paint, 69687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext) 69787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org : SkRGB16_Shader_Blitter(device, paint, shaderContext) { 6985119bdb952025a30f115b9c6a187173956e55097reed@android.com SkASSERT(SkShader::CanCallShadeSpan16(fShaderFlags)); 6998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 701a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comvoid SkRGB16_Shader16_Blitter::blitH(int x, int y, int width) { 7028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x + width <= fDevice.width()); 7038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 70587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext = fShaderContext; 7068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 70787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org int alpha = shaderContext->getSpan16Alpha(); 7088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0xFF == alpha) { 70987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan16(x, y, device, width); 7108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 7118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* span16 = (uint16_t*)fBuffer; 71287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan16(x, y, span16, width); 7138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBlendRGB16(span16, device, SkAlpha255To256(alpha), width); 7148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 717dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.comvoid SkRGB16_Shader16_Blitter::blitRect(int x, int y, int width, int height) { 71887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext = fShaderContext; 71987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org uint16_t* dst = fDevice.getAddr16(x, y); 72087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org size_t dstRB = fDevice.rowBytes(); 72187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org int alpha = shaderContext->getSpan16Alpha(); 722dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com 723dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com if (0xFF == alpha) { 7243c9b2a4a0e4f57db23640e85959ee78b86634628reed@android.com if (fShaderFlags & SkShader::kConstInY16_Flag) { 725dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com // have the shader blit directly into the device the first time 72687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan16(x, y, dst, width); 727dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com // and now just memcpy that line on the subsequent lines 728dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com if (--height > 0) { 729dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com const uint16_t* orig = dst; 730dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com do { 731dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com dst = (uint16_t*)((char*)dst + dstRB); 732dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com memcpy(dst, orig, width << 1); 733dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com } while (--height); 734dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com } 735dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com } else { // need to call shadeSpan16 for every line 736dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com do { 73787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan16(x, y, dst, width); 738dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com y += 1; 739dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com dst = (uint16_t*)((char*)dst + dstRB); 740dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com } while (--height); 741dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com } 742dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com } else { 743dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com int scale = SkAlpha255To256(alpha); 744dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com uint16_t* span16 = (uint16_t*)fBuffer; 7453c9b2a4a0e4f57db23640e85959ee78b86634628reed@android.com if (fShaderFlags & SkShader::kConstInY16_Flag) { 74687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan16(x, y, span16, width); 747dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com do { 748dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com SkBlendRGB16(span16, dst, scale, width); 749dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com dst = (uint16_t*)((char*)dst + dstRB); 750dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com } while (--height); 751dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com } else { 752dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com do { 75387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan16(x, y, span16, width); 754dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com SkBlendRGB16(span16, dst, scale, width); 755dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com y += 1; 756dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com dst = (uint16_t*)((char*)dst + dstRB); 757dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com } while (--height); 758dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com } 759dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com } 760dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com} 761dafaf7ac4d89f183dc515907665cdac3e3098466reed@android.com 7628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Shader16_Blitter::blitAntiH(int x, int y, 7638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkAlpha* SK_RESTRICT antialias, 764a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* SK_RESTRICT runs) { 76587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext = fShaderContext; 7668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor* SK_RESTRICT span = fBuffer; 76787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 76987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org int alpha = shaderContext->getSpan16Alpha(); 7708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* span16 = (uint16_t*)span; 7718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0xFF == alpha) { 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = *runs; 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 7768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count <= fDevice.width()); // don't overrun fBuffer 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int aa = *antialias; 7818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa == 255) { 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // go direct to the device! 78387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan16(x, y, device, count); 7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else if (aa) { 78587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan16(x, y, span16, count); 7868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 7898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += count; 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // span alpha is < 255 7948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha = SkAlpha255To256(alpha); 7958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = *runs; 7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count <= fDevice.width()); // don't overrun fBuffer 8018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int aa = SkAlphaMul(*antialias, alpha); 8038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa) { 80487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan16(x, y, span16, count); 8058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); 8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 8098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += count; 8128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkBitmap& device, 81987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkPaint& paint, 82087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext) 82187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org: INHERITED(device, paint, shaderContext) { 8228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(paint.getXfermode() == NULL); 8238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor)); 8258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // compute SkBlitRow::Procs 8278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned flags = 0; 828fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 8295119bdb952025a30f115b9c6a187173956e55097reed@android.com uint32_t shaderFlags = fShaderFlags; 8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // shaders take care of global alpha, so we never set it in SkBlitRow 8318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!(shaderFlags & SkShader::kOpaqueAlpha_Flag)) { 8328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkBlitRow::kSrcPixelAlpha_Flag; 833c2050e3a3ecfb8738b36e2add15c526e8e0f21fecommit-bot@chromium.org } 8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't dither if the shader is really 16bit 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.isDither() && !(shaderFlags & SkShader::kIntrinsicly16_Flag)) { 8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkBlitRow::kDither_Flag; 8378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // used when we know our global alpha is 0xFF 839cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org fOpaqueProc = SkBlitRow::Factory(flags, kRGB_565_SkColorType); 8408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // used when we know our global alpha is < 0xFF 8418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fAlphaProc = SkBlitRow::Factory(flags | SkBlitRow::kGlobalAlpha_Flag, 842cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org kRGB_565_SkColorType); 8438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRGB16_Shader_Blitter::~SkRGB16_Shader_Blitter() { 8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fBuffer); 8478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Shader_Blitter::blitH(int x, int y, int width) { 8508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x + width <= fDevice.width()); 8518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 85287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderContext->shadeSpan(x, y, fBuffer, width); 8538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // shaders take care of global alpha, so we pass 0xFF (should be ignored) 8548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fOpaqueProc(fDevice.getAddr16(x, y), fBuffer, width, 0xFF, x, y); 8558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8575119bdb952025a30f115b9c6a187173956e55097reed@android.comvoid SkRGB16_Shader_Blitter::blitRect(int x, int y, int width, int height) { 85887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext = fShaderContext; 85987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkBlitRow::Proc proc = fOpaqueProc; 86087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkPMColor* buffer = fBuffer; 86187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org uint16_t* dst = fDevice.getAddr16(x, y); 86287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org size_t dstRB = fDevice.rowBytes(); 8635119bdb952025a30f115b9c6a187173956e55097reed@android.com 8643c9b2a4a0e4f57db23640e85959ee78b86634628reed@android.com if (fShaderFlags & SkShader::kConstInY32_Flag) { 86587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, buffer, width); 8665119bdb952025a30f115b9c6a187173956e55097reed@android.com do { 8675119bdb952025a30f115b9c6a187173956e55097reed@android.com proc(dst, buffer, width, 0xFF, x, y); 8685119bdb952025a30f115b9c6a187173956e55097reed@android.com y += 1; 8695119bdb952025a30f115b9c6a187173956e55097reed@android.com dst = (uint16_t*)((char*)dst + dstRB); 8705119bdb952025a30f115b9c6a187173956e55097reed@android.com } while (--height); 8715119bdb952025a30f115b9c6a187173956e55097reed@android.com } else { 8725119bdb952025a30f115b9c6a187173956e55097reed@android.com do { 87387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, buffer, width); 8745119bdb952025a30f115b9c6a187173956e55097reed@android.com proc(dst, buffer, width, 0xFF, x, y); 8755119bdb952025a30f115b9c6a187173956e55097reed@android.com y += 1; 8765119bdb952025a30f115b9c6a187173956e55097reed@android.com dst = (uint16_t*)((char*)dst + dstRB); 8775119bdb952025a30f115b9c6a187173956e55097reed@android.com } while (--height); 8785119bdb952025a30f115b9c6a187173956e55097reed@android.com } 8795119bdb952025a30f115b9c6a187173956e55097reed@android.com} 8805119bdb952025a30f115b9c6a187173956e55097reed@android.com 8818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int count_nonzero_span(const int16_t runs[], const SkAlpha aa[]) { 8828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = 0; 8838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 8848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = *runs; 8858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (n == 0 || *aa == 0) { 8868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 8878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += n; 8898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com aa += n; 8908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count += n; 8918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 8938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Shader_Blitter::blitAntiH(int x, int y, 8968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkAlpha* SK_RESTRICT antialias, 897a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* SK_RESTRICT runs) { 89887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext = fShaderContext; 8998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor* SK_RESTRICT span = fBuffer; 90087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 9018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 9038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = *runs; 9048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 9058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 9068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int aa = *antialias; 9088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0 == aa) { 9098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 9108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 9118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 9128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += count; 9138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com continue; 9148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int nonZeroCount = count + count_nonzero_span(runs + count, antialias + count); 9178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer 91987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, nonZeroCount); 9208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor* localSpan = span; 9228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 9238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBlitRow::Proc proc = (aa == 0xFF) ? fOpaqueProc : fAlphaProc; 9248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com proc(device, localSpan, count, aa, x, y); 9258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += count; 9278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 9288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 9298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 9308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com nonZeroCount -= count; 9318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (nonZeroCount == 0) { 9328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 9338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com localSpan += count; 9358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(nonZeroCount > 0); 9368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count = *runs; 9378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 9388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com aa = *antialias; 9398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////// 9448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter( 94687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkBitmap& device, const SkPaint& paint, 94787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext) 94887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org: INHERITED(device, paint, shaderContext) { 9498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXfermode = paint.getXfermode(); 9508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fXfermode); 9518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXfermode->ref(); 9528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = device.width(); 9548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBuffer = (SkPMColor*)sk_malloc_throw((width + (SkAlign4(width) >> 2)) * sizeof(SkPMColor)); 9558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fAAExpand = (uint8_t*)(fBuffer + width); 9568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRGB16_Shader_Xfermode_Blitter::~SkRGB16_Shader_Xfermode_Blitter() { 9598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXfermode->unref(); 9608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fBuffer); 9618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Shader_Xfermode_Blitter::blitH(int x, int y, int width) { 9648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x + width <= fDevice.width()); 9658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* device = fDevice.getAddr16(x, y); 9678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor* span = fBuffer; 9688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 96987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderContext->shadeSpan(x, y, span, width); 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXfermode->xfer16(device, span, width, NULL); 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y, 9748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkAlpha* SK_RESTRICT antialias, 975a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const int16_t* SK_RESTRICT runs) { 97687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext = fShaderContext; 97787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkXfermode* mode = fXfermode; 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor* SK_RESTRICT span = fBuffer; 97987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org uint8_t* SK_RESTRICT aaExpand = fAAExpand; 98087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 9818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = *runs; 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 9868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int aa = *antialias; 9888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0 == aa) { 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 9908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 9918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 9928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += count; 9938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com continue; 9948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int nonZeroCount = count + count_nonzero_span(runs + count, 9978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias + count); 9988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer 100087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, nonZeroCount); 10018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += nonZeroCount; 10038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor* localSpan = span; 10048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 10058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa == 0xFF) { 10068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mode->xfer16(device, localSpan, count, NULL); 10078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 10088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(aa); 10098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(aaExpand, aa, count); 10108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mode->xfer16(device, localSpan, count, aaExpand); 10118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 10138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 10148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 10158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com nonZeroCount -= count; 10168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (nonZeroCount == 0) { 10178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 10188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com localSpan += count; 10208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(nonZeroCount > 0); 10218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count = *runs; 10228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 10238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com aa = *antialias; 10248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1025fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 10268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10281fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com/////////////////////////////////////////////////////////////////////////////// 10298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10301fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.comSkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, const SkPaint& paint, 103187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext, 1032a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org SkTBlitterAllocator* allocator) { 1033a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org SkASSERT(allocator != NULL); 1034a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org 10351fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkBlitter* blitter; 10361fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkShader* shader = paint.getShader(); 10371fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkXfermode* mode = paint.getXfermode(); 10381fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 10391fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com // we require a shader if there is an xfermode, handled by our caller 104049f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(NULL == mode || shader); 10411fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com 10421fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com if (shader) { 104387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkASSERT(shaderContext != NULL); 10441fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com if (mode) { 104587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org blitter = allocator->createT<SkRGB16_Shader_Xfermode_Blitter>(device, paint, 104687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext); 104787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org } else if (shaderContext->canCallShadeSpan16()) { 104887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org blitter = allocator->createT<SkRGB16_Shader16_Blitter>(device, paint, shaderContext); 10491fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } else { 105087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org blitter = allocator->createT<SkRGB16_Shader_Blitter>(device, paint, shaderContext); 10511fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } 10521fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } else { 10531fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com // no shader, no xfermode, (and we always ignore colorfilter) 10541fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com SkColor color = paint.getColor(); 10551fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com if (0 == SkColorGetA(color)) { 1056a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<SkNullBlitter>(); 1057867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#ifdef USE_BLACK_BLITTER 10581fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } else if (SK_ColorBLACK == color) { 1059a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<SkRGB16_Black_Blitter>(device, paint); 1060867ee807cc95c77aff830e9e6c1988bfbe604405reed@android.com#endif 10611fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } else if (0xFF == SkColorGetA(color)) { 1062a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<SkRGB16_Opaque_Blitter>(device, paint); 10631fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } else { 1064a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<SkRGB16_Blitter>(device, paint); 10651fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } 10661fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com } 1067fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 10681fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com return blitter; 10698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1070