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

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

Issue 18110012: Add canFilterMaskGPU & filterMaskGPU to SkMaskFilter (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: added comments & fixed nits Created 7 years, 5 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 | Annotate | Revision Log
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 "effects/GrTextureDomainEffect.h" 10 #include "effects/GrTextureDomainEffect.h"
(...skipping 29 matching lines...) Expand all
40 40
41 // we use the same effect slot on GrPaint for bitmaps and shaders (since drawBit map, drawSprite, 41 // we use the same effect slot on GrPaint for bitmaps and shaders (since drawBit map, drawSprite,
42 // and drawDevice ignore SkShader) 42 // and drawDevice ignore SkShader)
43 enum { 43 enum {
44 kShaderEffectIdx = 0, 44 kShaderEffectIdx = 0,
45 kBitmapEffectIdx = 0, 45 kBitmapEffectIdx = 0,
46 kColorFilterEffectIdx = 1, 46 kColorFilterEffectIdx = 1,
47 kXfermodeEffectIdx = 2, 47 kXfermodeEffectIdx = 2,
48 }; 48 };
49 49
50 #define MAX_BLUR_SIGMA 4.0f
51 // FIXME: This value comes from from SkBlurMaskFilter.cpp.
52 // Should probably be put in a common header someplace.
53 #define MAX_BLUR_RADIUS SkIntToScalar(128)
54 // This constant approximates the scaling done in the software path's
55 // "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)).
56 // IMHO, it actually should be 1: we blur "less" than we should do
57 // according to the CSS and canvas specs, simply because Safari does the same.
58 // Firefox used to do the same too, until 4.0 where they fixed it. So at some
59 // point we should probably get rid of these scaling constants and rebaseline
60 // all the blur tests.
61 #define BLUR_SIGMA_SCALE 0.6f
62 // This constant represents the screen alignment criterion in texels for 50 // This constant represents the screen alignment criterion in texels for
63 // requiring texture domain clamping to prevent color bleeding when drawing 51 // requiring texture domain clamping to prevent color bleeding when drawing
64 // a sub region of a larger source image. 52 // a sub region of a larger source image.
65 #define COLOR_BLEED_TOLERANCE SkFloatToScalar(0.001f) 53 #define COLOR_BLEED_TOLERANCE SkFloatToScalar(0.001f)
66 54
67 #define DO_DEFERRED_CLEAR() \ 55 #define DO_DEFERRED_CLEAR() \
68 do { \ 56 do { \
69 if (fNeedClear) { \ 57 if (fNeedClear) { \
70 this->clear(SK_ColorTRANSPARENT); \ 58 this->clear(SK_ColorTRANSPARENT); \
71 } \ 59 } \
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 } 757 }
770 758
771 #include "SkMaskFilter.h" 759 #include "SkMaskFilter.h"
772 #include "SkBounder.h" 760 #include "SkBounder.h"
773 761
774 /////////////////////////////////////////////////////////////////////////////// 762 ///////////////////////////////////////////////////////////////////////////////
775 763
776 // helpers for applying mask filters 764 // helpers for applying mask filters
777 namespace { 765 namespace {
778 766
779 // We prefer to blur small rect with small radius via CPU. 767 // Draw a mask using the supplied paint. Since the coverage/geometry
780 #define MIN_GPU_BLUR_SIZE SkIntToScalar(64) 768 // is already burnt into the mask this boils down to a rect draw.
781 #define MIN_GPU_BLUR_RADIUS SkIntToScalar(32) 769 // Return true if the mask was successfully drawn.
782 inline bool shouldDrawBlurWithCPU(const SkRect& rect, SkScalar radius) { 770 bool draw_mask(GrContext* context, const SkRect& maskRect,
783 if (rect.width() <= MIN_GPU_BLUR_SIZE && 771 GrPaint* grp, GrTexture* mask) {
784 rect.height() <= MIN_GPU_BLUR_SIZE &&
785 radius <= MIN_GPU_BLUR_RADIUS) {
786 return true;
787 }
788 return false;
789 }
790
791 bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, const SkSt rokeRec& stroke,
792 SkMaskFilter* filter, const SkRegion& clip,
793 SkBounder* bounder, GrPaint* grp) {
794 SkMaskFilter::BlurInfo info;
795 SkMaskFilter::BlurType blurType = filter->asABlur(&info);
796 if (SkMaskFilter::kNone_BlurType == blurType) {
797 return false;
798 }
799 SkScalar radius = info.fIgnoreTransform ? info.fRadius
800 : context->getMatrix().mapRadius(inf o.fRadius);
801 radius = SkMinScalar(radius, MAX_BLUR_RADIUS);
802 if (radius <= 0) {
803 return false;
804 }
805
806 SkRect srcRect = devPath.getBounds();
807 if (shouldDrawBlurWithCPU(srcRect, radius)) {
808 return false;
809 }
810
811 float sigma = SkScalarToFloat(radius) * BLUR_SIGMA_SCALE;
812 float sigma3 = sigma * 3.0f;
813
814 SkRect clipRect;
815 clipRect.set(clip.getBounds());
816
817 // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area.
818 srcRect.inset(SkFloatToScalar(-sigma3), SkFloatToScalar(-sigma3));
819 clipRect.inset(SkFloatToScalar(-sigma3), SkFloatToScalar(-sigma3));
820 srcRect.intersect(clipRect);
821 SkRect finalRect = srcRect;
822 SkIRect finalIRect;
823 finalRect.roundOut(&finalIRect);
824 if (clip.quickReject(finalIRect)) {
825 return true;
826 }
827 if (bounder && !bounder->doIRect(finalIRect)) {
828 return true;
829 }
830 GrPoint offset = GrPoint::Make(-srcRect.fLeft, -srcRect.fTop);
831 srcRect.offset(offset);
832 GrTextureDesc desc;
833 desc.fFlags = kRenderTarget_GrTextureFlagBit;
834 desc.fWidth = SkScalarCeilToInt(srcRect.width());
835 desc.fHeight = SkScalarCeilToInt(srcRect.height());
836 // We actually only need A8, but it often isn't supported as a
837 // render target so default to RGBA_8888
838 desc.fConfig = kRGBA_8888_GrPixelConfig;
839
840 if (context->isConfigRenderable(kAlpha_8_GrPixelConfig)) {
841 desc.fConfig = kAlpha_8_GrPixelConfig;
842 }
843
844 GrAutoScratchTexture pathEntry(context, desc);
845 GrTexture* pathTexture = pathEntry.texture();
846 if (NULL == pathTexture) {
847 return false;
848 }
849
850 SkAutoTUnref<GrTexture> blurTexture;
851
852 {
853 GrContext::AutoRenderTarget art(context, pathTexture->asRenderTarget());
854 GrContext::AutoClip ac(context, srcRect);
855
856 context->clear(NULL, 0);
857
858 GrPaint tempPaint;
859 if (grp->isAntiAlias()) {
860 tempPaint.setAntiAlias(true);
861 // AA uses the "coverage" stages on GrDrawTarget. Coverage with a ds t
862 // blend coeff of zero requires dual source blending support in orde r
863 // to properly blend partially covered pixels. This means the AA
864 // code path may not be taken. So we use a dst blend coeff of ISA. W e
865 // could special case AA draws to a dst surface with known alpha=0 t o
866 // use a zero dst coeff when dual source blending isn't available.f
867 tempPaint.setBlendFunc(kOne_GrBlendCoeff, kISC_GrBlendCoeff);
868 }
869
870 GrContext::AutoMatrix am;
871
872 // Draw hard shadow to pathTexture with path top-left at origin using te mpPaint.
873 SkMatrix translate;
874 translate.setTranslate(offset.fX, offset.fY);
875 am.set(context, translate);
876 context->drawPath(tempPaint, devPath, stroke);
877
878 // If we're doing a normal blur, we can clobber the pathTexture in the
879 // gaussianBlur. Otherwise, we need to save it for later compositing.
880 bool isNormalBlur = blurType == SkMaskFilter::kNormal_BlurType;
881 blurTexture.reset(context->gaussianBlur(pathTexture, isNormalBlur,
882 srcRect, sigma, sigma));
883 if (NULL == blurTexture) {
884 return false;
885 }
886
887 if (!isNormalBlur) {
888 context->setIdentityMatrix();
889 GrPaint paint;
890 SkMatrix matrix;
891 matrix.setIDiv(pathTexture->width(), pathTexture->height());
892 // Blend pathTexture over blurTexture.
893 context->setRenderTarget(blurTexture->asRenderTarget());
894 paint.colorStage(0)->setEffect(
895 GrSimpleTextureEffect::Create(pathTexture, matrix))->unref();
896 if (SkMaskFilter::kInner_BlurType == blurType) {
897 // inner: dst = dst * src
898 paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff);
899 } else if (SkMaskFilter::kSolid_BlurType == blurType) {
900 // solid: dst = src + dst - src * dst
901 // = (1 - dst) * src + 1 * dst
902 paint.setBlendFunc(kIDC_GrBlendCoeff, kOne_GrBlendCoeff);
903 } else if (SkMaskFilter::kOuter_BlurType == blurType) {
904 // outer: dst = dst * (1 - src)
905 // = 0 * src + (1 - src) * dst
906 paint.setBlendFunc(kZero_GrBlendCoeff, kISC_GrBlendCoeff);
907 }
908 context->drawRect(paint, srcRect);
909 }
910 }
911 772
912 GrContext::AutoMatrix am; 773 GrContext::AutoMatrix am;
913 if (!am.setIdentity(context, grp)) { 774 if (!am.setIdentity(context, grp)) {
914 return false; 775 return false;
915 } 776 }
916 777
917 static const int MASK_IDX = GrPaint::kMaxCoverageStages - 1; 778 static const int MASK_IDX = GrPaint::kMaxCoverageStages - 1;
918 // we assume the last mask index is available for use 779 // we assume the last mask index is available for use
919 GrAssert(!grp->isCoverageStageEnabled(MASK_IDX)); 780 GrAssert(!grp->isCoverageStageEnabled(MASK_IDX));
920 781
921 SkMatrix matrix; 782 SkMatrix matrix;
922 matrix.setTranslate(-finalRect.fLeft, -finalRect.fTop); 783 matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop);
923 matrix.postIDiv(blurTexture->width(), blurTexture->height()); 784 matrix.postIDiv(mask->width(), mask->height());
924 785
925 grp->coverageStage(MASK_IDX)->reset(); 786 grp->coverageStage(MASK_IDX)->reset();
926 grp->coverageStage(MASK_IDX)->setEffect( 787 grp->coverageStage(MASK_IDX)->setEffect(GrSimpleTextureEffect::Create(mask, matrix))->unref();
927 GrSimpleTextureEffect::Create(blurTexture, matrix))->unref(); 788 context->drawRect(*grp, maskRect);
928 context->drawRect(*grp, finalRect);
929 return true; 789 return true;
930 } 790 }
931 791
932 bool drawWithMaskFilter(GrContext* context, const SkPath& devPath, 792 bool draw_with_mask_filter(GrContext* context, const SkPath& devPath,
933 SkMaskFilter* filter, const SkRegion& clip, SkBounder* b ounder, 793 SkMaskFilter* filter, const SkRegion& clip, SkBounder * bounder,
934 GrPaint* grp, SkPaint::Style style) { 794 GrPaint* grp, SkPaint::Style style) {
935 SkMask srcM, dstM; 795 SkMask srcM, dstM;
936 796
937 if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &context->getMat rix(), &srcM, 797 if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &context->getMat rix(), &srcM,
938 SkMask::kComputeBoundsAndRenderImage_CreateMode, sty le)) { 798 SkMask::kComputeBoundsAndRenderImage_CreateMode, sty le)) {
939 return false; 799 return false;
940 } 800 }
941 SkAutoMaskFreeImage autoSrc(srcM.fImage); 801 SkAutoMaskFreeImage autoSrc(srcM.fImage);
942 802
943 if (!filter->filterMask(&dstM, srcM, context->getMatrix(), NULL)) { 803 if (!filter->filterMask(&dstM, srcM, context->getMatrix(), NULL)) {
944 return false; 804 return false;
945 } 805 }
946 // this will free-up dstM when we're done (allocated in filterMask()) 806 // this will free-up dstM when we're done (allocated in filterMask())
947 SkAutoMaskFreeImage autoDst(dstM.fImage); 807 SkAutoMaskFreeImage autoDst(dstM.fImage);
948 808
949 if (clip.quickReject(dstM.fBounds)) { 809 if (clip.quickReject(dstM.fBounds)) {
950 return false; 810 return false;
951 } 811 }
952 if (bounder && !bounder->doIRect(dstM.fBounds)) { 812 if (bounder && !bounder->doIRect(dstM.fBounds)) {
953 return false; 813 return false;
954 } 814 }
955 815
956 // we now have a device-aligned 8bit mask in dstM, ready to be drawn using 816 // we now have a device-aligned 8bit mask in dstM, ready to be drawn using
957 // the current clip (and identity matrix) and GrPaint settings 817 // the current clip (and identity matrix) and GrPaint settings
958 GrContext::AutoMatrix am;
959 am.setIdentity(context, grp);
960
961 GrTextureDesc desc; 818 GrTextureDesc desc;
962 desc.fWidth = dstM.fBounds.width(); 819 desc.fWidth = dstM.fBounds.width();
963 desc.fHeight = dstM.fBounds.height(); 820 desc.fHeight = dstM.fBounds.height();
964 desc.fConfig = kAlpha_8_GrPixelConfig; 821 desc.fConfig = kAlpha_8_GrPixelConfig;
965 822
966 GrAutoScratchTexture ast(context, desc); 823 GrAutoScratchTexture ast(context, desc);
967 GrTexture* texture = ast.texture(); 824 GrTexture* texture = ast.texture();
968 825
969 if (NULL == texture) { 826 if (NULL == texture) {
970 return false; 827 return false;
971 } 828 }
972 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, 829 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
973 dstM.fImage, dstM.fRowBytes); 830 dstM.fImage, dstM.fRowBytes);
974 831
975 static const int MASK_IDX = GrPaint::kMaxCoverageStages - 1; 832 SkRect maskRect = SkRect::MakeFromIRect(dstM.fBounds);
976 // we assume the last mask index is available for use
977 GrAssert(!grp->isCoverageStageEnabled(MASK_IDX));
978 833
979 SkMatrix m; 834 return draw_mask(context, maskRect, grp, texture);
980 m.setTranslate(-dstM.fBounds.fLeft*SK_Scalar1, -dstM.fBounds.fTop*SK_Scalar1 ); 835 }
981 m.postIDiv(texture->width(), texture->height());
982 836
983 grp->coverageStage(MASK_IDX)->setEffect(GrSimpleTextureEffect::Create(textur e, m))->unref(); 837 // Create a mask of 'devPath' and place the result in 'mask'. Return true on
984 GrRect d; 838 // success; false otherwise.
985 d.setLTRB(SkIntToScalar(dstM.fBounds.fLeft), 839 bool create_mask_GPU(GrContext* context,
986 SkIntToScalar(dstM.fBounds.fTop), 840 const SkRect& maskRect,
987 SkIntToScalar(dstM.fBounds.fRight), 841 const SkPath& devPath,
988 SkIntToScalar(dstM.fBounds.fBottom)); 842 const SkStrokeRec& stroke,
843 bool doAA,
844 GrAutoScratchTexture* mask) {
845 GrTextureDesc desc;
846 desc.fFlags = kRenderTarget_GrTextureFlagBit;
847 desc.fWidth = SkScalarCeilToInt(maskRect.width());
848 desc.fHeight = SkScalarCeilToInt(maskRect.height());
849 // We actually only need A8, but it often isn't supported as a
850 // render target so default to RGBA_8888
851 desc.fConfig = kRGBA_8888_GrPixelConfig;
852 if (context->isConfigRenderable(kAlpha_8_GrPixelConfig)) {
853 desc.fConfig = kAlpha_8_GrPixelConfig;
854 }
989 855
990 context->drawRect(*grp, d); 856 mask->set(context, desc);
857 if (NULL == mask->texture()) {
858 return false;
859 }
860
861 GrTexture* maskTexture = mask->texture();
862 SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height());
863
864 GrContext::AutoRenderTarget art(context, maskTexture->asRenderTarget());
865 GrContext::AutoClip ac(context, clipRect);
866
867 context->clear(NULL, 0x0);
868
869 GrPaint tempPaint;
870 if (doAA) {
871 tempPaint.setAntiAlias(true);
872 // AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst
873 // blend coeff of zero requires dual source blending support in order
874 // to properly blend partially covered pixels. This means the AA
875 // code path may not be taken. So we use a dst blend coeff of ISA. We
876 // could special case AA draws to a dst surface with known alpha=0 to
877 // use a zero dst coeff when dual source blending isn't available.
878 tempPaint.setBlendFunc(kOne_GrBlendCoeff, kISC_GrBlendCoeff);
879 }
880
881 GrContext::AutoMatrix am;
882
883 // Draw the mask into maskTexture with the path's top-left at the origin usi ng tempPaint.
884 SkMatrix translate;
885 translate.setTranslate(-maskRect.fLeft, -maskRect.fTop);
886 am.set(context, translate);
887 context->drawPath(tempPaint, devPath, stroke);
991 return true; 888 return true;
992 } 889 }
993 890
891 SkBitmap wrap_texture(GrTexture* texture) {
892 SkBitmap result;
893 bool dummy;
894 SkBitmap::Config config = grConfig2skConfig(texture->config(), &dummy);
895 result.setConfig(config, texture->width(), texture->height());
896 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (texture)))->unref();
897 return result;
994 } 898 }
995 899
996 /////////////////////////////////////////////////////////////////////////////// 900 };
997 901
998 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, 902 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
999 const SkPaint& paint, const SkMatrix* prePathMatrix, 903 const SkPaint& paint, const SkMatrix* prePathMatrix,
1000 bool pathIsMutable) { 904 bool pathIsMutable) {
1001 CHECK_FOR_NODRAW_ANNOTATION(paint); 905 CHECK_FOR_NODRAW_ANNOTATION(paint);
1002 CHECK_SHOULD_DRAW(draw, false); 906 CHECK_SHOULD_DRAW(draw, false);
1003 907
1004 GrPaint grPaint; 908 GrPaint grPaint;
1005 if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { 909 if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
1006 return; 910 return;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 } 948 }
1045 949
1046 if (!pathEffect && doHairLine) { 950 if (!pathEffect && doHairLine) {
1047 stroke.setHairlineStyle(); 951 stroke.setHairlineStyle();
1048 } 952 }
1049 953
1050 if (paint.getMaskFilter()) { 954 if (paint.getMaskFilter()) {
1051 if (!stroke.isHairlineStyle()) { 955 if (!stroke.isHairlineStyle()) {
1052 if (stroke.applyToPath(&tmpPath, *pathPtr)) { 956 if (stroke.applyToPath(&tmpPath, *pathPtr)) {
1053 pathPtr = &tmpPath; 957 pathPtr = &tmpPath;
958 pathIsMutable = true;
1054 stroke.setFillStyle(); 959 stroke.setFillStyle();
1055 } 960 }
1056 } 961 }
1057 962
1058 // avoid possibly allocating a new path in transform if we can 963 // avoid possibly allocating a new path in transform if we can
1059 SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath; 964 SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath;
1060 965
1061 // transform the path into device space 966 // transform the path into device space
1062 pathPtr->transform(fContext->getMatrix(), devPathPtr); 967 pathPtr->transform(fContext->getMatrix(), devPathPtr);
1063 if (!drawWithGPUMaskFilter(fContext, *devPathPtr, stroke, paint.getMaskF ilter(), 968
1064 *draw.fClip, draw.fBounder, &grPaint)) { 969 SkRect maskRect;
1065 SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_S tyle : 970 if (paint.getMaskFilter()->canFilterMaskGPU(devPathPtr->getBounds(),
1066 SkPaint::kFill_Sty le; 971 draw.fClip->getBounds(),
1067 drawWithMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(), 972 fContext->getMatrix(),
1068 *draw.fClip, draw.fBounder, &grPaint, style); 973 &maskRect)) {
974 SkIRect finalIRect;
975 maskRect.roundOut(&finalIRect);
976 if (draw.fClip->quickReject(finalIRect)) {
977 // clipped out
978 return;
979 }
980 if (NULL != draw.fBounder && !draw.fBounder->doIRect(finalIRect)) {
981 // nothing to draw
982 return;
983 }
984
985 GrAutoScratchTexture mask;
986
987 if (create_mask_GPU(fContext, maskRect, *devPathPtr, stroke,
988 grPaint.isAntiAlias(), &mask)) {
989 GrTexture* filtered;
990
991 if (paint.getMaskFilter()->filterMaskGPU(mask.texture(), maskRec t, &filtered, true)) {
992 SkAutoTUnref<GrTexture> atu(filtered);
993
994 if (draw_mask(fContext, maskRect, &grPaint, filtered)) {
995 // This path is completely drawn
996 return;
997 }
998 }
999 }
1069 } 1000 }
1001
1002 // draw the mask on the CPU - this is a fallthrough path in case the
1003 // GPU path fails
1004 SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style :
1005 SkPaint::kFill_Style;
1006 draw_with_mask_filter(fContext, *devPathPtr, paint.getMaskFilter(),
1007 *draw.fClip, draw.fBounder, &grPaint, style);
1070 return; 1008 return;
1071 } 1009 }
1072 1010
1073 fContext->drawPath(grPaint, *pathPtr, stroke); 1011 fContext->drawPath(grPaint, *pathPtr, stroke);
1074 } 1012 }
1075 1013
1076 namespace { 1014 namespace {
1077 1015
1078 inline int get_tile_count(int l, int t, int r, int b, int tileSize) { 1016 inline int get_tile_count(int l, int t, int r, int b, int tileSize) {
1079 int tilesX = (r / tileSize) - (l / tileSize) + 1; 1017 int tilesX = (r / tileSize) - (l / tileSize) + 1;
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 textureDomain, 1368 textureDomain,
1431 GrTextureDomainEffect::kClamp _WrapMode, 1369 GrTextureDomainEffect::kClamp _WrapMode,
1432 params.isBilerp())); 1370 params.isBilerp()));
1433 } else { 1371 } else {
1434 effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), param s)); 1372 effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), param s));
1435 } 1373 }
1436 grPaint->colorStage(kBitmapEffectIdx)->setEffect(effect); 1374 grPaint->colorStage(kBitmapEffectIdx)->setEffect(effect);
1437 fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m); 1375 fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m);
1438 } 1376 }
1439 1377
1440 static SkBitmap wrap_texture(GrTexture* texture) {
1441 SkBitmap result;
1442 bool dummy;
1443 SkBitmap::Config config = grConfig2skConfig(texture->config(), &dummy);
1444 result.setConfig(config, texture->width(), texture->height());
1445 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (texture)))->unref();
1446 return result;
1447 }
1448
1449 static bool filter_texture(SkDevice* device, GrContext* context, 1378 static bool filter_texture(SkDevice* device, GrContext* context,
1450 GrTexture* texture, SkImageFilter* filter, 1379 GrTexture* texture, SkImageFilter* filter,
1451 int w, int h, SkBitmap* result) { 1380 int w, int h, SkBitmap* result) {
1452 GrAssert(filter); 1381 GrAssert(filter);
1453 SkDeviceImageFilterProxy proxy(device); 1382 SkDeviceImageFilterProxy proxy(device);
1454 1383
1455 if (filter->canFilterImageGPU()) { 1384 if (filter->canFilterImageGPU()) {
1456 // Save the render target and set it to NULL, so we don't accidentally d raw to it in the 1385 // Save the render target and set it to NULL, so we don't accidentally d raw to it in the
1457 // filter. Also set the clip wide open and the matrix to identity. 1386 // filter. Also set the clip wide open and the matrix to identity.
1458 GrContext::AutoWideOpenIdentityDraw awo(context, NULL); 1387 GrContext::AutoWideOpenIdentityDraw awo(context, NULL);
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 // want explicitly our impl, so guard against a subclass of us overriding it 1530 // want explicitly our impl, so guard against a subclass of us overriding it
1602 if (!this->SkGpuDevice::canHandleImageFilter(filter)) { 1531 if (!this->SkGpuDevice::canHandleImageFilter(filter)) {
1603 return false; 1532 return false;
1604 } 1533 }
1605 1534
1606 SkAutoLockPixels alp(src, !src.getTexture()); 1535 SkAutoLockPixels alp(src, !src.getTexture());
1607 if (!src.getTexture() && !src.readyToDraw()) { 1536 if (!src.getTexture() && !src.readyToDraw()) {
1608 return false; 1537 return false;
1609 } 1538 }
1610 1539
1611 GrPaint paint;
1612
1613 GrTexture* texture; 1540 GrTexture* texture;
1614 // We assume here that the filter will not attempt to tile the src. Otherwis e, this cache lookup 1541 // We assume here that the filter will not attempt to tile the src. Otherwis e, this cache lookup
1615 // must be pushed upstack. 1542 // must be pushed upstack.
1616 SkAutoCachedTexture act(this, src, NULL, &texture); 1543 SkAutoCachedTexture act(this, src, NULL, &texture);
1617 1544
1618 return filter_texture(this, fContext, texture, filter, src.width(), src.heig ht(), result); 1545 return filter_texture(this, fContext, texture, filter, src.width(), src.heig ht(), result);
1619 } 1546 }
1620 1547
1621 /////////////////////////////////////////////////////////////////////////////// 1548 ///////////////////////////////////////////////////////////////////////////////
1622 1549
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 GrTexture* texture, 1779 GrTexture* texture,
1853 bool needClear) 1780 bool needClear)
1854 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { 1781 : SkDevice(make_bitmap(context, texture->asRenderTarget())) {
1855 1782
1856 GrAssert(texture && texture->asRenderTarget()); 1783 GrAssert(texture && texture->asRenderTarget());
1857 // This constructor is called from onCreateCompatibleDevice. It has locked t he RT in the texture 1784 // This constructor is called from onCreateCompatibleDevice. It has locked t he RT in the texture
1858 // cache. We pass true for the third argument so that it will get unlocked. 1785 // cache. We pass true for the third argument so that it will get unlocked.
1859 this->initFromRenderTarget(context, texture->asRenderTarget(), true); 1786 this->initFromRenderTarget(context, texture->asRenderTarget(), true);
1860 fNeedClear = needClear; 1787 fNeedClear = needClear;
1861 } 1788 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698