Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: src/gpu/effects/GrColorSpaceEffect.cpp

Issue 1919993002: Added --deepColor option to SampleApp, triggers creation of a ten-bit/channel buffer on Windows. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Plumb gamma to shader, fix window title Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "GrColorSpaceEffect.h"
9
10 #include "GrContext.h"
11 #include "GrCoordTransform.h"
12 #include "GrFragmentProcessor.h"
13 #include "GrInvariantOutput.h"
14 #include "GrProcessor.h"
15 #include "SkColorSpace.h"
16 #include "glsl/GrGLSLFragmentProcessor.h"
17 #include "glsl/GrGLSLFragmentShaderBuilder.h"
18
19 class GrGLColorSpaceEffect : public GrGLSLFragmentProcessor {
20 public:
21 void emitCode(EmitArgs& args) override {
22 const GrColorSpaceEffect& cse = args.fFp.cast<GrColorSpaceEffect>();
23 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
24 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
25
26 const char* gammaUniName = nullptr;
27 if (cse.manualDstGamma() && !cse.gammaIsSRGB()) {
28 fGammaUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kVec3 f_GrSLType,
29 kDefault_GrSLPrecision, "Gamm a", &gammaUniName);
30 }
31
32 GrGLSLShaderVar tmpVar("tmpColor", kVec4f_GrSLType, 0, kHigh_GrSLPrecisi on);
33 SkString tmpDecl;
34 tmpVar.appendDecl(args.fGLSLCaps, &tmpDecl);
35
36 if (cse.manualDstGamma()) {
37 SkString srgbFuncName;
38 if (cse.gammaIsSRGB()) {
39 static const GrGLSLShaderVar gSrgbArgs[] = {
40 GrGLSLShaderVar("x", kFloat_GrSLType),
41 };
42
43 fragBuilder->emitFunction(kFloat_GrSLType,
44 "linear_to_srgb",
45 SK_ARRAY_COUNT(gSrgbArgs),
46 gSrgbArgs,
47 "return (x <= 0.0031308f) ? (x * 12.92 f) "
48 ": (1.055f * pow(x, 0.416666667f) - 0. 055f);",
49 &srgbFuncName);
50 }
51
52 fragBuilder->codeAppendf("%s;", tmpDecl.c_str());
53
54 fragBuilder->codeAppendf("%s = ", tmpVar.c_str());
55 fragBuilder->appendTextureLookup(args.fTexSamplers[0], args.fCoords[ 0].c_str(),
56 args.fCoords[0].getType());
57 fragBuilder->codeAppend(";");
58
59 if (cse.gammaIsSRGB()) {
60 fragBuilder->codeAppendf("%s = vec4(%s(%s.r), %s(%s.g), %s(%s.b) , %s.a);",
61 args.fOutputColor,
62 srgbFuncName.c_str(), tmpVar.c_str(),
63 srgbFuncName.c_str(), tmpVar.c_str(),
64 srgbFuncName.c_str(), tmpVar.c_str(),
65 tmpVar.c_str());
66 } else {
67 fragBuilder->codeAppendf("%s = vec4(pow(%s.rgb, %s.rgb), %s.a);" ,
68 args.fOutputColor, tmpVar.c_str(), gamm aUniName,
69 tmpVar.c_str());
70 }
71 } else {
72 // Pass-through case:
73 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, tmpVar.c_str ());
74 }
75 }
76
77 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& pro c) {
78 const GrColorSpaceEffect& cse = proc.cast<GrColorSpaceEffect>();
79 if (cse.manualDstGamma() && !cse.gammaIsSRGB()) {
80 SkFloat3 gamma = cse.gamma();
81 pdman.set3fv(fGammaUni, 1, &gamma.fVec[0]);
82 }
83 }
84
85 static inline void GenKey(const GrProcessor& processor, const GrGLSLCaps&,
86 GrProcessorKeyBuilder* b) {
87 const GrColorSpaceEffect& cse = processor.cast<GrColorSpaceEffect>();
88 uint32_t key = cse.manualDstGamma() ? 0x1 : 0x0;
89 key |= cse.gammaIsSRGB() << 1;
90 b->add32(key);
91 }
92
93 private:
94 GrGLSLProgramDataManager::UniformHandle fGammaUni;
95
96 typedef GrGLSLFragmentProcessor INHERITED;
97 };
98
99 ///////////////////////////////////////////////////////////////////////////////
100
101 static inline float invert_gamma(float x) {
102 // TODO: What's the deal with kDevice_Named? (It has gamma == 0).
103 return SkScalarNearlyZero(x) ? 1.0f : (1.0f / x);
104 }
105
106 GrColorSpaceEffect::GrColorSpaceEffect(GrTexture* texture,
107 const SkColorSpace* srcColorSpace,
108 const SkColorSpace* dstColorSpace,
109 uint32_t colorSpaceOpsFlags)
110 : INHERITED(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
111 , fManualDstGamma(SkToBool(colorSpaceOpsFlags & GrContext::kManualDstGamma_C olorSpaceOpsFlag)) {
112 this->initClassID<GrColorSpaceEffect>();
113
114 fGamma = dstColorSpace->gamma();
115
116 // TODO: Add an isSRGB (or isSRGBGamma) on SkColorSpace
117 fGammaIsSRGB =
118 SkScalarNearlyEqual(fGamma.fVec[0], 2.2f) &&
119 SkScalarNearlyEqual(fGamma.fVec[1], 2.2f) &&
120 SkScalarNearlyEqual(fGamma.fVec[2], 2.2f);
121
122 // Store inverse destination gamma, for use in shader
123 fGamma.fVec[0] = invert_gamma(fGamma.fVec[0]);
124 fGamma.fVec[1] = invert_gamma(fGamma.fVec[1]);
125 fGamma.fVec[2] = invert_gamma(fGamma.fVec[2]);
126
127 // TODO: Actually read out the color matrices, do the concat, inject that in the shader
128 SkASSERT(srcColorSpace == dstColorSpace);
129 }
130
131 bool GrColorSpaceEffect::onIsEqual(const GrFragmentProcessor& s) const {
132 const GrColorSpaceEffect& other = s.cast<GrColorSpaceEffect>();
133 // Conservative implemenation. Gamma doesn't matter if manual-gamma flag isn 't set.
134 return
135 other.fManualDstGamma == fManualDstGamma &&
136 other.fGammaIsSRGB == fGammaIsSRGB &&
137 other.fGamma.fVec[0] == fGamma.fVec[0] &&
138 other.fGamma.fVec[1] == fGamma.fVec[1] &&
139 other.fGamma.fVec[2] == fGamma.fVec[2];
140 }
141
142 void GrColorSpaceEffect::onComputeInvariantOutput(GrInvariantOutput* inout) cons t {
143 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
144 }
145
146 ///////////////////////////////////////////////////////////////////////////////
147
148 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrColorSpaceEffect);
149
150 const GrFragmentProcessor* GrColorSpaceEffect::TestCreate(GrProcessorTestData* d ) {
151 sk_sp<SkColorSpace> srgb = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named) ;
152 bool doManualGamma = d->fRandom->nextBool();
153 uint32_t opsFlags = doManualGamma ? GrContext::kManualDstGamma_ColorSpaceOps Flag : 0;
154 return new GrColorSpaceEffect(d->fTextures[GrProcessorUnitTest::kSkiaPMTextu reIdx],
155 srgb.get(), srgb.get(), opsFlags);
156 }
157
158 ///////////////////////////////////////////////////////////////////////////////
159
160 void GrColorSpaceEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
161 GrProcessorKeyBuilder* b) const {
162 GrGLColorSpaceEffect::GenKey(*this, caps, b);
163 }
164
165 GrGLSLFragmentProcessor* GrColorSpaceEffect::onCreateGLSLInstance() const {
166 return new GrGLColorSpaceEffect();
167 }
168
169 const GrFragmentProcessor* GrColorSpaceEffect::Create(GrTexture* texture,
170 const SkColorSpace* srcCol orSpace,
171 const SkColorSpace* dstCol orSpace,
172 uint32_t colorSpaceOpsFlag s) {
173 return new GrColorSpaceEffect(texture, srcColorSpace, dstColorSpace, colorSp aceOpsFlags);
174 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698