aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrColorSpaceXform.h
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2017-10-30 13:47:41 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-31 14:55:14 +0000
commitf06ead925c631c42fae734de1e7c72237a2e91f4 (patch)
treed2ae0175607b41087df6bcc55d6fe4342eecc739 /src/gpu/GrColorSpaceXform.h
parent761f44853fcead7e7a105e1870cb970646814058 (diff)
Add support for transfer functions to GrColorSpaceXform
With this change, untagged sources (eg N32) are treated as sRGB data, which causes a huge number of GMs to render more correctly in GPU sRGB/F16/etc... configs. Also, because the sources are treated as having a color space, we actually do gamut conversion for wide or narrow gamut outputs. This change also applies the transfer function math to individual colors in the case of gradient stops and color shaders. (The CPU backend doesn't do this yet, but I think we've decided there's no reason not to support it). Bug: skia: Change-Id: If76e9e4a268f9f74110ff4bbe4fe189ba5d19d9f Reviewed-on: https://skia-review.googlesource.com/64100 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src/gpu/GrColorSpaceXform.h')
-rw-r--r--src/gpu/GrColorSpaceXform.h46
1 files changed, 37 insertions, 9 deletions
diff --git a/src/gpu/GrColorSpaceXform.h b/src/gpu/GrColorSpaceXform.h
index 3f03e5652d..f63b1660f3 100644
--- a/src/gpu/GrColorSpaceXform.h
+++ b/src/gpu/GrColorSpaceXform.h
@@ -10,29 +10,42 @@
#include "GrColor.h"
#include "GrFragmentProcessor.h"
+#include "SkColorSpace.h"
#include "SkMatrix44.h"
#include "SkRefCnt.h"
-class SkColorSpace;
-
/**
- * Represents a color gamut transformation (as a 4x4 color matrix)
+ * Represents a color space transformation
*/
class GrColorSpaceXform : public SkRefCnt {
public:
- GrColorSpaceXform(const SkMatrix44& srcToDst);
+ GrColorSpaceXform(const SkColorSpaceTransferFn&, const SkMatrix44&, uint32_t);
+
+ static sk_sp<GrColorSpaceXform> Make(const SkColorSpace* src,
+ GrPixelConfig srcConfig,
+ const SkColorSpace* dst);
+ static sk_sp<GrColorSpaceXform> MakeGamutXform(const SkColorSpace* src,
+ const SkColorSpace* dst) {
+ auto result = Make(src, kUnknown_GrPixelConfig, dst);
+ SkASSERT(!result || 0 == (result->fFlags & ~kApplyGamutXform_Flag));
+ return result;
+ }
- static sk_sp<GrColorSpaceXform> Make(const SkColorSpace* src, const SkColorSpace* dst);
+ const SkColorSpaceTransferFn& transferFn() const { return fSrcTransferFn; }
+ const float* transferFnCoeffs() const {
+ static_assert(0 == offsetof(SkColorSpaceTransferFn, fG), "TransferFn layout");
+ return &fSrcTransferFn.fG;
+ }
- const SkMatrix44& srcToDst() const { return fSrcToDst; }
+ const SkMatrix44& gamutXform() const { return fGamutXform; }
/**
* GrGLSLFragmentProcessor::GenKey() must call this and include the returned value in its
* computed key.
*/
static uint32_t XformKey(const GrColorSpaceXform* xform) {
- // Code generation changes if there is an xform, but it otherwise constant
- return SkToBool(xform) ? 1 : 0;
+ // Code generation depends on which steps we apply (as encoded by fFlags)
+ return SkToBool(xform) ? xform->fFlags : 0;
}
static bool Equals(const GrColorSpaceXform* a, const GrColorSpaceXform* b);
@@ -41,7 +54,21 @@ public:
GrColor4f clampedXform(const GrColor4f& srcColor);
private:
- SkMatrix44 fSrcToDst;
+ friend class GrGLSLColorSpaceXformHelper;
+
+ enum Flags {
+ kApplyTransferFn_Flag = 0x1,
+ kApplyGamutXform_Flag = 0x2,
+
+ // Almost never used. This handles the case where the src data is sRGB pixel config,
+ // but the color space has a different transfer function. In that case, we first undo
+ // the HW sRGB -> Linear conversion, before applying any other steps.
+ kApplyInverseSRGB_Flag = 0x4,
+ };
+
+ SkColorSpaceTransferFn fSrcTransferFn;
+ SkMatrix44 fGamutXform;
+ uint32_t fFlags;
};
class GrColorSpaceXformEffect : public GrFragmentProcessor {
@@ -52,6 +79,7 @@ public:
*/
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child,
const SkColorSpace* src,
+ GrPixelConfig srcConfig,
const SkColorSpace* dst);
const char* name() const override { return "ColorSpaceXform"; }