diff options
Diffstat (limited to 'src/gpu/effects')
-rw-r--r-- | src/gpu/effects/GrBicubicEffect.cpp | 4 | ||||
-rw-r--r-- | src/gpu/effects/GrMatrixConvolutionEffect.cpp | 4 | ||||
-rw-r--r-- | src/gpu/effects/GrTextureDomain.cpp | 93 | ||||
-rw-r--r-- | src/gpu/effects/GrTextureDomain.h | 33 |
4 files changed, 69 insertions, 65 deletions
diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp index 9d8e728efc..50a2a5d3e4 100644 --- a/src/gpu/effects/GrBicubicEffect.cpp +++ b/src/gpu/effects/GrBicubicEffect.cpp @@ -124,7 +124,7 @@ void GrGLBicubicEffect::onSetData(const GrGLSLProgramDataManager& pdman, imageIncrement[0] = 1.0f / texture->width(); imageIncrement[1] = 1.0f / texture->height(); pdman.set2fv(fImageIncrementUni, 1, imageIncrement); - fDomain.setData(pdman, bicubicEffect.domain(), texture->origin()); + fDomain.setData(pdman, bicubicEffect.domain(), texture); if (SkToBool(bicubicEffect.colorSpaceXform())) { pdman.setSkMatrix44(fColorSpaceXformUni, bicubicEffect.colorSpaceXform()->srcToDst()); } @@ -146,7 +146,7 @@ GrBicubicEffect::GrBicubicEffect(GrTexture* texture, const SkRect& domain) : INHERITED(texture, std::move(colorSpaceXform), matrix, GrSamplerParams(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode)) - , fDomain(domain, GrTextureDomain::kClamp_Mode) { + , fDomain(texture, domain, GrTextureDomain::kClamp_Mode) { this->initClassID<GrBicubicEffect>(); } diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp index 96f7014284..8b98d0b32f 100644 --- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp +++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp @@ -144,7 +144,7 @@ void GrGLMatrixConvolutionEffect::onSetData(const GrGLSLProgramDataManager& pdma pdman.set4fv(fKernelUni, arrayCount, conv.kernel()); pdman.set1f(fGainUni, conv.gain()); pdman.set1f(fBiasUni, conv.bias()); - fDomain.setData(pdman, conv.domain(), texture->origin()); + fDomain.setData(pdman, conv.domain(), texture); } GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, @@ -161,7 +161,7 @@ GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, fGain(SkScalarToFloat(gain)), fBias(SkScalarToFloat(bias) / 255.0f), fConvolveAlpha(convolveAlpha), - fDomain(GrTextureDomain::MakeTexelDomainForMode(texture, bounds, tileMode), tileMode) { + fDomain(texture, GrTextureDomain::MakeTexelDomainForMode(bounds, tileMode), tileMode) { this->initClassID<GrMatrixConvolutionEffect>(); for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) { fKernel[i] = SkScalarToFloat(kernel[i]); diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp index c6ff9f73e4..d6872e1c2e 100644 --- a/src/gpu/effects/GrTextureDomain.cpp +++ b/src/gpu/effects/GrTextureDomain.cpp @@ -17,29 +17,41 @@ #include "glsl/GrGLSLShaderBuilder.h" #include "glsl/GrGLSLUniformHandler.h" -GrTextureDomain::GrTextureDomain(const SkRect& domain, Mode mode, int index) - : fIndex(index) { +static bool can_ignore_rect(GrTexture* tex, const SkRect& domain) { + // This logic is relying on the instantiated size of 'tex'. In the deferred world it + // will have to change so this logic only fires for kExact texture proxies. This shouldn't + // change the actual behavior of Ganesh since shaders shouldn't be accessing pixels outside + // of the content rectangle. + const SkIRect kFullRect = SkIRect::MakeWH(tex->width(), tex->height()); + + return domain.contains(kFullRect); +} - static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1}; - if (domain.contains(kFullRect) && kClamp_Mode == mode) { - fMode = kIgnore_Mode; - } else { - fMode = mode; +GrTextureDomain::GrTextureDomain(GrTexture* tex, const SkRect& domain, Mode mode, int index) + : fMode(mode), fIndex(index) { + + if (kIgnore_Mode == fMode) { + return; } - if (fMode != kIgnore_Mode) { - // We don't currently handle domains that are empty or don't intersect the texture. - // It is OK if the domain rect is a line or point, but it should not be inverted. We do not - // handle rects that do not intersect the [0..1]x[0..1] rect. - SkASSERT(domain.fLeft <= domain.fRight); - SkASSERT(domain.fTop <= domain.fBottom); - fDomain.fLeft = SkScalarPin(domain.fLeft, kFullRect.fLeft, kFullRect.fRight); - fDomain.fRight = SkScalarPin(domain.fRight, kFullRect.fLeft, kFullRect.fRight); - fDomain.fTop = SkScalarPin(domain.fTop, kFullRect.fTop, kFullRect.fBottom); - fDomain.fBottom = SkScalarPin(domain.fBottom, kFullRect.fTop, kFullRect.fBottom); - SkASSERT(fDomain.fLeft <= fDomain.fRight); - SkASSERT(fDomain.fTop <= fDomain.fBottom); + if (kClamp_Mode == mode && can_ignore_rect(tex, domain)) { + fMode = kIgnore_Mode; + return; } + + const SkRect kFullRect = SkRect::MakeIWH(tex->width(), tex->height()); + + // We don't currently handle domains that are empty or don't intersect the texture. + // It is OK if the domain rect is a line or point, but it should not be inverted. We do not + // handle rects that do not intersect the [0..1]x[0..1] rect. + SkASSERT(domain.fLeft <= domain.fRight); + SkASSERT(domain.fTop <= domain.fBottom); + fDomain.fLeft = SkScalarPin(domain.fLeft, 0.0f, kFullRect.fRight); + fDomain.fRight = SkScalarPin(domain.fRight, fDomain.fLeft, kFullRect.fRight); + fDomain.fTop = SkScalarPin(domain.fTop, 0.0f, kFullRect.fBottom); + fDomain.fBottom = SkScalarPin(domain.fBottom, fDomain.fTop, kFullRect.fBottom); + SkASSERT(fDomain.fLeft <= fDomain.fRight); + SkASSERT(fDomain.fTop <= fDomain.fBottom); } ////////////////////////////////////////////////////////////////////////////// @@ -145,17 +157,26 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLSLShaderBuilder* builder, void GrTextureDomain::GLDomain::setData(const GrGLSLProgramDataManager& pdman, const GrTextureDomain& textureDomain, - GrSurfaceOrigin textureOrigin) { + GrTexture* tex) { SkASSERT(textureDomain.mode() == fMode); if (kIgnore_Mode != textureDomain.mode()) { + SkScalar wInv = SK_Scalar1 / tex->width(); + SkScalar hInv = SK_Scalar1 / tex->height(); + float values[kPrevDomainCount] = { - SkScalarToFloat(textureDomain.domain().left()), - SkScalarToFloat(textureDomain.domain().top()), - SkScalarToFloat(textureDomain.domain().right()), - SkScalarToFloat(textureDomain.domain().bottom()) + SkScalarToFloat(textureDomain.domain().fLeft * wInv), + SkScalarToFloat(textureDomain.domain().fTop * hInv), + SkScalarToFloat(textureDomain.domain().fRight * wInv), + SkScalarToFloat(textureDomain.domain().fBottom * hInv) }; + + SkASSERT(values[0] >= 0.0f && values[0] <= 1.0f); + SkASSERT(values[1] >= 0.0f && values[1] <= 1.0f); + SkASSERT(values[2] >= 0.0f && values[2] <= 1.0f); + SkASSERT(values[3] >= 0.0f && values[3] <= 1.0f); + // vertical flip if necessary - if (kBottomLeft_GrSurfaceOrigin == textureOrigin) { + if (kBottomLeft_GrSurfaceOrigin == tex->origin()) { values[1] = 1.0f - values[1]; values[3] = 1.0f - values[3]; // The top and bottom were just flipped, so correct the ordering @@ -177,9 +198,8 @@ sk_sp<GrFragmentProcessor> GrTextureDomainEffect::Make(GrTexture* texture, const SkRect& domain, GrTextureDomain::Mode mode, GrSamplerParams::FilterMode filterMode) { - static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1}; if (GrTextureDomain::kIgnore_Mode == mode || - (GrTextureDomain::kClamp_Mode == mode && domain.contains(kFullRect))) { + (GrTextureDomain::kClamp_Mode == mode && can_ignore_rect(texture, domain))) { return GrSimpleTextureEffect::Make(texture, std::move(colorSpaceXform), matrix, filterMode); } else { return sk_sp<GrFragmentProcessor>( @@ -195,7 +215,7 @@ GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, GrTextureDomain::Mode mode, GrSamplerParams::FilterMode filterMode) : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode) - , fTextureDomain(domain, mode) { + , fTextureDomain(texture, domain, mode) { SkASSERT(mode != GrTextureDomain::kRepeat_Mode || filterMode == GrSamplerParams::kNone_FilterMode); this->initClassID<GrTextureDomainEffect>(); @@ -235,7 +255,7 @@ GrGLSLFragmentProcessor* GrTextureDomainEffect::onCreateGLSLInstance() const { void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& fp) override { const GrTextureDomainEffect& tde = fp.cast<GrTextureDomainEffect>(); const GrTextureDomain& domain = tde.fTextureDomain; - fGLDomain.setData(pdman, domain, tde.textureSampler(0).texture()->origin()); + fGLDomain.setData(pdman, domain, tde.textureSampler(0).texture()); if (SkToBool(tde.colorSpaceXform())) { pdman.setSkMatrix44(fColorSpaceXformUni, tde.colorSpaceXform()->srcToDst()); } @@ -273,18 +293,19 @@ GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrTextureDomainEffect); sk_sp<GrFragmentProcessor> GrTextureDomainEffect::TestCreate(GrProcessorTestData* d) { int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : GrProcessorUnitTest::kAlphaTextureIdx; + GrTexture* tex = d->fTextures[texIdx]; SkRect domain; - domain.fLeft = d->fRandom->nextUScalar1(); - domain.fRight = d->fRandom->nextRangeScalar(domain.fLeft, SK_Scalar1); - domain.fTop = d->fRandom->nextUScalar1(); - domain.fBottom = d->fRandom->nextRangeScalar(domain.fTop, SK_Scalar1); + domain.fLeft = d->fRandom->nextRangeScalar(0, tex->width()); + domain.fRight = d->fRandom->nextRangeScalar(domain.fLeft, tex->width()); + domain.fTop = d->fRandom->nextRangeScalar(0, tex->height()); + domain.fBottom = d->fRandom->nextRangeScalar(domain.fTop, tex->height()); GrTextureDomain::Mode mode = (GrTextureDomain::Mode) d->fRandom->nextULessThan(GrTextureDomain::kModeCount); const SkMatrix& matrix = GrTest::TestMatrix(d->fRandom); bool bilerp = mode != GrTextureDomain::kRepeat_Mode ? d->fRandom->nextBool() : false; auto colorSpaceXform = GrTest::TestColorXform(d->fRandom); return GrTextureDomainEffect::Make( - d->fTextures[texIdx], + tex, colorSpaceXform, matrix, domain, @@ -303,7 +324,7 @@ sk_sp<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::Make(GrTe GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor( GrTexture* texture, const SkIRect& subset, const SkIPoint& deviceSpaceOffset) : fTextureSampler(texture, GrSamplerParams::ClampNoFilter()) - , fTextureDomain(GrTextureDomain::MakeTexelDomain(texture, subset), + , fTextureDomain(texture, GrTextureDomain::MakeTexelDomain(subset), GrTextureDomain::kDecal_Mode) { this->addTextureSampler(&fTextureSampler); fDeviceSpaceOffset.fX = deviceSpaceOffset.fX - subset.fLeft; @@ -342,7 +363,7 @@ GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLS const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp = fp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>(); GrTexture* texture = dstdfp.textureSampler(0).texture(); - fGLDomain.setData(pdman, dstdfp.fTextureDomain, texture->origin()); + fGLDomain.setData(pdman, dstdfp.fTextureDomain, texture); float iw = 1.f / texture->width(); float ih = 1.f / texture->height(); float scaleAndTransData[4] = { diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h index 72204b1f8e..66bd2201e3 100644 --- a/src/gpu/effects/GrTextureDomain.h +++ b/src/gpu/effects/GrTextureDomain.h @@ -44,8 +44,7 @@ public: static const int kModeCount = kLastMode + 1; static const GrTextureDomain& IgnoredDomain() { - static const SkRect gDummyRect = {0, 0, 0, 0}; - static const GrTextureDomain gDomain(gDummyRect, kIgnore_Mode); + static const GrTextureDomain gDomain(nullptr, SkRect::MakeEmpty(), kIgnore_Mode); return gDomain; } @@ -53,36 +52,22 @@ public: * @param index Pass a value >= 0 if using multiple texture domains in the same effect. * It is used to keep inserted variables from causing name collisions. */ - GrTextureDomain(const SkRect& domain, Mode, int index = -1); + GrTextureDomain(GrTexture*, const SkRect& domain, Mode, int index = -1); const SkRect& domain() const { return fDomain; } Mode mode() const { return fMode; } /* Computes a domain that bounds all the texels in texelRect. Note that with bilerp enabled texels neighboring the domain may be read. */ - static const SkRect MakeTexelDomain(const GrTexture* texture, const SkIRect& texelRect) { - SkScalar wInv = SK_Scalar1 / texture->width(); - SkScalar hInv = SK_Scalar1 / texture->height(); - SkRect result = { - texelRect.fLeft * wInv, - texelRect.fTop * hInv, - texelRect.fRight * wInv, - texelRect.fBottom * hInv - }; - return result; + static const SkRect MakeTexelDomain(const SkIRect& texelRect) { + return SkRect::Make(texelRect); } - static const SkRect MakeTexelDomainForMode(const GrTexture* texture, const SkIRect& texelRect, Mode mode) { + static const SkRect MakeTexelDomainForMode(const SkIRect& texelRect, Mode mode) { // For Clamp mode, inset by half a texel. - SkScalar wInv = SK_Scalar1 / texture->width(); - SkScalar hInv = SK_Scalar1 / texture->height(); SkScalar inset = (mode == kClamp_Mode && !texelRect.isEmpty()) ? SK_ScalarHalf : 0; - return SkRect::MakeLTRB( - (texelRect.fLeft + inset) * wInv, - (texelRect.fTop + inset) * hInv, - (texelRect.fRight - inset) * wInv, - (texelRect.fBottom - inset) * hInv - ); + return SkRect::MakeLTRB(texelRect.fLeft + inset, texelRect.fTop + inset, + texelRect.fRight - inset, texelRect.fBottom - inset); } bool operator==(const GrTextureDomain& that) const { @@ -130,7 +115,7 @@ public: * origin. */ void setData(const GrGLSLProgramDataManager& pdman, const GrTextureDomain& textureDomain, - GrSurfaceOrigin textureOrigin); + GrTexture* texure); enum { kDomainKeyBits = 2, // See DomainKey(). @@ -157,8 +142,6 @@ protected: Mode fMode; SkRect fDomain; int fIndex; - - typedef GrSingleTextureEffect INHERITED; }; /** |