blob: cc3d490d3c8f9943d9e633299313218fc6543119 [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
10#include "GrContext.h"
11#include "GrGpu.h"
Brian Osman32342f02017-03-04 08:12:46 -050012#include "GrResourceProvider.h"
Brian Osmane8e54582016-11-28 10:06:27 -050013
Brian Salomon2bbdcc42017-09-07 12:36:34 -040014sk_sp<GrTextureProxy> GrTextureMaker::refTextureProxyForParams(const GrSamplerState& params,
Robert Phillips3798c862017-03-27 11:08:16 -040015 SkColorSpace* dstColorSpace,
16 sk_sp<SkColorSpace>* texColorSpace,
17 SkScalar scaleAdjust[2]) {
Brian Osmane8e54582016-11-28 10:06:27 -050018 CopyParams copyParams;
Brian Salomon2bbdcc42017-09-07 12:36:34 -040019 bool willBeMipped = params.filter() == GrSamplerState::Filter::kMipMap;
Brian Osmane8e54582016-11-28 10:06:27 -050020
21 if (!fContext->caps()->mipMapSupport()) {
22 willBeMipped = false;
23 }
24
25 if (texColorSpace) {
Brian Osman61624f02016-12-09 14:51:59 -050026 *texColorSpace = this->getColorSpace(dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050027 }
28
Stan Ilievba81af22017-06-08 15:16:53 -040029 sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
30 AllowedTexGenType::kCheap));
31 if (original) {
32 if (!fContext->getGpu()->isACopyNeededForTextureParams(original.get(), params, &copyParams,
33 scaleAdjust)) {
34 return original;
35 }
36 } else {
37 if (!fContext->getGpu()->isACopyNeededForTextureParams(this->width(), this->height(),
38 params, &copyParams, scaleAdjust)) {
39 return this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
40 AllowedTexGenType::kAny);
41 }
Brian Osmane8e54582016-11-28 10:06:27 -050042 }
Stan Ilievba81af22017-06-08 15:16:53 -040043
Robert Phillips066f0202017-07-25 10:16:35 -040044 GrSurfaceOrigin origOrigin;
Brian Osmane8e54582016-11-28 10:06:27 -050045 GrUniqueKey copyKey;
Brian Osman61624f02016-12-09 14:51:59 -050046 this->makeCopyKey(copyParams, &copyKey, dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -050047 if (copyKey.isValid()) {
Robert Phillipsd3e247f2017-07-25 08:00:17 -040048 if (original) {
49 origOrigin = original->origin();
50 } else {
51 origOrigin = kTopLeft_GrSurfaceOrigin;
52 }
Greg Danielcd871402017-09-26 12:49:26 -040053 sk_sp<GrTextureProxy> result(fContext->resourceProvider()->findOrCreateProxyByUniqueKey(
Robert Phillips066f0202017-07-25 10:16:35 -040054 copyKey, origOrigin));
Brian Osmane8e54582016-11-28 10:06:27 -050055 if (result) {
56 return result;
57 }
58 }
59
Stan Ilievba81af22017-06-08 15:16:53 -040060 sk_sp<GrTextureProxy> result;
61 if (original) {
Greg Daniele1da1d92017-10-06 15:59:27 -040062 result = CopyOnGpu(fContext, std::move(original), nullptr, copyParams, willBeMipped);
Stan Ilievba81af22017-06-08 15:16:53 -040063 } else {
64 result = this->generateTextureProxyForParams(copyParams, willBeMipped, dstColorSpace);
65 }
66
Brian Osmane8e54582016-11-28 10:06:27 -050067 if (!result) {
68 return nullptr;
69 }
70
71 if (copyKey.isValid()) {
Robert Phillipsd3e247f2017-07-25 08:00:17 -040072 SkASSERT(result->origin() == origOrigin);
Robert Phillips3798c862017-03-27 11:08:16 -040073 fContext->resourceProvider()->assignUniqueKeyToProxy(copyKey, result.get());
Brian Osmane8e54582016-11-28 10:06:27 -050074 this->didCacheCopy(copyKey);
75 }
76 return result;
77}
78
Brian Salomonaff329b2017-08-11 09:40:37 -040079std::unique_ptr<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
80 const SkMatrix& textureMatrix,
81 const SkRect& constraintRect,
82 FilterConstraint filterConstraint,
83 bool coordsLimitedToConstraintRect,
Brian Salomon2bbdcc42017-09-07 12:36:34 -040084 const GrSamplerState::Filter* filterOrNullForBicubic,
Brian Salomonaff329b2017-08-11 09:40:37 -040085 SkColorSpace* dstColorSpace) {
Brian Salomon2bbdcc42017-09-07 12:36:34 -040086 const GrSamplerState::Filter* fmForDetermineDomain = filterOrNullForBicubic;
87 if (filterOrNullForBicubic && GrSamplerState::Filter::kMipMap == *filterOrNullForBicubic &&
Brian Osmane8e54582016-11-28 10:06:27 -050088 kYes_FilterConstraint == filterConstraint) {
89 // TODo: Here we should force a copy restricted to the constraintRect since MIP maps will
90 // read outside the constraint rect. However, as in the adjuster case, we aren't currently
91 // doing that.
92 // We instead we compute the domain as though were bilerping which is only correct if we
93 // only sample level 0.
Brian Salomon2bbdcc42017-09-07 12:36:34 -040094 static const GrSamplerState::Filter kBilerp = GrSamplerState::Filter::kBilerp;
Brian Osmane8e54582016-11-28 10:06:27 -050095 fmForDetermineDomain = &kBilerp;
96 }
97
Brian Salomon2bbdcc42017-09-07 12:36:34 -040098 GrSamplerState samplerState;
Brian Osmane8e54582016-11-28 10:06:27 -050099 if (filterOrNullForBicubic) {
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400100 samplerState = GrSamplerState(GrSamplerState::WrapMode::kClamp, *filterOrNullForBicubic);
Brian Osmane8e54582016-11-28 10:06:27 -0500101 } else {
102 // Bicubic doesn't use filtering for it's texture accesses.
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400103 samplerState = GrSamplerState::ClampNearest();
Brian Osmane8e54582016-11-28 10:06:27 -0500104 }
105 sk_sp<SkColorSpace> texColorSpace;
Robert Phillips67c18d62017-01-20 12:44:06 -0500106 SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400107 sk_sp<GrTextureProxy> proxy(this->refTextureProxyForParams(samplerState, dstColorSpace,
108 &texColorSpace, scaleAdjust));
Robert Phillips3798c862017-03-27 11:08:16 -0400109 if (!proxy) {
Brian Osmane8e54582016-11-28 10:06:27 -0500110 return nullptr;
111 }
Robert Phillips67c18d62017-01-20 12:44:06 -0500112 SkMatrix adjustedMatrix = textureMatrix;
113 adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
Brian Osmane8e54582016-11-28 10:06:27 -0500114 SkRect domain;
115 DomainMode domainMode =
Brian Salomon4df00922017-09-07 16:34:11 +0000116 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
117 proxy.get(),
118 nullptr, fmForDetermineDomain, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500119 SkASSERT(kTightCopy_DomainMode != domainMode);
Brian Osman5e341672017-10-18 10:23:18 -0400120 auto fp = CreateFragmentProcessorForDomainAndFilter(std::move(proxy), adjustedMatrix,
121 domainMode, domain, filterOrNullForBicubic);
122 return GrColorSpaceXformEffect::Make(std::move(fp), texColorSpace.get(), dstColorSpace);
Brian Osmane8e54582016-11-28 10:06:27 -0500123}
124
Robert Phillips3798c862017-03-27 11:08:16 -0400125sk_sp<GrTextureProxy> GrTextureMaker::generateTextureProxyForParams(const CopyParams& copyParams,
126 bool willBeMipped,
127 SkColorSpace* dstColorSpace) {
Stan Ilievba81af22017-06-08 15:16:53 -0400128 sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
129 AllowedTexGenType::kAny));
Brian Osmane8e54582016-11-28 10:06:27 -0500130 if (!original) {
131 return nullptr;
132 }
Robert Phillips4f358be2017-03-23 08:21:00 -0400133
Greg Daniele1da1d92017-10-06 15:59:27 -0400134 return CopyOnGpu(fContext, std::move(original), nullptr, copyParams, willBeMipped);
Brian Osmane8e54582016-11-28 10:06:27 -0500135}