1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef GrGLSLColorSpaceXformHelper_DEFINED
9 #define GrGLSLColorSpaceXformHelper_DEFINED
10 
11 #include "src/core/SkColorSpacePriv.h"
12 #include "src/core/SkColorSpaceXformSteps.h"
13 #include "src/gpu/GrColorSpaceXform.h"
14 #include "src/gpu/glsl/GrGLSLUniformHandler.h"
15 
16 /**
17  * Helper class to assist with using GrColorSpaceXform within an FP. This manages all of the
18  * uniforms needed, and can be passed to shader builder functions to automatically generate the
19  * correct color space transformation code.
20  */
21 class GrGLSLColorSpaceXformHelper : public SkNoncopyable {
22 public:
GrGLSLColorSpaceXformHelper()23     GrGLSLColorSpaceXformHelper() {
24         memset(&fFlags, 0, sizeof(fFlags));
25     }
26 
27     void emitCode(GrGLSLUniformHandler* uniformHandler, const GrColorSpaceXform* colorSpaceXform,
28                   uint32_t visibility = kFragment_GrShaderFlag) {
29         SkASSERT(uniformHandler);
30         if (colorSpaceXform) {
31             fFlags = colorSpaceXform->fSteps.flags;
32             if (this->applySrcTF()) {
33                 fSrcTFVar = uniformHandler->addUniformArray(visibility, kHalf_GrSLType,
34                                                             "SrcTF", kNumTransferFnCoeffs);
35                 fSrcTFKind = classify_transfer_fn(colorSpaceXform->fSteps.srcTF);
36             }
37             if (this->applyGamutXform()) {
38                 fGamutXformVar = uniformHandler->addUniform(visibility, kHalf3x3_GrSLType,
39                                                             "ColorXform");
40             }
41             if (this->applyDstTF()) {
42                 fDstTFVar = uniformHandler->addUniformArray(visibility, kHalf_GrSLType,
43                                                             "DstTF", kNumTransferFnCoeffs);
44                 fDstTFKind = classify_transfer_fn(colorSpaceXform->fSteps.dstTFInv);
45             }
46         }
47     }
48 
setData(const GrGLSLProgramDataManager & pdman,const GrColorSpaceXform * colorSpaceXform)49     void setData(const GrGLSLProgramDataManager& pdman, const GrColorSpaceXform* colorSpaceXform) {
50         if (this->applySrcTF()) {
51             pdman.set1fv(fSrcTFVar, kNumTransferFnCoeffs, &colorSpaceXform->fSteps.srcTF.g);
52         }
53         if (this->applyGamutXform()) {
54             pdman.setMatrix3f(fGamutXformVar, colorSpaceXform->fSteps.src_to_dst_matrix);
55         }
56         if (this->applyDstTF()) {
57             pdman.set1fv(fDstTFVar, kNumTransferFnCoeffs, &colorSpaceXform->fSteps.dstTFInv.g);
58         }
59     }
60 
isNoop()61     bool isNoop() const { return (0 == fFlags.mask()); }
62 
applyUnpremul()63     bool applyUnpremul() const   { return fFlags.unpremul; }
applySrcTF()64     bool applySrcTF() const      { return fFlags.linearize; }
applyGamutXform()65     bool applyGamutXform() const { return fFlags.gamut_transform; }
applyDstTF()66     bool applyDstTF() const      { return fFlags.encode; }
applyPremul()67     bool applyPremul() const     { return fFlags.premul; }
68 
srcTFKind()69     TFKind srcTFKind() const { return fSrcTFKind; }
dstTFKind()70     TFKind dstTFKind() const { return fDstTFKind; }
71 
srcTFUniform()72     GrGLSLProgramDataManager::UniformHandle srcTFUniform() const { return fSrcTFVar; }
gamutXformUniform()73     GrGLSLProgramDataManager::UniformHandle gamutXformUniform() const { return fGamutXformVar; }
dstTFUniform()74     GrGLSLProgramDataManager::UniformHandle dstTFUniform() const { return fDstTFVar; }
75 
76 private:
77     static const int kNumTransferFnCoeffs = 7;
78 
79     GrGLSLProgramDataManager::UniformHandle fSrcTFVar;
80     GrGLSLProgramDataManager::UniformHandle fGamutXformVar;
81     GrGLSLProgramDataManager::UniformHandle fDstTFVar;
82     SkColorSpaceXformSteps::Flags fFlags;
83     TFKind fSrcTFKind;
84     TFKind fDstTFKind;
85 };
86 
87 #endif
88