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 |