blob: fa428ed0fbbe8153830407f6150484258663ef82 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/GrTextureMaker.h"
Brian Osmane8e54582016-11-28 10:06:27 -05009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/private/GrRecordingContext.h"
11#include "src/gpu/GrColorSpaceXform.h"
12#include "src/gpu/GrGpu.h"
13#include "src/gpu/GrProxyProvider.h"
14#include "src/gpu/GrRecordingContextPriv.h"
Brian Osmane8e54582016-11-28 10:06:27 -050015
Brian Salomon2a943df2018-05-04 13:43:19 -040016sk_sp<GrTextureProxy> GrTextureMaker::onRefTextureProxyForParams(const GrSamplerState& params,
Greg Daniel8e9b4c42018-07-20 10:30:48 -040017 bool willBeMipped,
Brian Salomon2a943df2018-05-04 13:43:19 -040018 SkScalar scaleAdjust[2]) {
Robert Phillips9338c602019-02-19 12:52:29 -050019 if (this->width() > this->context()->priv().caps()->maxTextureSize() ||
20 this->height() > this->context()->priv().caps()->maxTextureSize()) {
Brian Osman875f7852018-04-12 13:29:08 -040021 return nullptr;
22 }
23
Brian Osmane8e54582016-11-28 10:06:27 -050024 CopyParams copyParams;
Brian Osmane8e54582016-11-28 10:06:27 -050025
Brian Osmane7fd8c32018-10-19 13:30:39 -040026 sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped,
Stan Ilievba81af22017-06-08 15:16:53 -040027 AllowedTexGenType::kCheap));
Greg Daniel8f5bbda2018-06-08 17:22:23 -040028 bool needsCopyForMipsOnly = false;
Stan Ilievba81af22017-06-08 15:16:53 -040029 if (original) {
Greg Daniel8f5bbda2018-06-08 17:22:23 -040030 if (!params.isRepeated() ||
Robert Phillips9338c602019-02-19 12:52:29 -050031 !GrGpu::IsACopyNeededForRepeatWrapMode(this->context()->priv().caps(), original.get(),
Greg Daniel8f5bbda2018-06-08 17:22:23 -040032 original->width(), original->height(),
33 params.filter(), &copyParams, scaleAdjust)) {
Robert Phillips9338c602019-02-19 12:52:29 -050034 needsCopyForMipsOnly = GrGpu::IsACopyNeededForMips(this->context()->priv().caps(),
Greg Daniel8f5bbda2018-06-08 17:22:23 -040035 original.get(), params.filter(),
36 &copyParams);
37 if (!needsCopyForMipsOnly) {
38 return original;
39 }
Stan Ilievba81af22017-06-08 15:16:53 -040040 }
41 } else {
Greg Daniel8f5bbda2018-06-08 17:22:23 -040042 if (!params.isRepeated() ||
Robert Phillips9338c602019-02-19 12:52:29 -050043 !GrGpu::IsACopyNeededForRepeatWrapMode(this->context()->priv().caps(), nullptr,
Greg Daniel8f5bbda2018-06-08 17:22:23 -040044 this->width(), this->height(),
45 params.filter(), &copyParams, scaleAdjust)) {
Brian Osmane7fd8c32018-10-19 13:30:39 -040046 return this->refOriginalTextureProxy(willBeMipped, AllowedTexGenType::kAny);
Stan Ilievba81af22017-06-08 15:16:53 -040047 }
Brian Osmane8e54582016-11-28 10:06:27 -050048 }
Stan Ilievba81af22017-06-08 15:16:53 -040049
Robert Phillips9338c602019-02-19 12:52:29 -050050 GrProxyProvider* proxyProvider = this->context()->priv().proxyProvider();
Robert Phillips1afd4cd2018-01-08 13:40:32 -050051
52 GrSurfaceOrigin origOrigin = original ? original->origin() : kTopLeft_GrSurfaceOrigin;
Brian Osmane8e54582016-11-28 10:06:27 -050053 GrUniqueKey copyKey;
Brian Osmanb3f38302018-09-07 15:24:44 -040054 this->makeCopyKey(copyParams, &copyKey);
Greg Daniel2d59d2f2017-10-31 15:25:14 -040055 sk_sp<GrTextureProxy> cachedProxy;
Brian Osmane8e54582016-11-28 10:06:27 -050056 if (copyKey.isValid()) {
Brian Salomon2af3e702019-08-11 19:10:31 -040057 cachedProxy =
58 proxyProvider->findOrCreateProxyByUniqueKey(copyKey, this->colorType(), origOrigin);
Greg Daniel2d59d2f2017-10-31 15:25:14 -040059 if (cachedProxy && (!willBeMipped || GrMipMapped::kYes == cachedProxy->mipMapped())) {
60 return cachedProxy;
Brian Osmane8e54582016-11-28 10:06:27 -050061 }
62 }
63
Greg Daniel8f5bbda2018-06-08 17:22:23 -040064 sk_sp<GrTextureProxy> source;
Stan Ilievba81af22017-06-08 15:16:53 -040065 if (original) {
Greg Daniel8f5bbda2018-06-08 17:22:23 -040066 source = std::move(original);
Greg Daniel2d59d2f2017-10-31 15:25:14 -040067 } else if (cachedProxy) {
Greg Daniel8f5bbda2018-06-08 17:22:23 -040068 source = cachedProxy;
Stan Ilievba81af22017-06-08 15:16:53 -040069 } else {
Greg Daniel2d59d2f2017-10-31 15:25:14 -040070 // Since we will be copying this texture there is no reason to make it mipped
Brian Osmane7fd8c32018-10-19 13:30:39 -040071 source = this->refOriginalTextureProxy(false, AllowedTexGenType::kAny);
Stan Ilievba81af22017-06-08 15:16:53 -040072 }
Greg Daniel8f5bbda2018-06-08 17:22:23 -040073
74 if (!source) {
Greg Daniel2d59d2f2017-10-31 15:25:14 -040075 return nullptr;
76 }
77
Brian Salomond6287472019-06-24 15:50:07 -040078 sk_sp<GrTextureProxy> result =
79 CopyOnGpu(this->context(), source, this->colorType(), copyParams, willBeMipped);
Stan Ilievba81af22017-06-08 15:16:53 -040080
Brian Osmane8e54582016-11-28 10:06:27 -050081 if (!result) {
Greg Daniel8f5bbda2018-06-08 17:22:23 -040082 // If we were unable to make a copy and we only needed a copy for mips, then we will return
83 // the source texture here and require that the GPU backend is able to fall back to using
84 // bilerp if mips are required.
85 if (needsCopyForMipsOnly) {
86 return source;
87 }
Brian Osmane8e54582016-11-28 10:06:27 -050088 return nullptr;
89 }
90
91 if (copyKey.isValid()) {
Robert Phillipsd3e247f2017-07-25 08:00:17 -040092 SkASSERT(result->origin() == origOrigin);
Greg Daniel2d59d2f2017-10-31 15:25:14 -040093 if (cachedProxy) {
94 SkASSERT(GrMipMapped::kYes == result->mipMapped() &&
95 GrMipMapped::kNo == cachedProxy->mipMapped());
96 // If we had a cachedProxy, that means there already is a proxy in the cache which
97 // matches the key, but it does not have mip levels and we require them. Thus we must
98 // remove the unique key from that proxy.
Chris Dalton2de13dd2019-01-03 15:11:59 -070099 SkASSERT(cachedProxy->getUniqueKey() == copyKey);
100 proxyProvider->removeUniqueKeyFromProxy(cachedProxy.get());
Greg Daniel2d59d2f2017-10-31 15:25:14 -0400101 }
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500102 proxyProvider->assignUniqueKeyToProxy(copyKey, result.get());
Robert Phillipsa41c6852019-02-07 10:44:10 -0500103 this->didCacheCopy(copyKey, proxyProvider->contextID());
Brian Osmane8e54582016-11-28 10:06:27 -0500104 }
105 return result;
106}
107
Brian Salomonaff329b2017-08-11 09:40:37 -0400108std::unique_ptr<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
109 const SkMatrix& textureMatrix,
110 const SkRect& constraintRect,
111 FilterConstraint filterConstraint,
112 bool coordsLimitedToConstraintRect,
Brian Osman05c8f462018-10-22 17:13:36 -0400113 const GrSamplerState::Filter* filterOrNullForBicubic) {
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400114 const GrSamplerState::Filter* fmForDetermineDomain = filterOrNullForBicubic;
115 if (filterOrNullForBicubic && GrSamplerState::Filter::kMipMap == *filterOrNullForBicubic &&
Brian Osmane8e54582016-11-28 10:06:27 -0500116 kYes_FilterConstraint == filterConstraint) {
Michael Ludwigddeed372019-02-20 16:50:10 -0500117 // TODO: Here we should force a copy restricted to the constraintRect since MIP maps will
Brian Osmane8e54582016-11-28 10:06:27 -0500118 // read outside the constraint rect. However, as in the adjuster case, we aren't currently
119 // doing that.
120 // We instead we compute the domain as though were bilerping which is only correct if we
121 // only sample level 0.
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400122 static const GrSamplerState::Filter kBilerp = GrSamplerState::Filter::kBilerp;
Brian Osmane8e54582016-11-28 10:06:27 -0500123 fmForDetermineDomain = &kBilerp;
124 }
125
Robert Phillips67c18d62017-01-20 12:44:06 -0500126 SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
Michael Ludwigddeed372019-02-20 16:50:10 -0500127 sk_sp<GrTextureProxy> proxy(this->refTextureProxyForParams(filterOrNullForBicubic,
128 scaleAdjust));
Robert Phillips3798c862017-03-27 11:08:16 -0400129 if (!proxy) {
Brian Osmane8e54582016-11-28 10:06:27 -0500130 return nullptr;
131 }
Robert Phillips67c18d62017-01-20 12:44:06 -0500132 SkMatrix adjustedMatrix = textureMatrix;
133 adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
Michael Ludwigddeed372019-02-20 16:50:10 -0500134
Brian Osmane8e54582016-11-28 10:06:27 -0500135 SkRect domain;
136 DomainMode domainMode =
Brian Salomon4df00922017-09-07 16:34:11 +0000137 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
Greg Danielc77085d2017-11-01 16:38:48 -0400138 proxy.get(), fmForDetermineDomain, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500139 SkASSERT(kTightCopy_DomainMode != domainMode);
Michael Ludwigddeed372019-02-20 16:50:10 -0500140 return this->createFragmentProcessorForDomainAndFilter(
141 std::move(proxy), adjustedMatrix, domainMode, domain, filterOrNullForBicubic);
Brian Osmane8e54582016-11-28 10:06:27 -0500142}