| 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: |
| 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(nullptr, visibility, kHalf_GrSLType, |
| 32 | "SrcTF" , kNumTransferFnCoeffs); |
| 33 | fSrcTFKind = classify_transfer_fn(colorSpaceXform->fSteps.srcTF); |
| 34 | } |
| 35 | if (this->applyGamutXform()) { |
| 36 | fGamutXformVar = uniformHandler->addUniform(nullptr, visibility, kHalf3x3_GrSLType, |
| 37 | "ColorXform" ); |
| 38 | } |
| 39 | if (this->applyDstTF()) { |
| 40 | fDstTFVar = uniformHandler->addUniformArray(nullptr, visibility, kHalf_GrSLType, |
| 41 | "DstTF" , kNumTransferFnCoeffs); |
| 42 | fDstTFKind = classify_transfer_fn(colorSpaceXform->fSteps.dstTFInv); |
| 43 | } |
| 44 | } |
| 45 | } |
| 46 | |
| 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 | |
| 59 | bool isNoop() const { return (0 == fFlags.mask()); } |
| 60 | |
| 61 | bool applyUnpremul() const { return fFlags.unpremul; } |
| 62 | bool applySrcTF() const { return fFlags.linearize; } |
| 63 | bool applyGamutXform() const { return fFlags.gamut_transform; } |
| 64 | bool applyDstTF() const { return fFlags.encode; } |
| 65 | bool applyPremul() const { return fFlags.premul; } |
| 66 | |
| 67 | TFKind srcTFKind() const { return fSrcTFKind; } |
| 68 | TFKind dstTFKind() const { return fDstTFKind; } |
| 69 | |
| 70 | GrGLSLProgramDataManager::UniformHandle srcTFUniform() const { return fSrcTFVar; } |
| 71 | GrGLSLProgramDataManager::UniformHandle gamutXformUniform() const { return fGamutXformVar; } |
| 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 | |