add store(PixelFormat,...)
Add store(PixelFormat,...) to mirror earlier load/gather. Use store() in SkVMBlitter to let us to write to any format supported by SkColorType_to_PixelFormat(). This means we can read and write all the same formats now. There's a note on the SkColorType enum about some SkColorTypes being read-only, but I've taken that to be descriptive and not proscriptive. It's worth paying attention to grayscale. Gray PixelFormats hold the same bit size and shift for each of r,g,b so load/gather just naturally unpack the same value into each channel. When we want to store gray we need to dot r,g,b together, here back into the red channel to accommodate future gray-alpha. Change-Id: I81ad252a35e2534d2d8c6123354b1d19c7018898 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302330 Commit-Queue: Mike Klein <mtklein@google.com> Reviewed-by: Mike Reed <reed@google.com>
This commit is contained in:
parent
03c932c74f
commit
e552f925da
@ -1190,6 +1190,34 @@ namespace skvm {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool Builder::store(PixelFormat f, Arg ptr, Color c) {
|
||||
// Detect a grayscale PixelFormat: r,g,b bit counts and shifts all equal.
|
||||
if (f.r_bits == f.g_bits && f.g_bits == f.b_bits &&
|
||||
f.r_shift == f.g_shift && f.g_shift == f.b_shift) {
|
||||
|
||||
// TODO: pull these coefficients from an SkColorSpace? This is sRGB luma/luminance.
|
||||
c.r = c.r * 0.2126f
|
||||
+ c.g * 0.7152f
|
||||
+ c.b * 0.0722f;
|
||||
f.g_bits = f.b_bits = 0;
|
||||
}
|
||||
|
||||
I32 bits = splat(0);
|
||||
if (f.r_bits) { bits = pack(bits, to_unorm(f.r_bits, c.r), f.r_shift); }
|
||||
if (f.g_bits) { bits = pack(bits, to_unorm(f.g_bits, c.g), f.g_shift); }
|
||||
if (f.b_bits) { bits = pack(bits, to_unorm(f.b_bits, c.b), f.b_shift); }
|
||||
if (f.a_bits) { bits = pack(bits, to_unorm(f.a_bits, c.a), f.a_shift); }
|
||||
|
||||
switch (byte_size(f)) {
|
||||
case 1: store8 (ptr, bits); return true;
|
||||
case 2: store16(ptr, bits); return true;
|
||||
case 4: store32(ptr, bits); return true;
|
||||
// TODO: 8,16
|
||||
default: SkUNREACHABLE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Builder::unpremul(F32* r, F32* g, F32* b, F32 a) {
|
||||
skvm::F32 invA = 1.0f / a,
|
||||
inf = bit_cast(splat(0x7f800000));
|
||||
|
@ -718,6 +718,7 @@ namespace skvm {
|
||||
I32 to_unorm(int bits, F32); // E.g. to_unorm(8, x) -> round(x * 255)
|
||||
|
||||
Color load(PixelFormat, Arg ptr);
|
||||
bool store(PixelFormat, Arg ptr, Color);
|
||||
Color gather(PixelFormat, Arg ptr, int offset, I32 index);
|
||||
Color gather(PixelFormat f, Uniform u, I32 index) {
|
||||
return gather(f, u.ptr, u.offset, index);
|
||||
@ -1041,6 +1042,7 @@ namespace skvm {
|
||||
static inline F32 from_unorm(int bits, I32 x) { return x->from_unorm(bits,x); }
|
||||
static inline I32 to_unorm(int bits, F32 x) { return x-> to_unorm(bits,x); }
|
||||
|
||||
static inline bool store(PixelFormat f, Arg p, Color c) { return c->store(f,p,c); }
|
||||
static inline Color gather(PixelFormat f, Arg p, int off, I32 ix) {
|
||||
return ix->gather(f,p,off,ix);
|
||||
}
|
||||
|
@ -159,18 +159,9 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
switch (params.dst.colorType()) {
|
||||
default: *ok = false;
|
||||
break;
|
||||
|
||||
case kRGB_565_SkColorType:
|
||||
case kRGB_888x_SkColorType:
|
||||
case kRGBA_8888_SkColorType:
|
||||
case kBGRA_8888_SkColorType:
|
||||
case kRGBA_1010102_SkColorType:
|
||||
case kBGRA_1010102_SkColorType:
|
||||
case kRGB_101010x_SkColorType:
|
||||
case kBGR_101010x_SkColorType: break;
|
||||
skvm::PixelFormat unused;
|
||||
if (!SkColorType_to_PixelFormat(params.dst.colorType(), &unused)) {
|
||||
*ok = false;
|
||||
}
|
||||
|
||||
return {
|
||||
@ -359,36 +350,7 @@ namespace {
|
||||
src.a = clamp01(src.a);
|
||||
}
|
||||
|
||||
// Store back to the destination.
|
||||
// TODO: use PixelFormat like we do for unpacking.
|
||||
switch (params.dst.colorType()) {
|
||||
default: SkUNREACHABLE;
|
||||
|
||||
case kRGB_565_SkColorType:
|
||||
store16(dst_ptr, pack(pack(to_unorm(5,src.b),
|
||||
to_unorm(6,src.g), 5),
|
||||
to_unorm(5,src.r),11));
|
||||
break;
|
||||
|
||||
case kBGRA_8888_SkColorType: std::swap(src.r, src.b); [[fallthrough]];
|
||||
case kRGB_888x_SkColorType: [[fallthrough]];
|
||||
case kRGBA_8888_SkColorType:
|
||||
store32(dst_ptr, pack(pack(to_unorm(8, src.r),
|
||||
to_unorm(8, src.g), 8),
|
||||
pack(to_unorm(8, src.b),
|
||||
to_unorm(8, src.a), 8), 16));
|
||||
break;
|
||||
|
||||
case kBGR_101010x_SkColorType: [[fallthrough]];
|
||||
case kBGRA_1010102_SkColorType: std::swap(src.r, src.b); [[fallthrough]];
|
||||
case kRGB_101010x_SkColorType: [[fallthrough]];
|
||||
case kRGBA_1010102_SkColorType:
|
||||
store32(dst_ptr, pack(pack(to_unorm(10, src.r),
|
||||
to_unorm(10, src.g), 10),
|
||||
pack(to_unorm(10, src.b),
|
||||
to_unorm( 2, src.a), 10), 20));
|
||||
break;
|
||||
}
|
||||
SkAssertResult(store(pixelFormat, dst_ptr, src));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user