blob: 07c080e12bc819a4ebe7f5e249a48a516685253b [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 -050025GrSurfaceProxyView GrTextureAdjuster::makeMippedCopy() {
Robert Phillips9338c602019-02-19 12:52:29 -050026 GrProxyProvider* proxyProvider = this->context()->priv().proxyProvider();
Robert Phillips1afd4cd2018-01-08 13:40:32 -050027
Brian Salomonb62cee32020-02-28 13:34:16 -050028 GrUniqueKey baseKey, mipMappedKey;
29 GrMakeKeyFromImageID(&baseKey, fUniqueID, SkIRect::MakeSize(this->dimensions()));
30 if (baseKey.isValid()) {
31 static const GrUniqueKey::Domain kMipMappedDomain = GrUniqueKey::GenerateDomain();
32 GrUniqueKey::Builder builder(&mipMappedKey, baseKey, kMipMappedDomain, 0);
33 }
Greg Daniel09c94002018-06-08 22:11:51 +000034 sk_sp<GrTextureProxy> cachedCopy;
Brian Salomonb62cee32020-02-28 13:34:16 -050035 if (mipMappedKey.isValid()) {
36 cachedCopy = proxyProvider->findOrCreateProxyByUniqueKey(mipMappedKey, this->colorType());
Brian Salomonc8d092a2020-02-24 10:14:21 -050037 if (cachedCopy) {
Brian Salomonb62cee32020-02-28 13:34:16 -050038 return {std::move(cachedCopy), fOriginal.origin(), fOriginal.swizzle()};
Robert Phillips0c984a02017-03-16 07:51:56 -040039 }
40 }
41
Brian Salomonc8d092a2020-02-24 10:14:21 -050042 GrSurfaceProxyView copyView = GrCopyBaseMipMapToTextureProxy(
Brian Salomonb62cee32020-02-28 13:34:16 -050043 this->context(), fOriginal.proxy(), fOriginal.origin(), this->colorType());
Brian Salomonc8d092a2020-02-24 10:14:21 -050044 if (!copyView) {
45 return {};
Greg Danielcce65002020-01-23 11:16:49 -050046 }
Brian Salomonb62cee32020-02-28 13:34:16 -050047 if (mipMappedKey.isValid()) {
48 SkASSERT(copyView.origin() == fOriginal.origin());
49 // TODO: If we move listeners up from SkImage_Lazy to SkImage_Base then add one here.
50 proxyProvider->assignUniqueKeyToProxy(mipMappedKey, copyView.asTextureProxy());
Brian Osmane8e54582016-11-28 10:06:27 -050051 }
Greg Danielcc104db2020-02-03 14:17:08 -050052 return copyView;
Brian Osmane8e54582016-11-28 10:06:27 -050053}
54
Brian Salomonecbb0fb2020-02-28 18:07:32 -050055GrSurfaceProxyView GrTextureAdjuster::onView(GrMipMapped mipMapped) {
Robert Phillips9338c602019-02-19 12:52:29 -050056 if (this->context()->priv().abandoned()) {
Brian Osmane8e54582016-11-28 10:06:27 -050057 // The texture was abandoned.
Greg Danielcc104db2020-02-03 14:17:08 -050058 return {};
Brian Osmane8e54582016-11-28 10:06:27 -050059 }
Brian Salomon4df00922017-09-07 16:34:11 +000060
Robert Phillips9338c602019-02-19 12:52:29 -050061 SkASSERT(this->width() <= this->context()->priv().caps()->maxTextureSize() &&
62 this->height() <= this->context()->priv().caps()->maxTextureSize());
Brian Osman875f7852018-04-12 13:29:08 -040063
Brian Salomonb62cee32020-02-28 13:34:16 -050064 GrTextureProxy* texProxy = fOriginal.asTextureProxy();
Greg Danielcc104db2020-02-03 14:17:08 -050065 SkASSERT(texProxy);
Brian Salomonecbb0fb2020-02-28 18:07:32 -050066 if (mipMapped == GrMipMapped::kNo || texProxy->mipMapped() == GrMipMapped::kYes) {
Brian Salomonb62cee32020-02-28 13:34:16 -050067 return fOriginal;
Brian Osmane8e54582016-11-28 10:06:27 -050068 }
69
Brian Salomonc8d092a2020-02-24 10:14:21 -050070 GrSurfaceProxyView copy = this->makeMippedCopy();
71 if (!copy) {
Greg Daniel8f5bbda2018-06-08 17:22:23 -040072 // If we were unable to make a copy and we only needed a copy for mips, then we will return
73 // the source texture here and require that the GPU backend is able to fall back to using
74 // bilerp if mips are required.
Brian Salomonb62cee32020-02-28 13:34:16 -050075 return fOriginal;
Greg Daniel8f5bbda2018-06-08 17:22:23 -040076 }
Brian Salomonc8d092a2020-02-24 10:14:21 -050077 SkASSERT(copy.asTextureProxy());
78 return copy;
Brian Osmane8e54582016-11-28 10:06:27 -050079}
80
Brian Salomonaff329b2017-08-11 09:40:37 -040081std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor(
Brian Salomonc8d092a2020-02-24 10:14:21 -050082 const SkMatrix& textureMatrix,
Greg Danielc77085d2017-11-01 16:38:48 -040083 const SkRect& constraintRect,
Brian Salomonaff329b2017-08-11 09:40:37 -040084 FilterConstraint filterConstraint,
85 bool coordsLimitedToConstraintRect,
Brian Osman05c8f462018-10-22 17:13:36 -040086 const GrSamplerState::Filter* filterOrNullForBicubic) {
Brian Salomonecbb0fb2020-02-28 18:07:32 -050087 GrSurfaceProxyView view;
88 if (filterOrNullForBicubic) {
89 view = this->view(*filterOrNullForBicubic);
90 } else {
91 view = this->view(GrMipMapped::kNo);
92 }
Brian Salomonc8d092a2020-02-24 10:14:21 -050093 if (!view) {
Brian Osmane8e54582016-11-28 10:06:27 -050094 return nullptr;
95 }
Greg Danielcc104db2020-02-03 14:17:08 -050096 SkASSERT(view.asTextureProxy());
Brian Osmane8e54582016-11-28 10:06:27 -050097
Michael Ludwigddeed372019-02-20 16:50:10 -050098 SkRect domain;
Brian Osmane8e54582016-11-28 10:06:27 -050099 DomainMode domainMode =
Greg Danielc77085d2017-11-01 16:38:48 -0400100 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
Greg Danielcc104db2020-02-03 14:17:08 -0500101 view.proxy(), filterOrNullForBicubic, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500102 if (kTightCopy_DomainMode == domainMode) {
103 // TODO: Copy the texture and adjust the texture matrix (both parts need to consider
104 // non-int constraint rect)
105 // For now: treat as bilerp and ignore what goes on above level 0.
106
107 // We only expect MIP maps to require a tight copy.
108 SkASSERT(filterOrNullForBicubic &&
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400109 GrSamplerState::Filter::kMipMap == *filterOrNullForBicubic);
110 static const GrSamplerState::Filter kBilerp = GrSamplerState::Filter::kBilerp;
Brian Osmane8e54582016-11-28 10:06:27 -0500111 domainMode =
Greg Danielc77085d2017-11-01 16:38:48 -0400112 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
Greg Danielcc104db2020-02-03 14:17:08 -0500113 view.proxy(), &kBilerp, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500114 SkASSERT(kTightCopy_DomainMode != domainMode);
115 }
116 SkASSERT(kNoDomain_DomainMode == domainMode ||
117 (domain.fLeft <= domain.fRight && domain.fTop <= domain.fBottom));
Michael Ludwigddeed372019-02-20 16:50:10 -0500118 return this->createFragmentProcessorForDomainAndFilter(
Greg Danielcc104db2020-02-03 14:17:08 -0500119 std::move(view), textureMatrix, domainMode, domain, filterOrNullForBicubic);
Brian Osmane8e54582016-11-28 10:06:27 -0500120}