aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrTextureProducer.cpp
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-09-07 16:34:11 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-07 16:34:22 +0000
commit4df0092eac6e9bb5afc516773a0c618630193dc6 (patch)
tree7fd4a8d27fecb048c5d6e0ad00f79414696d2687 /src/gpu/GrTextureProducer.cpp
parent1e75f2a1020cde6698420d5d088c5c42e7c037ac (diff)
Revert "Remove "content" rect from GrTextureAdjuster."
This reverts commit 6e4bbbefe153495cf34ea42aa72691756e6ab40e. Reason for revert: assertion failure Original change's description: > Remove "content" rect from GrTextureAdjuster. > > Since we got rid of texture-backed bitmaps this is no longer required. > > Change-Id: Id15c745994a3d6a1489e193b5d29916fa0931264 > Reviewed-on: https://skia-review.googlesource.com/36340 > Commit-Queue: Brian Salomon <bsalomon@google.com> > Reviewed-by: Robert Phillips <robertphillips@google.com> TBR=bsalomon@google.com,robertphillips@google.com Change-Id: I2229ec05079368ff196ff351107f88062080e5ec No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://skia-review.googlesource.com/43720 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/gpu/GrTextureProducer.cpp')
-rw-r--r--src/gpu/GrTextureProducer.cpp115
1 files changed, 97 insertions, 18 deletions
diff --git a/src/gpu/GrTextureProducer.cpp b/src/gpu/GrTextureProducer.cpp
index f7d71fa18d..92732238e6 100644
--- a/src/gpu/GrTextureProducer.cpp
+++ b/src/gpu/GrTextureProducer.cpp
@@ -16,7 +16,9 @@
sk_sp<GrTextureProxy> GrTextureProducer::CopyOnGpu(GrContext* context,
sk_sp<GrTextureProxy> inputProxy,
+ const SkIRect* subset,
const CopyParams& copyParams) {
+ SkASSERT(!subset || !subset->isEmpty());
SkASSERT(context);
const SkRect dstRect = SkRect::MakeIWH(copyParams.fWidth, copyParams.fHeight);
@@ -31,13 +33,23 @@ sk_sp<GrTextureProxy> GrTextureProducer::CopyOnGpu(GrContext* context,
GrPaint paint;
paint.setGammaCorrect(true);
- SkRect localRect = SkRect::MakeWH(inputProxy->width(), inputProxy->height());
+ SkRect localRect;
+ if (subset) {
+ localRect = SkRect::Make(*subset);
+ } else {
+ localRect = SkRect::MakeWH(inputProxy->width(), inputProxy->height());
+ }
bool needsDomain = false;
if (copyParams.fFilter != GrSamplerParams::kNone_FilterMode) {
bool resizing = localRect.width() != dstRect.width() ||
localRect.height() != dstRect.height();
- needsDomain = resizing && !GrResourceProvider::IsFunctionallyExact(inputProxy.get());
+
+ if (GrResourceProvider::IsFunctionallyExact(inputProxy.get())) {
+ needsDomain = subset && resizing;
+ } else {
+ needsDomain = resizing;
+ }
}
if (needsDomain) {
@@ -76,45 +88,62 @@ GrTextureProducer::DomainMode GrTextureProducer::DetermineDomainMode(
FilterConstraint filterConstraint,
bool coordsLimitedToConstraintRect,
GrTextureProxy* proxy,
+ const SkIRect* contentRect,
const GrSamplerParams::FilterMode* filterModeOrNullForBicubic,
SkRect* domainRect) {
const SkIRect proxyBounds = SkIRect::MakeWH(proxy->width(), proxy->height());
SkASSERT(proxyBounds.contains(constraintRect));
+ // We only expect a content area rect if there is some non-content area.
+ SkASSERT(!contentRect ||
+ (!contentRect->contains(proxyBounds) &&
+ proxyBounds.contains(*contentRect) &&
+ contentRect->contains(constraintRect)));
const bool proxyIsExact = GrResourceProvider::IsFunctionallyExact(proxy);
- // We don't expect to have an image that is in an inexact proxy unless the caller was aware
- // of the potential of sampling outside of the proxy's bounds and specified a constraint rect
- // with a filter constraint.
- SkASSERT(kYes_FilterConstraint == filterConstraint || proxyIsExact);
+
// If the constraint rectangle contains the whole proxy then no need for a domain.
if (constraintRect.contains(proxyBounds) && proxyIsExact) {
return kNoDomain_DomainMode;
}
+ if (!contentRect && !proxyIsExact) {
+ contentRect = &proxyBounds;
+ }
+
bool restrictFilterToRect = (filterConstraint == GrTextureProducer::kYes_FilterConstraint);
// If we can filter outside the constraint rect, and there is no non-content area of the
// proxy, and we aren't going to generate sample coords outside the constraint rect then we
// don't need a domain.
- if (!restrictFilterToRect && coordsLimitedToConstraintRect) {
+ if (!restrictFilterToRect && !contentRect && coordsLimitedToConstraintRect) {
return kNoDomain_DomainMode;
}
// Get the domain inset based on sampling mode (or bail if mipped)
+ SkScalar filterHalfWidth = 0.f;
if (filterModeOrNullForBicubic) {
switch (*filterModeOrNullForBicubic) {
case GrSamplerParams::kNone_FilterMode:
if (coordsLimitedToConstraintRect) {
return kNoDomain_DomainMode;
+ } else {
+ filterHalfWidth = 0.f;
}
break;
case GrSamplerParams::kBilerp_FilterMode:
+ filterHalfWidth = .5f;
break;
case GrSamplerParams::kMipMap_FilterMode:
- // No domain can save us with mip maps.
- return restrictFilterToRect ? kTightCopy_DomainMode : kNoDomain_DomainMode;
+ if (restrictFilterToRect || contentRect) {
+ // No domain can save us here.
+ return kTightCopy_DomainMode;
+ }
+ return kNoDomain_DomainMode;
}
+ } else {
+ // bicubic does nearest filtering internally.
+ filterHalfWidth = 1.5f;
}
// Both bilerp and bicubic use bilinear filtering and so need to be clamped to the center
@@ -126,17 +155,67 @@ GrTextureProducer::DomainMode GrTextureProducer::DetermineDomainMode(
// the domain.
if (restrictFilterToRect) {
*domainRect = constraintRect.makeInset(kDomainInset, kDomainInset);
- if (domainRect->fLeft > domainRect->fRight) {
- domainRect->fLeft = domainRect->fRight =
- SkScalarAve(domainRect->fLeft, domainRect->fRight);
- }
- if (domainRect->fTop > domainRect->fBottom) {
- domainRect->fTop = domainRect->fBottom =
- SkScalarAve(domainRect->fTop, domainRect->fBottom);
+ } else if (contentRect) {
+ // If we got here then: there is a contentRect, the coords are limited to the
+ // constraint rect, and we're allowed to filter across the constraint rect boundary. So
+ // we check whether the filter would reach across the edge of the content area.
+ // We will only set the sides that are required.
+
+ domainRect->setLargest();
+ if (coordsLimitedToConstraintRect) {
+ // We may be able to use the fact that the texture coords are limited to the constraint
+ // rect in order to avoid having to add a domain.
+ bool needContentAreaConstraint = false;
+ if (contentRect->fLeft > 0 &&
+ contentRect->fLeft + filterHalfWidth > constraintRect.fLeft) {
+ domainRect->fLeft = contentRect->fLeft + kDomainInset;
+ needContentAreaConstraint = true;
+ }
+ if (contentRect->fTop > 0 &&
+ contentRect->fTop + filterHalfWidth > constraintRect.fTop) {
+ domainRect->fTop = contentRect->fTop + kDomainInset;
+ needContentAreaConstraint = true;
+ }
+ if ((!proxyIsExact || contentRect->fRight < proxy->width()) &&
+ contentRect->fRight - filterHalfWidth < constraintRect.fRight) {
+ domainRect->fRight = contentRect->fRight - kDomainInset;
+ needContentAreaConstraint = true;
+ }
+ if ((!proxyIsExact || contentRect->fBottom < proxy->height()) &&
+ contentRect->fBottom - filterHalfWidth < constraintRect.fBottom) {
+ domainRect->fBottom = contentRect->fBottom - kDomainInset;
+ needContentAreaConstraint = true;
+ }
+ if (!needContentAreaConstraint) {
+ return kNoDomain_DomainMode;
+ }
+ } else {
+ // Our sample coords for the texture are allowed to be outside the constraintRect so we
+ // don't consider it when computing the domain.
+ if (contentRect->fLeft > 0) {
+ domainRect->fLeft = contentRect->fLeft + kDomainInset;
+ }
+ if (contentRect->fTop > 0) {
+ domainRect->fTop = contentRect->fTop + kDomainInset;
+ }
+ if (!proxyIsExact || contentRect->fRight < proxy->width()) {
+ domainRect->fRight = contentRect->fRight - kDomainInset;
+ }
+ if (!proxyIsExact || contentRect->fBottom < proxy->height()) {
+ domainRect->fBottom = contentRect->fBottom - kDomainInset;
+ }
}
- return kDomain_DomainMode;
+ } else {
+ return kNoDomain_DomainMode;
+ }
+
+ if (domainRect->fLeft > domainRect->fRight) {
+ domainRect->fLeft = domainRect->fRight = SkScalarAve(domainRect->fLeft, domainRect->fRight);
+ }
+ if (domainRect->fTop > domainRect->fBottom) {
+ domainRect->fTop = domainRect->fBottom = SkScalarAve(domainRect->fTop, domainRect->fBottom);
}
- return kNoDomain_DomainMode;
+ return kDomain_DomainMode;
}
std::unique_ptr<GrFragmentProcessor> GrTextureProducer::CreateFragmentProcessorForDomainAndFilter(