1f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 2f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/* 3f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Copyright 2006 The Android Open Source Project 4f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * 5f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 6f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * found in the LICENSE file. 7f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger */ 8f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 9f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 10f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkSpriteBlitter.h" 11f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkBlitRow.h" 12f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkColorFilter.h" 13f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkColorPriv.h" 14f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkTemplates.h" 15f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkUtils.h" 16f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkXfermode.h" 17f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 18f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 19f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 20f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass Sprite_D32_S32 : public SkSpriteBlitter { 21f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 22f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Sprite_D32_S32(const SkBitmap& src, U8CPU alpha) : INHERITED(src) { 23f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(src.config() == SkBitmap::kARGB_8888_Config); 24f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 25f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned flags32 = 0; 26f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (255 != alpha) { 27f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger flags32 |= SkBlitRow::kGlobalAlpha_Flag32; 28f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 29f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (!src.isOpaque()) { 30f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32; 31f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 32f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 33f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fProc32 = SkBlitRow::Factory32(flags32); 34f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fAlpha = alpha; 35f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 36f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 37f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void blitRect(int x, int y, int width, int height) { 38f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(width > 0 && height > 0); 39f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger uint32_t* SK_RESTRICT dst = fDevice->getAddr32(x, y); 40f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const uint32_t* SK_RESTRICT src = fSource->getAddr32(x - fLeft, 41f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger y - fTop); 42f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger size_t dstRB = fDevice->rowBytes(); 43f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger size_t srcRB = fSource->rowBytes(); 44f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkBlitRow::Proc32 proc = fProc32; 45f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger U8CPU alpha = fAlpha; 46f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 47f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 48f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger proc(dst, src, width, alpha); 49f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB); 50f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB); 51f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (--height != 0); 52f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 53f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 54f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate: 55f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkBlitRow::Proc32 fProc32; 56f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger U8CPU fAlpha; 57f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 58f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger typedef SkSpriteBlitter INHERITED; 59f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 60f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 61f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 62f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 63f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass Sprite_D32_XferFilter : public SkSpriteBlitter { 64f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 65f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Sprite_D32_XferFilter(const SkBitmap& source, const SkPaint& paint) 66f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger : SkSpriteBlitter(source) { 67f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fColorFilter = paint.getColorFilter(); 68f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkSafeRef(fColorFilter); 69f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 70f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fXfermode = paint.getXfermode(); 71f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkSafeRef(fXfermode); 72f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 73f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fBufferSize = 0; 74f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fBuffer = NULL; 75f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 76f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned flags32 = 0; 77f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (255 != paint.getAlpha()) { 78f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger flags32 |= SkBlitRow::kGlobalAlpha_Flag32; 79f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 80f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (!source.isOpaque()) { 81f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32; 82f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 83f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 84f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fProc32 = SkBlitRow::Factory32(flags32); 85f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fAlpha = paint.getAlpha(); 86f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 87f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 88f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual ~Sprite_D32_XferFilter() { 89f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger delete[] fBuffer; 90f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkSafeUnref(fXfermode); 91f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkSafeUnref(fColorFilter); 92f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 93f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 94f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void setup(const SkBitmap& device, int left, int top, 95f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPaint& paint) { 96f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger this->INHERITED::setup(device, left, top, paint); 97f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 98f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int width = device.width(); 99f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (width > fBufferSize) { 100f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fBufferSize = width; 101f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger delete[] fBuffer; 102f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fBuffer = new SkPMColor[width]; 103f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 104f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 105f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 106f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprotected: 107f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkColorFilter* fColorFilter; 108f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermode* fXfermode; 109f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int fBufferSize; 110f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor* fBuffer; 111f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkBlitRow::Proc32 fProc32; 112f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger U8CPU fAlpha; 113f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 114f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate: 115f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger typedef SkSpriteBlitter INHERITED; 116f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 117f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 118f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 119f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 120f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass Sprite_D32_S32A_XferFilter : public Sprite_D32_XferFilter { 121f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 122f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Sprite_D32_S32A_XferFilter(const SkBitmap& source, const SkPaint& paint) 123f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger : Sprite_D32_XferFilter(source, paint) {} 124f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 125f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void blitRect(int x, int y, int width, int height) { 126f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(width > 0 && height > 0); 127f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger uint32_t* SK_RESTRICT dst = fDevice->getAddr32(x, y); 128f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const uint32_t* SK_RESTRICT src = fSource->getAddr32(x - fLeft, 129f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger y - fTop); 130f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned dstRB = fDevice->rowBytes(); 131f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned srcRB = fSource->rowBytes(); 132f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkColorFilter* colorFilter = fColorFilter; 133f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermode* xfermode = fXfermode; 134f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 135f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 136f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* tmp = src; 137f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 138f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL != colorFilter) { 139f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger colorFilter->filterSpan(src, width, fBuffer); 140f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger tmp = fBuffer; 141f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 142f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 143f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL != xfermode) { 144f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger xfermode->xfer32(dst, tmp, width, NULL); 145f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 146f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fProc32(dst, tmp, width, fAlpha); 147f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 148f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 149f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB); 150f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB); 151f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (--height != 0); 152f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 153f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 154f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate: 155f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger typedef Sprite_D32_XferFilter INHERITED; 156f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 157f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 158f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic void fillbuffer(SkPMColor* SK_RESTRICT dst, 159f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor16* SK_RESTRICT src, int count) { 160f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(count > 0); 161f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 162f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 163f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *dst++ = SkPixel4444ToPixel32(*src++); 164f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (--count != 0); 165f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 166f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 167f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass Sprite_D32_S4444_XferFilter : public Sprite_D32_XferFilter { 168f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 169f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Sprite_D32_S4444_XferFilter(const SkBitmap& source, const SkPaint& paint) 170f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger : Sprite_D32_XferFilter(source, paint) {} 171f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 172f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void blitRect(int x, int y, int width, int height) { 173f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(width > 0 && height > 0); 174f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y); 175f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft, 176f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger y - fTop); 177f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned dstRB = fDevice->rowBytes(); 178f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned srcRB = fSource->rowBytes(); 179f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor* SK_RESTRICT buffer = fBuffer; 180f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkColorFilter* colorFilter = fColorFilter; 181f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermode* xfermode = fXfermode; 182f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 183f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 184f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fillbuffer(buffer, src, width); 185f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 186f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL != colorFilter) { 187f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger colorFilter->filterSpan(buffer, width, buffer); 188f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 189f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL != xfermode) { 190f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger xfermode->xfer32(dst, buffer, width, NULL); 191f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 192f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fProc32(dst, buffer, width, fAlpha); 193f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 194f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 195f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB); 196f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB); 197f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (--height != 0); 198f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 199f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 200f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate: 201f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger typedef Sprite_D32_XferFilter INHERITED; 202f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 203f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 204f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 205f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 206f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic void src_row(SkPMColor* SK_RESTRICT dst, 207f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor16* SK_RESTRICT src, int count) { 208f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 209f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *dst = SkPixel4444ToPixel32(*src); 210f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger src += 1; 211f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst += 1; 212f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (--count != 0); 213f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 214f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 215f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass Sprite_D32_S4444_Opaque : public SkSpriteBlitter { 216f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 217f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Sprite_D32_S4444_Opaque(const SkBitmap& source) : SkSpriteBlitter(source) {} 218f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 219f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void blitRect(int x, int y, int width, int height) { 220f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(width > 0 && height > 0); 221f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y); 222f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft, 223f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger y - fTop); 224f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned dstRB = fDevice->rowBytes(); 225f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned srcRB = fSource->rowBytes(); 226f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 227f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 228f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger src_row(dst, src, width); 229f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB); 230f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB); 231f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (--height != 0); 232f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 233f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 234f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 235f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic void srcover_row(SkPMColor* SK_RESTRICT dst, 236f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor16* SK_RESTRICT src, int count) { 237f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 238f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *dst = SkPMSrcOver(SkPixel4444ToPixel32(*src), *dst); 239f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger src += 1; 240f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst += 1; 241f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (--count != 0); 242f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 243f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 244f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass Sprite_D32_S4444 : public SkSpriteBlitter { 245f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 246f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Sprite_D32_S4444(const SkBitmap& source) : SkSpriteBlitter(source) {} 247f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 248f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void blitRect(int x, int y, int width, int height) { 249f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(width > 0 && height > 0); 250f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y); 251f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft, 252f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger y - fTop); 253f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned dstRB = fDevice->rowBytes(); 254f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned srcRB = fSource->rowBytes(); 255f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 256f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 257f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger srcover_row(dst, src, width); 258f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB); 259f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB); 260f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (--height != 0); 261f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 262f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 263f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 264f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 265f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 266f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkTemplatesPriv.h" 267f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 268f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkSpriteBlitter* SkSpriteBlitter::ChooseD32(const SkBitmap& source, 269f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPaint& paint, 270f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger void* storage, size_t storageSize) { 271f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (paint.getMaskFilter() != NULL) { 272f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return NULL; 273f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 274f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 275f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger U8CPU alpha = paint.getAlpha(); 276f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermode* xfermode = paint.getXfermode(); 277f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkColorFilter* filter = paint.getColorFilter(); 278f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkSpriteBlitter* blitter = NULL; 279f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 280f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger switch (source.getConfig()) { 281f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger case SkBitmap::kARGB_4444_Config: 282f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (alpha != 0xFF) { 283f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return NULL; // we only have opaque sprites 284f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 285f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (xfermode || filter) { 286f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_XferFilter, 287f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger storage, storageSize, (source, paint)); 288f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (source.isOpaque()) { 289f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_Opaque, 290f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger storage, storageSize, (source)); 291f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 292f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444, 293f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger storage, storageSize, (source)); 294f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 295f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger break; 296f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger case SkBitmap::kARGB_8888_Config: 297f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (xfermode || filter) { 298f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (255 == alpha) { 299f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // this can handle xfermode or filter, but not alpha 300f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32A_XferFilter, 301f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger storage, storageSize, (source, paint)); 302f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 303f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 304f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // this can handle alpha, but not xfermode or filter 305f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32, 306f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger storage, storageSize, (source, alpha)); 307f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 308f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger break; 309f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger default: 310f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger break; 311f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 312f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return blitter; 313f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 314