SkSpriteBlitter_RGB16.cpp revision cba73780bbd12fd254229517aec04fcbf0b64b52
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 "SkSpriteBlitter.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitRow.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplates.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define D16_S32A_Opaque_Pixel(dst, sc) \ 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comdo { \ 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (sc) { \ 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst = SkSrcOver32To16(sc, *dst); \ 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } \ 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} while (0) 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline void D16_S32A_Blend_Pixel_helper(uint16_t* dst, SkPMColor sc, 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned src_scale) { 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t dc = *dst; 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned sa = SkGetPackedA32(sc); 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dr, dg, db; 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (255 == sa) { 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dr = SkAlphaBlend(SkPacked32ToR16(sc), SkGetPackedR16(dc), src_scale); 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dg = SkAlphaBlend(SkPacked32ToG16(sc), SkGetPackedG16(dc), src_scale); 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com db = SkAlphaBlend(SkPacked32ToB16(sc), SkGetPackedB16(dc), src_scale); 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dst_scale = 255 - SkAlphaMul(sa, src_scale); 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dr = (SkPacked32ToR16(sc) * src_scale + 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGetPackedR16(dc) * dst_scale) >> 8; 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dg = (SkPacked32ToG16(sc) * src_scale + 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGetPackedG16(dc) * dst_scale) >> 8; 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com db = (SkPacked32ToB16(sc) * src_scale + 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGetPackedB16(dc) * dst_scale) >> 8; 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst = SkPackRGB16(dr, dg, db); 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define D16_S32A_Blend_Pixel(dst, sc, src_scale) \ 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { if (sc) D16_S32A_Blend_Pixel_helper(dst, sc, src_scale); } while (0) 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sprite_D16_S16_Opaque : public SkSpriteBlitter { 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Sprite_D16_S16_Opaque(const SkBitmap& source) 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : SkSpriteBlitter(source) {} 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // overrides 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual void blitRect(int x, int y, int width, int height) { 58a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com uint16_t* SK_RESTRICT dst = fDevice->getAddr16(x, y); 59a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const uint16_t* SK_RESTRICT src = fSource->getAddr16(x - fLeft, 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com y - fTop); 61e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t dstRB = fDevice->rowBytes(); 62e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t srcRB = fSource->rowBytes(); 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--height >= 0) { 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(dst, src, width << 1); 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dst = (uint16_t*)((char*)dst + dstRB); 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com src = (const uint16_t*)((const char*)src + srcRB); 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define D16_S16_Blend_Pixel(dst, sc, scale) \ 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { \ 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t dc = *dst; \ 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst = SkBlendRGB16(sc, dc, scale); \ 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (0) 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_S16_Blend 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS , uint8_t alpha 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS uint8_t fSrcAlpha; 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT fSrcAlpha = alpha; 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE uint16_t 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr16 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) int scale = SkAlpha255To256(fSrcAlpha); 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S16_Blend_Pixel(dst, src, scale) 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_POSTAMBLE(srcBM) 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define D16_S4444_Opaque(dst, sc) \ 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { \ 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t dc = *dst; \ 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst = SkSrcOver4444To16(sc, dc); \ 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (0) 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_S4444_Opaque 101fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#define SkSPRITE_ARGS 102fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#define SkSPRITE_FIELDS 103fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#define SkSPRITE_INIT 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE SkPMColor16 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr16 108fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#define SkSPRITE_PREAMBLE(srcBM, x, y) 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S4444_Opaque(dst, src) 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_POSTAMBLE(srcBM) 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define D16_S4444_Blend(dst, sc, scale16) \ 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { \ 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t dc = *dst; \ 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst = SkBlend4444To16(sc, dc, scale16); \ 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (0) 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_S4444_Blend 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS , uint8_t alpha 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS uint8_t fSrcAlpha; 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT fSrcAlpha = alpha; 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE uint16_t 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr16 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) int scale = SkAlpha15To16(fSrcAlpha); 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S4444_Blend(dst, src, scale) 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_POSTAMBLE(srcBM) 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_SIndex8A_Opaque 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE uint8_t 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr8 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) const SkPMColor* ctable = srcBM.getColorTable()->lockColors() 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S32A_Opaque_Pixel(dst, ctable[src]) 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 1480a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com#define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlockColors() 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_SIndex8A_Blend 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS , uint8_t alpha 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS uint8_t fSrcAlpha; 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT fSrcAlpha = alpha; 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE uint8_t 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr8 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) const SkPMColor* ctable = srcBM.getColorTable()->lockColors(); unsigned src_scale = SkAlpha255To256(fSrcAlpha); 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S32A_Blend_Pixel(dst, ctable[src], src_scale) 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 1620a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com#define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlockColors(); 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1671c12abe3508cd69615c2dd50653f782835e325cereed@android.comstatic intptr_t asint(const void* ptr) { 1681c12abe3508cd69615c2dd50653f782835e325cereed@android.com return reinterpret_cast<const char*>(ptr) - (const char*)0; 1691c12abe3508cd69615c2dd50653f782835e325cereed@android.com} 1701c12abe3508cd69615c2dd50653f782835e325cereed@android.com 171a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comstatic void blitrow_d16_si8(uint16_t* SK_RESTRICT dst, 172a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const uint8_t* SK_RESTRICT src, int count, 173a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const uint16_t* SK_RESTRICT ctable) { 1741c12abe3508cd69615c2dd50653f782835e325cereed@android.com if (count <= 8) { 1751c12abe3508cd69615c2dd50653f782835e325cereed@android.com do { 1761c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[*src++]; 1771c12abe3508cd69615c2dd50653f782835e325cereed@android.com } while (--count); 1781c12abe3508cd69615c2dd50653f782835e325cereed@android.com return; 1791c12abe3508cd69615c2dd50653f782835e325cereed@android.com } 1801c12abe3508cd69615c2dd50653f782835e325cereed@android.com 1811c12abe3508cd69615c2dd50653f782835e325cereed@android.com // eat src until we're on a 4byte boundary 1821c12abe3508cd69615c2dd50653f782835e325cereed@android.com while (asint(src) & 3) { 1831c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[*src++]; 1841c12abe3508cd69615c2dd50653f782835e325cereed@android.com count -= 1; 1851c12abe3508cd69615c2dd50653f782835e325cereed@android.com } 1861c12abe3508cd69615c2dd50653f782835e325cereed@android.com 1871c12abe3508cd69615c2dd50653f782835e325cereed@android.com int qcount = count >> 2; 1881c12abe3508cd69615c2dd50653f782835e325cereed@android.com SkASSERT(qcount > 0); 1891c12abe3508cd69615c2dd50653f782835e325cereed@android.com const uint32_t* qsrc = reinterpret_cast<const uint32_t*>(src); 1901c12abe3508cd69615c2dd50653f782835e325cereed@android.com if (asint(dst) & 2) { 1911c12abe3508cd69615c2dd50653f782835e325cereed@android.com do { 1921c12abe3508cd69615c2dd50653f782835e325cereed@android.com uint32_t s4 = *qsrc++; 1931c12abe3508cd69615c2dd50653f782835e325cereed@android.com#ifdef SK_CPU_LENDIAN 1941c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[s4 & 0xFF]; 1951c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[(s4 >> 8) & 0xFF]; 1961c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[(s4 >> 16) & 0xFF]; 1971c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[s4 >> 24]; 1981c12abe3508cd69615c2dd50653f782835e325cereed@android.com#else // BENDIAN 1991c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[s4 >> 24]; 2001c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[(s4 >> 16) & 0xFF]; 2011c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[(s4 >> 8) & 0xFF]; 2021c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[s4 & 0xFF]; 2031c12abe3508cd69615c2dd50653f782835e325cereed@android.com#endif 2041c12abe3508cd69615c2dd50653f782835e325cereed@android.com } while (--qcount); 2051c12abe3508cd69615c2dd50653f782835e325cereed@android.com } else { // dst is on a 4byte boundary 2061c12abe3508cd69615c2dd50653f782835e325cereed@android.com uint32_t* ddst = reinterpret_cast<uint32_t*>(dst); 2071c12abe3508cd69615c2dd50653f782835e325cereed@android.com do { 2081c12abe3508cd69615c2dd50653f782835e325cereed@android.com uint32_t s4 = *qsrc++; 2091c12abe3508cd69615c2dd50653f782835e325cereed@android.com#ifdef SK_CPU_LENDIAN 2101c12abe3508cd69615c2dd50653f782835e325cereed@android.com *ddst++ = (ctable[(s4 >> 8) & 0xFF] << 16) | ctable[s4 & 0xFF]; 2111c12abe3508cd69615c2dd50653f782835e325cereed@android.com *ddst++ = (ctable[s4 >> 24] << 16) | ctable[(s4 >> 16) & 0xFF]; 2121c12abe3508cd69615c2dd50653f782835e325cereed@android.com#else // BENDIAN 2131c12abe3508cd69615c2dd50653f782835e325cereed@android.com *ddst++ = (ctable[s4 >> 24] << 16) | ctable[(s4 >> 16) & 0xFF]; 2141c12abe3508cd69615c2dd50653f782835e325cereed@android.com *ddst++ = (ctable[(s4 >> 8) & 0xFF] << 16) | ctable[s4 & 0xFF]; 2151c12abe3508cd69615c2dd50653f782835e325cereed@android.com#endif 2161c12abe3508cd69615c2dd50653f782835e325cereed@android.com } while (--qcount); 2171c12abe3508cd69615c2dd50653f782835e325cereed@android.com dst = reinterpret_cast<uint16_t*>(ddst); 2181c12abe3508cd69615c2dd50653f782835e325cereed@android.com } 2191c12abe3508cd69615c2dd50653f782835e325cereed@android.com src = reinterpret_cast<const uint8_t*>(qsrc); 2201c12abe3508cd69615c2dd50653f782835e325cereed@android.com count &= 3; 2211c12abe3508cd69615c2dd50653f782835e325cereed@android.com // catch any remaining (will be < 4) 2221c12abe3508cd69615c2dd50653f782835e325cereed@android.com while (--count >= 0) { 2231c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[*src++]; 2241c12abe3508cd69615c2dd50653f782835e325cereed@android.com } 2251c12abe3508cd69615c2dd50653f782835e325cereed@android.com} 2261c12abe3508cd69615c2dd50653f782835e325cereed@android.com 2271c12abe3508cd69615c2dd50653f782835e325cereed@android.com#define SkSPRITE_ROW_PROC(d, s, n, x, y) blitrow_d16_si8(d, s, n, ctable) 228084ad42b91546f0f99d7cd5064c04edacede66ffreed@android.com 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_SIndex8_Opaque 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE uint8_t 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr8 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) const uint16_t* ctable = srcBM.getColorTable()->lock16BitCache() 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) *dst = ctable[src] 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlock16BitCache() 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_SIndex8_Blend 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS , uint8_t alpha 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS uint8_t fSrcAlpha; 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT fSrcAlpha = alpha; 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE uint8_t 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr8 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) const uint16_t* ctable = srcBM.getColorTable()->lock16BitCache(); unsigned src_scale = SkAlpha255To256(fSrcAlpha); 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S16_Blend_Pixel(dst, ctable[src], src_scale) 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlock16BitCache(); 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sprite_D16_S32_BlitRowProc : public SkSpriteBlitter { 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Sprite_D16_S32_BlitRowProc(const SkBitmap& source) 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : SkSpriteBlitter(source) {} 263fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // overrides 265fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual void setup(const SkBitmap& device, int left, int top, 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::setup(device, left, top, paint); 269fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned flags = 0; 271fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.getAlpha() < 0xFF) { 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkBlitRow::kGlobalAlpha_Flag; 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fSource->isOpaque()) { 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkBlitRow::kSrcPixelAlpha_Flag; 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.isDither()) { 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkBlitRow::kDither_Flag; 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 281cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org fProc = SkBlitRow::Factory(flags, kRGB_565_SkColorType); 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 283fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual void blitRect(int x, int y, int width, int height) { 285a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com uint16_t* SK_RESTRICT dst = fDevice->getAddr16(x, y); 286a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const SkPMColor* SK_RESTRICT src = fSource->getAddr32(x - fLeft, 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com y - fTop); 288e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t dstRB = fDevice->rowBytes(); 289e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t srcRB = fSource->rowBytes(); 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBlitRow::Proc proc = fProc; 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU alpha = fPaint->getAlpha(); 292fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--height >= 0) { 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com proc(dst, src, width, alpha, x, y); 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com y += 1; 296a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com dst = (uint16_t* SK_RESTRICT)((char*)dst + dstRB); 297a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com src = (const SkPMColor* SK_RESTRICT)((const char*)src + srcRB); 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 300fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBlitRow::Proc fProc; 303fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkSpriteBlitter INHERITED; 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 309a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.orgSkSpriteBlitter* SkSpriteBlitter::ChooseD16(const SkBitmap& source, const SkPaint& paint, 310a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org SkTBlitterAllocator* allocator) { 311a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org 312a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org SkASSERT(allocator != NULL); 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.getMaskFilter() != NULL) { // may add cases for this 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.getXfermode() != NULL) { // may add cases for this 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.getColorFilter() != NULL) { // may add cases for this 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkSpriteBlitter* blitter = NULL; 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned alpha = paint.getAlpha(); 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 327900ecf2f1579d42c9d2959831787af0346320f86reed@google.com switch (source.colorType()) { 32828fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: { 329a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<Sprite_D16_S32_BlitRowProc>(source); 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 331a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org } 332900ecf2f1579d42c9d2959831787af0346320f86reed@google.com case kARGB_4444_SkColorType: 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (255 == alpha) { 334a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<Sprite_D16_S4444_Opaque>(source); 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 336a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<Sprite_D16_S4444_Blend>(source, alpha >> 4); 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 339900ecf2f1579d42c9d2959831787af0346320f86reed@google.com case kRGB_565_SkColorType: 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (255 == alpha) { 341a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<Sprite_D16_S16_Opaque>(source); 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 343a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<Sprite_D16_S16_Blend>(source, alpha); 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 346900ecf2f1579d42c9d2959831787af0346320f86reed@google.com case kIndex_8_SkColorType: 347755dd4773dad70d5fbe3f8bb091eaf268ea752c7reed@android.com if (paint.isDither()) { 348755dd4773dad70d5fbe3f8bb091eaf268ea752c7reed@android.com // we don't support dither yet in these special cases 349755dd4773dad70d5fbe3f8bb091eaf268ea752c7reed@android.com break; 350755dd4773dad70d5fbe3f8bb091eaf268ea752c7reed@android.com } 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (source.isOpaque()) { 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (255 == alpha) { 353a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<Sprite_D16_SIndex8_Opaque>(source); 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 355a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<Sprite_D16_SIndex8_Blend>(source, alpha); 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (255 == alpha) { 359a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<Sprite_D16_SIndex8A_Opaque>(source); 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 361a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org blitter = allocator->createT<Sprite_D16_SIndex8A_Blend>(source, alpha); 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return blitter; 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 370