blob: cc61533044d28fcd1e547592e11ca3a0194fee63 [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"
Brian Osman1cb41712017-10-19 12:54:52 -04009#include "GrColorSpaceXform.h"
Brian Osmane8e54582016-11-28 10:06:27 -050010#include "GrContext.h"
Robert Phillips1afd4cd2018-01-08 13:40:32 -050011#include "GrContextPriv.h"
Robert Phillips009e9af2017-06-15 14:01:04 -040012#include "GrGpu.h"
Robert Phillips1afd4cd2018-01-08 13:40:32 -050013#include "GrProxyProvider.h"
Brian Osman3b655982017-03-07 16:58:08 -050014#include "SkGr.h"
Brian Osmane8e54582016-11-28 10:06:27 -050015
Robert Phillips3798c862017-03-27 11:08:16 -040016GrTextureAdjuster::GrTextureAdjuster(GrContext* context, sk_sp<GrTextureProxy> original,
Brian Salomon4df00922017-09-07 16:34:11 +000017 SkAlphaType alphaType,
Greg Danielc77085d2017-11-01 16:38:48 -040018 uint32_t uniqueID,
Brian Salomon4df00922017-09-07 16:34:11 +000019 SkColorSpace* cs)
Greg Danielc77085d2017-11-01 16:38:48 -040020 : INHERITED(original->width(), original->height(),
Brian Salomon4df00922017-09-07 16:34:11 +000021 GrPixelConfigIsAlphaOnly(original->config()))
22 , fContext(context)
23 , fOriginal(std::move(original))
24 , fAlphaType(alphaType)
25 , fColorSpace(cs)
Greg Danielc77085d2017-11-01 16:38:48 -040026 , fUniqueID(uniqueID) {}
Brian Osmane8e54582016-11-28 10:06:27 -050027
28void GrTextureAdjuster::makeCopyKey(const CopyParams& params, GrUniqueKey* copyKey,
Brian Osman61624f02016-12-09 14:51:59 -050029 SkColorSpace* dstColorSpace) {
30 // Destination color space is irrelevant - we already have a texture so we're just sub-setting
Brian Osmane8e54582016-11-28 10:06:27 -050031 GrUniqueKey baseKey;
32 GrMakeKeyFromImageID(&baseKey, fUniqueID, SkIRect::MakeWH(this->width(), this->height()));
33 MakeCopyKeyFromOrigKey(baseKey, params, copyKey);
34}
35
36void GrTextureAdjuster::didCacheCopy(const GrUniqueKey& copyKey) {
37 // We don't currently have a mechanism for notifications on Images!
38}
39
Greg Daniele1da1d92017-10-06 15:59:27 -040040sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxyCopy(const CopyParams& copyParams,
41 bool willBeMipped) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -050042 GrProxyProvider* proxyProvider = fContext->contextPriv().proxyProvider();
43
Robert Phillips0c984a02017-03-16 07:51:56 -040044 GrUniqueKey key;
45 this->makeCopyKey(copyParams, &key, nullptr);
46 if (key.isValid()) {
Greg Danielcd871402017-09-26 12:49:26 -040047 sk_sp<GrTextureProxy> cachedCopy =
Robert Phillips1afd4cd2018-01-08 13:40:32 -050048 proxyProvider->findOrCreateProxyByUniqueKey(key, this->originalProxy()->origin());
Robert Phillips0c984a02017-03-16 07:51:56 -040049 if (cachedCopy) {
50 return cachedCopy;
51 }
52 }
53
54 sk_sp<GrTextureProxy> proxy = this->originalProxyRef();
Robert Phillips0c984a02017-03-16 07:51:56 -040055
Greg Danielc77085d2017-11-01 16:38:48 -040056 sk_sp<GrTextureProxy> copy = CopyOnGpu(fContext, std::move(proxy), copyParams, willBeMipped);
Robert Phillips0c984a02017-03-16 07:51:56 -040057 if (copy) {
58 if (key.isValid()) {
Robert Phillips78814092017-07-24 15:26:17 -040059 SkASSERT(copy->origin() == this->originalProxy()->origin());
Robert Phillips1afd4cd2018-01-08 13:40:32 -050060 proxyProvider->assignUniqueKeyToProxy(key, copy.get());
Brian Osmane8e54582016-11-28 10:06:27 -050061 this->didCacheCopy(key);
62 }
63 }
64 return copy;
65}
66
Brian Salomon2a943df2018-05-04 13:43:19 -040067sk_sp<GrTextureProxy> GrTextureAdjuster::onRefTextureProxyForParams(
68 const GrSamplerState& params,
69 SkColorSpace* dstColorSpace,
70 sk_sp<SkColorSpace>* texColorSpace,
71 SkScalar scaleAdjust[2]) {
Robert Phillips3798c862017-03-27 11:08:16 -040072 sk_sp<GrTextureProxy> proxy = this->originalProxyRef();
Brian Osmane8e54582016-11-28 10:06:27 -050073 CopyParams copyParams;
Brian Osmane8e54582016-11-28 10:06:27 -050074
Robert Phillips0c984a02017-03-16 07:51:56 -040075 if (!fContext) {
Brian Osmane8e54582016-11-28 10:06:27 -050076 // The texture was abandoned.
77 return nullptr;
78 }
Brian Salomon4df00922017-09-07 16:34:11 +000079
Brian Salomon2a943df2018-05-04 13:43:19 -040080 if (texColorSpace) {
81 *texColorSpace = sk_ref_sp(fColorSpace);
82 }
Brian Salomonc7fe0f72018-05-11 10:14:21 -040083 SkASSERT(this->width() <= fContext->contextPriv().caps()->maxTextureSize() &&
84 this->height() <= fContext->contextPriv().caps()->maxTextureSize());
Brian Osman875f7852018-04-12 13:29:08 -040085
Brian Salomonc7fe0f72018-05-11 10:14:21 -040086 if (!GrGpu::IsACopyNeededForTextureParams(fContext->contextPriv().caps(), proxy.get(),
87 proxy->width(), proxy->height(), params, &copyParams,
88 scaleAdjust)) {
Robert Phillips3798c862017-03-27 11:08:16 -040089 return proxy;
Brian Osmane8e54582016-11-28 10:06:27 -050090 }
91
Greg Danielc77085d2017-11-01 16:38:48 -040092 bool willBeMipped = GrSamplerState::Filter::kMipMap == params.filter();
Greg Daniele1da1d92017-10-06 15:59:27 -040093 return this->refTextureProxyCopy(copyParams, willBeMipped);
Brian Osmane8e54582016-11-28 10:06:27 -050094}
95
Brian Salomonaff329b2017-08-11 09:40:37 -040096std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor(
97 const SkMatrix& origTextureMatrix,
Greg Danielc77085d2017-11-01 16:38:48 -040098 const SkRect& constraintRect,
Brian Salomonaff329b2017-08-11 09:40:37 -040099 FilterConstraint filterConstraint,
100 bool coordsLimitedToConstraintRect,
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400101 const GrSamplerState::Filter* filterOrNullForBicubic,
Brian Salomonaff329b2017-08-11 09:40:37 -0400102 SkColorSpace* dstColorSpace) {
Brian Osmane8e54582016-11-28 10:06:27 -0500103 SkMatrix textureMatrix = origTextureMatrix;
Brian Osmane8e54582016-11-28 10:06:27 -0500104
105 SkRect domain;
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400106 GrSamplerState samplerState;
Brian Osmane8e54582016-11-28 10:06:27 -0500107 if (filterOrNullForBicubic) {
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400108 samplerState.setFilterMode(*filterOrNullForBicubic);
Brian Osmane8e54582016-11-28 10:06:27 -0500109 }
Robert Phillips67c18d62017-01-20 12:44:06 -0500110 SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400111 sk_sp<GrTextureProxy> proxy(
Brian Salomon2a943df2018-05-04 13:43:19 -0400112 this->refTextureProxyForParams(samplerState, nullptr, nullptr, scaleAdjust));
Robert Phillips3798c862017-03-27 11:08:16 -0400113 if (!proxy) {
Brian Osmane8e54582016-11-28 10:06:27 -0500114 return nullptr;
115 }
116 // If we made a copy then we only copied the contentArea, in which case the new texture is all
117 // content.
Robert Phillips3798c862017-03-27 11:08:16 -0400118 if (proxy.get() != this->originalProxy()) {
Robert Phillips67c18d62017-01-20 12:44:06 -0500119 textureMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
Brian Osmane8e54582016-11-28 10:06:27 -0500120 }
121
122 DomainMode domainMode =
Greg Danielc77085d2017-11-01 16:38:48 -0400123 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
124 proxy.get(), filterOrNullForBicubic, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500125 if (kTightCopy_DomainMode == domainMode) {
126 // TODO: Copy the texture and adjust the texture matrix (both parts need to consider
127 // non-int constraint rect)
128 // For now: treat as bilerp and ignore what goes on above level 0.
129
130 // We only expect MIP maps to require a tight copy.
131 SkASSERT(filterOrNullForBicubic &&
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400132 GrSamplerState::Filter::kMipMap == *filterOrNullForBicubic);
133 static const GrSamplerState::Filter kBilerp = GrSamplerState::Filter::kBilerp;
Brian Osmane8e54582016-11-28 10:06:27 -0500134 domainMode =
Greg Danielc77085d2017-11-01 16:38:48 -0400135 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
136 proxy.get(), &kBilerp, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500137 SkASSERT(kTightCopy_DomainMode != domainMode);
138 }
139 SkASSERT(kNoDomain_DomainMode == domainMode ||
140 (domain.fLeft <= domain.fRight && domain.fTop <= domain.fBottom));
Brian Osmanf06ead92017-10-30 13:47:41 -0400141 GrPixelConfig config = proxy->config();
Brian Osman5e341672017-10-18 10:23:18 -0400142 auto fp = CreateFragmentProcessorForDomainAndFilter(std::move(proxy), textureMatrix,
143 domainMode, domain, filterOrNullForBicubic);
Brian Osmanf06ead92017-10-30 13:47:41 -0400144 return GrColorSpaceXformEffect::Make(std::move(fp), fColorSpace, config, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -0500145}