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 "effects/GrBicubicEffect.h" | 10 #include "effects/GrBicubicEffect.h" |
| (...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 712 | 712 |
| 713 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, | 713 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, |
| 714 const SkPaint& paint, const SkMatrix* prePathMatrix, | 714 const SkPaint& paint, const SkMatrix* prePathMatrix, |
| 715 bool pathIsMutable) { | 715 bool pathIsMutable) { |
| 716 CHECK_FOR_ANNOTATION(paint); | 716 CHECK_FOR_ANNOTATION(paint); |
| 717 CHECK_SHOULD_DRAW(draw); | 717 CHECK_SHOULD_DRAW(draw); |
| 718 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext); | 718 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext); |
| 719 | 719 |
| 720 SkASSERT(!pathIsMutable || origSrcPath.isVolatile()); | 720 SkASSERT(!pathIsMutable || origSrcPath.isVolatile()); |
| 721 | 721 |
| 722 GrPaint grPaint; | 722 GrStrokeInfo strokeInfo(paint); |
| 723 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint) ; | |
| 724 | 723 |
| 725 // If we have a prematrix, apply it to the path, optimizing for the case | 724 // If we have a prematrix, apply it to the path, optimizing for the case |
| 726 // where the original path can in fact be modified in place (even though | 725 // where the original path can in fact be modified in place (even though |
| 727 // its parameter type is const). | 726 // its parameter type is const). |
| 728 SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath); | 727 SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath); |
| 729 SkTLazy<SkPath> tmpPath; | 728 SkTLazy<SkPath> tmpPath; |
| 730 SkTLazy<SkPath> effectPath; | 729 SkTLazy<SkPath> effectPath; |
| 730 SkPathEffect* pathEffect = paint.getPathEffect(); | |
| 731 | |
| 732 SkMatrix viewMatrix = *draw.fMatrix; | |
| 731 | 733 |
| 732 if (prePathMatrix) { | 734 if (prePathMatrix) { |
| 733 SkPath* result = pathPtr; | 735 // stroking and path effects are supposed to be applied *after* the preP athMatrix. |
| 736 // The pre-path-matrix also should not affect shadeing. | |
| 737 if (NULL == pathEffect && NULL == paint.getShader() && | |
| 738 (strokeInfo.getStrokeRec().isFillStyle() || | |
| 739 strokeInfo.getStrokeRec().isHairlineStyle())) { | |
| 740 viewMatrix.preConcat(*prePathMatrix); | |
| 741 } else { | |
| 742 SkPath* result = pathPtr; | |
| 734 | 743 |
| 735 if (!pathIsMutable) { | 744 if (!pathIsMutable) { |
| 736 result = tmpPath.init(); | 745 result = tmpPath.init(); |
| 737 result->setIsVolatile(true); | 746 result->setIsVolatile(true); |
| 738 pathIsMutable = true; | 747 pathIsMutable = true; |
| 748 } | |
| 749 // should I push prePathMatrix on our MV stack temporarily, instead | |
| 750 // of applying it here? See SkDraw.cpp | |
| 751 pathPtr->transform(*prePathMatrix, result); | |
| 752 pathPtr = result; | |
| 739 } | 753 } |
| 740 // should I push prePathMatrix on our MV stack temporarily, instead | |
| 741 // of applying it here? See SkDraw.cpp | |
| 742 pathPtr->transform(*prePathMatrix, result); | |
| 743 pathPtr = result; | |
| 744 } | 754 } |
| 745 // at this point we're done with prePathMatrix | 755 // at this point we're done with prePathMatrix |
| 746 SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;) | 756 SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;) |
| 747 | 757 |
| 748 GrStrokeInfo strokeInfo(paint); | 758 GrPaint grPaint; |
| 749 SkPathEffect* pathEffect = paint.getPathEffect(); | 759 SkPaint2GrPaintShader(this->context(), paint, viewMatrix, true, &grPaint); |
| 760 | |
| 750 const SkRect* cullRect = NULL; // TODO: what is our bounds? | 761 const SkRect* cullRect = NULL; // TODO: what is our bounds? |
| 751 SkStrokeRec* strokePtr = strokeInfo.getStrokeRecPtr(); | 762 SkStrokeRec* strokePtr = strokeInfo.getStrokeRecPtr(); |
| 752 if (pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr, stroke Ptr, | 763 if (pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr, stroke Ptr, |
| 753 cullRect)) { | 764 cullRect)) { |
| 754 pathPtr = effectPath.get(); | 765 pathPtr = effectPath.get(); |
| 755 pathIsMutable = true; | 766 pathIsMutable = true; |
| 756 strokeInfo.removeDash(); | 767 strokeInfo.removeDash(); |
| 757 } | 768 } |
| 758 | 769 |
| 759 const SkStrokeRec& stroke = strokeInfo.getStrokeRec(); | 770 const SkStrokeRec& stroke = strokeInfo.getStrokeRec(); |
| 760 if (paint.getMaskFilter()) { | 771 if (paint.getMaskFilter()) { |
| 761 if (!stroke.isHairlineStyle()) { | 772 if (!stroke.isHairlineStyle()) { |
| 762 SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init(); | 773 SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init(); |
| 763 if (stroke.applyToPath(strokedPath, *pathPtr)) { | 774 if (stroke.applyToPath(strokedPath, *pathPtr)) { |
| 764 pathPtr = strokedPath; | 775 pathPtr = strokedPath; |
| 765 pathIsMutable = true; | 776 pathIsMutable = true; |
| 766 strokeInfo.setFillStyle(); | 777 strokeInfo.setFillStyle(); |
| 767 } | 778 } |
| 768 } | 779 } |
| 769 | 780 |
| 770 // avoid possibly allocating a new path in transform if we can | 781 // avoid possibly allocating a new path in transform if we can |
| 771 SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init(); | 782 SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init(); |
| 772 if (!pathIsMutable) { | 783 if (!pathIsMutable) { |
| 773 devPathPtr->setIsVolatile(true); | 784 devPathPtr->setIsVolatile(true); |
| 774 } | 785 } |
| 775 | 786 |
| 776 // transform the path into device space | 787 // transform the path into device space |
| 777 pathPtr->transform(*draw.fMatrix, devPathPtr); | 788 pathPtr->transform(viewMatrix, devPathPtr); |
| 778 | 789 |
| 779 SkRect maskRect; | 790 SkRect maskRect; |
| 780 if (paint.getMaskFilter()->canFilterMaskGPU(devPathPtr->getBounds(), | 791 if (paint.getMaskFilter()->canFilterMaskGPU(devPathPtr->getBounds(), |
| 781 draw.fClip->getBounds(), | 792 draw.fClip->getBounds(), |
| 782 *draw.fMatrix, | 793 viewMatrix, |
| 783 &maskRect)) { | 794 &maskRect)) { |
| 784 // The context's matrix may change while creating the mask, so save the CTM here to | |
|
bsalomon
2015/01/29 15:59:51
The context no longer maintains a current matrix.
| |
| 785 // pass to filterMaskGPU. | |
| 786 const SkMatrix ctm = *draw.fMatrix; | |
| 787 | |
| 788 SkIRect finalIRect; | 795 SkIRect finalIRect; |
| 789 maskRect.roundOut(&finalIRect); | 796 maskRect.roundOut(&finalIRect); |
| 790 if (draw.fClip->quickReject(finalIRect)) { | 797 if (draw.fClip->quickReject(finalIRect)) { |
| 791 // clipped out | 798 // clipped out |
| 792 return; | 799 return; |
| 793 } | 800 } |
| 794 | 801 |
| 795 if (paint.getMaskFilter()->directFilterMaskGPU(fContext, &grPaint, * draw.fMatrix, | 802 if (paint.getMaskFilter()->directFilterMaskGPU(fContext, &grPaint, v iewMatrix, |
| 796 stroke, *devPathPtr)) { | 803 stroke, *devPathPtr)) { |
| 797 // the mask filter was able to draw itself directly, so there's nothing | 804 // the mask filter was able to draw itself directly, so there's nothing |
| 798 // left to do. | 805 // left to do. |
| 799 return; | 806 return; |
| 800 } | 807 } |
| 801 | 808 |
| 802 | 809 |
| 803 SkAutoTUnref<GrTexture> mask(create_mask_GPU(fContext, maskRect, *de vPathPtr, | 810 SkAutoTUnref<GrTexture> mask(create_mask_GPU(fContext, maskRect, *de vPathPtr, |
| 804 strokeInfo, grPaint.isA ntiAlias(), | 811 strokeInfo, grPaint.isA ntiAlias(), |
| 805 fRenderTarget->numSampl es())); | 812 fRenderTarget->numSampl es())); |
| 806 if (mask) { | 813 if (mask) { |
| 807 GrTexture* filtered; | 814 GrTexture* filtered; |
| 808 | 815 |
| 809 if (paint.getMaskFilter()->filterMaskGPU(mask, ctm, maskRect, &f iltered, true)) { | 816 if (paint.getMaskFilter()->filterMaskGPU(mask, viewMatrix, maskR ect, &filtered, true)) { |
| 810 // filterMaskGPU gives us ownership of a ref to the result | 817 // filterMaskGPU gives us ownership of a ref to the result |
| 811 SkAutoTUnref<GrTexture> atu(filtered); | 818 SkAutoTUnref<GrTexture> atu(filtered); |
| 812 if (draw_mask(fContext, *draw.fMatrix, maskRect, &grPaint, f iltered)) { | 819 if (draw_mask(fContext, viewMatrix, maskRect, &grPaint, filt ered)) { |
| 813 // This path is completely drawn | 820 // This path is completely drawn |
| 814 return; | 821 return; |
| 815 } | 822 } |
| 816 } | 823 } |
| 817 } | 824 } |
| 818 } | 825 } |
| 819 | 826 |
| 820 // draw the mask on the CPU - this is a fallthrough path in case the | 827 // draw the mask on the CPU - this is a fallthrough path in case the |
| 821 // GPU path fails | 828 // GPU path fails |
| 822 SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style : | 829 SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style : |
| 823 SkPaint::kFill_Style; | 830 SkPaint::kFill_Style; |
| 824 draw_with_mask_filter(fContext, *draw.fMatrix, *devPathPtr, paint.getMas kFilter(), | 831 draw_with_mask_filter(fContext, viewMatrix, *devPathPtr, paint.getMaskFi lter(), |
| 825 *draw.fClip, &grPaint, style); | 832 *draw.fClip, &grPaint, style); |
| 826 return; | 833 return; |
| 827 } | 834 } |
| 828 | 835 |
| 829 fContext->drawPath(grPaint, *draw.fMatrix, *pathPtr, strokeInfo); | 836 fContext->drawPath(grPaint, viewMatrix, *pathPtr, strokeInfo); |
| 830 } | 837 } |
| 831 | 838 |
| 832 static const int kBmpSmallTileSize = 1 << 10; | 839 static const int kBmpSmallTileSize = 1 << 10; |
| 833 | 840 |
| 834 static inline int get_tile_count(const SkIRect& srcRect, int tileSize) { | 841 static inline int get_tile_count(const SkIRect& srcRect, int tileSize) { |
| 835 int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1; | 842 int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1; |
| 836 int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1; | 843 int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1; |
| 837 return tilesX * tilesY; | 844 return tilesX * tilesY; |
| 838 } | 845 } |
| 839 | 846 |
| (...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1903 #endif | 1910 #endif |
| 1904 } | 1911 } |
| 1905 | 1912 |
| 1906 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { | 1913 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { |
| 1907 // We always return a transient cache, so it is freed after each | 1914 // We always return a transient cache, so it is freed after each |
| 1908 // filter traversal. | 1915 // filter traversal. |
| 1909 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); | 1916 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); |
| 1910 } | 1917 } |
| 1911 | 1918 |
| 1912 #endif | 1919 #endif |
| OLD | NEW |