| OLD | NEW |
| (Empty) |
| 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 "SkTemplates.h" | |
| 20 #include "SkUtils.h" | |
| 21 #include "SkColorPriv.h" | |
| 22 | |
| 23 #define D32_S32A_Opaque_Pixel(dst, sc) \ | |
| 24 do { \ | |
| 25 if (sc) { \ | |
| 26 unsigned srcA = SkGetPackedA32(sc); \ | |
| 27 uint32_t result = sc; \ | |
| 28 if (srcA != 0xFF) { \ | |
| 29 result += SkAlphaMulQ(*dst, SkAlpha255To256(255 - srcA)); \ | |
| 30 } \ | |
| 31 *dst = result; \ | |
| 32 } \ | |
| 33 } while (0) | |
| 34 | |
| 35 #define SkSPRITE_CLASSNAME Sprite_D32_S32A_Opaque | |
| 36 #define SkSPRITE_ARGS | |
| 37 #define SkSPRITE_FIELDS | |
| 38 #define SkSPRITE_INIT | |
| 39 #define SkSPRITE_DST_TYPE uint32_t | |
| 40 #define SkSPRITE_SRC_TYPE uint32_t | |
| 41 #define SkSPRITE_DST_GETADDR getAddr32 | |
| 42 #define SkSPRITE_SRC_GETADDR getAddr32 | |
| 43 #define SkSPRITE_PREAMBLE(srcBM, x, y) | |
| 44 #define SkSPRITE_BLIT_PIXEL(dst, src) D32_S32A_Opaque_Pixel(dst, src) | |
| 45 #define SkSPRITE_NEXT_ROW | |
| 46 #define SkSPRITE_POSTAMBLE(srcBM) | |
| 47 #include "SkSpriteBlitterTemplate.h" | |
| 48 | |
| 49 /////////////////////////////////////////////////////////////////////////////// | |
| 50 | |
| 51 class Sprite_D32_S32_Opaque : public SkSpriteBlitter { | |
| 52 public: | |
| 53 Sprite_D32_S32_Opaque(const SkBitmap& source) : SkSpriteBlitter(source) {} | |
| 54 | |
| 55 virtual void blitRect(int x, int y, int width, int height) { | |
| 56 SkASSERT(width > 0 && height > 0); | |
| 57 SK_RESTRICT uint32_t* dst = fDevice->getAddr32(x, y); | |
| 58 const SK_RESTRICT uint32_t* src = fSource->getAddr32(x - fLeft, | |
| 59 y - fTop); | |
| 60 unsigned dstRB = fDevice->rowBytes(); | |
| 61 unsigned srcRB = fSource->rowBytes(); | |
| 62 size_t size = width * sizeof(uint32_t); | |
| 63 | |
| 64 do { | |
| 65 memcpy(dst, src, size); | |
| 66 dst = (SK_RESTRICT uint32_t*)((char*)dst + dstRB); | |
| 67 src = (const SK_RESTRICT uint32_t*)((const char*)src + srcRB); | |
| 68 } while (--height != 0); | |
| 69 } | |
| 70 }; | |
| 71 | |
| 72 /////////////////////////////////////////////////////////////////////////////// | |
| 73 | |
| 74 #include "SkColorFilter.h" | |
| 75 #include "SkXfermode.h" | |
| 76 | |
| 77 class Sprite_D32_XferFilter : public SkSpriteBlitter { | |
| 78 public: | |
| 79 Sprite_D32_XferFilter(const SkBitmap& source, const SkPaint& paint) | |
| 80 : SkSpriteBlitter(source) { | |
| 81 fColorFilter = paint.getColorFilter(); | |
| 82 fColorFilter->safeRef(); | |
| 83 | |
| 84 fXfermode = paint.getXfermode(); | |
| 85 fXfermode->safeRef(); | |
| 86 | |
| 87 fBufferSize = 0; | |
| 88 fBuffer = NULL; | |
| 89 } | |
| 90 | |
| 91 virtual ~Sprite_D32_XferFilter() { | |
| 92 delete[] fBuffer; | |
| 93 fXfermode->safeUnref(); | |
| 94 fColorFilter->safeUnref(); | |
| 95 } | |
| 96 | |
| 97 virtual void setup(const SkBitmap& device, int left, int top, | |
| 98 const SkPaint& paint) { | |
| 99 this->INHERITED::setup(device, left, top, paint); | |
| 100 | |
| 101 int width = device.width(); | |
| 102 if (width > fBufferSize) { | |
| 103 fBufferSize = width; | |
| 104 delete[] fBuffer; | |
| 105 fBuffer = new SkPMColor[width]; | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 protected: | |
| 110 SkColorFilter* fColorFilter; | |
| 111 SkXfermode* fXfermode; | |
| 112 int fBufferSize; | |
| 113 SkPMColor* fBuffer; | |
| 114 | |
| 115 private: | |
| 116 typedef SkSpriteBlitter INHERITED; | |
| 117 }; | |
| 118 | |
| 119 /////////////////////////////////////////////////////////////////////////////// | |
| 120 | |
| 121 class Sprite_D32_S32A_XferFilter : public Sprite_D32_XferFilter { | |
| 122 public: | |
| 123 Sprite_D32_S32A_XferFilter(const SkBitmap& source, const SkPaint& paint) | |
| 124 : Sprite_D32_XferFilter(source, paint) {} | |
| 125 | |
| 126 virtual void blitRect(int x, int y, int width, int height) { | |
| 127 SkASSERT(width > 0 && height > 0); | |
| 128 SK_RESTRICT uint32_t* dst = fDevice->getAddr32(x, y); | |
| 129 const SK_RESTRICT uint32_t* src = fSource->getAddr32(x - fLeft, | |
| 130 y - fTop); | |
| 131 unsigned dstRB = fDevice->rowBytes(); | |
| 132 unsigned srcRB = fSource->rowBytes(); | |
| 133 SkColorFilter* colorFilter = fColorFilter; | |
| 134 SkXfermode* xfermode = fXfermode; | |
| 135 | |
| 136 do { | |
| 137 const SkPMColor* tmp = src; | |
| 138 | |
| 139 if (NULL != colorFilter) { | |
| 140 colorFilter->filterSpan(src, width, fBuffer); | |
| 141 tmp = fBuffer; | |
| 142 } | |
| 143 | |
| 144 if (NULL != xfermode) { | |
| 145 xfermode->xfer32(dst, tmp, width, NULL); | |
| 146 } else { | |
| 147 for (int i = 0; i < width; i++) { | |
| 148 dst[i] = SkPMSrcOver(tmp[i], dst[i]); | |
| 149 } | |
| 150 } | |
| 151 | |
| 152 dst = (SK_RESTRICT uint32_t*)((char*)dst + dstRB); | |
| 153 src = (const SK_RESTRICT uint32_t*)((const char*)src + srcRB); | |
| 154 } while (--height != 0); | |
| 155 } | |
| 156 | |
| 157 private: | |
| 158 typedef Sprite_D32_XferFilter INHERITED; | |
| 159 }; | |
| 160 | |
| 161 static void fillbuffer(SK_RESTRICT SkPMColor dst[], | |
| 162 const SK_RESTRICT SkPMColor16 src[], int count) { | |
| 163 SkASSERT(count > 0); | |
| 164 | |
| 165 do { | |
| 166 *dst++ = SkPixel4444ToPixel32(*src++); | |
| 167 } while (--count != 0); | |
| 168 } | |
| 169 | |
| 170 class Sprite_D32_S4444_XferFilter : public Sprite_D32_XferFilter { | |
| 171 public: | |
| 172 Sprite_D32_S4444_XferFilter(const SkBitmap& source, const SkPaint& paint) | |
| 173 : Sprite_D32_XferFilter(source, paint) {} | |
| 174 | |
| 175 virtual void blitRect(int x, int y, int width, int height) { | |
| 176 SkASSERT(width > 0 && height > 0); | |
| 177 SK_RESTRICT SkPMColor* dst = fDevice->getAddr32(x, y); | |
| 178 const SK_RESTRICT SkPMColor16* src = fSource->getAddr16(x - fLeft, | |
| 179 y - fTop); | |
| 180 unsigned dstRB = fDevice->rowBytes(); | |
| 181 unsigned srcRB = fSource->rowBytes(); | |
| 182 SK_RESTRICT SkPMColor* buffer = fBuffer; | |
| 183 SkColorFilter* colorFilter = fColorFilter; | |
| 184 SkXfermode* xfermode = fXfermode; | |
| 185 | |
| 186 do { | |
| 187 fillbuffer(buffer, src, width); | |
| 188 | |
| 189 if (NULL != colorFilter) { | |
| 190 colorFilter->filterSpan(buffer, width, buffer); | |
| 191 } | |
| 192 if (NULL != xfermode) { | |
| 193 xfermode->xfer32(dst, buffer, width, NULL); | |
| 194 } else { | |
| 195 for (int i = 0; i < width; i++) { | |
| 196 dst[i] = SkPMSrcOver(buffer[i], dst[i]); | |
| 197 } | |
| 198 } | |
| 199 | |
| 200 dst = (SK_RESTRICT SkPMColor*)((char*)dst + dstRB); | |
| 201 src = (const SK_RESTRICT SkPMColor16*)((const char*)src + srcRB); | |
| 202 } while (--height != 0); | |
| 203 } | |
| 204 | |
| 205 private: | |
| 206 typedef Sprite_D32_XferFilter INHERITED; | |
| 207 }; | |
| 208 | |
| 209 /////////////////////////////////////////////////////////////////////////////// | |
| 210 | |
| 211 static void src_row(SK_RESTRICT SkPMColor dst[], | |
| 212 const SK_RESTRICT SkPMColor16 src[], int count) { | |
| 213 do { | |
| 214 *dst = SkPixel4444ToPixel32(*src); | |
| 215 src += 1; | |
| 216 dst += 1; | |
| 217 } while (--count != 0); | |
| 218 } | |
| 219 | |
| 220 class Sprite_D32_S4444_Opaque : public SkSpriteBlitter { | |
| 221 public: | |
| 222 Sprite_D32_S4444_Opaque(const SkBitmap& source) : SkSpriteBlitter(source) {} | |
| 223 | |
| 224 virtual void blitRect(int x, int y, int width, int height) { | |
| 225 SkASSERT(width > 0 && height > 0); | |
| 226 SK_RESTRICT SkPMColor* dst = fDevice->getAddr32(x, y); | |
| 227 const SK_RESTRICT SkPMColor16* src = fSource->getAddr16(x - fLeft, | |
| 228 y - fTop); | |
| 229 unsigned dstRB = fDevice->rowBytes(); | |
| 230 unsigned srcRB = fSource->rowBytes(); | |
| 231 | |
| 232 do { | |
| 233 src_row(dst, src, width); | |
| 234 dst = (SK_RESTRICT SkPMColor*)((char*)dst + dstRB); | |
| 235 src = (const SK_RESTRICT SkPMColor16*)((const char*)src + srcRB); | |
| 236 } while (--height != 0); | |
| 237 } | |
| 238 }; | |
| 239 | |
| 240 static void srcover_row(SK_RESTRICT SkPMColor dst[], | |
| 241 const SK_RESTRICT SkPMColor16 src[], int count) { | |
| 242 do { | |
| 243 *dst = SkPMSrcOver(SkPixel4444ToPixel32(*src), *dst); | |
| 244 src += 1; | |
| 245 dst += 1; | |
| 246 } while (--count != 0); | |
| 247 } | |
| 248 | |
| 249 class Sprite_D32_S4444 : public SkSpriteBlitter { | |
| 250 public: | |
| 251 Sprite_D32_S4444(const SkBitmap& source) : SkSpriteBlitter(source) {} | |
| 252 | |
| 253 virtual void blitRect(int x, int y, int width, int height) { | |
| 254 SkASSERT(width > 0 && height > 0); | |
| 255 SK_RESTRICT SkPMColor* dst = fDevice->getAddr32(x, y); | |
| 256 const SK_RESTRICT SkPMColor16* src = fSource->getAddr16(x - fLeft, | |
| 257 y - fTop); | |
| 258 unsigned dstRB = fDevice->rowBytes(); | |
| 259 unsigned srcRB = fSource->rowBytes(); | |
| 260 | |
| 261 do { | |
| 262 srcover_row(dst, src, width); | |
| 263 dst = (SK_RESTRICT SkPMColor*)((char*)dst + dstRB); | |
| 264 src = (const SK_RESTRICT SkPMColor16*)((const char*)src + srcRB); | |
| 265 } while (--height != 0); | |
| 266 } | |
| 267 }; | |
| 268 | |
| 269 /////////////////////////////////////////////////////////////////////////////// | |
| 270 | |
| 271 #include "SkTemplatesPriv.h" | |
| 272 | |
| 273 SkSpriteBlitter* SkSpriteBlitter::ChooseD32(const SkBitmap& source, | |
| 274 const SkPaint& paint, | |
| 275 void* storage, size_t storageSize) { | |
| 276 if (paint.getMaskFilter() != NULL || paint.getAlpha() != 0xFF) { | |
| 277 return NULL; | |
| 278 } | |
| 279 | |
| 280 SkXfermode* xfermode = paint.getXfermode(); | |
| 281 SkColorFilter* filter = paint.getColorFilter(); | |
| 282 SkSpriteBlitter* blitter = NULL; | |
| 283 | |
| 284 switch (source.getConfig()) { | |
| 285 case SkBitmap::kARGB_4444_Config: | |
| 286 if (xfermode || filter) { | |
| 287 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_XferFilter, | |
| 288 storage, storageSize, (source, paint)); | |
| 289 } else if (source.isOpaque()) { | |
| 290 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_Opaque, | |
| 291 storage, storageSize, (source)); | |
| 292 } else { | |
| 293 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444, | |
| 294 storage, storageSize, (source)); | |
| 295 } | |
| 296 break; | |
| 297 case SkBitmap::kARGB_8888_Config: | |
| 298 if (xfermode || filter) { | |
| 299 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32A_XferFilter, | |
| 300 storage, storageSize, (source, paint)); | |
| 301 } else if (source.isOpaque()) { | |
| 302 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32_Opaque, | |
| 303 storage, storageSize, (source)); | |
| 304 } else { | |
| 305 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32A_Opaque, | |
| 306 storage, storageSize, (source)); | |
| 307 } | |
| 308 break; | |
| 309 default: | |
| 310 break; | |
| 311 } | |
| 312 return blitter; | |
| 313 } | |
| 314 | |
| OLD | NEW |