OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2010 Google Inc. | 2 * Copyright 2010 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 "SkGr.h" | 8 #include "SkGr.h" |
9 | 9 |
10 #include "GrCaps.h" | 10 #include "GrCaps.h" |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 break; | 496 break; |
497 case Stretch::kNone_Type: | 497 case Stretch::kNone_Type: |
498 SkDEBUGFAIL("Shouldn't get here."); | 498 SkDEBUGFAIL("Shouldn't get here."); |
499 break; | 499 break; |
500 } | 500 } |
501 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar (stretch.fHeight)); | 501 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar (stretch.fHeight)); |
502 canvas.drawBitmapRect(bmp, dstRect, &paint); | 502 canvas.drawBitmapRect(bmp, dstRect, &paint); |
503 return stretched; | 503 return stretched; |
504 } | 504 } |
505 | 505 |
506 static GrTexture* create_bitmap_texture(GrContext* ctx, | |
507 const SkBitmap& bmp, | |
508 const Stretch& stretch, | |
509 const GrUniqueKey& unstretchedKey, | |
510 const GrUniqueKey& stretchedKey) { | |
511 if (Stretch::kNone_Type != stretch.fType) { | |
512 SkAutoTUnref<GrTexture> unstretched; | |
513 // Check if we have the unstretched version in the cache, if not create it. | |
514 if (unstretchedKey.isValid()) { | |
515 unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueK ey(unstretchedKey)); | |
516 } | |
517 if (!unstretched) { | |
518 unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstre tchedKey)); | |
519 if (!unstretched) { | |
520 // We might not have been able to create a unstrecthed texture b ecause it is smaller | |
521 // than the min texture size. In that case do cpu stretching. | |
522 SkBitmap stretchedBmp = stretch_on_cpu(bmp, stretch); | |
523 return create_unstretched_bitmap_texture(ctx, stretchedBmp, stre tchedKey); | |
524 } | |
525 } | |
526 return stretch_texture(unstretched, stretch, bmp.pixelRef(), stretchedKe y); | |
527 } | |
528 return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey); | |
529 } | |
530 | |
531 bool GrIsImageInCache(const GrContext* ctx, uint32_t imageID, const SkIRect& sub set, | 506 bool GrIsImageInCache(const GrContext* ctx, uint32_t imageID, const SkIRect& sub set, |
532 GrTexture* nativeTexture, const GrTextureParams* params) { | 507 GrTexture* nativeTexture, const GrTextureParams* params) { |
533 Stretch stretch; | 508 Stretch stretch; |
534 get_stretch(ctx, subset.width(), subset.height(), params, &stretch); | 509 get_stretch(ctx, subset.width(), subset.height(), params, &stretch); |
535 | 510 |
536 // Handle the case where the bitmap/image is explicitly texture backed. | 511 // Handle the case where the bitmap/image is explicitly texture backed. |
537 if (nativeTexture) { | 512 if (nativeTexture) { |
538 if (Stretch::kNone_Type == stretch.fType) { | 513 if (Stretch::kNone_Type == stretch.fType) { |
539 return true; | 514 return true; |
540 } | 515 } |
(...skipping 14 matching lines...) Expand all Loading... | |
555 | 530 |
556 bool GrIsBitmapInCache(const GrContext* ctx, const SkBitmap& bitmap, | 531 bool GrIsBitmapInCache(const GrContext* ctx, const SkBitmap& bitmap, |
557 const GrTextureParams* params) { | 532 const GrTextureParams* params) { |
558 if (bitmap.isVolatile()) { | 533 if (bitmap.isVolatile()) { |
559 return false; // we don't cache volatile bitmaps. | 534 return false; // we don't cache volatile bitmaps. |
560 } | 535 } |
561 return GrIsImageInCache(ctx, bitmap.getGenerationID(), bitmap.getSubset(), b itmap.getTexture(), | 536 return GrIsImageInCache(ctx, bitmap.getGenerationID(), bitmap.getSubset(), b itmap.getTexture(), |
562 params); | 537 params); |
563 } | 538 } |
564 | 539 |
565 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, | 540 class GrTextureMaker { |
566 const SkBitmap& bitmap, | 541 public: |
567 const GrTextureParams* params) { | 542 GrTextureMaker(int width, int height) : fWidth(width), fHeight(height) {} |
568 | 543 |
544 int width() const { return fWidth; } | |
545 int height() const { return fHeight; } | |
546 | |
547 GrTexture* refCachedTexture(GrContext*, const GrTextureParams*); | |
548 | |
549 protected: | |
550 /** | |
551 * Return the maker's "original" unstretched texture. It is the responsibil ity of the maker | |
552 * to make this efficient ... if the texture is being generated, the maker must handle | |
553 * caching it. | |
554 */ | |
555 virtual GrTexture* onRefUnstretchedTexture(GrContext*) = 0; | |
556 | |
557 /** | |
558 * If we need to stretch the maker's original texture, the maker is asked t o return a key | |
559 * that identifies its origianl + the stretch parameter. If the maker does not want to cache | |
560 * the stretched version (e.g. the maker is volatile), this should ignore t he key parameter | |
561 * and return false. | |
562 */ | |
563 virtual bool onMakeStretchedKey(const Stretch&, GrUniqueKey* stretchedKey) = 0; | |
564 | |
565 /** | |
566 * Return a new (uncached) texture that is the stretch of the maker's origi nal. | |
567 * | |
568 * The base-class handles general logic for this, and only needs access to the following | |
569 * methods: | |
570 * - onRefUnstretchedTexture() | |
571 * - onGetROBitmkap() | |
bsalomon
2015/09/29 19:23:29
ROBitmap
reed1
2015/09/29 19:38:13
Done.
| |
572 * | |
573 * Subclass may override this if they can handle stretching more efficientl y. | |
574 */ | |
575 virtual GrTexture* onGenerateStretchedTexture(GrContext*, const Stretch&); | |
576 | |
577 /** | |
578 * If a stretched version of the texture is generated, it may be cached (as suming that | |
579 * onMakeStretchedKey() returns true). In that case, the maker is notified in case it | |
580 * wants to note that for when the maker is destroyed. | |
581 */ | |
582 virtual void onNotifyStretchCached(const GrUniqueKey& stretchedKey) = 0; | |
583 | |
584 /** | |
585 * Some GPUs are unreliable w/ very small texture sizes. If we run into tha t case, this | |
586 * method will be called (in service of onGenerateStretchedTexture) to retu rn a raster version | |
587 * of the original texture. | |
588 */ | |
589 virtual bool onGetROBitmap(SkBitmap*) = 0; | |
590 | |
591 private: | |
592 const int fWidth; | |
593 const int fHeight; | |
594 }; | |
595 | |
596 GrTexture* GrTextureMaker::onGenerateStretchedTexture(GrContext* ctx, const Stre tch& stretch) { | |
597 if (this->width() < ctx->caps()->minTextureSize() || | |
598 this->height() < ctx->caps()->minTextureSize()) | |
599 { | |
600 // we can't trust our ability to use HW to perform the stretch, so we re quest | |
601 // a raster instead, and perform the stretch on the CPU. | |
602 SkBitmap bitmap; | |
603 if (!this->onGetROBitmap(&bitmap)) { | |
604 return nullptr; | |
605 } | |
606 SkBitmap stretchedBmp = stretch_on_cpu(bitmap, stretch); | |
607 return create_unstretched_bitmap_texture(ctx, stretchedBmp, GrUniqueKey( )); | |
608 } else { | |
609 SkAutoTUnref<GrTexture> unstretched(this->onRefUnstretchedTexture(ctx)); | |
610 if (!unstretched) { | |
611 return nullptr; | |
612 } | |
613 return stretch_texture(unstretched, stretch, nullptr, GrUniqueKey()); | |
614 } | |
615 } | |
616 | |
bsalomon
2015/09/29 19:23:29
extra \n
reed1
2015/09/29 19:38:13
Done.
| |
617 | |
618 GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, const GrTextureParam s* params) { | |
569 Stretch stretch; | 619 Stretch stretch; |
570 get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); | 620 get_stretch(ctx, this->width(), this->height(), params, &stretch); |
571 | 621 |
572 GrTexture* result = bitmap.getTexture(); | 622 if (Stretch::kNone_Type == stretch.fType) { |
573 if (result) { | 623 return this->onRefUnstretchedTexture(ctx); |
574 if (Stretch::kNone_Type == stretch.fType) { | |
575 return SkRef(result); | |
576 } | |
577 GrUniqueKey stretchedKey; | |
578 // Don't create a key for the resized version if the bmp is volatile. | |
579 if (!bitmap.isVolatile()) { | |
580 const GrUniqueKey& key = result->getUniqueKey(); | |
581 if (key.isValid()) { | |
582 make_stretched_key(key, stretch, &stretchedKey); | |
583 GrTexture* stretched = | |
584 ctx->textureProvider()->findAndRefTextureByUniqueKey(stretch edKey); | |
585 if (stretched) { | |
586 return stretched; | |
587 } | |
588 } | |
589 } | |
590 return stretch_texture(result, stretch, bitmap.pixelRef(), stretchedKey) ; | |
591 } | 624 } |
592 | 625 |
593 GrUniqueKey key, resizedKey; | 626 GrUniqueKey stretchedKey; |
594 | 627 if (this->onMakeStretchedKey(stretch, &stretchedKey)) { |
595 if (!bitmap.isVolatile()) { | 628 GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey (stretchedKey); |
596 // If the bitmap isn't changing try to find a cached copy first. | |
597 make_image_keys(bitmap.getGenerationID(), bitmap.getSubset(), stretch, & key, &resizedKey); | |
598 | |
599 result = ctx->textureProvider()->findAndRefTextureByUniqueKey( | |
600 resizedKey.isValid() ? resizedKey : key); | |
601 if (result) { | 629 if (result) { |
602 return result; | 630 return result; |
603 } | 631 } |
604 } | 632 } |
605 | 633 |
606 result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey); | 634 GrTexture* result = this->onGenerateStretchedTexture(ctx, stretch); |
607 if (result) { | 635 if (!result) { |
608 return result; | 636 return nullptr; |
609 } | 637 } |
610 | 638 |
611 SkErrorInternals::SetError( kInternalError_SkError, | 639 if (stretchedKey.isValid()) { |
612 "---- failed to create texture for cache [%d %d] \n", | 640 ctx->textureProvider()->assignUniqueKeyToTexture(stretchedKey, result); |
613 bitmap.width(), bitmap.height()); | 641 this->onNotifyStretchCached(stretchedKey); |
642 } | |
643 return result; | |
644 } | |
614 | 645 |
615 return nullptr; | 646 class Bitmap_GrTextureMaker : public GrTextureMaker { |
647 public: | |
648 Bitmap_GrTextureMaker(const SkBitmap& bitmap) | |
649 : INHERITED(bitmap.width(), bitmap.height()) | |
650 , fBitmap(bitmap) | |
651 {} | |
652 | |
653 protected: | |
654 GrTexture* onRefUnstretchedTexture(GrContext* ctx) override { | |
655 GrTexture* tex = fBitmap.getTexture(); | |
656 if (tex) { | |
657 return SkRef(tex); | |
658 } | |
659 | |
660 GrUniqueKey unstretchedKey; | |
661 make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap .getSubset()); | |
662 return create_unstretched_bitmap_texture(ctx, fBitmap, unstretchedKey); | |
663 } | |
664 | |
665 bool onMakeStretchedKey(const Stretch& stretch, GrUniqueKey* stretchedKey) o verride { | |
666 if (fBitmap.isVolatile()) { | |
667 return false; | |
668 } | |
669 | |
670 GrUniqueKey unstretchedKey; | |
671 make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap .getSubset()); | |
672 return make_stretched_key(unstretchedKey, stretch, stretchedKey); | |
673 } | |
674 | |
675 void onNotifyStretchCached(const GrUniqueKey& stretchedKey) override { | |
676 fBitmap.pixelRef()->addGenIDChangeListener(new BitmapInvalidator(stretch edKey)); | |
677 } | |
678 | |
679 bool onGetROBitmap(SkBitmap* bitmap) override { | |
680 *bitmap = fBitmap; | |
681 return true; | |
682 } | |
683 | |
684 private: | |
685 const SkBitmap fBitmap; | |
686 | |
687 typedef GrTextureMaker INHERITED; | |
688 }; | |
689 | |
690 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap, | |
691 const GrTextureParams* params) { | |
692 return Bitmap_GrTextureMaker(bitmap).refCachedTexture(ctx, params); | |
616 } | 693 } |
617 | 694 |
618 // TODO: make this be the canonical signature, and turn the version that takes G rTextureParams* | 695 // TODO: make this be the canonical signature, and turn the version that takes G rTextureParams* |
619 // into a wrapper that contains the inverse of these tables. | 696 // into a wrapper that contains the inverse of these tables. |
620 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, | 697 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, |
621 const SkBitmap& bitmap, | 698 const SkBitmap& bitmap, |
622 SkImageUsageType usage) { | 699 SkImageUsageType usage) { |
623 // Just need a params that will trigger the correct cache key / etc, since t he usage doesn't | 700 // Just need a params that will trigger the correct cache key / etc, since t he usage doesn't |
624 // tell us the specifics about filter level or specific tiling. | 701 // tell us the specifics about filter level or specific tiling. |
625 | 702 |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
941 SkErrorInternals::SetError( kInvalidPaint_SkError, | 1018 SkErrorInternals::SetError( kInvalidPaint_SkError, |
942 "Sorry, I don't understand the filtering " | 1019 "Sorry, I don't understand the filtering " |
943 "mode you asked for. Falling back to " | 1020 "mode you asked for. Falling back to " |
944 "MIPMaps."); | 1021 "MIPMaps."); |
945 textureFilterMode = GrTextureParams::kMipMap_FilterMode; | 1022 textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
946 break; | 1023 break; |
947 | 1024 |
948 } | 1025 } |
949 return textureFilterMode; | 1026 return textureFilterMode; |
950 } | 1027 } |
OLD | NEW |