SkSpriteBlitter_RGB16.cpp revision 1c12abe3508cd69615c2dd50653f782835e325ce
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* libs/graphics/sgl/SkSpriteBlitter_RGB16.cpp 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** Copyright 2006, The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** 58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** Licensed under the Apache License, Version 2.0 (the "License"); 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** you may not use this file except in compliance with the License. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** You may obtain a copy of the License at 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** http://www.apache.org/licenses/LICENSE-2.0 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** Unless required by applicable law or agreed to in writing, software 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** distributed under the License is distributed on an "AS IS" BASIS, 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** See the License for the specific language governing permissions and 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** limitations under the License. 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitter.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitRow.h" 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplates.h" 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define D16_S32A_Opaque_Pixel(dst, sc) \ 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comdo { \ 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (sc) { \ 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst = SkSrcOver32To16(sc, *dst); \ 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } \ 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} while (0) 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline void D16_S32A_Blend_Pixel_helper(uint16_t* dst, SkPMColor sc, 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned src_scale) { 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t dc = *dst; 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned sa = SkGetPackedA32(sc); 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dr, dg, db; 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (255 == sa) { 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dr = SkAlphaBlend(SkPacked32ToR16(sc), SkGetPackedR16(dc), src_scale); 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dg = SkAlphaBlend(SkPacked32ToG16(sc), SkGetPackedG16(dc), src_scale); 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com db = SkAlphaBlend(SkPacked32ToB16(sc), SkGetPackedB16(dc), src_scale); 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dst_scale = 255 - SkAlphaMul(sa, src_scale); 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dr = (SkPacked32ToR16(sc) * src_scale + 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGetPackedR16(dc) * dst_scale) >> 8; 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dg = (SkPacked32ToG16(sc) * src_scale + 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGetPackedG16(dc) * dst_scale) >> 8; 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com db = (SkPacked32ToB16(sc) * src_scale + 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGetPackedB16(dc) * dst_scale) >> 8; 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst = SkPackRGB16(dr, dg, db); 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define D16_S32A_Blend_Pixel(dst, sc, src_scale) \ 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { if (sc) D16_S32A_Blend_Pixel_helper(dst, sc, src_scale); } while (0) 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sprite_D16_S16_Opaque : public SkSpriteBlitter { 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Sprite_D16_S16_Opaque(const SkBitmap& source) 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : SkSpriteBlitter(source) {} 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // overrides 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual void blitRect(int x, int y, int width, int height) { 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_RESTRICT uint16_t* dst = fDevice->getAddr16(x, y); 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SK_RESTRICT uint16_t* src = fSource->getAddr16(x - fLeft, 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com y - fTop); 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dstRB = fDevice->rowBytes(); 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned srcRB = fSource->rowBytes(); 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--height >= 0) { 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(dst, src, width << 1); 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dst = (uint16_t*)((char*)dst + dstRB); 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com src = (const uint16_t*)((const char*)src + srcRB); 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define D16_S16_Blend_Pixel(dst, sc, scale) \ 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { \ 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t dc = *dst; \ 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst = SkBlendRGB16(sc, dc, scale); \ 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (0) 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_S16_Blend 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS , uint8_t alpha 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS uint8_t fSrcAlpha; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT fSrcAlpha = alpha; 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE uint16_t 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr16 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) int scale = SkAlpha255To256(fSrcAlpha); 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S16_Blend_Pixel(dst, src, scale) 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_POSTAMBLE(srcBM) 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define D16_S4444_Opaque(dst, sc) \ 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { \ 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t dc = *dst; \ 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst = SkSrcOver4444To16(sc, dc); \ 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (0) 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_S4444_Opaque 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE SkPMColor16 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr16 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S4444_Opaque(dst, src) 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_POSTAMBLE(srcBM) 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define D16_S4444_Blend(dst, sc, scale16) \ 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { \ 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t dc = *dst; \ 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst = SkBlend4444To16(sc, dc, scale16); \ 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (0) 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_S4444_Blend 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS , uint8_t alpha 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS uint8_t fSrcAlpha; 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT fSrcAlpha = alpha; 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE uint16_t 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr16 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) int scale = SkAlpha15To16(fSrcAlpha); 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S4444_Blend(dst, src, scale) 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_POSTAMBLE(srcBM) 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_SIndex8A_Opaque 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE uint8_t 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr8 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) const SkPMColor* ctable = srcBM.getColorTable()->lockColors() 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S32A_Opaque_Pixel(dst, ctable[src]) 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlockColors(false) 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_SIndex8A_Blend 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS , uint8_t alpha 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS uint8_t fSrcAlpha; 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT fSrcAlpha = alpha; 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE uint8_t 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr8 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) const SkPMColor* ctable = srcBM.getColorTable()->lockColors(); unsigned src_scale = SkAlpha255To256(fSrcAlpha); 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S32A_Blend_Pixel(dst, ctable[src], src_scale) 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlockColors(false); 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1751c12abe3508cd69615c2dd50653f782835e325cereed@android.comstatic intptr_t asint(const void* ptr) { 1761c12abe3508cd69615c2dd50653f782835e325cereed@android.com return reinterpret_cast<const char*>(ptr) - (const char*)0; 1771c12abe3508cd69615c2dd50653f782835e325cereed@android.com} 1781c12abe3508cd69615c2dd50653f782835e325cereed@android.com 1791c12abe3508cd69615c2dd50653f782835e325cereed@android.comstatic void blitrow_d16_si8(SK_RESTRICT uint16_t* dst, 1801c12abe3508cd69615c2dd50653f782835e325cereed@android.com SK_RESTRICT const uint8_t* src, int count, 1811c12abe3508cd69615c2dd50653f782835e325cereed@android.com SK_RESTRICT const uint16_t* ctable) { 1821c12abe3508cd69615c2dd50653f782835e325cereed@android.com if (count <= 8) { 1831c12abe3508cd69615c2dd50653f782835e325cereed@android.com do { 1841c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[*src++]; 1851c12abe3508cd69615c2dd50653f782835e325cereed@android.com } while (--count); 1861c12abe3508cd69615c2dd50653f782835e325cereed@android.com return; 1871c12abe3508cd69615c2dd50653f782835e325cereed@android.com } 1881c12abe3508cd69615c2dd50653f782835e325cereed@android.com 1891c12abe3508cd69615c2dd50653f782835e325cereed@android.com // eat src until we're on a 4byte boundary 1901c12abe3508cd69615c2dd50653f782835e325cereed@android.com while (asint(src) & 3) { 1911c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[*src++]; 1921c12abe3508cd69615c2dd50653f782835e325cereed@android.com count -= 1; 1931c12abe3508cd69615c2dd50653f782835e325cereed@android.com } 1941c12abe3508cd69615c2dd50653f782835e325cereed@android.com 1951c12abe3508cd69615c2dd50653f782835e325cereed@android.com int qcount = count >> 2; 1961c12abe3508cd69615c2dd50653f782835e325cereed@android.com SkASSERT(qcount > 0); 1971c12abe3508cd69615c2dd50653f782835e325cereed@android.com const uint32_t* qsrc = reinterpret_cast<const uint32_t*>(src); 1981c12abe3508cd69615c2dd50653f782835e325cereed@android.com if (asint(dst) & 2) { 1991c12abe3508cd69615c2dd50653f782835e325cereed@android.com do { 2001c12abe3508cd69615c2dd50653f782835e325cereed@android.com uint32_t s4 = *qsrc++; 2011c12abe3508cd69615c2dd50653f782835e325cereed@android.com#ifdef SK_CPU_LENDIAN 2021c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[s4 & 0xFF]; 2031c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[(s4 >> 8) & 0xFF]; 2041c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[(s4 >> 16) & 0xFF]; 2051c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[s4 >> 24]; 2061c12abe3508cd69615c2dd50653f782835e325cereed@android.com#else // BENDIAN 2071c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[s4 >> 24]; 2081c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[(s4 >> 16) & 0xFF]; 2091c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[(s4 >> 8) & 0xFF]; 2101c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[s4 & 0xFF]; 2111c12abe3508cd69615c2dd50653f782835e325cereed@android.com#endif 2121c12abe3508cd69615c2dd50653f782835e325cereed@android.com } while (--qcount); 2131c12abe3508cd69615c2dd50653f782835e325cereed@android.com } else { // dst is on a 4byte boundary 2141c12abe3508cd69615c2dd50653f782835e325cereed@android.com uint32_t* ddst = reinterpret_cast<uint32_t*>(dst); 2151c12abe3508cd69615c2dd50653f782835e325cereed@android.com do { 2161c12abe3508cd69615c2dd50653f782835e325cereed@android.com uint32_t s4 = *qsrc++; 2171c12abe3508cd69615c2dd50653f782835e325cereed@android.com#ifdef SK_CPU_LENDIAN 2181c12abe3508cd69615c2dd50653f782835e325cereed@android.com *ddst++ = (ctable[(s4 >> 8) & 0xFF] << 16) | ctable[s4 & 0xFF]; 2191c12abe3508cd69615c2dd50653f782835e325cereed@android.com *ddst++ = (ctable[s4 >> 24] << 16) | ctable[(s4 >> 16) & 0xFF]; 2201c12abe3508cd69615c2dd50653f782835e325cereed@android.com#else // BENDIAN 2211c12abe3508cd69615c2dd50653f782835e325cereed@android.com *ddst++ = (ctable[s4 >> 24] << 16) | ctable[(s4 >> 16) & 0xFF]; 2221c12abe3508cd69615c2dd50653f782835e325cereed@android.com *ddst++ = (ctable[(s4 >> 8) & 0xFF] << 16) | ctable[s4 & 0xFF]; 2231c12abe3508cd69615c2dd50653f782835e325cereed@android.com#endif 2241c12abe3508cd69615c2dd50653f782835e325cereed@android.com } while (--qcount); 2251c12abe3508cd69615c2dd50653f782835e325cereed@android.com dst = reinterpret_cast<uint16_t*>(ddst); 2261c12abe3508cd69615c2dd50653f782835e325cereed@android.com } 2271c12abe3508cd69615c2dd50653f782835e325cereed@android.com src = reinterpret_cast<const uint8_t*>(qsrc); 2281c12abe3508cd69615c2dd50653f782835e325cereed@android.com count &= 3; 2291c12abe3508cd69615c2dd50653f782835e325cereed@android.com // catch any remaining (will be < 4) 2301c12abe3508cd69615c2dd50653f782835e325cereed@android.com while (--count >= 0) { 2311c12abe3508cd69615c2dd50653f782835e325cereed@android.com *dst++ = ctable[*src++]; 2321c12abe3508cd69615c2dd50653f782835e325cereed@android.com } 2331c12abe3508cd69615c2dd50653f782835e325cereed@android.com} 2341c12abe3508cd69615c2dd50653f782835e325cereed@android.com 2351c12abe3508cd69615c2dd50653f782835e325cereed@android.com#define SkSPRITE_ROW_PROC(d, s, n, x, y) blitrow_d16_si8(d, s, n, ctable) 2361c12abe3508cd69615c2dd50653f782835e325cereed@android.com 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_SIndex8_Opaque 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE uint8_t 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr8 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) const uint16_t* ctable = srcBM.getColorTable()->lock16BitCache() 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) *dst = ctable[src] 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlock16BitCache() 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_CLASSNAME Sprite_D16_SIndex8_Blend 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_ARGS , uint8_t alpha 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_FIELDS uint8_t fSrcAlpha; 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_INIT fSrcAlpha = alpha; 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_TYPE uint16_t 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_TYPE uint8_t 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_DST_GETADDR getAddr16 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_SRC_GETADDR getAddr8 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_PREAMBLE(srcBM, x, y) const uint16_t* ctable = srcBM.getColorTable()->lock16BitCache(); unsigned src_scale = SkAlpha255To256(fSrcAlpha); 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S16_Blend_Pixel(dst, ctable[src], src_scale) 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_NEXT_ROW 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlock16BitCache(); 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitterTemplate.h" 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sprite_D16_S32_BlitRowProc : public SkSpriteBlitter { 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Sprite_D16_S32_BlitRowProc(const SkBitmap& source) 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : SkSpriteBlitter(source) {} 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // overrides 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual void setup(const SkBitmap& device, int left, int top, 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::setup(device, left, top, paint); 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned flags = 0; 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.getAlpha() < 0xFF) { 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkBlitRow::kGlobalAlpha_Flag; 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fSource->isOpaque()) { 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkBlitRow::kSrcPixelAlpha_Flag; 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.isDither()) { 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkBlitRow::kDither_Flag; 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fProc = SkBlitRow::Factory(flags, SkBitmap::kRGB_565_Config); 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual void blitRect(int x, int y, int width, int height) { 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_RESTRICT uint16_t* dst = fDevice->getAddr16(x, y); 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SK_RESTRICT SkPMColor* src = fSource->getAddr32(x - fLeft, 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com y - fTop); 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dstRB = fDevice->rowBytes(); 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned srcRB = fSource->rowBytes(); 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBlitRow::Proc proc = fProc; 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU alpha = fPaint->getAlpha(); 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--height >= 0) { 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com proc(dst, src, width, alpha, x, y); 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com y += 1; 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dst = (SK_RESTRICT uint16_t*)((char*)dst + dstRB); 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com src = (const SK_RESTRICT SkPMColor*)((const char*)src + srcRB); 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBlitRow::Proc fProc; 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkSpriteBlitter INHERITED; 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplatesPriv.h" 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkSpriteBlitter* SkSpriteBlitter::ChooseD16(const SkBitmap& source, 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint, 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void* storage, size_t storageSize) { 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.getMaskFilter() != NULL) { // may add cases for this 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.getXfermode() != NULL) { // may add cases for this 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.getColorFilter() != NULL) { // may add cases for this 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkSpriteBlitter* blitter = NULL; 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned alpha = paint.getAlpha(); 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (source.getConfig()) { 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkBitmap::kARGB_8888_Config: 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S32_BlitRowProc, 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com storage, storageSize, (source)); 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkBitmap::kARGB_4444_Config: 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (255 == alpha) { 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S4444_Opaque, 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com storage, storageSize, (source)); 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S4444_Blend, 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com storage, storageSize, (source, alpha >> 4)); 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkBitmap::kRGB_565_Config: 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (255 == alpha) { 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S16_Opaque, 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com storage, storageSize, (source)); 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S16_Blend, 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com storage, storageSize, (source, alpha)); 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkBitmap::kIndex8_Config: 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (source.isOpaque()) { 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (255 == alpha) { 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Opaque, 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com storage, storageSize, (source)); 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Blend, 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com storage, storageSize, (source, alpha)); 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (255 == alpha) { 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8A_Opaque, 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com storage, storageSize, (source)); 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8A_Blend, 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com storage, storageSize, (source, alpha)); 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return blitter; 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 383