Skip to content

Commit

Permalink
Revert "Remove copies for wrap modes in GrTextureProducer."
Browse files Browse the repository at this point in the history
This reverts commit 7fba244.

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>
  • Loading branch information
rphilli authored and Skia Commit-Bot committed Feb 21, 2020
1 parent 3928466 commit bf5cb0f
Show file tree
Hide file tree
Showing 26 changed files with 371 additions and 168 deletions.
4 changes: 2 additions & 2 deletions gm/image_pict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,8 @@ class ImageCacheratorGM : public skiagm::GM {
}

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;
Expand Down
9 changes: 4 additions & 5 deletions src/gpu/GrBitmapTextureMaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
4 changes: 2 additions & 2 deletions src/gpu/GrBitmapTextureMaker.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class GrBitmapTextureMaker : public GrTextureMaker {
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;
Expand Down
57 changes: 52 additions & 5 deletions src/gpu/GrGpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,61 @@ void GrGpu::disconnect(DisconnectType) {}

////////////////////////////////////////////////////////////////////////////////

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;
}

bool GrGpu::IsACopyNeededForMips(const GrCaps* caps, const GrTextureProxy* texProxy,
GrSamplerState::Filter filter) {
GrSamplerState::Filter filter,
GrTextureProducer::CopyParams* copyParams) {
SkASSERT(texProxy);
if (filter != GrSamplerState::Filter::kMipMap || texProxy->mipMapped() == GrMipMapped::kYes ||
!caps->mipMapSupport()) {
return false;
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 SkMipMap::ComputeLevelCount(texProxy->width(), texProxy->height()) > 0;

return false;
}

static bool validate_texel_levels(SkISize dimensions, GrColorType texelColorType,
Expand Down
12 changes: 11 additions & 1 deletion src/gpu/GrGpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -594,12 +594,22 @@ class GrGpu : public SkRefCnt {
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) {
Expand Down
9 changes: 5 additions & 4 deletions src/gpu/GrImageTextureMaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
}

Expand Down
13 changes: 7 additions & 6 deletions src/gpu/GrImageTextureMaker.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ class GrImageTextureMaker : public GrTextureMaker {
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;
Expand All @@ -51,9 +53,8 @@ class GrYUVAImageTextureMaker : public GrTextureMaker {
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,
Expand Down
89 changes: 63 additions & 26 deletions src/gpu/GrTextureAdjuster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 (key.isValid()) {
SkASSERT(copyView.origin() == originalView.origin());
proxyProvider->assignUniqueKeyToProxy(key, copyView.asTextureProxy());
this->didCacheMipMappedCopy(key, proxyProvider->contextID());
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->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 {};
Expand All @@ -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())) {
return view;
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 =
Expand Down
9 changes: 5 additions & 4 deletions src/gpu/GrTextureAdjuster.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,17 @@ class GrTextureAdjuster : public GrTextureProducer {
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;
Expand Down
Loading

0 comments on commit bf5cb0f

Please sign in to comment.