blob: ee4641b5e7b805deb6a81431bc3ac08ed384c346 [file] [log] [blame]
Brian Osmane8e54582016-11-28 10:06:27 -05001/*
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"
Brian Osman32342f02017-03-04 08:12:46 -050012#include "GrResourceProvider.h"
Brian Osmane8e54582016-11-28 10:06:27 -050013
14GrTexture* GrTextureMaker::refTextureForParams(const GrSamplerParams& params,
Brian Osman61624f02016-12-09 14:51:59 -050015 SkColorSpace* dstColorSpace,
Robert Phillips67c18d62017-01-20 12:44:06 -050016 sk_sp<SkColorSpace>* texColorSpace,
17 SkScalar scaleAdjust[2]) {
Brian Osmane8e54582016-11-28 10:06:27 -050018 CopyParams copyParams;
19 bool willBeMipped = params.filterMode() == GrSamplerParams::kMipMap_FilterMode;
20
21 if (!fContext->caps()->mipMapSupport()) {
22 willBeMipped = false;
23 }
24
25 if (texColorSpace) {
Brian Osman61624f02016-12-09 14:51:59 -050026 *texColorSpace = this->getColorSpace(dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050027 }
28
Robert Phillips81444fb2017-03-21 09:14:35 -040029 if (!fContext->getGpu()->isACopyNeededForTextureParams(this->width(), this->height(), params,
30 &copyParams, scaleAdjust)) {
Robert Phillips78075802017-03-23 11:11:59 -040031 sk_sp<GrTextureProxy>proxy = this->refOriginalTextureProxy(willBeMipped, dstColorSpace);
32 if (!proxy) {
33 return nullptr;
34 }
35
36 sk_sp<GrTexture> tex(SkSafeRef(proxy->instantiate(fContext->resourceProvider())));
37 return tex.release();
Brian Osmane8e54582016-11-28 10:06:27 -050038 }
39 GrUniqueKey copyKey;
Brian Osman61624f02016-12-09 14:51:59 -050040 this->makeCopyKey(copyParams, &copyKey, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050041 if (copyKey.isValid()) {
Brian Osman32342f02017-03-04 08:12:46 -050042 GrTexture* result = fContext->resourceProvider()->findAndRefTextureByUniqueKey(copyKey);
Brian Osmane8e54582016-11-28 10:06:27 -050043 if (result) {
44 return result;
45 }
46 }
47
Brian Osman61624f02016-12-09 14:51:59 -050048 GrTexture* result = this->generateTextureForParams(copyParams, willBeMipped, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050049 if (!result) {
50 return nullptr;
51 }
52
53 if (copyKey.isValid()) {
Brian Osman32342f02017-03-04 08:12:46 -050054 fContext->resourceProvider()->assignUniqueKeyToTexture(copyKey, result);
Brian Osmane8e54582016-11-28 10:06:27 -050055 this->didCacheCopy(copyKey);
56 }
57 return result;
58}
59
60sk_sp<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
61 const SkMatrix& textureMatrix,
62 const SkRect& constraintRect,
63 FilterConstraint filterConstraint,
64 bool coordsLimitedToConstraintRect,
65 const GrSamplerParams::FilterMode* filterOrNullForBicubic,
Brian Osman61624f02016-12-09 14:51:59 -050066 SkColorSpace* dstColorSpace) {
Brian Osmane8e54582016-11-28 10:06:27 -050067
68 const GrSamplerParams::FilterMode* fmForDetermineDomain = filterOrNullForBicubic;
69 if (filterOrNullForBicubic && GrSamplerParams::kMipMap_FilterMode == *filterOrNullForBicubic &&
70 kYes_FilterConstraint == filterConstraint) {
71 // TODo: Here we should force a copy restricted to the constraintRect since MIP maps will
72 // read outside the constraint rect. However, as in the adjuster case, we aren't currently
73 // doing that.
74 // We instead we compute the domain as though were bilerping which is only correct if we
75 // only sample level 0.
76 static const GrSamplerParams::FilterMode kBilerp = GrSamplerParams::kBilerp_FilterMode;
77 fmForDetermineDomain = &kBilerp;
78 }
79
80 GrSamplerParams params;
81 if (filterOrNullForBicubic) {
82 params.reset(SkShader::kClamp_TileMode, *filterOrNullForBicubic);
83 } else {
84 // Bicubic doesn't use filtering for it's texture accesses.
85 params.reset(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode);
86 }
87 sk_sp<SkColorSpace> texColorSpace;
Robert Phillips67c18d62017-01-20 12:44:06 -050088 SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
89 sk_sp<GrTexture> texture(this->refTextureForParams(params, dstColorSpace, &texColorSpace,
90 scaleAdjust));
Brian Osmane8e54582016-11-28 10:06:27 -050091 if (!texture) {
92 return nullptr;
93 }
Robert Phillips67c18d62017-01-20 12:44:06 -050094 SkMatrix adjustedMatrix = textureMatrix;
95 adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
Brian Osmane8e54582016-11-28 10:06:27 -050096 SkRect domain;
97 DomainMode domainMode =
98 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
Robert Phillipse98234f2017-01-09 14:23:59 -050099 texture->width(), texture->height(),
100 nullptr, fmForDetermineDomain, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500101 SkASSERT(kTightCopy_DomainMode != domainMode);
Brian Osmane8e54582016-11-28 10:06:27 -0500102 sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(),
103 dstColorSpace);
104 return CreateFragmentProcessorForDomainAndFilter(texture.get(), std::move(colorSpaceXform),
Robert Phillips67c18d62017-01-20 12:44:06 -0500105 adjustedMatrix, domainMode, domain,
Brian Osmane8e54582016-11-28 10:06:27 -0500106 filterOrNullForBicubic);
107}
108
109GrTexture* GrTextureMaker::generateTextureForParams(const CopyParams& copyParams, bool willBeMipped,
Brian Osman61624f02016-12-09 14:51:59 -0500110 SkColorSpace* dstColorSpace) {
Robert Phillips4f358be2017-03-23 08:21:00 -0400111 sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace));
Brian Osmane8e54582016-11-28 10:06:27 -0500112 if (!original) {
113 return nullptr;
114 }
Robert Phillips4f358be2017-03-23 08:21:00 -0400115
116 sk_sp<GrTextureProxy> copy = CopyOnGpu(fContext, std::move(original), nullptr, copyParams);
117 if (!copy) {
118 return nullptr;
119 }
120
121 sk_sp<GrTexture> tex(SkSafeRef(copy->instantiate(fContext->resourceProvider())));
122 return tex.release();
Brian Osmane8e54582016-11-28 10:06:27 -0500123}