blob: 6d4628acbf9080d5ba58a9f71b1d6120b6ad2344 [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 "include/private/GrRecordingContext.h"
9#include "src/gpu/GrColorSpaceXform.h"
10#include "src/gpu/GrGpu.h"
11#include "src/gpu/GrProxyProvider.h"
12#include "src/gpu/GrRecordingContextPriv.h"
13#include "src/gpu/GrTextureAdjuster.h"
14#include "src/gpu/SkGr.h"
Brian Osmane8e54582016-11-28 10:06:27 -050015
Brian Salomone7499c72019-06-24 12:12:36 -040016GrTextureAdjuster::GrTextureAdjuster(GrRecordingContext* context,
Greg Danielcc104db2020-02-03 14:17:08 -050017 GrSurfaceProxyView original,
Greg Daniela4828a12019-10-11 13:51:02 -040018 const GrColorInfo& colorInfo,
19 uint32_t uniqueID,
20 bool useDecal)
Greg Danielcc104db2020-02-03 14:17:08 -050021 : INHERITED(context, {colorInfo, original.proxy()->dimensions()}, useDecal)
Greg Daniela4828a12019-10-11 13:51:02 -040022 , fOriginal(std::move(original))
23 , fUniqueID(uniqueID) {}
24
Brian Salomonc8d092a2020-02-24 10:14:21 -050025void GrTextureAdjuster::makeMipMappedKey(GrUniqueKey* mipMappedKey) {
Brian Osman61624f02016-12-09 14:51:59 -050026 // Destination color space is irrelevant - we already have a texture so we're just sub-setting
Brian Osmane8e54582016-11-28 10:06:27 -050027 GrUniqueKey baseKey;
Brian Salomon1a217eb2019-10-24 10:50:36 -040028 GrMakeKeyFromImageID(&baseKey, fUniqueID, SkIRect::MakeSize(this->dimensions()));
Brian Salomonc8d092a2020-02-24 10:14:21 -050029 MakeMipMappedKeyFromOriginalKey(baseKey, mipMappedKey);
Brian Osmane8e54582016-11-28 10:06:27 -050030}
31
Brian Salomonc8d092a2020-02-24 10:14:21 -050032void GrTextureAdjuster::didCacheMipMappedCopy(const GrUniqueKey& mipMappedKey,
33 uint32_t contextUniqueID) {
Brian Osmane8e54582016-11-28 10:06:27 -050034 // We don't currently have a mechanism for notifications on Images!
35}
36
Brian Salomonc8d092a2020-02-24 10:14:21 -050037GrSurfaceProxyView GrTextureAdjuster::makeMippedCopy() {
Robert Phillips9338c602019-02-19 12:52:29 -050038 GrProxyProvider* proxyProvider = this->context()->priv().proxyProvider();
Robert Phillips1afd4cd2018-01-08 13:40:32 -050039
Robert Phillips0c984a02017-03-16 07:51:56 -040040 GrUniqueKey key;
Brian Salomonc8d092a2020-02-24 10:14:21 -050041 this->makeMipMappedKey(&key);
Greg Daniel09c94002018-06-08 22:11:51 +000042 sk_sp<GrTextureProxy> cachedCopy;
Greg Danielcc104db2020-02-03 14:17:08 -050043 const GrSurfaceProxyView& originalView = this->originalProxyView();
Robert Phillips0c984a02017-03-16 07:51:56 -040044 if (key.isValid()) {
Greg Daniel3a365112020-02-14 10:47:18 -050045 cachedCopy = proxyProvider->findOrCreateProxyByUniqueKey(key, this->colorType());
Brian Salomonc8d092a2020-02-24 10:14:21 -050046 if (cachedCopy) {
47 return {std::move(cachedCopy), originalView.origin(), originalView.swizzle()};
Robert Phillips0c984a02017-03-16 07:51:56 -040048 }
49 }
50
Brian Salomonc8d092a2020-02-24 10:14:21 -050051 GrSurfaceProxyView copyView = GrCopyBaseMipMapToTextureProxy(
52 this->context(), originalView.proxy(), originalView.origin(), this->colorType());
53 if (!copyView) {
54 return {};
Greg Danielcce65002020-01-23 11:16:49 -050055 }
Brian Salomonc8d092a2020-02-24 10:14:21 -050056 if (key.isValid()) {
57 SkASSERT(copyView.origin() == originalView.origin());
58 proxyProvider->assignUniqueKeyToProxy(key, copyView.asTextureProxy());
59 this->didCacheMipMappedCopy(key, proxyProvider->contextID());
Brian Osmane8e54582016-11-28 10:06:27 -050060 }
Greg Danielcc104db2020-02-03 14:17:08 -050061 return copyView;
Brian Osmane8e54582016-11-28 10:06:27 -050062}
63
Greg Danielcc104db2020-02-03 14:17:08 -050064GrSurfaceProxyView GrTextureAdjuster::onRefTextureProxyViewForParams(GrSamplerState params,
Brian Salomonc8d092a2020-02-24 10:14:21 -050065 bool willBeMipped) {
Robert Phillips9338c602019-02-19 12:52:29 -050066 if (this->context()->priv().abandoned()) {
Brian Osmane8e54582016-11-28 10:06:27 -050067 // The texture was abandoned.
Greg Danielcc104db2020-02-03 14:17:08 -050068 return {};
Brian Osmane8e54582016-11-28 10:06:27 -050069 }
Brian Salomon4df00922017-09-07 16:34:11 +000070
Robert Phillips9338c602019-02-19 12:52:29 -050071 SkASSERT(this->width() <= this->context()->priv().caps()->maxTextureSize() &&
72 this->height() <= this->context()->priv().caps()->maxTextureSize());
Brian Osman875f7852018-04-12 13:29:08 -040073
Greg Danielcc104db2020-02-03 14:17:08 -050074 GrSurfaceProxyView view = this->originalProxyViewRef();
75 GrTextureProxy* texProxy = view.asTextureProxy();
76 SkASSERT(texProxy);
Brian Salomonc8d092a2020-02-24 10:14:21 -050077 if (!GrGpu::IsACopyNeededForMips(this->context()->priv().caps(), texProxy, params.filter())) {
78 return view;
Brian Osmane8e54582016-11-28 10:06:27 -050079 }
80
Brian Salomonc8d092a2020-02-24 10:14:21 -050081 GrSurfaceProxyView copy = this->makeMippedCopy();
82 if (!copy) {
Greg Daniel8f5bbda2018-06-08 17:22:23 -040083 // If we were unable to make a copy and we only needed a copy for mips, then we will return
84 // the source texture here and require that the GPU backend is able to fall back to using
85 // bilerp if mips are required.
Greg Danielcc104db2020-02-03 14:17:08 -050086 return view;
Greg Daniel8f5bbda2018-06-08 17:22:23 -040087 }
Brian Salomonc8d092a2020-02-24 10:14:21 -050088 SkASSERT(copy.asTextureProxy());
89 return copy;
Brian Osmane8e54582016-11-28 10:06:27 -050090}
91
Brian Salomonaff329b2017-08-11 09:40:37 -040092std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor(
Brian Salomonc8d092a2020-02-24 10:14:21 -050093 const SkMatrix& textureMatrix,
Greg Danielc77085d2017-11-01 16:38:48 -040094 const SkRect& constraintRect,
Brian Salomonaff329b2017-08-11 09:40:37 -040095 FilterConstraint filterConstraint,
96 bool coordsLimitedToConstraintRect,
Brian Osman05c8f462018-10-22 17:13:36 -040097 const GrSamplerState::Filter* filterOrNullForBicubic) {
Brian Salomonc8d092a2020-02-24 10:14:21 -050098 GrSurfaceProxyView view = this->viewForParams(filterOrNullForBicubic);
99 if (!view) {
Brian Osmane8e54582016-11-28 10:06:27 -0500100 return nullptr;
101 }
Greg Danielcc104db2020-02-03 14:17:08 -0500102 SkASSERT(view.asTextureProxy());
Brian Osmane8e54582016-11-28 10:06:27 -0500103
Michael Ludwigddeed372019-02-20 16:50:10 -0500104 SkRect domain;
Brian Osmane8e54582016-11-28 10:06:27 -0500105 DomainMode domainMode =
Greg Danielc77085d2017-11-01 16:38:48 -0400106 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
Greg Danielcc104db2020-02-03 14:17:08 -0500107 view.proxy(), filterOrNullForBicubic, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500108 if (kTightCopy_DomainMode == domainMode) {
109 // TODO: Copy the texture and adjust the texture matrix (both parts need to consider
110 // non-int constraint rect)
111 // For now: treat as bilerp and ignore what goes on above level 0.
112
113 // We only expect MIP maps to require a tight copy.
114 SkASSERT(filterOrNullForBicubic &&
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400115 GrSamplerState::Filter::kMipMap == *filterOrNullForBicubic);
116 static const GrSamplerState::Filter kBilerp = GrSamplerState::Filter::kBilerp;
Brian Osmane8e54582016-11-28 10:06:27 -0500117 domainMode =
Greg Danielc77085d2017-11-01 16:38:48 -0400118 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
Greg Danielcc104db2020-02-03 14:17:08 -0500119 view.proxy(), &kBilerp, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500120 SkASSERT(kTightCopy_DomainMode != domainMode);
121 }
122 SkASSERT(kNoDomain_DomainMode == domainMode ||
123 (domain.fLeft <= domain.fRight && domain.fTop <= domain.fBottom));
Michael Ludwigddeed372019-02-20 16:50:10 -0500124 return this->createFragmentProcessorForDomainAndFilter(
Greg Danielcc104db2020-02-03 14:17:08 -0500125 std::move(view), textureMatrix, domainMode, domain, filterOrNullForBicubic);
Brian Osmane8e54582016-11-28 10:06:27 -0500126}