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

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

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

Powered by Google App Engine
This is Rietveld 408576698