| 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/GrTextureDomainEffect.h" | 10 #include "effects/GrTextureDomainEffect.h" |
| (...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1071 srcRectPtr->height() / bitmap.height()); | 1071 srcRectPtr->height() / bitmap.height()); |
| 1072 if (fracUsed <= SK_ScalarHalf) { | 1072 if (fracUsed <= SK_ScalarHalf) { |
| 1073 return true; | 1073 return true; |
| 1074 } else { | 1074 } else { |
| 1075 return false; | 1075 return false; |
| 1076 } | 1076 } |
| 1077 } | 1077 } |
| 1078 | 1078 |
| 1079 void SkGpuDevice::drawBitmap(const SkDraw& draw, | 1079 void SkGpuDevice::drawBitmap(const SkDraw& draw, |
| 1080 const SkBitmap& bitmap, | 1080 const SkBitmap& bitmap, |
| 1081 const SkIRect* srcRectPtr, | |
| 1082 const SkMatrix& m, | 1081 const SkMatrix& m, |
| 1083 const SkPaint& paint) { | 1082 const SkPaint& paint) { |
| 1084 | |
| 1085 SkRect tmp; | |
| 1086 SkRect* tmpPtr = NULL; | |
| 1087 | |
| 1088 // convert from SkIRect to SkRect | |
| 1089 if (NULL != srcRectPtr) { | |
| 1090 tmp.set(*srcRectPtr); | |
| 1091 tmpPtr = &tmp; | |
| 1092 } | |
| 1093 | |
| 1094 // We cannot call drawBitmapRect here since 'm' could be anything | 1083 // We cannot call drawBitmapRect here since 'm' could be anything |
| 1095 this->drawBitmapCommon(draw, bitmap, tmpPtr, m, paint); | 1084 this->drawBitmapCommon(draw, bitmap, NULL, m, paint); |
| 1096 } | 1085 } |
| 1097 | 1086 |
| 1098 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, | 1087 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, |
| 1099 const SkBitmap& bitmap, | 1088 const SkBitmap& bitmap, |
| 1100 const SkRect* srcRectPtr, | 1089 const SkRect* srcRectPtr, |
| 1101 const SkMatrix& m, | 1090 const SkMatrix& m, |
| 1102 const SkPaint& paint) { | 1091 const SkPaint& paint) { |
| 1103 CHECK_SHOULD_DRAW(draw, false); | 1092 CHECK_SHOULD_DRAW(draw, false); |
| 1104 | 1093 |
| 1105 SkRect srcRect; | 1094 SkRect srcRect; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 SkMatrix tmpM(m); | 1198 SkMatrix tmpM(m); |
| 1210 tmpM.preTranslate(SkIntToScalar(iTileR.fLeft), | 1199 tmpM.preTranslate(SkIntToScalar(iTileR.fLeft), |
| 1211 SkIntToScalar(iTileR.fTop)); | 1200 SkIntToScalar(iTileR.fTop)); |
| 1212 | 1201 |
| 1213 this->internalDrawBitmap(tmpB, tileR, tmpM, params, paint); | 1202 this->internalDrawBitmap(tmpB, tileR, tmpM, params, paint); |
| 1214 } | 1203 } |
| 1215 } | 1204 } |
| 1216 } | 1205 } |
| 1217 } | 1206 } |
| 1218 | 1207 |
| 1219 namespace { | 1208 static bool has_aligned_samples(const SkRect& srcRect, |
| 1220 | 1209 const SkRect& transformedRect) { |
| 1221 bool hasAlignedSamples(const SkRect& srcRect, const SkRect& transformedRect) { | |
| 1222 // detect pixel disalignment | 1210 // detect pixel disalignment |
| 1223 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - | 1211 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - |
| 1224 transformedRect.left()) < COLOR_BLEED_TOLERANCE && | 1212 transformedRect.left()) < COLOR_BLEED_TOLERANCE && |
| 1225 SkScalarAbs(SkScalarRoundToScalar(transformedRect.top()) - | 1213 SkScalarAbs(SkScalarRoundToScalar(transformedRect.top()) - |
| 1226 transformedRect.top()) < COLOR_BLEED_TOLERANCE && | 1214 transformedRect.top()) < COLOR_BLEED_TOLERANCE && |
| 1227 SkScalarAbs(transformedRect.width() - srcRect.width()) < | 1215 SkScalarAbs(transformedRect.width() - srcRect.width()) < |
| 1228 COLOR_BLEED_TOLERANCE && | 1216 COLOR_BLEED_TOLERANCE && |
| 1229 SkScalarAbs(transformedRect.height() - srcRect.height()) < | 1217 SkScalarAbs(transformedRect.height() - srcRect.height()) < |
| 1230 COLOR_BLEED_TOLERANCE) { | 1218 COLOR_BLEED_TOLERANCE) { |
| 1231 return true; | 1219 return true; |
| 1232 } | 1220 } |
| 1233 return false; | 1221 return false; |
| 1234 } | 1222 } |
| 1235 | 1223 |
| 1236 bool mayColorBleed(const SkRect& srcRect, const SkRect& transformedRect, | 1224 static bool may_color_bleed(const SkRect& srcRect, |
| 1237 const SkMatrix& m) { | 1225 const SkRect& transformedRect, |
| 1238 // Only gets called if hasAlignedSamples returned false. | 1226 const SkMatrix& m) { |
| 1227 // Only gets called if has_aligned_samples returned false. |
| 1239 // So we can assume that sampling is axis aligned but not texel aligned. | 1228 // So we can assume that sampling is axis aligned but not texel aligned. |
| 1240 GrAssert(!hasAlignedSamples(srcRect, transformedRect)); | 1229 GrAssert(!has_aligned_samples(srcRect, transformedRect)); |
| 1241 SkRect innerSrcRect(srcRect), innerTransformedRect, | 1230 SkRect innerSrcRect(srcRect), innerTransformedRect, |
| 1242 outerTransformedRect(transformedRect); | 1231 outerTransformedRect(transformedRect); |
| 1243 innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf); | 1232 innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf); |
| 1244 m.mapRect(&innerTransformedRect, innerSrcRect); | 1233 m.mapRect(&innerTransformedRect, innerSrcRect); |
| 1245 | 1234 |
| 1246 // The gap between outerTransformedRect and innerTransformedRect | 1235 // The gap between outerTransformedRect and innerTransformedRect |
| 1247 // represents the projection of the source border area, which is | 1236 // represents the projection of the source border area, which is |
| 1248 // problematic for color bleeding. We must check whether any | 1237 // problematic for color bleeding. We must check whether any |
| 1249 // destination pixels sample the border area. | 1238 // destination pixels sample the border area. |
| 1250 outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE); | 1239 outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE); |
| 1251 innerTransformedRect.outset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE); | 1240 innerTransformedRect.outset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE); |
| 1252 SkIRect outer, inner; | 1241 SkIRect outer, inner; |
| 1253 outerTransformedRect.round(&outer); | 1242 outerTransformedRect.round(&outer); |
| 1254 innerTransformedRect.round(&inner); | 1243 innerTransformedRect.round(&inner); |
| 1255 // If the inner and outer rects round to the same result, it means the | 1244 // If the inner and outer rects round to the same result, it means the |
| 1256 // border does not overlap any pixel centers. Yay! | 1245 // border does not overlap any pixel centers. Yay! |
| 1257 return inner != outer; | 1246 return inner != outer; |
| 1258 } | 1247 } |
| 1259 | 1248 |
| 1260 } // unnamed namespace | |
| 1261 | 1249 |
| 1262 /* | 1250 /* |
| 1263 * This is called by drawBitmap(), which has to handle images that may be too | 1251 * This is called by drawBitmap(), which has to handle images that may be too |
| 1264 * large to be represented by a single texture. | 1252 * large to be represented by a single texture. |
| 1265 * | 1253 * |
| 1266 * internalDrawBitmap assumes that the specified bitmap will fit in a texture | 1254 * internalDrawBitmap assumes that the specified bitmap will fit in a texture |
| 1267 * and that non-texture portion of the GrPaint has already been setup. | 1255 * and that non-texture portion of the GrPaint has already been setup. |
| 1268 */ | 1256 */ |
| 1269 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, | 1257 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, |
| 1270 const SkRect& srcRect, | 1258 const SkRect& srcRect, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1287 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), | 1275 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), |
| 1288 SkScalarMul(srcRect.fTop, hInv), | 1276 SkScalarMul(srcRect.fTop, hInv), |
| 1289 SkScalarMul(srcRect.fRight, wInv), | 1277 SkScalarMul(srcRect.fRight, wInv), |
| 1290 SkScalarMul(srcRect.fBottom, hInv)); | 1278 SkScalarMul(srcRect.fBottom, hInv)); |
| 1291 | 1279 |
| 1292 bool needsTextureDomain = false; | 1280 bool needsTextureDomain = false; |
| 1293 if (params.isBilerp()) { | 1281 if (params.isBilerp()) { |
| 1294 // Need texture domain if drawing a sub rect. | 1282 // Need texture domain if drawing a sub rect. |
| 1295 needsTextureDomain = srcRect.width() < bitmap.width() || | 1283 needsTextureDomain = srcRect.width() < bitmap.width() || |
| 1296 srcRect.height() < bitmap.height(); | 1284 srcRect.height() < bitmap.height(); |
| 1297 if (m.rectStaysRect() && fContext->getMatrix().rectStaysRect()) { | 1285 if (needsTextureDomain && m.rectStaysRect() && fContext->getMatrix().rec
tStaysRect()) { |
| 1298 // sampling is axis-aligned | 1286 // sampling is axis-aligned |
| 1299 SkRect transformedRect; | 1287 SkRect transformedRect; |
| 1300 SkMatrix srcToDeviceMatrix(m); | 1288 SkMatrix srcToDeviceMatrix(m); |
| 1301 srcToDeviceMatrix.postConcat(fContext->getMatrix()); | 1289 srcToDeviceMatrix.postConcat(fContext->getMatrix()); |
| 1302 srcToDeviceMatrix.mapRect(&transformedRect, srcRect); | 1290 srcToDeviceMatrix.mapRect(&transformedRect, srcRect); |
| 1303 | 1291 |
| 1304 if (hasAlignedSamples(srcRect, transformedRect)) { | 1292 if (has_aligned_samples(srcRect, transformedRect)) { |
| 1305 // We could also turn off filtering here (but we already did a c
ache lookup with | 1293 // We could also turn off filtering here (but we already did a c
ache lookup with |
| 1306 // params). | 1294 // params). |
| 1307 needsTextureDomain = false; | 1295 needsTextureDomain = false; |
| 1308 } else { | 1296 } else { |
| 1309 needsTextureDomain = needsTextureDomain && | 1297 needsTextureDomain = may_color_bleed(srcRect, transformedRect, m
); |
| 1310 mayColorBleed(srcRect, transformedRect, m); | |
| 1311 } | 1298 } |
| 1312 } | 1299 } |
| 1313 } | 1300 } |
| 1314 | 1301 |
| 1315 SkRect textureDomain = SkRect::MakeEmpty(); | 1302 SkRect textureDomain = SkRect::MakeEmpty(); |
| 1316 SkAutoTUnref<GrEffectRef> effect; | 1303 SkAutoTUnref<GrEffectRef> effect; |
| 1317 if (needsTextureDomain) { | 1304 if (needsTextureDomain) { |
| 1318 // Use a constrained texture domain to avoid color bleeding | 1305 // Use a constrained texture domain to avoid color bleeding |
| 1319 SkScalar left, top, right, bottom; | 1306 SkScalar left, top, right, bottom; |
| 1320 if (srcRect.width() > SK_Scalar1) { | 1307 if (srcRect.width() > SK_Scalar1) { |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1763 GrTexture* texture, | 1750 GrTexture* texture, |
| 1764 bool needClear) | 1751 bool needClear) |
| 1765 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { | 1752 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { |
| 1766 | 1753 |
| 1767 GrAssert(texture && texture->asRenderTarget()); | 1754 GrAssert(texture && texture->asRenderTarget()); |
| 1768 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture | 1755 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture |
| 1769 // cache. We pass true for the third argument so that it will get unlocked. | 1756 // cache. We pass true for the third argument so that it will get unlocked. |
| 1770 this->initFromRenderTarget(context, texture->asRenderTarget(), true); | 1757 this->initFromRenderTarget(context, texture->asRenderTarget(), true); |
| 1771 fNeedClear = needClear; | 1758 fNeedClear = needClear; |
| 1772 } | 1759 } |
| OLD | NEW |