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

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

Issue 131323004: Handle drawBitmapRect src_rect->dst_rect mapping as a local matrix rather than view matrix when the… (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: f Created 6 years, 11 months 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 | Annotate | Revision Log
« no previous file with comments | « include/gpu/SkGpuDevice.h ('k') | no next file » | 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 "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
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
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
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
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
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, &params, &texture); 1400 SkAutoCachedTexture act(this, bitmap, &params, &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
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
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 }
OLDNEW
« no previous file with comments | « include/gpu/SkGpuDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698