Revert "Remove copies for wrap modes in GrTextureProducer."

This reverts commit 7fba244ea9.

Reason for revert: See if this is blocking the Chrome roll

Original change's description:
> Remove copies for wrap modes in GrTextureProducer.
> 
> GrTextureEffect now supports implementing wrap modes in shaders
> for subsets and texture types with HW sampling restrictions.
> 
> Change-Id: I5c93ade044465e13c5f56f7437fbbe288db0a8a8
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271056
> Reviewed-by: Greg Daniel <egdaniel@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>

TBR=egdaniel@google.com,bsalomon@google.com

Change-Id: I14397bec8ff4ba165c28faa8f44497f47d865862
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/272522
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2020-02-21 13:46:38 +00:00 committed by Skia Commit-Bot
parent 392846665c
commit bf5cb0f539
26 changed files with 374 additions and 171 deletions

View File

@ -273,8 +273,8 @@ protected:
}
static void draw_as_tex(SkCanvas* canvas, SkImage* image, SkScalar x, SkScalar y) {
GrSurfaceProxyView view =
as_IB(image)->refView(canvas->getGrContext(), GrSamplerState::Filter::kBilerp);
GrSurfaceProxyView view = as_IB(image)->refView(canvas->getGrContext(),
GrSamplerState::Filter::kBilerp, nullptr);
if (!view) {
// show placeholder if we have no texture
SkPaint paint;

View File

@ -122,14 +122,13 @@ GrSurfaceProxyView GrBitmapTextureMaker::refOriginalTextureProxyView(bool willBe
return {};
}
void GrBitmapTextureMaker::makeMipMappedKey(GrUniqueKey* mipMappedKey) {
void GrBitmapTextureMaker::makeCopyKey(const CopyParams& copyParams, GrUniqueKey* copyKey) {
// Destination color space is irrelevant - we always upload the bitmap's contents as-is
if (fOriginalKey.isValid()) {
MakeMipMappedKeyFromOriginalKey(fOriginalKey, mipMappedKey);
MakeCopyKeyFromOrigKey(fOriginalKey, copyParams, copyKey);
}
}
void GrBitmapTextureMaker::didCacheMipMappedCopy(const GrUniqueKey& mipMappedKey,
uint32_t contextUniqueID) {
GrInstallBitmapUniqueKeyInvalidator(mipMappedKey, contextUniqueID, fBitmap.pixelRef());
void GrBitmapTextureMaker::didCacheCopy(const GrUniqueKey& copyKey, uint32_t contextUniqueID) {
GrInstallBitmapUniqueKeyInvalidator(copyKey, contextUniqueID, fBitmap.pixelRef());
}

View File

@ -26,8 +26,8 @@ private:
GrSurfaceProxyView refOriginalTextureProxyView(bool willBeMipped,
AllowedTexGenType onlyIfFast) override;
void makeMipMappedKey(GrUniqueKey* mipMappedKey) override;
void didCacheMipMappedCopy(const GrUniqueKey& mipMappedKey, uint32_t contextUniqueID) override;
void makeCopyKey(const CopyParams& copyParams, GrUniqueKey* copyKey) override;
void didCacheCopy(const GrUniqueKey& copyKey, uint32_t contextUniqueID) override;
const SkBitmap fBitmap;
const SkBackingFit fFit;

View File

@ -45,14 +45,61 @@ void GrGpu::disconnect(DisconnectType) {}
////////////////////////////////////////////////////////////////////////////////
bool GrGpu::IsACopyNeededForMips(const GrCaps* caps, const GrTextureProxy* texProxy,
GrSamplerState::Filter filter) {
SkASSERT(texProxy);
if (filter != GrSamplerState::Filter::kMipMap || texProxy->mipMapped() == GrMipMapped::kYes ||
!caps->mipMapSupport()) {
bool GrGpu::IsACopyNeededForRepeatWrapMode(const GrCaps* caps,
GrTextureProxy* texProxy,
SkISize dimensions,
GrSamplerState::Filter filter,
GrTextureProducer::CopyParams* copyParams,
SkScalar scaleAdjust[2]) {
if (!caps->npotTextureTileSupport() &&
(!SkIsPow2(dimensions.width()) || !SkIsPow2(dimensions.height()))) {
SkASSERT(scaleAdjust);
copyParams->fDimensions = {SkNextPow2(dimensions.width()), SkNextPow2(dimensions.height())};
SkASSERT(scaleAdjust);
scaleAdjust[0] = ((SkScalar)copyParams->fDimensions.width()) / dimensions.width();
scaleAdjust[1] = ((SkScalar)copyParams->fDimensions.height()) / dimensions.height();
switch (filter) {
case GrSamplerState::Filter::kNearest:
copyParams->fFilter = GrSamplerState::Filter::kNearest;
break;
case GrSamplerState::Filter::kBilerp:
case GrSamplerState::Filter::kMipMap:
// We are only ever scaling up so no reason to ever indicate kMipMap.
copyParams->fFilter = GrSamplerState::Filter::kBilerp;
break;
}
return true;
}
if (texProxy) {
// If the texture format itself doesn't support repeat wrap mode or mipmapping (and
// those capabilities are required) force a copy.
if (texProxy->hasRestrictedSampling()) {
copyParams->fFilter = GrSamplerState::Filter::kNearest;
copyParams->fDimensions = texProxy->dimensions();
return true;
}
}
return false;
}
return SkMipMap::ComputeLevelCount(texProxy->width(), texProxy->height()) > 0;
bool GrGpu::IsACopyNeededForMips(const GrCaps* caps, const GrTextureProxy* texProxy,
GrSamplerState::Filter filter,
GrTextureProducer::CopyParams* copyParams) {
SkASSERT(texProxy);
int mipCount = SkMipMap::ComputeLevelCount(texProxy->width(), texProxy->height());
bool willNeedMips = GrSamplerState::Filter::kMipMap == filter && caps->mipMapSupport() &&
mipCount;
// If the texture format itself doesn't support mipmapping (and those capabilities are required)
// force a copy.
if (willNeedMips && texProxy->mipMapped() == GrMipMapped::kNo) {
copyParams->fFilter = GrSamplerState::Filter::kNearest;
copyParams->fDimensions = texProxy->dimensions();
return true;
}
return false;
}
static bool validate_texel_levels(SkISize dimensions, GrColorType texelColorType,

View File

@ -594,12 +594,22 @@ public:
virtual GrStencilAttachment* createStencilAttachmentForRenderTarget(
const GrRenderTarget*, int width, int height, int numStencilSamples) = 0;
// Determines whether a texture will need to be rescaled in order to be used with the
// GrSamplerState.
static bool IsACopyNeededForRepeatWrapMode(const GrCaps*,
GrTextureProxy* texProxy,
SkISize dimensions,
GrSamplerState::Filter,
GrTextureProducer::CopyParams*,
SkScalar scaleAdjust[2]);
// Determines whether a texture will need to be copied because the draw requires mips but the
// texutre doesn't have any. This call should be only checked if IsACopyNeededForTextureParams
// fails. If the previous call succeeds, then a copy should be done using those params and the
// mip mapping requirements will be handled there.
static bool IsACopyNeededForMips(const GrCaps* caps, const GrTextureProxy* texProxy,
GrSamplerState::Filter filter);
GrSamplerState::Filter filter,
GrTextureProducer::CopyParams* copyParams);
void handleDirtyContext() {
if (fResetBits) {

View File

@ -39,14 +39,15 @@ GrSurfaceProxyView GrImageTextureMaker::refOriginalTextureProxyView(bool willBeM
onlyIfFast);
}
void GrImageTextureMaker::makeMipMappedKey(GrUniqueKey* mipMappedKey) {
void GrImageTextureMaker::makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) {
if (fOriginalKey.isValid() && SkImage::kAllow_CachingHint == fCachingHint) {
GrUniqueKey cacheKey;
fImage->makeCacheKeyFromOrigKey(fOriginalKey, &cacheKey);
MakeMipMappedKeyFromOriginalKey(cacheKey, mipMappedKey);
MakeCopyKeyFromOrigKey(cacheKey, stretch, paramsCopyKey);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
GrYUVAImageTextureMaker::GrYUVAImageTextureMaker(GrContext* context, const SkImage* client,
@ -74,13 +75,13 @@ GrSurfaceProxyView GrYUVAImageTextureMaker::refOriginalTextureProxyView(
}
}
void GrYUVAImageTextureMaker::makeMipMappedKey(GrUniqueKey* mipMappedKey) {
void GrYUVAImageTextureMaker::makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) {
// TODO: Do we ever want to disable caching?
if (fOriginalKey.isValid()) {
GrUniqueKey cacheKey;
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
GrUniqueKey::Builder builder(&cacheKey, fOriginalKey, kDomain, 0, "Image");
MakeMipMappedKeyFromOriginalKey(cacheKey, mipMappedKey);
MakeCopyKeyFromOrigKey(cacheKey, stretch, paramsCopyKey);
}
}

View File

@ -22,12 +22,14 @@ public:
SkImage::CachingHint chint, bool useDecal = false);
private:
// TODO: consider overriding this, for the case where the underlying generator might be
// able to efficiently produce a "stretched" texture natively (e.g. picture-backed)
// GrTexture* generateTextureForParams(const CopyParams&) override;
GrSurfaceProxyView refOriginalTextureProxyView(bool willBeMipped,
AllowedTexGenType onlyIfFast) override;
void makeMipMappedKey(GrUniqueKey* mipMappedKey) override;
void didCacheMipMappedCopy(const GrUniqueKey& mipMappedKey, uint32_t contextUniqueID) override {
}
void makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) override;
void didCacheCopy(const GrUniqueKey& copyKey, uint32_t contextUniqueID) override {}
const SkImage_Lazy* fImage;
GrUniqueKey fOriginalKey;
@ -51,9 +53,8 @@ protected:
GrSurfaceProxyView refOriginalTextureProxyView(bool willBeMipped,
AllowedTexGenType onlyIfFast) override;
void makeMipMappedKey(GrUniqueKey* mipMappedKey) override;
void didCacheMipMappedCopy(const GrUniqueKey& mipMappedKey, uint32_t contextUniqueID) override {
}
void makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) override;
void didCacheCopy(const GrUniqueKey& copyKey, uint32_t contextUniqueID) override {}
std::unique_ptr<GrFragmentProcessor> createFragmentProcessor(
const SkMatrix& textureMatrix,

View File

@ -22,47 +22,65 @@ GrTextureAdjuster::GrTextureAdjuster(GrRecordingContext* context,
, fOriginal(std::move(original))
, fUniqueID(uniqueID) {}
void GrTextureAdjuster::makeMipMappedKey(GrUniqueKey* mipMappedKey) {
void GrTextureAdjuster::makeCopyKey(const CopyParams& params, GrUniqueKey* copyKey) {
// Destination color space is irrelevant - we already have a texture so we're just sub-setting
GrUniqueKey baseKey;
GrMakeKeyFromImageID(&baseKey, fUniqueID, SkIRect::MakeSize(this->dimensions()));
MakeMipMappedKeyFromOriginalKey(baseKey, mipMappedKey);
MakeCopyKeyFromOrigKey(baseKey, params, copyKey);
}
void GrTextureAdjuster::didCacheMipMappedCopy(const GrUniqueKey& mipMappedKey,
uint32_t contextUniqueID) {
void GrTextureAdjuster::didCacheCopy(const GrUniqueKey& copyKey, uint32_t contextUniqueID) {
// We don't currently have a mechanism for notifications on Images!
}
GrSurfaceProxyView GrTextureAdjuster::makeMippedCopy() {
GrSurfaceProxyView GrTextureAdjuster::copy(const CopyParams& copyParams, bool willBeMipped,
bool copyForMipsOnly) {
GrProxyProvider* proxyProvider = this->context()->priv().proxyProvider();
GrUniqueKey key;
this->makeMipMappedKey(&key);
this->makeCopyKey(copyParams, &key);
sk_sp<GrTextureProxy> cachedCopy;
const GrSurfaceProxyView& originalView = this->originalProxyView();
if (key.isValid()) {
cachedCopy = proxyProvider->findOrCreateProxyByUniqueKey(key, this->colorType());
if (cachedCopy) {
return {std::move(cachedCopy), originalView.origin(), originalView.swizzle()};
if (cachedCopy && (!willBeMipped || GrMipMapped::kYes == cachedCopy->mipMapped())) {
// TODO: Once we no longer use CopyOnGpu which can fallback to arbitrary formats and
// colorTypes, we can use the swizzle of the originalView.
GrSwizzle swizzle = cachedCopy->textureSwizzleDoNotUse();
return GrSurfaceProxyView(std::move(cachedCopy), originalView.origin(), swizzle);
}
}
GrSurfaceProxyView copyView = GrCopyBaseMipMapToTextureProxy(
this->context(), originalView.proxy(), originalView.origin(), this->colorType());
if (!copyView) {
return {};
GrSurfaceProxyView copyView;
if (copyForMipsOnly) {
copyView = GrCopyBaseMipMapToTextureProxy(this->context(), originalView.proxy(),
originalView.origin(), this->colorType());
} else {
copyView = CopyOnGpu(this->context(), this->originalProxyViewRef(), this->colorType(),
copyParams, willBeMipped);
}
if (copyView.proxy()) {
if (key.isValid()) {
SkASSERT(copyView.origin() == originalView.origin());
if (cachedCopy) {
SkASSERT(GrMipMapped::kYes == copyView.asTextureProxy()->mipMapped() &&
GrMipMapped::kNo == cachedCopy->mipMapped());
// If we had a cachedProxy, that means there already is a proxy in the cache which
// matches the key, but it does not have mip levels and we require them. Thus we
// must remove the unique key from that proxy.
SkASSERT(cachedCopy->getUniqueKey() == key);
proxyProvider->removeUniqueKeyFromProxy(cachedCopy.get());
}
proxyProvider->assignUniqueKeyToProxy(key, copyView.asTextureProxy());
this->didCacheMipMappedCopy(key, proxyProvider->contextID());
this->didCacheCopy(key, proxyProvider->contextID());
}
}
return copyView;
}
GrSurfaceProxyView GrTextureAdjuster::onRefTextureProxyViewForParams(GrSamplerState params,
bool willBeMipped) {
bool willBeMipped,
SkScalar scaleAdjust[2]) {
if (this->context()->priv().abandoned()) {
// The texture was abandoned.
return {};
@ -74,32 +92,51 @@ GrSurfaceProxyView GrTextureAdjuster::onRefTextureProxyViewForParams(GrSamplerSt
GrSurfaceProxyView view = this->originalProxyViewRef();
GrTextureProxy* texProxy = view.asTextureProxy();
SkASSERT(texProxy);
if (!GrGpu::IsACopyNeededForMips(this->context()->priv().caps(), texProxy, params.filter())) {
CopyParams copyParams;
bool needsCopyForMipsOnly = false;
if (!params.isRepeated() ||
!GrGpu::IsACopyNeededForRepeatWrapMode(this->context()->priv().caps(), texProxy,
texProxy->dimensions(), params.filter(), &copyParams,
scaleAdjust)) {
needsCopyForMipsOnly = GrGpu::IsACopyNeededForMips(this->context()->priv().caps(),
texProxy, params.filter(),
&copyParams);
if (!needsCopyForMipsOnly) {
return view;
}
}
GrSurfaceProxyView copy = this->makeMippedCopy();
if (!copy) {
GrSurfaceProxyView result = this->copy(copyParams, willBeMipped, needsCopyForMipsOnly);
if (!result.proxy() && needsCopyForMipsOnly) {
// If we were unable to make a copy and we only needed a copy for mips, then we will return
// the source texture here and require that the GPU backend is able to fall back to using
// bilerp if mips are required.
return view;
}
SkASSERT(copy.asTextureProxy());
return copy;
SkASSERT(result.asTextureProxy());
return result;
}
std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor(
const SkMatrix& textureMatrix,
const SkMatrix& origTextureMatrix,
const SkRect& constraintRect,
FilterConstraint filterConstraint,
bool coordsLimitedToConstraintRect,
const GrSamplerState::Filter* filterOrNullForBicubic) {
GrSurfaceProxyView view = this->viewForParams(filterOrNullForBicubic);
if (!view) {
SkMatrix textureMatrix = origTextureMatrix;
SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
GrSurfaceProxyView view = this->viewForParams(filterOrNullForBicubic, scaleAdjust);
if (!view.proxy()) {
return nullptr;
}
SkASSERT(view.asTextureProxy());
// If we made a copy then we only copied the contentArea, in which case the new texture is all
// content.
if (view.proxy() != this->originalProxyView().proxy()) {
textureMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
}
SkRect domain;
DomainMode domainMode =

View File

@ -33,16 +33,17 @@ public:
uint32_t uniqueID, bool useDecal = false);
protected:
void makeMipMappedKey(GrUniqueKey* mipMappedKey) override;
void didCacheMipMappedCopy(const GrUniqueKey& mipMappedKey, uint32_t contextUniqueID) override;
void makeCopyKey(const CopyParams& params, GrUniqueKey* copyKey) override;
void didCacheCopy(const GrUniqueKey& copyKey, uint32_t contextUniqueID) override;
const GrSurfaceProxyView& originalProxyView() const { return fOriginal; }
GrSurfaceProxyView originalProxyViewRef() const { return fOriginal; }
private:
GrSurfaceProxyView onRefTextureProxyViewForParams(GrSamplerState, bool willBeMipped) override;
GrSurfaceProxyView onRefTextureProxyViewForParams(GrSamplerState, bool willBeMipped,
SkScalar scaleAdjust[2]) override;
GrSurfaceProxyView makeMippedCopy();
GrSurfaceProxyView copy(const CopyParams& copyParams, bool willBeMipped, bool copyOnlyForMips);
GrSurfaceProxyView fOriginal;
uint32_t fUniqueID;

View File

@ -14,66 +14,102 @@
#include "src/gpu/GrRecordingContextPriv.h"
GrSurfaceProxyView GrTextureMaker::onRefTextureProxyViewForParams(GrSamplerState params,
bool willBeMipped) {
bool willBeMipped,
SkScalar scaleAdjust[2]) {
if (this->width() > this->context()->priv().caps()->maxTextureSize() ||
this->height() > this->context()->priv().caps()->maxTextureSize()) {
return {};
}
CopyParams copyParams;
GrSurfaceProxyView original = this->refOriginalTextureProxyView(willBeMipped,
AllowedTexGenType::kCheap);
if (!original) {
bool needsCopyForMipsOnly = false;
if (original.proxy()) {
GrTextureProxy* texProxy = original.asTextureProxy();
SkASSERT(texProxy);
if (!params.isRepeated() ||
!GrGpu::IsACopyNeededForRepeatWrapMode(this->context()->priv().caps(), texProxy,
texProxy->dimensions(), params.filter(),
&copyParams, scaleAdjust)) {
needsCopyForMipsOnly = GrGpu::IsACopyNeededForMips(this->context()->priv().caps(),
texProxy, params.filter(),
&copyParams);
if (!needsCopyForMipsOnly) {
return original;
}
}
} else {
if (!params.isRepeated() ||
!GrGpu::IsACopyNeededForRepeatWrapMode(this->context()->priv().caps(), nullptr,
this->dimensions(), params.filter(), &copyParams,
scaleAdjust)) {
return this->refOriginalTextureProxyView(willBeMipped, AllowedTexGenType::kAny);
}
GrTextureProxy* texProxy = original.asTextureProxy();
if (!GrGpu::IsACopyNeededForMips(this->context()->priv().caps(), texProxy, params.filter())) {
return original;
}
GrProxyProvider* proxyProvider = this->context()->priv().proxyProvider();
GrSurfaceOrigin origOrigin = original.proxy() ? original.origin() : kTopLeft_GrSurfaceOrigin;
GrUniqueKey mipMappedKey;
this->makeMipMappedKey(&mipMappedKey);
if (mipMappedKey.isValid()) {
auto cachedProxy =
proxyProvider->findOrCreateProxyByUniqueKey(mipMappedKey, this->colorType());
GrUniqueKey copyKey;
this->makeCopyKey(copyParams, &copyKey);
GrSurfaceProxyView cachedView;
if (copyKey.isValid()) {
auto cachedProxy = proxyProvider->findOrCreateProxyByUniqueKey(copyKey, this->colorType());
if (cachedProxy) {
SkASSERT(cachedProxy->mipMapped() == GrMipMapped::kYes);
// TODO: Once we no longer use MakeMipMappedCopy which can fallback to arbitrary formats
// and colorTypes, we can use the swizzle of the originalView.
GrMipMapped mipped = cachedProxy->mipMapped();
// TODO: Once we no longer use CopyOnGpu which can fallback to arbitrary formats and
// colorTypes, we can use the swizzle of the originalView.
GrSwizzle swizzle = cachedProxy->textureSwizzleDoNotUse();
return GrSurfaceProxyView(std::move(cachedProxy), origOrigin, swizzle);
cachedView = GrSurfaceProxyView(std::move(cachedProxy), origOrigin, swizzle);
if (!willBeMipped || GrMipMapped::kYes == mipped) {
return cachedView;
}
}
}
GrSurfaceProxyView source;
if (original) {
if (original.proxy()) {
source = std::move(original);
} else if (cachedView.proxy()) {
source = cachedView;
} else {
// Since we will be copying this texture there is no reason to make it mipped
source = this->refOriginalTextureProxyView(false, AllowedTexGenType::kAny);
if (!source) {
}
if (!source.proxy()) {
return {};
}
}
SkASSERT(source.asTextureProxy());
GrSurfaceProxyView result = MakeMipMappedCopy(this->context(), source, this->colorType());
GrSurfaceProxyView result =
CopyOnGpu(this->context(), source, this->colorType(), copyParams, willBeMipped);
if (!result) {
if (!result.proxy()) {
// If we were unable to make a copy and we only needed a copy for mips, then we will return
// the source texture here and require that the GPU backend is able to fall back to using
// bilerp if mips are required.
if (needsCopyForMipsOnly) {
return source;
}
return {};
}
if (mipMappedKey.isValid()) {
if (copyKey.isValid()) {
SkASSERT(result.origin() == origOrigin);
proxyProvider->assignUniqueKeyToProxy(mipMappedKey, result.asTextureProxy());
this->didCacheMipMappedCopy(mipMappedKey, proxyProvider->contextID());
if (cachedView.proxy()) {
SkASSERT(GrMipMapped::kYes == result.asTextureProxy()->mipMapped() &&
GrMipMapped::kNo == cachedView.asTextureProxy()->mipMapped());
// If we had a cachedProxy, that means there already is a proxy in the cache which
// matches the key, but it does not have mip levels and we require them. Thus we must
// remove the unique key from that proxy.
SkASSERT(cachedView.asTextureProxy()->getUniqueKey() == copyKey);
proxyProvider->removeUniqueKeyFromProxy(cachedView.asTextureProxy());
}
proxyProvider->assignUniqueKeyToProxy(copyKey, result.asTextureProxy());
this->didCacheCopy(copyKey, proxyProvider->contextID());
}
return result;
}
@ -96,10 +132,13 @@ std::unique_ptr<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
fmForDetermineDomain = &kBilerp;
}
GrSurfaceProxyView view = this->viewForParams(filterOrNullForBicubic);
if (!view) {
SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
GrSurfaceProxyView view = this->viewForParams(filterOrNullForBicubic, scaleAdjust);
if (!view.proxy()) {
return nullptr;
}
SkMatrix adjustedMatrix = textureMatrix;
adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
SkRect domain;
DomainMode domainMode =
@ -107,5 +146,5 @@ std::unique_ptr<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
view.proxy(), fmForDetermineDomain, &domain);
SkASSERT(kTightCopy_DomainMode != domainMode);
return this->createFragmentProcessorForDomainAndFilter(
std::move(view), textureMatrix, domainMode, domain, filterOrNullForBicubic);
std::move(view), adjustedMatrix, domainMode, domain, filterOrNullForBicubic);
}

View File

@ -40,7 +40,9 @@ protected:
AllowedTexGenType genType) = 0;
private:
GrSurfaceProxyView onRefTextureProxyViewForParams(GrSamplerState, bool willBeMipped) override;
GrSurfaceProxyView onRefTextureProxyViewForParams(GrSamplerState,
bool willBeMipped,
SkScalar scaleAdjust[2]) override;
typedef GrTextureProducer INHERITED;
};

View File

@ -21,35 +21,53 @@
#include "src/gpu/effects/GrTextureDomain.h"
#include "src/gpu/effects/GrTextureEffect.h"
GrSurfaceProxyView GrTextureProducer::MakeMipMappedCopy(GrRecordingContext* context,
GrSurfaceProxyView GrTextureProducer::CopyOnGpu(GrRecordingContext* context,
GrSurfaceProxyView inputView,
GrColorType colorType) {
GrColorType colorType,
const CopyParams& copyParams,
bool dstWillRequireMipMaps) {
SkASSERT(context);
SkASSERT(inputView.asTextureProxy());
GrSurfaceProxy* proxy = inputView.proxy();
SkRect proxyRect = proxy->getBoundsRect();
const SkRect dstRect = SkRect::Make(copyParams.fDimensions);
GrMipMapped mipMapped = dstWillRequireMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo;
GrSurfaceProxyView view =
GrCopyBaseMipMapToTextureProxy(context, proxy, inputView.origin(), colorType);
if (view) {
GrSurfaceProxy* proxy = inputView.proxy();
SkRect localRect = proxy->getBoundsRect();
bool resizing = false;
if (copyParams.fFilter != GrSamplerState::Filter::kNearest) {
resizing = localRect.width() != dstRect.width() || localRect.height() != dstRect.height();
}
if (copyParams.fFilter == GrSamplerState::Filter::kNearest && !resizing &&
dstWillRequireMipMaps) {
GrSurfaceProxyView view = GrCopyBaseMipMapToTextureProxy(context, proxy, inputView.origin(),
colorType);
if (view.proxy()) {
return view;
}
}
auto copyRTC = GrRenderTargetContext::MakeWithFallback(
context, colorType, nullptr, SkBackingFit::kExact, inputView.dimensions(), 1,
GrMipMapped::kYes, proxy->isProtected(), inputView.origin());
context, colorType, nullptr, SkBackingFit::kExact, copyParams.fDimensions, 1,
mipMapped, proxy->isProtected(), inputView.origin());
if (!copyRTC) {
return {};
}
const auto& caps = *context->priv().caps();
GrPaint paint;
auto fp = GrTextureEffect::Make(std::move(inputView), kUnknown_SkAlphaType, SkMatrix::I(),
GrSamplerState::Filter::kNearest);
GrSamplerState sampler(GrSamplerState::WrapMode::kClamp, copyParams.fFilter);
auto boundsRect = SkRect::Make(proxy->dimensions());
auto fp = GrTextureEffect::MakeSubset(std::move(inputView), kUnknown_SkAlphaType, SkMatrix::I(),
sampler, boundsRect, localRect, caps);
paint.addColorFragmentProcessor(std::move(fp));
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
copyRTC->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), proxyRect);
copyRTC->fillRectToRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), dstRect,
localRect);
return copyRTC->readSurfaceView();
}
@ -200,7 +218,7 @@ std::unique_ptr<GrFragmentProcessor> GrTextureProducer::createFragmentProcessorF
}
GrSurfaceProxyView GrTextureProducer::viewForParams(
const GrSamplerState::Filter* filterOrNullForBicubic) {
const GrSamplerState::Filter* filterOrNullForBicubic, SkScalar scaleAdjust[2]) {
GrSamplerState sampler; // Default is nearest + clamp
if (filterOrNullForBicubic) {
sampler.setFilterMode(*filterOrNullForBicubic);
@ -212,29 +230,36 @@ GrSurfaceProxyView GrTextureProducer::viewForParams(
sampler.setWrapModeY(GrSamplerState::WrapMode::kClampToBorder);
}
}
return this->viewForParams(sampler);
return this->viewForParams(sampler, scaleAdjust);
}
GrSurfaceProxyView GrTextureProducer::viewForParams(GrSamplerState sampler) {
GrSurfaceProxyView GrTextureProducer::viewForParams(GrSamplerState sampler,
SkScalar scaleAdjust[2]) {
// Check that the caller pre-initialized scaleAdjust
SkASSERT(!scaleAdjust || (scaleAdjust[0] == 1 && scaleAdjust[1] == 1));
const GrCaps* caps = this->context()->priv().caps();
int mipCount = SkMipMap::ComputeLevelCount(this->width(), this->height());
bool willBeMipped = GrSamplerState::Filter::kMipMap == sampler.filter() && mipCount &&
caps->mipMapSupport();
auto result = this->onRefTextureProxyViewForParams(sampler, willBeMipped);
if (!result) {
return {};
}
SkASSERT(result.asTextureProxy());
auto result = this->onRefTextureProxyViewForParams(sampler, willBeMipped, scaleAdjust);
// Check to make sure that if we say the texture willBeMipped that the returned texture has mip
// maps, unless the config is not copyable.
SkASSERT(!willBeMipped || result.asTextureProxy()->mipMapped() == GrMipMapped::kYes ||
SkASSERT(!result.proxy() || !willBeMipped ||
result.asTextureProxy()->mipMapped() == GrMipMapped::kYes ||
!caps->isFormatCopyable(result.proxy()->backendFormat()));
SkASSERT(result.proxy()->dimensions() == this->dimensions());
SkASSERT(!result.proxy() || result.asTextureProxy());
SkDEBUGCODE(bool expectNoScale = (sampler.filter() != GrSamplerState::Filter::kMipMap &&
!sampler.isRepeated()));
// Check that the "no scaling expected" case always returns a proxy of the same size as the
// producer.
SkASSERT(!result.proxy() || !expectNoScale ||
result.proxy()->dimensions() == this->dimensions());
return result;
}
@ -245,7 +270,7 @@ std::pair<GrSurfaceProxyView, GrColorType> GrTextureProducer::view(GrMipMapped w
: GrSamplerState::Filter::kMipMap;
GrSamplerState sampler(GrSamplerState::WrapMode::kClamp, filter);
auto result = this->viewForParams(sampler);
auto result = this->viewForParams(sampler, nullptr);
#ifdef SK_DEBUG
const GrCaps* caps = this->context()->priv().caps();

View File

@ -32,6 +32,11 @@ struct SkRect;
*/
class GrTextureProducer : public SkNoncopyable {
public:
struct CopyParams {
GrSamplerState::Filter fFilter;
SkISize fDimensions;
};
enum FilterConstraint {
kYes_FilterConstraint,
kNo_FilterConstraint,
@ -66,10 +71,21 @@ public:
/**
* Returns a texture that is safe for use with the params.
*
* If the size of the returned texture does not match width()/height() then the contents of the
* original may have been scaled to fit the texture or the original may have been copied into
* a subrect of the copy. 'scaleAdjust' must be applied to the normalized texture coordinates
* in order to correct for the latter case.
*
* If the GrSamplerState is known to clamp and use kNearest or kBilerp filter mode then the
* proxy will always be unscaled and nullptr can be passed for scaleAdjust. There is a weird
* contract that if scaleAdjust is not null it must be initialized to {1, 1} before calling
* this method. (TODO: Fix this and make this function always initialize scaleAdjust).
*/
GrSurfaceProxyView viewForParams(GrSamplerState);
GrSurfaceProxyView viewForParams(GrSamplerState, SkScalar scaleAdjust[2]);
GrSurfaceProxyView viewForParams(const GrSamplerState::Filter* filterOrNullForBicubic);
GrSurfaceProxyView viewForParams(const GrSamplerState::Filter* filterOrNullForBicubic,
SkScalar scaleAdjust[2]);
/**
* Returns a texture. If willNeedMips is true then the returned texture is guaranteed to have
@ -105,29 +121,35 @@ protected:
GrColorType colorType() const { return fImageInfo.colorType(); }
/** Helper for creating a key for a copy from an original key. */
static void MakeMipMappedKeyFromOriginalKey(const GrUniqueKey& origKey,
GrUniqueKey* mipMappedKey) {
SkASSERT(!mipMappedKey->isValid());
static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
const CopyParams& copyParams,
GrUniqueKey* copyKey) {
SkASSERT(!copyKey->isValid());
if (origKey.isValid()) {
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
GrUniqueKey::Builder builder(mipMappedKey, origKey, kDomain, 0);
GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3);
builder[0] = static_cast<uint32_t>(copyParams.fFilter);
builder[1] = copyParams.fDimensions.width();
builder[2] = copyParams.fDimensions.height();
}
}
/**
* If we need to make a copy with MIP maps the producer is asked to return a key that identifies
* the original conteny + the addition of MIP map levels. If the producer does not want to cache
* the copy it can simply leave the key uninitialized.
* If we need to make a copy in order to be compatible with GrTextureParams producer is asked to
* return a key that identifies its original content + the CopyParms parameter. If the producer
* does not want to cache the stretched version (e.g. the producer is volatile), this should
* simply return without initializing the copyKey. If the texture generated by this producer
* depends on the destination color space, then that information should also be incorporated
* in the key.
*/
virtual void makeMipMappedKey(GrUniqueKey* mipMappedKey) = 0;
virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey) = 0;
/**
* If a stretched version of the texture is generated, it may be cached (assuming that
* makeMipMappedKey() returns true). In that case, the maker is notified in case it
* makeCopyKey() returns true). In that case, the maker is notified in case it
* wants to note that for when the maker is destroyed.
*/
virtual void didCacheMipMappedCopy(const GrUniqueKey& mipMappedKey,
uint32_t contextUniqueID) = 0;
virtual void didCacheCopy(const GrUniqueKey& copyKey, uint32_t contextUniqueID) = 0;
enum DomainMode {
kNoDomain_DomainMode,
@ -135,11 +157,12 @@ protected:
kTightCopy_DomainMode
};
// TODO: Try to remove the draw fallback and directly use GrCopyBaseMipMapToTextureProxy
// instead.
static GrSurfaceProxyView MakeMipMappedCopy(GrRecordingContext*,
GrSurfaceProxyView,
GrColorType colorType);
// This can draw to accomplish the copy, thus the recording context is needed
static GrSurfaceProxyView CopyOnGpu(GrRecordingContext*,
GrSurfaceProxyView inputView,
GrColorType,
const CopyParams& copyParams,
bool dstWillRequireMipMaps);
static DomainMode DetermineDomainMode(const SkRect& constraintRect,
FilterConstraint filterConstraint,
@ -158,8 +181,8 @@ protected:
GrRecordingContext* context() const { return fContext; }
private:
virtual GrSurfaceProxyView onRefTextureProxyViewForParams(GrSamplerState,
bool willBeMipped) = 0;
virtual GrSurfaceProxyView onRefTextureProxyViewForParams(GrSamplerState, bool willBeMipped,
SkScalar scaleAdjust[2]) = 0;
GrRecordingContext* fContext;
const GrImageInfo fImageInfo;

View File

@ -918,13 +918,15 @@ void SkGpuDevice::drawBitmapTile(const SkBitmap& bitmap,
bitmap.height() <= this->caps()->maxTileSize());
SkASSERT(!samplerState.isRepeated());
GrSurfaceProxyView view = GrRefCachedBitmapView(fContext.get(), bitmap, samplerState);
SkScalar scales[2] = {1.f, 1.f};
GrSurfaceProxyView view = GrRefCachedBitmapView(fContext.get(), bitmap, samplerState, scales);
if (!view) {
return;
}
// Compute a matrix that maps the rect we will draw to the src rect.
SkMatrix texMatrix = SkMatrix::MakeRectToRect(dstRect, srcRect, SkMatrix::kFill_ScaleToFit);
texMatrix.postScale(scales[0], scales[1]);
SkAlphaType srcAlphaType = bitmap.alphaType();
@ -1050,7 +1052,7 @@ void SkGpuDevice::drawSpecial(SkSpecialImage* special, int left, int top, const
auto filter = paint.getFilterQuality() > kNone_SkFilterQuality
? GrSamplerState::Filter::kBilerp
: GrSamplerState::Filter::kNearest;
GrSurfaceProxyView clipView = as_IB(clipImage)->refView(this->context(), filter);
GrSurfaceProxyView clipView = as_IB(clipImage)->refView(this->context(), filter, nullptr);
// Fold clip matrix into ctm
ctm.preConcat(clipMatrix);
SkMatrix inverseClipMatrix;
@ -1343,7 +1345,7 @@ void SkGpuDevice::drawProducerLattice(GrTextureProducer* producer,
auto dstColorSpace = fRenderTargetContext->colorInfo().colorSpace();
const GrSamplerState::Filter filter = compute_lattice_filter_mode(*paint);
auto view = producer->viewForParams(&filter);
auto view = producer->viewForParams(&filter, nullptr);
if (!view) {
return;
}

View File

@ -537,7 +537,7 @@ void SkGpuDevice::drawEdgeAAImageSet(const SkCanvas::ImageSetEntry set[], int co
uint32_t uniqueID;
view = image->refPinnedView(this->context(), &uniqueID);
if (!view) {
view = image->refView(this->context(), GrSamplerState::Filter::kBilerp);
view = image->refView(this->context(), GrSamplerState::Filter::kBilerp, nullptr);
}
}

View File

@ -134,9 +134,9 @@ GrSurfaceProxyView GrCopyBaseMipMapToTextureProxy(GrRecordingContext* ctx,
}
GrSurfaceProxyView GrRefCachedBitmapView(GrRecordingContext* ctx, const SkBitmap& bitmap,
GrSamplerState params) {
GrSamplerState params, SkScalar scaleAdjust[2]) {
GrBitmapTextureMaker maker(ctx, bitmap, GrBitmapTextureMaker::Cached::kYes);
return maker.viewForParams(params);
return maker.viewForParams(params, scaleAdjust);
}
GrSurfaceProxyView GrMakeCachedBitmapProxyView(GrRecordingContext* context, const SkBitmap& bitmap,

View File

@ -163,12 +163,15 @@ static_assert((int)kIDA_GrBlendCoeff == (int)SkBlendModeCoeff::kIDA);
////////////////////////////////////////////////////////////////////////////////
// Texture management
/**
* Returns a view that wraps a texture representing the bitmap that is compatible with the
/** Returns a view that wraps a texture representing the bitmap that is compatible with the
* GrSamplerState. The texture is inserted into the cache (unless the bitmap is marked volatile)
* and can be retrieved again via this function.
* The 'scaleAdjust' in/out parameter will be updated to hold any rescaling that needs to be
* performed on the absolute texture coordinates (e.g., if the texture is resized out to
* the next power of two). It can be null if the caller is sure the bitmap won't be resized.
*/
GrSurfaceProxyView GrRefCachedBitmapView(GrRecordingContext*, const SkBitmap&, GrSamplerState);
GrSurfaceProxyView GrRefCachedBitmapView(GrRecordingContext*, const SkBitmap&, GrSamplerState,
SkScalar scaleAdjust[2]);
/**
* Creates a new texture with mipmap levels and copies the baseProxy into the base layer.

View File

@ -64,7 +64,8 @@ public:
// this call will flatten a SkImage_GpuYUV to a single texture.
virtual const GrSurfaceProxyView* view(GrRecordingContext*) const { return nullptr; }
virtual GrSurfaceProxyView refView(GrRecordingContext*, GrSamplerState) const = 0;
virtual GrSurfaceProxyView refView(GrRecordingContext*, GrSamplerState,
SkScalar scaleAdjust[2]) const = 0;
virtual GrSurfaceProxyView refPinnedView(GrRecordingContext*, uint32_t* uniqueID) const {
return {};
}

View File

@ -186,8 +186,8 @@ bool SkImage_GpuBase::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels,
return sContext->readPixels(dstInfo, dstPixels, dstRB, {srcX, srcY});
}
GrSurfaceProxyView SkImage_GpuBase::refView(GrRecordingContext* context,
GrSamplerState params) const {
GrSurfaceProxyView SkImage_GpuBase::refView(GrRecordingContext* context, GrSamplerState params,
SkScalar scaleAdjust[2]) const {
if (!context || !fContext->priv().matches(context)) {
SkASSERT(0);
return {};
@ -195,7 +195,7 @@ GrSurfaceProxyView SkImage_GpuBase::refView(GrRecordingContext* context,
GrTextureAdjuster adjuster(fContext.get(), *this->view(context), this->imageInfo().colorInfo(),
this->uniqueID());
return adjuster.viewForParams(params);
return adjuster.viewForParams(params, scaleAdjust);
}
GrBackendTexture SkImage_GpuBase::onGetBackendTexture(bool flushPendingGrContextIO,

View File

@ -28,7 +28,8 @@ public:
bool onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
int srcX, int srcY, CachingHint) const override;
GrSurfaceProxyView refView(GrRecordingContext*, GrSamplerState) const final;
GrSurfaceProxyView refView(GrRecordingContext*, GrSamplerState,
SkScalar scaleAdjust[2]) const final;
GrSurfaceProxyView refPinnedView(GrRecordingContext* context, uint32_t* uniqueID) const final {
*uniqueID = this->uniqueID();

View File

@ -92,11 +92,13 @@ bool SkImage_GpuYUVA::setupMipmapsForPlanes(GrRecordingContext* context) const {
}
for (int i = 0; i < fNumViews; ++i) {
GrTextureProducer::CopyParams copyParams;
int mipCount = SkMipMap::ComputeLevelCount(fViews[i].proxy()->width(),
fViews[i].proxy()->height());
if (mipCount && GrGpu::IsACopyNeededForMips(fContext->priv().caps(),
fViews[i].asTextureProxy(),
GrSamplerState::Filter::kMipMap)) {
GrSamplerState::Filter::kMipMap,
&copyParams)) {
auto mippedView = GrCopyBaseMipMapToTextureProxy(context, fViews[i].asTextureProxy(),
fOrigin, fProxyColorTypes[i]);
if (!mippedView.proxy()) {

View File

@ -238,13 +238,14 @@ bool SkImage_Lazy::onIsValid(GrContext* context) const {
///////////////////////////////////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
GrSurfaceProxyView SkImage_Lazy::refView(GrRecordingContext* context, GrSamplerState params) const {
GrSurfaceProxyView SkImage_Lazy::refView(GrRecordingContext* context, GrSamplerState params,
SkScalar scaleAdjust[2]) const {
if (!context) {
return {};
}
GrImageTextureMaker textureMaker(context, this, kAllow_CachingHint);
return textureMaker.viewForParams(params);
return textureMaker.viewForParams(params, scaleAdjust);
}
#endif

View File

@ -42,7 +42,8 @@ public:
bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY,
CachingHint) const override;
#if SK_SUPPORT_GPU
GrSurfaceProxyView refView(GrRecordingContext*, GrSamplerState) const override;
GrSurfaceProxyView refView(GrRecordingContext*, GrSamplerState,
SkScalar scaleAdjust[2]) const override;
sk_sp<SkCachedData> getPlanes(SkYUVASizeInfo*, SkYUVAIndex[4],
SkYUVColorSpace*, const void* planes[4]) override;
#endif

View File

@ -85,7 +85,8 @@ public:
const SkBitmap* onPeekBitmap() const override { return &fBitmap; }
#if SK_SUPPORT_GPU
GrSurfaceProxyView refView(GrRecordingContext*, GrSamplerState) const override;
GrSurfaceProxyView refView(GrRecordingContext*, GrSamplerState,
SkScalar scaleAdjust[2]) const override;
#endif
bool getROPixels(SkBitmap*, CachingHint) const override;
@ -173,8 +174,8 @@ bool SkImage_Raster::getROPixels(SkBitmap* dst, CachingHint) const {
}
#if SK_SUPPORT_GPU
GrSurfaceProxyView SkImage_Raster::refView(GrRecordingContext* context,
GrSamplerState params) const {
GrSurfaceProxyView SkImage_Raster::refView(GrRecordingContext* context, GrSamplerState params,
SkScalar scaleAdjust[2]) const {
if (!context) {
return {};
}
@ -183,10 +184,10 @@ GrSurfaceProxyView SkImage_Raster::refView(GrRecordingContext* context,
if (GrSurfaceProxyView view = this->refPinnedView(context, &uniqueID)) {
GrTextureAdjuster adjuster(context, std::move(view), fBitmap.info().colorInfo(),
fPinnedUniqueID);
return adjuster.viewForParams(params);
return adjuster.viewForParams(params, scaleAdjust);
}
return GrRefCachedBitmapView(context, fBitmap, params);
return GrRefCachedBitmapView(context, fBitmap, params, scaleAdjust);
}
#endif
@ -209,7 +210,8 @@ bool SkImage_Raster::onPinAsTexture(GrContext* ctx) const {
} else {
SkASSERT(fPinnedCount == 0);
SkASSERT(fPinnedUniqueID == 0);
fPinnedView = GrRefCachedBitmapView(ctx, fBitmap, GrSamplerState::Filter::kNearest);
fPinnedView =
GrRefCachedBitmapView(ctx, fBitmap, GrSamplerState::Filter::kNearest, nullptr);
if (!fPinnedView) {
return false;
}

View File

@ -213,13 +213,16 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor(
fImage->width(), fImage->height(), args.fFilterQuality, *args.fViewMatrix, *lm,
args.fContext->priv().options().fSharpenMipmappedTextures, &doBicubic);
GrSamplerState samplerState(wm, textureFilterMode);
GrSurfaceProxyView view = as_IB(fImage)->refView(args.fContext, samplerState);
SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
GrSurfaceProxyView view = as_IB(fImage)->refView(args.fContext, samplerState, scaleAdjust);
if (!view) {
return nullptr;
}
SkAlphaType srcAlphaType = fImage->alphaType();
lmInverse.postScale(scaleAdjust[0], scaleAdjust[1]);
const auto& caps = *args.fContext->priv().caps();
std::unique_ptr<GrFragmentProcessor> inner;

View File

@ -970,19 +970,20 @@ static void test_cross_context_image(skiatest::Reporter* reporter, const GrConte
sk_sp<SkImage> refImg(imageMaker(ctx));
// Any context should be able to borrow the texture at this point
GrSurfaceProxyView view = as_IB(refImg)->refView(ctx, GrSamplerState::Filter::kNearest);
GrSurfaceProxyView view =
as_IB(refImg)->refView(ctx, GrSamplerState::Filter::kNearest, nullptr);
REPORTER_ASSERT(reporter, view);
// But once it's borrowed, no other context should be able to borrow
otherTestContext->makeCurrent();
GrSurfaceProxyView otherView =
as_IB(refImg)->refView(otherCtx, GrSamplerState::Filter::kNearest);
as_IB(refImg)->refView(otherCtx, GrSamplerState::Filter::kNearest, nullptr);
REPORTER_ASSERT(reporter, !otherView);
// Original context (that's already borrowing) should be okay
testContext->makeCurrent();
GrSurfaceProxyView viewSecondRef =
as_IB(refImg)->refView(ctx, GrSamplerState::Filter::kNearest);
as_IB(refImg)->refView(ctx, GrSamplerState::Filter::kNearest, nullptr);
REPORTER_ASSERT(reporter, viewSecondRef);
// Release first ref from the original context
@ -991,7 +992,7 @@ static void test_cross_context_image(skiatest::Reporter* reporter, const GrConte
// We released one proxy but not the other from the current borrowing context. Make sure
// a new context is still not able to borrow the texture.
otherTestContext->makeCurrent();
otherView = as_IB(refImg)->refView(otherCtx, GrSamplerState::Filter::kNearest);
otherView = as_IB(refImg)->refView(otherCtx, GrSamplerState::Filter::kNearest, nullptr);
REPORTER_ASSERT(reporter, !otherView);
// Release second ref from the original context
@ -1000,7 +1001,7 @@ static void test_cross_context_image(skiatest::Reporter* reporter, const GrConte
// Now we should be able to borrow the texture from the other context
otherTestContext->makeCurrent();
otherView = as_IB(refImg)->refView(otherCtx, GrSamplerState::Filter::kNearest);
otherView = as_IB(refImg)->refView(otherCtx, GrSamplerState::Filter::kNearest, nullptr);
REPORTER_ASSERT(reporter, otherView);
// Release everything
@ -1041,7 +1042,8 @@ DEF_GPUTEST(SkImage_CrossContextGrayAlphaConfigs, reporter, options) {
sk_sp<SkImage> image = SkImage::MakeCrossContextFromPixmap(ctx, pixmap, false);
REPORTER_ASSERT(reporter, image);
GrSurfaceProxyView view = as_IB(image)->refView(ctx, GrSamplerState::Filter::kNearest);
GrSurfaceProxyView view =
as_IB(image)->refView(ctx, GrSamplerState::Filter::kNearest, nullptr);
REPORTER_ASSERT(reporter, view);
bool expectAlpha = kAlpha_8_SkColorType == ct;