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 size_t SkMipMap::AllocLevelsSize(int levelCount, size_t pixelSize) { | 112 SkMipMap::Level* SkMipMap::AllocLevels(int levelCount, size_t pixelSize) { |
113 if (levelCount < 0) { | 113 if (levelCount < 0) { |
114 return 0; | 114 return NULL; |
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 0; | 118 return NULL; |
119 } | 119 } |
120 return sk_64_asS32(size); | 120 return (Level*)sk_malloc_throw(sk_64_asS32(size)); |
121 } | 121 } |
122 | 122 |
123 SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { | 123 SkMipMap* SkMipMap::Build(const SkBitmap& src) { |
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 size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size); | 168 Level* levels = SkMipMap::AllocLevels(countLevels, size); |
169 if (0 == storageSize) { | 169 if (NULL == levels) { |
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; | |
189 uint8_t* baseAddr = (uint8_t*)&levels[countLevels]; | 173 uint8_t* baseAddr = (uint8_t*)&levels[countLevels]; |
190 uint8_t* addr = baseAddr; | 174 uint8_t* addr = baseAddr; |
191 int width = src.width(); | 175 int width = src.width(); |
192 int height = src.height(); | 176 int height = src.height(); |
193 uint32_t rowBytes; | 177 uint32_t rowBytes; |
194 SkBitmap srcBM(src); | 178 SkBitmap srcBM(src); |
195 | 179 |
196 for (int i = 0; i < countLevels; ++i) { | 180 for (int i = 0; i < countLevels; ++i) { |
197 width >>= 1; | 181 width >>= 1; |
198 height >>= 1; | 182 height >>= 1; |
(...skipping 14 matching lines...) Expand all Loading... |
213 proc(&dstBM, x, y, srcBM); | 197 proc(&dstBM, x, y, srcBM); |
214 } | 198 } |
215 } | 199 } |
216 srcBM.unlockPixels(); | 200 srcBM.unlockPixels(); |
217 | 201 |
218 srcBM = dstBM; | 202 srcBM = dstBM; |
219 addr += height * rowBytes; | 203 addr += height * rowBytes; |
220 } | 204 } |
221 SkASSERT(addr == baseAddr + size); | 205 SkASSERT(addr == baseAddr + size); |
222 | 206 |
223 return mipmap; | 207 return SkNEW_ARGS(SkMipMap, (levels, countLevels, size)); |
224 } | 208 } |
225 | 209 |
226 /////////////////////////////////////////////////////////////////////////////// | 210 /////////////////////////////////////////////////////////////////////////////// |
227 | 211 |
228 //static int gCounter; | 212 //static int gCounter; |
229 | 213 |
| 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 |
230 static SkFixed compute_level(SkScalar scale) { | 226 static SkFixed compute_level(SkScalar scale) { |
231 SkFixed s = SkAbs32(SkScalarToFixed(SkScalarInvert(scale))); | 227 SkFixed s = SkAbs32(SkScalarToFixed(SkScalarInvert(scale))); |
232 | 228 |
233 if (s < SK_Fixed1) { | 229 if (s < SK_Fixed1) { |
234 return 0; | 230 return 0; |
235 } | 231 } |
236 int clz = SkCLZ(s); | 232 int clz = SkCLZ(s); |
237 SkASSERT(clz >= 1 && clz <= 15); | 233 SkASSERT(clz >= 1 && clz <= 15); |
238 return SkIntToFixed(15 - clz) + ((unsigned)(s << (clz + 1)) >> 16); | 234 return SkIntToFixed(15 - clz) + ((unsigned)(s << (clz + 1)) >> 16); |
239 } | 235 } |
240 | 236 |
241 bool SkMipMap::extractLevel(SkScalar scale, Level* levelPtr) const { | 237 bool SkMipMap::extractLevel(SkScalar scale, Level* levelPtr) const { |
242 if (NULL == fLevels) { | |
243 return false; | |
244 } | |
245 | |
246 if (scale >= SK_Scalar1) { | 238 if (scale >= SK_Scalar1) { |
247 return false; | 239 return false; |
248 } | 240 } |
249 | 241 |
250 int level = compute_level(scale) >> 16; | 242 int level = compute_level(scale) >> 16; |
251 SkASSERT(level >= 0); | 243 SkASSERT(level >= 0); |
252 if (level <= 0) { | 244 if (level <= 0) { |
253 return false; | 245 return false; |
254 } | 246 } |
255 | 247 |
256 if (level > fCount) { | 248 if (level > fCount) { |
257 level = fCount; | 249 level = fCount; |
258 } | 250 } |
259 if (levelPtr) { | 251 if (levelPtr) { |
260 *levelPtr = fLevels[level - 1]; | 252 *levelPtr = fLevels[level - 1]; |
261 } | 253 } |
262 return true; | 254 return true; |
263 } | 255 } |
OLD | NEW |