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

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

Issue 1261433009: Refugee from Dead Machine 11: Add SkCanvas::drawLitAtlas call Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: update 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
« no previous file with comments | « src/core/SkLightingShader.h ('k') | src/core/SkPictureFlat.h » ('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 /* 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 "SkPoint3.h"
15 #include "SkReadBuffer.h" 16 #include "SkReadBuffer.h"
17 #include "SkRSXform.h"
16 #include "SkWriteBuffer.h" 18 #include "SkWriteBuffer.h"
17 19
18 //////////////////////////////////////////////////////////////////////////// 20 ////////////////////////////////////////////////////////////////////////////
19 21
20 /* 22 /*
21 SkLightingShader TODOs: 23 SkLightingShader TODOs:
22 support other than clamp mode 24 support other than clamp mode
23 allow 'diffuse' & 'normal' to be of different dimensions? 25 allow 'diffuse' & 'normal' to be of different dimensions?
24 support different light types 26 support different light types
25 support multiple lights 27 support multiple lights
26 enforce normal map is 4 channel 28 enforce normal map is 4 channel
27 use SkImages instead if SkBitmaps 29 use SkImages instead if SkBitmaps
28 30
29 To Test: 31 To Test:
30 non-opaque diffuse textures 32 non-opaque diffuse textures
31 A8 diffuse textures 33 A8 diffuse textures
32 down & upsampled draws 34 down & upsampled draws
33 */ 35 */
34 36
35 37
36 38
37 /** \class SkLightingShaderImpl 39 /** \class SkLightingShaderImpl
38 This subclass of shader applies lighting. 40 This subclass of shader applies lighting.
39 */ 41 */
40 class SK_API SkLightingShaderImpl : public SkShader { 42 class SK_API SkLightingShaderImpl : public SkShader {
41 public: 43 public:
42 44
43 /** Create a new lighting shader that use the provided normal map, light 45 /** Create a new lighting shader that use the provided normal map and
44 and ambient color to light the diffuse bitmap. 46 lights to light the diffuse bitmap.
45 @param diffuse the diffuse bitmap 47 @param diffuse the diffuse bitmap
46 @param normal the normal map 48 @param normal the normal map
47 @param light the light applied to the normal map 49 @param lights the lights applied to the normal map
48 @param ambient the linear (unpremul) ambient light color 50 @param numLights the number of lights in 'lights'
49 */ 51 */
50 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal, 52 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal,
51 const SkLightingShader::Light& light, 53 const SkLightingShader::Lights* lights,
52 const SkColor3f& ambient, const SkMatrix* localMatrix) 54 const SkRSXform& xform,
53 : INHERITED(localMatrix) 55 const SkMatrix* diffLocalM, const SkMatrix* normLocalM)
56 : INHERITED(diffLocalM)
54 , fDiffuseMap(diffuse) 57 , fDiffuseMap(diffuse)
55 , fNormalMap(normal) 58 , fNormalMap(normal)
56 , fLight(light) 59 , fLights(SkRef(lights))
57 , fAmbientColor(ambient) { 60 , fXform(xform) {
58 if (!fLight.fDirection.normalize()) { 61
59 fLight.fDirection = SkPoint3::Make(0.0f, 0.0f, 1.0f); 62 if (normLocalM) {
63 fNormLocalMatrix = *normLocalM;
64 } else {
65 fNormLocalMatrix.reset();
60 } 66 }
67 // Pre-cache so future calls to fNormLocalMatrix.getType() are threadsaf e.
68 (void)fNormLocalMatrix.getType();
69
61 } 70 }
62 71
63 bool isOpaque() const override; 72 bool isOpaque() const override;
64 73
65 bool asFragmentProcessor(GrContext*, const SkPaint& paint, const SkMatrix& v iewM, 74 bool asFragmentProcessor(GrContext*, const SkPaint& paint, const SkMatrix& v iewM,
66 const SkMatrix* localMatrix, GrColor* color, 75 const SkMatrix* localMatrix, GrColor* color,
67 GrProcessorDataManager*, GrFragmentProcessor** fp) const override; 76 GrProcessorDataManager*, GrFragmentProcessor** fp) const override;
68 77
69 size_t contextSize() const override; 78 size_t contextSize() const override;
70 79
(...skipping 16 matching lines...) Expand all
87 96
88 typedef SkShader::Context INHERITED; 97 typedef SkShader::Context INHERITED;
89 }; 98 };
90 99
91 SK_TO_STRING_OVERRIDE() 100 SK_TO_STRING_OVERRIDE()
92 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl) 101 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl)
93 102
94 protected: 103 protected:
95 void flatten(SkWriteBuffer&) const override; 104 void flatten(SkWriteBuffer&) const override;
96 Context* onCreateContext(const ContextRec&, void*) const override; 105 Context* onCreateContext(const ContextRec&, void*) const override;
106 bool computeNormTotalInverse(const ContextRec& rec, SkMatrix* normTotalInver se) const;
97 107
98 private: 108 private:
99 SkBitmap fDiffuseMap; 109 SkBitmap fDiffuseMap;
100 SkBitmap fNormalMap; 110 SkBitmap fNormalMap;
101 SkLightingShader::Light fLight; 111
102 SkColor3f fAmbientColor; // linear (unpremul) color. Range is 0..1/channel. 112 SkAutoTUnref<const SkLightingShader::Lights> fLights;
113
114 SkMatrix fNormLocalMatrix;
115 SkRSXform fXform;
103 116
104 friend class SkLightingShader; 117 friend class SkLightingShader;
105 118
106 typedef SkShader INHERITED; 119 typedef SkShader INHERITED;
107 }; 120 };
108 121
109 //////////////////////////////////////////////////////////////////////////// 122 ////////////////////////////////////////////////////////////////////////////
110 123
111 #if SK_SUPPORT_GPU 124 #if SK_SUPPORT_GPU
112 125
113 #include "GrCoordTransform.h" 126 #include "GrCoordTransform.h"
114 #include "GrFragmentProcessor.h" 127 #include "GrFragmentProcessor.h"
115 #include "GrTextureAccess.h" 128 #include "GrTextureAccess.h"
116 #include "gl/GrGLProcessor.h" 129 #include "gl/GrGLProcessor.h"
117 #include "gl/builders/GrGLProgramBuilder.h" 130 #include "gl/builders/GrGLProgramBuilder.h"
118 #include "SkGr.h" 131 #include "SkGr.h"
119 132
120 class LightingFP : public GrFragmentProcessor { 133 class LightingFP : public GrFragmentProcessor {
121 public: 134 public:
122 LightingFP(GrTexture* diffuse, GrTexture* normal, const SkMatrix& matrix, 135 LightingFP(GrTexture* diffuse, GrTexture* normal,
123 const SkVector3& lightDir, const SkColor3f& lightColor, 136 const SkMatrix& diffMatrix, const SkMatrix& normMatrix,
124 const SkColor3f& ambientColor) 137 const SkLightingShader::Lights* lights, const SkVector& xform)
125 : fDeviceTransform(kDevice_GrCoordSet, matrix) 138 : fDiffDeviceTransform(kDevice_GrCoordSet, diffMatrix)
139 , fNormDeviceTransform(kDevice_GrCoordSet, normMatrix)
126 , fDiffuseTextureAccess(diffuse) 140 , fDiffuseTextureAccess(diffuse)
127 , fNormalTextureAccess(normal) 141 , fNormalTextureAccess(normal)
128 , fLightDir(lightDir) 142 , fXform(xform) {
129 , fLightColor(lightColor) 143 this->addCoordTransform(&fDiffDeviceTransform);
130 , fAmbientColor(ambientColor) { 144 this->addCoordTransform(&fNormDeviceTransform);
131 this->addCoordTransform(&fDeviceTransform);
132 this->addTextureAccess(&fDiffuseTextureAccess); 145 this->addTextureAccess(&fDiffuseTextureAccess);
133 this->addTextureAccess(&fNormalTextureAccess); 146 this->addTextureAccess(&fNormalTextureAccess);
134 147
148 // fuse all ambient lights into a single one
149 fAmbientColor.set(0.0f, 0.0f, 0.0f);
150 for (int i = 0; i < lights->numLights(); ++i) {
151 if (SkLight::kAmbient_LightType == lights->light(i).type()) {
152 fAmbientColor += lights->light(i).color();
153 } else {
154 fLightColor = lights->light(i).color();
155 fLightDir = lights->light(i).dir();
156 }
157 }
158
135 this->initClassID<LightingFP>(); 159 this->initClassID<LightingFP>();
136 } 160 }
137 161
138 class LightingGLFP : public GrGLFragmentProcessor { 162 class LightingGLFP : public GrGLFragmentProcessor {
139 public: 163 public:
140 LightingGLFP() { 164 LightingGLFP() {
141 fLightDir.fX = 10000.0f; 165 fLightDir.fX = 10000.0f;
142 fLightColor.fX = 0.0f; 166 fLightColor.fX = 0.0f;
143 fAmbientColor.fX = 0.0f; 167 fAmbientColor.fX = 0.0f;
168 fXform.fX = 0.0f;
144 } 169 }
145 170
146 void emitCode(EmitArgs& args) override { 171 void emitCode(EmitArgs& args) override {
147 172
148 GrGLFragmentBuilder* fpb = args.fBuilder->getFragmentShaderBuilder() ; 173 GrGLFragmentBuilder* fpb = args.fBuilder->getFragmentShaderBuilder() ;
149 174
150 // add uniforms 175 // add uniforms
151 const char* lightDirUniName = NULL; 176 const char* lightDirUniName = NULL;
152 fLightDirUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragme nt_Visibility, 177 fLightDirUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragme nt_Visibility,
153 kVec3f_GrSLType, kDefault_G rSLPrecision, 178 kVec3f_GrSLType, kDefault_G rSLPrecision,
154 "LightDir", &lightDirUniNam e); 179 "LightDir", &lightDirUniNam e);
155 180
156 const char* lightColorUniName = NULL; 181 const char* lightColorUniName = NULL;
157 fLightColorUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFrag ment_Visibility, 182 fLightColorUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFrag ment_Visibility,
158 kVec3f_GrSLType, kDefault _GrSLPrecision, 183 kVec3f_GrSLType, kDefault _GrSLPrecision,
159 "LightColor", &lightColor UniName); 184 "LightColor", &lightColor UniName);
160 185
161 const char* ambientColorUniName = NULL; 186 const char* ambientColorUniName = NULL;
162 fAmbientColorUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFr agment_Visibility, 187 fAmbientColorUni1 = args.fBuilder->addUniform(GrGLProgramBuilder::kF ragment_Visibility,
163 kVec3f_GrSLType, kDefau lt_GrSLPrecision, 188 kVec3f_GrSLType, kDefau lt_GrSLPrecision,
164 "AmbientColor", &ambien tColorUniName); 189 "AmbientColor", &ambien tColorUniName);
165 190
191 const char* xformUniName = NULL;
192 fXformUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_ Visibility,
193 kVec2f_GrSLType, kDefault_GrSL Precision,
194 "Xform", &xformUniName);
195
166 fpb->codeAppend("vec4 diffuseColor = "); 196 fpb->codeAppend("vec4 diffuseColor = ");
167 fpb->appendTextureLookupAndModulate(args.fInputColor, args.fSamplers [0], 197 fpb->appendTextureLookupAndModulate(args.fInputColor, args.fSamplers [0],
168 args.fCoords[0].c_str(), 198 args.fCoords[0].c_str(),
169 args.fCoords[0].getType()); 199 args.fCoords[0].getType());
170 fpb->codeAppend(";"); 200 fpb->codeAppend(";");
171 201
172 fpb->codeAppend("vec4 normalColor = "); 202 fpb->codeAppend("vec4 normalColor = ");
173 fpb->appendTextureLookup(args.fSamplers[1], 203 fpb->appendTextureLookup(args.fSamplers[1],
174 args.fCoords[0].c_str(), 204 args.fCoords[1].c_str(),
175 args.fCoords[0].getType()); 205 args.fCoords[1].getType());
176 fpb->codeAppend(";"); 206 fpb->codeAppend(";");
177 207
178 fpb->codeAppend("vec3 normal = normalize(normalColor.rgb - vec3(0.5) );"); 208 fpb->codeAppend("vec3 normal = normalColor.rgb - vec3(0.5);");
179 fpb->codeAppendf("vec3 lightDir = normalize(%s);", lightDirUniName); 209
180 fpb->codeAppend("float NdotL = dot(normal, lightDir);"); 210 fpb->codeAppendf("mat3 m = mat3(%s.x, -%s.y, 0.0, %s.y, %s.x, 0.0, 0 .0, 0.0, 1.0);",
211 xformUniName, xformUniName, xformUniName, xformUniN ame);
212
213 fpb->codeAppend("normal = normalize(m*normal);");
214
215 fpb->codeAppendf("float NdotL = dot(normal, %s);", lightDirUniName);
181 // diffuse light 216 // diffuse light
182 fpb->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightCo lorUniName); 217 fpb->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightCo lorUniName);
183 // ambient light 218 // ambient light
184 fpb->codeAppendf("result += %s;", ambientColorUniName); 219 fpb->codeAppendf("result += %s;", ambientColorUniName);
185 fpb->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", args.fOut putColor); 220 fpb->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", args.fOut putColor);
186 } 221 }
187 222
188 void setData(const GrGLProgramDataManager& pdman, const GrProcessor& pro c) override { 223 void setData(const GrGLProgramDataManager& pdman, const GrProcessor& pro c) override {
189 const LightingFP& lightingFP = proc.cast<LightingFP>(); 224 const LightingFP& lightingFP = proc.cast<LightingFP>();
190 225
191 const SkVector3& lightDir = lightingFP.lightDir(); 226 const SkVector3& lightDir = lightingFP.lightDir();
192 if (lightDir != fLightDir) { 227 if (lightDir != fLightDir) {
193 pdman.set3fv(fLightDirUni, 1, &lightDir.fX); 228 pdman.set3fv(fLightDirUni, 1, &lightDir.fX);
194 fLightDir = lightDir; 229 fLightDir = lightDir;
195 } 230 }
196 231
197 const SkColor3f& lightColor = lightingFP.lightColor(); 232 const SkColor3f& lightColor = lightingFP.lightColor();
198 if (lightColor != fLightColor) { 233 if (lightColor != fLightColor) {
199 pdman.set3fv(fLightColorUni, 1, &lightColor.fX); 234 pdman.set3fv(fLightColorUni, 1, &lightColor.fX);
200 fLightColor = lightColor; 235 fLightColor = lightColor;
201 } 236 }
202 237
203 const SkColor3f& ambientColor = lightingFP.ambientColor(); 238 const SkColor3f& ambientColor = lightingFP.ambientColor();
204 if (ambientColor != fAmbientColor) { 239 if (ambientColor != fAmbientColor) {
205 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); 240 pdman.set3fv(fAmbientColorUni1, 1, &ambientColor.fX);
206 fAmbientColor = ambientColor; 241 fAmbientColor = ambientColor;
207 } 242 }
243
244 const SkVector& xform = lightingFP.xform();
245 if (xform != fXform) {
246 pdman.set2fv(fXformUni, 1, &xform.fX);
247 fXform = xform;
248 }
208 } 249 }
209 250
210 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, 251 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
211 GrProcessorKeyBuilder* b) { 252 GrProcessorKeyBuilder* b) {
212 // const LightingFP& lightingFP = proc.cast<LightingFP>(); 253 // const LightingFP& lightingFP = proc.cast<LightingFP>();
213 // only one shader generated currently 254 // only one shader generated currently
214 b->add32(0x0); 255 b->add32(0x0);
215 } 256 }
216 257
217 private: 258 private:
218 SkVector3 fLightDir; 259 SkVector3 fLightDir;
219 GrGLProgramDataManager::UniformHandle fLightDirUni; 260 GrGLProgramDataManager::UniformHandle fLightDirUni;
220 261
221 SkColor3f fLightColor; 262 SkColor3f fLightColor;
222 GrGLProgramDataManager::UniformHandle fLightColorUni; 263 GrGLProgramDataManager::UniformHandle fLightColorUni;
223 264
224 SkColor3f fAmbientColor; 265 SkColor3f fAmbientColor;
225 GrGLProgramDataManager::UniformHandle fAmbientColorUni; 266 GrGLProgramDataManager::UniformHandle fAmbientColorUni1;
267
268 SkVector fXform;
269 GrGLProgramDataManager::UniformHandle fXformUni;
226 }; 270 };
227 271
228 GrGLFragmentProcessor* createGLInstance() const override { return SkNEW(Ligh tingGLFP); } 272 GrGLFragmentProcessor* createGLInstance() const override { return SkNEW(Ligh tingGLFP); }
229 273
230 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override { 274 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override {
231 LightingGLFP::GenKey(*this, caps, b); 275 LightingGLFP::GenKey(*this, caps, b);
232 } 276 }
233 277
234 const char* name() const override { return "LightingFP"; } 278 const char* name() const override { return "LightingFP"; }
235 279
236 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 280 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
237 inout->mulByUnknownFourComponents(); 281 inout->mulByUnknownFourComponents();
238 } 282 }
239 283
240 const SkVector3& lightDir() const { return fLightDir; } 284 const SkVector3& lightDir() const { return fLightDir; }
241 const SkColor3f& lightColor() const { return fLightColor; } 285 const SkColor3f& lightColor() const { return fLightColor; }
242 const SkColor3f& ambientColor() const { return fAmbientColor; } 286 const SkColor3f& ambientColor() const { return fAmbientColor; }
287 const SkVector& xform() const { return fXform; }
243 288
244 private: 289 private:
245 bool onIsEqual(const GrFragmentProcessor& proc) const override { 290 bool onIsEqual(const GrFragmentProcessor& proc) const override {
246 const LightingFP& lightingFP = proc.cast<LightingFP>(); 291 const LightingFP& lightingFP = proc.cast<LightingFP>();
247 return fDeviceTransform == lightingFP.fDeviceTransform && 292 return fDiffDeviceTransform == lightingFP.fDiffDeviceTransform &&
293 fNormDeviceTransform == lightingFP.fNormDeviceTransform &&
248 fDiffuseTextureAccess == lightingFP.fDiffuseTextureAccess && 294 fDiffuseTextureAccess == lightingFP.fDiffuseTextureAccess &&
249 fNormalTextureAccess == lightingFP.fNormalTextureAccess && 295 fNormalTextureAccess == lightingFP.fNormalTextureAccess &&
250 fLightDir == lightingFP.fLightDir && 296 fLightDir == lightingFP.fLightDir &&
251 fLightColor == lightingFP.fLightColor && 297 fLightColor == lightingFP.fLightColor &&
252 fAmbientColor == lightingFP.fAmbientColor; 298 fAmbientColor == lightingFP.fAmbientColor &&
299 fXform == lightingFP.fXform;
253 } 300 }
254 301
255 GrCoordTransform fDeviceTransform; 302 GrCoordTransform fDiffDeviceTransform;
256 GrTextureAccess fDiffuseTextureAccess; 303 GrCoordTransform fNormDeviceTransform;
257 GrTextureAccess fNormalTextureAccess; 304 GrTextureAccess fDiffuseTextureAccess;
258 SkVector3 fLightDir; 305 GrTextureAccess fNormalTextureAccess;
259 SkColor3f fLightColor; 306
260 SkColor3f fAmbientColor; 307 SkVector3 fLightDir;
308 SkColor3f fLightColor;
309 SkColor3f fAmbientColor;
310
311 SkVector fXform;
261 }; 312 };
262 313
263 //////////////////////////////////////////////////////////////////////////// 314 ////////////////////////////////////////////////////////////////////////////
264 315
265 bool SkLightingShaderImpl::asFragmentProcessor(GrContext* context, const SkPaint & paint, 316 static bool make_mat(const SkBitmap& bm,
266 const SkMatrix& viewM, const SkMa trix* localMatrix, 317 const SkMatrix& localMatrix1,
267 GrColor* color, GrProcessorDataMa nager*, 318 const SkMatrix* localMatrix2,
268 GrFragmentProcessor** fp) const { 319 SkMatrix* result) {
269 // we assume diffuse and normal maps have same width and height 320
270 // TODO: support different sizes 321 result->setIDiv(bm.width(), bm.height());
271 SkASSERT(fDiffuseMap.width() == fNormalMap.width() &&
272 fDiffuseMap.height() == fNormalMap.height());
273 SkMatrix matrix;
274 matrix.setIDiv(fDiffuseMap.width(), fDiffuseMap.height());
275 322
276 SkMatrix lmInverse; 323 SkMatrix lmInverse;
277 if (!this->getLocalMatrix().invert(&lmInverse)) { 324 if (!localMatrix1.invert(&lmInverse)) {
278 return false; 325 return false;
279 } 326 }
280 if (localMatrix) { 327 if (localMatrix2) {
281 SkMatrix inv; 328 SkMatrix inv;
282 if (!localMatrix->invert(&inv)) { 329 if (!localMatrix2->invert(&inv)) {
283 return false; 330 return false;
284 } 331 }
285 lmInverse.postConcat(inv); 332 lmInverse.postConcat(inv);
286 } 333 }
287 matrix.preConcat(lmInverse); 334 result->preConcat(lmInverse);
288 335
336 return true;
337 }
338
339 static GrTextureParams::FilterMode pick_filter_level(SkFilterQuality filterIn,
340 const SkMatrix& viewM,
341 const SkMatrix& localM) {
289 // Must set wrap and filter on the sampler before requesting a texture. In t wo places below 342 // Must set wrap and filter on the sampler before requesting a texture. In t wo places below
290 // we check the matrix scale factors to determine how to interpret the filte r quality setting. 343 // we check the matrix scale factors to determine how to interpret the filte r quality setting.
291 // This completely ignores the complexity of the drawVertices case where exp licit local coords 344 // This completely ignores the complexity of the drawVertices case where exp licit local coords
292 // are provided by the caller. 345 // are provided by the caller.
293 GrTextureParams::FilterMode textureFilterMode = GrTextureParams::kBilerp_Fil terMode; 346 GrTextureParams::FilterMode textureFilterMode = GrTextureParams::kBilerp_Fil terMode;
294 switch (paint.getFilterQuality()) { 347 switch (filterIn) {
295 case kNone_SkFilterQuality: 348 case kNone_SkFilterQuality:
296 textureFilterMode = GrTextureParams::kNone_FilterMode; 349 textureFilterMode = GrTextureParams::kNone_FilterMode;
297 break; 350 break;
298 case kLow_SkFilterQuality: 351 case kLow_SkFilterQuality:
299 textureFilterMode = GrTextureParams::kBilerp_FilterMode; 352 textureFilterMode = GrTextureParams::kBilerp_FilterMode;
300 break; 353 break;
301 case kMedium_SkFilterQuality:{ 354 case kMedium_SkFilterQuality:{
302 SkMatrix matrix; 355 SkMatrix matrix;
303 matrix.setConcat(viewM, this->getLocalMatrix()); 356 matrix.setConcat(viewM, localM);
304 if (matrix.getMinScale() < SK_Scalar1) { 357 if (matrix.getMinScale() < SK_Scalar1) {
305 textureFilterMode = GrTextureParams::kMipMap_FilterMode; 358 textureFilterMode = GrTextureParams::kMipMap_FilterMode;
306 } else { 359 } else {
307 // Don't trigger MIP level generation unnecessarily. 360 // Don't trigger MIP level generation unnecessarily.
308 textureFilterMode = GrTextureParams::kBilerp_FilterMode; 361 textureFilterMode = GrTextureParams::kBilerp_FilterMode;
309 } 362 }
310 break; 363 break;
311 } 364 }
312 case kHigh_SkFilterQuality: 365 case kHigh_SkFilterQuality:
313 default: 366 default:
314 SkErrorInternals::SetError(kInvalidPaint_SkError, 367 SkErrorInternals::SetError(kInvalidPaint_SkError,
315 "Sorry, I don't understand the filtering " 368 "Sorry, I don't understand the filtering "
316 "mode you asked for. Falling back to " 369 "mode you asked for. Falling back to "
317 "MIPMaps."); 370 "MIPMaps.");
318 textureFilterMode = GrTextureParams::kMipMap_FilterMode; 371 textureFilterMode = GrTextureParams::kMipMap_FilterMode;
319 break; 372 break;
320 373
321 } 374 }
322 375
376 return textureFilterMode;
377 }
378
379 bool SkLightingShaderImpl::asFragmentProcessor(GrContext* context, const SkPaint & paint,
380 const SkMatrix& viewM, const SkMa trix* localMatrix,
381 GrColor* color, GrProcessorDataMa nager*,
382 GrFragmentProcessor** fp) const {
383 // we assume diffuse and normal maps have same width and height
384 // TODO: support different sizes
385 SkASSERT(fDiffuseMap.width() == fNormalMap.width() &&
386 fDiffuseMap.height() == fNormalMap.height());
387 SkMatrix diffM, normM;
388
389 if (!make_mat(fDiffuseMap, this->getLocalMatrix(), localMatrix, &diffM)) {
390 return false;
391 }
392
393 if (!make_mat(fNormalMap, fNormLocalMatrix, localMatrix, &normM)) {
394 return false;
395 }
396
397 GrTextureParams::FilterMode diffFilterMode = pick_filter_level(paint.getFilt erQuality(),
398 viewM,
399 this->getLoca lMatrix());
400
401 GrTextureParams::FilterMode normFilterMode = pick_filter_level(paint.getFilt erQuality(),
402 viewM,
403 fNormLocalMat rix);
404
323 // TODO: support other tile modes 405 // TODO: support other tile modes
324 GrTextureParams params(kClamp_TileMode, textureFilterMode); 406 GrTextureParams diffParams(kClamp_TileMode, diffFilterMode);
325 SkAutoTUnref<GrTexture> diffuseTexture(GrRefCachedBitmapTexture(context, fDi ffuseMap, &params)); 407 SkAutoTUnref<GrTexture> diffuseTexture(GrRefCachedBitmapTexture(context, fDi ffuseMap, &diffParams));
326 if (!diffuseTexture) { 408 if (!diffuseTexture) {
327 SkErrorInternals::SetError(kInternalError_SkError, 409 SkErrorInternals::SetError(kInternalError_SkError,
328 "Couldn't convert bitmap to texture."); 410 "Couldn't convert bitmap to texture.");
329 return false; 411 return false;
330 } 412 }
331 413
332 SkAutoTUnref<GrTexture> normalTexture(GrRefCachedBitmapTexture(context, fNor malMap, &params)); 414 GrTextureParams normParams(kClamp_TileMode, normFilterMode);
415 SkAutoTUnref<GrTexture> normalTexture(GrRefCachedBitmapTexture(context, fNor malMap, &normParams));
333 if (!normalTexture) { 416 if (!normalTexture) {
334 SkErrorInternals::SetError(kInternalError_SkError, 417 SkErrorInternals::SetError(kInternalError_SkError,
335 "Couldn't convert bitmap to texture."); 418 "Couldn't convert bitmap to texture.");
336 return false; 419 return false;
337 } 420 }
338 421
339 *fp = SkNEW_ARGS(LightingFP, (diffuseTexture, normalTexture, matrix, 422 SkVector vec = SkVector::Make(fXform.fSCos, fXform.fSSin);
340 fLight.fDirection, fLight.fColor, fAmbientColo r)); 423
424 *fp = SkNEW_ARGS(LightingFP, (diffuseTexture, normalTexture, diffM, normM, f Lights, vec));
341 *color = GrColorPackA4(paint.getAlpha()); 425 *color = GrColorPackA4(paint.getAlpha());
342 return true; 426 return true;
343 } 427 }
344 #else 428 #else
345 429
346 bool SkLightingShaderImpl::asFragmentProcessor(GrContext* context, const SkPaint & paint, 430 bool SkLightingShaderImpl::asFragmentProcessor(GrContext* context, const SkPaint & paint,
347 const SkMatrix& viewM, const SkMa trix* localMatrix, 431 const SkMatrix& viewM, const SkMa trix* localMatrix,
348 GrColor* color, GrProcessorDataMa nager*, 432 GrColor* color, GrProcessorDataMa nager*,
349 GrFragmentProcessor** fp) const { 433 GrFragmentProcessor** fp) const {
350 SkDEBUGFAIL("Should not call in GPU-less build"); 434 SkDEBUGFAIL("Should not call in GPU-less build");
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 fFlags = flags; 467 fFlags = flags;
384 } 468 }
385 469
386 SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() { 470 SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() {
387 // The bitmap proc states have been created outside of the context on memory that will be freed 471 // The bitmap proc states have been created outside of the context on memory that will be freed
388 // elsewhere. Call the destructors but leave the freeing of the memory to th e caller. 472 // elsewhere. Call the destructors but leave the freeing of the memory to th e caller.
389 fDiffuseState->~SkBitmapProcState(); 473 fDiffuseState->~SkBitmapProcState();
390 fNormalState->~SkBitmapProcState(); 474 fNormalState->~SkBitmapProcState();
391 } 475 }
392 476
393 static inline int light(SkScalar light, int diff, SkScalar NdotL, SkScalar ambie nt) { 477 static inline SkPMColor convert(SkColor3f color, U8CPU a) {
394 SkScalar color = light * diff * NdotL + 255 * ambient; 478 if (color.fX <= 0.0f) {
395 if (color <= 0.0f) { 479 color.fX = 0.0f;
396 return 0; 480 } else if (color.fX >= 255.0f) {
397 } else if (color >= 255.0f) { 481 color.fX = 255.0f;
398 return 255; 482 }
399 } else { 483
400 return (int) color; 484 if (color.fY <= 0.0f) {
401 } 485 color.fY = 0.0f;
486 } else if (color.fY >= 255.0f) {
487 color.fY = 255.0f;
488 }
489
490 if (color.fZ <= 0.0f) {
491 color.fZ = 0.0f;
492 } else if (color.fZ >= 255.0f) {
493 color.fZ = 255.0f;
494 }
495
496 return SkPreMultiplyARGB(a, (int) color.fX, (int) color.fY, (int) color.fZ) ;
402 } 497 }
403 498
499 #include "SkMatrix44.h"
500
404 // larger is better (fewer times we have to loop), but we shouldn't 501 // larger is better (fewer times we have to loop), but we shouldn't
405 // take up too much stack-space (each could here costs 16 bytes) 502 // take up too much stack-space (each one here costs 16 bytes)
406 #define TMP_COUNT 16 503 #define TMP_COUNT 16
407 504
408 void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y, 505 void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y,
409 SkPMColor result[], int count) { 506 SkPMColor result[], int count) {
410 const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShader Impl&>(fShader); 507 const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShader Impl&>(fShader);
411 508
412 SkPMColor tmpColor[TMP_COUNT], tmpColor2[TMP_COUNT]; 509 uint32_t tmpColor[TMP_COUNT+2], tmpNormal[TMP_COUNT+2];
413 SkPMColor tmpNormal[TMP_COUNT], tmpNormal2[TMP_COUNT]; 510 SkPMColor tmpColor2[TMP_COUNT+32], tmpNormal2[TMP_COUNT+32];
414 511
415 SkBitmapProcState::MatrixProc diffMProc = fDiffuseState->getMatrixProc(); 512 SkBitmapProcState::MatrixProc diffMProc = fDiffuseState->getMatrixProc();
416 SkBitmapProcState::SampleProc32 diffSProc = fDiffuseState->getSampleProc32() ; 513 SkBitmapProcState::SampleProc32 diffSProc = fDiffuseState->getSampleProc32() ;
417 514
418 SkBitmapProcState::MatrixProc normalMProc = fNormalState->getMatrixProc(); 515 SkBitmapProcState::MatrixProc normalMProc = fNormalState->getMatrixProc();
419 SkBitmapProcState::SampleProc32 normalSProc = fNormalState->getSampleProc32( ); 516 SkBitmapProcState::SampleProc32 normalSProc = fNormalState->getSampleProc32( );
420 517
518 int diffMax = fDiffuseState->maxCountForBufferSize(sizeof(tmpColor[0]) * TMP _COUNT);
519 int normMax = fNormalState->maxCountForBufferSize(sizeof(tmpNormal[0]) * TMP _COUNT);
520 int max = diffMax > normMax ? diffMax : normMax;
521
522 if (max > 8) {
523 int foo = 0;
524 foo++;
525 }
526
421 SkASSERT(fDiffuseState->fPixmap.addr()); 527 SkASSERT(fDiffuseState->fPixmap.addr());
422 SkASSERT(fNormalState->fPixmap.addr()); 528 SkASSERT(fNormalState->fPixmap.addr());
423 529
424 SkPoint3 norm; 530 SkPoint3 norm1, xformedNorm;
425 SkScalar NdotL; 531 SkScalar blah[4], xformedBlah[4];
426 int r, g, b; 532
533 xformedNorm.fX = 0.0f;
534 blah[0] = xformedBlah[0] = 0.0f;
535 #if 1
536 SkMatrix baz;
537 baz.setRSXform(lightShader.fXform);
538 baz.setTranslateX(0.0f);
539 baz.setTranslateY(0.0f);
540 SkMatrix44 bar(baz);
541 SkMatrix44 inv;
542 bar.invert(&inv);
543 #endif
427 544
428 do { 545 do {
429 int n = count; 546 int n = count;
430 if (n > TMP_COUNT) { 547 if (n > max) {
431 n = TMP_COUNT; 548 n = max;
432 } 549 }
433 550
434 diffMProc(*fDiffuseState, tmpColor, n, x, y); 551 diffMProc(*fDiffuseState, tmpColor, n, x, y);
435 diffSProc(*fDiffuseState, tmpColor, n, tmpColor2); 552 diffSProc(*fDiffuseState, tmpColor, n, tmpColor2);
436 553
437 normalMProc(*fNormalState, tmpNormal, n, x, y); 554 normalMProc(*fNormalState, tmpNormal, n, x, y);
438 normalSProc(*fNormalState, tmpNormal, n, tmpNormal2); 555 normalSProc(*fNormalState, tmpNormal, n, tmpNormal2);
439 556
440 for (int i = 0; i < n; ++i) { 557 for (int i = 0; i < n; ++i) {
441 SkASSERT(0xFF == SkColorGetA(tmpNormal2[i])); // opaque -> unpremul 558 SkASSERT(0xFF == SkColorGetA(tmpNormal2[i])); // opaque -> unpremul
442 norm.set(SkIntToScalar(SkGetPackedR32(tmpNormal2[i]))-127.0f, 559 norm1.set(SkIntToScalar(SkGetPackedR32(tmpNormal2[i]))-127.0f,
443 SkIntToScalar(SkGetPackedG32(tmpNormal2[i]))-127.0f, 560 SkIntToScalar(SkGetPackedG32(tmpNormal2[i]))-127.0f,
444 SkIntToScalar(SkGetPackedB32(tmpNormal2[i]))-127.0f); 561 SkIntToScalar(SkGetPackedB32(tmpNormal2[i]))-127.0f);
445 norm.normalize(); 562 norm1.normalize();
563
564 #if 1
565 blah[0] = norm1.fX;
566 blah[1] = norm1.fY;
567 blah[2] = norm1.fZ;
568 blah[3] = 1.0f;
569
570 inv.mapScalars(blah, xformedBlah);
571
572 xformedNorm.fX = xformedBlah[0];
573 xformedNorm.fY = xformedBlah[1];
574 xformedNorm.fZ = xformedBlah[2];
575 #endif
446 576
447 SkColor diffColor = SkUnPreMultiply::PMColorToColor(tmpColor2[i]); 577 SkColor diffColor = SkUnPreMultiply::PMColorToColor(tmpColor2[i]);
448 NdotL = norm.dot(lightShader.fLight.fDirection);
449 578
450 // This is all done in linear unpremul color space 579 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f);
451 r = light(lightShader.fLight.fColor.fX, SkColorGetR(diffColor), Ndot L, 580 // This is all done in linear unpremul color space (each component 0 ..255.0f though)
452 lightShader.fAmbientColor.fX); 581 for (int l = 0; l < lightShader.fLights->numLights(); ++l) {
453 g = light(lightShader.fLight.fColor.fY, SkColorGetG(diffColor), Ndot L, 582 const SkLight& light = lightShader.fLights->light(l);
454 lightShader.fAmbientColor.fY);
455 b = light(lightShader.fLight.fColor.fZ, SkColorGetB(diffColor), Ndot L,
456 lightShader.fAmbientColor.fZ);
457 583
458 result[i] = SkPreMultiplyARGB(SkColorGetA(diffColor), r, g, b); 584 if (SkLight::kAmbient_LightType == light.type()) {
585 accum += light.color().makeScale(255.0f);
586 } else {
587 SkScalar NdotL = xformedNorm.dot(light.dir());
588
589 accum.fX += light.color().fX * SkColorGetR(diffColor) * Ndot L;
590 accum.fY += light.color().fY * SkColorGetG(diffColor) * Ndot L;
591 accum.fZ += light.color().fZ * SkColorGetB(diffColor) * Ndot L;
592 }
593 }
594
595 result[i] = convert(accum, SkColorGetA(diffColor));
459 } 596 }
460 597
461 result += n; 598 result += n;
462 x += n; 599 x += n;
463 count -= n; 600 count -= n;
464 } while (count > 0); 601 } while (count > 0);
465 } 602 }
466 603
467 //////////////////////////////////////////////////////////////////////////// 604 ////////////////////////////////////////////////////////////////////////////
468 605
469 #ifndef SK_IGNORE_TO_STRING 606 #ifndef SK_IGNORE_TO_STRING
470 void SkLightingShaderImpl::toString(SkString* str) const { 607 void SkLightingShaderImpl::toString(SkString* str) const {
471 str->appendf("LightingShader: ()"); 608 str->appendf("LightingShader: ()");
472 } 609 }
473 #endif 610 #endif
474 611
475 SkFlattenable* SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) { 612 SkFlattenable* SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) {
476 SkMatrix localMatrix; 613 SkMatrix diffLocalM;
477 buf.readMatrix(&localMatrix); 614 bool hasDiffLocalM = buf.readBool();
615 if (hasDiffLocalM) {
616 buf.readMatrix(&diffLocalM);
617 } else {
618 diffLocalM.reset();
619 }
620
621 SkMatrix normLocalM;
622 bool hasNormLocalM = buf.readBool();
623 if (hasNormLocalM) {
624 buf.readMatrix(&normLocalM);
625 } else {
626 normLocalM.reset();
627 }
478 628
479 SkBitmap diffuse; 629 SkBitmap diffuse;
480 if (!buf.readBitmap(&diffuse)) { 630 if (!buf.readBitmap(&diffuse)) {
481 return NULL; 631 return NULL;
482 } 632 }
483 diffuse.setImmutable(); 633 diffuse.setImmutable();
484 634
485 SkBitmap normal; 635 SkBitmap normal;
486 if (!buf.readBitmap(&normal)) { 636 if (!buf.readBitmap(&normal)) {
487 return NULL; 637 return NULL;
488 } 638 }
489 normal.setImmutable(); 639 normal.setImmutable();
490 640
491 SkLightingShader::Light light; 641 int numLights = buf.readInt();
492 if (!buf.readScalarArray(&light.fDirection.fX, 3)) { 642
493 return NULL; 643 SkLightingShader::Lights::Builder builder;
494 } 644
495 if (!buf.readScalarArray(&light.fColor.fX, 3)) { 645 for (int l = 0; l < numLights; ++l) {
496 return NULL; 646
647 bool isAmbient = buf.readBool();
648
649 SkColor3f color;
650 if (!buf.readScalarArray(&color.fX, 3)) {
651 return NULL;
652 }
653
654 if (isAmbient) {
655 builder.add(SkLight::SkLight(color));
656 } else {
657 SkVector3 dir;
658 if (!buf.readScalarArray(&dir.fX, 3)) {
659 return NULL;
660 }
661 builder.add(SkLight::SkLight(color, dir));
662 }
497 } 663 }
498 664
499 SkColor3f ambient; 665 SkAutoTUnref<const SkLightingShader::Lights> lights(builder.finish());
500 if (!buf.readScalarArray(&ambient.fX, 3)) {
501 return NULL;
502 }
503 666
504 return SkNEW_ARGS(SkLightingShaderImpl, (diffuse, normal, light, ambient, &l ocalMatrix)); 667 SkRSXform xform;
668 //xform.reset();
669
670 return SkNEW_ARGS(SkLightingShaderImpl, (diffuse, normal, lights,
671 xform, &diffLocalM, &normLocalM));
505 } 672 }
506 673
507 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { 674 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const {
508 buf.writeMatrix(this->getLocalMatrix()); 675 this->INHERITED::flatten(buf);
676
677 bool hasNormLocalM = !fNormLocalMatrix.isIdentity();
678 buf.writeBool(hasNormLocalM);
679 if (hasNormLocalM) {
680 buf.writeMatrix(fNormLocalMatrix);
681 }
509 682
510 buf.writeBitmap(fDiffuseMap); 683 buf.writeBitmap(fDiffuseMap);
511 buf.writeBitmap(fNormalMap); 684 buf.writeBitmap(fNormalMap);
512 buf.writeScalarArray(&fLight.fDirection.fX, 3); 685
513 buf.writeScalarArray(&fLight.fColor.fX, 3); 686 buf.writeInt(fLights->numLights());
514 buf.writeScalarArray(&fAmbientColor.fX, 3); 687 for (int l = 0; l < fLights->numLights(); ++l) {
688 const SkLight& light = fLights->light(l);
689
690 bool isAmbient = SkLight::kAmbient_LightType == light.type();
691
692 buf.writeBool(isAmbient);
693 buf.writeScalarArray(&light.color().fX, 3);
694 if (!isAmbient) {
695 buf.writeScalarArray(&light.dir().fX, 3);
696 }
697 }
698 }
699
700 bool SkLightingShaderImpl::computeNormTotalInverse(const ContextRec& rec,
701 SkMatrix* normTotalInverse) c onst {
702 SkMatrix total;
703 total.setConcat(*rec.fMatrix, fNormLocalMatrix);
704
705 const SkMatrix* m = &total;
706 if (rec.fLocalMatrix) {
707 total.setConcat(*m, *rec.fLocalMatrix);
708 m = &total;
709 }
710 return m->invert(normTotalInverse);
515 } 711 }
516 712
517 SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, 713 SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec,
518 void* storage) const { 714 void* storage) const {
519 715
520 SkMatrix totalInverse; 716 SkMatrix diffTotalInv;
521 // Do this first, so we know the matrix can be inverted. 717 // computeTotalInverse was called in SkShader::createContext so we know it w ill succeed
522 if (!this->computeTotalInverse(rec, &totalInverse)) { 718 SkAssertResult(this->computeTotalInverse(rec, &diffTotalInv));
719
720 SkMatrix normTotalInv;
721 if (!this->computeNormTotalInverse(rec, &normTotalInv)) {
523 return NULL; 722 return NULL;
524 } 723 }
525 724
526 void* diffuseStateStorage = (char*)storage + sizeof(LightingShaderContext); 725 void* diffuseStateStorage = (char*)storage + sizeof(LightingShaderContext);
527 SkBitmapProcState* diffuseState = SkNEW_PLACEMENT(diffuseStateStorage, SkBit mapProcState); 726 SkBitmapProcState* diffuseState = SkNEW_PLACEMENT(diffuseStateStorage, SkBit mapProcState);
528 SkASSERT(diffuseState); 727 SkASSERT(diffuseState);
529 728
530 diffuseState->fTileModeX = SkShader::kClamp_TileMode; 729 diffuseState->fTileModeX = SkShader::kClamp_TileMode;
531 diffuseState->fTileModeY = SkShader::kClamp_TileMode; 730 diffuseState->fTileModeY = SkShader::kClamp_TileMode;
532 diffuseState->fOrigBitmap = fDiffuseMap; 731 diffuseState->fOrigBitmap = fDiffuseMap;
533 if (!diffuseState->chooseProcs(totalInverse, *rec.fPaint)) { 732 if (!diffuseState->chooseProcs(diffTotalInv, *rec.fPaint)) {
534 diffuseState->~SkBitmapProcState(); 733 diffuseState->~SkBitmapProcState();
535 return NULL; 734 return NULL;
536 } 735 }
537 736
538 void* normalStateStorage = (char*)storage + sizeof(LightingShaderContext) + sizeof(SkBitmapProcState); 737 void* normalStateStorage = (char*)storage + sizeof(LightingShaderContext) + sizeof(SkBitmapProcState);
539 SkBitmapProcState* normalState = SkNEW_PLACEMENT(normalStateStorage, SkBitma pProcState); 738 SkBitmapProcState* normalState = SkNEW_PLACEMENT(normalStateStorage, SkBitma pProcState);
540 SkASSERT(normalState); 739 SkASSERT(normalState);
541 740
542 normalState->fTileModeX = SkShader::kClamp_TileMode; 741 normalState->fTileModeX = SkShader::kClamp_TileMode;
543 normalState->fTileModeY = SkShader::kClamp_TileMode; 742 normalState->fTileModeY = SkShader::kClamp_TileMode;
544 normalState->fOrigBitmap = fNormalMap; 743 normalState->fOrigBitmap = fNormalMap;
545 if (!normalState->chooseProcs(totalInverse, *rec.fPaint)) { 744 if (!normalState->chooseProcs(normTotalInv, *rec.fPaint)) {
546 diffuseState->~SkBitmapProcState(); 745 diffuseState->~SkBitmapProcState();
547 normalState->~SkBitmapProcState(); 746 normalState->~SkBitmapProcState();
548 return NULL; 747 return NULL;
549 } 748 }
550 749
551 return SkNEW_PLACEMENT_ARGS(storage, LightingShaderContext, (*this, rec, 750 return SkNEW_PLACEMENT_ARGS(storage, LightingShaderContext, (*this, rec,
552 diffuseState, n ormalState)); 751 diffuseState, n ormalState));
553 } 752 }
554 753
555 /////////////////////////////////////////////////////////////////////////////// 754 ///////////////////////////////////////////////////////////////////////////////
556 755
557 static bool bitmap_is_too_big(const SkBitmap& bm) { 756 static bool bitmap_is_too_big(const SkBitmap& bm) {
558 // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it 757 // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it
559 // communicates between its matrix-proc and its sampler-proc. Until we can 758 // communicates between its matrix-proc and its sampler-proc. Until we can
560 // widen that, we have to reject bitmaps that are larger. 759 // widen that, we have to reject bitmaps that are larger.
561 // 760 //
562 static const int kMaxSize = 65535; 761 static const int kMaxSize = 65535;
563 762
564 return bm.width() > kMaxSize || bm.height() > kMaxSize; 763 return bm.width() > kMaxSize || bm.height() > kMaxSize;
565 } 764 }
566 765
567 SkShader* SkLightingShader::Create(const SkBitmap& diffuse, const SkBitmap& norm al, 766 SkShader* SkLightingShader::Create(const SkBitmap& diffuse, const SkBitmap& norm al,
568 const SkLightingShader::Light& light, 767 const Lights* lights,
569 const SkColor3f& ambient, 768 const SkRSXform& xform,
570 const SkMatrix* localMatrix) { 769 const SkMatrix* diffLocalM, const SkMatrix* n ormLocalM) {
571 if (diffuse.isNull() || bitmap_is_too_big(diffuse) || 770 if (diffuse.isNull() || bitmap_is_too_big(diffuse) ||
572 normal.isNull() || bitmap_is_too_big(normal) || 771 normal.isNull() || bitmap_is_too_big(normal) ||
573 diffuse.width() != normal.width() || 772 diffuse.width() != normal.width() ||
574 diffuse.height() != normal.height()) { 773 diffuse.height() != normal.height()) {
575 return nullptr; 774 return nullptr;
576 } 775 }
577 776
578 return SkNEW_ARGS(SkLightingShaderImpl, (diffuse, normal, light, ambient, lo calMatrix)); 777 return SkNEW_ARGS(SkLightingShaderImpl, (diffuse, normal, lights,
778 xform, diffLocalM, normLocalM));
579 } 779 }
580 780
581 /////////////////////////////////////////////////////////////////////////////// 781 ///////////////////////////////////////////////////////////////////////////////
582 782
583 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) 783 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader)
584 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) 784 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl)
585 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 785 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
586 786
587 /////////////////////////////////////////////////////////////////////////////// 787 ///////////////////////////////////////////////////////////////////////////////
OLDNEW
« no previous file with comments | « src/core/SkLightingShader.h ('k') | src/core/SkPictureFlat.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698