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

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

Issue 2132113002: SkLS accepts nullptr for pointer args, handles alpha accurately, has new GM (Closed) Base URL: https://skia.googlesource.com/skia@dvonbeck-diffuse-api-change
Patch Set: Fixed more windows warnings Created 4 years, 5 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/SkNormalSource.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 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBitmapProcShader.h" 8 #include "SkBitmapProcShader.h"
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 "SkNormalSource.h" 15 #include "SkNormalSource.h"
16 #include "SkPoint3.h" 16 #include "SkPoint3.h"
17 #include "SkReadBuffer.h" 17 #include "SkReadBuffer.h"
18 #include "SkWriteBuffer.h" 18 #include "SkWriteBuffer.h"
19 19
20 //////////////////////////////////////////////////////////////////////////// 20 ////////////////////////////////////////////////////////////////////////////
21 21
22 /* 22 /*
23 SkLightingShader TODOs: 23 SkLightingShader TODOs:
24 support other than clamp mode
25 allow 'diffuse' & 'normal' to be of different dimensions?
26 support different light types 24 support different light types
27 support multiple lights 25 support multiple lights
28 enforce normal map is 4 channel 26 fix non-opaque diffuse textures
29 use SkImages instead if SkBitmaps
30 27
31 To Test: 28 To Test:
32 non-opaque diffuse textures
33 A8 diffuse textures 29 A8 diffuse textures
34 down & upsampled draws 30 down & upsampled draws
35 */ 31 */
36 32
37 33
38 34
39 /** \class SkLightingShaderImpl 35 /** \class SkLightingShaderImpl
40 This subclass of shader applies lighting. 36 This subclass of shader applies lighting.
41 */ 37 */
42 class SkLightingShaderImpl : public SkShader { 38 class SkLightingShaderImpl : public SkShader {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 70
75 ~LightingShaderContext() override; 71 ~LightingShaderContext() override;
76 72
77 void shadeSpan(int x, int y, SkPMColor[], int count) override; 73 void shadeSpan(int x, int y, SkPMColor[], int count) override;
78 74
79 uint32_t getFlags() const override { return fFlags; } 75 uint32_t getFlags() const override { return fFlags; }
80 76
81 private: 77 private:
82 SkShader::Context* fDiffuseContext; 78 SkShader::Context* fDiffuseContext;
83 SkNormalSource::Provider* fNormalProvider; 79 SkNormalSource::Provider* fNormalProvider;
80 SkColor fPaintColor;
84 uint32_t fFlags; 81 uint32_t fFlags;
85 82
86 void* fHeapAllocated; 83 void* fHeapAllocated;
87 84
88 typedef SkShader::Context INHERITED; 85 typedef SkShader::Context INHERITED;
89 }; 86 };
90 87
91 SK_TO_STRING_OVERRIDE() 88 SK_TO_STRING_OVERRIDE()
92 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl) 89 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl)
93 90
(...skipping 20 matching lines...) Expand all
114 #include "GrFragmentProcessor.h" 111 #include "GrFragmentProcessor.h"
115 #include "GrInvariantOutput.h" 112 #include "GrInvariantOutput.h"
116 #include "GrTextureAccess.h" 113 #include "GrTextureAccess.h"
117 #include "glsl/GrGLSLFragmentProcessor.h" 114 #include "glsl/GrGLSLFragmentProcessor.h"
118 #include "glsl/GrGLSLFragmentShaderBuilder.h" 115 #include "glsl/GrGLSLFragmentShaderBuilder.h"
119 #include "glsl/GrGLSLProgramDataManager.h" 116 #include "glsl/GrGLSLProgramDataManager.h"
120 #include "glsl/GrGLSLUniformHandler.h" 117 #include "glsl/GrGLSLUniformHandler.h"
121 #include "SkGr.h" 118 #include "SkGr.h"
122 #include "SkGrPriv.h" 119 #include "SkGrPriv.h"
123 120
121 // This FP expects a premul'd color input for its diffuse color. Premul'ing of t he paint's color is
122 // handled by the asFragmentProcessor() factory, but shaders providing diffuse c olor must output it
123 // premul'd.
124 class LightingFP : public GrFragmentProcessor { 124 class LightingFP : public GrFragmentProcessor {
125 public: 125 public:
126 LightingFP(sk_sp<GrFragmentProcessor> normalFP, sk_sp<SkLights> lights) { 126 LightingFP(sk_sp<GrFragmentProcessor> normalFP, sk_sp<SkLights> lights) {
127 127
128 // fuse all ambient lights into a single one 128 // fuse all ambient lights into a single one
129 fAmbientColor.set(0.0f, 0.0f, 0.0f); 129 fAmbientColor.set(0.0f, 0.0f, 0.0f);
130 for (int i = 0; i < lights->numLights(); ++i) { 130 for (int i = 0; i < lights->numLights(); ++i) {
131 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) { 131 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) {
132 fAmbientColor += lights->light(i).color(); 132 fAmbientColor += lights->light(i).color();
133 } else { 133 } else {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 fragBuilder->codeAppendf("vec4 diffuseColor = %s;", args.fInputColor ); 173 fragBuilder->codeAppendf("vec4 diffuseColor = %s;", args.fInputColor );
174 174
175 SkString dstNormalName("dstNormal"); 175 SkString dstNormalName("dstNormal");
176 this->emitChild(0, nullptr, &dstNormalName, args); 176 this->emitChild(0, nullptr, &dstNormalName, args);
177 177
178 fragBuilder->codeAppendf("vec3 normal = %s.xyz;", dstNormalName.c_st r()); 178 fragBuilder->codeAppendf("vec3 normal = %s.xyz;", dstNormalName.c_st r());
179 fragBuilder->codeAppendf("float NdotL = clamp(dot(normal, %s), 0.0, 1.0);", 179 fragBuilder->codeAppendf("float NdotL = clamp(dot(normal, %s), 0.0, 1.0);",
180 lightDirUniName); 180 lightDirUniName);
181 // diffuse light 181 // diffuse light
182 fragBuilder->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightColorUniName); 182 fragBuilder->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightColorUniName);
183 // ambient light 183 // ambient light (multiplied by input color's alpha because we're wo rking in premul'd
184 fragBuilder->codeAppendf("result += %s;", ambientColorUniName); 184 // space)
185 fragBuilder->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", a rgs.fOutputColor); 185 fragBuilder->codeAppendf("result += diffuseColor.a * %s;", ambientCo lorUniName);
186
187 // Clamping to alpha (equivalent to an unpremul'd clamp to 1.0)
188 fragBuilder->codeAppendf("%s = vec4(clamp(result.rgb, 0.0, diffuseCo lor.a), "
189 "diffuseColor.a);", args.fOutputC olor);
186 } 190 }
187 191
188 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, 192 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
189 GrProcessorKeyBuilder* b) { 193 GrProcessorKeyBuilder* b) {
190 // const LightingFP& lightingFP = proc.cast<LightingFP>(); 194 // const LightingFP& lightingFP = proc.cast<LightingFP>();
191 // only one shader generated currently 195 // only one shader generated currently
192 b->add32(0x0); 196 b->add32(0x0);
193 } 197 }
194 198
195 protected: 199 protected:
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 const SkMatrix* localMatrix , 267 const SkMatrix* localMatrix ,
264 SkFilterQuality filterQuali ty, 268 SkFilterQuality filterQuali ty,
265 SkSourceGammaTreatment gamm aTreatment) const { 269 SkSourceGammaTreatment gamm aTreatment) const {
266 sk_sp<GrFragmentProcessor> normalFP( 270 sk_sp<GrFragmentProcessor> normalFP(
267 fNormalSource->asFragmentProcessor(context, viewM, localMatrix, filt erQuality, 271 fNormalSource->asFragmentProcessor(context, viewM, localMatrix, filt erQuality,
268 gammaTreatment)); 272 gammaTreatment));
269 if (!normalFP) { 273 if (!normalFP) {
270 return nullptr; 274 return nullptr;
271 } 275 }
272 276
273 sk_sp<GrFragmentProcessor> fpPipeline[] = { 277 if (fDiffuseShader) {
278 sk_sp<GrFragmentProcessor> fpPipeline[] = {
274 fDiffuseShader->asFragmentProcessor(context, viewM, localMatrix, fil terQuality, 279 fDiffuseShader->asFragmentProcessor(context, viewM, localMatrix, fil terQuality,
275 gammaTreatment), 280 gammaTreatment),
276 sk_make_sp<LightingFP>(std::move(normalFP), fLights) 281 sk_make_sp<LightingFP>(std::move(normalFP), fLights)
277 }; 282 };
278 if(!fpPipeline[0]) { 283 if(!fpPipeline[0]) {
279 return nullptr; 284 return nullptr;
285 }
286
287 sk_sp<GrFragmentProcessor> innerLightFP = GrFragmentProcessor::RunInSeri es(fpPipeline, 2);
288 // FP is wrapped because paint's alpha needs to be applied to output
289 return GrFragmentProcessor::MulOutputByInputAlpha(std::move(innerLightFP ));
290 } else {
291 // FP is wrapped because paint comes in unpremul'd to fragment shader, b ut LightingFP
292 // expects premul'd color.
293 return GrFragmentProcessor::PremulInput(sk_make_sp<LightingFP>(std::move (normalFP),
294 fLights)) ;
280 } 295 }
281
282 sk_sp<GrFragmentProcessor> inner(GrFragmentProcessor::RunInSeries(fpPipeline , 2));
283
284 return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner));
285 } 296 }
286 297
287 #endif 298 #endif
288 299
289 //////////////////////////////////////////////////////////////////////////// 300 ////////////////////////////////////////////////////////////////////////////
290 301
291 bool SkLightingShaderImpl::isOpaque() const { 302 bool SkLightingShaderImpl::isOpaque() const {
292 return fDiffuseShader->isOpaque(); 303 return (fDiffuseShader ? fDiffuseShader->isOpaque() : false);
293 } 304 }
294 305
295 SkLightingShaderImpl::LightingShaderContext::LightingShaderContext( 306 SkLightingShaderImpl::LightingShaderContext::LightingShaderContext(
296 const SkLightingShaderImpl& shader, const ContextRec& rec, 307 const SkLightingShaderImpl& shader, const ContextRec& rec,
297 SkShader::Context* diffuseContext, SkNormalSource::Provider* normalProvi der, 308 SkShader::Context* diffuseContext, SkNormalSource::Provider* normalProvi der,
298 void* heapAllocated) 309 void* heapAllocated)
299 : INHERITED(shader, rec) 310 : INHERITED(shader, rec)
300 , fDiffuseContext(diffuseContext) 311 , fDiffuseContext(diffuseContext)
301 , fNormalProvider(normalProvider) 312 , fNormalProvider(normalProvider)
302 , fHeapAllocated(heapAllocated) { 313 , fHeapAllocated(heapAllocated) {
303 bool isOpaque = shader.isOpaque(); 314 bool isOpaque = shader.isOpaque();
304 315
305 // update fFlags 316 // update fFlags
306 uint32_t flags = 0; 317 uint32_t flags = 0;
307 if (isOpaque && (255 == this->getPaintAlpha())) { 318 if (isOpaque && (255 == this->getPaintAlpha())) {
308 flags |= kOpaqueAlpha_Flag; 319 flags |= kOpaqueAlpha_Flag;
309 } 320 }
310 321
322 fPaintColor = rec.fPaint->getColor();
311 fFlags = flags; 323 fFlags = flags;
312 } 324 }
313 325
314 SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() { 326 SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() {
315 // The dependencies have been created outside of the context on memory that was allocated by 327 // The dependencies have been created outside of the context on memory that was allocated by
316 // the onCreateContext() method. Call the destructors and free the memory. 328 // the onCreateContext() method. Call the destructors and free the memory.
317 fDiffuseContext->~Context(); 329 if (fDiffuseContext) {
330 fDiffuseContext->~Context();
331 }
318 fNormalProvider->~Provider(); 332 fNormalProvider->~Provider();
319 333
320 sk_free(fHeapAllocated); 334 sk_free(fHeapAllocated);
321 } 335 }
322 336
323 static inline SkPMColor convert(SkColor3f color, U8CPU a) { 337 static inline SkPMColor convert(SkColor3f color, U8CPU a) {
324 if (color.fX <= 0.0f) { 338 if (color.fX <= 0.0f) {
325 color.fX = 0.0f; 339 color.fX = 0.0f;
326 } else if (color.fX >= 255.0f) { 340 } else if (color.fX >= 255.0f) {
327 color.fX = 255.0f; 341 color.fX = 255.0f;
(...skipping 17 matching lines...) Expand all
345 // larger is better (fewer times we have to loop), but we shouldn't 359 // larger is better (fewer times we have to loop), but we shouldn't
346 // take up too much stack-space (each one here costs 16 bytes) 360 // take up too much stack-space (each one here costs 16 bytes)
347 #define BUFFER_MAX 16 361 #define BUFFER_MAX 16
348 void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y, 362 void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y,
349 SkPMColor result[], int count) { 363 SkPMColor result[], int count) {
350 const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShader Impl&>(fShader); 364 const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShader Impl&>(fShader);
351 365
352 SkPMColor diffuse[BUFFER_MAX]; 366 SkPMColor diffuse[BUFFER_MAX];
353 SkPoint3 normals[BUFFER_MAX]; 367 SkPoint3 normals[BUFFER_MAX];
354 368
369 SkColor diffColor = fPaintColor;
370
355 do { 371 do {
356 int n = SkTMin(count, BUFFER_MAX); 372 int n = SkTMin(count, BUFFER_MAX);
357 373
358 fDiffuseContext->shadeSpan(x, y, diffuse, n);
359 fNormalProvider->fillScanLine(x, y, normals, n); 374 fNormalProvider->fillScanLine(x, y, normals, n);
360 375
376 if (fDiffuseContext) {
377 fDiffuseContext->shadeSpan(x, y, diffuse, n);
378 }
379
361 for (int i = 0; i < n; ++i) { 380 for (int i = 0; i < n; ++i) {
362 381 if (fDiffuseContext) {
363 SkColor diffColor = SkUnPreMultiply::PMColorToColor(diffuse[i]); 382 diffColor = SkUnPreMultiply::PMColorToColor(diffuse[i]);
383 }
364 384
365 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f); 385 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f);
366 // This is all done in linear unpremul color space (each component 0 ..255.0f though) 386 // This is all done in linear unpremul color space (each component 0 ..255.0f though)
367 for (int l = 0; l < lightShader.fLights->numLights(); ++l) { 387 for (int l = 0; l < lightShader.fLights->numLights(); ++l) {
368 const SkLights::Light& light = lightShader.fLights->light(l); 388 const SkLights::Light& light = lightShader.fLights->light(l);
369 389
370 if (SkLights::Light::kAmbient_LightType == light.type()) { 390 if (SkLights::Light::kAmbient_LightType == light.type()) {
371 accum += light.color().makeScale(255.0f); 391 accum += light.color().makeScale(255.0f);
372 } else { 392 } else {
373 SkScalar NdotL = normals[i].dot(light.dir()); 393 SkScalar NdotL = normals[i].dot(light.dir());
374 if (NdotL < 0.0f) { 394 if (NdotL < 0.0f) {
375 NdotL = 0.0f; 395 NdotL = 0.0f;
376 } 396 }
377 397
378 accum.fX += light.color().fX * SkColorGetR(diffColor) * Ndot L; 398 accum.fX += light.color().fX * SkColorGetR(diffColor) * Ndot L;
379 accum.fY += light.color().fY * SkColorGetG(diffColor) * Ndot L; 399 accum.fY += light.color().fY * SkColorGetG(diffColor) * Ndot L;
380 accum.fZ += light.color().fZ * SkColorGetB(diffColor) * Ndot L; 400 accum.fZ += light.color().fZ * SkColorGetB(diffColor) * Ndot L;
381 } 401 }
382 } 402 }
383 403
404 // convert() premultiplies the accumulate color with alpha
384 result[i] = convert(accum, SkColorGetA(diffColor)); 405 result[i] = convert(accum, SkColorGetA(diffColor));
385 } 406 }
386 407
387 result += n; 408 result += n;
388 x += n; 409 x += n;
389 count -= n; 410 count -= n;
390 } while (count > 0); 411 } while (count > 0);
391 } 412 }
392 413
393 //////////////////////////////////////////////////////////////////////////// 414 ////////////////////////////////////////////////////////////////////////////
(...skipping 29 matching lines...) Expand all
423 if (!buf.readScalarArray(&dir.fX, 3)) { 444 if (!buf.readScalarArray(&dir.fX, 3)) {
424 return nullptr; 445 return nullptr;
425 } 446 }
426 builder.add(SkLights::Light(color, dir)); 447 builder.add(SkLights::Light(color, dir));
427 } 448 }
428 } 449 }
429 450
430 sk_sp<SkLights> lights(builder.finish()); 451 sk_sp<SkLights> lights(builder.finish());
431 452
432 sk_sp<SkNormalSource> normalSource(buf.readFlattenable<SkNormalSource>()); 453 sk_sp<SkNormalSource> normalSource(buf.readFlattenable<SkNormalSource>());
433 sk_sp<SkShader> diffuseShader(buf.readFlattenable<SkShader>()); 454
455 bool hasDiffuse = buf.readBool();
456 sk_sp<SkShader> diffuseShader = nullptr;
457 if (hasDiffuse) {
458 diffuseShader = buf.readFlattenable<SkShader>();
459 }
434 460
435 return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move( normalSource), 461 return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move( normalSource),
436 std::move(lights)); 462 std::move(lights));
437 } 463 }
438 464
439 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { 465 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const {
440 this->INHERITED::flatten(buf); 466 this->INHERITED::flatten(buf);
441 467
442 buf.writeInt(fLights->numLights()); 468 buf.writeInt(fLights->numLights());
443 for (int l = 0; l < fLights->numLights(); ++l) { 469 for (int l = 0; l < fLights->numLights(); ++l) {
444 const SkLights::Light& light = fLights->light(l); 470 const SkLights::Light& light = fLights->light(l);
445 471
446 bool isAmbient = SkLights::Light::kAmbient_LightType == light.type(); 472 bool isAmbient = SkLights::Light::kAmbient_LightType == light.type();
447 473
448 buf.writeBool(isAmbient); 474 buf.writeBool(isAmbient);
449 buf.writeScalarArray(&light.color().fX, 3); 475 buf.writeScalarArray(&light.color().fX, 3);
450 if (!isAmbient) { 476 if (!isAmbient) {
451 buf.writeScalarArray(&light.dir().fX, 3); 477 buf.writeScalarArray(&light.dir().fX, 3);
452 } 478 }
453 } 479 }
454 480
455 buf.writeFlattenable(fNormalSource.get()); 481 buf.writeFlattenable(fNormalSource.get());
456 buf.writeFlattenable(fDiffuseShader.get()); 482 buf.writeBool(fDiffuseShader);
483 if (fDiffuseShader) {
484 buf.writeFlattenable(fDiffuseShader.get());
485 }
457 } 486 }
458 487
459 size_t SkLightingShaderImpl::onContextSize(const ContextRec& rec) const { 488 size_t SkLightingShaderImpl::onContextSize(const ContextRec& rec) const {
460 return sizeof(LightingShaderContext); 489 return sizeof(LightingShaderContext);
461 } 490 }
462 491
463 SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, 492 SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec,
464 void* storage) const { 493 void* storage) const {
465 size_t heapRequired = fDiffuseShader->contextSize(rec) + 494 size_t heapRequired = (fDiffuseShader ? fDiffuseShader->contextSize(rec) : 0 ) +
466 fNormalSource->providerSize(rec); 495 fNormalSource->providerSize(rec);
467 void* heapAllocated = sk_malloc_throw(heapRequired); 496 void* heapAllocated = sk_malloc_throw(heapRequired);
468 497
469 void* diffuseContextStorage = heapAllocated; 498 void* diffuseContextStorage = heapAllocated;
470 SkShader::Context* diffuseContext = fDiffuseShader->createContext(rec, diffu seContextStorage); 499 void* normalProviderStorage = (char*) diffuseContextStorage +
471 if (!diffuseContext) { 500 (fDiffuseShader ? fDiffuseShader->contextSize( rec) : 0);
472 sk_free(heapAllocated); 501
473 return nullptr; 502 SkShader::Context *diffuseContext = nullptr;
503 if (fDiffuseShader) {
504 diffuseContext = fDiffuseShader->createContext(rec, diffuseContextStorag e);
505 if (!diffuseContext) {
506 sk_free(heapAllocated);
507 return nullptr;
508 }
474 } 509 }
475 510
476 void* normalProviderStorage = (char*)heapAllocated + fDiffuseShader->context Size(rec);
477 SkNormalSource::Provider* normalProvider = fNormalSource->asProvider(rec, 511 SkNormalSource::Provider* normalProvider = fNormalSource->asProvider(rec,
478 normalP roviderStorage); 512 normalP roviderStorage);
479 if (!normalProvider) { 513 if (!normalProvider) {
480 diffuseContext->~Context(); 514 diffuseContext->~Context();
481 sk_free(heapAllocated); 515 sk_free(heapAllocated);
482 return nullptr; 516 return nullptr;
483 } 517 }
484 518
485 return new (storage) LightingShaderContext(*this, rec, diffuseContext, norma lProvider, 519 return new (storage) LightingShaderContext(*this, rec, diffuseContext, norma lProvider,
486 heapAllocated); 520 heapAllocated);
487 } 521 }
488 522
489 /////////////////////////////////////////////////////////////////////////////// 523 ///////////////////////////////////////////////////////////////////////////////
490 524
491 sk_sp<SkShader> SkLightingShader::Make(sk_sp<SkShader> diffuseShader, 525 sk_sp<SkShader> SkLightingShader::Make(sk_sp<SkShader> diffuseShader,
492 sk_sp<SkNormalSource> normalSource, 526 sk_sp<SkNormalSource> normalSource,
493 sk_sp<SkLights> lights) { 527 sk_sp<SkLights> lights) {
494 if (!diffuseShader || !normalSource) { 528 if (!normalSource) {
495 // TODO: Use paint's color in absence of a diffuseShader 529 normalSource = SkNormalSource::MakeFlat();
496 // TODO: Use a default implementation of normalSource instead
497 return nullptr;
498 } 530 }
499 531
500 return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move( normalSource), 532 return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move( normalSource),
501 std::move(lights)); 533 std::move(lights));
502 } 534 }
503 535
504 /////////////////////////////////////////////////////////////////////////////// 536 ///////////////////////////////////////////////////////////////////////////////
505 537
506 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) 538 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader)
507 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) 539 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl)
508 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 540 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
509 541
510 /////////////////////////////////////////////////////////////////////////////// 542 ///////////////////////////////////////////////////////////////////////////////
OLDNEW
« no previous file with comments | « src/core/SkLightingShader.h ('k') | src/core/SkNormalSource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698