OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrTextureParamsAdjuster.h" | 8 #include "GrTextureParamsAdjuster.h" |
9 | 9 |
10 #include "GrCaps.h" | 10 #include "GrCaps.h" |
11 #include "GrContext.h" | 11 #include "GrContext.h" |
12 #include "GrDrawContext.h" | 12 #include "GrDrawContext.h" |
13 #include "GrGpu.h" | 13 #include "GrGpu.h" |
14 #include "GrGpuResourcePriv.h" | 14 #include "GrGpuResourcePriv.h" |
15 #include "GrResourceKey.h" | 15 #include "GrResourceKey.h" |
16 #include "GrTexture.h" | 16 #include "GrTexture.h" |
17 #include "GrTextureParams.h" | 17 #include "GrTextureParams.h" |
18 #include "GrTextureProvider.h" | 18 #include "GrTextureProvider.h" |
19 #include "SkCanvas.h" | 19 #include "SkCanvas.h" |
20 #include "SkGr.h" | 20 #include "SkGr.h" |
21 #include "SkGrPriv.h" | 21 #include "SkGrPriv.h" |
22 #include "effects/GrBicubicEffect.h" | |
22 #include "effects/GrTextureDomain.h" | 23 #include "effects/GrTextureDomain.h" |
23 | 24 |
24 typedef GrTextureProducer::CopyParams CopyParams; | 25 typedef GrTextureProducer::CopyParams CopyParams; |
25 | 26 |
26 ////////////////////////////////////////////////////////////////////////////// | 27 ////////////////////////////////////////////////////////////////////////////// |
27 | 28 |
28 static GrTexture* copy_on_gpu(GrTexture* inputTexture, const SkIRect* subset, | 29 static GrTexture* copy_on_gpu(GrTexture* inputTexture, const SkIRect* subset, |
29 const CopyParams& copyParams) { | 30 const CopyParams& copyParams) { |
30 SkASSERT(!subset || !subset->isEmpty()); | 31 SkASSERT(!subset || !subset->isEmpty()); |
31 GrContext* context = inputTexture->getContext(); | 32 GrContext* context = inputTexture->getContext(); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
164 result->resourcePriv().setUniqueKey(key); | 165 result->resourcePriv().setUniqueKey(key); |
165 this->didCacheCopy(key); | 166 this->didCacheCopy(key); |
166 } | 167 } |
167 if (outOffset) { | 168 if (outOffset) { |
168 outOffset->set(0, 0); | 169 outOffset->set(0, 0); |
169 } | 170 } |
170 } | 171 } |
171 return result; | 172 return result; |
172 } | 173 } |
173 | 174 |
175 enum DomainMode { | |
176 kNoDomain_DomainMode, | |
177 kDomain_DomainMode, | |
178 kTightCopy_DomainMode | |
179 }; | |
180 | |
181 /** Determines whether a texture domain is necessary and if so what domain to us e. In the case of | |
182 mip maps it may indicate that a copy must be made to avoid filtering outside the constraint | |
183 rectangle or the content area of the texture. */ | |
184 static DomainMode determine_domain_mode( | |
robertphillips
2015/11/05 20:13:24
tab these over one to avoid lining up with the cod
bsalomon
2015/11/06 15:24:26
Done.
| |
185 const SkRect& constraintRect, | |
186 GrTextureAdjuster::FilterConstraint filterConstraint, | |
187 bool coordsLimitedContraintRect, | |
188 int texW, int texH, | |
189 const SkIRect* textureContentArea, | |
190 const GrTextureParams::FilterMode* filterModeOrNullForBicubic, | |
191 SkRect* domainRect) { | |
robertphillips
2015/11/05 20:13:24
... or maybe a '\n' here ?
bsalomon
2015/11/06 15:24:26
Done.
| |
192 SkASSERT(SkRect::MakeIWH(texW, texH).contains(constraintRect)); | |
193 // We only expect a content area rect if there is some non-content area. | |
194 SkASSERT(!textureContentArea || | |
195 (!textureContentArea->contains(SkIRect::MakeWH(texW, texH)) && | |
196 SkRect::Make(*textureContentArea).contains(constraintRect))); | |
197 | |
198 SkRect textureBounds = SkRect::MakeIWH(texW, texH); | |
199 // If the src rectangle contains the whole texture then no need for a domain . | |
200 if (constraintRect.contains(textureBounds)) { | |
201 return kNoDomain_DomainMode; | |
202 } | |
203 | |
204 bool restrictFilterToRect = (filterConstraint == GrTextureAdjuster::kYes_Fil terConstraint); | |
205 | |
206 // If we can filter outside the constraint rect, and there is no non-content area of the | |
207 // texture, and we aren't going to generate sample coords outside the constr aint rect then we | |
208 // don't need a domain. | |
209 if (!restrictFilterToRect && !textureContentArea && coordsLimitedContraintRe ct) { | |
210 return kNoDomain_DomainMode; | |
211 } | |
212 | |
213 // Get the domain inset based on sampling mode (or bail if mipped) | |
214 SkScalar filterHalfWidth; | |
215 if (filterModeOrNullForBicubic) { | |
216 switch (*filterModeOrNullForBicubic) { | |
217 case GrTextureParams::kNone_FilterMode: | |
218 if (coordsLimitedContraintRect) { | |
219 return kNoDomain_DomainMode; | |
220 } else { | |
221 filterHalfWidth = 0.f; | |
222 } | |
223 break; | |
224 case GrTextureParams::kBilerp_FilterMode: | |
225 filterHalfWidth = 1.f; | |
226 break; | |
227 case GrTextureParams::kMipMap_FilterMode: | |
228 // No domain can save use here. | |
229 return kTightCopy_DomainMode; | |
230 } | |
231 } else { | |
232 // bicubic does nearest filtering internally. | |
233 filterHalfWidth = 2.f; | |
234 } | |
235 | |
robertphillips
2015/11/05 20:13:24
// We will inset the domain half a pixel b.c. ...
bsalomon
2015/11/06 15:24:25
Done.
| |
236 static const SkScalar kDomainInset = 0.5f; | |
robertphillips
2015/11/05 20:13:24
can -> to ?
bsalomon
2015/11/06 15:24:26
Done.
| |
237 // Figure out the limits of pixels we're allowed can sample from. | |
238 // Unless we know the amount of outset and the texture matrix we have to con servatively enforce | |
239 // the domain. | |
240 if (restrictFilterToRect) { | |
241 domainRect->fLeft = constraintRect.fLeft + kDomainInset; | |
242 domainRect->fTop = constraintRect.fTop + kDomainInset; | |
243 domainRect->fRight = constraintRect.fRight - kDomainInset; | |
244 domainRect->fBottom = constraintRect.fBottom - kDomainInset; | |
245 } else if (textureContentArea) { | |
246 // If we got here then: there is a textureContentArea, the coords are li mited to the | |
247 // constraint rect, and we're allowed to filter across the constraint re ct boundary. So | |
robertphillips
2015/11/05 20:13:24
from -> to ?
bsalomon
2015/11/06 15:24:26
Done.
| |
248 // we check whether the filter would reach from the edge of the content area. | |
249 bool needContentAreaConstraint = false; | |
250 // We will only set the sides that are required. | |
251 domainRect->setLargest(); | |
252 if (textureContentArea->fLeft > 0 && | |
253 textureContentArea->fLeft + filterHalfWidth > constraintRect.fLeft) { | |
254 domainRect->fLeft = textureContentArea->fLeft + kDomainInset; | |
255 needContentAreaConstraint = true; | |
256 } | |
257 if (textureContentArea->fTop > 0 && | |
258 textureContentArea->fTop + filterHalfWidth > constraintRect.fTop) { | |
259 domainRect->fTop = textureContentArea->fTop + kDomainInset; | |
260 needContentAreaConstraint = true; | |
261 } | |
262 if (textureContentArea->fRight < texW && | |
263 textureContentArea->fRight - filterHalfWidth < constraintRect.fRight ) { | |
264 domainRect->fRight = textureContentArea->fRight - kDomainInset; | |
265 needContentAreaConstraint = true; | |
266 } | |
267 if (textureContentArea->fBottom < texW && | |
268 textureContentArea->fBottom - filterHalfWidth < constraintRect.fBott om) { | |
269 domainRect->fBottom = textureContentArea->fBottom - kDomainInset; | |
270 needContentAreaConstraint = true; | |
271 } | |
272 if (!needContentAreaConstraint) { | |
273 return kNoDomain_DomainMode; | |
274 } | |
275 } else { | |
276 return kNoDomain_DomainMode; | |
277 } | |
278 | |
279 if (domainRect->fLeft > domainRect->fRight) { | |
280 domainRect->fLeft = domainRect->fRight = SkScalarAve(domainRect->fLeft, domainRect->fRight); | |
281 } | |
282 if (domainRect->fTop > domainRect->fBottom) { | |
283 domainRect->fTop = domainRect->fBottom = SkScalarAve(domainRect->fTop, d omainRect->fBottom); | |
284 } | |
robertphillips
2015/11/05 20:13:24
What happens to the sides that are still out at th
bsalomon
2015/11/06 15:24:26
They'd still be really large (in abs value). This
| |
285 domainRect->fLeft /= texW; | |
286 domainRect->fTop /= texH; | |
287 domainRect->fRight /= texW; | |
288 domainRect->fBottom /= texH; | |
289 return kDomain_DomainMode; | |
290 } | |
291 | |
292 const GrFragmentProcessor* GrTextureAdjuster::createFragmentProcessor( | |
293 const SkMatrix& textureMatrix, | |
294 const SkRect& constraintRect, | |
295 FilterConstraint filterConstraint, | |
296 bool coordsLimitedToConstraintRect, | |
297 const GrTextureParams::FilterMode* filterOrNullForBicubic) { | |
298 | |
299 const SkIRect* contentArea = this->contentArea(); | |
300 | |
301 SkRect domain; | |
302 GrTexture* texture = this->originalTexture(); | |
303 DomainMode domainMode = | |
304 determine_domain_mode(constraintRect, filterConstraint, coordsLimitedToC onstraintRect, | |
305 texture->width(), texture->height(), | |
306 contentArea, filterOrNullForBicubic, | |
307 &domain); | |
308 if (kTightCopy_DomainMode == domainMode) { | |
309 // TODO: Copy the texture and adjust the texture matrix (both parts need to consider | |
310 // non-int constraint rect) | |
311 // For now: treat as bilerp and ignore what goes on above level 0. | |
312 SkASSERT(filterOrNullForBicubic && | |
313 GrTextureParams::kMipMap_FilterMode == *filterOrNullForBicubic) ; | |
314 static const GrTextureParams::FilterMode kBilerp = GrTextureParams::kBil erp_FilterMode; | |
315 domainMode = | |
316 determine_domain_mode(constraintRect, filterConstraint, coordsLimite dToConstraintRect, | |
317 texture->width(), texture->height(), | |
318 contentArea, &kBilerp, &domain); | |
319 SkASSERT(kTightCopy_DomainMode != domainMode); | |
320 filterOrNullForBicubic = &kBilerp; | |
321 } | |
322 SkASSERT(kNoDomain_DomainMode == domainMode || | |
323 (domain.fLeft <= domain.fRight && domain.fTop <= domain.fBottom)); | |
324 if (filterOrNullForBicubic) { | |
325 if (kDomain_DomainMode == domainMode) { | |
326 SkASSERT(*filterOrNullForBicubic != GrTextureParams::kMipMap_FilterM ode); | |
327 return GrTextureDomainEffect::Create(texture, textureMatrix, domain, | |
328 GrTextureDomain::kClamp_Mode, | |
329 *filterOrNullForBicubic); | |
330 } else { | |
331 GrTextureParams params(SkShader::kClamp_TileMode, *filterOrNullForBi cubic); | |
332 return GrSimpleTextureEffect::Create(texture, textureMatrix, params) ; | |
333 } | |
334 } else { | |
335 if (kDomain_DomainMode == domainMode) { | |
336 return GrBicubicEffect::Create(texture, textureMatrix, domain); | |
337 } else { | |
338 static const SkShader::TileMode kClampClamp[] = | |
339 { SkShader::kClamp_TileMode, SkShader::kClamp_TileMode }; | |
340 return GrBicubicEffect::Create(texture, textureMatrix, kClampClamp); | |
341 } | |
342 } | |
343 } | |
344 | |
174 ////////////////////////////////////////////////////////////////////////////// | 345 ////////////////////////////////////////////////////////////////////////////// |
175 | 346 |
176 GrTexture* GrTextureMaker::refTextureForParams(GrContext* ctx, const GrTexturePa rams& params) { | 347 GrTexture* GrTextureMaker::refTextureForParams(GrContext* ctx, const GrTexturePa rams& params) { |
177 CopyParams copyParams; | 348 CopyParams copyParams; |
178 if (!ctx->getGpu()->makeCopyForTextureParams(this->width(), this->height(), params, | 349 if (!ctx->getGpu()->makeCopyForTextureParams(this->width(), this->height(), params, |
179 ©Params)) { | 350 ©Params)) { |
180 return this->refOriginalTexture(ctx); | 351 return this->refOriginalTexture(ctx); |
181 } | 352 } |
182 GrUniqueKey copyKey; | 353 GrUniqueKey copyKey; |
183 this->makeCopyKey(copyParams, ©Key); | 354 this->makeCopyKey(copyParams, ©Key); |
(...skipping 16 matching lines...) Expand all Loading... | |
200 return result; | 371 return result; |
201 } | 372 } |
202 | 373 |
203 GrTexture* GrTextureMaker::generateTextureForParams(GrContext* ctx, const CopyPa rams& copyParams) { | 374 GrTexture* GrTextureMaker::generateTextureForParams(GrContext* ctx, const CopyPa rams& copyParams) { |
204 SkAutoTUnref<GrTexture> original(this->refOriginalTexture(ctx)); | 375 SkAutoTUnref<GrTexture> original(this->refOriginalTexture(ctx)); |
205 if (!original) { | 376 if (!original) { |
206 return nullptr; | 377 return nullptr; |
207 } | 378 } |
208 return copy_on_gpu(original, nullptr, copyParams); | 379 return copy_on_gpu(original, nullptr, copyParams); |
209 } | 380 } |
OLD | NEW |