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

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

Issue 2043393002: Refactoring of GPU NormalMap handling out into its own class (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Fixed SK_API flags, got rid of NormalMapSource::Make 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
« no previous file with comments | « src/core/SkLightingShader.h ('k') | src/core/SkLightingShader_NormalSource.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBitmapProcShader.h"
8 #include "SkBitmapProcState.h" 9 #include "SkBitmapProcState.h"
9 #include "SkColor.h" 10 #include "SkColor.h"
10 #include "SkEmptyShader.h" 11 #include "SkEmptyShader.h"
11 #include "SkErrorInternals.h" 12 #include "SkErrorInternals.h"
12 #include "SkLightingShader.h" 13 #include "SkLightingShader.h"
13 #include "SkMathPriv.h" 14 #include "SkMathPriv.h"
14 #include "SkPoint3.h" 15 #include "SkPoint3.h"
15 #include "SkReadBuffer.h" 16 #include "SkReadBuffer.h"
16 #include "SkWriteBuffer.h" 17 #include "SkWriteBuffer.h"
17 18
(...skipping 12 matching lines...) Expand all
30 non-opaque diffuse textures 31 non-opaque diffuse textures
31 A8 diffuse textures 32 A8 diffuse textures
32 down & upsampled draws 33 down & upsampled draws
33 */ 34 */
34 35
35 36
36 37
37 /** \class SkLightingShaderImpl 38 /** \class SkLightingShaderImpl
38 This subclass of shader applies lighting. 39 This subclass of shader applies lighting.
39 */ 40 */
40 class SK_API SkLightingShaderImpl : public SkShader { 41 class SkLightingShaderImpl : public SkShader {
41 public: 42 public:
42 43
43 /** Create a new lighting shader that uses the provided normal map and 44 /** Create a new lighting shader that uses the provided normal map and
44 lights to light the diffuse bitmap. 45 lights to light the diffuse bitmap.
45 @param diffuse the diffuse bitmap 46 @param diffuse the diffuse bitmap
46 @param normal the normal map 47 @param normal the normal map
47 @param lights the lights applied to the normal map 48 @param lights the lights applied to the normal map
48 @param invNormRotation rotation applied to the normal map's normals 49 @param invNormRotation rotation applied to the normal map's normals
49 @param diffLocalM the local matrix for the diffuse coordinates 50 @param diffLocalM the local matrix for the diffuse coordinates
50 @param normLocalM the local matrix for the normal coordinates 51 @param normLocalM the local matrix for the normal coordinates
52 @param normalSource the normal source for GPU computations
51 */ 53 */
52 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal, 54 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal,
53 const sk_sp<SkLights> lights, 55 const sk_sp<SkLights> lights,
54 const SkVector& invNormRotation, 56 const SkVector& invNormRotation,
55 const SkMatrix* diffLocalM, const SkMatrix* normLocalM) 57 const SkMatrix* diffLocalM, const SkMatrix* normLocalM,
58 sk_sp<SkLightingShader::NormalSource> normalSource)
56 : INHERITED(diffLocalM) 59 : INHERITED(diffLocalM)
57 , fDiffuseMap(diffuse) 60 , fDiffuseMap(diffuse)
58 , fNormalMap(normal) 61 , fNormalMap(normal)
59 , fLights(std::move(lights)) 62 , fLights(std::move(lights))
60 , fInvNormRotation(invNormRotation) { 63 , fInvNormRotation(invNormRotation) {
61 64
62 if (normLocalM) { 65 if (normLocalM) {
63 fNormLocalMatrix = *normLocalM; 66 fNormLocalMatrix = *normLocalM;
64 } else { 67 } else {
65 fNormLocalMatrix.reset(); 68 fNormLocalMatrix.reset();
66 } 69 }
67 // Pre-cache so future calls to fNormLocalMatrix.getType() are threadsaf e. 70 // Pre-cache so future calls to fNormLocalMatrix.getType() are threadsaf e.
68 (void)fNormLocalMatrix.getType(); 71 (void)fNormLocalMatrix.getType();
69 72
73 fNormalSource = std::move(normalSource);
70 } 74 }
71 75
72 bool isOpaque() const override; 76 bool isOpaque() const override;
73 77
74 #if SK_SUPPORT_GPU 78 #if SK_SUPPORT_GPU
75 sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, 79 sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*,
76 const SkMatrix& viewM, 80 const SkMatrix& viewM,
77 const SkMatrix* localMatrix, 81 const SkMatrix* localMatrix,
78 SkFilterQuality, 82 SkFilterQuality,
79 SkSourceGammaTreatment) const override; 83 SkSourceGammaTreatment) const override;
(...skipping 30 matching lines...) Expand all
110 114
111 private: 115 private:
112 SkBitmap fDiffuseMap; 116 SkBitmap fDiffuseMap;
113 SkBitmap fNormalMap; 117 SkBitmap fNormalMap;
114 118
115 sk_sp<SkLights> fLights; 119 sk_sp<SkLights> fLights;
116 120
117 SkMatrix fNormLocalMatrix; 121 SkMatrix fNormLocalMatrix;
118 SkVector fInvNormRotation; 122 SkVector fInvNormRotation;
119 123
124 sk_sp<SkLightingShader::NormalSource> fNormalSource;
125
120 friend class SkLightingShader; 126 friend class SkLightingShader;
121 127
122 typedef SkShader INHERITED; 128 typedef SkShader INHERITED;
123 }; 129 };
124 130
125 //////////////////////////////////////////////////////////////////////////// 131 ////////////////////////////////////////////////////////////////////////////
126 132
127 #if SK_SUPPORT_GPU 133 #if SK_SUPPORT_GPU
128 134
129 #include "GrCoordTransform.h" 135 #include "GrCoordTransform.h"
130 #include "GrFragmentProcessor.h" 136 #include "GrFragmentProcessor.h"
131 #include "GrInvariantOutput.h" 137 #include "GrInvariantOutput.h"
132 #include "GrTextureAccess.h" 138 #include "GrTextureAccess.h"
133 #include "glsl/GrGLSLFragmentProcessor.h" 139 #include "glsl/GrGLSLFragmentProcessor.h"
134 #include "glsl/GrGLSLFragmentShaderBuilder.h" 140 #include "glsl/GrGLSLFragmentShaderBuilder.h"
135 #include "glsl/GrGLSLProgramDataManager.h" 141 #include "glsl/GrGLSLProgramDataManager.h"
136 #include "glsl/GrGLSLUniformHandler.h" 142 #include "glsl/GrGLSLUniformHandler.h"
137 #include "SkGr.h" 143 #include "SkGr.h"
138 #include "SkGrPriv.h" 144 #include "SkGrPriv.h"
139 145
140 class LightingFP : public GrFragmentProcessor { 146 class LightingFP : public GrFragmentProcessor {
141 public: 147 public:
142 LightingFP(GrTexture* diffuse, GrTexture* normal, const SkMatrix& diffMatrix , 148 LightingFP(GrTexture* diffuse, const SkMatrix& diffMatrix, const GrTexturePa rams& diffParams,
143 const SkMatrix& normMatrix, const GrTextureParams& diffParams, 149 sk_sp<SkLights> lights, sk_sp<GrFragmentProcessor> normalFP)
144 const GrTextureParams& normParams, sk_sp<SkLights> lights,
145 const SkVector& invNormRotation)
146 : fDiffDeviceTransform(kLocal_GrCoordSet, diffMatrix, diffuse, diffParam s.filterMode()) 150 : fDiffDeviceTransform(kLocal_GrCoordSet, diffMatrix, diffuse, diffParam s.filterMode())
147 , fNormDeviceTransform(kLocal_GrCoordSet, normMatrix, normal, normParams .filterMode()) 151 , fDiffuseTextureAccess(diffuse, diffParams) {
148 , fDiffuseTextureAccess(diffuse, diffParams)
149 , fNormalTextureAccess(normal, normParams)
150 , fInvNormRotation(invNormRotation) {
151 this->addCoordTransform(&fDiffDeviceTransform); 152 this->addCoordTransform(&fDiffDeviceTransform);
152 this->addCoordTransform(&fNormDeviceTransform);
153 this->addTextureAccess(&fDiffuseTextureAccess); 153 this->addTextureAccess(&fDiffuseTextureAccess);
154 this->addTextureAccess(&fNormalTextureAccess);
155 154
156 // fuse all ambient lights into a single one 155 // fuse all ambient lights into a single one
157 fAmbientColor.set(0.0f, 0.0f, 0.0f); 156 fAmbientColor.set(0.0f, 0.0f, 0.0f);
158 for (int i = 0; i < lights->numLights(); ++i) { 157 for (int i = 0; i < lights->numLights(); ++i) {
159 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) { 158 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) {
160 fAmbientColor += lights->light(i).color(); 159 fAmbientColor += lights->light(i).color();
161 } else { 160 } else {
162 // TODO: handle more than one of these 161 // TODO: handle more than one of these
163 fLightColor = lights->light(i).color(); 162 fLightColor = lights->light(i).color();
164 fLightDir = lights->light(i).dir(); 163 fLightDir = lights->light(i).dir();
165 } 164 }
166 } 165 }
167 166
167 this->registerChildProcessor(std::move(normalFP));
168 this->initClassID<LightingFP>(); 168 this->initClassID<LightingFP>();
169 } 169 }
170 170
171 class LightingGLFP : public GrGLSLFragmentProcessor { 171 class GLSLLightingFP : public GrGLSLFragmentProcessor {
172 public: 172 public:
173 LightingGLFP() { 173 GLSLLightingFP() {
174 fLightDir.fX = 10000.0f; 174 fLightDir.fX = 10000.0f;
175 fLightColor.fX = 0.0f; 175 fLightColor.fX = 0.0f;
176 fAmbientColor.fX = 0.0f; 176 fAmbientColor.fX = 0.0f;
177 fInvNormRotation.set(0.0f, 0.0f);
178 } 177 }
179 178
180 void emitCode(EmitArgs& args) override { 179 void emitCode(EmitArgs& args) override {
181 180
182 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; 181 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
183 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 182 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
184 183
185 // add uniforms 184 // add uniforms
186 const char* lightDirUniName = nullptr; 185 const char* lightDirUniName = nullptr;
187 fLightDirUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 186 fLightDirUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
188 kVec3f_GrSLType, kDefault_ GrSLPrecision, 187 kVec3f_GrSLType, kDefault_ GrSLPrecision,
189 "LightDir", &lightDirUniNa me); 188 "LightDir", &lightDirUniNa me);
190 189
191 const char* lightColorUniName = nullptr; 190 const char* lightColorUniName = nullptr;
192 fLightColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 191 fLightColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
193 kVec3f_GrSLType, kDefaul t_GrSLPrecision, 192 kVec3f_GrSLType, kDefaul t_GrSLPrecision,
194 "LightColor", &lightColo rUniName); 193 "LightColor", &lightColo rUniName);
195 194
196 const char* ambientColorUniName = nullptr; 195 const char* ambientColorUniName = nullptr;
197 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag , 196 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag ,
198 kVec3f_GrSLType, kDefa ult_GrSLPrecision, 197 kVec3f_GrSLType, kDefa ult_GrSLPrecision,
199 "AmbientColor", &ambie ntColorUniName); 198 "AmbientColor", &ambie ntColorUniName);
200 199
201 const char* xformUniName = nullptr;
202 fXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
203 kVec2f_GrSLType, kDefault_GrS LPrecision,
204 "Xform", &xformUniName);
205
206 fragBuilder->codeAppend("vec4 diffuseColor = "); 200 fragBuilder->codeAppend("vec4 diffuseColor = ");
207 fragBuilder->appendTextureLookupAndModulate(args.fInputColor, args.f TexSamplers[0], 201 fragBuilder->appendTextureLookupAndModulate(args.fInputColor, args.f TexSamplers[0],
208 args.fCoords[0].c_str(), 202 args.fCoords[0].c_str(),
209 args.fCoords[0].getType()); 203 args.fCoords[0].getType());
210 fragBuilder->codeAppend(";"); 204 fragBuilder->codeAppend(";");
211 205
212 fragBuilder->codeAppend("vec4 normalColor = "); 206 SkString dstNormalName("dstNormal");
213 fragBuilder->appendTextureLookup(args.fTexSamplers[1], 207 this->emitChild(0, nullptr, &dstNormalName, args);
214 args.fCoords[1].c_str(),
215 args.fCoords[1].getType());
216 fragBuilder->codeAppend(";");
217 208
218 fragBuilder->codeAppend("vec3 normal = normalColor.rgb - vec3(0.5);" ); 209 fragBuilder->codeAppendf("vec3 normal = %s.xyz;", dstNormalName.c_st r());
219
220 fragBuilder->codeAppendf(
221 "mat3 m = mat3(%s.x, -%s.y, 0.0, %s.y, %s.x, 0. 0, 0.0, 0.0, 1.0);",
222 xformUniName, xformUniName, xformUniName, xform UniName);
223
224 // TODO: inverse map the light direction vectors in the vertex shade r rather than
225 // transforming all the normals here!
226 fragBuilder->codeAppend("normal = normalize(m*normal);");
227
228 fragBuilder->codeAppendf("float NdotL = clamp(dot(normal, %s), 0.0, 1.0);", 210 fragBuilder->codeAppendf("float NdotL = clamp(dot(normal, %s), 0.0, 1.0);",
229 lightDirUniName); 211 lightDirUniName);
230 // diffuse light 212 // diffuse light
231 fragBuilder->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightColorUniName); 213 fragBuilder->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightColorUniName);
232 // ambient light 214 // ambient light
233 fragBuilder->codeAppendf("result += %s;", ambientColorUniName); 215 fragBuilder->codeAppendf("result += %s;", ambientColorUniName);
234 fragBuilder->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", a rgs.fOutputColor); 216 fragBuilder->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", a rgs.fOutputColor);
235 } 217 }
236 218
237 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, 219 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
(...skipping 17 matching lines...) Expand all
255 if (lightColor != fLightColor) { 237 if (lightColor != fLightColor) {
256 pdman.set3fv(fLightColorUni, 1, &lightColor.fX); 238 pdman.set3fv(fLightColorUni, 1, &lightColor.fX);
257 fLightColor = lightColor; 239 fLightColor = lightColor;
258 } 240 }
259 241
260 const SkColor3f& ambientColor = lightingFP.ambientColor(); 242 const SkColor3f& ambientColor = lightingFP.ambientColor();
261 if (ambientColor != fAmbientColor) { 243 if (ambientColor != fAmbientColor) {
262 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); 244 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX);
263 fAmbientColor = ambientColor; 245 fAmbientColor = ambientColor;
264 } 246 }
265
266 const SkVector& invNormRotation = lightingFP.invNormRotation();
267 if (invNormRotation != fInvNormRotation) {
268 pdman.set2fv(fXformUni, 1, &invNormRotation.fX);
269 fInvNormRotation = invNormRotation;
270 }
271 } 247 }
272 248
273 private: 249 private:
274 SkVector3 fLightDir; 250 SkVector3 fLightDir;
275 GrGLSLProgramDataManager::UniformHandle fLightDirUni; 251 GrGLSLProgramDataManager::UniformHandle fLightDirUni;
276 252
277 SkColor3f fLightColor; 253 SkColor3f fLightColor;
278 GrGLSLProgramDataManager::UniformHandle fLightColorUni; 254 GrGLSLProgramDataManager::UniformHandle fLightColorUni;
279 255
280 SkColor3f fAmbientColor; 256 SkColor3f fAmbientColor;
281 GrGLSLProgramDataManager::UniformHandle fAmbientColorUni; 257 GrGLSLProgramDataManager::UniformHandle fAmbientColorUni;
282
283 SkVector fInvNormRotation;
284 GrGLSLProgramDataManager::UniformHandle fXformUni;
285 }; 258 };
286 259
287 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { 260 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
288 LightingGLFP::GenKey(*this, caps, b); 261 GLSLLightingFP::GenKey(*this, caps, b);
289 } 262 }
290 263
291 const char* name() const override { return "LightingFP"; } 264 const char* name() const override { return "LightingFP"; }
292 265
293 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 266 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
294 inout->mulByUnknownFourComponents(); 267 inout->mulByUnknownFourComponents();
295 } 268 }
296 269
297 const SkVector3& lightDir() const { return fLightDir; } 270 const SkVector3& lightDir() const { return fLightDir; }
298 const SkColor3f& lightColor() const { return fLightColor; } 271 const SkColor3f& lightColor() const { return fLightColor; }
299 const SkColor3f& ambientColor() const { return fAmbientColor; } 272 const SkColor3f& ambientColor() const { return fAmbientColor; }
300 const SkVector& invNormRotation() const { return fInvNormRotation; }
301 273
302 private: 274 private:
303 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new LightingGLFP; } 275 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLLightingFP; }
304 276
305 bool onIsEqual(const GrFragmentProcessor& proc) const override { 277 bool onIsEqual(const GrFragmentProcessor& proc) const override {
306 const LightingFP& lightingFP = proc.cast<LightingFP>(); 278 const LightingFP& lightingFP = proc.cast<LightingFP>();
307 return fDiffDeviceTransform == lightingFP.fDiffDeviceTransform && 279 return fDiffDeviceTransform == lightingFP.fDiffDeviceTransform &&
308 fNormDeviceTransform == lightingFP.fNormDeviceTransform &&
309 fDiffuseTextureAccess == lightingFP.fDiffuseTextureAccess && 280 fDiffuseTextureAccess == lightingFP.fDiffuseTextureAccess &&
310 fNormalTextureAccess == lightingFP.fNormalTextureAccess &&
311 fLightDir == lightingFP.fLightDir && 281 fLightDir == lightingFP.fLightDir &&
312 fLightColor == lightingFP.fLightColor && 282 fLightColor == lightingFP.fLightColor &&
313 fAmbientColor == lightingFP.fAmbientColor && 283 fAmbientColor == lightingFP.fAmbientColor;
314 fInvNormRotation == lightingFP.fInvNormRotation;
315 } 284 }
316 285
317 GrCoordTransform fDiffDeviceTransform; 286 GrCoordTransform fDiffDeviceTransform;
318 GrCoordTransform fNormDeviceTransform;
319 GrTextureAccess fDiffuseTextureAccess; 287 GrTextureAccess fDiffuseTextureAccess;
320 GrTextureAccess fNormalTextureAccess;
321 SkVector3 fLightDir; 288 SkVector3 fLightDir;
322 SkColor3f fLightColor; 289 SkColor3f fLightColor;
323 SkColor3f fAmbientColor; 290 SkColor3f fAmbientColor;
324
325 SkVector fInvNormRotation;
326 }; 291 };
327 292
328 //////////////////////////////////////////////////////////////////////////// 293 ////////////////////////////////////////////////////////////////////////////
329 294
330 static bool make_mat(const SkBitmap& bm, 295 static bool make_mat(const SkBitmap& bm,
331 const SkMatrix& localMatrix1, 296 const SkMatrix& localMatrix1,
332 const SkMatrix* localMatrix2, 297 const SkMatrix* localMatrix2,
333 SkMatrix* result) { 298 SkMatrix* result) {
334 299
335 result->setIDiv(bm.width(), bm.height()); 300 result->setIDiv(bm.width(), bm.height());
(...skipping 14 matching lines...) Expand all
350 return true; 315 return true;
351 } 316 }
352 317
353 sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor( 318 sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor(
354 GrContext* context, 319 GrContext* context,
355 const SkMatrix& viewM, 320 const SkMatrix& viewM,
356 const SkMatrix* localMatrix , 321 const SkMatrix* localMatrix ,
357 SkFilterQuality filterQuali ty, 322 SkFilterQuality filterQuali ty,
358 SkSourceGammaTreatment gamm aTreatment) const { 323 SkSourceGammaTreatment gamm aTreatment) const {
359 // we assume diffuse and normal maps have same width and height 324 // we assume diffuse and normal maps have same width and height
360 // TODO: support different sizes 325 // TODO: support different sizes, will be addressed when diffuse maps are fa ctored out of
326 // SkLightingShader in a future CL
361 SkASSERT(fDiffuseMap.width() == fNormalMap.width() && 327 SkASSERT(fDiffuseMap.width() == fNormalMap.width() &&
362 fDiffuseMap.height() == fNormalMap.height()); 328 fDiffuseMap.height() == fNormalMap.height());
363 SkMatrix diffM, normM; 329 SkMatrix diffM;
364 330
365 if (!make_mat(fDiffuseMap, this->getLocalMatrix(), localMatrix, &diffM)) { 331 if (!make_mat(fDiffuseMap, this->getLocalMatrix(), localMatrix, &diffM)) {
366 return nullptr; 332 return nullptr;
367 } 333 }
368 334
369 if (!make_mat(fNormalMap, fNormLocalMatrix, localMatrix, &normM)) {
370 return nullptr;
371 }
372
373 bool doBicubic; 335 bool doBicubic;
374 GrTextureParams::FilterMode diffFilterMode = GrSkFilterQualityToGrFilterMode ( 336 GrTextureParams::FilterMode diffFilterMode = GrSkFilterQualityToGrFilterMode (
375 SkTMin(filterQuality, kMedium_SkFilterQu ality), 337 SkTMin(filterQuality, kMediu m_SkFilterQuality),
376 viewM, 338 viewM,
377 this->getLocalMatrix(), 339 this->getLocalMatrix(),
378 &doBicubic); 340 &doBicubic);
379 SkASSERT(!doBicubic);
380
381 GrTextureParams::FilterMode normFilterMode = GrSkFilterQualityToGrFilterMode (
382 SkTMin(filterQuality, kMedium_SkFilterQu ality),
383 viewM,
384 fNormLocalMatrix,
385 &doBicubic);
386 SkASSERT(!doBicubic); 341 SkASSERT(!doBicubic);
387 342
388 // TODO: support other tile modes 343 // TODO: support other tile modes
389 GrTextureParams diffParams(kClamp_TileMode, diffFilterMode); 344 GrTextureParams diffParams(kClamp_TileMode, diffFilterMode);
390 SkAutoTUnref<GrTexture> diffuseTexture(GrRefCachedBitmapTexture(context, 345 SkAutoTUnref<GrTexture> diffuseTexture(GrRefCachedBitmapTexture(context, fDi ffuseMap,
391 fDiffuseMap, diffParams, 346 diffParams, gammaTreatment));
392 gammaTreatme nt));
393 if (!diffuseTexture) { 347 if (!diffuseTexture) {
394 SkErrorInternals::SetError(kInternalError_SkError, "Couldn't convert bit map to texture."); 348 SkErrorInternals::SetError(kInternalError_SkError, "Couldn't convert bit map to texture.");
395 return nullptr; 349 return nullptr;
396 } 350 }
397 351
398 GrTextureParams normParams(kClamp_TileMode, normFilterMode); 352 sk_sp<GrFragmentProcessor> normalFP(
399 SkAutoTUnref<GrTexture> normalTexture(GrRefCachedBitmapTexture(context, 353 fNormalSource->asFragmentProcessor(context, viewM, localMatrix, filt erQuality,
400 fNormalMap, n ormParams, 354 gammaTreatment));
401 gammaTreatmen t)); 355 sk_sp<GrFragmentProcessor> inner (
402 if (!normalTexture) { 356 new LightingFP(diffuseTexture, diffM, diffParams, fLights, std::move (normalFP)));
403 SkErrorInternals::SetError(kInternalError_SkError, "Couldn't convert bit map to texture.");
404 return nullptr;
405 }
406 357
407 sk_sp<GrFragmentProcessor> inner (
408 new LightingFP(diffuseTexture, normalTexture, diffM, normM, diffParams, normParams, fLights,
409 fInvNormRotation));
410 return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner)); 358 return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner));
411 } 359 }
412 360
413 #endif 361 #endif
414 362
415 //////////////////////////////////////////////////////////////////////////// 363 ////////////////////////////////////////////////////////////////////////////
416 364
417 bool SkLightingShaderImpl::isOpaque() const { 365 bool SkLightingShaderImpl::isOpaque() const {
418 return fDiffuseMap.isOpaque(); 366 return fDiffuseMap.isOpaque();
419 } 367 }
420 368
421 SkLightingShaderImpl::LightingShaderContext::LightingShaderContext(const SkLight ingShaderImpl& shader, 369 SkLightingShaderImpl::LightingShaderContext::LightingShaderContext(
422 const Context Rec& rec, 370 const SkLighting ShaderImpl& shader,
423 SkBitmapProcS tate* diffuseState, 371 const ContextRec & rec,
424 SkBitmapProcS tate* normalState) 372 SkBitmapProcStat e* diffuseState,
373 SkBitmapProcStat e* normalState)
425 : INHERITED(shader, rec) 374 : INHERITED(shader, rec)
426 , fDiffuseState(diffuseState) 375 , fDiffuseState(diffuseState)
427 , fNormalState(normalState) 376 , fNormalState(normalState) {
428 {
429 const SkPixmap& pixmap = fDiffuseState->fPixmap; 377 const SkPixmap& pixmap = fDiffuseState->fPixmap;
430 bool isOpaque = pixmap.isOpaque(); 378 bool isOpaque = pixmap.isOpaque();
431 379
432 // update fFlags 380 // update fFlags
433 uint32_t flags = 0; 381 uint32_t flags = 0;
434 if (isOpaque && (255 == this->getPaintAlpha())) { 382 if (isOpaque && (255 == this->getPaintAlpha())) {
435 flags |= kOpaqueAlpha_Flag; 383 flags |= kOpaqueAlpha_Flag;
436 } 384 }
437 385
438 fFlags = flags; 386 fFlags = flags;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 } 556 }
609 } 557 }
610 558
611 sk_sp<SkLights> lights(builder.finish()); 559 sk_sp<SkLights> lights(builder.finish());
612 560
613 SkVector invNormRotation = {1,0}; 561 SkVector invNormRotation = {1,0};
614 if (!buf.isVersionLT(SkReadBuffer::kLightingShaderWritesInvNormRotation)) { 562 if (!buf.isVersionLT(SkReadBuffer::kLightingShaderWritesInvNormRotation)) {
615 invNormRotation = buf.readPoint(); 563 invNormRotation = buf.readPoint();
616 } 564 }
617 565
566 sk_sp<SkLightingShader::NormalSource> normalSource(
567 buf.readFlattenable<SkLightingShader::NormalSource>());
568
618 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), invNormRotation, 569 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), invNormRotation,
619 &diffLocalM, &normLocalM); 570 &diffLocalM, &normLocalM, std::move( normalSource));
620 } 571 }
621 572
622 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { 573 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const {
623 this->INHERITED::flatten(buf); 574 this->INHERITED::flatten(buf);
624 575
625 bool hasNormLocalM = !fNormLocalMatrix.isIdentity(); 576 bool hasNormLocalM = !fNormLocalMatrix.isIdentity();
626 buf.writeBool(hasNormLocalM); 577 buf.writeBool(hasNormLocalM);
627 if (hasNormLocalM) { 578 if (hasNormLocalM) {
628 buf.writeMatrix(fNormLocalMatrix); 579 buf.writeMatrix(fNormLocalMatrix);
629 } 580 }
630 581
631 buf.writeBitmap(fDiffuseMap); 582 buf.writeBitmap(fDiffuseMap);
632 buf.writeBitmap(fNormalMap); 583 buf.writeBitmap(fNormalMap);
633 584
634 buf.writeInt(fLights->numLights()); 585 buf.writeInt(fLights->numLights());
635 for (int l = 0; l < fLights->numLights(); ++l) { 586 for (int l = 0; l < fLights->numLights(); ++l) {
636 const SkLights::Light& light = fLights->light(l); 587 const SkLights::Light& light = fLights->light(l);
637 588
638 bool isAmbient = SkLights::Light::kAmbient_LightType == light.type(); 589 bool isAmbient = SkLights::Light::kAmbient_LightType == light.type();
639 590
640 buf.writeBool(isAmbient); 591 buf.writeBool(isAmbient);
641 buf.writeScalarArray(&light.color().fX, 3); 592 buf.writeScalarArray(&light.color().fX, 3);
642 if (!isAmbient) { 593 if (!isAmbient) {
643 buf.writeScalarArray(&light.dir().fX, 3); 594 buf.writeScalarArray(&light.dir().fX, 3);
644 } 595 }
645 } 596 }
646 buf.writePoint(fInvNormRotation); 597 buf.writePoint(fInvNormRotation);
598
599 buf.writeFlattenable(fNormalSource.get());
647 } 600 }
648 601
649 bool SkLightingShaderImpl::computeNormTotalInverse(const ContextRec& rec, 602 bool SkLightingShaderImpl::computeNormTotalInverse(const ContextRec& rec,
650 SkMatrix* normTotalInverse) c onst { 603 SkMatrix* normTotalInverse) c onst {
651 SkMatrix total; 604 SkMatrix total;
652 total.setConcat(*rec.fMatrix, fNormLocalMatrix); 605 total.setConcat(*rec.fMatrix, fNormLocalMatrix);
653 606
654 const SkMatrix* m = &total; 607 const SkMatrix* m = &total;
655 if (rec.fLocalMatrix) { 608 if (rec.fLocalMatrix) {
656 total.setConcat(*m, *rec.fLocalMatrix); 609 total.setConcat(*m, *rec.fLocalMatrix);
(...skipping 21 matching lines...) Expand all
678 void* diffuseStateStorage = (char*)storage + sizeof(LightingShaderContext); 631 void* diffuseStateStorage = (char*)storage + sizeof(LightingShaderContext);
679 SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcStat e(fDiffuseMap, 632 SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcStat e(fDiffuseMap,
680 SkShader::kClamp_TileMode, SkShade r::kClamp_TileMode, 633 SkShader::kClamp_TileMode, SkShade r::kClamp_TileMode,
681 SkMipMap::De duceTreatment(rec)); 634 SkMipMap::De duceTreatment(rec));
682 SkASSERT(diffuseState); 635 SkASSERT(diffuseState);
683 if (!diffuseState->setup(diffTotalInv, *rec.fPaint)) { 636 if (!diffuseState->setup(diffTotalInv, *rec.fPaint)) {
684 diffuseState->~SkBitmapProcState(); 637 diffuseState->~SkBitmapProcState();
685 return nullptr; 638 return nullptr;
686 } 639 }
687 640
688 void* normalStateStorage = (char*)storage + sizeof(LightingShaderContext) + sizeof(SkBitmapProcState); 641 void* normalStateStorage = (char*)storage +
642 sizeof(LightingShaderContext) +
643 sizeof(SkBitmapProcState);
689 SkBitmapProcState* normalState = new (normalStateStorage) SkBitmapProcState( fNormalMap, 644 SkBitmapProcState* normalState = new (normalStateStorage) SkBitmapProcState( fNormalMap,
690 SkShader::kClamp_TileMode, SkShader: :kClamp_TileMode, 645 SkShader::kClamp_TileMode, SkShader: :kClamp_TileMode,
691 SkMipMap::De duceTreatment(rec)); 646 SkMipMap::De duceTreatment(rec));
692 SkASSERT(normalState); 647 SkASSERT(normalState);
693 if (!normalState->setup(normTotalInv, *rec.fPaint)) { 648 if (!normalState->setup(normTotalInv, *rec.fPaint)) {
694 diffuseState->~SkBitmapProcState(); 649 diffuseState->~SkBitmapProcState();
695 normalState->~SkBitmapProcState(); 650 normalState->~SkBitmapProcState();
696 return nullptr; 651 return nullptr;
697 } 652 }
698 653
699 return new (storage) LightingShaderContext(*this, rec, diffuseState, normalS tate); 654 return new (storage) LightingShaderContext(*this, rec, diffuseState, normalS tate);
700 } 655 }
701 656
702 /////////////////////////////////////////////////////////////////////////////// 657 ///////////////////////////////////////////////////////////////////////////////
703 658
704 static bool bitmap_is_too_big(const SkBitmap& bm) {
705 // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it
706 // communicates between its matrix-proc and its sampler-proc. Until we can
707 // widen that, we have to reject bitmaps that are larger.
708 //
709 static const int kMaxSize = 65535;
710
711 return bm.width() > kMaxSize || bm.height() > kMaxSize;
712 }
713
714 sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, const SkBitmap& normal, 659 sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, const SkBitmap& normal,
715 sk_sp<SkLights> lights, 660 sk_sp<SkLights> lights,
716 const SkVector& invNormRotation, 661 const SkVector& invNormRotation,
717 const SkMatrix* diffLocalM, const SkMatri x* normLocalM) { 662 const SkMatrix* diffLocalM, const SkMatri x* normLocalM) {
718 if (diffuse.isNull() || bitmap_is_too_big(diffuse) || 663 if (diffuse.isNull() || SkBitmapProcShader::BitmapIsTooBig(diffuse) ||
719 normal.isNull() || bitmap_is_too_big(normal) || 664 normal.isNull() || SkBitmapProcShader::BitmapIsTooBig(normal) ||
720 diffuse.width() != normal.width() || 665 diffuse.width() != normal.width() ||
721 diffuse.height() != normal.height()) { 666 diffuse.height() != normal.height()) {
722 return nullptr; 667 return nullptr;
723 } 668 }
724
725 SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1)); 669 SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1));
726 670
671 sk_sp<SkLightingShader::NormalSource> normalSource =
672 SkLightingShader::NormalSource::MakeMap(normal, invNormRotation, nor mLocalM);
673
727 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), 674 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights),
728 invNormRotation, diffLocalM, normLoc alM); 675 invNormRotation, diffLocalM, normLocalM, std::move(normalSource));
729 } 676 }
730 677
731 /////////////////////////////////////////////////////////////////////////////// 678 ///////////////////////////////////////////////////////////////////////////////
732 679
733 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) 680 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader)
734 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) 681 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl)
735 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 682 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
736 683
737 /////////////////////////////////////////////////////////////////////////////// 684 ///////////////////////////////////////////////////////////////////////////////
OLDNEW
« no previous file with comments | « src/core/SkLightingShader.h ('k') | src/core/SkLightingShader_NormalSource.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698