Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: src/core/SkMipMap.cpp

Issue 1599133002: remove SK_SUPPORT_LEGACY_MIPLEVEL_BUILDER code (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 11
12 #ifdef SK_SUPPORT_LEGACY_MIPLEVEL_BUILDER
13
14 static void downsample32_nocheck(void* dst, int, int, const void* srcPtr, const SkPixmap& srcPM) {
15 const uint32_t* p = static_cast<const uint32_t*>(srcPtr);
16 const uint32_t* baseP = p;
17 uint32_t c, ag, rb;
18
19 c = *p; ag = (c >> 8) & 0xFF00FF; rb = c & 0xFF00FF;
20 p += 1;
21
22 c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
23
24 p = baseP;
25 p += srcPM.rowBytes() >> 2;
26
27 c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
28 p += 1;
29
30 c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
31
32 *(uint32_t*)dst = ((rb >> 2) & 0xFF00FF) | ((ag << 6) & 0xFF00FF00);
33 }
34
35 static void downsample32_check(void* dst, int x, int y, const void* srcPtr, cons t SkPixmap& srcPM) {
36 const uint32_t* p = static_cast<const uint32_t*>(srcPtr);
37 const uint32_t* baseP = p;
38
39 x <<= 1;
40 y <<= 1;
41 SkASSERT(srcPM.addr32(x, y) == p);
42
43 SkPMColor c, ag, rb;
44
45 c = *p; ag = (c >> 8) & 0xFF00FF; rb = c & 0xFF00FF;
46 if (x < srcPM.width() - 1) {
47 p += 1;
48 }
49 c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
50
51 p = baseP;
52 if (y < srcPM.height() - 1) {
53 p += srcPM.rowBytes() >> 2;
54 }
55 c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
56 if (x < srcPM.width() - 1) {
57 p += 1;
58 }
59 c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
60
61 *((uint32_t*)dst) = ((rb >> 2) & 0xFF00FF) | ((ag << 6) & 0xFF00FF00);
62 }
63
64 static inline uint32_t expand16(U16CPU c) {
65 return (c & ~SK_G16_MASK_IN_PLACE) | ((c & SK_G16_MASK_IN_PLACE) << 16);
66 }
67
68 // returns dirt in the top 16bits, but we don't care, since we only
69 // store the low 16bits.
70 static inline U16CPU pack16(uint32_t c) {
71 return (c & ~SK_G16_MASK_IN_PLACE) | ((c >> 16) & SK_G16_MASK_IN_PLACE);
72 }
73
74 static void downsample16(void* dst, int x, int y, const void* srcPtr, const SkPi xmap& srcPM) {
75 const uint16_t* p = static_cast<const uint16_t*>(srcPtr);
76 const uint16_t* baseP = p;
77
78 x <<= 1;
79 y <<= 1;
80 SkASSERT(srcPM.addr16(x, y) == p);
81
82 SkPMColor c;
83
84 c = expand16(*p);
85 if (x < srcPM.width() - 1) {
86 p += 1;
87 }
88 c += expand16(*p);
89
90 p = baseP;
91 if (y < srcPM.height() - 1) {
92 p += srcPM.rowBytes() >> 1;
93 }
94 c += expand16(*p);
95 if (x < srcPM.width() - 1) {
96 p += 1;
97 }
98 c += expand16(*p);
99
100 *((uint16_t*)dst) = (uint16_t)pack16(c >> 2);
101 }
102
103 static uint32_t expand4444(U16CPU c) {
104 return (c & 0xF0F) | ((c & ~0xF0F) << 12);
105 }
106
107 static U16CPU collaps4444(uint32_t c) {
108 return (c & 0xF0F) | ((c >> 12) & ~0xF0F);
109 }
110
111 static void downsample4444(void* dst, int x, int y, const void* srcPtr, const Sk Pixmap& srcPM) {
112 const uint16_t* p = static_cast<const uint16_t*>(srcPtr);
113 const uint16_t* baseP = p;
114
115 x <<= 1;
116 y <<= 1;
117 SkASSERT(srcPM.addr16(x, y) == p);
118
119 uint32_t c;
120
121 c = expand4444(*p);
122 if (x < srcPM.width() - 1) {
123 p += 1;
124 }
125 c += expand4444(*p);
126
127 p = baseP;
128 if (y < srcPM.height() - 1) {
129 p += srcPM.rowBytes() >> 1;
130 }
131 c += expand4444(*p);
132 if (x < srcPM.width() - 1) {
133 p += 1;
134 }
135 c += expand4444(*p);
136
137 *((uint16_t*)dst) = (uint16_t)collaps4444(c >> 2);
138 }
139
140 static void downsample8_nocheck(void* dst, int, int, const void* srcPtr, const S kPixmap& srcPM) {
141 const size_t rb = srcPM.rowBytes();
142 const uint8_t* p = static_cast<const uint8_t*>(srcPtr);
143 *(uint8_t*)dst = (p[0] + p[1] + p[rb] + p[rb + 1]) >> 2;
144 }
145
146 static void downsample8_check(void* dst, int x, int y, const void* srcPtr, const SkPixmap& srcPM) {
147 const uint8_t* p = static_cast<const uint8_t*>(srcPtr);
148 const uint8_t* baseP = p;
149
150 x <<= 1;
151 y <<= 1;
152 SkASSERT(srcPM.addr8(x, y) == p);
153
154 unsigned c = *p;
155 if (x < srcPM.width() - 1) {
156 p += 1;
157 }
158 c += *p;
159
160 p = baseP;
161 if (y < srcPM.height() - 1) {
162 p += srcPM.rowBytes();
163 }
164 c += *p;
165 if (x < srcPM.width() - 1) {
166 p += 1;
167 }
168 c += *p;
169
170 *(uint8_t*)dst = c >> 2;
171 }
172
173 size_t SkMipMap::AllocLevelsSize(int levelCount, size_t pixelSize) {
174 if (levelCount < 0) {
175 return 0;
176 }
177 int64_t size = sk_64_mul(levelCount + 1, sizeof(Level)) + pixelSize;
178 if (!sk_64_isS32(size)) {
179 return 0;
180 }
181 return sk_64_asS32(size);
182 }
183
184 typedef void SkDownSampleProc(void*, int x, int y, const void* srcPtr, const SkP ixmap& srcPM);
185
186 SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) {
187 SkDownSampleProc* proc_nocheck, *proc_check;
188
189 const SkColorType ct = src.colorType();
190 const SkAlphaType at = src.alphaType();
191 switch (ct) {
192 case kRGBA_8888_SkColorType:
193 case kBGRA_8888_SkColorType:
194 proc_check = downsample32_check;
195 proc_nocheck = downsample32_nocheck;
196 break;
197 case kRGB_565_SkColorType:
198 proc_check = downsample16;
199 proc_nocheck = proc_check;
200 break;
201 case kARGB_4444_SkColorType:
202 proc_check = downsample4444;
203 proc_nocheck = proc_check;
204 break;
205 case kAlpha_8_SkColorType:
206 case kGray_8_SkColorType:
207 proc_check = downsample8_check;
208 proc_nocheck = downsample8_nocheck;
209 break;
210 default:
211 return nullptr; // don't build mipmaps for any other colortypes (yet )
212 }
213
214 // whip through our loop to compute the exact size needed
215 size_t size = 0;
216 int countLevels = 0;
217 {
218 int width = src.width();
219 int height = src.height();
220 for (;;) {
221 width >>= 1;
222 height >>= 1;
223 if (0 == width || 0 == height) {
224 break;
225 }
226 size += SkColorTypeMinRowBytes(ct, width) * height;
227 countLevels += 1;
228 }
229 }
230 if (0 == countLevels) {
231 return nullptr;
232 }
233
234 size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size);
235 if (0 == storageSize) {
236 return nullptr;
237 }
238
239 SkMipMap* mipmap;
240 if (fact) {
241 SkDiscardableMemory* dm = fact(storageSize);
242 if (nullptr == dm) {
243 return nullptr;
244 }
245 mipmap = new SkMipMap(storageSize, dm);
246 } else {
247 mipmap = new SkMipMap(sk_malloc_throw(storageSize), storageSize);
248 }
249
250 // init
251 mipmap->fCount = countLevels;
252 mipmap->fLevels = (Level*)mipmap->writable_data();
253
254 Level* levels = mipmap->fLevels;
255 uint8_t* baseAddr = (uint8_t*)&levels[countLevels];
256 uint8_t* addr = baseAddr;
257 int width = src.width();
258 int height = src.height();
259 uint32_t rowBytes;
260 SkPixmap srcPM(src);
261
262 for (int i = 0; i < countLevels; ++i) {
263 width >>= 1;
264 height >>= 1;
265 rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width));
266
267 levels[i].fPixmap = SkPixmap(SkImageInfo::Make(width, height, ct, at), a ddr, rowBytes);
268 levels[i].fScale = (float)width / src.width();
269
270 SkPixmap dstPM(SkImageInfo::Make(width, height, ct, at), addr, rowBytes) ;
271
272 const int widthEven = width & ~1;
273 const int heightEven = height & ~1;
274 const size_t pixelSize = srcPM.info().bytesPerPixel();
275
276 const void* srcBasePtr = srcPM.addr();
277 void* dstBasePtr = dstPM.writable_addr();
278 for (int y = 0; y < heightEven; y++) {
279 const void* srcPtr = srcBasePtr;
280 void* dstPtr = dstBasePtr;
281 for (int x = 0; x < widthEven; x++) {
282 proc_nocheck(dstPtr, x, y, srcPtr, srcPM);
283 srcPtr = (char*)srcPtr + pixelSize * 2;
284 dstPtr = (char*)dstPtr + pixelSize;
285 }
286 if (width & 1) {
287 proc_check(dstPtr, widthEven, y, srcPtr, srcPM);
288 }
289
290 srcBasePtr = (char*)srcBasePtr + srcPM.rowBytes() * 2;
291 dstBasePtr = (char*)dstBasePtr + dstPM.rowBytes();
292 }
293 if (height & 1) {
294 const void* srcPtr = srcBasePtr;
295 void* dstPtr = dstBasePtr;
296 for (int x = 0; x < width; x++) {
297 proc_check(dstPtr, x, heightEven, srcPtr, srcPM);
298 srcPtr = (char*)srcPtr + pixelSize * 2;
299 dstPtr = (char*)dstPtr + pixelSize;
300 }
301 }
302 srcPM = dstPM;
303 addr += height * rowBytes;
304 }
305 SkASSERT(addr == baseAddr + size);
306
307 return mipmap;
308 }
309
310 #else // new technique that handles odd dimensions better
311
312 // 12 //
313 // ColorTypeFilter is the "Type" we pass to some downsample template functions. 13 // ColorTypeFilter is the "Type" we pass to some downsample template functions.
314 // It controls how we expand a pixel into a large type, with space between each component, 14 // It controls how we expand a pixel into a large type, with space between each component,
315 // so we can then perform our simple filter (either box or triangle) and store t he intermediates 15 // so we can then perform our simple filter (either box or triangle) and store t he intermediates
316 // in the expanded type. 16 // in the expanded type.
317 // 17 //
318 18
319 struct ColorTypeFilter_8888 { 19 struct ColorTypeFilter_8888 {
320 typedef uint32_t Type; 20 typedef uint32_t Type;
321 static uint64_t Expand(uint32_t x) { 21 static uint64_t Expand(uint32_t x) {
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 srcBasePtr = (char*)srcBasePtr + srcRB * 2; // jump two rows 297 srcBasePtr = (char*)srcBasePtr + srcRB * 2; // jump two rows
598 dstBasePtr = (char*)dstBasePtr + dstPM.rowBytes(); 298 dstBasePtr = (char*)dstBasePtr + dstPM.rowBytes();
599 } 299 }
600 srcPM = dstPM; 300 srcPM = dstPM;
601 addr += height * rowBytes; 301 addr += height * rowBytes;
602 } 302 }
603 SkASSERT(addr == baseAddr + size); 303 SkASSERT(addr == baseAddr + size);
604 304
605 return mipmap; 305 return mipmap;
606 } 306 }
607 #endif
608 307
609 /////////////////////////////////////////////////////////////////////////////// 308 ///////////////////////////////////////////////////////////////////////////////
610 309
611 bool SkMipMap::extractLevel(SkScalar scale, Level* levelPtr) const { 310 bool SkMipMap::extractLevel(SkScalar scale, Level* levelPtr) const {
612 if (nullptr == fLevels) { 311 if (nullptr == fLevels) {
613 return false; 312 return false;
614 } 313 }
615 314
616 if (scale >= SK_Scalar1 || scale <= 0 || !SkScalarIsFinite(scale)) { 315 if (scale >= SK_Scalar1 || scale <= 0 || !SkScalarIsFinite(scale)) {
617 return false; 316 return false;
(...skipping 30 matching lines...) Expand all
648 return nullptr; 347 return nullptr;
649 } 348 }
650 const SkPixmap& srcPixmap = srcUnlocker.pixmap(); 349 const SkPixmap& srcPixmap = srcUnlocker.pixmap();
651 // Try to catch where we might have returned nullptr for src crbug.com/49281 8 350 // Try to catch where we might have returned nullptr for src crbug.com/49281 8
652 if (nullptr == srcPixmap.addr()) { 351 if (nullptr == srcPixmap.addr()) {
653 sk_throw(); 352 sk_throw();
654 } 353 }
655 return Build(srcPixmap, fact); 354 return Build(srcPixmap, fact);
656 } 355 }
657 356
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698