diff options
author | Brian Salomon <bsalomon@google.com> | 2017-09-07 16:34:11 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-09-07 16:34:22 +0000 |
commit | 4df0092eac6e9bb5afc516773a0c618630193dc6 (patch) | |
tree | 7fd4a8d27fecb048c5d6e0ad00f79414696d2687 /src/gpu/GrTextureProducer.cpp | |
parent | 1e75f2a1020cde6698420d5d088c5c42e7c037ac (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.cpp | 115 |
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( |