blob: f5ee4d3b6830bf0fcfec83e1e26a1cecdf24bb4f [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)) {
Brian Osman61624f02016-12-09 14:51:59 -050031 return this->refOriginalTexture(willBeMipped, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050032 }
33 GrUniqueKey copyKey;
Brian Osman61624f02016-12-09 14:51:59 -050034 this->makeCopyKey(copyParams, &copyKey, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050035 if (copyKey.isValid()) {
Brian Osman32342f02017-03-04 08:12:46 -050036 GrTexture* result = fContext->resourceProvider()->findAndRefTextureByUniqueKey(copyKey);
Brian Osmane8e54582016-11-28 10:06:27 -050037 if (result) {
38 return result;
39 }
40 }
41
Brian Osman61624f02016-12-09 14:51:59 -050042 GrTexture* result = this->generateTextureForParams(copyParams, willBeMipped, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050043 if (!result) {
44 return nullptr;
45 }
46
47 if (copyKey.isValid()) {
Brian Osman32342f02017-03-04 08:12:46 -050048 fContext->resourceProvider()->assignUniqueKeyToTexture(copyKey, result);
Brian Osmane8e54582016-11-28 10:06:27 -050049 this->didCacheCopy(copyKey);
50 }
51 return result;
52}
53
54sk_sp<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
55 const SkMatrix& textureMatrix,
56 const SkRect& constraintRect,
57 FilterConstraint filterConstraint,
58 bool coordsLimitedToConstraintRect,
59 const GrSamplerParams::FilterMode* filterOrNullForBicubic,
Brian Osman61624f02016-12-09 14:51:59 -050060 SkColorSpace* dstColorSpace) {
Brian Osmane8e54582016-11-28 10:06:27 -050061
62 const GrSamplerParams::FilterMode* fmForDetermineDomain = filterOrNullForBicubic;
63 if (filterOrNullForBicubic && GrSamplerParams::kMipMap_FilterMode == *filterOrNullForBicubic &&
64 kYes_FilterConstraint == filterConstraint) {
65 // TODo: Here we should force a copy restricted to the constraintRect since MIP maps will
66 // read outside the constraint rect. However, as in the adjuster case, we aren't currently
67 // doing that.
68 // We instead we compute the domain as though were bilerping which is only correct if we
69 // only sample level 0.
70 static const GrSamplerParams::FilterMode kBilerp = GrSamplerParams::kBilerp_FilterMode;
71 fmForDetermineDomain = &kBilerp;
72 }
73
74 GrSamplerParams params;
75 if (filterOrNullForBicubic) {
76 params.reset(SkShader::kClamp_TileMode, *filterOrNullForBicubic);
77 } else {
78 // Bicubic doesn't use filtering for it's texture accesses.
79 params.reset(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode);
80 }
81 sk_sp<SkColorSpace> texColorSpace;
Robert Phillips67c18d62017-01-20 12:44:06 -050082 SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
83 sk_sp<GrTexture> texture(this->refTextureForParams(params, dstColorSpace, &texColorSpace,
84 scaleAdjust));
Brian Osmane8e54582016-11-28 10:06:27 -050085 if (!texture) {
86 return nullptr;
87 }
Robert Phillips67c18d62017-01-20 12:44:06 -050088 SkMatrix adjustedMatrix = textureMatrix;
89 adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
Brian Osmane8e54582016-11-28 10:06:27 -050090 SkRect domain;
91 DomainMode domainMode =
92 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
Robert Phillipse98234f2017-01-09 14:23:59 -050093 texture->width(), texture->height(),
94 nullptr, fmForDetermineDomain, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -050095 SkASSERT(kTightCopy_DomainMode != domainMode);
Brian Osmane8e54582016-11-28 10:06:27 -050096 sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(),
97 dstColorSpace);
98 return CreateFragmentProcessorForDomainAndFilter(texture.get(), std::move(colorSpaceXform),
Robert Phillips67c18d62017-01-20 12:44:06 -050099 adjustedMatrix, domainMode, domain,
Brian Osmane8e54582016-11-28 10:06:27 -0500100 filterOrNullForBicubic);
101}
102
103GrTexture* GrTextureMaker::generateTextureForParams(const CopyParams& copyParams, bool willBeMipped,
Brian Osman61624f02016-12-09 14:51:59 -0500104 SkColorSpace* dstColorSpace) {
Robert Phillips4f358be2017-03-23 08:21:00 -0400105 sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace));
Brian Osmane8e54582016-11-28 10:06:27 -0500106 if (!original) {
107 return nullptr;
108 }
Robert Phillips4f358be2017-03-23 08:21:00 -0400109
110 sk_sp<GrTextureProxy> copy = CopyOnGpu(fContext, std::move(original), nullptr, copyParams);
111 if (!copy) {
112 return nullptr;
113 }
114
115 sk_sp<GrTexture> tex(SkSafeRef(copy->instantiate(fContext->resourceProvider())));
116 return tex.release();
Brian Osmane8e54582016-11-28 10:06:27 -0500117}