OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2015 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "SkGpuDevice.h" | |
9 | |
10 #include "GrBlurUtils.h" | |
11 #include "GrCaps.h" | |
12 #include "GrDrawContext.h" | |
13 #include "GrStrokeInfo.h" | |
14 #include "GrTextureParamsAdjuster.h" | |
15 #include "SkDraw.h" | |
16 #include "SkGrPriv.h" | |
17 #include "SkMaskFilter.h" | |
18 #include "effects/GrBicubicEffect.h" | |
19 #include "effects/GrSimpleTextureEffect.h" | |
20 #include "effects/GrTextureDomain.h" | |
21 | |
22 static inline bool use_shader(bool textureIsAlphaOnly, const SkPaint& paint) { | |
23 return textureIsAlphaOnly && paint.getShader(); | |
24 } | |
25 | |
26 static const GrFragmentProcessor* mix_texture_fp_with_paint_color_and_shader( | |
27 const GrFragmentProcessor* textureFP, | |
28 bool textureIsAlphaOnly, | |
29 GrContext* context, | |
30 const SkMatrix& viewMatrix, | |
31 const SkPaint& paint) { | |
robertphillips
2015/11/05 20:49:39
'\n' ?
bsalomon
2015/11/06 15:24:26
Done.
| |
32 if (textureIsAlphaOnly) { | |
33 if (const SkShader* shader = paint.getShader()) { | |
34 SkAutoTUnref<const GrFragmentProcessor> shaderFP( | |
35 shader->asFragmentProcessor(context, | |
36 viewMatrix, | |
37 nullptr, | |
38 paint.getFilterQuality())); | |
39 if (!shaderFP) { | |
40 return nullptr; | |
41 } | |
42 const GrFragmentProcessor* fpSeries[] = { shaderFP, textureFP }; | |
43 return GrFragmentProcessor::RunInSeries(fpSeries, 2); | |
44 } else { | |
45 return GrFragmentProcessor::MulOutputByInputUnpremulColor(textureFP) ; | |
46 } | |
47 } else { | |
48 return GrFragmentProcessor::MulOutputByInputAlpha(textureFP); | |
49 } | |
50 } | |
51 | |
52 void SkGpuDevice::drawTextureRect(GrTextureAdjuster* adjuster, | |
53 bool alphaTexture, | |
54 const SkRect& clippedSrcRect, | |
55 const SkRect& dstRect, | |
56 const SkMatrix& viewMatrix, | |
57 const GrClip& clip, | |
58 const SkPaint& paint, | |
59 SkCanvas::SrcRectConstraint constraint) { | |
60 SkMatrix localMatrix; | |
61 if (localMatrix.setRectToRect(clippedSrcRect, dstRect, SkMatrix::kFill_Scale ToFit)) { | |
62 this->drawTextureRectPrecomputedLocalMatrix(adjuster, alphaTexture, clip pedSrcRect, | |
63 dstRect, viewMatrix, localMa trix, clip, | |
64 paint, constraint); | |
65 } | |
66 } | |
67 | |
68 void SkGpuDevice::drawTextureRectPrecomputedLocalMatrix(GrTextureAdjuster* adjus ter, | |
69 bool alphaTexture, | |
70 const SkRect& clippedSrc Rect, | |
71 const SkRect& dstRect, | |
72 const SkMatrix& viewMatr ix, | |
73 const SkMatrix& localMat rix, | |
74 const GrClip& clip, | |
75 const SkPaint& paint, | |
76 SkCanvas::SrcRectConstra int constraint) { | |
77 // Specifying the texture coords as local coordinates is an attempt to enabl e more batching | |
78 // by not baking anything about the srcRect, dstRect, or viewMatrix, into th e texture FP. In | |
79 // the future this should be an opaque optimization enabled by the combinati on of batch/GP and | |
80 // FP. | |
81 const SkMatrix* textureFPMatrix; | |
82 SkMatrix tempMatrix; | |
83 const SkMaskFilter* mf = paint.getMaskFilter(); | |
84 GrTexture* texture = adjuster->originalTexture(); | |
85 // The shader expects proper local coords, so we can't replace local coords with texture coords | |
86 // if the shader will be used. If we have a mask filter we will change the u nderlying geometry | |
87 // that is rendered. | |
88 bool canUseTextureCoordsAsLocalCoords = !use_shader(alphaTexture, paint) && !mf; | |
89 if (canUseTextureCoordsAsLocalCoords) { | |
90 textureFPMatrix = &SkMatrix::I(); | |
91 } else { | |
92 if (!localMatrix.invert(&tempMatrix)) { | |
93 return; | |
94 } | |
95 tempMatrix.postIDiv(texture->width(), texture->height()); | |
96 textureFPMatrix = &tempMatrix; | |
97 } | |
98 | |
99 bool doBicubic; | |
100 GrTextureParams::FilterMode fm = | |
101 GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), viewMatrix, lo calMatrix, | |
102 &doBicubic); | |
103 const GrTextureParams::FilterMode* filterMode = doBicubic ? nullptr : &fm; | |
104 | |
105 GrTextureAdjuster::FilterConstraint constraintMode; | |
106 if (SkCanvas::kFast_SrcRectConstraint == constraint) { | |
107 constraintMode = GrTextureAdjuster::kNo_FilterConstraint; | |
108 } else { | |
109 constraintMode = GrTextureAdjuster::kYes_FilterConstraint; | |
110 } | |
111 | |
112 // If we have to outset for AA then we will generate texture coords outside the src rect. The | |
113 // same happens for any mask filter that extends the bounds rendered in the dst. | |
114 bool coordsAllInsideSrcRect = !paint.isAntiAlias() && !mf; | |
115 | |
116 SkAutoTUnref<const GrFragmentProcessor> fp(adjuster->createFragmentProcessor ( | |
117 *textureFPMatrix, clippedSrcRect, constraintMode, coordsAllInsideSrcRect , filterMode)); | |
118 if (!fp) { | |
119 return; | |
120 } | |
121 fp.reset(mix_texture_fp_with_paint_color_and_shader(fp, alphaTexture, this-> context(), | |
122 viewMatrix, paint)); | |
123 GrPaint grPaint; | |
124 if (!SkPaintToGrPaintReplaceShader(fContext, paint, fp, &grPaint)) { | |
125 return; | |
126 } | |
127 | |
128 if (canUseTextureCoordsAsLocalCoords) { | |
129 SkRect localRect; | |
130 localRect.fLeft = clippedSrcRect.fLeft / texture->width(); | |
131 localRect.fBottom = clippedSrcRect.fBottom / texture->height(); | |
132 localRect.fRight = clippedSrcRect.fRight / texture->width(); | |
133 localRect.fTop = clippedSrcRect.fTop / texture->height(); | |
134 fDrawContext->fillRectToRect(clip, grPaint, viewMatrix, dstRect, localRe ct); | |
135 return; | |
136 } | |
137 | |
138 if (!mf) { | |
139 fDrawContext->drawRect(clip, grPaint, viewMatrix, dstRect); | |
140 return; | |
141 } | |
142 | |
143 // First see if we can do the draw + mask filter direct to the dst. | |
144 SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); | |
145 SkRRect rrect; | |
146 rrect.setRect(dstRect); | |
147 if (mf->directFilterRRectMaskGPU(fContext->textureProvider(), | |
148 fDrawContext, | |
149 &grPaint, | |
150 clip, | |
151 viewMatrix, | |
152 rec, | |
153 rrect)) { | |
154 return; | |
155 } | |
156 SkPath rectPath; | |
157 rectPath.addRect(dstRect); | |
158 GrBlurUtils::drawPathWithMaskFilter(this->context(), fDrawContext, fRenderTa rget, fClip, | |
159 rectPath, &grPaint, viewMatrix, mf, pain t.getPathEffect(), | |
160 GrStrokeInfo::FillInfo()); | |
161 } | |
OLD | NEW |