blob: 96bcea4d61bc8910e3b1ed9ec8c5e1eee977d34c [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
Robert Phillips3798c862017-03-27 11:08:16 -040014sk_sp<GrTextureProxy> GrTextureMaker::refTextureProxyForParams(const GrSamplerParams& params,
15 SkColorSpace* dstColorSpace,
16 sk_sp<SkColorSpace>* texColorSpace,
17 SkScalar scaleAdjust[2]) {
Brian Osmane8e54582016-11-28 10:06:27 -050018 CopyParams copyParams;
19 bool willBeMipped = params.filterMode() == GrSamplerParams::kMipMap_FilterMode;
20
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 Phillipsd3e247f2017-07-25 08:00:17 -040044 SkDEBUGCODE(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#ifdef SK_DEBUG
49 if (original) {
50 origOrigin = original->origin();
51 } else {
52 origOrigin = kTopLeft_GrSurfaceOrigin;
53 }
54#endif
Robert Phillips96be9df2017-07-21 14:17:45 +000055 sk_sp<GrTextureProxy> result(fContext->resourceProvider()->findProxyByUniqueKey(copyKey));
Brian Osmane8e54582016-11-28 10:06:27 -050056 if (result) {
57 return result;
58 }
59 }
60
Stan Ilievba81af22017-06-08 15:16:53 -040061 sk_sp<GrTextureProxy> result;
62 if (original) {
63 result = CopyOnGpu(fContext, std::move(original), nullptr, copyParams);
64 } else {
65 result = this->generateTextureProxyForParams(copyParams, willBeMipped, dstColorSpace);
66 }
67
Brian Osmane8e54582016-11-28 10:06:27 -050068 if (!result) {
69 return nullptr;
70 }
71
72 if (copyKey.isValid()) {
Robert Phillipsd3e247f2017-07-25 08:00:17 -040073 SkASSERT(result->origin() == origOrigin);
Robert Phillips3798c862017-03-27 11:08:16 -040074 fContext->resourceProvider()->assignUniqueKeyToProxy(copyKey, result.get());
Brian Osmane8e54582016-11-28 10:06:27 -050075 this->didCacheCopy(copyKey);
76 }
77 return result;
78}
79
80sk_sp<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
81 const SkMatrix& textureMatrix,
82 const SkRect& constraintRect,
83 FilterConstraint filterConstraint,
84 bool coordsLimitedToConstraintRect,
85 const GrSamplerParams::FilterMode* filterOrNullForBicubic,
Brian Osman61624f02016-12-09 14:51:59 -050086 SkColorSpace* dstColorSpace) {
Brian Osmane8e54582016-11-28 10:06:27 -050087
88 const GrSamplerParams::FilterMode* fmForDetermineDomain = filterOrNullForBicubic;
89 if (filterOrNullForBicubic && GrSamplerParams::kMipMap_FilterMode == *filterOrNullForBicubic &&
90 kYes_FilterConstraint == filterConstraint) {
91 // TODo: Here we should force a copy restricted to the constraintRect since MIP maps will
92 // read outside the constraint rect. However, as in the adjuster case, we aren't currently
93 // doing that.
94 // We instead we compute the domain as though were bilerping which is only correct if we
95 // only sample level 0.
96 static const GrSamplerParams::FilterMode kBilerp = GrSamplerParams::kBilerp_FilterMode;
97 fmForDetermineDomain = &kBilerp;
98 }
99
100 GrSamplerParams params;
101 if (filterOrNullForBicubic) {
102 params.reset(SkShader::kClamp_TileMode, *filterOrNullForBicubic);
103 } else {
104 // Bicubic doesn't use filtering for it's texture accesses.
105 params.reset(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode);
106 }
107 sk_sp<SkColorSpace> texColorSpace;
Robert Phillips67c18d62017-01-20 12:44:06 -0500108 SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
Robert Phillips3798c862017-03-27 11:08:16 -0400109 sk_sp<GrTextureProxy> proxy(this->refTextureProxyForParams(params, dstColorSpace,
110 &texColorSpace,
111 scaleAdjust));
112 if (!proxy) {
Brian Osmane8e54582016-11-28 10:06:27 -0500113 return nullptr;
114 }
Robert Phillips67c18d62017-01-20 12:44:06 -0500115 SkMatrix adjustedMatrix = textureMatrix;
116 adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
Brian Osmane8e54582016-11-28 10:06:27 -0500117 SkRect domain;
118 DomainMode domainMode =
119 DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
Robert Phillips3798c862017-03-27 11:08:16 -0400120 proxy.get(),
Robert Phillipse98234f2017-01-09 14:23:59 -0500121 nullptr, fmForDetermineDomain, &domain);
Brian Osmane8e54582016-11-28 10:06:27 -0500122 SkASSERT(kTightCopy_DomainMode != domainMode);
Brian Osmane8e54582016-11-28 10:06:27 -0500123 sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(),
124 dstColorSpace);
Robert Phillipsfbcef6e2017-06-15 12:07:18 -0400125 return CreateFragmentProcessorForDomainAndFilter(std::move(proxy),
Robert Phillips3798c862017-03-27 11:08:16 -0400126 std::move(colorSpaceXform),
Robert Phillips67c18d62017-01-20 12:44:06 -0500127 adjustedMatrix, domainMode, domain,
Brian Osmane8e54582016-11-28 10:06:27 -0500128 filterOrNullForBicubic);
129}
130
Robert Phillips3798c862017-03-27 11:08:16 -0400131sk_sp<GrTextureProxy> GrTextureMaker::generateTextureProxyForParams(const CopyParams& copyParams,
132 bool willBeMipped,
133 SkColorSpace* dstColorSpace) {
Stan Ilievba81af22017-06-08 15:16:53 -0400134 sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
135 AllowedTexGenType::kAny));
Brian Osmane8e54582016-11-28 10:06:27 -0500136 if (!original) {
137 return nullptr;
138 }
Robert Phillips4f358be2017-03-23 08:21:00 -0400139
Robert Phillips3798c862017-03-27 11:08:16 -0400140 return CopyOnGpu(fContext, std::move(original), nullptr, copyParams);
Brian Osmane8e54582016-11-28 10:06:27 -0500141}