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 
25     void emitCode(GrGLSLUniformHandler* uniformHandler, const GrColorSpaceXform* colorSpaceXform,
26                   uint32_t visibility = kFragment_GrShaderFlag) {
27         SkASSERT(uniformHandler);
28         if (colorSpaceXform) {
29             fFlags = colorSpaceXform->fSteps.flags;
30             if (this->applySrcTF()) {
31                 fSrcTFVar = uniformHandler->addUniformArray(visibility, kHalf_GrSLType,
32                                                             "SrcTF", kNumTransferFnCoeffs);
33                 fSrcTFKind = classify_transfer_fn(colorSpaceXform->fSteps.srcTF);
34             }
35             if (this->applyGamutXform()) {
36                 fGamutXformVar = uniformHandler->addUniform(visibility, kHalf3x3_GrSLType,
37                                                             "ColorXform");
38             }
39             if (this->applyDstTF()) {
40                 fDstTFVar = uniformHandler->addUniformArray(visibility, kHalf_GrSLType,
41                                                             "DstTF", kNumTransferFnCoeffs);
42                 fDstTFKind = classify_transfer_fn(colorSpaceXform->fSteps.dstTFInv);
43             }
44         }
45     }
46 
setData(const GrGLSLProgramDataManager & pdman,const GrColorSpaceXform * colorSpaceXform)47     void setData(const GrGLSLProgramDataManager& pdman, const GrColorSpaceXform* colorSpaceXform) {
48         if (this->applySrcTF()) {
49             pdman.set1fv(fSrcTFVar, kNumTransferFnCoeffs, &colorSpaceXform->fSteps.srcTF.g);
50         }
51         if (this->applyGamutXform()) {
52             pdman.setMatrix3f(fGamutXformVar, colorSpaceXform->fSteps.src_to_dst_matrix);
53         }
54         if (this->applyDstTF()) {
55             pdman.set1fv(fDstTFVar, kNumTransferFnCoeffs, &colorSpaceXform->fSteps.dstTFInv.g);
56         }
57     }
58 
isNoop()59     bool isNoop() const { return (0 == fFlags.mask()); }
60 
applyUnpremul()61     bool applyUnpremul() const   { return fFlags.unpremul; }
applySrcTF()62     bool applySrcTF() const      { return fFlags.linearize; }
applyGamutXform()63     bool applyGamutXform() const { return fFlags.gamut_transform; }
applyDstTF()64     bool applyDstTF() const      { return fFlags.encode; }
applyPremul()65     bool applyPremul() const     { return fFlags.premul; }
66 
srcTFKind()67     TFKind srcTFKind() const { return fSrcTFKind; }
dstTFKind()68     TFKind dstTFKind() const { return fDstTFKind; }
69 
srcTFUniform()70     GrGLSLProgramDataManager::UniformHandle srcTFUniform() const { return fSrcTFVar; }
gamutXformUniform()71     GrGLSLProgramDataManager::UniformHandle gamutXformUniform() const { return fGamutXformVar; }
dstTFUniform()72     GrGLSLProgramDataManager::UniformHandle dstTFUniform() const { return fDstTFVar; }
73 
74 private:
75     static const int kNumTransferFnCoeffs = 7;
76 
77     GrGLSLProgramDataManager::UniformHandle fSrcTFVar;
78     GrGLSLProgramDataManager::UniformHandle fGamutXformVar;
79     GrGLSLProgramDataManager::UniformHandle fDstTFVar;
80     SkColorSpaceXformSteps::Flags fFlags;
81     TFKind fSrcTFKind;
82     TFKind fDstTFKind;
83 };
84 
85 #endif
86