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" 11d0195f840fa964da51f7a1192b432954794e660cMike Reed#include "SkBlitRow.h" 12d0195f840fa964da51f7a1192b432954794e660cMike Reed#include "SkColorFilter.h" 13d0195f840fa964da51f7a1192b432954794e660cMike Reed#include "SkColorPriv.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplates.h" 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h" 16d0195f840fa964da51f7a1192b432954794e660cMike Reed#include "SkXfermode.h" 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20d0195f840fa964da51f7a1192b432954794e660cMike Reedclass Sprite_D32_S32 : public SkSpriteBlitter { 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 22d0195f840fa964da51f7a1192b432954794e660cMike Reed Sprite_D32_S32(const SkBitmap& src, U8CPU alpha) : INHERITED(src) { 23d0195f840fa964da51f7a1192b432954794e660cMike Reed SkASSERT(src.config() == SkBitmap::kARGB_8888_Config); 24d0195f840fa964da51f7a1192b432954794e660cMike Reed 25d0195f840fa964da51f7a1192b432954794e660cMike Reed unsigned flags32 = 0; 26d0195f840fa964da51f7a1192b432954794e660cMike Reed if (255 != alpha) { 27d0195f840fa964da51f7a1192b432954794e660cMike Reed flags32 |= SkBlitRow::kGlobalAlpha_Flag32; 28d0195f840fa964da51f7a1192b432954794e660cMike Reed } 29d0195f840fa964da51f7a1192b432954794e660cMike Reed if (!src.isOpaque()) { 30d0195f840fa964da51f7a1192b432954794e660cMike Reed flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32; 31d0195f840fa964da51f7a1192b432954794e660cMike Reed } 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 33d0195f840fa964da51f7a1192b432954794e660cMike Reed fProc32 = SkBlitRow::Factory32(flags32); 34d0195f840fa964da51f7a1192b432954794e660cMike Reed fAlpha = alpha; 35d0195f840fa964da51f7a1192b432954794e660cMike Reed } 3640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void blitRect(int x, int y, int width, int height) { 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(width > 0 && height > 0); 391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t* SK_RESTRICT dst = fDevice->getAddr32(x, y); 401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint32_t* SK_RESTRICT src = fSource->getAddr32(x - fLeft, 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project y - fTop); 42d0195f840fa964da51f7a1192b432954794e660cMike Reed size_t dstRB = fDevice->rowBytes(); 43d0195f840fa964da51f7a1192b432954794e660cMike Reed size_t srcRB = fSource->rowBytes(); 44d0195f840fa964da51f7a1192b432954794e660cMike Reed SkBlitRow::Proc32 proc = fProc32; 45d0195f840fa964da51f7a1192b432954794e660cMike Reed U8CPU alpha = fAlpha; 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 48d0195f840fa964da51f7a1192b432954794e660cMike Reed proc(dst, src, width, alpha); 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB); 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB); 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--height != 0); 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 53d0195f840fa964da51f7a1192b432954794e660cMike Reed 54d0195f840fa964da51f7a1192b432954794e660cMike Reedprivate: 55d0195f840fa964da51f7a1192b432954794e660cMike Reed SkBlitRow::Proc32 fProc32; 56d0195f840fa964da51f7a1192b432954794e660cMike Reed U8CPU fAlpha; 5740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 58d0195f840fa964da51f7a1192b432954794e660cMike Reed typedef SkSpriteBlitter INHERITED; 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sprite_D32_XferFilter : public SkSpriteBlitter { 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Sprite_D32_XferFilter(const SkBitmap& source, const SkPaint& paint) 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : SkSpriteBlitter(source) { 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fColorFilter = paint.getColorFilter(); 6840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fColorFilter); 6940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fXfermode = paint.getXfermode(); 7140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fXfermode); 7240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBufferSize = 0; 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBuffer = NULL; 75d0195f840fa964da51f7a1192b432954794e660cMike Reed 76d0195f840fa964da51f7a1192b432954794e660cMike Reed unsigned flags32 = 0; 77d0195f840fa964da51f7a1192b432954794e660cMike Reed if (255 != paint.getAlpha()) { 78d0195f840fa964da51f7a1192b432954794e660cMike Reed flags32 |= SkBlitRow::kGlobalAlpha_Flag32; 79d0195f840fa964da51f7a1192b432954794e660cMike Reed } 80d0195f840fa964da51f7a1192b432954794e660cMike Reed if (!source.isOpaque()) { 81d0195f840fa964da51f7a1192b432954794e660cMike Reed flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32; 82d0195f840fa964da51f7a1192b432954794e660cMike Reed } 8340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 84d0195f840fa964da51f7a1192b432954794e660cMike Reed fProc32 = SkBlitRow::Factory32(flags32); 85d0195f840fa964da51f7a1192b432954794e660cMike Reed fAlpha = paint.getAlpha(); 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual ~Sprite_D32_XferFilter() { 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project delete[] fBuffer; 9040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fXfermode); 9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fColorFilter); 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void setup(const SkBitmap& device, int left, int top, 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPaint& paint) { 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->INHERITED::setup(device, left, top, paint); 9740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int width = device.width(); 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (width > fBufferSize) { 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBufferSize = width; 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project delete[] fBuffer; 1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBuffer = new SkPMColor[width]; 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 107d0195f840fa964da51f7a1192b432954794e660cMike Reed SkColorFilter* fColorFilter; 108d0195f840fa964da51f7a1192b432954794e660cMike Reed SkXfermode* fXfermode; 109d0195f840fa964da51f7a1192b432954794e660cMike Reed int fBufferSize; 110d0195f840fa964da51f7a1192b432954794e660cMike Reed SkPMColor* fBuffer; 111d0195f840fa964da51f7a1192b432954794e660cMike Reed SkBlitRow::Proc32 fProc32; 112d0195f840fa964da51f7a1192b432954794e660cMike Reed U8CPU fAlpha; 113d0195f840fa964da51f7a1192b432954794e660cMike Reed 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkSpriteBlitter INHERITED; 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sprite_D32_S32A_XferFilter : public Sprite_D32_XferFilter { 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Sprite_D32_S32A_XferFilter(const SkBitmap& source, const SkPaint& paint) 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : Sprite_D32_XferFilter(source, paint) {} 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void blitRect(int x, int y, int width, int height) { 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(width > 0 && height > 0); 1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t* SK_RESTRICT dst = fDevice->getAddr32(x, y); 1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint32_t* SK_RESTRICT src = fSource->getAddr32(x - fLeft, 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project y - fTop); 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned dstRB = fDevice->rowBytes(); 1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned srcRB = fSource->rowBytes(); 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkColorFilter* colorFilter = fColorFilter; 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkXfermode* xfermode = fXfermode; 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPMColor* tmp = src; 13740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (NULL != colorFilter) { 1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project colorFilter->filterSpan(src, width, fBuffer); 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project tmp = fBuffer; 1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 14240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (NULL != xfermode) { 1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project xfermode->xfer32(dst, tmp, width, NULL); 1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 146d0195f840fa964da51f7a1192b432954794e660cMike Reed fProc32(dst, tmp, width, fAlpha); 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB); 1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB); 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--height != 0); 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 15340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef Sprite_D32_XferFilter INHERITED; 1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void fillbuffer(SkPMColor* SK_RESTRICT dst, 1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor16* SK_RESTRICT src, int count) { 1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(count > 0); 16140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst++ = SkPixel4444ToPixel32(*src++); 1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--count != 0); 1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sprite_D32_S4444_XferFilter : public Sprite_D32_XferFilter { 1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Sprite_D32_S4444_XferFilter(const SkBitmap& source, const SkPaint& paint) 1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : Sprite_D32_XferFilter(source, paint) {} 17140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void blitRect(int x, int y, int width, int height) { 1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(width > 0 && height > 0); 1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y); 1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft, 1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project y - fTop); 1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned dstRB = fDevice->rowBytes(); 1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned srcRB = fSource->rowBytes(); 1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor* SK_RESTRICT buffer = fBuffer; 1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkColorFilter* colorFilter = fColorFilter; 1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkXfermode* xfermode = fXfermode; 1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fillbuffer(buffer, src, width); 18540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (NULL != colorFilter) { 1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project colorFilter->filterSpan(buffer, width, buffer); 1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (NULL != xfermode) { 1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project xfermode->xfer32(dst, buffer, width, NULL); 1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 192d0195f840fa964da51f7a1192b432954794e660cMike Reed fProc32(dst, buffer, width, fAlpha); 1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 19440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB); 1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB); 1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--height != 0); 1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 19940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef Sprite_D32_XferFilter INHERITED; 2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void src_row(SkPMColor* SK_RESTRICT dst, 2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor16* SK_RESTRICT src, int count) { 2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst = SkPixel4444ToPixel32(*src); 2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project src += 1; 2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst += 1; 2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--count != 0); 2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sprite_D32_S4444_Opaque : public SkSpriteBlitter { 2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Sprite_D32_S4444_Opaque(const SkBitmap& source) : SkSpriteBlitter(source) {} 21840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void blitRect(int x, int y, int width, int height) { 2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(width > 0 && height > 0); 2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y); 2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft, 2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project y - fTop); 2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned dstRB = fDevice->rowBytes(); 2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned srcRB = fSource->rowBytes(); 22640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project src_row(dst, src, width); 2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB); 2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB); 2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--height != 0); 2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void srcover_row(SkPMColor* SK_RESTRICT dst, 2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor16* SK_RESTRICT src, int count) { 2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst = SkPMSrcOver(SkPixel4444ToPixel32(*src), *dst); 2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project src += 1; 2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst += 1; 2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--count != 0); 2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sprite_D32_S4444 : public SkSpriteBlitter { 2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Sprite_D32_S4444(const SkBitmap& source) : SkSpriteBlitter(source) {} 24740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void blitRect(int x, int y, int width, int height) { 2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(width > 0 && height > 0); 2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y); 2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft, 2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project y - fTop); 2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned dstRB = fDevice->rowBytes(); 2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned srcRB = fSource->rowBytes(); 25540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project srcover_row(dst, src, width); 2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB); 2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB); 2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--height != 0); 2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplatesPriv.h" 2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkSpriteBlitter* SkSpriteBlitter::ChooseD32(const SkBitmap& source, 2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPaint& paint, 2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void* storage, size_t storageSize) { 271d0195f840fa964da51f7a1192b432954794e660cMike Reed if (paint.getMaskFilter() != NULL) { 2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 275d0195f840fa964da51f7a1192b432954794e660cMike Reed U8CPU alpha = paint.getAlpha(); 2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkXfermode* xfermode = paint.getXfermode(); 2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkColorFilter* filter = paint.getColorFilter(); 2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkSpriteBlitter* blitter = NULL; 2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (source.getConfig()) { 2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case SkBitmap::kARGB_4444_Config: 282d0195f840fa964da51f7a1192b432954794e660cMike Reed if (alpha != 0xFF) { 283d0195f840fa964da51f7a1192b432954794e660cMike Reed return NULL; // we only have opaque sprites 284d0195f840fa964da51f7a1192b432954794e660cMike Reed } 2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (xfermode || filter) { 2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_XferFilter, 2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source, paint)); 2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else if (source.isOpaque()) { 2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_Opaque, 2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source)); 2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444, 2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source)); 2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case SkBitmap::kARGB_8888_Config: 2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (xfermode || filter) { 298d0195f840fa964da51f7a1192b432954794e660cMike Reed if (255 == alpha) { 299d0195f840fa964da51f7a1192b432954794e660cMike Reed // this can handle xfermode or filter, but not alpha 300d0195f840fa964da51f7a1192b432954794e660cMike Reed SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32A_XferFilter, 3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project storage, storageSize, (source, paint)); 302d0195f840fa964da51f7a1192b432954794e660cMike Reed } 3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 304d0195f840fa964da51f7a1192b432954794e660cMike Reed // this can handle alpha, but not xfermode or filter 305d0195f840fa964da51f7a1192b432954794e660cMike Reed SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32, 306d0195f840fa964da51f7a1192b432954794e660cMike Reed storage, storageSize, (source, alpha)); 3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project default: 3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return blitter; 3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 314