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

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

Powered by Google App Engine
This is Rietveld 408576698