| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkMipMap.h" | 8 #include "SkMipMap.h" |
| 9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 } | 102 } |
| 103 c += expand4444(*p); | 103 c += expand4444(*p); |
| 104 if (x < src.width() - 1) { | 104 if (x < src.width() - 1) { |
| 105 p += 1; | 105 p += 1; |
| 106 } | 106 } |
| 107 c += expand4444(*p); | 107 c += expand4444(*p); |
| 108 | 108 |
| 109 *dst->getAddr16(x >> 1, y >> 1) = (uint16_t)collaps4444(c >> 2); | 109 *dst->getAddr16(x >> 1, y >> 1) = (uint16_t)collaps4444(c >> 2); |
| 110 } | 110 } |
| 111 | 111 |
| 112 SkMipMap::Level* SkMipMap::AllocLevels(int levelCount, size_t pixelSize) { | 112 size_t SkMipMap::AllocLevelsSize(int levelCount, size_t pixelSize) { |
| 113 if (levelCount < 0) { | 113 if (levelCount < 0) { |
| 114 return NULL; | 114 return 0; |
| 115 } | 115 } |
| 116 int64_t size = sk_64_mul(levelCount + 1, sizeof(Level)) + pixelSize; | 116 int64_t size = sk_64_mul(levelCount + 1, sizeof(Level)) + pixelSize; |
| 117 if (!sk_64_isS32(size)) { | 117 if (!sk_64_isS32(size)) { |
| 118 return NULL; | 118 return 0; |
| 119 } | 119 } |
| 120 return (Level*)sk_malloc_throw(sk_64_asS32(size)); | 120 return sk_64_asS32(size); |
| 121 } | 121 } |
| 122 | 122 |
| 123 SkMipMap* SkMipMap::Build(const SkBitmap& src) { | 123 SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { |
| 124 void (*proc)(SkBitmap* dst, int x, int y, const SkBitmap& src); | 124 void (*proc)(SkBitmap* dst, int x, int y, const SkBitmap& src); |
| 125 | 125 |
| 126 const SkColorType ct = src.colorType(); | 126 const SkColorType ct = src.colorType(); |
| 127 const SkAlphaType at = src.alphaType(); | 127 const SkAlphaType at = src.alphaType(); |
| 128 switch (ct) { | 128 switch (ct) { |
| 129 case kRGBA_8888_SkColorType: | 129 case kRGBA_8888_SkColorType: |
| 130 case kBGRA_8888_SkColorType: | 130 case kBGRA_8888_SkColorType: |
| 131 proc = downsampleby2_proc32; | 131 proc = downsampleby2_proc32; |
| 132 break; | 132 break; |
| 133 case kRGB_565_SkColorType: | 133 case kRGB_565_SkColorType: |
| (...skipping 24 matching lines...) Expand all Loading... |
| 158 break; | 158 break; |
| 159 } | 159 } |
| 160 size += SkColorTypeMinRowBytes(ct, width) * height; | 160 size += SkColorTypeMinRowBytes(ct, width) * height; |
| 161 countLevels += 1; | 161 countLevels += 1; |
| 162 } | 162 } |
| 163 } | 163 } |
| 164 if (0 == countLevels) { | 164 if (0 == countLevels) { |
| 165 return NULL; | 165 return NULL; |
| 166 } | 166 } |
| 167 | 167 |
| 168 Level* levels = SkMipMap::AllocLevels(countLevels, size); | 168 size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size); |
| 169 if (NULL == levels) { | 169 if (0 == storageSize) { |
| 170 return NULL; | 170 return NULL; |
| 171 } | 171 } |
| 172 | 172 |
| 173 SkMipMap* mipmap; |
| 174 if (fact) { |
| 175 SkDiscardableMemory* dm = fact(storageSize); |
| 176 if (NULL == dm) { |
| 177 return NULL; |
| 178 } |
| 179 mipmap = SkNEW_ARGS(SkMipMap, (storageSize, dm)); |
| 180 } else { |
| 181 mipmap = SkNEW_ARGS(SkMipMap, (sk_malloc_throw(storageSize), storageSize
)); |
| 182 } |
| 183 |
| 184 // init |
| 185 mipmap->fCount = countLevels; |
| 186 mipmap->fLevels = (Level*)mipmap->writable_data(); |
| 187 |
| 188 Level* levels = mipmap->fLevels; |
| 173 uint8_t* baseAddr = (uint8_t*)&levels[countLevels]; | 189 uint8_t* baseAddr = (uint8_t*)&levels[countLevels]; |
| 174 uint8_t* addr = baseAddr; | 190 uint8_t* addr = baseAddr; |
| 175 int width = src.width(); | 191 int width = src.width(); |
| 176 int height = src.height(); | 192 int height = src.height(); |
| 177 uint32_t rowBytes; | 193 uint32_t rowBytes; |
| 178 SkBitmap srcBM(src); | 194 SkBitmap srcBM(src); |
| 179 | 195 |
| 180 for (int i = 0; i < countLevels; ++i) { | 196 for (int i = 0; i < countLevels; ++i) { |
| 181 width >>= 1; | 197 width >>= 1; |
| 182 height >>= 1; | 198 height >>= 1; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 197 proc(&dstBM, x, y, srcBM); | 213 proc(&dstBM, x, y, srcBM); |
| 198 } | 214 } |
| 199 } | 215 } |
| 200 srcBM.unlockPixels(); | 216 srcBM.unlockPixels(); |
| 201 | 217 |
| 202 srcBM = dstBM; | 218 srcBM = dstBM; |
| 203 addr += height * rowBytes; | 219 addr += height * rowBytes; |
| 204 } | 220 } |
| 205 SkASSERT(addr == baseAddr + size); | 221 SkASSERT(addr == baseAddr + size); |
| 206 | 222 |
| 207 return SkNEW_ARGS(SkMipMap, (levels, countLevels, size)); | 223 return mipmap; |
| 208 } | 224 } |
| 209 | 225 |
| 210 /////////////////////////////////////////////////////////////////////////////// | 226 /////////////////////////////////////////////////////////////////////////////// |
| 211 | 227 |
| 212 //static int gCounter; | 228 //static int gCounter; |
| 213 | 229 |
| 214 SkMipMap::SkMipMap(Level* levels, int count, size_t size) | |
| 215 : fSize(size), fLevels(levels), fCount(count) { | |
| 216 SkASSERT(levels); | |
| 217 SkASSERT(count > 0); | |
| 218 // SkDebugf("mips %d\n", ++gCounter); | |
| 219 } | |
| 220 | |
| 221 SkMipMap::~SkMipMap() { | |
| 222 sk_free(fLevels); | |
| 223 // SkDebugf("mips %d\n", --gCounter); | |
| 224 } | |
| 225 | |
| 226 static SkFixed compute_level(SkScalar scale) { | 230 static SkFixed compute_level(SkScalar scale) { |
| 227 SkFixed s = SkAbs32(SkScalarToFixed(SkScalarInvert(scale))); | 231 SkFixed s = SkAbs32(SkScalarToFixed(SkScalarInvert(scale))); |
| 228 | 232 |
| 229 if (s < SK_Fixed1) { | 233 if (s < SK_Fixed1) { |
| 230 return 0; | 234 return 0; |
| 231 } | 235 } |
| 232 int clz = SkCLZ(s); | 236 int clz = SkCLZ(s); |
| 233 SkASSERT(clz >= 1 && clz <= 15); | 237 SkASSERT(clz >= 1 && clz <= 15); |
| 234 return SkIntToFixed(15 - clz) + ((unsigned)(s << (clz + 1)) >> 16); | 238 return SkIntToFixed(15 - clz) + ((unsigned)(s << (clz + 1)) >> 16); |
| 235 } | 239 } |
| 236 | 240 |
| 237 bool SkMipMap::extractLevel(SkScalar scale, Level* levelPtr) const { | 241 bool SkMipMap::extractLevel(SkScalar scale, Level* levelPtr) const { |
| 242 if (NULL == fLevels) { |
| 243 return false; |
| 244 } |
| 245 |
| 238 if (scale >= SK_Scalar1) { | 246 if (scale >= SK_Scalar1) { |
| 239 return false; | 247 return false; |
| 240 } | 248 } |
| 241 | 249 |
| 242 int level = compute_level(scale) >> 16; | 250 int level = compute_level(scale) >> 16; |
| 243 SkASSERT(level >= 0); | 251 SkASSERT(level >= 0); |
| 244 if (level <= 0) { | 252 if (level <= 0) { |
| 245 return false; | 253 return false; |
| 246 } | 254 } |
| 247 | 255 |
| 248 if (level > fCount) { | 256 if (level > fCount) { |
| 249 level = fCount; | 257 level = fCount; |
| 250 } | 258 } |
| 251 if (levelPtr) { | 259 if (levelPtr) { |
| 252 *levelPtr = fLevels[level - 1]; | 260 *levelPtr = fLevels[level - 1]; |
| 253 } | 261 } |
| 254 return true; | 262 return true; |
| 255 } | 263 } |
| OLD | NEW |