blob: 5043675a0d307d9c3988ee568361d44badc47dff [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 "GrTextureMaker.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"
Brian Osmane8e54582016-11-28 10:06:27 -050013#include "GrGpu.h"
Robert Phillips1afd4cd2018-01-08 13:40:32 -050014#include "GrProxyProvider.h"
Brian Osmane8e54582016-11-28 10:06:27 -050015
Brian Salomon2bbdcc42017-09-07 12:36:34 -040016sk_sp<GrTextureProxy> GrTextureMaker::refTextureProxyForParams(const GrSamplerState& params,
Robert Phillips3798c862017-03-27 11:08:16 -040017 SkColorSpace* dstColorSpace,
18 sk_sp<SkColorSpace>* texColorSpace,
19 SkScalar scaleAdjust[2]) {
Brian Osmane8e54582016-11-28 10:06:27 -050020 CopyParams copyParams;
Brian Salomon2bbdcc42017-09-07 12:36:34 -040021 bool willBeMipped = params.filter() == GrSamplerState::Filter::kMipMap;
Brian Osmane8e54582016-11-28 10:06:27 -050022
23 if (!fContext->caps()->mipMapSupport()) {
24 willBeMipped = false;
25 }
26
27 if (texColorSpace) {
Brian Osman61624f02016-12-09 14:51:59 -050028 *texColorSpace = this->getColorSpace(dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050029 }
30
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050031 GrGpu* gpu = fContext->contextPriv().getGpu();
Stan Ilievba81af22017-06-08 15:16:53 -040032 sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
33 AllowedTexGenType::kCheap));
34 if (original) {
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050035 if (!gpu->isACopyNeededForTextureParams(original.get(), params, &copyParams, scaleAdjust)) {
Stan Ilievba81af22017-06-08 15:16:53 -040036 return original;
37 }
38 } else {
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050039 if (!gpu->isACopyNeededForTextureParams(this->width(), this->height(),
40 params, &copyParams, scaleAdjust)) {
Stan Ilievba81af22017-06-08 15:16:53 -040041 return this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
42 AllowedTexGenType::kAny);
43 }
Brian Osmane8e54582016-11-28 10:06:27 -050044 }
Stan Ilievba81af22017-06-08 15:16:53 -040045
Robert Phillips1afd4cd2018-01-08 13:40:32 -050046 GrProxyProvider* proxyProvider = fContext->contextPriv().proxyProvider();
47
48 GrSurfaceOrigin origOrigin = original ? original->origin() : kTopLeft_GrSurfaceOrigin;
Brian Osmane8e54582016-11-28 10:06:27 -050049 GrUniqueKey copyKey;
Brian Osman61624f02016-12-09 14:51:59 -050050 this->makeCopyKey(copyParams, &copyKey, dstColorSpace);
Greg Daniel2d59d2f2017-10-31 15:25:14 -040051 sk_sp<GrTextureProxy> cachedProxy;
Brian Osmane8e54582016-11-28 10:06:27 -050052 if (copyKey.isValid()) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -050053 cachedProxy = proxyProvider->findOrCreateProxyByUniqueKey(copyKey, origOrigin);
Greg Daniel2d59d2f2017-10-31 15:25:14 -040054 if (cachedProxy && (!willBeMipped || GrMipMapped::kYes == cachedProxy->mipMapped())) {
55 return cachedProxy;
Brian Osmane8e54582016-11-28 10:06:27 -050056 }
57 }
58
Stan Ilievba81af22017-06-08 15:16:53 -040059 sk_sp<GrTextureProxy> result;
60 if (original) {
Greg Daniel2d59d2f2017-10-31 15:25:14 -040061 result = std::move(original);
62 } else if (cachedProxy) {
63 result = cachedProxy;
Stan Ilievba81af22017-06-08 15:16:53 -040064 } else {
Greg Daniel2d59d2f2017-10-31 15:25:14 -040065 // Since we will be copying this texture there is no reason to make it mipped
66 result = this->refOriginalTextureProxy(false, dstColorSpace,
67 AllowedTexGenType::kAny);
Stan Ilievba81af22017-06-08 15:16:53 -040068 }
Greg Daniel2d59d2f2017-10-31 15:25:14 -040069 if (!result) {
70 return nullptr;
71 }
72
Greg Danielc77085d2017-11-01 16:38:48 -040073 result = CopyOnGpu(fContext, std::move(result), copyParams, willBeMipped);
Stan Ilievba81af22017-06-08 15:16:53 -040074
Brian Osmane8e54582016-11-28 10:06:27 -050075 if (!result) {
76 return nullptr;
77 }
78
79 if (copyKey.isValid()) {
Robert Phillipsd3e247f2017-07-25 08:00:17 -040080 SkASSERT(result->origin() == origOrigin);
Greg Daniel2d59d2f2017-10-31 15:25:14 -040081 if (cachedProxy) {
82 SkASSERT(GrMipMapped::kYes == result->mipMapped() &&
83 GrMipMapped::kNo == cachedProxy->mipMapped());
84 // If we had a cachedProxy, that means there already is a proxy in the cache which
85 // matches the key, but it does not have mip levels and we require them. Thus we must
86 // remove the unique key from that proxy.
Robert Phillips1afd4cd2018-01-08 13:40:32 -050087 proxyProvider->removeUniqueKeyFromProxy(copyKey, cachedProxy.get());
Greg Daniel2d59d2f2017-10-31 15:25:14 -040088 }
Robert Phillips1afd4cd2018-01-08 13:40:32 -050089 proxyProvider->assignUniqueKeyToProxy(copyKey, result.get());
Brian Osmane8e54582016-11-28 10:06:27 -050090 this->didCacheCopy(copyKey);
91 }
92 return result;
93}
94
Brian Salomonaff329b2017-08-11 09:40:37 -040095std::unique_ptr<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
96 const SkMatrix& textureMatrix,
97 const SkRect& constraintRect,
98 FilterConstraint filterConstraint,
99 bool coordsLimitedToConstraintRect,
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400100 const GrSamplerState::Filter* filterOrNullForBicubic,
Brian Salomonaff329b2017-08-11 09:40:37 -0400101 SkColorSpace* dstColorSpace) {
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400102 const GrSamplerState::Filter* fmForDetermineDomain = filterOrNullForBicubic;
103 if (filterOrNullForBicubic && GrSamplerState::Filter::kMipMap == *filterOrNullForBicubic &&
Brian Osmane8e54582016-11-28 10:06:27 -0500104 kYes_FilterConstraint == filterConstraint) {
105 // TODo: Here we should force a copy restricted to the constraintRect since MIP maps will
106 // read outside the constraint rect. However, as in the adjuster case, we aren't currently
107 // doing that.
108 // We instead we compute the domain as though were bilerping which is only correct if we
109 // only sample level 0.
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400110 static const GrSamplerState::Filter kBilerp = GrSamplerState::Filter::kBilerp;
Brian Osmane8e54582016-11-28 10:06:27 -0500111 fmForDetermineDomain = &kBilerp;
112 }
113
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400114 GrSamplerState samplerState;
Brian Osmane8e54582016-11-28 10:06:27 -0500115 if (filterOrNullForBicubic) {
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400116 samplerState = GrSamplerState(GrSamplerState::WrapMode::kClamp, *filterOrNullForBicubic);
Brian Osmane8e54582016-11-28 10:06:27 -0500117 } else {
118 // Bicubic doesn't use filtering for it's texture accesses.
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400119 samplerState = GrSamplerState::ClampNearest();
Brian Osmane8e54582016-11-28 10:06:27 -0500120 }
121 sk_sp<SkColorSpace> texColorSpace;
Robert Phillips67c18d62017-01-20 12:44:06 -0500122 SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400123 sk_sp<GrTextureProxy> proxy(this->refTextureProxyForParams(samplerState, dstColorSpace,
124 &texColorSpace, scaleAdjust));
Robert Phillips3798c862017-03-27 11:08:16 -0400125 if (!proxy) {
Brian Osmane8e54582016-11-28 10:06:27 -0500126 return nullptr;
127 }
Robert Phillips67c18d62017-01-20 12:44:06 -0500128 SkMatrix adjustedMatrix = textureMatrix;
129 adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
Brian Osmane8e54582016-11-28 10:06:27 -0500130 SkRect domain;
131 DomainMode domainMode =
Brian Salomon4df00922017-09-07 16:34:11 +0000132 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
Greg Danielc77085d2017-11-01 16:38:48 -0400133 proxy.get(), fmForDetermineDomain, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500134 SkASSERT(kTightCopy_DomainMode != domainMode);
Brian Osmanf06ead92017-10-30 13:47:41 -0400135 GrPixelConfig config = proxy->config();
Brian Osman5e341672017-10-18 10:23:18 -0400136 auto fp = CreateFragmentProcessorForDomainAndFilter(std::move(proxy), adjustedMatrix,
137 domainMode, domain, filterOrNullForBicubic);
Brian Osmanf06ead92017-10-30 13:47:41 -0400138 return GrColorSpaceXformEffect::Make(std::move(fp), texColorSpace.get(), config, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -0500139}
140
Robert Phillips3798c862017-03-27 11:08:16 -0400141sk_sp<GrTextureProxy> GrTextureMaker::generateTextureProxyForParams(const CopyParams& copyParams,
142 bool willBeMipped,
143 SkColorSpace* dstColorSpace) {
Stan Ilievba81af22017-06-08 15:16:53 -0400144 sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
145 AllowedTexGenType::kAny));
Brian Osmane8e54582016-11-28 10:06:27 -0500146 if (!original) {
147 return nullptr;
148 }
Robert Phillips4f358be2017-03-23 08:21:00 -0400149
Greg Danielc77085d2017-11-01 16:38:48 -0400150 return CopyOnGpu(fContext, std::move(original), copyParams, willBeMipped);
Brian Osmane8e54582016-11-28 10:06:27 -0500151}