| OLD | NEW |
| (Empty) |
| 1 /* libs/graphics/sgl/SkSpriteBlitter_RGB16.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 "SkTemplates.h" | |
| 21 #include "SkUtils.h" | |
| 22 #include "SkColorPriv.h" | |
| 23 | |
| 24 #define D16_S32A_Opaque_Pixel(dst, sc) \ | |
| 25 do { \ | |
| 26 if (sc) { \ | |
| 27 *dst = SkSrcOver32To16(sc, *dst); \ | |
| 28 } \ | |
| 29 } while (0) | |
| 30 | |
| 31 static inline void D16_S32A_Blend_Pixel_helper(uint16_t* dst, SkPMColor sc, | |
| 32 unsigned src_scale) { | |
| 33 uint16_t dc = *dst; | |
| 34 unsigned sa = SkGetPackedA32(sc); | |
| 35 unsigned dr, dg, db; | |
| 36 | |
| 37 if (255 == sa) { | |
| 38 dr = SkAlphaBlend(SkPacked32ToR16(sc), SkGetPackedR16(dc), src_scale); | |
| 39 dg = SkAlphaBlend(SkPacked32ToG16(sc), SkGetPackedG16(dc), src_scale); | |
| 40 db = SkAlphaBlend(SkPacked32ToB16(sc), SkGetPackedB16(dc), src_scale); | |
| 41 } else { | |
| 42 unsigned dst_scale = 255 - SkAlphaMul(sa, src_scale); | |
| 43 dr = (SkPacked32ToR16(sc) * src_scale + | |
| 44 SkGetPackedR16(dc) * dst_scale) >> 8; | |
| 45 dg = (SkPacked32ToG16(sc) * src_scale + | |
| 46 SkGetPackedG16(dc) * dst_scale) >> 8; | |
| 47 db = (SkPacked32ToB16(sc) * src_scale + | |
| 48 SkGetPackedB16(dc) * dst_scale) >> 8; | |
| 49 } | |
| 50 *dst = SkPackRGB16(dr, dg, db); | |
| 51 } | |
| 52 | |
| 53 #define D16_S32A_Blend_Pixel(dst, sc, src_scale) \ | |
| 54 do { if (sc) D16_S32A_Blend_Pixel_helper(dst, sc, src_scale); } while (0) | |
| 55 | |
| 56 | |
| 57 /////////////////////////////////////////////////////////////////////////////// | |
| 58 | |
| 59 class Sprite_D16_S16_Opaque : public SkSpriteBlitter { | |
| 60 public: | |
| 61 Sprite_D16_S16_Opaque(const SkBitmap& source) | |
| 62 : SkSpriteBlitter(source) {} | |
| 63 | |
| 64 // overrides | |
| 65 virtual void blitRect(int x, int y, int width, int height) { | |
| 66 SK_RESTRICT uint16_t* dst = fDevice->getAddr16(x, y); | |
| 67 const SK_RESTRICT uint16_t* src = fSource->getAddr16(x - fLeft, | |
| 68 y - fTop); | |
| 69 unsigned dstRB = fDevice->rowBytes(); | |
| 70 unsigned srcRB = fSource->rowBytes(); | |
| 71 | |
| 72 while (--height >= 0) { | |
| 73 memcpy(dst, src, width << 1); | |
| 74 dst = (uint16_t*)((char*)dst + dstRB); | |
| 75 src = (const uint16_t*)((const char*)src + srcRB); | |
| 76 } | |
| 77 } | |
| 78 }; | |
| 79 | |
| 80 #define D16_S16_Blend_Pixel(dst, sc, scale) \ | |
| 81 do { \ | |
| 82 uint16_t dc = *dst; \ | |
| 83 *dst = SkBlendRGB16(sc, dc, scale); \ | |
| 84 } while (0) | |
| 85 | |
| 86 #define SkSPRITE_CLASSNAME Sprite_D16_S16_Blend | |
| 87 #define SkSPRITE_ARGS , uint8_t alpha | |
| 88 #define SkSPRITE_FIELDS uint8_t fSrcAlpha; | |
| 89 #define SkSPRITE_INIT fSrcAlpha = alpha; | |
| 90 #define SkSPRITE_DST_TYPE uint16_t | |
| 91 #define SkSPRITE_SRC_TYPE uint16_t | |
| 92 #define SkSPRITE_DST_GETADDR getAddr16 | |
| 93 #define SkSPRITE_SRC_GETADDR getAddr16 | |
| 94 #define SkSPRITE_PREAMBLE(srcBM, x, y) int scale = SkAlpha255To256(fSrcAlph
a); | |
| 95 #define SkSPRITE_BLIT_PIXEL(dst, src) D16_S16_Blend_Pixel(dst, src, scale) | |
| 96 #define SkSPRITE_NEXT_ROW | |
| 97 #define SkSPRITE_POSTAMBLE(srcBM) | |
| 98 #include "SkSpriteBlitterTemplate.h" | |
| 99 | |
| 100 /////////////////////////////////////////////////////////////////////////////// | |
| 101 | |
| 102 #define D16_S4444_Opaque(dst, sc) \ | |
| 103 do { \ | |
| 104 uint16_t dc = *dst; \ | |
| 105 *dst = SkSrcOver4444To16(sc, dc); \ | |
| 106 } while (0) | |
| 107 | |
| 108 #define SkSPRITE_CLASSNAME Sprite_D16_S4444_Opaque | |
| 109 #define SkSPRITE_ARGS | |
| 110 #define SkSPRITE_FIELDS | |
| 111 #define SkSPRITE_INIT | |
| 112 #define SkSPRITE_DST_TYPE uint16_t | |
| 113 #define SkSPRITE_SRC_TYPE SkPMColor16 | |
| 114 #define SkSPRITE_DST_GETADDR getAddr16 | |
| 115 #define SkSPRITE_SRC_GETADDR getAddr16 | |
| 116 #define SkSPRITE_PREAMBLE(srcBM, x, y) | |
| 117 #define SkSPRITE_BLIT_PIXEL(dst, src) D16_S4444_Opaque(dst, src) | |
| 118 #define SkSPRITE_NEXT_ROW | |
| 119 #define SkSPRITE_POSTAMBLE(srcBM) | |
| 120 #include "SkSpriteBlitterTemplate.h" | |
| 121 | |
| 122 #define D16_S4444_Blend(dst, sc, scale16) \ | |
| 123 do { \ | |
| 124 uint16_t dc = *dst; \ | |
| 125 *dst = SkBlend4444To16(sc, dc, scale16); \ | |
| 126 } while (0) | |
| 127 | |
| 128 | |
| 129 #define SkSPRITE_CLASSNAME Sprite_D16_S4444_Blend | |
| 130 #define SkSPRITE_ARGS , uint8_t alpha | |
| 131 #define SkSPRITE_FIELDS uint8_t fSrcAlpha; | |
| 132 #define SkSPRITE_INIT fSrcAlpha = alpha; | |
| 133 #define SkSPRITE_DST_TYPE uint16_t | |
| 134 #define SkSPRITE_SRC_TYPE uint16_t | |
| 135 #define SkSPRITE_DST_GETADDR getAddr16 | |
| 136 #define SkSPRITE_SRC_GETADDR getAddr16 | |
| 137 #define SkSPRITE_PREAMBLE(srcBM, x, y) int scale = SkAlpha15To16(fSrcAlpha)
; | |
| 138 #define SkSPRITE_BLIT_PIXEL(dst, src) D16_S4444_Blend(dst, src, scale) | |
| 139 #define SkSPRITE_NEXT_ROW | |
| 140 #define SkSPRITE_POSTAMBLE(srcBM) | |
| 141 #include "SkSpriteBlitterTemplate.h" | |
| 142 | |
| 143 /////////////////////////////////////////////////////////////////////////////// | |
| 144 | |
| 145 #define SkSPRITE_CLASSNAME Sprite_D16_SIndex8A_Opaque | |
| 146 #define SkSPRITE_ARGS | |
| 147 #define SkSPRITE_FIELDS | |
| 148 #define SkSPRITE_INIT | |
| 149 #define SkSPRITE_DST_TYPE uint16_t | |
| 150 #define SkSPRITE_SRC_TYPE uint8_t | |
| 151 #define SkSPRITE_DST_GETADDR getAddr16 | |
| 152 #define SkSPRITE_SRC_GETADDR getAddr8 | |
| 153 #define SkSPRITE_PREAMBLE(srcBM, x, y) const SkPMColor* ctable = srcBM.getC
olorTable()->lockColors() | |
| 154 #define SkSPRITE_BLIT_PIXEL(dst, src) D16_S32A_Opaque_Pixel(dst, ctable[sr
c]) | |
| 155 #define SkSPRITE_NEXT_ROW | |
| 156 #define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlockColors(
false) | |
| 157 #include "SkSpriteBlitterTemplate.h" | |
| 158 | |
| 159 #define SkSPRITE_CLASSNAME Sprite_D16_SIndex8A_Blend | |
| 160 #define SkSPRITE_ARGS , uint8_t alpha | |
| 161 #define SkSPRITE_FIELDS uint8_t fSrcAlpha; | |
| 162 #define SkSPRITE_INIT fSrcAlpha = alpha; | |
| 163 #define SkSPRITE_DST_TYPE uint16_t | |
| 164 #define SkSPRITE_SRC_TYPE uint8_t | |
| 165 #define SkSPRITE_DST_GETADDR getAddr16 | |
| 166 #define SkSPRITE_SRC_GETADDR getAddr8 | |
| 167 #define SkSPRITE_PREAMBLE(srcBM, x, y) const SkPMColor* ctable = srcBM.getC
olorTable()->lockColors(); unsigned src_scale = SkAlpha255To256(fSrcAlpha); | |
| 168 #define SkSPRITE_BLIT_PIXEL(dst, src) D16_S32A_Blend_Pixel(dst, ctable[src
], src_scale) | |
| 169 #define SkSPRITE_NEXT_ROW | |
| 170 #define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlockColors(
false); | |
| 171 #include "SkSpriteBlitterTemplate.h" | |
| 172 | |
| 173 /////////////////////////////////////////////////////////////////////////////// | |
| 174 | |
| 175 #define SkSPRITE_CLASSNAME Sprite_D16_SIndex8_Opaque | |
| 176 #define SkSPRITE_ARGS | |
| 177 #define SkSPRITE_FIELDS | |
| 178 #define SkSPRITE_INIT | |
| 179 #define SkSPRITE_DST_TYPE uint16_t | |
| 180 #define SkSPRITE_SRC_TYPE uint8_t | |
| 181 #define SkSPRITE_DST_GETADDR getAddr16 | |
| 182 #define SkSPRITE_SRC_GETADDR getAddr8 | |
| 183 #define SkSPRITE_PREAMBLE(srcBM, x, y) const uint16_t* ctable = srcBM.getCo
lorTable()->lock16BitCache() | |
| 184 #define SkSPRITE_BLIT_PIXEL(dst, src) *dst = ctable[src] | |
| 185 #define SkSPRITE_NEXT_ROW | |
| 186 #define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlock16BitCa
che() | |
| 187 #include "SkSpriteBlitterTemplate.h" | |
| 188 | |
| 189 #define SkSPRITE_CLASSNAME Sprite_D16_SIndex8_Blend | |
| 190 #define SkSPRITE_ARGS , uint8_t alpha | |
| 191 #define SkSPRITE_FIELDS uint8_t fSrcAlpha; | |
| 192 #define SkSPRITE_INIT fSrcAlpha = alpha; | |
| 193 #define SkSPRITE_DST_TYPE uint16_t | |
| 194 #define SkSPRITE_SRC_TYPE uint8_t | |
| 195 #define SkSPRITE_DST_GETADDR getAddr16 | |
| 196 #define SkSPRITE_SRC_GETADDR getAddr8 | |
| 197 #define SkSPRITE_PREAMBLE(srcBM, x, y) const uint16_t* ctable = srcBM.getCo
lorTable()->lock16BitCache(); unsigned src_scale = SkAlpha255To256(fSrcAlpha); | |
| 198 #define SkSPRITE_BLIT_PIXEL(dst, src) D16_S16_Blend_Pixel(dst, ctable[src]
, src_scale) | |
| 199 #define SkSPRITE_NEXT_ROW | |
| 200 #define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlock16BitCa
che(); | |
| 201 #include "SkSpriteBlitterTemplate.h" | |
| 202 | |
| 203 /////////////////////////////////////////////////////////////////////////////// | |
| 204 | |
| 205 class Sprite_D16_S32_BlitRowProc : public SkSpriteBlitter { | |
| 206 public: | |
| 207 Sprite_D16_S32_BlitRowProc(const SkBitmap& source) | |
| 208 : SkSpriteBlitter(source) {} | |
| 209 | |
| 210 // overrides | |
| 211 | |
| 212 virtual void setup(const SkBitmap& device, int left, int top, | |
| 213 const SkPaint& paint) { | |
| 214 this->INHERITED::setup(device, left, top, paint); | |
| 215 | |
| 216 unsigned flags = 0; | |
| 217 | |
| 218 if (paint.getAlpha() < 0xFF) { | |
| 219 flags |= SkBlitRow::kGlobalAlpha_Flag; | |
| 220 } | |
| 221 if (!fSource->isOpaque()) { | |
| 222 flags |= SkBlitRow::kSrcPixelAlpha_Flag; | |
| 223 } | |
| 224 if (paint.isDither()) { | |
| 225 flags |= SkBlitRow::kDither_Flag; | |
| 226 } | |
| 227 fProc = SkBlitRow::Factory(flags, SkBitmap::kRGB_565_Config); | |
| 228 } | |
| 229 | |
| 230 virtual void blitRect(int x, int y, int width, int height) { | |
| 231 SK_RESTRICT uint16_t* dst = fDevice->getAddr16(x, y); | |
| 232 const SK_RESTRICT SkPMColor* src = fSource->getAddr32(x - fLeft, | |
| 233 y - fTop); | |
| 234 unsigned dstRB = fDevice->rowBytes(); | |
| 235 unsigned srcRB = fSource->rowBytes(); | |
| 236 SkBlitRow::Proc proc = fProc; | |
| 237 U8CPU alpha = fPaint->getAlpha(); | |
| 238 | |
| 239 while (--height >= 0) { | |
| 240 proc(dst, src, width, alpha, x, y); | |
| 241 y += 1; | |
| 242 dst = (SK_RESTRICT uint16_t*)((char*)dst + dstRB); | |
| 243 src = (const SK_RESTRICT SkPMColor*)((const char*)src + srcRB); | |
| 244 } | |
| 245 } | |
| 246 | |
| 247 private: | |
| 248 SkBlitRow::Proc fProc; | |
| 249 | |
| 250 typedef SkSpriteBlitter INHERITED; | |
| 251 }; | |
| 252 | |
| 253 /////////////////////////////////////////////////////////////////////////////// | |
| 254 | |
| 255 #include "SkTemplatesPriv.h" | |
| 256 | |
| 257 SkSpriteBlitter* SkSpriteBlitter::ChooseD16(const SkBitmap& source, | |
| 258 const SkPaint& paint, | |
| 259 void* storage, size_t storageSize) { | |
| 260 if (paint.getMaskFilter() != NULL) { // may add cases for this | |
| 261 return NULL; | |
| 262 } | |
| 263 if (paint.getXfermode() != NULL) { // may add cases for this | |
| 264 return NULL; | |
| 265 } | |
| 266 if (paint.getColorFilter() != NULL) { // may add cases for this | |
| 267 return NULL; | |
| 268 } | |
| 269 | |
| 270 SkSpriteBlitter* blitter = NULL; | |
| 271 unsigned alpha = paint.getAlpha(); | |
| 272 | |
| 273 switch (source.getConfig()) { | |
| 274 case SkBitmap::kARGB_8888_Config: | |
| 275 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S32_BlitRowProc, | |
| 276 storage, storageSize, (source)); | |
| 277 break; | |
| 278 case SkBitmap::kARGB_4444_Config: | |
| 279 if (255 == alpha) { | |
| 280 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S4444_Opaque, | |
| 281 storage, storageSize, (source)); | |
| 282 } else { | |
| 283 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S4444_Blend, | |
| 284 storage, storageSize, (source, alpha >> 4)); | |
| 285 } | |
| 286 break; | |
| 287 case SkBitmap::kRGB_565_Config: | |
| 288 if (255 == alpha) { | |
| 289 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S16_Opaque, | |
| 290 storage, storageSize, (source)); | |
| 291 } else { | |
| 292 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S16_Blend, | |
| 293 storage, storageSize, (source, alpha)); | |
| 294 } | |
| 295 break; | |
| 296 case SkBitmap::kIndex8_Config: | |
| 297 if (source.isOpaque()) { | |
| 298 if (255 == alpha) { | |
| 299 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Opaque, | |
| 300 storage, storageSize, (source)); | |
| 301 } else { | |
| 302 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Blend, | |
| 303 storage, storageSize, (source, alpha)); | |
| 304 } | |
| 305 } else { | |
| 306 if (255 == alpha) { | |
| 307 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8A_Opaque, | |
| 308 storage, storageSize, (source)); | |
| 309 } else { | |
| 310 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8A_Blend, | |
| 311 storage, storageSize, (source, alpha)); | |
| 312 } | |
| 313 } | |
| 314 break; | |
| 315 default: | |
| 316 break; | |
| 317 } | |
| 318 return blitter; | |
| 319 } | |
| 320 | |
| OLD | NEW |