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
refTextureProxyForParams(const GrSamplerParams & params,SkColorSpace * dstColorSpace,sk_sp<SkColorSpace> * texColorSpace,SkScalar scaleAdjust[2])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 if (!fContext->getGpu()->isACopyNeededForTextureParams(this->width(), this->height(), params,
30 ©Params, scaleAdjust)) {
31 return this->refOriginalTextureProxy(willBeMipped, dstColorSpace);
32 }
33 GrUniqueKey copyKey;
34 this->makeCopyKey(copyParams, ©Key, dstColorSpace);
35 if (copyKey.isValid()) {
36 sk_sp<GrTextureProxy> result(fContext->resourceProvider()->findProxyByUniqueKey(copyKey));
37 if (result) {
38 return result;
39 }
40 }
41
42 sk_sp<GrTextureProxy> result(this->generateTextureProxyForParams(copyParams, willBeMipped,
43 dstColorSpace));
44 if (!result) {
45 return nullptr;
46 }
47
48 if (copyKey.isValid()) {
49 fContext->resourceProvider()->assignUniqueKeyToProxy(copyKey, result.get());
50 this->didCacheCopy(copyKey);
51 }
52 return result;
53 }
54
createFragmentProcessor(const SkMatrix & textureMatrix,const SkRect & constraintRect,FilterConstraint filterConstraint,bool coordsLimitedToConstraintRect,const GrSamplerParams::FilterMode * filterOrNullForBicubic,SkColorSpace * dstColorSpace)55 sk_sp<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
56 const SkMatrix& textureMatrix,
57 const SkRect& constraintRect,
58 FilterConstraint filterConstraint,
59 bool coordsLimitedToConstraintRect,
60 const GrSamplerParams::FilterMode* filterOrNullForBicubic,
61 SkColorSpace* dstColorSpace) {
62
63 const GrSamplerParams::FilterMode* fmForDetermineDomain = filterOrNullForBicubic;
64 if (filterOrNullForBicubic && GrSamplerParams::kMipMap_FilterMode == *filterOrNullForBicubic &&
65 kYes_FilterConstraint == filterConstraint) {
66 // TODo: Here we should force a copy restricted to the constraintRect since MIP maps will
67 // read outside the constraint rect. However, as in the adjuster case, we aren't currently
68 // doing that.
69 // We instead we compute the domain as though were bilerping which is only correct if we
70 // only sample level 0.
71 static const GrSamplerParams::FilterMode kBilerp = GrSamplerParams::kBilerp_FilterMode;
72 fmForDetermineDomain = &kBilerp;
73 }
74
75 GrSamplerParams params;
76 if (filterOrNullForBicubic) {
77 params.reset(SkShader::kClamp_TileMode, *filterOrNullForBicubic);
78 } else {
79 // Bicubic doesn't use filtering for it's texture accesses.
80 params.reset(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode);
81 }
82 sk_sp<SkColorSpace> texColorSpace;
83 SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
84 sk_sp<GrTextureProxy> proxy(this->refTextureProxyForParams(params, dstColorSpace,
85 &texColorSpace,
86 scaleAdjust));
87 if (!proxy) {
88 return nullptr;
89 }
90 SkMatrix adjustedMatrix = textureMatrix;
91 adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
92 SkRect domain;
93 DomainMode domainMode =
94 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
95 proxy.get(),
96 nullptr, fmForDetermineDomain, &domain);
97 SkASSERT(kTightCopy_DomainMode != domainMode);
98 sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(),
99 dstColorSpace);
100 return CreateFragmentProcessorForDomainAndFilter(fContext->resourceProvider(), std::move(proxy),
101 std::move(colorSpaceXform),
102 adjustedMatrix, domainMode, domain,
103 filterOrNullForBicubic);
104 }
105
generateTextureProxyForParams(const CopyParams & copyParams,bool willBeMipped,SkColorSpace * dstColorSpace)106 sk_sp<GrTextureProxy> GrTextureMaker::generateTextureProxyForParams(const CopyParams& copyParams,
107 bool willBeMipped,
108 SkColorSpace* dstColorSpace) {
109 sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace));
110 if (!original) {
111 return nullptr;
112 }
113
114 return CopyOnGpu(fContext, std::move(original), nullptr, copyParams);
115 }
116