| 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" | |
| 43 #include "effects/GrBicubicEffect.h" | 42 #include "effects/GrBicubicEffect.h" |
| 44 #include "effects/GrDashingEffect.h" | 43 #include "effects/GrDashingEffect.h" |
| 45 #include "effects/GrSimpleTextureEffect.h" | 44 #include "effects/GrSimpleTextureEffect.h" |
| 46 #include "effects/GrTextureDomain.h" | 45 #include "effects/GrTextureDomain.h" |
| 47 | 46 |
| 48 #if SK_SUPPORT_GPU | 47 #if SK_SUPPORT_GPU |
| 49 | 48 |
| 50 enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 }; | 49 enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 }; |
| 51 | 50 |
| 52 #if 0 | 51 #if 0 |
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 needsTextureDomain = false; | 911 needsTextureDomain = false; |
| 913 } else { | 912 } else { |
| 914 needsTextureDomain = may_color_bleed(srcRect, transformedRect, | 913 needsTextureDomain = may_color_bleed(srcRect, transformedRect, |
| 915 contextMatrix, isMSAA); | 914 contextMatrix, isMSAA); |
| 916 } | 915 } |
| 917 } | 916 } |
| 918 } | 917 } |
| 919 return needsTextureDomain; | 918 return needsTextureDomain; |
| 920 } | 919 } |
| 921 | 920 |
| 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 grPaint.addColorProcessor(fp); | |
| 966 | |
| 967 if (!SkPaint2GrPaint(context, renderTarget, paint, viewMatrix, true, | |
| 968 &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 | |
| 998 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, | 921 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, |
| 999 const SkBitmap& bitmap, | 922 const SkBitmap& bitmap, |
| 1000 const SkRect* srcRectPtr, | 923 const SkRect* srcRectPtr, |
| 1001 const SkSize* dstSizePtr, | 924 const SkSize* dstSizePtr, |
| 1002 const SkPaint& paint, | 925 const SkPaint& paint, |
| 1003 SkCanvas::SrcRectConstraint constraint) { | 926 SkCanvas::SrcRectConstraint constraint) { |
| 1004 CHECK_SHOULD_DRAW(draw); | 927 CHECK_SHOULD_DRAW(draw); |
| 1005 | 928 |
| 1006 SkRect srcRect; | 929 SkRect srcRect; |
| 1007 SkSize dstSize; | 930 SkSize dstSize; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 if (isDstPixelAligned) | 980 if (isDstPixelAligned) |
| 1058 directDraw = true; | 981 directDraw = true; |
| 1059 } | 982 } |
| 1060 } | 983 } |
| 1061 | 984 |
| 1062 if (paint.getMaskFilter() || !directDraw) { | 985 if (paint.getMaskFilter() || !directDraw) { |
| 1063 // Convert the bitmap to a shader so that the rect can be drawn | 986 // Convert the bitmap to a shader so that the rect can be drawn |
| 1064 // through drawRect, which supports mask filters. | 987 // through drawRect, which supports mask filters. |
| 1065 SkBitmap tmp; // subset of bitmap, if necessary | 988 SkBitmap tmp; // subset of bitmap, if necessary |
| 1066 const SkBitmap* bitmapPtr = &bitmap; | 989 const SkBitmap* bitmapPtr = &bitmap; |
| 1067 SkMatrix srcRectToDstRect; | 990 SkMatrix localM; |
| 1068 if (srcRectPtr) { | 991 if (srcRectPtr) { |
| 1069 srcRectToDstRect.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop)
; | 992 localM.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop); |
| 1070 srcRectToDstRect.postScale(dstSize.fWidth / srcRectPtr->width(), | 993 localM.postScale(dstSize.fWidth / srcRectPtr->width(), |
| 1071 dstSize.fHeight / srcRectPtr->height()); | 994 dstSize.fHeight / srcRectPtr->height()); |
| 1072 // In bleed mode we position and trim the bitmap based on the src re
ct which is | 995 // In bleed mode we position and trim the bitmap based on the src re
ct which is |
| 1073 // already accounted for in 'm' and 'srcRect'. In clamp mode we need
to chop out | 996 // already accounted for in 'm' and 'srcRect'. In clamp mode we need
to chop out |
| 1074 // the desired portion of the bitmap and then update 'm' and 'srcRec
t' to | 997 // the desired portion of the bitmap and then update 'm' and 'srcRec
t' to |
| 1075 // compensate. | 998 // compensate. |
| 1076 if (SkCanvas::kStrict_SrcRectConstraint == constraint) { | 999 if (SkCanvas::kStrict_SrcRectConstraint == constraint) { |
| 1077 SkIRect iSrc; | 1000 SkIRect iSrc; |
| 1078 srcRect.roundOut(&iSrc); | 1001 srcRect.roundOut(&iSrc); |
| 1079 | 1002 |
| 1080 SkPoint offset = SkPoint::Make(SkIntToScalar(iSrc.fLeft), | 1003 SkPoint offset = SkPoint::Make(SkIntToScalar(iSrc.fLeft), |
| 1081 SkIntToScalar(iSrc.fTop)); | 1004 SkIntToScalar(iSrc.fTop)); |
| 1082 | 1005 |
| 1083 if (!bitmap.extractSubset(&tmp, iSrc)) { | 1006 if (!bitmap.extractSubset(&tmp, iSrc)) { |
| 1084 return; // extraction failed | 1007 return; // extraction failed |
| 1085 } | 1008 } |
| 1086 bitmapPtr = &tmp; | 1009 bitmapPtr = &tmp; |
| 1087 srcRect.offset(-offset.fX, -offset.fY); | 1010 srcRect.offset(-offset.fX, -offset.fY); |
| 1088 | 1011 |
| 1089 // The source rect has changed so update the matrix | 1012 // The source rect has changed so update the matrix |
| 1090 srcRectToDstRect.preTranslate(offset.fX, offset.fY); | 1013 localM.preTranslate(offset.fX, offset.fY); |
| 1091 } | 1014 } |
| 1092 } else { | 1015 } else { |
| 1093 srcRectToDstRect.reset(); | 1016 localM.reset(); |
| 1094 } | 1017 } |
| 1095 | 1018 |
| 1096 // If we have a maskfilter then we can't batch, so we take a slow path.
However, we fast | 1019 SkPaint paintWithShader(paint); |
| 1097 // path the case where we are drawing an AA rect so we can batch many dr
awImageRect calls | 1020 paintWithShader.setShader(SkShader::CreateBitmapShader(*bitmapPtr, |
| 1098 if (paint.getMaskFilter()) { | 1021 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &localM))->unr
ef(); |
| 1099 SkPaint paintWithShader(paint); | 1022 SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight}; |
| 1100 paintWithShader.setShader(SkShader::CreateBitmapShader(*bitmapPtr, | 1023 this->drawRect(draw, dstRect, paintWithShader); |
| 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 } | |
| 1109 | 1024 |
| 1110 return; | 1025 return; |
| 1111 } | 1026 } |
| 1112 | 1027 |
| 1113 // If there is no mask filter than it is OK to handle the src rect -> dst re
ct scaling using | 1028 // If there is no mask filter than it is OK to handle the src rect -> dst re
ct scaling using |
| 1114 // the view matrix rather than a local matrix. | 1029 // the view matrix rather than a local matrix. |
| 1115 SkMatrix m; | 1030 SkMatrix m; |
| 1116 m.setScale(dstSize.fWidth / srcRect.width(), | 1031 m.setScale(dstSize.fWidth / srcRect.width(), |
| 1117 dstSize.fHeight / srcRect.height()); | 1032 dstSize.fHeight / srcRect.height()); |
| 1118 SkMatrix viewM = *draw.fMatrix; | 1033 SkMatrix viewM = *draw.fMatrix; |
| (...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1922 #endif | 1837 #endif |
| 1923 } | 1838 } |
| 1924 | 1839 |
| 1925 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { | 1840 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { |
| 1926 // We always return a transient cache, so it is freed after each | 1841 // We always return a transient cache, so it is freed after each |
| 1927 // filter traversal. | 1842 // filter traversal. |
| 1928 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); | 1843 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); |
| 1929 } | 1844 } |
| 1930 | 1845 |
| 1931 #endif | 1846 #endif |
| OLD | NEW |