diff options
author | Brian Osman <brianosman@google.com> | 2016-11-28 10:06:27 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-11-28 15:44:40 +0000 |
commit | e8e54580c3c91fd485187af040af118aa5153261 (patch) | |
tree | 27d67ccb3500d300ba40e52bef56c05b095999df /src/gpu/GrTextureAdjuster.cpp | |
parent | e9f78b41c65a78400c22a1b79007b1b9e187a745 (diff) |
GrTextureProducer cleanup, phase two: Producer, Adjuster, Maker
Previously: GrTextureProducer, GrTextureAdjuster, and GrTextureMaker
were all in GrTextureParamsAdjuster.h. Now they're each in their own
header.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5202
Change-Id: I17fa9057b11511aa4d3e15569ea1c378cfec4c80
Reviewed-on: https://skia-review.googlesource.com/5202
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src/gpu/GrTextureAdjuster.cpp')
-rw-r--r-- | src/gpu/GrTextureAdjuster.cpp | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/src/gpu/GrTextureAdjuster.cpp b/src/gpu/GrTextureAdjuster.cpp new file mode 100644 index 0000000000..24d050a1ed --- /dev/null +++ b/src/gpu/GrTextureAdjuster.cpp @@ -0,0 +1,167 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrTextureAdjuster.h" + +#include "GrContext.h" +#include "GrGpu.h" +#include "GrGpuResourcePriv.h" +#include "GrTexture.h" +#include "SkGrPriv.h" + +GrTextureAdjuster::GrTextureAdjuster(GrTexture* original, SkAlphaType alphaType, + const SkIRect& contentArea, uint32_t uniqueID, + SkColorSpace* cs) + : INHERITED(contentArea.width(), contentArea.height(), + GrPixelConfigIsAlphaOnly(original->config())) + , fOriginal(original) + , fAlphaType(alphaType) + , fColorSpace(cs) + , fUniqueID(uniqueID) { + SkASSERT(SkIRect::MakeWH(original->width(), original->height()).contains(contentArea)); + if (contentArea.fLeft > 0 || contentArea.fTop > 0 || + contentArea.fRight < original->width() || contentArea.fBottom < original->height()) { + fContentArea.set(contentArea); + } +} + +void GrTextureAdjuster::makeCopyKey(const CopyParams& params, GrUniqueKey* copyKey, + SkDestinationSurfaceColorMode) { + // Color mode is irrelevant in this case - we already have a texture so we're just sub-setting + GrUniqueKey baseKey; + GrMakeKeyFromImageID(&baseKey, fUniqueID, SkIRect::MakeWH(this->width(), this->height())); + MakeCopyKeyFromOrigKey(baseKey, params, copyKey); +} + +void GrTextureAdjuster::didCacheCopy(const GrUniqueKey& copyKey) { + // We don't currently have a mechanism for notifications on Images! +} + +GrTexture* GrTextureAdjuster::refCopy(const CopyParams& copyParams) { + GrTexture* texture = this->originalTexture(); + GrContext* context = texture->getContext(); + const SkIRect* contentArea = this->contentAreaOrNull(); + GrUniqueKey key; + this->makeCopyKey(copyParams, &key, SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware); + if (key.isValid()) { + GrTexture* cachedCopy = context->textureProvider()->findAndRefTextureByUniqueKey(key); + if (cachedCopy) { + return cachedCopy; + } + } + GrTexture* copy = CopyOnGpu(texture, contentArea, copyParams); + if (copy) { + if (key.isValid()) { + copy->resourcePriv().setUniqueKey(key); + this->didCacheCopy(key); + } + } + return copy; +} + +GrTexture* GrTextureAdjuster::refTextureSafeForParams(const GrSamplerParams& params, + SkDestinationSurfaceColorMode colorMode, + SkIPoint* outOffset) { + GrTexture* texture = this->originalTexture(); + GrContext* context = texture->getContext(); + CopyParams copyParams; + const SkIRect* contentArea = this->contentAreaOrNull(); + + if (!context) { + // The texture was abandoned. + return nullptr; + } + + 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 (!context->getGpu()->makeCopyForTextureParams(texture, params, ©Params)) { + if (outOffset) { + if (contentArea) { + outOffset->set(contentArea->fLeft, contentArea->fRight); + } else { + outOffset->set(0, 0); + } + } + return SkRef(texture); + } + + GrTexture* copy = this->refCopy(copyParams); + if (copy && outOffset) { + outOffset->set(0, 0); + } + return copy; +} + +sk_sp<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor( + const SkMatrix& origTextureMatrix, + const SkRect& origConstraintRect, + FilterConstraint filterConstraint, + bool coordsLimitedToConstraintRect, + const GrSamplerParams::FilterMode* filterOrNullForBicubic, + SkColorSpace* dstColorSpace, + SkDestinationSurfaceColorMode colorMode) { + + 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; + if (filterOrNullForBicubic) { + params.setFilterMode(*filterOrNullForBicubic); + } + sk_sp<GrTexture> texture(this->refTextureSafeForParams(params, colorMode, nullptr)); + if (!texture) { + return nullptr; + } + // If we made a copy then we only copied the contentArea, in which case the new texture is all + // content. + if (texture.get() != this->originalTexture()) { + contentArea = nullptr; + } + + DomainMode domainMode = + DetermineDomainMode(*constraintRect, filterConstraint, coordsLimitedToConstraintRect, + texture->width(), texture->height(), + 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) + // For now: treat as bilerp and ignore what goes on above level 0. + + // We only expect MIP maps to require a tight copy. + SkASSERT(filterOrNullForBicubic && + GrSamplerParams::kMipMap_FilterMode == *filterOrNullForBicubic); + static const GrSamplerParams::FilterMode kBilerp = GrSamplerParams::kBilerp_FilterMode; + domainMode = + DetermineDomainMode(*constraintRect, filterConstraint, coordsLimitedToConstraintRect, + texture->width(), texture->height(), + contentArea, &kBilerp, &domain); + SkASSERT(kTightCopy_DomainMode != domainMode); + } + SkASSERT(kNoDomain_DomainMode == domainMode || + (domain.fLeft <= domain.fRight && domain.fTop <= domain.fBottom)); + textureMatrix.postIDiv(texture->width(), texture->height()); + sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(fColorSpace, + dstColorSpace); + return CreateFragmentProcessorForDomainAndFilter(texture.get(), std::move(colorSpaceXform), + textureMatrix, domainMode, domain, + filterOrNullForBicubic); +} |