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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 SkIntToScalar(w), | 1441 SkIntToScalar(w), |
1434 SkIntToScalar(h)), | 1442 SkIntToScalar(h)), |
1435 SkRect::MakeXYWH(0, | 1443 SkRect::MakeXYWH(0, |
1436 0, | 1444 0, |
1437 SK_Scalar1 * w / texture->width(), | 1445 SK_Scalar1 * w / texture->width(), |
1438 SK_Scalar1 * h / texture->height()
)); | 1446 SK_Scalar1 * h / texture->height()
)); |
1439 } | 1447 } |
1440 | 1448 |
1441 void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, | 1449 void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, |
1442 const SkRect* src, const SkRect& dst, | 1450 const SkRect* src, const SkRect& dst, |
1443 const SkPaint& paint) { | 1451 const SkPaint& paint, |
| 1452 SkCanvas::DrawBitmapRectFlags flags) { |
1444 SkMatrix matrix; | 1453 SkMatrix matrix; |
1445 SkRect bitmapBounds, tmpSrc; | 1454 SkRect bitmapBounds, tmpSrc; |
1446 | 1455 |
1447 bitmapBounds.set(0, 0, | 1456 bitmapBounds.set(0, 0, |
1448 SkIntToScalar(bitmap.width()), | 1457 SkIntToScalar(bitmap.width()), |
1449 SkIntToScalar(bitmap.height())); | 1458 SkIntToScalar(bitmap.height())); |
1450 | 1459 |
1451 // Compute matrix from the two rectangles | 1460 // Compute matrix from the two rectangles |
1452 if (NULL != src) { | 1461 if (NULL != src) { |
1453 tmpSrc = *src; | 1462 tmpSrc = *src; |
1454 } else { | 1463 } else { |
1455 tmpSrc = bitmapBounds; | 1464 tmpSrc = bitmapBounds; |
1456 } | 1465 } |
1457 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); | 1466 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); |
1458 | 1467 |
1459 // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null
. | 1468 // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null
. |
1460 if (NULL != src) { | 1469 if (NULL != src) { |
1461 if (!bitmapBounds.contains(tmpSrc)) { | 1470 if (!bitmapBounds.contains(tmpSrc)) { |
1462 if (!tmpSrc.intersect(bitmapBounds)) { | 1471 if (!tmpSrc.intersect(bitmapBounds)) { |
1463 return; // nothing to draw | 1472 return; // nothing to draw |
1464 } | 1473 } |
1465 } | 1474 } |
1466 } | 1475 } |
1467 | 1476 |
1468 this->drawBitmapCommon(draw, bitmap, &tmpSrc, matrix, paint); | 1477 this->drawBitmapCommon(draw, bitmap, &tmpSrc, matrix, paint, flags); |
1469 } | 1478 } |
1470 | 1479 |
1471 void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device, | 1480 void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device, |
1472 int x, int y, const SkPaint& paint) { | 1481 int x, int y, const SkPaint& paint) { |
1473 // clear of the source device must occur before CHECK_SHOULD_DRAW | 1482 // clear of the source device must occur before CHECK_SHOULD_DRAW |
1474 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); | 1483 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); |
1475 if (dev->fNeedClear) { | 1484 if (dev->fNeedClear) { |
1476 // TODO: could check here whether we really need to draw at all | 1485 // TODO: could check here whether we really need to draw at all |
1477 dev->clear(0x0); | 1486 dev->clear(0x0); |
1478 } | 1487 } |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1788 GrTexture* texture, | 1797 GrTexture* texture, |
1789 bool needClear) | 1798 bool needClear) |
1790 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { | 1799 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { |
1791 | 1800 |
1792 GrAssert(texture && texture->asRenderTarget()); | 1801 GrAssert(texture && texture->asRenderTarget()); |
1793 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture | 1802 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture |
1794 // cache. We pass true for the third argument so that it will get unlocked. | 1803 // cache. We pass true for the third argument so that it will get unlocked. |
1795 this->initFromRenderTarget(context, texture->asRenderTarget(), true); | 1804 this->initFromRenderTarget(context, texture->asRenderTarget(), true); |
1796 fNeedClear = needClear; | 1805 fNeedClear = needClear; |
1797 } | 1806 } |
OLD | NEW |