Revert "Remove "content" rect from GrTextureAdjuster."
This reverts commit 6e4bbbefe1
.
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>
This commit is contained in:
parent
1e75f2a102
commit
4df0092eac
@ -13,14 +13,22 @@
|
||||
#include "SkGr.h"
|
||||
|
||||
GrTextureAdjuster::GrTextureAdjuster(GrContext* context, sk_sp<GrTextureProxy> original,
|
||||
SkAlphaType alphaType, uint32_t uniqueID, SkColorSpace* cs)
|
||||
: INHERITED(original->width(), original->height(),
|
||||
GrPixelConfigIsAlphaOnly(original->config()))
|
||||
, fContext(context)
|
||||
, fOriginal(std::move(original))
|
||||
, fAlphaType(alphaType)
|
||||
, fColorSpace(cs)
|
||||
, fUniqueID(uniqueID) {}
|
||||
SkAlphaType alphaType,
|
||||
const SkIRect& contentArea, uint32_t uniqueID,
|
||||
SkColorSpace* cs)
|
||||
: INHERITED(contentArea.width(), contentArea.height(),
|
||||
GrPixelConfigIsAlphaOnly(original->config()))
|
||||
, fContext(context)
|
||||
, fOriginal(std::move(original))
|
||||
, fAlphaType(alphaType)
|
||||
, fColorSpace(cs)
|
||||
, fUniqueID(uniqueID) {
|
||||
SkASSERT(SkIRect::MakeWH(fOriginal->width(), fOriginal->height()).contains(contentArea));
|
||||
if (contentArea.fLeft > 0 || contentArea.fTop > 0 ||
|
||||
contentArea.fRight < fOriginal->width() || contentArea.fBottom < fOriginal->height()) {
|
||||
fContentArea.set(contentArea);
|
||||
}
|
||||
}
|
||||
|
||||
void GrTextureAdjuster::makeCopyKey(const CopyParams& params, GrUniqueKey* copyKey,
|
||||
SkColorSpace* dstColorSpace) {
|
||||
@ -46,8 +54,9 @@ sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxyCopy(const CopyParams& c
|
||||
}
|
||||
|
||||
sk_sp<GrTextureProxy> proxy = this->originalProxyRef();
|
||||
const SkIRect* contentArea = this->contentAreaOrNull();
|
||||
|
||||
sk_sp<GrTextureProxy> copy = CopyOnGpu(fContext, std::move(proxy), copyParams);
|
||||
sk_sp<GrTextureProxy> copy = CopyOnGpu(fContext, std::move(proxy), contentArea, copyParams);
|
||||
if (copy) {
|
||||
if (key.isValid()) {
|
||||
SkASSERT(copy->origin() == this->originalProxy()->origin());
|
||||
@ -60,31 +69,60 @@ sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxyCopy(const CopyParams& c
|
||||
|
||||
sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxySafeForParams(
|
||||
const GrSamplerParams& params,
|
||||
SkIPoint* outOffset,
|
||||
SkScalar scaleAdjust[2]) {
|
||||
sk_sp<GrTextureProxy> proxy = this->originalProxyRef();
|
||||
CopyParams copyParams;
|
||||
const SkIRect* contentArea = this->contentAreaOrNull();
|
||||
|
||||
if (!fContext) {
|
||||
// The texture was abandoned.
|
||||
return nullptr;
|
||||
}
|
||||
if (!fContext->getGpu()->isACopyNeededForTextureParams(proxy.get(), params, ©Params,
|
||||
scaleAdjust)) {
|
||||
|
||||
if (contentArea && GrSamplerParams::kMipMap_FilterMode == params.filterMode()) {
|
||||
// If we generate a MIP chain for texture it will read pixel values from outside the content
|
||||
// area.
|
||||
copyParams.fWidth = contentArea->width();
|
||||
copyParams.fHeight = contentArea->height();
|
||||
copyParams.fFilter = GrSamplerParams::kBilerp_FilterMode;
|
||||
} else if (!fContext->getGpu()->isACopyNeededForTextureParams(proxy.get(), params, ©Params,
|
||||
scaleAdjust)) {
|
||||
if (outOffset) {
|
||||
if (contentArea) {
|
||||
outOffset->set(contentArea->fLeft, contentArea->fRight);
|
||||
} else {
|
||||
outOffset->set(0, 0);
|
||||
}
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
|
||||
sk_sp<GrTextureProxy> copy = this->refTextureProxyCopy(copyParams);
|
||||
if (copy && outOffset) {
|
||||
outOffset->set(0, 0);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor(
|
||||
const SkMatrix& origTextureMatrix,
|
||||
const SkRect& constraintRect,
|
||||
const SkRect& origConstraintRect,
|
||||
FilterConstraint filterConstraint,
|
||||
bool coordsLimitedToConstraintRect,
|
||||
const GrSamplerParams::FilterMode* filterOrNullForBicubic,
|
||||
SkColorSpace* dstColorSpace) {
|
||||
SkMatrix textureMatrix = origTextureMatrix;
|
||||
const SkIRect* contentArea = this->contentAreaOrNull();
|
||||
// Convert the constraintRect to be relative to the texture rather than the content area so
|
||||
// that both rects are in the same coordinate system.
|
||||
SkTCopyOnFirstWrite<SkRect> constraintRect(origConstraintRect);
|
||||
if (contentArea) {
|
||||
SkScalar l = SkIntToScalar(contentArea->fLeft);
|
||||
SkScalar t = SkIntToScalar(contentArea->fTop);
|
||||
constraintRect.writable()->offset(l, t);
|
||||
textureMatrix.postTranslate(l, t);
|
||||
}
|
||||
|
||||
SkRect domain;
|
||||
GrSamplerParams params;
|
||||
@ -92,19 +130,22 @@ std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor(
|
||||
params.setFilterMode(*filterOrNullForBicubic);
|
||||
}
|
||||
SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
|
||||
sk_sp<GrTextureProxy> proxy(this->refTextureProxySafeForParams(params, scaleAdjust));
|
||||
sk_sp<GrTextureProxy> proxy(this->refTextureProxySafeForParams(params, nullptr, scaleAdjust));
|
||||
if (!proxy) {
|
||||
return nullptr;
|
||||
}
|
||||
// If we made a copy then we only copied the contentArea, in which case the new texture is all
|
||||
// content.
|
||||
if (proxy.get() != this->originalProxy()) {
|
||||
contentArea = nullptr;
|
||||
textureMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
|
||||
}
|
||||
|
||||
DomainMode domainMode =
|
||||
DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
|
||||
proxy.get(), filterOrNullForBicubic, &domain);
|
||||
DetermineDomainMode(*constraintRect, filterConstraint, coordsLimitedToConstraintRect,
|
||||
proxy.get(),
|
||||
contentArea, filterOrNullForBicubic,
|
||||
&domain);
|
||||
if (kTightCopy_DomainMode == domainMode) {
|
||||
// TODO: Copy the texture and adjust the texture matrix (both parts need to consider
|
||||
// non-int constraint rect)
|
||||
@ -115,8 +156,9 @@ std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor(
|
||||
GrSamplerParams::kMipMap_FilterMode == *filterOrNullForBicubic);
|
||||
static const GrSamplerParams::FilterMode kBilerp = GrSamplerParams::kBilerp_FilterMode;
|
||||
domainMode =
|
||||
DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
|
||||
proxy.get(), &kBilerp, &domain);
|
||||
DetermineDomainMode(*constraintRect, filterConstraint, coordsLimitedToConstraintRect,
|
||||
proxy.get(),
|
||||
contentArea, &kBilerp, &domain);
|
||||
SkASSERT(kTightCopy_DomainMode != domainMode);
|
||||
}
|
||||
SkASSERT(kNoDomain_DomainMode == domainMode ||
|
||||
|
@ -21,9 +21,10 @@
|
||||
class GrTextureAdjuster : public GrTextureProducer {
|
||||
public:
|
||||
/** Makes the subset of the texture safe to use with the given texture parameters.
|
||||
If the copy's size does not match subset's dimensions then the resulting scale
|
||||
factors used to sample the copy are returned in 'scaleAdjust'. */
|
||||
sk_sp<GrTextureProxy> refTextureProxySafeForParams(const GrSamplerParams&,
|
||||
outOffset will be the top-left corner of the subset if a copy is not made. Otherwise,
|
||||
the copy will be tight to the contents and outOffset will be (0, 0). If the copy's size
|
||||
does not match subset's dimensions then the contents are scaled to fit the copy.*/
|
||||
sk_sp<GrTextureProxy> refTextureProxySafeForParams(const GrSamplerParams&, SkIPoint* outOffset,
|
||||
SkScalar scaleAdjust[2]);
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> createFragmentProcessor(
|
||||
@ -36,8 +37,8 @@ public:
|
||||
|
||||
// We do not ref the texture nor the colorspace, so the caller must keep them in scope while
|
||||
// this Adjuster is alive.
|
||||
GrTextureAdjuster(GrContext*, sk_sp<GrTextureProxy>, SkAlphaType, uint32_t uniqueID,
|
||||
SkColorSpace*);
|
||||
GrTextureAdjuster(GrContext*, sk_sp<GrTextureProxy>, SkAlphaType, const SkIRect& area,
|
||||
uint32_t uniqueID, SkColorSpace*);
|
||||
|
||||
protected:
|
||||
SkAlphaType alphaType() const override { return fAlphaType; }
|
||||
@ -48,7 +49,11 @@ protected:
|
||||
GrTextureProxy* originalProxy() const { return fOriginal.get(); }
|
||||
sk_sp<GrTextureProxy> originalProxyRef() const { return fOriginal; }
|
||||
|
||||
/** Returns the content area or null for the whole original texture */
|
||||
const SkIRect* contentAreaOrNull() { return fContentArea.getMaybeNull(); }
|
||||
|
||||
private:
|
||||
SkTLazy<SkIRect> fContentArea;
|
||||
GrContext* fContext;
|
||||
sk_sp<GrTextureProxy> fOriginal;
|
||||
SkAlphaType fAlphaType;
|
||||
|
@ -59,7 +59,7 @@ sk_sp<GrTextureProxy> GrTextureMaker::refTextureProxyForParams(const GrSamplerPa
|
||||
|
||||
sk_sp<GrTextureProxy> result;
|
||||
if (original) {
|
||||
result = CopyOnGpu(fContext, std::move(original), copyParams);
|
||||
result = CopyOnGpu(fContext, std::move(original), nullptr, copyParams);
|
||||
} else {
|
||||
result = this->generateTextureProxyForParams(copyParams, willBeMipped, dstColorSpace);
|
||||
}
|
||||
@ -114,8 +114,9 @@ std::unique_ptr<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
|
||||
adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
|
||||
SkRect domain;
|
||||
DomainMode domainMode =
|
||||
DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
|
||||
proxy.get(), fmForDetermineDomain, &domain);
|
||||
DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
|
||||
proxy.get(),
|
||||
nullptr, fmForDetermineDomain, &domain);
|
||||
SkASSERT(kTightCopy_DomainMode != domainMode);
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(),
|
||||
dstColorSpace);
|
||||
@ -134,5 +135,5 @@ sk_sp<GrTextureProxy> GrTextureMaker::generateTextureProxyForParams(const CopyPa
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return CopyOnGpu(fContext, std::move(original), copyParams);
|
||||
return CopyOnGpu(fContext, std::move(original), nullptr, copyParams);
|
||||
}
|
||||
|
@ -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);
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
if (domainRect->fTop > domainRect->fBottom) {
|
||||
domainRect->fTop = domainRect->fBottom =
|
||||
SkScalarAve(domainRect->fTop, domainRect->fBottom);
|
||||
}
|
||||
return kDomain_DomainMode;
|
||||
} else {
|
||||
return kNoDomain_DomainMode;
|
||||
}
|
||||
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 kDomain_DomainMode;
|
||||
}
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> GrTextureProducer::CreateFragmentProcessorForDomainAndFilter(
|
||||
|
@ -119,13 +119,14 @@ protected:
|
||||
};
|
||||
|
||||
static sk_sp<GrTextureProxy> CopyOnGpu(GrContext*, sk_sp<GrTextureProxy> inputProxy,
|
||||
const CopyParams& copyParams);
|
||||
const SkIRect* subset, const CopyParams& copyParams);
|
||||
|
||||
static DomainMode DetermineDomainMode(
|
||||
const SkRect& constraintRect,
|
||||
FilterConstraint filterConstraint,
|
||||
bool coordsLimitedToConstraintRect,
|
||||
GrTextureProxy*,
|
||||
const SkIRect* textureContentArea,
|
||||
const GrSamplerParams::FilterMode* filterModeOrNullForBicubic,
|
||||
SkRect* domainRect);
|
||||
|
||||
|
@ -1406,7 +1406,8 @@ void SkGpuDevice::drawImageNine(const SkImage* image,
|
||||
ASSERT_SINGLE_OWNER
|
||||
uint32_t pinnedUniqueID;
|
||||
if (sk_sp<GrTextureProxy> proxy = as_IB(image)->refPinnedTextureProxy(&pinnedUniqueID)) {
|
||||
GrTextureAdjuster adjuster(this->context(), std::move(proxy), image->alphaType(),
|
||||
GrTextureAdjuster adjuster(this->context(), std::move(proxy),
|
||||
image->alphaType(), image->bounds(),
|
||||
pinnedUniqueID, as_IB(image)->onImageInfo().colorSpace());
|
||||
this->drawProducerNine(&adjuster, center, dst, paint);
|
||||
} else {
|
||||
@ -1460,7 +1461,8 @@ void SkGpuDevice::drawImageLattice(const SkImage* image,
|
||||
ASSERT_SINGLE_OWNER
|
||||
uint32_t pinnedUniqueID;
|
||||
if (sk_sp<GrTextureProxy> proxy = as_IB(image)->refPinnedTextureProxy(&pinnedUniqueID)) {
|
||||
GrTextureAdjuster adjuster(this->context(), std::move(proxy), image->alphaType(),
|
||||
GrTextureAdjuster adjuster(this->context(), std::move(proxy),
|
||||
image->alphaType(), image->bounds(),
|
||||
pinnedUniqueID, as_IB(image)->onImageInfo().colorSpace());
|
||||
this->drawProducerLattice(&adjuster, lattice, dst, paint);
|
||||
} else {
|
||||
|
@ -145,8 +145,9 @@ void SkGpuDevice::drawPinnedTextureProxy(sk_sp<GrTextureProxy> proxy, uint32_t p
|
||||
this->clip(), fRenderTargetContext.get());
|
||||
return;
|
||||
}
|
||||
GrTextureAdjuster adjuster(this->context(), std::move(proxy), alphaType, pinnedUniqueID,
|
||||
colorSpace);
|
||||
auto contentRect = SkIRect::MakeWH(proxy->width(), proxy->height());
|
||||
GrTextureAdjuster adjuster(this->context(), std::move(proxy), alphaType, contentRect,
|
||||
pinnedUniqueID, colorSpace);
|
||||
this->drawTextureProducer(&adjuster, srcRect, dstRect, constraint, viewMatrix, paint);
|
||||
}
|
||||
|
||||
|
@ -123,9 +123,9 @@ sk_sp<GrTextureProxy> SkImage_Gpu::asTextureProxyRef(GrContext* context,
|
||||
*texColorSpace = this->fColorSpace;
|
||||
}
|
||||
|
||||
GrTextureAdjuster adjuster(fContext, fProxy, this->alphaType(), this->uniqueID(),
|
||||
this->fColorSpace.get());
|
||||
return adjuster.refTextureProxySafeForParams(params, scaleAdjust);
|
||||
GrTextureAdjuster adjuster(fContext, fProxy, this->alphaType(), this->bounds(),
|
||||
this->uniqueID(), this->fColorSpace.get());
|
||||
return adjuster.refTextureProxySafeForParams(params, nullptr, scaleAdjust);
|
||||
}
|
||||
|
||||
static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) {
|
||||
|
@ -186,9 +186,10 @@ sk_sp<GrTextureProxy> SkImage_Raster::asTextureProxyRef(GrContext* context,
|
||||
uint32_t uniqueID;
|
||||
sk_sp<GrTextureProxy> tex = this->refPinnedTextureProxy(&uniqueID);
|
||||
if (tex) {
|
||||
GrTextureAdjuster adjuster(context, fPinnedProxy, fBitmap.alphaType(), fPinnedUniqueID,
|
||||
fBitmap.colorSpace());
|
||||
return adjuster.refTextureProxySafeForParams(params, scaleAdjust);
|
||||
GrTextureAdjuster adjuster(context, fPinnedProxy,
|
||||
fBitmap.alphaType(), fBitmap.bounds(),
|
||||
fPinnedUniqueID, fBitmap.colorSpace());
|
||||
return adjuster.refTextureProxySafeForParams(params, nullptr, scaleAdjust);
|
||||
}
|
||||
|
||||
return GrRefCachedBitmapTextureProxy(context, fBitmap, params, scaleAdjust);
|
||||
|
@ -13,10 +13,11 @@
|
||||
#include "GrTextureProducer.h"
|
||||
#include "GrTextureProxy.h"
|
||||
|
||||
// For DetermineDomainMode (in the MDB world) we have 3 rects:
|
||||
// For DetermineDomainMode (in the MDB world) we have 4 rects:
|
||||
// 1) the final instantiated backing storage (i.e., the actual GrTexture's extent)
|
||||
// 2) the proxy's extent, which may or may not match the GrTexture's extent
|
||||
// 3) the constraint rect, which can optionally be hard or soft
|
||||
// 3) the content rect, which can be a subset of the proxy's extent or null
|
||||
// 4) the constraint rect, which can optionally be hard or soft
|
||||
// This test "fuzzes" all the combinations of these rects.
|
||||
class GrTextureProducer_TestAccess {
|
||||
public:
|
||||
@ -27,12 +28,14 @@ public:
|
||||
GrTextureProducer::FilterConstraint filterConstraint,
|
||||
bool coordsLimitedToConstraintRect,
|
||||
GrTextureProxy* proxy,
|
||||
const SkIRect* textureContentArea,
|
||||
const GrSamplerParams::FilterMode* filterModeOrNullForBicubic,
|
||||
SkRect* domainRect) {
|
||||
return GrTextureProducer::DetermineDomainMode(constraintRect,
|
||||
filterConstraint,
|
||||
coordsLimitedToConstraintRect,
|
||||
proxy,
|
||||
textureContentArea,
|
||||
filterModeOrNullForBicubic,
|
||||
domainRect);
|
||||
}
|
||||
@ -40,6 +43,22 @@ public:
|
||||
|
||||
using DomainMode = GrTextureProducer_TestAccess::DomainMode;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
static bool is_irect(const SkRect& r) {
|
||||
return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) &&
|
||||
SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom);
|
||||
}
|
||||
#endif
|
||||
|
||||
static SkIRect to_irect(const SkRect& r) {
|
||||
SkASSERT(is_irect(r));
|
||||
return SkIRect::MakeLTRB(SkScalarRoundToInt(r.fLeft),
|
||||
SkScalarRoundToInt(r.fTop),
|
||||
SkScalarRoundToInt(r.fRight),
|
||||
SkScalarRoundToInt(r.fBottom));
|
||||
}
|
||||
|
||||
|
||||
class RectInfo {
|
||||
public:
|
||||
enum Side { kLeft = 0, kTop = 1, kRight = 2, kBot = 3 };
|
||||
@ -297,6 +316,20 @@ static const SkRect* full_inset(const RectInfo& enclosing,
|
||||
kInsetLeft_Flag|kInsetTop_Flag|kInsetRight_Flag|kInsetBot_Flag, name);
|
||||
}
|
||||
|
||||
// This is only used for content rect creation. We ensure 'result' is correct but
|
||||
// return null to indicate no content area (other than what the proxy specifies).
|
||||
static const SkRect* null_rect(const RectInfo& enclosing,
|
||||
RectInfo* result,
|
||||
bool isInsetHard,
|
||||
bool areCoordsLimitedToRect,
|
||||
float insetAmount,
|
||||
float halfFilterWidth) {
|
||||
static const char* name = "null";
|
||||
generic_inset(enclosing, result, isInsetHard, areCoordsLimitedToRect,
|
||||
insetAmount, halfFilterWidth, 0, name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Make a rect with no inset. This is only used for constraint rect creation.
|
||||
static const SkRect* no_inset(const RectInfo& enclosing,
|
||||
RectInfo* result,
|
||||
@ -332,50 +365,70 @@ static void proxy_test(skiatest::Reporter* reporter, GrResourceProvider* resourc
|
||||
sk_sp<GrTextureProxy> proxy = create_proxy(resourceProvider, isPowerOfTwoSized,
|
||||
isExact, &outermost);
|
||||
SkASSERT(outermost.isHardOrBadAllAround());
|
||||
for (auto isConstraintRectHard : { true, false }) {
|
||||
if (!isConstraintRectHard && !isExact) {
|
||||
// GrTextureProducer expects that texture inexactness is expressed as a
|
||||
// constraint rect and asserts if not. This skips a case that never happens
|
||||
// through the public API.
|
||||
continue;
|
||||
|
||||
for (auto contentRectMaker : { left_only, top_only, right_only,
|
||||
bot_only, full_inset, null_rect}) {
|
||||
RectInfo contentRectStorage;
|
||||
const SkRect* contentRect = (*contentRectMaker)(outermost,
|
||||
&contentRectStorage,
|
||||
true, false, 5.0f, -1.0f);
|
||||
if (contentRect) {
|
||||
// We only have content rects if they actually reduce the extent of the content
|
||||
SkASSERT(!contentRect->contains(outermost.rect()));
|
||||
SkASSERT(outermost.rect().contains(*contentRect));
|
||||
SkASSERT(is_irect(*contentRect));
|
||||
}
|
||||
for (auto areCoordsLimitedToConstraintRect : { true, false }) {
|
||||
for (int filterMode = 0; filterMode < 4; ++filterMode) {
|
||||
for (auto constraintRectMaker : { left_only, top_only, right_only,
|
||||
bot_only, full_inset, no_inset }) {
|
||||
for (auto insetAmt : { 0.25f, 0.75f, 1.25f, 1.75f, 5.0f }) {
|
||||
RectInfo constraintRectStorage;
|
||||
const SkRect* constraintRect = (*constraintRectMaker)(
|
||||
outermost,
|
||||
&constraintRectStorage,
|
||||
isConstraintRectHard,
|
||||
areCoordsLimitedToConstraintRect,
|
||||
insetAmt,
|
||||
gHalfFilterWidth[filterMode]);
|
||||
SkASSERT(constraintRect); // always need one of these
|
||||
SkASSERT(outermost.rect().contains(*constraintRect));
|
||||
SkASSERT(contentRectStorage.isHardOrBadAllAround());
|
||||
|
||||
actualMode = GrTextureProducer_TestAccess::DetermineDomainMode(
|
||||
*constraintRect,
|
||||
isConstraintRectHard
|
||||
? GrTextureProducer::kYes_FilterConstraint
|
||||
: GrTextureProducer::kNo_FilterConstraint,
|
||||
areCoordsLimitedToConstraintRect,
|
||||
proxy.get(),
|
||||
gModePtrs[filterMode],
|
||||
&actualDomainRect);
|
||||
|
||||
expectedMode = DomainMode::kNoDomain_DomainMode;
|
||||
if (constraintRectStorage.hasABad()) {
|
||||
if (3 == filterMode) {
|
||||
expectedMode = DomainMode::kTightCopy_DomainMode;
|
||||
for (auto isConstraintRectHard : { true, false }) {
|
||||
for (auto areCoordsLimitedToConstraintRect : { true, false }) {
|
||||
for (int filterMode = 0; filterMode < 4; ++filterMode) {
|
||||
for (auto constraintRectMaker : { left_only, top_only, right_only,
|
||||
bot_only, full_inset, no_inset }) {
|
||||
for (auto insetAmt : { 0.25f, 0.75f, 1.25f, 1.75f, 5.0f }) {
|
||||
RectInfo constraintRectStorage;
|
||||
const SkRect* constraintRect = (*constraintRectMaker)(
|
||||
contentRect ? contentRectStorage : outermost,
|
||||
&constraintRectStorage,
|
||||
isConstraintRectHard,
|
||||
areCoordsLimitedToConstraintRect,
|
||||
insetAmt,
|
||||
gHalfFilterWidth[filterMode]);
|
||||
SkASSERT(constraintRect); // always need one of these
|
||||
if (contentRect) {
|
||||
SkASSERT(contentRect->contains(*constraintRect));
|
||||
} else {
|
||||
expectedMode = DomainMode::kDomain_DomainMode;
|
||||
SkASSERT(outermost.rect().contains(*constraintRect));
|
||||
}
|
||||
}
|
||||
|
||||
REPORTER_ASSERT(reporter, expectedMode == actualMode);
|
||||
// TODO: add a check that the returned domain rect is correct
|
||||
SkIRect contentIRect;
|
||||
if (contentRect) {
|
||||
contentIRect = to_irect(*contentRect);
|
||||
}
|
||||
|
||||
actualMode = GrTextureProducer_TestAccess::DetermineDomainMode(
|
||||
*constraintRect,
|
||||
isConstraintRectHard
|
||||
? GrTextureProducer::kYes_FilterConstraint
|
||||
: GrTextureProducer::kNo_FilterConstraint,
|
||||
areCoordsLimitedToConstraintRect,
|
||||
proxy.get(),
|
||||
contentRect ? &contentIRect : nullptr,
|
||||
gModePtrs[filterMode],
|
||||
&actualDomainRect);
|
||||
|
||||
expectedMode = DomainMode::kNoDomain_DomainMode;
|
||||
if (constraintRectStorage.hasABad()) {
|
||||
if (3 == filterMode) {
|
||||
expectedMode = DomainMode::kTightCopy_DomainMode;
|
||||
} else {
|
||||
expectedMode = DomainMode::kDomain_DomainMode;
|
||||
}
|
||||
}
|
||||
|
||||
REPORTER_ASSERT(reporter, expectedMode == actualMode);
|
||||
// TODO: add a check that the returned domain rect is correct
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user