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