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 |