aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/effects/GrTextureDomain.cpp
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-01-09 14:23:59 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-10 16:15:02 +0000
commite98234f231d66848e149db683c11b6388e10b233 (patch)
tree48bbfcde8b5519a3903a1be0e6b28b04dee6b819 /src/gpu/effects/GrTextureDomain.cpp
parent8e619a2b4eb31753e6fcb4a9ec494d31ace755da (diff)
Start making texture coordinates be absolute
The idea here is that we will pass GrTextureProxys in (where we're currently passing GrTextures) and defer the normalization until the texture is actually instantiated (and possibly move it to the GPU entirely) This CL does (intentionally) change the texturedomaineffect GM but I believe the new behavior is more correct. Change-Id: I4e0510b3dfb65ff0d0ee5921f9a6f94151e602d3 Reviewed-on: https://skia-review.googlesource.com/6807 Commit-Queue: Robert Phillips <robertphillips@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/gpu/effects/GrTextureDomain.cpp')
-rw-r--r--src/gpu/effects/GrTextureDomain.cpp93
1 files changed, 57 insertions, 36 deletions
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] = {