Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Side by Side Diff: src/gpu/SkGpuDevice.cpp

Issue 1157773003: Move SkGpuDevice::internalDrawPath to GrBlurUtils::drawPathWithMaskFilter (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: more cleanup Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/SkGpuDevice.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "GrContext.h" 11 #include "GrContext.h"
11 #include "GrDrawContext.h" 12 #include "GrDrawContext.h"
12 #include "GrGpu.h" 13 #include "GrGpu.h"
13 #include "GrGpuResourcePriv.h" 14 #include "GrGpuResourcePriv.h"
14 #include "GrLayerHoister.h" 15 #include "GrLayerHoister.h"
15 #include "GrRecordReplaceDraw.h" 16 #include "GrRecordReplaceDraw.h"
16 #include "GrStrokeInfo.h" 17 #include "GrStrokeInfo.h"
17 #include "GrTextContext.h" 18 #include "GrTextContext.h"
18 #include "GrTracing.h" 19 #include "GrTracing.h"
19 #include "SkCanvasPriv.h" 20 #include "SkCanvasPriv.h"
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 fNeedClear = flags & kNeedClear_Flag; 161 fNeedClear = flags & kNeedClear_Flag;
161 162
162 fRenderTarget = SkRef(rt); 163 fRenderTarget = SkRef(rt);
163 164
164 SkImageInfo info = rt->surfacePriv().info().makeWH(width, height); 165 SkImageInfo info = rt->surfacePriv().info().makeWH(width, height);
165 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt)); 166 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt));
166 fLegacyBitmap.setInfo(info); 167 fLegacyBitmap.setInfo(info);
167 fLegacyBitmap.setPixelRef(pr)->unref(); 168 fLegacyBitmap.setPixelRef(pr)->unref();
168 169
169 bool useDFT = fSurfaceProps.isUseDistanceFieldFonts(); 170 bool useDFT = fSurfaceProps.isUseDistanceFieldFonts();
170 fTextContext = fContext->createTextContext(fRenderTarget, this, this->getLea kyProperties(), 171 fTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProp erties(), useDFT);
171 useDFT);
172 fDrawContext.reset(SkRef(fContext->drawContext())); 172 fDrawContext.reset(SkRef(fContext->drawContext()));
173 } 173 }
174 174
175 GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::B udgeted budgeted, 175 GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::B udgeted budgeted,
176 const SkImageInfo& origInfo, int sampleCount) { 176 const SkImageInfo& origInfo, int sampleCount) {
177 if (kUnknown_SkColorType == origInfo.colorType() || 177 if (kUnknown_SkColorType == origInfo.colorType() ||
178 origInfo.width() < 0 || origInfo.height() < 0) { 178 origInfo.width() < 0 || origInfo.height() < 0) {
179 return NULL; 179 return NULL;
180 } 180 }
181 181
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 return; 619 return;
620 } 620 }
621 621
622 fDrawContext->drawOval(fRenderTarget, fClip, grPaint, *draw.fMatrix, oval, s trokeInfo); 622 fDrawContext->drawOval(fRenderTarget, fClip, grPaint, *draw.fMatrix, oval, s trokeInfo);
623 } 623 }
624 624
625 #include "SkMaskFilter.h" 625 #include "SkMaskFilter.h"
626 626
627 /////////////////////////////////////////////////////////////////////////////// 627 ///////////////////////////////////////////////////////////////////////////////
628 628
629 // helpers for applying mask filters 629 static SkBitmap wrap_texture(GrTexture* texture, int width, int height) {
630 namespace {
631
632 // Draw a mask using the supplied paint. Since the coverage/geometry
633 // is already burnt into the mask this boils down to a rect draw.
634 // Return true if the mask was successfully drawn.
635 bool draw_mask(GrDrawContext* drawContext,
636 GrRenderTarget* rt,
637 const GrClip& clip,
638 const SkMatrix& viewMatrix,
639 const SkRect& maskRect,
640 GrPaint* grp,
641 GrTexture* mask) {
642 SkMatrix matrix;
643 matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop);
644 matrix.postIDiv(mask->width(), mask->height());
645
646 grp->addCoverageProcessor(GrSimpleTextureEffect::Create(mask, matrix,
647 kDevice_GrCoordSet)) ->unref();
648
649 SkMatrix inverse;
650 if (!viewMatrix.invert(&inverse)) {
651 return false;
652 }
653 drawContext->drawNonAARectWithLocalMatrix(rt, clip, *grp, SkMatrix::I(), mas kRect, inverse);
654 return true;
655 }
656
657 static bool clip_bounds_quick_reject(const SkIRect& clipBounds, const SkIRect& r ect) {
658 return clipBounds.isEmpty() || rect.isEmpty() || !SkIRect::Intersects(clipBo unds, rect);
659 }
660
661 bool draw_with_mask_filter(GrDrawContext* drawContext,
662 GrTextureProvider* textureProvider,
663 GrRenderTarget* rt,
664 const GrClip& clipData,
665 const SkMatrix& viewMatrix,
666 const SkPath& devPath,
667 SkMaskFilter* filter,
668 const SkIRect& clipBounds,
669 GrPaint* grp,
670 SkPaint::Style style) {
671 SkMask srcM, dstM;
672
673 if (!SkDraw::DrawToMask(devPath, &clipBounds, filter, &viewMatrix, &srcM,
674 SkMask::kComputeBoundsAndRenderImage_CreateMode, sty le)) {
675 return false;
676 }
677 SkAutoMaskFreeImage autoSrc(srcM.fImage);
678
679 if (!filter->filterMask(&dstM, srcM, viewMatrix, NULL)) {
680 return false;
681 }
682 // this will free-up dstM when we're done (allocated in filterMask())
683 SkAutoMaskFreeImage autoDst(dstM.fImage);
684
685 if (clip_bounds_quick_reject(clipBounds, dstM.fBounds)) {
686 return false;
687 }
688
689 // we now have a device-aligned 8bit mask in dstM, ready to be drawn using
690 // the current clip (and identity matrix) and GrPaint settings
691 GrSurfaceDesc desc;
692 desc.fWidth = dstM.fBounds.width();
693 desc.fHeight = dstM.fBounds.height();
694 desc.fConfig = kAlpha_8_GrPixelConfig;
695
696 SkAutoTUnref<GrTexture> texture(textureProvider->refScratchTexture(
697 desc, GrTextureProvider::kApprox_ScratchTexMatch));
698 if (!texture) {
699 return false;
700 }
701 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
702 dstM.fImage, dstM.fRowBytes);
703
704 SkRect maskRect = SkRect::Make(dstM.fBounds);
705
706 return draw_mask(drawContext, rt, clipData, viewMatrix, maskRect, grp, textu re);
707 }
708
709 // Create a mask of 'devPath' and place the result in 'mask'.
710 GrTexture* create_mask_GPU(GrContext* context,
711 const SkRect& maskRect,
712 const SkPath& devPath,
713 const GrStrokeInfo& strokeInfo,
714 bool doAA,
715 int sampleCnt) {
716 GrSurfaceDesc desc;
717 desc.fFlags = kRenderTarget_GrSurfaceFlag;
718 desc.fWidth = SkScalarCeilToInt(maskRect.width());
719 desc.fHeight = SkScalarCeilToInt(maskRect.height());
720 desc.fSampleCnt = doAA ? sampleCnt : 0;
721 // We actually only need A8, but it often isn't supported as a
722 // render target so default to RGBA_8888
723 desc.fConfig = kRGBA_8888_GrPixelConfig;
724
725 if (context->isConfigRenderable(kAlpha_8_GrPixelConfig,
726 desc.fSampleCnt > 0)) {
727 desc.fConfig = kAlpha_8_GrPixelConfig;
728 }
729
730 GrTexture* mask = context->textureProvider()->refScratchTexture(
731 desc, GrTextureProvider::kApprox_ScratchTexMatch);
732 if (NULL == mask) {
733 return NULL;
734 }
735
736 SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height());
737
738 GrDrawContext* drawContext = context->drawContext();
739 if (!drawContext) {
740 return NULL;
741 }
742
743 drawContext->clear(mask->asRenderTarget(), NULL, 0x0, true);
744
745 GrPaint tempPaint;
746 tempPaint.setAntiAlias(doAA);
747 tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
748
749 // setup new clip
750 GrClip clip(clipRect);
751
752 // Draw the mask into maskTexture with the path's top-left at the origin usi ng tempPaint.
753 SkMatrix translate;
754 translate.setTranslate(-maskRect.fLeft, -maskRect.fTop);
755 drawContext->drawPath(mask->asRenderTarget(), clip, tempPaint, translate, de vPath, strokeInfo);
756 return mask;
757 }
758
759 SkBitmap wrap_texture(GrTexture* texture, int width, int height) {
760 SkBitmap result; 630 SkBitmap result;
761 result.setInfo(SkImageInfo::MakeN32Premul(width, height)); 631 result.setInfo(SkImageInfo::MakeN32Premul(width, height));
762 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unre f(); 632 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unre f();
763 return result; 633 return result;
764 } 634 }
765 635
766 };
767
768 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, 636 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
769 const SkPaint& paint, const SkMatrix* prePathMatrix, 637 const SkPaint& paint, const SkMatrix* prePathMatrix,
770 bool pathIsMutable) { 638 bool pathIsMutable) {
771 CHECK_FOR_ANNOTATION(paint); 639 CHECK_FOR_ANNOTATION(paint);
772 CHECK_SHOULD_DRAW(draw); 640 CHECK_SHOULD_DRAW(draw);
773 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext); 641 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext);
774 642
775 return this->internalDrawPath(origSrcPath, paint, *draw.fMatrix, prePathMatr ix, 643 GrBlurUtils::drawPathWithMaskFilter(fContext, fDrawContext, fRenderTarget,
776 draw.fClip->getBounds(), pathIsMutable); 644 fClip, origSrcPath, paint,
777 } 645 *draw.fMatrix, prePathMatrix,
778 646 draw.fClip->getBounds(), pathIsMutable);
779 void SkGpuDevice::internalDrawPath(const SkPath& origSrcPath, const SkPaint& pai nt,
780 const SkMatrix& origViewMatrix, const SkMatri x* prePathMatrix,
781 const SkIRect& clipBounds, bool pathIsMutable ) {
782 SkASSERT(!pathIsMutable || origSrcPath.isVolatile());
783
784 GrStrokeInfo strokeInfo(paint);
785
786 // If we have a prematrix, apply it to the path, optimizing for the case
787 // where the original path can in fact be modified in place (even though
788 // its parameter type is const).
789 SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath);
790 SkTLazy<SkPath> tmpPath;
791 SkTLazy<SkPath> effectPath;
792 SkPathEffect* pathEffect = paint.getPathEffect();
793
794 SkMatrix viewMatrix = origViewMatrix;
795
796 if (prePathMatrix) {
797 // stroking, path effects, and blurs are supposed to be applied *after* the prePathMatrix.
798 // The pre-path-matrix also should not affect shading.
799 if (NULL == paint.getMaskFilter() && NULL == pathEffect && NULL == paint .getShader() &&
800 (strokeInfo.isFillStyle() || strokeInfo.isHairlineStyle())) {
801 viewMatrix.preConcat(*prePathMatrix);
802 } else {
803 SkPath* result = pathPtr;
804
805 if (!pathIsMutable) {
806 result = tmpPath.init();
807 result->setIsVolatile(true);
808 pathIsMutable = true;
809 }
810 // should I push prePathMatrix on our MV stack temporarily, instead
811 // of applying it here? See SkDraw.cpp
812 pathPtr->transform(*prePathMatrix, result);
813 pathPtr = result;
814 }
815 }
816 // at this point we're done with prePathMatrix
817 SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
818
819 GrPaint grPaint;
820 if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, viewMatrix, true , &grPaint)) {
821 return;
822 }
823
824 const SkRect* cullRect = NULL; // TODO: what is our bounds?
825 if (!strokeInfo.isDashed() && pathEffect && pathEffect->filterPath(effectPat h.init(), *pathPtr,
826 &strokeIn fo, cullRect)) {
827 pathPtr = effectPath.get();
828 pathIsMutable = true;
829 }
830
831 if (paint.getMaskFilter()) {
832 if (!strokeInfo.isHairlineStyle()) {
833 SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init();
834 if (strokeInfo.isDashed()) {
835 if (pathEffect->filterPath(strokedPath, *pathPtr, &strokeInfo, c ullRect)) {
836 pathPtr = strokedPath;
837 pathIsMutable = true;
838 }
839 strokeInfo.removeDash();
840 }
841 if (strokeInfo.applyToPath(strokedPath, *pathPtr)) {
842 pathPtr = strokedPath;
843 pathIsMutable = true;
844 strokeInfo.setFillStyle();
845 }
846 }
847
848 // avoid possibly allocating a new path in transform if we can
849 SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init();
850 if (!pathIsMutable) {
851 devPathPtr->setIsVolatile(true);
852 }
853
854 // transform the path into device space
855 pathPtr->transform(viewMatrix, devPathPtr);
856
857 SkRect maskRect;
858 if (paint.getMaskFilter()->canFilterMaskGPU(devPathPtr->getBounds(),
859 clipBounds,
860 viewMatrix,
861 &maskRect)) {
862 SkIRect finalIRect;
863 maskRect.roundOut(&finalIRect);
864 if (clip_bounds_quick_reject(clipBounds, finalIRect)) {
865 // clipped out
866 return;
867 }
868
869 if (paint.getMaskFilter()->directFilterMaskGPU(fContext,
870 fRenderTarget,
871 &grPaint,
872 fClip,
873 viewMatrix,
874 strokeInfo,
875 *devPathPtr)) {
876 // the mask filter was able to draw itself directly, so there's nothing
877 // left to do.
878 return;
879 }
880
881
882 SkAutoTUnref<GrTexture> mask(create_mask_GPU(fContext,
883 maskRect,
884 *devPathPtr,
885 strokeInfo,
886 grPaint.isAntiAlias(),
887 fRenderTarget->numSampl es()));
888 if (mask) {
889 GrTexture* filtered;
890
891 if (paint.getMaskFilter()->filterMaskGPU(mask, viewMatrix, maskR ect, &filtered, true)) {
892 // filterMaskGPU gives us ownership of a ref to the result
893 SkAutoTUnref<GrTexture> atu(filtered);
894 if (draw_mask(fDrawContext,
895 fRenderTarget,
896 fClip,
897 viewMatrix,
898 maskRect,
899 &grPaint,
900 filtered)) {
901 // This path is completely drawn
902 return;
903 }
904 }
905 }
906 }
907
908 // draw the mask on the CPU - this is a fallthrough path in case the
909 // GPU path fails
910 SkPaint::Style style = strokeInfo.isHairlineStyle() ? SkPaint::kStroke_S tyle :
911 SkPaint::kFill_Sty le;
912 draw_with_mask_filter(fDrawContext, fContext->textureProvider(), fRender Target,
913 fClip, viewMatrix, *devPathPtr,
914 paint.getMaskFilter(), clipBounds, &grPaint, style );
915 return;
916 }
917
918 fDrawContext->drawPath(fRenderTarget, fClip, grPaint, viewMatrix, *pathPtr, strokeInfo);
919 } 647 }
920 648
921 static const int kBmpSmallTileSize = 1 << 10; 649 static const int kBmpSmallTileSize = 1 << 10;
922 650
923 static inline int get_tile_count(const SkIRect& srcRect, int tileSize) { 651 static inline int get_tile_count(const SkIRect& srcRect, int tileSize) {
924 int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1; 652 int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1;
925 int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1; 653 int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1;
926 return tilesX * tilesY; 654 return tilesX * tilesY;
927 } 655 }
928 656
(...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after
1924 draw.fClip->getBounds()); 1652 draw.fClip->getBounds());
1925 } 1653 }
1926 1654
1927 void SkGpuDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSca lar x, SkScalar y, 1655 void SkGpuDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSca lar x, SkScalar y,
1928 const SkPaint& paint, SkDrawFilter* drawFilter) { 1656 const SkPaint& paint, SkDrawFilter* drawFilter) {
1929 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawTextBlob", fContext); 1657 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawTextBlob", fContext);
1930 CHECK_SHOULD_DRAW(draw); 1658 CHECK_SHOULD_DRAW(draw);
1931 1659
1932 SkDEBUGCODE(this->validate();) 1660 SkDEBUGCODE(this->validate();)
1933 1661
1934 fTextContext->drawTextBlob(fRenderTarget, fClip, paint, *draw.fMatrix, blob, x, y, drawFilter, 1662 fTextContext->drawTextBlob(this, fRenderTarget, fClip, paint, *draw.fMatrix,
1935 draw.fClip->getBounds()); 1663 blob, x, y, drawFilter, draw.fClip->getBounds());
1936 } 1664 }
1937 1665
1938 /////////////////////////////////////////////////////////////////////////////// 1666 ///////////////////////////////////////////////////////////////////////////////
1939 1667
1940 bool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const { 1668 bool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const {
1941 if (paint.getShader() || 1669 if (paint.getShader() ||
1942 !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode) || 1670 !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode) ||
1943 paint.getMaskFilter() || 1671 paint.getMaskFilter() ||
1944 paint.getRasterizer() || 1672 paint.getRasterizer() ||
1945 paint.getColorFilter() || 1673 paint.getColorFilter() ||
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2064 #endif 1792 #endif
2065 } 1793 }
2066 1794
2067 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { 1795 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() {
2068 // We always return a transient cache, so it is freed after each 1796 // We always return a transient cache, so it is freed after each
2069 // filter traversal. 1797 // filter traversal.
2070 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); 1798 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize);
2071 } 1799 }
2072 1800
2073 #endif 1801 #endif
OLDNEW
« no previous file with comments | « src/gpu/SkGpuDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698