/* * 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 "GrTextureMaker.h" #include "GrContext.h" #include "GrGpu.h" #include "GrResourceProvider.h" sk_sp GrTextureMaker::refTextureProxyForParams(const GrSamplerParams& params, SkColorSpace* dstColorSpace, sk_sp* texColorSpace, SkScalar scaleAdjust[2]) { CopyParams copyParams; bool willBeMipped = params.filterMode() == GrSamplerParams::kMipMap_FilterMode; if (!fContext->caps()->mipMapSupport()) { willBeMipped = false; } if (texColorSpace) { *texColorSpace = this->getColorSpace(dstColorSpace); } if (!fContext->getGpu()->isACopyNeededForTextureParams(this->width(), this->height(), params, ©Params, scaleAdjust)) { return this->refOriginalTextureProxy(willBeMipped, dstColorSpace); } GrUniqueKey copyKey; this->makeCopyKey(copyParams, ©Key, dstColorSpace); if (copyKey.isValid()) { sk_sp result(fContext->resourceProvider()->findProxyByUniqueKey(copyKey)); if (result) { return result; } } sk_sp result(this->generateTextureProxyForParams(copyParams, willBeMipped, dstColorSpace)); if (!result) { return nullptr; } if (copyKey.isValid()) { fContext->resourceProvider()->assignUniqueKeyToProxy(copyKey, result.get()); this->didCacheCopy(copyKey); } return result; } sk_sp GrTextureMaker::createFragmentProcessor( const SkMatrix& textureMatrix, const SkRect& constraintRect, FilterConstraint filterConstraint, bool coordsLimitedToConstraintRect, const GrSamplerParams::FilterMode* filterOrNullForBicubic, SkColorSpace* dstColorSpace) { const GrSamplerParams::FilterMode* fmForDetermineDomain = filterOrNullForBicubic; if (filterOrNullForBicubic && GrSamplerParams::kMipMap_FilterMode == *filterOrNullForBicubic && kYes_FilterConstraint == filterConstraint) { // TODo: Here we should force a copy restricted to the constraintRect since MIP maps will // read outside the constraint rect. However, as in the adjuster case, we aren't currently // doing that. // We instead we compute the domain as though were bilerping which is only correct if we // only sample level 0. static const GrSamplerParams::FilterMode kBilerp = GrSamplerParams::kBilerp_FilterMode; fmForDetermineDomain = &kBilerp; } GrSamplerParams params; if (filterOrNullForBicubic) { params.reset(SkShader::kClamp_TileMode, *filterOrNullForBicubic); } else { // Bicubic doesn't use filtering for it's texture accesses. params.reset(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode); } sk_sp texColorSpace; SkScalar scaleAdjust[2] = { 1.0f, 1.0f }; sk_sp proxy(this->refTextureProxyForParams(params, dstColorSpace, &texColorSpace, scaleAdjust)); if (!proxy) { return nullptr; } SkMatrix adjustedMatrix = textureMatrix; adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]); SkRect domain; DomainMode domainMode = DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect, proxy.get(), nullptr, fmForDetermineDomain, &domain); SkASSERT(kTightCopy_DomainMode != domainMode); sk_sp colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(), dstColorSpace); return CreateFragmentProcessorForDomainAndFilter(fContext->resourceProvider(), std::move(proxy), std::move(colorSpaceXform), adjustedMatrix, domainMode, domain, filterOrNullForBicubic); } sk_sp GrTextureMaker::generateTextureProxyForParams(const CopyParams& copyParams, bool willBeMipped, SkColorSpace* dstColorSpace) { sk_sp original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace)); if (!original) { return nullptr; } return CopyOnGpu(fContext, std::move(original), nullptr, copyParams); }