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

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: Clean up Created 5 years, 6 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
« src/gpu/GrAtlasTextContext.cpp ('K') | « 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 "GrContext.h" 10 #include "GrContext.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 fNeedClear = flags & kNeedClear_Flag; 160 fNeedClear = flags & kNeedClear_Flag;
161 161
162 fRenderTarget = SkRef(rt); 162 fRenderTarget = SkRef(rt);
163 163
164 SkImageInfo info = rt->surfacePriv().info().makeWH(width, height); 164 SkImageInfo info = rt->surfacePriv().info().makeWH(width, height);
165 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt)); 165 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt));
166 fLegacyBitmap.setInfo(info); 166 fLegacyBitmap.setInfo(info);
167 fLegacyBitmap.setPixelRef(pr)->unref(); 167 fLegacyBitmap.setPixelRef(pr)->unref();
168 168
169 bool useDFT = fSurfaceProps.isUseDistanceFieldFonts(); 169 bool useDFT = fSurfaceProps.isUseDistanceFieldFonts();
170 fTextContext = fContext->createTextContext(fRenderTarget, this, this->getLea kyProperties(), 170 fTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProp erties(), useDFT);
171 useDFT);
172 fDrawContext.reset(SkRef(fContext->drawContext())); 171 fDrawContext.reset(SkRef(fContext->drawContext()));
173 } 172 }
174 173
175 GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::B udgeted budgeted, 174 GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::B udgeted budgeted,
176 const SkImageInfo& origInfo, int sampleCount) { 175 const SkImageInfo& origInfo, int sampleCount) {
177 if (kUnknown_SkColorType == origInfo.colorType() || 176 if (kUnknown_SkColorType == origInfo.colorType() ||
178 origInfo.width() < 0 || origInfo.height() < 0) { 177 origInfo.width() < 0 || origInfo.height() < 0) {
179 return NULL; 178 return NULL;
180 } 179 }
181 180
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 return; 618 return;
620 } 619 }
621 620
622 fDrawContext->drawOval(fRenderTarget, fClip, grPaint, *draw.fMatrix, oval, s trokeInfo); 621 fDrawContext->drawOval(fRenderTarget, fClip, grPaint, *draw.fMatrix, oval, s trokeInfo);
623 } 622 }
624 623
625 #include "SkMaskFilter.h" 624 #include "SkMaskFilter.h"
626 625
627 /////////////////////////////////////////////////////////////////////////////// 626 ///////////////////////////////////////////////////////////////////////////////
628 627
629 // helpers for applying mask filters 628 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; 629 SkBitmap result;
761 result.setInfo(SkImageInfo::MakeN32Premul(width, height)); 630 result.setInfo(SkImageInfo::MakeN32Premul(width, height));
762 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unre f(); 631 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unre f();
763 return result; 632 return result;
764 } 633 }
765 634
766 };
767
768 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, 635 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
769 const SkPaint& paint, const SkMatrix* prePathMatrix, 636 const SkPaint& paint, const SkMatrix* prePathMatrix,
770 bool pathIsMutable) { 637 bool pathIsMutable) {
771 CHECK_FOR_ANNOTATION(paint); 638 CHECK_FOR_ANNOTATION(paint);
772 CHECK_SHOULD_DRAW(draw); 639 CHECK_SHOULD_DRAW(draw);
773 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext); 640 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext);
774 641
775 return this->internalDrawPath(origSrcPath, paint, *draw.fMatrix, prePathMatr ix, 642 fDrawContext->drawPathFull(fContext, fRenderTarget, fClip,
776 draw.fClip->getBounds(), pathIsMutable); 643 origSrcPath, paint,
777 } 644 *draw.fMatrix, prePathMatrix,
778 645 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 } 646 }
920 647
921 static const int kBmpSmallTileSize = 1 << 10; 648 static const int kBmpSmallTileSize = 1 << 10;
922 649
923 static inline int get_tile_count(const SkIRect& srcRect, int tileSize) { 650 static inline int get_tile_count(const SkIRect& srcRect, int tileSize) {
924 int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1; 651 int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1;
925 int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1; 652 int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1;
926 return tilesX * tilesY; 653 return tilesX * tilesY;
927 } 654 }
928 655
(...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after
1924 draw.fClip->getBounds()); 1651 draw.fClip->getBounds());
1925 } 1652 }
1926 1653
1927 void SkGpuDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSca lar x, SkScalar y, 1654 void SkGpuDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSca lar x, SkScalar y,
1928 const SkPaint& paint, SkDrawFilter* drawFilter) { 1655 const SkPaint& paint, SkDrawFilter* drawFilter) {
1929 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawTextBlob", fContext); 1656 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawTextBlob", fContext);
1930 CHECK_SHOULD_DRAW(draw); 1657 CHECK_SHOULD_DRAW(draw);
1931 1658
1932 SkDEBUGCODE(this->validate();) 1659 SkDEBUGCODE(this->validate();)
1933 1660
1934 fTextContext->drawTextBlob(fRenderTarget, fClip, paint, *draw.fMatrix, blob, x, y, drawFilter, 1661 fTextContext->drawTextBlob(this, fRenderTarget, fClip, paint, *draw.fMatrix,
1935 draw.fClip->getBounds()); 1662 blob, x, y, drawFilter, draw.fClip->getBounds());
1936 } 1663 }
1937 1664
1938 /////////////////////////////////////////////////////////////////////////////// 1665 ///////////////////////////////////////////////////////////////////////////////
1939 1666
1940 bool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const { 1667 bool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const {
1941 if (paint.getShader() || 1668 if (paint.getShader() ||
1942 !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode) || 1669 !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode) ||
1943 paint.getMaskFilter() || 1670 paint.getMaskFilter() ||
1944 paint.getRasterizer() || 1671 paint.getRasterizer() ||
1945 paint.getColorFilter() || 1672 paint.getColorFilter() ||
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2064 #endif 1791 #endif
2065 } 1792 }
2066 1793
2067 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { 1794 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() {
2068 // We always return a transient cache, so it is freed after each 1795 // We always return a transient cache, so it is freed after each
2069 // filter traversal. 1796 // filter traversal.
2070 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); 1797 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize);
2071 } 1798 }
2072 1799
2073 #endif 1800 #endif
OLDNEW
« src/gpu/GrAtlasTextContext.cpp ('K') | « src/gpu/SkGpuDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698