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

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

Issue 1265983003: Address some SkLightingShader TODOs (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix type Created 5 years, 4 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/effects/SkLightingShader.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
1 1
2 /* 2 /*
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkBitmapProcState.h" 9 #include "SkBitmapProcState.h"
10 #include "SkColor.h" 10 #include "SkColor.h"
11 #include "SkEmptyShader.h" 11 #include "SkEmptyShader.h"
12 #include "SkErrorInternals.h" 12 #include "SkErrorInternals.h"
13 #include "SkLightingShader.h" 13 #include "SkLightingShader.h"
14 #include "SkMathPriv.h" 14 #include "SkMathPriv.h"
15 #include "SkReadBuffer.h" 15 #include "SkReadBuffer.h"
16 #include "SkWriteBuffer.h" 16 #include "SkWriteBuffer.h"
17 17
18 //////////////////////////////////////////////////////////////////////////// 18 ////////////////////////////////////////////////////////////////////////////
19 19
20 /* 20 /*
21 SkLightingShader TODOs: 21 SkLightingShader TODOs:
22 support other than clamp mode 22 support other than clamp mode
23 allow 'diffuse' & 'normal' to be of different dimensions? 23 allow 'diffuse' & 'normal' to be of different dimensions?
24 support different light types 24 support different light types
25 support multiple lights 25 support multiple lights
26 enforce normal map is 4 channel 26 enforce normal map is 4 channel
27 use SkImages instead if SkBitmaps 27 use SkImages instead if SkBitmaps
28 vec3 for ambient and light-color
29 add dox for both lighting equation, and how we compute normal from bitma p
30 28
31 To Test: 29 To Test:
32 non-opaque diffuse textures 30 non-opaque diffuse textures
33 A8 diffuse textures 31 A8 diffuse textures
34 down & upsampled draws 32 down & upsampled draws
35 */ 33 */
36 34
37 35
38 36
39 /** \class SkLightingShaderImpl 37 /** \class SkLightingShaderImpl
40 This subclass of shader applies lighting. 38 This subclass of shader applies lighting.
41 */ 39 */
42 class SK_API SkLightingShaderImpl : public SkShader { 40 class SK_API SkLightingShaderImpl : public SkShader {
43 public: 41 public:
44 42
45 /** Create a new lighting shader that use the provided normal map, light 43 /** Create a new lighting shader that use the provided normal map, light
46 and ambient color to light the diffuse bitmap. 44 and ambient color to light the diffuse bitmap.
47 @param diffuse the diffuse bitmap 45 @param diffuse the diffuse bitmap
48 @param normal the normal map 46 @param normal the normal map
49 @param light the light applied to the normal map 47 @param light the light applied to the normal map
50 @param ambient the linear (unpremul) ambient light color 48 @param ambient the linear (unpremul) ambient light color
51 */ 49 */
52 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal, 50 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal,
53 const SkLightingShader::Light& light, 51 const SkLightingShader::Light& light,
54 const SkColor ambient, const SkMatrix* localMatrix) 52 const SkColor3f& ambient, const SkMatrix* localMatrix)
55 : INHERITED(localMatrix) 53 : INHERITED(localMatrix)
56 , fDiffuseMap(diffuse) 54 , fDiffuseMap(diffuse)
57 , fNormalMap(normal) 55 , fNormalMap(normal)
58 , fLight(light) 56 , fLight(light)
59 , fAmbientColor(ambient) { 57 , fAmbientColor(ambient) {
60 if (!fLight.fDirection.normalize()) { 58 if (!fLight.fDirection.normalize()) {
61 fLight.fDirection = SkPoint3::Make(0.0f, 0.0f, 1.0f); 59 fLight.fDirection = SkPoint3::Make(0.0f, 0.0f, 1.0f);
62 } 60 }
63 SkColorSetA(fLight.fColor, 0xFF);
64 SkColorSetA(fAmbientColor, 0xFF);
65 } 61 }
66 62
67 bool isOpaque() const override; 63 bool isOpaque() const override;
68 64
69 bool asFragmentProcessor(GrContext*, const SkPaint& paint, const SkMatrix& v iewM, 65 bool asFragmentProcessor(GrContext*, const SkPaint& paint, const SkMatrix& v iewM,
70 const SkMatrix* localMatrix, GrColor* color, 66 const SkMatrix* localMatrix, GrColor* color,
71 GrProcessorDataManager*, GrFragmentProcessor** fp) const override; 67 GrProcessorDataManager*, GrFragmentProcessor** fp) const override;
72 68
73 size_t contextSize() const override; 69 size_t contextSize() const override;
74 70
(...skipping 21 matching lines...) Expand all
96 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl) 92 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl)
97 93
98 protected: 94 protected:
99 void flatten(SkWriteBuffer&) const override; 95 void flatten(SkWriteBuffer&) const override;
100 Context* onCreateContext(const ContextRec&, void*) const override; 96 Context* onCreateContext(const ContextRec&, void*) const override;
101 97
102 private: 98 private:
103 SkBitmap fDiffuseMap; 99 SkBitmap fDiffuseMap;
104 SkBitmap fNormalMap; 100 SkBitmap fNormalMap;
105 SkLightingShader::Light fLight; 101 SkLightingShader::Light fLight;
106 SkColor fAmbientColor; // linear (unpremul) color 102 SkColor3f fAmbientColor; // linear (unpremul) color. Range is 0..1/channel.
107 103
108 friend class SkLightingShader; 104 friend class SkLightingShader;
109 105
110 typedef SkShader INHERITED; 106 typedef SkShader INHERITED;
111 }; 107 };
112 108
113 //////////////////////////////////////////////////////////////////////////// 109 ////////////////////////////////////////////////////////////////////////////
114 110
115 #if SK_SUPPORT_GPU 111 #if SK_SUPPORT_GPU
116 112
117 #include "GrCoordTransform.h" 113 #include "GrCoordTransform.h"
118 #include "GrFragmentProcessor.h" 114 #include "GrFragmentProcessor.h"
119 #include "GrTextureAccess.h" 115 #include "GrTextureAccess.h"
120 #include "gl/GrGLProcessor.h" 116 #include "gl/GrGLProcessor.h"
121 #include "gl/builders/GrGLProgramBuilder.h" 117 #include "gl/builders/GrGLProgramBuilder.h"
122 #include "SkGr.h" 118 #include "SkGr.h"
123 119
124 class LightingFP : public GrFragmentProcessor { 120 class LightingFP : public GrFragmentProcessor {
125 public: 121 public:
126 LightingFP(GrTexture* diffuse, GrTexture* normal, const SkMatrix& matrix, 122 LightingFP(GrTexture* diffuse, GrTexture* normal, const SkMatrix& matrix,
127 SkVector3 lightDir, GrColor lightColor, GrColor ambientColor) 123 const SkVector3& lightDir, const SkColor3f& lightColor,
124 const SkColor3f& ambientColor)
128 : fDeviceTransform(kDevice_GrCoordSet, matrix) 125 : fDeviceTransform(kDevice_GrCoordSet, matrix)
129 , fDiffuseTextureAccess(diffuse) 126 , fDiffuseTextureAccess(diffuse)
130 , fNormalTextureAccess(normal) 127 , fNormalTextureAccess(normal)
131 , fLightDir(lightDir) 128 , fLightDir(lightDir)
132 , fLightColor(lightColor) 129 , fLightColor(lightColor)
133 , fAmbientColor(ambientColor) { 130 , fAmbientColor(ambientColor) {
134 this->addCoordTransform(&fDeviceTransform); 131 this->addCoordTransform(&fDeviceTransform);
135 this->addTextureAccess(&fDiffuseTextureAccess); 132 this->addTextureAccess(&fDiffuseTextureAccess);
136 this->addTextureAccess(&fNormalTextureAccess); 133 this->addTextureAccess(&fNormalTextureAccess);
137 134
138 this->initClassID<LightingFP>(); 135 this->initClassID<LightingFP>();
139 } 136 }
140 137
141 class LightingGLFP : public GrGLFragmentProcessor { 138 class LightingGLFP : public GrGLFragmentProcessor {
142 public: 139 public:
143 LightingGLFP() : fLightColor(GrColor_ILLEGAL), fAmbientColor(GrColor_ILL EGAL) { 140 LightingGLFP() {
144 fLightDir.fX = 10000.0f; 141 fLightDir.fX = 10000.0f;
142 fLightColor.fX = 0.0f;
143 fAmbientColor.fX = 0.0f;
145 } 144 }
146 145
147 void emitCode(EmitArgs& args) override { 146 void emitCode(EmitArgs& args) override {
148 147
149 GrGLFragmentBuilder* fpb = args.fBuilder->getFragmentShaderBuilder() ; 148 GrGLFragmentBuilder* fpb = args.fBuilder->getFragmentShaderBuilder() ;
150 149
151 // add uniforms 150 // add uniforms
152 const char* lightDirUniName = NULL; 151 const char* lightDirUniName = NULL;
153 fLightDirUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragme nt_Visibility, 152 fLightDirUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragme nt_Visibility,
154 kVec3f_GrSLType, kDefault_G rSLPrecision, 153 kVec3f_GrSLType, kDefault_G rSLPrecision,
155 "LightDir", &lightDirUniNam e); 154 "LightDir", &lightDirUniNam e);
156 155
157 const char* lightColorUniName = NULL; 156 const char* lightColorUniName = NULL;
158 fLightColorUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFrag ment_Visibility, 157 fLightColorUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFrag ment_Visibility,
159 kVec4f_GrSLType, kDefault _GrSLPrecision, 158 kVec3f_GrSLType, kDefault _GrSLPrecision,
160 "LightColor", &lightColor UniName); 159 "LightColor", &lightColor UniName);
161 160
162 const char* ambientColorUniName = NULL; 161 const char* ambientColorUniName = NULL;
163 fAmbientColorUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFr agment_Visibility, 162 fAmbientColorUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFr agment_Visibility,
164 kVec4f_GrSLType, kDefau lt_GrSLPrecision, 163 kVec3f_GrSLType, kDefau lt_GrSLPrecision,
165 "AmbientColor", &ambien tColorUniName); 164 "AmbientColor", &ambien tColorUniName);
166 165
167 fpb->codeAppend("vec4 diffuseColor = "); 166 fpb->codeAppend("vec4 diffuseColor = ");
168 fpb->appendTextureLookupAndModulate(args.fInputColor, args.fSamplers [0], 167 fpb->appendTextureLookupAndModulate(args.fInputColor, args.fSamplers [0],
169 args.fCoords[0].c_str(), 168 args.fCoords[0].c_str(),
170 args.fCoords[0].getType()); 169 args.fCoords[0].getType());
171 fpb->codeAppend(";"); 170 fpb->codeAppend(";");
172 171
173 fpb->codeAppend("vec4 normalColor = "); 172 fpb->codeAppend("vec4 normalColor = ");
174 fpb->appendTextureLookup(args.fSamplers[1], 173 fpb->appendTextureLookup(args.fSamplers[1],
175 args.fCoords[0].c_str(), 174 args.fCoords[0].c_str(),
176 args.fCoords[0].getType()); 175 args.fCoords[0].getType());
177 fpb->codeAppend(";"); 176 fpb->codeAppend(";");
178 177
179 fpb->codeAppend("vec3 normal = normalize(normalColor.rgb - vec3(0.5) );"); 178 fpb->codeAppend("vec3 normal = normalize(normalColor.rgb - vec3(0.5) );");
180 fpb->codeAppendf("vec3 lightDir = normalize(%s);", lightDirUniName); 179 fpb->codeAppendf("vec3 lightDir = normalize(%s);", lightDirUniName);
181 fpb->codeAppend("float NdotL = dot(normal, lightDir);"); 180 fpb->codeAppend("float NdotL = dot(normal, lightDir);");
182 // diffuse light 181 // diffuse light
183 fpb->codeAppendf("vec3 result = %s.rgb*diffuseColor.rgb*NdotL;", lig htColorUniName); 182 fpb->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightCo lorUniName);
184 // ambient light 183 // ambient light
185 fpb->codeAppendf("result += %s.rgb;", ambientColorUniName); 184 fpb->codeAppendf("result += %s;", ambientColorUniName);
186 fpb->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", args.fOut putColor); 185 fpb->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", args.fOut putColor);
187 } 186 }
188 187
189 void setData(const GrGLProgramDataManager& pdman, const GrProcessor& pro c) override { 188 void setData(const GrGLProgramDataManager& pdman, const GrProcessor& pro c) override {
190 const LightingFP& lightingFP = proc.cast<LightingFP>(); 189 const LightingFP& lightingFP = proc.cast<LightingFP>();
191 190
192 SkVector3 lightDir = lightingFP.lightDir(); 191 const SkVector3& lightDir = lightingFP.lightDir();
193 if (lightDir != fLightDir) { 192 if (lightDir != fLightDir) {
194 pdman.set3fv(fLightDirUni, 1, &lightDir.fX); 193 pdman.set3fv(fLightDirUni, 1, &lightDir.fX);
195 fLightDir = lightDir; 194 fLightDir = lightDir;
196 } 195 }
197 196
198 GrColor lightColor = lightingFP.lightColor(); 197 const SkColor3f& lightColor = lightingFP.lightColor();
199 if (lightColor != fLightColor) { 198 if (lightColor != fLightColor) {
200 GrGLfloat c[4]; 199 pdman.set3fv(fLightColorUni, 1, &lightColor.fX);
201 GrColorToRGBAFloat(lightColor, c);
202 pdman.set4fv(fLightColorUni, 1, c);
203 fLightColor = lightColor; 200 fLightColor = lightColor;
204 } 201 }
205 202
206 GrColor ambientColor = lightingFP.ambientColor(); 203 const SkColor3f& ambientColor = lightingFP.ambientColor();
207 if (ambientColor != fAmbientColor) { 204 if (ambientColor != fAmbientColor) {
208 GrGLfloat c[4]; 205 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX);
209 GrColorToRGBAFloat(ambientColor, c);
210 pdman.set4fv(fAmbientColorUni, 1, c);
211 fAmbientColor = ambientColor; 206 fAmbientColor = ambientColor;
212 } 207 }
213 } 208 }
214 209
215 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, 210 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
216 GrProcessorKeyBuilder* b) { 211 GrProcessorKeyBuilder* b) {
217 // const LightingFP& lightingFP = proc.cast<LightingFP>(); 212 // const LightingFP& lightingFP = proc.cast<LightingFP>();
218 // only one shader generated currently 213 // only one shader generated currently
219 b->add32(0x0); 214 b->add32(0x0);
220 } 215 }
221 216
222 private: 217 private:
223 SkVector3 fLightDir; 218 SkVector3 fLightDir;
224 GrGLProgramDataManager::UniformHandle fLightDirUni; 219 GrGLProgramDataManager::UniformHandle fLightDirUni;
225 220
226 GrColor fLightColor; 221 SkColor3f fLightColor;
227 GrGLProgramDataManager::UniformHandle fLightColorUni; 222 GrGLProgramDataManager::UniformHandle fLightColorUni;
228 223
229 GrColor fAmbientColor; 224 SkColor3f fAmbientColor;
230 GrGLProgramDataManager::UniformHandle fAmbientColorUni; 225 GrGLProgramDataManager::UniformHandle fAmbientColorUni;
231 }; 226 };
232 227
233 GrGLFragmentProcessor* createGLInstance() const override { return SkNEW(Ligh tingGLFP); } 228 GrGLFragmentProcessor* createGLInstance() const override { return SkNEW(Ligh tingGLFP); }
234 229
235 void getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) con st override { 230 void getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) con st override {
236 LightingGLFP::GenKey(*this, caps, b); 231 LightingGLFP::GenKey(*this, caps, b);
237 } 232 }
238 233
239 const char* name() const override { return "LightingFP"; } 234 const char* name() const override { return "LightingFP"; }
240 235
241 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 236 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
242 inout->mulByUnknownFourComponents(); 237 inout->mulByUnknownFourComponents();
243 } 238 }
244 239
245 SkVector3 lightDir() const { return fLightDir; } 240 const SkVector3& lightDir() const { return fLightDir; }
246 GrColor lightColor() const { return fLightColor; } 241 const SkColor3f& lightColor() const { return fLightColor; }
247 GrColor ambientColor() const { return fAmbientColor; } 242 const SkColor3f& ambientColor() const { return fAmbientColor; }
248 243
249 private: 244 private:
250 bool onIsEqual(const GrFragmentProcessor& proc) const override { 245 bool onIsEqual(const GrFragmentProcessor& proc) const override {
251 const LightingFP& lightingFP = proc.cast<LightingFP>(); 246 const LightingFP& lightingFP = proc.cast<LightingFP>();
252 return fDeviceTransform == lightingFP.fDeviceTransform && 247 return fDeviceTransform == lightingFP.fDeviceTransform &&
253 fDiffuseTextureAccess == lightingFP.fDiffuseTextureAccess && 248 fDiffuseTextureAccess == lightingFP.fDiffuseTextureAccess &&
254 fNormalTextureAccess == lightingFP.fNormalTextureAccess && 249 fNormalTextureAccess == lightingFP.fNormalTextureAccess &&
255 fLightDir == lightingFP.fLightDir && 250 fLightDir == lightingFP.fLightDir &&
256 fLightColor == lightingFP.fLightColor && 251 fLightColor == lightingFP.fLightColor &&
257 fAmbientColor == lightingFP.fAmbientColor; 252 fAmbientColor == lightingFP.fAmbientColor;
258 } 253 }
259 254
260 GrCoordTransform fDeviceTransform; 255 GrCoordTransform fDeviceTransform;
261 GrTextureAccess fDiffuseTextureAccess; 256 GrTextureAccess fDiffuseTextureAccess;
262 GrTextureAccess fNormalTextureAccess; 257 GrTextureAccess fNormalTextureAccess;
263 SkVector3 fLightDir; 258 SkVector3 fLightDir;
264 GrColor fLightColor; 259 SkColor3f fLightColor;
265 GrColor fAmbientColor; 260 SkColor3f fAmbientColor;
266 }; 261 };
267 262
268 //////////////////////////////////////////////////////////////////////////// 263 ////////////////////////////////////////////////////////////////////////////
269 264
270 bool SkLightingShaderImpl::asFragmentProcessor(GrContext* context, const SkPaint & paint, 265 bool SkLightingShaderImpl::asFragmentProcessor(GrContext* context, const SkPaint & paint,
271 const SkMatrix& viewM, const SkMa trix* localMatrix, 266 const SkMatrix& viewM, const SkMa trix* localMatrix,
272 GrColor* color, GrProcessorDataMa nager*, 267 GrColor* color, GrProcessorDataMa nager*,
273 GrFragmentProcessor** fp) const { 268 GrFragmentProcessor** fp) const {
274 // we assume diffuse and normal maps have same width and height 269 // we assume diffuse and normal maps have same width and height
275 // TODO: support different sizes 270 // TODO: support different sizes
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 return false; 329 return false;
335 } 330 }
336 331
337 SkAutoTUnref<GrTexture> normalTexture(GrRefCachedBitmapTexture(context, fNor malMap, &params)); 332 SkAutoTUnref<GrTexture> normalTexture(GrRefCachedBitmapTexture(context, fNor malMap, &params));
338 if (!normalTexture) { 333 if (!normalTexture) {
339 SkErrorInternals::SetError(kInternalError_SkError, 334 SkErrorInternals::SetError(kInternalError_SkError,
340 "Couldn't convert bitmap to texture."); 335 "Couldn't convert bitmap to texture.");
341 return false; 336 return false;
342 } 337 }
343 338
344 GrColor lightColor = GrColorPackRGBA(SkColorGetR(fLight.fColor), SkColorGetG (fLight.fColor),
345 SkColorGetB(fLight.fColor), SkColorGetA (fLight.fColor));
346 GrColor ambientColor = GrColorPackRGBA(SkColorGetR(fAmbientColor), SkColorGe tG(fAmbientColor),
347 SkColorGetB(fAmbientColor), SkColorGe tA(fAmbientColor));
348
349 *fp = SkNEW_ARGS(LightingFP, (diffuseTexture, normalTexture, matrix, 339 *fp = SkNEW_ARGS(LightingFP, (diffuseTexture, normalTexture, matrix,
350 fLight.fDirection, lightColor, ambientColor)); 340 fLight.fDirection, fLight.fColor, fAmbientColo r));
351 *color = GrColorPackA4(paint.getAlpha()); 341 *color = GrColorPackA4(paint.getAlpha());
352 return true; 342 return true;
353 } 343 }
354 #else 344 #else
355 345
356 bool SkLightingShaderImpl::asFragmentProcessor(GrContext* context, const SkPaint & paint, 346 bool SkLightingShaderImpl::asFragmentProcessor(GrContext* context, const SkPaint & paint,
357 const SkMatrix& viewM, const SkMa trix* localMatrix, 347 const SkMatrix& viewM, const SkMa trix* localMatrix,
358 GrColor* color, GrProcessorDataMa nager*, 348 GrColor* color, GrProcessorDataMa nager*,
359 GrFragmentProcessor** fp) const { 349 GrFragmentProcessor** fp) const {
360 SkDEBUGFAIL("Should not call in GPU-less build"); 350 SkDEBUGFAIL("Should not call in GPU-less build");
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 fFlags = flags; 383 fFlags = flags;
394 } 384 }
395 385
396 SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() { 386 SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() {
397 // The bitmap proc states have been created outside of the context on memory that will be freed 387 // The bitmap proc states have been created outside of the context on memory that will be freed
398 // elsewhere. Call the destructors but leave the freeing of the memory to th e caller. 388 // elsewhere. Call the destructors but leave the freeing of the memory to th e caller.
399 fDiffuseState->~SkBitmapProcState(); 389 fDiffuseState->~SkBitmapProcState();
400 fNormalState->~SkBitmapProcState(); 390 fNormalState->~SkBitmapProcState();
401 } 391 }
402 392
403 static inline int light(int light, int diff, SkScalar NdotL, int ambient) { 393 static inline int light(SkScalar light, int diff, SkScalar NdotL, SkScalar ambie nt) {
404 int color = int(light * diff * NdotL + 255 * ambient); 394 SkScalar color = light * diff * NdotL + 255 * ambient;
405 if (color <= 0) { 395 if (color <= 0.0f) {
406 return 0; 396 return 0;
407 } else if (color >= 255*255) { 397 } else if (color >= 255.0f) {
408 return 255; 398 return 255;
409 } else { 399 } else {
410 return SkDiv255Round(color); 400 return (int) color;
411 } 401 }
412 } 402 }
413 403
414 // larger is better (fewer times we have to loop), but we shouldn't 404 // larger is better (fewer times we have to loop), but we shouldn't
415 // take up too much stack-space (each could here costs 16 bytes) 405 // take up too much stack-space (each could here costs 16 bytes)
416 #define TMP_COUNT 16 406 #define TMP_COUNT 16
417 407
418 void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y, 408 void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y,
419 SkPMColor result[], int count) { 409 SkPMColor result[], int count) {
420 const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShader Impl&>(fShader); 410 const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShader Impl&>(fShader);
(...skipping 30 matching lines...) Expand all
451 SkASSERT(0xFF == SkColorGetA(tmpNormal2[i])); // opaque -> unpremul 441 SkASSERT(0xFF == SkColorGetA(tmpNormal2[i])); // opaque -> unpremul
452 norm.set(SkIntToScalar(SkGetPackedR32(tmpNormal2[i]))-127.0f, 442 norm.set(SkIntToScalar(SkGetPackedR32(tmpNormal2[i]))-127.0f,
453 SkIntToScalar(SkGetPackedG32(tmpNormal2[i]))-127.0f, 443 SkIntToScalar(SkGetPackedG32(tmpNormal2[i]))-127.0f,
454 SkIntToScalar(SkGetPackedB32(tmpNormal2[i]))-127.0f); 444 SkIntToScalar(SkGetPackedB32(tmpNormal2[i]))-127.0f);
455 norm.normalize(); 445 norm.normalize();
456 446
457 SkColor diffColor = SkUnPreMultiply::PMColorToColor(tmpColor2[i]); 447 SkColor diffColor = SkUnPreMultiply::PMColorToColor(tmpColor2[i]);
458 NdotL = norm.dot(lightShader.fLight.fDirection); 448 NdotL = norm.dot(lightShader.fLight.fDirection);
459 449
460 // This is all done in linear unpremul color space 450 // This is all done in linear unpremul color space
461 r = light(SkColorGetR(lightShader.fLight.fColor), SkColorGetR(diffCo lor), NdotL, 451 r = light(lightShader.fLight.fColor.fX, SkColorGetR(diffColor), Ndot L,
462 SkColorGetR(lightShader.fAmbientColor)); 452 lightShader.fAmbientColor.fX);
463 g = light(SkColorGetG(lightShader.fLight.fColor), SkColorGetG(diffCo lor), NdotL, 453 g = light(lightShader.fLight.fColor.fY, SkColorGetG(diffColor), Ndot L,
464 SkColorGetG(lightShader.fAmbientColor)); 454 lightShader.fAmbientColor.fY);
465 b = light(SkColorGetB(lightShader.fLight.fColor), SkColorGetB(diffCo lor), NdotL, 455 b = light(lightShader.fLight.fColor.fZ, SkColorGetB(diffColor), Ndot L,
466 SkColorGetB(lightShader.fAmbientColor)); 456 lightShader.fAmbientColor.fZ);
467 457
468 result[i] = SkPreMultiplyARGB(SkColorGetA(diffColor), r, g, b); 458 result[i] = SkPreMultiplyARGB(SkColorGetA(diffColor), r, g, b);
469 } 459 }
470 460
471 result += n; 461 result += n;
472 x += n; 462 x += n;
473 count -= n; 463 count -= n;
474 } while (count > 0); 464 } while (count > 0);
475 } 465 }
476 466
(...skipping 18 matching lines...) Expand all
495 SkBitmap normal; 485 SkBitmap normal;
496 if (!buf.readBitmap(&normal)) { 486 if (!buf.readBitmap(&normal)) {
497 return NULL; 487 return NULL;
498 } 488 }
499 normal.setImmutable(); 489 normal.setImmutable();
500 490
501 SkLightingShader::Light light; 491 SkLightingShader::Light light;
502 if (!buf.readScalarArray(&light.fDirection.fX, 3)) { 492 if (!buf.readScalarArray(&light.fDirection.fX, 3)) {
503 return NULL; 493 return NULL;
504 } 494 }
505 light.fColor = buf.readColor(); 495 if (!buf.readScalarArray(&light.fColor.fX, 3)) {
496 return NULL;
497 }
506 498
507 SkColor ambient = buf.readColor(); 499 SkColor3f ambient;
500 if (!buf.readScalarArray(&ambient.fX, 3)) {
501 return NULL;
502 }
508 503
509 return SkNEW_ARGS(SkLightingShaderImpl, (diffuse, normal, light, ambient, &l ocalMatrix)); 504 return SkNEW_ARGS(SkLightingShaderImpl, (diffuse, normal, light, ambient, &l ocalMatrix));
510 } 505 }
511 506
512 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { 507 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const {
513 buf.writeMatrix(this->getLocalMatrix()); 508 buf.writeMatrix(this->getLocalMatrix());
514 509
515 buf.writeBitmap(fDiffuseMap); 510 buf.writeBitmap(fDiffuseMap);
516 buf.writeBitmap(fNormalMap); 511 buf.writeBitmap(fNormalMap);
517 buf.writeScalarArray(&fLight.fDirection.fX, 3); 512 buf.writeScalarArray(&fLight.fDirection.fX, 3);
518 buf.writeColor(fLight.fColor); 513 buf.writeScalarArray(&fLight.fColor.fX, 3);
519 buf.writeColor(fAmbientColor); 514 buf.writeScalarArray(&fAmbientColor.fX, 3);
520 } 515 }
521 516
522 SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, 517 SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec,
523 void* storage) const { 518 void* storage) const {
524 519
525 SkMatrix totalInverse; 520 SkMatrix totalInverse;
526 // Do this first, so we know the matrix can be inverted. 521 // Do this first, so we know the matrix can be inverted.
527 if (!this->computeTotalInverse(rec, &totalInverse)) { 522 if (!this->computeTotalInverse(rec, &totalInverse)) {
528 return NULL; 523 return NULL;
529 } 524 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 // communicates between its matrix-proc and its sampler-proc. Until we can 559 // communicates between its matrix-proc and its sampler-proc. Until we can
565 // widen that, we have to reject bitmaps that are larger. 560 // widen that, we have to reject bitmaps that are larger.
566 // 561 //
567 static const int kMaxSize = 65535; 562 static const int kMaxSize = 65535;
568 563
569 return bm.width() > kMaxSize || bm.height() > kMaxSize; 564 return bm.width() > kMaxSize || bm.height() > kMaxSize;
570 } 565 }
571 566
572 SkShader* SkLightingShader::Create(const SkBitmap& diffuse, const SkBitmap& norm al, 567 SkShader* SkLightingShader::Create(const SkBitmap& diffuse, const SkBitmap& norm al,
573 const SkLightingShader::Light& light, 568 const SkLightingShader::Light& light,
574 const SkColor ambient, 569 const SkColor3f& ambient,
575 const SkMatrix* localMatrix) { 570 const SkMatrix* localMatrix) {
576 if (diffuse.isNull() || bitmap_is_too_big(diffuse) || 571 if (diffuse.isNull() || bitmap_is_too_big(diffuse) ||
577 normal.isNull() || bitmap_is_too_big(normal) || 572 normal.isNull() || bitmap_is_too_big(normal) ||
578 diffuse.width() != normal.width() || 573 diffuse.width() != normal.width() ||
579 diffuse.height() != normal.height()) { 574 diffuse.height() != normal.height()) {
580 return nullptr; 575 return nullptr;
581 } 576 }
582 577
583 return SkNEW_ARGS(SkLightingShaderImpl, (diffuse, normal, light, ambient, lo calMatrix)); 578 return SkNEW_ARGS(SkLightingShaderImpl, (diffuse, normal, light, ambient, lo calMatrix));
584 } 579 }
585 580
586 /////////////////////////////////////////////////////////////////////////////// 581 ///////////////////////////////////////////////////////////////////////////////
587 582
588 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) 583 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader)
589 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) 584 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl)
590 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 585 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
591 586
592 /////////////////////////////////////////////////////////////////////////////// 587 ///////////////////////////////////////////////////////////////////////////////
OLDNEW
« no previous file with comments | « src/effects/SkLightingShader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698