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