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 21 matching lines...) Expand all Loading... |
32 #include "SkPictureData.h" | 32 #include "SkPictureData.h" |
33 #include "SkRRect.h" | 33 #include "SkRRect.h" |
34 #include "SkRecord.h" | 34 #include "SkRecord.h" |
35 #include "SkStroke.h" | 35 #include "SkStroke.h" |
36 #include "SkSurface.h" | 36 #include "SkSurface.h" |
37 #include "SkSurface_Gpu.h" | 37 #include "SkSurface_Gpu.h" |
38 #include "SkTLazy.h" | 38 #include "SkTLazy.h" |
39 #include "SkUtils.h" | 39 #include "SkUtils.h" |
40 #include "SkVertState.h" | 40 #include "SkVertState.h" |
41 #include "SkXfermode.h" | 41 #include "SkXfermode.h" |
| 42 #include "batches/GrRectBatchFactory.h" |
42 #include "effects/GrBicubicEffect.h" | 43 #include "effects/GrBicubicEffect.h" |
43 #include "effects/GrDashingEffect.h" | 44 #include "effects/GrDashingEffect.h" |
44 #include "effects/GrSimpleTextureEffect.h" | 45 #include "effects/GrSimpleTextureEffect.h" |
45 #include "effects/GrTextureDomain.h" | 46 #include "effects/GrTextureDomain.h" |
46 | 47 |
47 #if SK_SUPPORT_GPU | 48 #if SK_SUPPORT_GPU |
48 | 49 |
49 enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 }; | 50 enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 }; |
50 | 51 |
51 #if 0 | 52 #if 0 |
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
911 needsTextureDomain = false; | 912 needsTextureDomain = false; |
912 } else { | 913 } else { |
913 needsTextureDomain = may_color_bleed(srcRect, transformedRect, | 914 needsTextureDomain = may_color_bleed(srcRect, transformedRect, |
914 contextMatrix, isMSAA); | 915 contextMatrix, isMSAA); |
915 } | 916 } |
916 } | 917 } |
917 } | 918 } |
918 return needsTextureDomain; | 919 return needsTextureDomain; |
919 } | 920 } |
920 | 921 |
| 922 static void draw_aa_bitmap(GrDrawContext* drawContext, GrContext* context, |
| 923 GrRenderTarget* renderTarget, const GrClip& clip, |
| 924 const SkMatrix& viewMatrix, const SkMatrix& srcRectTo
DstRect, |
| 925 const SkPaint& paint, const SkBitmap* bitmapPtr, cons
t SkSize& dstSize) { |
| 926 SkShader::TileMode tm[] = { |
| 927 SkShader::kClamp_TileMode, |
| 928 SkShader::kClamp_TileMode, |
| 929 }; |
| 930 |
| 931 bool doBicubic; |
| 932 GrTextureParams::FilterMode textureFilterMode = |
| 933 GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), viewMatrix
, |
| 934 srcRectToDstRect, |
| 935 &doBicubic); |
| 936 |
| 937 // Setup texture to wrap bitmap |
| 938 GrTextureParams params(tm, textureFilterMode); |
| 939 SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(context, *bitmapPtr
, ¶ms)); |
| 940 |
| 941 if (!texture) { |
| 942 SkErrorInternals::SetError(kInternalError_SkError, |
| 943 "Couldn't convert bitmap to texture."); |
| 944 return; |
| 945 } |
| 946 |
| 947 // Setup paint |
| 948 GrColor paintColor = (kAlpha_8_SkColorType == bitmapPtr->colorType()) ? |
| 949 SkColor2GrColor(paint.getColor()) : |
| 950 SkColor2GrColorJustAlpha(paint.getColor()); |
| 951 |
| 952 GrPaint grPaint; |
| 953 |
| 954 // Create and insert texture effect |
| 955 SkAutoTUnref<const GrFragmentProcessor> fp; |
| 956 if (doBicubic) { |
| 957 fp.reset(GrBicubicEffect::Create(grPaint.getProcessorDataManager(), text
ure, |
| 958 SkMatrix::I(), |
| 959 tm)); |
| 960 } else { |
| 961 fp.reset(GrSimpleTextureEffect::Create(grPaint.getProcessorDataManager()
, texture, |
| 962 SkMatrix::I(), params)); |
| 963 } |
| 964 |
| 965 // The bitmap read has to be first |
| 966 grPaint.addColorProcessor(fp); |
| 967 if (!SkPaint2GrPaintNoShader(context, renderTarget, paint, SkColor2GrColor(p
aint.getColor()), |
| 968 false, &grPaint)) { |
| 969 return; |
| 970 } |
| 971 |
| 972 grPaint.setColor(paintColor); |
| 973 |
| 974 // Setup dst rect and final matrix |
| 975 SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight}; |
| 976 |
| 977 SkRect devRect; |
| 978 viewMatrix.mapRect(&devRect, dstRect); |
| 979 |
| 980 SkMatrix matrix; |
| 981 matrix.setIDiv(bitmapPtr->width(), bitmapPtr->height()); |
| 982 |
| 983 SkMatrix dstRectToSrcRect; |
| 984 if (!srcRectToDstRect.invert(&dstRectToSrcRect)) { |
| 985 return; |
| 986 } |
| 987 matrix.preConcat(dstRectToSrcRect); |
| 988 |
| 989 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateFillAA(grPaint.get
Color(), |
| 990 viewMatrix, |
| 991 matrix, |
| 992 dstRect, |
| 993 devRect)); |
| 994 |
| 995 drawContext->drawBatch(renderTarget, clip, grPaint, batch); |
| 996 } |
| 997 |
921 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, | 998 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, |
922 const SkBitmap& bitmap, | 999 const SkBitmap& bitmap, |
923 const SkRect* srcRectPtr, | 1000 const SkRect* srcRectPtr, |
924 const SkSize* dstSizePtr, | 1001 const SkSize* dstSizePtr, |
925 const SkPaint& paint, | 1002 const SkPaint& paint, |
926 SkCanvas::SrcRectConstraint constraint) { | 1003 SkCanvas::SrcRectConstraint constraint) { |
927 CHECK_SHOULD_DRAW(draw); | 1004 CHECK_SHOULD_DRAW(draw); |
928 | 1005 |
929 SkRect srcRect; | 1006 SkRect srcRect; |
930 SkSize dstSize; | 1007 SkSize dstSize; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 if (isDstPixelAligned) | 1057 if (isDstPixelAligned) |
981 directDraw = true; | 1058 directDraw = true; |
982 } | 1059 } |
983 } | 1060 } |
984 | 1061 |
985 if (paint.getMaskFilter() || !directDraw) { | 1062 if (paint.getMaskFilter() || !directDraw) { |
986 // Convert the bitmap to a shader so that the rect can be drawn | 1063 // Convert the bitmap to a shader so that the rect can be drawn |
987 // through drawRect, which supports mask filters. | 1064 // through drawRect, which supports mask filters. |
988 SkBitmap tmp; // subset of bitmap, if necessary | 1065 SkBitmap tmp; // subset of bitmap, if necessary |
989 const SkBitmap* bitmapPtr = &bitmap; | 1066 const SkBitmap* bitmapPtr = &bitmap; |
990 SkMatrix localM; | 1067 SkMatrix srcRectToDstRect; |
991 if (srcRectPtr) { | 1068 if (srcRectPtr) { |
992 localM.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop); | 1069 srcRectToDstRect.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop)
; |
993 localM.postScale(dstSize.fWidth / srcRectPtr->width(), | 1070 srcRectToDstRect.postScale(dstSize.fWidth / srcRectPtr->width(), |
994 dstSize.fHeight / srcRectPtr->height()); | 1071 dstSize.fHeight / srcRectPtr->height()); |
995 // In bleed mode we position and trim the bitmap based on the src re
ct which is | 1072 // In bleed mode we position and trim the bitmap based on the src re
ct which is |
996 // already accounted for in 'm' and 'srcRect'. In clamp mode we need
to chop out | 1073 // already accounted for in 'm' and 'srcRect'. In clamp mode we need
to chop out |
997 // the desired portion of the bitmap and then update 'm' and 'srcRec
t' to | 1074 // the desired portion of the bitmap and then update 'm' and 'srcRec
t' to |
998 // compensate. | 1075 // compensate. |
999 if (SkCanvas::kStrict_SrcRectConstraint == constraint) { | 1076 if (SkCanvas::kStrict_SrcRectConstraint == constraint) { |
1000 SkIRect iSrc; | 1077 SkIRect iSrc; |
1001 srcRect.roundOut(&iSrc); | 1078 srcRect.roundOut(&iSrc); |
1002 | 1079 |
1003 SkPoint offset = SkPoint::Make(SkIntToScalar(iSrc.fLeft), | 1080 SkPoint offset = SkPoint::Make(SkIntToScalar(iSrc.fLeft), |
1004 SkIntToScalar(iSrc.fTop)); | 1081 SkIntToScalar(iSrc.fTop)); |
1005 | 1082 |
1006 if (!bitmap.extractSubset(&tmp, iSrc)) { | 1083 if (!bitmap.extractSubset(&tmp, iSrc)) { |
1007 return; // extraction failed | 1084 return; // extraction failed |
1008 } | 1085 } |
1009 bitmapPtr = &tmp; | 1086 bitmapPtr = &tmp; |
1010 srcRect.offset(-offset.fX, -offset.fY); | 1087 srcRect.offset(-offset.fX, -offset.fY); |
1011 | 1088 |
1012 // The source rect has changed so update the matrix | 1089 // The source rect has changed so update the matrix |
1013 localM.preTranslate(offset.fX, offset.fY); | 1090 srcRectToDstRect.preTranslate(offset.fX, offset.fY); |
1014 } | 1091 } |
1015 } else { | 1092 } else { |
1016 localM.reset(); | 1093 srcRectToDstRect.reset(); |
1017 } | 1094 } |
1018 | 1095 |
1019 SkPaint paintWithShader(paint); | 1096 // If we have a maskfilter then we can't batch, so we take a slow path.
However, we fast |
1020 paintWithShader.setShader(SkShader::CreateBitmapShader(*bitmapPtr, | 1097 // path the case where we are drawing an AA rect so we can batch many dr
awImageRect calls |
1021 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &localM))->unr
ef(); | 1098 if (paint.getMaskFilter()) { |
1022 SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight}; | 1099 SkPaint paintWithShader(paint); |
1023 this->drawRect(draw, dstRect, paintWithShader); | 1100 paintWithShader.setShader(SkShader::CreateBitmapShader(*bitmapPtr, |
| 1101 SkShader::kClamp_TileMode, SkShader::kClam
p_TileMode, |
| 1102 &srcRectToDstRect))->unref(); |
| 1103 SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight}; |
| 1104 this->drawRect(draw, dstRect, paintWithShader); |
| 1105 } else { |
| 1106 draw_aa_bitmap(fDrawContext, fContext, fRenderTarget, fClip, *draw.f
Matrix, |
| 1107 srcRectToDstRect, paint, bitmapPtr, dstSize); |
| 1108 } |
1024 | 1109 |
1025 return; | 1110 return; |
1026 } | 1111 } |
1027 | 1112 |
1028 // If there is no mask filter than it is OK to handle the src rect -> dst re
ct scaling using | 1113 // If there is no mask filter than it is OK to handle the src rect -> dst re
ct scaling using |
1029 // the view matrix rather than a local matrix. | 1114 // the view matrix rather than a local matrix. |
1030 SkMatrix m; | 1115 SkMatrix m; |
1031 m.setScale(dstSize.fWidth / srcRect.width(), | 1116 m.setScale(dstSize.fWidth / srcRect.width(), |
1032 dstSize.fHeight / srcRect.height()); | 1117 dstSize.fHeight / srcRect.height()); |
1033 SkMatrix viewM = *draw.fMatrix; | 1118 SkMatrix viewM = *draw.fMatrix; |
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1837 #endif | 1922 #endif |
1838 } | 1923 } |
1839 | 1924 |
1840 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { | 1925 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { |
1841 // We always return a transient cache, so it is freed after each | 1926 // We always return a transient cache, so it is freed after each |
1842 // filter traversal. | 1927 // filter traversal. |
1843 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); | 1928 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); |
1844 } | 1929 } |
1845 | 1930 |
1846 #endif | 1931 #endif |
OLD | NEW |