blob: 37272be4c9a38e5cee7ec2d73e1685b7ec43bf2c [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"
12
13GrTexture* GrTextureMaker::refTextureForParams(const GrSamplerParams& params,
Brian Osman61624f02016-12-09 14:51:59 -050014 SkColorSpace* dstColorSpace,
Brian Osmane8e54582016-11-28 10:06:27 -050015 sk_sp<SkColorSpace>* texColorSpace) {
16 CopyParams copyParams;
17 bool willBeMipped = params.filterMode() == GrSamplerParams::kMipMap_FilterMode;
18
19 if (!fContext->caps()->mipMapSupport()) {
20 willBeMipped = false;
21 }
22
23 if (texColorSpace) {
Brian Osman61624f02016-12-09 14:51:59 -050024 *texColorSpace = this->getColorSpace(dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050025 }
26
27 if (!fContext->getGpu()->makeCopyForTextureParams(this->width(), this->height(), params,
28 &copyParams)) {
Brian Osman61624f02016-12-09 14:51:59 -050029 return this->refOriginalTexture(willBeMipped, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050030 }
31 GrUniqueKey copyKey;
Brian Osman61624f02016-12-09 14:51:59 -050032 this->makeCopyKey(copyParams, &copyKey, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050033 if (copyKey.isValid()) {
34 GrTexture* result = fContext->textureProvider()->findAndRefTextureByUniqueKey(copyKey);
35 if (result) {
36 return result;
37 }
38 }
39
Brian Osman61624f02016-12-09 14:51:59 -050040 GrTexture* result = this->generateTextureForParams(copyParams, willBeMipped, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050041 if (!result) {
42 return nullptr;
43 }
44
45 if (copyKey.isValid()) {
46 fContext->textureProvider()->assignUniqueKeyToTexture(copyKey, result);
47 this->didCacheCopy(copyKey);
48 }
49 return result;
50}
51
52sk_sp<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
53 const SkMatrix& textureMatrix,
54 const SkRect& constraintRect,
55 FilterConstraint filterConstraint,
56 bool coordsLimitedToConstraintRect,
57 const GrSamplerParams::FilterMode* filterOrNullForBicubic,
Brian Osman61624f02016-12-09 14:51:59 -050058 SkColorSpace* dstColorSpace) {
Brian Osmane8e54582016-11-28 10:06:27 -050059
60 const GrSamplerParams::FilterMode* fmForDetermineDomain = filterOrNullForBicubic;
61 if (filterOrNullForBicubic && GrSamplerParams::kMipMap_FilterMode == *filterOrNullForBicubic &&
62 kYes_FilterConstraint == filterConstraint) {
63 // TODo: Here we should force a copy restricted to the constraintRect since MIP maps will
64 // read outside the constraint rect. However, as in the adjuster case, we aren't currently
65 // doing that.
66 // We instead we compute the domain as though were bilerping which is only correct if we
67 // only sample level 0.
68 static const GrSamplerParams::FilterMode kBilerp = GrSamplerParams::kBilerp_FilterMode;
69 fmForDetermineDomain = &kBilerp;
70 }
71
72 GrSamplerParams params;
73 if (filterOrNullForBicubic) {
74 params.reset(SkShader::kClamp_TileMode, *filterOrNullForBicubic);
75 } else {
76 // Bicubic doesn't use filtering for it's texture accesses.
77 params.reset(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode);
78 }
79 sk_sp<SkColorSpace> texColorSpace;
Brian Osman61624f02016-12-09 14:51:59 -050080 sk_sp<GrTexture> texture(this->refTextureForParams(params, dstColorSpace, &texColorSpace));
Brian Osmane8e54582016-11-28 10:06:27 -050081 if (!texture) {
82 return nullptr;
83 }
84 SkRect domain;
85 DomainMode domainMode =
86 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
Robert Phillipse98234f2017-01-09 14:23:59 -050087 texture->width(), texture->height(),
88 nullptr, fmForDetermineDomain, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -050089 SkASSERT(kTightCopy_DomainMode != domainMode);
90 SkMatrix normalizedTextureMatrix = textureMatrix;
91 normalizedTextureMatrix.postIDiv(texture->width(), texture->height());
92 sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(),
93 dstColorSpace);
94 return CreateFragmentProcessorForDomainAndFilter(texture.get(), std::move(colorSpaceXform),
95 normalizedTextureMatrix, domainMode, domain,
96 filterOrNullForBicubic);
97}
98
99GrTexture* GrTextureMaker::generateTextureForParams(const CopyParams& copyParams, bool willBeMipped,
Brian Osman61624f02016-12-09 14:51:59 -0500100 SkColorSpace* dstColorSpace) {
101 sk_sp<GrTexture> original(this->refOriginalTexture(willBeMipped, dstColorSpace));
Brian Osmane8e54582016-11-28 10:06:27 -0500102 if (!original) {
103 return nullptr;
104 }
105 return CopyOnGpu(original.get(), nullptr, copyParams);
106}