OLD | NEW |
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 */ | 51 */ |
52 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal, | 52 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal, |
53 const SkLightingShader::Lights* 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 : INHERITED(diffLocalM) | 56 : INHERITED(diffLocalM) |
57 , fDiffuseMap(diffuse) | 57 , fDiffuseMap(diffuse) |
58 , fNormalMap(normal) | 58 , fNormalMap(normal) |
59 , fLights(SkRef(lights)) | 59 , fLights(std::move(lights)) |
60 , fInvNormRotation(invNormRotation) { | 60 , fInvNormRotation(invNormRotation) { |
61 | 61 |
62 if (normLocalM) { | 62 if (normLocalM) { |
63 fNormLocalMatrix = *normLocalM; | 63 fNormLocalMatrix = *normLocalM; |
64 } else { | 64 } else { |
65 fNormLocalMatrix.reset(); | 65 fNormLocalMatrix.reset(); |
66 } | 66 } |
67 // Pre-cache so future calls to fNormLocalMatrix.getType() are threadsaf
e. | 67 // Pre-cache so future calls to fNormLocalMatrix.getType() are threadsaf
e. |
68 (void)fNormLocalMatrix.getType(); | 68 (void)fNormLocalMatrix.getType(); |
69 | 69 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 SK_TO_STRING_OVERRIDE() | 101 SK_TO_STRING_OVERRIDE() |
102 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl) | 102 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl) |
103 | 103 |
104 protected: | 104 protected: |
105 void flatten(SkWriteBuffer&) const override; | 105 void flatten(SkWriteBuffer&) const override; |
106 size_t onContextSize(const ContextRec&) const override; | 106 size_t onContextSize(const ContextRec&) const override; |
107 Context* onCreateContext(const ContextRec&, void*) const override; | 107 Context* onCreateContext(const ContextRec&, void*) const override; |
108 bool computeNormTotalInverse(const ContextRec& rec, SkMatrix* normTotalInver
se) const; | 108 bool computeNormTotalInverse(const ContextRec& rec, SkMatrix* normTotalInver
se) const; |
109 | 109 |
110 private: | 110 private: |
111 SkBitmap fDiffuseMap; | 111 SkBitmap fDiffuseMap; |
112 SkBitmap fNormalMap; | 112 SkBitmap fNormalMap; |
113 | 113 |
114 SkAutoTUnref<const SkLightingShader::Lights> fLights; | 114 sk_sp<SkLights> fLights; |
115 | 115 |
116 SkMatrix fNormLocalMatrix; | 116 SkMatrix fNormLocalMatrix; |
117 SkVector fInvNormRotation; | 117 SkVector fInvNormRotation; |
118 | 118 |
119 friend class SkLightingShader; | 119 friend class SkLightingShader; |
120 | 120 |
121 typedef SkShader INHERITED; | 121 typedef SkShader INHERITED; |
122 }; | 122 }; |
123 | 123 |
124 //////////////////////////////////////////////////////////////////////////// | 124 //////////////////////////////////////////////////////////////////////////// |
125 | 125 |
126 #if SK_SUPPORT_GPU | 126 #if SK_SUPPORT_GPU |
127 | 127 |
128 #include "GrCoordTransform.h" | 128 #include "GrCoordTransform.h" |
129 #include "GrFragmentProcessor.h" | 129 #include "GrFragmentProcessor.h" |
130 #include "GrInvariantOutput.h" | 130 #include "GrInvariantOutput.h" |
131 #include "GrTextureAccess.h" | 131 #include "GrTextureAccess.h" |
132 #include "glsl/GrGLSLFragmentProcessor.h" | 132 #include "glsl/GrGLSLFragmentProcessor.h" |
133 #include "glsl/GrGLSLFragmentShaderBuilder.h" | 133 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
134 #include "glsl/GrGLSLProgramDataManager.h" | 134 #include "glsl/GrGLSLProgramDataManager.h" |
135 #include "glsl/GrGLSLUniformHandler.h" | 135 #include "glsl/GrGLSLUniformHandler.h" |
136 #include "SkGr.h" | 136 #include "SkGr.h" |
137 #include "SkGrPriv.h" | 137 #include "SkGrPriv.h" |
138 | 138 |
139 class LightingFP : public GrFragmentProcessor { | 139 class LightingFP : public GrFragmentProcessor { |
140 public: | 140 public: |
141 LightingFP(GrTexture* diffuse, GrTexture* normal, const SkMatrix& diffMatrix
, | 141 LightingFP(GrTexture* diffuse, GrTexture* normal, const SkMatrix& diffMatrix
, |
142 const SkMatrix& normMatrix, const GrTextureParams& diffParams, | 142 const SkMatrix& normMatrix, const GrTextureParams& diffParams, |
143 const GrTextureParams& normParams, const SkLightingShader::Lights
* lights, | 143 const GrTextureParams& normParams, sk_sp<SkLights> lights, |
144 const SkVector& invNormRotation) | 144 const SkVector& invNormRotation) |
145 : fDiffDeviceTransform(kLocal_GrCoordSet, diffMatrix, diffuse, diffParam
s.filterMode()) | 145 : fDiffDeviceTransform(kLocal_GrCoordSet, diffMatrix, diffuse, diffParam
s.filterMode()) |
146 , fNormDeviceTransform(kLocal_GrCoordSet, normMatrix, normal, normParams
.filterMode()) | 146 , fNormDeviceTransform(kLocal_GrCoordSet, normMatrix, normal, normParams
.filterMode()) |
147 , fDiffuseTextureAccess(diffuse, diffParams) | 147 , fDiffuseTextureAccess(diffuse, diffParams) |
148 , fNormalTextureAccess(normal, normParams) | 148 , fNormalTextureAccess(normal, normParams) |
149 , fInvNormRotation(invNormRotation) { | 149 , fInvNormRotation(invNormRotation) { |
150 this->addCoordTransform(&fDiffDeviceTransform); | 150 this->addCoordTransform(&fDiffDeviceTransform); |
151 this->addCoordTransform(&fNormDeviceTransform); | 151 this->addCoordTransform(&fNormDeviceTransform); |
152 this->addTextureAccess(&fDiffuseTextureAccess); | 152 this->addTextureAccess(&fDiffuseTextureAccess); |
153 this->addTextureAccess(&fNormalTextureAccess); | 153 this->addTextureAccess(&fNormalTextureAccess); |
154 | 154 |
155 // fuse all ambient lights into a single one | 155 // fuse all ambient lights into a single one |
156 fAmbientColor.set(0.0f, 0.0f, 0.0f); | 156 fAmbientColor.set(0.0f, 0.0f, 0.0f); |
157 for (int i = 0; i < lights->numLights(); ++i) { | 157 for (int i = 0; i < lights->numLights(); ++i) { |
158 if (SkLight::kAmbient_LightType == lights->light(i).type()) { | 158 if (SkLights::Light::kAmbient_LightType == lights->light(i).type())
{ |
159 fAmbientColor += lights->light(i).color(); | 159 fAmbientColor += lights->light(i).color(); |
160 } else { | 160 } else { |
161 // TODO: handle more than one of these | 161 // TODO: handle more than one of these |
162 fLightColor = lights->light(i).color(); | 162 fLightColor = lights->light(i).color(); |
163 fLightDir = lights->light(i).dir(); | 163 fLightDir = lights->light(i).dir(); |
164 } | 164 } |
165 } | 165 } |
166 | 166 |
167 this->initClassID<LightingFP>(); | 167 this->initClassID<LightingFP>(); |
168 } | 168 } |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 lightShader.fInvNormRotation.fY * norm.fY; | 512 lightShader.fInvNormRotation.fY * norm.fY; |
513 xformedNorm.fY = lightShader.fInvNormRotation.fX * norm.fX - | 513 xformedNorm.fY = lightShader.fInvNormRotation.fX * norm.fX - |
514 lightShader.fInvNormRotation.fY * norm.fY; | 514 lightShader.fInvNormRotation.fY * norm.fY; |
515 xformedNorm.fZ = norm.fZ; | 515 xformedNorm.fZ = norm.fZ; |
516 | 516 |
517 SkColor diffColor = SkUnPreMultiply::PMColorToColor(tmpColor2[i]); | 517 SkColor diffColor = SkUnPreMultiply::PMColorToColor(tmpColor2[i]); |
518 | 518 |
519 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f); | 519 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f); |
520 // This is all done in linear unpremul color space (each component 0
..255.0f though) | 520 // This is all done in linear unpremul color space (each component 0
..255.0f though) |
521 for (int l = 0; l < lightShader.fLights->numLights(); ++l) { | 521 for (int l = 0; l < lightShader.fLights->numLights(); ++l) { |
522 const SkLight& light = lightShader.fLights->light(l); | 522 const SkLights::Light& light = lightShader.fLights->light(l); |
523 | 523 |
524 if (SkLight::kAmbient_LightType == light.type()) { | 524 if (SkLights::Light::kAmbient_LightType == light.type()) { |
525 accum += light.color().makeScale(255.0f); | 525 accum += light.color().makeScale(255.0f); |
526 } else { | 526 } else { |
527 SkScalar NdotL = xformedNorm.dot(light.dir()); | 527 SkScalar NdotL = xformedNorm.dot(light.dir()); |
528 if (NdotL < 0.0f) { | 528 if (NdotL < 0.0f) { |
529 NdotL = 0.0f; | 529 NdotL = 0.0f; |
530 } | 530 } |
531 | 531 |
532 accum.fX += light.color().fX * SkColorGetR(diffColor) * Ndot
L; | 532 accum.fX += light.color().fX * SkColorGetR(diffColor) * Ndot
L; |
533 accum.fY += light.color().fY * SkColorGetG(diffColor) * Ndot
L; | 533 accum.fY += light.color().fY * SkColorGetG(diffColor) * Ndot
L; |
534 accum.fZ += light.color().fZ * SkColorGetB(diffColor) * Ndot
L; | 534 accum.fZ += light.color().fZ * SkColorGetB(diffColor) * Ndot
L; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 diffuse.setImmutable(); | 576 diffuse.setImmutable(); |
577 | 577 |
578 SkBitmap normal; | 578 SkBitmap normal; |
579 if (!buf.readBitmap(&normal)) { | 579 if (!buf.readBitmap(&normal)) { |
580 return nullptr; | 580 return nullptr; |
581 } | 581 } |
582 normal.setImmutable(); | 582 normal.setImmutable(); |
583 | 583 |
584 int numLights = buf.readInt(); | 584 int numLights = buf.readInt(); |
585 | 585 |
586 SkLightingShader::Lights::Builder builder; | 586 SkLights::Builder builder; |
587 | 587 |
588 for (int l = 0; l < numLights; ++l) { | 588 for (int l = 0; l < numLights; ++l) { |
589 bool isAmbient = buf.readBool(); | 589 bool isAmbient = buf.readBool(); |
590 | 590 |
591 SkColor3f color; | 591 SkColor3f color; |
592 if (!buf.readScalarArray(&color.fX, 3)) { | 592 if (!buf.readScalarArray(&color.fX, 3)) { |
593 return nullptr; | 593 return nullptr; |
594 } | 594 } |
595 | 595 |
596 if (isAmbient) { | 596 if (isAmbient) { |
597 builder.add(SkLight(color)); | 597 builder.add(SkLights::Light(color)); |
598 } else { | 598 } else { |
599 SkVector3 dir; | 599 SkVector3 dir; |
600 if (!buf.readScalarArray(&dir.fX, 3)) { | 600 if (!buf.readScalarArray(&dir.fX, 3)) { |
601 return nullptr; | 601 return nullptr; |
602 } | 602 } |
603 builder.add(SkLight(color, dir)); | 603 builder.add(SkLights::Light(color, dir)); |
604 } | 604 } |
605 } | 605 } |
606 | 606 |
607 SkAutoTUnref<const SkLightingShader::Lights> lights(builder.finish()); | 607 sk_sp<SkLights> lights(builder.finish()); |
608 | 608 |
609 SkVector invNormRotation = {1,0}; | 609 SkVector invNormRotation = {1,0}; |
610 if (!buf.isVersionLT(SkReadBuffer::kLightingShaderWritesInvNormRotation)) { | 610 if (!buf.isVersionLT(SkReadBuffer::kLightingShaderWritesInvNormRotation)) { |
611 invNormRotation = buf.readPoint(); | 611 invNormRotation = buf.readPoint(); |
612 } | 612 } |
613 | 613 |
614 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, lights, invNormRota
tion, | 614 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights),
invNormRotation, |
615 &diffLocalM, &normLocalM); | 615 &diffLocalM, &normLocalM); |
616 } | 616 } |
617 | 617 |
618 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { | 618 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { |
619 this->INHERITED::flatten(buf); | 619 this->INHERITED::flatten(buf); |
620 | 620 |
621 bool hasNormLocalM = !fNormLocalMatrix.isIdentity(); | 621 bool hasNormLocalM = !fNormLocalMatrix.isIdentity(); |
622 buf.writeBool(hasNormLocalM); | 622 buf.writeBool(hasNormLocalM); |
623 if (hasNormLocalM) { | 623 if (hasNormLocalM) { |
624 buf.writeMatrix(fNormLocalMatrix); | 624 buf.writeMatrix(fNormLocalMatrix); |
625 } | 625 } |
626 | 626 |
627 buf.writeBitmap(fDiffuseMap); | 627 buf.writeBitmap(fDiffuseMap); |
628 buf.writeBitmap(fNormalMap); | 628 buf.writeBitmap(fNormalMap); |
629 | 629 |
630 buf.writeInt(fLights->numLights()); | 630 buf.writeInt(fLights->numLights()); |
631 for (int l = 0; l < fLights->numLights(); ++l) { | 631 for (int l = 0; l < fLights->numLights(); ++l) { |
632 const SkLight& light = fLights->light(l); | 632 const SkLights::Light& light = fLights->light(l); |
633 | 633 |
634 bool isAmbient = SkLight::kAmbient_LightType == light.type(); | 634 bool isAmbient = SkLights::Light::kAmbient_LightType == light.type(); |
635 | 635 |
636 buf.writeBool(isAmbient); | 636 buf.writeBool(isAmbient); |
637 buf.writeScalarArray(&light.color().fX, 3); | 637 buf.writeScalarArray(&light.color().fX, 3); |
638 if (!isAmbient) { | 638 if (!isAmbient) { |
639 buf.writeScalarArray(&light.dir().fX, 3); | 639 buf.writeScalarArray(&light.dir().fX, 3); |
640 } | 640 } |
641 } | 641 } |
642 buf.writePoint(fInvNormRotation); | 642 buf.writePoint(fInvNormRotation); |
643 } | 643 } |
644 | 644 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
699 // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it | 699 // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it |
700 // communicates between its matrix-proc and its sampler-proc. Until we can | 700 // communicates between its matrix-proc and its sampler-proc. Until we can |
701 // widen that, we have to reject bitmaps that are larger. | 701 // widen that, we have to reject bitmaps that are larger. |
702 // | 702 // |
703 static const int kMaxSize = 65535; | 703 static const int kMaxSize = 65535; |
704 | 704 |
705 return bm.width() > kMaxSize || bm.height() > kMaxSize; | 705 return bm.width() > kMaxSize || bm.height() > kMaxSize; |
706 } | 706 } |
707 | 707 |
708 sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, const SkBitmap&
normal, | 708 sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, const SkBitmap&
normal, |
709 const Lights* lights, | 709 sk_sp<SkLights> lights, |
710 const SkVector& invNormRotation, | 710 const SkVector& invNormRotation, |
711 const SkMatrix* diffLocalM, const SkMatri
x* normLocalM) { | 711 const SkMatrix* diffLocalM, const SkMatri
x* normLocalM) { |
712 if (diffuse.isNull() || bitmap_is_too_big(diffuse) || | 712 if (diffuse.isNull() || bitmap_is_too_big(diffuse) || |
713 normal.isNull() || bitmap_is_too_big(normal) || | 713 normal.isNull() || bitmap_is_too_big(normal) || |
714 diffuse.width() != normal.width() || | 714 diffuse.width() != normal.width() || |
715 diffuse.height() != normal.height()) { | 715 diffuse.height() != normal.height()) { |
716 return nullptr; | 716 return nullptr; |
717 } | 717 } |
718 | 718 |
719 SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1)); | 719 SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1)); |
720 | 720 |
721 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, lights, invNormRota
tion, diffLocalM, | 721 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), |
722 normLocalM); | 722 invNormRotation, diffLocalM, normLoc
alM); |
723 } | 723 } |
724 | 724 |
725 /////////////////////////////////////////////////////////////////////////////// | 725 /////////////////////////////////////////////////////////////////////////////// |
726 | 726 |
727 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) | 727 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) |
728 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) | 728 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) |
729 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 729 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
730 | 730 |
731 /////////////////////////////////////////////////////////////////////////////// | 731 /////////////////////////////////////////////////////////////////////////////// |
OLD | NEW |