blob: e68703afa1377da87adc04b17788c5ba8d86ff4d [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,
Robert Phillips67c18d62017-01-20 12:44:06 -050015 sk_sp<SkColorSpace>* texColorSpace,
16 SkScalar scaleAdjust[2]) {
Brian Osmane8e54582016-11-28 10:06:27 -050017 CopyParams copyParams;
18 bool willBeMipped = params.filterMode() == GrSamplerParams::kMipMap_FilterMode;
19
20 if (!fContext->caps()->mipMapSupport()) {
21 willBeMipped = false;
22 }
23
24 if (texColorSpace) {
Brian Osman61624f02016-12-09 14:51:59 -050025 *texColorSpace = this->getColorSpace(dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050026 }
27
28 if (!fContext->getGpu()->makeCopyForTextureParams(this->width(), this->height(), params,
Robert Phillips67c18d62017-01-20 12:44:06 -050029 &copyParams, scaleAdjust)) {
Brian Osman61624f02016-12-09 14:51:59 -050030 return this->refOriginalTexture(willBeMipped, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050031 }
32 GrUniqueKey copyKey;
Brian Osman61624f02016-12-09 14:51:59 -050033 this->makeCopyKey(copyParams, &copyKey, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050034 if (copyKey.isValid()) {
35 GrTexture* result = fContext->textureProvider()->findAndRefTextureByUniqueKey(copyKey);
36 if (result) {
37 return result;
38 }
39 }
40
Brian Osman61624f02016-12-09 14:51:59 -050041 GrTexture* result = this->generateTextureForParams(copyParams, willBeMipped, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050042 if (!result) {
43 return nullptr;
44 }
45
46 if (copyKey.isValid()) {
47 fContext->textureProvider()->assignUniqueKeyToTexture(copyKey, result);
48 this->didCacheCopy(copyKey);
49 }
50 return result;
51}
52
53sk_sp<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
54 const SkMatrix& textureMatrix,
55 const SkRect& constraintRect,
56 FilterConstraint filterConstraint,
57 bool coordsLimitedToConstraintRect,
58 const GrSamplerParams::FilterMode* filterOrNullForBicubic,
Brian Osman61624f02016-12-09 14:51:59 -050059 SkColorSpace* dstColorSpace) {
Brian Osmane8e54582016-11-28 10:06:27 -050060
61 const GrSamplerParams::FilterMode* fmForDetermineDomain = filterOrNullForBicubic;
62 if (filterOrNullForBicubic && GrSamplerParams::kMipMap_FilterMode == *filterOrNullForBicubic &&
63 kYes_FilterConstraint == filterConstraint) {
64 // TODo: Here we should force a copy restricted to the constraintRect since MIP maps will
65 // read outside the constraint rect. However, as in the adjuster case, we aren't currently
66 // doing that.
67 // We instead we compute the domain as though were bilerping which is only correct if we
68 // only sample level 0.
69 static const GrSamplerParams::FilterMode kBilerp = GrSamplerParams::kBilerp_FilterMode;
70 fmForDetermineDomain = &kBilerp;
71 }
72
73 GrSamplerParams params;
74 if (filterOrNullForBicubic) {
75 params.reset(SkShader::kClamp_TileMode, *filterOrNullForBicubic);
76 } else {
77 // Bicubic doesn't use filtering for it's texture accesses.
78 params.reset(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode);
79 }
80 sk_sp<SkColorSpace> texColorSpace;
Robert Phillips67c18d62017-01-20 12:44:06 -050081 SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
82 sk_sp<GrTexture> texture(this->refTextureForParams(params, dstColorSpace, &texColorSpace,
83 scaleAdjust));
Brian Osmane8e54582016-11-28 10:06:27 -050084 if (!texture) {
85 return nullptr;
86 }
Robert Phillips67c18d62017-01-20 12:44:06 -050087 SkMatrix adjustedMatrix = textureMatrix;
88 adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
Brian Osmane8e54582016-11-28 10:06:27 -050089 SkRect domain;
90 DomainMode domainMode =
91 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
Robert Phillipse98234f2017-01-09 14:23:59 -050092 texture->width(), texture->height(),
93 nullptr, fmForDetermineDomain, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -050094 SkASSERT(kTightCopy_DomainMode != domainMode);
Brian Osmane8e54582016-11-28 10:06:27 -050095 sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(),
96 dstColorSpace);
97 return CreateFragmentProcessorForDomainAndFilter(texture.get(), std::move(colorSpaceXform),
Robert Phillips67c18d62017-01-20 12:44:06 -050098 adjustedMatrix, domainMode, domain,
Brian Osmane8e54582016-11-28 10:06:27 -050099 filterOrNullForBicubic);
100}
101
102GrTexture* GrTextureMaker::generateTextureForParams(const CopyParams& copyParams, bool willBeMipped,
Brian Osman61624f02016-12-09 14:51:59 -0500103 SkColorSpace* dstColorSpace) {
104 sk_sp<GrTexture> original(this->refOriginalTexture(willBeMipped, dstColorSpace));
Brian Osmane8e54582016-11-28 10:06:27 -0500105 if (!original) {
106 return nullptr;
107 }
108 return CopyOnGpu(original.get(), nullptr, copyParams);
109}