const GrFragmentProcessor* GrTextureAdjuster::createFragmentProcessor( const SkMatrix& origTextureMatrix, const SkRect& origConstraintRect, FilterConstraint filterConstraint, bool coordsLimitedToConstraintRect, const GrTextureParams::FilterMode* filterOrNullForBicubic) { 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; GrTextureParams params; if (filterOrNullForBicubic) { params.setFilterMode(*filterOrNullForBicubic); } SkAutoTUnref<GrTexture> texture(this->refTextureSafeForParams(params, 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 != this->originalTexture()) { contentArea = nullptr; } DomainMode domainMode = determine_domain_mode(*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 && GrTextureParams::kMipMap_FilterMode == *filterOrNullForBicubic); static const GrTextureParams::FilterMode kBilerp = GrTextureParams::kBilerp_FilterMode; domainMode = determine_domain_mode(*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()); return create_fp_for_domain_and_filter(texture, textureMatrix, domainMode, domain, filterOrNullForBicubic); }
sk_sp<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor( const SkMatrix& textureMatrix, const SkRect& constraintRect, FilterConstraint filterConstraint, bool coordsLimitedToConstraintRect, const GrTextureParams::FilterMode* filterOrNullForBicubic, SkColorSpace* dstColorSpace, SkSourceGammaTreatment gammaTreatment) { const GrTextureParams::FilterMode* fmForDetermineDomain = filterOrNullForBicubic; if (filterOrNullForBicubic && GrTextureParams::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 GrTextureParams::FilterMode kBilerp = GrTextureParams::kBilerp_FilterMode; fmForDetermineDomain = &kBilerp; } GrTextureParams 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, GrTextureParams::kNone_FilterMode); } SkAutoTUnref<GrTexture> texture(this->refTextureForParams(params, gammaTreatment)); if (!texture) { return nullptr; } SkRect domain; DomainMode domainMode = determine_domain_mode(constraintRect, filterConstraint, coordsLimitedToConstraintRect, texture->width(), texture->height(), nullptr, fmForDetermineDomain, &domain); SkASSERT(kTightCopy_DomainMode != domainMode); SkMatrix normalizedTextureMatrix = textureMatrix; normalizedTextureMatrix.postIDiv(texture->width(), texture->height()); sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(this->getColorSpace(), dstColorSpace); return create_fp_for_domain_and_filter(texture, std::move(colorSpaceXform), normalizedTextureMatrix, domainMode, domain, filterOrNullForBicubic); }
uint16_t GrVkSampler::GenerateKey(const GrTextureParams& params, uint32_t mipLevels) { const int kTileModeXShift = 2; const int kTileModeYShift = 4; const int kMipLevelShift = 6; uint16_t key = params.filterMode(); SkASSERT(params.filterMode() <= 3); key |= (params.getTileModeX() << kTileModeXShift); GR_STATIC_ASSERT(SkShader::kTileModeCount <= 4); key |= (params.getTileModeY() << kTileModeYShift); SkASSERT(mipLevels < 1024); key |= (mipLevels << kMipLevelShift); return key; }
GrSingleTextureEffect::GrSingleTextureEffect(GrProcessorDataManager* procDataManager, GrTexture* texture, const SkMatrix& m, const GrTextureParams& params, GrCoordSet coordSet) : fCoordTransform(coordSet, m, texture, params.filterMode()) , fTextureAccess(texture, params) { this->addCoordTransform(&fCoordTransform); this->addTextureAccess(&fTextureAccess); }
bool GrGpu::makeCopyForTextureParams(int width, int height, const GrTextureParams& textureParams, GrTextureProducer::CopyParams* copyParams) const { const GrCaps& caps = *this->caps(); if (textureParams.isTiled() && !caps.npotTextureTileSupport() && (!SkIsPow2(width) || !SkIsPow2(height))) { copyParams->fWidth = GrNextPow2(width); copyParams->fHeight = GrNextPow2(height); switch (textureParams.filterMode()) { case GrTextureParams::kNone_FilterMode: copyParams->fFilter = GrTextureParams::kNone_FilterMode; break; case GrTextureParams::kBilerp_FilterMode: case GrTextureParams::kMipMap_FilterMode: // We are only ever scaling up so no reason to ever indicate kMipMap. copyParams->fFilter = GrTextureParams::kBilerp_FilterMode; break; } return true; } return false; }