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

Side by Side Diff: src/core/SkNormalSourceImpl.cpp

Issue 2043393002: Refactoring of GPU NormalMap handling out into its own class (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Created 4 years, 6 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
« src/core/SkLightingShader.cpp ('K') | « src/core/SkNormalSourceImpl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "SkNormalSourceImpl.h"
9 #include "SkShader.h"
10
11 class NormalMapFP : public GrFragmentProcessor {
12 public:
13 NormalMapFP(GrTexture* normal, const SkMatrix& normMatrix, const GrTexturePa rams& normParams,
14 const SkVector& invNormRotation)
15 : fNormDeviceTransform(kLocal_GrCoordSet, normMatrix, normal, normPa rams.filterMode())
egdaniel 2016/06/09 16:56:38 Skia's style has these initiliazers only tabbed in
dvonbeck 2016/06/09 18:51:29 Done.
16 , fNormalTextureAccess(normal, normParams)
17 , fInvNormRotation(invNormRotation) {
18 this->addCoordTransform(&fNormDeviceTransform);
19 this->addTextureAccess(&fNormalTextureAccess);
20
21 this->initClassID<NormalMapFP>();
22 }
23
24 class NormalMapGLFP : public GrGLSLFragmentProcessor {
egdaniel 2016/06/09 16:56:38 Usually we put the GL in front of the class name,
dvonbeck 2016/06/09 18:51:29 Done.
25 public:
26 NormalMapGLFP() {
27 fInvNormRotation.set(0.0f, 0.0f);
28 }
29
30 void emitCode(EmitArgs& args) override {
31
32 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
33 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
34
35 // add uniform
36 const char* xformUniName = nullptr;
37 fXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
38 kVec2f_GrSLType, kDefault_GrS LPrecision,
39 "Xform", &xformUniName);
40
41 fragBuilder->codeAppend("vec4 normalColor = ");
42 fragBuilder->appendTextureLookup(args.fTexSamplers[0],
43 args.fCoords[0].c_str(),
44 args.fCoords[0].getType());
45 fragBuilder->codeAppend(";");
46
47 fragBuilder->codeAppend("vec3 normal = normalColor.rgb - vec3(0.5);" );
48
49 // TODO: inverse map the light direction vectors in the vertex shade r rather than
50 // transforming all the normals here!
51 fragBuilder->codeAppendf(
52 "mat3 m = mat3(%s.x, -%s.y, 0.0, %s.y, %s.x, 0.0, 0.0, 0.0, 1.0);",
53 xformUniName, xformUniName, xformUniName, xformUniName);
54
55 fragBuilder->codeAppend("normal = normalize(m*normal);");
56 fragBuilder->codeAppendf("%s = vec4(normal, 0);", args.fOutputColor) ;
57 }
58
59 // TODO does this need changing now?
60 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
61 GrProcessorKeyBuilder* b) {
62 // const LightingFP& lightingFP = proc.cast<LightingFP>();
63 // only one shader generated currently
64 b->add32(0x0);
egdaniel 2016/06/09 16:56:38 This should be fine outputing zero. Clean up the c
dvonbeck 2016/06/09 18:51:29 Done.
65 }
66
67 protected:
68 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {
69 const NormalMapFP& normalMapFP = proc.cast<NormalMapFP>();
70
71 const SkVector& invNormRotation = normalMapFP.invNormRotation();
72 if (invNormRotation != fInvNormRotation) {
73 pdman.set2fv(fXformUni, 1, &invNormRotation.fX);
74 fInvNormRotation = invNormRotation;
75 }
76 }
77
78 private:
79 SkVector fInvNormRotation;
80 GrGLSLProgramDataManager::UniformHandle fXformUni;
81 };
82
83 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
84 NormalMapGLFP::GenKey(*this, caps, b);
85 }
86
87 const char* name() const override { return "NormalMapFP"; }
88
89 // TODO what is this? keep? delete?
90 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
91 inout->mulByUnknownFourComponents();
egdaniel 2016/06/09 16:56:38 Since this guy doesn't actually use his input, and
dvonbeck 2016/06/09 18:51:29 The object doesn't have a setUnknownFourComponents
egdaniel 2016/06/10 14:23:27 Sorry that was the function on the inner struct. T
dvonbeck 2016/06/10 15:22:28 Done.
92 }
93
94 const SkVector& invNormRotation() const { return fInvNormRotation; }
95
96 private:
97 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new NormalMapGLFP; }
98
99 bool onIsEqual(const GrFragmentProcessor& proc) const override {
100 const NormalMapFP& normalMapFP = proc.cast<NormalMapFP>();
101 return fNormDeviceTransform == normalMapFP.fNormDeviceTransform &&
102 fNormalTextureAccess == normalMapFP.fNormalTextureAccess &&
103 fInvNormRotation == normalMapFP.fInvNormRotation;
104 }
105
106 GrCoordTransform fNormDeviceTransform;
107 GrTextureAccess fNormalTextureAccess;
108
109 SkVector fInvNormRotation;
110 };
111
112 // TODO same code at SkLightingShader.cpp. Refactor to common source!
113 static bool make_mat(const SkBitmap& bm,
114 const SkMatrix& localMatrix1,
115 const SkMatrix* localMatrix2,
116 SkMatrix* result) {
117
118 result->setIDiv(bm.width(), bm.height());
119
120 SkMatrix lmInverse;
121 if (!localMatrix1.invert(&lmInverse)) {
122 return false;
123 }
124 if (localMatrix2) {
125 SkMatrix inv;
126 if (!localMatrix2->invert(&inv)) {
127 return false;
128 }
129 lmInverse.postConcat(inv);
130 }
131 result->preConcat(lmInverse);
132
133 return true;
134 }
135
136 class NormalMapSourceImpl : public NormalSource {
137 public:
138 NormalMapSourceImpl(const SkBitmap &normal, const SkVector &invNormRotation,
139 const SkMatrix *normLocalM)
egdaniel 2016/06/09 16:56:38 alight with other parameters
dvonbeck 2016/06/09 18:51:29 Done.
140 : fNormalMap(normal)
egdaniel 2016/06/09 16:56:38 again remove one tab
dvonbeck 2016/06/09 18:51:29 Done.
141 , fInvNormRotation(invNormRotation) {
142
143 if (normLocalM) {
144 fNormLocalMatrix = *normLocalM;
145 } else {
146 fNormLocalMatrix.reset();
147 }
148 // Pre-cache so future calls to fNormLocalMatrix.getType() are threadsaf e.
149 (void)fNormLocalMatrix.getType();
150 }
151
152 const GrFragmentProcessor* asFragmentProcessor(
153 GrContext* context,
154 const SkMatrix& viewM,
155 const SkMatrix* localMatrix,
156 SkFilterQuality filterQuality,
157 SkSourceGammaTreatment gammaTreatme nt) const override;
158
159 private:
160 SkBitmap fNormalMap;
161 SkMatrix fNormLocalMatrix;
162 SkVector fInvNormRotation;
163 };
164
165 const GrFragmentProcessor* NormalMapSourceImpl::asFragmentProcessor(
166 GrContext *context,
167 const SkMatrix &viewM,
168 const SkMatrix *localMatrix ,
169 SkFilterQuality filterQuali ty,
170 SkSourceGammaTreatment gamm aTreatment) const {
171
172 // TODO Here, the old code was checking that diffuse map and normal map are same size, that
egdaniel 2016/06/09 16:56:38 We should really have a way so that the diffuse bi
dvonbeck 2016/06/09 18:51:29 Acknowledged.
173 // TODO needs to happen somewhere again!
174
175 SkMatrix normM;
176 if (!make_mat(fNormalMap, fNormLocalMatrix, localMatrix, &normM)) {
177 return nullptr;
178 }
179
180 bool doBicubic;
181 GrTextureParams::FilterMode normFilterMode = GrSkFilterQualityToGrFilterMode (
182 SkTMin(filterQuality, kMedium_SkFilterQuality),
183 viewM,
184 fNormLocalMatrix,
185 &doBicubic);
186 SkASSERT(!doBicubic);
187
188 // TODO: support other tile modes
189 GrTextureParams normParams(SkShader::kClamp_TileMode, normFilterMode);
190 SkAutoTUnref<GrTexture> normalTexture(GrRefCachedBitmapTexture(context,
191 fNormalMap,
192 normParams,
193 gammaTreatmen t));
194 if (!normalTexture) {
195 SkErrorInternals::SetError(kInternalError_SkError, "Couldn't convert bit map to texture.");
196 return nullptr;
197 }
198
199 // TODO is this correct memory handling?
egdaniel 2016/06/09 16:56:38 yes this is fine here. It is the callers responsib
dvonbeck 2016/06/09 18:51:29 Done.
200 return new NormalMapFP(normalTexture, normM, normParams, fInvNormRotation);
201 }
202
203 // TODO This function is also in SkLightingShader. Refactor to common source?
204 // TODO what does it mean for the funciton to be static
205 static bool bitmap_is_too_big(const SkBitmap& bm) {
206 // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it
207 // communicates between its matrix-proc and its sampler-proc. Until we can
208 // widen that, we have to reject bitmaps that are larger.
209 //
210 static const int kMaxSize = 65535;
211
212 return bm.width() > kMaxSize || bm.height() > kMaxSize;
213 }
214
215 sk_sp<NormalSource> NormalMapSource::Make(const SkBitmap &normal, const SkVector &invNormRotation,
216 const SkMatrix *normLocalM) {
217
218 // TODO not checking normal and diffuse maps to be same size
219 if (normal.isNull() || bitmap_is_too_big(normal)) {
220 return nullptr;
221 }
222
223 SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1));
224
225 return sk_make_sp<NormalMapSourceImpl>(normal, invNormRotation, normLocalM);
226 }
OLDNEW
« src/core/SkLightingShader.cpp ('K') | « src/core/SkNormalSourceImpl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698