• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                                                            &copyParams, scaleAdjust)) {
31         return this->refOriginalTextureProxy(willBeMipped, dstColorSpace);
32     }
33     GrUniqueKey copyKey;
34     this->makeCopyKey(copyParams, &copyKey, 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