OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "SkColorPriv.h" | 8 #include "SkColorPriv.h" |
9 #include "SkReadBuffer.h" | 9 #include "SkReadBuffer.h" |
10 #include "SkWriteBuffer.h" | 10 #include "SkWriteBuffer.h" |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 #endif | 375 #endif |
376 | 376 |
377 /////////////////////////////////////////////////////////////////////////////// | 377 /////////////////////////////////////////////////////////////////////////////// |
378 | 378 |
379 #if SK_SUPPORT_GPU | 379 #if SK_SUPPORT_GPU |
380 | 380 |
381 #include "GrTextureAccess.h" | 381 #include "GrTextureAccess.h" |
382 #include "effects/GrSimpleTextureEffect.h" | 382 #include "effects/GrSimpleTextureEffect.h" |
383 #include "SkGr.h" | 383 #include "SkGr.h" |
384 | 384 |
385 // Note that this will return -1 if either matrix is perspective. | |
386 static SkScalar get_combined_min_stretch(const SkMatrix& viewMatrix, const SkMat
rix& localMatrix) { | |
387 if (localMatrix.isIdentity()) { | |
388 return viewMatrix.getMinScale(); | |
389 } else { | |
390 SkMatrix combined; | |
391 combined.setConcat(viewMatrix, localMatrix); | |
392 return combined.getMinScale(); | |
393 } | |
394 } | |
395 | |
396 GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint&
paint, | 385 GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint&
paint, |
397 const SkMatrix* localMatrix) const
{ | 386 const SkMatrix* localMatrix) const
{ |
398 SkMatrix matrix; | 387 SkMatrix matrix; |
399 matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); | 388 matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); |
400 | 389 |
401 SkMatrix lmInverse; | 390 SkMatrix lmInverse; |
402 if (!this->getLocalMatrix().invert(&lmInverse)) { | 391 if (!this->getLocalMatrix().invert(&lmInverse)) { |
403 return NULL; | 392 return NULL; |
404 } | 393 } |
405 if (localMatrix) { | 394 if (localMatrix) { |
406 SkMatrix inv; | 395 SkMatrix inv; |
407 if (!localMatrix->invert(&inv)) { | 396 if (!localMatrix->invert(&inv)) { |
408 return NULL; | 397 return NULL; |
409 } | 398 } |
410 lmInverse.postConcat(inv); | 399 lmInverse.postConcat(inv); |
411 } | 400 } |
412 matrix.preConcat(lmInverse); | 401 matrix.preConcat(lmInverse); |
413 | 402 |
414 SkShader::TileMode tm[] = { | 403 SkShader::TileMode tm[] = { |
415 (TileMode)fTileModeX, | 404 (TileMode)fTileModeX, |
416 (TileMode)fTileModeY, | 405 (TileMode)fTileModeY, |
417 }; | 406 }; |
418 | 407 |
419 // Must set wrap and filter on the sampler before requesting a texture. In t
wo places below | 408 // Must set wrap and filter on the sampler before requesting a texture. In t
wo places below |
420 // we check the matrix scale factors to determine how to interpret the filte
r quality setting. | 409 // we check the matrix scale factors to determine how to interpret the filte
r quality setting. |
421 // This completely ignores the complexity of the drawVertices case where exp
licit local coords | 410 // This completely ignores the complexity of the drawVertices case where exp
licit local coords |
422 // are provided by the caller. | 411 // are provided by the caller. |
423 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); | 412 bool useBicubic = false; |
424 GrTextureParams::FilterMode textureFilterMode; | 413 GrTextureParams::FilterMode textureFilterMode; |
425 switch(paintFilterLevel) { | 414 switch(paint.getFilterLevel()) { |
426 case SkPaint::kNone_FilterLevel: | 415 case SkPaint::kNone_FilterLevel: |
427 textureFilterMode = GrTextureParams::kNone_FilterMode; | 416 textureFilterMode = GrTextureParams::kNone_FilterMode; |
428 break; | 417 break; |
429 case SkPaint::kLow_FilterLevel: | 418 case SkPaint::kLow_FilterLevel: |
430 textureFilterMode = GrTextureParams::kBilerp_FilterMode; | 419 textureFilterMode = GrTextureParams::kBilerp_FilterMode; |
431 break; | 420 break; |
432 case SkPaint::kMedium_FilterLevel: | 421 case SkPaint::kMedium_FilterLevel: { |
433 if (get_combined_min_stretch(context->getMatrix(), this->getLocalMat
rix()) < | 422 SkMatrix matrix; |
434 SK_Scalar1) { | 423 matrix.setConcat(context->getMatrix(), this->getLocalMatrix()); |
| 424 if (matrix.getMinScale() < SK_Scalar1) { |
435 textureFilterMode = GrTextureParams::kMipMap_FilterMode; | 425 textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
436 } else { | 426 } else { |
437 // Don't trigger MIP level generation unnecessarily. | 427 // Don't trigger MIP level generation unnecessarily. |
438 textureFilterMode = GrTextureParams::kBilerp_FilterMode; | 428 textureFilterMode = GrTextureParams::kBilerp_FilterMode; |
439 } | 429 } |
440 break; | 430 break; |
441 case SkPaint::kHigh_FilterLevel: | 431 } |
442 // Minification can look bad with bicubic filtering. | 432 case SkPaint::kHigh_FilterLevel: { |
443 if (get_combined_min_stretch(context->getMatrix(), this->getLocalMat
rix()) >= | 433 SkMatrix matrix; |
444 SK_Scalar1) { | 434 matrix.setConcat(context->getMatrix(), this->getLocalMatrix()); |
445 // fall back to no filtering here; we will install another shade
r that will do the | 435 useBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilte
rMode); |
446 // HQ filtering. | |
447 textureFilterMode = GrTextureParams::kNone_FilterMode; | |
448 } else { | |
449 // Fall back to MIP-mapping. | |
450 paintFilterLevel = SkPaint::kMedium_FilterLevel; | |
451 textureFilterMode = GrTextureParams::kMipMap_FilterMode; | |
452 } | |
453 break; | 436 break; |
| 437 } |
454 default: | 438 default: |
455 SkErrorInternals::SetError( kInvalidPaint_SkError, | 439 SkErrorInternals::SetError( kInvalidPaint_SkError, |
456 "Sorry, I don't understand the filtering
" | 440 "Sorry, I don't understand the filtering
" |
457 "mode you asked for. Falling back to " | 441 "mode you asked for. Falling back to " |
458 "MIPMaps."); | 442 "MIPMaps."); |
459 textureFilterMode = GrTextureParams::kMipMap_FilterMode; | 443 textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
460 break; | 444 break; |
461 | 445 |
462 } | 446 } |
463 GrTextureParams params(tm, textureFilterMode); | 447 GrTextureParams params(tm, textureFilterMode); |
464 GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, fRawBitmap, &p
arams); | 448 GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, fRawBitmap, &p
arams); |
465 | 449 |
466 if (NULL == texture) { | 450 if (NULL == texture) { |
467 SkErrorInternals::SetError( kInternalError_SkError, | 451 SkErrorInternals::SetError( kInternalError_SkError, |
468 "Couldn't convert bitmap to texture."); | 452 "Couldn't convert bitmap to texture."); |
469 return NULL; | 453 return NULL; |
470 } | 454 } |
471 | 455 |
472 GrEffectRef* effect = NULL; | 456 GrEffectRef* effect = NULL; |
473 if (paintFilterLevel == SkPaint::kHigh_FilterLevel) { | 457 if (useBicubic) { |
474 effect = GrBicubicEffect::Create(texture, matrix, tm); | 458 effect = GrBicubicEffect::Create(texture, matrix, tm); |
475 } else { | 459 } else { |
476 effect = GrSimpleTextureEffect::Create(texture, matrix, params); | 460 effect = GrSimpleTextureEffect::Create(texture, matrix, params); |
477 } | 461 } |
478 GrUnlockAndUnrefCachedBitmapTexture(texture); | 462 GrUnlockAndUnrefCachedBitmapTexture(texture); |
479 return effect; | 463 return effect; |
480 } | 464 } |
481 #endif | 465 #endif |
OLD | NEW |