blob: 17200f2c141f8ad1d83750406ef54a383079f130 [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
Greg Danielcc104db2020-02-03 14:17:08 -050016GrSurfaceProxyView GrTextureMaker::onRefTextureProxyViewForParams(GrSamplerState params,
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +000017 bool willBeMipped,
18 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()) {
Greg Danielcc104db2020-02-03 14:17:08 -050021 return {};
Brian Osman875f7852018-04-12 13:29:08 -040022 }
23
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +000024 CopyParams copyParams;
25
Greg Danielcc104db2020-02-03 14:17:08 -050026 GrSurfaceProxyView original = this->refOriginalTextureProxyView(willBeMipped,
27 AllowedTexGenType::kCheap);
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +000028 bool needsCopyForMipsOnly = false;
29 if (original.proxy()) {
30 GrTextureProxy* texProxy = original.asTextureProxy();
31 SkASSERT(texProxy);
32 if (!params.isRepeated() ||
33 !GrGpu::IsACopyNeededForRepeatWrapMode(this->context()->priv().caps(), texProxy,
34 texProxy->dimensions(), params.filter(),
35 &copyParams, scaleAdjust)) {
36 needsCopyForMipsOnly = GrGpu::IsACopyNeededForMips(this->context()->priv().caps(),
37 texProxy, params.filter(),
38 &copyParams);
39 if (!needsCopyForMipsOnly) {
40 return original;
41 }
42 }
43 } else {
44 if (!params.isRepeated() ||
45 !GrGpu::IsACopyNeededForRepeatWrapMode(this->context()->priv().caps(), nullptr,
46 this->dimensions(), params.filter(), &copyParams,
47 scaleAdjust)) {
48 return this->refOriginalTextureProxyView(willBeMipped, AllowedTexGenType::kAny);
49 }
Brian Osmane8e54582016-11-28 10:06:27 -050050 }
Stan Ilievba81af22017-06-08 15:16:53 -040051
Robert Phillips9338c602019-02-19 12:52:29 -050052 GrProxyProvider* proxyProvider = this->context()->priv().proxyProvider();
Robert Phillips1afd4cd2018-01-08 13:40:32 -050053
Greg Danielcc104db2020-02-03 14:17:08 -050054 GrSurfaceOrigin origOrigin = original.proxy() ? original.origin() : kTopLeft_GrSurfaceOrigin;
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +000055 GrUniqueKey copyKey;
56 this->makeCopyKey(copyParams, &copyKey);
57 GrSurfaceProxyView cachedView;
58 if (copyKey.isValid()) {
59 auto cachedProxy = proxyProvider->findOrCreateProxyByUniqueKey(copyKey, this->colorType());
Greg Danielcc104db2020-02-03 14:17:08 -050060 if (cachedProxy) {
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +000061 GrMipMapped mipped = cachedProxy->mipMapped();
62 // TODO: Once we no longer use CopyOnGpu which can fallback to arbitrary formats and
63 // colorTypes, we can use the swizzle of the originalView.
Greg Daniel87506ab2020-02-12 13:05:42 -050064 GrSwizzle swizzle = cachedProxy->textureSwizzleDoNotUse();
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +000065 cachedView = GrSurfaceProxyView(std::move(cachedProxy), origOrigin, swizzle);
66 if (!willBeMipped || GrMipMapped::kYes == mipped) {
67 return cachedView;
68 }
Brian Osmane8e54582016-11-28 10:06:27 -050069 }
70 }
71
Greg Danielcc104db2020-02-03 14:17:08 -050072 GrSurfaceProxyView source;
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +000073 if (original.proxy()) {
Greg Daniel8f5bbda2018-06-08 17:22:23 -040074 source = std::move(original);
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +000075 } else if (cachedView.proxy()) {
76 source = cachedView;
Stan Ilievba81af22017-06-08 15:16:53 -040077 } else {
Greg Daniel2d59d2f2017-10-31 15:25:14 -040078 // Since we will be copying this texture there is no reason to make it mipped
Greg Danielcc104db2020-02-03 14:17:08 -050079 source = this->refOriginalTextureProxyView(false, AllowedTexGenType::kAny);
Stan Ilievba81af22017-06-08 15:16:53 -040080 }
Greg Daniel8f5bbda2018-06-08 17:22:23 -040081
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +000082 if (!source.proxy()) {
83 return {};
84 }
Greg Danielcc104db2020-02-03 14:17:08 -050085 SkASSERT(source.asTextureProxy());
Greg Daniel2d59d2f2017-10-31 15:25:14 -040086
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +000087 GrSurfaceProxyView result =
88 CopyOnGpu(this->context(), source, this->colorType(), copyParams, willBeMipped);
Stan Ilievba81af22017-06-08 15:16:53 -040089
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +000090 if (!result.proxy()) {
Greg Daniel8f5bbda2018-06-08 17:22:23 -040091 // If we were unable to make a copy and we only needed a copy for mips, then we will return
92 // the source texture here and require that the GPU backend is able to fall back to using
93 // bilerp if mips are required.
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +000094 if (needsCopyForMipsOnly) {
95 return source;
96 }
97 return {};
Brian Osmane8e54582016-11-28 10:06:27 -050098 }
99
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +0000100 if (copyKey.isValid()) {
Greg Danielcc104db2020-02-03 14:17:08 -0500101 SkASSERT(result.origin() == origOrigin);
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +0000102 if (cachedView.proxy()) {
103 SkASSERT(GrMipMapped::kYes == result.asTextureProxy()->mipMapped() &&
104 GrMipMapped::kNo == cachedView.asTextureProxy()->mipMapped());
105 // If we had a cachedProxy, that means there already is a proxy in the cache which
106 // matches the key, but it does not have mip levels and we require them. Thus we must
107 // remove the unique key from that proxy.
108 SkASSERT(cachedView.asTextureProxy()->getUniqueKey() == copyKey);
109 proxyProvider->removeUniqueKeyFromProxy(cachedView.asTextureProxy());
110 }
111 proxyProvider->assignUniqueKeyToProxy(copyKey, result.asTextureProxy());
112 this->didCacheCopy(copyKey, proxyProvider->contextID());
Brian Osmane8e54582016-11-28 10:06:27 -0500113 }
114 return result;
115}
116
Brian Salomonaff329b2017-08-11 09:40:37 -0400117std::unique_ptr<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
118 const SkMatrix& textureMatrix,
119 const SkRect& constraintRect,
120 FilterConstraint filterConstraint,
121 bool coordsLimitedToConstraintRect,
Brian Osman05c8f462018-10-22 17:13:36 -0400122 const GrSamplerState::Filter* filterOrNullForBicubic) {
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400123 const GrSamplerState::Filter* fmForDetermineDomain = filterOrNullForBicubic;
124 if (filterOrNullForBicubic && GrSamplerState::Filter::kMipMap == *filterOrNullForBicubic &&
Brian Osmane8e54582016-11-28 10:06:27 -0500125 kYes_FilterConstraint == filterConstraint) {
Michael Ludwigddeed372019-02-20 16:50:10 -0500126 // TODO: Here we should force a copy restricted to the constraintRect since MIP maps will
Brian Osmane8e54582016-11-28 10:06:27 -0500127 // read outside the constraint rect. However, as in the adjuster case, we aren't currently
128 // doing that.
129 // We instead we compute the domain as though were bilerping which is only correct if we
130 // only sample level 0.
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400131 static const GrSamplerState::Filter kBilerp = GrSamplerState::Filter::kBilerp;
Brian Osmane8e54582016-11-28 10:06:27 -0500132 fmForDetermineDomain = &kBilerp;
133 }
134
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +0000135 SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
136 GrSurfaceProxyView view = this->viewForParams(filterOrNullForBicubic, scaleAdjust);
137 if (!view.proxy()) {
Brian Osmane8e54582016-11-28 10:06:27 -0500138 return nullptr;
139 }
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +0000140 SkMatrix adjustedMatrix = textureMatrix;
141 adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
Michael Ludwigddeed372019-02-20 16:50:10 -0500142
Brian Osmane8e54582016-11-28 10:06:27 -0500143 SkRect domain;
144 DomainMode domainMode =
Brian Salomon4df00922017-09-07 16:34:11 +0000145 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
Greg Danielcc104db2020-02-03 14:17:08 -0500146 view.proxy(), fmForDetermineDomain, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500147 SkASSERT(kTightCopy_DomainMode != domainMode);
Michael Ludwigddeed372019-02-20 16:50:10 -0500148 return this->createFragmentProcessorForDomainAndFilter(
Robert Phillipsbf5cb0f2020-02-21 13:46:38 +0000149 std::move(view), adjustedMatrix, domainMode, domain, filterOrNullForBicubic);
Brian Osmane8e54582016-11-28 10:06:27 -0500150}