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

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

Issue 2050773002: Refactoring of CPU NormalMap handling out into its own class (Closed) Base URL: https://skia.googlesource.com/skia@dvonbeck-normals-gpu-cl
Patch Set: SkLS Context dependencies now allocated on the heap 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/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 "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 "SkPoint3.h" 16 #include "SkPoint3.h"
16 #include "SkReadBuffer.h" 17 #include "SkReadBuffer.h"
17 #include "SkWriteBuffer.h" 18 #include "SkWriteBuffer.h"
18 19
19 //////////////////////////////////////////////////////////////////////////// 20 ////////////////////////////////////////////////////////////////////////////
20 21
21 /* 22 /*
22 SkLightingShader TODOs: 23 SkLightingShader TODOs:
23 support other than clamp mode 24 support other than clamp mode
24 allow 'diffuse' & 'normal' to be of different dimensions? 25 allow 'diffuse' & 'normal' to be of different dimensions?
(...skipping 23 matching lines...) Expand all
48 @param lights the lights applied to the normal map 49 @param lights the lights applied to the normal map
49 @param invNormRotation rotation applied to the normal map's normals 50 @param invNormRotation rotation applied to the normal map's normals
50 @param diffLocalM the local matrix for the diffuse coordinates 51 @param diffLocalM the local matrix for the diffuse coordinates
51 @param normLocalM the local matrix for the normal coordinates 52 @param normLocalM the local matrix for the normal coordinates
52 @param normalSource the normal source for GPU computations 53 @param normalSource the normal source for GPU computations
53 */ 54 */
54 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal, 55 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal,
55 const sk_sp<SkLights> lights, 56 const sk_sp<SkLights> lights,
56 const SkVector& invNormRotation, 57 const SkVector& invNormRotation,
57 const SkMatrix* diffLocalM, const SkMatrix* normLocalM, 58 const SkMatrix* diffLocalM, const SkMatrix* normLocalM,
58 sk_sp<SkLightingShader::NormalSource> normalSource) 59 sk_sp<SkNormalSource> normalSource)
59 : INHERITED(diffLocalM) 60 : INHERITED(diffLocalM)
60 , fDiffuseMap(diffuse) 61 , fDiffuseMap(diffuse)
61 , fNormalMap(normal) 62 , fNormalMap(normal)
62 , fLights(std::move(lights)) 63 , fLights(std::move(lights))
63 , fInvNormRotation(invNormRotation) { 64 , fInvNormRotation(invNormRotation) {
64 65
65 if (normLocalM) { 66 if (normLocalM) {
66 fNormLocalMatrix = *normLocalM; 67 fNormLocalMatrix = *normLocalM;
67 } else { 68 } else {
68 fNormLocalMatrix.reset(); 69 fNormLocalMatrix.reset();
(...skipping 12 matching lines...) Expand all
81 const SkMatrix* localMatrix, 82 const SkMatrix* localMatrix,
82 SkFilterQuality, 83 SkFilterQuality,
83 SkSourceGammaTreatment) const override; 84 SkSourceGammaTreatment) const override;
84 #endif 85 #endif
85 86
86 class LightingShaderContext : public SkShader::Context { 87 class LightingShaderContext : public SkShader::Context {
87 public: 88 public:
88 // The context takes ownership of the states. It will call their destruc tors 89 // The context takes ownership of the states. It will call their destruc tors
89 // but will NOT free the memory. 90 // but will NOT free the memory.
90 LightingShaderContext(const SkLightingShaderImpl&, const ContextRec&, 91 LightingShaderContext(const SkLightingShaderImpl&, const ContextRec&,
91 SkBitmapProcState* diffuseState, SkBitmapProcState * normalState); 92 SkBitmapProcState* diffuseState, SkNormalSource::P rovider*,
93 void* heapAllocated);
92 ~LightingShaderContext() override; 94 ~LightingShaderContext() override;
93 95
94 void shadeSpan(int x, int y, SkPMColor[], int count) override; 96 void shadeSpan(int x, int y, SkPMColor[], int count) override;
95 97
96 uint32_t getFlags() const override { return fFlags; } 98 uint32_t getFlags() const override { return fFlags; }
97 99
98 private: 100 private:
99 SkBitmapProcState* fDiffuseState; 101 SkBitmapProcState* fDiffuseState;
100 SkBitmapProcState* fNormalState; 102 SkNormalSource::Provider* fNormalProvider;
101 uint32_t fFlags; 103 uint32_t fFlags;
104
105 void* fHeapAllocated;
102 106
103 typedef SkShader::Context INHERITED; 107 typedef SkShader::Context INHERITED;
104 }; 108 };
105 109
106 SK_TO_STRING_OVERRIDE() 110 SK_TO_STRING_OVERRIDE()
107 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl) 111 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl)
108 112
109 protected: 113 protected:
110 void flatten(SkWriteBuffer&) const override; 114 void flatten(SkWriteBuffer&) const override;
111 size_t onContextSize(const ContextRec&) const override; 115 size_t onContextSize(const ContextRec&) const override;
112 Context* onCreateContext(const ContextRec&, void*) const override; 116 Context* onCreateContext(const ContextRec&, void*) const override;
113 bool computeNormTotalInverse(const ContextRec& rec, SkMatrix* normTotalInver se) const;
114 117
115 private: 118 private:
116 SkBitmap fDiffuseMap; 119 SkBitmap fDiffuseMap;
117 SkBitmap fNormalMap; 120 SkBitmap fNormalMap;
118 121
119 sk_sp<SkLights> fLights; 122 sk_sp<SkLights> fLights;
120 123
121 SkMatrix fNormLocalMatrix; 124 SkMatrix fNormLocalMatrix;
122 SkVector fInvNormRotation; 125 SkVector fInvNormRotation;
123 126
124 sk_sp<SkLightingShader::NormalSource> fNormalSource; 127 sk_sp<SkNormalSource> fNormalSource;
125 128
126 friend class SkLightingShader; 129 friend class SkLightingShader;
127 130
128 typedef SkShader INHERITED; 131 typedef SkShader INHERITED;
129 }; 132 };
130 133
131 //////////////////////////////////////////////////////////////////////////// 134 ////////////////////////////////////////////////////////////////////////////
132 135
133 #if SK_SUPPORT_GPU 136 #if SK_SUPPORT_GPU
134 137
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 363
361 #endif 364 #endif
362 365
363 //////////////////////////////////////////////////////////////////////////// 366 ////////////////////////////////////////////////////////////////////////////
364 367
365 bool SkLightingShaderImpl::isOpaque() const { 368 bool SkLightingShaderImpl::isOpaque() const {
366 return fDiffuseMap.isOpaque(); 369 return fDiffuseMap.isOpaque();
367 } 370 }
368 371
369 SkLightingShaderImpl::LightingShaderContext::LightingShaderContext( 372 SkLightingShaderImpl::LightingShaderContext::LightingShaderContext(
370 const SkLighting ShaderImpl& shader, 373 const SkLightingShaderImpl& shader, const ContextRec& rec, SkBitmapProcS tate* diffuseState,
371 const ContextRec & rec, 374 SkNormalSource::Provider* normalProvider, void* heapAllocated)
372 SkBitmapProcStat e* diffuseState,
373 SkBitmapProcStat e* normalState)
374 : INHERITED(shader, rec) 375 : INHERITED(shader, rec)
375 , fDiffuseState(diffuseState) 376 , fDiffuseState(diffuseState)
376 , fNormalState(normalState) { 377 , fNormalProvider(normalProvider)
378 , fHeapAllocated(heapAllocated) {
377 const SkPixmap& pixmap = fDiffuseState->fPixmap; 379 const SkPixmap& pixmap = fDiffuseState->fPixmap;
378 bool isOpaque = pixmap.isOpaque(); 380 bool isOpaque = pixmap.isOpaque();
379 381
380 // update fFlags 382 // update fFlags
381 uint32_t flags = 0; 383 uint32_t flags = 0;
382 if (isOpaque && (255 == this->getPaintAlpha())) { 384 if (isOpaque && (255 == this->getPaintAlpha())) {
383 flags |= kOpaqueAlpha_Flag; 385 flags |= kOpaqueAlpha_Flag;
384 } 386 }
385 387
386 fFlags = flags; 388 fFlags = flags;
387 } 389 }
388 390
389 SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() { 391 SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() {
390 // The bitmap proc states have been created outside of the context on memory that will be freed 392 // The bitmap proc states have been created outside of the context on memory that will be freed
391 // elsewhere. Call the destructors but leave the freeing of the memory to th e caller. 393 // elsewhere. Call the destructors but leave the freeing of the memory to th e caller.
392 fDiffuseState->~SkBitmapProcState(); 394 fDiffuseState->~SkBitmapProcState();
393 fNormalState->~SkBitmapProcState(); 395 fNormalProvider->~Provider();
396
397 sk_free(fHeapAllocated);
394 } 398 }
395 399
396 static inline SkPMColor convert(SkColor3f color, U8CPU a) { 400 static inline SkPMColor convert(SkColor3f color, U8CPU a) {
397 if (color.fX <= 0.0f) { 401 if (color.fX <= 0.0f) {
398 color.fX = 0.0f; 402 color.fX = 0.0f;
399 } else if (color.fX >= 255.0f) { 403 } else if (color.fX >= 255.0f) {
400 color.fX = 255.0f; 404 color.fX = 255.0f;
401 } 405 }
402 406
403 if (color.fY <= 0.0f) { 407 if (color.fY <= 0.0f) {
404 color.fY = 0.0f; 408 color.fY = 0.0f;
405 } else if (color.fY >= 255.0f) { 409 } else if (color.fY >= 255.0f) {
406 color.fY = 255.0f; 410 color.fY = 255.0f;
407 } 411 }
408 412
409 if (color.fZ <= 0.0f) { 413 if (color.fZ <= 0.0f) {
410 color.fZ = 0.0f; 414 color.fZ = 0.0f;
411 } else if (color.fZ >= 255.0f) { 415 } else if (color.fZ >= 255.0f) {
412 color.fZ = 255.0f; 416 color.fZ = 255.0f;
413 } 417 }
414 418
415 return SkPreMultiplyARGB(a, (int) color.fX, (int) color.fY, (int) color.fZ) ; 419 return SkPreMultiplyARGB(a, (int) color.fX, (int) color.fY, (int) color.fZ) ;
416 } 420 }
417 421
418 // larger is better (fewer times we have to loop), but we shouldn't 422 // larger is better (fewer times we have to loop), but we shouldn't
419 // take up too much stack-space (each one here costs 16 bytes) 423 // take up too much stack-space (each one here costs 16 bytes)
420 #define TMP_COUNT 16 424 #define TMP_COUNT 16
421 425 #define BUFFER_MAX ((int)(TMP_COUNT * sizeof(uint32_t)))
422 void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y, 426 void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y,
423 SkPMColor result[], int count) { 427 SkPMColor result[], int count) {
424 const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShader Impl&>(fShader); 428 const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShader Impl&>(fShader);
425 429
426 uint32_t tmpColor[TMP_COUNT], tmpNormal[TMP_COUNT]; 430 uint32_t tmpColor[TMP_COUNT];
427 SkPMColor tmpColor2[2*TMP_COUNT], tmpNormal2[2*TMP_COUNT]; 431 SkPMColor tmpColor2[2*TMP_COUNT];
428 432
429 SkBitmapProcState::MatrixProc diffMProc = fDiffuseState->getMatrixProc(); 433 SkBitmapProcState::MatrixProc diffMProc = fDiffuseState->getMatrixProc();
430 SkBitmapProcState::SampleProc32 diffSProc = fDiffuseState->getSampleProc32() ; 434 SkBitmapProcState::SampleProc32 diffSProc = fDiffuseState->getSampleProc32() ;
431 435
432 SkBitmapProcState::MatrixProc normalMProc = fNormalState->getMatrixProc(); 436 int max = fDiffuseState->maxCountForBufferSize(BUFFER_MAX);
433 SkBitmapProcState::SampleProc32 normalSProc = fNormalState->getSampleProc32( );
434
435 int diffMax = fDiffuseState->maxCountForBufferSize(sizeof(tmpColor[0]) * TMP _COUNT);
436 int normMax = fNormalState->maxCountForBufferSize(sizeof(tmpNormal[0]) * TMP _COUNT);
437 int max = SkTMin(diffMax, normMax);
438 437
439 SkASSERT(fDiffuseState->fPixmap.addr()); 438 SkASSERT(fDiffuseState->fPixmap.addr());
440 SkASSERT(fNormalState->fPixmap.addr());
441 439
442 SkPoint3 norm, xformedNorm; 440 SkASSERT(max <= BUFFER_MAX);
441 SkPoint3 normals[BUFFER_MAX];
443 442
444 do { 443 do {
445 int n = count; 444 int n = count;
446 if (n > max) { 445 if (n > max) {
447 n = max; 446 n = max;
448 } 447 }
449 448
450 diffMProc(*fDiffuseState, tmpColor, n, x, y); 449 diffMProc(*fDiffuseState, tmpColor, n, x, y);
451 diffSProc(*fDiffuseState, tmpColor, n, tmpColor2); 450 diffSProc(*fDiffuseState, tmpColor, n, tmpColor2);
452 451
453 normalMProc(*fNormalState, tmpNormal, n, x, y); 452 fNormalProvider->fillScanLine(x, y, normals, n);
454 normalSProc(*fNormalState, tmpNormal, n, tmpNormal2);
455 453
456 for (int i = 0; i < n; ++i) { 454 for (int i = 0; i < n; ++i) {
457 SkASSERT(0xFF == SkColorGetA(tmpNormal2[i])); // opaque -> unpremul
458 norm.set(SkIntToScalar(SkGetPackedR32(tmpNormal2[i]))-127.0f,
459 SkIntToScalar(SkGetPackedG32(tmpNormal2[i]))-127.0f,
460 SkIntToScalar(SkGetPackedB32(tmpNormal2[i]))-127.0f);
461 norm.normalize();
462
463 xformedNorm.fX = lightShader.fInvNormRotation.fX * norm.fX +
464 lightShader.fInvNormRotation.fY * norm.fY;
465 xformedNorm.fY = -lightShader.fInvNormRotation.fY * norm.fX +
466 lightShader.fInvNormRotation.fX * norm.fY;
467 xformedNorm.fZ = norm.fZ;
468 455
469 SkColor diffColor = SkUnPreMultiply::PMColorToColor(tmpColor2[i]); 456 SkColor diffColor = SkUnPreMultiply::PMColorToColor(tmpColor2[i]);
470 457
471 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f); 458 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f);
472 // This is all done in linear unpremul color space (each component 0 ..255.0f though) 459 // This is all done in linear unpremul color space (each component 0 ..255.0f though)
473 for (int l = 0; l < lightShader.fLights->numLights(); ++l) { 460 for (int l = 0; l < lightShader.fLights->numLights(); ++l) {
474 const SkLights::Light& light = lightShader.fLights->light(l); 461 const SkLights::Light& light = lightShader.fLights->light(l);
475 462
476 if (SkLights::Light::kAmbient_LightType == light.type()) { 463 if (SkLights::Light::kAmbient_LightType == light.type()) {
477 accum += light.color().makeScale(255.0f); 464 accum += light.color().makeScale(255.0f);
478 } else { 465 } else {
479 SkScalar NdotL = xformedNorm.dot(light.dir()); 466 SkScalar NdotL = normals[i].dot(light.dir());
480 if (NdotL < 0.0f) { 467 if (NdotL < 0.0f) {
481 NdotL = 0.0f; 468 NdotL = 0.0f;
482 } 469 }
483 470
484 accum.fX += light.color().fX * SkColorGetR(diffColor) * Ndot L; 471 accum.fX += light.color().fX * SkColorGetR(diffColor) * Ndot L;
485 accum.fY += light.color().fY * SkColorGetG(diffColor) * Ndot L; 472 accum.fY += light.color().fY * SkColorGetG(diffColor) * Ndot L;
486 accum.fZ += light.color().fZ * SkColorGetB(diffColor) * Ndot L; 473 accum.fZ += light.color().fZ * SkColorGetB(diffColor) * Ndot L;
487 } 474 }
488 } 475 }
489 476
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 } 543 }
557 } 544 }
558 545
559 sk_sp<SkLights> lights(builder.finish()); 546 sk_sp<SkLights> lights(builder.finish());
560 547
561 SkVector invNormRotation = {1,0}; 548 SkVector invNormRotation = {1,0};
562 if (!buf.isVersionLT(SkReadBuffer::kLightingShaderWritesInvNormRotation)) { 549 if (!buf.isVersionLT(SkReadBuffer::kLightingShaderWritesInvNormRotation)) {
563 invNormRotation = buf.readPoint(); 550 invNormRotation = buf.readPoint();
564 } 551 }
565 552
566 sk_sp<SkLightingShader::NormalSource> normalSource( 553 sk_sp<SkNormalSource> normalSource(buf.readFlattenable<SkNormalSource>());
567 buf.readFlattenable<SkLightingShader::NormalSource>());
568 554
569 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), invNormRotation, 555 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), invNormRotation,
570 &diffLocalM, &normLocalM, std::move( normalSource)); 556 &diffLocalM, &normLocalM, std::move( normalSource));
571 } 557 }
572 558
573 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { 559 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const {
574 this->INHERITED::flatten(buf); 560 this->INHERITED::flatten(buf);
575 561
576 bool hasNormLocalM = !fNormLocalMatrix.isIdentity(); 562 bool hasNormLocalM = !fNormLocalMatrix.isIdentity();
577 buf.writeBool(hasNormLocalM); 563 buf.writeBool(hasNormLocalM);
(...skipping 14 matching lines...) Expand all
592 buf.writeScalarArray(&light.color().fX, 3); 578 buf.writeScalarArray(&light.color().fX, 3);
593 if (!isAmbient) { 579 if (!isAmbient) {
594 buf.writeScalarArray(&light.dir().fX, 3); 580 buf.writeScalarArray(&light.dir().fX, 3);
595 } 581 }
596 } 582 }
597 buf.writePoint(fInvNormRotation); 583 buf.writePoint(fInvNormRotation);
598 584
599 buf.writeFlattenable(fNormalSource.get()); 585 buf.writeFlattenable(fNormalSource.get());
600 } 586 }
601 587
602 bool SkLightingShaderImpl::computeNormTotalInverse(const ContextRec& rec, 588 size_t SkLightingShaderImpl::onContextSize(const ContextRec& rec) const {
603 SkMatrix* normTotalInverse) c onst { 589 return sizeof(LightingShaderContext);
604 SkMatrix total;
605 total.setConcat(*rec.fMatrix, fNormLocalMatrix);
606
607 const SkMatrix* m = &total;
608 if (rec.fLocalMatrix) {
609 total.setConcat(*m, *rec.fLocalMatrix);
610 m = &total;
611 }
612 return m->invert(normTotalInverse);
613 }
614
615 size_t SkLightingShaderImpl::onContextSize(const ContextRec&) const {
616 return 2 * sizeof(SkBitmapProcState) + sizeof(LightingShaderContext);
617 } 590 }
618 591
619 SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, 592 SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec,
620 void* storage) const { 593 void* storage) const {
621 594
622 SkMatrix diffTotalInv; 595 SkMatrix diffTotalInv;
623 // computeTotalInverse was called in SkShader::createContext so we know it w ill succeed 596 // computeTotalInverse was called in SkShader::createContext so we know it w ill succeed
624 SkAssertResult(this->computeTotalInverse(rec, &diffTotalInv)); 597 SkAssertResult(this->computeTotalInverse(rec, &diffTotalInv));
625 598
626 SkMatrix normTotalInv; 599 size_t heapRequired = sizeof(SkBitmapProcState) + fNormalSource->providerSiz e(rec);
627 if (!this->computeNormTotalInverse(rec, &normTotalInv)) { 600 void* heapAllocated = sk_malloc_throw(heapRequired);
628 return nullptr;
629 }
630 601
631 void* diffuseStateStorage = (char*)storage + sizeof(LightingShaderContext); 602 void* diffuseStateStorage = heapAllocated;
632 SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcStat e(fDiffuseMap, 603 SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcStat e(fDiffuseMap,
633 SkShader::kClamp_TileMode, SkShade r::kClamp_TileMode, 604 SkShader::kClamp_TileMode, SkShade r::kClamp_TileMode,
634 SkMipMap::De duceTreatment(rec)); 605 SkMipMap::De duceTreatment(rec));
635 SkASSERT(diffuseState); 606 SkASSERT(diffuseState);
636 if (!diffuseState->setup(diffTotalInv, *rec.fPaint)) { 607 if (!diffuseState->setup(diffTotalInv, *rec.fPaint)) {
637 diffuseState->~SkBitmapProcState(); 608 diffuseState->~SkBitmapProcState();
609 sk_free(heapAllocated);
610 return nullptr;
611 }
612 void* normalProviderStorage = (char*)heapAllocated + sizeof(SkBitmapProcStat e);
613
614 SkNormalSource::Provider* normalProvider = fNormalSource->asProvider(rec,
615 normalP roviderStorage);
616 if (!normalProvider) {
617 diffuseState->~SkBitmapProcState();
618 sk_free(heapAllocated);
638 return nullptr; 619 return nullptr;
639 } 620 }
640 621
641 void* normalStateStorage = (char*)storage + 622 return new (storage) LightingShaderContext(*this, rec, diffuseState, normalP rovider,
642 sizeof(LightingShaderContext) + 623 heapAllocated);
643 sizeof(SkBitmapProcState);
644 SkBitmapProcState* normalState = new (normalStateStorage) SkBitmapProcState( fNormalMap,
645 SkShader::kClamp_TileMode, SkShader: :kClamp_TileMode,
646 SkMipMap::De duceTreatment(rec));
647 SkASSERT(normalState);
648 if (!normalState->setup(normTotalInv, *rec.fPaint)) {
649 diffuseState->~SkBitmapProcState();
650 normalState->~SkBitmapProcState();
651 return nullptr;
652 }
653
654 return new (storage) LightingShaderContext(*this, rec, diffuseState, normalS tate);
655 } 624 }
656 625
657 /////////////////////////////////////////////////////////////////////////////// 626 ///////////////////////////////////////////////////////////////////////////////
658 627
659 sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, const SkBitmap& normal, 628 sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, const SkBitmap& normal,
660 sk_sp<SkLights> lights, 629 sk_sp<SkLights> lights,
661 const SkVector& invNormRotation, 630 const SkVector& invNormRotation,
662 const SkMatrix* diffLocalM, const SkMatri x* normLocalM) { 631 const SkMatrix* diffLocalM, const SkMatri x* normLocalM) {
663 if (diffuse.isNull() || SkBitmapProcShader::BitmapIsTooBig(diffuse) || 632 if (diffuse.isNull() || SkBitmapProcShader::BitmapIsTooBig(diffuse) ||
664 normal.isNull() || SkBitmapProcShader::BitmapIsTooBig(normal) || 633 normal.isNull() || SkBitmapProcShader::BitmapIsTooBig(normal) ||
665 diffuse.width() != normal.width() || 634 diffuse.width() != normal.width() ||
666 diffuse.height() != normal.height()) { 635 diffuse.height() != normal.height()) {
667 return nullptr; 636 return nullptr;
668 } 637 }
669 SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1)); 638 SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1));
670 639
671 sk_sp<SkLightingShader::NormalSource> normalSource = 640 // TODO: support other tile modes
672 SkLightingShader::NormalSource::MakeMap(normal, invNormRotation, nor mLocalM); 641 sk_sp<SkShader> mapShader = SkMakeBitmapShader(normal, SkShader::kClamp_Tile Mode,
642 SkShader::kClamp_TileMode, no rmLocalM, nullptr);
643
644 sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeFromNormalMap(mapSh ader,
645 invNo rmRotation);
673 646
674 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), 647 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights),
675 invNormRotation, diffLocalM, normLocalM, std::move(normalSource)); 648 invNormRotation, diffLocalM, normLocalM, std::move(normalSource));
676 } 649 }
677 650
678 /////////////////////////////////////////////////////////////////////////////// 651 ///////////////////////////////////////////////////////////////////////////////
679 652
680 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) 653 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader)
681 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) 654 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl)
682 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 655 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
683 656
684 /////////////////////////////////////////////////////////////////////////////// 657 ///////////////////////////////////////////////////////////////////////////////
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