Improve GrGLNonlinearColorSpaceXformEffect to support scRGB
Improve GrGLNonlinearColorSpaceXformEffect to correctly implement
scRGB transfer function and allow for negative colors.
Relax SkSurface_Gpu::Valid to allow kRGBA_half_GrPixelConfig
render target without a color space needed for legacy blending on
Android.
Bug: b/62347704
Change-Id: Ibc6144e69c26cdbdcbf29348c4f612fb6b639e01
Reviewed-on: https://skia-review.googlesource.com/26143
Commit-Queue: Stan Iliev <stani@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/core/SkImageInfoPriv.h b/src/core/SkImageInfoPriv.h
index 38de97f..716c35d 100644
--- a/src/core/SkImageInfoPriv.h
+++ b/src/core/SkImageInfoPriv.h
@@ -34,7 +34,7 @@
}
if (kRGBA_F16_SkColorType == info.colorType() &&
- (!info.colorSpace() || !info.colorSpace()->gammaIsLinear())) {
+ (info.colorSpace() && (!info.colorSpace()->gammaIsLinear()))) {
return false;
}
diff --git a/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp b/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp
index bfa2ed7..c0573e9 100644
--- a/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp
+++ b/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp
@@ -63,7 +63,9 @@
transferFnBody.appendf("float E = %s[4];", coeffsName);
transferFnBody.appendf("float F = %s[5];", coeffsName);
transferFnBody.appendf("float G = %s[6];", coeffsName);
- transferFnBody.appendf("return (x < D) ? (C * x) + F : pow(A * x + B, G) + E;");
+ transferFnBody.append("float s = sign(x);");
+ transferFnBody.append("x = abs(x);");
+ transferFnBody.appendf("return s * ((x < D) ? (C * x) + F : pow(A * x + B, G) + E);");
fragBuilder->emitFunction(kFloat_GrSLType, fnName, SK_ARRAY_COUNT(gTransferFnFuncArgs),
gTransferFnFuncArgs, transferFnBody.c_str(), &tfFuncNames[i]);
}
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 143a603..a474ffe 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -161,7 +161,7 @@
bool SkSurface_Gpu::Valid(const SkImageInfo& info) {
switch (info.colorType()) {
case kRGBA_F16_SkColorType:
- return info.colorSpace() && info.colorSpace()->gammaIsLinear();
+ return (!info.colorSpace()) || info.colorSpace()->gammaIsLinear();
case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
return !info.colorSpace() || info.colorSpace()->gammaCloseToSRGB();
@@ -173,7 +173,7 @@
bool SkSurface_Gpu::Valid(GrContext* context, GrPixelConfig config, SkColorSpace* colorSpace) {
switch (config) {
case kRGBA_half_GrPixelConfig:
- return colorSpace && colorSpace->gammaIsLinear();
+ return (!colorSpace) || colorSpace->gammaIsLinear();
case kSRGBA_8888_GrPixelConfig:
case kSBGRA_8888_GrPixelConfig:
return context->caps()->srgbSupport() && colorSpace && colorSpace->gammaCloseToSRGB();
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp
index 51b9487..3869487 100644
--- a/src/image/SkSurface_Raster.cpp
+++ b/src/image/SkSurface_Raster.cpp
@@ -63,7 +63,7 @@
shift = 2;
break;
case kRGBA_F16_SkColorType:
- if (!info.colorSpace() || !info.colorSpace()->gammaIsLinear()) {
+ if (info.colorSpace() && (!info.colorSpace()->gammaIsLinear())) {
return false;
}
shift = 3;
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 797750f..202df58 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -837,7 +837,7 @@
{ kN32_SkColorType, srgbColorSpace, true, "N32-srgb" },
{ kN32_SkColorType, adobeColorSpace, true, "N32-adobe" },
{ kN32_SkColorType, oddColorSpace, false, "N32-odd" },
- { kRGBA_F16_SkColorType, nullptr, false, "F16-nullptr" },
+ { kRGBA_F16_SkColorType, nullptr, true, "F16-nullptr" },
{ kRGBA_F16_SkColorType, linearColorSpace, true, "F16-linear" },
{ kRGBA_F16_SkColorType, srgbColorSpace, false, "F16-srgb" },
{ kRGBA_F16_SkColorType, adobeColorSpace, false, "F16-adobe" },