| OLD | NEW |
| 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 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 COLOR_BLEED_TOLERANCE && | 838 COLOR_BLEED_TOLERANCE && |
| 839 SkScalarAbs(transformedRect.height() - srcRect.height()) < | 839 SkScalarAbs(transformedRect.height() - srcRect.height()) < |
| 840 COLOR_BLEED_TOLERANCE) { | 840 COLOR_BLEED_TOLERANCE) { |
| 841 return true; | 841 return true; |
| 842 } | 842 } |
| 843 return false; | 843 return false; |
| 844 } | 844 } |
| 845 | 845 |
| 846 static bool may_color_bleed(const SkRect& srcRect, | 846 static bool may_color_bleed(const SkRect& srcRect, |
| 847 const SkRect& transformedRect, | 847 const SkRect& transformedRect, |
| 848 const SkMatrix& m) { | 848 const SkMatrix& m, |
| 849 bool isMSAA) { |
| 849 // Only gets called if has_aligned_samples returned false. | 850 // Only gets called if has_aligned_samples returned false. |
| 850 // So we can assume that sampling is axis aligned but not texel aligned. | 851 // So we can assume that sampling is axis aligned but not texel aligned. |
| 851 SkASSERT(!has_aligned_samples(srcRect, transformedRect)); | 852 SkASSERT(!has_aligned_samples(srcRect, transformedRect)); |
| 852 SkRect innerSrcRect(srcRect), innerTransformedRect, | 853 SkRect innerSrcRect(srcRect), innerTransformedRect, |
| 853 outerTransformedRect(transformedRect); | 854 outerTransformedRect(transformedRect); |
| 854 innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf); | 855 if (isMSAA) { |
| 856 innerSrcRect.inset(SK_Scalar1, SK_Scalar1); |
| 857 } else { |
| 858 innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf); |
| 859 } |
| 855 m.mapRect(&innerTransformedRect, innerSrcRect); | 860 m.mapRect(&innerTransformedRect, innerSrcRect); |
| 856 | 861 |
| 857 // The gap between outerTransformedRect and innerTransformedRect | 862 // The gap between outerTransformedRect and innerTransformedRect |
| 858 // represents the projection of the source border area, which is | 863 // represents the projection of the source border area, which is |
| 859 // problematic for color bleeding. We must check whether any | 864 // problematic for color bleeding. We must check whether any |
| 860 // destination pixels sample the border area. | 865 // destination pixels sample the border area. |
| 861 outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE); | 866 outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE); |
| 862 innerTransformedRect.outset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE); | 867 innerTransformedRect.outset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE); |
| 863 SkIRect outer, inner; | 868 SkIRect outer, inner; |
| 864 outerTransformedRect.round(&outer); | 869 outerTransformedRect.round(&outer); |
| 865 innerTransformedRect.round(&inner); | 870 innerTransformedRect.round(&inner); |
| 866 // If the inner and outer rects round to the same result, it means the | 871 // If the inner and outer rects round to the same result, it means the |
| 867 // border does not overlap any pixel centers. Yay! | 872 // border does not overlap any pixel centers. Yay! |
| 868 return inner != outer; | 873 return inner != outer; |
| 869 } | 874 } |
| 870 | 875 |
| 871 static bool needs_texture_domain(const SkBitmap& bitmap, | 876 static bool needs_texture_domain(const SkBitmap& bitmap, |
| 872 const SkRect& srcRect, | 877 const SkRect& srcRect, |
| 873 GrTextureParams ¶ms, | 878 GrTextureParams ¶ms, |
| 874 const SkMatrix& contextMatrix, | 879 const SkMatrix& contextMatrix, |
| 875 bool bicubic) { | 880 bool bicubic, |
| 881 bool isMSAA) { |
| 876 bool needsTextureDomain = false; | 882 bool needsTextureDomain = false; |
| 877 GrTexture* tex = bitmap.getTexture(); | 883 GrTexture* tex = bitmap.getTexture(); |
| 878 int width = tex ? tex->width() : bitmap.width(); | 884 int width = tex ? tex->width() : bitmap.width(); |
| 879 int height = tex ? tex->height() : bitmap.height(); | 885 int height = tex ? tex->height() : bitmap.height(); |
| 880 | 886 |
| 881 if (bicubic || params.filterMode() != GrTextureParams::kNone_FilterMode) { | 887 if (bicubic || params.filterMode() != GrTextureParams::kNone_FilterMode) { |
| 882 // Need texture domain if drawing a sub rect | 888 // Need texture domain if drawing a sub rect |
| 883 needsTextureDomain = srcRect.width() < width || | 889 needsTextureDomain = srcRect.width() < width || |
| 884 srcRect.height() < height; | 890 srcRect.height() < height; |
| 885 if (!bicubic && needsTextureDomain && contextMatrix.rectStaysRect()) { | 891 if (!bicubic && needsTextureDomain && contextMatrix.rectStaysRect()) { |
| 886 // sampling is axis-aligned | 892 // sampling is axis-aligned |
| 887 SkRect transformedRect; | 893 SkRect transformedRect; |
| 888 contextMatrix.mapRect(&transformedRect, srcRect); | 894 contextMatrix.mapRect(&transformedRect, srcRect); |
| 889 | 895 |
| 890 if (has_aligned_samples(srcRect, transformedRect)) { | 896 if (has_aligned_samples(srcRect, transformedRect)) { |
| 891 params.setFilterMode(GrTextureParams::kNone_FilterMode); | 897 params.setFilterMode(GrTextureParams::kNone_FilterMode); |
| 892 needsTextureDomain = false; | 898 needsTextureDomain = false; |
| 893 } else { | 899 } else { |
| 894 needsTextureDomain = may_color_bleed(srcRect, transformedRect, c
ontextMatrix); | 900 needsTextureDomain = may_color_bleed(srcRect, transformedRect, |
| 901 contextMatrix, isMSAA); |
| 895 } | 902 } |
| 896 } | 903 } |
| 897 } | 904 } |
| 898 return needsTextureDomain; | 905 return needsTextureDomain; |
| 899 } | 906 } |
| 900 | 907 |
| 901 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, | 908 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, |
| 902 const SkBitmap& bitmap, | 909 const SkBitmap& bitmap, |
| 903 const SkRect* srcRectPtr, | 910 const SkRect* srcRectPtr, |
| 904 const SkSize* dstSizePtr, | 911 const SkSize* dstSizePtr, |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1065 if (this->shouldTileBitmap(bitmap, viewM, params, srcRectPtr, maxTileSize, &
tileSize, | 1072 if (this->shouldTileBitmap(bitmap, viewM, params, srcRectPtr, maxTileSize, &
tileSize, |
| 1066 &clippedSrcRect)) { | 1073 &clippedSrcRect)) { |
| 1067 this->drawTiledBitmap(bitmap, viewM, srcRect, clippedSrcRect, params, pa
int, constraint, | 1074 this->drawTiledBitmap(bitmap, viewM, srcRect, clippedSrcRect, params, pa
int, constraint, |
| 1068 tileSize, doBicubic); | 1075 tileSize, doBicubic); |
| 1069 } else { | 1076 } else { |
| 1070 // take the simple case | 1077 // take the simple case |
| 1071 bool needsTextureDomain = needs_texture_domain(bitmap, | 1078 bool needsTextureDomain = needs_texture_domain(bitmap, |
| 1072 srcRect, | 1079 srcRect, |
| 1073 params, | 1080 params, |
| 1074 viewM, | 1081 viewM, |
| 1075 doBicubic); | 1082 doBicubic, |
| 1083 fRenderTarget->isUnifiedM
ultisampled()); |
| 1076 this->internalDrawBitmap(bitmap, | 1084 this->internalDrawBitmap(bitmap, |
| 1077 viewM, | 1085 viewM, |
| 1078 srcRect, | 1086 srcRect, |
| 1079 params, | 1087 params, |
| 1080 paint, | 1088 paint, |
| 1081 constraint, | 1089 constraint, |
| 1082 doBicubic, | 1090 doBicubic, |
| 1083 needsTextureDomain); | 1091 needsTextureDomain); |
| 1084 } | 1092 } |
| 1085 } | 1093 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1146 srcRect.roundOut(&iClampRect); | 1154 srcRect.roundOut(&iClampRect); |
| 1147 } | 1155 } |
| 1148 int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1; | 1156 int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1; |
| 1149 clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect)
; | 1157 clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect)
; |
| 1150 } | 1158 } |
| 1151 | 1159 |
| 1152 if (bitmap.extractSubset(&tmpB, iTileR)) { | 1160 if (bitmap.extractSubset(&tmpB, iTileR)) { |
| 1153 // now offset it to make it "local" to our tmp bitmap | 1161 // now offset it to make it "local" to our tmp bitmap |
| 1154 tileR.offset(-offset.fX, -offset.fY); | 1162 tileR.offset(-offset.fX, -offset.fY); |
| 1155 GrTextureParams paramsTemp = params; | 1163 GrTextureParams paramsTemp = params; |
| 1156 bool needsTextureDomain = needs_texture_domain(bitmap, | 1164 bool needsTextureDomain = needs_texture_domain( |
| 1157 srcRect, | 1165 bitmap, srcRect, params
Temp, |
| 1158 paramsTemp, | 1166 viewM, bicubic, |
| 1159 viewM, | 1167 fRenderTarget->isUnifie
dMultisampled()); |
| 1160 bicubic); | |
| 1161 this->internalDrawBitmap(tmpB, | 1168 this->internalDrawBitmap(tmpB, |
| 1162 viewM, | 1169 viewM, |
| 1163 tileR, | 1170 tileR, |
| 1164 paramsTemp, | 1171 paramsTemp, |
| 1165 paint, | 1172 paint, |
| 1166 constraint, | 1173 constraint, |
| 1167 bicubic, | 1174 bicubic, |
| 1168 needsTextureDomain); | 1175 needsTextureDomain); |
| 1169 } | 1176 } |
| 1170 } | 1177 } |
| (...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1856 #endif | 1863 #endif |
| 1857 } | 1864 } |
| 1858 | 1865 |
| 1859 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { | 1866 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { |
| 1860 // We always return a transient cache, so it is freed after each | 1867 // We always return a transient cache, so it is freed after each |
| 1861 // filter traversal. | 1868 // filter traversal. |
| 1862 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); | 1869 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); |
| 1863 } | 1870 } |
| 1864 | 1871 |
| 1865 #endif | 1872 #endif |
| OLD | NEW |