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

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

Issue 2249163004: Fix tile bitmap code in SkGpuDevice to compute correct local coords (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: fix int->scalar warning on windows Created 4 years, 4 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 | « src/gpu/SkGpuDevice.h ('k') | 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 2011 Google Inc. 2 * Copyright 2011 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 "SkGpuDevice.h" 8 #include "SkGpuDevice.h"
9 9
10 #include "GrBlurUtils.h" 10 #include "GrBlurUtils.h"
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 } else { 666 } else {
667 return maxTileSize; 667 return maxTileSize;
668 } 668 }
669 } 669 }
670 670
671 // Given a bitmap, an optional src rect, and a context with a clip and matrix de termine what 671 // Given a bitmap, an optional src rect, and a context with a clip and matrix de termine what
672 // pixels from the bitmap are necessary. 672 // pixels from the bitmap are necessary.
673 static void determine_clipped_src_rect(int width, int height, 673 static void determine_clipped_src_rect(int width, int height,
674 const GrClip& clip, 674 const GrClip& clip,
675 const SkMatrix& viewMatrix, 675 const SkMatrix& viewMatrix,
676 const SkMatrix& srcToDstRect,
676 const SkISize& imageSize, 677 const SkISize& imageSize,
677 const SkRect* srcRectPtr, 678 const SkRect* srcRectPtr,
678 SkIRect* clippedSrcIRect) { 679 SkIRect* clippedSrcIRect) {
679 clip.getConservativeBounds(width, height, clippedSrcIRect, nullptr); 680 clip.getConservativeBounds(width, height, clippedSrcIRect, nullptr);
680 SkMatrix inv; 681 SkMatrix inv = SkMatrix::Concat(viewMatrix, srcToDstRect);
681 if (!viewMatrix.invert(&inv)) { 682 if (!inv.invert(&inv)) {
682 clippedSrcIRect->setEmpty(); 683 clippedSrcIRect->setEmpty();
683 return; 684 return;
684 } 685 }
685 SkRect clippedSrcRect = SkRect::Make(*clippedSrcIRect); 686 SkRect clippedSrcRect = SkRect::Make(*clippedSrcIRect);
686 inv.mapRect(&clippedSrcRect); 687 inv.mapRect(&clippedSrcRect);
687 if (srcRectPtr) { 688 if (srcRectPtr) {
688 // we've setup src space 0,0 to map to the top left of the src rect. 689 // we've setup src space 0,0 to map to the top left of the src rect.
689 clippedSrcRect.offset(srcRectPtr->fLeft, srcRectPtr->fTop); 690 clippedSrcRect.offset(srcRectPtr->fLeft, srcRectPtr->fTop);
690 if (!clippedSrcRect.intersect(*srcRectPtr)) { 691 if (!clippedSrcRect.intersect(*srcRectPtr)) {
691 clippedSrcIRect->setEmpty(); 692 clippedSrcIRect->setEmpty();
692 return; 693 return;
693 } 694 }
694 } 695 }
695 clippedSrcRect.roundOut(clippedSrcIRect); 696 clippedSrcRect.roundOut(clippedSrcIRect);
696 SkIRect bmpBounds = SkIRect::MakeSize(imageSize); 697 SkIRect bmpBounds = SkIRect::MakeSize(imageSize);
697 if (!clippedSrcIRect->intersect(bmpBounds)) { 698 if (!clippedSrcIRect->intersect(bmpBounds)) {
698 clippedSrcIRect->setEmpty(); 699 clippedSrcIRect->setEmpty();
699 } 700 }
700 } 701 }
701 702
702 bool SkGpuDevice::shouldTileImageID(uint32_t imageID, const SkIRect& imageRect, 703 bool SkGpuDevice::shouldTileImageID(uint32_t imageID, const SkIRect& imageRect,
703 const SkMatrix& viewMatrix, 704 const SkMatrix& viewMatrix,
705 const SkMatrix& srcToDstRect,
704 const GrTextureParams& params, 706 const GrTextureParams& params,
705 const SkRect* srcRectPtr, 707 const SkRect* srcRectPtr,
706 int maxTileSize, 708 int maxTileSize,
707 int* tileSize, 709 int* tileSize,
708 SkIRect* clippedSubset) const { 710 SkIRect* clippedSubset) const {
709 ASSERT_SINGLE_OWNER 711 ASSERT_SINGLE_OWNER
710 // if it's larger than the max tile size, then we have no choice but tiling. 712 // if it's larger than the max tile size, then we have no choice but tiling.
711 if (imageRect.width() > maxTileSize || imageRect.height() > maxTileSize) { 713 if (imageRect.width() > maxTileSize || imageRect.height() > maxTileSize) {
712 determine_clipped_src_rect(fDrawContext->width(), fDrawContext->height() , 714 determine_clipped_src_rect(fDrawContext->width(), fDrawContext->height() , fClip, viewMatrix,
713 fClip, viewMatrix, imageRect.size(), 715 srcToDstRect, imageRect.size(), srcRectPtr, c lippedSubset);
714 srcRectPtr, clippedSubset);
715 *tileSize = determine_tile_size(*clippedSubset, maxTileSize); 716 *tileSize = determine_tile_size(*clippedSubset, maxTileSize);
716 return true; 717 return true;
717 } 718 }
718 719
719 // If the image would only produce 4 tiles of the smaller size, don't bother tiling it. 720 // If the image would only produce 4 tiles of the smaller size, don't bother tiling it.
720 const size_t area = imageRect.width() * imageRect.height(); 721 const size_t area = imageRect.width() * imageRect.height();
721 if (area < 4 * kBmpSmallTileSize * kBmpSmallTileSize) { 722 if (area < 4 * kBmpSmallTileSize * kBmpSmallTileSize) {
722 return false; 723 return false;
723 } 724 }
724 725
725 // At this point we know we could do the draw by uploading the entire bitmap 726 // At this point we know we could do the draw by uploading the entire bitmap
726 // as a texture. However, if the texture would be large compared to the 727 // as a texture. However, if the texture would be large compared to the
727 // cache size and we don't require most of it for this draw then tile to 728 // cache size and we don't require most of it for this draw then tile to
728 // reduce the amount of upload and cache spill. 729 // reduce the amount of upload and cache spill.
729 730
730 // assumption here is that sw bitmap size is a good proxy for its size as 731 // assumption here is that sw bitmap size is a good proxy for its size as
731 // a texture 732 // a texture
732 size_t bmpSize = area * sizeof(SkPMColor); // assume 32bit pixels 733 size_t bmpSize = area * sizeof(SkPMColor); // assume 32bit pixels
733 size_t cacheSize; 734 size_t cacheSize;
734 fContext->getResourceCacheLimits(nullptr, &cacheSize); 735 fContext->getResourceCacheLimits(nullptr, &cacheSize);
735 if (bmpSize < cacheSize / 2) { 736 if (bmpSize < cacheSize / 2) {
736 return false; 737 return false;
737 } 738 }
738 739
739 // Figure out how much of the src we will need based on the src rect and cli pping. Reject if 740 // Figure out how much of the src we will need based on the src rect and cli pping. Reject if
740 // tiling memory savings would be < 50%. 741 // tiling memory savings would be < 50%.
741 determine_clipped_src_rect(fDrawContext->width(), fDrawContext->height(), 742 determine_clipped_src_rect(fDrawContext->width(), fDrawContext->height(), fC lip, viewMatrix,
742 fClip, viewMatrix, imageRect.size(), srcRectPtr, 743 srcToDstRect, imageRect.size(), srcRectPtr, clipp edSubset);
743 clippedSubset);
744 *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile. 744 *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile.
745 size_t usedTileBytes = get_tile_count(*clippedSubset, kBmpSmallTileSize) * 745 size_t usedTileBytes = get_tile_count(*clippedSubset, kBmpSmallTileSize) *
746 kBmpSmallTileSize * kBmpSmallTileSize; 746 kBmpSmallTileSize * kBmpSmallTileSize;
747 747
748 return usedTileBytes < 2 * bmpSize; 748 return usedTileBytes < 2 * bmpSize;
749 } 749 }
750 750
751 bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap,
752 const SkMatrix& viewMatrix,
753 const GrTextureParams& params,
754 const SkRect* srcRectPtr,
755 int maxTileSize,
756 int* tileSize,
757 SkIRect* clippedSrcRect) const {
758 ASSERT_SINGLE_OWNER
759 return this->shouldTileImageID(bitmap.getGenerationID(), bitmap.getSubset(), viewMatrix, params,
760 srcRectPtr, maxTileSize, tileSize, clippedSrc Rect);
761 }
762
763 bool SkGpuDevice::shouldTileImage(const SkImage* image, const SkRect* srcRectPtr , 751 bool SkGpuDevice::shouldTileImage(const SkImage* image, const SkRect* srcRectPtr ,
764 SkCanvas::SrcRectConstraint constraint, SkFilt erQuality quality, 752 SkCanvas::SrcRectConstraint constraint, SkFilt erQuality quality,
765 const SkMatrix& viewMatrix) const { 753 const SkMatrix& viewMatrix,
754 const SkMatrix& srcToDstRect) const {
766 ASSERT_SINGLE_OWNER 755 ASSERT_SINGLE_OWNER
767 // if image is explictly texture backed then just use the texture 756 // if image is explictly texture backed then just use the texture
768 if (as_IB(image)->peekTexture()) { 757 if (as_IB(image)->peekTexture()) {
769 return false; 758 return false;
770 } 759 }
771 760
772 GrTextureParams params; 761 GrTextureParams params;
773 bool doBicubic; 762 bool doBicubic;
774 GrTextureParams::FilterMode textureFilterMode = 763 GrTextureParams::FilterMode textureFilterMode =
775 GrSkFilterQualityToGrFilterMode(quality, viewMatrix, SkMatri x::I(), &doBicubic); 764 GrSkFilterQualityToGrFilterMode(quality, viewMatrix, srcToDs tRect, &doBicubic);
776 765
777 int tileFilterPad; 766 int tileFilterPad;
778 if (doBicubic) { 767 if (doBicubic) {
779 tileFilterPad = GrBicubicEffect::kFilterTexelPad; 768 tileFilterPad = GrBicubicEffect::kFilterTexelPad;
780 } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) { 769 } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) {
781 tileFilterPad = 0; 770 tileFilterPad = 0;
782 } else { 771 } else {
783 tileFilterPad = 1; 772 tileFilterPad = 1;
784 } 773 }
785 params.setFilterMode(textureFilterMode); 774 params.setFilterMode(textureFilterMode);
786 775
787 int maxTileSize = fContext->caps()->maxTileSize() - 2 * tileFilterPad; 776 int maxTileSize = fContext->caps()->maxTileSize() - 2 * tileFilterPad;
788 777
789 // these are output, which we safely ignore, as we just want to know the pre dicate 778 // these are output, which we safely ignore, as we just want to know the pre dicate
790 int outTileSize; 779 int outTileSize;
791 SkIRect outClippedSrcRect; 780 SkIRect outClippedSrcRect;
792 781
793 return this->shouldTileImageID(image->unique(), image->bounds(), viewMatrix, params, srcRectPtr, 782 return this->shouldTileImageID(image->unique(), image->bounds(), viewMatrix, srcToDstRect,
794 maxTileSize, &outTileSize, &outClippedSrcRect ); 783 params, srcRectPtr, maxTileSize, &outTileSize ,
784 &outClippedSrcRect);
795 } 785 }
796 786
797 void SkGpuDevice::drawBitmap(const SkDraw& origDraw, 787 void SkGpuDevice::drawBitmap(const SkDraw& origDraw,
798 const SkBitmap& bitmap, 788 const SkBitmap& bitmap,
799 const SkMatrix& m, 789 const SkMatrix& m,
800 const SkPaint& paint) { 790 const SkPaint& paint) {
801 ASSERT_SINGLE_OWNER 791 ASSERT_SINGLE_OWNER
802 CHECK_SHOULD_DRAW(origDraw); 792 CHECK_SHOULD_DRAW(origDraw);
803 SkMatrix viewMatrix; 793 SkMatrix viewMatrix;
804 viewMatrix.setConcat(*origDraw.fMatrix, m); 794 viewMatrix.setConcat(*origDraw.fMatrix, m);
(...skipping 25 matching lines...) Expand all
830 if (doBicubic) { 820 if (doBicubic) {
831 tileFilterPad = GrBicubicEffect::kFilterTexelPad; 821 tileFilterPad = GrBicubicEffect::kFilterTexelPad;
832 } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) { 822 } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) {
833 tileFilterPad = 0; 823 tileFilterPad = 0;
834 } else { 824 } else {
835 tileFilterPad = 1; 825 tileFilterPad = 1;
836 } 826 }
837 params.setFilterMode(textureFilterMode); 827 params.setFilterMode(textureFilterMode);
838 828
839 int maxTileSizeForFilter = fContext->caps()->maxTileSize() - 2 * tileFil terPad; 829 int maxTileSizeForFilter = fContext->caps()->maxTileSize() - 2 * tileFil terPad;
840 if (this->shouldTileBitmap(bitmap, viewMatrix, params, &srcRect, 830 if (this->shouldTileImageID(bitmap.getGenerationID(), bitmap.getSubset() , viewMatrix,
841 maxTileSizeForFilter, &tileSize, &clippedSrcR ect)) { 831 SkMatrix::I(), params, &srcRect, maxTileSize ForFilter,
842 this->drawTiledBitmap(bitmap, viewMatrix, srcRect, clippedSrcRect, p arams, paint, 832 &tileSize, &clippedSrcRect)) {
843 SkCanvas::kStrict_SrcRectConstraint, tileSize, doBicubic); 833 this->drawTiledBitmap(bitmap, viewMatrix, SkMatrix::I(), srcRect, cl ippedSrcRect,
834 params, paint, SkCanvas::kStrict_SrcRectConstr aint, tileSize,
835 doBicubic);
844 return; 836 return;
845 } 837 }
846 } 838 }
847 GrBitmapTextureMaker maker(fContext, bitmap); 839 GrBitmapTextureMaker maker(fContext, bitmap);
848 this->drawTextureProducer(&maker, nullptr, nullptr, SkCanvas::kStrict_SrcRec tConstraint, 840 this->drawTextureProducer(&maker, nullptr, nullptr, SkCanvas::kStrict_SrcRec tConstraint,
849 viewMatrix, fClip, paint); 841 viewMatrix, fClip, paint);
850 } 842 }
851 843
852 // This method outsets 'iRect' by 'outset' all around and then clamps its extent s to 844 // This method outsets 'iRect' by 'outset' all around and then clamps its extent s to
853 // 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner 845 // 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner
(...skipping 25 matching lines...) Expand all
879 } 871 }
880 if (iRect->fBottom > clamp.fBottom) { 872 if (iRect->fBottom > clamp.fBottom) {
881 iRect->fBottom = clamp.fBottom; 873 iRect->fBottom = clamp.fBottom;
882 } 874 }
883 } 875 }
884 876
885 // Break 'bitmap' into several tiles to draw it since it has already 877 // Break 'bitmap' into several tiles to draw it since it has already
886 // been determined to be too large to fit in VRAM 878 // been determined to be too large to fit in VRAM
887 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, 879 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
888 const SkMatrix& viewMatrix, 880 const SkMatrix& viewMatrix,
881 const SkMatrix& dstMatrix,
889 const SkRect& srcRect, 882 const SkRect& srcRect,
890 const SkIRect& clippedSrcIRect, 883 const SkIRect& clippedSrcIRect,
891 const GrTextureParams& params, 884 const GrTextureParams& params,
892 const SkPaint& origPaint, 885 const SkPaint& origPaint,
893 SkCanvas::SrcRectConstraint constraint, 886 SkCanvas::SrcRectConstraint constraint,
894 int tileSize, 887 int tileSize,
895 bool bicubic) { 888 bool bicubic) {
896 ASSERT_SINGLE_OWNER 889 ASSERT_SINGLE_OWNER
897 890
898 // This is the funnel for all paths that draw tiled bitmaps/images. Log hist ogram entries. 891 // This is the funnel for all paths that draw tiled bitmaps/images. Log hist ogram entries.
(...skipping 27 matching lines...) Expand all
926 SkIntToScalar((y + 1) * tileSize)); 919 SkIntToScalar((y + 1) * tileSize));
927 920
928 if (!SkRect::Intersects(tileR, clippedSrcRect)) { 921 if (!SkRect::Intersects(tileR, clippedSrcRect)) {
929 continue; 922 continue;
930 } 923 }
931 924
932 if (!tileR.intersect(srcRect)) { 925 if (!tileR.intersect(srcRect)) {
933 continue; 926 continue;
934 } 927 }
935 928
936 SkBitmap tmpB;
937 SkIRect iTileR; 929 SkIRect iTileR;
938 tileR.roundOut(&iTileR); 930 tileR.roundOut(&iTileR);
939 SkPoint offset = SkPoint::Make(SkIntToScalar(iTileR.fLeft), 931 SkVector offset = SkPoint::Make(SkIntToScalar(iTileR.fLeft),
940 SkIntToScalar(iTileR.fTop)); 932 SkIntToScalar(iTileR.fTop));
941 933 SkRect rectToDraw = SkRect::MakeXYWH(offset.fX, offset.fY,
942 // Adjust the context matrix to draw at the right x,y in device spac e 934 tileR.width(), tileR.height());
943 SkMatrix viewM = viewMatrix; 935 dstMatrix.mapRect(&rectToDraw);
944 SkMatrix tmpM;
945 tmpM.setTranslate(offset.fX - srcRect.fLeft, offset.fY - srcRect.fTo p);
946 viewM.preConcat(tmpM);
947
948 if (GrTextureParams::kNone_FilterMode != params.filterMode() || bicu bic) { 936 if (GrTextureParams::kNone_FilterMode != params.filterMode() || bicu bic) {
949 SkIRect iClampRect; 937 SkIRect iClampRect;
950 938
951 if (SkCanvas::kFast_SrcRectConstraint == constraint) { 939 if (SkCanvas::kFast_SrcRectConstraint == constraint) {
952 // In bleed mode we want to always expand the tile on all ed ges 940 // In bleed mode we want to always expand the tile on all ed ges
953 // but stay within the bitmap bounds 941 // but stay within the bitmap bounds
954 iClampRect = SkIRect::MakeWH(bitmap.width(), bitmap.height() ); 942 iClampRect = SkIRect::MakeWH(bitmap.width(), bitmap.height() );
955 } else { 943 } else {
956 // In texture-domain/clamp mode we only want to expand the 944 // In texture-domain/clamp mode we only want to expand the
957 // tile on edges interior to "srcRect" (i.e., we want to 945 // tile on edges interior to "srcRect" (i.e., we want to
958 // not bleed across the original clamped edges) 946 // not bleed across the original clamped edges)
959 srcRect.roundOut(&iClampRect); 947 srcRect.roundOut(&iClampRect);
960 } 948 }
961 int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1; 949 int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1;
962 clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect) ; 950 clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect) ;
963 } 951 }
964 952
953 SkBitmap tmpB;
965 if (bitmap.extractSubset(&tmpB, iTileR)) { 954 if (bitmap.extractSubset(&tmpB, iTileR)) {
966 // now offset it to make it "local" to our tmp bitmap 955 // now offset it to make it "local" to our tmp bitmap
967 tileR.offset(-offset.fX, -offset.fY); 956 tileR.offset(-offset.fX, -offset.fY);
968 GrTextureParams paramsTemp = params; 957 GrTextureParams paramsTemp = params;
969 // de-optimized this determination 958 // de-optimized this determination
970 bool needsTextureDomain = true; 959 bool needsTextureDomain = true;
971 this->internalDrawBitmap(tmpB, 960 this->drawBitmapTile(tmpB,
972 viewM, 961 viewMatrix,
973 tileR, 962 rectToDraw,
974 paramsTemp, 963 tileR,
975 *paint, 964 paramsTemp,
976 constraint, 965 *paint,
977 bicubic, 966 constraint,
978 needsTextureDomain); 967 bicubic,
968 needsTextureDomain);
979 } 969 }
980 } 970 }
981 } 971 }
982 } 972 }
983 973
984 /* 974 void SkGpuDevice::drawBitmapTile(const SkBitmap& bitmap,
985 * This is called by drawBitmap(), which has to handle images that may be too 975 const SkMatrix& viewMatrix,
986 * large to be represented by a single texture. 976 const SkRect& dstRect,
987 * 977 const SkRect& srcRect,
988 * internalDrawBitmap assumes that the specified bitmap will fit in a texture 978 const GrTextureParams& params,
989 * and that non-texture portion of the GrPaint has already been setup. 979 const SkPaint& paint,
990 */ 980 SkCanvas::SrcRectConstraint constraint,
991 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, 981 bool bicubic,
992 const SkMatrix& viewMatrix, 982 bool needsTextureDomain) {
993 const SkRect& srcRect,
994 const GrTextureParams& params,
995 const SkPaint& paint,
996 SkCanvas::SrcRectConstraint constraint,
997 bool bicubic,
998 bool needsTextureDomain) {
999 // We should have already handled bitmaps larger than the max texture size. 983 // We should have already handled bitmaps larger than the max texture size.
1000 SkASSERT(bitmap.width() <= fContext->caps()->maxTextureSize() && 984 SkASSERT(bitmap.width() <= fContext->caps()->maxTextureSize() &&
1001 bitmap.height() <= fContext->caps()->maxTextureSize()); 985 bitmap.height() <= fContext->caps()->maxTextureSize());
1002 // We should be respecting the max tile size by the time we get here. 986 // We should be respecting the max tile size by the time we get here.
1003 SkASSERT(bitmap.width() <= fContext->caps()->maxTileSize() && 987 SkASSERT(bitmap.width() <= fContext->caps()->maxTileSize() &&
1004 bitmap.height() <= fContext->caps()->maxTileSize()); 988 bitmap.height() <= fContext->caps()->maxTileSize());
1005 989
1006 sk_sp<GrTexture> texture = GrMakeCachedBitmapTexture(fContext, bitmap, param s, 990 sk_sp<GrTexture> texture = GrMakeCachedBitmapTexture(fContext, bitmap, param s,
1007 fDrawContext->sourceGam maTreatment()); 991 fDrawContext->sourceGam maTreatment());
1008 if (nullptr == texture) { 992 if (nullptr == texture) {
1009 return; 993 return;
1010 } 994 }
1011 995
1012 sk_sp<GrColorSpaceXform> colorSpaceXform = 996 sk_sp<GrColorSpaceXform> colorSpaceXform =
1013 GrColorSpaceXform::Make(bitmap.colorSpace(), fDrawContext->getColorSpace ()); 997 GrColorSpaceXform::Make(bitmap.colorSpace(), fDrawContext->getColorSpace ());
1014 SkRect dstRect = {0, 0, srcRect.width(), srcRect.height() }; 998
1015 SkRect paintRect; 999 SkScalar iw = 1.f / texture->width();
1016 SkScalar wInv = SkScalarInvert(SkIntToScalar(texture->width())); 1000 SkScalar ih = 1.f / texture->height();
1017 SkScalar hInv = SkScalarInvert(SkIntToScalar(texture->height()));
1018 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv),
1019 SkScalarMul(srcRect.fTop, hInv),
1020 SkScalarMul(srcRect.fRight, wInv),
1021 SkScalarMul(srcRect.fBottom, hInv));
1022 1001
1023 SkMatrix texMatrix; 1002 SkMatrix texMatrix;
1024 texMatrix.reset(); 1003 // Compute a matrix that maps the rect we will draw to the src rect.
1025 if (kAlpha_8_SkColorType == bitmap.colorType() && paint.getShader()) { 1004 texMatrix.setRectToRect(dstRect, srcRect, SkMatrix::kStart_ScaleToFit);
1026 // In cases where we are doing an A8 bitmap draw with a shader installed , we cannot use 1005 texMatrix.postScale(iw, ih);
1027 // local coords with the bitmap draw since it may mess up texture look u ps for the shader.
1028 // Thus we need to pass in the transform matrix directly to the texture processor used for
1029 // the bitmap draw.
1030 texMatrix.setScale(wInv, hInv);
1031 }
1032
1033 SkRect textureDomain = SkRect::MakeEmpty();
1034 1006
1035 // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring 1007 // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
1036 // the rest from the SkPaint. 1008 // the rest from the SkPaint.
1037 sk_sp<GrFragmentProcessor> fp; 1009 sk_sp<GrFragmentProcessor> fp;
1038 1010
1039 if (needsTextureDomain && (SkCanvas::kStrict_SrcRectConstraint == constraint )) { 1011 if (needsTextureDomain && (SkCanvas::kStrict_SrcRectConstraint == constraint )) {
1040 // Use a constrained texture domain to avoid color bleeding 1012 // Use a constrained texture domain to avoid color bleeding
1041 SkScalar left, top, right, bottom; 1013 SkRect domain;
1042 if (srcRect.width() > SK_Scalar1) { 1014 if (srcRect.width() > SK_Scalar1) {
1043 SkScalar border = SK_ScalarHalf / texture->width(); 1015 domain.fLeft = (srcRect.fLeft + 0.5f) * iw;
1044 left = paintRect.left() + border; 1016 domain.fRight = (srcRect.fRight - 0.5f) * iw;
1045 right = paintRect.right() - border;
1046 } else { 1017 } else {
1047 left = right = SkScalarHalf(paintRect.left() + paintRect.right()); 1018 domain.fLeft = domain.fRight = srcRect.centerX() * iw;
1048 } 1019 }
1049 if (srcRect.height() > SK_Scalar1) { 1020 if (srcRect.height() > SK_Scalar1) {
1050 SkScalar border = SK_ScalarHalf / texture->height(); 1021 domain.fTop = (srcRect.fTop + 0.5f) * ih;
1051 top = paintRect.top() + border; 1022 domain.fBottom = (srcRect.fBottom - 0.5f) * ih;
1052 bottom = paintRect.bottom() - border;
1053 } else { 1023 } else {
1054 top = bottom = SkScalarHalf(paintRect.top() + paintRect.bottom()); 1024 domain.fTop = domain.fBottom = srcRect.centerY() * ih;
1055 } 1025 }
1056 textureDomain.setLTRB(left, top, right, bottom);
1057 if (bicubic) { 1026 if (bicubic) {
1058 fp = GrBicubicEffect::Make(texture.get(), std::move(colorSpaceXform) , texMatrix, 1027 fp = GrBicubicEffect::Make(texture.get(), std::move(colorSpaceXform) , texMatrix,
1059 textureDomain); 1028 domain);
1060 } else { 1029 } else {
1061 fp = GrTextureDomainEffect::Make(texture.get(), std::move(colorSpace Xform), texMatrix, 1030 fp = GrTextureDomainEffect::Make(texture.get(), std::move(colorSpace Xform), texMatrix,
1062 textureDomain, GrTextureDomain::kCl amp_Mode, 1031 domain, GrTextureDomain::kClamp_Mod e,
1063 params.filterMode()); 1032 params.filterMode());
1064 } 1033 }
1065 } else if (bicubic) { 1034 } else if (bicubic) {
1066 SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode()); 1035 SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode());
1067 SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTil eModeY() }; 1036 SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTil eModeY() };
1068 fp = GrBicubicEffect::Make(texture.get(), std::move(colorSpaceXform), te xMatrix, tileModes); 1037 fp = GrBicubicEffect::Make(texture.get(), std::move(colorSpaceXform), te xMatrix, tileModes);
1069 } else { 1038 } else {
1070 fp = GrSimpleTextureEffect::Make(texture.get(), std::move(colorSpaceXfor m), texMatrix, params); 1039 fp = GrSimpleTextureEffect::Make(texture.get(), std::move(colorSpaceXfor m), texMatrix, params);
1071 } 1040 }
1072 1041
1073 GrPaint grPaint; 1042 GrPaint grPaint;
1074 if (!SkPaintToGrPaintWithTexture(this->context(), fDrawContext.get(), paint, viewMatrix, 1043 if (!SkPaintToGrPaintWithTexture(this->context(), fDrawContext.get(), paint, viewMatrix,
1075 std::move(fp), kAlpha_8_SkColorType == bitm ap.colorType(), 1044 std::move(fp), kAlpha_8_SkColorType == bitm ap.colorType(),
1076 &grPaint)) { 1045 &grPaint)) {
1077 return; 1046 return;
1078 } 1047 }
1079 1048
1080 if (kAlpha_8_SkColorType == bitmap.colorType() && paint.getShader()) { 1049 fDrawContext->drawRect(fClip, grPaint, viewMatrix, dstRect);
1081 // We don't have local coords in this case and have previously set the t ransform
1082 // matrices directly on the texture processor.
1083 fDrawContext->drawRect(fClip, grPaint, viewMatrix, dstRect);
1084 } else {
1085 fDrawContext->fillRectToRect(fClip, grPaint, viewMatrix, dstRect, paintR ect);
1086 }
1087 } 1050 }
1088 1051
1089 void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, 1052 void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
1090 int left, int top, const SkPaint& paint) { 1053 int left, int top, const SkPaint& paint) {
1091 ASSERT_SINGLE_OWNER 1054 ASSERT_SINGLE_OWNER
1092 CHECK_SHOULD_DRAW(draw); 1055 CHECK_SHOULD_DRAW(draw);
1093 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawSprite", fContext); 1056 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawSprite", fContext);
1094 1057
1095 if (fContext->abandoned()) { 1058 if (fContext->abandoned()) {
1096 return; 1059 return;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 if (doBicubic) { 1204 if (doBicubic) {
1242 tileFilterPad = GrBicubicEffect::kFilterTexelPad; 1205 tileFilterPad = GrBicubicEffect::kFilterTexelPad;
1243 } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) { 1206 } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) {
1244 tileFilterPad = 0; 1207 tileFilterPad = 0;
1245 } else { 1208 } else {
1246 tileFilterPad = 1; 1209 tileFilterPad = 1;
1247 } 1210 }
1248 params.setFilterMode(textureFilterMode); 1211 params.setFilterMode(textureFilterMode);
1249 1212
1250 int maxTileSizeForFilter = fContext->caps()->maxTileSize() - 2 * tileFil terPad; 1213 int maxTileSizeForFilter = fContext->caps()->maxTileSize() - 2 * tileFil terPad;
1251 // Fold the dst rect into the view matrix. This is only OK because we do n't get here if 1214 if (this->shouldTileImageID(bitmap.getGenerationID(), bitmap.getSubset() , *draw.fMatrix,
1252 // we have a mask filter. 1215 srcToDstMatrix, params, src, maxTileSizeForF ilter, &tileSize,
1253 SkMatrix viewMatrix = *draw.fMatrix; 1216 &clippedSrcRect)) {
1254 viewMatrix.preTranslate(dst->fLeft, dst->fTop); 1217 this->drawTiledBitmap(bitmap, *draw.fMatrix, srcToDstMatrix, *src, c lippedSrcRect,
1255 viewMatrix.preScale(dst->width()/src->width(), dst->height()/src->height ()); 1218 params, paint, constraint, tileSize, doBicubic );
1256 if (this->shouldTileBitmap(bitmap, viewMatrix, params, src,
1257 maxTileSizeForFilter, &tileSize, &clippedSrcR ect)) {
1258 this->drawTiledBitmap(bitmap, viewMatrix, *src, clippedSrcRect, para ms, paint,
1259 constraint, tileSize, doBicubic);
1260 return; 1219 return;
1261 } 1220 }
1262 } 1221 }
1263 GrBitmapTextureMaker maker(fContext, bitmap); 1222 GrBitmapTextureMaker maker(fContext, bitmap);
1264 this->drawTextureProducer(&maker, src, dst, constraint, *draw.fMatrix, fClip , paint); 1223 this->drawTextureProducer(&maker, src, dst, constraint, *draw.fMatrix, fClip , paint);
1265 } 1224 }
1266 1225
1267 sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkBitmap& bitmap) { 1226 sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkBitmap& bitmap) {
1268 SkAutoLockPixels alp(bitmap, true); 1227 SkAutoLockPixels alp(bitmap, true);
1269 if (!bitmap.readyToDraw()) { 1228 if (!bitmap.readyToDraw()) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1358 viewMatrix.preTranslate(x, y); 1317 viewMatrix.preTranslate(x, y);
1359 if (as_IB(image)->peekTexture()) { 1318 if (as_IB(image)->peekTexture()) {
1360 CHECK_SHOULD_DRAW(draw); 1319 CHECK_SHOULD_DRAW(draw);
1361 GrImageTextureAdjuster adjuster(as_IB(image)); 1320 GrImageTextureAdjuster adjuster(as_IB(image));
1362 this->drawTextureProducer(&adjuster, nullptr, nullptr, SkCanvas::kFast_S rcRectConstraint, 1321 this->drawTextureProducer(&adjuster, nullptr, nullptr, SkCanvas::kFast_S rcRectConstraint,
1363 viewMatrix, fClip, paint); 1322 viewMatrix, fClip, paint);
1364 return; 1323 return;
1365 } else { 1324 } else {
1366 SkBitmap bm; 1325 SkBitmap bm;
1367 if (this->shouldTileImage(image, nullptr, SkCanvas::kFast_SrcRectConstra int, 1326 if (this->shouldTileImage(image, nullptr, SkCanvas::kFast_SrcRectConstra int,
1368 paint.getFilterQuality(), *draw.fMatrix)) { 1327 paint.getFilterQuality(), *draw.fMatrix, SkMat rix::I())) {
1369 // only support tiling as bitmap at the moment, so force raster-vers ion 1328 // only support tiling as bitmap at the moment, so force raster-vers ion
1370 if (!as_IB(image)->getROPixels(&bm)) { 1329 if (!as_IB(image)->getROPixels(&bm)) {
1371 return; 1330 return;
1372 } 1331 }
1373 this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint); 1332 this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
1374 } else if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) { 1333 } else if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) {
1375 CHECK_SHOULD_DRAW(draw); 1334 CHECK_SHOULD_DRAW(draw);
1376 GrImageTextureMaker maker(fContext, cacher, image, SkImage::kAllow_C achingHint); 1335 GrImageTextureMaker maker(fContext, cacher, image, SkImage::kAllow_C achingHint);
1377 this->drawTextureProducer(&maker, nullptr, nullptr, SkCanvas::kFast_ SrcRectConstraint, 1336 this->drawTextureProducer(&maker, nullptr, nullptr, SkCanvas::kFast_ SrcRectConstraint,
1378 viewMatrix, fClip, paint); 1337 viewMatrix, fClip, paint);
1379 } else if (as_IB(image)->getROPixels(&bm)) { 1338 } else if (as_IB(image)->getROPixels(&bm)) {
1380 this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint); 1339 this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
1381 } 1340 }
1382 } 1341 }
1383 } 1342 }
1384 1343
1385 void SkGpuDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src, 1344 void SkGpuDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src,
1386 const SkRect& dst, const SkPaint& paint, 1345 const SkRect& dst, const SkPaint& paint,
1387 SkCanvas::SrcRectConstraint constraint) { 1346 SkCanvas::SrcRectConstraint constraint) {
1388 ASSERT_SINGLE_OWNER 1347 ASSERT_SINGLE_OWNER
1389 if (as_IB(image)->peekTexture()) { 1348 if (as_IB(image)->peekTexture()) {
1390 CHECK_SHOULD_DRAW(draw); 1349 CHECK_SHOULD_DRAW(draw);
1391 GrImageTextureAdjuster adjuster(as_IB(image)); 1350 GrImageTextureAdjuster adjuster(as_IB(image));
1392 this->drawTextureProducer(&adjuster, src, &dst, constraint, *draw.fMatri x, fClip, paint); 1351 this->drawTextureProducer(&adjuster, src, &dst, constraint, *draw.fMatri x, fClip, paint);
1393 return; 1352 return;
1394 } 1353 }
1395 SkBitmap bm; 1354 SkBitmap bm;
1396 SkMatrix totalMatrix = *draw.fMatrix; 1355 SkMatrix srcToDstRect;
1397 totalMatrix.preScale(dst.width() / (src ? src->width() : image->width()), 1356 srcToDstRect.setRectToRect((src ? *src : SkRect::MakeIWH(image->width(), ima ge->height())),
1398 dst.height() / (src ? src->height() : image->height())) ; 1357 dst, SkMatrix::kFill_ScaleToFit);
1399 if (this->shouldTileImage(image, src, constraint, paint.getFilterQuality(), totalMatrix)) { 1358 if (this->shouldTileImage(image, src, constraint, paint.getFilterQuality(), *draw.fMatrix,
1359 srcToDstRect)) {
1400 // only support tiling as bitmap at the moment, so force raster-version 1360 // only support tiling as bitmap at the moment, so force raster-version
1401 if (!as_IB(image)->getROPixels(&bm)) { 1361 if (!as_IB(image)->getROPixels(&bm)) {
1402 return; 1362 return;
1403 } 1363 }
1404 this->drawBitmapRect(draw, bm, src, dst, paint, constraint); 1364 this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
1405 } else if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) { 1365 } else if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) {
1406 CHECK_SHOULD_DRAW(draw); 1366 CHECK_SHOULD_DRAW(draw);
1407 GrImageTextureMaker maker(fContext, cacher, image, SkImage::kAllow_Cachi ngHint); 1367 GrImageTextureMaker maker(fContext, cacher, image, SkImage::kAllow_Cachi ngHint);
1408 this->drawTextureProducer(&maker, src, &dst, constraint, *draw.fMatrix, fClip, paint); 1368 this->drawTextureProducer(&maker, src, &dst, constraint, *draw.fMatrix, fClip, paint);
1409 } else if (as_IB(image)->getROPixels(&bm)) { 1369 } else if (as_IB(image)->getROPixels(&bm)) {
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1754 } 1714 }
1755 1715
1756 SkImageFilterCache* SkGpuDevice::getImageFilterCache() { 1716 SkImageFilterCache* SkGpuDevice::getImageFilterCache() {
1757 ASSERT_SINGLE_OWNER 1717 ASSERT_SINGLE_OWNER
1758 // We always return a transient cache, so it is freed after each 1718 // We always return a transient cache, so it is freed after each
1759 // filter traversal. 1719 // filter traversal.
1760 return SkImageFilterCache::Create(kDefaultImageFilterCacheSize); 1720 return SkImageFilterCache::Create(kDefaultImageFilterCacheSize);
1761 } 1721 }
1762 1722
1763 #endif 1723 #endif
OLDNEW
« no previous file with comments | « src/gpu/SkGpuDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698