Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Side by Side Diff: src/gpu/SkGr.cpp

Issue 1376603002: try texture-maker to generalize stretching for npot and min-tex-size (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698