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 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1075 } else { | 1075 } else { |
1076 return false; | 1076 return false; |
1077 } | 1077 } |
1078 } | 1078 } |
1079 | 1079 |
1080 void SkGpuDevice::drawBitmap(const SkDraw& draw, | 1080 void SkGpuDevice::drawBitmap(const SkDraw& draw, |
1081 const SkBitmap& bitmap, | 1081 const SkBitmap& bitmap, |
1082 const SkMatrix& m, | 1082 const SkMatrix& m, |
1083 const SkPaint& paint) { | 1083 const SkPaint& paint) { |
1084 // We cannot call drawBitmapRect here since 'm' could be anything | 1084 // We cannot call drawBitmapRect here since 'm' could be anything |
1085 this->drawBitmapCommon(draw, bitmap, NULL, m, paint); | 1085 this->drawBitmapCommon(draw, bitmap, NULL, m, paint, |
| 1086 SkCanvas::kNone_DrawBitmapRectflag); |
1086 } | 1087 } |
1087 | 1088 |
1088 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, | 1089 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, |
1089 const SkBitmap& bitmap, | 1090 const SkBitmap& bitmap, |
1090 const SkRect* srcRectPtr, | 1091 const SkRect* srcRectPtr, |
1091 const SkMatrix& m, | 1092 const SkMatrix& m, |
1092 const SkPaint& paint) { | 1093 const SkPaint& paint, |
| 1094 SkCanvas::DrawBitmapRectFlags flags) { |
1093 CHECK_SHOULD_DRAW(draw, false); | 1095 CHECK_SHOULD_DRAW(draw, false); |
1094 | 1096 |
1095 SkRect srcRect; | 1097 SkRect srcRect; |
1096 if (NULL == srcRectPtr) { | 1098 if (NULL == srcRectPtr) { |
1097 srcRect.set(0, 0, SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.he
ight())); | 1099 srcRect.set(0, 0, SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.he
ight())); |
1098 } else { | 1100 } else { |
1099 srcRect = *srcRectPtr; | 1101 srcRect = *srcRectPtr; |
1100 } | 1102 } |
1101 | 1103 |
1102 if (paint.getMaskFilter()){ | 1104 if (paint.getMaskFilter()){ |
| 1105 // TODO: this path needs to be updated to respect the bleed flag |
| 1106 |
1103 // Convert the bitmap to a shader so that the rect can be drawn | 1107 // Convert the bitmap to a shader so that the rect can be drawn |
1104 // through drawRect, which supports mask filters. | 1108 // through drawRect, which supports mask filters. |
1105 SkMatrix newM(m); | 1109 SkMatrix newM(m); |
1106 SkBitmap tmp; // subset of bitmap, if necessary | 1110 SkBitmap tmp; // subset of bitmap, if necessary |
1107 const SkBitmap* bitmapPtr = &bitmap; | 1111 const SkBitmap* bitmapPtr = &bitmap; |
1108 if (NULL != srcRectPtr) { | 1112 if (NULL != srcRectPtr) { |
1109 SkIRect iSrc; | 1113 SkIRect iSrc; |
1110 srcRect.roundOut(&iSrc); | 1114 srcRect.roundOut(&iSrc); |
1111 if (!bitmap.extractSubset(&tmp, iSrc)) { | 1115 if (!bitmap.extractSubset(&tmp, iSrc)) { |
1112 return; // extraction failed | 1116 return; // extraction failed |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1161 "MIPMaps."); | 1165 "MIPMaps."); |
1162 textureFilterMode = GrTextureParams::kMipMap_FilterMode; | 1166 textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
1163 break; | 1167 break; |
1164 | 1168 |
1165 } | 1169 } |
1166 | 1170 |
1167 params.setFilterMode(textureFilterMode); | 1171 params.setFilterMode(textureFilterMode); |
1168 | 1172 |
1169 if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { | 1173 if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { |
1170 // take the simple case | 1174 // take the simple case |
1171 this->internalDrawBitmap(bitmap, srcRect, m, params, paint); | 1175 this->internalDrawBitmap(bitmap, srcRect, m, params, paint, flags); |
1172 } else { | 1176 } else { |
1173 this->drawTiledBitmap(bitmap, srcRect, m, params, paint); | 1177 this->drawTiledBitmap(bitmap, srcRect, m, params, paint, flags); |
1174 } | 1178 } |
1175 } | 1179 } |
1176 | 1180 |
1177 // Break 'bitmap' into several tiles to draw it since it has already | 1181 // Break 'bitmap' into several tiles to draw it since it has already |
1178 // been determined to be too large to fit in VRAM | 1182 // been determined to be too large to fit in VRAM |
1179 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, | 1183 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, |
1180 const SkRect& srcRect, | 1184 const SkRect& srcRect, |
1181 const SkMatrix& m, | 1185 const SkMatrix& m, |
1182 const GrTextureParams& params, | 1186 const GrTextureParams& params, |
1183 const SkPaint& paint) { | 1187 const SkPaint& paint, |
| 1188 SkCanvas::DrawBitmapRectFlags flags) { |
| 1189 // TODO: this method needs to be updated to respect the bleed flag |
1184 const int maxTextureSize = fContext->getMaxTextureSize(); | 1190 const int maxTextureSize = fContext->getMaxTextureSize(); |
1185 | 1191 |
1186 int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize); | 1192 int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize); |
1187 | 1193 |
1188 // compute clip bounds in local coordinates | 1194 // compute clip bounds in local coordinates |
1189 SkRect clipRect; | 1195 SkRect clipRect; |
1190 { | 1196 { |
1191 const GrRenderTarget* rt = fContext->getRenderTarget(); | 1197 const GrRenderTarget* rt = fContext->getRenderTarget(); |
1192 clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height())); | 1198 clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height())); |
1193 if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect))
{ | 1199 if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect))
{ |
(...skipping 28 matching lines...) Expand all Loading... |
1222 SkBitmap tmpB; | 1228 SkBitmap tmpB; |
1223 SkIRect iTileR; | 1229 SkIRect iTileR; |
1224 tileR.roundOut(&iTileR); | 1230 tileR.roundOut(&iTileR); |
1225 if (bitmap.extractSubset(&tmpB, iTileR)) { | 1231 if (bitmap.extractSubset(&tmpB, iTileR)) { |
1226 // now offset it to make it "local" to our tmp bitmap | 1232 // now offset it to make it "local" to our tmp bitmap |
1227 tileR.offset(SkIntToScalar(-iTileR.fLeft), SkIntToScalar(-iTileR
.fTop)); | 1233 tileR.offset(SkIntToScalar(-iTileR.fLeft), SkIntToScalar(-iTileR
.fTop)); |
1228 SkMatrix tmpM(m); | 1234 SkMatrix tmpM(m); |
1229 tmpM.preTranslate(SkIntToScalar(iTileR.fLeft), | 1235 tmpM.preTranslate(SkIntToScalar(iTileR.fLeft), |
1230 SkIntToScalar(iTileR.fTop)); | 1236 SkIntToScalar(iTileR.fTop)); |
1231 | 1237 |
1232 this->internalDrawBitmap(tmpB, tileR, tmpM, params, paint); | 1238 this->internalDrawBitmap(tmpB, tileR, tmpM, params, paint, flags
); |
1233 } | 1239 } |
1234 } | 1240 } |
1235 } | 1241 } |
1236 } | 1242 } |
1237 | 1243 |
1238 static bool has_aligned_samples(const SkRect& srcRect, | 1244 static bool has_aligned_samples(const SkRect& srcRect, |
1239 const SkRect& transformedRect) { | 1245 const SkRect& transformedRect) { |
1240 // detect pixel disalignment | 1246 // detect pixel disalignment |
1241 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - | 1247 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - |
1242 transformedRect.left()) < COLOR_BLEED_TOLERANCE && | 1248 transformedRect.left()) < COLOR_BLEED_TOLERANCE && |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1281 * This is called by drawBitmap(), which has to handle images that may be too | 1287 * This is called by drawBitmap(), which has to handle images that may be too |
1282 * large to be represented by a single texture. | 1288 * large to be represented by a single texture. |
1283 * | 1289 * |
1284 * internalDrawBitmap assumes that the specified bitmap will fit in a texture | 1290 * internalDrawBitmap assumes that the specified bitmap will fit in a texture |
1285 * and that non-texture portion of the GrPaint has already been setup. | 1291 * and that non-texture portion of the GrPaint has already been setup. |
1286 */ | 1292 */ |
1287 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, | 1293 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, |
1288 const SkRect& srcRect, | 1294 const SkRect& srcRect, |
1289 const SkMatrix& m, | 1295 const SkMatrix& m, |
1290 const GrTextureParams& params, | 1296 const GrTextureParams& params, |
1291 const SkPaint& paint) { | 1297 const SkPaint& paint, |
| 1298 SkCanvas::DrawBitmapRectFlags flags) { |
1292 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && | 1299 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && |
1293 bitmap.height() <= fContext->getMaxTextureSize()); | 1300 bitmap.height() <= fContext->getMaxTextureSize()); |
1294 | 1301 |
1295 GrTexture* texture; | 1302 GrTexture* texture; |
1296 SkAutoCachedTexture act(this, bitmap, ¶ms, &texture); | 1303 SkAutoCachedTexture act(this, bitmap, ¶ms, &texture); |
1297 if (NULL == texture) { | 1304 if (NULL == texture) { |
1298 return; | 1305 return; |
1299 } | 1306 } |
1300 | 1307 |
1301 SkRect dstRect(srcRect); | 1308 SkRect dstRect(srcRect); |
1302 SkRect paintRect; | 1309 SkRect paintRect; |
1303 SkScalar wInv = SkScalarInvert(SkIntToScalar(bitmap.width())); | 1310 SkScalar wInv = SkScalarInvert(SkIntToScalar(bitmap.width())); |
1304 SkScalar hInv = SkScalarInvert(SkIntToScalar(bitmap.height())); | 1311 SkScalar hInv = SkScalarInvert(SkIntToScalar(bitmap.height())); |
1305 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), | 1312 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), |
1306 SkScalarMul(srcRect.fTop, hInv), | 1313 SkScalarMul(srcRect.fTop, hInv), |
1307 SkScalarMul(srcRect.fRight, wInv), | 1314 SkScalarMul(srcRect.fRight, wInv), |
1308 SkScalarMul(srcRect.fBottom, hInv)); | 1315 SkScalarMul(srcRect.fBottom, hInv)); |
1309 | 1316 |
1310 bool needsTextureDomain = false; | 1317 bool needsTextureDomain = false; |
1311 if (params.filterMode() != GrTextureParams::kNone_FilterMode) { | 1318 if (!(flags & SkCanvas::kBleed_DrawBitmapRectFlag) && |
| 1319 params.filterMode() != GrTextureParams::kNone_FilterMode) { |
1312 // Need texture domain if drawing a sub rect. | 1320 // Need texture domain if drawing a sub rect. |
1313 needsTextureDomain = srcRect.width() < bitmap.width() || | 1321 needsTextureDomain = srcRect.width() < bitmap.width() || |
1314 srcRect.height() < bitmap.height(); | 1322 srcRect.height() < bitmap.height(); |
1315 if (needsTextureDomain && m.rectStaysRect() && fContext->getMatrix().rec
tStaysRect()) { | 1323 if (needsTextureDomain && m.rectStaysRect() && fContext->getMatrix().rec
tStaysRect()) { |
1316 // sampling is axis-aligned | 1324 // sampling is axis-aligned |
1317 SkRect transformedRect; | 1325 SkRect transformedRect; |
1318 SkMatrix srcToDeviceMatrix(m); | 1326 SkMatrix srcToDeviceMatrix(m); |
1319 srcToDeviceMatrix.postConcat(fContext->getMatrix()); | 1327 srcToDeviceMatrix.postConcat(fContext->getMatrix()); |
1320 srcToDeviceMatrix.mapRect(&transformedRect, srcRect); | 1328 srcToDeviceMatrix.mapRect(&transformedRect, srcRect); |
1321 | 1329 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 SkIntToScalar(w), | 1439 SkIntToScalar(w), |
1432 SkIntToScalar(h)), | 1440 SkIntToScalar(h)), |
1433 SkRect::MakeXYWH(0, | 1441 SkRect::MakeXYWH(0, |
1434 0, | 1442 0, |
1435 SK_Scalar1 * w / texture->width(), | 1443 SK_Scalar1 * w / texture->width(), |
1436 SK_Scalar1 * h / texture->height()
)); | 1444 SK_Scalar1 * h / texture->height()
)); |
1437 } | 1445 } |
1438 | 1446 |
1439 void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, | 1447 void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, |
1440 const SkRect* src, const SkRect& dst, | 1448 const SkRect* src, const SkRect& dst, |
1441 const SkPaint& paint) { | 1449 const SkPaint& paint, |
| 1450 SkCanvas::DrawBitmapRectFlags flags) { |
1442 SkMatrix matrix; | 1451 SkMatrix matrix; |
1443 SkRect bitmapBounds, tmpSrc; | 1452 SkRect bitmapBounds, tmpSrc; |
1444 | 1453 |
1445 bitmapBounds.set(0, 0, | 1454 bitmapBounds.set(0, 0, |
1446 SkIntToScalar(bitmap.width()), | 1455 SkIntToScalar(bitmap.width()), |
1447 SkIntToScalar(bitmap.height())); | 1456 SkIntToScalar(bitmap.height())); |
1448 | 1457 |
1449 // Compute matrix from the two rectangles | 1458 // Compute matrix from the two rectangles |
1450 if (NULL != src) { | 1459 if (NULL != src) { |
1451 tmpSrc = *src; | 1460 tmpSrc = *src; |
1452 } else { | 1461 } else { |
1453 tmpSrc = bitmapBounds; | 1462 tmpSrc = bitmapBounds; |
1454 } | 1463 } |
1455 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); | 1464 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); |
1456 | 1465 |
1457 // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null
. | 1466 // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null
. |
1458 if (NULL != src) { | 1467 if (NULL != src) { |
1459 if (!bitmapBounds.contains(tmpSrc)) { | 1468 if (!bitmapBounds.contains(tmpSrc)) { |
1460 if (!tmpSrc.intersect(bitmapBounds)) { | 1469 if (!tmpSrc.intersect(bitmapBounds)) { |
1461 return; // nothing to draw | 1470 return; // nothing to draw |
1462 } | 1471 } |
1463 } | 1472 } |
1464 } | 1473 } |
1465 | 1474 |
1466 this->drawBitmapCommon(draw, bitmap, &tmpSrc, matrix, paint); | 1475 this->drawBitmapCommon(draw, bitmap, &tmpSrc, matrix, paint, flags); |
1467 } | 1476 } |
1468 | 1477 |
1469 void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device, | 1478 void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device, |
1470 int x, int y, const SkPaint& paint) { | 1479 int x, int y, const SkPaint& paint) { |
1471 // clear of the source device must occur before CHECK_SHOULD_DRAW | 1480 // clear of the source device must occur before CHECK_SHOULD_DRAW |
1472 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); | 1481 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); |
1473 if (dev->fNeedClear) { | 1482 if (dev->fNeedClear) { |
1474 // TODO: could check here whether we really need to draw at all | 1483 // TODO: could check here whether we really need to draw at all |
1475 dev->clear(0x0); | 1484 dev->clear(0x0); |
1476 } | 1485 } |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1784 GrTexture* texture, | 1793 GrTexture* texture, |
1785 bool needClear) | 1794 bool needClear) |
1786 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { | 1795 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { |
1787 | 1796 |
1788 GrAssert(texture && texture->asRenderTarget()); | 1797 GrAssert(texture && texture->asRenderTarget()); |
1789 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture | 1798 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture |
1790 // cache. We pass true for the third argument so that it will get unlocked. | 1799 // cache. We pass true for the third argument so that it will get unlocked. |
1791 this->initFromRenderTarget(context, texture->asRenderTarget(), true); | 1800 this->initFromRenderTarget(context, texture->asRenderTarget(), true); |
1792 fNeedClear = needClear; | 1801 fNeedClear = needClear; |
1793 } | 1802 } |
OLD | NEW |