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 |