1e8e54580c3c91fd485187af040af118aa5153261Brian Osman/* 2e8e54580c3c91fd485187af040af118aa5153261Brian Osman * Copyright 2016 Google Inc. 3e8e54580c3c91fd485187af040af118aa5153261Brian Osman * 4e8e54580c3c91fd485187af040af118aa5153261Brian Osman * Use of this source code is governed by a BSD-style license that can be 5e8e54580c3c91fd485187af040af118aa5153261Brian Osman * found in the LICENSE file. 6e8e54580c3c91fd485187af040af118aa5153261Brian Osman */ 7e8e54580c3c91fd485187af040af118aa5153261Brian Osman 8e8e54580c3c91fd485187af040af118aa5153261Brian Osman#include "GrTextureMaker.h" 9e8e54580c3c91fd485187af040af118aa5153261Brian Osman 10e8e54580c3c91fd485187af040af118aa5153261Brian Osman#include "GrContext.h" 11e8e54580c3c91fd485187af040af118aa5153261Brian Osman#include "GrGpu.h" 1232342f032e1dfd133040324f851f0365f9d4cb51Brian Osman#include "GrResourceProvider.h" 13e8e54580c3c91fd485187af040af118aa5153261Brian Osman 143798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillipssk_sp<GrTextureProxy> GrTextureMaker::refTextureProxyForParams(const GrSamplerParams& params, 153798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips SkColorSpace* dstColorSpace, 163798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips sk_sp<SkColorSpace>* texColorSpace, 173798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips SkScalar scaleAdjust[2]) { 18e8e54580c3c91fd485187af040af118aa5153261Brian Osman CopyParams copyParams; 19e8e54580c3c91fd485187af040af118aa5153261Brian Osman bool willBeMipped = params.filterMode() == GrSamplerParams::kMipMap_FilterMode; 20e8e54580c3c91fd485187af040af118aa5153261Brian Osman 21e8e54580c3c91fd485187af040af118aa5153261Brian Osman if (!fContext->caps()->mipMapSupport()) { 22e8e54580c3c91fd485187af040af118aa5153261Brian Osman willBeMipped = false; 23e8e54580c3c91fd485187af040af118aa5153261Brian Osman } 24e8e54580c3c91fd485187af040af118aa5153261Brian Osman 25e8e54580c3c91fd485187af040af118aa5153261Brian Osman if (texColorSpace) { 2661624f0c716b576706659750d87b6956f4c15722Brian Osman *texColorSpace = this->getColorSpace(dstColorSpace); 27e8e54580c3c91fd485187af040af118aa5153261Brian Osman } 28e8e54580c3c91fd485187af040af118aa5153261Brian Osman 2981444fbc22d09c92f6c577254c6c82dfa9967391Robert Phillips if (!fContext->getGpu()->isACopyNeededForTextureParams(this->width(), this->height(), params, 3081444fbc22d09c92f6c577254c6c82dfa9967391Robert Phillips ©Params, scaleAdjust)) { 313798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips return this->refOriginalTextureProxy(willBeMipped, dstColorSpace); 32e8e54580c3c91fd485187af040af118aa5153261Brian Osman } 33e8e54580c3c91fd485187af040af118aa5153261Brian Osman GrUniqueKey copyKey; 3461624f0c716b576706659750d87b6956f4c15722Brian Osman this->makeCopyKey(copyParams, ©Key, dstColorSpace); 35e8e54580c3c91fd485187af040af118aa5153261Brian Osman if (copyKey.isValid()) { 363798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips sk_sp<GrTextureProxy> result(fContext->resourceProvider()->findProxyByUniqueKey(copyKey)); 37e8e54580c3c91fd485187af040af118aa5153261Brian Osman if (result) { 38e8e54580c3c91fd485187af040af118aa5153261Brian Osman return result; 39e8e54580c3c91fd485187af040af118aa5153261Brian Osman } 40e8e54580c3c91fd485187af040af118aa5153261Brian Osman } 41e8e54580c3c91fd485187af040af118aa5153261Brian Osman 423798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips sk_sp<GrTextureProxy> result(this->generateTextureProxyForParams(copyParams, willBeMipped, 433798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips dstColorSpace)); 44e8e54580c3c91fd485187af040af118aa5153261Brian Osman if (!result) { 45e8e54580c3c91fd485187af040af118aa5153261Brian Osman return nullptr; 46e8e54580c3c91fd485187af040af118aa5153261Brian Osman } 47e8e54580c3c91fd485187af040af118aa5153261Brian Osman 48e8e54580c3c91fd485187af040af118aa5153261Brian Osman if (copyKey.isValid()) { 493798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips fContext->resourceProvider()->assignUniqueKeyToProxy(copyKey, result.get()); 50e8e54580c3c91fd485187af040af118aa5153261Brian Osman this->didCacheCopy(copyKey); 51e8e54580c3c91fd485187af040af118aa5153261Brian Osman } 52e8e54580c3c91fd485187af040af118aa5153261Brian Osman return result; 53e8e54580c3c91fd485187af040af118aa5153261Brian Osman} 54e8e54580c3c91fd485187af040af118aa5153261Brian Osman 55e8e54580c3c91fd485187af040af118aa5153261Brian Osmansk_sp<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor( 56e8e54580c3c91fd485187af040af118aa5153261Brian Osman const SkMatrix& textureMatrix, 57e8e54580c3c91fd485187af040af118aa5153261Brian Osman const SkRect& constraintRect, 58e8e54580c3c91fd485187af040af118aa5153261Brian Osman FilterConstraint filterConstraint, 59e8e54580c3c91fd485187af040af118aa5153261Brian Osman bool coordsLimitedToConstraintRect, 60e8e54580c3c91fd485187af040af118aa5153261Brian Osman const GrSamplerParams::FilterMode* filterOrNullForBicubic, 6161624f0c716b576706659750d87b6956f4c15722Brian Osman SkColorSpace* dstColorSpace) { 62e8e54580c3c91fd485187af040af118aa5153261Brian Osman 63e8e54580c3c91fd485187af040af118aa5153261Brian Osman const GrSamplerParams::FilterMode* fmForDetermineDomain = filterOrNullForBicubic; 64e8e54580c3c91fd485187af040af118aa5153261Brian Osman if (filterOrNullForBicubic && GrSamplerParams::kMipMap_FilterMode == *filterOrNullForBicubic && 65e8e54580c3c91fd485187af040af118aa5153261Brian Osman kYes_FilterConstraint == filterConstraint) { 66e8e54580c3c91fd485187af040af118aa5153261Brian Osman // TODo: Here we should force a copy restricted to the constraintRect since MIP maps will 67e8e54580c3c91fd485187af040af118aa5153261Brian Osman // read outside the constraint rect. However, as in the adjuster case, we aren't currently 68e8e54580c3c91fd485187af040af118aa5153261Brian Osman // doing that. 69e8e54580c3c91fd485187af040af118aa5153261Brian Osman // We instead we compute the domain as though were bilerping which is only correct if we 70e8e54580c3c91fd485187af040af118aa5153261Brian Osman // only sample level 0. 71e8e54580c3c91fd485187af040af118aa5153261Brian Osman static const GrSamplerParams::FilterMode kBilerp = GrSamplerParams::kBilerp_FilterMode; 72e8e54580c3c91fd485187af040af118aa5153261Brian Osman fmForDetermineDomain = &kBilerp; 73e8e54580c3c91fd485187af040af118aa5153261Brian Osman } 74e8e54580c3c91fd485187af040af118aa5153261Brian Osman 75e8e54580c3c91fd485187af040af118aa5153261Brian Osman GrSamplerParams params; 76e8e54580c3c91fd485187af040af118aa5153261Brian Osman if (filterOrNullForBicubic) { 77e8e54580c3c91fd485187af040af118aa5153261Brian Osman params.reset(SkShader::kClamp_TileMode, *filterOrNullForBicubic); 78e8e54580c3c91fd485187af040af118aa5153261Brian Osman } else { 79e8e54580c3c91fd485187af040af118aa5153261Brian Osman // Bicubic doesn't use filtering for it's texture accesses. 80e8e54580c3c91fd485187af040af118aa5153261Brian Osman params.reset(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode); 81e8e54580c3c91fd485187af040af118aa5153261Brian Osman } 82e8e54580c3c91fd485187af040af118aa5153261Brian Osman sk_sp<SkColorSpace> texColorSpace; 8367c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips SkScalar scaleAdjust[2] = { 1.0f, 1.0f }; 843798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips sk_sp<GrTextureProxy> proxy(this->refTextureProxyForParams(params, dstColorSpace, 853798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips &texColorSpace, 863798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips scaleAdjust)); 873798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips if (!proxy) { 88e8e54580c3c91fd485187af040af118aa5153261Brian Osman return nullptr; 89e8e54580c3c91fd485187af040af118aa5153261Brian Osman } 9067c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips SkMatrix adjustedMatrix = textureMatrix; 9167c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]); 92e8e54580c3c91fd485187af040af118aa5153261Brian Osman SkRect domain; 93e8e54580c3c91fd485187af040af118aa5153261Brian Osman DomainMode domainMode = 94e8e54580c3c91fd485187af040af118aa5153261Brian Osman DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect, 953798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips proxy.get(), 96e98234f231d66848e149db683c11b6388e10b233Robert Phillips nullptr, fmForDetermineDomain, &domain); 97e8e54580c3c91fd485187af040af118aa5153261Brian Osman SkASSERT(kTightCopy_DomainMode != domainMode); 98e8e54580c3c91fd485187af040af118aa5153261Brian Osman sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(), 99e8e54580c3c91fd485187af040af118aa5153261Brian Osman dstColorSpace); 1003798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips return CreateFragmentProcessorForDomainAndFilter(fContext->resourceProvider(), std::move(proxy), 1013798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips std::move(colorSpaceXform), 10267c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips adjustedMatrix, domainMode, domain, 103e8e54580c3c91fd485187af040af118aa5153261Brian Osman filterOrNullForBicubic); 104e8e54580c3c91fd485187af040af118aa5153261Brian Osman} 105e8e54580c3c91fd485187af040af118aa5153261Brian Osman 1063798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillipssk_sp<GrTextureProxy> GrTextureMaker::generateTextureProxyForParams(const CopyParams& copyParams, 1073798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips bool willBeMipped, 1083798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips SkColorSpace* dstColorSpace) { 1094f358be6b72cca97856b3f59d83448650d359d93Robert Phillips sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace)); 110e8e54580c3c91fd485187af040af118aa5153261Brian Osman if (!original) { 111e8e54580c3c91fd485187af040af118aa5153261Brian Osman return nullptr; 112e8e54580c3c91fd485187af040af118aa5153261Brian Osman } 1134f358be6b72cca97856b3f59d83448650d359d93Robert Phillips 1143798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips return CopyOnGpu(fContext, std::move(original), nullptr, copyParams); 115e8e54580c3c91fd485187af040af118aa5153261Brian Osman} 116