| 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 "effects/GrBicubicEffect.h" | 10 #include "effects/GrBicubicEffect.h" |
| 11 #include "effects/GrTextureDomain.h" | 11 #include "effects/GrTextureDomain.h" |
| 12 #include "effects/GrSimpleTextureEffect.h" | 12 #include "effects/GrSimpleTextureEffect.h" |
| 13 | 13 |
| 14 #include "GrContext.h" | 14 #include "GrContext.h" |
| 15 #include "GrBitmapTextContext.h" | 15 #include "GrBitmapTextContext.h" |
| 16 #if SK_DISTANCEFIELD_FONTS | 16 #if SK_DISTANCEFIELD_FONTS |
| 17 #include "GrDistanceFieldTextContext.h" | 17 #include "GrDistanceFieldTextContext.h" |
| 18 #endif | 18 #endif |
| 19 | 19 |
| 20 #include "SkGrTexturePixelRef.h" | 20 #include "SkGrTexturePixelRef.h" |
| 21 | 21 |
| 22 #include "SkColorFilter.h" | 22 #include "SkColorFilter.h" |
| 23 #include "SkDeviceImageFilterProxy.h" | 23 #include "SkDeviceImageFilterProxy.h" |
| 24 #include "SkDrawProcs.h" | 24 #include "SkDrawProcs.h" |
| 25 #include "SkGlyphCache.h" | 25 #include "SkGlyphCache.h" |
| 26 #include "SkImageFilter.h" | 26 #include "SkImageFilter.h" |
| 27 #include "SkPathEffect.h" | 27 #include "SkPathEffect.h" |
| 28 #include "SkRRect.h" | 28 #include "SkRRect.h" |
| 29 #include "SkStroke.h" | 29 #include "SkStroke.h" |
| 30 #include "SkTLazy.h" |
| 30 #include "SkUtils.h" | 31 #include "SkUtils.h" |
| 31 #include "SkErrorInternals.h" | 32 #include "SkErrorInternals.h" |
| 32 | 33 |
| 33 #define CACHE_COMPATIBLE_DEVICE_TEXTURES 1 | 34 #define CACHE_COMPATIBLE_DEVICE_TEXTURES 1 |
| 34 | 35 |
| 35 #if 0 | 36 #if 0 |
| 36 extern bool (*gShouldDrawProc)(); | 37 extern bool (*gShouldDrawProc)(); |
| 37 #define CHECK_SHOULD_DRAW(draw, forceI) \ | 38 #define CHECK_SHOULD_DRAW(draw, forceI) \ |
| 38 do { \ | 39 do { \ |
| 39 if (gShouldDrawProc && !gShouldDrawProc()) return; \ | 40 if (gShouldDrawProc && !gShouldDrawProc()) return; \ |
| (...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1008 const GrClipData* clip = context->getClip(); | 1009 const GrClipData* clip = context->getClip(); |
| 1009 clip->getConservativeBounds(context->getRenderTarget(), clippedSrcIRect, NUL
L); | 1010 clip->getConservativeBounds(context->getRenderTarget(), clippedSrcIRect, NUL
L); |
| 1010 SkMatrix inv; | 1011 SkMatrix inv; |
| 1011 if (!context->getMatrix().invert(&inv)) { | 1012 if (!context->getMatrix().invert(&inv)) { |
| 1012 clippedSrcIRect->setEmpty(); | 1013 clippedSrcIRect->setEmpty(); |
| 1013 return; | 1014 return; |
| 1014 } | 1015 } |
| 1015 SkRect clippedSrcRect = SkRect::Make(*clippedSrcIRect); | 1016 SkRect clippedSrcRect = SkRect::Make(*clippedSrcIRect); |
| 1016 inv.mapRect(&clippedSrcRect); | 1017 inv.mapRect(&clippedSrcRect); |
| 1017 if (NULL != srcRectPtr) { | 1018 if (NULL != srcRectPtr) { |
| 1019 // we've setup src space 0,0 to map to the top left of the src rect. |
| 1020 clippedSrcRect.offset(srcRectPtr->fLeft, srcRectPtr->fTop); |
| 1018 if (!clippedSrcRect.intersect(*srcRectPtr)) { | 1021 if (!clippedSrcRect.intersect(*srcRectPtr)) { |
| 1019 clippedSrcIRect->setEmpty(); | 1022 clippedSrcIRect->setEmpty(); |
| 1020 return; | 1023 return; |
| 1021 } | 1024 } |
| 1022 } | 1025 } |
| 1023 clippedSrcRect.roundOut(clippedSrcIRect); | 1026 clippedSrcRect.roundOut(clippedSrcIRect); |
| 1024 SkIRect bmpBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); | 1027 SkIRect bmpBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); |
| 1025 if (!clippedSrcIRect->intersect(bmpBounds)) { | 1028 if (!clippedSrcIRect->intersect(bmpBounds)) { |
| 1026 clippedSrcIRect->setEmpty(); | 1029 clippedSrcIRect->setEmpty(); |
| 1027 } | 1030 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1070 | 1073 |
| 1071 // Figure out how much of the src we will need based on the src rect and cli
pping. | 1074 // Figure out how much of the src we will need based on the src rect and cli
pping. |
| 1072 determine_clipped_src_rect(fContext, bitmap, srcRectPtr, clippedSrcRect); | 1075 determine_clipped_src_rect(fContext, bitmap, srcRectPtr, clippedSrcRect); |
| 1073 *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max
sized tile. | 1076 *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max
sized tile. |
| 1074 size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) * | 1077 size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) * |
| 1075 kBmpSmallTileSize * kBmpSmallTileSize; | 1078 kBmpSmallTileSize * kBmpSmallTileSize; |
| 1076 | 1079 |
| 1077 return usedTileBytes < 2 * bmpSize; | 1080 return usedTileBytes < 2 * bmpSize; |
| 1078 } | 1081 } |
| 1079 | 1082 |
| 1080 void SkGpuDevice::drawBitmap(const SkDraw& draw, | 1083 void SkGpuDevice::drawBitmap(const SkDraw& origDraw, |
| 1081 const SkBitmap& bitmap, | 1084 const SkBitmap& bitmap, |
| 1082 const SkMatrix& m, | 1085 const SkMatrix& m, |
| 1083 const SkPaint& paint) { | 1086 const SkPaint& paint) { |
| 1084 // We cannot call drawBitmapRect here since 'm' could be anything | 1087 SkMatrix concat; |
| 1085 this->drawBitmapCommon(draw, bitmap, NULL, m, paint, | 1088 SkTCopyOnFirstWrite<SkDraw> draw(origDraw); |
| 1086 SkCanvas::kNone_DrawBitmapRectFlag); | 1089 if (!m.isIdentity()) { |
| 1090 concat.setConcat(*draw->fMatrix, m); |
| 1091 draw.writable()->fMatrix = &concat; |
| 1092 } |
| 1093 this->drawBitmapCommon(*draw, bitmap, NULL, NULL, paint, SkCanvas::kNone_Dra
wBitmapRectFlag); |
| 1087 } | 1094 } |
| 1088 | 1095 |
| 1089 // This method outsets 'iRect' by 'outset' all around and then clamps its extent
s to | 1096 // This method outsets 'iRect' by 'outset' all around and then clamps its extent
s to |
| 1090 // 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner | 1097 // 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner |
| 1091 // of 'iRect' for all possible outsets/clamps. | 1098 // of 'iRect' for all possible outsets/clamps. |
| 1092 static inline void clamped_outset_with_offset(SkIRect* iRect, | 1099 static inline void clamped_outset_with_offset(SkIRect* iRect, |
| 1093 int outset, | 1100 int outset, |
| 1094 SkPoint* offset, | 1101 SkPoint* offset, |
| 1095 const SkIRect& clamp) { | 1102 const SkIRect& clamp) { |
| 1096 iRect->outset(outset, outset); | 1103 iRect->outset(outset, outset); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1115 iRect->fRight = clamp.fRight; | 1122 iRect->fRight = clamp.fRight; |
| 1116 } | 1123 } |
| 1117 if (iRect->fBottom > clamp.fBottom) { | 1124 if (iRect->fBottom > clamp.fBottom) { |
| 1118 iRect->fBottom = clamp.fBottom; | 1125 iRect->fBottom = clamp.fBottom; |
| 1119 } | 1126 } |
| 1120 } | 1127 } |
| 1121 | 1128 |
| 1122 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, | 1129 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, |
| 1123 const SkBitmap& bitmap, | 1130 const SkBitmap& bitmap, |
| 1124 const SkRect* srcRectPtr, | 1131 const SkRect* srcRectPtr, |
| 1125 const SkMatrix& m, | 1132 const SkSize* dstSizePtr, |
| 1126 const SkPaint& paint, | 1133 const SkPaint& paint, |
| 1127 SkCanvas::DrawBitmapRectFlags flags) { | 1134 SkCanvas::DrawBitmapRectFlags flags) { |
| 1128 CHECK_SHOULD_DRAW(draw, false); | 1135 CHECK_SHOULD_DRAW(draw, false); |
| 1129 | 1136 |
| 1130 SkRect srcRect; | 1137 SkRect srcRect; |
| 1138 SkSize dstSize; |
| 1131 // If there is no src rect, or the src rect contains the entire bitmap then
we're effectively | 1139 // If there is no src rect, or the src rect contains the entire bitmap then
we're effectively |
| 1132 // in the (easier) bleed case, so update flags. | 1140 // in the (easier) bleed case, so update flags. |
| 1133 if (NULL == srcRectPtr) { | 1141 if (NULL == srcRectPtr) { |
| 1134 srcRect.set(0, 0, SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.he
ight())); | 1142 SkScalar w = SkIntToScalar(bitmap.width()); |
| 1143 SkScalar h = SkIntToScalar(bitmap.height()); |
| 1144 dstSize.fWidth = w; |
| 1145 dstSize.fHeight = h; |
| 1146 srcRect.set(0, 0, w, h); |
| 1135 flags = (SkCanvas::DrawBitmapRectFlags) (flags | SkCanvas::kBleed_DrawBi
tmapRectFlag); | 1147 flags = (SkCanvas::DrawBitmapRectFlags) (flags | SkCanvas::kBleed_DrawBi
tmapRectFlag); |
| 1136 } else { | 1148 } else { |
| 1149 SkASSERT(NULL != dstSizePtr); |
| 1137 srcRect = *srcRectPtr; | 1150 srcRect = *srcRectPtr; |
| 1151 dstSize = *dstSizePtr; |
| 1138 if (srcRect.fLeft <= 0 && srcRect.fTop <= 0 && | 1152 if (srcRect.fLeft <= 0 && srcRect.fTop <= 0 && |
| 1139 srcRect.fRight >= bitmap.width() && srcRect.fBottom >= bitmap.height
()) { | 1153 srcRect.fRight >= bitmap.width() && srcRect.fBottom >= bitmap.height
()) { |
| 1140 flags = (SkCanvas::DrawBitmapRectFlags) (flags | SkCanvas::kBleed_Dr
awBitmapRectFlag); | 1154 flags = (SkCanvas::DrawBitmapRectFlags) (flags | SkCanvas::kBleed_Dr
awBitmapRectFlag); |
| 1141 } | 1155 } |
| 1142 } | 1156 } |
| 1143 | 1157 |
| 1144 if (paint.getMaskFilter()){ | 1158 if (paint.getMaskFilter()){ |
| 1145 // Convert the bitmap to a shader so that the rect can be drawn | 1159 // Convert the bitmap to a shader so that the rect can be drawn |
| 1146 // through drawRect, which supports mask filters. | 1160 // through drawRect, which supports mask filters. |
| 1147 SkMatrix newM(m); | |
| 1148 SkBitmap tmp; // subset of bitmap, if necessary | 1161 SkBitmap tmp; // subset of bitmap, if necessary |
| 1149 const SkBitmap* bitmapPtr = &bitmap; | 1162 const SkBitmap* bitmapPtr = &bitmap; |
| 1163 SkMatrix localM; |
| 1150 if (NULL != srcRectPtr) { | 1164 if (NULL != srcRectPtr) { |
| 1165 localM.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop); |
| 1166 localM.postScale(dstSize.fWidth / srcRectPtr->width(), |
| 1167 dstSize.fHeight / srcRectPtr->height()); |
| 1151 // In bleed mode we position and trim the bitmap based on the src re
ct which is | 1168 // In bleed mode we position and trim the bitmap based on the src re
ct which is |
| 1152 // already accounted for in 'm' and 'srcRect'. In clamp mode we need
to chop out | 1169 // already accounted for in 'm' and 'srcRect'. In clamp mode we need
to chop out |
| 1153 // the desired portion of the bitmap and then update 'm' and 'srcRec
t' to | 1170 // the desired portion of the bitmap and then update 'm' and 'srcRec
t' to |
| 1154 // compensate. | 1171 // compensate. |
| 1155 if (!(SkCanvas::kBleed_DrawBitmapRectFlag & flags)) { | 1172 if (!(SkCanvas::kBleed_DrawBitmapRectFlag & flags)) { |
| 1156 SkIRect iSrc; | 1173 SkIRect iSrc; |
| 1157 srcRect.roundOut(&iSrc); | 1174 srcRect.roundOut(&iSrc); |
| 1158 | 1175 |
| 1159 SkPoint offset = SkPoint::Make(SkIntToScalar(iSrc.fLeft), | 1176 SkPoint offset = SkPoint::Make(SkIntToScalar(iSrc.fLeft), |
| 1160 SkIntToScalar(iSrc.fTop)); | 1177 SkIntToScalar(iSrc.fTop)); |
| 1161 | 1178 |
| 1162 if (!bitmap.extractSubset(&tmp, iSrc)) { | 1179 if (!bitmap.extractSubset(&tmp, iSrc)) { |
| 1163 return; // extraction failed | 1180 return; // extraction failed |
| 1164 } | 1181 } |
| 1165 bitmapPtr = &tmp; | 1182 bitmapPtr = &tmp; |
| 1166 srcRect.offset(-offset.fX, -offset.fY); | 1183 srcRect.offset(-offset.fX, -offset.fY); |
| 1184 |
| 1167 // The source rect has changed so update the matrix | 1185 // The source rect has changed so update the matrix |
| 1168 newM.preTranslate(offset.fX, offset.fY); | 1186 localM.preTranslate(offset.fX, offset.fY); |
| 1169 } | 1187 } |
| 1188 } else { |
| 1189 localM.reset(); |
| 1170 } | 1190 } |
| 1171 | 1191 |
| 1172 SkPaint paintWithTexture(paint); | 1192 SkPaint paintWithShader(paint); |
| 1173 paintWithTexture.setShader(SkShader::CreateBitmapShader(*bitmapPtr, | 1193 paintWithShader.setShader(SkShader::CreateBitmapShader(*bitmapPtr, |
| 1174 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref(); | 1194 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref(); |
| 1175 | 1195 paintWithShader.getShader()->setLocalMatrix(localM); |
| 1176 // Transform 'newM' needs to be concatenated to the current matrix, | 1196 SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight}; |
| 1177 // rather than transforming the primitive directly, so that 'newM' will | 1197 this->drawRect(draw, dstRect, paintWithShader); |
| 1178 // also affect the behavior of the mask filter. | |
| 1179 SkMatrix drawMatrix; | |
| 1180 drawMatrix.setConcat(fContext->getMatrix(), newM); | |
| 1181 SkDraw transformedDraw(draw); | |
| 1182 transformedDraw.fMatrix = &drawMatrix; | |
| 1183 | |
| 1184 this->drawRect(transformedDraw, srcRect, paintWithTexture); | |
| 1185 | 1198 |
| 1186 return; | 1199 return; |
| 1187 } | 1200 } |
| 1188 | 1201 |
| 1202 // If there is no mask filter than it is OK to handle the src rect -> dst re
ct scaling using |
| 1203 // the view matrix rather than a local matrix. |
| 1204 SkMatrix m; |
| 1205 m.setScale(dstSize.fWidth / srcRect.width(), |
| 1206 dstSize.fHeight / srcRect.height()); |
| 1189 fContext->concatMatrix(m); | 1207 fContext->concatMatrix(m); |
| 1190 | 1208 |
| 1191 GrTextureParams params; | 1209 GrTextureParams params; |
| 1192 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); | 1210 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); |
| 1193 GrTextureParams::FilterMode textureFilterMode; | 1211 GrTextureParams::FilterMode textureFilterMode; |
| 1194 | 1212 |
| 1195 int tileFilterPad; | 1213 int tileFilterPad; |
| 1196 bool doBicubic = false; | 1214 bool doBicubic = false; |
| 1197 | 1215 |
| 1198 switch(paintFilterLevel) { | 1216 switch(paintFilterLevel) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 if (!tileR.intersect(srcRect)) { | 1298 if (!tileR.intersect(srcRect)) { |
| 1281 continue; | 1299 continue; |
| 1282 } | 1300 } |
| 1283 | 1301 |
| 1284 SkBitmap tmpB; | 1302 SkBitmap tmpB; |
| 1285 SkIRect iTileR; | 1303 SkIRect iTileR; |
| 1286 tileR.roundOut(&iTileR); | 1304 tileR.roundOut(&iTileR); |
| 1287 SkPoint offset = SkPoint::Make(SkIntToScalar(iTileR.fLeft), | 1305 SkPoint offset = SkPoint::Make(SkIntToScalar(iTileR.fLeft), |
| 1288 SkIntToScalar(iTileR.fTop)); | 1306 SkIntToScalar(iTileR.fTop)); |
| 1289 | 1307 |
| 1308 // Adjust the context matrix to draw at the right x,y in device spac
e |
| 1309 SkMatrix tmpM; |
| 1310 GrContext::AutoMatrix am; |
| 1311 tmpM.setTranslate(offset.fX - srcRect.fLeft, offset.fY - srcRect.fTo
p); |
| 1312 am.setPreConcat(fContext, tmpM); |
| 1313 |
| 1290 if (SkPaint::kNone_FilterLevel != paint.getFilterLevel() || bicubic)
{ | 1314 if (SkPaint::kNone_FilterLevel != paint.getFilterLevel() || bicubic)
{ |
| 1291 SkIRect iClampRect; | 1315 SkIRect iClampRect; |
| 1292 | 1316 |
| 1293 if (SkCanvas::kBleed_DrawBitmapRectFlag & flags) { | 1317 if (SkCanvas::kBleed_DrawBitmapRectFlag & flags) { |
| 1294 // In bleed mode we want to always expand the tile on all ed
ges | 1318 // In bleed mode we want to always expand the tile on all ed
ges |
| 1295 // but stay within the bitmap bounds | 1319 // but stay within the bitmap bounds |
| 1296 iClampRect = SkIRect::MakeWH(bitmap.width(), bitmap.height()
); | 1320 iClampRect = SkIRect::MakeWH(bitmap.width(), bitmap.height()
); |
| 1297 } else { | 1321 } else { |
| 1298 // In texture-domain/clamp mode we only want to expand the | 1322 // In texture-domain/clamp mode we only want to expand the |
| 1299 // tile on edges interior to "srcRect" (i.e., we want to | 1323 // tile on edges interior to "srcRect" (i.e., we want to |
| 1300 // not bleed across the original clamped edges) | 1324 // not bleed across the original clamped edges) |
| 1301 srcRect.roundOut(&iClampRect); | 1325 srcRect.roundOut(&iClampRect); |
| 1302 } | 1326 } |
| 1303 int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1; | 1327 int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1; |
| 1304 clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect)
; | 1328 clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect)
; |
| 1305 } | 1329 } |
| 1306 | 1330 |
| 1307 if (bitmap.extractSubset(&tmpB, iTileR)) { | 1331 if (bitmap.extractSubset(&tmpB, iTileR)) { |
| 1308 // now offset it to make it "local" to our tmp bitmap | 1332 // now offset it to make it "local" to our tmp bitmap |
| 1309 tileR.offset(-offset.fX, -offset.fY); | 1333 tileR.offset(-offset.fX, -offset.fY); |
| 1310 SkMatrix tmpM; | 1334 |
| 1311 tmpM.setTranslate(offset.fX, offset.fY); | |
| 1312 GrContext::AutoMatrix am; | |
| 1313 am.setPreConcat(fContext, tmpM); | |
| 1314 this->internalDrawBitmap(tmpB, tileR, params, paint, flags, bicu
bic); | 1335 this->internalDrawBitmap(tmpB, tileR, params, paint, flags, bicu
bic); |
| 1315 } | 1336 } |
| 1316 } | 1337 } |
| 1317 } | 1338 } |
| 1318 } | 1339 } |
| 1319 | 1340 |
| 1320 static bool has_aligned_samples(const SkRect& srcRect, | 1341 static bool has_aligned_samples(const SkRect& srcRect, |
| 1321 const SkRect& transformedRect) { | 1342 const SkRect& transformedRect) { |
| 1322 // detect pixel disalignment | 1343 // detect pixel disalignment |
| 1323 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - | 1344 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1374 bool bicubic) { | 1395 bool bicubic) { |
| 1375 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && | 1396 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && |
| 1376 bitmap.height() <= fContext->getMaxTextureSize()); | 1397 bitmap.height() <= fContext->getMaxTextureSize()); |
| 1377 | 1398 |
| 1378 GrTexture* texture; | 1399 GrTexture* texture; |
| 1379 SkAutoCachedTexture act(this, bitmap, ¶ms, &texture); | 1400 SkAutoCachedTexture act(this, bitmap, ¶ms, &texture); |
| 1380 if (NULL == texture) { | 1401 if (NULL == texture) { |
| 1381 return; | 1402 return; |
| 1382 } | 1403 } |
| 1383 | 1404 |
| 1384 SkRect dstRect(srcRect); | 1405 SkRect dstRect = {0, 0, srcRect.width(), srcRect.height() }; |
| 1385 SkRect paintRect; | 1406 SkRect paintRect; |
| 1386 SkScalar wInv = SkScalarInvert(SkIntToScalar(texture->width())); | 1407 SkScalar wInv = SkScalarInvert(SkIntToScalar(texture->width())); |
| 1387 SkScalar hInv = SkScalarInvert(SkIntToScalar(texture->height())); | 1408 SkScalar hInv = SkScalarInvert(SkIntToScalar(texture->height())); |
| 1388 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), | 1409 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), |
| 1389 SkScalarMul(srcRect.fTop, hInv), | 1410 SkScalarMul(srcRect.fTop, hInv), |
| 1390 SkScalarMul(srcRect.fRight, wInv), | 1411 SkScalarMul(srcRect.fRight, wInv), |
| 1391 SkScalarMul(srcRect.fBottom, hInv)); | 1412 SkScalarMul(srcRect.fBottom, hInv)); |
| 1392 | 1413 |
| 1393 bool needsTextureDomain = false; | 1414 bool needsTextureDomain = false; |
| 1394 if (!(flags & SkCanvas::kBleed_DrawBitmapRectFlag) && | 1415 if (!(flags & SkCanvas::kBleed_DrawBitmapRectFlag) && |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1526 SkRect::MakeXYWH(SkIntToScalar(left), | 1547 SkRect::MakeXYWH(SkIntToScalar(left), |
| 1527 SkIntToScalar(top), | 1548 SkIntToScalar(top), |
| 1528 SkIntToScalar(w), | 1549 SkIntToScalar(w), |
| 1529 SkIntToScalar(h)), | 1550 SkIntToScalar(h)), |
| 1530 SkRect::MakeXYWH(0, | 1551 SkRect::MakeXYWH(0, |
| 1531 0, | 1552 0, |
| 1532 SK_Scalar1 * w / texture->width(), | 1553 SK_Scalar1 * w / texture->width(), |
| 1533 SK_Scalar1 * h / texture->height()
)); | 1554 SK_Scalar1 * h / texture->height()
)); |
| 1534 } | 1555 } |
| 1535 | 1556 |
| 1536 void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, | 1557 void SkGpuDevice::drawBitmapRect(const SkDraw& origDraw, const SkBitmap& bitmap, |
| 1537 const SkRect* src, const SkRect& dst, | 1558 const SkRect* src, const SkRect& dst, |
| 1538 const SkPaint& paint, | 1559 const SkPaint& paint, |
| 1539 SkCanvas::DrawBitmapRectFlags flags) { | 1560 SkCanvas::DrawBitmapRectFlags flags) { |
| 1540 SkMatrix matrix; | 1561 SkMatrix matrix; |
| 1541 SkRect bitmapBounds, tmpSrc; | 1562 SkRect bitmapBounds, tmpSrc; |
| 1542 | 1563 |
| 1543 bitmapBounds.set(0, 0, | 1564 bitmapBounds.set(0, 0, |
| 1544 SkIntToScalar(bitmap.width()), | 1565 SkIntToScalar(bitmap.width()), |
| 1545 SkIntToScalar(bitmap.height())); | 1566 SkIntToScalar(bitmap.height())); |
| 1546 | 1567 |
| 1547 // Compute matrix from the two rectangles | 1568 // Compute matrix from the two rectangles |
| 1548 if (NULL != src) { | 1569 if (NULL != src) { |
| 1549 tmpSrc = *src; | 1570 tmpSrc = *src; |
| 1550 } else { | 1571 } else { |
| 1551 tmpSrc = bitmapBounds; | 1572 tmpSrc = bitmapBounds; |
| 1552 } | 1573 } |
| 1574 |
| 1553 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); | 1575 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); |
| 1554 | 1576 |
| 1555 // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null
. | 1577 // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null
. |
| 1556 if (NULL != src) { | 1578 if (NULL != src) { |
| 1557 if (!bitmapBounds.contains(tmpSrc)) { | 1579 if (!bitmapBounds.contains(tmpSrc)) { |
| 1558 if (!tmpSrc.intersect(bitmapBounds)) { | 1580 if (!tmpSrc.intersect(bitmapBounds)) { |
| 1559 return; // nothing to draw | 1581 return; // nothing to draw |
| 1560 } | 1582 } |
| 1561 } | 1583 } |
| 1562 } | 1584 } |
| 1563 | 1585 |
| 1564 this->drawBitmapCommon(draw, bitmap, &tmpSrc, matrix, paint, flags); | 1586 SkRect tmpDst; |
| 1587 matrix.mapRect(&tmpDst, tmpSrc); |
| 1588 |
| 1589 SkTCopyOnFirstWrite<SkDraw> draw(origDraw); |
| 1590 if (0 != tmpDst.fLeft || 0 != tmpDst.fTop) { |
| 1591 // Translate so that tempDst's top left is at the origin. |
| 1592 matrix = *origDraw.fMatrix; |
| 1593 matrix.preTranslate(tmpDst.fLeft, tmpDst.fTop); |
| 1594 draw.writable()->fMatrix = &matrix; |
| 1595 } |
| 1596 SkSize dstSize; |
| 1597 dstSize.fWidth = tmpDst.width(); |
| 1598 dstSize.fHeight = tmpDst.height(); |
| 1599 |
| 1600 this->drawBitmapCommon(*draw, bitmap, &tmpSrc, &dstSize, paint, flags); |
| 1565 } | 1601 } |
| 1566 | 1602 |
| 1567 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, | 1603 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, |
| 1568 int x, int y, const SkPaint& paint) { | 1604 int x, int y, const SkPaint& paint) { |
| 1569 // clear of the source device must occur before CHECK_SHOULD_DRAW | 1605 // clear of the source device must occur before CHECK_SHOULD_DRAW |
| 1570 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); | 1606 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); |
| 1571 if (dev->fNeedClear) { | 1607 if (dev->fNeedClear) { |
| 1572 // TODO: could check here whether we really need to draw at all | 1608 // TODO: could check here whether we really need to draw at all |
| 1573 dev->clear(0x0); | 1609 dev->clear(0x0); |
| 1574 } | 1610 } |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1921 GrTexture* texture, | 1957 GrTexture* texture, |
| 1922 bool needClear) | 1958 bool needClear) |
| 1923 : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) { | 1959 : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) { |
| 1924 | 1960 |
| 1925 SkASSERT(texture && texture->asRenderTarget()); | 1961 SkASSERT(texture && texture->asRenderTarget()); |
| 1926 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture | 1962 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture |
| 1927 // cache. We pass true for the third argument so that it will get unlocked. | 1963 // cache. We pass true for the third argument so that it will get unlocked. |
| 1928 this->initFromRenderTarget(context, texture->asRenderTarget(), true); | 1964 this->initFromRenderTarget(context, texture->asRenderTarget(), true); |
| 1929 fNeedClear = needClear; | 1965 fNeedClear = needClear; |
| 1930 } | 1966 } |
| OLD | NEW |