commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2012 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 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 8 | #include "src/gpu/effects/GrTextureDomain.h" |
Robert Phillips | 40fd7c9 | 2017-01-30 08:06:27 -0500 | [diff] [blame] | 9 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 10 | #include "include/gpu/GrTexture.h" |
| 11 | #include "include/private/SkFloatingPoint.h" |
| 12 | #include "src/gpu/GrProxyProvider.h" |
| 13 | #include "src/gpu/GrShaderCaps.h" |
| 14 | #include "src/gpu/GrSurfaceProxyPriv.h" |
| 15 | #include "src/gpu/effects/generated/GrSimpleTextureEffect.h" |
| 16 | #include "src/gpu/glsl/GrGLSLFragmentProcessor.h" |
| 17 | #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" |
| 18 | #include "src/gpu/glsl/GrGLSLProgramDataManager.h" |
| 19 | #include "src/gpu/glsl/GrGLSLShaderBuilder.h" |
| 20 | #include "src/gpu/glsl/GrGLSLUniformHandler.h" |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 21 | |
Ben Wagner | f08d1d0 | 2018-06-18 15:11:00 -0400 | [diff] [blame] | 22 | #include <utility> |
| 23 | |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 24 | GrTextureDomain::GrTextureDomain(GrTextureProxy* proxy, const SkRect& domain, Mode modeX, |
| 25 | Mode modeY, int index) |
| 26 | : fModeX(modeX) |
| 27 | , fModeY(modeY) |
Robert Phillips | 40fd7c9 | 2017-01-30 08:06:27 -0500 | [diff] [blame] | 28 | , fIndex(index) { |
| 29 | |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 30 | if (!proxy) { |
| 31 | SkASSERT(modeX == kIgnore_Mode && modeY == kIgnore_Mode); |
Robert Phillips | 40fd7c9 | 2017-01-30 08:06:27 -0500 | [diff] [blame] | 32 | return; |
| 33 | } |
| 34 | |
Brian Salomon | 9f2b86c | 2019-10-22 10:37:46 -0400 | [diff] [blame] | 35 | const SkRect kFullRect = proxy->getBoundsRect(); |
Robert Phillips | 40fd7c9 | 2017-01-30 08:06:27 -0500 | [diff] [blame] | 36 | |
| 37 | // We don't currently handle domains that are empty or don't intersect the texture. |
| 38 | // It is OK if the domain rect is a line or point, but it should not be inverted. We do not |
| 39 | // handle rects that do not intersect the [0..1]x[0..1] rect. |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 40 | SkASSERT(domain.fLeft <= domain.fRight); |
| 41 | SkASSERT(domain.fTop <= domain.fBottom); |
Robert Phillips | 40fd7c9 | 2017-01-30 08:06:27 -0500 | [diff] [blame] | 42 | fDomain.fLeft = SkScalarPin(domain.fLeft, 0.0f, kFullRect.fRight); |
| 43 | fDomain.fRight = SkScalarPin(domain.fRight, fDomain.fLeft, kFullRect.fRight); |
| 44 | fDomain.fTop = SkScalarPin(domain.fTop, 0.0f, kFullRect.fBottom); |
| 45 | fDomain.fBottom = SkScalarPin(domain.fBottom, fDomain.fTop, kFullRect.fBottom); |
| 46 | SkASSERT(fDomain.fLeft <= fDomain.fRight); |
| 47 | SkASSERT(fDomain.fTop <= fDomain.fBottom); |
| 48 | } |
| 49 | |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 50 | ////////////////////////////////////////////////////////////////////////////// |
| 51 | |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 52 | static SkString clamp_expression(GrTextureDomain::Mode mode, const char* inCoord, |
| 53 | const char* coordSwizzle, const char* domain, |
| 54 | const char* minSwizzle, const char* maxSwizzle) { |
| 55 | SkString clampedExpr; |
| 56 | switch(mode) { |
| 57 | case GrTextureDomain::kIgnore_Mode: |
| 58 | clampedExpr.printf("%s.%s\n", inCoord, coordSwizzle); |
| 59 | break; |
| 60 | case GrTextureDomain::kDecal_Mode: |
| 61 | // The lookup coordinate to use for decal will be clamped just like kClamp_Mode, |
| 62 | // it's just that the post-processing will be different, so fall through |
| 63 | case GrTextureDomain::kClamp_Mode: |
| 64 | clampedExpr.printf("clamp(%s.%s, %s.%s, %s.%s)", |
| 65 | inCoord, coordSwizzle, domain, minSwizzle, domain, maxSwizzle); |
| 66 | break; |
| 67 | case GrTextureDomain::kRepeat_Mode: |
| 68 | clampedExpr.printf("mod(%s.%s - %s.%s, %s.%s - %s.%s) + %s.%s", |
| 69 | inCoord, coordSwizzle, domain, minSwizzle, domain, maxSwizzle, |
| 70 | domain, minSwizzle, domain, minSwizzle); |
| 71 | break; |
| 72 | default: |
| 73 | SkASSERTF(false, "Unknown texture domain mode: %u\n", (uint32_t) mode); |
| 74 | break; |
| 75 | } |
| 76 | return clampedExpr; |
| 77 | } |
| 78 | |
egdaniel | 2d721d3 | 2015-11-11 13:06:05 -0800 | [diff] [blame] | 79 | void GrTextureDomain::GLDomain::sampleTexture(GrGLSLShaderBuilder* builder, |
egdaniel | 7ea439b | 2015-12-03 09:20:44 -0800 | [diff] [blame] | 80 | GrGLSLUniformHandler* uniformHandler, |
Brian Salomon | 1edc5b9 | 2016-11-29 13:43:46 -0500 | [diff] [blame] | 81 | const GrShaderCaps* shaderCaps, |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 82 | const GrTextureDomain& textureDomain, |
| 83 | const char* outColor, |
| 84 | const SkString& inCoords, |
egdaniel | 09aa1fc | 2016-04-20 07:09:46 -0700 | [diff] [blame] | 85 | GrGLSLFragmentProcessor::SamplerHandle sampler, |
Brian Osman | 2240be9 | 2017-10-18 13:15:13 -0400 | [diff] [blame] | 86 | const char* inModulateColor) { |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 87 | SkASSERT(!fHasMode || (textureDomain.modeX() == fModeX && textureDomain.modeY() == fModeY)); |
| 88 | SkDEBUGCODE(fModeX = textureDomain.modeX();) |
| 89 | SkDEBUGCODE(fModeY = textureDomain.modeY();) |
Hans Wennborg | c63ec5c | 2017-12-08 18:56:23 -0800 | [diff] [blame] | 90 | SkDEBUGCODE(fHasMode = true;) |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 91 | |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 92 | if ((textureDomain.modeX() != kIgnore_Mode || textureDomain.modeY() != kIgnore_Mode) && |
| 93 | !fDomainUni.isValid()) { |
| 94 | // Must include the domain uniform since at least one axis uses it |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 95 | const char* name; |
| 96 | SkString uniName("TexDom"); |
| 97 | if (textureDomain.fIndex >= 0) { |
| 98 | uniName.appendS32(textureDomain.fIndex); |
| 99 | } |
Ethan Nicholas | f7b8820 | 2017-09-18 14:10:39 -0400 | [diff] [blame] | 100 | fDomainUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, |
egdaniel | 7ea439b | 2015-12-03 09:20:44 -0800 | [diff] [blame] | 101 | uniName.c_str(), &name); |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 102 | fDomainName = name; |
| 103 | } |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 104 | |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 105 | bool decalX = textureDomain.modeX() == kDecal_Mode; |
| 106 | bool decalY = textureDomain.modeY() == kDecal_Mode; |
| 107 | if ((decalX || decalY) && !fDecalUni.isValid()) { |
| 108 | const char* name; |
| 109 | SkString uniName("DecalParams"); |
| 110 | if (textureDomain.fIndex >= 0) { |
| 111 | uniName.appendS32(textureDomain.fIndex); |
joshualitt | 5ae5fc5 | 2014-07-29 12:59:27 -0700 | [diff] [blame] | 112 | } |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 113 | // Half3 since this will hold texture width, height, and then a step function control param |
| 114 | fDecalUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf3_GrSLType, |
| 115 | uniName.c_str(), &name); |
| 116 | fDecalName = name; |
| 117 | } |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 118 | |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 119 | // Add a block so that we can declare variables |
| 120 | GrGLSLShaderBuilder::ShaderBlock block(builder); |
| 121 | // Always use a local variable for the input coordinates; often callers pass in an expression |
| 122 | // and we want to cache it across all of its references in the code below |
| 123 | builder->codeAppendf("float2 origCoord = %s;", inCoords.c_str()); |
| 124 | builder->codeAppend("float2 clampedCoord = "); |
| 125 | if (textureDomain.modeX() != textureDomain.modeY()) { |
| 126 | // The wrap modes differ on the two axes, so build up a coordinate that respects each axis' |
| 127 | // domain rule independently before sampling the texture. |
| 128 | SkString tcX = clamp_expression(textureDomain.modeX(), "origCoord", "x", |
| 129 | fDomainName.c_str(), "x", "z"); |
| 130 | SkString tcY = clamp_expression(textureDomain.modeY(), "origCoord", "y", |
| 131 | fDomainName.c_str(), "y", "w"); |
| 132 | builder->codeAppendf("float2(%s, %s)", tcX.c_str(), tcY.c_str()); |
| 133 | } else { |
| 134 | // Since the x and y axis wrap modes are the same, they can be calculated together using |
| 135 | // more efficient vector operations |
| 136 | SkString tc = clamp_expression(textureDomain.modeX(), "origCoord", "xy", |
| 137 | fDomainName.c_str(), "xy", "zw"); |
| 138 | builder->codeAppend(tc.c_str()); |
| 139 | } |
| 140 | builder->codeAppend(";"); |
| 141 | |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 142 | // Look up the texture sample at the clamped coordinate location |
| 143 | builder->codeAppend("half4 inside = "); |
| 144 | builder->appendTextureLookupAndModulate(inModulateColor, sampler, "clampedCoord", |
| 145 | kFloat2_GrSLType); |
| 146 | builder->codeAppend(";"); |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 147 | |
| 148 | // Apply decal mode's transparency interpolation if needed |
| 149 | if (decalX || decalY) { |
| 150 | // The decal err is the max absoluate value between the clamped coordinate and the original |
| 151 | // pixel coordinate. This will then be clamped to 1.f if it's greater than the control |
| 152 | // parameter, which simulates kNearest and kBilerp behavior depending on if it's 0 or 1. |
| 153 | if (decalX && decalY) { |
Ethan Nicholas | e1f5502 | 2019-02-05 17:17:40 -0500 | [diff] [blame] | 154 | builder->codeAppendf("half err = max(half(abs(clampedCoord.x - origCoord.x) * %s.x), " |
| 155 | "half(abs(clampedCoord.y - origCoord.y) * %s.y));", |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 156 | fDecalName.c_str(), fDecalName.c_str()); |
| 157 | } else if (decalX) { |
Ethan Nicholas | e1f5502 | 2019-02-05 17:17:40 -0500 | [diff] [blame] | 158 | builder->codeAppendf("half err = half(abs(clampedCoord.x - origCoord.x) * %s.x);", |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 159 | fDecalName.c_str()); |
| 160 | } else { |
| 161 | SkASSERT(decalY); |
Ethan Nicholas | e1f5502 | 2019-02-05 17:17:40 -0500 | [diff] [blame] | 162 | builder->codeAppendf("half err = half(abs(clampedCoord.y - origCoord.y) * %s.y);", |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 163 | fDecalName.c_str()); |
joshualitt | 5ae5fc5 | 2014-07-29 12:59:27 -0700 | [diff] [blame] | 164 | } |
joshualitt | 5ae5fc5 | 2014-07-29 12:59:27 -0700 | [diff] [blame] | 165 | |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 166 | // Apply a transform to the error rate, which let's us simulate nearest or bilerp filtering |
| 167 | // in the same shader. When the texture is nearest filtered, fSizeName.z is set to 1/2 so |
| 168 | // this becomes a step function centered at .5 away from the clamped coordinate (but the |
| 169 | // domain for decal is inset by .5 so the edge lines up properly). When bilerp, fSizeName.z |
| 170 | // is set to 1 and it becomes a simple linear blend between texture and transparent. |
| 171 | builder->codeAppendf("if (err > %s.z) { err = 1.0; } else if (%s.z < 1) { err = 0.0; }", |
| 172 | fDecalName.c_str(), fDecalName.c_str()); |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 173 | builder->codeAppendf("%s = mix(inside, half4(0, 0, 0, 0), err);", outColor); |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 174 | } else { |
| 175 | // A simple look up |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 176 | builder->codeAppendf("%s = inside;", outColor); |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 177 | } |
| 178 | } |
| 179 | |
egdaniel | 018fb62 | 2015-10-28 07:26:40 -0700 | [diff] [blame] | 180 | void GrTextureDomain::GLDomain::setData(const GrGLSLProgramDataManager& pdman, |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 181 | const GrTextureDomain& textureDomain, |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 182 | GrTextureProxy* proxy, |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 183 | const GrSamplerState& sampler) { |
| 184 | GrTexture* tex = proxy->peekTexture(); |
Brian Salomon | f29caf1 | 2019-11-15 12:12:28 -0500 | [diff] [blame] | 185 | SkASSERT(fHasMode && textureDomain.modeX() == fModeX && textureDomain.modeY() == fModeY); |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 186 | if (kIgnore_Mode != textureDomain.modeX() || kIgnore_Mode != textureDomain.modeY()) { |
| 187 | bool sendDecalData = textureDomain.modeX() == kDecal_Mode || |
| 188 | textureDomain.modeY() == kDecal_Mode; |
| 189 | |
| 190 | // If the texture is using nearest filtering, then the decal filter weight should step from |
| 191 | // 0 (texture) to 1 (transparent) one half pixel away from the domain. When doing any other |
| 192 | // form of filtering, the weight should be 1.0 so that it smoothly interpolates between the |
| 193 | // texture and transparent. |
| 194 | SkScalar decalFilterWeight = sampler.filter() == GrSamplerState::Filter::kNearest ? |
| 195 | SK_ScalarHalf : 1.0f; |
Brian Salomon | 246bc3d | 2018-12-06 15:33:02 -0500 | [diff] [blame] | 196 | SkScalar wInv, hInv, h; |
| 197 | if (proxy->textureType() == GrTextureType::kRectangle) { |
| 198 | wInv = hInv = 1.f; |
| 199 | h = tex->height(); |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 200 | |
| 201 | // Don't do any scaling by texture size for decal filter rate, it's already in pixels |
| 202 | if (sendDecalData) { |
| 203 | pdman.set3f(fDecalUni, 1.f, 1.f, decalFilterWeight); |
| 204 | } |
Brian Salomon | 246bc3d | 2018-12-06 15:33:02 -0500 | [diff] [blame] | 205 | } else { |
| 206 | wInv = SK_Scalar1 / tex->width(); |
| 207 | hInv = SK_Scalar1 / tex->height(); |
| 208 | h = 1.f; |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 209 | |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 210 | if (sendDecalData) { |
| 211 | pdman.set3f(fDecalUni, tex->width(), tex->height(), decalFilterWeight); |
| 212 | } |
Brian Salomon | 246bc3d | 2018-12-06 15:33:02 -0500 | [diff] [blame] | 213 | } |
Robert Phillips | e98234f | 2017-01-09 14:23:59 -0500 | [diff] [blame] | 214 | |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 215 | float values[kPrevDomainCount] = { |
| 216 | SkScalarToFloat(textureDomain.domain().fLeft * wInv), |
| 217 | SkScalarToFloat(textureDomain.domain().fTop * hInv), |
| 218 | SkScalarToFloat(textureDomain.domain().fRight * wInv), |
| 219 | SkScalarToFloat(textureDomain.domain().fBottom * hInv) |
| 220 | }; |
Robert Phillips | e98234f | 2017-01-09 14:23:59 -0500 | [diff] [blame] | 221 | |
Brian Salomon | 246bc3d | 2018-12-06 15:33:02 -0500 | [diff] [blame] | 222 | if (proxy->textureType() == GrTextureType::kRectangle) { |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 223 | SkASSERT(values[0] >= 0.0f && values[0] <= proxy->width()); |
| 224 | SkASSERT(values[1] >= 0.0f && values[1] <= proxy->height()); |
| 225 | SkASSERT(values[2] >= 0.0f && values[2] <= proxy->width()); |
| 226 | SkASSERT(values[3] >= 0.0f && values[3] <= proxy->height()); |
Brian Salomon | 246bc3d | 2018-12-06 15:33:02 -0500 | [diff] [blame] | 227 | } else { |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 228 | SkASSERT(values[0] >= 0.0f && values[0] <= 1.0f); |
| 229 | SkASSERT(values[1] >= 0.0f && values[1] <= 1.0f); |
| 230 | SkASSERT(values[2] >= 0.0f && values[2] <= 1.0f); |
| 231 | SkASSERT(values[3] >= 0.0f && values[3] <= 1.0f); |
Brian Salomon | 246bc3d | 2018-12-06 15:33:02 -0500 | [diff] [blame] | 232 | } |
Robert Phillips | e98234f | 2017-01-09 14:23:59 -0500 | [diff] [blame] | 233 | |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 234 | // vertical flip if necessary |
Robert Phillips | c686ce3 | 2017-07-21 14:12:29 -0400 | [diff] [blame] | 235 | if (kBottomLeft_GrSurfaceOrigin == proxy->origin()) { |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 236 | values[1] = h - values[1]; |
| 237 | values[3] = h - values[3]; |
Brian Salomon | 246bc3d | 2018-12-06 15:33:02 -0500 | [diff] [blame] | 238 | |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 239 | // The top and bottom were just flipped, so correct the ordering |
| 240 | // of elements so that values = (l, t, r, b). |
Ben Wagner | f08d1d0 | 2018-06-18 15:11:00 -0400 | [diff] [blame] | 241 | using std::swap; |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 242 | swap(values[1], values[3]); |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 243 | } |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 244 | if (0 != memcmp(values, fPrevDomain, kPrevDomainCount * sizeof(float))) { |
| 245 | pdman.set4fv(fDomainUni, 1, values); |
| 246 | memcpy(fPrevDomain, values, kPrevDomainCount * sizeof(float)); |
| 247 | } |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 248 | } |
| 249 | } |
| 250 | |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 251 | /////////////////////////////////////////////////////////////////////////////// |
Brian Salomon | 587e08f | 2017-01-27 10:59:27 -0500 | [diff] [blame] | 252 | |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 253 | std::unique_ptr<GrFragmentProcessor> GrTextureDomainEffect::Make( |
| 254 | sk_sp<GrTextureProxy> proxy, |
Brian Salomon | 078e8fa | 2019-11-22 04:10:18 +0000 | [diff] [blame^] | 255 | GrColorType srcColorType, |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 256 | const SkMatrix& matrix, |
| 257 | const SkRect& domain, |
| 258 | GrTextureDomain::Mode mode, |
| 259 | GrSamplerState::Filter filterMode) { |
Brian Salomon | 078e8fa | 2019-11-22 04:10:18 +0000 | [diff] [blame^] | 260 | return Make(std::move(proxy), srcColorType, matrix, domain, mode, mode, |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 261 | GrSamplerState(GrSamplerState::WrapMode::kClamp, filterMode)); |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 262 | } |
| 263 | |
Brian Salomon | 078e8fa | 2019-11-22 04:10:18 +0000 | [diff] [blame^] | 264 | std::unique_ptr<GrFragmentProcessor> GrTextureDomainEffect::Make( |
| 265 | sk_sp<GrTextureProxy> proxy, |
| 266 | GrColorType srcColorType, |
| 267 | const SkMatrix& matrix, |
| 268 | const SkRect& domain, |
| 269 | GrTextureDomain::Mode modeX, |
| 270 | GrTextureDomain::Mode modeY, |
| 271 | const GrSamplerState& sampler) { |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 272 | // If both domain modes happen to be ignore, it would be faster to just drop the domain logic |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 273 | // entirely Technically, we could also use the simple texture effect if the domain modes agree |
| 274 | // with the sampler modes and the proxy is the same size as the domain. It's a lot easier for |
| 275 | // calling code to detect these cases and handle it themselves. |
| 276 | return std::unique_ptr<GrFragmentProcessor>(new GrTextureDomainEffect( |
Brian Salomon | 078e8fa | 2019-11-22 04:10:18 +0000 | [diff] [blame^] | 277 | std::move(proxy), srcColorType, matrix, domain, modeX, modeY, sampler)); |
Robert Phillips | 40fd7c9 | 2017-01-30 08:06:27 -0500 | [diff] [blame] | 278 | } |
| 279 | |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 280 | GrTextureDomainEffect::GrTextureDomainEffect(sk_sp<GrTextureProxy> proxy, |
Brian Salomon | 078e8fa | 2019-11-22 04:10:18 +0000 | [diff] [blame^] | 281 | GrColorType srcColorType, |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 282 | const SkMatrix& matrix, |
| 283 | const SkRect& domain, |
| 284 | GrTextureDomain::Mode modeX, |
| 285 | GrTextureDomain::Mode modeY, |
| 286 | const GrSamplerState& sampler) |
| 287 | : INHERITED(kGrTextureDomainEffect_ClassID, |
Brian Salomon | 078e8fa | 2019-11-22 04:10:18 +0000 | [diff] [blame^] | 288 | ModulateForSamplerOptFlags(srcColorType, |
| 289 | GrTextureDomain::IsDecalSampled(sampler, modeX, modeY))) |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 290 | , fCoordTransform(matrix, proxy.get()) |
| 291 | , fTextureDomain(proxy.get(), domain, modeX, modeY) |
| 292 | , fTextureSampler(std::move(proxy), sampler) { |
| 293 | SkASSERT((modeX != GrTextureDomain::kRepeat_Mode && modeY != GrTextureDomain::kRepeat_Mode) || |
| 294 | sampler.filter() == GrSamplerState::Filter::kNearest); |
Brian Salomon | 6cd51b5 | 2017-07-26 19:07:15 -0400 | [diff] [blame] | 295 | this->addCoordTransform(&fCoordTransform); |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 296 | this->setTextureSamplerCnt(1); |
Robert Phillips | 40fd7c9 | 2017-01-30 08:06:27 -0500 | [diff] [blame] | 297 | } |
| 298 | |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 299 | GrTextureDomainEffect::GrTextureDomainEffect(const GrTextureDomainEffect& that) |
| 300 | : INHERITED(kGrTextureDomainEffect_ClassID, that.optimizationFlags()) |
Brian Salomon | 3f6f965 | 2017-07-28 07:34:05 -0400 | [diff] [blame] | 301 | , fCoordTransform(that.fCoordTransform) |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 302 | , fTextureDomain(that.fTextureDomain) |
| 303 | , fTextureSampler(that.fTextureSampler) { |
Brian Salomon | 3f6f965 | 2017-07-28 07:34:05 -0400 | [diff] [blame] | 304 | this->addCoordTransform(&fCoordTransform); |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 305 | this->setTextureSamplerCnt(1); |
Brian Salomon | 3f6f965 | 2017-07-28 07:34:05 -0400 | [diff] [blame] | 306 | } |
| 307 | |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 308 | void GrTextureDomainEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, |
| 309 | GrProcessorKeyBuilder* b) const { |
| 310 | b->add32(GrTextureDomain::GLDomain::DomainKey(fTextureDomain)); |
joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 311 | } |
| 312 | |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 313 | GrGLSLFragmentProcessor* GrTextureDomainEffect::onCreateGLSLInstance() const { |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 314 | class GLSLProcessor : public GrGLSLFragmentProcessor { |
| 315 | public: |
| 316 | void emitCode(EmitArgs& args) override { |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 317 | const GrTextureDomainEffect& tde = args.fFp.cast<GrTextureDomainEffect>(); |
| 318 | const GrTextureDomain& domain = tde.fTextureDomain; |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 319 | |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 320 | GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; |
Ethan Nicholas | d4efe68 | 2019-08-29 16:10:13 -0400 | [diff] [blame] | 321 | SkString coords2D = |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 322 | fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint); |
Brian Osman | c468963 | 2016-12-19 17:04:59 -0500 | [diff] [blame] | 323 | |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 324 | fGLDomain.sampleTexture(fragBuilder, |
| 325 | args.fUniformHandler, |
| 326 | args.fShaderCaps, |
| 327 | domain, |
| 328 | args.fOutputColor, |
| 329 | coords2D, |
| 330 | args.fTexSamplers[0], |
| 331 | args.fInputColor); |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 332 | } |
| 333 | |
| 334 | protected: |
Brian Salomon | ab015ef | 2017-04-04 10:15:51 -0400 | [diff] [blame] | 335 | void onSetData(const GrGLSLProgramDataManager& pdman, |
| 336 | const GrFragmentProcessor& fp) override { |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 337 | const GrTextureDomainEffect& tde = fp.cast<GrTextureDomainEffect>(); |
| 338 | const GrTextureDomain& domain = tde.fTextureDomain; |
| 339 | GrTextureProxy* proxy = tde.textureSampler(0).proxy(); |
| 340 | |
| 341 | fGLDomain.setData(pdman, domain, proxy, tde.textureSampler(0).samplerState()); |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 342 | } |
| 343 | |
| 344 | private: |
| 345 | GrTextureDomain::GLDomain fGLDomain; |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 346 | }; |
| 347 | |
| 348 | return new GLSLProcessor; |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 349 | } |
| 350 | |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 351 | bool GrTextureDomainEffect::onIsEqual(const GrFragmentProcessor& sBase) const { |
| 352 | const GrTextureDomainEffect& s = sBase.cast<GrTextureDomainEffect>(); |
| 353 | return this->fTextureDomain == s.fTextureDomain; |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 354 | } |
| 355 | |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 356 | /////////////////////////////////////////////////////////////////////////////// |
| 357 | |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 358 | GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrTextureDomainEffect); |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 359 | |
Hal Canary | 6f6961e | 2017-01-31 13:50:44 -0500 | [diff] [blame] | 360 | #if GR_TEST_UTILS |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 361 | std::unique_ptr<GrFragmentProcessor> GrTextureDomainEffect::TestCreate(GrProcessorTestData* d) { |
| 362 | int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx |
| 363 | : GrProcessorUnitTest::kAlphaTextureIdx; |
| 364 | sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx); |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 365 | SkRect domain; |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 366 | domain.fLeft = d->fRandom->nextRangeScalar(0, proxy->width()); |
| 367 | domain.fRight = d->fRandom->nextRangeScalar(domain.fLeft, proxy->width()); |
| 368 | domain.fTop = d->fRandom->nextRangeScalar(0, proxy->height()); |
| 369 | domain.fBottom = d->fRandom->nextRangeScalar(domain.fTop, proxy->height()); |
| 370 | GrTextureDomain::Mode modeX = |
| 371 | (GrTextureDomain::Mode) d->fRandom->nextULessThan(GrTextureDomain::kModeCount); |
| 372 | GrTextureDomain::Mode modeY = |
| 373 | (GrTextureDomain::Mode) d->fRandom->nextULessThan(GrTextureDomain::kModeCount); |
joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 374 | const SkMatrix& matrix = GrTest::TestMatrix(d->fRandom); |
Michael Ludwig | 170de01 | 2019-11-15 21:55:18 +0000 | [diff] [blame] | 375 | bool bilerp = modeX != GrTextureDomain::kRepeat_Mode && modeY != GrTextureDomain::kRepeat_Mode ? |
| 376 | d->fRandom->nextBool() : false; |
Brian Salomon | 078e8fa | 2019-11-22 04:10:18 +0000 | [diff] [blame^] | 377 | return GrTextureDomainEffect::Make( |
| 378 | std::move(proxy), |
| 379 | d->textureProxyColorType(texIdx), |
| 380 | matrix, |
| 381 | domain, |
| 382 | modeX, |
| 383 | modeY, |
| 384 | GrSamplerState(GrSamplerState::WrapMode::kClamp, bilerp ? |
| 385 | GrSamplerState::Filter::kBilerp : GrSamplerState::Filter::kNearest)); |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 386 | } |
Hal Canary | 6f6961e | 2017-01-31 13:50:44 -0500 | [diff] [blame] | 387 | #endif |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 388 | |
| 389 | /////////////////////////////////////////////////////////////////////////////// |
Brian Salomon | aff329b | 2017-08-11 09:40:37 -0400 | [diff] [blame] | 390 | std::unique_ptr<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::Make( |
| 391 | sk_sp<GrTextureProxy> proxy, const SkIRect& subset, const SkIPoint& deviceSpaceOffset) { |
| 392 | return std::unique_ptr<GrFragmentProcessor>(new GrDeviceSpaceTextureDecalFragmentProcessor( |
Robert Phillips | fbcef6e | 2017-06-15 12:07:18 -0400 | [diff] [blame] | 393 | std::move(proxy), subset, deviceSpaceOffset)); |
Robert Phillips | 40fd7c9 | 2017-01-30 08:06:27 -0500 | [diff] [blame] | 394 | } |
| 395 | |
| 396 | GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor( |
Brian Salomon | 2bbdcc4 | 2017-09-07 12:36:34 -0400 | [diff] [blame] | 397 | sk_sp<GrTextureProxy> proxy, const SkIRect& subset, const SkIPoint& deviceSpaceOffset) |
Ethan Nicholas | abff956 | 2017-10-09 10:54:08 -0400 | [diff] [blame] | 398 | : INHERITED(kGrDeviceSpaceTextureDecalFragmentProcessor_ClassID, |
| 399 | kCompatibleWithCoverageAsAlpha_OptimizationFlag) |
Brian Salomon | 2bbdcc4 | 2017-09-07 12:36:34 -0400 | [diff] [blame] | 400 | , fTextureSampler(proxy, GrSamplerState::ClampNearest()) |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 401 | , fTextureDomain(proxy.get(), |
| 402 | GrTextureDomain::MakeTexelDomain(subset, GrTextureDomain::kDecal_Mode), |
| 403 | GrTextureDomain::kDecal_Mode, GrTextureDomain::kDecal_Mode) { |
Brian Salomon | f7dcd76 | 2018-07-30 14:48:15 -0400 | [diff] [blame] | 404 | this->setTextureSamplerCnt(1); |
Robert Phillips | 40fd7c9 | 2017-01-30 08:06:27 -0500 | [diff] [blame] | 405 | fDeviceSpaceOffset.fX = deviceSpaceOffset.fX - subset.fLeft; |
| 406 | fDeviceSpaceOffset.fY = deviceSpaceOffset.fY - subset.fTop; |
Robert Phillips | 40fd7c9 | 2017-01-30 08:06:27 -0500 | [diff] [blame] | 407 | } |
| 408 | |
Brian Salomon | 1a2a7ab | 2017-07-26 13:11:51 -0400 | [diff] [blame] | 409 | GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor( |
| 410 | const GrDeviceSpaceTextureDecalFragmentProcessor& that) |
Ethan Nicholas | abff956 | 2017-10-09 10:54:08 -0400 | [diff] [blame] | 411 | : INHERITED(kGrDeviceSpaceTextureDecalFragmentProcessor_ClassID, |
| 412 | kCompatibleWithCoverageAsAlpha_OptimizationFlag) |
Brian Salomon | 1a2a7ab | 2017-07-26 13:11:51 -0400 | [diff] [blame] | 413 | , fTextureSampler(that.fTextureSampler) |
| 414 | , fTextureDomain(that.fTextureDomain) |
| 415 | , fDeviceSpaceOffset(that.fDeviceSpaceOffset) { |
Brian Salomon | f7dcd76 | 2018-07-30 14:48:15 -0400 | [diff] [blame] | 416 | this->setTextureSamplerCnt(1); |
Brian Salomon | 1a2a7ab | 2017-07-26 13:11:51 -0400 | [diff] [blame] | 417 | } |
| 418 | |
Brian Salomon | aff329b | 2017-08-11 09:40:37 -0400 | [diff] [blame] | 419 | std::unique_ptr<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::clone() const { |
| 420 | return std::unique_ptr<GrFragmentProcessor>( |
| 421 | new GrDeviceSpaceTextureDecalFragmentProcessor(*this)); |
Brian Salomon | 1a2a7ab | 2017-07-26 13:11:51 -0400 | [diff] [blame] | 422 | } |
| 423 | |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 424 | GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLSLInstance() const { |
| 425 | class GLSLProcessor : public GrGLSLFragmentProcessor { |
| 426 | public: |
| 427 | void emitCode(EmitArgs& args) override { |
| 428 | const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp = |
| 429 | args.fFp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>(); |
| 430 | const char* scaleAndTranslateName; |
| 431 | fScaleAndTranslateUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, |
Ethan Nicholas | f7b8820 | 2017-09-18 14:10:39 -0400 | [diff] [blame] | 432 | kHalf4_GrSLType, |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 433 | "scaleAndTranslate", |
| 434 | &scaleAndTranslateName); |
Ethan Nicholas | e1f5502 | 2019-02-05 17:17:40 -0500 | [diff] [blame] | 435 | args.fFragBuilder->codeAppendf("half2 coords = half2(sk_FragCoord.xy * %s.xy + %s.zw);", |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 436 | scaleAndTranslateName, scaleAndTranslateName); |
| 437 | fGLDomain.sampleTexture(args.fFragBuilder, |
| 438 | args.fUniformHandler, |
Brian Salomon | 1edc5b9 | 2016-11-29 13:43:46 -0500 | [diff] [blame] | 439 | args.fShaderCaps, |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 440 | dstdfp.fTextureDomain, |
| 441 | args.fOutputColor, |
| 442 | SkString("coords"), |
| 443 | args.fTexSamplers[0], |
| 444 | args.fInputColor); |
| 445 | } |
| 446 | |
| 447 | protected: |
Brian Salomon | ab015ef | 2017-04-04 10:15:51 -0400 | [diff] [blame] | 448 | void onSetData(const GrGLSLProgramDataManager& pdman, |
| 449 | const GrFragmentProcessor& fp) override { |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 450 | const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp = |
| 451 | fp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>(); |
Brian Salomon | 7da2fc7 | 2018-12-10 13:40:07 -0500 | [diff] [blame] | 452 | GrTextureProxy* proxy = dstdfp.textureSampler(0).proxy(); |
Brian Salomon | fd98c2c | 2018-07-31 17:25:29 -0400 | [diff] [blame] | 453 | GrTexture* texture = proxy->peekTexture(); |
Robert Phillips | 9bee2e5 | 2017-05-29 12:37:20 -0400 | [diff] [blame] | 454 | |
Michael Ludwig | be315a2 | 2018-12-17 09:50:51 -0500 | [diff] [blame] | 455 | fGLDomain.setData(pdman, dstdfp.fTextureDomain, proxy, |
| 456 | dstdfp.textureSampler(0).samplerState()); |
Brian Salomon | 0bbecb2 | 2016-11-17 11:38:22 -0500 | [diff] [blame] | 457 | float iw = 1.f / texture->width(); |
| 458 | float ih = 1.f / texture->height(); |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 459 | float scaleAndTransData[4] = { |
| 460 | iw, ih, |
| 461 | -dstdfp.fDeviceSpaceOffset.fX * iw, -dstdfp.fDeviceSpaceOffset.fY * ih |
| 462 | }; |
Robert Phillips | c686ce3 | 2017-07-21 14:12:29 -0400 | [diff] [blame] | 463 | if (proxy->origin() == kBottomLeft_GrSurfaceOrigin) { |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 464 | scaleAndTransData[1] = -scaleAndTransData[1]; |
| 465 | scaleAndTransData[3] = 1 - scaleAndTransData[3]; |
| 466 | } |
| 467 | pdman.set4fv(fScaleAndTranslateUni, 1, scaleAndTransData); |
| 468 | } |
| 469 | |
| 470 | private: |
| 471 | GrTextureDomain::GLDomain fGLDomain; |
| 472 | UniformHandle fScaleAndTranslateUni; |
| 473 | }; |
| 474 | |
| 475 | return new GLSLProcessor; |
| 476 | } |
| 477 | |
| 478 | bool GrDeviceSpaceTextureDecalFragmentProcessor::onIsEqual(const GrFragmentProcessor& fp) const { |
| 479 | const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp = |
| 480 | fp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>(); |
Brian Salomon | 1a2a7ab | 2017-07-26 13:11:51 -0400 | [diff] [blame] | 481 | return dstdfp.fTextureSampler.proxy()->underlyingUniqueID() == |
| 482 | fTextureSampler.proxy()->underlyingUniqueID() && |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 483 | dstdfp.fDeviceSpaceOffset == fDeviceSpaceOffset && |
| 484 | dstdfp.fTextureDomain == fTextureDomain; |
| 485 | } |
| 486 | |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 487 | /////////////////////////////////////////////////////////////////////////////// |
| 488 | |
| 489 | GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDeviceSpaceTextureDecalFragmentProcessor); |
| 490 | |
Hal Canary | 6f6961e | 2017-01-31 13:50:44 -0500 | [diff] [blame] | 491 | #if GR_TEST_UTILS |
Brian Salomon | aff329b | 2017-08-11 09:40:37 -0400 | [diff] [blame] | 492 | std::unique_ptr<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::TestCreate( |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 493 | GrProcessorTestData* d) { |
| 494 | int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx |
| 495 | : GrProcessorUnitTest::kAlphaTextureIdx; |
Robert Phillips | 40fd7c9 | 2017-01-30 08:06:27 -0500 | [diff] [blame] | 496 | sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx); |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 497 | SkIRect subset; |
Robert Phillips | 40fd7c9 | 2017-01-30 08:06:27 -0500 | [diff] [blame] | 498 | subset.fLeft = d->fRandom->nextULessThan(proxy->width() - 1); |
| 499 | subset.fRight = d->fRandom->nextRangeU(subset.fLeft, proxy->width()); |
| 500 | subset.fTop = d->fRandom->nextULessThan(proxy->height() - 1); |
| 501 | subset.fBottom = d->fRandom->nextRangeU(subset.fTop, proxy->height()); |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 502 | SkIPoint pt; |
| 503 | pt.fX = d->fRandom->nextULessThan(2048); |
| 504 | pt.fY = d->fRandom->nextULessThan(2048); |
Robert Phillips | fbcef6e | 2017-06-15 12:07:18 -0400 | [diff] [blame] | 505 | return GrDeviceSpaceTextureDecalFragmentProcessor::Make(std::move(proxy), subset, pt); |
commit-bot@chromium.org | 907fbd5 | 2013-12-09 17:03:02 +0000 | [diff] [blame] | 506 | } |
Hal Canary | 6f6961e | 2017-01-31 13:50:44 -0500 | [diff] [blame] | 507 | #endif |