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

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

Issue 1459433002: Convert SkGpuDevice::drawTextureAdjuster to SkGpuDevice::drawTextureProducer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: remove redudant virtual decl Created 5 years, 1 month 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') | src/gpu/SkGpuDevice_drawTexture.cpp » ('j') | 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 extern bool (*gShouldDrawProc)(); 56 extern bool (*gShouldDrawProc)();
57 #define CHECK_SHOULD_DRAW(draw) \ 57 #define CHECK_SHOULD_DRAW(draw) \
58 do { \ 58 do { \
59 if (gShouldDrawProc && !gShouldDrawProc()) return; \ 59 if (gShouldDrawProc && !gShouldDrawProc()) return; \
60 this->prepareDraw(draw); \ 60 this->prepareDraw(draw); \
61 } while (0) 61 } while (0)
62 #else 62 #else
63 #define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw) 63 #define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw)
64 #endif 64 #endif
65 65
66 // This constant represents the screen alignment criterion in texels for
67 // requiring texture domain clamping to prevent color bleeding when drawing
68 // a sub region of a larger source image.
69 #define COLOR_BLEED_TOLERANCE 0.001f
70
71 #define DO_DEFERRED_CLEAR() \ 66 #define DO_DEFERRED_CLEAR() \
72 do { \ 67 do { \
73 if (fNeedClear) { \ 68 if (fNeedClear) { \
74 this->clearAll(); \ 69 this->clearAll(); \
75 } \ 70 } \
76 } while (false) \ 71 } while (false) \
77 72
78 /////////////////////////////////////////////////////////////////////////////// 73 ///////////////////////////////////////////////////////////////////////////////
79 74
80 #define CHECK_FOR_ANNOTATION(paint) \ 75 #define CHECK_FOR_ANNOTATION(paint) \
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 SkIRect outClippedSrcRect; 830 SkIRect outClippedSrcRect;
836 831
837 return this->shouldTileImageID(image->unique(), image->bounds(), viewMatrix, params, srcRectPtr, 832 return this->shouldTileImageID(image->unique(), image->bounds(), viewMatrix, params, srcRectPtr,
838 maxTileSize, &outTileSize, &outClippedSrcRect ); 833 maxTileSize, &outTileSize, &outClippedSrcRect );
839 } 834 }
840 835
841 void SkGpuDevice::drawBitmap(const SkDraw& origDraw, 836 void SkGpuDevice::drawBitmap(const SkDraw& origDraw,
842 const SkBitmap& bitmap, 837 const SkBitmap& bitmap,
843 const SkMatrix& m, 838 const SkMatrix& m,
844 const SkPaint& paint) { 839 const SkPaint& paint) {
845 840 CHECK_SHOULD_DRAW(origDraw);
846 GrTexture* texture = bitmap.getTexture(); 841 bool alphaOnly = kAlpha_8_SkColorType == bitmap.colorType();
847 if (texture) { 842 SkMatrix viewMatrix;
848 CHECK_SHOULD_DRAW(origDraw); 843 viewMatrix.setConcat(*origDraw.fMatrix, m);
849 bool alphaOnly = kAlpha_8_SkColorType == bitmap.colorType(); 844 if (bitmap.getTexture()) {
850 GrBitmapTextureAdjuster adjuster(&bitmap); 845 GrBitmapTextureAdjuster adjuster(&bitmap);
851 SkMatrix viewMatrix; 846 // We can use kFast here because we know texture-backed bitmaps don't su pport extractSubset.
852 viewMatrix.setConcat(*origDraw.fMatrix, m); 847 this->drawTextureProducer(&adjuster, alphaOnly, nullptr, nullptr,
853 this->drawTextureAdjuster(&adjuster, alphaOnly, nullptr, nullptr,
854 SkCanvas::kFast_SrcRectConstraint, viewMatrix, fClip, paint); 848 SkCanvas::kFast_SrcRectConstraint, viewMatrix, fClip, paint);
855 return; 849 return;
856 } 850 }
857 SkMatrix concat; 851 int maxTileSize = fContext->caps()->maxTileSize();
858 SkTCopyOnFirstWrite<SkDraw> draw(origDraw); 852
859 if (!m.isIdentity()) { 853 // The tile code path doesn't currently support AA, so if the paint asked fo r aa and we could
860 concat.setConcat(*draw->fMatrix, m); 854 // draw untiled, then we bypass checking for tiling purely for optimization reasons.
861 draw.writable()->fMatrix = &concat; 855 bool drawAA = !fRenderTarget->isUnifiedMultisampled() &&
856 paint.isAntiAlias() &&
857 bitmap.width() <= maxTileSize &&
858 bitmap.height() <= maxTileSize;
859
860 bool skipTileCheck = drawAA || paint.getMaskFilter();
861
862 if (!skipTileCheck) {
863 SkRect srcRect = SkRect::MakeIWH(bitmap.width(), bitmap.height());
864 int tileSize;
865 SkIRect clippedSrcRect;
866
867 GrTextureParams params;
868 bool doBicubic;
869 GrTextureParams::FilterMode textureFilterMode =
870 GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), viewMatrix , SkMatrix::I(),
871 &doBicubic);
872
873 int tileFilterPad;
874
875 if (doBicubic) {
876 tileFilterPad = GrBicubicEffect::kFilterTexelPad;
877 } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) {
878 tileFilterPad = 0;
879 } else {
880 tileFilterPad = 1;
881 }
882 params.setFilterMode(textureFilterMode);
883
884 int maxTileSizeForFilter = fContext->caps()->maxTileSize() - 2 * tileFil terPad;
885 if (this->shouldTileBitmap(bitmap, viewMatrix, params, &srcRect,
886 maxTileSizeForFilter, &tileSize, &clippedSrcR ect)) {
887 this->drawTiledBitmap(bitmap, viewMatrix, srcRect, clippedSrcRect, p arams, paint,
888 SkCanvas::kStrict_SrcRectConstraint, tileSize, doBicubic);
889 return;
890 }
862 } 891 }
863 this->drawBitmapCommon(*draw, bitmap, nullptr, nullptr, paint, 892 GrBitmapTextureMaker maker(fContext, bitmap);
864 SkCanvas::kStrict_SrcRectConstraint); 893 this->drawTextureProducer(&maker, alphaOnly, nullptr, nullptr,
894 SkCanvas::kStrict_SrcRectConstraint, viewMatrix, f Clip, paint);
865 } 895 }
866 896
867 // This method outsets 'iRect' by 'outset' all around and then clamps its extent s to 897 // This method outsets 'iRect' by 'outset' all around and then clamps its extent s to
868 // 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner 898 // 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner
869 // of 'iRect' for all possible outsets/clamps. 899 // of 'iRect' for all possible outsets/clamps.
870 static inline void clamped_outset_with_offset(SkIRect* iRect, 900 static inline void clamped_outset_with_offset(SkIRect* iRect,
871 int outset, 901 int outset,
872 SkPoint* offset, 902 SkPoint* offset,
873 const SkIRect& clamp) { 903 const SkIRect& clamp) {
874 iRect->outset(outset, outset); 904 iRect->outset(outset, outset);
(...skipping 15 matching lines...) Expand all
890 } 920 }
891 921
892 if (iRect->fRight > clamp.fRight) { 922 if (iRect->fRight > clamp.fRight) {
893 iRect->fRight = clamp.fRight; 923 iRect->fRight = clamp.fRight;
894 } 924 }
895 if (iRect->fBottom > clamp.fBottom) { 925 if (iRect->fBottom > clamp.fBottom) {
896 iRect->fBottom = clamp.fBottom; 926 iRect->fBottom = clamp.fBottom;
897 } 927 }
898 } 928 }
899 929
900 static bool has_aligned_samples(const SkRect& srcRect,
901 const SkRect& transformedRect) {
902 // detect pixel disalignment
903 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) -
904 transformedRect.left()) < COLOR_BLEED_TOLERANCE &&
905 SkScalarAbs(SkScalarRoundToScalar(transformedRect.top()) -
906 transformedRect.top()) < COLOR_BLEED_TOLERANCE &&
907 SkScalarAbs(transformedRect.width() - srcRect.width()) <
908 COLOR_BLEED_TOLERANCE &&
909 SkScalarAbs(transformedRect.height() - srcRect.height()) <
910 COLOR_BLEED_TOLERANCE) {
911 return true;
912 }
913 return false;
914 }
915
916 static bool may_color_bleed(const SkRect& srcRect,
917 const SkRect& transformedRect,
918 const SkMatrix& m,
919 bool isMSAA) {
920 // Only gets called if has_aligned_samples returned false.
921 // So we can assume that sampling is axis aligned but not texel aligned.
922 SkASSERT(!has_aligned_samples(srcRect, transformedRect));
923 SkRect innerSrcRect(srcRect), innerTransformedRect,
924 outerTransformedRect(transformedRect);
925 if (isMSAA) {
926 innerSrcRect.inset(SK_Scalar1, SK_Scalar1);
927 } else {
928 innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf);
929 }
930 m.mapRect(&innerTransformedRect, innerSrcRect);
931
932 // The gap between outerTransformedRect and innerTransformedRect
933 // represents the projection of the source border area, which is
934 // problematic for color bleeding. We must check whether any
935 // destination pixels sample the border area.
936 outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE);
937 innerTransformedRect.outset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE);
938 SkIRect outer, inner;
939 outerTransformedRect.round(&outer);
940 innerTransformedRect.round(&inner);
941 // If the inner and outer rects round to the same result, it means the
942 // border does not overlap any pixel centers. Yay!
943 return inner != outer;
944 }
945
946 static bool needs_texture_domain(const SkBitmap& bitmap,
947 const SkRect& srcRect,
948 GrTextureParams &params,
949 const SkMatrix& contextMatrix,
950 bool bicubic,
951 bool isMSAA) {
952 bool needsTextureDomain = false;
953 GrTexture* tex = bitmap.getTexture();
954 int width = tex ? tex->width() : bitmap.width();
955 int height = tex ? tex->height() : bitmap.height();
956
957 if (bicubic || params.filterMode() != GrTextureParams::kNone_FilterMode) {
958 // Need texture domain if drawing a sub rect
959 needsTextureDomain = srcRect.width() < width ||
960 srcRect.height() < height;
961 if (!bicubic && needsTextureDomain && contextMatrix.rectStaysRect()) {
962 // sampling is axis-aligned
963 SkRect transformedRect;
964 contextMatrix.mapRect(&transformedRect, srcRect);
965
966 if (has_aligned_samples(srcRect, transformedRect)) {
967 params.setFilterMode(GrTextureParams::kNone_FilterMode);
968 needsTextureDomain = false;
969 } else {
970 needsTextureDomain = may_color_bleed(srcRect, transformedRect,
971 contextMatrix, isMSAA);
972 }
973 }
974 }
975 return needsTextureDomain;
976 }
977
978 static void draw_aa_bitmap(GrDrawContext* drawContext, GrContext* context,
979 GrRenderTarget* renderTarget, const GrClip& clip,
980 const SkMatrix& viewMatrix, const SkMatrix& srcRectTo DstRect,
981 const SkPaint& paint, const SkBitmap* bitmapPtr, cons t SkSize& dstSize) {
982 SkShader::TileMode tm[] = {
983 SkShader::kClamp_TileMode,
984 SkShader::kClamp_TileMode,
985 };
986
987 bool doBicubic;
988 GrTextureParams::FilterMode textureFilterMode =
989 GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), viewMatrix ,
990 srcRectToDstRect,
991 &doBicubic);
992
993 // Setup texture to wrap bitmap
994 GrTextureParams params(tm, textureFilterMode);
995 SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(context, *bitmapPtr , params));
996
997 if (!texture) {
998 SkErrorInternals::SetError(kInternalError_SkError,
999 "Couldn't convert bitmap to texture.");
1000 return;
1001 }
1002
1003
1004 GrPaint grPaint;
1005
1006 // Create and insert texture effect
1007 SkAutoTUnref<const GrFragmentProcessor> fp;
1008 if (doBicubic) {
1009 fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), tm));
1010 } else {
1011 fp.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params));
1012 }
1013
1014 if (kAlpha_8_SkColorType == bitmapPtr->colorType()) {
1015 fp.reset(GrFragmentProcessor::MulOutputByInputUnpremulColor(fp));
1016 } else {
1017 fp.reset(GrFragmentProcessor::MulOutputByInputAlpha(fp));
1018 }
1019
1020 if (!SkPaintToGrPaintReplaceShader(context, paint, fp, &grPaint)) {
1021 return;
1022 }
1023
1024 // Setup dst rect and final matrix
1025 SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight};
1026
1027 SkRect devRect;
1028 viewMatrix.mapRect(&devRect, dstRect);
1029
1030 SkMatrix matrix;
1031 matrix.setIDiv(bitmapPtr->width(), bitmapPtr->height());
1032
1033 SkMatrix dstRectToSrcRect;
1034 if (!srcRectToDstRect.invert(&dstRectToSrcRect)) {
1035 return;
1036 }
1037 matrix.preConcat(dstRectToSrcRect);
1038
1039 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFill(grPaint.get Color(),
1040 viewMatrix,
1041 matrix,
1042 dstRect,
1043 devRect));
1044
1045 drawContext->drawBatch(clip, grPaint, batch);
1046 }
1047
1048 static bool can_ignore_strict_subset_constraint(const SkBitmap& bitmap, const Sk Rect& subset) {
1049 GrTexture* tex = bitmap.getTexture();
1050 int width = tex ? tex->width() : bitmap.width();
1051 int height = tex ? tex->height() : bitmap.height();
1052 return subset.contains(SkRect::MakeIWH(width, height));
1053 }
1054
1055 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
1056 const SkBitmap& bitmap,
1057 const SkRect* srcRectPtr,
1058 const SkSize* dstSizePtr,
1059 const SkPaint& paint,
1060 SkCanvas::SrcRectConstraint constraint) {
1061 CHECK_SHOULD_DRAW(draw);
1062
1063 SkRect srcRect;
1064 SkSize dstSize;
1065 // If there is no src rect, or the src rect contains the entire bitmap then we're effectively
1066 // in the (easier) bleed case, so update flags.
1067 if (nullptr == srcRectPtr) {
1068 SkScalar w = SkIntToScalar(bitmap.width());
1069 SkScalar h = SkIntToScalar(bitmap.height());
1070 dstSize.fWidth = w;
1071 dstSize.fHeight = h;
1072 srcRect.set(0, 0, w, h);
1073 } else {
1074 SkASSERT(dstSizePtr);
1075 srcRect = *srcRectPtr;
1076 dstSize = *dstSizePtr;
1077 }
1078
1079 if (can_ignore_strict_subset_constraint(bitmap, srcRect)) {
1080 constraint = SkCanvas::kFast_SrcRectConstraint;
1081 }
1082
1083 // If the render target is not msaa and draw is antialiased, we call
1084 // drawRect instead of drawing on the render target directly.
1085 // FIXME: the tiled bitmap code path doesn't currently support
1086 // anti-aliased edges, we work around that for now by drawing directly
1087 // if the image size exceeds maximum texture size.
1088 int maxTileSize = fContext->caps()->maxTileSize();
1089 bool drawAA = !fRenderTarget->isUnifiedMultisampled() &&
1090 paint.isAntiAlias() &&
1091 bitmap.width() <= maxTileSize &&
1092 bitmap.height() <= maxTileSize;
1093
1094 if (paint.getMaskFilter() || drawAA) {
1095 // Convert the bitmap to a shader so that the rect can be drawn
1096 // through drawRect, which supports mask filters.
1097 SkBitmap tmp; // subset of bitmap, if necessary
1098 const SkBitmap* bitmapPtr = &bitmap;
1099 SkMatrix srcRectToDstRect;
1100 if (srcRectPtr) {
1101 srcRectToDstRect.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop) ;
1102 srcRectToDstRect.postScale(dstSize.fWidth / srcRectPtr->width(),
1103 dstSize.fHeight / srcRectPtr->height());
1104 // In bleed mode we position and trim the bitmap based on the src re ct which is
1105 // already accounted for in 'm' and 'srcRect'. In clamp mode we need to chop out
1106 // the desired portion of the bitmap and then update 'm' and 'srcRec t' to
1107 // compensate.
1108 if (SkCanvas::kStrict_SrcRectConstraint == constraint) {
1109 SkIRect iSrc;
1110 srcRect.roundOut(&iSrc);
1111
1112 SkPoint offset = SkPoint::Make(SkIntToScalar(iSrc.fLeft),
1113 SkIntToScalar(iSrc.fTop));
1114
1115 if (!bitmap.extractSubset(&tmp, iSrc)) {
1116 return; // extraction failed
1117 }
1118 bitmapPtr = &tmp;
1119 srcRect.offset(-offset.fX, -offset.fY);
1120
1121 // The source rect has changed so update the matrix
1122 srcRectToDstRect.preTranslate(offset.fX, offset.fY);
1123 }
1124 } else {
1125 srcRectToDstRect.reset();
1126 }
1127
1128 // If we have a maskfilter then we can't batch, so we take a slow path. However, we fast
1129 // path the case where we are drawing an AA rect so we can batch many dr awImageRect calls
1130 if (paint.getMaskFilter()) {
1131 SkPaint paintWithShader(paint);
1132 paintWithShader.setShader(SkShader::CreateBitmapShader(*bitmapPtr,
1133 SkShader::kClamp_TileMode, SkShader::kClam p_TileMode,
1134 &srcRectToDstRect))->unref();
1135 SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight};
1136 this->drawRect(draw, dstRect, paintWithShader);
1137 } else {
1138 draw_aa_bitmap(fDrawContext, fContext, fRenderTarget, fClip, *draw.f Matrix,
1139 srcRectToDstRect, paint, bitmapPtr, dstSize);
1140 }
1141
1142 return;
1143 }
1144
1145 // If there is no mask filter than it is OK to handle the src rect -> dst re ct scaling using
1146 // the view matrix rather than a local matrix.
1147 SkMatrix viewM = *draw.fMatrix;
1148 viewM.preScale(dstSize.fWidth / srcRect.width(),
1149 dstSize.fHeight / srcRect.height());
1150
1151 GrTextureParams params;
1152 bool doBicubic;
1153 GrTextureParams::FilterMode textureFilterMode =
1154 GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), viewM, SkM atrix::I(),
1155 &doBicubic);
1156
1157 int tileFilterPad;
1158 if (doBicubic) {
1159 tileFilterPad = GrBicubicEffect::kFilterTexelPad;
1160 } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) {
1161 tileFilterPad = 0;
1162 } else {
1163 tileFilterPad = 1;
1164 }
1165 params.setFilterMode(textureFilterMode);
1166
1167 maxTileSize = fContext->caps()->maxTileSize() - 2 * tileFilterPad;
1168 int tileSize;
1169
1170 SkIRect clippedSrcRect;
1171 if (this->shouldTileBitmap(bitmap, viewM, params, srcRectPtr, maxTileSize, & tileSize,
1172 &clippedSrcRect)) {
1173 this->drawTiledBitmap(bitmap, viewM, srcRect, clippedSrcRect, params, pa int, constraint,
1174 tileSize, doBicubic);
1175 } else {
1176 // take the simple case
1177 bool needsTextureDomain = needs_texture_domain(bitmap,
1178 srcRect,
1179 params,
1180 viewM,
1181 doBicubic,
1182 fRenderTarget->isUnifiedM ultisampled());
1183 this->internalDrawBitmap(bitmap,
1184 viewM,
1185 srcRect,
1186 params,
1187 paint,
1188 constraint,
1189 doBicubic,
1190 needsTextureDomain);
1191 }
1192 }
1193
1194 // Break 'bitmap' into several tiles to draw it since it has already 930 // Break 'bitmap' into several tiles to draw it since it has already
1195 // been determined to be too large to fit in VRAM 931 // been determined to be too large to fit in VRAM
1196 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, 932 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
1197 const SkMatrix& viewMatrix, 933 const SkMatrix& viewMatrix,
1198 const SkRect& srcRect, 934 const SkRect& srcRect,
1199 const SkIRect& clippedSrcIRect, 935 const SkIRect& clippedSrcIRect,
1200 const GrTextureParams& params, 936 const GrTextureParams& params,
1201 const SkPaint& origPaint, 937 const SkPaint& origPaint,
1202 SkCanvas::SrcRectConstraint constraint, 938 SkCanvas::SrcRectConstraint constraint,
1203 int tileSize, 939 int tileSize,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 srcRect.roundOut(&iClampRect); 998 srcRect.roundOut(&iClampRect);
1263 } 999 }
1264 int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1; 1000 int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1;
1265 clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect) ; 1001 clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect) ;
1266 } 1002 }
1267 1003
1268 if (bitmap.extractSubset(&tmpB, iTileR)) { 1004 if (bitmap.extractSubset(&tmpB, iTileR)) {
1269 // now offset it to make it "local" to our tmp bitmap 1005 // now offset it to make it "local" to our tmp bitmap
1270 tileR.offset(-offset.fX, -offset.fY); 1006 tileR.offset(-offset.fX, -offset.fY);
1271 GrTextureParams paramsTemp = params; 1007 GrTextureParams paramsTemp = params;
1272 bool needsTextureDomain = needs_texture_domain( 1008 // de-optimized this determination
1273 bitmap, srcRect, params Temp, 1009 bool needsTextureDomain = true;
1274 viewM, bicubic,
1275 fRenderTarget->isUnifie dMultisampled());
1276 this->internalDrawBitmap(tmpB, 1010 this->internalDrawBitmap(tmpB,
1277 viewM, 1011 viewM,
1278 tileR, 1012 tileR,
1279 paramsTemp, 1013 paramsTemp,
1280 *paint, 1014 *paint,
1281 constraint, 1015 constraint,
1282 bicubic, 1016 bicubic,
1283 needsTextureDomain); 1017 needsTextureDomain);
1284 } 1018 }
1285 } 1019 }
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 SkRect::MakeXYWH(SkIntToScalar(left), 1229 SkRect::MakeXYWH(SkIntToScalar(left),
1496 SkIntToScalar(top), 1230 SkIntToScalar(top),
1497 SkIntToScalar(w), 1231 SkIntToScalar(w),
1498 SkIntToScalar(h)), 1232 SkIntToScalar(h)),
1499 SkRect::MakeXYWH(0, 1233 SkRect::MakeXYWH(0,
1500 0, 1234 0,
1501 SK_Scalar1 * w / texture->widt h(), 1235 SK_Scalar1 * w / texture->widt h(),
1502 SK_Scalar1 * h / texture->heig ht())); 1236 SK_Scalar1 * h / texture->heig ht()));
1503 } 1237 }
1504 1238
1505 void SkGpuDevice::drawBitmapRect(const SkDraw& origDraw, const SkBitmap& bitmap, 1239 void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
1506 const SkRect* src, const SkRect& dst, 1240 const SkRect* src, const SkRect& origDst,
1507 const SkPaint& paint, SkCanvas::SrcRectConstrai nt constraint) { 1241 const SkPaint& paint, SkCanvas::SrcRectConstrai nt constraint) {
1508 if (GrTexture* tex = bitmap.getTexture()) { 1242 bool alphaOnly = kAlpha_8_SkColorType == bitmap.colorType();
1509 CHECK_SHOULD_DRAW(origDraw); 1243 if (bitmap.getTexture()) {
1510 bool alphaOnly = GrPixelConfigIsAlphaOnly(tex->config()); 1244 CHECK_SHOULD_DRAW(draw);
1511 GrBitmapTextureAdjuster adjuster(&bitmap); 1245 GrBitmapTextureAdjuster adjuster(&bitmap);
1512 this->drawTextureAdjuster(&adjuster, alphaOnly, src, &dst, constraint, * origDraw.fMatrix, 1246 this->drawTextureProducer(&adjuster, alphaOnly, src, &origDst, constrain t, *draw.fMatrix,
1513 fClip, paint); 1247 fClip, paint);
1514 return; 1248 return;
1515 } 1249 }
1516 1250 // The src rect is inferred to be the bmp bounds if not provided. Otherwise, the src rect must
1517 SkMatrix matrix; 1251 // be clipped to the bmp bounds. To determine tiling parameters we need the filter mode which
1518 SkRect bitmapBounds, tmpSrc; 1252 // in turn requires knowing the src-to-dst mapping. If the src was clipped t o the bmp bounds
1519 1253 // then we use the src-to-dst mapping to compute a new clipped dst rect.
1520 bitmapBounds.set(0, 0, 1254 const SkRect* dst = &origDst;
1521 SkIntToScalar(bitmap.width()), 1255 const SkRect bmpBounds = SkRect::MakeIWH(bitmap.width(), bitmap.height());
1522 SkIntToScalar(bitmap.height()));
1523
1524 // Compute matrix from the two rectangles 1256 // Compute matrix from the two rectangles
1525 if (src) { 1257 if (!src) {
1526 tmpSrc = *src; 1258 src = &bmpBounds;
1527 } else {
1528 tmpSrc = bitmapBounds;
1529 } 1259 }
1530 1260
1531 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); 1261 SkMatrix srcToDstMatrix;
1532 1262 if (!srcToDstMatrix.setRectToRect(*src, *dst, SkMatrix::kFill_ScaleToFit)) {
1533 // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null . 1263 return;
1534 if (src) { 1264 }
1535 if (!bitmapBounds.contains(tmpSrc)) { 1265 SkRect tmpSrc, tmpDst;
1536 if (!tmpSrc.intersect(bitmapBounds)) { 1266 if (src != &bmpBounds) {
1267 if (!bmpBounds.contains(*src)) {
1268 tmpSrc = *src;
1269 if (!tmpSrc.intersect(bmpBounds)) {
1537 return; // nothing to draw 1270 return; // nothing to draw
1538 } 1271 }
1272 src = &tmpSrc;
1273 srcToDstMatrix.mapRect(&tmpDst, *src);
1274 dst = &tmpDst;
1539 } 1275 }
1540 } 1276 }
1541 1277
1542 SkRect tmpDst; 1278 int maxTileSize = fContext->caps()->maxTileSize();
1543 matrix.mapRect(&tmpDst, tmpSrc);
1544 1279
1545 SkTCopyOnFirstWrite<SkDraw> draw(origDraw); 1280 // The tile code path doesn't currently support AA, so if the paint asked fo r aa and we could
1546 if (0 != tmpDst.fLeft || 0 != tmpDst.fTop) { 1281 // draw untiled, then we bypass checking for tiling purely for optimization reasons.
1547 // Translate so that tempDst's top left is at the origin. 1282 bool drawAA = !fRenderTarget->isUnifiedMultisampled() &&
1548 matrix = *origDraw.fMatrix; 1283 paint.isAntiAlias() &&
1549 matrix.preTranslate(tmpDst.fLeft, tmpDst.fTop); 1284 bitmap.width() <= maxTileSize &&
1550 draw.writable()->fMatrix = &matrix; 1285 bitmap.height() <= maxTileSize;
1286
1287 bool skipTileCheck = drawAA || paint.getMaskFilter();
1288
1289 if (!skipTileCheck) {
1290 int tileSize;
1291 SkIRect clippedSrcRect;
1292
1293 GrTextureParams params;
1294 bool doBicubic;
1295 GrTextureParams::FilterMode textureFilterMode =
1296 GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), *draw.fMat rix, srcToDstMatrix,
1297 &doBicubic);
1298
1299 int tileFilterPad;
1300
1301 if (doBicubic) {
1302 tileFilterPad = GrBicubicEffect::kFilterTexelPad;
1303 } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) {
1304 tileFilterPad = 0;
1305 } else {
1306 tileFilterPad = 1;
1307 }
1308 params.setFilterMode(textureFilterMode);
1309
1310 int maxTileSizeForFilter = fContext->caps()->maxTileSize() - 2 * tileFil terPad;
1311 // Fold the dst rect into the view matrix. This is only OK because we do n't get here if
1312 // we have a mask filter.
1313 SkMatrix viewMatrix = *draw.fMatrix;
1314 viewMatrix.preTranslate(dst->fLeft, dst->fTop);
1315 viewMatrix.preScale(dst->width()/src->width(), dst->height()/src->height ());
1316 if (this->shouldTileBitmap(bitmap, viewMatrix, params, src,
1317 maxTileSizeForFilter, &tileSize, &clippedSrcR ect)) {
1318 this->drawTiledBitmap(bitmap, viewMatrix, *src, clippedSrcRect, para ms, paint,
1319 constraint, tileSize, doBicubic);
1320 return;
1321 }
1551 } 1322 }
1552 SkSize dstSize; 1323 GrBitmapTextureMaker maker(fContext, bitmap);
1553 dstSize.fWidth = tmpDst.width(); 1324 this->drawTextureProducer(&maker, alphaOnly, src, dst, constraint, *draw.fMa trix, fClip, paint);
1554 dstSize.fHeight = tmpDst.height();
1555
1556 this->drawBitmapCommon(*draw, bitmap, &tmpSrc, &dstSize, paint, constraint);
1557 } 1325 }
1558 1326
1559 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, 1327 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
1560 int x, int y, const SkPaint& paint) { 1328 int x, int y, const SkPaint& paint) {
1561 // clear of the source device must occur before CHECK_SHOULD_DRAW 1329 // clear of the source device must occur before CHECK_SHOULD_DRAW
1562 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext); 1330 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext);
1563 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); 1331 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
1564 1332
1565 // TODO: If the source device covers the whole of this device, we could 1333 // TODO: If the source device covers the whole of this device, we could
1566 // omit fNeedsClear -related flushing. 1334 // omit fNeedsClear -related flushing.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 1441
1674 void SkGpuDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x , SkScalar y, 1442 void SkGpuDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x , SkScalar y,
1675 const SkPaint& paint) { 1443 const SkPaint& paint) {
1676 SkBitmap bm; 1444 SkBitmap bm;
1677 if (GrTexture* tex = as_IB(image)->peekTexture()) { 1445 if (GrTexture* tex = as_IB(image)->peekTexture()) {
1678 CHECK_SHOULD_DRAW(draw); 1446 CHECK_SHOULD_DRAW(draw);
1679 SkMatrix viewMatrix = *draw.fMatrix; 1447 SkMatrix viewMatrix = *draw.fMatrix;
1680 viewMatrix.preTranslate(x, y); 1448 viewMatrix.preTranslate(x, y);
1681 bool alphaOnly = GrPixelConfigIsAlphaOnly(tex->config()); 1449 bool alphaOnly = GrPixelConfigIsAlphaOnly(tex->config());
1682 GrImageTextureAdjuster adjuster(as_IB(image)); 1450 GrImageTextureAdjuster adjuster(as_IB(image));
1683 this->drawTextureAdjuster(&adjuster, alphaOnly, nullptr, nullptr, 1451 this->drawTextureProducer(&adjuster, alphaOnly, nullptr, nullptr,
1684 SkCanvas::kFast_SrcRectConstraint, viewMatrix, fClip, paint); 1452 SkCanvas::kFast_SrcRectConstraint, viewMatrix, fClip, paint);
1685 return; 1453 return;
1686 } else { 1454 } else {
1687 if (this->shouldTileImage(image, nullptr, SkCanvas::kFast_SrcRectConstra int, 1455 if (this->shouldTileImage(image, nullptr, SkCanvas::kFast_SrcRectConstra int,
1688 paint.getFilterQuality(), *draw.fMatrix)) { 1456 paint.getFilterQuality(), *draw.fMatrix)) {
1689 // only support tiling as bitmap at the moment, so force raster-vers ion 1457 // only support tiling as bitmap at the moment, so force raster-vers ion
1690 if (!as_IB(image)->getROPixels(&bm)) { 1458 if (!as_IB(image)->getROPixels(&bm)) {
1691 return; 1459 return;
1692 } 1460 }
1693 } else { 1461 } else {
1694 if (!wrap_as_bm(this->context(), image, &bm)) { 1462 if (!wrap_as_bm(this->context(), image, &bm)) {
1695 return; 1463 return;
1696 } 1464 }
1697 } 1465 }
1698 } 1466 }
1699 this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint); 1467 this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
1700 } 1468 }
1701 1469
1702 void SkGpuDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src, 1470 void SkGpuDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src,
1703 const SkRect& dst, const SkPaint& paint, 1471 const SkRect& dst, const SkPaint& paint,
1704 SkCanvas::SrcRectConstraint constraint) { 1472 SkCanvas::SrcRectConstraint constraint) {
1705 if (GrTexture* tex = as_IB(image)->peekTexture()) { 1473 if (GrTexture* tex = as_IB(image)->peekTexture()) {
1706 CHECK_SHOULD_DRAW(draw); 1474 CHECK_SHOULD_DRAW(draw);
1707 GrImageTextureAdjuster adjuster(as_IB(image)); 1475 GrImageTextureAdjuster adjuster(as_IB(image));
1708 bool alphaOnly = GrPixelConfigIsAlphaOnly(tex->config()); 1476 bool alphaOnly = GrPixelConfigIsAlphaOnly(tex->config());
1709 this->drawTextureAdjuster(&adjuster, alphaOnly, src, &dst, constraint, * draw.fMatrix, 1477 this->drawTextureProducer(&adjuster, alphaOnly, src, &dst, constraint, * draw.fMatrix,
1710 fClip, paint); 1478 fClip, paint);
1711 return; 1479 return;
1712 } 1480 }
1713 SkBitmap bm; 1481 SkBitmap bm;
1714 SkMatrix viewMatrix = *draw.fMatrix; 1482 SkMatrix viewMatrix = *draw.fMatrix;
1715 viewMatrix.preScale(dst.width() / (src ? src->width() : image->width()), 1483 viewMatrix.preScale(dst.width() / (src ? src->width() : image->width()),
1716 dst.height() / (src ? src->height() : image->height())); 1484 dst.height() / (src ? src->height() : image->height()));
1717 if (this->shouldTileImage(image, src, constraint, paint.getFilterQuality(), viewMatrix)) { 1485 if (this->shouldTileImage(image, src, constraint, paint.getFilterQuality(), viewMatrix)) {
1718 // only support tiling as bitmap at the moment, so force raster-version 1486 // only support tiling as bitmap at the moment, so force raster-version
1719 if (!as_IB(image)->getROPixels(&bm)) { 1487 if (!as_IB(image)->getROPixels(&bm)) {
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
2070 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); 1838 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize);
2071 } 1839 }
2072 1840
2073 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { 1841 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() {
2074 // We always return a transient cache, so it is freed after each 1842 // We always return a transient cache, so it is freed after each
2075 // filter traversal. 1843 // filter traversal.
2076 return SkGpuDevice::NewImageFilterCache(); 1844 return SkGpuDevice::NewImageFilterCache();
2077 } 1845 }
2078 1846
2079 #endif 1847 #endif
OLDNEW
« no previous file with comments | « src/gpu/SkGpuDevice.h ('k') | src/gpu/SkGpuDevice_drawTexture.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698