| Index: src/effects/SkLightingImageFilter.cpp
|
| diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
|
| index c86bf6b628c59917df0424286022670c79d45ac2..7a74f73624bc89411c12d79c8e149417f2e50852 100644
|
| --- a/src/effects/SkLightingImageFilter.cpp
|
| +++ b/src/effects/SkLightingImageFilter.cpp
|
| @@ -162,27 +162,30 @@ inline SkPoint3 bottomRightNormal(int m[9], SkScalar surfaceScale) {
|
| surfaceScale);
|
| }
|
|
|
| -template <class LightingType, class LightType> void lightBitmap(const LightingType& lightingType, const SkLight* light, const SkBitmap& src, SkBitmap* dst, SkScalar surfaceScale) {
|
| +template <class LightingType, class LightType> void lightBitmap(const LightingType& lightingType, const SkLight* light, const SkBitmap& src, SkBitmap* dst, SkScalar surfaceScale, const SkIRect& bounds) {
|
| + SkASSERT(dst->width() == bounds.width() && dst->height() == bounds.height());
|
| const LightType* l = static_cast<const LightType*>(light);
|
| - int y = 0;
|
| + int left = bounds.left(), right = bounds.right();
|
| + int bottom = bounds.bottom();
|
| + int y = bounds.top();
|
| + SkPMColor* dptr = dst->getAddr32(0, 0);
|
| {
|
| - const SkPMColor* row1 = src.getAddr32(0, 0);
|
| - const SkPMColor* row2 = src.getAddr32(0, 1);
|
| - SkPMColor* dptr = dst->getAddr32(0, 0);
|
| + int x = left;
|
| + const SkPMColor* row1 = src.getAddr32(x, y);
|
| + const SkPMColor* row2 = src.getAddr32(x, y + 1);
|
| int m[9];
|
| - int x = 0;
|
| m[4] = SkGetPackedA32(*row1++);
|
| m[5] = SkGetPackedA32(*row1++);
|
| m[7] = SkGetPackedA32(*row2++);
|
| m[8] = SkGetPackedA32(*row2++);
|
| SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
|
| *dptr++ = lightingType.light(topLeftNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
|
| - for (x = 1; x < src.width() - 1; ++x)
|
| + for (++x; x < right - 1; ++x)
|
| {
|
| shiftMatrixLeft(m);
|
| m[5] = SkGetPackedA32(*row1++);
|
| m[8] = SkGetPackedA32(*row2++);
|
| - surfaceToLight = l->surfaceToLight(x, 0, m[4], surfaceScale);
|
| + surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
|
| *dptr++ = lightingType.light(topNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
|
| }
|
| shiftMatrixLeft(m);
|
| @@ -190,13 +193,12 @@ template <class LightingType, class LightType> void lightBitmap(const LightingTy
|
| *dptr++ = lightingType.light(topRightNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
|
| }
|
|
|
| - for (++y; y < src.height() - 1; ++y) {
|
| - const SkPMColor* row0 = src.getAddr32(0, y - 1);
|
| - const SkPMColor* row1 = src.getAddr32(0, y);
|
| - const SkPMColor* row2 = src.getAddr32(0, y + 1);
|
| - SkPMColor* dptr = dst->getAddr32(0, y);
|
| + for (++y; y < bottom - 1; ++y) {
|
| + int x = left;
|
| + const SkPMColor* row0 = src.getAddr32(x, y - 1);
|
| + const SkPMColor* row1 = src.getAddr32(x, y);
|
| + const SkPMColor* row2 = src.getAddr32(x, y + 1);
|
| int m[9];
|
| - int x = 0;
|
| m[1] = SkGetPackedA32(*row0++);
|
| m[2] = SkGetPackedA32(*row0++);
|
| m[4] = SkGetPackedA32(*row1++);
|
| @@ -205,7 +207,7 @@ template <class LightingType, class LightType> void lightBitmap(const LightingTy
|
| m[8] = SkGetPackedA32(*row2++);
|
| SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
|
| *dptr++ = lightingType.light(leftNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
|
| - for (x = 1; x < src.width() - 1; ++x) {
|
| + for (++x; x < right - 1; ++x) {
|
| shiftMatrixLeft(m);
|
| m[2] = SkGetPackedA32(*row0++);
|
| m[5] = SkGetPackedA32(*row1++);
|
| @@ -219,10 +221,9 @@ template <class LightingType, class LightType> void lightBitmap(const LightingTy
|
| }
|
|
|
| {
|
| - const SkPMColor* row0 = src.getAddr32(0, src.height() - 2);
|
| - const SkPMColor* row1 = src.getAddr32(0, src.height() - 1);
|
| - int x = 0;
|
| - SkPMColor* dptr = dst->getAddr32(0, src.height() - 1);
|
| + int x = left;
|
| + const SkPMColor* row0 = src.getAddr32(x, bottom - 2);
|
| + const SkPMColor* row1 = src.getAddr32(x, bottom - 1);
|
| int m[9];
|
| m[1] = SkGetPackedA32(*row0++);
|
| m[2] = SkGetPackedA32(*row0++);
|
| @@ -230,7 +231,7 @@ template <class LightingType, class LightType> void lightBitmap(const LightingTy
|
| m[5] = SkGetPackedA32(*row1++);
|
| SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
|
| *dptr++ = lightingType.light(bottomLeftNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
|
| - for (x = 1; x < src.width() - 1; ++x)
|
| + for (++x; x < right - 1; ++x)
|
| {
|
| shiftMatrixLeft(m);
|
| m[2] = SkGetPackedA32(*row0++);
|
| @@ -261,11 +262,11 @@ void writePoint3(const SkPoint3& point, SkFlattenableWriteBuffer& buffer) {
|
| class SkDiffuseLightingImageFilter : public SkLightingImageFilter {
|
| public:
|
| SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale,
|
| - SkScalar kd, SkImageFilter* input);
|
| + SkScalar kd, SkImageFilter* input, const SkIRect* cropRect);
|
| SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDiffuseLightingImageFilter)
|
|
|
| #if SK_SUPPORT_GPU
|
| - virtual bool asNewEffect(GrEffectRef** effect, GrTexture*) const SK_OVERRIDE;
|
| + virtual bool asNewEffect(GrEffectRef** effect, GrTexture*, const SkIPoint& offset) const SK_OVERRIDE;
|
| #endif
|
| SkScalar kd() const { return fKD; }
|
|
|
| @@ -283,11 +284,11 @@ private:
|
|
|
| class SkSpecularLightingImageFilter : public SkLightingImageFilter {
|
| public:
|
| - SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input);
|
| + SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input, const SkIRect* cropRect);
|
| SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSpecularLightingImageFilter)
|
|
|
| #if SK_SUPPORT_GPU
|
| - virtual bool asNewEffect(GrEffectRef** effect, GrTexture*) const SK_OVERRIDE;
|
| + virtual bool asNewEffect(GrEffectRef** effect, GrTexture*, const SkIPoint& offset) const SK_OVERRIDE;
|
| #endif
|
|
|
| SkScalar ks() const { return fKS; }
|
| @@ -309,11 +310,12 @@ private:
|
|
|
| class GrLightingEffect : public GrSingleTextureEffect {
|
| public:
|
| - GrLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale);
|
| + GrLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale, const SkIPoint& offset);
|
| virtual ~GrLightingEffect();
|
|
|
| const SkLight* light() const { return fLight; }
|
| SkScalar surfaceScale() const { return fSurfaceScale; }
|
| + const SkIPoint& offset() const { return fOffset; }
|
|
|
| virtual void getConstantColorComponents(GrColor* color,
|
| uint32_t* validFlags) const SK_OVERRIDE {
|
| @@ -328,6 +330,7 @@ private:
|
| typedef GrSingleTextureEffect INHERITED;
|
| const SkLight* fLight;
|
| SkScalar fSurfaceScale;
|
| + SkIPoint fOffset;
|
| };
|
|
|
| class GrDiffuseLightingEffect : public GrLightingEffect {
|
| @@ -335,10 +338,12 @@ public:
|
| static GrEffectRef* Create(GrTexture* texture,
|
| const SkLight* light,
|
| SkScalar surfaceScale,
|
| + const SkIPoint& offset,
|
| SkScalar kd) {
|
| AutoEffectUnref effect(SkNEW_ARGS(GrDiffuseLightingEffect, (texture,
|
| light,
|
| surfaceScale,
|
| + offset,
|
| kd)));
|
| return CreateEffectRef(effect);
|
| }
|
| @@ -356,6 +361,7 @@ private:
|
| GrDiffuseLightingEffect(GrTexture* texture,
|
| const SkLight* light,
|
| SkScalar surfaceScale,
|
| + const SkIPoint& offset,
|
| SkScalar kd);
|
|
|
| GR_DECLARE_EFFECT_TEST;
|
| @@ -368,11 +374,13 @@ public:
|
| static GrEffectRef* Create(GrTexture* texture,
|
| const SkLight* light,
|
| SkScalar surfaceScale,
|
| + const SkIPoint& offset,
|
| SkScalar ks,
|
| SkScalar shininess) {
|
| AutoEffectUnref effect(SkNEW_ARGS(GrSpecularLightingEffect, (texture,
|
| light,
|
| surfaceScale,
|
| + offset,
|
| ks,
|
| shininess)));
|
| return CreateEffectRef(effect);
|
| @@ -391,6 +399,7 @@ private:
|
| GrSpecularLightingEffect(GrTexture* texture,
|
| const SkLight* light,
|
| SkScalar surfaceScale,
|
| + const SkIPoint& offset,
|
| SkScalar ks,
|
| SkScalar shininess);
|
|
|
| @@ -425,7 +434,9 @@ public:
|
|
|
| // This is called from GrGLLightingEffect's setData(). Subclasses of GrGLLight must call
|
| // INHERITED::setData().
|
| - virtual void setData(const GrGLUniformManager&, const SkLight* light) const;
|
| + virtual void setData(const GrGLUniformManager&,
|
| + const SkLight* light,
|
| + const SkIPoint& offset) const;
|
|
|
| protected:
|
| /**
|
| @@ -445,7 +456,9 @@ private:
|
| class GrGLDistantLight : public GrGLLight {
|
| public:
|
| virtual ~GrGLDistantLight() {}
|
| - virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE;
|
| + virtual void setData(const GrGLUniformManager&,
|
| + const SkLight* light,
|
| + const SkIPoint& offset) const SK_OVERRIDE;
|
| virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE;
|
|
|
| private:
|
| @@ -458,12 +471,13 @@ private:
|
| class GrGLPointLight : public GrGLLight {
|
| public:
|
| virtual ~GrGLPointLight() {}
|
| - virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE;
|
| + virtual void setData(const GrGLUniformManager&,
|
| + const SkLight* light,
|
| + const SkIPoint& offset) const SK_OVERRIDE;
|
| virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE;
|
|
|
| private:
|
| typedef GrGLLight INHERITED;
|
| - SkPoint3 fLocation;
|
| UniformHandle fLocationUni;
|
| };
|
|
|
| @@ -472,7 +486,9 @@ private:
|
| class GrGLSpotLight : public GrGLLight {
|
| public:
|
| virtual ~GrGLSpotLight() {}
|
| - virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE;
|
| + virtual void setData(const GrGLUniformManager&,
|
| + const SkLight* light,
|
| + const SkIPoint& offset) const SK_OVERRIDE;
|
| virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE;
|
| virtual void emitLightColor(GrGLShaderBuilder*, const char *surfaceToLight) SK_OVERRIDE;
|
|
|
| @@ -741,8 +757,8 @@ private:
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -SkLightingImageFilter::SkLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkImageFilter* input)
|
| - : INHERITED(input),
|
| +SkLightingImageFilter::SkLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkImageFilter* input, const SkIRect* cropRect)
|
| + : INHERITED(input, cropRect),
|
| fLight(light),
|
| fSurfaceScale(SkScalarDiv(surfaceScale, SkIntToScalar(255)))
|
| {
|
| @@ -753,55 +769,55 @@ SkLightingImageFilter::SkLightingImageFilter(SkLight* light, SkScalar surfaceSca
|
|
|
| SkImageFilter* SkLightingImageFilter::CreateDistantLitDiffuse(
|
| const SkPoint3& direction, SkColor lightColor, SkScalar surfaceScale,
|
| - SkScalar kd, SkImageFilter* input) {
|
| + SkScalar kd, SkImageFilter* input, const SkIRect* cropRect) {
|
| return SkNEW_ARGS(SkDiffuseLightingImageFilter,
|
| (SkNEW_ARGS(SkDistantLight, (direction, lightColor)), surfaceScale, kd,
|
| - input));
|
| + input, cropRect));
|
| }
|
|
|
| SkImageFilter* SkLightingImageFilter::CreatePointLitDiffuse(
|
| const SkPoint3& location, SkColor lightColor, SkScalar surfaceScale,
|
| - SkScalar kd, SkImageFilter* input) {
|
| + SkScalar kd, SkImageFilter* input, const SkIRect* cropRect) {
|
| return SkNEW_ARGS(SkDiffuseLightingImageFilter,
|
| (SkNEW_ARGS(SkPointLight, (location, lightColor)), surfaceScale, kd,
|
| - input));
|
| + input, cropRect));
|
| }
|
|
|
| SkImageFilter* SkLightingImageFilter::CreateSpotLitDiffuse(
|
| const SkPoint3& location, const SkPoint3& target,
|
| SkScalar specularExponent, SkScalar cutoffAngle,
|
| SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
|
| - SkImageFilter* input) {
|
| + SkImageFilter* input, const SkIRect* cropRect) {
|
| return SkNEW_ARGS(SkDiffuseLightingImageFilter,
|
| (SkNEW_ARGS(SkSpotLight, (location, target, specularExponent,
|
| cutoffAngle, lightColor)),
|
| - surfaceScale, kd, input));
|
| + surfaceScale, kd, input, cropRect));
|
| }
|
|
|
| SkImageFilter* SkLightingImageFilter::CreateDistantLitSpecular(
|
| const SkPoint3& direction, SkColor lightColor, SkScalar surfaceScale,
|
| - SkScalar ks, SkScalar shininess, SkImageFilter* input) {
|
| + SkScalar ks, SkScalar shininess, SkImageFilter* input, const SkIRect* cropRect) {
|
| return SkNEW_ARGS(SkSpecularLightingImageFilter,
|
| (SkNEW_ARGS(SkDistantLight, (direction, lightColor)),
|
| - surfaceScale, ks, shininess, input));
|
| + surfaceScale, ks, shininess, input, cropRect));
|
| }
|
|
|
| SkImageFilter* SkLightingImageFilter::CreatePointLitSpecular(
|
| const SkPoint3& location, SkColor lightColor, SkScalar surfaceScale,
|
| - SkScalar ks, SkScalar shininess, SkImageFilter* input) {
|
| + SkScalar ks, SkScalar shininess, SkImageFilter* input, const SkIRect* cropRect) {
|
| return SkNEW_ARGS(SkSpecularLightingImageFilter,
|
| (SkNEW_ARGS(SkPointLight, (location, lightColor)),
|
| - surfaceScale, ks, shininess, input));
|
| + surfaceScale, ks, shininess, input, cropRect));
|
| }
|
|
|
| SkImageFilter* SkLightingImageFilter::CreateSpotLitSpecular(
|
| const SkPoint3& location, const SkPoint3& target,
|
| SkScalar specularExponent, SkScalar cutoffAngle,
|
| SkColor lightColor, SkScalar surfaceScale,
|
| - SkScalar ks, SkScalar shininess, SkImageFilter* input) {
|
| + SkScalar ks, SkScalar shininess, SkImageFilter* input, const SkIRect* cropRect) {
|
| return SkNEW_ARGS(SkSpecularLightingImageFilter,
|
| (SkNEW_ARGS(SkSpotLight, (location, target, specularExponent, cutoffAngle, lightColor)),
|
| - surfaceScale, ks, shininess, input));
|
| + surfaceScale, ks, shininess, input, cropRect));
|
| }
|
|
|
| SkLightingImageFilter::~SkLightingImageFilter() {
|
| @@ -823,8 +839,8 @@ void SkLightingImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -SkDiffuseLightingImageFilter::SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar kd, SkImageFilter* input)
|
| - : SkLightingImageFilter(light, surfaceScale, input),
|
| +SkDiffuseLightingImageFilter::SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar kd, SkImageFilter* input, const SkIRect* cropRect = NULL)
|
| + : SkLightingImageFilter(light, surfaceScale, input, cropRect),
|
| fKD(kd)
|
| {
|
| }
|
| @@ -844,7 +860,7 @@ bool SkDiffuseLightingImageFilter::onFilterImage(Proxy*,
|
| const SkBitmap& src,
|
| const SkMatrix&,
|
| SkBitmap* dst,
|
| - SkIPoint*) {
|
| + SkIPoint* offset) {
|
| if (src.config() != SkBitmap::kARGB_8888_Config) {
|
| return false;
|
| }
|
| @@ -852,32 +868,43 @@ bool SkDiffuseLightingImageFilter::onFilterImage(Proxy*,
|
| if (!src.getPixels()) {
|
| return false;
|
| }
|
| - if (src.width() < 2 || src.height() < 2) {
|
| +
|
| + SkIRect bounds;
|
| + src.getBounds(&bounds);
|
| + if (!this->applyCropRect(&bounds)) {
|
| + return false;
|
| + }
|
| +
|
| + if (bounds.width() < 2 || bounds.height() < 2) {
|
| return false;
|
| }
|
| - dst->setConfig(src.config(), src.width(), src.height());
|
| +
|
| + dst->setConfig(src.config(), bounds.width(), bounds.height());
|
| dst->allocPixels();
|
|
|
| DiffuseLightingType lightingType(fKD);
|
| switch (light()->type()) {
|
| case SkLight::kDistant_LightType:
|
| - lightBitmap<DiffuseLightingType, SkDistantLight>(lightingType, light(), src, dst, surfaceScale());
|
| + lightBitmap<DiffuseLightingType, SkDistantLight>(lightingType, light(), src, dst, surfaceScale(), bounds);
|
| break;
|
| case SkLight::kPoint_LightType:
|
| - lightBitmap<DiffuseLightingType, SkPointLight>(lightingType, light(), src, dst, surfaceScale());
|
| + lightBitmap<DiffuseLightingType, SkPointLight>(lightingType, light(), src, dst, surfaceScale(), bounds);
|
| break;
|
| case SkLight::kSpot_LightType:
|
| - lightBitmap<DiffuseLightingType, SkSpotLight>(lightingType, light(), src, dst, surfaceScale());
|
| + lightBitmap<DiffuseLightingType, SkSpotLight>(lightingType, light(), src, dst, surfaceScale(), bounds);
|
| break;
|
| }
|
| +
|
| + offset->fX += bounds.left();
|
| + offset->fY += bounds.top();
|
| return true;
|
| }
|
|
|
| #if SK_SUPPORT_GPU
|
| -bool SkDiffuseLightingImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* texture) const {
|
| +bool SkDiffuseLightingImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* texture, const SkIPoint& offset) const {
|
| if (effect) {
|
| SkScalar scale = SkScalarMul(surfaceScale(), SkIntToScalar(255));
|
| - *effect = GrDiffuseLightingEffect::Create(texture, light(), scale, kd());
|
| + *effect = GrDiffuseLightingEffect::Create(texture, light(), scale, offset, kd());
|
| }
|
| return true;
|
| }
|
| @@ -885,8 +912,8 @@ bool SkDiffuseLightingImageFilter::asNewEffect(GrEffectRef** effect, GrTexture*
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -SkSpecularLightingImageFilter::SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input)
|
| - : SkLightingImageFilter(light, surfaceScale, input),
|
| +SkSpecularLightingImageFilter::SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input, const SkIRect* cropRect)
|
| + : SkLightingImageFilter(light, surfaceScale, input, cropRect),
|
| fKS(ks),
|
| fShininess(shininess)
|
| {
|
| @@ -909,7 +936,7 @@ bool SkSpecularLightingImageFilter::onFilterImage(Proxy*,
|
| const SkBitmap& src,
|
| const SkMatrix&,
|
| SkBitmap* dst,
|
| - SkIPoint*) {
|
| + SkIPoint* offset) {
|
| if (src.config() != SkBitmap::kARGB_8888_Config) {
|
| return false;
|
| }
|
| @@ -917,32 +944,42 @@ bool SkSpecularLightingImageFilter::onFilterImage(Proxy*,
|
| if (!src.getPixels()) {
|
| return false;
|
| }
|
| - if (src.width() < 2 || src.height() < 2) {
|
| +
|
| + SkIRect bounds;
|
| + src.getBounds(&bounds);
|
| + if (!this->applyCropRect(&bounds)) {
|
| + return false;
|
| + }
|
| +
|
| + if (bounds.width() < 2 || bounds.height() < 2) {
|
| return false;
|
| }
|
| - dst->setConfig(src.config(), src.width(), src.height());
|
| +
|
| + dst->setConfig(src.config(), bounds.width(), bounds.height());
|
| dst->allocPixels();
|
|
|
| SpecularLightingType lightingType(fKS, fShininess);
|
| switch (light()->type()) {
|
| case SkLight::kDistant_LightType:
|
| - lightBitmap<SpecularLightingType, SkDistantLight>(lightingType, light(), src, dst, surfaceScale());
|
| + lightBitmap<SpecularLightingType, SkDistantLight>(lightingType, light(), src, dst, surfaceScale(), bounds);
|
| break;
|
| case SkLight::kPoint_LightType:
|
| - lightBitmap<SpecularLightingType, SkPointLight>(lightingType, light(), src, dst, surfaceScale());
|
| + lightBitmap<SpecularLightingType, SkPointLight>(lightingType, light(), src, dst, surfaceScale(), bounds);
|
| break;
|
| case SkLight::kSpot_LightType:
|
| - lightBitmap<SpecularLightingType, SkSpotLight>(lightingType, light(), src, dst, surfaceScale());
|
| + lightBitmap<SpecularLightingType, SkSpotLight>(lightingType, light(), src, dst, surfaceScale(), bounds);
|
| break;
|
| }
|
| + offset->fX += bounds.left();
|
| + offset->fY += bounds.top();
|
| return true;
|
| }
|
|
|
| #if SK_SUPPORT_GPU
|
| -bool SkSpecularLightingImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* texture) const {
|
| +bool SkSpecularLightingImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* texture, const SkIPoint& offset) const {
|
| if (effect) {
|
| SkScalar scale = SkScalarMul(surfaceScale(), SkIntToScalar(255));
|
| - *effect = GrSpecularLightingEffect::Create(texture, light(), scale, ks(), shininess());
|
| + *effect = GrSpecularLightingEffect::Create(texture, light(), scale, offset, ks(), shininess());
|
| }
|
| return true;
|
| }
|
| @@ -1048,10 +1085,14 @@ private:
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -GrLightingEffect::GrLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale)
|
| +GrLightingEffect::GrLightingEffect(GrTexture* texture,
|
| + const SkLight* light,
|
| + SkScalar surfaceScale,
|
| + const SkIPoint& offset)
|
| : INHERITED(texture, MakeDivByTextureWHMatrix(texture))
|
| , fLight(light)
|
| - , fSurfaceScale(surfaceScale) {
|
| + , fSurfaceScale(surfaceScale)
|
| + , fOffset(offset) {
|
| fLight->ref();
|
| if (light->requiresFragmentPosition()) {
|
| this->setWillReadFragmentPosition();
|
| @@ -1071,8 +1112,12 @@ bool GrLightingEffect::onIsEqual(const GrEffect& sBase) const {
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -GrDiffuseLightingEffect::GrDiffuseLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale, SkScalar kd)
|
| - : INHERITED(texture, light, surfaceScale), fKD(kd) {
|
| +GrDiffuseLightingEffect::GrDiffuseLightingEffect(GrTexture* texture,
|
| + const SkLight* light,
|
| + SkScalar surfaceScale,
|
| + const SkIPoint& offset,
|
| + SkScalar kd)
|
| + : INHERITED(texture, light, surfaceScale, offset), fKD(kd) {
|
| }
|
|
|
| const GrBackendEffectFactory& GrDiffuseLightingEffect::getFactory() const {
|
| @@ -1094,8 +1139,9 @@ GrEffectRef* GrDiffuseLightingEffect::TestCreate(SkMWCRandom* random,
|
| SkScalar surfaceScale = random->nextSScalar1();
|
| SkScalar kd = random->nextUScalar1();
|
| SkAutoTUnref<SkLight> light(create_random_light(random));
|
| + SkIPoint offset = SkIPoint::Make(random->nextS(), random->nextS());
|
| return GrDiffuseLightingEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx],
|
| - light, surfaceScale, kd);
|
| + light, surfaceScale, offset, kd);
|
| }
|
|
|
|
|
| @@ -1235,7 +1281,7 @@ void GrGLLightingEffect::setData(const GrGLUniformManager& uman,
|
| float ySign = texture->origin() == kTopLeft_GrSurfaceOrigin ? -1.0f : 1.0f;
|
| uman.set2f(fImageIncrementUni, 1.0f / texture->width(), ySign / texture->height());
|
| uman.set1f(fSurfaceScaleUni, lighting.surfaceScale());
|
| - fLight->setData(uman, lighting.light());
|
| + fLight->setData(uman, lighting.light(), lighting.offset());
|
| fEffectMatrix.setData(uman,
|
| lighting.getMatrix(),
|
| drawEffect,
|
| @@ -1285,8 +1331,13 @@ void GrGLDiffuseLightingEffect::setData(const GrGLUniformManager& uman,
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -GrSpecularLightingEffect::GrSpecularLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess)
|
| - : INHERITED(texture, light, surfaceScale),
|
| +GrSpecularLightingEffect::GrSpecularLightingEffect(GrTexture* texture,
|
| + const SkLight* light,
|
| + SkScalar surfaceScale,
|
| + const SkIPoint& offset,
|
| + SkScalar ks,
|
| + SkScalar shininess)
|
| + : INHERITED(texture, light, surfaceScale, offset),
|
| fKS(ks),
|
| fShininess(shininess) {
|
| }
|
| @@ -1312,8 +1363,9 @@ GrEffectRef* GrSpecularLightingEffect::TestCreate(SkMWCRandom* random,
|
| SkScalar ks = random->nextUScalar1();
|
| SkScalar shininess = random->nextUScalar1();
|
| SkAutoTUnref<SkLight> light(create_random_light(random));
|
| + SkIPoint offset = SkIPoint::Make(random->nextS(), random->nextS());
|
| return GrSpecularLightingEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx],
|
| - light, surfaceScale, ks, shininess);
|
| + light, surfaceScale, offset, ks, shininess);
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
| @@ -1372,14 +1424,18 @@ void GrGLLight::emitLightColor(GrGLShaderBuilder* builder,
|
| builder->fsCodeAppend(builder->getUniformCStr(this->lightColorUni()));
|
| }
|
|
|
| -void GrGLLight::setData(const GrGLUniformManager& uman, const SkLight* light) const {
|
| +void GrGLLight::setData(const GrGLUniformManager& uman,
|
| + const SkLight* light,
|
| + const SkIPoint&) const {
|
| setUniformPoint3(uman, fColorUni, light->color() * SkScalarInvert(SkIntToScalar(255)));
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -void GrGLDistantLight::setData(const GrGLUniformManager& uman, const SkLight* light) const {
|
| - INHERITED::setData(uman, light);
|
| +void GrGLDistantLight::setData(const GrGLUniformManager& uman,
|
| + const SkLight* light,
|
| + const SkIPoint& offset) const {
|
| + INHERITED::setData(uman, light, offset);
|
| SkASSERT(light->type() == SkLight::kDistant_LightType);
|
| const SkDistantLight* distantLight = static_cast<const SkDistantLight*>(light);
|
| setUniformNormal3(uman, fDirectionUni, distantLight->direction());
|
| @@ -1394,11 +1450,16 @@ void GrGLDistantLight::emitSurfaceToLight(GrGLShaderBuilder* builder, const char
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -void GrGLPointLight::setData(const GrGLUniformManager& uman, const SkLight* light) const {
|
| - INHERITED::setData(uman, light);
|
| +void GrGLPointLight::setData(const GrGLUniformManager& uman,
|
| + const SkLight* light,
|
| + const SkIPoint& offset) const {
|
| + INHERITED::setData(uman, light, offset);
|
| SkASSERT(light->type() == SkLight::kPoint_LightType);
|
| const SkPointLight* pointLight = static_cast<const SkPointLight*>(light);
|
| - setUniformPoint3(uman, fLocationUni, pointLight->location());
|
| + SkPoint3 location = pointLight->location();
|
| + location.fX -= offset.fX;
|
| + location.fY -= offset.fY;
|
| + setUniformPoint3(uman, fLocationUni, location);
|
| }
|
|
|
| void GrGLPointLight::emitSurfaceToLight(GrGLShaderBuilder* builder, const char* z) {
|
| @@ -1410,11 +1471,16 @@ void GrGLPointLight::emitSurfaceToLight(GrGLShaderBuilder* builder, const char*
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -void GrGLSpotLight::setData(const GrGLUniformManager& uman, const SkLight* light) const {
|
| - INHERITED::setData(uman, light);
|
| +void GrGLSpotLight::setData(const GrGLUniformManager& uman,
|
| + const SkLight* light,
|
| + const SkIPoint& offset) const {
|
| + INHERITED::setData(uman, light, offset);
|
| SkASSERT(light->type() == SkLight::kSpot_LightType);
|
| const SkSpotLight* spotLight = static_cast<const SkSpotLight *>(light);
|
| - setUniformPoint3(uman, fLocationUni, spotLight->location());
|
| + SkPoint3 location = spotLight->location();
|
| + location.fX -= offset.fX;
|
| + location.fY -= offset.fY;
|
| + setUniformPoint3(uman, fLocationUni, location);
|
| uman.set1f(fExponentUni, spotLight->specularExponent());
|
| uman.set1f(fCosInnerConeAngleUni, spotLight->cosInnerConeAngle());
|
| uman.set1f(fCosOuterConeAngleUni, spotLight->cosOuterConeAngle());
|
|
|