Reland "Add sRGB 8888 colortype"
This is a reland of 0f7c10ef5681d5c739bcd8862c58d856fd663a0c
Original change's description:
> Add sRGB 8888 colortype
>
> A color type that linearizes just after loading, and re-encodes to sRGB
> just before storing, mimicking the GPU formats that work the same way.
>
> Notes:
> - No mipmap support
> - No SkPngEncoder support (HashAndEncode's .pngs are ok, though?)
> - Needs better testing
>
> This is a re-creation of reviews.skia.org/392990
>
> Change-Id: I4739c2280211e7176aae98ba0a8476a7fe5efa72
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/438219
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Brian Salomon <bsalomon@google.com>
Change-Id: I5b6bb28c4c1faa6c97fcad7552d12c331535714d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/441402
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/core/SkColorSpacePriv.h b/src/core/SkColorSpacePriv.h
index 9b4fad9..d4e3f4d 100644
--- a/src/core/SkColorSpacePriv.h
+++ b/src/core/SkColorSpacePriv.h
@@ -101,6 +101,10 @@
return linearExp || linearFn;
}
+skvm::F32 sk_program_transfer_fn(
+ skvm::F32 v, TFKind,
+ skvm::F32 G, skvm::F32 A, skvm::F32 B, skvm::F32 C, skvm::F32 D, skvm::F32 E, skvm::F32 F);
+
skvm::Color sk_program_transfer_fn(skvm::Builder*, skvm::Uniforms*,
const skcms_TransferFunction&, skvm::Color);
diff --git a/src/core/SkColorSpaceXformSteps.cpp b/src/core/SkColorSpaceXformSteps.cpp
index c091d6a..501f8b4 100644
--- a/src/core/SkColorSpaceXformSteps.cpp
+++ b/src/core/SkColorSpaceXformSteps.cpp
@@ -137,6 +137,47 @@
if (flags.premul) { p->append(SkRasterPipeline::premul); }
}
+skvm::F32 sk_program_transfer_fn(
+ skvm::F32 v, TFKind tf_kind,
+ skvm::F32 G, skvm::F32 A, skvm::F32 B, skvm::F32 C, skvm::F32 D, skvm::F32 E, skvm::F32 F)
+{
+ // Strip off the sign bit and save it for later.
+ skvm::I32 bits = pun_to_I32(v),
+ sign = bits & 0x80000000;
+ v = pun_to_F32(bits ^ sign);
+
+ switch (tf_kind) {
+ case Bad_TF: SkASSERT(false); break;
+
+ case sRGBish_TF: {
+ v = select(v <= D, C*v + F
+ , approx_powf(A*v + B, G) + E);
+ } break;
+
+ case PQish_TF: {
+ skvm::F32 vC = approx_powf(v, C);
+ v = approx_powf(max(B * vC + A, 0.0f) / (E * vC + D), F);
+ } break;
+
+ case HLGish_TF: {
+ skvm::F32 vA = v*A,
+ K = F + 1.0f;
+ v = K*select(vA <= 1.0f, approx_powf(vA, B)
+ , approx_exp((v-E) * C + D));
+ } break;
+
+ case HLGinvish_TF: {
+ skvm::F32 K = F + 1.0f;
+ v /= K;
+ v = select(v <= 1.0f, A * approx_powf(v, B)
+ , C * approx_log(v-D) + E);
+ } break;
+ }
+
+ // Re-apply the original sign bit on our way out the door.
+ return pun_to_F32(sign | pun_to_I32(v));
+}
+
skvm::Color sk_program_transfer_fn(skvm::Builder* p, skvm::Uniforms* uniforms,
const skcms_TransferFunction& tf, skvm::Color c) {
skvm::F32 G = p->uniformF(uniforms->pushF(tf.g)),
@@ -146,46 +187,13 @@
D = p->uniformF(uniforms->pushF(tf.d)),
E = p->uniformF(uniforms->pushF(tf.e)),
F = p->uniformF(uniforms->pushF(tf.f));
-
- auto apply = [&](skvm::F32 v) -> skvm::F32 {
- // Strip off the sign bit and save it for later.
- skvm::I32 bits = pun_to_I32(v),
- sign = bits & 0x80000000;
- v = pun_to_F32(bits ^ sign);
-
- switch (classify_transfer_fn(tf)) {
- case Bad_TF: SkASSERT(false); break;
-
- case sRGBish_TF:
- v = select(v <= D, C*v + F
- , approx_powf(A*v + B, G) + E);
- break;
-
- case PQish_TF: {
- skvm::F32 vC = approx_powf(v, C);
- v = approx_powf(max(B * vC + A, 0.0f) / (E * vC + D), F);
- } break;
-
- case HLGish_TF: {
- skvm::F32 vA = v*A,
- K = F + 1.0f;
- v = K*select(vA <= 1.0f, approx_powf(vA, B)
- , approx_exp((v-E) * C + D));
- } break;
-
- case HLGinvish_TF:
- skvm::F32 K = F + 1.0f;
- v /= K;
- v = select(v <= 1.0f, A * approx_powf(v, B)
- , C * approx_log(v-D) + E);
- break;
- }
-
- // Re-apply the original sign bit on our way out the door.
- return pun_to_F32(sign | pun_to_I32(v));
+ TFKind tf_kind = classify_transfer_fn(tf);
+ return {
+ sk_program_transfer_fn(c.r, tf_kind, G,A,B,C,D,E,F),
+ sk_program_transfer_fn(c.g, tf_kind, G,A,B,C,D,E,F),
+ sk_program_transfer_fn(c.b, tf_kind, G,A,B,C,D,E,F),
+ c.a,
};
-
- return {apply(c.r), apply(c.g), apply(c.b), c.a};
}
skvm::Color SkColorSpaceXformSteps::program(skvm::Builder* p, skvm::Uniforms* uniforms,
diff --git a/src/core/SkConvertPixels.cpp b/src/core/SkConvertPixels.cpp
index 42b2aa0..f00042b 100644
--- a/src/core/SkConvertPixels.cpp
+++ b/src/core/SkConvertPixels.cpp
@@ -124,7 +124,8 @@
}
case kBGRA_8888_SkColorType:
- case kRGBA_8888_SkColorType: {
+ case kRGBA_8888_SkColorType:
+ case kSRGBA_8888_SkColorType: {
auto src32 = (const uint32_t*) src;
for (int y = 0; y < srcInfo.height(); y++) {
for (int x = 0; x < srcInfo.width(); x++) {
diff --git a/src/core/SkImageInfo.cpp b/src/core/SkImageInfo.cpp
index 81994fb..dc045ec 100644
--- a/src/core/SkImageInfo.cpp
+++ b/src/core/SkImageInfo.cpp
@@ -33,6 +33,7 @@
case kA16_float_SkColorType: return 2;
case kR16G16_float_SkColorType: return 4;
case kR16G16B16A16_unorm_SkColorType: return 8;
+ case kSRGBA_8888_SkColorType: return 4;
}
SkUNREACHABLE;
}
@@ -93,6 +94,7 @@
[[fallthrough]];
case kARGB_4444_SkColorType:
case kRGBA_8888_SkColorType:
+ case kSRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
case kRGBA_1010102_SkColorType:
case kBGRA_1010102_SkColorType:
diff --git a/src/core/SkMipmap.cpp b/src/core/SkMipmap.cpp
index eef99dc..5074a00 100644
--- a/src/core/SkMipmap.cpp
+++ b/src/core/SkMipmap.cpp
@@ -543,6 +543,9 @@
case kBGR_101010x_SkColorType: // TODO: use 1010102?
case kRGBA_F32_SkColorType:
return nullptr;
+
+ case kSRGBA_8888_SkColorType: // TODO: needs careful handling
+ return nullptr;
}
if (src.width() <= 1 && src.height() <= 1) {
diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp
index 2545c62..47a9974 100644
--- a/src/core/SkPixmap.cpp
+++ b/src/core/SkPixmap.cpp
@@ -128,6 +128,7 @@
}
case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
+ case kSRGBA_8888_SkColorType:
value = static_cast<const uint8_t*>(srcPtr)[3] * (1.0f/255);
break;
case kRGBA_1010102_SkColorType:
@@ -326,6 +327,30 @@
SkPMColor c = SkSwizzle_RGBA_to_PMColor(value);
return toColor(c);
}
+ case kSRGBA_8888_SkColorType: {
+ auto srgb_to_linear = [](float x) {
+ return (x <= 0.04045f) ? x * (1 / 12.92f)
+ : sk_float_pow(x * (1 / 1.055f) + (0.055f / 1.055f), 2.4f);
+ };
+
+ uint32_t value = *this->addr32(x, y);
+ float r = ((value >> 0) & 0xff) * (1/255.0f),
+ g = ((value >> 8) & 0xff) * (1/255.0f),
+ b = ((value >> 16) & 0xff) * (1/255.0f),
+ a = ((value >> 24) & 0xff) * (1/255.0f);
+ r = srgb_to_linear(r);
+ g = srgb_to_linear(g);
+ b = srgb_to_linear(b);
+ if (a != 0 && needsUnpremul) {
+ r = SkTPin(r/a, 0.0f, 1.0f);
+ g = SkTPin(g/a, 0.0f, 1.0f);
+ b = SkTPin(b/a, 0.0f, 1.0f);
+ }
+ return (uint32_t)( r * 255.0f ) << 16
+ | (uint32_t)( g * 255.0f ) << 8
+ | (uint32_t)( b * 255.0f ) << 0
+ | (uint32_t)( a * 255.0f ) << 24;
+ }
case kRGB_101010x_SkColorType: {
uint32_t value = *this->addr32(x, y);
// Convert 10-bit rgb to 8-bit bgr, and mask in 0xff alpha at the top.
@@ -481,7 +506,8 @@
return true;
}
case kBGRA_8888_SkColorType:
- case kRGBA_8888_SkColorType: {
+ case kRGBA_8888_SkColorType:
+ case kSRGBA_8888_SkColorType: {
SkPMColor c = (SkPMColor)~0;
for (int y = 0; y < height; ++y) {
const SkPMColor* row = this->addr32(0, y);
diff --git a/src/core/SkRasterPipeline.cpp b/src/core/SkRasterPipeline.cpp
index b5d30be..93ad3a9 100644
--- a/src/core/SkRasterPipeline.cpp
+++ b/src/core/SkRasterPipeline.cpp
@@ -210,6 +210,11 @@
case kBGRA_8888_SkColorType: this->append(load_8888, ctx);
this->append(swap_rb);
break;
+
+ case kSRGBA_8888_SkColorType:
+ this->append(load_8888, ctx);
+ this->append_transfer_function(*skcms_sRGB_TransferFunction());
+ break;
}
}
@@ -256,6 +261,14 @@
case kBGRA_8888_SkColorType: this->append(load_8888_dst, ctx);
this->append(swap_rb_dst);
break;
+
+ case kSRGBA_8888_SkColorType:
+ // TODO: We could remove the double-swap if we had _dst versions of all the TF stages
+ this->append(load_8888_dst, ctx);
+ this->append(swap_src_dst);
+ this->append_transfer_function(*skcms_sRGB_TransferFunction());
+ this->append(swap_src_dst);
+ break;
}
}
@@ -302,6 +315,11 @@
case kBGRA_8888_SkColorType: this->append(swap_rb);
this->append(store_8888, ctx);
break;
+
+ case kSRGBA_8888_SkColorType:
+ this->append_transfer_function(*skcms_sRGB_Inverse_TransferFunction());
+ this->append(store_8888, ctx);
+ break;
}
}
diff --git a/src/core/SkRasterPipeline.h b/src/core/SkRasterPipeline.h
index 6e8b4be..3b03020 100644
--- a/src/core/SkRasterPipeline.h
+++ b/src/core/SkRasterPipeline.h
@@ -38,7 +38,7 @@
#define SK_RASTER_PIPELINE_STAGES(M) \
M(callback) \
- M(move_src_dst) M(move_dst_src) \
+ M(move_src_dst) M(move_dst_src) M(swap_src_dst) \
M(clamp_0) M(clamp_1) M(clamp_a) M(clamp_gamut) \
M(unpremul) M(premul) M(premul_dst) \
M(force_opaque) M(force_opaque_dst) \
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp
index fd3fc5f..b1313de 100644
--- a/src/core/SkRasterPipelineBlitter.cpp
+++ b/src/core/SkRasterPipelineBlitter.cpp
@@ -208,7 +208,8 @@
case kGray_8_SkColorType:
case kRGB_888x_SkColorType:
case kRGBA_8888_SkColorType:
- case kBGRA_8888_SkColorType: blitter->fDitherRate = 1/255.0f; break;
+ case kBGRA_8888_SkColorType:
+ case kSRGBA_8888_SkColorType: blitter->fDitherRate = 1/255.0f; break;
case kRGB_101010x_SkColorType:
case kRGBA_1010102_SkColorType:
case kBGR_101010x_SkColorType:
diff --git a/src/core/SkVM.cpp b/src/core/SkVM.cpp
index 8c760d5..967b593 100644
--- a/src/core/SkVM.cpp
+++ b/src/core/SkVM.cpp
@@ -13,6 +13,7 @@
#include "include/private/SkTFitsIn.h"
#include "include/private/SkThreadID.h"
#include "include/private/SkVx.h"
+#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkCpu.h"
#include "src/core/SkEnumerate.h"
@@ -112,7 +113,20 @@
#endif
#endif
+#if defined(SKSL_STANDALONE)
+ // skslc needs to link against this module (for the VM code generator). This module pulls in
+ // color-space code, but attempting to add those transitive dependencies to skslc gets out of
+ // hand. So we terminate the chain here with stub functions. Note that skslc's usage of SkVM
+ // never cares about color management.
+ skvm::F32 sk_program_transfer_fn(
+ skvm::F32 v, TFKind tf_kind,
+ skvm::F32 G, skvm::F32 A, skvm::F32 B, skvm::F32 C, skvm::F32 D, skvm::F32 E, skvm::F32 F) {
+ return v;
+ }
+ const skcms_TransferFunction* skcms_sRGB_TransferFunction() { return nullptr; }
+ const skcms_TransferFunction* skcms_sRGB_Inverse_TransferFunction() { return nullptr; }
+#endif
namespace skvm {
@@ -1043,6 +1057,7 @@
PixelFormat SkColorType_to_PixelFormat(SkColorType ct) {
auto UNORM = PixelFormat::UNORM,
+ SRGB = PixelFormat::SRGB,
FLOAT = PixelFormat::FLOAT;
switch (ct) {
case kUnknown_SkColorType: break;
@@ -1065,6 +1080,7 @@
case kRGBA_8888_SkColorType: return {UNORM, 8,8,8,8, 0,8,16,24};
case kRGB_888x_SkColorType: return {UNORM, 8,8,8,0, 0,8,16,32}; // 32-bit
case kBGRA_8888_SkColorType: return {UNORM, 8,8,8,8, 16,8, 0,24};
+ case kSRGBA_8888_SkColorType: return { SRGB, 8,8,8,8, 0,8,16,24};
case kRGBA_1010102_SkColorType: return {UNORM, 10,10,10,2, 0,10,20,30};
case kBGRA_1010102_SkColorType: return {UNORM, 10,10,10,2, 20,10, 0,30};
@@ -1091,19 +1107,43 @@
static Color unpack(PixelFormat f, I32 x) {
SkASSERT(byte_size(f) <= 4);
- auto unpack_channel = [=](int bits, int shift) {
+
+ auto from_srgb = [](int bits, I32 channel) -> F32 {
+ const skcms_TransferFunction* tf = skcms_sRGB_TransferFunction();
+ F32 v = from_unorm(bits, channel);
+ return sk_program_transfer_fn(v, sRGBish_TF,
+ v->splat(tf->g),
+ v->splat(tf->a),
+ v->splat(tf->b),
+ v->splat(tf->c),
+ v->splat(tf->d),
+ v->splat(tf->e),
+ v->splat(tf->f));
+ };
+
+ auto unpack_rgb = [=](int bits, int shift) -> F32 {
I32 channel = extract(x, shift, (1<<bits)-1);
switch (f.encoding) {
case PixelFormat::UNORM: return from_unorm(bits, channel);
+ case PixelFormat:: SRGB: return from_srgb (bits, channel);
+ case PixelFormat::FLOAT: return from_fp16 ( channel);
+ }
+ SkUNREACHABLE;
+ };
+ auto unpack_alpha = [=](int bits, int shift) -> F32 {
+ I32 channel = extract(x, shift, (1<<bits)-1);
+ switch (f.encoding) {
+ case PixelFormat::UNORM:
+ case PixelFormat:: SRGB: return from_unorm(bits, channel);
case PixelFormat::FLOAT: return from_fp16 ( channel);
}
SkUNREACHABLE;
};
return {
- f.r_bits ? unpack_channel(f.r_bits, f.r_shift) : x->splat(0.0f),
- f.g_bits ? unpack_channel(f.g_bits, f.g_shift) : x->splat(0.0f),
- f.b_bits ? unpack_channel(f.b_bits, f.b_shift) : x->splat(0.0f),
- f.a_bits ? unpack_channel(f.a_bits, f.a_shift) : x->splat(1.0f),
+ f.r_bits ? unpack_rgb (f.r_bits, f.r_shift) : x->splat(0.0f),
+ f.g_bits ? unpack_rgb (f.g_bits, f.g_shift) : x->splat(0.0f),
+ f.b_bits ? unpack_rgb (f.b_bits, f.b_shift) : x->splat(0.0f),
+ f.a_bits ? unpack_alpha(f.a_bits, f.a_shift) : x->splat(1.0f),
};
}
@@ -1211,19 +1251,42 @@
static I32 pack32(PixelFormat f, Color c) {
SkASSERT(byte_size(f) <= 4);
+
+ auto to_srgb = [](int bits, F32 v) {
+ const skcms_TransferFunction* tf = skcms_sRGB_Inverse_TransferFunction();
+ return to_unorm(bits, sk_program_transfer_fn(v, sRGBish_TF,
+ v->splat(tf->g),
+ v->splat(tf->a),
+ v->splat(tf->b),
+ v->splat(tf->c),
+ v->splat(tf->d),
+ v->splat(tf->e),
+ v->splat(tf->f)));
+ };
+
I32 packed = c->splat(0);
- auto pack_channel = [&](F32 channel, int bits, int shift) {
+ auto pack_rgb = [&](F32 channel, int bits, int shift) {
I32 encoded;
switch (f.encoding) {
case PixelFormat::UNORM: encoded = to_unorm(bits, channel); break;
+ case PixelFormat:: SRGB: encoded = to_srgb (bits, channel); break;
case PixelFormat::FLOAT: encoded = to_fp16 ( channel); break;
}
packed = pack(packed, encoded, shift);
};
- if (f.r_bits) { pack_channel(c.r, f.r_bits, f.r_shift); }
- if (f.g_bits) { pack_channel(c.g, f.g_bits, f.g_shift); }
- if (f.b_bits) { pack_channel(c.b, f.b_bits, f.b_shift); }
- if (f.a_bits) { pack_channel(c.a, f.a_bits, f.a_shift); }
+ auto pack_alpha = [&](F32 channel, int bits, int shift) {
+ I32 encoded;
+ switch (f.encoding) {
+ case PixelFormat::UNORM:
+ case PixelFormat:: SRGB: encoded = to_unorm(bits, channel); break;
+ case PixelFormat::FLOAT: encoded = to_fp16 ( channel); break;
+ }
+ packed = pack(packed, encoded, shift);
+ };
+ if (f.r_bits) { pack_rgb (c.r, f.r_bits, f.r_shift); }
+ if (f.g_bits) { pack_rgb (c.g, f.g_bits, f.g_shift); }
+ if (f.b_bits) { pack_rgb (c.b, f.b_bits, f.b_shift); }
+ if (f.a_bits) { pack_alpha(c.a, f.a_bits, f.a_shift); }
return packed;
}
diff --git a/src/core/SkVM.h b/src/core/SkVM.h
index 670e1cd..60277e8 100644
--- a/src/core/SkVM.h
+++ b/src/core/SkVM.h
@@ -560,7 +560,7 @@
};
struct PixelFormat {
- enum { UNORM, FLOAT} encoding;
+ enum { UNORM, SRGB, FLOAT} encoding;
int r_bits, g_bits, b_bits, a_bits,
r_shift, g_shift, b_shift, a_shift;
};
diff --git a/src/core/SkVMBlitter.cpp b/src/core/SkVMBlitter.cpp
index 76415cf..3be35ee 100644
--- a/src/core/SkVMBlitter.cpp
+++ b/src/core/SkVMBlitter.cpp
@@ -114,7 +114,8 @@
case kGray_8_SkColorType:
case kRGB_888x_SkColorType:
case kRGBA_8888_SkColorType:
- case kBGRA_8888_SkColorType: rate = 1/255.0f; break;
+ case kBGRA_8888_SkColorType:
+ case kSRGBA_8888_SkColorType: rate = 1/255.0f; break;
case kRGB_101010x_SkColorType:
case kRGBA_1010102_SkColorType:
case kBGR_101010x_SkColorType:
diff --git a/src/gpu/GrDataUtils.cpp b/src/gpu/GrDataUtils.cpp
index 0d449d6..d14c466 100644
--- a/src/gpu/GrDataUtils.cpp
+++ b/src/gpu/GrDataUtils.cpp
@@ -747,18 +747,3 @@
return true;
}
-
-GrColorType SkColorTypeAndFormatToGrColorType(const GrCaps* caps,
- SkColorType skCT,
- const GrBackendFormat& format) {
- GrColorType grCT = SkColorTypeToGrColorType(skCT);
- // Until we support SRGB in the SkColorType we have to do this manual check here to make sure
- // we use the correct GrColorType.
- if (caps->isFormatSRGB(format)) {
- if (grCT != GrColorType::kRGBA_8888) {
- return GrColorType::kUnknown;
- }
- grCT = GrColorType::kRGBA_8888_SRGB;
- }
- return grCT;
-}
diff --git a/src/gpu/GrDirectContext.cpp b/src/gpu/GrDirectContext.cpp
index cb9edf0..4ada100 100644
--- a/src/gpu/GrDirectContext.cpp
+++ b/src/gpu/GrDirectContext.cpp
@@ -683,7 +683,7 @@
}
GrBackendFormat format = backendTexture.getBackendFormat();
- GrColorType grColorType = SkColorTypeAndFormatToGrColorType(this->caps(), skColorType, format);
+ GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
if (!this->caps()->areColorTypeAndFormatCompatible(grColorType, format)) {
return false;
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 9468369..b8a8971 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -154,7 +154,7 @@
#ifdef SK_DEBUG
const GrBackendFormat& format = fChooser.backendFormat();
const GrCaps* caps = this->context()->priv().caps();
- GrColorType grCT = SkColorTypeAndFormatToGrColorType(caps, this->colorType(), format);
+ GrColorType grCT = SkColorTypeToGrColorType(this->colorType());
SkASSERT(caps->isFormatCompressed(format) ||
caps->areColorTypeAndFormatCompatible(grCT, format));
#endif
@@ -179,7 +179,7 @@
#ifdef SK_DEBUG
const GrBackendFormat& format = fChooser.backendFormat();
const GrCaps* caps = this->context()->priv().caps();
- GrColorType grCT = SkColorTypeAndFormatToGrColorType(caps, this->colorType(), format);
+ GrColorType grCT = SkColorTypeToGrColorType(this->colorType());
SkASSERT(caps->isFormatCompressed(format) ||
caps->areColorTypeAndFormatCompatible(grCT, format));
#endif
@@ -457,7 +457,7 @@
const GrCaps* caps = rContext->priv().caps();
- GrColorType grColorType = SkColorTypeAndFormatToGrColorType(caps, ct, tex.getBackendFormat());
+ GrColorType grColorType = SkColorTypeToGrColorType(ct);
if (GrColorType::kUnknown == grColorType) {
return nullptr;
}
@@ -482,7 +482,7 @@
const GrCaps* caps = dContext->priv().caps();
- GrColorType grColorType = SkColorTypeAndFormatToGrColorType(caps, ct, tex.getBackendFormat());
+ GrColorType grColorType = SkColorTypeToGrColorType(ct);
if (GrColorType::kUnknown == grColorType) {
return nullptr;
}
@@ -595,9 +595,7 @@
return nullptr;
}
- GrColorType grColorType = SkColorTypeAndFormatToGrColorType(threadSafeProxy->priv().caps(),
- colorType,
- backendFormat);
+ GrColorType grColorType = SkColorTypeToGrColorType(colorType);
if (GrColorType::kUnknown == grColorType) {
return nullptr;
}
@@ -834,9 +832,7 @@
SkColorTypeToGrColorType(this->colorType())};
}
GrSurfaceProxyView view = this->makeView(recordingContext);
- GrColorType ct = SkColorTypeAndFormatToGrColorType(recordingContext->priv().caps(),
- this->colorType(),
- view.proxy()->backendFormat());
+ GrColorType ct = SkColorTypeToGrColorType(this->colorType());
if (mipmapped == GrMipmapped::kYes) {
view = FindOrMakeCachedMipmappedView(recordingContext, std::move(view), this->uniqueID());
}
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 873b431..6a7662e 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -489,8 +489,7 @@
}
sampleCnt = std::max(1, sampleCnt);
- GrColorType grColorType = SkColorTypeAndFormatToGrColorType(rContext->priv().caps(), colorType,
- tex.getBackendFormat());
+ GrColorType grColorType = SkColorTypeToGrColorType(colorType);
if (grColorType == GrColorType::kUnknown) {
return nullptr;
}
@@ -607,8 +606,7 @@
return nullptr;
}
- GrColorType grColorType = SkColorTypeAndFormatToGrColorType(rContext->priv().caps(), colorType,
- rt.getBackendFormat());
+ GrColorType grColorType = SkColorTypeToGrColorType(colorType);
if (grColorType == GrColorType::kUnknown) {
return nullptr;
}
diff --git a/src/images/SkPngEncoder.cpp b/src/images/SkPngEncoder.cpp
index d3957f7..2cf3ba4 100644
--- a/src/images/SkPngEncoder.cpp
+++ b/src/images/SkPngEncoder.cpp
@@ -237,6 +237,11 @@
case kUnknown_SkColorType:
break;
+ // TODO: I don't think this can just use kRGBA's procs.
+ // kPremul is especially tricky here, since it's presumably TF⁻¹(rgb * a),
+ // so to get at unpremul rgb we'd need to undo the transfer function first.
+ case kSRGBA_8888_SkColorType: return nullptr;
+
case kRGBA_8888_SkColorType:
switch (info.alphaType()) {
case kOpaque_SkAlphaType:
diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h
index ff0d8c1..33a067f 100644
--- a/src/opts/SkRasterPipeline_opts.h
+++ b/src/opts/SkRasterPipeline_opts.h
@@ -1644,6 +1644,12 @@
b = db;
a = da;
}
+STAGE(swap_src_dst, Ctx::None) {
+ std::swap(r, dr);
+ std::swap(g, dg);
+ std::swap(b, db);
+ std::swap(a, da);
+}
STAGE(premul, Ctx::None) {
r = r * a;
@@ -3288,6 +3294,13 @@
a = da;
}
+STAGE_PP(swap_src_dst, Ctx::None) {
+ std::swap(r, dr);
+ std::swap(g, dg);
+ std::swap(b, db);
+ std::swap(a, da);
+}
+
// ~~~~~~ Blend modes ~~~~~~ //
// The same logic applied to all 4 channels.
diff --git a/src/shaders/SkImageShader.cpp b/src/shaders/SkImageShader.cpp
index d126df0..2e44dd0 100755
--- a/src/shaders/SkImageShader.cpp
+++ b/src/shaders/SkImageShader.cpp
@@ -539,6 +539,11 @@
case kBGRA_8888_SkColorType: p->append(SkRasterPipeline::gather_8888, ctx);
p->append(SkRasterPipeline::swap_rb ); break;
+ case kSRGBA_8888_SkColorType:
+ p->append(SkRasterPipeline::gather_8888, ctx);
+ p->append_transfer_function(*skcms_sRGB_TransferFunction());
+ break;
+
case kUnknown_SkColorType: SkASSERT(false);
}
if (decal_ctx) {