OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 | 8 |
9 #include "SkLights.h" | 9 #include "SkLights.h" |
10 #include "SkReadBuffer.h" | 10 #include "SkReadBuffer.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 | 54 |
55 uint32_t getFlags() const override { return fFlags; } | 55 uint32_t getFlags() const override { return fFlags; } |
56 | 56 |
57 private: | 57 private: |
58 SkShader::Context* fPovDepthContext; | 58 SkShader::Context* fPovDepthContext; |
59 SkShader::Context* fDiffuseContext; | 59 SkShader::Context* fDiffuseContext; |
60 uint32_t fFlags; | 60 uint32_t fFlags; |
61 | 61 |
62 void* fHeapAllocated; | 62 void* fHeapAllocated; |
63 | 63 |
64 int fNonAmbLightCnt; | |
65 SkPixmap* fShadowMapPixels[SkShadowShader::kMaxNonAmbientLights] = {null ptr}; | |
66 | |
67 | |
64 typedef SkShader::Context INHERITED; | 68 typedef SkShader::Context INHERITED; |
65 }; | 69 }; |
66 | 70 |
67 SK_TO_STRING_OVERRIDE() | 71 SK_TO_STRING_OVERRIDE() |
68 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkShadowShaderImpl) | 72 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkShadowShaderImpl) |
69 | 73 |
70 protected: | 74 protected: |
71 void flatten(SkWriteBuffer&) const override; | 75 void flatten(SkWriteBuffer&) const override; |
72 size_t onContextSize(const ContextRec&) const override; | 76 size_t onContextSize(const ContextRec&) const override; |
73 Context* onCreateContext(const ContextRec&, void*) const override; | 77 Context* onCreateContext(const ContextRec&, void*) const override; |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
493 , fHeapAllocated(heapAllocated) { | 497 , fHeapAllocated(heapAllocated) { |
494 bool isOpaque = shader.isOpaque(); | 498 bool isOpaque = shader.isOpaque(); |
495 | 499 |
496 // update fFlags | 500 // update fFlags |
497 uint32_t flags = 0; | 501 uint32_t flags = 0; |
498 if (isOpaque && (255 == this->getPaintAlpha())) { | 502 if (isOpaque && (255 == this->getPaintAlpha())) { |
499 flags |= kOpaqueAlpha_Flag; | 503 flags |= kOpaqueAlpha_Flag; |
500 } | 504 } |
501 | 505 |
502 fFlags = flags; | 506 fFlags = flags; |
507 | |
508 const SkShadowShaderImpl& lightShader = static_cast<const SkShadowShaderImpl &>(fShader); | |
509 | |
510 fNonAmbLightCnt = 0; | |
511 | |
robertphillips
2016/08/24 14:48:53
Since you're densely packing the pixmaps, let's ad
vjiaoblack
2016/08/29 15:45:48
Done.
| |
512 for (int i = 0; i < lightShader.fLights->numLights(); i++) { | |
513 if (lightShader.fLights->light(i).type() == SkLights::Light::kDirectiona l_LightType) { | |
514 fShadowMapPixels[fNonAmbLightCnt] = new SkPixmap(); | |
515 if (!lightShader.fLights->light(i).getShadowMap()-> | |
516 peekPixels(fShadowMapPixels[fNonAmbLightCnt])) { | |
robertphillips
2016/08/24 14:48:53
this assignment doesn't seem so good ...
vjiaoblack
2016/08/29 15:45:48
Done.
| |
517 fShadowMapPixels[fNonAmbLightCnt] = nullptr; | |
518 } | |
519 fNonAmbLightCnt++; | |
520 } | |
521 } | |
503 } | 522 } |
504 | 523 |
505 SkShadowShaderImpl::ShadowShaderContext::~ShadowShaderContext() { | 524 SkShadowShaderImpl::ShadowShaderContext::~ShadowShaderContext() { |
506 // The dependencies have been created outside of the context on memory that was allocated by | 525 // The dependencies have been created outside of the context on memory that was allocated by |
507 // the onCreateContext() method. Call the destructors and free the memory. | 526 // the onCreateContext() method. Call the destructors and free the memory. |
508 fPovDepthContext->~Context(); | 527 fPovDepthContext->~Context(); |
509 fDiffuseContext->~Context(); | 528 fDiffuseContext->~Context(); |
510 | 529 |
511 sk_free(fHeapAllocated); | 530 sk_free(fHeapAllocated); |
531 | |
532 for (int i = 0; i < SkShadowShader::kMaxNonAmbientLights; i++) { | |
533 if (fShadowMapPixels[i]) { | |
534 delete fShadowMapPixels[i]; | |
535 } | |
536 } | |
512 } | 537 } |
513 | 538 |
514 static inline SkPMColor convert(SkColor3f color, U8CPU a) { | 539 static inline SkPMColor convert(SkColor3f color, U8CPU a) { |
515 if (color.fX <= 0.0f) { | 540 if (color.fX <= 0.0f) { |
516 color.fX = 0.0f; | 541 color.fX = 0.0f; |
517 } else if (color.fX >= 255.0f) { | 542 } else if (color.fX >= 255.0f) { |
518 color.fX = 255.0f; | 543 color.fX = 255.0f; |
519 } | 544 } |
520 | 545 |
521 if (color.fY <= 0.0f) { | 546 if (color.fY <= 0.0f) { |
(...skipping 12 matching lines...) Expand all Loading... | |
534 } | 559 } |
535 | 560 |
536 // larger is better (fewer times we have to loop), but we shouldn't | 561 // larger is better (fewer times we have to loop), but we shouldn't |
537 // take up too much stack-space (each one here costs 16 bytes) | 562 // take up too much stack-space (each one here costs 16 bytes) |
538 #define BUFFER_MAX 16 | 563 #define BUFFER_MAX 16 |
539 void SkShadowShaderImpl::ShadowShaderContext::shadeSpan(int x, int y, | 564 void SkShadowShaderImpl::ShadowShaderContext::shadeSpan(int x, int y, |
540 SkPMColor result[], int count) { | 565 SkPMColor result[], int count) { |
541 const SkShadowShaderImpl& lightShader = static_cast<const SkShadowShaderImpl &>(fShader); | 566 const SkShadowShaderImpl& lightShader = static_cast<const SkShadowShaderImpl &>(fShader); |
542 | 567 |
543 SkPMColor diffuse[BUFFER_MAX]; | 568 SkPMColor diffuse[BUFFER_MAX]; |
569 SkPMColor povDepth[BUFFER_MAX]; | |
544 | 570 |
545 do { | 571 do { |
546 int n = SkTMin(count, BUFFER_MAX); | 572 int n = SkTMin(count, BUFFER_MAX); |
547 | 573 |
548 fPovDepthContext->shadeSpan(x, y, diffuse, n); | |
549 fDiffuseContext->shadeSpan(x, y, diffuse, n); | 574 fDiffuseContext->shadeSpan(x, y, diffuse, n); |
575 fPovDepthContext->shadeSpan(x, y, povDepth, n); | |
550 | 576 |
551 for (int i = 0; i < n; ++i) { | 577 for (int i = 0; i < n; ++i) { |
578 SkColor diffColor = SkUnPreMultiply::PMColorToColor(diffuse[i]); | |
579 SkColor povDepthColor = povDepth[i]; | |
552 | 580 |
553 SkColor diffColor = SkUnPreMultiply::PMColorToColor(diffuse[i]); | 581 SkColor3f totalColor = SkColor3f::Make(0.0f, 0.0f, 0.0f); |
582 SkColor3f totalLight = SkColor3f::Make(0.0f, 0.0f, 0.0f); | |
583 // This is all done in linear unpremul color space (each component 0 ..255.0f though) | |
554 | 584 |
555 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f); | 585 fNonAmbLightCnt = 0; |
556 // This is all done in linear unpremul color space (each component 0 ..255.0f though) | |
557 for (int l = 0; l < lightShader.fLights->numLights(); ++l) { | 586 for (int l = 0; l < lightShader.fLights->numLights(); ++l) { |
558 const SkLights::Light& light = lightShader.fLights->light(l); | 587 const SkLights::Light& light = lightShader.fLights->light(l); |
559 | 588 |
560 if (SkLights::Light::kAmbient_LightType == light.type()) { | 589 if (light.type() == SkLights::Light::kDirectional_LightType) { |
561 accum.fX += light.color().fX * SkColorGetR(diffColor); | 590 int xOffset = SkScalarRoundToInt(light.dir().fX * |
562 accum.fY += light.color().fY * SkColorGetG(diffColor); | 591 SkIntToScalar(SkColorGetB(p ovDepthColor))); |
563 accum.fZ += light.color().fZ * SkColorGetB(diffColor); | 592 int yOffset = SkScalarRoundToInt(light.dir().fY * |
564 } else { | 593 SkIntToScalar(SkColorGetB(p ovDepthColor))); |
565 // scaling by fZ accounts for lighting direction | 594 |
566 accum.fX += light.color().makeScale(light.dir().fZ).fX * SkC olorGetR(diffColor); | 595 int shX = (x + i + xOffset); |
567 accum.fY += light.color().makeScale(light.dir().fZ).fY * SkC olorGetG(diffColor); | 596 int shY = (y + yOffset); |
568 accum.fZ += light.color().makeScale(light.dir().fZ).fZ * SkC olorGetB(diffColor); | 597 |
598 shX = SkClampPos(shX); | |
599 shY = SkClampPos(shY); | |
600 | |
601 shX = SkClampMax(shX, light.getShadowMap()->width() - 1); | |
602 shY = SkClampMax(shY, light.getShadowMap()->height() - 1); | |
603 | |
604 int shDepth = 0; | |
605 int pvDepth = SkColorGetB(povDepthColor); // depth stored in blue channel | |
606 | |
607 if (fShadowMapPixels[fNonAmbLightCnt]) { | |
608 uint32_t pix = *fShadowMapPixels[fNonAmbLightCnt]->addr3 2(shX, shY); | |
609 SkColor shColor(pix); | |
610 | |
611 shDepth += SkColorGetB(shColor); | |
612 } else { | |
613 // TODO: handle not being able to read shadow map pixels | |
614 } | |
615 | |
616 if (pvDepth >= shDepth) { | |
617 // assume object normals are pointing straight up | |
618 totalLight.fX += light.dir().fZ * light.color().fX; | |
619 totalLight.fY += light.dir().fZ * light.color().fY; | |
620 totalLight.fZ += light.dir().fZ * light.color().fZ; | |
621 } | |
622 fNonAmbLightCnt++; | |
623 } else if (light.type() == SkLights::Light::kAmbient_LightType) { | |
624 totalLight += light.color(); | |
569 } | 625 } |
570 } | 626 } |
571 | 627 |
572 result[i] = convert(accum, SkColorGetA(diffColor)); | 628 totalColor.fX += SkColorGetR(diffColor) * totalLight.fX; |
629 totalColor.fY += SkColorGetG(diffColor) * totalLight.fY; | |
630 totalColor.fZ += SkColorGetB(diffColor) * totalLight.fZ; | |
631 | |
632 result[i] = convert(totalColor, SkColorGetA(diffColor)); | |
573 } | 633 } |
574 | 634 |
575 result += n; | 635 result += n; |
576 x += n; | 636 x += n; |
577 count -= n; | 637 count -= n; |
578 } while (count > 0); | 638 } while (count > 0); |
579 } | 639 } |
580 | 640 |
581 //////////////////////////////////////////////////////////////////////////// | 641 //////////////////////////////////////////////////////////////////////////// |
582 | 642 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
717 | 777 |
718 /////////////////////////////////////////////////////////////////////////////// | 778 /////////////////////////////////////////////////////////////////////////////// |
719 | 779 |
720 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader) | 780 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader) |
721 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl) | 781 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl) |
722 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 782 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
723 | 783 |
724 /////////////////////////////////////////////////////////////////////////////// | 784 /////////////////////////////////////////////////////////////////////////////// |
725 | 785 |
726 #endif | 786 #endif |
OLD | NEW |