SkSpriteBlitter_ARGB32.cpp revision 5f46e96757e9b914485cc6c819ed97b637503fcc
1/* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "SkSpriteBlitter.h" 9#include "SkArenaAlloc.h" 10#include "SkBlitRow.h" 11#include "SkColorFilter.h" 12#include "SkColorPriv.h" 13#include "SkTemplates.h" 14#include "SkUtils.h" 15#include "SkXfermodePriv.h" 16 17/////////////////////////////////////////////////////////////////////////////// 18 19class Sprite_D32_S32 : public SkSpriteBlitter { 20public: 21 Sprite_D32_S32(const SkPixmap& src, U8CPU alpha) : INHERITED(src) { 22 SkASSERT(src.colorType() == kN32_SkColorType); 23 24 unsigned flags32 = 0; 25 if (255 != alpha) { 26 flags32 |= SkBlitRow::kGlobalAlpha_Flag32; 27 } 28 if (!src.isOpaque()) { 29 flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32; 30 } 31 32 fProc32 = SkBlitRow::Factory32(flags32); 33 fAlpha = alpha; 34 } 35 36 void blitRect(int x, int y, int width, int height) override { 37 SkASSERT(width > 0 && height > 0); 38 uint32_t* SK_RESTRICT dst = fDst.writable_addr32(x, y); 39 const uint32_t* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop); 40 size_t dstRB = fDst.rowBytes(); 41 size_t srcRB = fSource.rowBytes(); 42 SkBlitRow::Proc32 proc = fProc32; 43 U8CPU alpha = fAlpha; 44 45 do { 46 proc(dst, src, width, alpha); 47 dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB); 48 src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB); 49 } while (--height != 0); 50 } 51 52private: 53 SkBlitRow::Proc32 fProc32; 54 U8CPU fAlpha; 55 56 typedef SkSpriteBlitter INHERITED; 57}; 58 59/////////////////////////////////////////////////////////////////////////////// 60 61class Sprite_D32_XferFilter : public SkSpriteBlitter { 62public: 63 Sprite_D32_XferFilter(const SkPixmap& source, const SkPaint& paint) : SkSpriteBlitter(source) { 64 fColorFilter = paint.getColorFilter(); 65 SkSafeRef(fColorFilter); 66 67 fXfermode = SkXfermode::Peek(paint.getBlendMode()); 68 69 fBufferSize = 0; 70 fBuffer = nullptr; 71 72 unsigned flags32 = 0; 73 if (255 != paint.getAlpha()) { 74 flags32 |= SkBlitRow::kGlobalAlpha_Flag32; 75 } 76 if (!source.isOpaque()) { 77 flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32; 78 } 79 80 fProc32 = SkBlitRow::Factory32(flags32); 81 fAlpha = paint.getAlpha(); 82 } 83 84 ~Sprite_D32_XferFilter() override { 85 delete[] fBuffer; 86 SkSafeUnref(fColorFilter); 87 } 88 89 void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) override { 90 this->INHERITED::setup(dst, left, top, paint); 91 92 int width = dst.width(); 93 if (width > fBufferSize) { 94 fBufferSize = width; 95 delete[] fBuffer; 96 fBuffer = new SkPMColor[width]; 97 } 98 } 99 100protected: 101 SkColorFilter* fColorFilter; 102 SkXfermode* fXfermode; 103 int fBufferSize; 104 SkPMColor* fBuffer; 105 SkBlitRow::Proc32 fProc32; 106 U8CPU fAlpha; 107 108private: 109 typedef SkSpriteBlitter INHERITED; 110}; 111 112/////////////////////////////////////////////////////////////////////////////// 113 114class Sprite_D32_S32A_XferFilter : public Sprite_D32_XferFilter { 115public: 116 Sprite_D32_S32A_XferFilter(const SkPixmap& source, const SkPaint& paint) 117 : Sprite_D32_XferFilter(source, paint) {} 118 119 void blitRect(int x, int y, int width, int height) override { 120 SkASSERT(width > 0 && height > 0); 121 uint32_t* SK_RESTRICT dst = fDst.writable_addr32(x, y); 122 const uint32_t* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop); 123 size_t dstRB = fDst.rowBytes(); 124 size_t srcRB = fSource.rowBytes(); 125 SkColorFilter* colorFilter = fColorFilter; 126 SkXfermode* xfermode = fXfermode; 127 128 do { 129 const SkPMColor* tmp = src; 130 131 if (colorFilter) { 132 colorFilter->filterSpan(src, width, fBuffer); 133 tmp = fBuffer; 134 } 135 136 if (xfermode) { 137 xfermode->xfer32(dst, tmp, width, nullptr); 138 } else { 139 fProc32(dst, tmp, width, fAlpha); 140 } 141 142 dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB); 143 src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB); 144 } while (--height != 0); 145 } 146 147private: 148 typedef Sprite_D32_XferFilter INHERITED; 149}; 150 151/////////////////////////////////////////////////////////////////////////////// 152 153SkSpriteBlitter* SkSpriteBlitter::ChooseL32(const SkPixmap& source, const SkPaint& paint, 154 SkArenaAlloc* allocator) { 155 SkASSERT(allocator != nullptr); 156 157 if (paint.getMaskFilter() != nullptr) { 158 return nullptr; 159 } 160 161 U8CPU alpha = paint.getAlpha(); 162 bool isSrcOver = paint.isSrcOver(); 163 SkColorFilter* filter = paint.getColorFilter(); 164 SkSpriteBlitter* blitter = nullptr; 165 166 if (source.colorType() == kN32_SkColorType) { 167 if (!isSrcOver || filter) { 168 if (255 == alpha) { 169 // this can handle xfermode or filter, but not alpha 170 blitter = allocator->make<Sprite_D32_S32A_XferFilter>(source, paint); 171 } 172 } else { 173 // this can handle alpha, but not xfermode or filter 174 blitter = allocator->make<Sprite_D32_S32>(source, alpha); 175 } 176 } 177 return blitter; 178} 179