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

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

Issue 1424313010: Separate out natively-texture image/bmp draws from cached-as-texture image/bmp draws (Closed) Base URL: https://skia.googlesource.com/skia.git@const
Patch Set: update Created 5 years, 1 month 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.cpp ('k') | src/gpu/SkGr.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 /** Determines how to combine the texture FP with the paint's color and SkShader , if any. */
27 static const GrFragmentProcessor* mix_texture_fp_with_paint_color_and_shader(
28 const GrFragmentProc essor* textureFP,
29 bool textureIsAlphaO nly,
30 GrContext* context,
31 const SkMatrix& view Matrix,
32 const SkPaint& paint ) {
33 // According to the SkCanvas API, we only consider the shader if the bitmap or image being
34 // rendered is alpha-only.
35 if (textureIsAlphaOnly) {
36 if (const SkShader* shader = paint.getShader()) {
37 SkAutoTUnref<const GrFragmentProcessor> shaderFP(
38 shader->asFragmentProcessor(context,
39 viewMatrix,
40 nullptr,
41 paint.getFilterQuality()));
42 if (!shaderFP) {
43 return nullptr;
44 }
45 const GrFragmentProcessor* fpSeries[] = { shaderFP, textureFP };
46 return GrFragmentProcessor::RunInSeries(fpSeries, 2);
47 } else {
48 return GrFragmentProcessor::MulOutputByInputUnpremulColor(textureFP) ;
49 }
50 } else {
51 return GrFragmentProcessor::MulOutputByInputAlpha(textureFP);
52 }
53 }
54
55 void SkGpuDevice::drawTextureAdjuster(GrTextureAdjuster* adjuster,
56 bool alphaOnly,
57 const SkRect* srcRect,
58 const SkRect* dstRect,
59 SkCanvas::SrcRectConstraint constraint,
60 const SkMatrix& viewMatrix,
61 const GrClip& clip,
62 const SkPaint& paint) {
63 // Figure out the actual dst and src rect by clipping the src rect to the bo unds of the
64 // adjuster. If the src rect is clipped then the dst rect must be recomputed . Also determine
65 // the matrix that maps the src rect to the dst rect.
66 SkRect clippedSrcRect;
67 SkRect clippedDstRect;
68 SkIRect contentIBounds;
69 adjuster->getContentArea(&contentIBounds);
70 const SkRect contentBounds = SkRect::Make(contentIBounds);
71 SkMatrix srcToDstMatrix;
72 if (srcRect) {
73 if (!dstRect) {
74 dstRect = &contentBounds;
75 }
76 if (!contentBounds.contains(*srcRect)) {
77 clippedSrcRect = *srcRect;
78 if (!clippedSrcRect.intersect(contentBounds)) {
79 return;
80 }
81 if (!srcToDstMatrix.setRectToRect(*srcRect, *dstRect, SkMatrix::kFil l_ScaleToFit)) {
82 return;
83 }
84 srcToDstMatrix.mapRect(&clippedDstRect, clippedSrcRect);
85 } else {
86 clippedSrcRect = *srcRect;
87 clippedDstRect = *dstRect;
88 if (!srcToDstMatrix.setRectToRect(*srcRect, *dstRect, SkMatrix::kFil l_ScaleToFit)) {
89 return;
90 }
91 }
92 } else {
93 clippedSrcRect = contentBounds;
94 if (dstRect) {
95 clippedDstRect = *dstRect;
96 if (!srcToDstMatrix.setRectToRect(contentBounds, *dstRect,
97 SkMatrix::kFill_ScaleToFit)) {
98 return;
99 }
100 } else {
101 clippedDstRect = contentBounds;
102 srcToDstMatrix.reset();
103 }
104 }
105
106 this->drawTextureAdjusterImpl(adjuster, alphaOnly, clippedSrcRect, clippedDs tRect, constraint,
107 viewMatrix, srcToDstMatrix, clip, paint);
108 }
109
110 void SkGpuDevice::drawTextureAdjusterImpl(GrTextureAdjuster* adjuster,
111 bool alphaTexture,
112 const SkRect& clippedSrcRect,
113 const SkRect& clippedDstRect,
114 SkCanvas::SrcRectConstraint constraint ,
115 const SkMatrix& viewMatrix,
116 const SkMatrix& srcToDstMatrix,
117 const GrClip& clip,
118 const SkPaint& paint) {
119 // Specifying the texture coords as local coordinates is an attempt to enabl e more batching
120 // by not baking anything about the srcRect, dstRect, or viewMatrix, into th e texture FP. In
121 // the future this should be an opaque optimization enabled by the combinati on of batch/GP and
122 // FP.
123 const SkMatrix* textureFPMatrix;
124 SkMatrix tempMatrix;
125 const SkMaskFilter* mf = paint.getMaskFilter();
126 GrTexture* texture = adjuster->originalTexture();
127 // The shader expects proper local coords, so we can't replace local coords with texture coords
128 // if the shader will be used. If we have a mask filter we will change the u nderlying geometry
129 // that is rendered.
130 bool canUseTextureCoordsAsLocalCoords = !use_shader(alphaTexture, paint) && !mf;
131 if (canUseTextureCoordsAsLocalCoords) {
132 textureFPMatrix = &SkMatrix::I();
133 } else {
134 if (!srcToDstMatrix.invert(&tempMatrix)) {
135 return;
136 }
137 tempMatrix.postIDiv(texture->width(), texture->height());
138 textureFPMatrix = &tempMatrix;
139 }
140
141 bool doBicubic;
142 GrTextureParams::FilterMode fm =
143 GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), viewMatrix, sr cToDstMatrix,
144 &doBicubic);
145 const GrTextureParams::FilterMode* filterMode = doBicubic ? nullptr : &fm;
146
147 GrTextureAdjuster::FilterConstraint constraintMode;
148 if (SkCanvas::kFast_SrcRectConstraint == constraint) {
149 constraintMode = GrTextureAdjuster::kNo_FilterConstraint;
150 } else {
151 constraintMode = GrTextureAdjuster::kYes_FilterConstraint;
152 }
153
154 // If we have to outset for AA then we will generate texture coords outside the src rect. The
155 // same happens for any mask filter that extends the bounds rendered in the dst.
156 // This is conservative as a mask filter does not have to expand the bounds rendered.
157 bool coordsAllInsideSrcRect = !paint.isAntiAlias() && !mf;
158
159 SkAutoTUnref<const GrFragmentProcessor> fp(adjuster->createFragmentProcessor (
160 *textureFPMatrix, clippedSrcRect, constraintMode, coordsAllInsideSrcRect , filterMode));
161 if (!fp) {
162 return;
163 }
164 fp.reset(mix_texture_fp_with_paint_color_and_shader(fp, alphaTexture, this-> context(),
165 viewMatrix, paint));
166 GrPaint grPaint;
167 if (!SkPaintToGrPaintReplaceShader(fContext, paint, fp, &grPaint)) {
168 return;
169 }
170
171 if (canUseTextureCoordsAsLocalCoords) {
172 SkRect localRect;
173 localRect.fLeft = clippedSrcRect.fLeft / texture->width();
174 localRect.fBottom = clippedSrcRect.fBottom / texture->height();
175 localRect.fRight = clippedSrcRect.fRight / texture->width();
176 localRect.fTop = clippedSrcRect.fTop / texture->height();
177 fDrawContext->fillRectToRect(clip, grPaint, viewMatrix, clippedDstRect, localRect);
178 return;
179 }
180
181 if (!mf) {
182 fDrawContext->drawRect(clip, grPaint, viewMatrix, clippedDstRect);
183 return;
184 }
185
186 // First see if we can do the draw + mask filter direct to the dst.
187 SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
188 SkRRect rrect;
189 rrect.setRect(clippedDstRect);
190 if (mf->directFilterRRectMaskGPU(fContext->textureProvider(),
191 fDrawContext,
192 &grPaint,
193 clip,
194 viewMatrix,
195 rec,
196 rrect)) {
197 return;
198 }
199 SkPath rectPath;
200 rectPath.addRect(clippedDstRect);
201 GrBlurUtils::drawPathWithMaskFilter(this->context(), fDrawContext, fRenderTa rget, fClip,
202 rectPath, &grPaint, viewMatrix, mf, pain t.getPathEffect(),
203 GrStrokeInfo::FillInfo());
204 }
OLDNEW
« no previous file with comments | « src/gpu/SkGpuDevice.cpp ('k') | src/gpu/SkGr.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698