1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "GrTextureMaker.h" 9 10 #include "GrContext.h" 11 #include "GrGpu.h" 12 #include "GrResourceProvider.h" 13 14 sk_sp<GrTextureProxy> GrTextureMaker::refTextureProxyForParams(const GrSamplerParams& params, 15 SkColorSpace* dstColorSpace, 16 sk_sp<SkColorSpace>* texColorSpace, 17 SkScalar scaleAdjust[2]) { 18 CopyParams copyParams; 19 bool willBeMipped = params.filterMode() == GrSamplerParams::kMipMap_FilterMode; 20 21 if (!fContext->caps()->mipMapSupport()) { 22 willBeMipped = false; 23 } 24 25 if (texColorSpace) { 26 *texColorSpace = this->getColorSpace(dstColorSpace); 27 } 28 29 sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace, 30 AllowedTexGenType::kCheap)); 31 if (original) { 32 if (!fContext->getGpu()->isACopyNeededForTextureParams(original.get(), params, ©Params, 33 scaleAdjust)) { 34 return original; 35 } 36 } else { 37 if (!fContext->getGpu()->isACopyNeededForTextureParams(this->width(), this->height(), 38 params, ©Params, scaleAdjust)) { 39 return this->refOriginalTextureProxy(willBeMipped, dstColorSpace, 40 AllowedTexGenType::kAny); 41 } 42 } 43 44 GrUniqueKey copyKey; 45 this->makeCopyKey(copyParams, ©Key, dstColorSpace); 46 if (copyKey.isValid()) { 47 sk_sp<GrTextureProxy> result(fContext->resourceProvider()->findProxyByUniqueKey(copyKey)); 48 if (result) { 49 return result; 50 } 51 } 52 53 sk_sp<GrTextureProxy> result; 54 if (original) { 55 result = CopyOnGpu(fContext, std::move(original), nullptr, copyParams); 56 } else { 57 result = this->generateTextureProxyForParams(copyParams, willBeMipped, dstColorSpace); 58 } 59 60 if (!result) { 61 return nullptr; 62 } 63 64 if (copyKey.isValid()) { 65 fContext->resourceProvider()->assignUniqueKeyToProxy(copyKey, result.get()); 66 this->didCacheCopy(copyKey); 67 } 68 return result; 69 } 70 71 sk_sp<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor( 72 const SkMatrix& textureMatrix, 73 const SkRect& constraintRect, 74 FilterConstraint filterConstraint, 75 bool coordsLimitedToConstraintRect, 76 const GrSamplerParams::FilterMode* filterOrNullForBicubic, 77 SkColorSpace* dstColorSpace) { 78 79 const GrSamplerParams::FilterMode* fmForDetermineDomain = filterOrNullForBicubic; 80 if (filterOrNullForBicubic && GrSamplerParams::kMipMap_FilterMode == *filterOrNullForBicubic && 81 kYes_FilterConstraint == filterConstraint) { 82 // TODo: Here we should force a copy restricted to the constraintRect since MIP maps will 83 // read outside the constraint rect. However, as in the adjuster case, we aren't currently 84 // doing that. 85 // We instead we compute the domain as though were bilerping which is only correct if we 86 // only sample level 0. 87 static const GrSamplerParams::FilterMode kBilerp = GrSamplerParams::kBilerp_FilterMode; 88 fmForDetermineDomain = &kBilerp; 89 } 90 91 GrSamplerParams params; 92 if (filterOrNullForBicubic) { 93 params.reset(SkShader::kClamp_TileMode, *filterOrNullForBicubic); 94 } else { 95 // Bicubic doesn't use filtering for it's texture accesses. 96 params.reset(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode); 97 } 98 sk_sp<SkColorSpace> texColorSpace; 99 SkScalar scaleAdjust[2] = { 1.0f, 1.0f }; 100 sk_sp<GrTextureProxy> proxy(this->refTextureProxyForParams(params, dstColorSpace, 101 &texColorSpace, 102 scaleAdjust)); 103 if (!proxy) { 104 return nullptr; 105 } 106 SkMatrix adjustedMatrix = textureMatrix; 107 adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]); 108 SkRect domain; 109 DomainMode domainMode = 110 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect, 111 proxy.get(), 112 nullptr, fmForDetermineDomain, &domain); 113 SkASSERT(kTightCopy_DomainMode != domainMode); 114 sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(), 115 dstColorSpace); 116 return CreateFragmentProcessorForDomainAndFilter(std::move(proxy), 117 std::move(colorSpaceXform), 118 adjustedMatrix, domainMode, domain, 119 filterOrNullForBicubic); 120 } 121 122 sk_sp<GrTextureProxy> GrTextureMaker::generateTextureProxyForParams(const CopyParams& copyParams, 123 bool willBeMipped, 124 SkColorSpace* dstColorSpace) { 125 sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace, 126 AllowedTexGenType::kAny)); 127 if (!original) { 128 return nullptr; 129 } 130 131 return CopyOnGpu(fContext, std::move(original), nullptr, copyParams); 132 } 133