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 "GrBlurUtils.h" | 10 #include "GrBlurUtils.h" |
11 #include "GrContext.h" | 11 #include "GrContext.h" |
12 #include "GrDrawContext.h" | 12 #include "GrDrawContext.h" |
13 #include "GrFontScaler.h" | 13 #include "GrFontScaler.h" |
14 #include "GrGpu.h" | 14 #include "GrGpu.h" |
15 #include "GrGpuResourcePriv.h" | 15 #include "GrGpuResourcePriv.h" |
16 #include "GrImageIDTextureAdjuster.h" | |
16 #include "GrLayerHoister.h" | 17 #include "GrLayerHoister.h" |
17 #include "GrRecordReplaceDraw.h" | 18 #include "GrRecordReplaceDraw.h" |
18 #include "GrStrokeInfo.h" | 19 #include "GrStrokeInfo.h" |
19 #include "GrTextContext.h" | 20 #include "GrTextContext.h" |
20 #include "GrTracing.h" | 21 #include "GrTracing.h" |
21 #include "SkCanvasPriv.h" | 22 #include "SkCanvasPriv.h" |
22 #include "SkDrawProcs.h" | 23 #include "SkDrawProcs.h" |
23 #include "SkErrorInternals.h" | 24 #include "SkErrorInternals.h" |
24 #include "SkGlyphCache.h" | 25 #include "SkGlyphCache.h" |
25 #include "SkGrTexturePixelRef.h" | 26 #include "SkGrTexturePixelRef.h" |
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
840 void SkGpuDevice::drawBitmap(const SkDraw& origDraw, | 841 void SkGpuDevice::drawBitmap(const SkDraw& origDraw, |
841 const SkBitmap& bitmap, | 842 const SkBitmap& bitmap, |
842 const SkMatrix& m, | 843 const SkMatrix& m, |
843 const SkPaint& paint) { | 844 const SkPaint& paint) { |
844 SkMatrix concat; | 845 SkMatrix concat; |
845 SkTCopyOnFirstWrite<SkDraw> draw(origDraw); | 846 SkTCopyOnFirstWrite<SkDraw> draw(origDraw); |
846 if (!m.isIdentity()) { | 847 if (!m.isIdentity()) { |
847 concat.setConcat(*draw->fMatrix, m); | 848 concat.setConcat(*draw->fMatrix, m); |
848 draw.writable()->fMatrix = &concat; | 849 draw.writable()->fMatrix = &concat; |
849 } | 850 } |
851 | |
852 GrTexture* texture = bitmap.getTexture(); | |
853 if (texture) { | |
854 CHECK_SHOULD_DRAW(*draw); | |
855 // src and dst rects are the same. | |
856 SkRect rect = SkRect::MakeWH(SkIntToScalar(bitmap.width()), SkIntToScala r(bitmap.height())); | |
857 // Since the src rect is the bitmap dimensions, no need to enforce a ble ed constraint. | |
858 static const SkCanvas::SrcRectConstraint kSrcRectConstraint = | |
859 SkCanvas::kFast_SrcRectConstraint; | |
860 bool alphaBitmap = kAlpha_8_SkColorType == bitmap.colorType(); | |
861 this->drawTextureRect(&GrBitmapTextureAdjuster(&bitmap), alphaBitmap, re ct, | |
862 rect, *draw->fMatrix, fClip, paint, kSrcRectConstr aint); | |
863 return; | |
864 } | |
850 this->drawBitmapCommon(*draw, bitmap, nullptr, nullptr, paint, SkCanvas::kSt rict_SrcRectConstraint); | 865 this->drawBitmapCommon(*draw, bitmap, nullptr, nullptr, paint, SkCanvas::kSt rict_SrcRectConstraint); |
851 } | 866 } |
852 | 867 |
853 // This method outsets 'iRect' by 'outset' all around and then clamps its extent s to | 868 // This method outsets 'iRect' by 'outset' all around and then clamps its extent s to |
854 // 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner | 869 // 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner |
855 // of 'iRect' for all possible outsets/clamps. | 870 // of 'iRect' for all possible outsets/clamps. |
856 static inline void clamped_outset_with_offset(SkIRect* iRect, | 871 static inline void clamped_outset_with_offset(SkIRect* iRect, |
857 int outset, | 872 int outset, |
858 SkPoint* offset, | 873 SkPoint* offset, |
859 const SkIRect& clamp) { | 874 const SkIRect& clamp) { |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1177 } | 1192 } |
1178 } | 1193 } |
1179 | 1194 |
1180 // Break 'bitmap' into several tiles to draw it since it has already | 1195 // Break 'bitmap' into several tiles to draw it since it has already |
1181 // been determined to be too large to fit in VRAM | 1196 // been determined to be too large to fit in VRAM |
1182 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, | 1197 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, |
1183 const SkMatrix& viewMatrix, | 1198 const SkMatrix& viewMatrix, |
1184 const SkRect& srcRect, | 1199 const SkRect& srcRect, |
1185 const SkIRect& clippedSrcIRect, | 1200 const SkIRect& clippedSrcIRect, |
1186 const GrTextureParams& params, | 1201 const GrTextureParams& params, |
1187 const SkPaint& paint, | 1202 const SkPaint& origPaint, |
1188 SkCanvas::SrcRectConstraint constraint, | 1203 SkCanvas::SrcRectConstraint constraint, |
1189 int tileSize, | 1204 int tileSize, |
1190 bool bicubic) { | 1205 bool bicubic) { |
1191 // The following pixel lock is technically redundant, but it is desirable | 1206 // The following pixel lock is technically redundant, but it is desirable |
1192 // to lock outside of the tile loop to prevent redecoding the whole image | 1207 // to lock outside of the tile loop to prevent redecoding the whole image |
1193 // at each tile in cases where 'bitmap' holds an SkDiscardablePixelRef that | 1208 // at each tile in cases where 'bitmap' holds an SkDiscardablePixelRef that |
1194 // is larger than the limit of the discardable memory pool. | 1209 // is larger than the limit of the discardable memory pool. |
1195 SkAutoLockPixels alp(bitmap); | 1210 SkAutoLockPixels alp(bitmap); |
1211 | |
1212 const SkPaint* paint = &origPaint; | |
1213 SkPaint tempPaint; | |
1214 if (origPaint.isAntiAlias() && !fRenderTarget->isUnifiedMultisampled()) { | |
1215 // Drop antialiasing to avoid seams at tile boundaries. | |
1216 tempPaint = origPaint; | |
1217 tempPaint.setAntiAlias(false); | |
1218 paint = &tempPaint; | |
1219 } | |
1196 SkRect clippedSrcRect = SkRect::Make(clippedSrcIRect); | 1220 SkRect clippedSrcRect = SkRect::Make(clippedSrcIRect); |
1197 | 1221 |
1198 int nx = bitmap.width() / tileSize; | 1222 int nx = bitmap.width() / tileSize; |
1199 int ny = bitmap.height() / tileSize; | 1223 int ny = bitmap.height() / tileSize; |
1200 for (int x = 0; x <= nx; x++) { | 1224 for (int x = 0; x <= nx; x++) { |
1201 for (int y = 0; y <= ny; y++) { | 1225 for (int y = 0; y <= ny; y++) { |
1202 SkRect tileR; | 1226 SkRect tileR; |
1203 tileR.set(SkIntToScalar(x * tileSize), | 1227 tileR.set(SkIntToScalar(x * tileSize), |
1204 SkIntToScalar(y * tileSize), | 1228 SkIntToScalar(y * tileSize), |
1205 SkIntToScalar((x + 1) * tileSize), | 1229 SkIntToScalar((x + 1) * tileSize), |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1247 tileR.offset(-offset.fX, -offset.fY); | 1271 tileR.offset(-offset.fX, -offset.fY); |
1248 GrTextureParams paramsTemp = params; | 1272 GrTextureParams paramsTemp = params; |
1249 bool needsTextureDomain = needs_texture_domain( | 1273 bool needsTextureDomain = needs_texture_domain( |
1250 bitmap, srcRect, params Temp, | 1274 bitmap, srcRect, params Temp, |
1251 viewM, bicubic, | 1275 viewM, bicubic, |
1252 fRenderTarget->isUnifie dMultisampled()); | 1276 fRenderTarget->isUnifie dMultisampled()); |
1253 this->internalDrawBitmap(tmpB, | 1277 this->internalDrawBitmap(tmpB, |
1254 viewM, | 1278 viewM, |
1255 tileR, | 1279 tileR, |
1256 paramsTemp, | 1280 paramsTemp, |
1257 paint, | 1281 *paint, |
1258 constraint, | 1282 constraint, |
1259 bicubic, | 1283 bicubic, |
1260 needsTextureDomain); | 1284 needsTextureDomain); |
1261 } | 1285 } |
1262 } | 1286 } |
1263 } | 1287 } |
1264 } | 1288 } |
1265 | 1289 |
1266 | 1290 |
1267 /* | 1291 /* |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1475 SkIntToScalar(h)), | 1499 SkIntToScalar(h)), |
1476 SkRect::MakeXYWH(0, | 1500 SkRect::MakeXYWH(0, |
1477 0, | 1501 0, |
1478 SK_Scalar1 * w / texture->widt h(), | 1502 SK_Scalar1 * w / texture->widt h(), |
1479 SK_Scalar1 * h / texture->heig ht())); | 1503 SK_Scalar1 * h / texture->heig ht())); |
1480 } | 1504 } |
1481 | 1505 |
1482 void SkGpuDevice::drawBitmapRect(const SkDraw& origDraw, const SkBitmap& bitmap, | 1506 void SkGpuDevice::drawBitmapRect(const SkDraw& origDraw, const SkBitmap& bitmap, |
1483 const SkRect* src, const SkRect& dst, | 1507 const SkRect* src, const SkRect& dst, |
1484 const SkPaint& paint, SkCanvas::SrcRectConstrai nt constraint) { | 1508 const SkPaint& paint, SkCanvas::SrcRectConstrai nt constraint) { |
1509 SkBitmap bm; | |
1510 if (GrTexture* tex = bitmap.getTexture()) { | |
1511 CHECK_SHOULD_DRAW(origDraw); | |
1512 // Will hold the src dst rect after clipping against the image bounds. | |
1513 SkRect clippedSrcRect; | |
1514 SkRect clippedDstRect; | |
1515 SkIRect contentArea = SkIRect::MakeWH(bitmap.width(), bitmap.height()); | |
1516 bool alphaBitmap = GrPixelConfigIsAlphaOnly(tex->config()); | |
1517 if (src) { | |
1518 SkRect bmpSrcBounds = SkRect::MakeIWH(bitmap.width(), bitmap.height( )); | |
1519 if (!bmpSrcBounds.contains(*src)) { | |
1520 clippedSrcRect = *src; | |
1521 if (!clippedSrcRect.intersect(bmpSrcBounds)) { | |
1522 return; | |
1523 } | |
1524 SkMatrix srcToDstMatrix; | |
1525 srcToDstMatrix.setRectToRect(*src, dst, SkMatrix::kFill_ScaleToF it); | |
1526 srcToDstMatrix.mapRect(&clippedDstRect, clippedSrcRect); | |
1527 // Since went through the trouble to compute the local matrix, c all this version and | |
1528 // return. | |
1529 this->drawTextureRectPrecomputedLocalMatrix( | |
1530 &GrBitmapTextureAdjuster(&bitmap), alphaBitmap, clippedSrcRe ct, clippedDstRect, | |
1531 *origDraw.fMatrix, srcToDstMatrix, fClip, paint, constraint) ; | |
1532 return; | |
1533 } else { | |
1534 clippedSrcRect = *src; | |
1535 clippedDstRect = dst; | |
1536 } | |
1537 } else { | |
1538 clippedSrcRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()), | |
1539 SkIntToScalar(bitmap.height())); | |
1540 } | |
1541 this->drawTextureRect(&GrBitmapTextureAdjuster(&bitmap), alphaBitmap, cl ippedSrcRect, | |
1542 clippedDstRect, *origDraw.fMatrix, fClip, paint, c onstraint); | |
1543 return; | |
1544 } | |
1545 | |
1485 SkMatrix matrix; | 1546 SkMatrix matrix; |
1486 SkRect bitmapBounds, tmpSrc; | 1547 SkRect bitmapBounds, tmpSrc; |
1487 | 1548 |
1488 bitmapBounds.set(0, 0, | 1549 bitmapBounds.set(0, 0, |
1489 SkIntToScalar(bitmap.width()), | 1550 SkIntToScalar(bitmap.width()), |
1490 SkIntToScalar(bitmap.height())); | 1551 SkIntToScalar(bitmap.height())); |
1491 | 1552 |
1492 // Compute matrix from the two rectangles | 1553 // Compute matrix from the two rectangles |
1493 if (src) { | 1554 if (src) { |
1494 tmpSrc = *src; | 1555 tmpSrc = *src; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1636 return true; | 1697 return true; |
1637 } else { | 1698 } else { |
1638 return as_IB(image)->getROPixels(bm); | 1699 return as_IB(image)->getROPixels(bm); |
1639 } | 1700 } |
1640 } | 1701 } |
1641 | 1702 |
1642 void SkGpuDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x , SkScalar y, | 1703 void SkGpuDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x , SkScalar y, |
1643 const SkPaint& paint) { | 1704 const SkPaint& paint) { |
1644 SkBitmap bm; | 1705 SkBitmap bm; |
1645 if (GrTexture* tex = as_IB(image)->peekTexture()) { | 1706 if (GrTexture* tex = as_IB(image)->peekTexture()) { |
1646 GrWrapTextureInBitmap(tex, image->width(), image->height(), image->isOpa que(), &bm); | 1707 CHECK_SHOULD_DRAW(draw); |
1708 SkRect srcRect = SkRect::MakeIWH(image->width(), image->height()); | |
1709 SkRect dstRect = srcRect; | |
1710 dstRect.offset(x, y); | |
1711 bool alphaBitmap = GrPixelConfigIsAlphaOnly(tex->config()); | |
1712 // Since the src rect is the image dimensions, no need to enforce a blee d constraint. | |
1713 static const SkCanvas::SrcRectConstraint kSrcRectConstraint = | |
1714 SkCanvas::kFast_SrcRectConstraint; | |
1715 this->drawTextureRect(&GrImageTextureAdjuster(as_IB(image)), alphaBitmap , srcRect, dstRect, | |
1716 *draw.fMatrix, fClip, paint, kSrcRectConstraint); | |
1717 return; | |
1647 } else { | 1718 } else { |
1648 if (this->shouldTileImage(image, nullptr, SkCanvas::kFast_SrcRectConstra int, | 1719 if (this->shouldTileImage(image, nullptr, SkCanvas::kFast_SrcRectConstra int, |
1649 paint.getFilterQuality(), *draw.fMatrix)) { | 1720 paint.getFilterQuality(), *draw.fMatrix)) { |
1650 // only support tiling as bitmap at the moment, so force raster-vers ion | 1721 // only support tiling as bitmap at the moment, so force raster-vers ion |
1651 if (!as_IB(image)->getROPixels(&bm)) { | 1722 if (!as_IB(image)->getROPixels(&bm)) { |
1652 return; | 1723 return; |
1653 } | 1724 } |
1654 } else { | 1725 } else { |
1655 if (!wrap_as_bm(this->context(), image, &bm)) { | 1726 if (!wrap_as_bm(this->context(), image, &bm)) { |
1656 return; | 1727 return; |
1657 } | 1728 } |
1658 } | 1729 } |
1659 } | 1730 } |
1660 this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint); | 1731 this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint); |
1661 } | 1732 } |
1662 | 1733 |
1663 void SkGpuDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src, | 1734 void SkGpuDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src, |
1664 const SkRect& dst, const SkPaint& paint, | 1735 const SkRect& dst, const SkPaint& paint, |
1665 SkCanvas::SrcRectConstraint constraint) { | 1736 SkCanvas::SrcRectConstraint constraint) { |
1666 SkBitmap bm; | 1737 SkBitmap bm; |
1667 if (GrTexture* tex = as_IB(image)->peekTexture()) { | 1738 if (GrTexture* tex = as_IB(image)->peekTexture()) { |
1668 GrWrapTextureInBitmap(tex, image->width(), image->height(), image->isOpa que(), &bm); | 1739 CHECK_SHOULD_DRAW(draw); |
1669 } else { | 1740 // Will hold the src dst rect after clipping against the image bounds. |
1670 SkMatrix viewMatrix = *draw.fMatrix; | 1741 SkRect clippedSrcRect; |
1671 viewMatrix.preScale(dst.width() / (src ? src->width() : image->width()), | 1742 SkRect clippedDstRect; |
1672 dst.height() / (src ? src->height() : image->height( ))); | 1743 bool alphaBitmap = GrPixelConfigIsAlphaOnly(tex->config()); |
1673 | 1744 if (src) { |
1674 if (this->shouldTileImage(image, src, constraint, paint.getFilterQuality (), viewMatrix)) { | 1745 SkRect imgSrcBounds = SkRect::MakeIWH(image->width(), image->height( )); |
1675 // only support tiling as bitmap at the moment, so force raster-vers ion | 1746 if (!imgSrcBounds.contains(*src)) { |
1676 if (!as_IB(image)->getROPixels(&bm)) { | 1747 clippedSrcRect = *src; |
1748 if (!clippedSrcRect.intersect(imgSrcBounds)) { | |
1749 return; | |
1750 } | |
1751 SkMatrix srcToDstMatrix; | |
1752 srcToDstMatrix.setRectToRect(*src, dst, SkMatrix::kFill_ScaleToF it); | |
1753 srcToDstMatrix.mapRect(&clippedDstRect, clippedSrcRect); | |
1754 // Since went through the trouble to compute the local matrix, c all this version and | |
1755 // return. | |
1756 this->drawTextureRectPrecomputedLocalMatrix( | |
1757 &GrImageTextureAdjuster(as_IB(image)), alphaBitmap, clippedS rcRect, | |
1758 clippedDstRect, *draw.fMatrix, srcToDstMatrix, fClip, paint, constraint); | |
joshualitt
2015/11/05 19:53:12
can this be made a helper? or do we want it to be
bsalomon
2015/11/05 20:10:37
I'm not sure I understand what you're asking/sugge
bsalomon
2015/11/06 15:24:26
Done.
| |
1677 return; | 1759 return; |
1760 } else { | |
1761 clippedSrcRect = *src; | |
1762 clippedDstRect = dst; | |
1678 } | 1763 } |
1679 } else { | 1764 } else { |
1680 if (!wrap_as_bm(this->context(), image, &bm)) { | 1765 clippedSrcRect = SkRect::MakeWH(SkIntToScalar(image->width()), |
1681 return; | 1766 SkIntToScalar(image->height())); |
1682 } | 1767 clippedDstRect = dst; |
1768 } | |
1769 this->drawTextureRect(&GrImageTextureAdjuster(as_IB(image)), alphaBitmap , clippedSrcRect, | |
1770 clippedDstRect, *draw.fMatrix, fClip, paint, const raint); | |
1771 return; | |
1772 } | |
1773 SkMatrix viewMatrix = *draw.fMatrix; | |
1774 viewMatrix.preScale(dst.width() / (src ? src->width() : image->width()), | |
1775 dst.height() / (src ? src->height() : image->height())); | |
1776 if (this->shouldTileImage(image, src, constraint, paint.getFilterQuality(), viewMatrix)) { | |
1777 // only support tiling as bitmap at the moment, so force raster-version | |
1778 if (!as_IB(image)->getROPixels(&bm)) { | |
1779 return; | |
1780 } | |
1781 } else { | |
1782 if (!wrap_as_bm(this->context(), image, &bm)) { | |
1783 return; | |
1683 } | 1784 } |
1684 } | 1785 } |
1685 this->drawBitmapRect(draw, bm, src, dst, paint, constraint); | 1786 this->drawBitmapRect(draw, bm, src, dst, paint, constraint); |
1686 } | 1787 } |
1687 | 1788 |
1688 /////////////////////////////////////////////////////////////////////////////// | 1789 /////////////////////////////////////////////////////////////////////////////// |
1689 | 1790 |
1690 // must be in SkCanvas::VertexMode order | 1791 // must be in SkCanvas::VertexMode order |
1691 static const GrPrimitiveType gVertexMode2PrimitiveType[] = { | 1792 static const GrPrimitiveType gVertexMode2PrimitiveType[] = { |
1692 kTriangles_GrPrimitiveType, | 1793 kTriangles_GrPrimitiveType, |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2025 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); | 2126 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); |
2026 } | 2127 } |
2027 | 2128 |
2028 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { | 2129 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { |
2029 // We always return a transient cache, so it is freed after each | 2130 // We always return a transient cache, so it is freed after each |
2030 // filter traversal. | 2131 // filter traversal. |
2031 return SkGpuDevice::NewImageFilterCache(); | 2132 return SkGpuDevice::NewImageFilterCache(); |
2032 } | 2133 } |
2033 | 2134 |
2034 #endif | 2135 #endif |
OLD | NEW |