| 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 |