blob: f30b0eb03d0a31c7b6b895fa3160282b1729809e [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 "GrTextureAdjuster.h"
9
Brian Osman1cb41712017-10-19 12:54:52 -040010#include "GrColorSpaceXform.h"
Brian Osmane8e54582016-11-28 10:06:27 -050011#include "GrContext.h"
Robert Phillips1afd4cd2018-01-08 13:40:32 -050012#include "GrContextPriv.h"
Robert Phillips009e9af2017-06-15 14:01:04 -040013#include "GrGpu.h"
Robert Phillips1afd4cd2018-01-08 13:40:32 -050014#include "GrProxyProvider.h"
Brian Osman3b655982017-03-07 16:58:08 -050015#include "SkGr.h"
Brian Osmane8e54582016-11-28 10:06:27 -050016
Robert Phillips3798c862017-03-27 11:08:16 -040017GrTextureAdjuster::GrTextureAdjuster(GrContext* context, sk_sp<GrTextureProxy> original,
Brian Salomon4df00922017-09-07 16:34:11 +000018 SkAlphaType alphaType,
Greg Danielc77085d2017-11-01 16:38:48 -040019 uint32_t uniqueID,
Brian Salomon4df00922017-09-07 16:34:11 +000020 SkColorSpace* cs)
Greg Danielc77085d2017-11-01 16:38:48 -040021 : INHERITED(original->width(), original->height(),
Brian Salomon4df00922017-09-07 16:34:11 +000022 GrPixelConfigIsAlphaOnly(original->config()))
23 , fContext(context)
24 , fOriginal(std::move(original))
25 , fAlphaType(alphaType)
26 , fColorSpace(cs)
Greg Danielc77085d2017-11-01 16:38:48 -040027 , fUniqueID(uniqueID) {}
Brian Osmane8e54582016-11-28 10:06:27 -050028
29void GrTextureAdjuster::makeCopyKey(const CopyParams& params, GrUniqueKey* copyKey,
Brian Osman61624f02016-12-09 14:51:59 -050030 SkColorSpace* dstColorSpace) {
31 // Destination color space is irrelevant - we already have a texture so we're just sub-setting
Brian Osmane8e54582016-11-28 10:06:27 -050032 GrUniqueKey baseKey;
33 GrMakeKeyFromImageID(&baseKey, fUniqueID, SkIRect::MakeWH(this->width(), this->height()));
34 MakeCopyKeyFromOrigKey(baseKey, params, copyKey);
35}
36
37void GrTextureAdjuster::didCacheCopy(const GrUniqueKey& copyKey) {
38 // We don't currently have a mechanism for notifications on Images!
39}
40
Greg Daniele1da1d92017-10-06 15:59:27 -040041sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxyCopy(const CopyParams& copyParams,
42 bool willBeMipped) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -050043 GrProxyProvider* proxyProvider = fContext->contextPriv().proxyProvider();
44
Robert Phillips0c984a02017-03-16 07:51:56 -040045 GrUniqueKey key;
46 this->makeCopyKey(copyParams, &key, nullptr);
47 if (key.isValid()) {
Greg Danielcd871402017-09-26 12:49:26 -040048 sk_sp<GrTextureProxy> cachedCopy =
Robert Phillips1afd4cd2018-01-08 13:40:32 -050049 proxyProvider->findOrCreateProxyByUniqueKey(key, this->originalProxy()->origin());
Robert Phillips0c984a02017-03-16 07:51:56 -040050 if (cachedCopy) {
51 return cachedCopy;
52 }
53 }
54
55 sk_sp<GrTextureProxy> proxy = this->originalProxyRef();
Robert Phillips0c984a02017-03-16 07:51:56 -040056
Greg Danielc77085d2017-11-01 16:38:48 -040057 sk_sp<GrTextureProxy> copy = CopyOnGpu(fContext, std::move(proxy), copyParams, willBeMipped);
Robert Phillips0c984a02017-03-16 07:51:56 -040058 if (copy) {
59 if (key.isValid()) {
Robert Phillips78814092017-07-24 15:26:17 -040060 SkASSERT(copy->origin() == this->originalProxy()->origin());
Robert Phillips1afd4cd2018-01-08 13:40:32 -050061 proxyProvider->assignUniqueKeyToProxy(key, copy.get());
Brian Osmane8e54582016-11-28 10:06:27 -050062 this->didCacheCopy(key);
63 }
64 }
65 return copy;
66}
67
Brian Salomon2bbdcc42017-09-07 12:36:34 -040068sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxySafeForParams(const GrSamplerState& params,
Brian Salomon2bbdcc42017-09-07 12:36:34 -040069 SkScalar scaleAdjust[2]) {
Robert Phillips3798c862017-03-27 11:08:16 -040070 sk_sp<GrTextureProxy> proxy = this->originalProxyRef();
Brian Osmane8e54582016-11-28 10:06:27 -050071 CopyParams copyParams;
Brian Osmane8e54582016-11-28 10:06:27 -050072
Robert Phillips0c984a02017-03-16 07:51:56 -040073 if (!fContext) {
Brian Osmane8e54582016-11-28 10:06:27 -050074 // The texture was abandoned.
75 return nullptr;
76 }
Brian Salomon4df00922017-09-07 16:34:11 +000077
Brian Osman875f7852018-04-12 13:29:08 -040078 SkASSERT(this->width() <= fContext->caps()->maxTextureSize() &&
79 this->height() <= fContext->caps()->maxTextureSize());
80
Robert Phillipsabf7b762018-03-21 12:13:37 -040081 if (!GrGpu::IsACopyNeededForTextureParams(fContext->caps(),
82 proxy.get(), proxy->width(), proxy->height(),
83 params, &copyParams, scaleAdjust)) {
Robert Phillips3798c862017-03-27 11:08:16 -040084 return proxy;
Brian Osmane8e54582016-11-28 10:06:27 -050085 }
86
Greg Danielc77085d2017-11-01 16:38:48 -040087 bool willBeMipped = GrSamplerState::Filter::kMipMap == params.filter();
Greg Daniele1da1d92017-10-06 15:59:27 -040088 return this->refTextureProxyCopy(copyParams, willBeMipped);
Brian Osmane8e54582016-11-28 10:06:27 -050089}
90
Brian Salomonaff329b2017-08-11 09:40:37 -040091std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor(
92 const SkMatrix& origTextureMatrix,
Greg Danielc77085d2017-11-01 16:38:48 -040093 const SkRect& constraintRect,
Brian Salomonaff329b2017-08-11 09:40:37 -040094 FilterConstraint filterConstraint,
95 bool coordsLimitedToConstraintRect,
Brian Salomon2bbdcc42017-09-07 12:36:34 -040096 const GrSamplerState::Filter* filterOrNullForBicubic,
Brian Salomonaff329b2017-08-11 09:40:37 -040097 SkColorSpace* dstColorSpace) {
Brian Osmane8e54582016-11-28 10:06:27 -050098 SkMatrix textureMatrix = origTextureMatrix;
Brian Osmane8e54582016-11-28 10:06:27 -050099
100 SkRect domain;
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400101 GrSamplerState samplerState;
Brian Osmane8e54582016-11-28 10:06:27 -0500102 if (filterOrNullForBicubic) {
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400103 samplerState.setFilterMode(*filterOrNullForBicubic);
Brian Osmane8e54582016-11-28 10:06:27 -0500104 }
Robert Phillips67c18d62017-01-20 12:44:06 -0500105 SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400106 sk_sp<GrTextureProxy> proxy(
Greg Daniel4faa0402017-09-29 15:21:28 -0400107 this->refTextureProxySafeForParams(samplerState, scaleAdjust));
Robert Phillips3798c862017-03-27 11:08:16 -0400108 if (!proxy) {
Brian Osmane8e54582016-11-28 10:06:27 -0500109 return nullptr;
110 }
111 // If we made a copy then we only copied the contentArea, in which case the new texture is all
112 // content.
Robert Phillips3798c862017-03-27 11:08:16 -0400113 if (proxy.get() != this->originalProxy()) {
Robert Phillips67c18d62017-01-20 12:44:06 -0500114 textureMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
Brian Osmane8e54582016-11-28 10:06:27 -0500115 }
116
117 DomainMode domainMode =
Greg Danielc77085d2017-11-01 16:38:48 -0400118 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
119 proxy.get(), filterOrNullForBicubic, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500120 if (kTightCopy_DomainMode == domainMode) {
121 // TODO: Copy the texture and adjust the texture matrix (both parts need to consider
122 // non-int constraint rect)
123 // For now: treat as bilerp and ignore what goes on above level 0.
124
125 // We only expect MIP maps to require a tight copy.
126 SkASSERT(filterOrNullForBicubic &&
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400127 GrSamplerState::Filter::kMipMap == *filterOrNullForBicubic);
128 static const GrSamplerState::Filter kBilerp = GrSamplerState::Filter::kBilerp;
Brian Osmane8e54582016-11-28 10:06:27 -0500129 domainMode =
Greg Danielc77085d2017-11-01 16:38:48 -0400130 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
131 proxy.get(), &kBilerp, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500132 SkASSERT(kTightCopy_DomainMode != domainMode);
133 }
134 SkASSERT(kNoDomain_DomainMode == domainMode ||
135 (domain.fLeft <= domain.fRight && domain.fTop <= domain.fBottom));
Brian Osmanf06ead92017-10-30 13:47:41 -0400136 GrPixelConfig config = proxy->config();
Brian Osman5e341672017-10-18 10:23:18 -0400137 auto fp = CreateFragmentProcessorForDomainAndFilter(std::move(proxy), textureMatrix,
138 domainMode, domain, filterOrNullForBicubic);
Brian Osmanf06ead92017-10-30 13:47:41 -0400139 return GrColorSpaceXformEffect::Make(std::move(fp), fColorSpace, config, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -0500140}