Add mipmap procs for F16 format.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1831353002

Review URL: https://codereview.chromium.org/1831353002
This commit is contained in:
brianosman 2016-04-06 07:32:08 -07:00 committed by Commit bot
parent 4334ff29b4
commit 1817d282cd

View File

@ -8,6 +8,7 @@
#include "SkMipMap.h"
#include "SkBitmap.h"
#include "SkColorPriv.h"
#include "SkHalf.h"
#include "SkMath.h"
#include "SkNx.h"
#include "SkTypes.h"
@ -70,10 +71,36 @@ struct ColorTypeFilter_8 {
}
};
struct ColorTypeFilter_F16 {
typedef uint64_t Type; // SkHalf x4
static Sk4f Expand(uint64_t x) {
return SkHalfToFloat_01(x);
}
static uint64_t Compact(const Sk4f& x) {
return SkFloatToHalf_01(x);
}
};
template <typename T> T add_121(const T& a, const T& b, const T& c) {
return a + b + b + c;
}
template <typename T> T shift_right(const T& x, int bits) {
return x >> bits;
}
Sk4f shift_right(const Sk4f& x, int bits) {
return x * (1.0f / (1 << bits));
}
template <typename T> T shift_left(const T& x, int bits) {
return x << bits;
}
Sk4f shift_left(const Sk4f& x, int bits) {
return x * (1 << bits);
}
//
// To produce each mip level, we need to filter down by 1/2 (e.g. 100x100 -> 50,50)
// If the starting dimension is odd, we floor the size of the lower level (e.g. 101 -> 50)
@ -98,7 +125,7 @@ template <typename F> void downsample_1_2(void* dst, const void* src, size_t src
auto c10 = F::Expand(p1[0]);
auto c = c00 + c10;
d[i] = F::Compact(c >> 1);
d[i] = F::Compact(shift_right(c, 1));
p0 += 2;
p1 += 2;
}
@ -117,7 +144,7 @@ template <typename F> void downsample_1_3(void* dst, const void* src, size_t src
auto c20 = F::Expand(p2[0]);
auto c = add_121(c00, c10, c20);
d[i] = F::Compact(c >> 2);
d[i] = F::Compact(shift_right(c, 2));
p0 += 2;
p1 += 2;
p2 += 2;
@ -134,7 +161,7 @@ template <typename F> void downsample_2_1(void* dst, const void* src, size_t src
auto c01 = F::Expand(p0[1]);
auto c = c00 + c01;
d[i] = F::Compact(c >> 1);
d[i] = F::Compact(shift_right(c, 1));
p0 += 2;
}
}
@ -152,7 +179,7 @@ template <typename F> void downsample_2_2(void* dst, const void* src, size_t src
auto c11 = F::Expand(p1[1]);
auto c = c00 + c10 + c01 + c11;
d[i] = F::Compact(c >> 2);
d[i] = F::Compact(shift_right(c, 2));
p0 += 2;
p1 += 2;
}
@ -174,7 +201,7 @@ template <typename F> void downsample_2_3(void* dst, const void* src, size_t src
auto c21 = F::Expand(p2[1]);
auto c = add_121(c00, c10, c20) + add_121(c01, c11, c21);
d[i] = F::Compact(c >> 3);
d[i] = F::Compact(shift_right(c, 3));
p0 += 2;
p1 += 2;
p2 += 2;
@ -193,7 +220,7 @@ template <typename F> void downsample_3_1(void* dst, const void* src, size_t src
c02 = F::Expand(p0[2]);
auto c = add_121(c00, c01, c02);
d[i] = F::Compact(c >> 2);
d[i] = F::Compact(shift_right(c, 2));
p0 += 2;
}
}
@ -215,7 +242,7 @@ template <typename F> void downsample_3_2(void* dst, const void* src, size_t src
c12 = F::Expand(p1[2]);
auto c = add_121(c00, c01, c02) + add_121(c10, c11, c12);
d[i] = F::Compact(c >> 3);
d[i] = F::Compact(shift_right(c, 3));
p0 += 2;
p1 += 2;
}
@ -242,8 +269,11 @@ template <typename F> void downsample_3_3(void* dst, const void* src, size_t src
auto c21 = F::Expand(p2[1]);
c22 = F::Expand(p2[2]);
auto c = add_121(c00, c01, c02) + (add_121(c10, c11, c12) << 1) + add_121(c20, c21, c22);
d[i] = F::Compact(c >> 4);
auto c =
add_121(c00, c01, c02) +
shift_left(add_121(c10, c11, c12), 1) +
add_121(c20, c21, c22);
d[i] = F::Compact(shift_right(c, 4));
p0 += 2;
p1 += 2;
p2 += 2;
@ -320,6 +350,16 @@ SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) {
proc_3_2 = downsample_3_2<ColorTypeFilter_8>;
proc_3_3 = downsample_3_3<ColorTypeFilter_8>;
break;
case kRGBA_F16_SkColorType:
proc_1_2 = downsample_1_2<ColorTypeFilter_F16>;
proc_1_3 = downsample_1_3<ColorTypeFilter_F16>;
proc_2_1 = downsample_2_1<ColorTypeFilter_F16>;
proc_2_2 = downsample_2_2<ColorTypeFilter_F16>;
proc_2_3 = downsample_2_3<ColorTypeFilter_F16>;
proc_3_1 = downsample_3_1<ColorTypeFilter_F16>;
proc_3_2 = downsample_3_2<ColorTypeFilter_F16>;
proc_3_3 = downsample_3_3<ColorTypeFilter_F16>;
break;
default:
// TODO: We could build miplevels for kIndex8 if the levels were in 8888.
// Means using more ram, but the quality would be fine.