SkMipMap.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. /*
  2. * Copyright 2013 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/core/SkMipMap.h"
  8. #include "include/core/SkBitmap.h"
  9. #include "include/core/SkTypes.h"
  10. #include "include/private/SkColorData.h"
  11. #include "include/private/SkHalf.h"
  12. #include "include/private/SkImageInfoPriv.h"
  13. #include "include/private/SkNx.h"
  14. #include "include/private/SkTo.h"
  15. #include "src/core/SkMathPriv.h"
  16. #include <new>
  17. //
  18. // ColorTypeFilter is the "Type" we pass to some downsample template functions.
  19. // It controls how we expand a pixel into a large type, with space between each component,
  20. // so we can then perform our simple filter (either box or triangle) and store the intermediates
  21. // in the expanded type.
  22. //
  23. struct ColorTypeFilter_8888 {
  24. typedef uint32_t Type;
  25. static Sk4h Expand(uint32_t x) {
  26. return SkNx_cast<uint16_t>(Sk4b::Load(&x));
  27. }
  28. static uint32_t Compact(const Sk4h& x) {
  29. uint32_t r;
  30. SkNx_cast<uint8_t>(x).store(&r);
  31. return r;
  32. }
  33. };
  34. struct ColorTypeFilter_565 {
  35. typedef uint16_t Type;
  36. static uint32_t Expand(uint16_t x) {
  37. return (x & ~SK_G16_MASK_IN_PLACE) | ((x & SK_G16_MASK_IN_PLACE) << 16);
  38. }
  39. static uint16_t Compact(uint32_t x) {
  40. return ((x & ~SK_G16_MASK_IN_PLACE) & 0xFFFF) | ((x >> 16) & SK_G16_MASK_IN_PLACE);
  41. }
  42. };
  43. struct ColorTypeFilter_4444 {
  44. typedef uint16_t Type;
  45. static uint32_t Expand(uint16_t x) {
  46. return (x & 0xF0F) | ((x & ~0xF0F) << 12);
  47. }
  48. static uint16_t Compact(uint32_t x) {
  49. return (x & 0xF0F) | ((x >> 12) & ~0xF0F);
  50. }
  51. };
  52. struct ColorTypeFilter_8 {
  53. typedef uint8_t Type;
  54. static unsigned Expand(unsigned x) {
  55. return x;
  56. }
  57. static uint8_t Compact(unsigned x) {
  58. return (uint8_t)x;
  59. }
  60. };
  61. struct ColorTypeFilter_F16 {
  62. typedef uint64_t Type; // SkHalf x4
  63. static Sk4f Expand(uint64_t x) {
  64. return SkHalfToFloat_finite_ftz(x);
  65. }
  66. static uint64_t Compact(const Sk4f& x) {
  67. uint64_t r;
  68. SkFloatToHalf_finite_ftz(x).store(&r);
  69. return r;
  70. }
  71. };
  72. template <typename T> T add_121(const T& a, const T& b, const T& c) {
  73. return a + b + b + c;
  74. }
  75. template <typename T> T shift_right(const T& x, int bits) {
  76. return x >> bits;
  77. }
  78. Sk4f shift_right(const Sk4f& x, int bits) {
  79. return x * (1.0f / (1 << bits));
  80. }
  81. template <typename T> T shift_left(const T& x, int bits) {
  82. return x << bits;
  83. }
  84. Sk4f shift_left(const Sk4f& x, int bits) {
  85. return x * (1 << bits);
  86. }
  87. //
  88. // To produce each mip level, we need to filter down by 1/2 (e.g. 100x100 -> 50,50)
  89. // If the starting dimension is odd, we floor the size of the lower level (e.g. 101 -> 50)
  90. // In those (odd) cases, we use a triangle filter, with 1-pixel overlap between samplings,
  91. // else for even cases, we just use a 2x box filter.
  92. //
  93. // This produces 4 possible isotropic filters: 2x2 2x3 3x2 3x3 where WxH indicates the number of
  94. // src pixels we need to sample in each dimension to produce 1 dst pixel.
  95. //
  96. // OpenGL expects a full mipmap stack to contain anisotropic space as well.
  97. // This means a 100x1 image would continue down to a 50x1 image, 25x1 image...
  98. // Because of this, we need 4 more anisotropic filters: 1x2, 1x3, 2x1, 3x1.
  99. template <typename F> void downsample_1_2(void* dst, const void* src, size_t srcRB, int count) {
  100. SkASSERT(count > 0);
  101. auto p0 = static_cast<const typename F::Type*>(src);
  102. auto p1 = (const typename F::Type*)((const char*)p0 + srcRB);
  103. auto d = static_cast<typename F::Type*>(dst);
  104. for (int i = 0; i < count; ++i) {
  105. auto c00 = F::Expand(p0[0]);
  106. auto c10 = F::Expand(p1[0]);
  107. auto c = c00 + c10;
  108. d[i] = F::Compact(shift_right(c, 1));
  109. p0 += 2;
  110. p1 += 2;
  111. }
  112. }
  113. template <typename F> void downsample_1_3(void* dst, const void* src, size_t srcRB, int count) {
  114. SkASSERT(count > 0);
  115. auto p0 = static_cast<const typename F::Type*>(src);
  116. auto p1 = (const typename F::Type*)((const char*)p0 + srcRB);
  117. auto p2 = (const typename F::Type*)((const char*)p1 + srcRB);
  118. auto d = static_cast<typename F::Type*>(dst);
  119. for (int i = 0; i < count; ++i) {
  120. auto c00 = F::Expand(p0[0]);
  121. auto c10 = F::Expand(p1[0]);
  122. auto c20 = F::Expand(p2[0]);
  123. auto c = add_121(c00, c10, c20);
  124. d[i] = F::Compact(shift_right(c, 2));
  125. p0 += 2;
  126. p1 += 2;
  127. p2 += 2;
  128. }
  129. }
  130. template <typename F> void downsample_2_1(void* dst, const void* src, size_t srcRB, int count) {
  131. SkASSERT(count > 0);
  132. auto p0 = static_cast<const typename F::Type*>(src);
  133. auto d = static_cast<typename F::Type*>(dst);
  134. for (int i = 0; i < count; ++i) {
  135. auto c00 = F::Expand(p0[0]);
  136. auto c01 = F::Expand(p0[1]);
  137. auto c = c00 + c01;
  138. d[i] = F::Compact(shift_right(c, 1));
  139. p0 += 2;
  140. }
  141. }
  142. template <typename F> void downsample_2_2(void* dst, const void* src, size_t srcRB, int count) {
  143. SkASSERT(count > 0);
  144. auto p0 = static_cast<const typename F::Type*>(src);
  145. auto p1 = (const typename F::Type*)((const char*)p0 + srcRB);
  146. auto d = static_cast<typename F::Type*>(dst);
  147. for (int i = 0; i < count; ++i) {
  148. auto c00 = F::Expand(p0[0]);
  149. auto c01 = F::Expand(p0[1]);
  150. auto c10 = F::Expand(p1[0]);
  151. auto c11 = F::Expand(p1[1]);
  152. auto c = c00 + c10 + c01 + c11;
  153. d[i] = F::Compact(shift_right(c, 2));
  154. p0 += 2;
  155. p1 += 2;
  156. }
  157. }
  158. template <typename F> void downsample_2_3(void* dst, const void* src, size_t srcRB, int count) {
  159. SkASSERT(count > 0);
  160. auto p0 = static_cast<const typename F::Type*>(src);
  161. auto p1 = (const typename F::Type*)((const char*)p0 + srcRB);
  162. auto p2 = (const typename F::Type*)((const char*)p1 + srcRB);
  163. auto d = static_cast<typename F::Type*>(dst);
  164. for (int i = 0; i < count; ++i) {
  165. auto c00 = F::Expand(p0[0]);
  166. auto c01 = F::Expand(p0[1]);
  167. auto c10 = F::Expand(p1[0]);
  168. auto c11 = F::Expand(p1[1]);
  169. auto c20 = F::Expand(p2[0]);
  170. auto c21 = F::Expand(p2[1]);
  171. auto c = add_121(c00, c10, c20) + add_121(c01, c11, c21);
  172. d[i] = F::Compact(shift_right(c, 3));
  173. p0 += 2;
  174. p1 += 2;
  175. p2 += 2;
  176. }
  177. }
  178. template <typename F> void downsample_3_1(void* dst, const void* src, size_t srcRB, int count) {
  179. SkASSERT(count > 0);
  180. auto p0 = static_cast<const typename F::Type*>(src);
  181. auto d = static_cast<typename F::Type*>(dst);
  182. auto c02 = F::Expand(p0[0]);
  183. for (int i = 0; i < count; ++i) {
  184. auto c00 = c02;
  185. auto c01 = F::Expand(p0[1]);
  186. c02 = F::Expand(p0[2]);
  187. auto c = add_121(c00, c01, c02);
  188. d[i] = F::Compact(shift_right(c, 2));
  189. p0 += 2;
  190. }
  191. }
  192. template <typename F> void downsample_3_2(void* dst, const void* src, size_t srcRB, int count) {
  193. SkASSERT(count > 0);
  194. auto p0 = static_cast<const typename F::Type*>(src);
  195. auto p1 = (const typename F::Type*)((const char*)p0 + srcRB);
  196. auto d = static_cast<typename F::Type*>(dst);
  197. // Given pixels:
  198. // a0 b0 c0 d0 e0 ...
  199. // a1 b1 c1 d1 e1 ...
  200. // We want:
  201. // (a0 + 2*b0 + c0 + a1 + 2*b1 + c1) / 8
  202. // (c0 + 2*d0 + e0 + c1 + 2*d1 + e1) / 8
  203. // ...
  204. auto c0 = F::Expand(p0[0]);
  205. auto c1 = F::Expand(p1[0]);
  206. auto c = c0 + c1;
  207. for (int i = 0; i < count; ++i) {
  208. auto a = c;
  209. auto b0 = F::Expand(p0[1]);
  210. auto b1 = F::Expand(p1[1]);
  211. auto b = b0 + b0 + b1 + b1;
  212. c0 = F::Expand(p0[2]);
  213. c1 = F::Expand(p1[2]);
  214. c = c0 + c1;
  215. auto sum = a + b + c;
  216. d[i] = F::Compact(shift_right(sum, 3));
  217. p0 += 2;
  218. p1 += 2;
  219. }
  220. }
  221. template <typename F> void downsample_3_3(void* dst, const void* src, size_t srcRB, int count) {
  222. SkASSERT(count > 0);
  223. auto p0 = static_cast<const typename F::Type*>(src);
  224. auto p1 = (const typename F::Type*)((const char*)p0 + srcRB);
  225. auto p2 = (const typename F::Type*)((const char*)p1 + srcRB);
  226. auto d = static_cast<typename F::Type*>(dst);
  227. // Given pixels:
  228. // a0 b0 c0 d0 e0 ...
  229. // a1 b1 c1 d1 e1 ...
  230. // a2 b2 c2 d2 e2 ...
  231. // We want:
  232. // (a0 + 2*b0 + c0 + 2*a1 + 4*b1 + 2*c1 + a2 + 2*b2 + c2) / 16
  233. // (c0 + 2*d0 + e0 + 2*c1 + 4*d1 + 2*e1 + c2 + 2*d2 + e2) / 16
  234. // ...
  235. auto c0 = F::Expand(p0[0]);
  236. auto c1 = F::Expand(p1[0]);
  237. auto c2 = F::Expand(p2[0]);
  238. auto c = add_121(c0, c1, c2);
  239. for (int i = 0; i < count; ++i) {
  240. auto a = c;
  241. auto b0 = F::Expand(p0[1]);
  242. auto b1 = F::Expand(p1[1]);
  243. auto b2 = F::Expand(p2[1]);
  244. auto b = shift_left(add_121(b0, b1, b2), 1);
  245. c0 = F::Expand(p0[2]);
  246. c1 = F::Expand(p1[2]);
  247. c2 = F::Expand(p2[2]);
  248. c = add_121(c0, c1, c2);
  249. auto sum = a + b + c;
  250. d[i] = F::Compact(shift_right(sum, 4));
  251. p0 += 2;
  252. p1 += 2;
  253. p2 += 2;
  254. }
  255. }
  256. ///////////////////////////////////////////////////////////////////////////////////////////////////
  257. size_t SkMipMap::AllocLevelsSize(int levelCount, size_t pixelSize) {
  258. if (levelCount < 0) {
  259. return 0;
  260. }
  261. int64_t size = sk_64_mul(levelCount + 1, sizeof(Level)) + pixelSize;
  262. if (!SkTFitsIn<int32_t>(size)) {
  263. return 0;
  264. }
  265. return SkTo<int32_t>(size);
  266. }
  267. SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) {
  268. typedef void FilterProc(void*, const void* srcPtr, size_t srcRB, int count);
  269. FilterProc* proc_1_2 = nullptr;
  270. FilterProc* proc_1_3 = nullptr;
  271. FilterProc* proc_2_1 = nullptr;
  272. FilterProc* proc_2_2 = nullptr;
  273. FilterProc* proc_2_3 = nullptr;
  274. FilterProc* proc_3_1 = nullptr;
  275. FilterProc* proc_3_2 = nullptr;
  276. FilterProc* proc_3_3 = nullptr;
  277. const SkColorType ct = src.colorType();
  278. const SkAlphaType at = src.alphaType();
  279. switch (ct) {
  280. case kRGBA_8888_SkColorType:
  281. case kBGRA_8888_SkColorType:
  282. proc_1_2 = downsample_1_2<ColorTypeFilter_8888>;
  283. proc_1_3 = downsample_1_3<ColorTypeFilter_8888>;
  284. proc_2_1 = downsample_2_1<ColorTypeFilter_8888>;
  285. proc_2_2 = downsample_2_2<ColorTypeFilter_8888>;
  286. proc_2_3 = downsample_2_3<ColorTypeFilter_8888>;
  287. proc_3_1 = downsample_3_1<ColorTypeFilter_8888>;
  288. proc_3_2 = downsample_3_2<ColorTypeFilter_8888>;
  289. proc_3_3 = downsample_3_3<ColorTypeFilter_8888>;
  290. break;
  291. case kRGB_565_SkColorType:
  292. proc_1_2 = downsample_1_2<ColorTypeFilter_565>;
  293. proc_1_3 = downsample_1_3<ColorTypeFilter_565>;
  294. proc_2_1 = downsample_2_1<ColorTypeFilter_565>;
  295. proc_2_2 = downsample_2_2<ColorTypeFilter_565>;
  296. proc_2_3 = downsample_2_3<ColorTypeFilter_565>;
  297. proc_3_1 = downsample_3_1<ColorTypeFilter_565>;
  298. proc_3_2 = downsample_3_2<ColorTypeFilter_565>;
  299. proc_3_3 = downsample_3_3<ColorTypeFilter_565>;
  300. break;
  301. case kARGB_4444_SkColorType:
  302. proc_1_2 = downsample_1_2<ColorTypeFilter_4444>;
  303. proc_1_3 = downsample_1_3<ColorTypeFilter_4444>;
  304. proc_2_1 = downsample_2_1<ColorTypeFilter_4444>;
  305. proc_2_2 = downsample_2_2<ColorTypeFilter_4444>;
  306. proc_2_3 = downsample_2_3<ColorTypeFilter_4444>;
  307. proc_3_1 = downsample_3_1<ColorTypeFilter_4444>;
  308. proc_3_2 = downsample_3_2<ColorTypeFilter_4444>;
  309. proc_3_3 = downsample_3_3<ColorTypeFilter_4444>;
  310. break;
  311. case kAlpha_8_SkColorType:
  312. case kGray_8_SkColorType:
  313. proc_1_2 = downsample_1_2<ColorTypeFilter_8>;
  314. proc_1_3 = downsample_1_3<ColorTypeFilter_8>;
  315. proc_2_1 = downsample_2_1<ColorTypeFilter_8>;
  316. proc_2_2 = downsample_2_2<ColorTypeFilter_8>;
  317. proc_2_3 = downsample_2_3<ColorTypeFilter_8>;
  318. proc_3_1 = downsample_3_1<ColorTypeFilter_8>;
  319. proc_3_2 = downsample_3_2<ColorTypeFilter_8>;
  320. proc_3_3 = downsample_3_3<ColorTypeFilter_8>;
  321. break;
  322. case kRGBA_F16Norm_SkColorType:
  323. case kRGBA_F16_SkColorType:
  324. proc_1_2 = downsample_1_2<ColorTypeFilter_F16>;
  325. proc_1_3 = downsample_1_3<ColorTypeFilter_F16>;
  326. proc_2_1 = downsample_2_1<ColorTypeFilter_F16>;
  327. proc_2_2 = downsample_2_2<ColorTypeFilter_F16>;
  328. proc_2_3 = downsample_2_3<ColorTypeFilter_F16>;
  329. proc_3_1 = downsample_3_1<ColorTypeFilter_F16>;
  330. proc_3_2 = downsample_3_2<ColorTypeFilter_F16>;
  331. proc_3_3 = downsample_3_3<ColorTypeFilter_F16>;
  332. break;
  333. default:
  334. return nullptr;
  335. }
  336. if (src.width() <= 1 && src.height() <= 1) {
  337. return nullptr;
  338. }
  339. // whip through our loop to compute the exact size needed
  340. size_t size = 0;
  341. int countLevels = ComputeLevelCount(src.width(), src.height());
  342. for (int currentMipLevel = countLevels; currentMipLevel >= 0; currentMipLevel--) {
  343. SkISize mipSize = ComputeLevelSize(src.width(), src.height(), currentMipLevel);
  344. size += SkColorTypeMinRowBytes(ct, mipSize.fWidth) * mipSize.fHeight;
  345. }
  346. size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size);
  347. if (0 == storageSize) {
  348. return nullptr;
  349. }
  350. SkMipMap* mipmap;
  351. if (fact) {
  352. SkDiscardableMemory* dm = fact(storageSize);
  353. if (nullptr == dm) {
  354. return nullptr;
  355. }
  356. mipmap = new SkMipMap(storageSize, dm);
  357. } else {
  358. mipmap = new SkMipMap(sk_malloc_throw(storageSize), storageSize);
  359. }
  360. // init
  361. mipmap->fCS = sk_ref_sp(src.info().colorSpace());
  362. mipmap->fCount = countLevels;
  363. mipmap->fLevels = (Level*)mipmap->writable_data();
  364. SkASSERT(mipmap->fLevels);
  365. Level* levels = mipmap->fLevels;
  366. uint8_t* baseAddr = (uint8_t*)&levels[countLevels];
  367. uint8_t* addr = baseAddr;
  368. int width = src.width();
  369. int height = src.height();
  370. uint32_t rowBytes;
  371. SkPixmap srcPM(src);
  372. // Depending on architecture and other factors, the pixel data alignment may need to be as
  373. // large as 8 (for F16 pixels). See the comment on SkMipMap::Level.
  374. SkASSERT(SkIsAlign8((uintptr_t)addr));
  375. for (int i = 0; i < countLevels; ++i) {
  376. FilterProc* proc;
  377. if (height & 1) {
  378. if (height == 1) { // src-height is 1
  379. if (width & 1) { // src-width is 3
  380. proc = proc_3_1;
  381. } else { // src-width is 2
  382. proc = proc_2_1;
  383. }
  384. } else { // src-height is 3
  385. if (width & 1) {
  386. if (width == 1) { // src-width is 1
  387. proc = proc_1_3;
  388. } else { // src-width is 3
  389. proc = proc_3_3;
  390. }
  391. } else { // src-width is 2
  392. proc = proc_2_3;
  393. }
  394. }
  395. } else { // src-height is 2
  396. if (width & 1) {
  397. if (width == 1) { // src-width is 1
  398. proc = proc_1_2;
  399. } else { // src-width is 3
  400. proc = proc_3_2;
  401. }
  402. } else { // src-width is 2
  403. proc = proc_2_2;
  404. }
  405. }
  406. width = SkTMax(1, width >> 1);
  407. height = SkTMax(1, height >> 1);
  408. rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width));
  409. // We make the Info w/o any colorspace, since that storage is not under our control, and
  410. // will not be deleted in a controlled fashion. When the caller is given the pixmap for
  411. // a given level, we augment this pixmap with fCS (which we do manage).
  412. new (&levels[i].fPixmap) SkPixmap(SkImageInfo::Make(width, height, ct, at), addr, rowBytes);
  413. levels[i].fScale = SkSize::Make(SkIntToScalar(width) / src.width(),
  414. SkIntToScalar(height) / src.height());
  415. const SkPixmap& dstPM = levels[i].fPixmap;
  416. const void* srcBasePtr = srcPM.addr();
  417. void* dstBasePtr = dstPM.writable_addr();
  418. const size_t srcRB = srcPM.rowBytes();
  419. for (int y = 0; y < height; y++) {
  420. proc(dstBasePtr, srcBasePtr, srcRB, width);
  421. srcBasePtr = (char*)srcBasePtr + srcRB * 2; // jump two rows
  422. dstBasePtr = (char*)dstBasePtr + dstPM.rowBytes();
  423. }
  424. srcPM = dstPM;
  425. addr += height * rowBytes;
  426. }
  427. SkASSERT(addr == baseAddr + size);
  428. SkASSERT(mipmap->fLevels);
  429. return mipmap;
  430. }
  431. int SkMipMap::ComputeLevelCount(int baseWidth, int baseHeight) {
  432. if (baseWidth < 1 || baseHeight < 1) {
  433. return 0;
  434. }
  435. // OpenGL's spec requires that each mipmap level have height/width equal to
  436. // max(1, floor(original_height / 2^i)
  437. // (or original_width) where i is the mipmap level.
  438. // Continue scaling down until both axes are size 1.
  439. const int largestAxis = SkTMax(baseWidth, baseHeight);
  440. if (largestAxis < 2) {
  441. // SkMipMap::Build requires a minimum size of 2.
  442. return 0;
  443. }
  444. const int leadingZeros = SkCLZ(static_cast<uint32_t>(largestAxis));
  445. // If the value 00011010 has 3 leading 0s then it has 5 significant bits
  446. // (the bits which are not leading zeros)
  447. const int significantBits = (sizeof(uint32_t) * 8) - leadingZeros;
  448. // This is making the assumption that the size of a byte is 8 bits
  449. // and that sizeof(uint32_t)'s implementation-defined behavior is 4.
  450. int mipLevelCount = significantBits;
  451. // SkMipMap does not include the base mip level.
  452. // For example, it contains levels 1-x instead of 0-x.
  453. // This is because the image used to create SkMipMap is the base level.
  454. // So subtract 1 from the mip level count.
  455. if (mipLevelCount > 0) {
  456. --mipLevelCount;
  457. }
  458. return mipLevelCount;
  459. }
  460. SkISize SkMipMap::ComputeLevelSize(int baseWidth, int baseHeight, int level) {
  461. if (baseWidth < 1 || baseHeight < 1) {
  462. return SkISize::Make(0, 0);
  463. }
  464. int maxLevelCount = ComputeLevelCount(baseWidth, baseHeight);
  465. if (level >= maxLevelCount || level < 0) {
  466. return SkISize::Make(0, 0);
  467. }
  468. // OpenGL's spec requires that each mipmap level have height/width equal to
  469. // max(1, floor(original_height / 2^i)
  470. // (or original_width) where i is the mipmap level.
  471. // SkMipMap does not include the base mip level.
  472. // For example, it contains levels 1-x instead of 0-x.
  473. // This is because the image used to create SkMipMap is the base level.
  474. // So subtract 1 from the mip level to get the index stored by SkMipMap.
  475. int width = SkTMax(1, baseWidth >> (level + 1));
  476. int height = SkTMax(1, baseHeight >> (level + 1));
  477. return SkISize::Make(width, height);
  478. }
  479. ///////////////////////////////////////////////////////////////////////////////
  480. bool SkMipMap::extractLevel(const SkSize& scaleSize, Level* levelPtr) const {
  481. if (nullptr == fLevels) {
  482. return false;
  483. }
  484. SkASSERT(scaleSize.width() >= 0 && scaleSize.height() >= 0);
  485. #ifndef SK_SUPPORT_LEGACY_ANISOTROPIC_MIPMAP_SCALE
  486. // Use the smallest scale to match the GPU impl.
  487. const SkScalar scale = SkTMin(scaleSize.width(), scaleSize.height());
  488. #else
  489. // Ideally we'd pick the smaller scale, to match Ganesh. But ignoring one of the
  490. // scales can produce some atrocious results, so for now we use the geometric mean.
  491. // (https://bugs.chromium.org/p/skia/issues/detail?id=4863)
  492. const SkScalar scale = SkScalarSqrt(scaleSize.width() * scaleSize.height());
  493. #endif
  494. if (scale >= SK_Scalar1 || scale <= 0 || !SkScalarIsFinite(scale)) {
  495. return false;
  496. }
  497. SkScalar L = -SkScalarLog2(scale);
  498. if (!SkScalarIsFinite(L)) {
  499. return false;
  500. }
  501. SkASSERT(L >= 0);
  502. int level = SkScalarFloorToInt(L);
  503. SkASSERT(level >= 0);
  504. if (level <= 0) {
  505. return false;
  506. }
  507. if (level > fCount) {
  508. level = fCount;
  509. }
  510. if (levelPtr) {
  511. *levelPtr = fLevels[level - 1];
  512. // need to augment with our colorspace
  513. levelPtr->fPixmap.setColorSpace(fCS);
  514. }
  515. return true;
  516. }
  517. // Helper which extracts a pixmap from the src bitmap
  518. //
  519. SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) {
  520. SkPixmap srcPixmap;
  521. if (!src.peekPixels(&srcPixmap)) {
  522. return nullptr;
  523. }
  524. return Build(srcPixmap, fact);
  525. }
  526. int SkMipMap::countLevels() const {
  527. return fCount;
  528. }
  529. bool SkMipMap::getLevel(int index, Level* levelPtr) const {
  530. if (nullptr == fLevels) {
  531. return false;
  532. }
  533. if (index < 0) {
  534. return false;
  535. }
  536. if (index > fCount - 1) {
  537. return false;
  538. }
  539. if (levelPtr) {
  540. *levelPtr = fLevels[index];
  541. }
  542. return true;
  543. }