Chromium Code Reviews| 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 |