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" |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 SkASSERT(!textureContentArea || | 206 SkASSERT(!textureContentArea || |
207 (!textureContentArea->contains(SkIRect::MakeWH(texW, texH)) && | 207 (!textureContentArea->contains(SkIRect::MakeWH(texW, texH)) && |
208 SkRect::Make(*textureContentArea).contains(constraintRect))); | 208 SkRect::Make(*textureContentArea).contains(constraintRect))); |
209 | 209 |
210 SkRect textureBounds = SkRect::MakeIWH(texW, texH); | 210 SkRect textureBounds = SkRect::MakeIWH(texW, texH); |
211 // If the src rectangle contains the whole texture then no need for a domain
. | 211 // If the src rectangle contains the whole texture then no need for a domain
. |
212 if (constraintRect.contains(textureBounds)) { | 212 if (constraintRect.contains(textureBounds)) { |
213 return kNoDomain_DomainMode; | 213 return kNoDomain_DomainMode; |
214 } | 214 } |
215 | 215 |
216 bool restrictFilterToRect = (filterConstraint == GrTextureAdjuster::kYes_Fil
terConstraint); | 216 bool restrictFilterToRect = (filterConstraint == GrTextureProducer::kYes_Fil
terConstraint); |
217 | 217 |
218 // If we can filter outside the constraint rect, and there is no non-content
area of the | 218 // If we can filter outside the constraint rect, and there is no non-content
area of the |
219 // texture, and we aren't going to generate sample coords outside the constr
aint rect then we | 219 // texture, and we aren't going to generate sample coords outside the constr
aint rect then we |
220 // don't need a domain. | 220 // don't need a domain. |
221 if (!restrictFilterToRect && !textureContentArea && coordsLimitedToConstrain
tRect) { | 221 if (!restrictFilterToRect && !textureContentArea && coordsLimitedToConstrain
tRect) { |
222 return kNoDomain_DomainMode; | 222 return kNoDomain_DomainMode; |
223 } | 223 } |
224 | 224 |
225 // Get the domain inset based on sampling mode (or bail if mipped) | 225 // Get the domain inset based on sampling mode (or bail if mipped) |
226 SkScalar filterHalfWidth = 0.f; | 226 SkScalar filterHalfWidth = 0.f; |
227 if (filterModeOrNullForBicubic) { | 227 if (filterModeOrNullForBicubic) { |
228 switch (*filterModeOrNullForBicubic) { | 228 switch (*filterModeOrNullForBicubic) { |
229 case GrTextureParams::kNone_FilterMode: | 229 case GrTextureParams::kNone_FilterMode: |
230 if (coordsLimitedToConstraintRect) { | 230 if (coordsLimitedToConstraintRect) { |
231 return kNoDomain_DomainMode; | 231 return kNoDomain_DomainMode; |
232 } else { | 232 } else { |
233 filterHalfWidth = 0.f; | 233 filterHalfWidth = 0.f; |
234 } | 234 } |
235 break; | 235 break; |
236 case GrTextureParams::kBilerp_FilterMode: | 236 case GrTextureParams::kBilerp_FilterMode: |
237 filterHalfWidth = .5f; | 237 filterHalfWidth = .5f; |
238 break; | 238 break; |
239 case GrTextureParams::kMipMap_FilterMode: | 239 case GrTextureParams::kMipMap_FilterMode: |
240 // No domain can save use here. | 240 if (restrictFilterToRect || textureContentArea) { |
241 return kTightCopy_DomainMode; | 241 // No domain can save us here. |
| 242 return kTightCopy_DomainMode; |
| 243 } |
| 244 return kNoDomain_DomainMode; |
242 } | 245 } |
243 } else { | 246 } else { |
244 // bicubic does nearest filtering internally. | 247 // bicubic does nearest filtering internally. |
245 filterHalfWidth = 1.5f; | 248 filterHalfWidth = 1.5f; |
246 } | 249 } |
247 | 250 |
248 // Both bilerp and bicubic use bilinear filtering and so need to be clamped
to the center | 251 // Both bilerp and bicubic use bilinear filtering and so need to be clamped
to the center |
249 // of the edge texel. Pinning to the texel center has no impact on nearest m
ode and MIP-maps | 252 // of the edge texel. Pinning to the texel center has no impact on nearest m
ode and MIP-maps |
250 | 253 |
251 static const SkScalar kDomainInset = 0.5f; | 254 static const SkScalar kDomainInset = 0.5f; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 if (domainRect->fTop > domainRect->fBottom) { | 320 if (domainRect->fTop > domainRect->fBottom) { |
318 domainRect->fTop = domainRect->fBottom = SkScalarAve(domainRect->fTop, d
omainRect->fBottom); | 321 domainRect->fTop = domainRect->fBottom = SkScalarAve(domainRect->fTop, d
omainRect->fBottom); |
319 } | 322 } |
320 domainRect->fLeft /= texW; | 323 domainRect->fLeft /= texW; |
321 domainRect->fTop /= texH; | 324 domainRect->fTop /= texH; |
322 domainRect->fRight /= texW; | 325 domainRect->fRight /= texW; |
323 domainRect->fBottom /= texH; | 326 domainRect->fBottom /= texH; |
324 return kDomain_DomainMode; | 327 return kDomain_DomainMode; |
325 } | 328 } |
326 | 329 |
| 330 static const GrFragmentProcessor* create_fp_for_domain_and_filter( |
| 331 GrTexture* texture, |
| 332 const SkMatrix& textureMatrix, |
| 333 DomainMode domainMode, |
| 334 const SkRect& domain, |
| 335 const GrTextureParams::FilterMode* filte
rOrNullForBicubic) { |
| 336 SkASSERT(kTightCopy_DomainMode != domainMode); |
| 337 if (filterOrNullForBicubic) { |
| 338 if (kDomain_DomainMode == domainMode) { |
| 339 return GrTextureDomainEffect::Create(texture, textureMatrix, domain, |
| 340 GrTextureDomain::kClamp_Mode, |
| 341 *filterOrNullForBicubic); |
| 342 } else { |
| 343 GrTextureParams params(SkShader::kClamp_TileMode, *filterOrNullForBi
cubic); |
| 344 return GrSimpleTextureEffect::Create(texture, textureMatrix, params)
; |
| 345 } |
| 346 } else { |
| 347 if (kDomain_DomainMode == domainMode) { |
| 348 return GrBicubicEffect::Create(texture, textureMatrix, domain); |
| 349 } else { |
| 350 static const SkShader::TileMode kClampClamp[] = |
| 351 { SkShader::kClamp_TileMode, SkShader::kClamp_TileMode }; |
| 352 return GrBicubicEffect::Create(texture, textureMatrix, kClampClamp); |
| 353 } |
| 354 } |
| 355 } |
| 356 |
327 const GrFragmentProcessor* GrTextureAdjuster::createFragmentProcessor( | 357 const GrFragmentProcessor* GrTextureAdjuster::createFragmentProcessor( |
328 const SkMatrix& origTextureMatrix, | 358 const SkMatrix& origTextureMatrix, |
329 const SkRect& origConstraintRect, | 359 const SkRect& origConstraintRect, |
330 FilterConstraint filterConstraint, | 360 FilterConstraint filterConstraint, |
331 bool coordsLimitedToConstraintRect, | 361 bool coordsLimitedToConstraintRect, |
332 const GrTextureParams::FilterMode* filte
rOrNullForBicubic) { | 362 const GrTextureParams::FilterMode* filte
rOrNullForBicubic) { |
333 | 363 |
334 SkMatrix textureMatrix = origTextureMatrix; | 364 SkMatrix textureMatrix = origTextureMatrix; |
335 const SkIRect* contentArea = this->contentAreaOrNull(); | 365 const SkIRect* contentArea = this->contentAreaOrNull(); |
336 // Convert the constraintRect to be relative to the texture rather than the
content area so | 366 // Convert the constraintRect to be relative to the texture rather than the
content area so |
(...skipping 24 matching lines...) Expand all Loading... |
361 static const GrTextureParams::FilterMode kBilerp = GrTextureParams::kBil
erp_FilterMode; | 391 static const GrTextureParams::FilterMode kBilerp = GrTextureParams::kBil
erp_FilterMode; |
362 domainMode = | 392 domainMode = |
363 determine_domain_mode(*constraintRect, filterConstraint, coordsLimit
edToConstraintRect, | 393 determine_domain_mode(*constraintRect, filterConstraint, coordsLimit
edToConstraintRect, |
364 texture->width(), texture->height(), | 394 texture->width(), texture->height(), |
365 contentArea, &kBilerp, &domain); | 395 contentArea, &kBilerp, &domain); |
366 SkASSERT(kTightCopy_DomainMode != domainMode); | 396 SkASSERT(kTightCopy_DomainMode != domainMode); |
367 } | 397 } |
368 SkASSERT(kNoDomain_DomainMode == domainMode || | 398 SkASSERT(kNoDomain_DomainMode == domainMode || |
369 (domain.fLeft <= domain.fRight && domain.fTop <= domain.fBottom)); | 399 (domain.fLeft <= domain.fRight && domain.fTop <= domain.fBottom)); |
370 textureMatrix.postIDiv(texture->width(), texture->height()); | 400 textureMatrix.postIDiv(texture->width(), texture->height()); |
371 if (filterOrNullForBicubic) { | 401 return create_fp_for_domain_and_filter(texture, textureMatrix, domainMode, d
omain, |
372 if (kDomain_DomainMode == domainMode) { | 402 filterOrNullForBicubic); |
373 return GrTextureDomainEffect::Create(texture, textureMatrix, domain, | |
374 GrTextureDomain::kClamp_Mode, | |
375 *filterOrNullForBicubic); | |
376 } else { | |
377 GrTextureParams params(SkShader::kClamp_TileMode, *filterOrNullForBi
cubic); | |
378 return GrSimpleTextureEffect::Create(texture, textureMatrix, params)
; | |
379 } | |
380 } else { | |
381 if (kDomain_DomainMode == domainMode) { | |
382 return GrBicubicEffect::Create(texture, textureMatrix, domain); | |
383 } else { | |
384 static const SkShader::TileMode kClampClamp[] = | |
385 { SkShader::kClamp_TileMode, SkShader::kClamp_TileMode }; | |
386 return GrBicubicEffect::Create(texture, textureMatrix, kClampClamp); | |
387 } | |
388 } | |
389 } | 403 } |
390 | 404 |
391 ////////////////////////////////////////////////////////////////////////////// | 405 ////////////////////////////////////////////////////////////////////////////// |
392 | 406 |
393 GrTexture* GrTextureMaker::refTextureForParams(GrContext* ctx, const GrTexturePa
rams& params) { | 407 GrTexture* GrTextureMaker::refTextureForParams(const GrTextureParams& params) { |
394 CopyParams copyParams; | 408 CopyParams copyParams; |
395 if (!ctx->getGpu()->makeCopyForTextureParams(this->width(), this->height(),
params, | 409 if (!fContext->getGpu()->makeCopyForTextureParams(this->width(), this->heigh
t(), params, |
396 ©Params)) { | 410 ©Params)) { |
397 return this->refOriginalTexture(ctx); | 411 return this->refOriginalTexture(); |
398 } | 412 } |
399 GrUniqueKey copyKey; | 413 GrUniqueKey copyKey; |
400 this->makeCopyKey(copyParams, ©Key); | 414 this->makeCopyKey(copyParams, ©Key); |
401 if (copyKey.isValid()) { | 415 if (copyKey.isValid()) { |
402 GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey
(copyKey); | 416 GrTexture* result = fContext->textureProvider()->findAndRefTextureByUniq
ueKey(copyKey); |
403 if (result) { | 417 if (result) { |
404 return result; | 418 return result; |
405 } | 419 } |
406 } | 420 } |
407 | 421 |
408 GrTexture* result = this->generateTextureForParams(ctx, copyParams); | 422 GrTexture* result = this->generateTextureForParams(copyParams); |
409 if (!result) { | 423 if (!result) { |
410 return nullptr; | 424 return nullptr; |
411 } | 425 } |
412 | 426 |
413 if (copyKey.isValid()) { | 427 if (copyKey.isValid()) { |
414 ctx->textureProvider()->assignUniqueKeyToTexture(copyKey, result); | 428 fContext->textureProvider()->assignUniqueKeyToTexture(copyKey, result); |
415 this->didCacheCopy(copyKey); | 429 this->didCacheCopy(copyKey); |
416 } | 430 } |
417 return result; | 431 return result; |
418 } | 432 } |
419 | 433 |
420 GrTexture* GrTextureMaker::generateTextureForParams(GrContext* ctx, const CopyPa
rams& copyParams) { | 434 const GrFragmentProcessor* GrTextureMaker::createFragmentProcessor( |
421 SkAutoTUnref<GrTexture> original(this->refOriginalTexture(ctx)); | 435 const SkMatrix& textureMatrix, |
| 436 const SkRect& constraintRect, |
| 437 FilterConstraint filterConstraint, |
| 438 bool coordsLimitedToConstraintRect, |
| 439 const GrTextureParams::FilterMode* filte
rOrNullForBicubic) { |
| 440 |
| 441 const GrTextureParams::FilterMode* fmForDetermineDomain = filterOrNullForBic
ubic; |
| 442 if (filterOrNullForBicubic && GrTextureParams::kMipMap_FilterMode == *filter
OrNullForBicubic && |
| 443 kYes_FilterConstraint == filterConstraint) { |
| 444 // TODo: Here we should force a copy restricted to the constraintRect si
nce MIP maps will |
| 445 // read outside the constraint rect. However, as in the adjuster case, w
e aren't currently |
| 446 // doing that. |
| 447 // We instead we compute the domain as though were bilerping which is on
ly correct if we |
| 448 // only sample level 0. |
| 449 static const GrTextureParams::FilterMode kBilerp = GrTextureParams::kBil
erp_FilterMode; |
| 450 fmForDetermineDomain = &kBilerp; |
| 451 } |
| 452 |
| 453 GrTextureParams params; |
| 454 if (filterOrNullForBicubic) { |
| 455 params.reset(SkShader::kClamp_TileMode, *filterOrNullForBicubic); |
| 456 } else { |
| 457 // Bicubic doesn't use filtering for it's texture accesses. |
| 458 params.reset(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMod
e); |
| 459 } |
| 460 SkAutoTUnref<GrTexture> texture(this->refTextureForParams(params)); |
| 461 if (!texture) { |
| 462 return nullptr; |
| 463 } |
| 464 SkRect domain; |
| 465 DomainMode domainMode = |
| 466 determine_domain_mode(constraintRect, filterConstraint, coordsLimitedToC
onstraintRect, |
| 467 texture->width(), texture->height(), nullptr, fmFo
rDetermineDomain, |
| 468 &domain); |
| 469 SkASSERT(kTightCopy_DomainMode != domainMode); |
| 470 SkMatrix normalizedTextureMatrix = textureMatrix; |
| 471 normalizedTextureMatrix.postIDiv(texture->width(), texture->height()); |
| 472 return create_fp_for_domain_and_filter(texture, normalizedTextureMatrix, dom
ainMode, domain, |
| 473 filterOrNullForBicubic); |
| 474 } |
| 475 |
| 476 GrTexture* GrTextureMaker::generateTextureForParams(const CopyParams& copyParams
) { |
| 477 SkAutoTUnref<GrTexture> original(this->refOriginalTexture()); |
422 if (!original) { | 478 if (!original) { |
423 return nullptr; | 479 return nullptr; |
424 } | 480 } |
425 return copy_on_gpu(original, nullptr, copyParams); | 481 return copy_on_gpu(original, nullptr, copyParams); |
426 } | 482 } |
OLD | NEW |