11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkSpriteBlitter.h" 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlitRow.h" 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplates.h" 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h" 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define D16_S32A_Opaque_Pixel(dst, sc) \ 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectdo { \ 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (sc) { \ 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst = SkSrcOver32To16(sc, *dst); \ 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } \ 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} while (0) 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline void D16_S32A_Blend_Pixel_helper(uint16_t* dst, SkPMColor sc, 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned src_scale) { 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint16_t dc = *dst; 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned sa = SkGetPackedA32(sc); 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned dr, dg, db; 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (255 == sa) { 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dr = SkAlphaBlend(SkPacked32ToR16(sc), SkGetPackedR16(dc), src_scale); 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dg = SkAlphaBlend(SkPacked32ToG16(sc), SkGetPackedG16(dc), src_scale); 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project db = SkAlphaBlend(SkPacked32ToB16(sc), SkGetPackedB16(dc), src_scale); 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned dst_scale = 255 - SkAlphaMul(sa, src_scale); 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dr = (SkPacked32ToR16(sc) * src_scale + 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGetPackedR16(dc) * dst_scale) >> 8; 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dg = (SkPacked32ToG16(sc) * src_scale + 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGetPackedG16(dc) * dst_scale) >> 8; 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project db = (SkPacked32ToB16(sc) * src_scale + 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGetPackedB16(dc) * dst_scale) >> 8; 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst = SkPackRGB16(dr, dg, db); 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define D16_S32A_Blend_Pixel(dst, sc, src_scale) \ 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { if (sc) D16_S32A_Blend_Pixel_helper(dst, sc, src_scale); } while (0) 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sprite_D16_S16_Opaque : public SkSpriteBlitter { 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Sprite_D16_S16_Opaque(const SkBitmap& source) 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : SkSpriteBlitter(source) {} 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // overrides 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void blitRect(int x, int y, int width, int height) { 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint16_t* SK_RESTRICT dst = fDevice->getAddr16(x, y); 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint16_t* SK_RESTRICT src = fSource->getAddr16(x - fLeft, 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project y - fTop); 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned dstRB = fDevice->rowBytes(); 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned srcRB = fSource->rowBytes(); 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (--height >= 0) { 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(dst, src, width << 1); 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst = (uint16_t*)((char*)dst + dstRB); 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project src = (const uint16_t*)((const char*)src + srcRB); 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define D16_S16_Blend_Pixel(dst, sc, scale) \ 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { \ 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint16_t dc = *dst; \ 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst = SkBlendRGB16(sc, dc, scale); \ 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (0) 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_CLASSNAME Sprite_D16_S16_Blend 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_ARGS , uint8_t alpha 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_FIELDS uint8_t fSrcAlpha; 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_INIT fSrcAlpha = alpha; 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_TYPE uint16_t 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_TYPE uint16_t 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_GETADDR getAddr16 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_GETADDR getAddr16 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_PREAMBLE(srcBM, x, y) int scale = SkAlpha255To256(fSrcAlpha); 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S16_Blend_Pixel(dst, src, scale) 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_NEXT_ROW 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_POSTAMBLE(srcBM) 900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkSpriteBlitterTemplate.h" 910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define D16_S4444_Opaque(dst, sc) \ 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { \ 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint16_t dc = *dst; \ 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst = SkSrcOver4444To16(sc, dc); \ 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (0) 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_CLASSNAME Sprite_D16_S4444_Opaque 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_ARGS 1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_FIELDS 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_INIT 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_TYPE uint16_t 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_TYPE SkPMColor16 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_GETADDR getAddr16 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_GETADDR getAddr16 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_PREAMBLE(srcBM, x, y) 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S4444_Opaque(dst, src) 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_NEXT_ROW 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_POSTAMBLE(srcBM) 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkSpriteBlitterTemplate.h" 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define D16_S4444_Blend(dst, sc, scale16) \ 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { \ 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint16_t dc = *dst; \ 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst = SkBlend4444To16(sc, dc, scale16); \ 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (0) 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_CLASSNAME Sprite_D16_S4444_Blend 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_ARGS , uint8_t alpha 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_FIELDS uint8_t fSrcAlpha; 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_INIT fSrcAlpha = alpha; 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_TYPE uint16_t 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_TYPE uint16_t 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_GETADDR getAddr16 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_GETADDR getAddr16 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_PREAMBLE(srcBM, x, y) int scale = SkAlpha15To16(fSrcAlpha); 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S4444_Blend(dst, src, scale) 1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_NEXT_ROW 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_POSTAMBLE(srcBM) 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkSpriteBlitterTemplate.h" 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_CLASSNAME Sprite_D16_SIndex8A_Opaque 1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_ARGS 1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_FIELDS 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_INIT 1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_TYPE uint16_t 1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_TYPE uint8_t 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_GETADDR getAddr16 1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_GETADDR getAddr8 1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_PREAMBLE(srcBM, x, y) const SkPMColor* ctable = srcBM.getColorTable()->lockColors() 1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S32A_Opaque_Pixel(dst, ctable[src]) 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_NEXT_ROW 1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlockColors(false) 1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkSpriteBlitterTemplate.h" 1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_CLASSNAME Sprite_D16_SIndex8A_Blend 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_ARGS , uint8_t alpha 1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_FIELDS uint8_t fSrcAlpha; 1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_INIT fSrcAlpha = alpha; 1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_TYPE uint16_t 1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_TYPE uint8_t 1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_GETADDR getAddr16 1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_GETADDR getAddr8 1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_PREAMBLE(srcBM, x, y) const SkPMColor* ctable = srcBM.getColorTable()->lockColors(); unsigned src_scale = SkAlpha255To256(fSrcAlpha); 1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S32A_Blend_Pixel(dst, ctable[src], src_scale) 1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_NEXT_ROW 1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlockColors(false); 1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkSpriteBlitterTemplate.h" 1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 167fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reedstatic intptr_t asint(const void* ptr) { 168fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed return reinterpret_cast<const char*>(ptr) - (const char*)0; 169fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed} 170fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed 1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void blitrow_d16_si8(uint16_t* SK_RESTRICT dst, 1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint8_t* SK_RESTRICT src, int count, 1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint16_t* SK_RESTRICT ctable) { 174fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed if (count <= 8) { 175fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed do { 176fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *dst++ = ctable[*src++]; 177fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed } while (--count); 178fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed return; 179fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed } 180fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed 181fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed // eat src until we're on a 4byte boundary 182fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed while (asint(src) & 3) { 183fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *dst++ = ctable[*src++]; 184fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed count -= 1; 185fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed } 186fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed 187fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed int qcount = count >> 2; 188fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed SkASSERT(qcount > 0); 189fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed const uint32_t* qsrc = reinterpret_cast<const uint32_t*>(src); 190fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed if (asint(dst) & 2) { 191fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed do { 192fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed uint32_t s4 = *qsrc++; 193fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed#ifdef SK_CPU_LENDIAN 194fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *dst++ = ctable[s4 & 0xFF]; 195fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *dst++ = ctable[(s4 >> 8) & 0xFF]; 196fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *dst++ = ctable[(s4 >> 16) & 0xFF]; 197fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *dst++ = ctable[s4 >> 24]; 198fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed#else // BENDIAN 199fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *dst++ = ctable[s4 >> 24]; 200fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *dst++ = ctable[(s4 >> 16) & 0xFF]; 201fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *dst++ = ctable[(s4 >> 8) & 0xFF]; 202fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *dst++ = ctable[s4 & 0xFF]; 203fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed#endif 204fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed } while (--qcount); 205fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed } else { // dst is on a 4byte boundary 206fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed uint32_t* ddst = reinterpret_cast<uint32_t*>(dst); 207fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed do { 208fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed uint32_t s4 = *qsrc++; 209fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed#ifdef SK_CPU_LENDIAN 210fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *ddst++ = (ctable[(s4 >> 8) & 0xFF] << 16) | ctable[s4 & 0xFF]; 211fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *ddst++ = (ctable[s4 >> 24] << 16) | ctable[(s4 >> 16) & 0xFF]; 212fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed#else // BENDIAN 213fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *ddst++ = (ctable[s4 >> 24] << 16) | ctable[(s4 >> 16) & 0xFF]; 214fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *ddst++ = (ctable[(s4 >> 8) & 0xFF] << 16) | ctable[s4 & 0xFF]; 215fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed#endif 216fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed } while (--qcount); 217fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed dst = reinterpret_cast<uint16_t*>(ddst); 218fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed } 219fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed src = reinterpret_cast<const uint8_t*>(qsrc); 220fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed count &= 3; 221fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed // catch any remaining (will be < 4) 222fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed while (--count >= 0) { 223fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed *dst++ = ctable[*src++]; 224fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed } 225fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed} 226fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed 227fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed#define SkSPRITE_ROW_PROC(d, s, n, x, y) blitrow_d16_si8(d, s, n, ctable) 228fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reed 2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_CLASSNAME Sprite_D16_SIndex8_Opaque 2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_ARGS 2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_FIELDS 2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_INIT 2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_TYPE uint16_t 2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_TYPE uint8_t 2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_GETADDR getAddr16 2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_GETADDR getAddr8 2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_PREAMBLE(srcBM, x, y) const uint16_t* ctable = srcBM.getColorTable()->lock16BitCache() 2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_BLIT_PIXEL(dst, src) *dst = ctable[src] 2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_NEXT_ROW 2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlock16BitCache() 2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkSpriteBlitterTemplate.h" 2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_CLASSNAME Sprite_D16_SIndex8_Blend 2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_ARGS , uint8_t alpha 2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_FIELDS uint8_t fSrcAlpha; 2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_INIT fSrcAlpha = alpha; 2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_TYPE uint16_t 2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_TYPE uint8_t 2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_DST_GETADDR getAddr16 2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_SRC_GETADDR getAddr8 2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_PREAMBLE(srcBM, x, y) const uint16_t* ctable = srcBM.getColorTable()->lock16BitCache(); unsigned src_scale = SkAlpha255To256(fSrcAlpha); 2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S16_Blend_Pixel(dst, ctable[src], src_scale) 2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_NEXT_ROW 2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlock16BitCache(); 2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkSpriteBlitterTemplate.h" 2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sprite_D16_S32_BlitRowProc : public SkSpriteBlitter { 2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Sprite_D16_S32_BlitRowProc(const SkBitmap& source) 2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : SkSpriteBlitter(source) {} 2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // overrides 2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void setup(const SkBitmap& device, int left, int top, 2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPaint& paint) { 2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->INHERITED::setup(device, left, top, paint); 2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned flags = 0; 2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (paint.getAlpha() < 0xFF) { 2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project flags |= SkBlitRow::kGlobalAlpha_Flag; 2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (!fSource->isOpaque()) { 2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project flags |= SkBlitRow::kSrcPixelAlpha_Flag; 2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (paint.isDither()) { 2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project flags |= SkBlitRow::kDither_Flag; 2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProc = SkBlitRow::Factory(flags, SkBitmap::kRGB_565_Config); 2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void blitRect(int x, int y, int width, int height) { 2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint16_t* SK_RESTRICT dst = fDevice->getAddr16(x, y); 2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src = fSource->getAddr32(x - fLeft, 2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project y - fTop); 2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned dstRB = fDevice->rowBytes(); 2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned srcRB = fSource->rowBytes(); 2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlitRow::Proc proc = fProc; 2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project U8CPU alpha = fPaint->getAlpha(); 2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (--height >= 0) { 2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project proc(dst, src, width, alpha, x, y); 2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project y += 1; 2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst = (uint16_t* SK_RESTRICT)((char*)dst + dstRB); 2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src = (const SkPMColor* SK_RESTRICT)((const char*)src + srcRB); 2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlitRow::Proc fProc; 3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkSpriteBlitter INHERITED; 3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplatesPriv.h" 3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkSpriteBlitter* SkSpriteBlitter::ChooseD16(const SkBitmap& source, 3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPaint& paint, 3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void* storage, size_t storageSize) { 3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (paint.getMaskFilter() != NULL) { // may add cases for this 3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (paint.getXfermode() != NULL) { // may add cases for this 3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (paint.getColorFilter() != NULL) { // may add cases for this 3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkSpriteBlitter* blitter = NULL; 3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned alpha = paint.getAlpha(); 3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (source.getConfig()) { 3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case SkBitmap::kARGB_8888_Config: 3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S32_BlitRowProc, 3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source)); 3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case SkBitmap::kARGB_4444_Config: 3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (255 == alpha) { 3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S4444_Opaque, 3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source)); 3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S4444_Blend, 3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source, alpha >> 4)); 3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case SkBitmap::kRGB_565_Config: 3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (255 == alpha) { 3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S16_Opaque, 3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source)); 3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S16_Blend, 3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source, alpha)); 3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case SkBitmap::kIndex8_Config: 3513026a9ec59b285412941d278a570e382088f8adaMike Reed if (paint.isDither()) { 3523026a9ec59b285412941d278a570e382088f8adaMike Reed // we don't support dither yet in these special cases 3533026a9ec59b285412941d278a570e382088f8adaMike Reed break; 3543026a9ec59b285412941d278a570e382088f8adaMike Reed } 3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (source.isOpaque()) { 3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (255 == alpha) { 3570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Opaque, 3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source)); 3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Blend, 3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source, alpha)); 3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (255 == alpha) { 3650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8A_Opaque, 3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source)); 3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8A_Blend, 3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source, alpha)); 3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project default: 3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return blitter; 3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 378